diff --git a/prs/8803/9347543 b/prs/8803/22983057 similarity index 100% rename from prs/8803/9347543 rename to prs/8803/22983057 diff --git a/prs/8803/ct_logs/all_runs.html b/prs/8803/ct_logs/all_runs.html index 9a133a87af4a1..5d4c49f584044 100644 --- a/prs/8803/ct_logs/all_runs.html +++ b/prs/8803/ct_logs/all_runs.html @@ -107,7 +107,7 @@

All test runs in "ct_logs"

-Wed Sep 11 2024 12:06:30test_server@27af2e7fa355 +Thu Sep 12 2024 11:29:20test_server@a4cca6e7dcb5 - 1 make_test_dir.system_test @@ -119,7 +119,7 @@

All test runs in "ct_logs"

-Wed Sep 11 2024 11:10:18test_server@43e13ac1be0c +Thu Sep 12 2024 10:32:23test_server@7a1fde2d1d55 - 1 make_test_dir.stdlib_test @@ -136,7 +136,7 @@

All test runs in "ct_logs"



diff --git a/prs/8803/ct_logs/ct_log_cache b/prs/8803/ct_logs/ct_log_cache index db416f539ac05..e13bbe63824a3 100644 Binary files a/prs/8803/ct_logs/ct_log_cache and b/prs/8803/ct_logs/ct_log_cache differ diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/last_name b/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/last_name deleted file mode 100644 index 5f50ae9bda098..0000000000000 --- a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/last_name +++ /dev/null @@ -1 +0,0 @@ -/buildroot/otp/erts/make_test_dir/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30 diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/last_name b/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/last_name deleted file mode 100644 index 5f50ae9bda098..0000000000000 --- a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/last_name +++ /dev/null @@ -1 +0,0 @@ -/buildroot/otp/erts/make_test_dir/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30 diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/suite.summary b/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/suite.summary deleted file mode 100644 index b8ba691e7cbab..0000000000000 --- a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/suite.summary +++ /dev/null @@ -1 +0,0 @@ -{summary,{107,0,2,0,247874758}}. diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/totals.info b/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/totals.info deleted file mode 100644 index 7cd4a16c549d9..0000000000000 Binary files a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/totals.info and /dev/null differ diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/last_name b/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/last_name deleted file mode 100644 index d85af3980372c..0000000000000 --- a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/last_name +++ /dev/null @@ -1 +0,0 @@ -/buildroot/otp/lib/stdlib/make_test_dir/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55 diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/last_name b/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/last_name deleted file mode 100644 index d85af3980372c..0000000000000 --- a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/last_name +++ /dev/null @@ -1 +0,0 @@ -/buildroot/otp/lib/stdlib/make_test_dir/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55 diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/suite.summary b/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/suite.summary deleted file mode 100644 index 9bfe971cf233b..0000000000000 --- a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/suite.summary +++ /dev/null @@ -1 +0,0 @@ -{summary,{2358,0,48,0,3113804063}}. diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/totals.info b/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/totals.info deleted file mode 100644 index 71f15229d7f87..0000000000000 Binary files a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/totals.info and /dev/null differ diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/MY_MODULE.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/MY_MODULE.beam similarity index 90% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/MY_MODULE.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/MY_MODULE.beam index 69ff7ae5af0f8..d872351be26e0 100644 Binary files a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/MY_MODULE.beam and b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/MY_MODULE.beam differ diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/ct_default.css b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/ct_default.css similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/ct_default.css rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/ct_default.css diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/ctlog.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/ctlog.html similarity index 78% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/ctlog.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/ctlog.html index 3e28ba75b1856..ecc2fa77f8b68 100644 --- a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/ctlog.html +++ b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/ctlog.html @@ -118,169 +118,169 @@

PRE/POST TEST I/O LOG

PROGRESS LOG

 
-
*** CT 2024-09-11 11:10:18.560 *** Common Test Logger started
+
*** CT 2024-09-12 10:32:23.554 *** Common Test Logger started
 VERBOSITY LEVELS:
 general level            100
 default                  100
 
 
-
*** CT 2024-09-11 11:10:18.564 *** Test Specification file(s)
+
*** CT 2024-09-12 10:32:23.557 *** Test Specification file(s)
 /buildroot/otp/lib/stdlib/make_test_dir/stdlib_test/stdlib_gh.spec 
 

-
*** CT 2024-09-11 11:10:55.037 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.747 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group parser in argparse_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.037 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.747 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group usage in argparse_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.038 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.747 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group validator in argparse_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.038 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.747 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group run in argparse_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.039 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.748 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group roundtrip in base64_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.040 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.749 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group valid_input in binary_property_test_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.040 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.749 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group out_of_binary in binary_property_test_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.040 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.749 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group invalid_subjects in binary_property_test_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.040 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.749 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group invalid_patterns in binary_property_test_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.040 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.749 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group misc_invalid in binary_property_test_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.040 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.749 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group invalid_input in binary_property_test_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.041 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.751 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group unused_vars_warn in erl_lint_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.041 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.751 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group on_load in erl_lint_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.048 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.757 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group basic_stats in rand_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.048 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.757 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group distr_stats in rand_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.048 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.757 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group reference_jump in rand_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.051 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.761 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group binaries_errors in unicode_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.055 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.764 *** TEST INFO
 1 test(s), 84 suite(s)
 

-
*** CT 2024-09-11 11:10:55.055 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.764 *** TEST INFO
 Timetrap time multiplier = 1
 Timetrap scaling enabled = false
 

-
*** CT 2024-09-11 11:10:55.160 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.870 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group parser in argparse_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.160 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.870 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group usage in argparse_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.160 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.870 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group validator in argparse_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.160 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.870 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group run in argparse_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.161 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.871 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group roundtrip in base64_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.161 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.871 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group valid_input in binary_property_test_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.161 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.871 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group out_of_binary in binary_property_test_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.161 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.871 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group invalid_subjects in binary_property_test_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.161 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.871 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group invalid_patterns in binary_property_test_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.161 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.871 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group misc_invalid in binary_property_test_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.161 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.871 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group invalid_input in binary_property_test_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.163 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.873 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group unused_vars_warn in erl_lint_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.163 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.873 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group on_load in erl_lint_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.170 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.880 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group basic_stats in rand_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.170 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.880 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group distr_stats in rand_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.170 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.880 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group reference_jump in rand_SUITE, using default.
 

-
*** CT 2024-09-11 11:10:55.173 *** TEST INFO
+
*** CT 2024-09-12 10:33:01.883 *** TEST INFO
 init_per_group/2 and end_per_group/2 missing for group binaries_errors in unicode_SUITE, using default.
 

-
*** CT 2024-09-11 12:02:51.848 *** Common Test Logger finished
+
*** CT 2024-09-12 11:26:02.590 *** Common Test Logger finished
 


diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/erl_pp_test.E b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/erl_pp_test.E similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/erl_pp_test.E rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/erl_pp_test.E diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/format_status_server.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/format_status_server.beam similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/format_status_server.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/format_status_server.beam diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/format_status_statem.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/format_status_statem.beam similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/format_status_statem.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/format_status_statem.beam diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/generic_fsm.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/generic_fsm.beam similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/generic_fsm.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/generic_fsm.beam diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/generic_server.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/generic_server.beam similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/generic_server.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/generic_server.beam diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/generic_server_timer.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/generic_server_timer.beam similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/generic_server_timer.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/generic_server_timer.beam diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/generic_statem.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/generic_statem.beam similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/generic_statem.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/generic_statem.beam diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/generic_statem_complex.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/generic_statem_complex.beam similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/generic_statem_complex.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/generic_statem_complex.beam diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/index.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/index.html similarity index 92% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/index.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/index.html index 4e031955b51f4..98eeaee04c3aa 100644 --- a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/index.html +++ b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/index.html @@ -3,7 +3,7 @@ -Test Results Wed Sep 11 2024 11:10:18 +Test Results Thu Sep 12 2024 10:32:23 @@ -81,7 +81,7 @@

Test Results

-

Wed Sep 11 2024 11:10:18

+

Thu Sep 12 2024 10:32:23


@@ -103,12 +103,12 @@

Wed Sep 11 2024 11:10:18

-make_test_dir.stdlib_test +make_test_dir.stdlib_test 2358 0 48 (48/0) 0 -3113.804s +3178.256s @@ -118,7 +118,7 @@

Wed Sep 11 2024 11:10:18

0 48 (48/0) 0 -3113.804s +3178.256s @@ -130,7 +130,7 @@

Wed Sep 11 2024 11:10:18

diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/jquery-latest.js b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/jquery-latest.js similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/jquery-latest.js rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/jquery-latest.js diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/jquery.tablesorter.min.js b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/jquery.tablesorter.min.js similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/jquery.tablesorter.min.js rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/jquery.tablesorter.min.js diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/l_mod.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/l_mod.beam similarity index 76% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/l_mod.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/l_mod.beam index 8a6cbca09d183..3515ca6e07a07 100644 Binary files a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/l_mod.beam and b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/l_mod.beam differ diff --git a/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/last_name b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/last_name new file mode 100644 index 0000000000000..5f7db20349087 --- /dev/null +++ b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/last_name @@ -0,0 +1 @@ +/buildroot/otp/lib/stdlib/make_test_dir/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01 diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/last_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/last_test.html similarity index 87% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/last_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/last_test.html index acb36ed788fc7..c9d6ca6956000 100644 --- a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/last_test.html +++ b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/last_test.html @@ -8,6 +8,6 @@

Last test

-make_test_dir.stdlib_test.logs +make_test_dir.stdlib_test.logs diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/argparse_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/argparse_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/argparse_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/argparse_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/array_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/array_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/array_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/array_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/base64_property_test_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/base64_property_test_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/base64_property_test_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/base64_property_test_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/base64_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/base64_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/base64_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/base64_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/beam_lib_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/beam_lib_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/beam_lib_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/beam_lib_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/binary_module_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/binary_module_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/binary_module_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/binary_module_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/binary_property_test_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/binary_property_test_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/binary_property_test_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/binary_property_test_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/c_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/c_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/c_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/c_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/calendar_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/calendar_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/calendar_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/calendar_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/dets_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/dets_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/dets_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/dets_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/dict_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/dict_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/dict_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/dict_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/digraph_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/digraph_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/digraph_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/digraph_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/digraph_utils_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/digraph_utils_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/digraph_utils_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/digraph_utils_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/edlin_context_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/edlin_context_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/edlin_context_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/edlin_context_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/edlin_expand_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/edlin_expand_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/edlin_expand_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/edlin_expand_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/epp_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/epp_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/epp_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/epp_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/erl_anno_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/erl_anno_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/erl_anno_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/erl_anno_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/erl_eval_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/erl_eval_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/erl_eval_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/erl_eval_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/erl_expand_records_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/erl_expand_records_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/erl_expand_records_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/erl_expand_records_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/erl_internal_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/erl_internal_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/erl_internal_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/erl_internal_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/erl_lint_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/erl_lint_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/erl_lint_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/erl_lint_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/erl_pp_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/erl_pp_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/erl_pp_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/erl_pp_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/erl_scan_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/erl_scan_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/erl_scan_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/erl_scan_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/error_logger_h_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/error_logger_h_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/error_logger_h_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/error_logger_h_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/escript_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/escript_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/escript_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/escript_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/ets_property_test_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/ets_property_test_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/ets_property_test_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/ets_property_test_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/ets_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/ets_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/ets_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/ets_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/ets_tough_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/ets_tough_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/ets_tough_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/ets_tough_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/file_sorter_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/file_sorter_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/file_sorter_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/file_sorter_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/filelib_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/filelib_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/filelib_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/filelib_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/filename_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/filename_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/filename_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/filename_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/fixtable_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/fixtable_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/fixtable_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/fixtable_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/format_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/format_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/format_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/format_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/gb_sets_property_test_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/gb_sets_property_test_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/gb_sets_property_test_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/gb_sets_property_test_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/gen_event_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/gen_event_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/gen_event_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/gen_event_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/gen_fsm_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/gen_fsm_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/gen_fsm_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/gen_fsm_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/gen_server_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/gen_server_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/gen_server_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/gen_server_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/gen_statem_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/gen_statem_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/gen_statem_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/gen_statem_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/id_transform_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/id_transform_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/id_transform_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/id_transform_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/io_proto_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/io_proto_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/io_proto_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/io_proto_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/io_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/io_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/io_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/io_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/json_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/json_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/json_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/json_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/last_link.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/last_link.html similarity index 87% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/last_link.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/last_link.html index 153eda04bdd41..c804ee0919c38 100644 --- a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/last_link.html +++ b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/last_link.html @@ -8,6 +8,6 @@

Last test

-make_test_dir.stdlib_test.logs +make_test_dir.stdlib_test.logs diff --git a/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/last_name b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/last_name new file mode 100644 index 0000000000000..5f7db20349087 --- /dev/null +++ b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/last_name @@ -0,0 +1 @@ +/buildroot/otp/lib/stdlib/make_test_dir/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01 diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/lists_property_test_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/lists_property_test_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/lists_property_test_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/lists_property_test_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/lists_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/lists_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/lists_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/lists_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/log_mf_h_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/log_mf_h_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/log_mf_h_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/log_mf_h_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/maps_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/maps_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/maps_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/maps_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/math_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/math_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/math_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/math_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/ms_transform_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/ms_transform_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/ms_transform_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/ms_transform_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/peer_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/peer_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/peer_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/peer_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/pool_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/pool_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/pool_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/pool_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/proc_lib_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/proc_lib_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/proc_lib_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/proc_lib_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/proplists_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/proplists_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/proplists_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/proplists_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/qlc_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/qlc_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/qlc_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/qlc_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/queue_property_test_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/queue_property_test_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/queue_property_test_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/queue_property_test_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/queue_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/queue_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/queue_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/queue_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/rand_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/rand_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/rand_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/rand_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/random_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/random_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/random_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/random_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/re_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/re_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/re_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/re_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.end_per_suite.3170.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.argparse.1282.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.end_per_suite.3170.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.argparse.1282.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.end_per_suite.3234.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.basic.1250.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.end_per_suite.3234.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.basic.1250.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.end_per_suite.3746.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.built_in_types.3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.end_per_suite.3746.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.built_in_types.3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.end_per_suite.3970.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.command_usage.229.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.end_per_suite.3970.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.command_usage.229.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.end_per_suite.4482.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.complex_command.99.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.end_per_suite.4482.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.complex_command.99.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.default_for_not_required.1378.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.default_for_not_required.1378.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.init_per_suite.3138.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.global_default.1410.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.init_per_suite.3138.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.global_default.1410.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.init_per_suite.3202.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.invalid_arguments.35.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.init_per_suite.3202.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.invalid_arguments.35.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.init_per_suite.3266.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.long_form_eq.67.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.init_per_suite.3266.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.long_form_eq.67.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.init_per_suite.3778.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.multi_short.1506.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.init_per_suite.3778.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.multi_short.1506.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.init_per_suite.4450.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.nargs.131.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.init_per_suite.4450.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.nargs.131.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.negative.1314.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ct_framework.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.negative.1314.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erl_print_suite.character.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.nodigits.1346.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erl_print_suite.character.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.nodigits.1346.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erl_print_suite.erlang_display.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.parser_error.195.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erl_print_suite.erlang_display.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.parser_error.195.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erl_print_suite.float.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.parser_error_usage.197.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erl_print_suite.float.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.parser_error_usage.197.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erl_print_suite.integer.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.pos_mixed_with_opt.4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erl_print_suite.integer.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.pos_mixed_with_opt.4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erl_print_suite.quote.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.proxy_arguments.5.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erl_print_suite.quote.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.proxy_arguments.5.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erl_print_suite.snprintf.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.readme.1186.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erl_print_suite.snprintf.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.readme.1186.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erl_print_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erl_print_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erl_print_suite.string.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.subcommand.1442.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erl_print_suite.string.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.subcommand.1442.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.arg_overflow.226.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.type_validators.1218.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.arg_overflow.226.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.type_validators.1218.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.arg_overflow.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.unicode.163.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.arg_overflow.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.unicode.163.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.compile_erl.34.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.usage.1570.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.compile_erl.34.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.usage.1570.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.compile_erl.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.usage_args_ordering.227.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.compile_erl.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.usage_args_ordering.227.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.compile_mib.130.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.usage_required_args.1602.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.compile_mib.130.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.usage_required_args.1602.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.compile_mib.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.usage_template.165.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.compile_mib.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.usage_template.165.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.compile_script.98.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.usage_width.261.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.compile_script.98.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.usage_width.261.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.compile_script.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.validator_exception.69.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.compile_script.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.validator_exception.69.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.compile_yecc.66.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.validator_exception_format.101.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.compile_yecc.66.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.validator_exception_format.101.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.compile_yecc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.very_short.1474.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.compile_yecc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/argparse_suite.very_short.1474.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.deep_cwd.194.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.deep_cwd.194.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.deep_cwd.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.fix_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.deep_cwd.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.fix_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.end_per_group.1410.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.foldl_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.end_per_group.1410.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.foldl_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.end_per_group.2914.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.foldr_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.end_per_group.2914.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.foldr_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.from_list_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.from_list_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.from_orddict_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.from_orddict_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features.2882.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features.2882.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.map_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.map_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_all.2050.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.new_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_all.2050.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.new_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_all.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.relax_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_all.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.relax_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_atom_warnings.1570.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.resize_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_atom_warnings.1570.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.resize_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_atom_warnings.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.set_get_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_atom_warnings.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.set_get_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_directives.1538.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.sparse_foldl_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_directives.1538.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.sparse_foldl_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_directives.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.sparse_foldr_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_directives.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.sparse_foldr_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_disable.1954.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.sparse_map_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_disable.1954.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.sparse_map_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_disable.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.sparse_to_list_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_disable.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.sparse_to_list_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_erlc_describe.1474.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.sparse_to_orddict_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_erlc_describe.1474.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.sparse_to_orddict_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_erlc_describe.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_erlc_describe.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_erlc_unknown.1506.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.to_list_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_erlc_unknown.1506.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.to_list_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_erlc_unknown.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.to_orddict_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_erlc_unknown.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/array_suite.to_orddict_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_include.2594.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_include.2594.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_include.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_1_malformed_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_include.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_1_malformed_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_load.2274.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_1_noisy_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_load.2274.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_1_noisy_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_load.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_load.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_macros.1602.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_2_malformed_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_macros.1602.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_2_malformed_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_macros.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_2_noisy_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_macros.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_2_noisy_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_runtime.2370.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_to_string_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_runtime.2370.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_to_string_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_runtime.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_to_string_1_malformed_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.features_runtime.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_to_string_1_malformed_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.good_citizen.162.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_to_string_1_noisy_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.good_citizen.162.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_to_string_1_noisy_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.good_citizen.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_to_string_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.good_citizen.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_to_string_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.init_per_group.1442.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_to_string_2_malformed_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.init_per_group.1442.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_to_string_2_malformed_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.init_per_group.2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_to_string_2_noisy_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.init_per_group.2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.decode_to_string_2_noisy_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.encode_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.encode_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.encode_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.encode_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.make_dep_options.258.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.encode_to_string_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.make_dep_options.258.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.encode_to_string_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.make_dep_options.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.encode_to_string_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.make_dep_options.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.encode_to_string_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.unicode_paths.290.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.unicode_paths.290.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.unicode_paths.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.mime_decode_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlc_suite.unicode_paths.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.mime_decode_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.args_file.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.mime_decode_1_malformed_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.args_file.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.mime_decode_1_malformed_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.args_file_env.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.mime_decode_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.args_file_env.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.mime_decode_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.argument_separation.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.mime_decode_2_malformed_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.argument_separation.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.mime_decode_2_malformed_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.argument_with_option.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.mime_decode_to_string_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.argument_with_option.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.mime_decode_to_string_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.mime_decode_to_string_1_malformed_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.mime_decode_to_string_1_malformed_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.env.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.mime_decode_to_string_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.env.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.mime_decode_to_string_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.evil_args_file.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.mime_decode_to_string_2_malformed_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.evil_args_file.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.mime_decode_to_string_2_malformed_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_property_test_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.missing_args_file.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.base64_decode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.missing_args_file.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.base64_decode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.otp_7461.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.base64_decode_modes.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.otp_7461.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.base64_decode_modes.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.base64_decode_to_string.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.base64_decode_to_string.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.zdbbl_dist_buf_busy_limit.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.base64_encode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/erlexec_suite.zdbbl_dist_buf_busy_limit.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.base64_encode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.atomic.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.base64_encode_modes.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.atomic.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.base64_encode_modes.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.broadcast.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.base64_encode_to_string.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.broadcast.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.base64_encode_to_string.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.cond_wait.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.base64_otp_5635.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.cond_wait.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.base64_otp_5635.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.create_join_thread.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.base64_otp_6279.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.create_join_thread.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.base64_otp_6279.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.detached_thread.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.big.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.detached_thread.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.big.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.dw_atomic_massage.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.illegal.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.dw_atomic_massage.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.illegal.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.equal_tids.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.mime_decode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.equal_tids.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.mime_decode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.max_threads.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.mime_decode_modes.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.max_threads.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.mime_decode_modes.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.mutex.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.mime_decode_to_string.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.mutex.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.mime_decode_to_string.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.rwmutex.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.mime_decode_to_string_modes.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.rwmutex.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.mime_decode_to_string_modes.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.rwspinlock.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.roundtrip_1.1666.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.rwspinlock.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.roundtrip_1.1666.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.spinlock.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.roundtrip_2.1698.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.spinlock.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.roundtrip_2.1698.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.roundtrip_3.1730.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.roundtrip_3.1730.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.thread_name.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.roundtrip_4.1762.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.thread_name.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.roundtrip_4.1762.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.try_lock_mutex.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.try_lock_mutex.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/base64_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.tsd.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.building.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/ethread_suite.tsd.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.building.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.'bin white space'.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.cmp.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.'bin white space'.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.cmp.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_default.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.cmp_literals.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_default.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.cmp_literals.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_default_dirty.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.encrypted_abstr.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_default_dirty.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.encrypted_abstr.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_dirname_fail.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.encrypted_abstr_file.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_dirname_fail.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.encrypted_abstr_file.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_no_srcfile.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_no_srcfile.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_no_use_dirname_fail.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.error.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_no_use_dirname_fail.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.error.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_not_abs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_not_abs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_ok_symlink.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.md5.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_ok_symlink.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.md5.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_outside_eprfx.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.missing_debug_info_backend.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_outside_eprfx.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.missing_debug_info_backend.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_outside_eprfx_dirty.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.normal.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_outside_eprfx_dirty.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.normal.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_same_dir.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.otp_6711.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_same_dir.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.otp_6711.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_unreachable_absolute.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_unreachable_absolute.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_unreachable_relative.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.strip.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_unreachable_relative.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.strip.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_unreasonable_path.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.strip_add_chunks.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.bin_unreasonable_path.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.strip_add_chunks.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.test_makedep_abstract_code.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/beam_lib_suite.test_makedep_abstract_code.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.badargs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.badargs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.bin_to_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/install_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.bin_to_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/nt_suite.nt.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.check_no_invalid_read_bug.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/nt_suite.nt.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.check_no_invalid_read_bug.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/nt_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.copy.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/nt_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.copy.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.call_to_deprecated.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.encode_decode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.call_to_deprecated.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.encode_decode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.call_to_now_0.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.error_info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.call_to_now_0.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.error_info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.call_to_size_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.guard.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.call_to_size_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.guard.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.deprecated_not_in_obsolete.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.hex_encoding.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.deprecated_not_in_obsolete.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.hex_encoding.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.interesting.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.interesting.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.erl_file_encoding.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.list_to_bin.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.erl_file_encoding.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.list_to_bin.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.longest_common_trap.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.longest_common_trap.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.obsolete_but_not_deprecated.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.parts.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.obsolete_but_not_deprecated.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.parts.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.runtime_dependencies_functions.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.random_ref_comp.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.runtime_dependencies_functions.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.random_ref_comp.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.runtime_dependencies_modules.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.random_ref_fla_comp.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.runtime_dependencies_modules.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.random_ref_fla_comp.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.random_ref_sr_comp.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.random_ref_sr_comp.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.strong_components.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.referenced.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.strong_components.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.referenced.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.test_runtime_dependencies_versions.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.scope_return.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.test_runtime_dependencies_versions.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.scope_return.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.undefined_functions.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.undefined_functions.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_module_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.xml_file_encoding.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.at_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/otp_suite.xml_file_encoding.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.at_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/parallel_messages_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.at_invalid_index_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/parallel_messages_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.at_invalid_index_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/parallel_messages_suite.test_message_queue_data_switching.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.at_invalid_subject_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/parallel_messages_suite.test_message_queue_data_switching.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.at_invalid_subject_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/parallel_messages_suite.test_throughput_benchmark.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.bin_to_list_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/parallel_messages_suite.test_throughput_benchmark.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.bin_to_list_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/run_erl_suite.basic.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.bin_to_list_2_3_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/run_erl_suite.basic.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.bin_to_list_2_3_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/run_erl_suite.defunct.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.bin_to_list_2_3_invalid_range_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/run_erl_suite.defunct.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.bin_to_list_2_3_invalid_range_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/run_erl_suite.heavier.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.bin_to_list_invalid_subject_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/run_erl_suite.heavier.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.bin_to_list_invalid_subject_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/run_erl_suite.heavy.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.compile_pattern_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/run_erl_suite.heavy.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.compile_pattern_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/run_erl_suite.sleepy_child.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.compile_pattern_invalid_pattern_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/run_erl_suite.sleepy_child.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.compile_pattern_invalid_pattern_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/run_erl_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.copy_2_invalid_n_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/run_erl_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.copy_2_invalid_n_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/upgrade_suite.ancient_major.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.copy_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/upgrade_suite.ancient_major.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.copy_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/upgrade_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.copy_invalid_subject_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/upgrade_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.copy_invalid_subject_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/upgrade_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.decode_hex_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/upgrade_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.decode_hex_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/upgrade_suite.major.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.decode_hex_invalid_chars_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/upgrade_suite.major.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.decode_hex_invalid_chars_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/upgrade_suite.minor.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.decode_hex_invalid_subject_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/upgrade_suite.minor.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.decode_hex_invalid_subject_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/upgrade_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.decode_unsigned_2_invalid_endianness_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/upgrade_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.decode_unsigned_2_invalid_endianness_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/z_suite.core_files.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.decode_unsigned_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/z_suite.core_files.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.decode_unsigned_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/z_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.decode_unsigned_invalid_subject_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/z_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.decode_unsigned_invalid_subject_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.argparse.35.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.encode_hex_2_invalid_case_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.argparse.35.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.encode_hex_2_invalid_case_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.basic.1250.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.encode_hex_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.basic.1250.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.encode_hex_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.built_in_types.3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.encode_hex_invalid_subject_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.built_in_types.3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.encode_hex_invalid_subject_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.command_usage.356.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.encode_unsigned_2_invalid_endianness_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.command_usage.356.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.encode_unsigned_2_invalid_endianness_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.complex_command.1378.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.encode_unsigned_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.complex_command.1378.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.encode_unsigned_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.default_for_not_required.36.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.encode_unsigned_invalid_integer_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.default_for_not_required.36.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.encode_unsigned_invalid_integer_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.global_default.196.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.global_default.196.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.invalid_arguments.1314.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.first_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.invalid_arguments.1314.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.first_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.long_form_eq.1186.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.first_invalid_subject_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.long_form_eq.1186.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.first_invalid_subject_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.multi_short.132.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.multi_short.132.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.nargs.4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.last_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.nargs.4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.last_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.negative.67.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.last_invalid_subject_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.negative.67.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.last_invalid_subject_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.nodigits.99.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.list_to_bin_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.nodigits.99.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.list_to_bin_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.parser_error.1410.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.list_to_bin_invalid_bytes_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.parser_error.1410.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.list_to_bin_invalid_bytes_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.parser_error_usage.388.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.longest_common_prefix_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.parser_error_usage.388.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.longest_common_prefix_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.pos_mixed_with_opt.131.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.longest_common_prefix_invalid_subject_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.pos_mixed_with_opt.131.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.longest_common_prefix_invalid_subject_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.proxy_arguments.164.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.longest_common_suffix_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.proxy_arguments.164.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.longest_common_suffix_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.readme.1218.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.longest_common_suffix_invalid_subject_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.readme.1218.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.longest_common_suffix_invalid_subject_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.match_3_invalid_scope_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.match_3_invalid_scope_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.subcommand.68.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.match_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.subcommand.68.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.match_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.type_validators.1282.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.match_invalid_pattern_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.type_validators.1282.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.match_invalid_pattern_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.unicode.1346.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.match_invalid_subject_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.unicode.1346.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.match_invalid_subject_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.usage.228.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.matches_3_invalid_scope_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.usage.228.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.matches_3_invalid_scope_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.usage_args_ordering.324.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.matches_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.usage_args_ordering.324.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.matches_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.usage_required_args.260.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.matches_invalid_pattern_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.usage_required_args.260.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.matches_invalid_pattern_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.usage_template.292.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.matches_invalid_subject_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.usage_template.292.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.matches_invalid_subject_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.usage_width.420.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.part_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.usage_width.420.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.part_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.validator_exception.37.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.part_invalid_range_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.validator_exception.37.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.part_invalid_range_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.validator_exception_format.69.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.part_invalid_subject_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.validator_exception_format.69.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.part_invalid_subject_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.very_short.100.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.replace_4_invalid_insert_replaced_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/argparse_suite.very_short.100.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.replace_4_invalid_insert_replaced_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.replace_4_invalid_scope_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.replace_4_invalid_scope_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.fix_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.replace_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.fix_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.replace_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.foldl_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.replace_invalid_pattern_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.foldl_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.replace_invalid_pattern_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.foldr_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.replace_invalid_replacement_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.foldr_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.replace_invalid_replacement_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.from_list_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.replace_invalid_subject_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.from_list_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.replace_invalid_subject_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.from_orddict_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.split_3_invalid_scope_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.from_orddict_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.split_3_invalid_scope_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.split_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.split_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.map_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.split_invalid_pattern_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.map_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.split_invalid_pattern_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.new_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.split_invalid_subject_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.new_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.split_invalid_subject_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.relax_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.relax_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/binary_property_test_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.resize_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.c_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.resize_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.c_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.set_get_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.c_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.set_get_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.c_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.sparse_foldl_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.c_3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.sparse_foldl_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.c_3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.sparse_foldr_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.c_4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.sparse_foldr_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.c_4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.sparse_map_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.c_default_outdir_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.sparse_map_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.c_default_outdir_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.sparse_to_list_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.c_default_outdir_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.sparse_to_list_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.c_default_outdir_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.sparse_to_orddict_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.sparse_to_orddict_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.to_list_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.ls.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.to_list_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.ls.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.to_orddict_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.memory.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/array_suite.to_orddict_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.memory.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.nc_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.nc_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_1_malformed_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.nc_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_1_malformed_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.nc_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_1_noisy_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.nc_3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_1_noisy_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.nc_3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.nc_4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.nc_4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_2_malformed_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.nc_default_outdir_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_2_malformed_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.nc_default_outdir_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_2_noisy_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.nc_default_outdir_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_2_noisy_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.nc_default_outdir_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_to_string_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_to_string_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/c_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_to_string_1_malformed_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.big_gregorian_days.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_to_string_1_malformed_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.big_gregorian_days.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_to_string_1_noisy_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.day_of_the_week.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_to_string_1_noisy_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.day_of_the_week.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_to_string_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.day_of_the_week_calibrate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_to_string_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.day_of_the_week_calibrate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_to_string_2_malformed_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_to_string_2_malformed_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_to_string_2_noisy_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.gregorian_days.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.decode_to_string_2_noisy_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.gregorian_days.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.encode_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.gregorian_seconds.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.encode_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.gregorian_seconds.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.encode_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.encode_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.encode_to_string_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.iso_week_number.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.encode_to_string_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.iso_week_number.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.encode_to_string_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.last_day_of_the_month.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.encode_to_string_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.last_day_of_the_month.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.leap_years.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.leap_years.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.local_time_to_universal_time_dst.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.local_time_to_universal_time_dst.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.mime_decode_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.rfc3339.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.mime_decode_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.rfc3339.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.mime_decode_1_malformed_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.mime_decode_1_malformed_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.mime_decode_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.system_time.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.mime_decode_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/calendar_suite.system_time.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/cover.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/cover.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/cover.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/cover.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.mime_decode_2_malformed_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.133.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.mime_decode_2_malformed_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.133.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.mime_decode_to_string_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.1826.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.mime_decode_to_string_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.1826.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.mime_decode_to_string_1_malformed_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.19710434.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.mime_decode_to_string_1_malformed_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.19710434.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.mime_decode_to_string_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.35426.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.mime_decode_to_string_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.35426.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.mime_decode_to_string_2_malformed_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.35778.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.mime_decode_to_string_2_malformed_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.35778.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.36.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_property_test_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.36.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.base64_decode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.36322.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.base64_decode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.36322.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.base64_decode_modes.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.36546.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.base64_decode_modes.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.36546.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.base64_decode_to_string.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.36866.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.base64_decode_to_string.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.36866.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.base64_encode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.36898.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.base64_encode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.36898.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.base64_encode_modes.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.408419.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.base64_encode_modes.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.408419.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.base64_encode_to_string.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.40930.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.base64_encode_to_string.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.40930.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.base64_otp_5635.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.40994.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.base64_otp_5635.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.40994.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.base64_otp_6279.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.504962.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.base64_otp_6279.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.504962.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.big.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.505154.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.big.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.505154.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.illegal.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.illegal.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.mime_decode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.1858.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.mime_decode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.1858.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.mime_decode_modes.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.19710466.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.mime_decode_modes.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.19710466.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.mime_decode_to_string.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.19710562.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.mime_decode_to_string.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.19710562.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.mime_decode_to_string_modes.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.19715490.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.mime_decode_to_string_modes.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.19715490.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.roundtrip_1.1506.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.19718082.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.roundtrip_1.1506.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.19718082.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.roundtrip_2.1538.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.19718146.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.roundtrip_2.1538.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.19718146.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.roundtrip_3.163.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.19721890.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.roundtrip_3.163.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.19721890.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.roundtrip_4.1570.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.34754.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.roundtrip_4.1570.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.34754.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.408451.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/base64_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.408451.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.building.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.41026.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.building.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.41026.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.cmp.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.491618.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.cmp.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.491618.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.cmp_literals.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.493218.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.cmp_literals.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.493218.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.encrypted_abstr.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.497570.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.encrypted_abstr.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.497570.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.encrypted_abstr_file.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.encrypted_abstr_file.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.1538.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.1538.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.error.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.1634.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.error.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.1634.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.19710306.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.19710306.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.md5.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.19717922.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.md5.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.19717922.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.missing_debug_info_backend.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.34786.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.missing_debug_info_backend.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.34786.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.normal.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.35458.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.normal.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.35458.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.otp_6711.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.35490.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.otp_6711.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.35490.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.35810.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.35810.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.strip.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.36354.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.strip.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.36354.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.strip_add_chunks.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.36578.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.strip_add_chunks.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.36578.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.test_makedep_abstract_code.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.37.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/beam_lib_suite.test_makedep_abstract_code.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.37.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.badargs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.40962.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.badargs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.40962.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.bin_to_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.504610.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.bin_to_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.504610.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.check_no_invalid_read_bug.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.504994.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.check_no_invalid_read_bug.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.504994.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.copy.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.741.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.copy.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.741.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.encode_decode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.encode_decode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.error_info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.19710498.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.error_info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.19710498.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.guard.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.19714626.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.guard.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.19714626.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.hex_encoding.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.19717890.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.hex_encoding.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.19717890.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.interesting.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.19718114.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.interesting.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.19718114.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.list_to_bin.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.19721858.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.list_to_bin.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.19721858.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.longest_common_trap.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.259.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.longest_common_trap.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.259.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.parts.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.2658.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.parts.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.2658.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.random_ref_comp.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.408483.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.random_ref_comp.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.408483.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.random_ref_fla_comp.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.491042.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.random_ref_fla_comp.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.491042.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.random_ref_sr_comp.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.492642.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.random_ref_sr_comp.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.492642.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.referenced.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.497442.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.referenced.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.497442.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.scope_return.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.502242.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.scope_return.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.502242.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.709.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_module_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.709.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.at_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.at_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ct_framework.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.at_invalid_index_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.access.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.at_invalid_index_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.access.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.at_invalid_subject_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.badarg.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.at_invalid_subject_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.badarg.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.bin_to_list_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.bag_next.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.bin_to_list_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.bag_next.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.bin_to_list_2_3_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.bags.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.bin_to_list_2_3_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.bags.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.bin_to_list_2_3_invalid_range_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.basic.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.bin_to_list_2_3_invalid_range_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.basic.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.bin_to_list_invalid_subject_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.cache_bags.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.bin_to_list_invalid_subject_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.cache_bags.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.compile_pattern_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.cache_duplicate_bags.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.compile_pattern_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.cache_duplicate_bags.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.compile_pattern_invalid_pattern_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.cache_sets.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.compile_pattern_invalid_pattern_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.cache_sets.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.copy_2_invalid_n_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.dirty_mark.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.copy_2_invalid_n_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.dirty_mark.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.copy_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.dirty_mark2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.copy_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.dirty_mark2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.copy_invalid_subject_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.duplicate_bags.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.copy_invalid_subject_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.duplicate_bags.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.decode_hex_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.decode_hex_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.decode_hex_invalid_chars_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.fixtable.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.decode_hex_invalid_chars_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.fixtable.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.decode_hex_invalid_subject_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.fold.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.decode_hex_invalid_subject_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.fold.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.decode_unsigned_2_invalid_endianness_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.decode_unsigned_2_invalid_endianness_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.decode_unsigned_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.init_table.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.decode_unsigned_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.init_table.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.decode_unsigned_invalid_subject_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.insert_new.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.decode_unsigned_invalid_subject_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.insert_new.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.encode_hex_2_invalid_case_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.many_clients.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.encode_hex_2_invalid_case_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.many_clients.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.encode_hex_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.match.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.encode_hex_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.match.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.encode_hex_invalid_subject_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.newly_started.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.encode_hex_invalid_subject_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.newly_started.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.encode_unsigned_2_invalid_endianness_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.oldbugs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.encode_unsigned_2_invalid_endianness_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.oldbugs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.encode_unsigned_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.open.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.encode_unsigned_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.open.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.encode_unsigned_invalid_integer_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.open_file.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.encode_unsigned_invalid_integer_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.open_file.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_11245.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_11245.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.first_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_11709.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.first_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_11709.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.first_invalid_subject_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_13229.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.first_invalid_subject_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_13229.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_13260.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_13260.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.last_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_13830.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.last_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_13830.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.last_invalid_subject_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_4208.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.last_invalid_subject_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_4208.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.list_to_bin_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_4738.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.list_to_bin_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_4738.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.list_to_bin_invalid_bytes_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_4906.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.list_to_bin_invalid_bytes_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_4906.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.longest_common_prefix_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_4989.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.longest_common_prefix_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_4989.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.longest_common_prefix_invalid_subject_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_5402.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.longest_common_prefix_invalid_subject_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_5402.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.longest_common_suffix_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_5487.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.longest_common_suffix_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_5487.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.longest_common_suffix_invalid_subject_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_6206.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.longest_common_suffix_invalid_subject_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_6206.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.match_3_invalid_scope_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_6359.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.match_3_invalid_scope_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_6359.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.match_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_7146.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.match_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_7146.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.match_invalid_pattern_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_8070.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.match_invalid_pattern_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_8070.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.match_invalid_subject_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_8856.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.match_invalid_subject_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_8856.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.matches_3_invalid_scope_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_8898.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.matches_3_invalid_scope_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_8898.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.matches_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_8899.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.matches_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_8899.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.matches_invalid_pattern_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_8903.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.matches_invalid_pattern_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_8903.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.matches_invalid_subject_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_8923.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.matches_invalid_subject_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_8923.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.part_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_9282.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.part_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.otp_9282.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.part_invalid_range_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.phash.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.part_invalid_range_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.phash.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.part_invalid_subject_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.receive_optimisation.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.part_invalid_subject_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.receive_optimisation.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.replace_4_invalid_insert_replaced_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.repair.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.replace_4_invalid_insert_replaced_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.repair.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.replace_4_invalid_scope_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.repair_continuation.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.replace_4_invalid_scope_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.repair_continuation.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.replace_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.select.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.replace_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.select.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.replace_invalid_pattern_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.sets.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.replace_invalid_pattern_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.sets.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.replace_invalid_replacement_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.simultaneous_open.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.replace_invalid_replacement_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.simultaneous_open.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.replace_invalid_subject_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.replace_invalid_subject_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.split_3_invalid_scope_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.truncated_segment_array.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.split_3_invalid_scope_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.truncated_segment_array.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.split_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.update_counter.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.split_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dets_suite.update_counter.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.split_invalid_pattern_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dict_suite.create.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.split_invalid_pattern_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dict_suite.create.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.split_invalid_subject_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dict_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.split_invalid_subject_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dict_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dict_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/binary_property_test_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dict_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.c_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dict_suite.iterate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.c_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dict_suite.iterate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.c_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dict_suite.remove.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.c_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dict_suite.remove.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.c_3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dict_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.c_3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dict_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.c_4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dict_suite.store.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.c_4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/dict_suite.store.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.c_default_outdir_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.cycle.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.c_default_outdir_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.cycle.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.c_default_outdir_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.data.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.c_default_outdir_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.data.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.degree.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.degree.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.edges.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.edges.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.ls.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.end_per_group.39458.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.ls.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.end_per_group.39458.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.memory.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.memory.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.nc_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.nc_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.nc_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.init_per_group.39426.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.nc_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.init_per_group.39426.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.nc_3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.nc_3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.nc_4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.nc_4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.nc_default_outdir_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.opts.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.nc_default_outdir_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.opts.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.nc_default_outdir_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.otp_3522.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.nc_default_outdir_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.otp_3522.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.otp_3630.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/c_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.otp_3630.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.big_gregorian_days.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.otp_8066.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.big_gregorian_days.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.otp_8066.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.day_of_the_week.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.path.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.day_of_the_week.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.path.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.day_of_the_week_calibrate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.day_of_the_week_calibrate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.vertex_names.39490.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.vertex_names.39490.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.gregorian_days.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.vertex_names.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.gregorian_days.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.vertex_names.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.gregorian_seconds.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.vertices.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.gregorian_seconds.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_suite.vertices.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.condensation.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.condensation.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.iso_week_number.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.iso_week_number.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.last_day_of_the_month.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.last_day_of_the_month.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.leap_years.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.isolated.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.leap_years.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.isolated.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.local_time_to_universal_time_dst.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.loop.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.local_time_to_universal_time_dst.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.loop.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.rfc3339.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.simple.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.rfc3339.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.simple.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.system_time.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.subgraph.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/calendar_suite.system_time.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.subgraph.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.101.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.topsort.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.101.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.topsort.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.19694274.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.tree.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.19694274.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/digraph_utils_suite.tree.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.19701250.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_context_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.19701250.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_context_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.291.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_context_suite.get_context.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.291.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_context_suite.get_context.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.3170.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_context_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.3170.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_context_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.3522.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_context_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.3522.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_context_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.4066.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.binding_completion.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.4066.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.binding_completion.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.4290.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.check_trailing.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.4290.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.check_trailing.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.452.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.452.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.4610.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.erl_1152.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.4610.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.erl_1152.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.4642.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.filename_completion.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.4642.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.filename_completion.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.503043.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.fun_completion.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.503043.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.fun_completion.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.503203.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.function_parameter_completion.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.503203.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.function_parameter_completion.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.9026.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.get_coverage.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.9026.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.get_coverage.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.9090.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.9090.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.invalid_module.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.invalid_module.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.1634.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.map_completion.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.1634.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.map_completion.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.19694306.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.no_completion.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.19694306.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.no_completion.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.19694402.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.normal.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.19694402.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.normal.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.19698914.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.quoted_both.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.19698914.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.quoted_both.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.19701282.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.quoted_fun.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.19701282.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.quoted_fun.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.19701346.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.quoted_module.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.19701346.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.quoted_module.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.19701410.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.record_completion.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.19701410.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.record_completion.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.19705570.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.19705570.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.2498.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.type_completion.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.2498.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.type_completion.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.395620.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.unicode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.395620.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/edlin_expand_suite.unicode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.474882.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.deterministic_include.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.474882.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.deterministic_include.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.481186.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.encoding.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.481186.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.encoding.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.9122.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.end_per_group.39554.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.9122.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.end_per_group.39554.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.133.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.133.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.1474.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.extends.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.1474.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.extends.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.19694146.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.file_macro.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.19694146.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.file_macro.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.19701186.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.function_macro.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.19701186.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.function_macro.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.2530.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.gh_4995.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.2530.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.gh_4995.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.3202.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.gh_8268.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.3202.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.gh_8268.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.3234.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.include_local.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.3234.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.include_local.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.33059.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.init_per_group.39522.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.33059.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.init_per_group.39522.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.3554.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.3554.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.4098.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.4098.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.4322.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.moduledoc_include.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.4322.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.moduledoc_include.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.488642.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.nondeterministic_include.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.488642.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.nondeterministic_include.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.5.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.not_circular.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.5.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.not_circular.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.503075.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_10302.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.503075.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_10302.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.9058.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_10820.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.9058.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_10820.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_11728.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_11728.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.1442.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_14285.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.1442.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_14285.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.19694338.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_16824.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.19694338.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_16824.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.19698050.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_16978.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.19698050.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_16978.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.19701154.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_4870.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.19701154.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_4870.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.19701314.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_4871.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.19701314.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_4871.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.19701378.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_5362.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.19701378.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_5362.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.19705538.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_6277.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.19705538.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_6277.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.2434.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_7702.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.2434.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_7702.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.33027.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_8130.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.33027.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_8130.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.474306.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_8388.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.474306.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_8388.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.475906.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_8470.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.475906.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_8470.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.481122.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_8562.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.481122.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_8562.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.486274.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_8665.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.486274.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_8665.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_8911.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ct_framework.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.otp_8911.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.access.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.overload_mac.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.access.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.overload_mac.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.badarg.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.pmod.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.badarg.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.pmod.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.bag_next.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.predef_mac.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.bag_next.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.predef_mac.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.bags.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.rec_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.bags.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.rec_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.basic.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.scan_file.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.basic.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.scan_file.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.cache_bags.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.skip_header.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.cache_bags.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.skip_header.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.cache_duplicate_bags.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.source_name.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.cache_duplicate_bags.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.source_name.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.cache_sets.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.cache_sets.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.dirty_mark.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.test_error.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.dirty_mark.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.test_error.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.dirty_mark2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.test_if.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.dirty_mark2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.test_if.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.duplicate_bags.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.test_warning.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.duplicate_bags.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.test_warning.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.upcase_mac_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.upcase_mac_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.fixtable.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.upcase_mac_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.fixtable.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.upcase_mac_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.fold.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.variable_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.fold.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/epp_suite.variable_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.bad.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.bad.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.init_table.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.end_location.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.init_table.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.end_location.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.insert_new.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.end_per_group.40898.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.insert_new.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.end_per_group.40898.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.many_clients.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.many_clients.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.match.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.match.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.newly_started.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.file.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.newly_started.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.file.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.oldbugs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.generated.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.oldbugs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.generated.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.open.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.init_per_group.40866.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.open.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.init_per_group.40866.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.open_file.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.open_file.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_11245.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_11245.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_11709.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.is_anno.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_11709.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.is_anno.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_13229.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.line.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_13229.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.line.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_13260.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.location.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_13260.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.location.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_13830.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.mapfold_anno.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_13830.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.mapfold_anno.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_4208.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.new.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_4208.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.new.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_4738.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.parse_abstract.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_4738.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.parse_abstract.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_4906.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.record.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_4906.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.record.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_4989.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_4989.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_5402.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.text.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_5402.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_anno_suite.text.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_5487.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.apply_atom.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_5487.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.apply_atom.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_6206.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.binary_and_map_aliases.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_6206.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.binary_and_map_aliases.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_6359.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.custom_stacktrace.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_6359.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.custom_stacktrace.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_7146.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.eep37.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_7146.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.eep37.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_8070.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.eep43.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_8070.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.eep43.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_8856.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.eep49.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_8856.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.eep49.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_8898.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.eep58.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_8898.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.eep58.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_8899.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_8899.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_8903.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.eval_expr_5.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_8903.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.eval_expr_5.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_8923.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.funs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_8923.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.funs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_9282.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.guard_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.otp_9282.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.guard_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.phash.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.guard_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.phash.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.guard_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.receive_optimisation.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.guard_3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.receive_optimisation.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.guard_3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.repair.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.guard_4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.repair.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.guard_4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.repair_continuation.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.guard_5.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.repair_continuation.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.guard_5.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.select.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.select.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.sets.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.lc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.sets.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.lc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.simultaneous_open.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.match_bin.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.simultaneous_open.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.match_bin.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.match_pattern.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.match_pattern.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.truncated_segment_array.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_10622.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.truncated_segment_array.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_10622.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.update_counter.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_13228.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dets_suite.update_counter.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_13228.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dict_suite.create.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_14708.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dict_suite.create.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_14708.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dict_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_14826.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dict_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_14826.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dict_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_15035.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dict_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_15035.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dict_suite.iterate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_16439.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dict_suite.iterate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_16439.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dict_suite.remove.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_16545.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dict_suite.remove.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_16545.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dict_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_16865.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dict_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_16865.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dict_suite.store.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_5269.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/dict_suite.store.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_5269.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.cycle.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_6539.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.cycle.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_6539.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.data.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_6543.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.data.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_6543.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.degree.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_6787.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.degree.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_6787.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.edges.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_6977.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.edges.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_6977.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.end_per_group.7170.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_7550.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.end_per_group.7170.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_7550.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_8133.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.otp_8133.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.pattern_expr.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.pattern_expr.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.init_per_group.7138.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.simple_cases.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.init_per_group.7138.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.simple_cases.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.string_plusplus.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.string_plusplus.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.opts.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.try_catch.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.opts.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.try_catch.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.otp_3522.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.unary_plus.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.otp_3522.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.unary_plus.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.otp_3630.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.zero_width.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.otp_3630.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_eval_suite.zero_width.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.otp_8066.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.attributes.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.otp_8066.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.attributes.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.path.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.path.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.vertex_names.7202.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.expr.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.vertex_names.7202.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.expr.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.vertex_names.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.guard.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.vertex_names.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.guard.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.vertices.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.init.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_suite.vertices.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.init.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.condensation.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.condensation.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.maps.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.maps.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.isolated.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.otp_5915.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.isolated.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.otp_5915.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.loop.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.otp_5990.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.loop.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.otp_5990.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.simple.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.otp_7078.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.simple.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.otp_7078.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.otp_7931.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.otp_7931.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.subgraph.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.pattern.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.subgraph.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.pattern.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.topsort.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.side_effects.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.topsort.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.side_effects.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.tree.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/digraph_utils_suite.tree.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_context_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.strict.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_context_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.strict.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_context_suite.get_context.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.update.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_context_suite.get_context.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_expand_records_suite.update.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_context_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_internal_suite.behav.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_context_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_internal_suite.behav.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_context_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_internal_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_context_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_internal_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.binding_completion.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_internal_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.binding_completion.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_internal_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.check_trailing.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_internal_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.check_trailing.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_internal_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.basic_errors.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.basic_errors.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.erl_1152.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.behaviour_basic.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.erl_1152.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.behaviour_basic.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.filename_completion.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.behaviour_multiple.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.filename_completion.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.behaviour_multiple.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.fun_completion.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.bif_clash.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.fun_completion.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.bif_clash.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.function_parameter_completion.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.bin_syntax_errors.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.function_parameter_completion.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.bin_syntax_errors.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.get_coverage.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.binary_aliases.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.get_coverage.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.binary_aliases.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.binary_types.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.binary_types.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.invalid_module.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.documentation_attributes.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.invalid_module.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.documentation_attributes.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.map_completion.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.eep49.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.map_completion.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.eep49.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.no_completion.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.export_all.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.no_completion.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.export_all.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.normal.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.export_vars_warn.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.normal.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.export_vars_warn.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.quoted_both.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.external_funs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.quoted_both.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.external_funs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.quoted_fun.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.format_warn.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.quoted_fun.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.format_warn.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.quoted_module.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.guard.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.quoted_module.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.guard.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.record_completion.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.illegal_module_name.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.record_completion.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.illegal_module_name.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.inline_nifs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.inline_nifs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.type_completion.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.maps.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.type_completion.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.maps.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.unicode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.maps_parallel_match.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/edlin_expand_suite.unicode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.maps_parallel_match.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.deterministic_include.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.maps_type.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.deterministic_include.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.maps_type.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.encoding.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.match_float_zero.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.encoding.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.match_float_zero.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.end_per_group.7266.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.messages_with_jaro_suggestions.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.end_per_group.7266.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.messages_with_jaro_suggestions.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.no_load_nif.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.no_load_nif.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.non_latin1_module.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.non_latin1_module.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.extends.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.on_load_failing.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.extends.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.on_load_failing.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.file_macro.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.on_load_successful.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.file_macro.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.on_load_successful.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.function_macro.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_10436.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.function_macro.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_10436.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.gh_4995.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_11254.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.gh_4995.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_11254.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.gh_8268.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_11771.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.gh_8268.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_11771.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.include_local.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_11772.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.include_local.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_11772.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.init_per_group.7234.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_11851.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.init_per_group.7234.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_11851.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_11861.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_11861.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_11872.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_11872.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.moduledoc_include.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_11879.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.moduledoc_include.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_11879.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.nondeterministic_include.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_11879_cont.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.nondeterministic_include.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_11879_cont.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.not_circular.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_13230.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.not_circular.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_13230.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_10302.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_14285.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_10302.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_14285.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_10820.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_14323.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_10820.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_14323.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_11728.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_14378.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_11728.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_14378.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_14285.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_15456.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_14285.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_15456.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_16824.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_15563.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_16824.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_15563.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_16978.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_16516.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_16978.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_16516.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_4870.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_16824.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_4870.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_16824.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_4871.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_4886.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_4871.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_4886.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_5362.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_4988.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_5362.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_4988.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_6277.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5091.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_6277.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5091.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_7702.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5276.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_7702.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5276.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_8130.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5338.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_8130.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5338.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_8388.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5362.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_8388.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5362.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_8470.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5371.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_8470.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5371.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_8562.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5494.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_8562.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5494.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_8665.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5644.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_8665.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5644.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_8911.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5878.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.otp_8911.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5878.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.overload_mac.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5917.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.overload_mac.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_5917.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.pmod.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_6585.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.pmod.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_6585.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.predef_mac.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_6885.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.predef_mac.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_6885.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.rec_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_7227.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.rec_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_7227.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.scan_file.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_7550.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.scan_file.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_7550.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.skip_header.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_8051.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.skip_header.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.otp_8051.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.source_name.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.predef.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.source_name.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.predef.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.record_errors.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.record_errors.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.test_error.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.redefined_builtin_type.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.test_error.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.redefined_builtin_type.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.test_if.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.removed.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.test_if.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.removed.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.test_warning.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.shadow_vars.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.test_warning.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.shadow_vars.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.upcase_mac_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.singleton_type_var_errors.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.upcase_mac_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.singleton_type_var_errors.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.upcase_mac_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.upcase_mac_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.variable_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.stacktrace_syntax.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/epp_suite.variable_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.stacktrace_syntax.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.bad.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.tilde_k.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.bad.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.tilde_k.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.end_location.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.too_many_arguments.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.end_location.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.too_many_arguments.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.end_per_group.8994.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.undefined_module.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.end_per_group.8994.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.undefined_module.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.undefined_nifs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.undefined_nifs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.underscore_match.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.underscore_match.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.file.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unsafe_vars.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.file.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unsafe_vars.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.generated.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unsafe_vars2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.generated.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unsafe_vars2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.init_per_group.8962.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unsafe_vars_try.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.init_per_group.8962.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unsafe_vars_try.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unsized_binary_in_bin_gen_pattern.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unsized_binary_in_bin_gen_pattern.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_function.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_function.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.is_anno.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_import.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.is_anno.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_import.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.line.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_record.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.line.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_record.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.location.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_type.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.location.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_type.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.mapfold_anno.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_type2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.mapfold_anno.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_type2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.new.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_unsafe_vars_warn.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.new.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_unsafe_vars_warn.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.parse_abstract.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_vars_otp_4858.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.parse_abstract.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_vars_otp_4858.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.record.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_vars_warn_basic.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.record.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_vars_warn_basic.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_vars_warn_fun.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_vars_warn_fun.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.text.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_vars_warn_lc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_anno_suite.text.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_vars_warn_lc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.apply_atom.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_vars_warn_rec.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.apply_atom.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.unused_vars_warn_rec.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.binary_and_map_aliases.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.update_literal.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.binary_and_map_aliases.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.update_literal.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.custom_stacktrace.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.warn_missing_spec.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.custom_stacktrace.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_lint_suite.warn_missing_spec.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.eep37.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.bits.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.eep37.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.bits.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.eep43.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.block.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.eep43.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.block.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.eep49.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.call.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.eep49.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.call.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.eep58.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.case1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.eep58.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.case1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.cond1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.cond1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.eval_expr_5.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.dialyzer_attrs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.eval_expr_5.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.dialyzer_attrs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.funs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.eep49.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.funs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.eep49.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.guard_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.eep58.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.guard_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.eep58.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.guard_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.end_per_group.41090.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.guard_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.end_per_group.41090.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.guard_3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.end_per_group.41410.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.guard_3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.end_per_group.41410.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.guard_4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.guard_4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.guard_5.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.guard_5.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.form_vars.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.form_vars.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.lc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.format_options.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.lc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.format_options.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.match_bin.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.func.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.match_bin.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.func.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.match_pattern.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.gh_5093.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.match_pattern.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.gh_5093.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_10622.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.head_tail.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_10622.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.head_tail.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_13228.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.hook.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_13228.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.hook.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_14708.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.if_then.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_14708.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.if_then.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_14826.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.import_export.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_14826.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.import_export.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_15035.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.init_per_group.41058.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_15035.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.init_per_group.41058.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_16439.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.init_per_group.41122.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_16439.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.init_per_group.41122.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_16545.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_16545.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_16865.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_16865.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_5269.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.maps_syntax.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_5269.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.maps_syntax.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_6539.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.messages.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_6539.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.messages.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_6543.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.misc_attrs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_6543.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.misc_attrs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_6787.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.neg_indent.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_6787.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.neg_indent.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_6977.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.ops.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_6977.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.ops.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_7550.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_10302.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_7550.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_10302.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_8133.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_10820.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.otp_8133.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_10820.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.pattern_expr.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_11100.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.pattern_expr.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_11100.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.simple_cases.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_11861.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.simple_cases.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_11861.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_13662.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_13662.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.string_plusplus.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_14285.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.string_plusplus.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_14285.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.try_catch.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_15592.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.try_catch.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_15592.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.unary_plus.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_15751.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.unary_plus.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_15751.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.zero_width.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_15755.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_eval_suite.zero_width.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_15755.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.attributes.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_16435.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.attributes.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_16435.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_6321.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_6321.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_6911.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_6911.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.expr.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_6914.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.expr.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_6914.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.guard.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_8150.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.guard.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_8150.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.init.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_8238.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.init.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_8238.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_8473.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_8473.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_8522.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_8522.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.maps.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_8567.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.maps.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_8567.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.otp_5915.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_8664.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.otp_5915.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_8664.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.otp_5990.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_9147.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.otp_5990.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.otp_9147.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.otp_7078.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.pr_1014.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.otp_7078.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.pr_1014.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.otp_7931.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.quoted_atom_types.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.otp_7931.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.quoted_atom_types.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.pattern.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.receive_after.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.pattern.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.receive_after.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.side_effects.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.recs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.side_effects.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.recs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.strict.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.try_catch.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.strict.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_pp_suite.try_catch.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.update.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_expand_records_suite.update.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_internal_suite.behav.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_internal_suite.behav.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_internal_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.error_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_internal_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.error_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_internal_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.error_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_internal_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.error_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_internal_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_internal_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.basic_errors.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.basic_errors.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.behaviour_basic.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.iso88591.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.behaviour_basic.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.iso88591.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.behaviour_multiple.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.otp_10302.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.behaviour_multiple.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.otp_10302.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.bif_clash.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.otp_10990.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.bif_clash.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.otp_10990.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.bin_syntax_errors.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.otp_10992.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.bin_syntax_errors.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.otp_10992.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.binary_aliases.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.otp_11807.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.binary_aliases.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.otp_11807.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.binary_types.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.otp_16480.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.binary_types.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.otp_16480.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.documentation_attributes.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.otp_17024.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.documentation_attributes.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.otp_17024.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.eep49.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.otp_7810.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.eep49.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.otp_7810.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.export_all.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.export_all.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.export_vars_warn.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.text_fun.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.export_vars_warn.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.text_fun.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.external_funs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.triple_quoted_string.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.external_funs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/erl_scan_suite.triple_quoted_string.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.format_warn.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/error_logger_h_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.format_warn.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/error_logger_h_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.guard.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/error_logger_h_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.guard.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/error_logger_h_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.illegal_module_name.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/error_logger_h_suite.logfile.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.illegal_module_name.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/error_logger_h_suite.logfile.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.inline_nifs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/error_logger_h_suite.logfile_truncated.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.inline_nifs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/error_logger_h_suite.logfile_truncated.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.maps.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/error_logger_h_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.maps.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/error_logger_h_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.maps_parallel_match.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/error_logger_h_suite.tty.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.maps_parallel_match.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/error_logger_h_suite.tty.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.maps_type.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/error_logger_h_suite.tty_truncated.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.maps_type.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/error_logger_h_suite.tty_truncated.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.match_float_zero.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.archive_script.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.match_float_zero.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.archive_script.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.messages_with_jaro_suggestions.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.archive_script_file_access.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.messages_with_jaro_suggestions.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.archive_script_file_access.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.no_load_nif.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.bad_io_server.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.no_load_nif.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.bad_io_server.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.non_latin1_module.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.basic.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.non_latin1_module.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.basic.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.on_load_failing.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.beam_script.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.on_load_failing.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.beam_script.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.on_load_successful.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.create_and_extract.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.on_load_successful.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.create_and_extract.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_10436.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.emulator_flags.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_10436.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.emulator_flags.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_11254.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.emulator_flags_no_shebang.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_11254.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.emulator_flags_no_shebang.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_11771.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_11771.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_11772.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.epp.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_11772.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.epp.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_11851.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.errors.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_11851.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.errors.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_11861.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.foldl.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_11861.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.foldl.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_11872.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_11872.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_11879.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.module_script.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_11879.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.module_script.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_11879_cont.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.overflow.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_11879_cont.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.overflow.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_13230.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_13230.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_14285.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.strange_name.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_14285.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.strange_name.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_14323.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.two_lines.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_14323.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.two_lines.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_14378.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.unicode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_14378.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/escript_suite.unicode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_15456.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_property_test_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_15456.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_property_test_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_15563.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_property_test_suite.first_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_15563.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_property_test_suite.first_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_16516.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_property_test_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_16516.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_property_test_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_16824.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_property_test_suite.last_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_16824.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_property_test_suite.last_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_4886.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_property_test_suite.next_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_4886.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_property_test_suite.next_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_4988.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_property_test_suite.prev_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_4988.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_property_test_suite.prev_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5091.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_property_test_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5091.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_property_test_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5276.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.bad_table.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5276.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.bad_table.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5338.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.baddelete.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5338.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.baddelete.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5362.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.badfile.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5362.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.badfile.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5371.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.badinsert.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5371.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.badinsert.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5494.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.badlookup.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5494.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.badlookup.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5644.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.badnew.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5644.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.badnew.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5878.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.bound_maps.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5878.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.bound_maps.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5917.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.compress_magic_ref.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_5917.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.compress_magic_ref.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_6585.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.default.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_6585.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.default.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_6885.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.delete_elem.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_6885.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.delete_elem.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_7227.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.delete_large_named_table.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_7227.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.delete_large_named_table.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_7550.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.delete_large_tab.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_7550.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.delete_large_tab.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_8051.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.delete_tab.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.otp_8051.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.delete_tab.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.predef.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.delete_unfix_race.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.predef.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.delete_unfix_race.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.record_errors.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.dups.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.record_errors.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.dups.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.redefined_builtin_type.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.empty.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.redefined_builtin_type.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.empty.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.removed.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.41954.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.removed.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.41954.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.shadow_vars.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.42082.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.shadow_vars.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.42082.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.singleton_type_var_errors.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.42690.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.singleton_type_var_errors.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.42690.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.43074.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.43074.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.stacktrace_syntax.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.43234.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.stacktrace_syntax.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.43234.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.tilde_k.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.43426.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.tilde_k.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.43426.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.too_many_arguments.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.43714.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.too_many_arguments.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.43714.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.undefined_module.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.43874.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.undefined_module.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.43874.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.undefined_nifs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.44226.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.undefined_nifs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.44226.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.underscore_match.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.49026.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.underscore_match.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.49026.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unsafe_vars.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.50658.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unsafe_vars.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.50658.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unsafe_vars2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unsafe_vars2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unsafe_vars_try.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unsafe_vars_try.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unsized_binary_in_bin_gen_pattern.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.error_info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unsized_binary_in_bin_gen_pattern.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.error_info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_function.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.ets_all.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_function.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.ets_all.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_import.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.evil_delete.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_import.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.evil_delete.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_record.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.evil_rename.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_record.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.evil_rename.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_type.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.evil_update_counter.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_type.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.evil_update_counter.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_type2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.exit_large_table_owner.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_type2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.exit_large_table_owner.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_unsafe_vars_warn.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.exit_many_large_table_owner.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_unsafe_vars_warn.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.exit_many_large_table_owner.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_vars_otp_4858.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.exit_many_many_tables_owner.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_vars_otp_4858.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.exit_many_many_tables_owner.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_vars_warn_basic.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.exit_many_tables_owner.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_vars_warn_basic.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.exit_many_tables_owner.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_vars_warn_fun.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.firstnext.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_vars_warn_fun.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.firstnext.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_vars_warn_lc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.firstnext_concurrent.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_vars_warn_lc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.firstnext_concurrent.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_vars_warn_rec.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.firstnext_lookup.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.unused_vars_warn_rec.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.firstnext_lookup.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.update_literal.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.firstnext_lookup_concurrent.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.update_literal.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.firstnext_lookup_concurrent.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.warn_missing_spec.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.fixtable_insert.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_lint_suite.warn_missing_spec.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.fixtable_insert.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.bits.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.fixtable_iter_bag.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.bits.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.fixtable_iter_bag.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.block.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.fixtable_next.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.block.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.fixtable_next.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.call.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.fold_badarg.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.call.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.fold_badarg.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.case1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.fold_empty.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.case1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.fold_empty.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.cond1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.foldl.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.cond1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.foldl.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.dialyzer_attrs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.foldl_ordered.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.dialyzer_attrs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.foldl_ordered.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.eep49.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.foldr.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.eep49.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.foldr.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.eep58.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.foldr_ordered.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.eep58.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.foldr_ordered.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.end_per_group.9186.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.give_away.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.end_per_group.9186.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.give_away.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.end_per_group.9506.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.grow_pseudo_deleted.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.end_per_group.9506.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.grow_pseudo_deleted.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.grow_shrink.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.grow_shrink.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.hash_clash.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.hash_clash.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.form_vars.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.heavy_concurrent.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.form_vars.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.heavy_concurrent.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.format_options.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.heavy_lookup.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.format_options.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.heavy_lookup.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.func.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.heavy_lookup_element.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.func.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.heavy_lookup_element.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.gh_5093.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.heir.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.gh_5093.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.heir.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.head_tail.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.head_tail.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.hook.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.info_binary_stress.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.hook.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.info_binary_stress.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.if_then.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.info_whereis_busy.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.if_then.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.info_whereis_busy.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.import_export.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.41858.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.import_export.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.41858.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.init_per_group.9154.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.41986.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.init_per_group.9154.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.41986.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.init_per_group.9218.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.42114.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.init_per_group.9218.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.42114.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.42914.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.42914.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.43138.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.43138.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.maps_syntax.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.43266.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.maps_syntax.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.43266.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.messages.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.43458.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.messages.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.43458.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.misc_attrs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.43746.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.misc_attrs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.43746.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.neg_indent.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.43906.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.neg_indent.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.43906.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.ops.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.48802.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.ops.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.48802.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_10302.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.50530.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_10302.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.50530.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_10820.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_10820.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_11100.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_11100.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_11861.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.insert_trap_delete.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_11861.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.insert_trap_delete.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_13662.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.insert_trap_rename.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_13662.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.insert_trap_rename.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_14285.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.interface_equality.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_14285.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.interface_equality.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_15592.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.keypos2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_15592.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.keypos2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_15751.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.lookup_element_default.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_15751.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.lookup_element_default.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_15755.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.lookup_element_mult.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_15755.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.lookup_element_mult.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_16435.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.lookup_order.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_16435.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.lookup_order.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_6321.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.massive_ets_all.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_6321.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.massive_ets_all.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_6911.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.match1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_6911.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.match1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_6914.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.match2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_6914.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.match2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_8150.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.match_delete.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_8150.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.match_delete.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_8238.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.match_delete3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_8238.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.match_delete3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_8473.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.match_heavy.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_8473.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.match_heavy.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_8522.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.match_object.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_8522.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.match_object.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_8567.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.match_object2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_8567.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.match_object2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_8664.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.member.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_8664.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.member.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_9147.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.memory.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.otp_9147.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.memory.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.pr_1014.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.meta_lookup_named_read.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.pr_1014.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.meta_lookup_named_read.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.quoted_atom_types.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.meta_lookup_named_write.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.quoted_atom_types.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.meta_lookup_named_write.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.receive_after.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.meta_lookup_unnamed_read.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.receive_after.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.meta_lookup_unnamed_read.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.recs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.meta_lookup_unnamed_write.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.recs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.meta_lookup_unnamed_write.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.meta_newdel_named.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.meta_newdel_named.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.try_catch.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.meta_newdel_unnamed.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_pp_suite.try_catch.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.meta_newdel_unnamed.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.meta_wb.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.meta_wb.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.misc1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.misc1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.error_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.ms_excessive_nesting.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.error_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.ms_excessive_nesting.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.error_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.named.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.error_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.named.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.ordered.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.ordered.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.ordered_match.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.ordered_match.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.iso88591.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_10182.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.iso88591.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_10182.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.otp_10302.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_5340.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.otp_10302.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_5340.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.otp_10990.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_6338.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.otp_10990.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_6338.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.otp_10992.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_6842_select_1000.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.otp_10992.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_6842_select_1000.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.otp_11807.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_7665.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.otp_11807.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_7665.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.otp_16480.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_8166.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.otp_16480.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_8166.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.otp_17024.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_8732.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.otp_17024.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_8732.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.otp_7810.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_9423.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.otp_7810.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_9423.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_9932.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.otp_9932.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.text_fun.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.partly_bound.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.text_fun.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.partly_bound.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.triple_quoted_string.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.privacy.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/erl_scan_suite.triple_quoted_string.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.privacy.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/error_logger_h_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.rename.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/error_logger_h_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.rename.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/error_logger_h_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.rename_unnamed.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/error_logger_h_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.rename_unnamed.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/error_logger_h_suite.logfile.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.safe_fixtable.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/error_logger_h_suite.logfile.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.safe_fixtable.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/error_logger_h_suite.logfile_truncated.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.select_bound_chunk.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/error_logger_h_suite.logfile_truncated.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.select_bound_chunk.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/error_logger_h_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.select_fail.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/error_logger_h_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.select_fail.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/error_logger_h_suite.tty.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.select_fixtab_owner_change.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/error_logger_h_suite.tty.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.select_fixtab_owner_change.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/error_logger_h_suite.tty_truncated.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.select_mbuf_trapping.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/error_logger_h_suite.tty_truncated.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.select_mbuf_trapping.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.archive_script.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.setbag.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.archive_script.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.setbag.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.archive_script_file_access.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.setopts.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.archive_script_file_access.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.setopts.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.bad_io_server.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.shrink_pseudo_deleted.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.bad_io_server.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.shrink_pseudo_deleted.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.basic.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.slot.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.basic.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.slot.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.beam_script.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.smp_fixed_delete.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.beam_script.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.smp_fixed_delete.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.create_and_extract.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.smp_insert.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.create_and_extract.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.smp_insert.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.emulator_flags.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.smp_ordered_iteration.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.emulator_flags.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.smp_ordered_iteration.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.emulator_flags_no_shebang.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.smp_select_delete.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.emulator_flags_no_shebang.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.smp_select_delete.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.smp_select_replace.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.smp_select_replace.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.epp.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.smp_unfix_fix.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.epp.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.smp_unfix_fix.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.errors.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.errors.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.foldl.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_bucket_disappears.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.foldl.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_bucket_disappears.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_delete_all_objects.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_delete_all_objects.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.module_script.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_delete_all_objects_trap.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.module_script.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_delete_all_objects_trap.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.overflow.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_delete_object.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.overflow.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_delete_object.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_ets_dets.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_ets_dets.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.strange_name.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_init_table.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.strange_name.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_init_table.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.two_lines.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.two_lines.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.unicode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list_bag.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/escript_suite.unicode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list_bag.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_property_test_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list_delete_parallel.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_property_test_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list_delete_parallel.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_property_test_suite.first_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list_delete_set.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_property_test_suite.first_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list_delete_set.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_property_test_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list_duplicate_bag.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_property_test_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list_duplicate_bag.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_property_test_suite.last_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list_insert_order_preserved.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_property_test_suite.last_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list_insert_order_preserved.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_property_test_suite.next_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list_kill_process.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_property_test_suite.next_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list_kill_process.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_property_test_suite.prev_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list_parallel.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_property_test_suite.prev_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list_parallel.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_property_test_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list_set.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_property_test_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_list_set.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.bad_table.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_new.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.bad_table.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_insert_new.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.baddelete.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_match_spec_run.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.baddelete.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_match_spec_run.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.badfile.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_named_select.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.badfile.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_named_select.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.badinsert.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_repair_continuation.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.badinsert.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_repair_continuation.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.badlookup.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_select_delete.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.badlookup.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_select_delete.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.badnew.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_select_flatmap_term_copy_bug.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.badnew.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_select_flatmap_term_copy_bug.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.bound_maps.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_select_hashmap_term_copy_bug.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.bound_maps.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_select_hashmap_term_copy_bug.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.compress_magic_ref.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_select_pam_stack_overflow_bug.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.compress_magic_ref.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_select_pam_stack_overflow_bug.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.default.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_select_replace.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.default.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_select_replace.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.delete_elem.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_select_replace_next_bug.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.delete_elem.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_select_replace_next_bug.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.delete_large_named_table.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_select_reverse.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.delete_large_named_table.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_select_reverse.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.delete_large_tab.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_test_ms.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.delete_large_tab.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_test_ms.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.delete_tab.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_whitebox.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.delete_tab.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.t_whitebox.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.delete_unfix_race.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.tab2file.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.delete_unfix_race.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.tab2file.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.dups.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.tab2file2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.dups.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.tab2file2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.empty.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.tab2list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.empty.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.tab2list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.10082.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.tabfile_ext1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.10082.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.tabfile_ext1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.10210.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.tabfile_ext2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.10210.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.tabfile_ext2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.10786.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.tabfile_ext3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.10786.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.tabfile_ext3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.11170.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.tabfile_ext4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.11170.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.tabfile_ext4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.11330.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.table_leak.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.11330.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.table_leak.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.11618.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.take.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.11618.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.take.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.11906.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.test_decentralized_counters_setting.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.11906.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.test_decentralized_counters_setting.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.12066.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.test_delete_table_while_size_snapshot.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.12066.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.test_delete_table_while_size_snapshot.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.18018.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.test_table_memory_concurrency.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.18018.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.test_table_memory_concurrency.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.19746.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.test_table_size_concurrency.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.19746.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.test_table_size_concurrency.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.33155.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.test_throughput_benchmark.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.33155.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.test_throughput_benchmark.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.types.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.types.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.update_counter.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.update_counter.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.error_info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.update_counter_table_growth.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.error_info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.update_counter_table_growth.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.ets_all.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.update_counter_with_default.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.ets_all.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.update_counter_with_default.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.evil_delete.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.update_counter_with_default_bad_pos.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.evil_delete.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.update_counter_with_default_bad_pos.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.evil_rename.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.update_element.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.evil_rename.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.update_element.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.evil_update_counter.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.update_element_default.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.evil_update_counter.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.update_element_default.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.exit_large_table_owner.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.verybadnew.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.exit_large_table_owner.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.verybadnew.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.exit_many_large_table_owner.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.whereis_table.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.exit_many_large_table_owner.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.whereis_table.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.exit_many_many_tables_owner.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.write_concurrency.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.exit_many_many_tables_owner.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_suite.write_concurrency.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.exit_many_tables_owner.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_tough_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.exit_many_tables_owner.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_tough_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.firstnext.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_tough_suite.ex1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.firstnext.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_tough_suite.ex1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.firstnext_concurrent.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_tough_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.firstnext_concurrent.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_tough_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.firstnext_lookup.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_tough_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.firstnext_lookup.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ets_tough_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.firstnext_lookup_concurrent.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.badarg.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.firstnext_lookup_concurrent.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.badarg.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.fixtable_insert.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.basic.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.fixtable_insert.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.basic.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.fixtable_iter_bag.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_check.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.fixtable_iter_bag.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_check.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.fixtable_next.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_merge.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.fixtable_next.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_merge.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.fold_badarg.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_sort.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.fold_badarg.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_sort.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.fold_empty.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_term_check.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.fold_empty.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_term_check.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.foldl.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_term_keycheck.484290.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.foldl.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_term_keycheck.484290.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.foldl_ordered.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_term_keycheck.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.foldl_ordered.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_term_keycheck.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.foldr.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_term_keymerge.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.foldr.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_term_keymerge.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.foldr_ordered.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_term_keysort.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.foldr_ordered.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_term_keysort.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.give_away.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_term_merge.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.give_away.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_term_merge.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.grow_pseudo_deleted.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_term_sort.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.grow_pseudo_deleted.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.binary_term_sort.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.grow_shrink.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.grow_shrink.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.hash_clash.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.hash_clash.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.heavy_concurrent.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.inout.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.heavy_concurrent.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.inout.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.heavy_lookup.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.many.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.heavy_lookup.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.many.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.heavy_lookup_element.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.misc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.heavy_lookup_element.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.misc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.heir.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.heir.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.term_check.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.term_check.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.info_binary_stress.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.term_keymerge.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.info_binary_stress.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.term_keymerge.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.info_whereis_busy.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.term_keysort.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.info_whereis_busy.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.term_keysort.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.10114.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.term_merge.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.10114.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.term_merge.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.10242.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.term_sort.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.10242.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/file_sorter_suite.term_sort.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.11010.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.11010.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.11234.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_dir_eexist.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.11234.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_dir_eexist.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.11362.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_dir_symlink.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.11362.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_dir_symlink.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.11650.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_path_binary_args.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.11650.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_path_binary_args.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.11938.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_path_invalid_path.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.11938.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_path_invalid_path.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.12098.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_path_nested_dirs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.12098.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_path_nested_dirs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.17794.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_path_relative_path.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.17794.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_path_relative_path.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.19586.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_path_relative_path_dot_dot.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.19586.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_path_relative_path_dot_dot.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.9986.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_path_single_dir.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.9986.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_path_single_dir.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_path_symlink.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.ensure_path_symlink.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.file_props_symlink.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.file_props_symlink.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.insert_trap_delete.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.find_source.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.insert_trap_delete.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.find_source.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.insert_trap_rename.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.find_source_otp.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.insert_trap_rename.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.find_source_otp.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.interface_equality.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.find_source_subdir.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.interface_equality.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.find_source_subdir.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.keypos2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.fold_files.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.keypos2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.fold_files.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.lookup_element_default.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.lookup_element_default.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.lookup_element_mult.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.is_file_symlink.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.lookup_element_mult.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.is_file_symlink.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.lookup_order.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.otp_5960.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.lookup_order.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.otp_5960.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.massive_ets_all.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.safe_relative_path.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.massive_ets_all.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.safe_relative_path.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.match1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.safe_relative_path_links.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.match1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.safe_relative_path_links.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.match2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.match2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.match_delete.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.wildcard_errors.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.match_delete.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.wildcard_errors.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.match_delete3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.wildcard_one.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.match_delete3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.wildcard_one.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.match_heavy.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.wildcard_symlink.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.match_heavy.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.wildcard_symlink.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.match_object.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.wildcard_two.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.match_object.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filelib_suite.wildcard_two.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.match_object2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.absname.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.match_object2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.absname.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.member.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.absname_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.member.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.absname_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.memory.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.absname_bin.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.memory.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.absname_bin.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.meta_lookup_named_read.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.absname_bin_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.meta_lookup_named_read.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.absname_bin_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.meta_lookup_named_write.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.basename_1.402275.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.meta_lookup_named_write.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.basename_1.402275.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.meta_lookup_unnamed_read.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.basename_2.486658.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.meta_lookup_unnamed_read.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.basename_2.486658.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.meta_lookup_unnamed_write.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.basename_bin_1.486690.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.meta_lookup_unnamed_write.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.basename_bin_1.486690.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.meta_newdel_named.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.basename_bin_2.486722.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.meta_newdel_named.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.basename_bin_2.486722.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.meta_newdel_unnamed.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.dirname.486498.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.meta_newdel_unnamed.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.dirname.486498.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.meta_wb.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.dirname_bin.486754.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.meta_wb.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.dirname_bin.486754.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.misc1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.misc1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.ms_excessive_nesting.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.ms_excessive_nesting.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.named.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.extension.486530.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.named.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.extension.486530.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.ordered.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.extension_bin.486562.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.ordered.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.extension_bin.486562.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.ordered_match.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.ordered_match.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_10182.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_10182.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_5340.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.join.486594.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_5340.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.join.486594.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_6338.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.join_bin.486786.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_6338.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.join_bin.486786.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_6842_select_1000.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.pathtype.486626.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_6842_select_1000.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.pathtype.486626.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_7665.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.pathtype_bin.421732.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_7665.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.pathtype_bin.421732.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_8166.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.rootname.421668.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_8166.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.rootname.421668.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_8732.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.rootname_bin.421764.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_8732.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.rootname_bin.421764.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_9423.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.split.421700.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_9423.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.split.421700.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_9932.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.split_bin.421796.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.otp_9932.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.split_bin.421796.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.partly_bound.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.partly_bound.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.privacy.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.t_basedir_api.421828.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.privacy.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.t_basedir_api.421828.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.rename.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.t_basedir_windows.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.rename.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.t_basedir_windows.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.rename_unnamed.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.t_basedir_xdg.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.rename_unnamed.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.t_basedir_xdg.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.safe_fixtable.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.t_nativename.402243.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.safe_fixtable.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.t_nativename.402243.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.select_bound_chunk.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.t_nativename_bin.402307.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.select_bound_chunk.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/filename_suite.t_nativename_bin.402307.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.select_fail.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.select_fail.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.select_fixtab_owner_change.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.fixbag.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.select_fixtab_owner_change.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.fixbag.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.select_mbuf_trapping.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.select_mbuf_trapping.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.setbag.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.insert_same_key.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.setbag.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.insert_same_key.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.setopts.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.multiple_fixes.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.setopts.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.multiple_fixes.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.shrink_pseudo_deleted.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.multiple_processes.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.shrink_pseudo_deleted.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.multiple_processes.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.slot.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.other_process_closes.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.slot.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.other_process_closes.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.smp_fixed_delete.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.other_process_deletes.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.smp_fixed_delete.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.other_process_deletes.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.smp_insert.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.owner_dies.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.smp_insert.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.owner_dies.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.smp_ordered_iteration.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.smp_ordered_iteration.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/fixtable_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.smp_select_delete.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/format_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.smp_select_delete.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/format_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.smp_select_replace.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/format_suite.hang_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.smp_select_replace.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/format_suite.hang_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.smp_unfix_fix.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/format_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.smp_unfix_fix.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/format_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/format_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/format_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_bucket_disappears.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.add_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_bucket_disappears.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.add_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_delete_all_objects.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.balance_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_delete_all_objects.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.balance_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_delete_all_objects_trap.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.delete_any_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_delete_all_objects_trap.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.delete_any_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_delete_object.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.delete_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_delete_object.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.delete_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_ets_dets.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.difference_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_ets_dets.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.difference_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_init_table.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_init_table.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.from_ordset_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.from_ordset_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list_bag.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list_bag.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list_delete_parallel.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.insert_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list_delete_parallel.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.insert_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list_delete_set.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.is_member_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list_delete_set.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.is_member_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list_duplicate_bag.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.iterator_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list_duplicate_bag.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.iterator_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list_insert_order_preserved.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.iterator_from_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list_insert_order_preserved.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.iterator_from_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list_kill_process.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.larger_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list_kill_process.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.larger_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list_parallel.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.largest_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list_parallel.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.largest_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list_set.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.singleton_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_list_set.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.singleton_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_new.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.smaller_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_insert_new.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.smaller_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_match_spec_run.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.smallest_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_match_spec_run.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.smallest_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_named_select.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_named_select.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_repair_continuation.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.take_largest_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_repair_continuation.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.take_largest_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_select_delete.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.take_smallest_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_select_delete.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gb_sets_property_test_suite.take_smallest_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_select_flatmap_term_copy_bug.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.add_handler.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_select_flatmap_term_copy_bug.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.add_handler.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_select_hashmap_term_copy_bug.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.add_sup_handler.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_select_hashmap_term_copy_bug.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.add_sup_handler.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_select_pam_stack_overflow_bug.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.auto_hibernate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_select_pam_stack_overflow_bug.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.auto_hibernate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_select_replace.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.call.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_select_replace.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.call.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_select_replace_next_bug.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.call_format_status.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_select_replace_next_bug.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.call_format_status.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_select_reverse.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.call_format_status_anon.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_select_reverse.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.call_format_status_anon.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_test_ms.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.delete_handler.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_test_ms.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.delete_handler.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_whitebox.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.end_per_group.402339.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.t_whitebox.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.end_per_group.402339.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.tab2file.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.tab2file.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.tab2file2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.tab2file2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.tab2list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.error_format_status.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.tab2list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.error_format_status.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.tabfile_ext1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.format_log_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.tabfile_ext1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.format_log_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.tabfile_ext2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.format_log_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.tabfile_ext2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.format_log_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.tabfile_ext3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.format_log_with_process_label.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.tabfile_ext3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.format_log_with_process_label.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.tabfile_ext4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.get_state.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.tabfile_ext4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.get_state.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.table_leak.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.hibernate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.table_leak.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.hibernate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.take.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.take.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.test_decentralized_counters_setting.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.init_per_group.487362.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.test_decentralized_counters_setting.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.init_per_group.487362.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.test_delete_table_while_size_snapshot.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.test_delete_table_while_size_snapshot.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.test_table_memory_concurrency.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.test_table_memory_concurrency.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.test_table_size_concurrency.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.notify.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.test_table_size_concurrency.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.notify.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.test_throughput_benchmark.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.replace_state.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.test_throughput_benchmark.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.replace_state.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.types.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.send_request_check_reqid_collection.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.types.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.send_request_check_reqid_collection.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.update_counter.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.send_request_receive_reqid_collection.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.update_counter.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.send_request_receive_reqid_collection.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.update_counter_table_growth.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.send_request_wait_reqid_collection.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.update_counter_table_growth.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.send_request_wait_reqid_collection.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.update_counter_with_default.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.update_counter_with_default.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.update_counter_with_default_bad_pos.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.start.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.update_counter_with_default_bad_pos.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.start.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.update_element.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.start_opt.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.update_element.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.start_opt.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.update_element_default.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.swap_handler.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.update_element_default.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.swap_handler.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.verybadnew.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.swap_sup_handler.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.verybadnew.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.swap_sup_handler.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.whereis_table.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.sync_notify.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.whereis_table.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.sync_notify.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.write_concurrency.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.undef_code_change.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_suite.write_concurrency.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.undef_code_change.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_tough_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.undef_handle_call.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_tough_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.undef_handle_call.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_tough_suite.ex1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.undef_handle_event.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_tough_suite.ex1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.undef_handle_event.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_tough_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.undef_handle_info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_tough_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.undef_handle_info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_tough_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.undef_in_terminate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ets_tough_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.undef_in_terminate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.badarg.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.undef_init.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.badarg.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.undef_init.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.basic.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.undef_terminate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.basic.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_event_suite.undef_terminate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_check.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.abnormal1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_check.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.abnormal1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_merge.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.abnormal2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_merge.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.abnormal2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_sort.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.auto_hibernate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_sort.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.auto_hibernate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_term_check.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.call_format_status.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_term_check.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.call_format_status.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_term_keycheck.468674.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.end_per_group.402371.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_term_keycheck.468674.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.end_per_group.402371.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_term_keycheck.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.end_per_group.402435.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_term_keycheck.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.end_per_group.402435.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_term_keymerge.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.end_per_group.421860.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_term_keymerge.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.end_per_group.421860.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_term_keysort.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.end_per_group.487458.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_term_keysort.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.end_per_group.487458.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_term_merge.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_term_merge.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_term_sort.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.binary_term_sort.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.enter_loop.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.enter_loop.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.error_format_status.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.error_format_status.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.inout.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.format_log_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.inout.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.format_log_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.many.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.format_log_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.many.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.format_log_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.misc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.format_log_with_process_label.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.misc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.format_log_with_process_label.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.get_state.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.get_state.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.term_check.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.hibernate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.term_check.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.hibernate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.term_keymerge.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.init_per_group.402403.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.term_keymerge.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.init_per_group.402403.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.term_keysort.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.init_per_group.402467.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.term_keysort.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.init_per_group.402467.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.term_merge.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.init_per_group.487394.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.term_merge.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.init_per_group.487394.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.term_sort.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.init_per_group.487426.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/file_sorter_suite.term_sort.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.init_per_group.487426.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_dir_eexist.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_dir_eexist.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_dir_symlink.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.replace_state.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_dir_symlink.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.replace_state.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_path_binary_args.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.reply_by_alias_with_payload.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_path_binary_args.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.reply_by_alias_with_payload.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_path_invalid_path.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.shutdown.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_path_invalid_path.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.shutdown.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_path_nested_dirs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_path_nested_dirs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_path_relative_path.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_path_relative_path.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_path_relative_path_dot_dot.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start10.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_path_relative_path_dot_dot.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start10.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_path_single_dir.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start11.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_path_single_dir.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start11.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_path_symlink.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start12.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.ensure_path_symlink.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start12.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.file_props_symlink.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.file_props_symlink.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.find_source.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.find_source.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.find_source_otp.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.find_source_otp.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.find_source_subdir.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start5.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.find_source_subdir.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start5.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.fold_files.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start6.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.fold_files.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start6.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start7.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start7.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.is_file_symlink.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start8.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.is_file_symlink.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start8.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.otp_5960.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start9.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.otp_5960.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.start9.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.safe_relative_path.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.sys1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.safe_relative_path.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.sys1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.safe_relative_path_links.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.terminate_crash_format.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.safe_relative_path_links.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.terminate_crash_format.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_code_change.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_code_change.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.wildcard_errors.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_handle_event.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.wildcard_errors.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_handle_event.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.wildcard_one.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_handle_info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.wildcard_one.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_handle_info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.wildcard_symlink.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_handle_sync_event.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.wildcard_symlink.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_handle_sync_event.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.wildcard_two.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_in_handle_info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filelib_suite.wildcard_two.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_in_handle_info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.absname.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_in_terminate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.absname.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_in_terminate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.absname_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_init.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.absname_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_init.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.absname_bin.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_terminate1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.absname_bin.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_terminate1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.absname_bin_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_terminate2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.absname_bin_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_fsm_suite.undef_terminate2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.basename_1.394948.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.abcast.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.basename_1.394948.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.abcast.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.basename_2.394916.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.auto_hibernate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.basename_2.394916.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.auto_hibernate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.basename_bin_1.496643.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.basename_bin_1.496643.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.basename_bin_2.496675.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call_format_status.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.basename_bin_2.496675.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call_format_status.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.dirname.470914.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call_remote1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.dirname.470914.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call_remote1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.dirname_bin.496707.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call_remote2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.dirname_bin.496707.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call_remote2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call_remote3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call_remote3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call_remote_n1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call_remote_n1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.extension.470946.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call_remote_n2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.extension.470946.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call_remote_n2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.extension_bin.394820.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call_remote_n3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.extension_bin.394820.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call_remote_n3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call_with_huge_message_queue.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.call_with_huge_message_queue.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.calling_self.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.calling_self.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.join.394852.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.cast.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.join.394852.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.cast.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.join_bin.496739.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.cast_fast.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.join_bin.496739.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.cast_fast.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.pathtype.470882.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.continue.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.pathtype.470882.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.continue.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.pathtype_bin.496771.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.crash.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.pathtype_bin.496771.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.crash.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.rootname.470978.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.crash_in_format_status.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.rootname.470978.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.crash_in_format_status.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.rootname_bin.395012.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.end_per_group.488418.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.rootname_bin.395012.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.end_per_group.488418.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.split.394980.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.end_per_group.488834.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.split.394980.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.end_per_group.488834.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.split_bin.395044.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.end_per_group.488866.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.split_bin.395044.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.end_per_group.488866.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.end_per_group.489442.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.end_per_group.489442.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.t_basedir_api.395108.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.end_per_group.489506.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.t_basedir_api.395108.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.end_per_group.489506.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.t_basedir_windows.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.t_basedir_windows.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.t_basedir_xdg.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.t_basedir_xdg.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.t_nativename.394884.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.error_format_status.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.t_nativename.394884.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.error_format_status.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.t_nativename_bin.395076.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.format_all_status.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/filename_suite.t_nativename_bin.395076.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.format_all_status.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.format_log_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.format_log_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.fixbag.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.format_log_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.fixbag.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.format_log_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.format_log_with_process_label.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.format_log_with_process_label.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.insert_same_key.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.get_state.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.insert_same_key.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.get_state.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.multiple_fixes.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.hibernate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.multiple_fixes.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.hibernate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.multiple_processes.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.multiple_processes.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.other_process_closes.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.init_per_group.487874.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.other_process_closes.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.init_per_group.487874.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.other_process_deletes.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.init_per_group.487906.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.other_process_deletes.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.init_per_group.487906.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.owner_dies.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.init_per_group.488450.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.owner_dies.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.init_per_group.488450.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.init_per_group.489410.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/fixtable_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.init_per_group.489410.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/format_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.init_per_group.489474.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/format_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.init_per_group.489474.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/format_suite.hang_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/format_suite.hang_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/format_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/format_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/format_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.loop_start_fail.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/format_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.loop_start_fail.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.add_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.multicall.487938.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.add_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.multicall.487938.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.balance_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.multicall_down.487970.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.balance_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.multicall_down.487970.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.delete_any_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.multicall_recv_opt_noconnection.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.delete_any_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.multicall_recv_opt_noconnection.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.delete_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.multicall_recv_opt_success.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.delete_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.multicall_recv_opt_success.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.difference_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.multicall_recv_opt_timeout.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.difference_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.multicall_recv_opt_timeout.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.multicall_remote.488002.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.multicall_remote.488002.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.from_ordset_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.multicall_remote_old2.402499.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.from_ordset_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.multicall_remote_old2.402499.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.otp_5854.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.otp_5854.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.insert_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.otp_7669.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.insert_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.otp_7669.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.is_member_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.replace_state.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.is_member_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.replace_state.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.iterator_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.reply_by_alias_with_payload.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.iterator_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.reply_by_alias_with_payload.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.iterator_from_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.send_request.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.iterator_from_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.send_request.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.larger_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.send_request_check_reqid_collection.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.larger_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.send_request_check_reqid_collection.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.largest_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.send_request_receive_reqid_collection.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.largest_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.send_request_receive_reqid_collection.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.singleton_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.send_request_wait_reqid_collection.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.singleton_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.send_request_wait_reqid_collection.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.smaller_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.spec_init.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.smaller_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.spec_init.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.smallest_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.spec_init_global_registered_parent.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.smallest_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.spec_init_global_registered_parent.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.spec_init_local_registered_parent.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.spec_init_local_registered_parent.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.take_largest_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.take_largest_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.take_smallest_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.start.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gb_sets_property_test_suite.take_smallest_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.start.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.add_handler.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.add_handler.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.add_sup_handler.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop10.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.add_sup_handler.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop10.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.auto_hibernate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.auto_hibernate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.call.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.call.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.call_format_status.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.call_format_status.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.call_format_status_anon.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop5.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.call_format_status_anon.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop5.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.delete_handler.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop6.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.delete_handler.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop6.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.end_per_group.496867.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop7.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.end_per_group.496867.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop7.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop8.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop8.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop9.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.stop9.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.error_format_status.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.terminate_crash_format.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.error_format_status.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.terminate_crash_format.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.format_log_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.throw_in_format_status.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.format_log_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.throw_in_format_status.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.format_log_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_code_change.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.format_log_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_code_change.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.format_log_with_process_label.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_handle_call.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.format_log_with_process_label.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_handle_call.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.get_state.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_handle_cast.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.get_state.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_handle_cast.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.hibernate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_handle_continue.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.hibernate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_handle_continue.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_handle_info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_handle_info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.init_per_group.496835.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_in_handle_info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.init_per_group.496835.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_in_handle_info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_in_terminate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_in_terminate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_init.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_init.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.notify.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_terminate1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.notify.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_terminate1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.replace_state.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_terminate2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.replace_state.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_server_suite.undef_terminate2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.send_request_check_reqid_collection.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal1.490658.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.send_request_check_reqid_collection.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal1.490658.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.send_request_receive_reqid_collection.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.send_request_receive_reqid_collection.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.send_request_wait_reqid_collection.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal1clean.490690.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.send_request_wait_reqid_collection.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal1clean.490690.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal1clean.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal1clean.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.start.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal1dirty.490722.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.start.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal1dirty.490722.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.start_opt.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal1dirty.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.start_opt.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal1dirty.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.swap_handler.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal2.490754.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.swap_handler.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal2.490754.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.swap_sup_handler.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.swap_sup_handler.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.sync_notify.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal3.490786.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.sync_notify.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal3.490786.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.undef_code_change.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.undef_code_change.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.undef_handle_call.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal4.490818.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.undef_handle_call.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal4.490818.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.undef_handle_event.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.undef_handle_event.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.abnormal4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.undef_handle_info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.auto_hibernate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.undef_handle_info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.auto_hibernate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.undef_in_terminate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.call_format_status.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.undef_in_terminate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.call_format_status.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.undef_init.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.code_change.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.undef_init.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.code_change.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.undef_terminate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.403107.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_event_suite.undef_terminate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.403107.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.abnormal1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.421892.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.abnormal1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.421892.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.abnormal2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.421924.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.abnormal2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.421924.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.auto_hibernate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.490018.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.auto_hibernate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.490018.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.call_format_status.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.490210.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.call_format_status.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.490210.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.end_per_group.471554.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.490530.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.end_per_group.471554.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.490530.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.end_per_group.496931.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.490594.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.end_per_group.496931.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.490594.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.end_per_group.496995.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.490946.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.end_per_group.496995.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.490946.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.end_per_group.497059.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.491010.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.end_per_group.497059.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.491010.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.enter_loop.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.enter_loop.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.enter_loop.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.enter_loop.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.error_format_status.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.error_format_status.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.error_format_status.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.error_format_status.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.format_log_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.event_order.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.format_log_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.event_order.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.format_log_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.event_types.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.format_log_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.event_types.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.format_log_with_process_label.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.format_all_status.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.format_log_with_process_label.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.format_all_status.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.get_state.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.format_log_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.get_state.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.format_log_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.hibernate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.format_log_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.hibernate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.format_log_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.init_per_group.471522.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.format_log_with_process_label.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.init_per_group.471522.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.format_log_with_process_label.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.init_per_group.496899.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.generic_timers.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.init_per_group.496899.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.generic_timers.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.init_per_group.496963.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.get_state.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.init_per_group.496963.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.get_state.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.init_per_group.497027.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.hibernate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.init_per_group.497027.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.hibernate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.489538.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.489538.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.490050.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.490050.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.replace_state.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.490242.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.replace_state.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.490242.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.reply_by_alias_with_payload.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.490562.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.reply_by_alias_with_payload.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.490562.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.shutdown.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.490626.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.shutdown.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.490626.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.490850.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.490850.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.490882.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.490882.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start10.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.490914.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start10.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.490914.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start11.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.490978.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start11.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.490978.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start12.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start12.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.loop_start_fail.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.loop_start_fail.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.next_events.489986.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.next_events.489986.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start5.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.next_events.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start5.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.next_events.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start6.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.pop_too_many.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start6.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.pop_too_many.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start7.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.replace_state.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start7.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.replace_state.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start8.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.reply_by_alias_with_payload.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start8.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.reply_by_alias_with_payload.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start9.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.send_request_check_reqid_collection.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.start9.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.send_request_check_reqid_collection.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.sys1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.send_request_receive_reqid_collection.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.sys1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.send_request_receive_reqid_collection.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.terminate_crash_format.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.send_request_wait_reqid_collection.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.terminate_crash_format.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.send_request_wait_reqid_collection.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_code_change.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.shutdown.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_code_change.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.shutdown.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_handle_event.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_handle_event.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_handle_info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start1.489570.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_handle_info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start1.489570.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_handle_sync_event.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_handle_sync_event.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_in_handle_info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start10.489890.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_in_handle_info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start10.489890.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_in_terminate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start10.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_in_terminate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start10.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_init.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start11.489922.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_init.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start11.489922.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_terminate1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start11.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_terminate1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start11.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_terminate2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start12.489954.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_fsm_suite.undef_terminate2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start12.489954.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.abcast.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start12.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.abcast.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start12.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.auto_hibernate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start2.489602.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.auto_hibernate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start2.489602.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call_format_status.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start3.489634.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call_format_status.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start3.489634.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call_remote1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call_remote1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call_remote2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start4.489666.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call_remote2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start4.489666.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call_remote3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call_remote3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call_remote_n1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start5a.489698.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call_remote_n1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start5a.489698.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call_remote_n2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start5a.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call_remote_n2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start5a.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call_remote_n3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start5b.489730.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call_remote_n3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start5b.489730.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call_with_huge_message_queue.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start5b.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.call_with_huge_message_queue.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start5b.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.calling_self.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start6.489762.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.calling_self.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start6.489762.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.cast.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start6.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.cast.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start6.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.cast_fast.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start7.489794.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.cast_fast.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start7.489794.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.continue.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start7.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.continue.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start7.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.crash.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start8.489826.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.crash.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start8.489826.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.crash_in_format_status.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start8.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.crash_in_format_status.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start8.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.end_per_group.472290.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start9.489858.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.end_per_group.472290.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start9.489858.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.end_per_group.472642.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start9.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.end_per_group.472642.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.start9.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.end_per_group.472674.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.state_enter.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.end_per_group.472674.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.state_enter.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.end_per_group.473250.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.state_timeout.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.end_per_group.473250.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.state_timeout.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.end_per_group.473314.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop1.490274.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.end_per_group.473314.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop1.490274.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop10.403043.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop10.403043.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.error_format_status.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop10.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.error_format_status.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop10.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.format_all_status.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop2.490306.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.format_all_status.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop2.490306.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.format_log_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.format_log_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.format_log_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop3.490338.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.format_log_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop3.490338.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.format_log_with_process_label.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.format_log_with_process_label.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.get_state.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop4.402819.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.get_state.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop4.402819.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.hibernate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.hibernate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop5.402851.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop5.402851.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.init_per_group.395140.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop5.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.init_per_group.395140.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop5.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.init_per_group.395172.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop6.490370.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.init_per_group.395172.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop6.490370.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.init_per_group.395300.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop6.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.init_per_group.395300.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop6.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.init_per_group.473218.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop7.402883.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.init_per_group.473218.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop7.402883.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.init_per_group.473282.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop7.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.init_per_group.473282.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop7.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop8.402915.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop8.402915.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop8.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop8.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.loop_start_fail.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop9.490434.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.loop_start_fail.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop9.490434.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.multicall.395204.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop9.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.multicall.395204.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop9.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.multicall_down.395236.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop_and_reply.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.multicall_down.395236.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.stop_and_reply.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.multicall_recv_opt_noconnection.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.sys1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.multicall_recv_opt_noconnection.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.sys1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.multicall_recv_opt_success.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.terminate_crash_format.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.multicall_recv_opt_success.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.terminate_crash_format.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.multicall_recv_opt_timeout.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.timeout_cancel_and_update.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.multicall_recv_opt_timeout.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.timeout_cancel_and_update.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.multicall_remote.395268.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.undef_code_change.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.multicall_remote.395268.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.undef_code_change.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.multicall_remote_old2.471874.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.undef_in_terminate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.multicall_remote_old2.471874.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.undef_in_terminate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.otp_5854.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.undef_terminate1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.otp_5854.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.undef_terminate1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.otp_7669.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.undef_terminate2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.otp_7669.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/gen_statem_suite.undef_terminate2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.replace_state.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/id_transform_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.replace_state.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/id_transform_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.reply_by_alias_with_payload.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/id_transform_suite.id_transform.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.reply_by_alias_with_payload.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/id_transform_suite.id_transform.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.send_request.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/id_transform_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.send_request.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/id_transform_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.send_request_check_reqid_collection.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/id_transform_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.send_request_check_reqid_collection.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/id_transform_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.send_request_receive_reqid_collection.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.binary_options.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.send_request_receive_reqid_collection.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.binary_options.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.send_request_wait_reqid_collection.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.broken_unicode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.send_request_wait_reqid_collection.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.broken_unicode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.spec_init.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.spec_init.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.spec_init_global_registered_parent.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.eof_on_pipe.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.spec_init_global_registered_parent.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.eof_on_pipe.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.spec_init_local_registered_parent.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.file_read_line_stdin_unicode_translation_error_binary_mode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.spec_init_local_registered_parent.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.file_read_line_stdin_unicode_translation_error_binary_mode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.file_read_line_stdin_unicode_translation_error_list_mode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.file_read_line_stdin_unicode_translation_error_list_mode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.start.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.file_read_stdin_binary_mode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.start.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.file_read_stdin_binary_mode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.file_read_stdin_latin1_binary_mode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.file_read_stdin_latin1_binary_mode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop10.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.file_read_stdin_latin1_list_mode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop10.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.file_read_stdin_latin1_list_mode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.file_read_stdin_list_mode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.file_read_stdin_list_mode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.file_read_stdin_unicode_translation_error_binary_mode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.file_read_stdin_unicode_translation_error_binary_mode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.file_read_stdin_unicode_translation_error_list_mode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.file_read_stdin_unicode_translation_error_list_mode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop5.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop5.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop6.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.io_fwrite_stdin_latin1_mode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop6.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.io_fwrite_stdin_latin1_mode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop7.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.io_get_chars_file_read_stdin_binary_mode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop7.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.io_get_chars_file_read_stdin_binary_mode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop8.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.io_get_chars_stdin_binary_mode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop8.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.io_get_chars_stdin_binary_mode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop9.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.io_get_chars_stdin_list_mode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.stop9.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.io_get_chars_stdin_list_mode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.terminate_crash_format.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.io_get_until_stdin_binary_mode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.terminate_crash_format.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.io_get_until_stdin_binary_mode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.throw_in_format_status.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.io_get_until_stdin_list_mode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.throw_in_format_status.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.io_get_until_stdin_list_mode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_code_change.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.raw_stdout.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_code_change.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.raw_stdout.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_handle_call.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.raw_stdout_isatty.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_handle_call.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.raw_stdout_isatty.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_handle_cast.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.read_modes_gl.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_handle_cast.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.read_modes_gl.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_handle_continue.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.read_modes_ogl.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_handle_continue.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.read_modes_ogl.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_handle_info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.setopts_getopts.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_handle_info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.setopts_getopts.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_in_handle_info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.shell_slogan.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_in_handle_info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.shell_slogan.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_in_terminate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_in_terminate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_init.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.unicode_options.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_init.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.unicode_options.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_terminate1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.unicode_options_gen.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_terminate1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.unicode_options_gen.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_terminate2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.unicode_prompt.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_server_suite.undef_terminate2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_proto_suite.unicode_prompt.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal1.498051.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.bad_printable_range.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal1.498051.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.bad_printable_range.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.build_text_without_maps_order.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.build_text_without_maps_order.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal1clean.498083.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.calling_self.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal1clean.498083.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.calling_self.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal1clean.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.chars_limit.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal1clean.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.chars_limit.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal1dirty.498115.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.coverage.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal1dirty.498115.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.coverage.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal1dirty.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.cr_whitespace_in_string.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal1dirty.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.cr_whitespace_in_string.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal2.498147.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.error_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal2.498147.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.error_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.error_info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.error_info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal3.498179.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.float_g.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal3.498179.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.float_g.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.float_w.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.float_w.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal4.498211.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.format_neg_zero.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal4.498211.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.format_neg_zero.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.format_string.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.abnormal4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.format_string.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.auto_hibernate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.github_4801.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.auto_hibernate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.github_4801.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.call_format_status.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.io_fread_newlines.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.call_format_status.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.io_fread_newlines.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.code_change.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.io_lib_collect_line_3_wb.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.code_change.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.io_lib_collect_line_3_wb.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.473826.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.io_lib_fread_literal.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.473826.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.io_lib_fread_literal.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.474146.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.io_lib_print_binary_depth_one.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.474146.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.io_lib_print_binary_depth_one.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.474210.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.io_lib_width_too_small.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.474210.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.io_lib_width_too_small.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.474274.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.io_with_huge_message_queue.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.474274.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.io_with_huge_message_queue.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.497443.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.limit_term.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.497443.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.limit_term.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.497955.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.manpage.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.497955.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.manpage.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.497987.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.maps.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.497987.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.maps.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.498243.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_10302.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.498243.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_10302.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.498339.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_10755.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.498339.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_10755.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_10836.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_10836.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_14175.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_14175.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.enter_loop.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_14178_unicode_atoms.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.enter_loop.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_14178_unicode_atoms.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.error_format_status.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_14285.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.error_format_status.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_14285.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.event_order.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_14983.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.event_order.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_14983.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.event_types.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_15076.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.event_types.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_15076.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.format_all_status.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_15103.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.format_all_status.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_15103.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.format_log_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_15159.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.format_log_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_15159.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.format_log_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_15639.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.format_log_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_15639.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.format_log_with_process_label.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_15705.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.format_log_with_process_label.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_15705.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.generic_timers.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_15847.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.generic_timers.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_15847.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.get_state.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_15875.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.get_state.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_15875.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.hibernate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_17525.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.hibernate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_17525.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.473346.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_5403.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.473346.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_5403.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.473858.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_5813.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.473858.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_5813.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.474114.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_6230.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.474114.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_6230.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.474178.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_6282.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.474178.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_6282.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.474242.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_6354.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.474242.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_6354.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.497475.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_6495.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.497475.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_6495.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.498019.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_6502.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.498019.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_6502.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.498275.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_6517.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.498275.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_6517.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.498307.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_6708.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.498307.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_6708.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_7084.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_7084.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_7421.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_7421.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.loop_start_fail.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_8989.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.loop_start_fail.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.otp_8989.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.next_events.473794.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.printable_range.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.next_events.473794.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.printable_range.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.next_events.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.next_events.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.pop_too_many.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.unscan_format_without_maps_order.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.pop_too_many.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/io_suite.unscan_format_without_maps_order.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.replace_state.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.counterexamples.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.replace_state.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.counterexamples.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.reply_by_alias_with_payload.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.end_per_group.403267.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.reply_by_alias_with_payload.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.end_per_group.403267.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.send_request_check_reqid_collection.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.end_per_group.493026.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.send_request_check_reqid_collection.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.end_per_group.493026.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.send_request_receive_reqid_collection.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.end_per_group.493186.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.send_request_receive_reqid_collection.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.end_per_group.493186.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.send_request_wait_reqid_collection.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.send_request_wait_reqid_collection.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.shutdown.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.init_per_group.403299.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.shutdown.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.init_per_group.403299.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.init_per_group.492802.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.init_per_group.492802.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start1.473378.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.init_per_group.493058.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start1.473378.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.init_per_group.493058.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start10.473698.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.property_escape_all.493154.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start10.473698.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.property_escape_all.493154.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start10.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.property_float_roundtrip.421988.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start10.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.property_float_roundtrip.421988.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start11.473730.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.property_integer_roundtrip.493122.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start11.473730.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.property_integer_roundtrip.493122.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start11.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.property_object_roundtrip.421956.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start11.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.property_object_roundtrip.421956.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start12.473762.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.property_string_roundtrip.493090.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start12.473762.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.property_string_roundtrip.493090.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start12.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start12.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start2.473410.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_decode_api.492962.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start2.473410.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_decode_api.492962.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_decode_api_stream.426245.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_decode_api_stream.426245.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start3.473442.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_decode_arrays.492930.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start3.473442.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_decode_arrays.492930.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_decode_atoms.492834.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_decode_atoms.492834.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start4.473474.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_decode_numbers.492866.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start4.473474.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_decode_numbers.492866.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_decode_objects.426181.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_decode_objects.426181.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start5a.473506.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_decode_strings.492898.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start5a.473506.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_decode_strings.492898.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start5a.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_decode_whitespace.426213.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start5a.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_decode_whitespace.426213.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start5b.473538.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_encode_atom.492706.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start5b.473538.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_encode_atom.492706.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start5b.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_encode_binary.403235.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start5b.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_encode_binary.403235.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start6.473570.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_encode_escape_all.492770.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start6.473570.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_encode_escape_all.492770.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start6.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_encode_float.492738.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start6.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_encode_float.492738.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start7.473602.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_encode_integer.403171.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start7.473602.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_encode_integer.403171.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start7.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_encode_list.403203.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start7.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_encode_list.403203.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start8.473634.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_encode_map.492674.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start8.473634.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_encode_map.492674.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start8.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_encode_proplist.403139.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start8.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_encode_proplist.403139.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start9.473666.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_format_fun.492994.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start9.473666.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_format_fun.492994.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start9.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_format_list.403331.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.start9.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_format_list.403331.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.state_enter.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_format_map.403363.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.state_enter.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_format_map.403363.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.state_timeout.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_json_test_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.state_timeout.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/json_suite.test_json_test_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop1.497507.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.all_false_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop1.497507.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.all_false_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.all_true_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.all_true_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop10.497891.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.any_false_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop10.497891.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.any_false_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop10.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.any_true_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop10.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.any_true_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop2.497539.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.append_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop2.497539.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.append_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.append_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.append_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop3.497571.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.concat_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop3.497571.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.concat_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.delete_absent_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.delete_absent_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop4.497603.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.delete_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop4.497603.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.delete_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.droplast_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.droplast_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop5.497635.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.dropwhile_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop5.497635.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.dropwhile_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop5.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.duplicate_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop5.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.duplicate_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop6.497667.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop6.497667.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop6.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.enumerate_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop6.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.enumerate_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop7.497699.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.enumerate_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop7.497699.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.enumerate_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop7.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.enumerate_3_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop7.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.enumerate_3_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop8.497731.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.filter_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop8.497731.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.filter_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop8.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.filtermap_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop8.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.filtermap_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop9.497827.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.flatlength_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop9.497827.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.flatlength_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop9.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.flatmap_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop9.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.flatmap_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop_and_reply.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.flatten_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.stop_and_reply.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.flatten_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.sys1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.flatten_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.sys1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.flatten_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.terminate_crash_format.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.foldl_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.terminate_crash_format.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.foldl_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.timeout_cancel_and_update.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.foldr_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.timeout_cancel_and_update.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.foldr_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.undef_code_change.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.foreach_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.undef_code_change.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.foreach_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.undef_in_terminate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.undef_in_terminate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.undef_terminate1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.join_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.undef_terminate1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.join_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.undef_terminate2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keydelete_absent_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/gen_statem_suite.undef_terminate2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keydelete_absent_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/id_transform_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keydelete_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/id_transform_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keydelete_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/id_transform_suite.id_transform.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keyfind_absent_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/id_transform_suite.id_transform.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keyfind_absent_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/id_transform_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keyfind_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/id_transform_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keyfind_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/id_transform_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keymap_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/id_transform_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keymap_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.binary_options.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keymember_absent_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.binary_options.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keymember_absent_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.broken_unicode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keymember_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.broken_unicode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keymember_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keymerge_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keymerge_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.eof_on_pipe.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keymerge_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.eof_on_pipe.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keymerge_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.file_read_line_stdin_unicode_translation_error_binary_mode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keyreplace_absent_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.file_read_line_stdin_unicode_translation_error_binary_mode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keyreplace_absent_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.file_read_line_stdin_unicode_translation_error_list_mode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keyreplace_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.file_read_line_stdin_unicode_translation_error_list_mode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keyreplace_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.file_read_stdin_binary_mode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keysearch_absent_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.file_read_stdin_binary_mode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keysearch_absent_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.file_read_stdin_latin1_binary_mode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keysearch_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.file_read_stdin_latin1_binary_mode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keysearch_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.file_read_stdin_latin1_list_mode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keysort_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.file_read_stdin_latin1_list_mode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keysort_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.file_read_stdin_list_mode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keystore_absent_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.file_read_stdin_list_mode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keystore_absent_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.file_read_stdin_unicode_translation_error_binary_mode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keystore_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.file_read_stdin_unicode_translation_error_binary_mode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keystore_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.file_read_stdin_unicode_translation_error_list_mode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keytake_absent_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.file_read_stdin_unicode_translation_error_list_mode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keytake_absent_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keytake_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.keytake_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.io_fwrite_stdin_latin1_mode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.last_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.io_fwrite_stdin_latin1_mode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.last_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.io_get_chars_file_read_stdin_binary_mode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.map_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.io_get_chars_file_read_stdin_binary_mode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.map_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.io_get_chars_stdin_binary_mode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.mapfoldl_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.io_get_chars_stdin_binary_mode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.mapfoldl_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.io_get_chars_stdin_list_mode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.mapfoldr_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.io_get_chars_stdin_list_mode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.mapfoldr_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.io_get_until_stdin_binary_mode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.max_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.io_get_until_stdin_binary_mode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.max_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.io_get_until_stdin_list_mode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.member_absent_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.io_get_until_stdin_list_mode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.member_absent_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.raw_stdout.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.member_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.raw_stdout.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.member_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.raw_stdout_isatty.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.merge3_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.raw_stdout_isatty.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.merge3_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.read_modes_gl.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.merge3_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.read_modes_gl.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.merge3_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.read_modes_ogl.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.merge_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.read_modes_ogl.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.merge_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.setopts_getopts.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.merge_1_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.setopts_getopts.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.merge_1_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.shell_slogan.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.merge_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.shell_slogan.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.merge_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.merge_2_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.merge_2_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.unicode_options.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.merge_3_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.unicode_options.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.merge_3_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.unicode_options_gen.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.merge_3_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.unicode_options_gen.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.merge_3_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.unicode_prompt.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.min_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_proto_suite.unicode_prompt.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.min_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.bad_printable_range.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.nth_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.bad_printable_range.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.nth_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.build_text_without_maps_order.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.nth_outofrange_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.build_text_without_maps_order.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.nth_outofrange_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.calling_self.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.nthtail_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.calling_self.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.nthtail_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.chars_limit.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.nthtail_outofrange_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.chars_limit.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.nthtail_outofrange_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.coverage.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.partition_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.coverage.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.partition_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.cr_whitespace_in_string.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.prefix_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.cr_whitespace_in_string.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.prefix_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.error_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.reverse_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.error_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.reverse_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.error_info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.reverse_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.error_info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.reverse_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.float_g.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.search_absent_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.float_g.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.search_absent_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.float_w.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.search_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.float_w.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.search_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.format_neg_zero.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.seq2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.format_neg_zero.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.seq2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.format_string.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.seq3_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.format_string.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.seq3_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.github_4801.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.sort_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.github_4801.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.sort_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.io_fread_newlines.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.sort_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.io_fread_newlines.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.sort_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.io_lib_collect_line_3_wb.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.split_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.io_lib_collect_line_3_wb.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.split_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.io_lib_fread_literal.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.split_outofrange_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.io_lib_fread_literal.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.split_outofrange_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.io_lib_print_binary_depth_one.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.splitwith_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.io_lib_print_binary_depth_one.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.splitwith_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.io_lib_width_too_small.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.io_lib_width_too_small.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.io_with_huge_message_queue.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.sublist_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.io_with_huge_message_queue.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.sublist_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.limit_term.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.sublist_3_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.limit_term.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.sublist_3_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.manpage.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.subtract_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.manpage.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.subtract_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.maps.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.suffix_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.maps.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.suffix_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_10302.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.sum_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_10302.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.sum_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_10755.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.takewhile_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_10755.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.takewhile_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_10836.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.ukeymerge_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_10836.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.ukeymerge_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_14175.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.ukeymerge_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_14175.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.ukeymerge_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_14178_unicode_atoms.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.ukeysort_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_14178_unicode_atoms.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.ukeysort_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_14285.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.umerge3_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_14285.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.umerge3_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_14983.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.umerge3_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_14983.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.umerge3_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_15076.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.umerge_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_15076.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.umerge_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_15103.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.umerge_1_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_15103.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.umerge_1_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_15159.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.umerge_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_15159.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.umerge_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_15639.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.umerge_2_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_15639.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.umerge_2_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_15705.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.umerge_3_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_15705.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.umerge_3_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_15847.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.umerge_3_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_15847.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.umerge_3_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_15875.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.uniq_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_15875.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.uniq_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_17525.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.uniq_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_17525.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.uniq_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_5403.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.unzip3_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_5403.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.unzip3_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_5813.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.unzip_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_5813.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.unzip_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_6230.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.usort_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_6230.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.usort_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_6282.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.usort_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_6282.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.usort_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_6354.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.zip3_3_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_6354.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.zip3_3_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_6495.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.zip3_4_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_6495.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.zip3_4_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_6502.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.zip_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_6502.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.zip_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_6517.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.zip_3_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_6517.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.zip_3_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_6708.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.zipwith3_4_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_6708.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.zipwith3_4_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_7084.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.zipwith3_5_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_7084.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.zipwith3_5_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_7421.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.zipwith_3_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_7421.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.zipwith_3_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_8989.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.zipwith_4_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.otp_8989.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_property_test_suite.zipwith_4_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.printable_range.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.append_1.493250.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.printable_range.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.append_1.493250.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.append_2.493282.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.append_2.493282.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.unscan_format_without_maps_order.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.droplast.404963.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/io_suite.unscan_format_without_maps_order.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.droplast.404963.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.counterexamples.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.dropwhile.404931.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.counterexamples.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.dropwhile.404931.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.end_per_group.395588.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.404195.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.end_per_group.395588.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.404195.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.end_per_group.476098.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.404611.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.end_per_group.476098.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.404611.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.end_per_group.476258.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.404803.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.end_per_group.476258.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.404803.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.422212.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.422212.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.init_per_group.476130.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.426917.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.init_per_group.476130.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.426917.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.init_per_group.476290.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.493442.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.init_per_group.476290.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.493442.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.init_per_group.498467.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.493474.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.init_per_group.498467.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.493474.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.493570.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.493570.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.property_escape_all.395492.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.493698.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.property_escape_all.395492.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.493698.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.property_float_roundtrip.498723.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.493794.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.property_float_roundtrip.498723.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.493794.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.property_integer_roundtrip.498691.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.493922.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.property_integer_roundtrip.498691.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.493922.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.property_object_roundtrip.498755.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.494050.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.property_object_roundtrip.498755.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.494050.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.property_string_roundtrip.395460.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.property_string_roundtrip.395460.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_decode_api.498627.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.enumerate.405027.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_decode_api.498627.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.enumerate.405027.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_decode_api_stream.395428.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.error_info.405059.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_decode_api_stream.395428.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.error_info.405059.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_decode_arrays.498659.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.filter_partition.427269.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_decode_arrays.498659.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.filter_partition.427269.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_decode_atoms.498499.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.flatten_1.493858.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_decode_atoms.498499.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.flatten_1.493858.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_decode_numbers.498531.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.flatten_1_e.426821.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_decode_numbers.498531.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.flatten_1_e.426821.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_decode_objects.498595.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.flatten_2.426853.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_decode_objects.498595.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.flatten_2.426853.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_decode_strings.498563.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.flatten_2_e.426885.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_decode_strings.498563.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.flatten_2_e.426885.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_decode_whitespace.395396.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.hof.427397.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_decode_whitespace.395396.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.hof.427397.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_encode_atom.475938.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.403523.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_encode_atom.475938.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.403523.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_encode_binary.475970.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.403779.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_encode_binary.475970.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.403779.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_encode_escape_all.476066.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.404227.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_encode_escape_all.476066.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.404227.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_encode_float.498371.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.404835.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_encode_float.498371.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.404835.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_encode_integer.476002.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.422020.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_encode_integer.476002.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.422020.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_encode_list.476034.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.422244.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_encode_list.476034.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.422244.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_encode_map.498403.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.426949.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_encode_map.498403.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.426949.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_encode_proplist.498435.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.493506.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_encode_proplist.498435.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.493506.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_format_fun.476226.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.493602.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_format_fun.476226.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.493602.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_format_list.476162.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.493730.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_format_list.476162.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.493730.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_format_map.476194.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.493826.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_format_map.476194.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.493826.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_json_test_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.493954.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/json_suite.test_json_test_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.493954.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.all_false_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.all_false_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.all_true_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.all_true_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.any_false_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.join.427365.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.any_false_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.join.427365.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.any_true_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keymember.403555.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.any_true_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keymember.403555.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.append_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keymerge.404259.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.append_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keymerge.404259.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.append_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keyreplace.493410.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.append_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keyreplace.493410.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.concat_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keysearch_keyfind.493314.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.concat_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keysearch_keyfind.493314.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.delete_absent_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keysort_1.404291.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.delete_absent_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keysort_1.404291.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.delete_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keysort_error.404419.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.delete_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keysort_error.404419.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.droplast_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keysort_i.404387.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.droplast_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keysort_i.404387.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.dropwhile_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keysort_rand.404355.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.dropwhile_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keysort_rand.404355.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.duplicate_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keystore.493346.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.duplicate_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keystore.493346.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keytake.493378.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.keytake.493378.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.enumerate_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.member.404899.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.enumerate_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.member.404899.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.enumerate_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.merge.403587.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.enumerate_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.merge.403587.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.enumerate_3_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.otp_5939.493986.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.enumerate_3_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.otp_5939.493986.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.filter_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.otp_6023.427141.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.filter_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.otp_6023.427141.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.filtermap_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.otp_6606.427109.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.filtermap_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.otp_6606.427109.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.flatlength_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.otp_7230.494018.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.flatlength_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.otp_7230.494018.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.flatmap_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.reverse.404867.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.flatmap_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.reverse.404867.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.flatten_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.rkeymerge.404323.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.flatten_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.rkeymerge.404323.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.flatten_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.rmerge.422052.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.flatten_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.rmerge.422052.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.foldl_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.rukeymerge.426341.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.foldl_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.rukeymerge.426341.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.foldr_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.rumerge.403843.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.foldr_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.rumerge.403843.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.foreach_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.search.404995.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.foreach_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.search.404995.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.seq_2.427013.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.seq_2.427013.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.join_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.seq_2_e.493890.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.join_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.seq_2_e.493890.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keydelete_absent_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.seq_3.427045.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keydelete_absent_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.seq_3.427045.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keydelete_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.seq_3_e.427077.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keydelete_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.seq_3_e.427077.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keyfind_absent_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.seq_loop.426981.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keyfind_absent_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.seq_loop.426981.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keyfind_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.sort_1.422084.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keyfind_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.sort_1.422084.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keymap_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.sort_rand.403619.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keymap_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.sort_rand.403619.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keymember_absent_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keymember_absent_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keymember_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.sublist_2.493762.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keymember_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.sublist_2.493762.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keymerge_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.sublist_2_e.426725.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keymerge_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.sublist_2_e.426725.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keymerge_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.sublist_3.426757.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keymerge_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.sublist_3.426757.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keyreplace_absent_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.sublist_3_e.426789.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keyreplace_absent_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.sublist_3_e.426789.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keyreplace_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.subtract.427333.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keyreplace_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.subtract.427333.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keysearch_absent_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.suffix.427301.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keysearch_absent_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.suffix.427301.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keysearch_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.takewhile.427237.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keysearch_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.takewhile.427237.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keysort_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.ukeymerge.426309.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keysort_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.ukeymerge.426309.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keystore_absent_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.ukeysort_1.426373.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keystore_absent_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.ukeysort_1.426373.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keystore_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.ukeysort_error.493538.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keystore_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.ukeysort_error.493538.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keytake_absent_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.ukeysort_i.426437.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keytake_absent_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.ukeysort_i.426437.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keytake_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.ukeysort_rand.426405.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.keytake_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.ukeysort_rand.426405.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.last_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.umerge.403811.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.last_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.umerge.403811.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.map_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.uniq_1.493634.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.map_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.uniq_1.493634.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.mapfoldl_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.uniq_2.493666.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.mapfoldl_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.uniq_2.493666.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.mapfoldr_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.usort_1.403875.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.mapfoldr_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.usort_1.403875.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.max_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.usort_rand.403907.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.max_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.usort_rand.403907.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.member_absent_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zip3_fail.422436.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.member_absent_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zip3_fail.422436.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.member_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zip3_pad.422500.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.member_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zip3_pad.422500.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.merge3_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zip3_trim.422468.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.merge3_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zip3_trim.422468.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.merge3_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zip_fail.427205.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.merge3_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zip_fail.427205.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.merge_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zip_pad.422404.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.merge_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zip_pad.422404.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.merge_1_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zip_trim.422372.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.merge_1_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zip_trim.422372.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.merge_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zip_unzip.422276.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.merge_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zip_unzip.422276.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.merge_2_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zip_unzip3.422308.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.merge_2_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zip_unzip3.422308.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.merge_3_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zipwith.427173.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.merge_3_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zipwith.427173.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.merge_3_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zipwith3.422340.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.merge_3_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zipwith3.422340.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.min_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zipwith3_fail.404707.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.min_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zipwith3_fail.404707.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.nth_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zipwith3_pad.404739.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.nth_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zipwith3_pad.404739.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.nth_outofrange_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zipwith3_trim.404771.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.nth_outofrange_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zipwith3_trim.404771.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.nthtail_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zipwith_fail.422532.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.nthtail_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zipwith_fail.422532.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.nthtail_outofrange_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zipwith_pad.404675.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.nthtail_outofrange_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zipwith_pad.404675.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.partition_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zipwith_trim.404643.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.partition_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/lists_suite.zipwith_trim.404643.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.prefix_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/log_mf_h_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.prefix_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/log_mf_h_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.reverse_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/log_mf_h_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.reverse_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/log_mf_h_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.reverse_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/log_mf_h_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.reverse_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/log_mf_h_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.search_absent_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/log_mf_h_suite.test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.search_absent_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/log_mf_h_suite.test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.search_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.error_info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.search_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.error_info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.seq2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.seq2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.seq3_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_filter_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.seq3_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_filter_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.sort_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_filtermap_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.sort_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_filtermap_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.sort_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_fold_3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.sort_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_fold_3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.split_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_foreach_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.split_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_foreach_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.split_outofrange_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_from_keys.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.split_outofrange_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_from_keys.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.splitwith_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_from_keys_check_trapping.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.splitwith_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_from_keys_check_trapping.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_from_keys_kill_process.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_from_keys_kill_process.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.sublist_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_from_list_check_trapping.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.sublist_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_from_list_check_trapping.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.sublist_3_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_from_list_kill_process.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.sublist_3_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_from_list_kill_process.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.subtract_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_get_3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.subtract_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_get_3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.suffix_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_groups_from_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.suffix_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_groups_from_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.sum_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_intersect.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.sum_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_intersect.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.takewhile_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_intersect_with.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.takewhile_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_intersect_with.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.ukeymerge_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_iterator_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.ukeymerge_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_iterator_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.ukeymerge_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_iterator_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.ukeymerge_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_iterator_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.ukeysort_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_iterator_valid.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.ukeysort_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_iterator_valid.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.umerge3_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_keys_kill_process.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.umerge3_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_keys_kill_process.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.umerge3_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_keys_trapping.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.umerge3_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_keys_trapping.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.umerge_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_map_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.umerge_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_map_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.umerge_1_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_merge_opt.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.umerge_1_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_merge_opt.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.umerge_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_merge_with.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.umerge_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_merge_with.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.umerge_2_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_put_opt.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.umerge_2_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_put_opt.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.umerge_3_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_size_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.umerge_3_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_size_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.umerge_3_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_update_with_3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.umerge_3_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_update_with_3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.uniq_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_update_with_4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.uniq_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_update_with_4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.uniq_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_values_kill_process.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.uniq_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_values_kill_process.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.unzip3_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_values_trapping.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.unzip3_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_values_trapping.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.unzip_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_with_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.unzip_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_with_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.usort_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_without_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.usort_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/maps_suite.t_without_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.usort_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/math_suite.constants.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.usort_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/math_suite.constants.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.zip3_3_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/math_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.zip3_3_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/math_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.zip3_4_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/math_suite.error_info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.zip3_4_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/math_suite.error_info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.zip_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/math_suite.floor_ceil.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.zip_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/math_suite.floor_ceil.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.zip_3_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/math_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.zip_3_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/math_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.zipwith3_4_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/math_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.zipwith3_4_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/math_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.zipwith3_5_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.action_function.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.zipwith3_5_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.action_function.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.zipwith_3_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.andalso_orelse.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.zipwith_3_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.andalso_orelse.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.zipwith_4_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.autoimported.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_property_test_suite.zipwith_4_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.autoimported.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.append_1.476386.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.basic_dbg.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.append_1.476386.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.basic_dbg.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.append_2.476418.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.basic_ets.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.append_2.476418.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.basic_ets.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.droplast.477634.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.binary_bifs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.droplast.477634.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.binary_bifs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.dropwhile.374757.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.bitsyntax.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.dropwhile.374757.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.bitsyntax.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.374373.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.eep37.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.374373.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.eep37.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.374501.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.374501.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.374629.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.float_1_function.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.374629.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.float_1_function.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.396228.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.from_shell.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.396228.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.from_shell.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.396260.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.396260.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.476962.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.map_expr_in_head.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.476962.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.map_expr_in_head.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.477186.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.map_expr_in_head_from_shell.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.477186.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.map_expr_in_head_from_shell.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.477282.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.map_exprs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.477282.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.map_exprs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.477698.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.map_exprs_from_shell.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.477698.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.map_exprs_from_shell.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.498851.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.map_pattern.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.498851.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.map_pattern.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.499043.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.map_pattern_from_shell.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.499043.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.map_pattern_from_shell.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.499203.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.multipass.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.499203.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.multipass.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.no_warnings.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.no_warnings.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.old_guards.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.old_guards.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.enumerate.374789.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.otp_14454.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.enumerate.374789.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.otp_14454.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.error_info.396836.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.otp_16824.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.error_info.396836.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.otp_16824.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.filter_partition.396804.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.record_defaults.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.filter_partition.396804.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.record_defaults.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.flatten_1.477346.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.record_index.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.flatten_1.477346.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.record_index.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.flatten_1_e.477410.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.records.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.flatten_1_e.477410.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.records.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.flatten_2.477378.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.semicolon.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.flatten_2.477378.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.semicolon.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.flatten_2_e.477442.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.flatten_2_e.477442.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.hof.477602.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.top_match.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.hof.477602.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.top_match.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.374405.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.unused_record.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.374405.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.unused_record.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.374661.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.warnings.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.374661.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/ms_transform_suite.warnings.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.396292.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.attached.427525.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.396292.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.attached.427525.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.396484.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.attached.428069.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.396484.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.attached.428069.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.476450.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.attached.428421.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.476450.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.attached.428421.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.476994.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.attached_cntrl_channel_handler_crash.405827.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.476994.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.attached_cntrl_channel_handler_crash.405827.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.477122.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.attached_cntrl_channel_handler_crash.427557.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.477122.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.attached_cntrl_channel_handler_crash.427557.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.477218.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.attached_cntrl_channel_handler_crash.428101.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.477218.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.attached_cntrl_channel_handler_crash.428101.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.477314.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.basic.405667.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.477314.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.basic.405667.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.498883.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.basic.423140.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.498883.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.basic.423140.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.499075.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.cast.405731.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.499075.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.cast.405731.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.499235.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.cast.423204.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.499235.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.cast.423204.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.cntrl_channel_handler_crash.405859.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.cntrl_channel_handler_crash.405859.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.cntrl_channel_handler_crash.422564.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.cntrl_channel_handler_crash.422564.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.join.477570.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.cntrl_channel_handler_crash.428133.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.join.477570.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.cntrl_channel_handler_crash.428133.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keymember.476482.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.cntrl_channel_handler_crash_old_release.405891.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keymember.476482.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.cntrl_channel_handler_crash_old_release.405891.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keymerge.476770.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.cntrl_channel_handler_crash_old_release.422596.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keymerge.476770.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.cntrl_channel_handler_crash_old_release.422596.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keyreplace.498819.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.cntrl_channel_handler_crash_old_release.423300.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keyreplace.498819.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.cntrl_channel_handler_crash_old_release.423300.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keysearch_keyfind.476514.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.detached.423268.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keysearch_keyfind.476514.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.detached.423268.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keysort_1.476802.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.detached.428293.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keysort_1.476802.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.detached.428293.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keysort_error.476898.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.dist.497666.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keysort_error.476898.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.dist.497666.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keysort_i.476930.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.dist_io_redirect.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keysort_i.476930.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.dist_io_redirect.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keysort_rand.476866.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.dist_localhost.427461.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keysort_rand.476866.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.dist_localhost.427461.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keystore.476546.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.dist_up_down.497698.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keystore.476546.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.dist_up_down.497698.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keytake.476578.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.duplicate_name.428037.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.keytake.476578.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.duplicate_name.428037.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.member.374725.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.duplicate_name.428389.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.member.374725.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.duplicate_name.428389.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.merge.498915.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.dyn_peer.405763.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.merge.498915.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.dyn_peer.405763.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.otp_5939.374437.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.dyn_peer.423236.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.otp_5939.374437.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.dyn_peer.423236.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.otp_6023.499555.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.end_per_group.405571.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.otp_6023.499555.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.end_per_group.405571.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.otp_6606.374469.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.end_per_group.423972.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.otp_6606.374469.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.end_per_group.423972.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.otp_7230.396452.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.end_per_group.424132.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.otp_7230.396452.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.end_per_group.424132.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.reverse.374693.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.end_per_group.498274.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.reverse.374693.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.end_per_group.498274.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.rkeymerge.476834.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.rkeymerge.476834.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.rmerge.498947.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.rmerge.498947.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.rukeymerge.477058.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.errors.497634.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.rukeymerge.477058.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.errors.497634.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.rumerge.476738.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.init_debug.405635.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.rumerge.476738.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.init_debug.405635.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.search.477666.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.init_per_group.405603.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.search.477666.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.init_per_group.405603.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.seq_2.396356.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.init_per_group.423044.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.seq_2.396356.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.init_per_group.423044.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.seq_2_e.396420.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.init_per_group.423108.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.seq_2_e.396420.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.init_per_group.423108.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.seq_3.396388.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.init_per_group.424004.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.seq_3.396388.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.init_per_group.424004.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.seq_3_e.374341.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.init_per_group.424164.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.seq_3_e.374341.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.init_per_group.424164.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.seq_loop.396324.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.seq_loop.396324.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.sort_1.499011.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.sort_1.499011.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.sort_rand.498979.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.io_redirect.405795.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.sort_rand.498979.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.io_redirect.405795.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.io_redirect.427973.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.io_redirect.427973.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.sublist_2.374245.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.multi_node.428005.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.sublist_2.374245.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.multi_node.428005.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.sublist_2_e.374309.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.multi_node.428357.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.sublist_2_e.374309.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.multi_node.428357.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.sublist_3.374277.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.old_release.424036.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.sublist_3.374277.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.old_release.424036.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.sublist_3_e.477250.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.peer_down_boot.497602.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.sublist_3_e.477250.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.peer_down_boot.497602.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.subtract.477538.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.peer_down_continue.427429.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.subtract.477538.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.peer_down_continue.427429.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.suffix.396772.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.peer_down_crash.497730.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.suffix.396772.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.peer_down_crash.497730.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.takewhile.396740.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.peer_down_crash_tcp.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.takewhile.396740.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.peer_down_crash_tcp.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.ukeymerge.477026.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.peer_states.405699.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.ukeymerge.477026.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.peer_states.405699.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.ukeysort_1.477090.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.peer_states.423172.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.ukeysort_1.477090.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.peer_states.423172.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.ukeysort_error.395940.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.post_process_args.427493.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.ukeysort_error.395940.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.post_process_args.427493.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.ukeysort_i.499523.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_close.405987.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.ukeysort_i.499523.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_close.405987.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.ukeysort_rand.395908.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_close.422628.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.ukeysort_rand.395908.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_close.422628.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.umerge.499107.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_close.428229.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.umerge.499107.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_close.428229.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.uniq_1.374213.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_halt.405923.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.uniq_1.374213.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_halt.405923.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.uniq_2.477154.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_halt.423332.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.uniq_2.477154.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_halt.423332.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.usort_1.499139.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_halt.427589.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.usort_1.499139.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_halt.427589.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.usort_rand.499171.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_halt_timeout.405251.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.usort_rand.499171.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_halt_timeout.405251.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zip3_fail.499619.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_halt_timeout.423588.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zip3_fail.499619.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_halt_timeout.423588.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zip3_pad.374565.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_halt_timeout.427621.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zip3_pad.374565.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_halt_timeout.427621.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zip3_trim.499651.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_stop.423620.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zip3_trim.499651.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_stop.423620.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zip_fail.396612.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_stop.427653.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zip_fail.396612.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_stop.427653.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zip_pad.374533.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_stop.428197.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zip_pad.374533.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_stop.428197.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zip_trim.396644.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_stop_timeout.423652.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zip_trim.396644.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_stop_timeout.423652.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zip_unzip.396516.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_stop_timeout.427685.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zip_unzip.396516.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_stop_timeout.427685.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zip_unzip3.396548.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_stop_timeout.428165.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zip_unzip3.396548.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.shutdown_stop_timeout.428165.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zipwith.396580.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zipwith.396580.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zipwith3.499587.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.stop_peer.427941.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zipwith3.499587.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.stop_peer.427941.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zipwith3_fail.477506.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.stop_peer.428325.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zipwith3_fail.477506.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/peer_suite.stop_peer.428325.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zipwith3_pad.374597.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/pool_suite.basic.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zipwith3_pad.374597.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/pool_suite.basic.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zipwith3_trim.396708.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/pool_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zipwith3_trim.396708.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/pool_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zipwith_fail.396676.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/pool_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zipwith_fail.396676.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/pool_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zipwith_pad.477474.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/pool_suite.link_race.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zipwith_pad.477474.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/pool_suite.link_race.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zipwith_trim.499683.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/pool_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/lists_suite.zipwith_trim.499683.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/pool_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/log_mf_h_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.crash.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/log_mf_h_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.crash.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/log_mf_h_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.end_per_group.424324.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/log_mf_h_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.end_per_group.424324.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/log_mf_h_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/log_mf_h_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/log_mf_h_suite.test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/log_mf_h_suite.test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.error_info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.hibernate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.error_info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.hibernate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.init_dont_hang.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.init_dont_hang.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_filter_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.init_per_group.424292.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_filter_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.init_per_group.424292.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_filtermap_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_filtermap_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_fold_3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_fold_3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_foreach_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.otp_6345.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_foreach_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.otp_6345.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_from_keys.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.report_cb.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_from_keys.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.report_cb.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_from_keys_check_trapping.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.spawn_opt.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_from_keys_check_trapping.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.spawn_opt.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_from_keys_kill_process.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_from_keys_kill_process.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_from_list_check_trapping.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.stacktrace.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_from_list_check_trapping.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.stacktrace.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_from_list_kill_process.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.stop.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_from_list_kill_process.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.stop.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_get_3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.sync_start_link.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_get_3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.sync_start_link.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_groups_from_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.sync_start_link_timeout.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_groups_from_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.sync_start_link_timeout.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_intersect.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.sync_start_monitor.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_intersect.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.sync_start_monitor.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_intersect_with.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.sync_start_monitor_link.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_intersect_with.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.sync_start_monitor_link.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_iterator_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.sync_start_monitor_link_timeout.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_iterator_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.sync_start_monitor_link_timeout.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_iterator_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.sync_start_nolink.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_iterator_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.sync_start_nolink.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_iterator_valid.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.sync_start_timeout.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_iterator_valid.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.sync_start_timeout.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_keys_kill_process.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.t_format.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_keys_kill_process.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.t_format.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_keys_trapping.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.t_format_arbitrary.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_keys_trapping.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proc_lib_suite.t_format_arbitrary.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_map_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proplists_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_map_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proplists_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_merge_opt.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proplists_suite.examples.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_merge_opt.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proplists_suite.examples.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_merge_with.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proplists_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_merge_with.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proplists_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_put_opt.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proplists_suite.map_conversion.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_put_opt.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proplists_suite.map_conversion.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_size_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proplists_suite.map_conversion_normalize.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_size_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proplists_suite.map_conversion_normalize.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_update_with_3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proplists_suite.pm_fold_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_update_with_3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proplists_suite.pm_fold_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_update_with_4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proplists_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_update_with_4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/proplists_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_values_kill_process.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.append.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_values_kill_process.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.append.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_values_trapping.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.backward.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_values_trapping.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.backward.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_with_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.badarg.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_with_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.badarg.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_without_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.cache.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/maps_suite.t_without_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.cache.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/math_suite.constants.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.cache_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/math_suite.constants.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.cache_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/math_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.cursor.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/math_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.cursor.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/math_suite.error_info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.dets.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/math_suite.error_info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.dets.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/math_suite.floor_ceil.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.eep37.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/math_suite.floor_ceil.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.eep37.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/math_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.end_per_group.407043.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/math_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.end_per_group.407043.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/math_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.end_per_group.425124.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/math_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.end_per_group.425124.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.action_function.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.end_per_group.425188.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.action_function.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.end_per_group.425188.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.andalso_orelse.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.end_per_group.425508.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.andalso_orelse.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.end_per_group.425508.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.autoimported.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.end_per_group.499938.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.autoimported.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.end_per_group.499938.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.basic_dbg.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.basic_dbg.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.basic_ets.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.basic_ets.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.binary_bifs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.errors.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.binary_bifs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.errors.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.bitsyntax.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.ets.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.bitsyntax.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.ets.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.eep37.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.eval.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.eep37.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.eval.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.eval_cache.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.eval_cache.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.float_1_function.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.eval_unique.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.float_1_function.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.eval_unique.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.from_shell.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.evaluator.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.from_shell.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.evaluator.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.exported_var.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.exported_var.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.map_expr_in_head.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.filesort.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.map_expr_in_head.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.filesort.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.map_expr_in_head_from_shell.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.filter.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.map_expr_in_head_from_shell.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.filter.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.map_exprs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.filter_var.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.map_exprs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.filter_var.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.map_exprs_from_shell.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.fold.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.map_exprs_from_shell.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.fold.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.map_pattern.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.forward.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.map_pattern.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.forward.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.map_pattern_from_shell.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.fun_clauses.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.map_pattern_from_shell.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.fun_clauses.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.multipass.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.generator_vars.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.multipass.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.generator_vars.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.no_warnings.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.indices.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.no_warnings.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.indices.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.old_guards.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.old_guards.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.otp_14454.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.init_per_group.407075.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.otp_14454.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.init_per_group.407075.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.otp_16824.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.init_per_group.424420.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.otp_16824.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.init_per_group.424420.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.record_defaults.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.init_per_group.425156.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.record_defaults.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.init_per_group.425156.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.record_index.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.init_per_group.425220.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.record_index.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.init_per_group.425220.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.records.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.init_per_group.425540.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.records.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.init_per_group.425540.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.semicolon.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.semicolon.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.top_match.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.join_complex.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.top_match.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.join_complex.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.unused_record.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.join_filter.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.unused_record.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.join_filter.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.warnings.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.join_lookup.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/ms_transform_suite.warnings.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.join_lookup.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.attached.375237.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.join_merge.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.attached.375237.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.join_merge.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.attached.396932.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.join_option.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.attached.396932.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.join_option.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.attached.501187.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.join_sort.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.attached.501187.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.join_sort.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.attached_cntrl_channel_handler_crash.397252.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.keysort.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.attached_cntrl_channel_handler_crash.397252.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.keysort.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.attached_cntrl_channel_handler_crash.499843.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.lc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.attached_cntrl_channel_handler_crash.499843.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.lc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.attached_cntrl_channel_handler_crash.501219.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.lookup1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.attached_cntrl_channel_handler_crash.501219.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.lookup1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.basic.481858.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.lookup2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.basic.481858.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.lookup2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.basic.501123.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.lookup_rec.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.basic.501123.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.lookup_rec.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.cast.375461.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.manpage.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.cast.375461.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.manpage.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.cast.481922.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.nested_info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.cast.481922.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.nested_info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.cntrl_channel_handler_crash.375013.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.nested_qlc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.cntrl_channel_handler_crash.375013.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.nested_qlc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.cntrl_channel_handler_crash.397284.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.nomatch.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.cntrl_channel_handler_crash.397284.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.nomatch.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.cntrl_channel_handler_crash.501251.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_11758.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.cntrl_channel_handler_crash.501251.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_11758.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.cntrl_channel_handler_crash_old_release.397316.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_12946.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.cntrl_channel_handler_crash_old_release.397316.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_12946.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.cntrl_channel_handler_crash_old_release.499875.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_5195.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.cntrl_channel_handler_crash_old_release.499875.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_5195.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.cntrl_channel_handler_crash_old_release.501283.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_5644.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.cntrl_channel_handler_crash_old_release.501283.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_5644.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.detached.375557.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_6038_bug.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.detached.375557.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_6038_bug.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.detached.481954.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_6359.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.detached.481954.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_6359.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.dist.374853.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_6562.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.dist.374853.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_6562.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.dist_io_redirect.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_6590.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.dist_io_redirect.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_6590.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.dist_localhost.396900.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_6673.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.dist_localhost.396900.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_6673.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.dist_up_down.374949.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_6674.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.dist_up_down.374949.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_6674.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.duplicate_name.375205.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_6964.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.duplicate_name.375205.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_6964.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.duplicate_name.375589.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_7114.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.duplicate_name.375589.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_7114.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.dyn_peer.375397.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_7232.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.dyn_peer.375397.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_7232.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.dyn_peer.481986.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_7238.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.dyn_peer.481986.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_7238.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.end_per_group.376005.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_7552.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.end_per_group.376005.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_7552.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.end_per_group.376133.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_7714.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.end_per_group.376133.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.otp_7714.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.end_per_group.397220.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.overridden_bif.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.end_per_group.397220.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.overridden_bif.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.end_per_group.501027.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.pattern.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.end_per_group.501027.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.pattern.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.pre_fun.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.pre_fun.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.process_dies.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.process_dies.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.errors.374821.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.single.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.errors.374821.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.single.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.init_debug.501091.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.skip_filters.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.init_debug.501091.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.skip_filters.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.init_per_group.376037.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.sort.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.init_per_group.376037.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.sort.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.init_per_group.376165.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.init_per_group.376165.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.init_per_group.397188.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.string_to_handle.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.init_per_group.397188.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.string_to_handle.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.init_per_group.481826.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.table.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.init_per_group.481826.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.table.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.init_per_group.501059.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.unused_var.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.init_per_group.501059.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/qlc_suite.unused_var.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.all_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.all_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.all_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.all_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.io_redirect.375141.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.any_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.io_redirect.375141.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.any_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.io_redirect.375525.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.any_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.io_redirect.375525.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.any_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.multi_node.375173.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.cons_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.multi_node.375173.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.cons_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.multi_node.375493.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.cons_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.multi_node.375493.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.cons_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.old_release.376069.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.daeh_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.old_release.376069.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.daeh_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.peer_down_boot.374981.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.daeh_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.peer_down_boot.374981.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.daeh_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.peer_down_continue.374917.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.delete_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.peer_down_continue.374917.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.delete_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.peer_down_crash.374885.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.delete_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.peer_down_crash.374885.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.delete_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.peer_down_crash_tcp.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.delete_r_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.peer_down_crash_tcp.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.delete_r_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.peer_states.481890.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.delete_r_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.peer_states.481890.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.delete_r_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.peer_states.501155.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.delete_with_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.peer_states.501155.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.delete_with_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.post_process_args.499811.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.delete_with_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.post_process_args.499811.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.delete_with_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_close.375685.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.delete_with_r_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_close.375685.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.delete_with_r_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_close.499939.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.delete_with_r_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_close.499939.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.delete_with_r_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_close.500515.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.drop_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_close.500515.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.drop_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_halt.375621.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.drop_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_halt.375621.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.drop_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_halt.396964.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.drop_r_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_halt.396964.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.drop_r_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_halt.500387.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.drop_r_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_halt.500387.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.drop_r_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_halt_timeout.396996.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_halt_timeout.396996.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_halt_timeout.482146.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.filter_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_halt_timeout.482146.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.filter_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_halt_timeout.500419.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.filter_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_halt_timeout.500419.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.filter_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_stop.397028.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.filtermap_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_stop.397028.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.filtermap_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_stop.482178.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.filtermap_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_stop.482178.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.filtermap_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_stop.500451.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.fold_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_stop.500451.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.fold_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_stop_timeout.375653.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.fold_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_stop_timeout.375653.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.fold_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_stop_timeout.499907.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.from_list_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_stop_timeout.499907.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.from_list_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_stop_timeout.500483.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.get_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.shutdown_stop_timeout.500483.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.get_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.get_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.get_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.stop_peer.375429.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.get_r_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.stop_peer.375429.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.get_r_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.stop_peer.482018.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.get_r_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/peer_suite.stop_peer.482018.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.get_r_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/pool_suite.basic.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.head_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/pool_suite.basic.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.head_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/pool_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.head_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/pool_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.head_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/pool_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.in_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/pool_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.in_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/pool_suite.link_race.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.in_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/pool_suite.link_race.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.in_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/pool_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.in_r_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/pool_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.in_r_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.crash.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.in_r_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.crash.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.in_r_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.end_per_group.482402.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.init_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.end_per_group.482402.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.init_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.init_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.init_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.hibernate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.is_empty_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.hibernate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.is_empty_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.init_dont_hang.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.is_empty_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.init_dont_hang.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.is_empty_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.init_per_group.482370.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.is_queue_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.init_per_group.482370.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.is_queue_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.join_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.join_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.join_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.join_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.otp_6345.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.last_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.otp_6345.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.last_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.report_cb.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.last_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.report_cb.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.last_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.spawn_opt.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.len_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.spawn_opt.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.len_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.len_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.len_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.stacktrace.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.liat_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.stacktrace.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.liat_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.stop.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.liat_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.stop.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.liat_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.sync_start_link.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.list_conversion_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.sync_start_link.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.list_conversion_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.sync_start_link_timeout.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.member_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.sync_start_link_timeout.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.member_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.sync_start_monitor.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.member_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.sync_start_monitor.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.member_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.sync_start_monitor_link.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.new_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.sync_start_monitor_link.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.new_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.sync_start_monitor_link_timeout.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.ops_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.sync_start_monitor_link_timeout.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.ops_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.sync_start_nolink.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.out_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.sync_start_nolink.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.out_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.sync_start_timeout.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.out_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.sync_start_timeout.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.out_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.t_format.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.out_r_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.t_format.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.out_r_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.t_format_arbitrary.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.out_r_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proc_lib_suite.t_format_arbitrary.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.out_r_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proplists_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.peek_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proplists_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.peek_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proplists_suite.examples.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.peek_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proplists_suite.examples.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.peek_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proplists_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.peek_r_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proplists_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.peek_r_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proplists_suite.map_conversion.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.peek_r_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proplists_suite.map_conversion.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.peek_r_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proplists_suite.map_conversion_normalize.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.reverse_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proplists_suite.map_conversion_normalize.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.reverse_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proplists_suite.pm_fold_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.reverse_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proplists_suite.pm_fold_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.reverse_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proplists_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.snoc_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/proplists_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.snoc_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.append.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.snoc_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.append.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.snoc_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.backward.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.split_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.backward.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.split_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.badarg.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.split_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.badarg.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.split_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.cache.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.cache.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.cache_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.tail_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.cache_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.tail_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.cursor.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.tail_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.cursor.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.tail_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.dets.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.to_list_invalid_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.dets.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_property_test_suite.to_list_invalid_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.eep37.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.do.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.eep37.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.do.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.end_per_group.398148.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.end_per_group.398148.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.end_per_group.483586.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.error.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.end_per_group.483586.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.error.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.end_per_group.501987.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.end_per_group.501987.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.end_per_group.502531.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.io_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.end_per_group.502531.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.io_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.end_per_group.502563.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.oops.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.end_per_group.502563.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.oops.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.op_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.op_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.errors.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.to_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.errors.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/queue_suite.to_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.ets.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.api_eq.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.ets.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.api_eq.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.eval.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.basic_stats_bytes.504674.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.eval.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.basic_stats_bytes.504674.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.eval_cache.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.basic_stats_standard_normal.504706.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.eval_cache.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.basic_stats_standard_normal.504706.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.eval_unique.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.basic_stats_uniform_1.407459.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.eval_unique.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.basic_stats_uniform_1.407459.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.evaluator.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.basic_stats_uniform_2.504642.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.evaluator.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.basic_stats_uniform_2.504642.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.exported_var.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.bytes_count.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.exported_var.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.bytes_count.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.filesort.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.exsp_jump_api.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.filesort.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.exsp_jump_api.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.filter.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.exsp_next_api.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.filter.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.exsp_next_api.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.filter_var.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.interval_float.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.filter_var.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.interval_float.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.fold.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.interval_int.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.fold.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.interval_int.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.forward.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.measure.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.forward.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.measure.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.fun_clauses.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.mwc59_api.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.fun_clauses.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.mwc59_api.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.generator_vars.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.plugin.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.generator_vars.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.plugin.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.indices.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.reference.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.indices.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.reference.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.reference_jump_procdict.19710370.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.reference_jump_procdict.19710370.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.init_per_group.483522.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.reference_jump_state.19710338.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.init_per_group.483522.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.reference_jump_state.19710338.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.init_per_group.483618.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.seed.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.init_per_group.483618.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.seed.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.init_per_group.484034.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.short_jump.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.init_per_group.484034.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.short_jump.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.init_per_group.501571.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.splitmix64_next_api.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.init_per_group.501571.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.splitmix64_next_api.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.init_per_group.502019.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.init_per_group.502019.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.stats_standard_normal.505090.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.stats_standard_normal.505090.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.stats_standard_normal_box_muller.505026.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.stats_standard_normal_box_muller.505026.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.join_complex.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.stats_standard_normal_box_muller_2.505058.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.join_complex.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.stats_standard_normal_box_muller_2.505058.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.join_filter.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.uniform_real_conv.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.join_filter.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/rand_suite.uniform_real_conv.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.join_lookup.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/random_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.join_lookup.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/random_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.join_merge.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/random_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.join_merge.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/random_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.join_option.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/random_suite.interval_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.join_option.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/random_suite.interval_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.join_sort.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/random_suite.seed.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.join_sort.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/random_suite.seed.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.keysort.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/random_suite.seed0.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.keysort.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/random_suite.seed0.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.lc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/random_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.lc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/random_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.lookup1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.bad_utf8_subject.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.lookup1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.bad_utf8_subject.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.lookup2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.combined_options.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.lookup2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.combined_options.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.lookup_rec.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.compile_options.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.lookup_rec.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.compile_options.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.manpage.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.manpage.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.nested_info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.error_handling.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.nested_info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.error_handling.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.nested_qlc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.error_info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.nested_qlc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.error_info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.nomatch.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.global_capture.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.nomatch.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.global_capture.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_11758.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.global_unicode_validation.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_11758.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.global_unicode_validation.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_12946.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_12946.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_5195.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.inspect.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_5195.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.inspect.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_5644.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.match_limit.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_5644.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.match_limit.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_6038_bug.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.opt_all_names.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_6038_bug.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.opt_all_names.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_6359.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.opt_dupnames.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_6359.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.opt_dupnames.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_6562.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.opt_never_utf.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_6562.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.opt_never_utf.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_6590.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.opt_no_start_optimize.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_6590.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.opt_no_start_optimize.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_6673.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.opt_ucp.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_6673.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.opt_ucp.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_6674.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.pcre.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_6674.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.pcre.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_6964.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.pcre_compile_workspace_overflow.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_6964.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.pcre_compile_workspace_overflow.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_7114.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.pcre_cve_2008_2371.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_7114.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.pcre_cve_2008_2371.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_7232.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.re_backwards_accented.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_7232.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.re_backwards_accented.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_7238.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.re_infinite_loop.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_7238.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.re_infinite_loop.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_7552.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.re_version.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_7552.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.re_version.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_7714.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.replace_autogen.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.otp_7714.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.replace_autogen.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.overridden_bif.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.replace_input_types.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.overridden_bif.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.replace_input_types.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.pattern.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.replace_return.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.pattern.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.replace_return.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.pre_fun.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.replace_with_fun.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.pre_fun.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.replace_with_fun.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.process_dies.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.run_options.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.process_dies.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.run_options.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.single.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.split_autogen.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.single.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.split_autogen.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.skip_filters.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.split_options.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.skip_filters.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.split_options.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.sort.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.split_specials.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.sort.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.split_specials.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.string_to_handle.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.sub_binaries.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.string_to_handle.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.sub_binaries.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.table.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.yield_on_subject_validation.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.table.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/re_suite.yield_on_subject_validation.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.unused_var.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/select_suite.return_values.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/qlc_suite.unused_var.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/select_suite.return_values.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.all_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/select_suite.select_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.all_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/select_suite.select_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.all_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/select_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.all_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/select_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.any_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.add_element_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.any_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.add_element_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.any_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.del_element_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.any_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.del_element_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.cons_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.cons_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.cons_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.filter_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.cons_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.filter_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.daeh_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.filtermap_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.daeh_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.filtermap_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.daeh_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.fold_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.daeh_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.fold_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.delete_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.from_list_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.delete_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.from_list_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.delete_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.delete_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.delete_r_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.intersection_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.delete_r_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.intersection_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.delete_r_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.intersection_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.delete_r_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.intersection_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.delete_with_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.is_disjoint_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.delete_with_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.is_disjoint_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.delete_with_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.is_element_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.delete_with_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.is_element_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.delete_with_r_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.is_empty_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.delete_with_r_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.is_empty_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.delete_with_r_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.is_equal_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.delete_with_r_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.is_equal_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.drop_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.is_set_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.drop_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.is_set_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.drop_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.is_subset_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.drop_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.is_subset_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.drop_r_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.map_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.drop_r_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.map_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.drop_r_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.operations_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.drop_r_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.operations_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.size_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.size_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.filter_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.filter_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.filter_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.subtract_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.filter_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.subtract_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.filtermap_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.to_list_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.filtermap_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.to_list_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.filtermap_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.union_1_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.filtermap_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.union_1_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.fold_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.union_2_case.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.fold_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_property_test_suite.union_2_case.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.fold_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.add_element.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.fold_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.add_element.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.from_list_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.create.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.from_list_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.create.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.get_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.del_element.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.get_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.del_element.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.get_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.get_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.get_r_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.filter.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.get_r_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.filter.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.get_r_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.filtermap.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.get_r_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.filtermap.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.head_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.fold.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.head_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.fold.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.head_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.head_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.in_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.intersection.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.in_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.intersection.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.in_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.is_disjoint.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.in_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.is_disjoint.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.in_r_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.is_empty.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.in_r_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.is_empty.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.in_r_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.is_equal.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.in_r_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.is_equal.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.init_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.is_set.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.init_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.is_set.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.init_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.is_subset.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.init_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.is_subset.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.iterate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.iterate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.is_empty_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.map.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.is_empty_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.map.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.is_empty_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.is_empty_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.is_queue_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.subtract.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.is_queue_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.subtract.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.join_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.take_largest.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.join_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.take_largest.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.join_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.take_smallest.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.join_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.take_smallest.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.last_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.union.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.last_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sets_suite.union.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.last_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.after_paragraph_comment.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.last_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.after_paragraph_comment.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.len_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.begin_comment_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.len_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.begin_comment_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.len_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.bullet_list_mix_with_number_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.len_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.bullet_list_mix_with_number_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.liat_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.bullet_list_with_anchor.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.liat_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.bullet_list_with_anchor.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.liat_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.complex_inline_format.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.liat_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.complex_inline_format.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.list_conversion_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.complex_nested_bullet_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.list_conversion_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.complex_nested_bullet_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.member_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.complex_nested_bullet_list2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.member_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.complex_nested_bullet_list2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.member_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.complex_nested_bullet_list3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.member_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.complex_nested_bullet_list3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.new_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.convert_erlang_html.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.new_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.convert_erlang_html.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.ops_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.convert_unknown_format.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.ops_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.convert_unknown_format.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.out_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.double_char_for_quote_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.out_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.double_char_for_quote_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.out_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19714690.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.out_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19714690.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.out_r_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19714754.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.out_r_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19714754.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.out_r_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19714818.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.out_r_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19714818.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.peek_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19714882.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.peek_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19714882.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.peek_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19714946.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.peek_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19714946.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.peek_r_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19715010.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.peek_r_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19715010.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.peek_r_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19715074.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.peek_r_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19715074.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.reverse_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19715138.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.reverse_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19715138.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.reverse_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19715202.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.reverse_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19715202.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.snoc_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19715266.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.snoc_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19715266.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.snoc_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19715330.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.snoc_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19715330.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.split_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19715394.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.split_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19715394.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.split_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19715458.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.split_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.19715458.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.tail_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.ending_br_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.tail_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.ending_br_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.tail_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.escaped_character.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.tail_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.escaped_character.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.to_list_invalid_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.even_nested_bullet_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_property_test_suite.to_list_invalid_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.even_nested_bullet_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.do.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.even_nested_numbered_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.do.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.even_nested_numbered_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.existing_doc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.existing_doc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.error.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.existing_moduledoc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.error.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.existing_moduledoc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.fake_table_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.fake_table_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.io_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.fence_code_ignores_link_format_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.io_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.fence_code_ignores_link_format_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.oops.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.fence_code_with_spaces.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.oops.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.fence_code_with_spaces.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.op_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.fence_code_with_tabs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.op_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.fence_code_with_tabs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.forget_closing_comment.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.forget_closing_comment.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.to_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_header_identifier.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/queue_suite.to_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_header_identifier.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.api_eq.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_heading_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.api_eq.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_heading_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.basic_stats_bytes.488706.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_inline_link_with_inline.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.basic_stats_bytes.488706.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_inline_link_with_inline.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.basic_stats_standard_normal.502691.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_multiple_inline.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.basic_stats_standard_normal.502691.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_multiple_inline.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.basic_stats_uniform_1.488674.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_multiple_inline_format_long.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.basic_stats_uniform_1.488674.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_multiple_inline_format_long.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.basic_stats_uniform_2.488738.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_multiple_inline_format_mixed.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.basic_stats_uniform_2.488738.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_multiple_inline_format_mixed.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.bytes_count.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_multiple_inline_format_short.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.bytes_count.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_multiple_inline_format_short.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.exsp_jump_api.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_paragraph_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.exsp_jump_api.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_paragraph_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.exsp_next_api.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_separator_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.exsp_next_api.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.format_separator_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.interval_float.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.h1_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.interval_float.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.h1_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.interval_int.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.h2_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.interval_int.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.h2_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.measure.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.h3_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.measure.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.h3_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.mwc59_api.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.h4_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.mwc59_api.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.h4_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.plugin.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.h5_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.plugin.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.h5_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.reference.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.h6_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.reference.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.h6_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.reference_jump_procdict.19694210.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.hidden_doc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.reference_jump_procdict.19694210.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.hidden_doc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.reference_jump_state.19694178.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.hidden_moduledoc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.reference_jump_state.19694178.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.hidden_moduledoc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.seed.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.ignore_three_spaces_before_quote.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.seed.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.ignore_three_spaces_before_quote.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.short_jump.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19714658.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.short_jump.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19714658.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.splitmix64_next_api.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19714722.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.splitmix64_next_api.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19714722.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19714786.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19714786.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.stats_standard_normal.503171.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19714850.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.stats_standard_normal.503171.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19714850.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.stats_standard_normal_box_muller.503107.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19714914.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.stats_standard_normal_box_muller.503107.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19714914.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.stats_standard_normal_box_muller_2.503139.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19714978.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.stats_standard_normal_box_muller_2.503139.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19714978.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.uniform_real_conv.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19715042.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/rand_suite.uniform_real_conv.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19715042.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/random_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19715106.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/random_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19715106.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/random_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19715170.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/random_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19715170.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/random_suite.interval_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19715234.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/random_suite.interval_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19715234.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/random_suite.seed.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19715298.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/random_suite.seed.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19715298.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/random_suite.seed0.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19715362.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/random_suite.seed0.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19715362.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/random_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19715426.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/random_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.19715426.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.bad_utf8_subject.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.bad_utf8_subject.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.combined_options.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.inline_code_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.combined_options.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.inline_code_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.compile_options.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.inline_mfa_link.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.compile_options.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.inline_mfa_link.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.italic_in_middle_word_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.italic_in_middle_word_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.error_handling.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.italic_with_colons.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.error_handling.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.italic_with_colons.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.error_info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.list_format_with_bold_in_sentence.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.error_info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.list_format_with_bold_in_sentence.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.global_capture.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.list_format_with_italics_in_sentence.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.global_capture.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.list_format_with_italics_in_sentence.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.global_unicode_validation.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.list_with_format.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.global_unicode_validation.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.list_with_format.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multi_word_format_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multi_word_format_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.inspect.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiline_bullet_indented_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.inspect.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiline_bullet_indented_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.match_limit.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiline_bullet_indented_list2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.match_limit.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiline_bullet_indented_list2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.opt_all_names.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiline_bullet_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.opt_all_names.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiline_bullet_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.opt_dupnames.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiline_link.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.opt_dupnames.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiline_link.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.opt_never_utf.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiline_link_not_allowed.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.opt_never_utf.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiline_link_not_allowed.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.opt_no_start_optimize.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiline_numbered_indented_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.opt_no_start_optimize.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiline_numbered_indented_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.opt_ucp.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiline_numbered_indented_list2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.opt_ucp.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiline_numbered_indented_list2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.pcre.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiline_numbered_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.pcre.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiline_numbered_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.pcre_compile_workspace_overflow.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiple_br_followed_by_paragraph_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.pcre_compile_workspace_overflow.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiple_br_followed_by_paragraph_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.pcre_cve_2008_2371.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiple_line_code_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.pcre_cve_2008_2371.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiple_line_code_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.re_backwards_accented.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiple_line_fence_code_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.re_backwards_accented.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiple_line_fence_code_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.re_infinite_loop.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiple_line_quote_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.re_infinite_loop.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiple_line_quote_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.re_version.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiple_lines_of_a_paragraph_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.re_version.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.multiple_lines_of_a_paragraph_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.replace_autogen.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.new_lines_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.replace_autogen.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.new_lines_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.replace_input_types.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.non_existing_doc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.replace_input_types.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.non_existing_doc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.replace_return.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.non_existing_moduledoc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.replace_return.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.non_existing_moduledoc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.replace_with_fun.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.odd_nested_bullet_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.replace_with_fun.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.odd_nested_bullet_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.run_options.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.odd_nested_numbered_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.run_options.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.odd_nested_numbered_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.split_autogen.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.paragraph_after_heading_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.split_autogen.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.paragraph_after_heading_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.split_options.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.paragraph_between_code_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.split_options.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.paragraph_between_code_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.split_specials.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.paragraph_between_fence_code_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.split_specials.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.paragraph_between_fence_code_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.paragraph_in_between_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.paragraph_in_between_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.sub_binaries.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.parens_with_italics.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.sub_binaries.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.parens_with_italics.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.yield_on_subject_validation.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.quote_before_and_after_paragraph_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/re_suite.yield_on_subject_validation.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.quote_before_and_after_paragraph_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/select_suite.return_values.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.quote_with_anchor_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/select_suite.return_values.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.quote_with_anchor_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/select_suite.select_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.quote_without_space.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/select_suite.select_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.quote_without_space.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/select_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.setext_h1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/select_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.setext_h1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.add_element_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.setext_h2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.add_element_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.setext_h2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.del_element_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.single_line_code_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.del_element_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.single_line_code_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.single_line_fence_code_no_language_spaces_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.single_line_fence_code_no_language_spaces_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.filter_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.single_line_fence_code_no_language_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.filter_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.single_line_fence_code_no_language_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.filtermap_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.single_line_fence_code_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.filtermap_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.single_line_fence_code_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.fold_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.single_line_quote_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.fold_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.single_line_quote_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.from_list_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_bullet_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.from_list_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_bullet_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_bullet_list_followed_inner_paragraph.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_bullet_list_followed_inner_paragraph.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.intersection_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_bullet_list_followed_inner_paragraph2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.intersection_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_bullet_list_followed_inner_paragraph2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.intersection_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_bullet_list_followed_inner_paragraph3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.intersection_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_bullet_list_followed_inner_paragraph3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.is_disjoint_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_bullet_list_followed_new_paragraph.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.is_disjoint_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_bullet_list_followed_new_paragraph.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.is_element_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_bullet_list_with_format.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.is_element_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_bullet_list_with_format.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.is_empty_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_numbered_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.is_empty_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_numbered_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.is_equal_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_numbered_list_followed_inner_paragraph.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.is_equal_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_numbered_list_followed_inner_paragraph.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.is_set_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_numbered_list_followed_inner_paragraph2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.is_set_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_numbered_list_followed_inner_paragraph2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.is_subset_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_numbered_list_followed_new_paragraph.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.is_subset_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_numbered_list_followed_new_paragraph.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.map_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_numbered_list_with_format.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.map_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.singleton_numbered_list_with_format.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.operations_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.skip_symbols_in_inline.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.operations_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.skip_symbols_in_inline.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.size_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.size_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.start_with_br_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.start_with_br_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.subtract_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.table_with_escaped_bars.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.subtract_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.table_with_escaped_bars.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.to_list_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.table_with_rows.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.to_list_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.table_with_rows.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.union_1_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.unmatched_complex_format_with_inline.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.union_1_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.unmatched_complex_format_with_inline.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.union_2_case.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.unmatched_format_simple.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_property_test_suite.union_2_case.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.unmatched_format_simple.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.add_element.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.unmatched_format_with_inline.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.add_element.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_markdown_suite.unmatched_format_with_inline.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.create.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.ansi.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.create.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.ansi.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.del_element.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.columns.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.del_element.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.columns.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.filter.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.filter.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.filtermap.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.filtermap.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.fold.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.fold.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.links.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.links.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.intersection.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.normalize.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.intersection.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.normalize.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.is_disjoint.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.render.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.is_disjoint.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.render.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.is_empty.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.render_non_native.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.is_empty.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.render_non_native.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.is_equal.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.render_prop.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.is_equal.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.render_prop.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.is_set.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.render_smoke.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.is_set.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.render_smoke.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.is_subset.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.is_subset.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_docs_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.iterate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.bs_construct_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.iterate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.bs_construct_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.map.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.bs_match_bin_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.map.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.bs_match_bin_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.bs_match_misc_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.bs_match_misc_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.subtract.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.bs_match_tail_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.subtract.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.bs_match_tail_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.take_largest.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.end_per_group.19713922.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.take_largest.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.end_per_group.19713922.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.take_smallest.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.end_per_group.19713986.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.take_smallest.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.end_per_group.19713986.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.union.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.end_per_group.19714178.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sets_suite.union.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.end_per_group.19714178.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.after_paragraph_comment.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.end_per_group.407971.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.after_paragraph_comment.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.end_per_group.407971.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.begin_comment_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.end_per_group.408035.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.begin_comment_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.end_per_group.408035.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.bullet_list_mix_with_number_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.end_per_group.425892.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.bullet_list_mix_with_number_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.end_per_group.425892.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.bullet_list_with_anchor.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.bullet_list_with_anchor.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.complex_inline_format.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.complex_inline_format.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.complex_nested_bullet_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.forget.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.complex_nested_bullet_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.forget.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.complex_nested_bullet_list2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.init_per_group.19713890.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.complex_nested_bullet_list2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.init_per_group.19713890.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.complex_nested_bullet_list3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.init_per_group.19713954.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.complex_nested_bullet_list3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.init_per_group.19713954.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.convert_erlang_html.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.init_per_group.19714018.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.convert_erlang_html.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.init_per_group.19714018.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.convert_unknown_format.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.init_per_group.19714210.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.convert_unknown_format.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.init_per_group.19714210.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.double_char_for_quote_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.init_per_group.408003.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.double_char_for_quote_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.init_per_group.408003.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698114.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.init_per_group.408067.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698114.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.init_per_group.408067.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698178.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698178.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698242.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698242.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698306.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.known_bugs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698306.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.known_bugs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698370.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.local_definitions_save_to_module_and_forget.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698370.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.local_definitions_save_to_module_and_forget.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698434.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_10302.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698434.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_10302.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698498.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_13719.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698498.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_13719.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698562.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_14285.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698562.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_14285.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698626.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_14296.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698626.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_14296.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698690.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_5195.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698690.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_5195.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698754.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_5226.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698754.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_5226.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698818.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_5327.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698818.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_5327.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698882.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_5435.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.19698882.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_5435.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_5915.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_5915.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.ending_br_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_5916.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.ending_br_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_5916.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.escaped_character.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_5990.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.escaped_character.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_5990.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.even_nested_bullet_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_6166.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.even_nested_bullet_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_6166.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.even_nested_numbered_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_6554.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.even_nested_numbered_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_6554.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.existing_doc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_7184.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.existing_doc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_7184.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.existing_moduledoc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_7232.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.existing_moduledoc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_7232.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.fake_table_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_8393.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.fake_table_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.otp_8393.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.fence_code_ignores_link_format_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.progex_bit_syntax.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.fence_code_ignores_link_format_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.progex_bit_syntax.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.fence_code_with_spaces.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.progex_funs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.fence_code_with_spaces.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.progex_funs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.fence_code_with_tabs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.progex_lc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.fence_code_with_tabs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.progex_lc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.forget_closing_comment.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.progex_records.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.forget_closing_comment.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.progex_records.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_header_identifier.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.prompt_width.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_header_identifier.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.prompt_width.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_heading_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.records.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_heading_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.records.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_inline_link_with_inline.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.refman_bit_syntax.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_inline_link_with_inline.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.refman_bit_syntax.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_multiple_inline.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.restricted_local.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_multiple_inline.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.restricted_local.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_multiple_inline_format_long.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_multiple_inline_format_long.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_multiple_inline_format_mixed.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.start_interactive.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_multiple_inline_format_mixed.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.start_interactive.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_multiple_inline_format_short.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.start_restricted_from_shell.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_multiple_inline_format_short.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.start_restricted_from_shell.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_paragraph_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.start_restricted_on_command_line.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_paragraph_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.start_restricted_on_command_line.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_separator_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.typed_records.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.format_separator_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.typed_records.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.h1_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.types.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.h1_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.types.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.h2_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.whereis.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.h2_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/shell_suite.whereis.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.h3_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sigils_suite.compiled_sigils.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.h3_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sigils_suite.compiled_sigils.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.h4_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sigils_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.h4_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sigils_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.h5_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sigils_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.h5_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sigils_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.h6_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sigils_suite.parse_sigils.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.h6_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sigils_suite.parse_sigils.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.hidden_doc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sigils_suite.scan_sigils.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.hidden_doc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sigils_suite.scan_sigils.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.hidden_moduledoc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sigils_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.hidden_moduledoc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sigils_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.ignore_three_spaces_before_quote.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/slave_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.ignore_three_spaces_before_quote.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/slave_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698082.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/slave_suite.errors.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698082.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/slave_suite.errors.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698146.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/slave_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698146.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/slave_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698210.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/slave_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698210.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/slave_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698274.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/slave_suite.start_link_nodedown.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698274.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/slave_suite.start_link_nodedown.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698338.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/slave_suite.t_start.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698338.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/slave_suite.t_start.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698402.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/slave_suite.t_start_link.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698402.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/slave_suite.t_start_link.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698466.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.a_function_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698466.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.a_function_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698530.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.canonical.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698530.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.canonical.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698594.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.composite_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698594.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.composite_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698658.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.constant_function.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698658.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.constant_function.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698722.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.converse_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698722.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.converse_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698786.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.difference.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698786.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.difference.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698850.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.digraph.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.19698850.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.digraph.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.domain_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.domain_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.inline_code_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.drestriction.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.inline_code_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.drestriction.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.inline_mfa_link.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.end_per_group.19715906.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.inline_mfa_link.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.end_per_group.19715906.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.italic_in_middle_word_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.italic_in_middle_word_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.italic_with_colons.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.italic_with_colons.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.list_format_with_bold_in_sentence.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.extension.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.list_format_with_bold_in_sentence.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.extension.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.list_format_with_italics_in_sentence.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.list_format_with_italics_in_sentence.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.list_with_format.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_difference.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.list_with_format.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_difference.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multi_word_format_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_domain_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multi_word_format_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_domain_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiline_bullet_indented_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_intersection_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiline_bullet_indented_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_intersection_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiline_bullet_indented_list2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_intersection_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiline_bullet_indented_list2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_intersection_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiline_bullet_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_projection.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiline_bullet_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_projection.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiline_link.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_range_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiline_link.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_range_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiline_link_not_allowed.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_specification.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiline_link_not_allowed.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_specification.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiline_numbered_indented_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_to_relation_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiline_numbered_indented_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_to_relation_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiline_numbered_indented_list2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_union_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiline_numbered_indented_list2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_union_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiline_numbered_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_union_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiline_numbered_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.family_union_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiple_br_followed_by_paragraph_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.from_sets_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiple_br_followed_by_paragraph_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.from_sets_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiple_line_code_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.from_term_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiple_line_code_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.from_term_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiple_line_fence_code_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.image.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiple_line_fence_code_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.image.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiple_line_quote_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.init_per_group.19715874.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiple_line_quote_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.init_per_group.19715874.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiple_lines_of_a_paragraph_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.multiple_lines_of_a_paragraph_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.new_lines_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.new_lines_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.non_existing_doc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.intersection_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.non_existing_doc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.intersection_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.non_existing_moduledoc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.intersection_of_family_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.non_existing_moduledoc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.intersection_of_family_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.odd_nested_bullet_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.inverse_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.odd_nested_bullet_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.inverse_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.odd_nested_numbered_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.inverse_image.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.odd_nested_numbered_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.inverse_image.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.paragraph_after_heading_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.is_a_function_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.paragraph_after_heading_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.is_a_function_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.paragraph_between_code_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.is_disjoint.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.paragraph_between_code_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.is_disjoint.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.paragraph_between_fence_code_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.is_equal.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.paragraph_between_fence_code_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.is_equal.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.paragraph_in_between_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.is_set_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.paragraph_in_between_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.is_set_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.parens_with_italics.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.is_sofs_set_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.parens_with_italics.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.is_sofs_set_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.quote_before_and_after_paragraph_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.is_subset.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.quote_before_and_after_paragraph_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.is_subset.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.quote_with_anchor_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.join.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.quote_with_anchor_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.join.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.quote_without_space.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.misc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.quote_without_space.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.misc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.setext_h1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.multiple_relative_product.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.setext_h1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.multiple_relative_product.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.setext_h2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.no_elements_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.setext_h2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.no_elements_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.single_line_code_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.partition_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.single_line_code_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.partition_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.single_line_fence_code_no_language_spaces_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.partition_3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.single_line_fence_code_no_language_spaces_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.partition_3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.single_line_fence_code_no_language_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.partition_family.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.single_line_fence_code_no_language_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.partition_family.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.single_line_fence_code_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.product_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.single_line_fence_code_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.product_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.single_line_quote_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.projection.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.single_line_quote_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.projection.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_bullet_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.range_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_bullet_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.range_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_bullet_list_followed_inner_paragraph.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.relation_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_bullet_list_followed_inner_paragraph.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.relation_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_bullet_list_followed_inner_paragraph2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.relation_to_family_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_bullet_list_followed_inner_paragraph2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.relation_to_family_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_bullet_list_followed_inner_paragraph3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.relative_product_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_bullet_list_followed_inner_paragraph3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.relative_product_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_bullet_list_followed_new_paragraph.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.relative_product_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_bullet_list_followed_new_paragraph.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.relative_product_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_bullet_list_with_format.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.restriction.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_bullet_list_with_format.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.restriction.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_numbered_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.set_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_numbered_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.set_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_numbered_list_followed_inner_paragraph.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.specification.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_numbered_list_followed_inner_paragraph.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.specification.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_numbered_list_followed_inner_paragraph2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_numbered_list_followed_inner_paragraph2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_numbered_list_followed_new_paragraph.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.strict_relation_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_numbered_list_followed_new_paragraph.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.strict_relation_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_numbered_list_with_format.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.substitution.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.singleton_numbered_list_with_format.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.substitution.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.skip_symbols_in_inline.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.symdiff.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.skip_symbols_in_inline.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.symdiff.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.symmetric_partition.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.symmetric_partition.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.start_with_br_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.to_sets_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.start_with_br_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.to_sets_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.table_with_escaped_bars.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.union_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.table_with_escaped_bars.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.union_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.table_with_rows.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.union_of_family_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.table_with_rows.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.union_of_family_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.unmatched_complex_format_with_inline.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.weak_relation_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.unmatched_complex_format_with_inline.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sofs_suite.weak_relation_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.unmatched_format_simple.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list.19715970.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.unmatched_format_simple.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list.19715970.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.unmatched_format_with_inline.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list.19716098.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_markdown_suite.unmatched_format_with_inline.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list.19716098.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.ansi.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list.19716226.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.ansi.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list.19716226.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.columns.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list.19716354.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.columns.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list.19716354.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list_array.19716002.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list_array.19716002.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list_array.19716130.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list_array.19716130.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list_array.19716258.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list_array.19716258.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.links.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list_array.19716386.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.links.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list_array.19716386.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.normalize.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list_array.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.normalize.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.double_random_to_list_array.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.render.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.end_per_group.19716034.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.render.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.end_per_group.19716034.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.render_non_native.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.end_per_group.19716162.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.render_non_native.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.end_per_group.19716162.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.render_prop.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.end_per_group.19716290.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.render_prop.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.end_per_group.19716290.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.render_smoke.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.end_per_group.19716418.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.render_smoke.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.end_per_group.19716418.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.end_per_group.19716482.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_docs_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.end_per_group.19716482.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.bs_construct_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.end_per_group.408323.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.bs_construct_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.end_per_group.408323.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.bs_match_bin_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.bs_match_bin_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.bs_match_misc_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.bs_match_misc_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.bs_match_tail_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.init_per_group.19715938.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.bs_match_tail_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.init_per_group.19715938.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.end_per_group.19697506.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.init_per_group.19716066.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.end_per_group.19697506.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.init_per_group.19716066.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.end_per_group.19697570.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.init_per_group.19716194.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.end_per_group.19697570.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.init_per_group.19716194.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.end_per_group.19697794.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.init_per_group.19716322.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.end_per_group.19697794.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.init_per_group.19716322.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.end_per_group.19697986.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.init_per_group.19716450.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.end_per_group.19697986.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.init_per_group.19716450.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.end_per_group.398500.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.init_per_group.19716514.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.end_per_group.398500.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.init_per_group.19716514.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.end_per_group.503715.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.end_per_group.503715.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.multi_big.408291.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.multi_big.408291.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.forget.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.multi_big.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.forget.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.multi_big.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.init_per_group.19697474.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.multi_medium.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.init_per_group.19697474.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.multi_medium.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.init_per_group.19697538.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.multi_small.408259.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.init_per_group.19697538.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.multi_small.408259.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.init_per_group.19697602.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.multi_small.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.init_per_group.19697602.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.multi_small.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.init_per_group.19697826.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.sched_big.408227.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.init_per_group.19697826.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.sched_big.408227.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.init_per_group.19697858.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.sched_big.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.init_per_group.19697858.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.sched_big.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.init_per_group.503747.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.sched_medium.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.init_per_group.503747.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.sched_medium.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.sched_small.408195.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.sched_small.408195.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.sched_small.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.sched_small.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.known_bugs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.single_big.408163.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.known_bugs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.single_big.408163.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.local_definitions_save_to_module_and_forget.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.single_big.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.local_definitions_save_to_module_and_forget.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.single_big.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_10302.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.single_medium.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_10302.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.single_medium.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_13719.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.single_small.408131.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_13719.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.single_small.408131.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_14285.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.single_small.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_14285.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.single_small.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_14296.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_14296.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_bench_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_5195.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_suite.app_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_5195.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_suite.app_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_5226.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_suite.appup_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_5226.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_suite.appup_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_5327.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_suite.assert_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_5327.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_suite.assert_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_5435.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_5435.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_5915.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_5915.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_5916.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_5916.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/stdlib_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_5990.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.casefold.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_5990.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.casefold.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_6166.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.cd_gc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_6166.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.cd_gc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_6554.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.centre.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_6554.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.centre.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_7184.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.chars.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_7184.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.chars.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_7232.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.chomp.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_7232.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.chomp.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_8393.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.chr_rchr.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.otp_8393.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.chr_rchr.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.progex_bit_syntax.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.copies.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.progex_bit_syntax.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.copies.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.progex_funs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.end_per_group.19716546.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.progex_funs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.end_per_group.19716546.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.progex_lc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.progex_lc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.progex_records.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.progex_records.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.prompt_width.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.equal.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.prompt_width.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.equal.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.records.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.find.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.records.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.find.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.refman_bit_syntax.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.init_per_group.408355.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.refman_bit_syntax.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.init_per_group.408355.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.restricted_local.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.restricted_local.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.start_interactive.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.is_empty.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.start_interactive.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.is_empty.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.start_restricted_from_shell.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.jaro_similarity.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.start_restricted_from_shell.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.jaro_similarity.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.start_restricted_on_command_line.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.join.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.start_restricted_on_command_line.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.join.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.typed_records.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.left_right.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.typed_records.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.left_right.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.types.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.len.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.types.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.len.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.whereis.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.length.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/shell_suite.whereis.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.length.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sigils_suite.compiled_sigils.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.lexemes.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sigils_suite.compiled_sigils.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.lexemes.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sigils_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.lowercase.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sigils_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.lowercase.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sigils_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.meas.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sigils_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.meas.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sigils_suite.parse_sigils.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.nth_lexeme.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sigils_suite.parse_sigils.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.nth_lexeme.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sigils_suite.scan_sigils.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.old_concat.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sigils_suite.scan_sigils.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.old_concat.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sigils_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.old_equal.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sigils_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.old_equal.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/slave_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.old_to_float.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/slave_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.old_to_float.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/slave_suite.errors.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.old_to_integer.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/slave_suite.errors.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.old_to_integer.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/slave_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.old_tokens.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/slave_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.old_tokens.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/slave_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.pad.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/slave_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.pad.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/slave_suite.start_link_nodedown.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.prefix.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/slave_suite.start_link_nodedown.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.prefix.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/slave_suite.t_start.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.replace.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/slave_suite.t_start.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.replace.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/slave_suite.t_start_link.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.reverse.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/slave_suite.t_start_link.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.reverse.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.a_function_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.slice.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.a_function_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.slice.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.canonical.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.span_cspan.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.canonical.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.span_cspan.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.composite_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.split.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.composite_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.split.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.constant_function.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.constant_function.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.converse_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.str_rstr.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.converse_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.str_rstr.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.difference.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.strip.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.difference.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.strip.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.digraph.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.sub_string.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.digraph.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.sub_string.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.domain_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.sub_word.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.domain_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.sub_word.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.drestriction.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.substr.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.drestriction.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.substr.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.end_per_group.19699362.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.take.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.end_per_group.19699362.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.take.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.titlecase.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.titlecase.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.to_float.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.to_float.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.extension.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.to_graphemes.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.extension.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.to_graphemes.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.to_integer.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.to_integer.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_difference.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.to_upper_to_lower.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_difference.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.to_upper_to_lower.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_domain_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.trim.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_domain_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.trim.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_intersection_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.uppercase.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_intersection_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.uppercase.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_intersection_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.words.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_intersection_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/string_suite.words.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/suite.log b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/suite.log similarity index 55% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/suite.log rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/suite.log index 6b7813b80f332..10d52cc748b74 100644 --- a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/suite.log +++ b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/suite.log @@ -1,12037 +1,12037 @@ -=== Suite started at 2024-09-11 11:10:55 +=== Suite started at 2024-09-12 10:33:01 === Starting test (with repeated test cases) =cases unknown =user otptest -=host 43e13ac1be0c -=hosts 43e13ac1be0c +=host 7a1fde2d1d55 +=hosts 7a1fde2d1d55 =emulator_vsn 15.0.1 =emulator beam =otp_release 28 -=started 2024-09-11 11:10:55 +=started 2024-09-12 10:33:01 =case ct_framework:init_per_suite =logfile ct_framework.init_per_suite.html =group_props [{suite,argparse_SUITE}] -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok =elapsed 0.0 =case ct_framework:init_per_group =logfile ct_framework.init_per_group.html =group_props [{suite,argparse_SUITE},{name,parser},parallel] -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 0.001755 +=elapsed 0.001779 =case argparse_SUITE:readme -=logfile argparse_suite.readme.1218.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.readme.1186.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 0.002079 +=elapsed 0.001782 =case argparse_SUITE:basic =logfile argparse_suite.basic.1250.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 0.001658 +=elapsed 0.00197 =case argparse_SUITE:long_form_eq -=logfile argparse_suite.long_form_eq.1186.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.long_form_eq.67.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 0.007773 +=elapsed 0.001938 =case argparse_SUITE:built_in_types =logfile argparse_suite.built_in_types.3.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 8.44e-4 +=elapsed 0.005675 =case argparse_SUITE:type_validators -=logfile argparse_suite.type_validators.1282.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.type_validators.1218.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 0.008713 +=elapsed 0.005073 =case argparse_SUITE:invalid_arguments -=logfile argparse_suite.invalid_arguments.1314.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.invalid_arguments.35.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 0.001769 +=elapsed 0.001071 =case argparse_SUITE:complex_command -=logfile argparse_suite.complex_command.1378.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.complex_command.99.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 3.23e-4 +=elapsed 0.001531 =case argparse_SUITE:unicode -=logfile argparse_suite.unicode.1346.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.unicode.163.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 0.004584 +=elapsed 0.001853 =case argparse_SUITE:parser_error -=logfile argparse_suite.parser_error.1410.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.parser_error.195.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 5.75e-4 +=elapsed 0.002115 =case argparse_SUITE:nargs -=logfile argparse_suite.nargs.4.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.nargs.131.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 0.002096 +=elapsed 5.17e-4 =case argparse_SUITE:argparse -=logfile argparse_suite.argparse.35.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.argparse.1282.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 0.008223 +=elapsed 0.001193 =case argparse_SUITE:negative -=logfile argparse_suite.negative.67.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.negative.1314.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 9.51e-4 +=elapsed 0.002063 =case argparse_SUITE:nodigits -=logfile argparse_suite.nodigits.99.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.nodigits.1346.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 0.001941 +=elapsed 3.56e-4 =case argparse_SUITE:pos_mixed_with_opt -=logfile argparse_suite.pos_mixed_with_opt.131.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.pos_mixed_with_opt.4.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 4.32e-4 +=elapsed 1.36e-4 =case argparse_SUITE:default_for_not_required -=logfile argparse_suite.default_for_not_required.36.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.default_for_not_required.1378.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 4.63e-4 +=elapsed 3.79e-4 =case argparse_SUITE:global_default -=logfile argparse_suite.global_default.196.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.global_default.1410.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 9.0e-6 +=elapsed 8.2e-5 =case argparse_SUITE:subcommand -=logfile argparse_suite.subcommand.68.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.subcommand.1442.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 4.3e-5 +=elapsed 1.08e-4 =case argparse_SUITE:very_short -=logfile argparse_suite.very_short.100.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.very_short.1474.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 1.2e-5 +=elapsed 2.7e-5 =case argparse_SUITE:multi_short -=logfile argparse_suite.multi_short.132.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.multi_short.1506.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 4.1e-5 +=elapsed 4.4e-5 =case argparse_SUITE:proxy_arguments -=logfile argparse_suite.proxy_arguments.164.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.proxy_arguments.5.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 1.38e-4 +=elapsed 2.22e-4 =case ct_framework:end_per_group =logfile ct_framework.end_per_group.html =group_props [{suite,argparse_SUITE},{name,parser},parallel] -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 3.4e-5 -=group_time 0.076s +=elapsed 4.6e-5 +=group_time 0.073s =case ct_framework:init_per_group -=logfile ct_framework.init_per_group.5.html +=logfile ct_framework.init_per_group.37.html =group_props [{name,validator},parallel,{suite,argparse_SUITE}] -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 3.8e-5 +=elapsed 4.2e-5 =case argparse_SUITE:validator_exception -=logfile argparse_suite.validator_exception.37.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.validator_exception.69.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 7.5e-5 +=elapsed 9.7e-5 =case argparse_SUITE:validator_exception_format -=logfile argparse_suite.validator_exception_format.69.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.validator_exception_format.101.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 6.6e-5 +=elapsed 6.0e-5 =case ct_framework:end_per_group -=logfile ct_framework.end_per_group.101.html +=logfile ct_framework.end_per_group.133.html =group_props [{name,validator},parallel,{suite,argparse_SUITE}] -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 3.8e-5 -=group_time 0.047s +=elapsed 5.0e-5 +=group_time 0.048s =case ct_framework:init_per_group -=logfile ct_framework.init_per_group.133.html +=logfile ct_framework.init_per_group.1538.html =group_props [{name,usage},parallel,{suite,argparse_SUITE}] -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 3.0e-5 +=elapsed 5.2e-5 =case argparse_SUITE:usage -=logfile argparse_suite.usage.228.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.usage.1570.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 5.63e-4 +=elapsed 0.001122 =case argparse_SUITE:usage_required_args -=logfile argparse_suite.usage_required_args.260.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.usage_required_args.1602.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 7.0e-5 +=elapsed 6.1e-5 =case argparse_SUITE:usage_template -=logfile argparse_suite.usage_template.292.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.usage_template.165.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 1.47e-4 +=elapsed 1.4e-4 =case argparse_SUITE:usage_args_ordering -=logfile argparse_suite.usage_args_ordering.324.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.usage_args_ordering.227.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 7.4e-5 +=elapsed 7.9e-5 =case argparse_SUITE:parser_error_usage -=logfile argparse_suite.parser_error_usage.388.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.parser_error_usage.197.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 2.48e-4 +=elapsed 1.12e-4 =case argparse_SUITE:command_usage -=logfile argparse_suite.command_usage.356.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.command_usage.229.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 7.3e-5 +=elapsed 6.2e-5 =case argparse_SUITE:usage_width -=logfile argparse_suite.usage_width.420.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=logfile argparse_suite.usage_width.261.html +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 2.04e-4 +=elapsed 1.89e-4 =case ct_framework:end_per_group -=logfile ct_framework.end_per_group.452.html +=logfile ct_framework.end_per_group.36.html =group_props [{name,usage},parallel,{suite,argparse_SUITE}] -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 3.0e-5 -=group_time 0.053s +=elapsed 4.7e-5 +=group_time 0.055s =case ct_framework:end_per_suite =logfile ct_framework.end_per_suite.html =group_props [{suite,argparse_SUITE}] -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok =elapsed 0.0 -=group_time 0.278s +=group_time 0.279s =case array_SUITE:init_per_suite =logfile array_suite.init_per_suite.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok =elapsed 0.0 =case array_SUITE:new_test =logfile array_suite.new_test.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 0.001767 +=elapsed 0.001939 =case array_SUITE:fix_test =logfile array_suite.fix_test.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 4.0e-6 +=elapsed 5.0e-6 =case array_SUITE:relax_test =logfile array_suite.relax_test.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 2.0e-6 +=elapsed 4.0e-6 =case array_SUITE:resize_test =logfile array_suite.resize_test.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 1.0e-5 +=elapsed 1.2e-5 =case array_SUITE:set_get_test =logfile array_suite.set_get_test.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok =elapsed 9.0e-6 =case array_SUITE:to_list_test =logfile array_suite.to_list_test.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 2.7e-5 +=elapsed 2.5e-5 =case array_SUITE:sparse_to_list_test =logfile array_suite.sparse_to_list_test.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 5.0e-6 +=elapsed 6.0e-6 =case array_SUITE:from_list_test =logfile array_suite.from_list_test.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:56 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 0.008203 +=elapsed 0.008462 =case array_SUITE:to_orddict_test =logfile array_suite.to_orddict_test.html -=started 2024-09-11 11:10:56 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 0.0001 +=elapsed 7.0e-5 =case array_SUITE:sparse_to_orddict_test =logfile array_suite.sparse_to_orddict_test.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:04 =result ok -=elapsed 5.0e-6 +=elapsed 6.0e-6 =case array_SUITE:from_orddict_test =logfile array_suite.from_orddict_test.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:04 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 0.016642 +=elapsed 0.016338 =case array_SUITE:map_test =logfile array_suite.map_test.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 0.009567 +=elapsed 0.009708 =case array_SUITE:sparse_map_test =logfile array_suite.sparse_map_test.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 0.008754 +=elapsed 0.00916 =case array_SUITE:foldl_test =logfile array_suite.foldl_test.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 1.63e-4 +=elapsed 1.35e-4 =case array_SUITE:sparse_foldl_test =logfile array_suite.sparse_foldl_test.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 1.47e-4 +=elapsed 1.17e-4 =case array_SUITE:foldr_test =logfile array_suite.foldr_test.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 1.55e-4 +=elapsed 1.28e-4 =case array_SUITE:sparse_foldr_test =logfile array_suite.sparse_foldr_test.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 1.41e-4 +=elapsed 1.19e-4 =case array_SUITE:end_per_suite =logfile array_suite.end_per_suite.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok =elapsed 1.0e-6 -=group_time 0.465s +=group_time 0.467s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.1442.html +=logfile ct_framework.init_per_suite.259.html =group_props [{suite,base64_SUITE}] -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok =elapsed 0.0 =case base64_SUITE:base64_encode =logfile base64_suite.base64_encode.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 0.0018 +=elapsed 0.002427 =case base64_SUITE:base64_encode_to_string =logfile base64_suite.base64_encode_to_string.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 2.0e-6 +=elapsed 5.0e-6 =case base64_SUITE:base64_encode_modes =logfile base64_suite.base64_encode_modes.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 2.0e-6 +=elapsed 5.0e-6 =case base64_SUITE:base64_decode =logfile base64_suite.base64_decode.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 2.9e-5 +=elapsed 4.6e-5 =case base64_SUITE:base64_decode_to_string =logfile base64_suite.base64_decode_to_string.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 2.6e-5 +=elapsed 4.6e-5 =case base64_SUITE:base64_decode_modes =logfile base64_suite.base64_decode_modes.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 7.0e-6 +=elapsed 1.2e-5 =case base64_SUITE:base64_otp_5635 =logfile base64_suite.base64_otp_5635.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 2.0e-6 +=elapsed 5.0e-6 =case base64_SUITE:base64_otp_6279 =logfile base64_suite.base64_otp_6279.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 3.0e-6 +=elapsed 6.0e-6 =case base64_SUITE:big =logfile base64_suite.big.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 0.006827 +=elapsed 0.007337 =case base64_SUITE:illegal =logfile base64_suite.illegal.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 6.0e-6 +=elapsed 1.4e-5 =case base64_SUITE:mime_decode =logfile base64_suite.mime_decode.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 1.4e-5 +=elapsed 2.1e-5 =case base64_SUITE:mime_decode_modes =logfile base64_suite.mime_decode_modes.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 5.0e-6 +=elapsed 9.0e-6 =case base64_SUITE:mime_decode_to_string =logfile base64_suite.mime_decode_to_string.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 8.0e-6 +=elapsed 1.4e-5 =case base64_SUITE:mime_decode_to_string_modes =logfile base64_suite.mime_decode_to_string_modes.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 2.0e-6 +=elapsed 6.0e-6 =case ct_framework:init_per_group -=logfile ct_framework.init_per_group.1474.html +=logfile ct_framework.init_per_group.1634.html =group_props [{name,roundtrip},parallel,{suite,base64_SUITE}] -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 3.1e-5 +=elapsed 4.1e-5 =case base64_SUITE:roundtrip_1 -=logfile base64_suite.roundtrip_1.1506.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=logfile base64_suite.roundtrip_1.1666.html +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 0.283147 +=elapsed 0.294764 =case base64_SUITE:roundtrip_2 -=logfile base64_suite.roundtrip_2.1538.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=logfile base64_suite.roundtrip_2.1698.html +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 0.28673 +=elapsed 0.298535 =case base64_SUITE:roundtrip_3 -=logfile base64_suite.roundtrip_3.163.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=logfile base64_suite.roundtrip_3.1730.html +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 0.11204 +=elapsed 0.10648 =case base64_SUITE:roundtrip_4 -=logfile base64_suite.roundtrip_4.1570.html -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=logfile base64_suite.roundtrip_4.1762.html +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 0.301191 +=elapsed 0.254835 =case ct_framework:end_per_group -=logfile ct_framework.end_per_group.291.html +=logfile ct_framework.end_per_group.1826.html =group_props [{name,roundtrip},parallel,{suite,base64_SUITE}] -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:57 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok -=elapsed 4.5e-5 -=group_time 0.348s +=elapsed 4.3e-5 +=group_time 0.347s =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.1634.html +=logfile ct_framework.end_per_suite.1858.html =group_props [{suite,base64_SUITE}] -=started 2024-09-11 11:10:57 -=ended 2024-09-11 11:10:58 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:05 =result ok =elapsed 0.0 -=group_time 0.721s +=group_time 0.729s =case base64_property_test_SUITE:init_per_suite =logfile base64_property_test_suite.init_per_suite.html -=started 2024-09-11 11:10:58 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:05 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 1.240891 +=elapsed 1.258748 =case base64_property_test_SUITE:encode_1_case =logfile base64_property_test_suite.encode_1_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.008506 +=elapsed 0.009072 =case base64_property_test_SUITE:encode_2_case =logfile base64_property_test_suite.encode_2_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.001808 +=elapsed 0.001589 =case base64_property_test_SUITE:encode_to_string_1_case =logfile base64_property_test_suite.encode_to_string_1_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.001624 +=elapsed 0.001467 =case base64_property_test_SUITE:encode_to_string_2_case =logfile base64_property_test_suite.encode_to_string_2_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.001705 +=elapsed 0.001556 =case base64_property_test_SUITE:decode_1_case =logfile base64_property_test_suite.decode_1_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.003861 +=elapsed 0.00386 =case base64_property_test_SUITE:decode_2_case =logfile base64_property_test_suite.decode_2_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.00943 +=elapsed 0.009097 =case base64_property_test_SUITE:decode_1_malformed_case =logfile base64_property_test_suite.decode_1_malformed_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.012488 +=elapsed 0.010787 =case base64_property_test_SUITE:decode_2_malformed_case =logfile base64_property_test_suite.decode_2_malformed_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.011886 +=elapsed 0.013351 =case base64_property_test_SUITE:decode_1_noisy_case =logfile base64_property_test_suite.decode_1_noisy_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.016319 +=elapsed 0.01819 =case base64_property_test_SUITE:decode_2_noisy_case =logfile base64_property_test_suite.decode_2_noisy_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.016248 +=elapsed 0.018551 =case base64_property_test_SUITE:decode_to_string_1_case =logfile base64_property_test_suite.decode_to_string_1_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.003902 +=elapsed 0.005174 =case base64_property_test_SUITE:decode_to_string_2_case =logfile base64_property_test_suite.decode_to_string_2_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.009198 +=elapsed 0.009971 =case base64_property_test_SUITE:decode_to_string_1_malformed_case =logfile base64_property_test_suite.decode_to_string_1_malformed_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.011465 +=elapsed 0.014687 =case base64_property_test_SUITE:decode_to_string_2_malformed_case =logfile base64_property_test_suite.decode_to_string_2_malformed_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.01231 +=elapsed 0.012918 =case base64_property_test_SUITE:decode_to_string_1_noisy_case =logfile base64_property_test_suite.decode_to_string_1_noisy_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.016161 +=elapsed 0.018991 =case base64_property_test_SUITE:decode_to_string_2_noisy_case =logfile base64_property_test_suite.decode_to_string_2_noisy_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.01628 +=elapsed 0.016344 =case base64_property_test_SUITE:mime_decode_1_case =logfile base64_property_test_suite.mime_decode_1_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.006767 +=elapsed 0.00688 =case base64_property_test_SUITE:mime_decode_2_case =logfile base64_property_test_suite.mime_decode_2_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.009031 +=elapsed 0.009083 =case base64_property_test_SUITE:mime_decode_1_malformed_case =logfile base64_property_test_suite.mime_decode_1_malformed_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.028318 +=elapsed 0.027995 =case base64_property_test_SUITE:mime_decode_2_malformed_case =logfile base64_property_test_suite.mime_decode_2_malformed_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.027197 +=elapsed 0.028394 =case base64_property_test_SUITE:mime_decode_to_string_1_case =logfile base64_property_test_suite.mime_decode_to_string_1_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:10:59 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.006503 +=elapsed 0.006286 =case base64_property_test_SUITE:mime_decode_to_string_2_case =logfile base64_property_test_suite.mime_decode_to_string_2_case.html -=started 2024-09-11 11:10:59 -=ended 2024-09-11 11:11:00 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:07 =result ok -=elapsed 0.008719 +=elapsed 0.008791 =case base64_property_test_SUITE:mime_decode_to_string_1_malformed_case =logfile base64_property_test_suite.mime_decode_to_string_1_malformed_case.html -=started 2024-09-11 11:11:00 -=ended 2024-09-11 11:11:00 +=started 2024-09-12 10:33:07 +=ended 2024-09-12 10:33:08 =result ok -=elapsed 0.02759 +=elapsed 0.029061 =case base64_property_test_SUITE:mime_decode_to_string_2_malformed_case =logfile base64_property_test_suite.mime_decode_to_string_2_malformed_case.html -=started 2024-09-11 11:11:00 -=ended 2024-09-11 11:11:00 +=started 2024-09-12 10:33:08 +=ended 2024-09-12 10:33:08 =result ok -=elapsed 0.028479 +=elapsed 0.026312 =case base64_property_test_SUITE:end_per_suite =logfile base64_property_test_suite.end_per_suite.html -=started 2024-09-11 11:11:00 -=ended 2024-09-11 11:11:00 +=started 2024-09-12 10:33:08 +=ended 2024-09-12 10:33:08 =result ok =elapsed 0.0 -=group_time 2.103s +=group_time 2.142s =case beam_lib_SUITE:init_per_suite =logfile beam_lib_suite.init_per_suite.html -=started 2024-09-11 11:11:00 -=ended 2024-09-11 11:11:00 +=started 2024-09-12 10:33:08 +=ended 2024-09-12 10:33:08 =result ok =elapsed 0.0 =case beam_lib_SUITE:error =logfile beam_lib_suite.error.html -=started 2024-09-11 11:11:00 -=ended 2024-09-11 11:11:00 +=started 2024-09-12 10:33:08 +=ended 2024-09-12 10:33:08 =result ok -=elapsed 0.017936 +=elapsed 0.017316 =case beam_lib_SUITE:normal =logfile beam_lib_suite.normal.html -=started 2024-09-11 11:11:00 -=ended 2024-09-11 11:11:00 +=started 2024-09-12 10:33:08 +=ended 2024-09-12 10:33:08 =result ok -=elapsed 0.006901 +=elapsed 0.005318 =case beam_lib_SUITE:cmp =logfile beam_lib_suite.cmp.html -=started 2024-09-11 11:11:00 -=ended 2024-09-11 11:11:00 +=started 2024-09-12 10:33:08 +=ended 2024-09-12 10:33:08 =result ok -=elapsed 0.009344 +=elapsed 0.008276 =case beam_lib_SUITE:cmp_literals =logfile beam_lib_suite.cmp_literals.html -=started 2024-09-11 11:11:00 -=ended 2024-09-11 11:11:00 +=started 2024-09-12 10:33:08 +=ended 2024-09-12 10:33:08 =result ok -=elapsed 0.004809 +=elapsed 0.004469 =case beam_lib_SUITE:strip =logfile beam_lib_suite.strip.html -=started 2024-09-11 11:11:00 -=ended 2024-09-11 11:11:00 +=started 2024-09-12 10:33:08 +=ended 2024-09-12 10:33:08 =result ok -=elapsed 0.032591 +=elapsed 0.03111 =case beam_lib_SUITE:strip_add_chunks =logfile beam_lib_suite.strip_add_chunks.html -=started 2024-09-11 11:11:00 -=ended 2024-09-11 11:11:00 +=started 2024-09-12 10:33:08 +=ended 2024-09-12 10:33:08 =result ok -=elapsed 0.036899 +=elapsed 0.041929 =case beam_lib_SUITE:otp_6711 =logfile beam_lib_suite.otp_6711.html -=started 2024-09-11 11:11:00 -=ended 2024-09-11 11:11:00 +=started 2024-09-12 10:33:08 +=ended 2024-09-12 10:33:08 =result ok -=elapsed 0.002465 +=elapsed 0.004306 =case beam_lib_SUITE:building =logfile beam_lib_suite.building.html -=started 2024-09-11 11:11:00 -=ended 2024-09-11 11:11:00 +=started 2024-09-12 10:33:08 +=ended 2024-09-12 10:33:08 =result ok -=elapsed 0.002995 +=elapsed 0.004305 =case beam_lib_SUITE:md5 =logfile beam_lib_suite.md5.html -=started 2024-09-11 11:11:00 -=ended 2024-09-11 11:11:00 +=started 2024-09-12 10:33:08 +=ended 2024-09-12 10:33:08 =result ok -=elapsed 0.359658 +=elapsed 0.423846 =case beam_lib_SUITE:encrypted_abstr =logfile beam_lib_suite.encrypted_abstr.html -=started 2024-09-11 11:11:00 -=ended 2024-09-11 11:11:01 +=started 2024-09-12 10:33:08 +=ended 2024-09-12 10:33:09 =result ok -=elapsed 0.19445 +=elapsed 0.199134 =case beam_lib_SUITE:encrypted_abstr_file =logfile beam_lib_suite.encrypted_abstr_file.html -=started 2024-09-11 11:11:01 -=ended 2024-09-11 11:11:01 +=started 2024-09-12 10:33:09 +=ended 2024-09-12 10:33:09 =result ok -=elapsed 0.008933 +=elapsed 0.009779 =case beam_lib_SUITE:missing_debug_info_backend =logfile beam_lib_suite.missing_debug_info_backend.html -=started 2024-09-11 11:11:01 -=ended 2024-09-11 11:11:01 +=started 2024-09-12 10:33:09 +=ended 2024-09-12 10:33:09 =result ok -=elapsed 0.001778 +=elapsed 0.002479 =case beam_lib_SUITE:test_makedep_abstract_code =logfile beam_lib_suite.test_makedep_abstract_code.html -=started 2024-09-11 11:11:01 -=ended 2024-09-11 11:11:01 +=started 2024-09-12 10:33:09 +=ended 2024-09-12 10:33:09 =result ok -=elapsed 0.001536 +=elapsed 0.002191 =case beam_lib_SUITE:end_per_suite =logfile beam_lib_suite.end_per_suite.html -=started 2024-09-11 11:11:01 -=ended 2024-09-11 11:11:01 +=started 2024-09-12 10:33:09 +=ended 2024-09-12 10:33:09 =result ok -=elapsed 1.0e-6 -=group_time 1.002s +=elapsed 3.0e-6 +=group_time 1.082s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.2434.html +=logfile ct_framework.init_per_suite.2658.html =group_props [{suite,binary_module_SUITE}] -=started 2024-09-11 11:11:01 -=ended 2024-09-11 11:11:01 +=started 2024-09-12 10:33:09 +=ended 2024-09-12 10:33:09 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =case binary_module_SUITE:scope_return =logfile binary_module_suite.scope_return.html -=started 2024-09-11 11:11:01 -=ended 2024-09-11 11:11:01 +=started 2024-09-12 10:33:09 +=ended 2024-09-12 10:33:09 =result ok -=elapsed 0.010728 +=elapsed 0.010689 =case binary_module_SUITE:interesting =logfile binary_module_suite.interesting.html -=started 2024-09-11 11:11:01 -=ended 2024-09-11 11:11:01 +=started 2024-09-12 10:33:09 +=ended 2024-09-12 10:33:09 =result ok -=elapsed 0.170793 +=elapsed 0.169506 =case binary_module_SUITE:random_ref_fla_comp =logfile binary_module_suite.random_ref_fla_comp.html -=started 2024-09-11 11:11:01 -=ended 2024-09-11 11:11:02 +=started 2024-09-12 10:33:09 +=ended 2024-09-12 10:33:10 =result ok -=elapsed 0.789169 +=elapsed 0.796363 =case binary_module_SUITE:random_ref_sr_comp =logfile binary_module_suite.random_ref_sr_comp.html -=started 2024-09-11 11:11:02 -=ended 2024-09-11 11:11:06 +=started 2024-09-12 10:33:10 +=ended 2024-09-12 10:33:14 =result ok -=elapsed 4.450728 +=elapsed 4.442264 =case binary_module_SUITE:random_ref_comp =logfile binary_module_suite.random_ref_comp.html -=started 2024-09-11 11:11:06 -=ended 2024-09-11 11:11:14 +=started 2024-09-12 10:33:14 +=ended 2024-09-12 10:33:22 =result ok -=elapsed 7.309498 +=elapsed 7.359783 =case binary_module_SUITE:parts =logfile binary_module_suite.parts.html -=started 2024-09-11 11:11:14 -=ended 2024-09-11 11:11:15 +=started 2024-09-12 10:33:22 +=ended 2024-09-12 10:33:23 =result ok -=elapsed 1.145255 +=elapsed 1.159081 =case binary_module_SUITE:bin_to_list =logfile binary_module_suite.bin_to_list.html -=started 2024-09-11 11:11:15 -=ended 2024-09-11 11:11:16 +=started 2024-09-12 10:33:23 +=ended 2024-09-12 10:33:24 =result ok -=elapsed 1.284052 +=elapsed 1.291164 =case binary_module_SUITE:list_to_bin =logfile binary_module_suite.list_to_bin.html -=started 2024-09-11 11:11:16 -=ended 2024-09-11 11:11:16 +=started 2024-09-12 10:33:24 +=ended 2024-09-12 10:33:24 =result ok -=elapsed 0.043687 +=elapsed 0.043663 =case binary_module_SUITE:copy =logfile binary_module_suite.copy.html -=started 2024-09-11 11:11:16 -=ended 2024-09-11 11:11:28 +=started 2024-09-12 10:33:24 +=ended 2024-09-12 10:33:36 =result ok -=elapsed 11.507594 +=elapsed 11.533604 =case binary_module_SUITE:referenced =logfile binary_module_suite.referenced.html -=started 2024-09-11 11:11:28 -=ended 2024-09-11 11:11:28 +=started 2024-09-12 10:33:36 +=ended 2024-09-12 10:33:36 =result ok -=elapsed 4.08e-4 +=elapsed 7.9e-5 =case binary_module_SUITE:guard =logfile binary_module_suite.guard.html -=started 2024-09-11 11:11:28 -=ended 2024-09-11 11:11:28 +=started 2024-09-12 10:33:36 +=ended 2024-09-12 10:33:36 =result ok: Guard tests are run in emulator test suite =elapsed 0.0 =case binary_module_SUITE:encode_decode =logfile binary_module_suite.encode_decode.html -=started 2024-09-11 11:11:28 -=ended 2024-09-11 11:11:28 +=started 2024-09-12 10:33:36 +=ended 2024-09-12 10:33:36 =result ok -=elapsed 0.028256 +=elapsed 0.028252 =case binary_module_SUITE:badargs =logfile binary_module_suite.badargs.html -=started 2024-09-11 11:11:28 -=ended 2024-09-11 11:11:28 +=started 2024-09-12 10:33:36 +=ended 2024-09-12 10:33:36 =result ok -=elapsed 7.6e-5 +=elapsed 7.8e-5 =case binary_module_SUITE:longest_common_trap =logfile binary_module_suite.longest_common_trap.html -=started 2024-09-11 11:11:28 -=ended 2024-09-11 11:11:28 +=started 2024-09-12 10:33:36 +=ended 2024-09-12 10:33:36 =result ok -=elapsed 3.88e-4 +=elapsed 4.04e-4 =case binary_module_SUITE:check_no_invalid_read_bug =logfile binary_module_suite.check_no_invalid_read_bug.html -=started 2024-09-11 11:11:28 -=ended 2024-09-11 11:11:28 +=started 2024-09-12 10:33:36 +=ended 2024-09-12 10:33:36 =result ok =elapsed 3.0e-6 =case binary_module_SUITE:error_info =logfile binary_module_suite.error_info.html -=started 2024-09-11 11:11:28 -=ended 2024-09-11 11:11:28 +=started 2024-09-12 10:33:36 +=ended 2024-09-12 10:33:36 =result ok -=elapsed 0.009087 +=elapsed 0.011178 =case binary_module_SUITE:hex_encoding =logfile binary_module_suite.hex_encoding.html -=started 2024-09-11 11:11:28 -=ended 2024-09-11 11:11:28 +=started 2024-09-12 10:33:36 +=ended 2024-09-12 10:33:36 =result ok -=elapsed 0.003572 +=elapsed 0.003652 =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.2498.html +=logfile ct_framework.end_per_suite.34754.html =group_props [{suite,binary_module_SUITE}] -=started 2024-09-11 11:11:28 -=ended 2024-09-11 11:11:28 +=started 2024-09-12 10:33:36 +=ended 2024-09-12 10:33:36 =result ok =elapsed 0.0 -=group_time 27.171s +=group_time 27.271s =case binary_property_test_SUITE:init_per_suite =logfile binary_property_test_suite.init_per_suite.html -=started 2024-09-11 11:11:28 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:36 +=ended 2024-09-12 10:33:37 =result ok -=elapsed 1.226647 +=elapsed 1.206272 =case ct_framework:init_per_group -=logfile ct_framework.init_per_group.2530.html +=logfile ct_framework.init_per_group.34786.html =group_props [{suite,binary_property_test_SUITE},{name,valid_input}] -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:37 +=ended 2024-09-12 10:33:37 =result ok -=elapsed 2.7e-5 +=elapsed 3.3e-5 =case binary_property_test_SUITE:at_case =logfile binary_property_test_suite.at_case.html -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:37 +=ended 2024-09-12 10:33:37 =result ok -=elapsed 0.002026 +=elapsed 0.002793 =case binary_property_test_SUITE:bin_to_list_1_case =logfile binary_property_test_suite.bin_to_list_1_case.html -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:37 +=ended 2024-09-12 10:33:37 =result ok -=elapsed 0.001508 +=elapsed 0.001985 =case binary_property_test_SUITE:bin_to_list_2_3_case =logfile binary_property_test_suite.bin_to_list_2_3_case.html -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:37 +=ended 2024-09-12 10:33:37 =result ok -=elapsed 0.002376 +=elapsed 0.00308 =case binary_property_test_SUITE:compile_pattern_case =logfile binary_property_test_suite.compile_pattern_case.html -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:37 +=ended 2024-09-12 10:33:37 =result ok -=elapsed 0.005853 +=elapsed 0.009892 =case binary_property_test_SUITE:copy_case =logfile binary_property_test_suite.copy_case.html -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:37 +=ended 2024-09-12 10:33:37 =result ok -=elapsed 0.001684 +=elapsed 0.002545 =case binary_property_test_SUITE:decode_hex_case =logfile binary_property_test_suite.decode_hex_case.html -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:37 +=ended 2024-09-12 10:33:37 =result ok -=elapsed 0.00208 +=elapsed 0.00317 =case binary_property_test_SUITE:decode_unsigned_case =logfile binary_property_test_suite.decode_unsigned_case.html -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:37 +=ended 2024-09-12 10:33:37 =result ok -=elapsed 0.001385 +=elapsed 0.001966 =case binary_property_test_SUITE:encode_hex_case =logfile binary_property_test_suite.encode_hex_case.html -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:37 +=ended 2024-09-12 10:33:37 =result ok -=elapsed 0.001626 +=elapsed 0.002383 =case binary_property_test_SUITE:encode_unsigned_case =logfile binary_property_test_suite.encode_unsigned_case.html -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:37 +=ended 2024-09-12 10:33:37 =result ok -=elapsed 9.85e-4 +=elapsed 0.00145 =case binary_property_test_SUITE:first_case =logfile binary_property_test_suite.first_case.html -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:37 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.001389 +=elapsed 0.002105 =case binary_property_test_SUITE:last_case =logfile binary_property_test_suite.last_case.html -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.001409 +=elapsed 0.002113 =case binary_property_test_SUITE:list_to_bin_case =logfile binary_property_test_suite.list_to_bin_case.html -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.001376 +=elapsed 0.002087 =case binary_property_test_SUITE:longest_common_prefix_case =logfile binary_property_test_suite.longest_common_prefix_case.html -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.006548 +=elapsed 0.011716 =case binary_property_test_SUITE:longest_common_suffix_case =logfile binary_property_test_suite.longest_common_suffix_case.html -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.007302 +=elapsed 0.011625 =case binary_property_test_SUITE:match_case =logfile binary_property_test_suite.match_case.html -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:29 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.00816 +=elapsed 0.021549 =case binary_property_test_SUITE:matches_case =logfile binary_property_test_suite.matches_case.html -=started 2024-09-11 11:11:29 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.009519 +=elapsed 0.013188 =case binary_property_test_SUITE:part_case =logfile binary_property_test_suite.part_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.001736 +=elapsed 0.001678 =case binary_property_test_SUITE:replace_case =logfile binary_property_test_suite.replace_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.015288 +=elapsed 0.018748 =case binary_property_test_SUITE:split_case =logfile binary_property_test_suite.split_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.010673 +=elapsed 0.011646 =case ct_framework:end_per_group -=logfile ct_framework.end_per_group.3170.html +=logfile ct_framework.end_per_group.35426.html =group_props [{suite,binary_property_test_SUITE},{name,valid_input}] -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 3.2e-5 -=group_time 0.532s +=elapsed 3.4e-5 +=group_time 0.581s =case ct_framework:init_per_group -=logfile ct_framework.init_per_group.3202.html +=logfile ct_framework.init_per_group.35458.html =group_props [{name,invalid_input},{suite,binary_property_test_SUITE}] -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok =elapsed 2.7e-5 =case ct_framework:init_per_group -=logfile ct_framework.init_per_group.3234.html +=logfile ct_framework.init_per_group.35490.html =group_props [{name,out_of_binary},{suite,binary_property_test_SUITE}] -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok =elapsed 2.5e-5 =case binary_property_test_SUITE:at_invalid_index_case =logfile binary_property_test_suite.at_invalid_index_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.001633 +=elapsed 0.001576 =case binary_property_test_SUITE:bin_to_list_2_3_invalid_range_case =logfile binary_property_test_suite.bin_to_list_2_3_invalid_range_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.001841 +=elapsed 0.001796 =case binary_property_test_SUITE:match_3_invalid_scope_case =logfile binary_property_test_suite.match_3_invalid_scope_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.010154 +=elapsed 0.01099 =case binary_property_test_SUITE:matches_3_invalid_scope_case =logfile binary_property_test_suite.matches_3_invalid_scope_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.008396 +=elapsed 0.008388 =case binary_property_test_SUITE:part_invalid_range_case =logfile binary_property_test_suite.part_invalid_range_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.001758 +=elapsed 0.002563 =case binary_property_test_SUITE:replace_4_invalid_scope_case =logfile binary_property_test_suite.replace_4_invalid_scope_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.007412 +=elapsed 0.01266 =case binary_property_test_SUITE:replace_4_invalid_insert_replaced_case =logfile binary_property_test_suite.replace_4_invalid_insert_replaced_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.008885 +=elapsed 0.01232 =case binary_property_test_SUITE:split_3_invalid_scope_case =logfile binary_property_test_suite.split_3_invalid_scope_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.005973 +=elapsed 0.012033 =case ct_framework:end_per_group -=logfile ct_framework.end_per_group.3522.html +=logfile ct_framework.end_per_group.35778.html =group_props [{name,out_of_binary},{suite,binary_property_test_SUITE}] -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 2.5e-5 -=group_time 0.248s +=elapsed 3.3e-5 +=group_time 0.264s =case ct_framework:init_per_group -=logfile ct_framework.init_per_group.3554.html +=logfile ct_framework.init_per_group.35810.html =group_props [{name,invalid_subjects},{suite,binary_property_test_SUITE}] -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 2.5e-5 +=elapsed 3.1e-5 =case binary_property_test_SUITE:at_invalid_subject_case =logfile binary_property_test_suite.at_invalid_subject_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.007139 +=elapsed 0.005678 =case binary_property_test_SUITE:bin_to_list_invalid_subject_case =logfile binary_property_test_suite.bin_to_list_invalid_subject_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.005835 +=elapsed 0.003725 =case binary_property_test_SUITE:copy_invalid_subject_case =logfile binary_property_test_suite.copy_invalid_subject_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.006443 +=elapsed 0.004337 =case binary_property_test_SUITE:decode_hex_invalid_subject_case =logfile binary_property_test_suite.decode_hex_invalid_subject_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.005266 +=elapsed 0.003981 =case binary_property_test_SUITE:decode_unsigned_invalid_subject_case =logfile binary_property_test_suite.decode_unsigned_invalid_subject_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.003875 +=elapsed 0.003731 =case binary_property_test_SUITE:encode_hex_invalid_subject_case =logfile binary_property_test_suite.encode_hex_invalid_subject_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.003918 +=elapsed 0.004082 =case binary_property_test_SUITE:first_invalid_subject_case =logfile binary_property_test_suite.first_invalid_subject_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.002603 +=elapsed 0.002247 =case binary_property_test_SUITE:last_invalid_subject_case =logfile binary_property_test_suite.last_invalid_subject_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.002186 +=elapsed 0.002708 =case binary_property_test_SUITE:longest_common_prefix_invalid_subject_case =logfile binary_property_test_suite.longest_common_prefix_invalid_subject_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.005608 +=elapsed 0.00665 =case binary_property_test_SUITE:longest_common_suffix_invalid_subject_case =logfile binary_property_test_suite.longest_common_suffix_invalid_subject_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.006244 +=elapsed 0.006194 =case binary_property_test_SUITE:match_invalid_subject_case =logfile binary_property_test_suite.match_invalid_subject_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:38 =result ok -=elapsed 0.007136 +=elapsed 0.00712 =case binary_property_test_SUITE:matches_invalid_subject_case =logfile binary_property_test_suite.matches_invalid_subject_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:38 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.009018 +=elapsed 0.007609 =case binary_property_test_SUITE:part_invalid_subject_case =logfile binary_property_test_suite.part_invalid_subject_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.003911 +=elapsed 0.003692 =case binary_property_test_SUITE:replace_invalid_subject_case =logfile binary_property_test_suite.replace_invalid_subject_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.007765 +=elapsed 0.009122 =case binary_property_test_SUITE:split_invalid_subject_case =logfile binary_property_test_suite.split_invalid_subject_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.007587 +=elapsed 0.009239 =case ct_framework:end_per_group -=logfile ct_framework.end_per_group.4066.html +=logfile ct_framework.end_per_group.36322.html =group_props [{name,invalid_subjects},{suite,binary_property_test_SUITE}] -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 2.9e-5 -=group_time 0.444s +=elapsed 2.6e-5 +=group_time 0.441s =case ct_framework:init_per_group -=logfile ct_framework.init_per_group.4098.html +=logfile ct_framework.init_per_group.36354.html =group_props [{name,invalid_patterns},{suite,binary_property_test_SUITE}] -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 5.4e-5 +=elapsed 2.5e-5 =case binary_property_test_SUITE:compile_pattern_invalid_pattern_case =logfile binary_property_test_suite.compile_pattern_invalid_pattern_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:30 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.025727 +=elapsed 0.024212 =case binary_property_test_SUITE:match_invalid_pattern_case =logfile binary_property_test_suite.match_invalid_pattern_case.html -=started 2024-09-11 11:11:30 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.027482 +=elapsed 0.028036 =case binary_property_test_SUITE:matches_invalid_pattern_case =logfile binary_property_test_suite.matches_invalid_pattern_case.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.031941 +=elapsed 0.023319 =case binary_property_test_SUITE:replace_invalid_pattern_case =logfile binary_property_test_suite.replace_invalid_pattern_case.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.032752 +=elapsed 0.033011 =case binary_property_test_SUITE:split_invalid_pattern_case =logfile binary_property_test_suite.split_invalid_pattern_case.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.026936 +=elapsed 0.028932 =case ct_framework:end_per_group -=logfile ct_framework.end_per_group.4290.html +=logfile ct_framework.end_per_group.36546.html =group_props [{name,invalid_patterns},{suite,binary_property_test_SUITE}] -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 2.3e-5 -=group_time 0.278s +=elapsed 2.6e-5 +=group_time 0.272s =case ct_framework:init_per_group -=logfile ct_framework.init_per_group.4322.html +=logfile ct_framework.init_per_group.36578.html =group_props [{name,misc_invalid},{suite,binary_property_test_SUITE}] -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 2.5e-5 +=elapsed 4.4e-5 =case binary_property_test_SUITE:copy_2_invalid_n_case =logfile binary_property_test_suite.copy_2_invalid_n_case.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.00148 +=elapsed 0.001675 =case binary_property_test_SUITE:decode_hex_invalid_chars_case =logfile binary_property_test_suite.decode_hex_invalid_chars_case.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.00144 +=elapsed 0.001579 =case binary_property_test_SUITE:decode_unsigned_2_invalid_endianness_case =logfile binary_property_test_suite.decode_unsigned_2_invalid_endianness_case.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.005028 +=elapsed 0.006324 =case binary_property_test_SUITE:encode_hex_2_invalid_case_case =logfile binary_property_test_suite.encode_hex_2_invalid_case_case.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.006468 +=elapsed 0.004772 =case binary_property_test_SUITE:encode_unsigned_invalid_integer_case =logfile binary_property_test_suite.encode_unsigned_invalid_integer_case.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 9.98e-4 +=elapsed 0.001164 =case binary_property_test_SUITE:encode_unsigned_2_invalid_endianness_case =logfile binary_property_test_suite.encode_unsigned_2_invalid_endianness_case.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.005481 +=elapsed 0.005326 =case binary_property_test_SUITE:list_to_bin_invalid_bytes_case =logfile binary_property_test_suite.list_to_bin_invalid_bytes_case.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.001517 +=elapsed 0.001731 =case binary_property_test_SUITE:replace_invalid_replacement_case =logfile binary_property_test_suite.replace_invalid_replacement_case.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.010587 +=elapsed 0.010621 =case ct_framework:end_per_group -=logfile ct_framework.end_per_group.4610.html +=logfile ct_framework.end_per_group.36866.html =group_props [{name,misc_invalid},{suite,binary_property_test_SUITE}] -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 2.5e-5 -=group_time 0.233s +=elapsed 4.3e-5 +=group_time 0.236s =case ct_framework:end_per_group -=logfile ct_framework.end_per_group.4642.html +=logfile ct_framework.end_per_group.36898.html =group_props [{name,invalid_input},{suite,binary_property_test_SUITE}] -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 2.4e-5 -=group_time 1.314s +=elapsed 2.5e-5 +=group_time 1.327s =case binary_property_test_SUITE:end_per_suite =logfile binary_property_test_suite.end_per_suite.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok =elapsed 0.0 -=group_time 3.142s +=group_time 3.185s =case c_SUITE:init_per_suite =logfile c_suite.init_per_suite.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok =elapsed 0.0 =case c_SUITE:c_1 =logfile c_suite.c_1.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.00253 +=elapsed 0.002917 =case c_SUITE:c_2 =logfile c_suite.c_2.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.002409 +=elapsed 0.002484 =case c_SUITE:c_3 =logfile c_suite.c_3.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.005223 +=elapsed 0.005457 =case c_SUITE:c_4 =logfile c_suite.c_4.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.004291 +=elapsed 0.005564 =case c_SUITE:nc_1 =logfile c_suite.nc_1.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.001484 +=elapsed 0.001651 =case c_SUITE:nc_2 =logfile c_suite.nc_2.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.001918 +=elapsed 0.001791 =case c_SUITE:nc_3 =logfile c_suite.nc_3.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.001908 +=elapsed 0.001758 =case c_SUITE:nc_4 =logfile c_suite.nc_4.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.001852 +=elapsed 0.00196 =case c_SUITE:c_default_outdir_1 =logfile c_suite.c_default_outdir_1.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:39 =result ok -=elapsed 0.003828 +=elapsed 0.005611 =case c_SUITE:c_default_outdir_2 =logfile c_suite.c_default_outdir_2.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:39 +=ended 2024-09-12 10:33:40 =result ok -=elapsed 0.006173 +=elapsed 0.005533 =case c_SUITE:nc_default_outdir_1 =logfile c_suite.nc_default_outdir_1.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok -=elapsed 0.001648 +=elapsed 0.001896 =case c_SUITE:nc_default_outdir_2 =logfile c_suite.nc_default_outdir_2.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok -=elapsed 0.001999 +=elapsed 0.00185 =case c_SUITE:ls =logfile c_suite.ls.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok -=elapsed 5.55e-4 +=elapsed 3.01e-4 =case c_SUITE:memory =logfile c_suite.memory.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok -=elapsed 7.48e-4 +=elapsed 0.001589 =case c_SUITE:end_per_suite =logfile c_suite.end_per_suite.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok =elapsed 0.0 -=group_time 0.387s +=group_time 0.389s =case calendar_SUITE:init_per_suite =logfile calendar_suite.init_per_suite.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok =elapsed 0.0 =case calendar_SUITE:gregorian_days =logfile calendar_suite.gregorian_days.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok -=elapsed 0.003874 +=elapsed 0.003822 =case calendar_SUITE:gregorian_seconds =logfile calendar_suite.gregorian_seconds.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:31 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok -=elapsed 0.002056 +=elapsed 0.001997 =case calendar_SUITE:day_of_the_week =logfile calendar_suite.day_of_the_week.html -=started 2024-09-11 11:11:31 -=ended 2024-09-11 11:11:32 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok -=elapsed 0.004017 +=elapsed 0.003978 =case calendar_SUITE:day_of_the_week_calibrate =logfile calendar_suite.day_of_the_week_calibrate.html -=started 2024-09-11 11:11:32 -=ended 2024-09-11 11:11:32 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =case calendar_SUITE:leap_years =logfile calendar_suite.leap_years.html -=started 2024-09-11 11:11:32 -=ended 2024-09-11 11:11:32 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok =elapsed 1.0e-6 =case calendar_SUITE:last_day_of_the_month =logfile calendar_suite.last_day_of_the_month.html -=started 2024-09-11 11:11:32 -=ended 2024-09-11 11:11:32 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok -=elapsed 1.6e-5 +=elapsed 1.4e-5 =case calendar_SUITE:local_time_to_universal_time_dst =logfile calendar_suite.local_time_to_universal_time_dst.html -=started 2024-09-11 11:11:32 -=ended 2024-09-11 11:11:32 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok -=elapsed 0.002641 +=elapsed 0.002687 =case calendar_SUITE:iso_week_number =logfile calendar_suite.iso_week_number.html -=started 2024-09-11 11:11:32 -=ended 2024-09-11 11:11:32 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok =elapsed 2.0e-6 =case calendar_SUITE:system_time =logfile calendar_suite.system_time.html -=started 2024-09-11 11:11:32 -=ended 2024-09-11 11:11:32 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok -=elapsed 2.0e-5 +=elapsed 2.5e-5 =case calendar_SUITE:rfc3339 =logfile calendar_suite.rfc3339.html -=started 2024-09-11 11:11:32 -=ended 2024-09-11 11:11:32 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok -=elapsed 1.37e-4 +=elapsed 2.2e-4 =case calendar_SUITE:big_gregorian_days =logfile calendar_suite.big_gregorian_days.html -=started 2024-09-11 11:11:32 -=ended 2024-09-11 11:11:32 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok -=elapsed 0.001274 +=elapsed 0.001269 =case calendar_SUITE:end_per_suite =logfile calendar_suite.end_per_suite.html -=started 2024-09-11 11:11:32 -=ended 2024-09-11 11:11:32 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok =elapsed 0.0 -=group_time 0.287s +=group_time 0.283s =case dets_SUITE:init_per_suite =logfile dets_suite.init_per_suite.html -=started 2024-09-11 11:11:32 -=ended 2024-09-11 11:11:32 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok =elapsed 1.0e-6 =case dets_SUITE:basic =logfile dets_suite.basic.html -=started 2024-09-11 11:11:32 -=ended 2024-09-11 11:11:32 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:40 =result ok -=elapsed 0.016677 +=elapsed 0.01666 =case dets_SUITE:open =logfile dets_suite.open.html -=started 2024-09-11 11:11:32 -=ended 2024-09-11 11:11:32 +=started 2024-09-12 10:33:40 +=ended 2024-09-12 10:33:41 =result ok -=elapsed 0.609905 +=elapsed 0.609718 =case dets_SUITE:sets =logfile dets_suite.sets.html -=started 2024-09-11 11:11:32 -=ended 2024-09-11 11:11:33 +=started 2024-09-12 10:33:41 +=ended 2024-09-12 10:33:41 =result ok -=elapsed 0.345619 +=elapsed 0.351104 =case dets_SUITE:bags =logfile dets_suite.bags.html -=started 2024-09-11 11:11:33 -=ended 2024-09-11 11:11:33 +=started 2024-09-12 10:33:41 +=ended 2024-09-12 10:33:41 =result ok -=elapsed 0.438761 +=elapsed 0.444547 =case dets_SUITE:duplicate_bags =logfile dets_suite.duplicate_bags.html -=started 2024-09-11 11:11:33 -=ended 2024-09-11 11:11:34 +=started 2024-09-12 10:33:41 +=ended 2024-09-12 10:33:42 =result ok -=elapsed 0.539135 +=elapsed 0.600119 =case dets_SUITE:newly_started =logfile dets_suite.newly_started.html -=started 2024-09-11 11:11:34 -=ended 2024-09-11 11:11:34 +=started 2024-09-12 10:33:42 +=ended 2024-09-12 10:33:42 =result ok -=elapsed 0.156433 +=elapsed 0.157174 =case dets_SUITE:open_file =logfile dets_suite.open_file.html -=started 2024-09-11 11:11:34 -=ended 2024-09-11 11:11:34 +=started 2024-09-12 10:33:42 +=ended 2024-09-12 10:33:42 =result ok -=elapsed 0.065592 +=elapsed 0.072459 =case dets_SUITE:init_table =logfile dets_suite.init_table.html -=started 2024-09-11 11:11:34 -=ended 2024-09-11 11:11:36 +=started 2024-09-12 10:33:42 +=ended 2024-09-12 10:33:44 =result ok -=elapsed 1.60331 +=elapsed 1.394347 =case dets_SUITE:repair =logfile dets_suite.repair.html -=started 2024-09-11 11:11:36 -=ended 2024-09-11 11:11:38 +=started 2024-09-12 10:33:44 +=ended 2024-09-12 10:33:45 =result ok -=elapsed 2.394702 +=elapsed 1.606682 =case dets_SUITE:access =logfile dets_suite.access.html -=started 2024-09-11 11:11:38 -=ended 2024-09-11 11:11:38 +=started 2024-09-12 10:33:45 +=ended 2024-09-12 10:33:45 =result ok -=elapsed 0.007624 +=elapsed 0.0038 =case dets_SUITE:oldbugs =logfile dets_suite.oldbugs.html -=started 2024-09-11 11:11:38 -=ended 2024-09-11 11:11:38 +=started 2024-09-12 10:33:45 +=ended 2024-09-12 10:33:45 =result ok -=elapsed 0.002443 +=elapsed 0.002199 =case dets_SUITE:truncated_segment_array =logfile dets_suite.truncated_segment_array.html -=started 2024-09-11 11:11:38 -=ended 2024-09-11 11:11:38 +=started 2024-09-12 10:33:45 +=ended 2024-09-12 10:33:45 =result ok -=elapsed 0.003748 +=elapsed 0.00328 =case dets_SUITE:dirty_mark =logfile dets_suite.dirty_mark.html -=started 2024-09-11 11:11:38 -=ended 2024-09-11 11:11:38 +=started 2024-09-12 10:33:45 +=ended 2024-09-12 10:33:46 =result ok -=elapsed 0.176829 +=elapsed 0.171574 =case dets_SUITE:dirty_mark2 =logfile dets_suite.dirty_mark2.html -=started 2024-09-11 11:11:38 -=ended 2024-09-11 11:11:41 +=started 2024-09-12 10:33:46 +=ended 2024-09-12 10:33:48 =result ok -=elapsed 2.286277 +=elapsed 2.284757 =case dets_SUITE:bag_next =logfile dets_suite.bag_next.html -=started 2024-09-11 11:11:41 -=ended 2024-09-11 11:11:41 +=started 2024-09-12 10:33:48 +=ended 2024-09-12 10:33:48 =result ok -=elapsed 0.004081 +=elapsed 0.004507 =case dets_SUITE:phash =logfile dets_suite.phash.html -=started 2024-09-11 11:11:41 -=ended 2024-09-11 11:11:41 +=started 2024-09-12 10:33:48 +=ended 2024-09-12 10:33:48 =result ok -=elapsed 0.004826 +=elapsed 0.004798 =case dets_SUITE:fold =logfile dets_suite.fold.html -=started 2024-09-11 11:11:41 -=ended 2024-09-11 11:11:41 +=started 2024-09-12 10:33:48 +=ended 2024-09-12 10:33:48 =result ok -=elapsed 0.004695 +=elapsed 0.004957 =case dets_SUITE:fixtable =logfile dets_suite.fixtable.html -=started 2024-09-11 11:11:41 -=ended 2024-09-11 11:11:41 +=started 2024-09-12 10:33:48 +=ended 2024-09-12 10:33:48 =result ok -=elapsed 0.023594 +=elapsed 0.023533 =case dets_SUITE:match =logfile dets_suite.match.html -=started 2024-09-11 11:11:41 -=ended 2024-09-11 11:11:41 +=started 2024-09-12 10:33:48 +=ended 2024-09-12 10:33:48 =result ok -=elapsed 0.019133 +=elapsed 0.023703 =case dets_SUITE:select =logfile dets_suite.select.html -=started 2024-09-11 11:11:41 -=ended 2024-09-11 11:11:41 +=started 2024-09-12 10:33:48 +=ended 2024-09-12 10:33:48 =result ok -=elapsed 0.011298 +=elapsed 0.011425 =case dets_SUITE:update_counter =logfile dets_suite.update_counter.html -=started 2024-09-11 11:11:41 -=ended 2024-09-11 11:11:41 +=started 2024-09-12 10:33:48 +=ended 2024-09-12 10:33:48 =result ok -=elapsed 0.003062 +=elapsed 0.003144 =case dets_SUITE:badarg =logfile dets_suite.badarg.html -=started 2024-09-11 11:11:41 -=ended 2024-09-11 11:11:41 +=started 2024-09-12 10:33:48 +=ended 2024-09-12 10:33:48 =result ok -=elapsed 0.002683 +=elapsed 0.002866 =case dets_SUITE:cache_sets =logfile dets_suite.cache_sets.html -=started 2024-09-11 11:11:41 -=ended 2024-09-11 11:11:45 +=started 2024-09-12 10:33:48 +=ended 2024-09-12 10:33:52 =result ok -=elapsed 4.229345 +=elapsed 4.220111 =case dets_SUITE:cache_bags =logfile dets_suite.cache_bags.html -=started 2024-09-11 11:11:45 -=ended 2024-09-11 11:11:50 +=started 2024-09-12 10:33:53 +=ended 2024-09-12 10:33:58 =result ok -=elapsed 5.041371 +=elapsed 5.088539 =case dets_SUITE:cache_duplicate_bags =logfile dets_suite.cache_duplicate_bags.html -=started 2024-09-11 11:11:50 -=ended 2024-09-11 11:11:55 +=started 2024-09-12 10:33:58 +=ended 2024-09-12 10:34:03 =result ok -=elapsed 5.084939 +=elapsed 5.092181 =case dets_SUITE:otp_4208 =logfile dets_suite.otp_4208.html -=started 2024-09-11 11:11:55 -=ended 2024-09-11 11:11:55 +=started 2024-09-12 10:34:03 +=ended 2024-09-12 10:34:03 =result ok -=elapsed 8.53e-4 +=elapsed 8.82e-4 =case dets_SUITE:otp_4989 =logfile dets_suite.otp_4989.html -=started 2024-09-11 11:11:55 -=ended 2024-09-11 11:11:56 +=started 2024-09-12 10:34:03 +=ended 2024-09-12 10:34:03 =result ok -=elapsed 0.222533 +=elapsed 0.220015 =case dets_SUITE:many_clients =logfile dets_suite.many_clients.html -=started 2024-09-11 11:11:56 -=ended 2024-09-11 11:11:56 +=started 2024-09-12 10:34:03 +=ended 2024-09-12 10:34:03 =result ok -=elapsed 0.068285 +=elapsed 0.069161 =case dets_SUITE:otp_4906 =logfile dets_suite.otp_4906.html -=started 2024-09-11 11:11:56 -=ended 2024-09-11 11:12:01 +=started 2024-09-12 10:34:03 +=ended 2024-09-12 10:34:09 =result ok -=elapsed 5.427985 +=elapsed 5.412001 =case dets_SUITE:otp_5402 =logfile dets_suite.otp_5402.html -=started 2024-09-11 11:12:01 -=ended 2024-09-11 11:12:06 +=started 2024-09-12 10:34:09 +=ended 2024-09-12 10:34:14 =result ok -=elapsed 5.001473 +=elapsed 5.001232 =case dets_SUITE:simultaneous_open =logfile dets_suite.simultaneous_open.html -=started 2024-09-11 11:12:06 -=ended 2024-09-11 11:12:16 +=started 2024-09-12 10:34:14 +=ended 2024-09-12 10:34:23 =result ok -=elapsed 9.808584 +=elapsed 9.879177 =case dets_SUITE:insert_new =logfile dets_suite.insert_new.html -=started 2024-09-11 11:12:16 -=ended 2024-09-11 11:12:16 +=started 2024-09-12 10:34:23 +=ended 2024-09-12 10:34:23 =result ok -=elapsed 8.74e-4 +=elapsed 7.78e-4 =case dets_SUITE:repair_continuation =logfile dets_suite.repair_continuation.html -=started 2024-09-11 11:12:16 -=ended 2024-09-11 11:12:16 +=started 2024-09-12 10:34:23 +=ended 2024-09-12 10:34:23 =result ok -=elapsed 0.006045 +=elapsed 0.005065 =case dets_SUITE:otp_5487 =logfile dets_suite.otp_5487.html -=started 2024-09-11 11:12:16 -=ended 2024-09-11 11:12:16 +=started 2024-09-12 10:34:23 +=ended 2024-09-12 10:34:24 =result ok -=elapsed 0.002988 +=elapsed 0.003763 =case dets_SUITE:otp_6206 =logfile dets_suite.otp_6206.html -=started 2024-09-11 11:12:16 -=ended 2024-09-11 11:12:17 +=started 2024-09-12 10:34:24 +=ended 2024-09-12 10:34:24 =result ok -=elapsed 0.366466 +=elapsed 0.400207 =case dets_SUITE:otp_6359 =logfile dets_suite.otp_6359.html -=started 2024-09-11 11:12:17 -=ended 2024-09-11 11:12:17 +=started 2024-09-12 10:34:24 +=ended 2024-09-12 10:34:24 =result ok -=elapsed 2.86e-4 +=elapsed 2.87e-4 =case dets_SUITE:otp_4738 =logfile dets_suite.otp_4738.html -=started 2024-09-11 11:12:17 -=ended 2024-09-11 11:12:17 +=started 2024-09-12 10:34:24 +=ended 2024-09-12 10:34:24 =result ok -=elapsed 0.007905 +=elapsed 0.011819 =case dets_SUITE:otp_7146 =logfile dets_suite.otp_7146.html -=started 2024-09-11 11:12:17 -=ended 2024-09-11 11:12:17 +=started 2024-09-12 10:34:24 +=ended 2024-09-12 10:34:24 =result ok -=elapsed 0.032056 +=elapsed 0.11953 =case dets_SUITE:otp_8070 =logfile dets_suite.otp_8070.html -=started 2024-09-11 11:12:17 -=ended 2024-09-11 11:12:17 +=started 2024-09-12 10:34:24 +=ended 2024-09-12 10:34:24 =result ok -=elapsed 3.24e-4 +=elapsed 4.95e-4 =case dets_SUITE:otp_8856 =logfile dets_suite.otp_8856.html -=started 2024-09-11 11:12:17 -=ended 2024-09-11 11:12:17 +=started 2024-09-12 10:34:24 +=ended 2024-09-12 10:34:24 =result ok -=elapsed 6.24e-4 +=elapsed 8.39e-4 =case dets_SUITE:otp_8898 =logfile dets_suite.otp_8898.html -=started 2024-09-11 11:12:17 -=ended 2024-09-11 11:12:17 +=started 2024-09-12 10:34:24 +=ended 2024-09-12 10:34:24 =result ok -=elapsed 0.007767 +=elapsed 0.008357 =case dets_SUITE:otp_8899 =logfile dets_suite.otp_8899.html -=started 2024-09-11 11:12:17 -=ended 2024-09-11 11:12:17 +=started 2024-09-12 10:34:24 +=ended 2024-09-12 10:34:24 =result ok -=elapsed 0.008892 +=elapsed 0.008427 =case dets_SUITE:otp_8903 =logfile dets_suite.otp_8903.html -=started 2024-09-11 11:12:17 -=ended 2024-09-11 11:12:17 +=started 2024-09-12 10:34:24 +=ended 2024-09-12 10:34:24 =result ok -=elapsed 5.77e-4 +=elapsed 9.29e-4 =case dets_SUITE:otp_8923 =logfile dets_suite.otp_8923.html -=started 2024-09-11 11:12:17 -=ended 2024-09-11 11:12:17 +=started 2024-09-12 10:34:24 +=ended 2024-09-12 10:34:24 =result ok -=elapsed 0.003922 +=elapsed 0.00472 =case dets_SUITE:otp_9282 =logfile dets_suite.otp_9282.html -=started 2024-09-11 11:12:17 -=ended 2024-09-11 11:12:17 +=started 2024-09-12 10:34:24 +=ended 2024-09-12 10:34:24 =result ok -=elapsed 0.001082 +=elapsed 0.001669 =case dets_SUITE:otp_11245 =logfile dets_suite.otp_11245.html -=started 2024-09-11 11:12:17 -=ended 2024-09-11 11:12:17 +=started 2024-09-12 10:34:24 +=ended 2024-09-12 10:34:24 =result ok -=elapsed 0.019552 +=elapsed 0.058831 =case dets_SUITE:otp_11709 =logfile dets_suite.otp_11709.html -=started 2024-09-11 11:12:17 -=ended 2024-09-11 11:12:17 +=started 2024-09-12 10:34:24 +=ended 2024-09-12 10:34:24 =result ok -=elapsed 0.029917 +=elapsed 0.029535 =case dets_SUITE:otp_13229 =logfile dets_suite.otp_13229.html -=started 2024-09-11 11:12:17 -=ended 2024-09-11 11:12:17 +=started 2024-09-12 10:34:24 +=ended 2024-09-12 10:34:24 =result ok -=elapsed 5.0e-6 +=elapsed 6.0e-6 =case dets_SUITE:otp_13260 =logfile dets_suite.otp_13260.html -=started 2024-09-11 11:12:17 -=ended 2024-09-11 11:12:17 +=started 2024-09-12 10:34:24 +=ended 2024-09-12 10:34:25 =result ok -=elapsed 0.204349 +=elapsed 0.305124 =case dets_SUITE:otp_13830 =logfile dets_suite.otp_13830.html -=started 2024-09-11 11:12:17 -=ended 2024-09-11 11:12:17 +=started 2024-09-12 10:34:25 +=ended 2024-09-12 10:34:25 =result ok -=elapsed 5.92e-4 +=elapsed 6.23e-4 =case dets_SUITE:receive_optimisation =logfile dets_suite.receive_optimisation.html -=started 2024-09-11 11:12:17 -=ended 2024-09-11 11:12:18 +=started 2024-09-12 10:34:25 +=ended 2024-09-12 10:34:25 =result ok -=elapsed 0.146613 +=elapsed 0.147484 =case dets_SUITE:end_per_suite =logfile dets_suite.end_per_suite.html -=started 2024-09-11 11:12:18 -=ended 2024-09-11 11:12:18 +=started 2024-09-12 10:34:25 +=ended 2024-09-12 10:34:25 =result ok =elapsed 1.0e-6 -=group_time 45.813s +=group_time 45.259s =case dict_SUITE:init_per_suite =logfile dict_suite.init_per_suite.html -=started 2024-09-11 11:12:18 -=ended 2024-09-11 11:12:18 +=started 2024-09-12 10:34:25 +=ended 2024-09-12 10:34:25 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =case dict_SUITE:create =logfile dict_suite.create.html -=started 2024-09-11 11:12:18 -=ended 2024-09-11 11:12:18 +=started 2024-09-12 10:34:25 +=ended 2024-09-12 10:34:25 =result ok -=elapsed 2.4e-5 +=elapsed 2.9e-5 =case dict_SUITE:store =logfile dict_suite.store.html -=started 2024-09-11 11:12:18 -=ended 2024-09-11 11:12:18 +=started 2024-09-12 10:34:25 +=ended 2024-09-12 10:34:26 =result ok -=elapsed 0.481611 +=elapsed 0.456093 =case dict_SUITE:remove =logfile dict_suite.remove.html -=started 2024-09-11 11:12:18 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:26 +=ended 2024-09-12 10:34:26 =result ok -=elapsed 0.577496 +=elapsed 0.5533 =case dict_SUITE:iterate =logfile dict_suite.iterate.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:26 +=ended 2024-09-12 10:34:26 =result ok -=elapsed 0.106648 +=elapsed 0.107022 =case dict_SUITE:end_per_suite =logfile dict_suite.end_per_suite.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:26 +=ended 2024-09-12 10:34:26 =result ok =elapsed 0.0 -=group_time 1.280s +=group_time 1.234s =case digraph_SUITE:init_per_suite =logfile digraph_suite.init_per_suite.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:26 +=ended 2024-09-12 10:34:26 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =case digraph_SUITE:opts =logfile digraph_suite.opts.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:26 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 1.27e-4 +=elapsed 1.78e-4 =case digraph_SUITE:degree =logfile digraph_suite.degree.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 7.3e-5 +=elapsed 1.04e-4 =case digraph_SUITE:path =logfile digraph_suite.path.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 7.8e-5 +=elapsed 1.14e-4 =case digraph_SUITE:cycle =logfile digraph_suite.cycle.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 9.6e-5 +=elapsed 1.39e-4 =case digraph_SUITE:init_per_group =logfile digraph_suite.init_per_group.html =group_props [{name,misc}] -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok =elapsed 0.0 =case digraph_SUITE:vertices =logfile digraph_suite.vertices.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok =elapsed 3.5e-5 =case digraph_SUITE:edges =logfile digraph_suite.edges.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 6.2e-5 +=elapsed 6.3e-5 =case digraph_SUITE:data =logfile digraph_suite.data.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok =elapsed 6.3e-5 =case digraph_SUITE:vertex_names =logfile digraph_suite.vertex_names.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok =elapsed 2.7e-5 =case digraph_SUITE:end_per_group =logfile digraph_suite.end_per_group.html =group_props [{name,misc}] -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok =elapsed 0.0 -=group_time 0.114s +=group_time 0.115s =case digraph_SUITE:init_per_group -=logfile digraph_suite.init_per_group.7138.html +=logfile digraph_suite.init_per_group.39426.html =group_props [{name,tickets}] -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok =elapsed 0.0 =case digraph_SUITE:otp_3522 =logfile digraph_suite.otp_3522.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok =elapsed 7.5e-5 =case digraph_SUITE:otp_3630 =logfile digraph_suite.otp_3630.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 2.35e-4 +=elapsed 2.38e-4 =case digraph_SUITE:otp_8066 =logfile digraph_suite.otp_8066.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 1.94e-4 +=elapsed 0.0002 =case digraph_SUITE:end_per_group -=logfile digraph_suite.end_per_group.7170.html +=logfile digraph_suite.end_per_group.39458.html =group_props [{name,tickets}] -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok =elapsed 0.0 =group_time 0.092s =case digraph_SUITE:vertex_names -=logfile digraph_suite.vertex_names.7202.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=logfile digraph_suite.vertex_names.39490.html +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok =elapsed 2.6e-5 =case digraph_SUITE:end_per_suite =logfile digraph_suite.end_per_suite.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok =elapsed 0.0 -=group_time 0.389s +=group_time 0.395s =case digraph_utils_SUITE:init_per_suite =logfile digraph_utils_suite.init_per_suite.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =case digraph_utils_SUITE:simple =logfile digraph_utils_suite.simple.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 2.03e-4 +=elapsed 2.02e-4 =case digraph_utils_SUITE:loop =logfile digraph_utils_suite.loop.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 5.1e-5 +=elapsed 8.0e-5 =case digraph_utils_SUITE:isolated =logfile digraph_utils_suite.isolated.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 4.6e-5 +=elapsed 7.2e-5 =case digraph_utils_SUITE:topsort =logfile digraph_utils_suite.topsort.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 3.2e-5 +=elapsed 4.5e-5 =case digraph_utils_SUITE:subgraph =logfile digraph_utils_suite.subgraph.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 6.6e-5 +=elapsed 9.8e-5 =case digraph_utils_SUITE:condensation =logfile digraph_utils_suite.condensation.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 8.1e-5 +=elapsed 1.19e-4 =case digraph_utils_SUITE:tree =logfile digraph_utils_suite.tree.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 2.55e-4 +=elapsed 3.38e-4 =case digraph_utils_SUITE:end_per_suite =logfile digraph_utils_suite.end_per_suite.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:19 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 0.0 -=group_time 0.182s +=elapsed 1.0e-6 +=group_time 0.188s =case edlin_context_SUITE:init_per_suite =logfile edlin_context_suite.init_per_suite.html -=started 2024-09-11 11:12:19 -=ended 2024-09-11 11:12:20 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =case edlin_context_SUITE:get_context =logfile edlin_context_suite.get_context.html -=started 2024-09-11 11:12:20 -=ended 2024-09-11 11:12:20 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 0.012721 +=elapsed 0.012304 =case edlin_context_SUITE:end_per_suite =logfile edlin_context_suite.end_per_suite.html -=started 2024-09-11 11:12:20 -=ended 2024-09-11 11:12:20 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok =elapsed 0.0 -=group_time 0.061s +=group_time 0.064s =case edlin_expand_SUITE:init_per_suite =logfile edlin_expand_suite.init_per_suite.html -=started 2024-09-11 11:12:20 -=ended 2024-09-11 11:12:20 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok =elapsed 0.0 =case edlin_expand_SUITE:normal =logfile edlin_expand_suite.normal.html -=started 2024-09-11 11:12:20 -=ended 2024-09-11 11:12:20 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 0.03547 +=elapsed 0.033352 =case edlin_expand_SUITE:filename_completion =logfile edlin_expand_suite.filename_completion.html -=started 2024-09-11 11:12:20 -=ended 2024-09-11 11:12:20 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 0.039355 +=elapsed 0.036355 =case edlin_expand_SUITE:binding_completion =logfile edlin_expand_suite.binding_completion.html -=started 2024-09-11 11:12:20 -=ended 2024-09-11 11:12:20 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:27 =result ok -=elapsed 0.009756 +=elapsed 0.009908 =case edlin_expand_SUITE:get_coverage =logfile edlin_expand_suite.get_coverage.html -=started 2024-09-11 11:12:20 -=ended 2024-09-11 11:12:22 +=started 2024-09-12 10:34:27 +=ended 2024-09-12 10:34:29 =result ok -=elapsed 1.863047 +=elapsed 1.808087 =case edlin_expand_SUITE:type_completion =logfile edlin_expand_suite.type_completion.html -=started 2024-09-11 11:12:22 -=ended 2024-09-11 11:12:27 -=result skipped: "Expansion too slow (5417815) on this machine" +=started 2024-09-12 10:34:29 +=ended 2024-09-12 10:34:35 +=result skipped: "Expansion too slow (5407207) on this machine" === *** SKIPPED test case 278 *** =case edlin_expand_SUITE:record_completion =logfile edlin_expand_suite.record_completion.html -=started 2024-09-11 11:12:27 -=ended 2024-09-11 11:12:27 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok -=elapsed 0.061194 +=elapsed 0.066516 =case edlin_expand_SUITE:fun_completion =logfile edlin_expand_suite.fun_completion.html -=started 2024-09-11 11:12:27 -=ended 2024-09-11 11:12:27 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok -=elapsed 0.044571 +=elapsed 0.043242 =case edlin_expand_SUITE:map_completion =logfile edlin_expand_suite.map_completion.html -=started 2024-09-11 11:12:27 -=ended 2024-09-11 11:12:27 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok -=elapsed 0.009009 +=elapsed 0.008765 =case edlin_expand_SUITE:function_parameter_completion =logfile edlin_expand_suite.function_parameter_completion.html -=started 2024-09-11 11:12:27 -=ended 2024-09-11 11:12:27 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok -=elapsed 0.115334 +=elapsed 0.113808 =case edlin_expand_SUITE:no_completion =logfile edlin_expand_suite.no_completion.html -=started 2024-09-11 11:12:27 -=ended 2024-09-11 11:12:27 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok -=elapsed 0.00608 +=elapsed 0.005947 =case edlin_expand_SUITE:quoted_fun =logfile edlin_expand_suite.quoted_fun.html -=started 2024-09-11 11:12:27 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok -=elapsed 0.041569 +=elapsed 0.046113 =case edlin_expand_SUITE:quoted_module =logfile edlin_expand_suite.quoted_module.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok -=elapsed 0.018715 +=elapsed 0.019607 =case edlin_expand_SUITE:quoted_both =logfile edlin_expand_suite.quoted_both.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok -=elapsed 0.03098 +=elapsed 0.031562 =case edlin_expand_SUITE:erl_1152 =logfile edlin_expand_suite.erl_1152.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok =elapsed 1.9e-5 =case edlin_expand_SUITE:check_trailing =logfile edlin_expand_suite.check_trailing.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok -=elapsed 3.4e-5 +=elapsed 3.1e-5 =case edlin_expand_SUITE:invalid_module =logfile edlin_expand_suite.invalid_module.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok -=elapsed 0.033026 +=elapsed 0.031346 =case edlin_expand_SUITE:unicode =logfile edlin_expand_suite.unicode.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok -=elapsed 0.010708 +=elapsed 0.011424 =case edlin_expand_SUITE:end_per_suite =logfile edlin_expand_suite.end_per_suite.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok -=elapsed 0.002971 -=group_time 8.225s +=elapsed 0.003232 +=group_time 8.161s =case epp_SUITE:init_per_suite =logfile epp_suite.init_per_suite.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok =elapsed 0.0 =case epp_SUITE:rec_1 =logfile epp_suite.rec_1.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok -=elapsed 0.001248 +=elapsed 0.001254 =case epp_SUITE:init_per_group =logfile epp_suite.init_per_group.html =group_props [{name,upcase_mac}] -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok =elapsed 0.0 =case epp_SUITE:upcase_mac_1 =logfile epp_suite.upcase_mac_1.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok -=elapsed 3.67e-4 +=elapsed 4.44e-4 =case epp_SUITE:upcase_mac_2 =logfile epp_suite.upcase_mac_2.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:35 =result ok -=elapsed 3.54e-4 +=elapsed 3.78e-4 =case epp_SUITE:end_per_group =logfile epp_suite.end_per_group.html =group_props [{name,upcase_mac}] -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:35 +=ended 2024-09-12 10:34:36 =result ok =elapsed 0.0 -=group_time 0.070s +=group_time 0.071s =case epp_SUITE:include_local =logfile epp_suite.include_local.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:36 +=ended 2024-09-12 10:34:36 =result ok -=elapsed 6.24e-4 +=elapsed 6.35e-4 =case epp_SUITE:predef_mac =logfile epp_suite.predef_mac.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:36 +=ended 2024-09-12 10:34:36 =result ok -=elapsed 3.76e-4 +=elapsed 3.72e-4 =case epp_SUITE:init_per_group -=logfile epp_suite.init_per_group.7234.html +=logfile epp_suite.init_per_group.39522.html =group_props [{name,variable}] -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:36 +=ended 2024-09-12 10:34:36 =result ok =elapsed 0.0 =case epp_SUITE:variable_1 =logfile epp_suite.variable_1.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:36 +=ended 2024-09-12 10:34:36 =result ok -=elapsed 7.58e-4 +=elapsed 7.29e-4 =case epp_SUITE:end_per_group -=logfile epp_suite.end_per_group.7266.html +=logfile epp_suite.end_per_group.39554.html =group_props [{name,variable}] -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:36 +=ended 2024-09-12 10:34:36 =result ok =elapsed 0.0 -=group_time 0.047s +=group_time 0.046s =case epp_SUITE:otp_4870 =logfile epp_suite.otp_4870.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:36 +=ended 2024-09-12 10:34:36 =result ok -=elapsed 7.72e-4 +=elapsed 7.71e-4 =case epp_SUITE:otp_4871 =logfile epp_suite.otp_4871.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:36 +=ended 2024-09-12 10:34:36 =result ok -=elapsed 0.004037 +=elapsed 0.004093 =case epp_SUITE:otp_5362 =logfile epp_suite.otp_5362.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:36 +=ended 2024-09-12 10:34:36 =result ok -=elapsed 0.009475 +=elapsed 0.009522 =case epp_SUITE:pmod =logfile epp_suite.pmod.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:36 +=ended 2024-09-12 10:34:36 =result ok -=elapsed 2.18e-4 +=elapsed 2.81e-4 =case epp_SUITE:not_circular =logfile epp_suite.not_circular.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:36 +=ended 2024-09-12 10:34:36 =result ok -=elapsed 0.157893 +=elapsed 0.156888 =case epp_SUITE:skip_header =logfile epp_suite.skip_header.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:36 +=ended 2024-09-12 10:34:36 =result ok -=elapsed 4.57e-4 +=elapsed 3.34e-4 =case epp_SUITE:otp_6277 =logfile epp_suite.otp_6277.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:36 +=ended 2024-09-12 10:34:36 =result ok -=elapsed 8.18e-4 +=elapsed 6.74e-4 =case epp_SUITE:gh_4995 =logfile epp_suite.gh_4995.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:36 +=ended 2024-09-12 10:34:36 =result ok -=elapsed 7.04e-4 +=elapsed 5.73e-4 =case epp_SUITE:otp_7702 =logfile epp_suite.otp_7702.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:28 +=started 2024-09-12 10:34:36 +=ended 2024-09-12 10:34:36 =result ok -=elapsed 0.002561 +=elapsed 0.002227 =case epp_SUITE:otp_8130 =logfile epp_suite.otp_8130.html -=started 2024-09-11 11:12:28 -=ended 2024-09-11 11:12:31 +=started 2024-09-12 10:34:36 +=ended 2024-09-12 10:34:39 =result ok -=elapsed 2.669461 +=elapsed 2.631588 =case epp_SUITE:overload_mac =logfile epp_suite.overload_mac.html -=started 2024-09-11 11:12:31 -=ended 2024-09-11 11:12:32 +=started 2024-09-12 10:34:39 +=ended 2024-09-12 10:34:39 =result ok -=elapsed 0.479792 +=elapsed 0.467683 =case epp_SUITE:otp_8388 =logfile epp_suite.otp_8388.html -=started 2024-09-11 11:12:32 -=ended 2024-09-11 11:12:32 +=started 2024-09-12 10:34:39 +=ended 2024-09-12 10:34:39 =result ok -=elapsed 0.00617 +=elapsed 0.006834 =case epp_SUITE:otp_8470 =logfile epp_suite.otp_8470.html -=started 2024-09-11 11:12:32 -=ended 2024-09-11 11:12:32 +=started 2024-09-12 10:34:39 +=ended 2024-09-12 10:34:39 =result ok -=elapsed 3.52e-4 +=elapsed 3.87e-4 =case epp_SUITE:otp_8562 =logfile epp_suite.otp_8562.html -=started 2024-09-11 11:12:32 -=ended 2024-09-11 11:12:32 +=started 2024-09-12 10:34:39 +=ended 2024-09-12 10:34:39 =result ok -=elapsed 0.001103 +=elapsed 0.001091 =case epp_SUITE:otp_8665 =logfile epp_suite.otp_8665.html -=started 2024-09-11 11:12:32 -=ended 2024-09-11 11:12:32 +=started 2024-09-12 10:34:39 +=ended 2024-09-12 10:34:39 =result ok -=elapsed 8.84e-4 +=elapsed 9.76e-4 =case epp_SUITE:otp_8911 =logfile epp_suite.otp_8911.html -=started 2024-09-11 11:12:32 -=ended 2024-09-11 11:12:32 +=started 2024-09-12 10:34:39 +=ended 2024-09-12 10:34:39 =result ok -=elapsed 0.012591 +=elapsed 0.013104 =case epp_SUITE:otp_10302 =logfile epp_suite.otp_10302.html -=started 2024-09-11 11:12:32 -=ended 2024-09-11 11:12:32 +=started 2024-09-12 10:34:39 +=ended 2024-09-12 10:34:39 =result ok -=elapsed 0.132495 +=elapsed 0.135884 =case epp_SUITE:otp_10820 =logfile epp_suite.otp_10820.html -=started 2024-09-11 11:12:32 -=ended 2024-09-11 11:12:33 +=started 2024-09-12 10:34:39 +=ended 2024-09-12 10:34:40 =result ok -=elapsed 0.65199 +=elapsed 0.66037 =case epp_SUITE:otp_11728 =logfile epp_suite.otp_11728.html -=started 2024-09-11 11:12:33 -=ended 2024-09-11 11:12:33 +=started 2024-09-12 10:34:40 +=ended 2024-09-12 10:34:40 =result ok -=elapsed 0.001014 +=elapsed 8.13e-4 =case epp_SUITE:encoding =logfile epp_suite.encoding.html -=started 2024-09-11 11:12:33 -=ended 2024-09-11 11:12:33 +=started 2024-09-12 10:34:40 +=ended 2024-09-12 10:34:40 =result ok -=elapsed 0.001704 +=elapsed 0.002274 =case epp_SUITE:extends =logfile epp_suite.extends.html -=started 2024-09-11 11:12:33 -=ended 2024-09-11 11:12:33 +=started 2024-09-12 10:34:40 +=ended 2024-09-12 10:34:40 =result ok -=elapsed 0.154441 +=elapsed 0.15724 =case epp_SUITE:function_macro =logfile epp_suite.function_macro.html -=started 2024-09-11 11:12:33 -=ended 2024-09-11 11:12:33 +=started 2024-09-12 10:34:40 +=ended 2024-09-12 10:34:41 =result ok -=elapsed 0.635106 +=elapsed 0.653432 =case epp_SUITE:test_error =logfile epp_suite.test_error.html -=started 2024-09-11 11:12:34 -=ended 2024-09-11 11:12:34 +=started 2024-09-12 10:34:41 +=ended 2024-09-12 10:34:41 =result ok -=elapsed 0.003125 +=elapsed 0.003111 =case epp_SUITE:test_warning =logfile epp_suite.test_warning.html -=started 2024-09-11 11:12:34 -=ended 2024-09-11 11:12:34 +=started 2024-09-12 10:34:41 +=ended 2024-09-12 10:34:41 =result ok -=elapsed 0.00593 +=elapsed 0.007273 =case epp_SUITE:otp_14285 =logfile epp_suite.otp_14285.html -=started 2024-09-11 11:12:34 -=ended 2024-09-11 11:12:34 +=started 2024-09-12 10:34:41 +=ended 2024-09-12 10:34:41 =result ok -=elapsed 0.001151 +=elapsed 0.001277 =case epp_SUITE:test_if =logfile epp_suite.test_if.html -=started 2024-09-11 11:12:34 -=ended 2024-09-11 11:12:35 +=started 2024-09-12 10:34:41 +=ended 2024-09-12 10:34:42 =result ok -=elapsed 1.139802 +=elapsed 1.171062 =case epp_SUITE:source_name =logfile epp_suite.source_name.html -=started 2024-09-11 11:12:35 -=ended 2024-09-11 11:12:35 +=started 2024-09-12 10:34:42 +=ended 2024-09-12 10:34:42 =result ok -=elapsed 0.001215 +=elapsed 0.00109 =case epp_SUITE:otp_16978 =logfile epp_suite.otp_16978.html -=started 2024-09-11 11:12:35 -=ended 2024-09-11 11:12:35 +=started 2024-09-12 10:34:42 +=ended 2024-09-12 10:34:43 =result ok -=elapsed 0.473777 +=elapsed 0.487348 =case epp_SUITE:otp_16824 =logfile epp_suite.otp_16824.html -=started 2024-09-11 11:12:35 -=ended 2024-09-11 11:12:35 +=started 2024-09-12 10:34:43 +=ended 2024-09-12 10:34:43 =result ok -=elapsed 0.040991 +=elapsed 0.047685 =case epp_SUITE:scan_file =logfile epp_suite.scan_file.html -=started 2024-09-11 11:12:35 -=ended 2024-09-11 11:12:35 +=started 2024-09-12 10:34:43 +=ended 2024-09-12 10:34:43 =result ok -=elapsed 5.34e-4 +=elapsed 6.46e-4 =case epp_SUITE:file_macro =logfile epp_suite.file_macro.html -=started 2024-09-11 11:12:35 -=ended 2024-09-11 11:12:35 +=started 2024-09-12 10:34:43 +=ended 2024-09-12 10:34:43 =result ok -=elapsed 5.21e-4 +=elapsed 5.29e-4 =case epp_SUITE:deterministic_include =logfile epp_suite.deterministic_include.html -=started 2024-09-11 11:12:35 -=ended 2024-09-11 11:12:35 +=started 2024-09-12 10:34:43 +=ended 2024-09-12 10:34:43 =result ok -=elapsed 0.001025 +=elapsed 9.78e-4 =case epp_SUITE:nondeterministic_include =logfile epp_suite.nondeterministic_include.html -=started 2024-09-11 11:12:35 -=ended 2024-09-11 11:12:35 +=started 2024-09-12 10:34:43 +=ended 2024-09-12 10:34:43 =result ok -=elapsed 0.001009 +=elapsed 9.28e-4 =case epp_SUITE:gh_8268 =logfile epp_suite.gh_8268.html -=started 2024-09-11 11:12:35 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:43 +=ended 2024-09-12 10:34:43 =result ok -=elapsed 0.309197 +=elapsed 0.318196 =case epp_SUITE:moduledoc_include =logfile epp_suite.moduledoc_include.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:43 +=ended 2024-09-12 10:34:43 =result ok -=elapsed 0.001628 +=elapsed 0.001437 =case epp_SUITE:end_per_suite =logfile epp_suite.end_per_suite.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:43 +=ended 2024-09-12 10:34:43 =result ok =elapsed 0.0 -=group_time 7.965s +=group_time 8.013s =case erl_anno_SUITE:init_per_suite =logfile erl_anno_suite.init_per_suite.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:43 +=ended 2024-09-12 10:34:43 =result ok =elapsed 0.0 =case erl_anno_SUITE:init_per_group =logfile erl_anno_suite.init_per_group.html =group_props [{name,anno}] -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:43 +=ended 2024-09-12 10:34:43 =result ok =elapsed 0.0 =case erl_anno_SUITE:new =logfile erl_anno_suite.new.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:43 +=ended 2024-09-12 10:34:43 =result ok =elapsed 2.0e-6 =case erl_anno_SUITE:is_anno =logfile erl_anno_suite.is_anno.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:43 +=ended 2024-09-12 10:34:44 =result ok =elapsed 4.0e-6 =case erl_anno_SUITE:generated =logfile erl_anno_suite.generated.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 2.9e-5 +=elapsed 3.0e-5 =case erl_anno_SUITE:end_location =logfile erl_anno_suite.end_location.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 1.5e-5 +=elapsed 1.3e-5 =case erl_anno_SUITE:file =logfile erl_anno_suite.file.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok =elapsed 1.0e-5 =case erl_anno_SUITE:line =logfile erl_anno_suite.line.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 9.0e-6 +=elapsed 7.0e-6 =case erl_anno_SUITE:location =logfile erl_anno_suite.location.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 2.6e-5 +=elapsed 1.8e-5 =case erl_anno_SUITE:record =logfile erl_anno_suite.record.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 3.6e-5 +=elapsed 2.6e-5 =case erl_anno_SUITE:text =logfile erl_anno_suite.text.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 1.3e-5 +=elapsed 1.0e-5 =case erl_anno_SUITE:bad =logfile erl_anno_suite.bad.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 9.0e-6 +=elapsed 7.0e-6 =case erl_anno_SUITE:end_per_group =logfile erl_anno_suite.end_per_group.html =group_props [{name,anno}] -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok =elapsed 0.0 -=group_time 0.251s +=group_time 0.244s =case erl_anno_SUITE:init_per_group -=logfile erl_anno_suite.init_per_group.8962.html +=logfile erl_anno_suite.init_per_group.40866.html =group_props [{name,parse}] -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok =elapsed 0.0 =case erl_anno_SUITE:parse_abstract =logfile erl_anno_suite.parse_abstract.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 3.2e-5 +=elapsed 2.6e-5 =case erl_anno_SUITE:mapfold_anno =logfile erl_anno_suite.mapfold_anno.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 3.0e-5 +=elapsed 2.4e-5 =case erl_anno_SUITE:end_per_group -=logfile erl_anno_suite.end_per_group.8994.html +=logfile erl_anno_suite.end_per_group.40898.html =group_props [{name,parse}] -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok =elapsed 0.0 -=group_time 0.069s +=group_time 0.067s =case erl_anno_SUITE:end_per_suite =logfile erl_anno_suite.end_per_suite.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok =elapsed 0.0 -=group_time 0.394s +=group_time 0.382s =case erl_eval_SUITE:init_per_suite =logfile erl_eval_suite.init_per_suite.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =case erl_eval_SUITE:guard_1 =logfile erl_eval_suite.guard_1.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 4.7e-5 +=elapsed 5.2e-5 =case erl_eval_SUITE:guard_2 =logfile erl_eval_suite.guard_2.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 2.7e-5 +=elapsed 2.8e-5 =case erl_eval_SUITE:match_pattern =logfile erl_eval_suite.match_pattern.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 5.42e-4 +=elapsed 5.45e-4 =case erl_eval_SUITE:string_plusplus =logfile erl_eval_suite.string_plusplus.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 3.26e-4 +=elapsed 3.22e-4 =case erl_eval_SUITE:pattern_expr =logfile erl_eval_suite.pattern_expr.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 1.8e-4 +=elapsed 2.21e-4 =case erl_eval_SUITE:match_bin =logfile erl_eval_suite.match_bin.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 3.09e-4 +=elapsed 3.23e-4 =case erl_eval_SUITE:guard_3 =logfile erl_eval_suite.guard_3.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 3.86e-4 +=elapsed 3.84e-4 =case erl_eval_SUITE:guard_4 =logfile erl_eval_suite.guard_4.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 7.88e-4 +=elapsed 8.11e-4 =case erl_eval_SUITE:guard_5 =logfile erl_eval_suite.guard_5.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 3.0e-5 +=elapsed 4.2e-5 =case erl_eval_SUITE:lc =logfile erl_eval_suite.lc.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:36 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 8.39e-4 +=elapsed 8.5e-4 =case erl_eval_SUITE:simple_cases =logfile erl_eval_suite.simple_cases.html -=started 2024-09-11 11:12:36 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 0.106816 +=elapsed 0.106825 =case erl_eval_SUITE:unary_plus =logfile erl_eval_suite.unary_plus.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 5.4e-5 +=elapsed 5.5e-5 =case erl_eval_SUITE:apply_atom =logfile erl_eval_suite.apply_atom.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 5.2e-5 +=elapsed 5.4e-5 =case erl_eval_SUITE:otp_5269 =logfile erl_eval_suite.otp_5269.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 0.001533 +=elapsed 0.001603 =case erl_eval_SUITE:otp_6539 =logfile erl_eval_suite.otp_6539.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 2.53e-4 +=elapsed 3.14e-4 =case erl_eval_SUITE:otp_6543 =logfile erl_eval_suite.otp_6543.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 0.005093 +=elapsed 0.005107 =case erl_eval_SUITE:otp_6787 =logfile erl_eval_suite.otp_6787.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 0.002003 +=elapsed 0.002137 =case erl_eval_SUITE:otp_6977 =logfile erl_eval_suite.otp_6977.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 1.22e-4 +=elapsed 1.25e-4 =case erl_eval_SUITE:otp_7550 =logfile erl_eval_suite.otp_7550.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 0.001534 +=elapsed 0.0016 =case erl_eval_SUITE:otp_8133 =logfile erl_eval_suite.otp_8133.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 7.34e-4 +=elapsed 7.51e-4 =case erl_eval_SUITE:otp_10622 =logfile erl_eval_suite.otp_10622.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 0.001054 +=elapsed 0.001049 =case erl_eval_SUITE:otp_13228 =logfile erl_eval_suite.otp_13228.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok =elapsed 1.1e-5 =case erl_eval_SUITE:otp_14826 =logfile erl_eval_suite.otp_14826.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:44 =result ok -=elapsed 0.002409 +=elapsed 0.001825 =case erl_eval_SUITE:funs =logfile erl_eval_suite.funs.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:44 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 0.071974 +=elapsed 0.071364 =case erl_eval_SUITE:custom_stacktrace =logfile erl_eval_suite.custom_stacktrace.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 2.17e-4 +=elapsed 2.14e-4 =case erl_eval_SUITE:try_catch =logfile erl_eval_suite.try_catch.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 0.002374 +=elapsed 0.002324 =case erl_eval_SUITE:eval_expr_5 =logfile erl_eval_suite.eval_expr_5.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok =elapsed 1.7e-5 =case erl_eval_SUITE:zero_width =logfile erl_eval_suite.zero_width.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 1.64e-4 +=elapsed 1.61e-4 =case erl_eval_SUITE:eep37 =logfile erl_eval_suite.eep37.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 5.7e-4 +=elapsed 5.28e-4 =case erl_eval_SUITE:eep43 =logfile erl_eval_suite.eep43.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 0.001154 +=elapsed 0.001148 =case erl_eval_SUITE:otp_15035 =logfile erl_eval_suite.otp_15035.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 5.9e-4 +=elapsed 6.26e-4 =case erl_eval_SUITE:otp_16439 =logfile erl_eval_suite.otp_16439.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 2.25e-4 +=elapsed 2.23e-4 =case erl_eval_SUITE:otp_14708 =logfile erl_eval_suite.otp_14708.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 0.001065 +=elapsed 9.93e-4 =case erl_eval_SUITE:otp_16545 =logfile erl_eval_suite.otp_16545.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 2.86e-4 +=elapsed 2.23e-4 =case erl_eval_SUITE:otp_16865 =logfile erl_eval_suite.otp_16865.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 2.99e-4 +=elapsed 2.45e-4 =case erl_eval_SUITE:eep49 =logfile erl_eval_suite.eep49.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 0.001122 +=elapsed 0.001046 =case erl_eval_SUITE:binary_and_map_aliases =logfile erl_eval_suite.binary_and_map_aliases.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 8.06e-4 +=elapsed 8.12e-4 =case erl_eval_SUITE:eep58 =logfile erl_eval_suite.eep58.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 8.9e-4 +=elapsed 8.15e-4 =case erl_eval_SUITE:end_per_suite =logfile erl_eval_suite.end_per_suite.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok =elapsed 0.0 -=group_time 1.094s +=group_time 1.084s =case erl_expand_records_SUITE:init_per_suite =logfile erl_expand_records_suite.init_per_suite.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok =elapsed 0.0 =case erl_expand_records_SUITE:attributes =logfile erl_expand_records_suite.attributes.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 0.003426 +=elapsed 0.003006 =case erl_expand_records_SUITE:expr =logfile erl_expand_records_suite.expr.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:37 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 0.081061 +=elapsed 0.086812 =case erl_expand_records_SUITE:guard =logfile erl_expand_records_suite.guard.html -=started 2024-09-11 11:12:37 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 0.001534 +=elapsed 0.001815 =case erl_expand_records_SUITE:init =logfile erl_expand_records_suite.init.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 0.019253 +=elapsed 0.025969 =case erl_expand_records_SUITE:pattern =logfile erl_expand_records_suite.pattern.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 0.018521 +=elapsed 0.018935 =case erl_expand_records_SUITE:strict =logfile erl_expand_records_suite.strict.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 0.012072 +=elapsed 0.014332 =case erl_expand_records_SUITE:update =logfile erl_expand_records_suite.update.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 0.009271 +=elapsed 0.00858 =case erl_expand_records_SUITE:maps =logfile erl_expand_records_suite.maps.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 0.007586 +=elapsed 0.009432 =case erl_expand_records_SUITE:side_effects =logfile erl_expand_records_suite.side_effects.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 4.0e-6 +=elapsed 2.0e-6 =case erl_expand_records_SUITE:init_per_group =logfile erl_expand_records_suite.init_per_group.html =group_props [{name,tickets}] -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok =elapsed 0.0 =case erl_expand_records_SUITE:otp_5915 =logfile erl_expand_records_suite.otp_5915.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 0.053086 +=elapsed 0.05328 =case erl_expand_records_SUITE:otp_7931 =logfile erl_expand_records_suite.otp_7931.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:45 =result ok -=elapsed 0.02183 +=elapsed 0.021213 =case erl_expand_records_SUITE:otp_5990 =logfile erl_expand_records_suite.otp_5990.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:45 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.017813 +=elapsed 0.01858 =case erl_expand_records_SUITE:otp_7078 =logfile erl_expand_records_suite.otp_7078.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.013014 +=elapsed 0.010908 =case erl_expand_records_SUITE:end_per_group =logfile erl_expand_records_suite.end_per_group.html =group_props [{name,tickets}] -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok =elapsed 0.0 -=group_time 0.224s +=group_time 0.220s =case erl_expand_records_SUITE:end_per_suite =logfile erl_expand_records_suite.end_per_suite.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok =elapsed 0.0 -=group_time 0.639s +=group_time 0.649s =case erl_internal_SUITE:init_per_suite =logfile erl_internal_suite.init_per_suite.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok =elapsed 0.0 =case erl_internal_SUITE:behav =logfile erl_internal_suite.behav.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok =elapsed 0.002097 =case erl_internal_SUITE:end_per_suite =logfile erl_internal_suite.end_per_suite.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok =elapsed 0.0 -=group_time 0.050s +=group_time 0.051s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.33027.html +=logfile ct_framework.init_per_suite.709.html =group_props [{suite,erl_lint_SUITE}] -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =case ct_framework:init_per_group -=logfile ct_framework.init_per_group.33059.html +=logfile ct_framework.init_per_group.741.html =group_props [{suite,erl_lint_SUITE},{name,unused_vars_warn}] -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 3.1e-5 +=elapsed 3.3e-5 =case erl_lint_SUITE:unused_vars_warn_basic =logfile erl_lint_suite.unused_vars_warn_basic.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.016191 +=elapsed 0.016517 =case erl_lint_SUITE:unused_vars_warn_lc =logfile erl_lint_suite.unused_vars_warn_lc.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.130424 +=elapsed 0.13108 =case erl_lint_SUITE:unused_vars_warn_rec =logfile erl_lint_suite.unused_vars_warn_rec.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.016289 +=elapsed 0.016652 =case erl_lint_SUITE:unused_vars_warn_fun =logfile erl_lint_suite.unused_vars_warn_fun.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.013181 +=elapsed 0.013494 =case erl_lint_SUITE:unused_vars_OTP_4858 =logfile erl_lint_suite.unused_vars_otp_4858.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.002008 +=elapsed 0.001571 =case erl_lint_SUITE:unused_unsafe_vars_warn =logfile erl_lint_suite.unused_unsafe_vars_warn.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.008393 +=elapsed 0.009394 =case ct_framework:end_per_group -=logfile ct_framework.end_per_group.9026.html +=logfile ct_framework.end_per_group.40930.html =group_props [{suite,erl_lint_SUITE},{name,unused_vars_warn}] -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:38 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok =elapsed 3.3e-5 -=group_time 0.346s +=group_time 0.348s =case erl_lint_SUITE:export_vars_warn =logfile erl_lint_suite.export_vars_warn.html -=started 2024-09-11 11:12:38 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.007486 +=elapsed 0.008742 =case erl_lint_SUITE:shadow_vars =logfile erl_lint_suite.shadow_vars.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.003299 +=elapsed 0.00384 =case erl_lint_SUITE:unused_import =logfile erl_lint_suite.unused_import.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.002629 +=elapsed 0.002599 =case erl_lint_SUITE:unused_function =logfile erl_lint_suite.unused_function.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.007665 +=elapsed 0.007694 =case erl_lint_SUITE:unsafe_vars =logfile erl_lint_suite.unsafe_vars.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.013873 +=elapsed 0.013932 =case erl_lint_SUITE:unsafe_vars2 =logfile erl_lint_suite.unsafe_vars2.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.001941 +=elapsed 0.001923 =case erl_lint_SUITE:unsafe_vars_try =logfile erl_lint_suite.unsafe_vars_try.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.011779 +=elapsed 0.011748 =case erl_lint_SUITE:guard =logfile erl_lint_suite.guard.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.031237 +=elapsed 0.031666 =case erl_lint_SUITE:unsized_binary_in_bin_gen_pattern =logfile erl_lint_suite.unsized_binary_in_bin_gen_pattern.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.002534 +=elapsed 0.002572 =case erl_lint_SUITE:otp_4886 =logfile erl_lint_suite.otp_4886.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.00125 +=elapsed 0.001266 =case erl_lint_SUITE:otp_4988 =logfile erl_lint_suite.otp_4988.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:46 =result ok -=elapsed 0.001536 +=elapsed 0.001537 =case erl_lint_SUITE:otp_5091 =logfile erl_lint_suite.otp_5091.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:46 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.086116 +=elapsed 0.085412 =case erl_lint_SUITE:otp_5276 =logfile erl_lint_suite.otp_5276.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.002487 +=elapsed 0.001984 =case erl_lint_SUITE:otp_5338 =logfile erl_lint_suite.otp_5338.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.001441 +=elapsed 0.001113 =case erl_lint_SUITE:otp_5362 =logfile erl_lint_suite.otp_5362.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.144903 +=elapsed 0.145298 =case erl_lint_SUITE:otp_5371 =logfile erl_lint_suite.otp_5371.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.016757 +=elapsed 0.017246 =case erl_lint_SUITE:otp_7227 =logfile erl_lint_suite.otp_7227.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.0303 +=elapsed 0.031069 =case erl_lint_SUITE:binary_aliases =logfile erl_lint_suite.binary_aliases.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.010645 +=elapsed 0.01134 =case erl_lint_SUITE:otp_5494 =logfile erl_lint_suite.otp_5494.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.002261 +=elapsed 0.002432 =case erl_lint_SUITE:otp_5644 =logfile erl_lint_suite.otp_5644.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.002531 +=elapsed 0.002658 =case erl_lint_SUITE:otp_5878 =logfile erl_lint_suite.otp_5878.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.063494 +=elapsed 0.068037 =case erl_lint_SUITE:otp_5917 =logfile erl_lint_suite.otp_5917.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.001816 +=elapsed 0.002214 =case erl_lint_SUITE:otp_6585 =logfile erl_lint_suite.otp_6585.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.003106 +=elapsed 0.004244 =case erl_lint_SUITE:otp_6885 =logfile erl_lint_suite.otp_6885.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.001737 +=elapsed 0.002699 =case erl_lint_SUITE:otp_10436 =logfile erl_lint_suite.otp_10436.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:39 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.00199 +=elapsed 0.002855 =case erl_lint_SUITE:otp_11254 =logfile erl_lint_suite.otp_11254.html -=started 2024-09-11 11:12:39 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.001088 +=elapsed 0.00174 =case erl_lint_SUITE:otp_11772 =logfile erl_lint_suite.otp_11772.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.0023 +=elapsed 0.003235 =case erl_lint_SUITE:otp_11771 =logfile erl_lint_suite.otp_11771.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.002478 +=elapsed 0.003529 =case erl_lint_SUITE:otp_11872 =logfile erl_lint_suite.otp_11872.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.001292 +=elapsed 0.002058 =case erl_lint_SUITE:export_all =logfile erl_lint_suite.export_all.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.003561 +=elapsed 0.005006 =case erl_lint_SUITE:bif_clash =logfile erl_lint_suite.bif_clash.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.050152 +=elapsed 0.06052 =case erl_lint_SUITE:behaviour_basic =logfile erl_lint_suite.behaviour_basic.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.008899 +=elapsed 0.010104 =case erl_lint_SUITE:behaviour_multiple =logfile erl_lint_suite.behaviour_multiple.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.016333 +=elapsed 0.018814 =case erl_lint_SUITE:otp_11861 =logfile erl_lint_suite.otp_11861.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.04661 +=elapsed 0.048895 =case erl_lint_SUITE:otp_7550 =logfile erl_lint_suite.otp_7550.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:47 =result ok -=elapsed 0.002449 +=elapsed 0.002348 =case erl_lint_SUITE:otp_8051 =logfile erl_lint_suite.otp_8051.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:47 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.001182 +=elapsed 9.83e-4 =case erl_lint_SUITE:format_warn =logfile erl_lint_suite.format_warn.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.037735 +=elapsed 0.036146 =case ct_framework:init_per_group -=logfile ct_framework.init_per_group.9058.html +=logfile ct_framework.init_per_group.40962.html =group_props [{name,on_load},{suite,erl_lint_SUITE}] -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 3.0e-5 +=elapsed 2.7e-5 =case erl_lint_SUITE:on_load_successful =logfile erl_lint_suite.on_load_successful.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.00679 +=elapsed 0.006192 =case erl_lint_SUITE:on_load_failing =logfile erl_lint_suite.on_load_failing.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.00566 +=elapsed 0.004854 =case ct_framework:end_per_group -=logfile ct_framework.end_per_group.9090.html +=logfile ct_framework.end_per_group.40994.html =group_props [{name,on_load},{suite,erl_lint_SUITE}] -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok =elapsed 2.9e-5 -=group_time 0.080s +=group_time 0.078s =case erl_lint_SUITE:too_many_arguments =logfile erl_lint_suite.too_many_arguments.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.001736 +=elapsed 0.001456 =case erl_lint_SUITE:basic_errors =logfile erl_lint_suite.basic_errors.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.010983 +=elapsed 0.007352 =case erl_lint_SUITE:bin_syntax_errors =logfile erl_lint_suite.bin_syntax_errors.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.003763 +=elapsed 0.002784 =case erl_lint_SUITE:predef =logfile erl_lint_suite.predef.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.008811 +=elapsed 0.007631 =case erl_lint_SUITE:maps =logfile erl_lint_suite.maps.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.020508 +=elapsed 0.017173 =case erl_lint_SUITE:maps_type =logfile erl_lint_suite.maps_type.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.00561 +=elapsed 0.005003 =case erl_lint_SUITE:maps_parallel_match =logfile erl_lint_suite.maps_parallel_match.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.018888 +=elapsed 0.016165 =case erl_lint_SUITE:otp_11851 =logfile erl_lint_suite.otp_11851.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.007505 +=elapsed 0.005897 =case erl_lint_SUITE:otp_11879 =logfile erl_lint_suite.otp_11879.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 2.48e-4 +=elapsed 2.02e-4 =case erl_lint_SUITE:otp_13230 =logfile erl_lint_suite.otp_13230.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.001641 +=elapsed 0.001002 =case erl_lint_SUITE:record_errors =logfile erl_lint_suite.record_errors.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.001589 +=elapsed 0.00114 =case erl_lint_SUITE:otp_11879_cont =logfile erl_lint_suite.otp_11879_cont.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.010824 +=elapsed 0.008399 =case erl_lint_SUITE:non_latin1_module =logfile erl_lint_suite.non_latin1_module.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.007424 +=elapsed 0.005004 =case erl_lint_SUITE:illegal_module_name =logfile erl_lint_suite.illegal_module_name.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.006326 +=elapsed 0.005788 =case erl_lint_SUITE:otp_14323 =logfile erl_lint_suite.otp_14323.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:40 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.004629 +=elapsed 0.003207 =case erl_lint_SUITE:stacktrace_syntax =logfile erl_lint_suite.stacktrace_syntax.html -=started 2024-09-11 11:12:40 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.005398 +=elapsed 0.003903 =case erl_lint_SUITE:otp_14285 =logfile erl_lint_suite.otp_14285.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.005646 +=elapsed 0.00392 =case erl_lint_SUITE:otp_14378 =logfile erl_lint_suite.otp_14378.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.002363 +=elapsed 0.002055 =case erl_lint_SUITE:external_funs =logfile erl_lint_suite.external_funs.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.003412 +=elapsed 0.003137 =case erl_lint_SUITE:otp_15456 =logfile erl_lint_suite.otp_15456.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.005631 +=elapsed 0.004998 =case erl_lint_SUITE:otp_15563 =logfile erl_lint_suite.otp_15563.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.001526 +=elapsed 0.001249 =case erl_lint_SUITE:unused_type =logfile erl_lint_suite.unused_type.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.006958 +=elapsed 0.005225 =case erl_lint_SUITE:binary_types =logfile erl_lint_suite.binary_types.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.004918 +=elapsed 0.003658 =case erl_lint_SUITE:removed =logfile erl_lint_suite.removed.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.002447 +=elapsed 0.00172 =case erl_lint_SUITE:otp_16516 =logfile erl_lint_suite.otp_16516.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.012591 +=elapsed 0.009396 =case erl_lint_SUITE:undefined_nifs =logfile erl_lint_suite.undefined_nifs.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.001402 +=elapsed 9.9e-4 =case erl_lint_SUITE:no_load_nif =logfile erl_lint_suite.no_load_nif.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.002327 +=elapsed 0.001974 =case erl_lint_SUITE:inline_nifs =logfile erl_lint_suite.inline_nifs.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.010948 +=elapsed 0.012015 =case erl_lint_SUITE:warn_missing_spec =logfile erl_lint_suite.warn_missing_spec.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:48 =result ok -=elapsed 0.017745 +=elapsed 0.016679 =case erl_lint_SUITE:otp_16824 =logfile erl_lint_suite.otp_16824.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:48 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.004206 +=elapsed 0.00369 =case erl_lint_SUITE:underscore_match =logfile erl_lint_suite.underscore_match.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.028412 +=elapsed 0.02825 =case erl_lint_SUITE:unused_record =logfile erl_lint_suite.unused_record.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.004304 +=elapsed 0.004273 =case erl_lint_SUITE:unused_type2 =logfile erl_lint_suite.unused_type2.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.013566 +=elapsed 0.014106 =case erl_lint_SUITE:eep49 =logfile erl_lint_suite.eep49.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.005934 +=elapsed 0.006911 =case erl_lint_SUITE:redefined_builtin_type =logfile erl_lint_suite.redefined_builtin_type.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.021906 +=elapsed 0.02355 =case erl_lint_SUITE:tilde_k =logfile erl_lint_suite.tilde_k.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.008026 +=elapsed 0.007734 =case erl_lint_SUITE:singleton_type_var_errors =logfile erl_lint_suite.singleton_type_var_errors.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.018163 +=elapsed 0.015839 =case erl_lint_SUITE:documentation_attributes =logfile erl_lint_suite.documentation_attributes.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.014998 +=elapsed 0.014969 =case erl_lint_SUITE:match_float_zero =logfile erl_lint_suite.match_float_zero.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.009878 +=elapsed 0.009412 =case erl_lint_SUITE:undefined_module =logfile erl_lint_suite.undefined_module.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.00104 +=elapsed 8.51e-4 =case erl_lint_SUITE:update_literal =logfile erl_lint_suite.update_literal.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.008459 +=elapsed 0.007398 =case erl_lint_SUITE:messages_with_jaro_suggestions =logfile erl_lint_suite.messages_with_jaro_suggestions.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.009877 +=elapsed 0.008155 =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.9122.html +=logfile ct_framework.end_per_suite.41026.html =group_props [{suite,erl_lint_SUITE}] -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok =elapsed 0.0 -=group_time 3.258s +=group_time 3.248s =case erl_pp_SUITE:init_per_suite =logfile erl_pp_suite.init_per_suite.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok =elapsed 0.0 =case erl_pp_SUITE:init_per_group =logfile erl_pp_suite.init_per_group.html =group_props [{name,expr}] -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok =elapsed 0.0 =case erl_pp_SUITE:func =logfile erl_pp_suite.func.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.026474 +=elapsed 0.024345 =case erl_pp_SUITE:call =logfile erl_pp_suite.call.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:41 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.002606 +=elapsed 0.002212 =case erl_pp_SUITE:recs =logfile erl_pp_suite.recs.html -=started 2024-09-11 11:12:41 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.062164 +=elapsed 0.061813 =case erl_pp_SUITE:try_catch =logfile erl_pp_suite.try_catch.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.040589 +=elapsed 0.040805 =case erl_pp_SUITE:if_then =logfile erl_pp_suite.if_then.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.007134 +=elapsed 0.006858 =case erl_pp_SUITE:receive_after =logfile erl_pp_suite.receive_after.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.014155 +=elapsed 0.013853 =case erl_pp_SUITE:bits =logfile erl_pp_suite.bits.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.02266 +=elapsed 0.027424 =case erl_pp_SUITE:head_tail =logfile erl_pp_suite.head_tail.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.011897 +=elapsed 0.011994 =case erl_pp_SUITE:cond1 =logfile erl_pp_suite.cond1.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 2.5e-5 +=elapsed 2.6e-5 =case erl_pp_SUITE:block =logfile erl_pp_suite.block.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.002406 +=elapsed 0.002457 =case erl_pp_SUITE:case1 =logfile erl_pp_suite.case1.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.002782 +=elapsed 0.002797 =case erl_pp_SUITE:ops =logfile erl_pp_suite.ops.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 0.007133 +=elapsed 0.007109 =case erl_pp_SUITE:messages =logfile erl_pp_suite.messages.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:49 =result ok -=elapsed 2.3e-5 +=elapsed 2.4e-5 =case erl_pp_SUITE:maps_syntax =logfile erl_pp_suite.maps_syntax.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:49 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 0.006191 +=elapsed 0.00573 =case erl_pp_SUITE:quoted_atom_types =logfile erl_pp_suite.quoted_atom_types.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 7.3e-5 +=elapsed 7.4e-5 =case erl_pp_SUITE:format_options =logfile erl_pp_suite.format_options.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 1.12e-4 +=elapsed 1.13e-4 =case erl_pp_SUITE:form_vars =logfile erl_pp_suite.form_vars.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 0.003483 +=elapsed 0.003501 =case erl_pp_SUITE:end_per_group =logfile erl_pp_suite.end_per_group.html =group_props [{name,expr}] -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok =elapsed 0.0 -=group_time 0.614s +=group_time 0.611s =case erl_pp_SUITE:init_per_group -=logfile erl_pp_suite.init_per_group.9154.html +=logfile erl_pp_suite.init_per_group.41058.html =group_props [{name,attributes}] -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok =elapsed 0.0 =case erl_pp_SUITE:misc_attrs =logfile erl_pp_suite.misc_attrs.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 2.96e-4 +=elapsed 3.24e-4 =case erl_pp_SUITE:import_export =logfile erl_pp_suite.import_export.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 0.010297 +=elapsed 0.011196 =case erl_pp_SUITE:dialyzer_attrs =logfile erl_pp_suite.dialyzer_attrs.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 1.67e-4 +=elapsed 1.88e-4 =case erl_pp_SUITE:end_per_group -=logfile erl_pp_suite.end_per_group.9186.html +=logfile erl_pp_suite.end_per_group.41090.html =group_props [{name,attributes}] -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok =elapsed 0.0 -=group_time 0.101s +=group_time 0.102s =case erl_pp_SUITE:hook =logfile erl_pp_suite.hook.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 6.96e-4 +=elapsed 0.0007 =case erl_pp_SUITE:neg_indent =logfile erl_pp_suite.neg_indent.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 0.001102 +=elapsed 0.001113 =case erl_pp_SUITE:init_per_group -=logfile erl_pp_suite.init_per_group.9218.html +=logfile erl_pp_suite.init_per_group.41122.html =group_props [{name,tickets}] -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok =elapsed 0.0 =case erl_pp_SUITE:otp_6321 =logfile erl_pp_suite.otp_6321.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok =elapsed 2.3e-5 =case erl_pp_SUITE:otp_6911 =logfile erl_pp_suite.otp_6911.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 1.05e-4 +=elapsed 1.11e-4 =case erl_pp_SUITE:otp_6914 =logfile erl_pp_suite.otp_6914.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 1.88e-4 +=elapsed 1.9e-4 =case erl_pp_SUITE:otp_8150 =logfile erl_pp_suite.otp_8150.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 0.00176 +=elapsed 0.0018 =case erl_pp_SUITE:otp_8238 =logfile erl_pp_suite.otp_8238.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 0.008597 +=elapsed 0.008837 =case erl_pp_SUITE:otp_8473 =logfile erl_pp_suite.otp_8473.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 7.6e-5 +=elapsed 8.0e-5 =case erl_pp_SUITE:otp_8522 =logfile erl_pp_suite.otp_8522.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 0.001105 +=elapsed 0.001462 =case erl_pp_SUITE:otp_8567 =logfile erl_pp_suite.otp_8567.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 7.6e-4 +=elapsed 9.25e-4 =case erl_pp_SUITE:otp_8664 =logfile erl_pp_suite.otp_8664.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 0.001762 +=elapsed 0.001945 =case erl_pp_SUITE:otp_9147 =logfile erl_pp_suite.otp_9147.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 8.5e-4 +=elapsed 9.04e-4 =case erl_pp_SUITE:otp_10302 =logfile erl_pp_suite.otp_10302.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:42 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:50 =result ok -=elapsed 0.004054 +=elapsed 0.004406 =case erl_pp_SUITE:otp_10820 =logfile erl_pp_suite.otp_10820.html -=started 2024-09-11 11:12:42 -=ended 2024-09-11 11:12:43 +=started 2024-09-12 10:34:50 +=ended 2024-09-12 10:34:51 =result ok -=elapsed 0.740982 +=elapsed 0.736032 =case erl_pp_SUITE:otp_11100 =logfile erl_pp_suite.otp_11100.html -=started 2024-09-11 11:12:43 -=ended 2024-09-11 11:12:43 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok -=elapsed 1.2e-4 +=elapsed 1.19e-4 =case erl_pp_SUITE:otp_11861 =logfile erl_pp_suite.otp_11861.html -=started 2024-09-11 11:12:43 -=ended 2024-09-11 11:12:43 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok -=elapsed 3.8e-5 +=elapsed 4.3e-5 =case erl_pp_SUITE:pr_1014 =logfile erl_pp_suite.pr_1014.html -=started 2024-09-11 11:12:43 -=ended 2024-09-11 11:12:43 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok -=elapsed 9.73e-4 +=elapsed 9.72e-4 =case erl_pp_SUITE:otp_13662 =logfile erl_pp_suite.otp_13662.html -=started 2024-09-11 11:12:43 -=ended 2024-09-11 11:12:43 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok -=elapsed 0.005508 +=elapsed 0.005625 =case erl_pp_SUITE:otp_14285 =logfile erl_pp_suite.otp_14285.html -=started 2024-09-11 11:12:43 -=ended 2024-09-11 11:12:43 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok -=elapsed 4.56e-4 +=elapsed 4.76e-4 =case erl_pp_SUITE:otp_15592 =logfile erl_pp_suite.otp_15592.html -=started 2024-09-11 11:12:43 -=ended 2024-09-11 11:12:43 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok =elapsed 7.0e-5 =case erl_pp_SUITE:otp_15751 =logfile erl_pp_suite.otp_15751.html -=started 2024-09-11 11:12:43 -=ended 2024-09-11 11:12:43 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok -=elapsed 5.87e-4 +=elapsed 6.32e-4 =case erl_pp_SUITE:otp_15755 =logfile erl_pp_suite.otp_15755.html -=started 2024-09-11 11:12:43 -=ended 2024-09-11 11:12:43 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok -=elapsed 2.93e-4 +=elapsed 2.34e-4 =case erl_pp_SUITE:otp_16435 =logfile erl_pp_suite.otp_16435.html -=started 2024-09-11 11:12:43 -=ended 2024-09-11 11:12:43 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok -=elapsed 3.96e-4 +=elapsed 3.34e-4 =case erl_pp_SUITE:gh_5093 =logfile erl_pp_suite.gh_5093.html -=started 2024-09-11 11:12:43 -=ended 2024-09-11 11:12:43 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok -=elapsed 1.63e-4 +=elapsed 1.26e-4 =case erl_pp_SUITE:eep49 =logfile erl_pp_suite.eep49.html -=started 2024-09-11 11:12:43 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok -=elapsed 7.7e-5 +=elapsed 5.7e-5 =case erl_pp_SUITE:eep58 =logfile erl_pp_suite.eep58.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok -=elapsed 1.09e-4 +=elapsed 1.05e-4 =case erl_pp_SUITE:end_per_group -=logfile erl_pp_suite.end_per_group.9506.html +=logfile erl_pp_suite.end_per_group.41410.html =group_props [{name,tickets}] -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok -=elapsed 1.0e-6 -=group_time 1.339s +=elapsed 0.0 +=group_time 1.335s =case erl_pp_SUITE:end_per_suite =logfile erl_pp_suite.end_per_suite.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok =elapsed 0.0 -=group_time 2.195s +=group_time 2.190s =case erl_scan_SUITE:init_per_suite =logfile erl_scan_suite.init_per_suite.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok =elapsed 0.0 =case erl_scan_SUITE:init_per_group =logfile erl_scan_suite.init_per_group.html =group_props [{name,error}] -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok =elapsed 0.0 =case erl_scan_SUITE:error_1 =logfile erl_scan_suite.error_1.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok =elapsed 3.0e-6 =case erl_scan_SUITE:error_2 =logfile erl_scan_suite.error_2.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok =elapsed 3.5e-5 =case erl_scan_SUITE:end_per_group =logfile erl_scan_suite.end_per_group.html =group_props [{name,error}] -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok =elapsed 0.0 =group_time 0.069s =case erl_scan_SUITE:iso88591 =logfile erl_scan_suite.iso88591.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:51 =result ok -=elapsed 1.4e-5 +=elapsed 1.5e-5 =case erl_scan_SUITE:otp_7810 =logfile erl_scan_suite.otp_7810.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:51 +=ended 2024-09-12 10:34:52 =result ok -=elapsed 0.251072 +=elapsed 0.251027 =case erl_scan_SUITE:otp_10302 =logfile erl_scan_suite.otp_10302.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:52 +=ended 2024-09-12 10:34:52 =result ok -=elapsed 4.1e-5 +=elapsed 4.2e-5 =case erl_scan_SUITE:otp_10990 =logfile erl_scan_suite.otp_10990.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:52 +=ended 2024-09-12 10:34:52 =result ok -=elapsed 4.0e-6 +=elapsed 5.0e-6 =case erl_scan_SUITE:otp_10992 =logfile erl_scan_suite.otp_10992.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:52 +=ended 2024-09-12 10:34:52 =result ok =elapsed 3.0e-6 =case erl_scan_SUITE:otp_11807 =logfile erl_scan_suite.otp_11807.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:52 +=ended 2024-09-12 10:34:52 =result ok =elapsed 7.0e-6 =case erl_scan_SUITE:otp_16480 =logfile erl_scan_suite.otp_16480.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:52 +=ended 2024-09-12 10:34:52 =result ok -=elapsed 3.0e-6 +=elapsed 4.0e-6 =case erl_scan_SUITE:otp_17024 =logfile erl_scan_suite.otp_17024.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:52 +=ended 2024-09-12 10:34:52 =result ok =elapsed 1.0e-6 =case erl_scan_SUITE:text_fun =logfile erl_scan_suite.text_fun.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:52 +=ended 2024-09-12 10:34:52 =result ok =elapsed 5.0e-5 =case erl_scan_SUITE:triple_quoted_string =logfile erl_scan_suite.triple_quoted_string.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:52 +=ended 2024-09-12 10:34:52 =result ok -=elapsed 2.9e-5 +=elapsed 3.0e-5 =case erl_scan_SUITE:end_per_suite =logfile erl_scan_suite.end_per_suite.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:52 +=ended 2024-09-12 10:34:52 =result ok =elapsed 0.0 -=group_time 0.602s +=group_time 0.597s =case error_logger_h_SUITE:init_per_suite =logfile error_logger_h_suite.init_per_suite.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:44 +=started 2024-09-12 10:34:52 +=ended 2024-09-12 10:34:52 =result ok =elapsed 0.0 =case error_logger_h_SUITE:logfile =logfile error_logger_h_suite.logfile.html -=started 2024-09-11 11:12:44 -=ended 2024-09-11 11:12:46 +=started 2024-09-12 10:34:52 +=ended 2024-09-12 10:34:54 =result ok -=elapsed 1.933541 +=elapsed 1.932511 =case error_logger_h_SUITE:logfile_truncated =logfile error_logger_h_suite.logfile_truncated.html -=started 2024-09-11 11:12:46 -=ended 2024-09-11 11:12:47 +=started 2024-09-12 10:34:54 +=ended 2024-09-12 10:34:54 =result ok -=elapsed 0.393011 +=elapsed 0.393653 =case error_logger_h_SUITE:tty =logfile error_logger_h_suite.tty.html -=started 2024-09-11 11:12:47 -=ended 2024-09-11 11:12:49 +=started 2024-09-12 10:34:54 +=ended 2024-09-12 10:34:56 =result ok -=elapsed 1.929853 +=elapsed 1.930411 =case error_logger_h_SUITE:tty_truncated =logfile error_logger_h_suite.tty_truncated.html -=started 2024-09-11 11:12:49 -=ended 2024-09-11 11:12:49 +=started 2024-09-12 10:34:56 +=ended 2024-09-12 10:34:57 =result ok -=elapsed 0.393487 +=elapsed 0.394604 =case error_logger_h_SUITE:end_per_suite =logfile error_logger_h_suite.end_per_suite.html -=started 2024-09-11 11:12:49 -=ended 2024-09-11 11:12:49 +=started 2024-09-12 10:34:57 +=ended 2024-09-12 10:34:57 =result ok =elapsed 0.0 =group_time 4.769s =case escript_SUITE:init_per_suite =logfile escript_suite.init_per_suite.html -=started 2024-09-11 11:12:49 -=ended 2024-09-11 11:12:49 +=started 2024-09-12 10:34:57 +=ended 2024-09-12 10:34:57 =result ok =elapsed 0.0 =case escript_SUITE:basic =logfile escript_suite.basic.html -=started 2024-09-11 11:12:49 -=ended 2024-09-11 11:12:52 +=started 2024-09-12 10:34:57 +=ended 2024-09-12 10:35:00 =result ok -=elapsed 2.911468 +=elapsed 2.913205 =case escript_SUITE:errors =logfile escript_suite.errors.html -=started 2024-09-11 11:12:52 -=ended 2024-09-11 11:12:53 +=started 2024-09-12 10:35:00 +=ended 2024-09-12 10:35:00 =result ok -=elapsed 0.681594 +=elapsed 0.667169 =case escript_SUITE:strange_name =logfile escript_suite.strange_name.html -=started 2024-09-11 11:12:53 -=ended 2024-09-11 11:12:53 +=started 2024-09-12 10:35:00 +=ended 2024-09-12 10:35:00 =result ok -=elapsed 0.256446 +=elapsed 0.259714 =case escript_SUITE:emulator_flags =logfile escript_suite.emulator_flags.html -=started 2024-09-11 11:12:53 -=ended 2024-09-11 11:12:53 +=started 2024-09-12 10:35:00 +=ended 2024-09-12 10:35:01 =result ok -=elapsed 0.257626 +=elapsed 0.260629 =case escript_SUITE:emulator_flags_no_shebang =logfile escript_suite.emulator_flags_no_shebang.html -=started 2024-09-11 11:12:53 -=ended 2024-09-11 11:12:53 +=started 2024-09-12 10:35:01 +=ended 2024-09-12 10:35:01 =result ok -=elapsed 0.256828 +=elapsed 0.271799 =case escript_SUITE:two_lines =logfile escript_suite.two_lines.html -=started 2024-09-11 11:12:53 -=ended 2024-09-11 11:12:54 +=started 2024-09-12 10:35:01 +=ended 2024-09-12 10:35:01 =result ok -=elapsed 0.274228 +=elapsed 0.260067 =case escript_SUITE:module_script =logfile escript_suite.module_script.html -=started 2024-09-11 11:12:54 -=ended 2024-09-11 11:12:55 +=started 2024-09-12 10:35:01 +=ended 2024-09-12 10:35:03 =result ok -=elapsed 1.316695 +=elapsed 1.320115 =case escript_SUITE:beam_script =logfile escript_suite.beam_script.html -=started 2024-09-11 11:12:55 -=ended 2024-09-11 11:12:56 +=started 2024-09-12 10:35:03 +=ended 2024-09-12 10:35:03 =result ok -=elapsed 0.741965 +=elapsed 0.730457 =case escript_SUITE:archive_script =logfile escript_suite.archive_script.html -=started 2024-09-11 11:12:56 -=ended 2024-09-11 11:12:57 +=started 2024-09-12 10:35:03 +=ended 2024-09-12 10:35:04 =result ok -=elapsed 0.871375 +=elapsed 0.844936 =case escript_SUITE:epp =logfile escript_suite.epp.html -=started 2024-09-11 11:12:57 -=ended 2024-09-11 11:12:57 +=started 2024-09-12 10:35:04 +=ended 2024-09-12 10:35:05 =result ok -=elapsed 0.259151 +=elapsed 0.254907 =case escript_SUITE:create_and_extract =logfile escript_suite.create_and_extract.html -=started 2024-09-11 11:12:57 -=ended 2024-09-11 11:13:22 +=started 2024-09-12 10:35:05 +=ended 2024-09-12 10:35:29 =result ok -=elapsed 24.699792 +=elapsed 24.705518 =case escript_SUITE:foldl =logfile escript_suite.foldl.html -=started 2024-09-11 11:13:22 -=ended 2024-09-11 11:13:22 +=started 2024-09-12 10:35:29 +=ended 2024-09-12 10:35:29 =result ok -=elapsed 0.019766 +=elapsed 0.020566 =case escript_SUITE:overflow =logfile escript_suite.overflow.html -=started 2024-09-11 11:13:22 -=ended 2024-09-11 11:13:22 +=started 2024-09-12 10:35:29 +=ended 2024-09-12 10:35:30 =result ok -=elapsed 0.474579 +=elapsed 0.48078 =case escript_SUITE:archive_script_file_access =logfile escript_suite.archive_script_file_access.html -=started 2024-09-11 11:13:22 -=ended 2024-09-11 11:13:23 +=started 2024-09-12 10:35:30 +=ended 2024-09-12 10:35:30 =result ok -=elapsed 0.507247 +=elapsed 0.492421 =case escript_SUITE:unicode =logfile escript_suite.unicode.html -=started 2024-09-11 11:13:23 -=ended 2024-09-11 11:13:24 +=started 2024-09-12 10:35:30 +=ended 2024-09-12 10:35:32 =result ok -=elapsed 1.541086 +=elapsed 1.555548 =case escript_SUITE:bad_io_server =logfile escript_suite.bad_io_server.html -=started 2024-09-11 11:13:24 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:32 +=ended 2024-09-12 10:35:32 =result ok -=elapsed 0.24545 +=elapsed 0.243843 =case escript_SUITE:end_per_suite =logfile escript_suite.end_per_suite.html -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:32 +=ended 2024-09-12 10:35:32 =result ok =elapsed 0.0 -=group_time 35.714s +=group_time 35.680s =case ets_SUITE:init_per_suite =logfile ets_suite.init_per_suite.html -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:32 +=ended 2024-09-12 10:35:32 =result ok -=elapsed 2.2e-5 +=elapsed 2.0e-5 =case ets_SUITE:init_per_group =logfile ets_suite.init_per_group.html =group_props [{name,new}] -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:32 +=ended 2024-09-12 10:35:32 =result ok =elapsed 0.0 =case ets_SUITE:default =logfile ets_suite.default.html -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:32 +=ended 2024-09-12 10:35:32 =result ok -=elapsed 0.00217 +=elapsed 0.00174 =case ets_SUITE:setbag =logfile ets_suite.setbag.html -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:32 +=ended 2024-09-12 10:35:32 =result ok -=elapsed 0.001682 +=elapsed 0.001916 =case ets_SUITE:badnew =logfile ets_suite.badnew.html -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:32 +=ended 2024-09-12 10:35:32 =result ok -=elapsed 0.001151 +=elapsed 0.001133 =case ets_SUITE:verybadnew =logfile ets_suite.verybadnew.html -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:32 +=ended 2024-09-12 10:35:32 =result ok -=elapsed 0.00115 +=elapsed 0.001482 =case ets_SUITE:named =logfile ets_suite.named.html -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:32 +=ended 2024-09-12 10:35:32 =result ok -=elapsed 0.001282 +=elapsed 0.001606 =case ets_SUITE:keypos2 =logfile ets_suite.keypos2.html -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:32 +=ended 2024-09-12 10:35:32 =result ok -=elapsed 0.001449 +=elapsed 0.002036 =case ets_SUITE:privacy =logfile ets_suite.privacy.html -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:32 +=ended 2024-09-12 10:35:33 =result ok -=elapsed 0.027274 +=elapsed 0.025261 =case ets_SUITE:end_per_group =logfile ets_suite.end_per_group.html =group_props [{name,new}] -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:33 +=ended 2024-09-12 10:35:33 =result ok =elapsed 0.0 -=group_time 0.218s +=group_time 0.216s =case ets_SUITE:init_per_group -=logfile ets_suite.init_per_group.9986.html +=logfile ets_suite.init_per_group.41858.html =group_props [{name,insert}] -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:33 +=ended 2024-09-12 10:35:33 =result ok =elapsed 0.0 =case ets_SUITE:empty =logfile ets_suite.empty.html -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:33 +=ended 2024-09-12 10:35:33 =result ok -=elapsed 0.10048 +=elapsed 0.099951 =case ets_SUITE:badinsert =logfile ets_suite.badinsert.html -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:33 +=ended 2024-09-12 10:35:33 =result ok -=elapsed 0.110992 +=elapsed 0.110009 =case ets_SUITE:end_per_group -=logfile ets_suite.end_per_group.10082.html +=logfile ets_suite.end_per_group.41954.html =group_props [{name,insert}] -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:33 +=ended 2024-09-12 10:35:33 =result ok =elapsed 0.0 -=group_time 0.280s +=group_time 0.279s =case ets_SUITE:init_per_group -=logfile ets_suite.init_per_group.10114.html +=logfile ets_suite.init_per_group.41986.html =group_props [{name,lookup}] -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:33 +=ended 2024-09-12 10:35:33 =result ok =elapsed 0.0 =case ets_SUITE:badlookup =logfile ets_suite.badlookup.html -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:33 +=ended 2024-09-12 10:35:33 =result ok -=elapsed 0.001327 +=elapsed 0.001257 =case ets_SUITE:lookup_order =logfile ets_suite.lookup_order.html -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:33 +=ended 2024-09-12 10:35:33 =result ok -=elapsed 0.060766 +=elapsed 0.057846 =case ets_SUITE:end_per_group -=logfile ets_suite.end_per_group.10210.html +=logfile ets_suite.end_per_group.42082.html =group_props [{name,lookup}] -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:25 +=started 2024-09-12 10:35:33 +=ended 2024-09-12 10:35:33 =result ok -=elapsed 0.0 -=group_time 0.130s +=elapsed 1.0e-6 +=group_time 0.126s =case ets_SUITE:init_per_group -=logfile ets_suite.init_per_group.10242.html +=logfile ets_suite.init_per_group.42114.html =group_props [{name,delete}] -=started 2024-09-11 11:13:25 -=ended 2024-09-11 11:13:26 +=started 2024-09-12 10:35:33 +=ended 2024-09-12 10:35:33 =result ok =elapsed 0.0 =case ets_SUITE:delete_elem =logfile ets_suite.delete_elem.html -=started 2024-09-11 11:13:26 -=ended 2024-09-11 11:13:26 +=started 2024-09-12 10:35:33 +=ended 2024-09-12 10:35:33 =result ok -=elapsed 0.025794 +=elapsed 0.024928 =case ets_SUITE:delete_tab =logfile ets_suite.delete_tab.html -=started 2024-09-11 11:13:26 -=ended 2024-09-11 11:13:26 +=started 2024-09-12 10:35:33 +=ended 2024-09-12 10:35:33 =result ok -=elapsed 0.02419 +=elapsed 0.02586 =case ets_SUITE:delete_large_tab =logfile ets_suite.delete_large_tab.html -=started 2024-09-11 11:13:26 -=ended 2024-09-11 11:13:30 +=started 2024-09-12 10:35:33 +=ended 2024-09-12 10:35:38 =result ok -=elapsed 4.396167 +=elapsed 4.856267 =case ets_SUITE:delete_large_named_table =logfile ets_suite.delete_large_named_table.html -=started 2024-09-11 11:13:30 -=ended 2024-09-11 11:13:34 +=started 2024-09-12 10:35:38 +=ended 2024-09-12 10:35:42 =result ok -=elapsed 4.156187 +=elapsed 4.307755 =case ets_SUITE:evil_delete =logfile ets_suite.evil_delete.html -=started 2024-09-11 11:13:34 -=ended 2024-09-11 11:13:37 +=started 2024-09-12 10:35:42 +=ended 2024-09-12 10:35:45 =result ok -=elapsed 3.099125 +=elapsed 3.122398 =case ets_SUITE:table_leak =logfile ets_suite.table_leak.html -=started 2024-09-11 11:13:37 -=ended 2024-09-11 11:14:17 +=started 2024-09-12 10:35:45 +=ended 2024-09-12 10:36:26 =result ok -=elapsed 39.994682 +=elapsed 40.357536 =case ets_SUITE:baddelete =logfile ets_suite.baddelete.html -=started 2024-09-11 11:14:17 -=ended 2024-09-11 11:14:17 +=started 2024-09-12 10:36:26 +=ended 2024-09-12 10:36:26 =result ok -=elapsed 0.002119 +=elapsed 0.001501 =case ets_SUITE:match_delete =logfile ets_suite.match_delete.html -=started 2024-09-11 11:14:17 -=ended 2024-09-11 11:14:17 +=started 2024-09-12 10:36:26 +=ended 2024-09-12 10:36:26 =result ok -=elapsed 0.027648 +=elapsed 0.026453 =case ets_SUITE:match_delete3 =logfile ets_suite.match_delete3.html -=started 2024-09-11 11:14:17 -=ended 2024-09-11 11:14:17 +=started 2024-09-12 10:36:26 +=ended 2024-09-12 10:36:26 =result ok -=elapsed 0.022287 +=elapsed 0.023201 =case ets_SUITE:end_per_group -=logfile ets_suite.end_per_group.10786.html +=logfile ets_suite.end_per_group.42690.html =group_props [{name,delete}] -=started 2024-09-11 11:14:17 -=ended 2024-09-11 11:14:17 +=started 2024-09-12 10:36:26 +=ended 2024-09-12 10:36:26 =result ok =elapsed 0.0 -=group_time 51.978s +=group_time 52.976s =case ets_SUITE:firstnext =logfile ets_suite.firstnext.html -=started 2024-09-11 11:14:17 -=ended 2024-09-11 11:14:18 +=started 2024-09-12 10:36:26 +=ended 2024-09-12 10:36:26 =result ok -=elapsed 0.057733 +=elapsed 0.058988 =case ets_SUITE:firstnext_concurrent =logfile ets_suite.firstnext_concurrent.html -=started 2024-09-11 11:14:18 -=ended 2024-09-11 11:14:33 +=started 2024-09-12 10:36:26 +=ended 2024-09-12 10:36:41 =result ok -=elapsed 15.003123 +=elapsed 15.003115 =case ets_SUITE:firstnext_lookup =logfile ets_suite.firstnext_lookup.html -=started 2024-09-11 11:14:33 -=ended 2024-09-11 11:14:33 +=started 2024-09-12 10:36:41 +=ended 2024-09-12 10:36:41 =result ok -=elapsed 0.077811 +=elapsed 0.060802 =case ets_SUITE:firstnext_lookup_concurrent =logfile ets_suite.firstnext_lookup_concurrent.html -=started 2024-09-11 11:14:33 -=ended 2024-09-11 11:14:48 +=started 2024-09-12 10:36:41 +=ended 2024-09-12 10:36:56 =result ok -=elapsed 15.002476 +=elapsed 15.002654 =case ets_SUITE:slot =logfile ets_suite.slot.html -=started 2024-09-11 11:14:48 -=ended 2024-09-11 11:14:48 +=started 2024-09-12 10:36:56 +=ended 2024-09-12 10:36:56 =result ok -=elapsed 0.062025 +=elapsed 0.061319 =case ets_SUITE:hash_clash =logfile ets_suite.hash_clash.html -=started 2024-09-11 11:14:48 -=ended 2024-09-11 11:14:48 +=started 2024-09-12 10:36:56 +=ended 2024-09-12 10:36:56 =result ok -=elapsed 6.0e-6 +=elapsed 7.0e-6 =case ets_SUITE:init_per_group -=logfile ets_suite.init_per_group.11010.html +=logfile ets_suite.init_per_group.42914.html =group_props [{name,match}] -=started 2024-09-11 11:14:48 -=ended 2024-09-11 11:14:48 +=started 2024-09-12 10:36:56 +=ended 2024-09-12 10:36:56 =result ok =elapsed 0.0 =case ets_SUITE:match1 =logfile ets_suite.match1.html -=started 2024-09-11 11:14:48 -=ended 2024-09-11 11:14:48 +=started 2024-09-12 10:36:56 +=ended 2024-09-12 10:36:56 =result ok -=elapsed 0.061628 +=elapsed 0.059721 =case ets_SUITE:match2 =logfile ets_suite.match2.html -=started 2024-09-11 11:14:48 -=ended 2024-09-11 11:14:48 +=started 2024-09-12 10:36:56 +=ended 2024-09-12 10:36:56 =result ok -=elapsed 0.023075 +=elapsed 0.022847 =case ets_SUITE:match_object =logfile ets_suite.match_object.html -=started 2024-09-11 11:14:48 -=ended 2024-09-11 11:14:48 +=started 2024-09-12 10:36:56 +=ended 2024-09-12 10:36:57 =result ok -=elapsed 0.075275 +=elapsed 0.077607 =case ets_SUITE:match_object2 =logfile ets_suite.match_object2.html -=started 2024-09-11 11:14:48 -=ended 2024-09-11 11:14:49 +=started 2024-09-12 10:36:57 +=ended 2024-09-12 10:36:57 =result ok -=elapsed 0.714962 +=elapsed 0.715858 =case ets_SUITE:end_per_group -=logfile ets_suite.end_per_group.11170.html +=logfile ets_suite.end_per_group.43074.html =group_props [{name,match}] -=started 2024-09-11 11:14:49 -=ended 2024-09-11 11:14:49 +=started 2024-09-12 10:36:57 +=ended 2024-09-12 10:36:57 =result ok =elapsed 0.0 -=group_time 0.990s +=group_time 0.992s =case ets_SUITE:t_match_spec_run =logfile ets_suite.t_match_spec_run.html -=started 2024-09-11 11:14:49 -=ended 2024-09-11 11:14:50 +=started 2024-09-12 10:36:57 +=ended 2024-09-12 10:36:58 =result ok -=elapsed 0.934991 +=elapsed 0.934731 =case ets_SUITE:init_per_group -=logfile ets_suite.init_per_group.11234.html +=logfile ets_suite.init_per_group.43138.html =group_props [{name,lookup_element}] -=started 2024-09-11 11:14:50 -=ended 2024-09-11 11:14:50 +=started 2024-09-12 10:36:58 +=ended 2024-09-12 10:36:58 =result ok =elapsed 0.0 =case ets_SUITE:lookup_element_mult =logfile ets_suite.lookup_element_mult.html -=started 2024-09-11 11:14:50 -=ended 2024-09-11 11:14:50 +=started 2024-09-12 10:36:58 +=ended 2024-09-12 10:36:58 =result ok -=elapsed 0.025333 +=elapsed 0.026264 =case ets_SUITE:lookup_element_default =logfile ets_suite.lookup_element_default.html -=started 2024-09-11 11:14:50 -=ended 2024-09-11 11:14:50 +=started 2024-09-12 10:36:58 +=ended 2024-09-12 10:36:58 =result ok -=elapsed 0.00151 +=elapsed 0.001409 =case ets_SUITE:end_per_group -=logfile ets_suite.end_per_group.11330.html +=logfile ets_suite.end_per_group.43234.html =group_props [{name,lookup_element}] -=started 2024-09-11 11:14:50 -=ended 2024-09-11 11:14:50 +=started 2024-09-12 10:36:58 +=ended 2024-09-12 10:36:58 =result ok =elapsed 0.0 -=group_time 0.095s +=group_time 0.096s =case ets_SUITE:init_per_group -=logfile ets_suite.init_per_group.11362.html +=logfile ets_suite.init_per_group.43266.html =group_props [{name,misc}] -=started 2024-09-11 11:14:50 -=ended 2024-09-11 11:14:50 +=started 2024-09-12 10:36:58 +=ended 2024-09-12 10:36:58 =result ok =elapsed 0.0 =case ets_SUITE:misc1 =logfile ets_suite.misc1.html -=started 2024-09-11 11:14:50 -=ended 2024-09-11 11:14:50 +=started 2024-09-12 10:36:58 +=ended 2024-09-12 10:36:59 =result ok -=elapsed 0.100684 +=elapsed 0.098833 =case ets_SUITE:safe_fixtable =logfile ets_suite.safe_fixtable.html -=started 2024-09-11 11:14:50 -=ended 2024-09-11 11:14:50 +=started 2024-09-12 10:36:59 +=ended 2024-09-12 10:36:59 =result ok -=elapsed 0.231918 +=elapsed 0.230592 =case ets_SUITE:info =logfile ets_suite.info.html -=started 2024-09-11 11:14:50 -=ended 2024-09-11 11:14:51 +=started 2024-09-12 10:36:59 +=ended 2024-09-12 10:36:59 =result ok -=elapsed 0.463496 +=elapsed 0.447602 =case ets_SUITE:info_binary_stress =logfile ets_suite.info_binary_stress.html -=started 2024-09-11 11:14:51 -=ended 2024-09-11 11:14:55 +=started 2024-09-12 10:36:59 +=ended 2024-09-12 10:37:03 =result ok -=elapsed 4.014238 +=elapsed 4.013099 =case ets_SUITE:info_whereis_busy =logfile ets_suite.info_whereis_busy.html -=started 2024-09-11 11:14:55 -=ended 2024-09-11 11:14:55 +=started 2024-09-12 10:37:03 +=ended 2024-09-12 10:37:03 =result ok -=elapsed 0.039859 +=elapsed 0.041049 =case ets_SUITE:dups =logfile ets_suite.dups.html -=started 2024-09-11 11:14:55 -=ended 2024-09-11 11:14:55 +=started 2024-09-12 10:37:03 +=ended 2024-09-12 10:37:03 =result ok -=elapsed 0.032763 +=elapsed 0.031762 =case ets_SUITE:tab2list =logfile ets_suite.tab2list.html -=started 2024-09-11 11:14:55 -=ended 2024-09-11 11:14:55 +=started 2024-09-12 10:37:03 +=ended 2024-09-12 10:37:03 =result ok -=elapsed 0.00535 +=elapsed 0.003526 =case ets_SUITE:end_per_group -=logfile ets_suite.end_per_group.11618.html +=logfile ets_suite.end_per_group.43426.html =group_props [{name,misc}] -=started 2024-09-11 11:14:55 -=ended 2024-09-11 11:14:55 +=started 2024-09-12 10:37:03 +=ended 2024-09-12 10:37:03 =result ok =elapsed 0.0 -=group_time 5.071s +=group_time 5.051s =case ets_SUITE:init_per_group -=logfile ets_suite.init_per_group.11650.html +=logfile ets_suite.init_per_group.43458.html =group_props [{name,files}] -=started 2024-09-11 11:14:55 -=ended 2024-09-11 11:14:55 +=started 2024-09-12 10:37:04 +=ended 2024-09-12 10:37:04 =result ok =elapsed 0.0 =case ets_SUITE:tab2file =logfile ets_suite.tab2file.html -=started 2024-09-11 11:14:55 -=ended 2024-09-11 11:14:55 +=started 2024-09-12 10:37:04 +=ended 2024-09-12 10:37:04 =result ok -=elapsed 0.022979 +=elapsed 0.022985 =case ets_SUITE:tab2file2 =logfile ets_suite.tab2file2.html -=started 2024-09-11 11:14:55 -=ended 2024-09-11 11:14:55 +=started 2024-09-12 10:37:04 +=ended 2024-09-12 10:37:04 =result ok -=elapsed 0.196397 +=elapsed 0.199742 =case ets_SUITE:tabfile_ext1 =logfile ets_suite.tabfile_ext1.html -=started 2024-09-11 11:14:55 -=ended 2024-09-11 11:14:55 +=started 2024-09-12 10:37:04 +=ended 2024-09-12 10:37:04 =result ok -=elapsed 0.098707 +=elapsed 0.090802 =case ets_SUITE:tabfile_ext2 =logfile ets_suite.tabfile_ext2.html -=started 2024-09-11 11:14:55 -=ended 2024-09-11 11:14:56 +=started 2024-09-12 10:37:04 +=ended 2024-09-12 10:37:04 =result ok -=elapsed 0.092663 +=elapsed 0.099325 =case ets_SUITE:tabfile_ext3 =logfile ets_suite.tabfile_ext3.html -=started 2024-09-11 11:14:56 -=ended 2024-09-11 11:14:56 +=started 2024-09-12 10:37:04 +=ended 2024-09-12 10:37:04 =result ok -=elapsed 0.006189 +=elapsed 0.007063 =case ets_SUITE:tabfile_ext4 =logfile ets_suite.tabfile_ext4.html -=started 2024-09-11 11:14:56 -=ended 2024-09-11 11:15:03 +=started 2024-09-12 10:37:04 +=ended 2024-09-12 10:37:11 =result ok -=elapsed 7.092138 +=elapsed 6.853179 =case ets_SUITE:badfile =logfile ets_suite.badfile.html -=started 2024-09-11 11:15:03 -=ended 2024-09-11 11:15:03 +=started 2024-09-12 10:37:11 +=ended 2024-09-12 10:37:11 =result ok -=elapsed 0.001293 +=elapsed 0.001141 =case ets_SUITE:end_per_group -=logfile ets_suite.end_per_group.11906.html +=logfile ets_suite.end_per_group.43714.html =group_props [{name,files}] -=started 2024-09-11 11:15:03 -=ended 2024-09-11 11:15:03 +=started 2024-09-12 10:37:11 +=ended 2024-09-12 10:37:11 =result ok =elapsed 0.0 -=group_time 7.927s +=group_time 7.698s =case ets_SUITE:init_per_group -=logfile ets_suite.init_per_group.11938.html +=logfile ets_suite.init_per_group.43746.html =group_props [{name,heavy}] -=started 2024-09-11 11:15:03 -=ended 2024-09-11 11:15:03 +=started 2024-09-12 10:37:11 +=ended 2024-09-12 10:37:11 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =case ets_SUITE:heavy_lookup =logfile ets_suite.heavy_lookup.html -=started 2024-09-11 11:15:03 -=ended 2024-09-11 11:15:06 +=started 2024-09-12 10:37:11 +=ended 2024-09-12 10:37:14 =result ok -=elapsed 2.912391 +=elapsed 2.940386 =case ets_SUITE:heavy_lookup_element =logfile ets_suite.heavy_lookup_element.html -=started 2024-09-11 11:15:06 -=ended 2024-09-11 11:15:20 +=started 2024-09-12 10:37:14 +=ended 2024-09-12 10:37:29 =result ok -=elapsed 14.531953 +=elapsed 14.577727 =case ets_SUITE:heavy_concurrent =logfile ets_suite.heavy_concurrent.html -=started 2024-09-11 11:15:20 -=ended 2024-09-11 11:15:51 +=started 2024-09-12 10:37:29 +=ended 2024-09-12 10:37:59 =result ok -=elapsed 30.04927 +=elapsed 30.137605 =case ets_SUITE:end_per_group -=logfile ets_suite.end_per_group.12066.html +=logfile ets_suite.end_per_group.43874.html =group_props [{name,heavy}] -=started 2024-09-11 11:15:51 -=ended 2024-09-11 11:15:51 +=started 2024-09-12 10:37:59 +=ended 2024-09-12 10:37:59 =result ok -=elapsed 0.0 -=group_time 47.585s +=elapsed 1.0e-6 +=group_time 47.749s =case ets_SUITE:init_per_group -=logfile ets_suite.init_per_group.12098.html +=logfile ets_suite.init_per_group.43906.html =group_props [{name,insert_list}] -=started 2024-09-11 11:15:51 -=ended 2024-09-11 11:15:51 +=started 2024-09-12 10:37:59 +=ended 2024-09-12 10:37:59 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =case ets_SUITE:t_insert_list =logfile ets_suite.t_insert_list.html -=started 2024-09-11 11:15:51 -=ended 2024-09-11 11:15:51 +=started 2024-09-12 10:37:59 +=ended 2024-09-12 10:37:59 =result ok -=elapsed 0.130954 +=elapsed 0.152095 =case ets_SUITE:t_insert_list_set =logfile ets_suite.t_insert_list_set.html -=started 2024-09-11 11:15:51 -=ended 2024-09-11 11:15:51 +=started 2024-09-12 10:37:59 +=ended 2024-09-12 10:37:59 =result ok -=elapsed 0.002158 +=elapsed 0.002441 =case ets_SUITE:t_insert_list_bag =logfile ets_suite.t_insert_list_bag.html -=started 2024-09-11 11:15:51 -=ended 2024-09-11 11:15:51 +=started 2024-09-12 10:37:59 +=ended 2024-09-12 10:37:59 =result ok -=elapsed 0.206803 +=elapsed 0.211888 =case ets_SUITE:t_insert_list_duplicate_bag =logfile ets_suite.t_insert_list_duplicate_bag.html -=started 2024-09-11 11:15:51 -=ended 2024-09-11 11:15:51 +=started 2024-09-12 10:37:59 +=ended 2024-09-12 10:37:59 =result ok -=elapsed 0.01188 +=elapsed 0.01223 =case ets_SUITE:t_insert_list_delete_set =logfile ets_suite.t_insert_list_delete_set.html -=started 2024-09-11 11:15:51 -=ended 2024-09-11 11:16:11 +=started 2024-09-12 10:37:59 +=ended 2024-09-12 10:38:19 =result ok -=elapsed 19.860666 +=elapsed 19.859028 =case ets_SUITE:t_insert_list_parallel =logfile ets_suite.t_insert_list_parallel.html -=started 2024-09-11 11:16:11 -=ended 2024-09-11 11:16:12 +=started 2024-09-12 10:38:19 +=ended 2024-09-12 10:38:21 =result ok -=elapsed 1.442708 +=elapsed 1.544193 =case ets_SUITE:t_insert_list_delete_parallel =logfile ets_suite.t_insert_list_delete_parallel.html -=started 2024-09-11 11:16:12 -=ended 2024-09-11 11:16:13 +=started 2024-09-12 10:38:21 +=ended 2024-09-12 10:38:22 =result ok -=elapsed 0.780748 +=elapsed 0.774694 =case ets_SUITE:t_insert_list_kill_process =logfile ets_suite.t_insert_list_kill_process.html -=started 2024-09-11 11:16:13 -=ended 2024-09-11 11:16:17 +=started 2024-09-12 10:38:22 +=ended 2024-09-12 10:38:25 =result ok -=elapsed 3.311108 +=elapsed 3.330851 =case ets_SUITE:t_insert_list_insert_order_preserved =logfile ets_suite.t_insert_list_insert_order_preserved.html -=started 2024-09-11 11:16:17 -=ended 2024-09-11 11:16:21 +=started 2024-09-12 10:38:25 +=ended 2024-09-12 10:38:29 =result ok -=elapsed 4.450603 +=elapsed 4.028859 =case ets_SUITE:insert_trap_delete =logfile ets_suite.insert_trap_delete.html -=started 2024-09-11 11:16:21 -=ended 2024-09-11 11:16:33 +=started 2024-09-12 10:38:29 +=ended 2024-09-12 10:38:42 =result ok -=elapsed 12.17525 +=elapsed 12.663215 =case ets_SUITE:insert_trap_rename =logfile ets_suite.insert_trap_rename.html -=started 2024-09-11 11:16:33 -=ended 2024-09-11 11:16:40 +=started 2024-09-12 10:38:42 +=ended 2024-09-12 10:38:49 =result ok -=elapsed 6.325662 +=elapsed 6.742551 =case ets_SUITE:end_per_group -=logfile ets_suite.end_per_group.33155.html +=logfile ets_suite.end_per_group.44226.html =group_props [{name,insert_list}] -=started 2024-09-11 11:16:40 -=ended 2024-09-11 11:16:40 +=started 2024-09-12 10:38:49 +=ended 2024-09-12 10:38:49 =result ok -=elapsed 1.0e-6 -=group_time 48.973s +=elapsed 0.0 +=group_time 49.600s =case ets_SUITE:ordered =logfile ets_suite.ordered.html -=started 2024-09-11 11:16:40 -=ended 2024-09-11 11:16:40 +=started 2024-09-12 10:38:49 +=ended 2024-09-12 10:38:49 =result ok -=elapsed 0.019604 +=elapsed 0.017445 =case ets_SUITE:ordered_match =logfile ets_suite.ordered_match.html -=started 2024-09-11 11:16:40 -=ended 2024-09-11 11:16:40 +=started 2024-09-12 10:38:49 +=ended 2024-09-12 10:38:49 =result ok -=elapsed 0.045454 +=elapsed 0.043533 =case ets_SUITE:interface_equality =logfile ets_suite.interface_equality.html -=started 2024-09-11 11:16:40 -=ended 2024-09-11 11:16:40 +=started 2024-09-12 10:38:49 +=ended 2024-09-12 10:38:49 =result ok -=elapsed 0.037976 +=elapsed 0.035904 =case ets_SUITE:fixtable_next =logfile ets_suite.fixtable_next.html -=started 2024-09-11 11:16:40 -=ended 2024-09-11 11:16:40 +=started 2024-09-12 10:38:49 +=ended 2024-09-12 10:38:49 =result ok -=elapsed 0.029679 +=elapsed 0.027433 =case ets_SUITE:fixtable_iter_bag =logfile ets_suite.fixtable_iter_bag.html -=started 2024-09-11 11:16:40 -=ended 2024-09-11 11:16:40 +=started 2024-09-12 10:38:49 +=ended 2024-09-12 10:38:49 =result ok -=elapsed 0.015624 +=elapsed 0.015712 =case ets_SUITE:fixtable_insert =logfile ets_suite.fixtable_insert.html -=started 2024-09-11 11:16:40 -=ended 2024-09-11 11:16:40 +=started 2024-09-12 10:38:49 +=ended 2024-09-12 10:38:49 =result ok -=elapsed 1.9e-4 +=elapsed 2.74e-4 =case ets_SUITE:rename =logfile ets_suite.rename.html -=started 2024-09-11 11:16:40 -=ended 2024-09-11 11:16:40 +=started 2024-09-12 10:38:49 +=ended 2024-09-12 10:38:49 =result ok -=elapsed 0.022649 +=elapsed 0.025578 =case ets_SUITE:rename_unnamed =logfile ets_suite.rename_unnamed.html -=started 2024-09-11 11:16:40 -=ended 2024-09-11 11:16:40 +=started 2024-09-12 10:38:49 +=ended 2024-09-12 10:38:49 =result ok -=elapsed 0.024028 +=elapsed 0.024382 =case ets_SUITE:evil_rename =logfile ets_suite.evil_rename.html -=started 2024-09-11 11:16:40 -=ended 2024-09-11 11:16:40 +=started 2024-09-12 10:38:49 +=ended 2024-09-12 10:38:49 =result ok -=elapsed 0.288298 +=elapsed 0.311365 =case ets_SUITE:update_element =logfile ets_suite.update_element.html -=started 2024-09-11 11:16:40 -=ended 2024-09-11 11:16:47 +=started 2024-09-12 10:38:49 +=ended 2024-09-12 10:38:57 =result ok -=elapsed 7.087755 +=elapsed 7.158045 =case ets_SUITE:update_element_default =logfile ets_suite.update_element_default.html -=started 2024-09-11 11:16:47 -=ended 2024-09-11 11:16:47 +=started 2024-09-12 10:38:57 +=ended 2024-09-12 10:38:57 =result ok -=elapsed 0.004713 +=elapsed 0.004488 =case ets_SUITE:update_counter =logfile ets_suite.update_counter.html -=started 2024-09-11 11:16:47 -=ended 2024-09-11 11:16:48 +=started 2024-09-12 10:38:57 +=ended 2024-09-12 10:38:57 =result ok -=elapsed 0.881859 +=elapsed 0.873009 =case ets_SUITE:evil_update_counter =logfile ets_suite.evil_update_counter.html -=started 2024-09-11 11:16:48 -=ended 2024-09-11 11:16:51 +=started 2024-09-12 10:38:57 +=ended 2024-09-12 10:39:00 =result ok -=elapsed 2.492607 +=elapsed 2.510748 =case ets_SUITE:update_counter_with_default =logfile ets_suite.update_counter_with_default.html -=started 2024-09-11 11:16:51 -=ended 2024-09-11 11:16:51 +=started 2024-09-12 10:39:00 +=ended 2024-09-12 10:39:00 =result ok -=elapsed 0.00165 +=elapsed 0.002824 =case ets_SUITE:update_counter_with_default_bad_pos =logfile ets_suite.update_counter_with_default_bad_pos.html -=started 2024-09-11 11:16:51 -=ended 2024-09-11 11:16:51 +=started 2024-09-12 10:39:00 +=ended 2024-09-12 10:39:00 =result ok -=elapsed 2.34e-4 +=elapsed 1.67e-4 =case ets_SUITE:partly_bound =logfile ets_suite.partly_bound.html -=started 2024-09-11 11:16:51 -=ended 2024-09-11 11:16:52 +=started 2024-09-12 10:39:00 +=ended 2024-09-12 10:39:01 =result ok -=elapsed 0.717338 +=elapsed 0.731143 =case ets_SUITE:update_counter_table_growth =logfile ets_suite.update_counter_table_growth.html -=started 2024-09-11 11:16:52 -=ended 2024-09-11 11:16:52 +=started 2024-09-12 10:39:01 +=ended 2024-09-12 10:39:01 =result ok -=elapsed 0.088448 +=elapsed 0.090793 =case ets_SUITE:match_heavy =logfile ets_suite.match_heavy.html -=started 2024-09-11 11:16:52 -=ended 2024-09-11 11:16:54 +=started 2024-09-12 10:39:01 +=ended 2024-09-12 10:39:03 =result ok -=elapsed 1.772169 +=elapsed 1.732686 =case ets_SUITE:init_per_group -=logfile ets_suite.init_per_group.17794.html +=logfile ets_suite.init_per_group.48802.html =group_props [{name,fold}] -=started 2024-09-11 11:16:54 -=ended 2024-09-11 11:16:54 +=started 2024-09-12 10:39:03 +=ended 2024-09-12 10:39:03 =result ok =elapsed 0.0 =case ets_SUITE:foldl_ordered =logfile ets_suite.foldl_ordered.html -=started 2024-09-11 11:16:54 -=ended 2024-09-11 11:16:54 +=started 2024-09-12 10:39:03 +=ended 2024-09-12 10:39:03 =result ok -=elapsed 0.038797 +=elapsed 0.034906 =case ets_SUITE:foldr_ordered =logfile ets_suite.foldr_ordered.html -=started 2024-09-11 11:16:54 -=ended 2024-09-11 11:16:54 +=started 2024-09-12 10:39:03 +=ended 2024-09-12 10:39:03 =result ok -=elapsed 0.078937 +=elapsed 0.034322 =case ets_SUITE:foldl =logfile ets_suite.foldl.html -=started 2024-09-11 11:16:54 -=ended 2024-09-11 11:16:54 +=started 2024-09-12 10:39:03 +=ended 2024-09-12 10:39:03 =result ok -=elapsed 0.142744 +=elapsed 0.10326 =case ets_SUITE:foldr =logfile ets_suite.foldr.html -=started 2024-09-11 11:16:54 -=ended 2024-09-11 11:16:54 +=started 2024-09-12 10:39:03 +=ended 2024-09-12 10:39:03 =result ok -=elapsed 0.118031 +=elapsed 0.104979 =case ets_SUITE:fold_empty =logfile ets_suite.fold_empty.html -=started 2024-09-11 11:16:54 -=ended 2024-09-11 11:16:54 +=started 2024-09-12 10:39:03 +=ended 2024-09-12 10:39:03 =result ok -=elapsed 0.056693 +=elapsed 0.056792 =case ets_SUITE:fold_badarg =logfile ets_suite.fold_badarg.html -=started 2024-09-11 11:16:54 -=ended 2024-09-11 11:16:54 +=started 2024-09-12 10:39:03 +=ended 2024-09-12 10:39:03 =result ok -=elapsed 2.0e-6 +=elapsed 1.8e-5 =case ets_SUITE:end_per_group -=logfile ets_suite.end_per_group.18018.html +=logfile ets_suite.end_per_group.49026.html =group_props [{name,fold}] -=started 2024-09-11 11:16:54 -=ended 2024-09-11 11:16:54 +=started 2024-09-12 10:39:03 +=ended 2024-09-12 10:39:03 =result ok =elapsed 0.0 -=group_time 0.595s +=group_time 0.495s =case ets_SUITE:member =logfile ets_suite.member.html -=started 2024-09-11 11:16:54 -=ended 2024-09-11 11:16:54 +=started 2024-09-12 10:39:03 +=ended 2024-09-12 10:39:03 =result ok -=elapsed 0.079869 +=elapsed 0.082042 =case ets_SUITE:t_delete_object =logfile ets_suite.t_delete_object.html -=started 2024-09-11 11:16:54 -=ended 2024-09-11 11:16:56 +=started 2024-09-12 10:39:03 +=ended 2024-09-12 10:39:05 =result ok -=elapsed 1.258042 +=elapsed 1.27435 =case ets_SUITE:select_bound_chunk =logfile ets_suite.select_bound_chunk.html -=started 2024-09-11 11:16:56 -=ended 2024-09-11 11:16:56 +=started 2024-09-12 10:39:05 +=ended 2024-09-12 10:39:05 =result ok -=elapsed 3.27e-4 +=elapsed 3.46e-4 =case ets_SUITE:t_init_table =logfile ets_suite.t_init_table.html -=started 2024-09-11 11:16:56 -=ended 2024-09-11 11:16:56 +=started 2024-09-12 10:39:05 +=ended 2024-09-12 10:39:05 =result ok -=elapsed 0.132539 +=elapsed 0.131293 =case ets_SUITE:t_whitebox =logfile ets_suite.t_whitebox.html -=started 2024-09-11 11:16:56 -=ended 2024-09-11 11:16:56 +=started 2024-09-12 10:39:05 +=ended 2024-09-12 10:39:05 =result ok -=elapsed 0.010708 +=elapsed 0.010383 =case ets_SUITE:t_delete_all_objects =logfile ets_suite.t_delete_all_objects.html -=started 2024-09-11 11:16:56 -=ended 2024-09-11 11:16:59 +=started 2024-09-12 10:39:05 +=ended 2024-09-12 10:39:08 =result ok -=elapsed 3.039437 +=elapsed 3.141918 =case ets_SUITE:t_delete_all_objects_trap =logfile ets_suite.t_delete_all_objects_trap.html -=started 2024-09-11 11:16:59 -=ended 2024-09-11 11:17:01 +=started 2024-09-12 10:39:08 +=ended 2024-09-12 10:39:11 =result ok -=elapsed 2.50602 +=elapsed 2.539645 =case ets_SUITE:t_test_ms =logfile ets_suite.t_test_ms.html -=started 2024-09-11 11:17:01 -=ended 2024-09-11 11:17:01 +=started 2024-09-12 10:39:11 +=ended 2024-09-12 10:39:11 =result ok -=elapsed 0.001153 +=elapsed 0.001266 =case ets_SUITE:t_select_delete =logfile ets_suite.t_select_delete.html -=started 2024-09-11 11:17:01 -=ended 2024-09-11 11:17:07 +=started 2024-09-12 10:39:11 +=ended 2024-09-12 10:39:16 =result ok -=elapsed 5.740803 +=elapsed 5.676493 =case ets_SUITE:t_select_replace =logfile ets_suite.t_select_replace.html -=started 2024-09-11 11:17:07 -=ended 2024-09-11 11:17:09 +=started 2024-09-12 10:39:16 +=ended 2024-09-12 10:39:18 =result ok -=elapsed 1.746123 +=elapsed 1.798839 =case ets_SUITE:t_select_replace_next_bug =logfile ets_suite.t_select_replace_next_bug.html -=started 2024-09-11 11:17:09 -=ended 2024-09-11 11:17:09 +=started 2024-09-12 10:39:18 +=ended 2024-09-12 10:39:18 =result ok -=elapsed 1.0e-5 +=elapsed 1.4e-5 =case ets_SUITE:t_select_pam_stack_overflow_bug =logfile ets_suite.t_select_pam_stack_overflow_bug.html -=started 2024-09-11 11:17:09 -=ended 2024-09-11 11:17:09 +=started 2024-09-12 10:39:18 +=ended 2024-09-12 10:39:18 =result ok -=elapsed 7.0e-6 +=elapsed 8.0e-6 =case ets_SUITE:t_select_flatmap_term_copy_bug =logfile ets_suite.t_select_flatmap_term_copy_bug.html -=started 2024-09-11 11:17:09 -=ended 2024-09-11 11:17:09 +=started 2024-09-12 10:39:18 +=ended 2024-09-12 10:39:18 =result ok -=elapsed 4.0e-5 +=elapsed 4.7e-5 =case ets_SUITE:t_select_hashmap_term_copy_bug =logfile ets_suite.t_select_hashmap_term_copy_bug.html -=started 2024-09-11 11:17:09 -=ended 2024-09-11 11:17:09 +=started 2024-09-12 10:39:18 +=ended 2024-09-12 10:39:18 =result ok -=elapsed 0.029657 +=elapsed 0.029626 =case ets_SUITE:t_ets_dets =logfile ets_suite.t_ets_dets.html -=started 2024-09-11 11:17:09 -=ended 2024-09-11 11:17:09 +=started 2024-09-12 10:39:18 +=ended 2024-09-12 10:39:18 =result ok -=elapsed 0.14697 +=elapsed 0.147044 =case ets_SUITE:memory =logfile ets_suite.memory.html -=started 2024-09-11 11:17:09 -=ended 2024-09-11 11:17:09 +=started 2024-09-12 10:39:18 +=ended 2024-09-12 10:39:18 =result ok -=elapsed 0.007253 +=elapsed 0.005328 =case ets_SUITE:t_select_reverse =logfile ets_suite.t_select_reverse.html -=started 2024-09-11 11:17:09 -=ended 2024-09-11 11:17:09 +=started 2024-09-12 10:39:18 +=ended 2024-09-12 10:39:18 =result ok -=elapsed 0.002097 +=elapsed 0.001988 =case ets_SUITE:t_bucket_disappears =logfile ets_suite.t_bucket_disappears.html -=started 2024-09-11 11:17:09 -=ended 2024-09-11 11:17:09 +=started 2024-09-12 10:39:18 +=ended 2024-09-12 10:39:18 =result ok -=elapsed 0.027675 +=elapsed 0.033452 =case ets_SUITE:t_named_select =logfile ets_suite.t_named_select.html -=started 2024-09-11 11:17:09 -=ended 2024-09-11 11:17:09 +=started 2024-09-12 10:39:18 +=ended 2024-09-12 10:39:19 =result ok -=elapsed 0.023191 +=elapsed 0.02602 =case ets_SUITE:select_fixtab_owner_change =logfile ets_suite.select_fixtab_owner_change.html -=started 2024-09-11 11:17:09 -=ended 2024-09-11 11:17:09 +=started 2024-09-12 10:39:19 +=ended 2024-09-12 10:39:19 =result ok -=elapsed 8.27e-4 +=elapsed 8.09e-4 =case ets_SUITE:select_fail =logfile ets_suite.select_fail.html -=started 2024-09-11 11:17:09 -=ended 2024-09-11 11:17:09 +=started 2024-09-12 10:39:19 +=ended 2024-09-12 10:39:19 =result ok -=elapsed 0.002977 +=elapsed 0.003292 =case ets_SUITE:t_insert_new =logfile ets_suite.t_insert_new.html -=started 2024-09-11 11:17:09 -=ended 2024-09-11 11:17:09 +=started 2024-09-12 10:39:19 +=ended 2024-09-12 10:39:19 =result ok -=elapsed 0.007186 +=elapsed 0.007529 =case ets_SUITE:t_repair_continuation =logfile ets_suite.t_repair_continuation.html -=started 2024-09-11 11:17:09 -=ended 2024-09-11 11:17:10 +=started 2024-09-12 10:39:19 +=ended 2024-09-12 10:39:19 =result ok -=elapsed 0.071895 +=elapsed 0.072091 =case ets_SUITE:otp_5340 =logfile ets_suite.otp_5340.html -=started 2024-09-11 11:17:10 -=ended 2024-09-11 11:17:10 +=started 2024-09-12 10:39:19 +=ended 2024-09-12 10:39:19 =result ok -=elapsed 0.107788 +=elapsed 0.112513 =case ets_SUITE:otp_6338 =logfile ets_suite.otp_6338.html -=started 2024-09-11 11:17:10 -=ended 2024-09-11 11:17:10 +=started 2024-09-12 10:39:19 +=ended 2024-09-12 10:39:19 =result ok -=elapsed 0.002721 +=elapsed 0.001861 =case ets_SUITE:otp_6842_select_1000 =logfile ets_suite.otp_6842_select_1000.html -=started 2024-09-11 11:17:10 -=ended 2024-09-11 11:17:10 +=started 2024-09-12 10:39:19 +=ended 2024-09-12 10:39:19 =result ok -=elapsed 0.48911 +=elapsed 0.490927 =case ets_SUITE:otp_7665 =logfile ets_suite.otp_7665.html -=started 2024-09-11 11:17:10 -=ended 2024-09-11 11:17:10 +=started 2024-09-12 10:39:19 +=ended 2024-09-12 10:39:19 =result ok -=elapsed 0.004249 +=elapsed 0.003356 =case ets_SUITE:select_mbuf_trapping =logfile ets_suite.select_mbuf_trapping.html -=started 2024-09-11 11:17:10 -=ended 2024-09-11 11:17:10 +=started 2024-09-12 10:39:19 +=ended 2024-09-12 10:39:19 =result ok -=elapsed 6.54e-4 +=elapsed 9.7e-4 =case ets_SUITE:otp_8732 =logfile ets_suite.otp_8732.html -=started 2024-09-11 11:17:10 -=ended 2024-09-11 11:17:10 +=started 2024-09-12 10:39:19 +=ended 2024-09-12 10:39:19 =result ok -=elapsed 0.001819 +=elapsed 0.001527 =case ets_SUITE:meta_wb =logfile ets_suite.meta_wb.html -=started 2024-09-11 11:17:10 -=ended 2024-09-11 11:17:11 +=started 2024-09-12 10:39:19 +=ended 2024-09-12 10:39:20 =result ok -=elapsed 0.493801 +=elapsed 0.491298 =case ets_SUITE:grow_shrink =logfile ets_suite.grow_shrink.html -=started 2024-09-11 11:17:11 -=ended 2024-09-11 11:17:11 +=started 2024-09-12 10:39:20 +=ended 2024-09-12 10:39:20 =result ok -=elapsed 0.253043 +=elapsed 0.257886 =case ets_SUITE:grow_pseudo_deleted =logfile ets_suite.grow_pseudo_deleted.html -=started 2024-09-11 11:17:11 -=ended 2024-09-11 11:17:11 +=started 2024-09-12 10:39:20 +=ended 2024-09-12 10:39:20 =result ok -=elapsed 0.133565 +=elapsed 0.139624 =case ets_SUITE:shrink_pseudo_deleted =logfile ets_suite.shrink_pseudo_deleted.html -=started 2024-09-11 11:17:11 -=ended 2024-09-11 11:17:11 +=started 2024-09-12 10:39:20 +=ended 2024-09-12 10:39:20 =result ok -=elapsed 0.03828 +=elapsed 0.039325 =case ets_SUITE:init_per_group -=logfile ets_suite.init_per_group.19586.html +=logfile ets_suite.init_per_group.50530.html =group_props [{name,meta_smp}] -=started 2024-09-11 11:17:11 -=ended 2024-09-11 11:17:11 +=started 2024-09-12 10:39:20 +=ended 2024-09-12 10:39:20 =result ok =elapsed 0.0 =case ets_SUITE:meta_lookup_unnamed_read =logfile ets_suite.meta_lookup_unnamed_read.html -=started 2024-09-11 11:17:11 -=ended 2024-09-11 11:17:11 +=started 2024-09-12 10:39:20 +=ended 2024-09-12 10:39:21 =result ok -=elapsed 0.002113 +=elapsed 0.001759 =case ets_SUITE:meta_lookup_unnamed_write =logfile ets_suite.meta_lookup_unnamed_write.html -=started 2024-09-11 11:17:11 -=ended 2024-09-11 11:17:11 +=started 2024-09-12 10:39:21 +=ended 2024-09-12 10:39:21 =result ok -=elapsed 0.002353 +=elapsed 0.002206 =case ets_SUITE:meta_lookup_named_read =logfile ets_suite.meta_lookup_named_read.html -=started 2024-09-11 11:17:11 -=ended 2024-09-11 11:17:11 +=started 2024-09-12 10:39:21 +=ended 2024-09-12 10:39:21 =result ok -=elapsed 0.002977 +=elapsed 0.003177 =case ets_SUITE:meta_lookup_named_write =logfile ets_suite.meta_lookup_named_write.html -=started 2024-09-11 11:17:11 -=ended 2024-09-11 11:17:11 +=started 2024-09-12 10:39:21 +=ended 2024-09-12 10:39:21 =result ok -=elapsed 0.003288 +=elapsed 0.003207 =case ets_SUITE:meta_newdel_unnamed =logfile ets_suite.meta_newdel_unnamed.html -=started 2024-09-11 11:17:11 -=ended 2024-09-11 11:17:11 +=started 2024-09-12 10:39:21 +=ended 2024-09-12 10:39:21 =result ok -=elapsed 0.017293 +=elapsed 0.01788 =case ets_SUITE:meta_newdel_named =logfile ets_suite.meta_newdel_named.html -=started 2024-09-11 11:17:11 -=ended 2024-09-11 11:17:11 +=started 2024-09-12 10:39:21 +=ended 2024-09-12 10:39:21 =result ok -=elapsed 0.02143 +=elapsed 0.022142 =case ets_SUITE:end_per_group -=logfile ets_suite.end_per_group.19746.html +=logfile ets_suite.end_per_group.50658.html =group_props [{name,meta_smp}] -=started 2024-09-11 11:17:11 -=ended 2024-09-11 11:17:11 +=started 2024-09-12 10:39:21 +=ended 2024-09-12 10:39:21 =result ok -=elapsed 0.0 -=group_time 0.209s +=elapsed 1.0e-6 +=group_time 0.212s =case ets_SUITE:smp_insert =logfile ets_suite.smp_insert.html -=started 2024-09-11 11:17:11 -=ended 2024-09-11 11:17:12 +=started 2024-09-12 10:39:21 +=ended 2024-09-12 10:39:21 =result ok -=elapsed 0.159991 +=elapsed 0.16437 =case ets_SUITE:smp_fixed_delete =logfile ets_suite.smp_fixed_delete.html -=started 2024-09-11 11:17:12 -=ended 2024-09-11 11:17:12 +=started 2024-09-12 10:39:21 +=ended 2024-09-12 10:39:21 =result ok -=elapsed 0.06841 +=elapsed 0.079309 =case ets_SUITE:smp_unfix_fix =logfile ets_suite.smp_unfix_fix.html -=started 2024-09-11 11:17:12 -=ended 2024-09-11 11:17:12 +=started 2024-09-12 10:39:21 +=ended 2024-09-12 10:39:21 =result ok -=elapsed 0.070132 +=elapsed 0.075406 =case ets_SUITE:smp_select_replace =logfile ets_suite.smp_select_replace.html -=started 2024-09-11 11:17:12 -=ended 2024-09-11 11:17:36 +=started 2024-09-12 10:39:21 +=ended 2024-09-12 10:39:45 =result ok -=elapsed 24.019865 +=elapsed 24.017347 =case ets_SUITE:smp_ordered_iteration =logfile ets_suite.smp_ordered_iteration.html -=started 2024-09-11 11:17:36 -=ended 2024-09-11 11:17:38 +=started 2024-09-12 10:39:45 +=ended 2024-09-12 10:39:47 =result ok -=elapsed 2.02109 +=elapsed 2.022445 =case ets_SUITE:smp_select_delete =logfile ets_suite.smp_select_delete.html -=started 2024-09-11 11:17:38 -=ended 2024-09-11 11:17:39 +=started 2024-09-12 10:39:47 +=ended 2024-09-12 10:39:49 =result ok -=elapsed 1.311088 +=elapsed 1.313032 =case ets_SUITE:otp_8166 =logfile ets_suite.otp_8166.html -=started 2024-09-11 11:17:39 -=ended 2024-09-11 11:17:40 +=started 2024-09-12 10:39:49 +=ended 2024-09-12 10:39:49 =result ok -=elapsed 0.270521 +=elapsed 0.238281 =case ets_SUITE:exit_large_table_owner =logfile ets_suite.exit_large_table_owner.html -=started 2024-09-11 11:17:40 -=ended 2024-09-11 11:17:50 +=started 2024-09-12 10:39:49 +=ended 2024-09-12 10:40:01 =result ok -=elapsed 10.576289 +=elapsed 12.23485 =case ets_SUITE:exit_many_large_table_owner =logfile ets_suite.exit_many_large_table_owner.html -=started 2024-09-11 11:17:50 -=ended 2024-09-11 11:18:10 +=started 2024-09-12 10:40:01 +=ended 2024-09-12 10:40:21 =result ok -=elapsed 20.221609 +=elapsed 19.978059 =case ets_SUITE:exit_many_tables_owner =logfile ets_suite.exit_many_tables_owner.html -=started 2024-09-11 11:18:10 -=ended 2024-09-11 11:18:10 +=started 2024-09-12 10:40:21 +=ended 2024-09-12 10:40:21 =result ok -=elapsed 0.012778 +=elapsed 0.011613 =case ets_SUITE:exit_many_many_tables_owner =logfile ets_suite.exit_many_many_tables_owner.html -=started 2024-09-11 11:18:10 -=ended 2024-09-11 11:18:12 +=started 2024-09-12 10:40:21 +=ended 2024-09-12 10:40:22 =result ok -=elapsed 1.077944 +=elapsed 1.108739 =case ets_SUITE:write_concurrency =logfile ets_suite.write_concurrency.html -=started 2024-09-11 11:18:12 -=ended 2024-09-11 11:18:12 +=started 2024-09-12 10:40:22 +=ended 2024-09-12 10:40:22 =result ok -=elapsed 0.002589 +=elapsed 0.001999 =case ets_SUITE:heir =logfile ets_suite.heir.html -=started 2024-09-11 11:18:12 -=ended 2024-09-11 11:18:12 +=started 2024-09-12 10:40:22 +=ended 2024-09-12 10:40:22 =result ok -=elapsed 0.195187 +=elapsed 0.204673 =case ets_SUITE:give_away =logfile ets_suite.give_away.html -=started 2024-09-11 11:18:12 -=ended 2024-09-11 11:18:12 +=started 2024-09-12 10:40:22 +=ended 2024-09-12 10:40:22 =result ok -=elapsed 0.003401 +=elapsed 0.00466 =case ets_SUITE:setopts =logfile ets_suite.setopts.html -=started 2024-09-11 11:18:12 -=ended 2024-09-11 11:18:12 +=started 2024-09-12 10:40:22 +=ended 2024-09-12 10:40:23 =result ok -=elapsed 0.001374 +=elapsed 0.001969 =case ets_SUITE:bad_table =logfile ets_suite.bad_table.html -=started 2024-09-11 11:18:12 -=ended 2024-09-11 11:18:12 +=started 2024-09-12 10:40:23 +=ended 2024-09-12 10:40:23 =result ok -=elapsed 0.189003 +=elapsed 0.179773 =case ets_SUITE:types =logfile ets_suite.types.html -=started 2024-09-11 11:18:12 -=ended 2024-09-11 11:18:12 +=started 2024-09-12 10:40:23 +=ended 2024-09-12 10:40:23 =result ok -=elapsed 0.034255 +=elapsed 0.033314 =case ets_SUITE:otp_10182 =logfile ets_suite.otp_10182.html -=started 2024-09-11 11:18:12 -=ended 2024-09-11 11:18:12 +=started 2024-09-12 10:40:23 +=ended 2024-09-12 10:40:23 =result ok -=elapsed 0.007981 +=elapsed 0.00999 =case ets_SUITE:otp_9932 =logfile ets_suite.otp_9932.html -=started 2024-09-11 11:18:12 -=ended 2024-09-11 11:18:12 +=started 2024-09-12 10:40:23 +=ended 2024-09-12 10:40:23 =result ok -=elapsed 5.6e-5 +=elapsed 5.2e-5 =case ets_SUITE:otp_9423 =logfile ets_suite.otp_9423.html -=started 2024-09-11 11:18:12 -=ended 2024-09-11 11:18:12 +=started 2024-09-12 10:40:23 +=ended 2024-09-12 10:40:23 =result ok -=elapsed 0.170665 +=elapsed 0.176195 =case ets_SUITE:compress_magic_ref =logfile ets_suite.compress_magic_ref.html -=started 2024-09-11 11:18:12 -=ended 2024-09-11 11:18:12 +=started 2024-09-12 10:40:23 +=ended 2024-09-12 10:40:23 =result ok -=elapsed 1.3e-4 +=elapsed 1.67e-4 =case ets_SUITE:ets_all =logfile ets_suite.ets_all.html -=started 2024-09-11 11:18:12 -=ended 2024-09-11 11:18:15 +=started 2024-09-12 10:40:23 +=ended 2024-09-12 10:40:26 =result ok -=elapsed 3.000905 +=elapsed 3.000396 =case ets_SUITE:massive_ets_all =logfile ets_suite.massive_ets_all.html -=started 2024-09-11 11:18:15 -=ended 2024-09-11 11:18:15 +=started 2024-09-12 10:40:26 +=ended 2024-09-12 10:40:26 =result ok -=elapsed 0.006577 +=elapsed 0.006559 =case ets_SUITE:take =logfile ets_suite.take.html -=started 2024-09-11 11:18:15 -=ended 2024-09-11 11:18:15 +=started 2024-09-12 10:40:26 +=ended 2024-09-12 10:40:26 =result ok -=elapsed 2.47e-4 +=elapsed 2.74e-4 =case ets_SUITE:whereis_table =logfile ets_suite.whereis_table.html -=started 2024-09-11 11:18:15 -=ended 2024-09-11 11:18:15 +=started 2024-09-12 10:40:26 +=ended 2024-09-12 10:40:26 =result ok -=elapsed 3.5e-5 +=elapsed 3.6e-5 =case ets_SUITE:delete_unfix_race =logfile ets_suite.delete_unfix_race.html -=started 2024-09-11 11:18:15 -=ended 2024-09-11 11:18:16 +=started 2024-09-12 10:40:26 +=ended 2024-09-12 10:40:26 =result ok -=elapsed 0.043239 +=elapsed 0.028933 =case ets_SUITE:test_throughput_benchmark =logfile ets_suite.test_throughput_benchmark.html -=started 2024-09-11 11:18:16 -=ended 2024-09-11 11:18:47 -=result ok: Result visualization -=elapsed 30.99899 +=started 2024-09-12 10:40:26 +=ended 2024-09-12 10:40:57 +=result ok: Result visualization +=elapsed 31.03073 === =case ets_SUITE:init_per_group =group_props [{name,"benchmark"}] -=started 2024-09-11 11:18:47 +=started 2024-09-12 10:40:57 =result skipped: Benchmark only === *** Skipping {ets_SUITE,init_per_group} *** === =case ets_SUITE:long_throughput_benchmark =group_props [{name,"benchmark"}] -=started 2024-09-11 11:18:47 +=started 2024-09-12 10:40:57 =result skipped: Benchmark only === *** Skipping test case #712 {ets_SUITE,long_throughput_benchmark} *** === =case ets_SUITE:end_per_group =group_props [{name,"benchmark"}] -=started 2024-09-11 11:18:47 +=started 2024-09-12 10:40:57 =result skipped: Benchmark only === *** Skipping {ets_SUITE,end_per_group} *** =case ets_SUITE:test_table_size_concurrency =logfile ets_suite.test_table_size_concurrency.html -=started 2024-09-11 11:18:47 -=ended 2024-09-11 11:18:48 +=started 2024-09-12 10:40:57 +=ended 2024-09-12 10:40:59 =result ok -=elapsed 1.192557 +=elapsed 1.32371 =case ets_SUITE:test_table_memory_concurrency =logfile ets_suite.test_table_memory_concurrency.html -=started 2024-09-11 11:18:48 -=ended 2024-09-11 11:18:50 +=started 2024-09-12 10:40:59 +=ended 2024-09-12 10:41:01 =result ok -=elapsed 1.264322 +=elapsed 1.319692 =case ets_SUITE:test_delete_table_while_size_snapshot =logfile ets_suite.test_delete_table_while_size_snapshot.html -=started 2024-09-11 11:18:50 -=ended 2024-09-11 11:18:50 +=started 2024-09-12 10:41:01 +=ended 2024-09-12 10:41:01 =result ok -=elapsed 0.507759 +=elapsed 0.495808 =case ets_SUITE:test_decentralized_counters_setting =logfile ets_suite.test_decentralized_counters_setting.html -=started 2024-09-11 11:18:50 -=ended 2024-09-11 11:18:50 +=started 2024-09-12 10:41:01 +=ended 2024-09-12 10:41:01 =result ok -=elapsed 0.002108 +=elapsed 0.002111 =case ets_SUITE:ms_excessive_nesting =logfile ets_suite.ms_excessive_nesting.html -=started 2024-09-11 11:18:50 -=ended 2024-09-11 11:18:51 +=started 2024-09-12 10:41:01 +=ended 2024-09-12 10:41:01 =result ok: match_spec_compile() got system_limit; select_replace(_,[ordered_set]) got system_limit; select_replace(_,[set]) got system_limit -=elapsed 0.173536 +=elapsed 0.168965 =case ets_SUITE:error_info =logfile ets_suite.error_info.html -=started 2024-09-11 11:18:51 -=ended 2024-09-11 11:18:51 +=started 2024-09-12 10:41:01 +=ended 2024-09-12 10:41:02 =result ok -=elapsed 0.116039 +=elapsed 0.096941 =case ets_SUITE:bound_maps =logfile ets_suite.bound_maps.html -=started 2024-09-11 11:18:51 -=ended 2024-09-11 11:18:51 +=started 2024-09-12 10:41:02 +=ended 2024-09-12 10:41:02 =result ok -=elapsed 1.0e-5 +=elapsed 1.3e-5 =case ets_SUITE:end_per_suite =logfile ets_suite.end_per_suite.html -=started 2024-09-11 11:18:51 -=ended 2024-09-11 11:18:51 +=started 2024-09-12 10:41:02 +=ended 2024-09-12 10:41:02 =result ok -=elapsed 1.1e-5 -=group_time 326.048s +=elapsed 9.0e-6 +=group_time 329.375s =case ets_property_test_SUITE:init_per_suite =logfile ets_property_test_suite.init_per_suite.html -=started 2024-09-11 11:18:51 -=ended 2024-09-11 11:18:52 +=started 2024-09-12 10:41:02 +=ended 2024-09-12 10:41:03 =result ok -=elapsed 1.280873 +=elapsed 1.274948 =case ets_property_test_SUITE:first_case =logfile ets_property_test_suite.first_case.html -=started 2024-09-11 11:18:52 -=ended 2024-09-11 11:18:52 +=started 2024-09-12 10:41:03 +=ended 2024-09-12 10:41:03 =result ok -=elapsed 0.135007 +=elapsed 0.115949 =case ets_property_test_SUITE:next_case =logfile ets_property_test_suite.next_case.html -=started 2024-09-11 11:18:52 -=ended 2024-09-11 11:18:52 +=started 2024-09-12 10:41:03 +=ended 2024-09-12 10:41:03 =result ok -=elapsed 0.136306 +=elapsed 0.100212 =case ets_property_test_SUITE:last_case =logfile ets_property_test_suite.last_case.html -=started 2024-09-11 11:18:52 -=ended 2024-09-11 11:18:53 +=started 2024-09-12 10:41:03 +=ended 2024-09-12 10:41:03 =result ok -=elapsed 0.117154 +=elapsed 0.131327 =case ets_property_test_SUITE:prev_case =logfile ets_property_test_suite.prev_case.html -=started 2024-09-11 11:18:53 -=ended 2024-09-11 11:18:53 +=started 2024-09-12 10:41:03 +=ended 2024-09-12 10:41:04 =result ok -=elapsed 0.113711 +=elapsed 0.121771 =case ets_property_test_SUITE:end_per_suite =logfile ets_property_test_suite.end_per_suite.html -=started 2024-09-11 11:18:53 -=ended 2024-09-11 11:18:53 +=started 2024-09-12 10:41:04 +=ended 2024-09-12 10:41:04 =result ok =elapsed 0.0 -=group_time 1.901s +=group_time 1.862s =case ets_tough_SUITE:init_per_suite =logfile ets_tough_suite.init_per_suite.html -=started 2024-09-11 11:18:53 -=ended 2024-09-11 11:18:53 +=started 2024-09-12 10:41:04 +=ended 2024-09-12 10:41:04 =result ok =elapsed 0.0 =case ets_tough_SUITE:ex1 =logfile ets_tough_suite.ex1.html -=started 2024-09-11 11:18:53 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:04 +=ended 2024-09-12 10:41:04 =result ok -=elapsed 0.832494 +=elapsed 0.851067 =case ets_tough_SUITE:end_per_suite =logfile ets_tough_suite.end_per_suite.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:04 +=ended 2024-09-12 10:41:04 =result ok =elapsed 0.0 -=group_time 0.882s +=group_time 0.901s =case file_sorter_SUITE:init_per_suite =logfile file_sorter_suite.init_per_suite.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:04 +=ended 2024-09-12 10:41:04 =result ok =elapsed 0.0 =case file_sorter_SUITE:basic =logfile file_sorter_suite.basic.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:04 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.006298 +=elapsed 0.006338 =case file_sorter_SUITE:badarg =logfile file_sorter_suite.badarg.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.003705 +=elapsed 0.003693 =case file_sorter_SUITE:term_sort =logfile file_sorter_suite.term_sort.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.052303 +=elapsed 0.063927 =case file_sorter_SUITE:term_keysort =logfile file_sorter_suite.term_keysort.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.025974 +=elapsed 0.029773 =case file_sorter_SUITE:binary_term_sort =logfile file_sorter_suite.binary_term_sort.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.055713 +=elapsed 0.055421 =case file_sorter_SUITE:binary_term_keysort =logfile file_sorter_suite.binary_term_keysort.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.023916 +=elapsed 0.024683 =case file_sorter_SUITE:binary_sort =logfile file_sorter_suite.binary_sort.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.053213 +=elapsed 0.056205 =case file_sorter_SUITE:term_merge =logfile file_sorter_suite.term_merge.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.015566 +=elapsed 0.019561 =case file_sorter_SUITE:term_keymerge =logfile file_sorter_suite.term_keymerge.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.059223 +=elapsed 0.072808 =case file_sorter_SUITE:binary_term_merge =logfile file_sorter_suite.binary_term_merge.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.010637 +=elapsed 0.013098 =case file_sorter_SUITE:binary_term_keymerge =logfile file_sorter_suite.binary_term_keymerge.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.052517 +=elapsed 0.058703 =case file_sorter_SUITE:binary_merge =logfile file_sorter_suite.binary_merge.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.010413 +=elapsed 0.012825 =case file_sorter_SUITE:term_check =logfile file_sorter_suite.term_check.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.038746 +=elapsed 0.041717 =case file_sorter_SUITE:binary_term_keycheck =logfile file_sorter_suite.binary_term_keycheck.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.003078 +=elapsed 0.003107 =case file_sorter_SUITE:binary_term_check =logfile file_sorter_suite.binary_term_check.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.008165 +=elapsed 0.008193 =case file_sorter_SUITE:binary_term_keycheck -=logfile file_sorter_suite.binary_term_keycheck.468674.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=logfile file_sorter_suite.binary_term_keycheck.484290.html +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.003034 +=elapsed 0.003008 =case file_sorter_SUITE:binary_check =logfile file_sorter_suite.binary_check.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.006614 +=elapsed 0.00666 =case file_sorter_SUITE:inout =logfile file_sorter_suite.inout.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:54 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.002023 +=elapsed 0.002011 =case file_sorter_SUITE:misc =logfile file_sorter_suite.misc.html -=started 2024-09-11 11:18:54 -=ended 2024-09-11 11:18:55 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:05 =result ok -=elapsed 0.015949 +=elapsed 0.016071 =case file_sorter_SUITE:many =logfile file_sorter_suite.many.html -=started 2024-09-11 11:18:55 -=ended 2024-09-11 11:18:55 +=started 2024-09-12 10:41:05 +=ended 2024-09-12 10:41:06 =result ok -=elapsed 0.760763 +=elapsed 0.83964 =case file_sorter_SUITE:end_per_suite =logfile file_sorter_suite.end_per_suite.html -=started 2024-09-11 11:18:55 -=ended 2024-09-11 11:18:55 +=started 2024-09-12 10:41:06 +=ended 2024-09-12 10:41:06 =result ok =elapsed 0.0 -=group_time 1.686s +=group_time 1.820s =case filelib_SUITE:init_per_suite =logfile filelib_suite.init_per_suite.html -=started 2024-09-11 11:18:55 -=ended 2024-09-11 11:18:55 +=started 2024-09-12 10:41:06 +=ended 2024-09-12 10:41:06 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =case filelib_SUITE:wildcard_one =logfile filelib_suite.wildcard_one.html -=started 2024-09-11 11:18:55 -=ended 2024-09-11 11:18:55 +=started 2024-09-12 10:41:06 +=ended 2024-09-12 10:41:06 =result ok -=elapsed 0.080286 +=elapsed 0.0822 =case filelib_SUITE:wildcard_two =logfile filelib_suite.wildcard_two.html -=started 2024-09-11 11:18:55 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:06 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 0.094842 +=elapsed 0.093205 =case filelib_SUITE:wildcard_errors =logfile filelib_suite.wildcard_errors.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 2.0e-5 +=elapsed 1.9e-5 =case filelib_SUITE:fold_files =logfile filelib_suite.fold_files.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 0.003363 +=elapsed 0.005032 =case filelib_SUITE:otp_5960 =logfile filelib_suite.otp_5960.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 4.13e-4 +=elapsed 6.55e-4 =case filelib_SUITE:ensure_dir_eexist =logfile filelib_suite.ensure_dir_eexist.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 4.86e-4 +=elapsed 6.56e-4 =case filelib_SUITE:ensure_dir_symlink =logfile filelib_suite.ensure_dir_symlink.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 2.82e-4 +=elapsed 3.97e-4 =case filelib_SUITE:ensure_path_single_dir =logfile filelib_suite.ensure_path_single_dir.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 1.63e-4 +=elapsed 2.17e-4 =case filelib_SUITE:ensure_path_nested_dirs =logfile filelib_suite.ensure_path_nested_dirs.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 2.73e-4 +=elapsed 4.16e-4 =case filelib_SUITE:ensure_path_binary_args =logfile filelib_suite.ensure_path_binary_args.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 2.46e-4 +=elapsed 3.87e-4 =case filelib_SUITE:ensure_path_symlink =logfile filelib_suite.ensure_path_symlink.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 2.73e-4 +=elapsed 4.01e-4 =case filelib_SUITE:ensure_path_relative_path =logfile filelib_suite.ensure_path_relative_path.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 2.77e-4 +=elapsed 4.56e-4 =case filelib_SUITE:ensure_path_relative_path_dot_dot =logfile filelib_suite.ensure_path_relative_path_dot_dot.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 2.23e-4 +=elapsed 2.77e-4 =case filelib_SUITE:ensure_path_invalid_path =logfile filelib_suite.ensure_path_invalid_path.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 4.23e-4 +=elapsed 6.19e-4 =case filelib_SUITE:wildcard_symlink =logfile filelib_suite.wildcard_symlink.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 9.93e-4 +=elapsed 0.001384 =case filelib_SUITE:is_file_symlink =logfile filelib_suite.is_file_symlink.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 7.12e-4 +=elapsed 0.001006 =case filelib_SUITE:file_props_symlink =logfile filelib_suite.file_props_symlink.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 4.77e-4 +=elapsed 6.84e-4 =case filelib_SUITE:find_source =logfile filelib_suite.find_source.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 0.00139 +=elapsed 0.002385 =case filelib_SUITE:find_source_subdir =logfile filelib_suite.find_source_subdir.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 0.001062 +=elapsed 0.001904 =case filelib_SUITE:find_source_otp =logfile filelib_suite.find_source_otp.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 0.408041 +=elapsed 0.39171 =case filelib_SUITE:safe_relative_path =logfile filelib_suite.safe_relative_path.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 0.007095 +=elapsed 0.006811 =case filelib_SUITE:safe_relative_path_links =logfile filelib_suite.safe_relative_path_links.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok -=elapsed 0.011075 +=elapsed 0.010884 =case filelib_SUITE:end_per_suite =logfile filelib_suite.end_per_suite.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:56 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok =elapsed 0.0 -=group_time 1.138s +=group_time 1.129s =case filename_SUITE:init_per_suite =logfile filename_suite.init_per_suite.html -=started 2024-09-11 11:18:56 -=ended 2024-09-11 11:18:57 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:07 =result ok =elapsed 0.0 =case filename_SUITE:absname =logfile filename_suite.absname.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=started 2024-09-12 10:41:07 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 3.39e-4 +=elapsed 3.06e-4 =case filename_SUITE:absname_2 =logfile filename_suite.absname_2.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 6.0e-6 +=elapsed 5.0e-6 =case filename_SUITE:absname_bin =logfile filename_suite.absname_bin.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 1.97e-4 +=elapsed 2.1e-4 =case filename_SUITE:absname_bin_2 =logfile filename_suite.absname_bin_2.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok =elapsed 6.0e-6 =case filename_SUITE:init_per_group =logfile filename_suite.init_per_group.html =group_props [{name,p},parallel] -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok =elapsed 0.0 =case filename_SUITE:dirname -=logfile filename_suite.dirname.470914.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.dirname.486498.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok =elapsed 7.0e-6 =case filename_SUITE:extension -=logfile filename_suite.extension.470946.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.extension.486530.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok =elapsed 6.0e-6 =case filename_SUITE:extension_bin -=logfile filename_suite.extension_bin.394820.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.extension_bin.486562.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 1.3e-5 +=elapsed 1.2e-5 =case filename_SUITE:join -=logfile filename_suite.join.394852.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.join.486594.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 2.5e-5 +=elapsed 2.6e-5 =case filename_SUITE:pathtype -=logfile filename_suite.pathtype.470882.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.pathtype.486626.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok =elapsed 2.0e-6 =case filename_SUITE:rootname -=logfile filename_suite.rootname.470978.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.rootname.421668.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 1.1e-5 +=elapsed 1.6e-5 =case filename_SUITE:split -=logfile filename_suite.split.394980.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.split.421700.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok =elapsed 5.0e-6 =case filename_SUITE:t_nativename -=logfile filename_suite.t_nativename.394884.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.t_nativename.402243.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 3.0e-6 +=elapsed 4.0e-6 =case filename_SUITE:basename_1 -=logfile filename_suite.basename_1.394948.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.basename_1.402275.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok =elapsed 5.0e-6 =case filename_SUITE:basename_2 -=logfile filename_suite.basename_2.394916.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.basename_2.486658.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 1.1e-5 +=elapsed 1.7e-5 =case filename_SUITE:basename_bin_1 -=logfile filename_suite.basename_bin_1.496643.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.basename_bin_1.486690.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 5.0e-6 +=elapsed 6.0e-6 =case filename_SUITE:basename_bin_2 -=logfile filename_suite.basename_bin_2.496675.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.basename_bin_2.486722.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 9.0e-6 +=elapsed 1.2e-5 =case filename_SUITE:dirname_bin -=logfile filename_suite.dirname_bin.496707.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.dirname_bin.486754.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok =elapsed 8.0e-6 =case filename_SUITE:join_bin -=logfile filename_suite.join_bin.496739.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.join_bin.486786.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 6.1e-5 +=elapsed 2.9e-5 =case filename_SUITE:pathtype_bin -=logfile filename_suite.pathtype_bin.496771.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.pathtype_bin.421732.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok =elapsed 2.0e-6 =case filename_SUITE:rootname_bin -=logfile filename_suite.rootname_bin.395012.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.rootname_bin.421764.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 1.0e-5 +=elapsed 9.0e-6 =case filename_SUITE:split_bin -=logfile filename_suite.split_bin.395044.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.split_bin.421796.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 6.0e-6 +=elapsed 8.0e-6 =case filename_SUITE:t_nativename_bin -=logfile filename_suite.t_nativename_bin.395076.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.t_nativename_bin.402307.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 2.0e-6 +=elapsed 3.0e-6 =case filename_SUITE:t_basedir_api -=logfile filename_suite.t_basedir_api.395108.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=logfile filename_suite.t_basedir_api.421828.html +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 1.39e-4 +=elapsed 1.12e-4 =case filename_SUITE:end_per_group =logfile filename_suite.end_per_group.html =group_props [{name,p},parallel] -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok =elapsed 0.0 -=group_time 0.067s +=group_time 0.069s =case filename_SUITE:t_basedir_xdg =logfile filename_suite.t_basedir_xdg.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 6.52e-4 +=elapsed 6.3e-4 =case filename_SUITE:t_basedir_windows =logfile filename_suite.t_basedir_windows.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 0.001377 +=elapsed 0.001314 =case filename_SUITE:end_per_suite =logfile filename_suite.end_per_suite.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok =elapsed 0.0 -=group_time 0.266s +=group_time 0.267s =case fixtable_SUITE:init_per_suite =logfile fixtable_suite.init_per_suite.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok =elapsed 0.0 =case fixtable_SUITE:multiple_fixes =logfile fixtable_suite.multiple_fixes.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:18:57 +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:08 =result ok -=elapsed 4.2e-4 +=elapsed 4.75e-4 =case fixtable_SUITE:multiple_processes =logfile fixtable_suite.multiple_processes.html -=started 2024-09-11 11:18:57 -=ended 2024-09-11 11:19:01 +=started 2024-09-12 10:41:08 +=ended 2024-09-12 10:41:12 =result ok -=elapsed 4.01229 +=elapsed 4.011508 =case fixtable_SUITE:other_process_deletes =logfile fixtable_suite.other_process_deletes.html -=started 2024-09-11 11:19:01 -=ended 2024-09-11 11:19:01 +=started 2024-09-12 10:41:12 +=ended 2024-09-12 10:41:12 =result ok -=elapsed 0.001793 +=elapsed 0.001785 =case fixtable_SUITE:owner_dies =logfile fixtable_suite.owner_dies.html -=started 2024-09-11 11:19:01 -=ended 2024-09-11 11:19:01 +=started 2024-09-12 10:41:12 +=ended 2024-09-12 10:41:12 =result ok -=elapsed 0.007467 +=elapsed 0.008081 =case fixtable_SUITE:other_process_closes =logfile fixtable_suite.other_process_closes.html -=started 2024-09-11 11:19:01 -=ended 2024-09-11 11:19:01 +=started 2024-09-12 10:41:12 +=ended 2024-09-12 10:41:12 =result ok -=elapsed 0.002307 +=elapsed 0.00223 =case fixtable_SUITE:insert_same_key =logfile fixtable_suite.insert_same_key.html -=started 2024-09-11 11:19:01 -=ended 2024-09-11 11:19:01 +=started 2024-09-12 10:41:12 +=ended 2024-09-12 10:41:12 =result ok -=elapsed 0.001155 +=elapsed 0.001477 =case fixtable_SUITE:fixbag =logfile fixtable_suite.fixbag.html -=started 2024-09-11 11:19:01 -=ended 2024-09-11 11:19:01 +=started 2024-09-12 10:41:12 +=ended 2024-09-12 10:41:12 =result ok =elapsed 7.0e-6 =case fixtable_SUITE:end_per_suite =logfile fixtable_suite.end_per_suite.html -=started 2024-09-11 11:19:01 -=ended 2024-09-11 11:19:01 +=started 2024-09-12 10:41:12 +=ended 2024-09-12 10:41:12 =result ok =elapsed 0.0 -=group_time 4.214s +=group_time 4.213s =case format_SUITE:init_per_suite =logfile format_suite.init_per_suite.html -=started 2024-09-11 11:19:01 -=ended 2024-09-11 11:19:01 +=started 2024-09-12 10:41:12 +=ended 2024-09-12 10:41:12 =result ok =elapsed 0.0 =case format_SUITE:hang_1 =logfile format_suite.hang_1.html -=started 2024-09-11 11:19:01 -=ended 2024-09-11 11:19:01 +=started 2024-09-12 10:41:12 +=ended 2024-09-12 10:41:12 =result ok =elapsed 2.0e-6 =case format_SUITE:end_per_suite =logfile format_suite.end_per_suite.html -=started 2024-09-11 11:19:01 -=ended 2024-09-11 11:19:01 +=started 2024-09-12 10:41:12 +=ended 2024-09-12 10:41:12 =result ok =elapsed 0.0 -=group_time 0.051s +=group_time 0.050s =case gb_sets_property_test_SUITE:init_per_suite =logfile gb_sets_property_test_suite.init_per_suite.html -=started 2024-09-11 11:19:01 -=ended 2024-09-11 11:19:02 +=started 2024-09-12 10:41:12 +=ended 2024-09-12 10:41:13 =result ok -=elapsed 1.264443 +=elapsed 1.255704 =case gb_sets_property_test_SUITE:add_case =logfile gb_sets_property_test_suite.add_case.html -=started 2024-09-11 11:19:02 -=ended 2024-09-11 11:19:03 +=started 2024-09-12 10:41:13 +=ended 2024-09-12 10:41:13 =result ok -=elapsed 0.123072 +=elapsed 0.136074 =case gb_sets_property_test_SUITE:balance_case =logfile gb_sets_property_test_suite.balance_case.html -=started 2024-09-11 11:19:03 -=ended 2024-09-11 11:19:03 +=started 2024-09-12 10:41:13 +=ended 2024-09-12 10:41:14 =result ok -=elapsed 0.13802 +=elapsed 0.139159 =case gb_sets_property_test_SUITE:delete_case =logfile gb_sets_property_test_suite.delete_case.html -=started 2024-09-11 11:19:03 -=ended 2024-09-11 11:19:03 +=started 2024-09-12 10:41:14 +=ended 2024-09-12 10:41:14 =result ok -=elapsed 0.128002 +=elapsed 0.132519 =case gb_sets_property_test_SUITE:delete_any_case =logfile gb_sets_property_test_suite.delete_any_case.html -=started 2024-09-11 11:19:03 -=ended 2024-09-11 11:19:03 +=started 2024-09-12 10:41:14 +=ended 2024-09-12 10:41:14 =result ok -=elapsed 0.130968 +=elapsed 0.129554 =case gb_sets_property_test_SUITE:difference_case =logfile gb_sets_property_test_suite.difference_case.html -=started 2024-09-11 11:19:03 -=ended 2024-09-11 11:19:03 +=started 2024-09-12 10:41:14 +=ended 2024-09-12 10:41:14 =result ok -=elapsed 0.180955 +=elapsed 0.189857 =case gb_sets_property_test_SUITE:from_ordset_case =logfile gb_sets_property_test_suite.from_ordset_case.html -=started 2024-09-11 11:19:03 -=ended 2024-09-11 11:19:03 +=started 2024-09-12 10:41:14 +=ended 2024-09-12 10:41:14 =result ok -=elapsed 0.055645 +=elapsed 0.067183 =case gb_sets_property_test_SUITE:insert_case =logfile gb_sets_property_test_suite.insert_case.html -=started 2024-09-11 11:19:03 -=ended 2024-09-11 11:19:03 +=started 2024-09-12 10:41:14 +=ended 2024-09-12 10:41:14 =result ok -=elapsed 0.139955 +=elapsed 0.129986 =case gb_sets_property_test_SUITE:is_member_case =logfile gb_sets_property_test_suite.is_member_case.html -=started 2024-09-11 11:19:03 -=ended 2024-09-11 11:19:04 +=started 2024-09-12 10:41:14 +=ended 2024-09-12 10:41:15 =result ok -=elapsed 0.124187 +=elapsed 0.129791 =case gb_sets_property_test_SUITE:iterator_case =logfile gb_sets_property_test_suite.iterator_case.html -=started 2024-09-11 11:19:04 -=ended 2024-09-11 11:19:04 +=started 2024-09-12 10:41:15 +=ended 2024-09-12 10:41:15 =result ok -=elapsed 0.073306 +=elapsed 0.073751 =case gb_sets_property_test_SUITE:iterator_from_case =logfile gb_sets_property_test_suite.iterator_from_case.html -=started 2024-09-11 11:19:04 -=ended 2024-09-11 11:19:04 +=started 2024-09-12 10:41:15 +=ended 2024-09-12 10:41:15 =result ok -=elapsed 0.077955 +=elapsed 0.064043 =case gb_sets_property_test_SUITE:larger_case =logfile gb_sets_property_test_suite.larger_case.html -=started 2024-09-11 11:19:04 -=ended 2024-09-11 11:19:04 +=started 2024-09-12 10:41:15 +=ended 2024-09-12 10:41:15 =result ok -=elapsed 0.132515 +=elapsed 0.122773 =case gb_sets_property_test_SUITE:largest_case =logfile gb_sets_property_test_suite.largest_case.html -=started 2024-09-11 11:19:04 -=ended 2024-09-11 11:19:04 +=started 2024-09-12 10:41:15 +=ended 2024-09-12 10:41:15 =result ok -=elapsed 0.084276 +=elapsed 0.067352 =case gb_sets_property_test_SUITE:singleton_case =logfile gb_sets_property_test_suite.singleton_case.html -=started 2024-09-11 11:19:04 -=ended 2024-09-11 11:19:04 +=started 2024-09-12 10:41:15 +=ended 2024-09-12 10:41:15 =result ok -=elapsed 0.00558 +=elapsed 0.00588 =case gb_sets_property_test_SUITE:smaller_case =logfile gb_sets_property_test_suite.smaller_case.html -=started 2024-09-11 11:19:04 -=ended 2024-09-11 11:19:04 +=started 2024-09-12 10:41:15 +=ended 2024-09-12 10:41:15 =result ok -=elapsed 0.124479 +=elapsed 0.122715 =case gb_sets_property_test_SUITE:smallest_case =logfile gb_sets_property_test_suite.smallest_case.html -=started 2024-09-11 11:19:04 -=ended 2024-09-11 11:19:04 +=started 2024-09-12 10:41:15 +=ended 2024-09-12 10:41:15 =result ok -=elapsed 0.057028 +=elapsed 0.060636 =case gb_sets_property_test_SUITE:take_largest_case =logfile gb_sets_property_test_suite.take_largest_case.html -=started 2024-09-11 11:19:04 -=ended 2024-09-11 11:19:04 +=started 2024-09-12 10:41:15 +=ended 2024-09-12 10:41:15 =result ok -=elapsed 0.066432 +=elapsed 0.062677 =case gb_sets_property_test_SUITE:take_smallest_case =logfile gb_sets_property_test_suite.take_smallest_case.html -=started 2024-09-11 11:19:04 -=ended 2024-09-11 11:19:04 +=started 2024-09-12 10:41:15 +=ended 2024-09-12 10:41:15 =result ok -=elapsed 0.061545 +=elapsed 0.067482 =case gb_sets_property_test_SUITE:end_per_suite =logfile gb_sets_property_test_suite.end_per_suite.html -=started 2024-09-11 11:19:04 -=ended 2024-09-11 11:19:04 +=started 2024-09-12 10:41:15 +=ended 2024-09-12 10:41:15 =result ok =elapsed 0.0 -=group_time 3.380s +=group_time 3.367s =case gen_event_SUITE:init_per_suite =logfile gen_event_suite.init_per_suite.html -=started 2024-09-11 11:19:04 -=ended 2024-09-11 11:19:05 +=started 2024-09-12 10:41:15 +=ended 2024-09-12 10:41:15 =result ok =elapsed 1.0e-6 =case gen_event_SUITE:start =logfile gen_event_suite.start.html -=started 2024-09-11 11:19:05 -=ended 2024-09-11 11:19:05 +=started 2024-09-12 10:41:15 +=ended 2024-09-12 10:41:16 =result ok -=elapsed 4.31e-4 +=elapsed 5.31e-4 =case gen_event_SUITE:init_per_group =logfile gen_event_suite.init_per_group.html =group_props [{name,test_all}] -=started 2024-09-11 11:19:05 -=ended 2024-09-11 11:19:05 +=started 2024-09-12 10:41:16 +=ended 2024-09-12 10:41:16 =result ok =elapsed 0.0 =case gen_event_SUITE:add_handler =logfile gen_event_suite.add_handler.html -=started 2024-09-11 11:19:05 -=ended 2024-09-11 11:19:05 +=started 2024-09-12 10:41:16 +=ended 2024-09-12 10:41:16 =result ok -=elapsed 3.7e-5 +=elapsed 5.7e-5 =case gen_event_SUITE:add_sup_handler =logfile gen_event_suite.add_sup_handler.html -=started 2024-09-11 11:19:05 -=ended 2024-09-11 11:19:06 +=started 2024-09-12 10:41:16 +=ended 2024-09-12 10:41:17 =result ok -=elapsed 1.000431 +=elapsed 1.000259 =case gen_event_SUITE:delete_handler =logfile gen_event_suite.delete_handler.html -=started 2024-09-11 11:19:06 -=ended 2024-09-11 11:19:06 +=started 2024-09-12 10:41:17 +=ended 2024-09-12 10:41:17 =result ok -=elapsed 4.8e-5 +=elapsed 5.6e-5 =case gen_event_SUITE:swap_handler =logfile gen_event_suite.swap_handler.html -=started 2024-09-11 11:19:06 -=ended 2024-09-11 11:19:06 +=started 2024-09-12 10:41:17 +=ended 2024-09-12 10:41:17 =result ok -=elapsed 4.1e-5 +=elapsed 4.5e-5 =case gen_event_SUITE:swap_sup_handler =logfile gen_event_suite.swap_sup_handler.html -=started 2024-09-11 11:19:06 -=ended 2024-09-11 11:19:06 +=started 2024-09-12 10:41:17 +=ended 2024-09-12 10:41:17 =result ok -=elapsed 4.6e-5 +=elapsed 5.4e-5 =case gen_event_SUITE:notify =logfile gen_event_suite.notify.html -=started 2024-09-11 11:19:06 -=ended 2024-09-11 11:19:06 +=started 2024-09-12 10:41:17 +=ended 2024-09-12 10:41:17 =result ok -=elapsed 0.001351 +=elapsed 0.001662 =case gen_event_SUITE:sync_notify =logfile gen_event_suite.sync_notify.html -=started 2024-09-11 11:19:06 -=ended 2024-09-11 11:19:06 +=started 2024-09-12 10:41:17 +=ended 2024-09-12 10:41:17 =result ok -=elapsed 0.001276 +=elapsed 0.001205 =case gen_event_SUITE:call =logfile gen_event_suite.call.html -=started 2024-09-11 11:19:06 -=ended 2024-09-11 11:19:06 +=started 2024-09-12 10:41:17 +=ended 2024-09-12 10:41:17 =result ok -=elapsed 0.002228 +=elapsed 0.001883 =case gen_event_SUITE:info =logfile gen_event_suite.info.html -=started 2024-09-11 11:19:06 -=ended 2024-09-11 11:19:06 +=started 2024-09-12 10:41:17 +=ended 2024-09-12 10:41:17 =result ok -=elapsed 0.001633 +=elapsed 0.001358 =case gen_event_SUITE:end_per_group =logfile gen_event_suite.end_per_group.html =group_props [{name,test_all}] -=started 2024-09-11 11:19:06 -=ended 2024-09-11 11:19:06 +=started 2024-09-12 10:41:17 +=ended 2024-09-12 10:41:17 =result ok =elapsed 0.0 -=group_time 1.233s +=group_time 1.237s =case gen_event_SUITE:hibernate =logfile gen_event_suite.hibernate.html -=started 2024-09-11 11:19:06 -=ended 2024-09-11 11:19:07 +=started 2024-09-12 10:41:17 +=ended 2024-09-12 10:41:18 =result ok -=elapsed 1.038781 +=elapsed 1.038962 =case gen_event_SUITE:auto_hibernate =logfile gen_event_suite.auto_hibernate.html -=started 2024-09-11 11:19:07 -=ended 2024-09-11 11:19:07 +=started 2024-09-12 10:41:18 +=ended 2024-09-12 10:41:18 =result ok -=elapsed 0.520778 +=elapsed 0.520953 =case gen_event_SUITE:call_format_status =logfile gen_event_suite.call_format_status.html -=started 2024-09-11 11:19:07 -=ended 2024-09-11 11:19:07 +=started 2024-09-12 10:41:18 +=ended 2024-09-12 10:41:18 =result ok -=elapsed 7.2e-5 +=elapsed 9.3e-5 =case gen_event_SUITE:call_format_status_anon =logfile gen_event_suite.call_format_status_anon.html -=started 2024-09-11 11:19:07 -=ended 2024-09-11 11:19:07 +=started 2024-09-12 10:41:18 +=ended 2024-09-12 10:41:18 =result ok -=elapsed 6.3e-5 +=elapsed 3.5e-5 =case gen_event_SUITE:error_format_status =logfile gen_event_suite.error_format_status.html -=started 2024-09-11 11:19:07 -=ended 2024-09-11 11:19:07 +=started 2024-09-12 10:41:18 +=ended 2024-09-12 10:41:18 =result ok -=elapsed 8.53e-4 +=elapsed 8.82e-4 =case gen_event_SUITE:get_state =logfile gen_event_suite.get_state.html -=started 2024-09-11 11:19:07 -=ended 2024-09-11 11:19:08 +=started 2024-09-12 10:41:18 +=ended 2024-09-12 10:41:18 =result ok -=elapsed 4.3e-5 +=elapsed 7.2e-5 =case gen_event_SUITE:replace_state =logfile gen_event_suite.replace_state.html -=started 2024-09-11 11:19:08 -=ended 2024-09-11 11:19:08 +=started 2024-09-12 10:41:18 +=ended 2024-09-12 10:41:18 =result ok -=elapsed 3.6e-5 +=elapsed 3.8e-5 =case gen_event_SUITE:start_opt =logfile gen_event_suite.start_opt.html -=started 2024-09-11 11:19:08 -=ended 2024-09-11 11:19:08 +=started 2024-09-12 10:41:18 +=ended 2024-09-12 10:41:19 =result ok -=elapsed 3.03e-4 +=elapsed 2.74e-4 =case gen_event_SUITE:init_per_group -=logfile gen_event_suite.init_per_group.496835.html +=logfile gen_event_suite.init_per_group.487362.html =group_props [{name,undef_callbacks}] -=started 2024-09-11 11:19:08 -=ended 2024-09-11 11:19:08 +=started 2024-09-12 10:41:19 +=ended 2024-09-12 10:41:19 =result ok -=elapsed 0.002493 +=elapsed 0.002401 =case gen_event_SUITE:undef_init =logfile gen_event_suite.undef_init.html -=started 2024-09-11 11:19:08 -=ended 2024-09-11 11:19:08 +=started 2024-09-12 10:41:19 +=ended 2024-09-12 10:41:19 =result ok -=elapsed 7.06e-4 +=elapsed 6.42e-4 =case gen_event_SUITE:undef_handle_call =logfile gen_event_suite.undef_handle_call.html -=started 2024-09-11 11:19:08 -=ended 2024-09-11 11:19:08 +=started 2024-09-12 10:41:19 +=ended 2024-09-12 10:41:19 =result ok -=elapsed 2.92e-4 +=elapsed 3.49e-4 =case gen_event_SUITE:undef_handle_event =logfile gen_event_suite.undef_handle_event.html -=started 2024-09-11 11:19:08 -=ended 2024-09-11 11:19:08 +=started 2024-09-12 10:41:19 +=ended 2024-09-12 10:41:19 =result ok -=elapsed 6.67e-4 +=elapsed 5.74e-4 =case gen_event_SUITE:undef_handle_info =logfile gen_event_suite.undef_handle_info.html -=started 2024-09-11 11:19:08 -=ended 2024-09-11 11:19:08 +=started 2024-09-12 10:41:19 +=ended 2024-09-12 10:41:19 =result ok -=elapsed 0.101063 +=elapsed 0.100707 =case gen_event_SUITE:undef_code_change =logfile gen_event_suite.undef_code_change.html -=started 2024-09-11 11:19:08 -=ended 2024-09-11 11:19:08 +=started 2024-09-12 10:41:19 +=ended 2024-09-12 10:41:19 =result ok -=elapsed 2.2e-5 +=elapsed 2.7e-5 =case gen_event_SUITE:undef_terminate =logfile gen_event_suite.undef_terminate.html -=started 2024-09-11 11:19:08 -=ended 2024-09-11 11:19:08 +=started 2024-09-12 10:41:19 +=ended 2024-09-12 10:41:19 =result ok -=elapsed 5.0e-6 +=elapsed 8.0e-6 =case gen_event_SUITE:end_per_group -=logfile gen_event_suite.end_per_group.496867.html +=logfile gen_event_suite.end_per_group.402339.html =group_props [{name,undef_callbacks}] -=started 2024-09-11 11:19:08 -=ended 2024-09-11 11:19:08 +=started 2024-09-12 10:41:19 +=ended 2024-09-12 10:41:19 =result ok =elapsed 0.0 =group_time 0.267s =case gen_event_SUITE:undef_in_terminate =logfile gen_event_suite.undef_in_terminate.html -=started 2024-09-11 11:19:08 -=ended 2024-09-11 11:19:08 +=started 2024-09-12 10:41:19 +=ended 2024-09-12 10:41:19 =result ok -=elapsed 2.0e-5 +=elapsed 2.8e-5 =case gen_event_SUITE:format_log_1 =logfile gen_event_suite.format_log_1.html -=started 2024-09-11 11:19:08 -=ended 2024-09-11 11:19:08 +=started 2024-09-12 10:41:19 +=ended 2024-09-12 10:41:19 =result ok -=elapsed 1.9e-4 +=elapsed 1.76e-4 =case gen_event_SUITE:format_log_2 =logfile gen_event_suite.format_log_2.html -=started 2024-09-11 11:19:08 -=ended 2024-09-11 11:19:08 +=started 2024-09-12 10:41:19 +=ended 2024-09-12 10:41:19 =result ok -=elapsed 0.0007 +=elapsed 6.59e-4 =case gen_event_SUITE:format_log_with_process_label =logfile gen_event_suite.format_log_with_process_label.html -=started 2024-09-11 11:19:08 -=ended 2024-09-11 11:19:08 +=started 2024-09-12 10:41:19 +=ended 2024-09-12 10:41:19 =result ok -=elapsed 1.99e-4 +=elapsed 1.92e-4 =case gen_event_SUITE:send_request_receive_reqid_collection =logfile gen_event_suite.send_request_receive_reqid_collection.html -=started 2024-09-11 11:19:08 -=ended 2024-09-11 11:19:10 +=started 2024-09-12 10:41:19 +=ended 2024-09-12 10:41:21 =result ok -=elapsed 1.902954 +=elapsed 1.902991 =case gen_event_SUITE:send_request_wait_reqid_collection =logfile gen_event_suite.send_request_wait_reqid_collection.html -=started 2024-09-11 11:19:10 -=ended 2024-09-11 11:19:12 +=started 2024-09-12 10:41:21 +=ended 2024-09-12 10:41:23 =result ok -=elapsed 1.802886 +=elapsed 1.802221 =case gen_event_SUITE:send_request_check_reqid_collection =logfile gen_event_suite.send_request_check_reqid_collection.html -=started 2024-09-11 11:19:12 -=ended 2024-09-11 11:19:13 +=started 2024-09-12 10:41:23 +=ended 2024-09-12 10:41:24 =result ok -=elapsed 1.003145 +=elapsed 1.00386 =case gen_event_SUITE:end_per_suite =logfile gen_event_suite.end_per_suite.html -=started 2024-09-11 11:19:13 -=ended 2024-09-11 11:19:13 +=started 2024-09-12 10:41:24 +=ended 2024-09-12 10:41:24 =result ok =elapsed 0.0 -=group_time 8.218s +=group_time 8.221s =case gen_fsm_SUITE:init_per_suite =logfile gen_fsm_suite.init_per_suite.html -=started 2024-09-11 11:19:13 -=ended 2024-09-11 11:19:13 +=started 2024-09-12 10:41:24 +=ended 2024-09-12 10:41:24 =result ok =elapsed 1.0e-6 =case gen_fsm_SUITE:init_per_group =logfile gen_fsm_suite.init_per_group.html =group_props [{name,start}] -=started 2024-09-11 11:19:13 -=ended 2024-09-11 11:19:13 +=started 2024-09-12 10:41:24 +=ended 2024-09-12 10:41:24 =result ok =elapsed 0.0 =case gen_fsm_SUITE:start1 =logfile gen_fsm_suite.start1.html -=started 2024-09-11 11:19:13 -=ended 2024-09-11 11:19:14 +=started 2024-09-12 10:41:24 +=ended 2024-09-12 10:41:25 =result ok -=elapsed 1.204204 +=elapsed 1.204507 =case gen_fsm_SUITE:start2 =logfile gen_fsm_suite.start2.html -=started 2024-09-11 11:19:14 -=ended 2024-09-11 11:19:15 +=started 2024-09-12 10:41:25 +=ended 2024-09-12 10:41:26 =result ok -=elapsed 1.205023 +=elapsed 1.20459 =case gen_fsm_SUITE:start3 =logfile gen_fsm_suite.start3.html -=started 2024-09-11 11:19:15 -=ended 2024-09-11 11:19:16 +=started 2024-09-12 10:41:26 +=ended 2024-09-12 10:41:27 =result ok -=elapsed 1.210945 +=elapsed 1.21033 =case gen_fsm_SUITE:start4 =logfile gen_fsm_suite.start4.html -=started 2024-09-11 11:19:16 -=ended 2024-09-11 11:19:16 +=started 2024-09-12 10:41:27 +=ended 2024-09-12 10:41:27 =result ok -=elapsed 0.001136 +=elapsed 0.001856 =case gen_fsm_SUITE:start5 =logfile gen_fsm_suite.start5.html -=started 2024-09-11 11:19:16 -=ended 2024-09-11 11:19:17 +=started 2024-09-12 10:41:27 +=ended 2024-09-12 10:41:27 =result ok -=elapsed 0.002135 +=elapsed 0.002164 =case gen_fsm_SUITE:start6 =logfile gen_fsm_suite.start6.html -=started 2024-09-11 11:19:17 -=ended 2024-09-11 11:19:18 +=started 2024-09-12 10:41:27 +=ended 2024-09-12 10:41:29 =result ok -=elapsed 1.204863 +=elapsed 1.204249 =case gen_fsm_SUITE:start7 =logfile gen_fsm_suite.start7.html -=started 2024-09-11 11:19:18 -=ended 2024-09-11 11:19:20 +=started 2024-09-12 10:41:29 +=ended 2024-09-12 10:41:31 =result ok -=elapsed 2.407958 +=elapsed 2.407979 =case gen_fsm_SUITE:start8 =logfile gen_fsm_suite.start8.html -=started 2024-09-11 11:19:20 -=ended 2024-09-11 11:19:23 +=started 2024-09-12 10:41:31 +=ended 2024-09-12 10:41:34 =result ok -=elapsed 2.407926 +=elapsed 2.408145 =case gen_fsm_SUITE:start9 =logfile gen_fsm_suite.start9.html -=started 2024-09-11 11:19:23 -=ended 2024-09-11 11:19:25 +=started 2024-09-12 10:41:34 +=ended 2024-09-12 10:41:36 =result ok -=elapsed 2.408243 +=elapsed 2.408103 =case gen_fsm_SUITE:start10 =logfile gen_fsm_suite.start10.html -=started 2024-09-11 11:19:25 -=ended 2024-09-11 11:19:27 +=started 2024-09-12 10:41:36 +=ended 2024-09-12 10:41:38 =result ok -=elapsed 2.407673 +=elapsed 2.408208 =case gen_fsm_SUITE:start11 =logfile gen_fsm_suite.start11.html -=started 2024-09-11 11:19:27 -=ended 2024-09-11 11:19:28 +=started 2024-09-12 10:41:38 +=ended 2024-09-12 10:41:38 =result ok -=elapsed 0.004126 +=elapsed 0.004112 =case gen_fsm_SUITE:start12 =logfile gen_fsm_suite.start12.html -=started 2024-09-11 11:19:28 -=ended 2024-09-11 11:19:30 +=started 2024-09-12 10:41:38 +=ended 2024-09-12 10:41:41 =result ok -=elapsed 2.408224 +=elapsed 2.407243 =case gen_fsm_SUITE:end_per_group =logfile gen_fsm_suite.end_per_group.html =group_props [{name,start}] -=started 2024-09-11 11:19:30 -=ended 2024-09-11 11:19:30 +=started 2024-09-12 10:41:41 +=ended 2024-09-12 10:41:41 =result ok =elapsed 0.0 -=group_time 17.173s +=group_time 17.168s =case gen_fsm_SUITE:init_per_group -=logfile gen_fsm_suite.init_per_group.471522.html +=logfile gen_fsm_suite.init_per_group.487394.html =group_props [{name,abnormal}] -=started 2024-09-11 11:19:30 -=ended 2024-09-11 11:19:30 +=started 2024-09-12 10:41:41 +=ended 2024-09-12 10:41:41 =result ok =elapsed 0.0 =case gen_fsm_SUITE:abnormal1 =logfile gen_fsm_suite.abnormal1.html -=started 2024-09-11 11:19:30 -=ended 2024-09-11 11:19:30 +=started 2024-09-12 10:41:41 +=ended 2024-09-12 10:41:41 =result ok -=elapsed 0.005205 +=elapsed 0.005247 =case gen_fsm_SUITE:abnormal2 =logfile gen_fsm_suite.abnormal2.html -=started 2024-09-11 11:19:30 -=ended 2024-09-11 11:19:30 +=started 2024-09-12 10:41:41 +=ended 2024-09-12 10:41:41 =result ok -=elapsed 0.001763 +=elapsed 0.002193 =case gen_fsm_SUITE:end_per_group -=logfile gen_fsm_suite.end_per_group.471554.html +=logfile gen_fsm_suite.end_per_group.402371.html =group_props [{name,abnormal}] -=started 2024-09-11 11:19:30 -=ended 2024-09-11 11:19:30 +=started 2024-09-12 10:41:41 +=ended 2024-09-12 10:41:41 =result ok =elapsed 0.0 -=group_time 0.078s +=group_time 0.076s =case gen_fsm_SUITE:shutdown =logfile gen_fsm_suite.shutdown.html -=started 2024-09-11 11:19:30 -=ended 2024-09-11 11:19:32 +=started 2024-09-12 10:41:41 +=ended 2024-09-12 10:41:43 =result ok -=elapsed 1.703815 +=elapsed 1.704082 =case gen_fsm_SUITE:init_per_group -=logfile gen_fsm_suite.init_per_group.496899.html +=logfile gen_fsm_suite.init_per_group.402403.html =group_props [{name,sys}] -=started 2024-09-11 11:19:32 -=ended 2024-09-11 11:19:32 +=started 2024-09-12 10:41:43 +=ended 2024-09-12 10:41:43 =result ok =elapsed 0.0 =case gen_fsm_SUITE:sys1 =logfile gen_fsm_suite.sys1.html -=started 2024-09-11 11:19:32 -=ended 2024-09-11 11:19:37 +=started 2024-09-12 10:41:43 +=ended 2024-09-12 10:41:48 =result ok -=elapsed 5.000493 +=elapsed 5.000519 =case gen_fsm_SUITE:call_format_status =logfile gen_fsm_suite.call_format_status.html -=started 2024-09-11 11:19:37 -=ended 2024-09-11 11:19:37 +=started 2024-09-12 10:41:48 +=ended 2024-09-12 10:41:48 =result ok -=elapsed 3.5e-4 +=elapsed 5.03e-4 =case gen_fsm_SUITE:error_format_status =logfile gen_fsm_suite.error_format_status.html -=started 2024-09-11 11:19:37 -=ended 2024-09-11 11:19:37 +=started 2024-09-12 10:41:48 +=ended 2024-09-12 10:41:48 =result ok -=elapsed 7.68e-4 +=elapsed 7.9e-4 =case gen_fsm_SUITE:terminate_crash_format =logfile gen_fsm_suite.terminate_crash_format.html -=started 2024-09-11 11:19:37 -=ended 2024-09-11 11:19:37 +=started 2024-09-12 10:41:48 +=ended 2024-09-12 10:41:48 =result ok -=elapsed 0.001079 +=elapsed 8.84e-4 =case gen_fsm_SUITE:get_state =logfile gen_fsm_suite.get_state.html -=started 2024-09-11 11:19:37 -=ended 2024-09-11 11:19:37 +=started 2024-09-12 10:41:48 +=ended 2024-09-12 10:41:48 =result ok -=elapsed 6.0e-5 +=elapsed 6.1e-5 =case gen_fsm_SUITE:replace_state =logfile gen_fsm_suite.replace_state.html -=started 2024-09-11 11:19:37 -=ended 2024-09-11 11:19:37 +=started 2024-09-12 10:41:48 +=ended 2024-09-12 10:41:48 =result ok =elapsed 4.3e-5 =case gen_fsm_SUITE:end_per_group -=logfile gen_fsm_suite.end_per_group.496931.html +=logfile gen_fsm_suite.end_per_group.402435.html =group_props [{name,sys}] -=started 2024-09-11 11:19:37 -=ended 2024-09-11 11:19:37 +=started 2024-09-12 10:41:48 +=ended 2024-09-12 10:41:48 =result ok =elapsed 0.0 -=group_time 5.161s +=group_time 5.162s =case gen_fsm_SUITE:hibernate =logfile gen_fsm_suite.hibernate.html -=started 2024-09-11 11:19:37 -=ended 2024-09-11 11:19:39 +=started 2024-09-12 10:41:48 +=ended 2024-09-12 10:41:50 =result ok -=elapsed 2.059222 +=elapsed 2.059187 =case gen_fsm_SUITE:auto_hibernate =logfile gen_fsm_suite.auto_hibernate.html -=started 2024-09-11 11:19:39 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:50 +=ended 2024-09-12 10:41:50 =result ok -=elapsed 0.422101 +=elapsed 0.421198 =case gen_fsm_SUITE:enter_loop =logfile gen_fsm_suite.enter_loop.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:50 +=ended 2024-09-12 10:41:50 =result ok -=elapsed 0.002546 +=elapsed 0.003409 =case gen_fsm_SUITE:init_per_group -=logfile gen_fsm_suite.init_per_group.496963.html +=logfile gen_fsm_suite.init_per_group.402467.html =group_props [{name,undef_callbacks}] -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:50 +=ended 2024-09-12 10:41:51 =result ok -=elapsed 0.002439 +=elapsed 0.002908 =case gen_fsm_SUITE:undef_handle_event =logfile gen_fsm_suite.undef_handle_event.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok -=elapsed 0.00242 +=elapsed 0.003015 =case gen_fsm_SUITE:undef_handle_sync_event =logfile gen_fsm_suite.undef_handle_sync_event.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok -=elapsed 8.73e-4 +=elapsed 0.001124 =case gen_fsm_SUITE:undef_handle_info =logfile gen_fsm_suite.undef_handle_info.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok -=elapsed 0.500891 +=elapsed 0.501012 =case gen_fsm_SUITE:undef_init =logfile gen_fsm_suite.undef_init.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok -=elapsed 0.001054 +=elapsed 0.001062 =case gen_fsm_SUITE:undef_code_change =logfile gen_fsm_suite.undef_code_change.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok -=elapsed 2.6e-5 +=elapsed 3.7e-5 =case gen_fsm_SUITE:undef_terminate1 =logfile gen_fsm_suite.undef_terminate1.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok =elapsed 1.6e-5 =case gen_fsm_SUITE:undef_terminate2 =logfile gen_fsm_suite.undef_terminate2.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok -=elapsed 5.26e-4 +=elapsed 8.47e-4 =case gen_fsm_SUITE:end_per_group -=logfile gen_fsm_suite.end_per_group.496995.html +=logfile gen_fsm_suite.end_per_group.421860.html =group_props [{name,undef_callbacks}] -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok =elapsed 0.0 -=group_time 0.691s +=group_time 0.693s =case gen_fsm_SUITE:undef_in_handle_info =logfile gen_fsm_suite.undef_in_handle_info.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok -=elapsed 6.94e-4 +=elapsed 8.93e-4 =case gen_fsm_SUITE:undef_in_terminate =logfile gen_fsm_suite.undef_in_terminate.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok -=elapsed 8.08e-4 +=elapsed 0.001542 =case gen_fsm_SUITE:init_per_group -=logfile gen_fsm_suite.init_per_group.497027.html +=logfile gen_fsm_suite.init_per_group.487426.html =group_props [{name,format_log}] -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok =elapsed 0.0 =case gen_fsm_SUITE:format_log_1 =logfile gen_fsm_suite.format_log_1.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok -=elapsed 1.42e-4 +=elapsed 1.62e-4 =case gen_fsm_SUITE:format_log_2 =logfile gen_fsm_suite.format_log_2.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok -=elapsed 7.93e-4 +=elapsed 7.57e-4 =case gen_fsm_SUITE:format_log_with_process_label =logfile gen_fsm_suite.format_log_with_process_label.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok -=elapsed 1.89e-4 +=elapsed 2.83e-4 =case gen_fsm_SUITE:end_per_group -=logfile gen_fsm_suite.end_per_group.497059.html +=logfile gen_fsm_suite.end_per_group.487458.html =group_props [{name,format_log}] -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok =elapsed 0.0 =group_time 0.092s =case gen_fsm_SUITE:reply_by_alias_with_payload =logfile gen_fsm_suite.reply_by_alias_with_payload.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok -=elapsed 8.0e-6 +=elapsed 1.0e-5 =case gen_fsm_SUITE:end_per_suite =logfile gen_fsm_suite.end_per_suite.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok =elapsed 0.0 -=group_time 27.691s +=group_time 27.687s =case gen_server_SUITE:init_per_suite =logfile gen_server_suite.init_per_suite.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:40 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:51 =result ok -=elapsed 0.004395 +=elapsed 0.004416 =case gen_server_SUITE:start =logfile gen_server_suite.start.html -=started 2024-09-11 11:19:40 -=ended 2024-09-11 11:19:41 +=started 2024-09-12 10:41:51 +=ended 2024-09-12 10:41:52 =result ok -=elapsed 0.516425 +=elapsed 0.518421 =case gen_server_SUITE:init_per_group =logfile gen_server_suite.init_per_group.html =group_props [{name,stop}] -=started 2024-09-11 11:19:41 -=ended 2024-09-11 11:19:41 +=started 2024-09-12 10:41:52 +=ended 2024-09-12 10:41:52 =result ok =elapsed 0.0 =case gen_server_SUITE:stop1 =logfile gen_server_suite.stop1.html -=started 2024-09-11 11:19:41 -=ended 2024-09-11 11:19:41 +=started 2024-09-12 10:41:52 +=ended 2024-09-12 10:41:52 =result ok -=elapsed 2.3e-5 +=elapsed 3.0e-5 =case gen_server_SUITE:stop2 =logfile gen_server_suite.stop2.html -=started 2024-09-11 11:19:41 -=ended 2024-09-11 11:19:41 +=started 2024-09-12 10:41:52 +=ended 2024-09-12 10:41:52 =result ok -=elapsed 5.84e-4 +=elapsed 5.88e-4 =case gen_server_SUITE:stop3 =logfile gen_server_suite.stop3.html -=started 2024-09-11 11:19:41 -=ended 2024-09-11 11:19:41 +=started 2024-09-12 10:41:52 +=ended 2024-09-12 10:41:52 =result ok -=elapsed 2.1e-5 +=elapsed 2.3e-5 =case gen_server_SUITE:stop4 =logfile gen_server_suite.stop4.html -=started 2024-09-11 11:19:41 -=ended 2024-09-11 11:19:41 +=started 2024-09-12 10:41:52 +=ended 2024-09-12 10:41:52 =result ok -=elapsed 2.1e-5 +=elapsed 1.9e-5 =case gen_server_SUITE:stop5 =logfile gen_server_suite.stop5.html -=started 2024-09-11 11:19:41 -=ended 2024-09-11 11:19:41 +=started 2024-09-12 10:41:52 +=ended 2024-09-12 10:41:52 =result ok -=elapsed 2.1e-5 +=elapsed 1.8e-5 =case gen_server_SUITE:stop6 =logfile gen_server_suite.stop6.html -=started 2024-09-11 11:19:41 -=ended 2024-09-11 11:19:41 +=started 2024-09-12 10:41:52 +=ended 2024-09-12 10:41:52 =result ok -=elapsed 7.8e-5 +=elapsed 8.8e-5 =case gen_server_SUITE:stop7 =logfile gen_server_suite.stop7.html -=started 2024-09-11 11:19:41 -=ended 2024-09-11 11:19:41 +=started 2024-09-12 10:41:52 +=ended 2024-09-12 10:41:52 =result ok -=elapsed 4.1e-5 +=elapsed 4.9e-5 =case gen_server_SUITE:stop8 =logfile gen_server_suite.stop8.html -=started 2024-09-11 11:19:41 -=ended 2024-09-11 11:19:41 +=started 2024-09-12 10:41:52 +=ended 2024-09-12 10:41:52 =result ok -=elapsed 0.160035 +=elapsed 0.151829 =case gen_server_SUITE:stop9 =logfile gen_server_suite.stop9.html -=started 2024-09-11 11:19:41 -=ended 2024-09-11 11:19:42 +=started 2024-09-12 10:41:52 +=ended 2024-09-12 10:41:53 =result ok -=elapsed 0.151572 +=elapsed 0.164657 =case gen_server_SUITE:stop10 =logfile gen_server_suite.stop10.html -=started 2024-09-11 11:19:42 -=ended 2024-09-11 11:19:42 +=started 2024-09-12 10:41:53 +=ended 2024-09-12 10:41:53 =result ok -=elapsed 0.351101 +=elapsed 0.34051 =case gen_server_SUITE:end_per_group =logfile gen_server_suite.end_per_group.html =group_props [{name,stop}] -=started 2024-09-11 11:19:42 -=ended 2024-09-11 11:19:42 +=started 2024-09-12 10:41:53 +=ended 2024-09-12 10:41:53 =result ok =elapsed 1.0e-6 -=group_time 0.916s +=group_time 0.909s =case gen_server_SUITE:crash =logfile gen_server_suite.crash.html -=started 2024-09-11 11:19:42 -=ended 2024-09-11 11:19:42 +=started 2024-09-12 10:41:53 +=ended 2024-09-12 10:41:53 =result ok -=elapsed 0.501376 +=elapsed 0.501356 =case gen_server_SUITE:loop_start_fail =logfile gen_server_suite.loop_start_fail.html -=started 2024-09-11 11:19:42 -=ended 2024-09-11 11:19:48 +=started 2024-09-12 10:41:53 +=ended 2024-09-12 10:41:59 =result ok -=elapsed 5.062116 +=elapsed 5.067939 =case gen_server_SUITE:call =logfile gen_server_suite.call.html -=started 2024-09-11 11:19:48 -=ended 2024-09-11 11:19:50 +=started 2024-09-12 10:41:59 +=ended 2024-09-12 10:42:01 =result ok -=elapsed 2.008721 +=elapsed 2.008687 =case gen_server_SUITE:send_request =logfile gen_server_suite.send_request.html -=started 2024-09-11 11:19:50 -=ended 2024-09-11 11:19:52 +=started 2024-09-12 10:42:01 +=ended 2024-09-12 10:42:03 =result ok -=elapsed 1.573731 +=elapsed 1.571408 =case gen_server_SUITE:send_request_receive_reqid_collection =logfile gen_server_suite.send_request_receive_reqid_collection.html -=started 2024-09-11 11:19:52 -=ended 2024-09-11 11:19:53 +=started 2024-09-12 10:42:03 +=ended 2024-09-12 10:42:04 =result ok -=elapsed 1.902831 +=elapsed 1.902747 =case gen_server_SUITE:send_request_wait_reqid_collection =logfile gen_server_suite.send_request_wait_reqid_collection.html -=started 2024-09-11 11:19:53 -=ended 2024-09-11 11:19:55 +=started 2024-09-12 10:42:04 +=ended 2024-09-12 10:42:06 =result ok -=elapsed 1.803057 +=elapsed 1.802951 =case gen_server_SUITE:send_request_check_reqid_collection =logfile gen_server_suite.send_request_check_reqid_collection.html -=started 2024-09-11 11:19:55 -=ended 2024-09-11 11:19:56 +=started 2024-09-12 10:42:06 +=ended 2024-09-12 10:42:07 =result ok -=elapsed 1.003793 +=elapsed 1.003675 =case gen_server_SUITE:cast =logfile gen_server_suite.cast.html -=started 2024-09-11 11:19:56 -=ended 2024-09-11 11:19:56 +=started 2024-09-12 10:42:07 +=ended 2024-09-12 10:42:07 =result ok -=elapsed 0.002195 +=elapsed 0.001873 =case gen_server_SUITE:cast_fast =logfile gen_server_suite.cast_fast.html -=started 2024-09-11 11:19:56 -=ended 2024-09-11 11:19:58 +=started 2024-09-12 10:42:07 +=ended 2024-09-12 10:42:09 =result ok -=elapsed 1.3383 +=elapsed 1.339861 =case gen_server_SUITE:info =logfile gen_server_suite.info.html -=started 2024-09-11 11:19:58 -=ended 2024-09-11 11:19:58 +=started 2024-09-12 10:42:09 +=ended 2024-09-12 10:42:09 =result ok -=elapsed 0.001862 +=elapsed 0.002008 =case gen_server_SUITE:abcast =logfile gen_server_suite.abcast.html -=started 2024-09-11 11:19:58 -=ended 2024-09-11 11:19:58 +=started 2024-09-12 10:42:09 +=ended 2024-09-12 10:42:09 =result ok -=elapsed 0.002073 +=elapsed 0.001799 =case gen_server_SUITE:continue =logfile gen_server_suite.continue.html -=started 2024-09-11 11:19:58 -=ended 2024-09-11 11:19:58 +=started 2024-09-12 10:42:09 +=ended 2024-09-12 10:42:09 =result ok -=elapsed 4.8e-5 +=elapsed 6.5e-5 =case gen_server_SUITE:init_per_group -=logfile gen_server_suite.init_per_group.395140.html +=logfile gen_server_suite.init_per_group.487874.html =group_props [{name,multi_call}] -=started 2024-09-11 11:19:58 -=ended 2024-09-11 11:19:58 +=started 2024-09-12 10:42:09 +=ended 2024-09-12 10:42:09 =result ok =elapsed 0.0 =case gen_server_SUITE:init_per_group -=logfile gen_server_suite.init_per_group.395172.html +=logfile gen_server_suite.init_per_group.487906.html =group_props [{name,multi_call_parallel},parallel] -=started 2024-09-11 11:19:58 -=ended 2024-09-11 11:19:58 +=started 2024-09-12 10:42:09 +=ended 2024-09-12 10:42:09 =result ok =elapsed 0.0 === =case gen_server_SUITE:multicall_remote_old1 =group_props [{name,"multi_call_parallel"}] -=started 2024-09-11 11:19:58 +=started 2024-09-12 10:42:09 =result skipped: Broken in docker === *** Skipping test case #911 {gen_server_SUITE,multicall_remote_old1} *** =case gen_server_SUITE:multicall -=logfile gen_server_suite.multicall.395204.html -=started 2024-09-11 11:19:58 -=ended 2024-09-11 11:20:00 +=logfile gen_server_suite.multicall.487938.html +=started 2024-09-12 10:42:09 +=ended 2024-09-12 10:42:11 =result ok -=elapsed 2.005927 +=elapsed 2.004856 =case gen_server_SUITE:multicall_down -=logfile gen_server_suite.multicall_down.395236.html -=started 2024-09-11 11:19:58 -=ended 2024-09-11 11:19:58 +=logfile gen_server_suite.multicall_down.487970.html +=started 2024-09-12 10:42:09 +=ended 2024-09-12 10:42:09 =result ok -=elapsed 0.009891 +=elapsed 0.006663 =case gen_server_SUITE:multicall_remote -=logfile gen_server_suite.multicall_remote.395268.html -=started 2024-09-11 11:19:58 -=ended 2024-09-11 11:20:01 +=logfile gen_server_suite.multicall_remote.488002.html +=started 2024-09-12 10:42:09 +=ended 2024-09-12 10:42:12 =result ok -=elapsed 2.790139 +=elapsed 2.81225 =case gen_server_SUITE:multicall_remote_old2 -=logfile gen_server_suite.multicall_remote_old2.471874.html -=started 2024-09-11 11:19:58 -=ended 2024-09-11 11:20:30 +=logfile gen_server_suite.multicall_remote_old2.402499.html +=started 2024-09-12 10:42:09 +=ended 2024-09-12 10:42:41 =result ok -=elapsed 31.736383 +=elapsed 31.718849 =case gen_server_SUITE:end_per_group -=logfile gen_server_suite.end_per_group.472290.html +=logfile gen_server_suite.end_per_group.488418.html =group_props [{name,multi_call_parallel},parallel] -=started 2024-09-11 11:20:30 -=ended 2024-09-11 11:20:30 +=started 2024-09-12 10:42:41 +=ended 2024-09-12 10:42:41 =result ok =elapsed 1.0e-6 -=group_time 31.786s +=group_time 31.772s =case gen_server_SUITE:init_per_group -=logfile gen_server_suite.init_per_group.395300.html +=logfile gen_server_suite.init_per_group.488450.html =group_props [{name,multi_call_sequence}] -=started 2024-09-11 11:20:30 -=ended 2024-09-11 11:20:30 +=started 2024-09-12 10:42:41 +=ended 2024-09-12 10:42:41 =result ok =elapsed 0.0 =case gen_server_SUITE:multicall_recv_opt_success =logfile gen_server_suite.multicall_recv_opt_success.html -=started 2024-09-11 11:20:30 -=ended 2024-09-11 11:20:30 -=result ok: Ratio: 1.08272809802733482876e+00 -=elapsed 0.628839 +=started 2024-09-12 10:42:41 +=ended 2024-09-12 10:42:41 +=result ok: Ratio: 1.05760937470734606158e+00 +=elapsed 0.614249 =case gen_server_SUITE:multicall_recv_opt_timeout =logfile gen_server_suite.multicall_recv_opt_timeout.html -=started 2024-09-11 11:20:30 -=ended 2024-09-11 11:20:35 -=result ok: Ratio: 9.99957039460168117806e-01 -=elapsed 4.608634 +=started 2024-09-12 10:42:41 +=ended 2024-09-12 10:42:46 +=result ok: Ratio: 9.99852047222122064518e-01 +=elapsed 4.595284 =case gen_server_SUITE:multicall_recv_opt_noconnection =logfile gen_server_suite.multicall_recv_opt_noconnection.html -=started 2024-09-11 11:20:35 -=ended 2024-09-11 11:20:36 -=result ok: Ratio: 9.86144722207283108695e-01 -=elapsed 1.429388 +=started 2024-09-12 10:42:46 +=ended 2024-09-12 10:42:47 +=result ok: Ratio: 9.88034566373387601601e-01 +=elapsed 1.413763 =case gen_server_SUITE:end_per_group -=logfile gen_server_suite.end_per_group.472642.html +=logfile gen_server_suite.end_per_group.488834.html =group_props [{name,multi_call_sequence}] -=started 2024-09-11 11:20:36 -=ended 2024-09-11 11:20:36 +=started 2024-09-12 10:42:47 +=ended 2024-09-12 10:42:47 =result ok -=elapsed 1.0e-6 -=group_time 6.760s +=elapsed 0.0 +=group_time 6.715s =case gen_server_SUITE:end_per_group -=logfile gen_server_suite.end_per_group.472674.html +=logfile gen_server_suite.end_per_group.488866.html =group_props [{name,multi_call}] -=started 2024-09-11 11:20:36 -=ended 2024-09-11 11:20:36 +=started 2024-09-12 10:42:47 +=ended 2024-09-12 10:42:47 =result ok =elapsed 0.0 -=group_time 38.615s +=group_time 38.555s =case gen_server_SUITE:call_remote1 =logfile gen_server_suite.call_remote1.html -=started 2024-09-11 11:20:36 -=ended 2024-09-11 11:20:37 +=started 2024-09-12 10:42:47 +=ended 2024-09-12 10:42:48 =result ok -=elapsed 0.00682 +=elapsed 0.007195 =case gen_server_SUITE:call_remote2 =logfile gen_server_suite.call_remote2.html -=started 2024-09-11 11:20:37 -=ended 2024-09-11 11:20:37 +=started 2024-09-12 10:42:48 +=ended 2024-09-12 10:42:48 =result ok -=elapsed 0.006663 +=elapsed 0.007352 =case gen_server_SUITE:calling_self =logfile gen_server_suite.calling_self.html -=started 2024-09-11 11:20:37 -=ended 2024-09-11 11:20:37 +=started 2024-09-12 10:42:48 +=ended 2024-09-12 10:42:48 =result ok =elapsed 1.0e-6 =case gen_server_SUITE:call_remote3 =logfile gen_server_suite.call_remote3.html -=started 2024-09-11 11:20:37 -=ended 2024-09-11 11:20:38 +=started 2024-09-12 10:42:48 +=ended 2024-09-12 10:42:48 =result ok -=elapsed 0.005977 +=elapsed 0.006462 =case gen_server_SUITE:call_remote_n1 =logfile gen_server_suite.call_remote_n1.html -=started 2024-09-11 11:20:38 -=ended 2024-09-11 11:20:38 +=started 2024-09-12 10:42:48 +=ended 2024-09-12 10:42:49 =result ok -=elapsed 0.005701 +=elapsed 0.005598 =case gen_server_SUITE:call_remote_n2 =logfile gen_server_suite.call_remote_n2.html -=started 2024-09-11 11:20:38 -=ended 2024-09-11 11:20:38 +=started 2024-09-12 10:42:49 +=ended 2024-09-12 10:42:49 =result ok -=elapsed 0.006016 +=elapsed 0.006391 =case gen_server_SUITE:call_remote_n3 =logfile gen_server_suite.call_remote_n3.html -=started 2024-09-11 11:20:38 -=ended 2024-09-11 11:20:39 +=started 2024-09-12 10:42:49 +=ended 2024-09-12 10:42:50 =result ok -=elapsed 0.005765 +=elapsed 0.005704 =case gen_server_SUITE:spec_init =logfile gen_server_suite.spec_init.html -=started 2024-09-11 11:20:39 -=ended 2024-09-11 11:20:40 +=started 2024-09-12 10:42:50 +=ended 2024-09-12 10:42:51 =result ok -=elapsed 1.007658 +=elapsed 1.010937 =case gen_server_SUITE:spec_init_local_registered_parent =logfile gen_server_suite.spec_init_local_registered_parent.html -=started 2024-09-11 11:20:40 -=ended 2024-09-11 11:20:40 +=started 2024-09-12 10:42:51 +=ended 2024-09-12 10:42:51 =result ok -=elapsed 1.44e-4 +=elapsed 9.7e-5 =case gen_server_SUITE:spec_init_global_registered_parent =logfile gen_server_suite.spec_init_global_registered_parent.html -=started 2024-09-11 11:20:40 -=ended 2024-09-11 11:20:40 +=started 2024-09-12 10:42:51 +=ended 2024-09-12 10:42:51 =result ok -=elapsed 3.6e-4 +=elapsed 2.41e-4 =case gen_server_SUITE:otp_5854 =logfile gen_server_suite.otp_5854.html -=started 2024-09-11 11:20:40 -=ended 2024-09-11 11:20:40 +=started 2024-09-12 10:42:51 +=ended 2024-09-12 10:42:51 =result ok -=elapsed 0.001681 +=elapsed 0.001419 =case gen_server_SUITE:hibernate =logfile gen_server_suite.hibernate.html -=started 2024-09-11 11:20:40 -=ended 2024-09-11 11:20:43 +=started 2024-09-12 10:42:51 +=ended 2024-09-12 10:42:54 =result ok -=elapsed 3.022883 +=elapsed 3.021727 =case gen_server_SUITE:auto_hibernate =logfile gen_server_suite.auto_hibernate.html -=started 2024-09-11 11:20:43 -=ended 2024-09-11 11:20:43 +=started 2024-09-12 10:42:54 +=ended 2024-09-12 10:42:54 =result ok -=elapsed 0.422076 +=elapsed 0.422715 =case gen_server_SUITE:otp_7669 =logfile gen_server_suite.otp_7669.html -=started 2024-09-11 11:20:43 -=ended 2024-09-11 11:20:43 +=started 2024-09-12 10:42:54 +=ended 2024-09-12 10:42:54 =result ok -=elapsed 0.027504 +=elapsed 0.030902 =case gen_server_SUITE:init_per_group -=logfile gen_server_suite.init_per_group.473218.html +=logfile gen_server_suite.init_per_group.489410.html =group_props [{name,format_status}] -=started 2024-09-11 11:20:43 -=ended 2024-09-11 11:20:43 +=started 2024-09-12 10:42:54 +=ended 2024-09-12 10:42:54 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =case gen_server_SUITE:call_format_status =logfile gen_server_suite.call_format_status.html -=started 2024-09-11 11:20:43 -=ended 2024-09-11 11:20:43 +=started 2024-09-12 10:42:54 +=ended 2024-09-12 10:42:54 =result ok -=elapsed 0.010961 +=elapsed 0.015761 =case gen_server_SUITE:error_format_status =logfile gen_server_suite.error_format_status.html -=started 2024-09-11 11:20:43 -=ended 2024-09-11 11:20:43 +=started 2024-09-12 10:42:54 +=ended 2024-09-12 10:42:54 =result ok -=elapsed 0.002166 +=elapsed 0.003963 =case gen_server_SUITE:terminate_crash_format =logfile gen_server_suite.terminate_crash_format.html -=started 2024-09-11 11:20:43 -=ended 2024-09-11 11:20:43 +=started 2024-09-12 10:42:54 +=ended 2024-09-12 10:42:54 =result ok -=elapsed 0.002633 +=elapsed 0.002621 =case gen_server_SUITE:crash_in_format_status =logfile gen_server_suite.crash_in_format_status.html -=started 2024-09-11 11:20:43 -=ended 2024-09-11 11:20:43 +=started 2024-09-12 10:42:54 +=ended 2024-09-12 10:42:54 =result ok -=elapsed 0.002258 +=elapsed 0.001778 =case gen_server_SUITE:throw_in_format_status =logfile gen_server_suite.throw_in_format_status.html -=started 2024-09-11 11:20:43 -=ended 2024-09-11 11:20:44 +=started 2024-09-12 10:42:54 +=ended 2024-09-12 10:42:54 =result ok -=elapsed 0.001744 +=elapsed 0.001973 =case gen_server_SUITE:format_all_status =logfile gen_server_suite.format_all_status.html -=started 2024-09-11 11:20:44 -=ended 2024-09-11 11:20:44 +=started 2024-09-12 10:42:54 +=ended 2024-09-12 10:42:54 =result ok -=elapsed 0.013967 +=elapsed 0.012193 =case gen_server_SUITE:end_per_group -=logfile gen_server_suite.end_per_group.473250.html +=logfile gen_server_suite.end_per_group.489442.html =group_props [{name,format_status}] -=started 2024-09-11 11:20:44 -=ended 2024-09-11 11:20:44 +=started 2024-09-12 10:42:54 +=ended 2024-09-12 10:42:54 =result ok =elapsed 0.0 -=group_time 0.195s +=group_time 0.199s =case gen_server_SUITE:get_state =logfile gen_server_suite.get_state.html -=started 2024-09-11 11:20:44 -=ended 2024-09-11 11:20:44 +=started 2024-09-12 10:42:54 +=ended 2024-09-12 10:42:54 =result ok -=elapsed 1.66e-4 +=elapsed 1.47e-4 =case gen_server_SUITE:replace_state =logfile gen_server_suite.replace_state.html -=started 2024-09-11 11:20:44 -=ended 2024-09-11 11:20:44 +=started 2024-09-12 10:42:54 +=ended 2024-09-12 10:42:55 =result ok -=elapsed 1.62e-4 +=elapsed 1.6e-4 =case gen_server_SUITE:call_with_huge_message_queue =logfile gen_server_suite.call_with_huge_message_queue.html -=started 2024-09-11 11:20:44 -=ended 2024-09-11 11:20:44 +=started 2024-09-12 10:42:55 +=ended 2024-09-12 10:42:55 =result ok -=elapsed 0.123953 +=elapsed 0.122228 =case gen_server_SUITE:init_per_group -=logfile gen_server_suite.init_per_group.473282.html +=logfile gen_server_suite.init_per_group.489474.html =group_props [{name,undef_callbacks}] -=started 2024-09-11 11:20:44 -=ended 2024-09-11 11:20:44 +=started 2024-09-12 10:42:55 +=ended 2024-09-12 10:42:55 =result ok -=elapsed 0.002838 +=elapsed 0.00263 =case gen_server_SUITE:undef_handle_call =logfile gen_server_suite.undef_handle_call.html -=started 2024-09-11 11:20:44 -=ended 2024-09-11 11:20:44 +=started 2024-09-12 10:42:55 +=ended 2024-09-12 10:42:55 =result ok -=elapsed 0.002704 +=elapsed 0.002768 =case gen_server_SUITE:undef_handle_cast =logfile gen_server_suite.undef_handle_cast.html -=started 2024-09-11 11:20:44 -=ended 2024-09-11 11:20:44 +=started 2024-09-12 10:42:55 +=ended 2024-09-12 10:42:55 =result ok -=elapsed 7.22e-4 +=elapsed 8.09e-4 =case gen_server_SUITE:undef_handle_info =logfile gen_server_suite.undef_handle_info.html -=started 2024-09-11 11:20:44 -=ended 2024-09-11 11:20:44 +=started 2024-09-12 10:42:55 +=ended 2024-09-12 10:42:55 =result ok -=elapsed 0.101105 +=elapsed 0.100678 =case gen_server_SUITE:undef_handle_continue =logfile gen_server_suite.undef_handle_continue.html -=started 2024-09-11 11:20:44 -=ended 2024-09-11 11:20:44 +=started 2024-09-12 10:42:55 +=ended 2024-09-12 10:42:55 =result ok -=elapsed 0.001059 +=elapsed 7.48e-4 =case gen_server_SUITE:undef_init =logfile gen_server_suite.undef_init.html -=started 2024-09-11 11:20:44 -=ended 2024-09-11 11:20:45 +=started 2024-09-12 10:42:55 +=ended 2024-09-12 10:42:55 =result ok -=elapsed 0.502321 +=elapsed 0.502984 =case gen_server_SUITE:undef_code_change =logfile gen_server_suite.undef_code_change.html -=started 2024-09-11 11:20:45 -=ended 2024-09-11 11:20:45 +=started 2024-09-12 10:42:55 +=ended 2024-09-12 10:42:56 =result ok -=elapsed 2.9e-5 +=elapsed 4.4e-5 =case gen_server_SUITE:undef_terminate1 =logfile gen_server_suite.undef_terminate1.html -=started 2024-09-11 11:20:45 -=ended 2024-09-11 11:20:45 +=started 2024-09-12 10:42:56 +=ended 2024-09-12 10:42:56 =result ok -=elapsed 1.7e-5 +=elapsed 2.2e-5 =case gen_server_SUITE:undef_terminate2 =logfile gen_server_suite.undef_terminate2.html -=started 2024-09-11 11:20:45 -=ended 2024-09-11 11:20:45 +=started 2024-09-12 10:42:56 +=ended 2024-09-12 10:42:56 =result ok -=elapsed 5.37e-4 +=elapsed 6.1e-4 =case gen_server_SUITE:end_per_group -=logfile gen_server_suite.end_per_group.473314.html +=logfile gen_server_suite.end_per_group.489506.html =group_props [{name,undef_callbacks}] -=started 2024-09-11 11:20:45 -=ended 2024-09-11 11:20:45 +=started 2024-09-12 10:42:56 +=ended 2024-09-12 10:42:56 =result ok =elapsed 0.0 -=group_time 0.817s +=group_time 0.819s =case gen_server_SUITE:undef_in_terminate =logfile gen_server_suite.undef_in_terminate.html -=started 2024-09-11 11:20:45 -=ended 2024-09-11 11:20:45 +=started 2024-09-12 10:42:56 +=ended 2024-09-12 10:42:56 =result ok -=elapsed 7.99e-4 +=elapsed 9.03e-4 =case gen_server_SUITE:undef_in_handle_info =logfile gen_server_suite.undef_in_handle_info.html -=started 2024-09-11 11:20:45 -=ended 2024-09-11 11:20:45 +=started 2024-09-12 10:42:56 +=ended 2024-09-12 10:42:56 =result ok -=elapsed 7.54e-4 +=elapsed 7.51e-4 =case gen_server_SUITE:format_log_1 =logfile gen_server_suite.format_log_1.html -=started 2024-09-11 11:20:45 -=ended 2024-09-11 11:20:45 +=started 2024-09-12 10:42:56 +=ended 2024-09-12 10:42:56 =result ok -=elapsed 1.07e-4 +=elapsed 1.32e-4 =case gen_server_SUITE:format_log_2 =logfile gen_server_suite.format_log_2.html -=started 2024-09-11 11:20:45 -=ended 2024-09-11 11:20:45 +=started 2024-09-12 10:42:56 +=ended 2024-09-12 10:42:56 =result ok -=elapsed 6.62e-4 +=elapsed 8.19e-4 =case gen_server_SUITE:format_log_with_process_label =logfile gen_server_suite.format_log_with_process_label.html -=started 2024-09-11 11:20:45 -=ended 2024-09-11 11:20:45 +=started 2024-09-12 10:42:56 +=ended 2024-09-12 10:42:56 =result ok -=elapsed 2.06e-4 +=elapsed 3.01e-4 =case gen_server_SUITE:reply_by_alias_with_payload =logfile gen_server_suite.reply_by_alias_with_payload.html -=started 2024-09-11 11:20:45 -=ended 2024-09-11 11:20:45 +=started 2024-09-12 10:42:56 +=ended 2024-09-12 10:42:56 =result ok -=elapsed 1.1e-5 +=elapsed 1.2e-5 =case gen_server_SUITE:end_per_suite =logfile gen_server_suite.end_per_suite.html -=started 2024-09-11 11:20:45 -=ended 2024-09-11 11:20:45 +=started 2024-09-12 10:42:56 +=ended 2024-09-12 10:42:56 =result ok =elapsed 0.0 -=group_time 64.383s +=group_time 64.314s =case gen_statem_SUITE:init_per_suite =logfile gen_statem_suite.init_per_suite.html -=started 2024-09-11 11:20:45 -=ended 2024-09-11 11:20:45 +=started 2024-09-12 10:42:56 +=ended 2024-09-12 10:42:56 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =case gen_statem_SUITE:init_per_group =logfile gen_statem_suite.init_per_group.html =group_props [{name,start}] -=started 2024-09-11 11:20:45 -=ended 2024-09-11 11:20:45 +=started 2024-09-12 10:42:56 +=ended 2024-09-12 10:42:56 =result ok =elapsed 0.0 =case gen_statem_SUITE:start1 =logfile gen_statem_suite.start1.html -=started 2024-09-11 11:20:45 -=ended 2024-09-11 11:20:48 +=started 2024-09-12 10:42:56 +=ended 2024-09-12 10:42:59 =result ok -=elapsed 2.80791 +=elapsed 2.807823 =case gen_statem_SUITE:start2 =logfile gen_statem_suite.start2.html -=started 2024-09-11 11:20:48 -=ended 2024-09-11 11:20:50 +=started 2024-09-12 10:42:59 +=ended 2024-09-12 10:43:01 =result ok -=elapsed 1.402923 +=elapsed 1.40287 =case gen_statem_SUITE:start3 =logfile gen_statem_suite.start3.html -=started 2024-09-11 11:20:50 -=ended 2024-09-11 11:20:52 +=started 2024-09-12 10:43:01 +=ended 2024-09-12 10:43:03 =result ok -=elapsed 1.408918 +=elapsed 1.408864 =case gen_statem_SUITE:start4 =logfile gen_statem_suite.start4.html -=started 2024-09-11 11:20:52 -=ended 2024-09-11 11:20:53 +=started 2024-09-12 10:43:03 +=ended 2024-09-12 10:43:04 =result ok -=elapsed 0.500954 +=elapsed 0.500874 =case gen_statem_SUITE:start5a =logfile gen_statem_suite.start5a.html -=started 2024-09-11 11:20:53 -=ended 2024-09-11 11:20:54 +=started 2024-09-12 10:43:04 +=ended 2024-09-12 10:43:05 =result ok -=elapsed 0.500922 +=elapsed 0.501873 =case gen_statem_SUITE:start5b =logfile gen_statem_suite.start5b.html -=started 2024-09-11 11:20:54 -=ended 2024-09-11 11:20:55 +=started 2024-09-12 10:43:05 +=ended 2024-09-12 10:43:06 =result ok -=elapsed 0.500925 +=elapsed 0.500887 =case gen_statem_SUITE:start6 =logfile gen_statem_suite.start6.html -=started 2024-09-11 11:20:55 -=ended 2024-09-11 11:20:57 +=started 2024-09-12 10:43:06 +=ended 2024-09-12 10:43:08 =result ok -=elapsed 1.402906 +=elapsed 1.402831 =case gen_statem_SUITE:start7 =logfile gen_statem_suite.start7.html -=started 2024-09-11 11:20:57 -=ended 2024-09-11 11:21:02 +=started 2024-09-12 10:43:08 +=ended 2024-09-12 10:43:13 =result ok -=elapsed 4.609924 +=elapsed 4.6099 =case gen_statem_SUITE:start8 =logfile gen_statem_suite.start8.html -=started 2024-09-11 11:21:02 -=ended 2024-09-11 11:21:05 +=started 2024-09-12 10:43:13 +=ended 2024-09-12 10:43:16 =result ok -=elapsed 2.304882 +=elapsed 2.304846 =case gen_statem_SUITE:start9 =logfile gen_statem_suite.start9.html -=started 2024-09-11 11:21:05 -=ended 2024-09-11 11:21:10 +=started 2024-09-12 10:43:16 +=ended 2024-09-12 10:43:21 =result ok -=elapsed 4.609926 +=elapsed 4.609885 =case gen_statem_SUITE:start10 =logfile gen_statem_suite.start10.html -=started 2024-09-11 11:21:10 -=ended 2024-09-11 11:21:13 +=started 2024-09-12 10:43:21 +=ended 2024-09-12 10:43:24 =result ok -=elapsed 2.304925 +=elapsed 2.304892 =case gen_statem_SUITE:start11 =logfile gen_statem_suite.start11.html -=started 2024-09-11 11:21:13 -=ended 2024-09-11 11:21:14 +=started 2024-09-12 10:43:24 +=ended 2024-09-12 10:43:25 =result ok -=elapsed 0.502922 +=elapsed 0.502894 =case gen_statem_SUITE:start12 =logfile gen_statem_suite.start12.html -=started 2024-09-11 11:21:14 -=ended 2024-09-11 11:21:17 +=started 2024-09-12 10:43:25 +=ended 2024-09-12 10:43:28 =result ok -=elapsed 2.304912 +=elapsed 2.304887 =case gen_statem_SUITE:next_events =logfile gen_statem_suite.next_events.html -=started 2024-09-11 11:21:17 -=ended 2024-09-11 11:21:17 +=started 2024-09-12 10:43:28 +=ended 2024-09-12 10:43:28 =result ok -=elapsed 1.38e-4 +=elapsed 1.82e-4 =case gen_statem_SUITE:end_per_group =logfile gen_statem_suite.end_per_group.html =group_props [{name,start}] -=started 2024-09-11 11:21:17 -=ended 2024-09-11 11:21:17 +=started 2024-09-12 10:43:28 +=ended 2024-09-12 10:43:28 =result ok =elapsed 0.0 -=group_time 32.514s +=group_time 32.518s =case gen_statem_SUITE:init_per_group -=logfile gen_statem_suite.init_per_group.473346.html +=logfile gen_statem_suite.init_per_group.489538.html =group_props [{name,start_handle_event}] -=started 2024-09-11 11:21:17 -=ended 2024-09-11 11:21:17 +=started 2024-09-12 10:43:28 +=ended 2024-09-12 10:43:28 =result ok =elapsed 0.0 =case gen_statem_SUITE:start1 -=logfile gen_statem_suite.start1.473378.html -=started 2024-09-11 11:21:17 -=ended 2024-09-11 11:21:21 +=logfile gen_statem_suite.start1.489570.html +=started 2024-09-12 10:43:28 +=ended 2024-09-12 10:43:32 =result ok -=elapsed 2.808913 +=elapsed 2.808886 =case gen_statem_SUITE:start2 -=logfile gen_statem_suite.start2.473410.html -=started 2024-09-11 11:21:21 -=ended 2024-09-11 11:21:23 +=logfile gen_statem_suite.start2.489602.html +=started 2024-09-12 10:43:32 +=ended 2024-09-12 10:43:34 =result ok -=elapsed 1.402923 +=elapsed 1.402873 =case gen_statem_SUITE:start3 -=logfile gen_statem_suite.start3.473442.html -=started 2024-09-11 11:21:23 -=ended 2024-09-11 11:21:25 +=logfile gen_statem_suite.start3.489634.html +=started 2024-09-12 10:43:34 +=ended 2024-09-12 10:43:36 =result ok -=elapsed 1.408929 +=elapsed 1.408878 =case gen_statem_SUITE:start4 -=logfile gen_statem_suite.start4.473474.html -=started 2024-09-11 11:21:25 -=ended 2024-09-11 11:21:26 +=logfile gen_statem_suite.start4.489666.html +=started 2024-09-12 10:43:36 +=ended 2024-09-12 10:43:37 =result ok -=elapsed 0.500949 +=elapsed 0.500843 =case gen_statem_SUITE:start5a -=logfile gen_statem_suite.start5a.473506.html -=started 2024-09-11 11:21:26 -=ended 2024-09-11 11:21:27 +=logfile gen_statem_suite.start5a.489698.html +=started 2024-09-12 10:43:37 +=ended 2024-09-12 10:43:38 =result ok -=elapsed 0.500914 +=elapsed 0.500876 =case gen_statem_SUITE:start5b -=logfile gen_statem_suite.start5b.473538.html -=started 2024-09-11 11:21:27 -=ended 2024-09-11 11:21:28 +=logfile gen_statem_suite.start5b.489730.html +=started 2024-09-12 10:43:38 +=ended 2024-09-12 10:43:39 =result ok -=elapsed 0.500905 +=elapsed 0.500866 =case gen_statem_SUITE:start6 -=logfile gen_statem_suite.start6.473570.html -=started 2024-09-11 11:21:28 -=ended 2024-09-11 11:21:30 +=logfile gen_statem_suite.start6.489762.html +=started 2024-09-12 10:43:39 +=ended 2024-09-12 10:43:41 =result ok -=elapsed 1.402927 +=elapsed 1.402912 =case gen_statem_SUITE:start7 -=logfile gen_statem_suite.start7.473602.html -=started 2024-09-11 11:21:30 -=ended 2024-09-11 11:21:35 +=logfile gen_statem_suite.start7.489794.html +=started 2024-09-12 10:43:41 +=ended 2024-09-12 10:43:46 =result ok -=elapsed 4.609935 +=elapsed 4.609857 =case gen_statem_SUITE:start8 -=logfile gen_statem_suite.start8.473634.html -=started 2024-09-11 11:21:35 -=ended 2024-09-11 11:21:38 +=logfile gen_statem_suite.start8.489826.html +=started 2024-09-12 10:43:46 +=ended 2024-09-12 10:43:48 =result ok -=elapsed 2.304928 +=elapsed 2.304893 =case gen_statem_SUITE:start9 -=logfile gen_statem_suite.start9.473666.html -=started 2024-09-11 11:21:38 -=ended 2024-09-11 11:21:43 +=logfile gen_statem_suite.start9.489858.html +=started 2024-09-12 10:43:48 +=ended 2024-09-12 10:43:54 =result ok -=elapsed 4.609904 +=elapsed 4.609888 =case gen_statem_SUITE:start10 -=logfile gen_statem_suite.start10.473698.html -=started 2024-09-11 11:21:43 -=ended 2024-09-11 11:21:46 +=logfile gen_statem_suite.start10.489890.html +=started 2024-09-12 10:43:54 +=ended 2024-09-12 10:43:56 =result ok -=elapsed 2.304925 +=elapsed 2.304887 =case gen_statem_SUITE:start11 -=logfile gen_statem_suite.start11.473730.html -=started 2024-09-11 11:21:46 -=ended 2024-09-11 11:21:47 +=logfile gen_statem_suite.start11.489922.html +=started 2024-09-12 10:43:56 +=ended 2024-09-12 10:43:57 =result ok -=elapsed 0.502924 +=elapsed 0.502884 =case gen_statem_SUITE:start12 -=logfile gen_statem_suite.start12.473762.html -=started 2024-09-11 11:21:47 -=ended 2024-09-11 11:21:49 +=logfile gen_statem_suite.start12.489954.html +=started 2024-09-12 10:43:57 +=ended 2024-09-12 10:44:00 =result ok -=elapsed 2.30489 +=elapsed 2.304873 =case gen_statem_SUITE:next_events -=logfile gen_statem_suite.next_events.473794.html -=started 2024-09-11 11:21:49 -=ended 2024-09-11 11:21:50 +=logfile gen_statem_suite.next_events.489986.html +=started 2024-09-12 10:44:00 +=ended 2024-09-12 10:44:01 =result ok -=elapsed 1.95e-4 +=elapsed 2.48e-4 =case gen_statem_SUITE:end_per_group -=logfile gen_statem_suite.end_per_group.473826.html +=logfile gen_statem_suite.end_per_group.490018.html =group_props [{name,start_handle_event}] -=started 2024-09-11 11:21:50 -=ended 2024-09-11 11:21:50 +=started 2024-09-12 10:44:01 +=ended 2024-09-12 10:44:01 =result ok =elapsed 0.0 -=group_time 32.523s +=group_time 32.519s =case gen_statem_SUITE:init_per_group -=logfile gen_statem_suite.init_per_group.473858.html +=logfile gen_statem_suite.init_per_group.490050.html =group_props [{name,stop}] -=started 2024-09-11 11:21:50 -=ended 2024-09-11 11:21:50 +=started 2024-09-12 10:44:01 +=ended 2024-09-12 10:44:01 =result ok =elapsed 0.0 =case gen_statem_SUITE:stop1 =logfile gen_statem_suite.stop1.html -=started 2024-09-11 11:21:50 -=ended 2024-09-11 11:21:51 +=started 2024-09-12 10:44:01 +=ended 2024-09-12 10:44:01 =result ok -=elapsed 1.24e-4 +=elapsed 1.36e-4 =case gen_statem_SUITE:stop2 =logfile gen_statem_suite.stop2.html -=started 2024-09-11 11:21:51 -=ended 2024-09-11 11:21:51 +=started 2024-09-12 10:44:01 +=ended 2024-09-12 10:44:02 =result ok -=elapsed 0.001182 +=elapsed 9.1e-4 =case gen_statem_SUITE:stop3 =logfile gen_statem_suite.stop3.html -=started 2024-09-11 11:21:51 -=ended 2024-09-11 11:21:52 +=started 2024-09-12 10:44:02 +=ended 2024-09-12 10:44:02 =result ok -=elapsed 1.26e-4 +=elapsed 1.29e-4 =case gen_statem_SUITE:stop4 =logfile gen_statem_suite.stop4.html -=started 2024-09-11 11:21:52 -=ended 2024-09-11 11:21:52 +=started 2024-09-12 10:44:02 +=ended 2024-09-12 10:44:03 =result ok -=elapsed 1.2e-4 +=elapsed 1.39e-4 =case gen_statem_SUITE:stop5 =logfile gen_statem_suite.stop5.html -=started 2024-09-11 11:21:52 -=ended 2024-09-11 11:21:53 +=started 2024-09-12 10:44:03 +=ended 2024-09-12 10:44:04 =result ok -=elapsed 1.02e-4 +=elapsed 1.84e-4 =case gen_statem_SUITE:stop6 =logfile gen_statem_suite.stop6.html -=started 2024-09-11 11:21:53 -=ended 2024-09-11 11:21:53 +=started 2024-09-12 10:44:04 +=ended 2024-09-12 10:44:04 =result ok -=elapsed 1.97e-4 +=elapsed 2.98e-4 =case gen_statem_SUITE:stop7 =logfile gen_statem_suite.stop7.html -=started 2024-09-11 11:21:53 -=ended 2024-09-11 11:21:54 +=started 2024-09-12 10:44:04 +=ended 2024-09-12 10:44:05 =result ok -=elapsed 1.34e-4 +=elapsed 1.86e-4 =case gen_statem_SUITE:stop8 =logfile gen_statem_suite.stop8.html -=started 2024-09-11 11:21:54 -=ended 2024-09-11 11:21:54 +=started 2024-09-12 10:44:05 +=ended 2024-09-12 10:44:05 =result ok -=elapsed 0.17102 +=elapsed 0.170187 =case gen_statem_SUITE:stop9 =logfile gen_statem_suite.stop9.html -=started 2024-09-11 11:21:54 -=ended 2024-09-11 11:21:55 +=started 2024-09-12 10:44:05 +=ended 2024-09-12 10:44:06 =result ok -=elapsed 0.173912 +=elapsed 0.157554 =case gen_statem_SUITE:stop10 =logfile gen_statem_suite.stop10.html -=started 2024-09-11 11:21:55 -=ended 2024-09-11 11:21:56 +=started 2024-09-12 10:44:06 +=ended 2024-09-12 10:44:07 =result ok -=elapsed 0.343829 +=elapsed 0.344183 =case gen_statem_SUITE:end_per_group -=logfile gen_statem_suite.end_per_group.497443.html +=logfile gen_statem_suite.end_per_group.490210.html =group_props [{name,stop}] -=started 2024-09-11 11:21:56 -=ended 2024-09-11 11:21:56 +=started 2024-09-12 10:44:07 +=ended 2024-09-12 10:44:07 =result ok =elapsed 0.0 -=group_time 5.951s +=group_time 5.932s =case gen_statem_SUITE:init_per_group -=logfile gen_statem_suite.init_per_group.497475.html +=logfile gen_statem_suite.init_per_group.490242.html =group_props [{name,stop_handle_event}] -=started 2024-09-11 11:21:56 -=ended 2024-09-11 11:21:56 +=started 2024-09-12 10:44:07 +=ended 2024-09-12 10:44:07 =result ok =elapsed 0.0 =case gen_statem_SUITE:stop1 -=logfile gen_statem_suite.stop1.497507.html -=started 2024-09-11 11:21:56 -=ended 2024-09-11 11:21:56 +=logfile gen_statem_suite.stop1.490274.html +=started 2024-09-12 10:44:07 +=ended 2024-09-12 10:44:07 =result ok -=elapsed 1.96e-4 +=elapsed 2.02e-4 =case gen_statem_SUITE:stop2 -=logfile gen_statem_suite.stop2.497539.html -=started 2024-09-11 11:21:56 -=ended 2024-09-11 11:21:57 +=logfile gen_statem_suite.stop2.490306.html +=started 2024-09-12 10:44:07 +=ended 2024-09-12 10:44:08 =result ok -=elapsed 0.001079 +=elapsed 9.34e-4 =case gen_statem_SUITE:stop3 -=logfile gen_statem_suite.stop3.497571.html -=started 2024-09-11 11:21:57 -=ended 2024-09-11 11:21:58 +=logfile gen_statem_suite.stop3.490338.html +=started 2024-09-12 10:44:08 +=ended 2024-09-12 10:44:08 =result ok -=elapsed 1.27e-4 +=elapsed 2.14e-4 =case gen_statem_SUITE:stop4 -=logfile gen_statem_suite.stop4.497603.html -=started 2024-09-11 11:21:58 -=ended 2024-09-11 11:21:58 +=logfile gen_statem_suite.stop4.402819.html +=started 2024-09-12 10:44:08 +=ended 2024-09-12 10:44:09 =result ok -=elapsed 1.57e-4 +=elapsed 2.21e-4 =case gen_statem_SUITE:stop5 -=logfile gen_statem_suite.stop5.497635.html -=started 2024-09-11 11:21:58 -=ended 2024-09-11 11:21:59 +=logfile gen_statem_suite.stop5.402851.html +=started 2024-09-12 10:44:09 +=ended 2024-09-12 10:44:09 =result ok -=elapsed 1.55e-4 +=elapsed 2.12e-4 =case gen_statem_SUITE:stop6 -=logfile gen_statem_suite.stop6.497667.html -=started 2024-09-11 11:21:59 -=ended 2024-09-11 11:21:59 +=logfile gen_statem_suite.stop6.490370.html +=started 2024-09-12 10:44:09 +=ended 2024-09-12 10:44:10 =result ok -=elapsed 2.69e-4 +=elapsed 3.18e-4 =case gen_statem_SUITE:stop7 -=logfile gen_statem_suite.stop7.497699.html -=started 2024-09-11 11:21:59 -=ended 2024-09-11 11:22:00 +=logfile gen_statem_suite.stop7.402883.html +=started 2024-09-12 10:44:10 +=ended 2024-09-12 10:44:11 =result ok -=elapsed 1.94e-4 +=elapsed 2.73e-4 =case gen_statem_SUITE:stop8 -=logfile gen_statem_suite.stop8.497731.html -=started 2024-09-11 11:22:00 -=ended 2024-09-11 11:22:00 +=logfile gen_statem_suite.stop8.402915.html +=started 2024-09-12 10:44:11 +=ended 2024-09-12 10:44:11 =result ok -=elapsed 0.159505 +=elapsed 0.161467 =case gen_statem_SUITE:stop9 -=logfile gen_statem_suite.stop9.497827.html -=started 2024-09-11 11:22:00 -=ended 2024-09-11 11:22:01 +=logfile gen_statem_suite.stop9.490434.html +=started 2024-09-12 10:44:11 +=ended 2024-09-12 10:44:12 =result ok -=elapsed 0.162183 +=elapsed 0.164338 =case gen_statem_SUITE:stop10 -=logfile gen_statem_suite.stop10.497891.html -=started 2024-09-11 11:22:01 -=ended 2024-09-11 11:22:02 +=logfile gen_statem_suite.stop10.403043.html +=started 2024-09-12 10:44:12 +=ended 2024-09-12 10:44:13 =result ok -=elapsed 0.351403 +=elapsed 0.351504 =case gen_statem_SUITE:end_per_group -=logfile gen_statem_suite.end_per_group.497955.html +=logfile gen_statem_suite.end_per_group.490530.html =group_props [{name,stop_handle_event}] -=started 2024-09-11 11:22:02 -=ended 2024-09-11 11:22:02 +=started 2024-09-12 10:44:13 +=ended 2024-09-12 10:44:13 =result ok =elapsed 0.0 -=group_time 5.934s +=group_time 5.939s =case gen_statem_SUITE:init_per_group -=logfile gen_statem_suite.init_per_group.474114.html +=logfile gen_statem_suite.init_per_group.490562.html =group_props [{name,abnormal}] -=started 2024-09-11 11:22:02 -=ended 2024-09-11 11:22:02 +=started 2024-09-12 10:44:13 +=ended 2024-09-12 10:44:13 =result ok =elapsed 0.0 =case gen_statem_SUITE:abnormal1 =logfile gen_statem_suite.abnormal1.html -=started 2024-09-11 11:22:02 -=ended 2024-09-11 11:22:06 +=started 2024-09-12 10:44:13 +=ended 2024-09-12 10:44:17 =result ok -=elapsed 3.703905 +=elapsed 3.703893 =case gen_statem_SUITE:abnormal1clean =logfile gen_statem_suite.abnormal1clean.html -=started 2024-09-11 11:22:06 -=ended 2024-09-11 11:22:09 +=started 2024-09-12 10:44:17 +=ended 2024-09-12 10:44:20 =result ok -=elapsed 2.604944 +=elapsed 2.604884 =case gen_statem_SUITE:abnormal1dirty =logfile gen_statem_suite.abnormal1dirty.html -=started 2024-09-11 11:22:09 -=ended 2024-09-11 11:22:12 +=started 2024-09-12 10:44:20 +=ended 2024-09-12 10:44:23 =result ok -=elapsed 2.60491 +=elapsed 2.604872 =case gen_statem_SUITE:abnormal2 =logfile gen_statem_suite.abnormal2.html -=started 2024-09-11 11:22:12 -=ended 2024-09-11 11:22:13 +=started 2024-09-12 10:44:23 +=ended 2024-09-12 10:44:24 =result ok -=elapsed 0.501863 +=elapsed 0.501878 =case gen_statem_SUITE:abnormal3 =logfile gen_statem_suite.abnormal3.html -=started 2024-09-11 11:22:13 -=ended 2024-09-11 11:22:14 +=started 2024-09-12 10:44:24 +=ended 2024-09-12 10:44:25 =result ok -=elapsed 0.501857 +=elapsed 0.501832 =case gen_statem_SUITE:abnormal4 =logfile gen_statem_suite.abnormal4.html -=started 2024-09-11 11:22:14 -=ended 2024-09-11 11:22:15 +=started 2024-09-12 10:44:25 +=ended 2024-09-12 10:44:26 =result ok -=elapsed 0.501827 +=elapsed 0.501835 =case gen_statem_SUITE:end_per_group -=logfile gen_statem_suite.end_per_group.497987.html +=logfile gen_statem_suite.end_per_group.490594.html =group_props [{name,abnormal}] -=started 2024-09-11 11:22:15 -=ended 2024-09-11 11:22:16 +=started 2024-09-12 10:44:26 +=ended 2024-09-12 10:44:26 =result ok =elapsed 0.0 -=group_time 13.586s +=group_time 13.587s =case gen_statem_SUITE:init_per_group -=logfile gen_statem_suite.init_per_group.498019.html +=logfile gen_statem_suite.init_per_group.490626.html =group_props [{name,abnormal_handle_event}] -=started 2024-09-11 11:22:16 -=ended 2024-09-11 11:22:16 +=started 2024-09-12 10:44:26 +=ended 2024-09-12 10:44:26 =result ok =elapsed 0.0 =case gen_statem_SUITE:abnormal1 -=logfile gen_statem_suite.abnormal1.498051.html -=started 2024-09-11 11:22:16 -=ended 2024-09-11 11:22:20 +=logfile gen_statem_suite.abnormal1.490658.html +=started 2024-09-12 10:44:26 +=ended 2024-09-12 10:44:31 =result ok -=elapsed 3.703923 +=elapsed 3.703884 =case gen_statem_SUITE:abnormal1clean -=logfile gen_statem_suite.abnormal1clean.498083.html -=started 2024-09-11 11:22:20 -=ended 2024-09-11 11:22:23 +=logfile gen_statem_suite.abnormal1clean.490690.html +=started 2024-09-12 10:44:31 +=ended 2024-09-12 10:44:34 =result ok -=elapsed 2.604916 +=elapsed 2.604869 =case gen_statem_SUITE:abnormal1dirty -=logfile gen_statem_suite.abnormal1dirty.498115.html -=started 2024-09-11 11:22:23 -=ended 2024-09-11 11:22:26 +=logfile gen_statem_suite.abnormal1dirty.490722.html +=started 2024-09-12 10:44:34 +=ended 2024-09-12 10:44:37 =result ok -=elapsed 2.604924 +=elapsed 2.604887 =case gen_statem_SUITE:abnormal2 -=logfile gen_statem_suite.abnormal2.498147.html -=started 2024-09-11 11:22:26 -=ended 2024-09-11 11:22:27 +=logfile gen_statem_suite.abnormal2.490754.html +=started 2024-09-12 10:44:37 +=ended 2024-09-12 10:44:38 =result ok -=elapsed 0.501875 +=elapsed 0.501836 =case gen_statem_SUITE:abnormal3 -=logfile gen_statem_suite.abnormal3.498179.html -=started 2024-09-11 11:22:27 -=ended 2024-09-11 11:22:28 +=logfile gen_statem_suite.abnormal3.490786.html +=started 2024-09-12 10:44:38 +=ended 2024-09-12 10:44:39 =result ok -=elapsed 0.501841 +=elapsed 0.501811 =case gen_statem_SUITE:abnormal4 -=logfile gen_statem_suite.abnormal4.498211.html -=started 2024-09-11 11:22:28 -=ended 2024-09-11 11:22:29 +=logfile gen_statem_suite.abnormal4.490818.html +=started 2024-09-12 10:44:39 +=ended 2024-09-12 10:44:40 =result ok -=elapsed 0.501901 +=elapsed 0.501889 =case gen_statem_SUITE:end_per_group -=logfile gen_statem_suite.end_per_group.498243.html +=logfile gen_statem_suite.end_per_group.403107.html =group_props [{name,abnormal_handle_event}] -=started 2024-09-11 11:22:29 -=ended 2024-09-11 11:22:29 +=started 2024-09-12 10:44:40 +=ended 2024-09-12 10:44:40 =result ok =elapsed 0.0 -=group_time 13.585s +=group_time 13.587s =case gen_statem_SUITE:shutdown =logfile gen_statem_suite.shutdown.html -=started 2024-09-11 11:22:29 -=ended 2024-09-11 11:22:31 +=started 2024-09-12 10:44:40 +=ended 2024-09-12 10:44:42 =result ok -=elapsed 1.402887 +=elapsed 1.402853 =case gen_statem_SUITE:loop_start_fail =logfile gen_statem_suite.loop_start_fail.html -=started 2024-09-11 11:22:31 -=ended 2024-09-11 11:22:37 +=started 2024-09-12 10:44:42 +=ended 2024-09-12 10:44:48 =result ok -=elapsed 5.100927 +=elapsed 5.094911 =case gen_statem_SUITE:stop_and_reply =logfile gen_statem_suite.stop_and_reply.html -=started 2024-09-11 11:22:37 -=ended 2024-09-11 11:22:38 +=started 2024-09-12 10:44:48 +=ended 2024-09-12 10:44:49 =result ok -=elapsed 1.002857 +=elapsed 1.002877 =case gen_statem_SUITE:state_enter =logfile gen_statem_suite.state_enter.html -=started 2024-09-11 11:22:38 -=ended 2024-09-11 11:22:42 +=started 2024-09-12 10:44:49 +=ended 2024-09-12 10:44:53 =result ok -=elapsed 3.50875 +=elapsed 3.508884 =case gen_statem_SUITE:event_order =logfile gen_statem_suite.event_order.html -=started 2024-09-11 11:22:42 -=ended 2024-09-11 11:22:44 +=started 2024-09-12 10:44:53 +=ended 2024-09-12 10:44:55 =result ok -=elapsed 1.002869 +=elapsed 1.002868 =case gen_statem_SUITE:state_timeout =logfile gen_statem_suite.state_timeout.html -=started 2024-09-11 11:22:44 -=ended 2024-09-11 11:22:46 +=started 2024-09-12 10:44:55 +=ended 2024-09-12 10:44:57 =result ok -=elapsed 1.501914 +=elapsed 1.501863 =case gen_statem_SUITE:timeout_cancel_and_update =logfile gen_statem_suite.timeout_cancel_and_update.html -=started 2024-09-11 11:22:46 -=ended 2024-09-11 11:22:47 +=started 2024-09-12 10:44:57 +=ended 2024-09-12 10:44:58 =result ok -=elapsed 0.569911 +=elapsed 0.569873 =case gen_statem_SUITE:event_types =logfile gen_statem_suite.event_types.html -=started 2024-09-11 11:22:47 -=ended 2024-09-11 11:22:48 +=started 2024-09-12 10:44:58 +=ended 2024-09-12 10:44:59 =result ok -=elapsed 0.501892 +=elapsed 0.501859 =case gen_statem_SUITE:generic_timers =logfile gen_statem_suite.generic_timers.html -=started 2024-09-11 11:22:48 -=ended 2024-09-11 11:22:50 +=started 2024-09-12 10:44:59 +=ended 2024-09-12 10:45:01 =result ok -=elapsed 1.501943 +=elapsed 1.501843 =case gen_statem_SUITE:code_change =logfile gen_statem_suite.code_change.html -=started 2024-09-11 11:22:50 -=ended 2024-09-11 11:22:50 +=started 2024-09-12 10:45:01 +=ended 2024-09-12 10:45:01 =result ok -=elapsed 2.95e-4 +=elapsed 3.4e-4 =case gen_statem_SUITE:init_per_group -=logfile gen_statem_suite.init_per_group.498275.html +=logfile gen_statem_suite.init_per_group.490850.html =group_props [{name,sys}] -=started 2024-09-11 11:22:50 -=ended 2024-09-11 11:22:50 +=started 2024-09-12 10:45:01 +=ended 2024-09-12 10:45:01 =result ok -=elapsed 0.003785 +=elapsed 0.003776 =case gen_statem_SUITE:sys1 =logfile gen_statem_suite.sys1.html -=started 2024-09-11 11:22:50 -=ended 2024-09-11 11:22:54 +=started 2024-09-12 10:45:01 +=ended 2024-09-12 10:45:05 =result ok -=elapsed 3.000942 +=elapsed 3.000947 =case gen_statem_SUITE:init_per_group -=logfile gen_statem_suite.init_per_group.498307.html +=logfile gen_statem_suite.init_per_group.490882.html =group_props [{name,format_status}] -=started 2024-09-11 11:22:54 -=ended 2024-09-11 11:22:54 +=started 2024-09-12 10:45:05 +=ended 2024-09-12 10:45:05 =result ok =elapsed 0.0 =case gen_statem_SUITE:call_format_status =logfile gen_statem_suite.call_format_status.html -=started 2024-09-11 11:22:54 -=ended 2024-09-11 11:22:55 +=started 2024-09-12 10:45:05 +=ended 2024-09-12 10:45:05 =result ok -=elapsed 0.005545 +=elapsed 0.004488 =case gen_statem_SUITE:error_format_status =logfile gen_statem_suite.error_format_status.html -=started 2024-09-11 11:22:55 -=ended 2024-09-11 11:22:56 +=started 2024-09-12 10:45:05 +=ended 2024-09-12 10:45:07 =result ok -=elapsed 1.003946 +=elapsed 1.004926 =case gen_statem_SUITE:terminate_crash_format =logfile gen_statem_suite.terminate_crash_format.html -=started 2024-09-11 11:22:56 -=ended 2024-09-11 11:22:58 +=started 2024-09-12 10:45:07 +=ended 2024-09-12 10:45:09 =result ok -=elapsed 1.511508 +=elapsed 1.511898 =case gen_statem_SUITE:format_all_status =logfile gen_statem_suite.format_all_status.html -=started 2024-09-11 11:22:58 -=ended 2024-09-11 11:22:59 +=started 2024-09-12 10:45:09 +=ended 2024-09-12 10:45:10 =result ok -=elapsed 0.001357 +=elapsed 0.001604 =case gen_statem_SUITE:end_per_group -=logfile gen_statem_suite.end_per_group.474146.html +=logfile gen_statem_suite.end_per_group.421892.html =group_props [{name,format_status}] -=started 2024-09-11 11:22:59 -=ended 2024-09-11 11:22:59 +=started 2024-09-12 10:45:10 +=ended 2024-09-12 10:45:10 =result ok =elapsed 0.0 -=group_time 4.640s +=group_time 4.641s =case gen_statem_SUITE:get_state =logfile gen_statem_suite.get_state.html -=started 2024-09-11 11:22:59 -=ended 2024-09-11 11:23:00 +=started 2024-09-12 10:45:10 +=ended 2024-09-12 10:45:11 =result ok -=elapsed 0.500911 +=elapsed 0.500877 =case gen_statem_SUITE:replace_state =logfile gen_statem_suite.replace_state.html -=started 2024-09-11 11:23:00 -=ended 2024-09-11 11:23:01 +=started 2024-09-12 10:45:11 +=ended 2024-09-12 10:45:12 =result ok -=elapsed 0.500923 +=elapsed 0.500896 =case gen_statem_SUITE:end_per_group -=logfile gen_statem_suite.end_per_group.498339.html +=logfile gen_statem_suite.end_per_group.421924.html =group_props [{name,sys}] -=started 2024-09-11 11:23:01 -=ended 2024-09-11 11:23:01 +=started 2024-09-12 10:45:12 +=ended 2024-09-12 10:45:12 =result ok =elapsed 0.0 -=group_time 10.263s +=group_time 10.265s =case gen_statem_SUITE:hibernate =logfile gen_statem_suite.hibernate.html -=started 2024-09-11 11:23:01 -=ended 2024-09-11 11:23:03 +=started 2024-09-12 10:45:12 +=ended 2024-09-12 10:45:13 =result ok -=elapsed 1.309916 +=elapsed 1.309871 =case gen_statem_SUITE:auto_hibernate =logfile gen_statem_suite.auto_hibernate.html -=started 2024-09-11 11:23:03 -=ended 2024-09-11 11:23:08 +=started 2024-09-12 10:45:13 +=ended 2024-09-12 10:45:19 =result ok -=elapsed 4.786915 +=elapsed 4.786823 =case gen_statem_SUITE:enter_loop =logfile gen_statem_suite.enter_loop.html -=started 2024-09-11 11:23:08 -=ended 2024-09-11 11:23:09 +=started 2024-09-12 10:45:19 +=ended 2024-09-12 10:45:20 =result ok -=elapsed 0.503904 +=elapsed 0.503832 =case gen_statem_SUITE:init_per_group -=logfile gen_statem_suite.init_per_group.474178.html +=logfile gen_statem_suite.init_per_group.490914.html =group_props [{name,undef_callbacks}] -=started 2024-09-11 11:23:09 -=ended 2024-09-11 11:23:09 +=started 2024-09-12 10:45:20 +=ended 2024-09-12 10:45:20 =result ok -=elapsed 0.006904 +=elapsed 0.007078 =case gen_statem_SUITE:undef_code_change =logfile gen_statem_suite.undef_code_change.html -=started 2024-09-11 11:23:09 -=ended 2024-09-11 11:23:09 +=started 2024-09-12 10:45:20 +=ended 2024-09-12 10:45:20 =result ok -=elapsed 0.002271 +=elapsed 0.002311 =case gen_statem_SUITE:undef_terminate1 =logfile gen_statem_suite.undef_terminate1.html -=started 2024-09-11 11:23:09 -=ended 2024-09-11 11:23:10 +=started 2024-09-12 10:45:20 +=ended 2024-09-12 10:45:21 =result ok -=elapsed 2.34e-4 +=elapsed 2.59e-4 =case gen_statem_SUITE:undef_terminate2 =logfile gen_statem_suite.undef_terminate2.html -=started 2024-09-11 11:23:10 -=ended 2024-09-11 11:23:11 +=started 2024-09-12 10:45:21 +=ended 2024-09-12 10:45:21 =result ok -=elapsed 0.001342 +=elapsed 0.00103 =case gen_statem_SUITE:pop_too_many =logfile gen_statem_suite.pop_too_many.html -=started 2024-09-11 11:23:11 -=ended 2024-09-11 11:23:11 +=started 2024-09-12 10:45:21 +=ended 2024-09-12 10:45:22 =result ok -=elapsed 0.001733 +=elapsed 0.002129 =case gen_statem_SUITE:end_per_group -=logfile gen_statem_suite.end_per_group.474210.html +=logfile gen_statem_suite.end_per_group.490946.html =group_props [{name,undef_callbacks}] -=started 2024-09-11 11:23:11 -=ended 2024-09-11 11:23:11 +=started 2024-09-12 10:45:22 +=ended 2024-09-12 10:45:22 =result ok =elapsed 0.0 -=group_time 2.131s +=group_time 2.130s =case gen_statem_SUITE:undef_in_terminate =logfile gen_statem_suite.undef_in_terminate.html -=started 2024-09-11 11:23:11 -=ended 2024-09-11 11:23:12 +=started 2024-09-12 10:45:22 +=ended 2024-09-12 10:45:22 =result ok -=elapsed 9.75e-4 +=elapsed 9.88e-4 =case gen_statem_SUITE:init_per_group -=logfile gen_statem_suite.init_per_group.474242.html +=logfile gen_statem_suite.init_per_group.490978.html =group_props [{name,format_log}] -=started 2024-09-11 11:23:12 -=ended 2024-09-11 11:23:12 +=started 2024-09-12 10:45:22 +=ended 2024-09-12 10:45:22 =result ok =elapsed 0.0 =case gen_statem_SUITE:format_log_1 =logfile gen_statem_suite.format_log_1.html -=started 2024-09-11 11:23:12 -=ended 2024-09-11 11:23:12 +=started 2024-09-12 10:45:22 +=ended 2024-09-12 10:45:23 =result ok -=elapsed 2.11e-4 +=elapsed 1.97e-4 =case gen_statem_SUITE:format_log_2 =logfile gen_statem_suite.format_log_2.html -=started 2024-09-11 11:23:12 -=ended 2024-09-11 11:23:13 +=started 2024-09-12 10:45:23 +=ended 2024-09-12 10:45:24 =result ok -=elapsed 0.001139 +=elapsed 0.001467 =case gen_statem_SUITE:format_log_with_process_label =logfile gen_statem_suite.format_log_with_process_label.html -=started 2024-09-11 11:23:13 -=ended 2024-09-11 11:23:13 +=started 2024-09-12 10:45:24 +=ended 2024-09-12 10:45:24 =result ok -=elapsed 3.42e-4 +=elapsed 2.43e-4 =case gen_statem_SUITE:end_per_group -=logfile gen_statem_suite.end_per_group.474274.html +=logfile gen_statem_suite.end_per_group.491010.html =group_props [{name,format_log}] -=started 2024-09-11 11:23:13 -=ended 2024-09-11 11:23:13 +=started 2024-09-12 10:45:24 +=ended 2024-09-12 10:45:24 =result ok =elapsed 0.0 =group_time 1.595s =case gen_statem_SUITE:reply_by_alias_with_payload =logfile gen_statem_suite.reply_by_alias_with_payload.html -=started 2024-09-11 11:23:13 -=ended 2024-09-11 11:23:14 +=started 2024-09-12 10:45:24 +=ended 2024-09-12 10:45:25 =result ok -=elapsed 1.3e-5 +=elapsed 2.0e-5 =case gen_statem_SUITE:send_request_receive_reqid_collection =logfile gen_statem_suite.send_request_receive_reqid_collection.html -=started 2024-09-11 11:23:14 -=ended 2024-09-11 11:23:16 +=started 2024-09-12 10:45:25 +=ended 2024-09-12 10:45:27 =result ok -=elapsed 1.902957 +=elapsed 1.902951 =case gen_statem_SUITE:send_request_wait_reqid_collection =logfile gen_statem_suite.send_request_wait_reqid_collection.html -=started 2024-09-11 11:23:16 -=ended 2024-09-11 11:23:18 +=started 2024-09-12 10:45:27 +=ended 2024-09-12 10:45:29 =result ok -=elapsed 1.802963 +=elapsed 1.802925 =case gen_statem_SUITE:send_request_check_reqid_collection =logfile gen_statem_suite.send_request_check_reqid_collection.html -=started 2024-09-11 11:23:18 -=ended 2024-09-11 11:23:20 +=started 2024-09-12 10:45:29 +=ended 2024-09-12 10:45:31 =result ok -=elapsed 1.003974 +=elapsed 1.00394 =case gen_statem_SUITE:end_per_suite =logfile gen_statem_suite.end_per_suite.html -=started 2024-09-11 11:23:20 -=ended 2024-09-11 11:23:20 +=started 2024-09-12 10:45:31 +=ended 2024-09-12 10:45:31 =result ok =elapsed 0.0 -=group_time 155.158s +=group_time 155.149s =case id_transform_SUITE:init_per_suite =logfile id_transform_suite.init_per_suite.html -=started 2024-09-11 11:23:20 -=ended 2024-09-11 11:23:20 +=started 2024-09-12 10:45:31 +=ended 2024-09-12 10:45:31 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =case id_transform_SUITE:id_transform =logfile id_transform_suite.id_transform.html -=started 2024-09-11 11:23:20 -=ended 2024-09-11 11:23:23 +=started 2024-09-12 10:45:31 +=ended 2024-09-12 10:45:34 =result ok -=elapsed 3.321889 +=elapsed 3.373953 =case id_transform_SUITE:end_per_suite =logfile id_transform_suite.end_per_suite.html -=started 2024-09-11 11:23:23 -=ended 2024-09-11 11:23:23 +=started 2024-09-12 10:45:34 +=ended 2024-09-12 10:45:34 =result ok =elapsed 0.0 -=group_time 3.377s +=group_time 3.427s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.474306.html +=logfile ct_framework.init_per_suite.491042.html =group_props [{suite,io_SUITE}] -=started 2024-09-11 11:23:23 -=ended 2024-09-11 11:23:23 +=started 2024-09-12 10:45:34 +=ended 2024-09-12 10:45:34 =result ok =elapsed 0.0 =case io_SUITE:error_1 =logfile io_suite.error_1.html -=started 2024-09-11 11:23:23 -=ended 2024-09-11 11:23:23 +=started 2024-09-12 10:45:34 +=ended 2024-09-12 10:45:34 =result ok -=elapsed 0.002789 +=elapsed 0.002809 =case io_SUITE:float_g =logfile io_suite.float_g.html -=started 2024-09-11 11:23:23 -=ended 2024-09-11 11:23:24 +=started 2024-09-12 10:45:34 +=ended 2024-09-12 10:45:34 =result ok -=elapsed 4.49e-4 +=elapsed 4.39e-4 =case io_SUITE:float_w =logfile io_suite.float_w.html -=started 2024-09-11 11:23:24 -=ended 2024-09-11 11:23:24 +=started 2024-09-12 10:45:34 +=ended 2024-09-12 10:45:34 =result ok -=elapsed 1.8e-4 +=elapsed 1.81e-4 =case io_SUITE:otp_5403 =logfile io_suite.otp_5403.html -=started 2024-09-11 11:23:24 -=ended 2024-09-11 11:23:24 +=started 2024-09-12 10:45:34 +=ended 2024-09-12 10:45:34 =result ok -=elapsed 1.4e-5 +=elapsed 1.5e-5 =case io_SUITE:otp_5813 =logfile io_suite.otp_5813.html -=started 2024-09-11 11:23:24 -=ended 2024-09-11 11:23:24 +=started 2024-09-12 10:45:34 +=ended 2024-09-12 10:45:35 =result ok -=elapsed 4.3e-4 +=elapsed 4.62e-4 =case io_SUITE:otp_6230 =logfile io_suite.otp_6230.html -=started 2024-09-11 11:23:24 -=ended 2024-09-11 11:23:24 +=started 2024-09-12 10:45:35 +=ended 2024-09-12 10:45:35 =result ok -=elapsed 0.004892 +=elapsed 0.005288 =case io_SUITE:otp_6282 =logfile io_suite.otp_6282.html -=started 2024-09-11 11:23:24 -=ended 2024-09-11 11:23:24 +=started 2024-09-12 10:45:35 +=ended 2024-09-12 10:45:35 =result ok =elapsed 6.6e-5 =case io_SUITE:otp_6354 =logfile io_suite.otp_6354.html -=started 2024-09-11 11:23:24 -=ended 2024-09-11 11:23:24 +=started 2024-09-12 10:45:35 +=ended 2024-09-12 10:45:35 =result ok -=elapsed 8.86e-4 +=elapsed 8.84e-4 =case io_SUITE:otp_6495 =logfile io_suite.otp_6495.html -=started 2024-09-11 11:23:24 -=ended 2024-09-11 11:23:24 +=started 2024-09-12 10:45:35 +=ended 2024-09-12 10:45:35 =result ok -=elapsed 2.0e-5 +=elapsed 1.9e-5 =case io_SUITE:otp_6517 =logfile io_suite.otp_6517.html -=started 2024-09-11 11:23:24 -=ended 2024-09-11 11:23:24 +=started 2024-09-12 10:45:35 +=ended 2024-09-12 10:45:35 =result ok =elapsed 5.0e-6 =case io_SUITE:otp_6502 =logfile io_suite.otp_6502.html -=started 2024-09-11 11:23:24 -=ended 2024-09-11 11:23:24 +=started 2024-09-12 10:45:35 +=ended 2024-09-12 10:45:35 =result ok =elapsed 3.2e-5 =case io_SUITE:manpage =logfile io_suite.manpage.html -=started 2024-09-11 11:23:24 -=ended 2024-09-11 11:23:24 +=started 2024-09-12 10:45:35 +=ended 2024-09-12 10:45:35 =result ok -=elapsed 3.36e-4 +=elapsed 3.35e-4 =case io_SUITE:otp_6708 =logfile io_suite.otp_6708.html -=started 2024-09-11 11:23:24 -=ended 2024-09-11 11:23:24 +=started 2024-09-12 10:45:35 +=ended 2024-09-12 10:45:35 =result ok -=elapsed 2.29e-4 +=elapsed 2.28e-4 =case io_SUITE:otp_7084 =logfile io_suite.otp_7084.html -=started 2024-09-11 11:23:24 -=ended 2024-09-11 11:23:25 +=started 2024-09-12 10:45:35 +=ended 2024-09-12 10:45:36 =result ok -=elapsed 0.970674 +=elapsed 0.97112 =case io_SUITE:otp_7421 =logfile io_suite.otp_7421.html -=started 2024-09-11 11:23:25 -=ended 2024-09-11 11:23:25 +=started 2024-09-12 10:45:36 +=ended 2024-09-12 10:45:36 =result ok -=elapsed 1.7e-5 +=elapsed 1.5e-5 =case io_SUITE:io_lib_collect_line_3_wb =logfile io_suite.io_lib_collect_line_3_wb.html -=started 2024-09-11 11:23:25 -=ended 2024-09-11 11:23:25 +=started 2024-09-12 10:45:36 +=ended 2024-09-12 10:45:36 =result ok -=elapsed 8.0e-5 +=elapsed 6.1e-5 =case io_SUITE:cr_whitespace_in_string =logfile io_suite.cr_whitespace_in_string.html -=started 2024-09-11 11:23:25 -=ended 2024-09-11 11:23:25 +=started 2024-09-12 10:45:36 +=ended 2024-09-12 10:45:36 =result ok -=elapsed 0.001687 +=elapsed 0.001776 =case io_SUITE:io_fread_newlines =logfile io_suite.io_fread_newlines.html -=started 2024-09-11 11:23:25 -=ended 2024-09-11 11:23:25 +=started 2024-09-12 10:45:36 +=ended 2024-09-12 10:45:36 =result ok -=elapsed 0.010468 +=elapsed 0.00983 =case io_SUITE:otp_8989 =logfile io_suite.otp_8989.html -=started 2024-09-11 11:23:25 -=ended 2024-09-11 11:23:25 +=started 2024-09-12 10:45:36 +=ended 2024-09-12 10:45:36 =result ok -=elapsed 1.46e-4 +=elapsed 9.8e-5 =case io_SUITE:io_lib_fread_literal =logfile io_suite.io_lib_fread_literal.html -=started 2024-09-11 11:23:25 -=ended 2024-09-11 11:23:25 +=started 2024-09-12 10:45:36 +=ended 2024-09-12 10:45:36 =result ok =elapsed 8.0e-6 =case io_SUITE:printable_range =logfile io_suite.printable_range.html -=started 2024-09-11 11:23:25 -=ended 2024-09-11 11:23:26 +=started 2024-09-12 10:45:36 +=ended 2024-09-12 10:45:37 =result ok -=elapsed 0.823461 +=elapsed 0.843191 =case io_SUITE:bad_printable_range =logfile io_suite.bad_printable_range.html -=started 2024-09-11 11:23:26 -=ended 2024-09-11 11:23:26 +=started 2024-09-12 10:45:37 +=ended 2024-09-12 10:45:37 =result ok -=elapsed 0.009062 +=elapsed 0.009037 =case io_SUITE:format_neg_zero =logfile io_suite.format_neg_zero.html -=started 2024-09-11 11:23:26 -=ended 2024-09-11 11:23:26 +=started 2024-09-12 10:45:37 +=ended 2024-09-12 10:45:37 =result ok -=elapsed 1.4e-5 +=elapsed 1.5e-5 =case io_SUITE:io_lib_print_binary_depth_one =logfile io_suite.io_lib_print_binary_depth_one.html -=started 2024-09-11 11:23:26 -=ended 2024-09-11 11:23:26 +=started 2024-09-12 10:45:37 +=ended 2024-09-12 10:45:37 =result ok =elapsed 2.6e-5 =case io_SUITE:otp_10302 =logfile io_suite.otp_10302.html -=started 2024-09-11 11:23:26 -=ended 2024-09-11 11:23:26 +=started 2024-09-12 10:45:37 +=ended 2024-09-12 10:45:37 =result ok -=elapsed 0.326179 +=elapsed 0.327996 =case io_SUITE:otp_10755 =logfile io_suite.otp_10755.html -=started 2024-09-11 11:23:26 -=ended 2024-09-11 11:23:26 +=started 2024-09-12 10:45:37 +=ended 2024-09-12 10:45:37 =result ok -=elapsed 0.002746 +=elapsed 0.002321 =case io_SUITE:otp_10836 =logfile io_suite.otp_10836.html -=started 2024-09-11 11:23:26 -=ended 2024-09-11 11:23:26 +=started 2024-09-12 10:45:37 +=ended 2024-09-12 10:45:37 =result ok -=elapsed 4.0e-6 +=elapsed 3.0e-6 =case io_SUITE:io_lib_width_too_small =logfile io_suite.io_lib_width_too_small.html -=started 2024-09-11 11:23:26 -=ended 2024-09-11 11:23:26 +=started 2024-09-12 10:45:37 +=ended 2024-09-12 10:45:37 =result ok -=elapsed 5.0e-6 +=elapsed 4.0e-6 =case io_SUITE:io_with_huge_message_queue =logfile io_suite.io_with_huge_message_queue.html -=started 2024-09-11 11:23:26 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:37 +=ended 2024-09-12 10:45:38 =result ok -=elapsed 0.438093 +=elapsed 0.435943 =case io_SUITE:calling_self =logfile io_suite.calling_self.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok -=elapsed 4.0e-6 +=elapsed 3.0e-6 =case io_SUITE:format_string =logfile io_suite.format_string.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok -=elapsed 1.3e-5 +=elapsed 1.0e-5 =case io_SUITE:maps =logfile io_suite.maps.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok -=elapsed 9.11e-4 +=elapsed 7.59e-4 =case io_SUITE:coverage =logfile io_suite.coverage.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok -=elapsed 1.39e-4 +=elapsed 9.2e-5 =case io_SUITE:otp_14178_unicode_atoms =logfile io_suite.otp_14178_unicode_atoms.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok -=elapsed 0.001948 +=elapsed 0.001935 =case io_SUITE:otp_14175 =logfile io_suite.otp_14175.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok -=elapsed 4.39e-4 +=elapsed 3.66e-4 =case io_SUITE:otp_14285 =logfile io_suite.otp_14285.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok -=elapsed 7.96e-4 +=elapsed 6.8e-4 =case io_SUITE:limit_term =logfile io_suite.limit_term.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok -=elapsed 4.07e-4 +=elapsed 3.14e-4 =case io_SUITE:otp_14983 =logfile io_suite.otp_14983.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok -=elapsed 0.169012 +=elapsed 0.162622 =case io_SUITE:otp_15103 =logfile io_suite.otp_15103.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok =elapsed 3.5e-5 =case io_SUITE:otp_15076 =logfile io_suite.otp_15076.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok -=elapsed 0.002431 +=elapsed 0.002362 =case io_SUITE:otp_15159 =logfile io_suite.otp_15159.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok =elapsed 6.0e-6 =case io_SUITE:otp_15639 =logfile io_suite.otp_15639.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok =elapsed 5.3e-5 =case io_SUITE:otp_15705 =logfile io_suite.otp_15705.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok -=elapsed 3.2e-5 +=elapsed 3.1e-5 =case io_SUITE:otp_15847 =logfile io_suite.otp_15847.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok =elapsed 9.0e-6 =case io_SUITE:otp_15875 =logfile io_suite.otp_15875.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok -=elapsed 1.0e-5 +=elapsed 1.1e-5 =case io_SUITE:github_4801 =logfile io_suite.github_4801.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:27 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:38 =result ok =elapsed 6.0e-6 =case io_SUITE:chars_limit =logfile io_suite.chars_limit.html -=started 2024-09-11 11:23:27 -=ended 2024-09-11 11:23:28 +=started 2024-09-12 10:45:38 +=ended 2024-09-12 10:45:39 =result ok -=elapsed 0.314225 +=elapsed 0.309974 =case io_SUITE:error_info =logfile io_suite.error_info.html -=started 2024-09-11 11:23:28 -=ended 2024-09-11 11:23:28 +=started 2024-09-12 10:45:39 +=ended 2024-09-12 10:45:39 =result ok -=elapsed 0.067924 +=elapsed 0.066957 =case io_SUITE:otp_17525 =logfile io_suite.otp_17525.html -=started 2024-09-11 11:23:28 -=ended 2024-09-11 11:23:28 +=started 2024-09-12 10:45:39 +=ended 2024-09-12 10:45:39 =result ok -=elapsed 5.2e-5 +=elapsed 4.0e-5 =case io_SUITE:unscan_format_without_maps_order =logfile io_suite.unscan_format_without_maps_order.html -=started 2024-09-11 11:23:28 -=ended 2024-09-11 11:23:28 +=started 2024-09-12 10:45:39 +=ended 2024-09-12 10:45:39 =result ok -=elapsed 1.0e-6 +=elapsed 2.0e-6 =case io_SUITE:build_text_without_maps_order =logfile io_suite.build_text_without_maps_order.html -=started 2024-09-11 11:23:28 -=ended 2024-09-11 11:23:28 +=started 2024-09-12 10:45:39 +=ended 2024-09-12 10:45:39 =result ok =elapsed 2.0e-6 =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.474882.html +=logfile ct_framework.end_per_suite.491618.html =group_props [{suite,io_SUITE}] -=started 2024-09-11 11:23:28 -=ended 2024-09-11 11:23:28 +=started 2024-09-12 10:45:39 +=ended 2024-09-12 10:45:39 =result ok =elapsed 0.0 -=group_time 4.444s +=group_time 4.436s =case io_proto_SUITE:init_per_suite =logfile io_proto_suite.init_per_suite.html -=started 2024-09-11 11:23:28 -=ended 2024-09-11 11:23:31 +=started 2024-09-12 10:45:39 +=ended 2024-09-12 10:45:42 =result ok -=elapsed 2.703315 +=elapsed 2.698928 =case io_proto_SUITE:setopts_getopts =logfile io_proto_suite.setopts_getopts.html -=started 2024-09-11 11:23:31 -=ended 2024-09-11 11:23:37 +=started 2024-09-12 10:45:42 +=ended 2024-09-12 10:45:48 =result ok -=elapsed 6.565371 +=elapsed 6.595002 =case io_proto_SUITE:unicode_options =logfile io_proto_suite.unicode_options.html -=started 2024-09-11 11:23:37 -=ended 2024-09-11 11:23:43 +=started 2024-09-12 10:45:48 +=ended 2024-09-12 10:45:54 =result ok -=elapsed 5.409495 +=elapsed 5.417986 =case io_proto_SUITE:unicode_options_gen =logfile io_proto_suite.unicode_options_gen.html -=started 2024-09-11 11:23:43 -=ended 2024-09-11 11:23:59 +=started 2024-09-12 10:45:54 +=ended 2024-09-12 10:46:10 =result ok -=elapsed 16.003044 +=elapsed 16.242842 =case io_proto_SUITE:binary_options =logfile io_proto_suite.binary_options.html -=started 2024-09-11 11:23:59 -=ended 2024-09-11 11:24:04 +=started 2024-09-12 10:46:10 +=ended 2024-09-12 10:46:15 =result ok -=elapsed 5.396961 +=elapsed 5.412293 =case io_proto_SUITE:read_modes_gl =logfile io_proto_suite.read_modes_gl.html -=started 2024-09-11 11:24:04 -=ended 2024-09-11 11:24:07 +=started 2024-09-12 10:46:15 +=ended 2024-09-12 10:46:19 =result ok -=elapsed 3.21158 +=elapsed 3.219871 =case io_proto_SUITE:read_modes_ogl =logfile io_proto_suite.read_modes_ogl.html -=started 2024-09-11 11:24:07 -=ended 2024-09-11 11:24:11 +=started 2024-09-12 10:46:19 +=ended 2024-09-12 10:46:22 =result ok -=elapsed 3.212719 +=elapsed 3.230303 =case io_proto_SUITE:broken_unicode =logfile io_proto_suite.broken_unicode.html -=started 2024-09-11 11:24:11 -=ended 2024-09-11 11:24:11 +=started 2024-09-12 10:46:22 +=ended 2024-09-12 10:46:22 =result ok -=elapsed 0.190096 +=elapsed 0.196731 =case io_proto_SUITE:eof_on_pipe =logfile io_proto_suite.eof_on_pipe.html -=started 2024-09-11 11:24:11 -=ended 2024-09-11 11:24:13 +=started 2024-09-12 10:46:22 +=ended 2024-09-12 10:46:24 =result ok -=elapsed 2.337648 +=elapsed 2.350462 =case io_proto_SUITE:unicode_prompt =logfile io_proto_suite.unicode_prompt.html -=started 2024-09-11 11:24:13 -=ended 2024-09-11 11:24:19 +=started 2024-09-12 10:46:24 +=ended 2024-09-12 10:46:30 =result ok -=elapsed 5.379182 +=elapsed 5.407778 =case io_proto_SUITE:shell_slogan =logfile io_proto_suite.shell_slogan.html -=started 2024-09-11 11:24:19 -=ended 2024-09-11 11:24:27 +=started 2024-09-12 10:46:30 +=ended 2024-09-12 10:46:38 =result ok -=elapsed 8.061345 +=elapsed 8.080561 =case io_proto_SUITE:raw_stdout =logfile io_proto_suite.raw_stdout.html -=started 2024-09-11 11:24:27 -=ended 2024-09-11 11:24:27 +=started 2024-09-12 10:46:38 +=ended 2024-09-12 10:46:38 =result ok -=elapsed 0.140739 +=elapsed 0.150707 =case io_proto_SUITE:raw_stdout_isatty =logfile io_proto_suite.raw_stdout_isatty.html -=started 2024-09-11 11:24:27 -=ended 2024-09-11 11:24:30 +=started 2024-09-12 10:46:38 +=ended 2024-09-12 10:46:41 =result ok -=elapsed 2.695213 +=elapsed 2.696344 =case io_proto_SUITE:file_read_stdin_binary_mode =logfile io_proto_suite.file_read_stdin_binary_mode.html -=started 2024-09-11 11:24:30 -=ended 2024-09-11 11:24:30 +=started 2024-09-12 10:46:41 +=ended 2024-09-12 10:46:41 =result ok -=elapsed 0.152697 +=elapsed 0.145538 =case io_proto_SUITE:file_read_stdin_list_mode =logfile io_proto_suite.file_read_stdin_list_mode.html -=started 2024-09-11 11:24:30 -=ended 2024-09-11 11:24:30 +=started 2024-09-12 10:46:41 +=ended 2024-09-12 10:46:41 =result ok -=elapsed 0.15106 +=elapsed 0.148728 =case io_proto_SUITE:file_read_stdin_unicode_translation_error_binary_mode =logfile io_proto_suite.file_read_stdin_unicode_translation_error_binary_mode.html -=started 2024-09-11 11:24:30 -=ended 2024-09-11 11:24:30 +=started 2024-09-12 10:46:41 +=ended 2024-09-12 10:46:41 =result ok -=elapsed 0.15637 +=elapsed 0.147428 =case io_proto_SUITE:file_read_stdin_unicode_translation_error_list_mode =logfile io_proto_suite.file_read_stdin_unicode_translation_error_list_mode.html -=started 2024-09-11 11:24:30 -=ended 2024-09-11 11:24:30 +=started 2024-09-12 10:46:41 +=ended 2024-09-12 10:46:42 =result ok -=elapsed 0.152608 +=elapsed 0.159118 =case io_proto_SUITE:file_read_line_stdin_unicode_translation_error_binary_mode =logfile io_proto_suite.file_read_line_stdin_unicode_translation_error_binary_mode.html -=started 2024-09-11 11:24:30 -=ended 2024-09-11 11:24:30 +=started 2024-09-12 10:46:42 +=ended 2024-09-12 10:46:42 =result ok -=elapsed 0.142044 +=elapsed 0.147729 =case io_proto_SUITE:file_read_line_stdin_unicode_translation_error_list_mode =logfile io_proto_suite.file_read_line_stdin_unicode_translation_error_list_mode.html -=started 2024-09-11 11:24:30 -=ended 2024-09-11 11:24:31 +=started 2024-09-12 10:46:42 +=ended 2024-09-12 10:46:42 =result ok -=elapsed 0.147763 +=elapsed 0.147671 =case io_proto_SUITE:io_get_chars_stdin_binary_mode =logfile io_proto_suite.io_get_chars_stdin_binary_mode.html -=started 2024-09-11 11:24:31 -=ended 2024-09-11 11:24:31 +=started 2024-09-12 10:46:42 +=ended 2024-09-12 10:46:42 =result ok -=elapsed 0.143668 +=elapsed 0.150874 =case io_proto_SUITE:io_get_chars_stdin_list_mode =logfile io_proto_suite.io_get_chars_stdin_list_mode.html -=started 2024-09-11 11:24:31 -=ended 2024-09-11 11:24:31 +=started 2024-09-12 10:46:42 +=ended 2024-09-12 10:46:42 =result ok -=elapsed 0.154471 +=elapsed 0.147285 =case io_proto_SUITE:io_get_until_stdin_binary_mode =logfile io_proto_suite.io_get_until_stdin_binary_mode.html -=started 2024-09-11 11:24:31 -=ended 2024-09-11 11:24:32 +=started 2024-09-12 10:46:42 +=ended 2024-09-12 10:46:43 =result ok -=elapsed 0.879555 +=elapsed 0.852295 =case io_proto_SUITE:io_get_until_stdin_list_mode =logfile io_proto_suite.io_get_until_stdin_list_mode.html -=started 2024-09-11 11:24:32 -=ended 2024-09-11 11:24:33 +=started 2024-09-12 10:46:43 +=ended 2024-09-12 10:46:45 =result ok -=elapsed 1.430349 +=elapsed 1.459588 =case io_proto_SUITE:io_get_chars_file_read_stdin_binary_mode =logfile io_proto_suite.io_get_chars_file_read_stdin_binary_mode.html -=started 2024-09-11 11:24:33 -=ended 2024-09-11 11:24:34 +=started 2024-09-12 10:46:45 +=ended 2024-09-12 10:46:45 =result ok -=elapsed 0.469912 +=elapsed 0.444404 =case io_proto_SUITE:file_read_stdin_latin1_binary_mode =logfile io_proto_suite.file_read_stdin_latin1_binary_mode.html -=started 2024-09-11 11:24:34 -=ended 2024-09-11 11:24:35 +=started 2024-09-12 10:46:45 +=ended 2024-09-12 10:46:46 =result ok -=elapsed 0.815776 +=elapsed 0.79246 =case io_proto_SUITE:file_read_stdin_latin1_list_mode =logfile io_proto_suite.file_read_stdin_latin1_list_mode.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=started 2024-09-12 10:46:46 +=ended 2024-09-12 10:46:46 =result ok -=elapsed 0.313907 +=elapsed 0.310197 =case io_proto_SUITE:io_fwrite_stdin_latin1_mode =logfile io_proto_suite.io_fwrite_stdin_latin1_mode.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=started 2024-09-12 10:46:46 +=ended 2024-09-12 10:46:46 =result ok -=elapsed 0.150701 +=elapsed 0.157438 =case io_proto_SUITE:end_per_suite =logfile io_proto_suite.end_per_suite.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=started 2024-09-12 10:46:46 +=ended 2024-09-12 10:46:46 =result ok =elapsed 2.0e-6 -=group_time 67.196s +=group_time 67.538s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.475906.html +=logfile ct_framework.init_per_suite.492642.html =group_props [{suite,json_SUITE}] -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=started 2024-09-12 10:46:46 +=ended 2024-09-12 10:46:46 =result ok =elapsed 0.0 =case json_SUITE:init_per_group =logfile json_suite.init_per_group.html =group_props [{name,encode},parallel] -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=started 2024-09-12 10:46:46 +=ended 2024-09-12 10:46:46 =result ok =elapsed 0.0 =case json_SUITE:test_encode_atom -=logfile json_suite.test_encode_atom.475938.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_encode_atom.492706.html +=started 2024-09-12 10:46:46 +=ended 2024-09-12 10:46:46 =result ok -=elapsed 0.002667 +=elapsed 0.003334 =case json_SUITE:test_encode_integer -=logfile json_suite.test_encode_integer.476002.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_encode_integer.403171.html +=started 2024-09-12 10:46:46 +=ended 2024-09-12 10:46:46 =result ok -=elapsed 0.002281 +=elapsed 0.002685 =case json_SUITE:test_encode_float -=logfile json_suite.test_encode_float.498371.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_encode_float.492738.html +=started 2024-09-12 10:46:46 +=ended 2024-09-12 10:46:46 =result ok -=elapsed 0.003479 +=elapsed 0.002469 =case json_SUITE:test_encode_binary -=logfile json_suite.test_encode_binary.475970.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_encode_binary.403235.html +=started 2024-09-12 10:46:46 +=ended 2024-09-12 10:46:46 =result ok -=elapsed 0.00458 +=elapsed 0.002633 =case json_SUITE:test_encode_map -=logfile json_suite.test_encode_map.498403.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_encode_map.492674.html +=started 2024-09-12 10:46:46 +=ended 2024-09-12 10:46:46 =result ok -=elapsed 0.002397 +=elapsed 0.003301 =case json_SUITE:test_encode_list -=logfile json_suite.test_encode_list.476034.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_encode_list.403203.html +=started 2024-09-12 10:46:46 +=ended 2024-09-12 10:46:46 =result ok -=elapsed 0.00202 +=elapsed 0.002982 =case json_SUITE:test_encode_proplist -=logfile json_suite.test_encode_proplist.498435.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_encode_proplist.403139.html +=started 2024-09-12 10:46:46 +=ended 2024-09-12 10:46:46 =result ok -=elapsed 7.32e-4 +=elapsed 0.003457 =case json_SUITE:test_encode_escape_all -=logfile json_suite.test_encode_escape_all.476066.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_encode_escape_all.492770.html +=started 2024-09-12 10:46:46 +=ended 2024-09-12 10:46:46 =result ok -=elapsed 0.002619 +=elapsed 0.002829 =case json_SUITE:end_per_group =logfile json_suite.end_per_group.html =group_props [{name,encode},parallel] -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=started 2024-09-12 10:46:46 +=ended 2024-09-12 10:46:47 =result ok =elapsed 0.0 -=group_time 0.056s +=group_time 0.058s =case json_SUITE:init_per_group -=logfile json_suite.init_per_group.498467.html +=logfile json_suite.init_per_group.492802.html =group_props [{name,decode},parallel] -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:47 =result ok =elapsed 0.0 =case json_SUITE:test_decode_atoms -=logfile json_suite.test_decode_atoms.498499.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_decode_atoms.492834.html +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:47 =result ok =elapsed 1.4e-5 =case json_SUITE:test_decode_numbers -=logfile json_suite.test_decode_numbers.498531.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_decode_numbers.492866.html +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:47 =result ok -=elapsed 1.55e-4 +=elapsed 1.35e-4 =case json_SUITE:test_decode_strings -=logfile json_suite.test_decode_strings.498563.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_decode_strings.492898.html +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:47 =result ok -=elapsed 3.44e-4 +=elapsed 4.18e-4 =case json_SUITE:test_decode_arrays -=logfile json_suite.test_decode_arrays.498659.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_decode_arrays.492930.html +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:47 =result ok -=elapsed 4.8e-5 +=elapsed 5.3e-5 =case json_SUITE:test_decode_objects -=logfile json_suite.test_decode_objects.498595.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_decode_objects.426181.html +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:47 =result ok -=elapsed 5.9e-5 +=elapsed 8.3e-5 =case json_SUITE:test_decode_whitespace -=logfile json_suite.test_decode_whitespace.395396.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_decode_whitespace.426213.html +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:47 =result ok -=elapsed 4.7e-5 +=elapsed 6.3e-5 =case json_SUITE:test_decode_api -=logfile json_suite.test_decode_api.498627.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_decode_api.492962.html +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:47 =result ok -=elapsed 2.3e-5 +=elapsed 2.1e-5 =case json_SUITE:test_decode_api_stream -=logfile json_suite.test_decode_api_stream.395428.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_decode_api_stream.426245.html +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:47 =result ok -=elapsed 1.8e-4 +=elapsed 3.06e-4 =case json_SUITE:end_per_group -=logfile json_suite.end_per_group.476098.html +=logfile json_suite.end_per_group.403267.html =group_props [{name,decode},parallel] -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:47 =result ok =elapsed 0.0 -=group_time 0.056s +=group_time 0.055s =case json_SUITE:init_per_group -=logfile json_suite.init_per_group.476130.html +=logfile json_suite.init_per_group.403299.html =group_props [{name,format},parallel] -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:47 =result ok =elapsed 0.0 =case json_SUITE:test_format_list -=logfile json_suite.test_format_list.476162.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_format_list.403331.html +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:47 =result ok -=elapsed 1.8e-5 +=elapsed 1.6e-5 =case json_SUITE:test_format_map -=logfile json_suite.test_format_map.476194.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_format_map.403363.html +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:47 =result ok -=elapsed 2.3e-5 +=elapsed 4.5e-5 =case json_SUITE:test_format_fun -=logfile json_suite.test_format_fun.476226.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=logfile json_suite.test_format_fun.492994.html +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:47 =result ok -=elapsed 2.2e-5 +=elapsed 1.7e-5 =case json_SUITE:end_per_group -=logfile json_suite.end_per_group.476258.html +=logfile json_suite.end_per_group.493026.html =group_props [{name,format},parallel] -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:35 +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:47 =result ok =elapsed 0.0 -=group_time 0.051s +=group_time 0.049s =case json_SUITE:test_json_test_suite =logfile json_suite.test_json_test_suite.html -=started 2024-09-11 11:24:35 -=ended 2024-09-11 11:24:36 +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:47 =result ok -=elapsed 0.542302 +=elapsed 0.542242 =case json_SUITE:init_per_group -=logfile json_suite.init_per_group.476290.html +=logfile json_suite.init_per_group.493058.html =group_props [{name,properties},parallel] -=started 2024-09-11 11:24:36 -=ended 2024-09-11 11:24:37 +=started 2024-09-12 10:46:47 +=ended 2024-09-12 10:46:48 =result ok -=elapsed 1.249974 +=elapsed 1.253516 =case json_SUITE:property_string_roundtrip -=logfile json_suite.property_string_roundtrip.395460.html -=started 2024-09-11 11:24:37 -=ended 2024-09-11 11:24:37 +=logfile json_suite.property_string_roundtrip.493090.html +=started 2024-09-12 10:46:48 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.009421 +=elapsed 0.009538 =case json_SUITE:property_integer_roundtrip -=logfile json_suite.property_integer_roundtrip.498691.html -=started 2024-09-11 11:24:37 -=ended 2024-09-11 11:24:37 +=logfile json_suite.property_integer_roundtrip.493122.html +=started 2024-09-12 10:46:48 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.004658 +=elapsed 0.007119 =case json_SUITE:property_float_roundtrip -=logfile json_suite.property_float_roundtrip.498723.html -=started 2024-09-11 11:24:37 -=ended 2024-09-11 11:24:37 +=logfile json_suite.property_float_roundtrip.421988.html +=started 2024-09-12 10:46:48 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.00781 +=elapsed 0.006525 =case json_SUITE:property_object_roundtrip -=logfile json_suite.property_object_roundtrip.498755.html -=started 2024-09-11 11:24:37 -=ended 2024-09-11 11:24:37 +=logfile json_suite.property_object_roundtrip.421956.html +=started 2024-09-12 10:46:48 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.008657 +=elapsed 0.008853 =case json_SUITE:property_escape_all -=logfile json_suite.property_escape_all.395492.html -=started 2024-09-11 11:24:37 -=ended 2024-09-11 11:24:37 +=logfile json_suite.property_escape_all.493154.html +=started 2024-09-12 10:46:48 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.010093 +=elapsed 0.008532 =case json_SUITE:end_per_group -=logfile json_suite.end_per_group.395588.html +=logfile json_suite.end_per_group.493186.html =group_props [{name,properties},parallel] -=started 2024-09-11 11:24:37 -=ended 2024-09-11 11:24:37 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 0.0 -=group_time 1.310s +=group_time 1.312s =case json_SUITE:counterexamples =logfile json_suite.counterexamples.html -=started 2024-09-11 11:24:37 -=ended 2024-09-11 11:24:37 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 1.1e-5 +=elapsed 9.0e-6 =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.395620.html +=logfile ct_framework.end_per_suite.493218.html =group_props [{suite,json_SUITE}] -=started 2024-09-11 11:24:37 -=ended 2024-09-11 11:24:37 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 0.0 -=group_time 2.191s +=group_time 2.193s =case lists_SUITE:init_per_suite =logfile lists_suite.init_per_suite.html -=started 2024-09-11 11:24:37 -=ended 2024-09-11 11:24:37 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =case lists_SUITE:init_per_group =logfile lists_suite.init_per_group.html =group_props [{name,append},parallel] -=started 2024-09-11 11:24:37 -=ended 2024-09-11 11:24:37 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 0.0 =case lists_SUITE:append_1 -=logfile lists_suite.append_1.476386.html -=started 2024-09-11 11:24:37 -=ended 2024-09-11 11:24:37 +=logfile lists_suite.append_1.493250.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 1.0e-6 =case lists_SUITE:append_2 -=logfile lists_suite.append_2.476418.html -=started 2024-09-11 11:24:37 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.append_2.493282.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.090116 +=elapsed 0.090945 =case lists_SUITE:end_per_group =logfile lists_suite.end_per_group.html =group_props [{name,append},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =group_time 0.137s =case lists_SUITE:init_per_group -=logfile lists_suite.init_per_group.476450.html +=logfile lists_suite.init_per_group.403523.html =group_props [{name,key},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 0.0 =case lists_SUITE:keymember -=logfile lists_suite.keymember.476482.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.keymember.403555.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.015017 +=elapsed 0.015374 =case lists_SUITE:keysearch_keyfind -=logfile lists_suite.keysearch_keyfind.476514.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.keysearch_keyfind.493314.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.016118 +=elapsed 0.016133 =case lists_SUITE:keystore -=logfile lists_suite.keystore.476546.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.keystore.493346.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 5.0e-6 +=elapsed 6.0e-6 =case lists_SUITE:keytake -=logfile lists_suite.keytake.476578.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.keytake.493378.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 7.0e-6 +=elapsed 6.0e-6 =case lists_SUITE:keyreplace -=logfile lists_suite.keyreplace.498819.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.keyreplace.493410.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 4.0e-6 +=elapsed 3.0e-6 =case lists_SUITE:end_per_group -=logfile lists_suite.end_per_group.498851.html +=logfile lists_suite.end_per_group.493442.html =group_props [{name,key},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.0 -=group_time 0.066s +=elapsed 1.0e-6 +=group_time 0.065s =case lists_SUITE:init_per_group -=logfile lists_suite.init_per_group.498883.html +=logfile lists_suite.init_per_group.422020.html =group_props [{name,sort},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 0.0 =case lists_SUITE:merge -=logfile lists_suite.merge.498915.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.merge.403587.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 6.5e-5 +=elapsed 6.4e-5 =case lists_SUITE:rmerge -=logfile lists_suite.rmerge.498947.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.rmerge.422052.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 2.4e-5 +=elapsed 2.8e-5 =case lists_SUITE:sort_1 -=logfile lists_suite.sort_1.499011.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.sort_1.422084.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.025464 +=elapsed 0.02541 =case lists_SUITE:sort_rand -=logfile lists_suite.sort_rand.498979.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.sort_rand.403619.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.006571 +=elapsed 0.006632 =case lists_SUITE:end_per_group -=logfile lists_suite.end_per_group.499043.html +=logfile lists_suite.end_per_group.493474.html =group_props [{name,sort},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =group_time 0.073s =case lists_SUITE:init_per_group -=logfile lists_suite.init_per_group.499075.html +=logfile lists_suite.init_per_group.403779.html =group_props [{name,usort},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 0.0 =case lists_SUITE:umerge -=logfile lists_suite.umerge.499107.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.umerge.403811.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 6.4e-5 +=elapsed 5.8e-5 =case lists_SUITE:rumerge -=logfile lists_suite.rumerge.476738.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.rumerge.403843.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 3.0e-5 +=elapsed 3.2e-5 =case lists_SUITE:usort_1 -=logfile lists_suite.usort_1.499139.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.usort_1.403875.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.023607 +=elapsed 0.021107 =case lists_SUITE:usort_rand -=logfile lists_suite.usort_rand.499171.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.usort_rand.403907.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.01134 +=elapsed 0.011212 =case lists_SUITE:end_per_group -=logfile lists_suite.end_per_group.499203.html +=logfile lists_suite.end_per_group.404195.html =group_props [{name,usort},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.0 -=group_time 0.072s +=elapsed 1.0e-6 +=group_time 0.071s =case lists_SUITE:init_per_group -=logfile lists_suite.init_per_group.499235.html +=logfile lists_suite.init_per_group.404227.html =group_props [{name,keysort},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 0.0 =case lists_SUITE:keymerge -=logfile lists_suite.keymerge.476770.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.keymerge.404259.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 9.0e-6 +=elapsed 1.1e-5 =case lists_SUITE:rkeymerge -=logfile lists_suite.rkeymerge.476834.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.rkeymerge.404323.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 1.1e-5 +=elapsed 1.0e-5 =case lists_SUITE:keysort_1 -=logfile lists_suite.keysort_1.476802.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.keysort_1.404291.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.035406 +=elapsed 0.035617 =case lists_SUITE:keysort_rand -=logfile lists_suite.keysort_rand.476866.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.keysort_rand.404355.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.010177 +=elapsed 0.00986 =case lists_SUITE:keysort_i -=logfile lists_suite.keysort_i.476930.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.keysort_i.404387.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 0.0 =case lists_SUITE:keysort_error -=logfile lists_suite.keysort_error.476898.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.keysort_error.404419.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 8.0e-6 +=elapsed 9.0e-6 =case lists_SUITE:end_per_group -=logfile lists_suite.end_per_group.476962.html +=logfile lists_suite.end_per_group.404611.html =group_props [{name,keysort},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =group_time 0.085s =case lists_SUITE:init_per_group -=logfile lists_suite.init_per_group.476994.html +=logfile lists_suite.init_per_group.493506.html =group_props [{name,ukeysort},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 0.0 =case lists_SUITE:ukeymerge -=logfile lists_suite.ukeymerge.477026.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.ukeymerge.426309.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 1.0e-5 +=elapsed 1.2e-5 =case lists_SUITE:rukeymerge -=logfile lists_suite.rukeymerge.477058.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.rukeymerge.426341.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 1.2e-5 +=elapsed 1.1e-5 =case lists_SUITE:ukeysort_1 -=logfile lists_suite.ukeysort_1.477090.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.ukeysort_1.426373.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.029651 +=elapsed 0.029221 =case lists_SUITE:ukeysort_rand -=logfile lists_suite.ukeysort_rand.395908.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.ukeysort_rand.426405.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.009077 +=elapsed 0.010726 =case lists_SUITE:ukeysort_i -=logfile lists_suite.ukeysort_i.499523.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.ukeysort_i.426437.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =case lists_SUITE:ukeysort_error -=logfile lists_suite.ukeysort_error.395940.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.ukeysort_error.493538.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 9.0e-6 +=elapsed 8.0e-6 =case lists_SUITE:end_per_group -=logfile lists_suite.end_per_group.396228.html +=logfile lists_suite.end_per_group.493570.html =group_props [{name,ukeysort},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.0 -=group_time 0.079s +=elapsed 1.0e-6 +=group_time 0.081s =case lists_SUITE:init_per_group -=logfile lists_suite.init_per_group.477122.html +=logfile lists_suite.init_per_group.493602.html =group_props [{name,uniq},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 0.0 =case lists_SUITE:uniq_1 -=logfile lists_suite.uniq_1.374213.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.uniq_1.493634.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 1.8e-5 +=elapsed 4.0e-6 =case lists_SUITE:uniq_2 -=logfile lists_suite.uniq_2.477154.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.uniq_2.493666.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 3.0e-6 =case lists_SUITE:end_per_group -=logfile lists_suite.end_per_group.477186.html +=logfile lists_suite.end_per_group.493698.html =group_props [{name,uniq},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 0.0 -=group_time 0.048s +=group_time 0.047s =case lists_SUITE:init_per_group -=logfile lists_suite.init_per_group.477218.html +=logfile lists_suite.init_per_group.493730.html =group_props [{name,sublist},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 0.0 =case lists_SUITE:sublist_2 -=logfile lists_suite.sublist_2.374245.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.sublist_2.493762.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 1.0e-6 =case lists_SUITE:sublist_3 -=logfile lists_suite.sublist_3.374277.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.sublist_3.426757.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 1.0e-6 =case lists_SUITE:sublist_2_e -=logfile lists_suite.sublist_2_e.374309.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.sublist_2_e.426725.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 8.0e-6 +=elapsed 7.0e-6 =case lists_SUITE:sublist_3_e -=logfile lists_suite.sublist_3_e.477250.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.sublist_3_e.426789.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 3.5e-5 +=elapsed 3.3e-5 =case lists_SUITE:end_per_group -=logfile lists_suite.end_per_group.477282.html +=logfile lists_suite.end_per_group.493794.html =group_props [{name,sublist},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 0.0 =group_time 0.050s =case lists_SUITE:init_per_group -=logfile lists_suite.init_per_group.477314.html +=logfile lists_suite.init_per_group.493826.html =group_props [{name,flatten},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 0.0 =case lists_SUITE:flatten_1 -=logfile lists_suite.flatten_1.477346.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.flatten_1.493858.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 2.0e-6 =case lists_SUITE:flatten_2 -=logfile lists_suite.flatten_2.477378.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.flatten_2.426853.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =case lists_SUITE:flatten_1_e -=logfile lists_suite.flatten_1_e.477410.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.flatten_1_e.426821.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok -=elapsed 4.0e-6 +=elapsed 5.0e-6 =case lists_SUITE:flatten_2_e -=logfile lists_suite.flatten_2_e.477442.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.flatten_2_e.426885.html +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:49 =result ok =elapsed 0.0 =case lists_SUITE:end_per_group -=logfile lists_suite.end_per_group.396260.html +=logfile lists_suite.end_per_group.426917.html =group_props [{name,flatten},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:49 +=ended 2024-09-12 10:46:50 =result ok =elapsed 0.0 =group_time 0.050s =case lists_SUITE:init_per_group -=logfile lists_suite.init_per_group.396292.html +=logfile lists_suite.init_per_group.426949.html =group_props [{name,seq},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 0.0 =case lists_SUITE:seq_loop -=logfile lists_suite.seq_loop.396324.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.seq_loop.426981.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 2.0e-6 =case lists_SUITE:seq_2 -=logfile lists_suite.seq_2.396356.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.seq_2.427013.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 2.0e-6 =case lists_SUITE:seq_3 -=logfile lists_suite.seq_3.396388.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.seq_3.427045.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 4.0e-6 +=elapsed 3.0e-6 =case lists_SUITE:seq_2_e -=logfile lists_suite.seq_2_e.396420.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.seq_2_e.493890.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 5.0e-6 =case lists_SUITE:seq_3_e -=logfile lists_suite.seq_3_e.374341.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.seq_3_e.427077.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 9.0e-6 =case lists_SUITE:end_per_group -=logfile lists_suite.end_per_group.374373.html +=logfile lists_suite.end_per_group.493922.html =group_props [{name,seq},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 0.0 =group_time 0.051s =case lists_SUITE:init_per_group -=logfile lists_suite.init_per_group.374405.html +=logfile lists_suite.init_per_group.493954.html =group_props [{name,tickets},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 0.0 =case lists_SUITE:otp_5939 -=logfile lists_suite.otp_5939.374437.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.otp_5939.493986.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 4.8e-5 +=elapsed 3.1e-5 =case lists_SUITE:otp_6023 -=logfile lists_suite.otp_6023.499555.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.otp_6023.427141.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 2.0e-6 =case lists_SUITE:otp_6606 -=logfile lists_suite.otp_6606.374469.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.otp_6606.427109.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 3.0e-6 =case lists_SUITE:otp_7230 -=logfile lists_suite.otp_7230.396452.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.otp_7230.494018.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 0.003185 +=elapsed 0.003949 =case lists_SUITE:end_per_group -=logfile lists_suite.end_per_group.374501.html +=logfile lists_suite.end_per_group.422212.html =group_props [{name,tickets},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 0.0 =group_time 0.052s =case lists_SUITE:init_per_group -=logfile lists_suite.init_per_group.396484.html +=logfile lists_suite.init_per_group.422244.html =group_props [{name,zip},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 0.0 =case lists_SUITE:zip_unzip -=logfile lists_suite.zip_unzip.396516.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.zip_unzip.422276.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 2.7e-5 +=elapsed 2.6e-5 =case lists_SUITE:zip_unzip3 -=logfile lists_suite.zip_unzip3.396548.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.zip_unzip3.422308.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 4.3e-5 +=elapsed 4.2e-5 =case lists_SUITE:zipwith -=logfile lists_suite.zipwith.396580.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.zipwith.427173.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 2.5e-5 +=elapsed 2.3e-5 =case lists_SUITE:zipwith3 -=logfile lists_suite.zipwith3.499587.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.zipwith3.422340.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 2.6e-5 +=elapsed 3.3e-5 =case lists_SUITE:zip_fail -=logfile lists_suite.zip_fail.396612.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.zip_fail.427205.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 5.0e-6 +=elapsed 6.0e-6 =case lists_SUITE:zip_trim -=logfile lists_suite.zip_trim.396644.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.zip_trim.422372.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =case lists_SUITE:zip_pad -=logfile lists_suite.zip_pad.374533.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.zip_pad.422404.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 1.0e-6 =case lists_SUITE:zip3_fail -=logfile lists_suite.zip3_fail.499619.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.zip3_fail.422436.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 2.0e-5 +=elapsed 1.0e-5 =case lists_SUITE:zip3_trim -=logfile lists_suite.zip3_trim.499651.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.zip3_trim.422468.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 1.0e-6 =case lists_SUITE:zip3_pad -=logfile lists_suite.zip3_pad.374565.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.zip3_pad.422500.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 2.0e-6 =case lists_SUITE:zipwith_fail -=logfile lists_suite.zipwith_fail.396676.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.zipwith_fail.422532.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 6.0e-6 +=elapsed 7.0e-6 =case lists_SUITE:zipwith_trim -=logfile lists_suite.zipwith_trim.499683.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.zipwith_trim.404643.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 0.0 =case lists_SUITE:zipwith_pad -=logfile lists_suite.zipwith_pad.477474.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.zipwith_pad.404675.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 1.0e-6 =case lists_SUITE:zipwith3_fail -=logfile lists_suite.zipwith3_fail.477506.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.zipwith3_fail.404707.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 1.1e-5 =case lists_SUITE:zipwith3_trim -=logfile lists_suite.zipwith3_trim.396708.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.zipwith3_trim.404771.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 1.0e-6 =case lists_SUITE:zipwith3_pad -=logfile lists_suite.zipwith3_pad.374597.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=logfile lists_suite.zipwith3_pad.404739.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 2.0e-6 =case lists_SUITE:end_per_group -=logfile lists_suite.end_per_group.374629.html +=logfile lists_suite.end_per_group.404803.html =group_props [{name,zip},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 0.0 -=group_time 0.061s +=group_time 0.060s =case lists_SUITE:init_per_group -=logfile lists_suite.init_per_group.374661.html +=logfile lists_suite.init_per_group.404835.html =group_props [{name,misc},parallel] -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:38 +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 0.0 =case lists_SUITE:reverse -=logfile lists_suite.reverse.374693.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:39 +=logfile lists_suite.reverse.404867.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 0.009812 +=elapsed 0.012616 =case lists_SUITE:member -=logfile lists_suite.member.374725.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:39 +=logfile lists_suite.member.404899.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 0.008136 +=elapsed 0.006158 =case lists_SUITE:dropwhile -=logfile lists_suite.dropwhile.374757.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:39 +=logfile lists_suite.dropwhile.404931.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 2.3e-5 +=elapsed 1.6e-5 =case lists_SUITE:takewhile -=logfile lists_suite.takewhile.396740.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:39 +=logfile lists_suite.takewhile.427237.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 2.1e-5 +=elapsed 3.8e-5 =case lists_SUITE:filter_partition -=logfile lists_suite.filter_partition.396804.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:39 +=logfile lists_suite.filter_partition.427269.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 6.0e-6 +=elapsed 7.0e-6 =case lists_SUITE:suffix -=logfile lists_suite.suffix.396772.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:39 +=logfile lists_suite.suffix.427301.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 0.024691 +=elapsed 0.029097 =case lists_SUITE:subtract -=logfile lists_suite.subtract.477538.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:42 +=logfile lists_suite.subtract.427333.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:53 =result ok -=elapsed 3.167491 +=elapsed 3.161264 =case lists_SUITE:join -=logfile lists_suite.join.477570.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:39 +=logfile lists_suite.join.427365.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 0.0 =case lists_SUITE:hof -=logfile lists_suite.hof.477602.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:39 +=logfile lists_suite.hof.427397.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok =elapsed 7.0e-6 =case lists_SUITE:droplast -=logfile lists_suite.droplast.477634.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:39 +=logfile lists_suite.droplast.404963.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 4.0e-6 +=elapsed 3.0e-6 =case lists_SUITE:search -=logfile lists_suite.search.477666.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:39 +=logfile lists_suite.search.404995.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 4.0e-6 +=elapsed 5.0e-6 =case lists_SUITE:enumerate -=logfile lists_suite.enumerate.374789.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:39 +=logfile lists_suite.enumerate.405027.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 2.5e-5 +=elapsed 2.6e-5 =case lists_SUITE:error_info -=logfile lists_suite.error_info.396836.html -=started 2024-09-11 11:24:38 -=ended 2024-09-11 11:24:39 +=logfile lists_suite.error_info.405059.html +=started 2024-09-12 10:46:50 +=ended 2024-09-12 10:46:50 =result ok -=elapsed 0.002204 +=elapsed 0.001121 =case lists_SUITE:end_per_group -=logfile lists_suite.end_per_group.477698.html +=logfile lists_suite.end_per_group.494050.html =group_props [{name,misc},parallel] -=started 2024-09-11 11:24:42 -=ended 2024-09-11 11:24:42 +=started 2024-09-12 10:46:53 +=ended 2024-09-12 10:46:53 =result ok -=elapsed 0.0 -=group_time 3.228s +=elapsed 1.0e-6 +=group_time 3.217s =case lists_SUITE:end_per_suite =logfile lists_suite.end_per_suite.html -=started 2024-09-11 11:24:42 -=ended 2024-09-11 11:24:42 +=started 2024-09-12 10:46:53 +=ended 2024-09-12 10:46:53 =result ok =elapsed 0.0 -=group_time 4.385s +=group_time 4.383s =case lists_property_test_SUITE:init_per_suite =logfile lists_property_test_suite.init_per_suite.html -=started 2024-09-11 11:24:42 -=ended 2024-09-11 11:24:43 +=started 2024-09-12 10:46:53 +=ended 2024-09-12 10:46:54 =result ok -=elapsed 1.262465 +=elapsed 1.256471 =case lists_property_test_SUITE:all_true_case =logfile lists_property_test_suite.all_true_case.html -=started 2024-09-11 11:24:43 -=ended 2024-09-11 11:24:43 +=started 2024-09-12 10:46:54 +=ended 2024-09-12 10:46:54 =result ok -=elapsed 0.070786 +=elapsed 0.065811 =case lists_property_test_SUITE:all_false_case =logfile lists_property_test_suite.all_false_case.html -=started 2024-09-11 11:24:43 -=ended 2024-09-11 11:24:43 +=started 2024-09-12 10:46:54 +=ended 2024-09-12 10:46:55 =result ok -=elapsed 0.119466 +=elapsed 0.116356 =case lists_property_test_SUITE:any_true_case =logfile lists_property_test_suite.any_true_case.html -=started 2024-09-11 11:24:43 -=ended 2024-09-11 11:24:43 +=started 2024-09-12 10:46:55 +=ended 2024-09-12 10:46:55 =result ok -=elapsed 0.117373 +=elapsed 0.127318 =case lists_property_test_SUITE:any_false_case =logfile lists_property_test_suite.any_false_case.html -=started 2024-09-11 11:24:43 -=ended 2024-09-11 11:24:43 +=started 2024-09-12 10:46:55 +=ended 2024-09-12 10:46:55 =result ok -=elapsed 0.05106 +=elapsed 0.068131 =case lists_property_test_SUITE:append_1_case =logfile lists_property_test_suite.append_1_case.html -=started 2024-09-11 11:24:43 -=ended 2024-09-11 11:24:44 +=started 2024-09-12 10:46:55 +=ended 2024-09-12 10:46:56 =result ok -=elapsed 0.873678 +=elapsed 0.731778 =case lists_property_test_SUITE:append_2_case =logfile lists_property_test_suite.append_2_case.html -=started 2024-09-11 11:24:44 -=ended 2024-09-11 11:24:45 +=started 2024-09-12 10:46:56 +=ended 2024-09-12 10:46:56 =result ok -=elapsed 0.127614 +=elapsed 0.130232 =case lists_property_test_SUITE:concat_case =logfile lists_property_test_suite.concat_case.html -=started 2024-09-11 11:24:45 -=ended 2024-09-11 11:24:45 +=started 2024-09-12 10:46:56 +=ended 2024-09-12 10:46:56 =result ok -=elapsed 0.026581 +=elapsed 0.022858 =case lists_property_test_SUITE:delete_case =logfile lists_property_test_suite.delete_case.html -=started 2024-09-11 11:24:45 -=ended 2024-09-11 11:24:45 +=started 2024-09-12 10:46:56 +=ended 2024-09-12 10:46:56 =result ok -=elapsed 0.133719 +=elapsed 0.115689 =case lists_property_test_SUITE:delete_absent_case =logfile lists_property_test_suite.delete_absent_case.html -=started 2024-09-11 11:24:45 -=ended 2024-09-11 11:24:45 +=started 2024-09-12 10:46:56 +=ended 2024-09-12 10:46:56 =result ok -=elapsed 0.071753 +=elapsed 0.057504 =case lists_property_test_SUITE:droplast_case =logfile lists_property_test_suite.droplast_case.html -=started 2024-09-11 11:24:45 -=ended 2024-09-11 11:24:45 +=started 2024-09-12 10:46:56 +=ended 2024-09-12 10:46:56 =result ok -=elapsed 0.071642 +=elapsed 0.056731 =case lists_property_test_SUITE:dropwhile_case =logfile lists_property_test_suite.dropwhile_case.html -=started 2024-09-11 11:24:45 -=ended 2024-09-11 11:24:45 +=started 2024-09-12 10:46:56 +=ended 2024-09-12 10:46:56 =result ok -=elapsed 0.153822 +=elapsed 0.155734 =case lists_property_test_SUITE:duplicate_case =logfile lists_property_test_suite.duplicate_case.html -=started 2024-09-11 11:24:45 -=ended 2024-09-11 11:24:45 +=started 2024-09-12 10:46:56 +=ended 2024-09-12 10:46:56 =result ok -=elapsed 0.010974 +=elapsed 0.011283 =case lists_property_test_SUITE:enumerate_1_case =logfile lists_property_test_suite.enumerate_1_case.html -=started 2024-09-11 11:24:45 -=ended 2024-09-11 11:24:45 +=started 2024-09-12 10:46:56 +=ended 2024-09-12 10:46:56 =result ok -=elapsed 0.143399 +=elapsed 0.150099 =case lists_property_test_SUITE:enumerate_2_case =logfile lists_property_test_suite.enumerate_2_case.html -=started 2024-09-11 11:24:45 -=ended 2024-09-11 11:24:45 +=started 2024-09-12 10:46:56 +=ended 2024-09-12 10:46:57 =result ok -=elapsed 0.148528 +=elapsed 0.150868 =case lists_property_test_SUITE:enumerate_3_case =logfile lists_property_test_suite.enumerate_3_case.html -=started 2024-09-11 11:24:45 -=ended 2024-09-11 11:24:46 +=started 2024-09-12 10:46:57 +=ended 2024-09-12 10:46:57 =result ok -=elapsed 0.148499 +=elapsed 0.151613 =case lists_property_test_SUITE:filter_case =logfile lists_property_test_suite.filter_case.html -=started 2024-09-11 11:24:46 -=ended 2024-09-11 11:24:46 +=started 2024-09-12 10:46:57 +=ended 2024-09-12 10:46:57 =result ok -=elapsed 0.155848 +=elapsed 0.142702 =case lists_property_test_SUITE:filtermap_case =logfile lists_property_test_suite.filtermap_case.html -=started 2024-09-11 11:24:46 -=ended 2024-09-11 11:24:46 +=started 2024-09-12 10:46:57 +=ended 2024-09-12 10:46:57 =result ok -=elapsed 0.227322 +=elapsed 0.226796 =case lists_property_test_SUITE:flatlength_case =logfile lists_property_test_suite.flatlength_case.html -=started 2024-09-11 11:24:46 -=ended 2024-09-11 11:24:46 +=started 2024-09-12 10:46:57 +=ended 2024-09-12 10:46:57 =result ok -=elapsed 0.067575 +=elapsed 0.046378 =case lists_property_test_SUITE:flatmap_case =logfile lists_property_test_suite.flatmap_case.html -=started 2024-09-11 11:24:46 -=ended 2024-09-11 11:24:50 +=started 2024-09-12 10:46:57 +=ended 2024-09-12 10:47:01 =result ok -=elapsed 3.412779 +=elapsed 3.385101 =case lists_property_test_SUITE:flatten_1_case =logfile lists_property_test_suite.flatten_1_case.html -=started 2024-09-11 11:24:50 -=ended 2024-09-11 11:24:50 +=started 2024-09-12 10:47:01 +=ended 2024-09-12 10:47:01 =result ok -=elapsed 0.071837 +=elapsed 0.055575 =case lists_property_test_SUITE:flatten_2_case =logfile lists_property_test_suite.flatten_2_case.html -=started 2024-09-11 11:24:50 -=ended 2024-09-11 11:24:50 +=started 2024-09-12 10:47:01 +=ended 2024-09-12 10:47:01 =result ok -=elapsed 0.133095 +=elapsed 0.096186 =case lists_property_test_SUITE:foldl_case =logfile lists_property_test_suite.foldl_case.html -=started 2024-09-11 11:24:50 -=ended 2024-09-11 11:24:50 +=started 2024-09-12 10:47:01 +=ended 2024-09-12 10:47:01 =result ok -=elapsed 0.361422 +=elapsed 0.353276 =case lists_property_test_SUITE:foldr_case =logfile lists_property_test_suite.foldr_case.html -=started 2024-09-11 11:24:50 -=ended 2024-09-11 11:24:51 +=started 2024-09-12 10:47:01 +=ended 2024-09-12 10:47:02 =result ok -=elapsed 0.369084 +=elapsed 0.362228 =case lists_property_test_SUITE:foreach_case =logfile lists_property_test_suite.foreach_case.html -=started 2024-09-11 11:24:51 -=ended 2024-09-11 11:24:51 +=started 2024-09-12 10:47:02 +=ended 2024-09-12 10:47:02 =result ok -=elapsed 0.067075 +=elapsed 0.077103 =case lists_property_test_SUITE:join_case =logfile lists_property_test_suite.join_case.html -=started 2024-09-11 11:24:51 -=ended 2024-09-11 11:24:51 +=started 2024-09-12 10:47:02 +=ended 2024-09-12 10:47:02 =result ok -=elapsed 0.066011 +=elapsed 0.063042 =case lists_property_test_SUITE:keydelete_case =logfile lists_property_test_suite.keydelete_case.html -=started 2024-09-11 11:24:51 -=ended 2024-09-11 11:24:51 +=started 2024-09-12 10:47:02 +=ended 2024-09-12 10:47:02 =result ok -=elapsed 0.153694 +=elapsed 0.14763 =case lists_property_test_SUITE:keydelete_absent_case =logfile lists_property_test_suite.keydelete_absent_case.html -=started 2024-09-11 11:24:51 -=ended 2024-09-11 11:24:51 +=started 2024-09-12 10:47:02 +=ended 2024-09-12 10:47:02 =result ok -=elapsed 0.064065 +=elapsed 0.059615 =case lists_property_test_SUITE:keyfind_case =logfile lists_property_test_suite.keyfind_case.html -=started 2024-09-11 11:24:51 -=ended 2024-09-11 11:24:51 +=started 2024-09-12 10:47:02 +=ended 2024-09-12 10:47:02 =result ok -=elapsed 0.155534 +=elapsed 0.146272 =case lists_property_test_SUITE:keyfind_absent_case =logfile lists_property_test_suite.keyfind_absent_case.html -=started 2024-09-11 11:24:51 -=ended 2024-09-11 11:24:51 +=started 2024-09-12 10:47:02 +=ended 2024-09-12 10:47:02 =result ok -=elapsed 0.0608 +=elapsed 0.057873 =case lists_property_test_SUITE:keymap_case =logfile lists_property_test_suite.keymap_case.html -=started 2024-09-11 11:24:51 -=ended 2024-09-11 11:24:52 +=started 2024-09-12 10:47:02 +=ended 2024-09-12 10:47:03 =result ok -=elapsed 0.901988 +=elapsed 0.842432 =case lists_property_test_SUITE:keymember_case =logfile lists_property_test_suite.keymember_case.html -=started 2024-09-11 11:24:52 -=ended 2024-09-11 11:24:52 +=started 2024-09-12 10:47:03 +=ended 2024-09-12 10:47:03 =result ok -=elapsed 0.132642 +=elapsed 0.141608 =case lists_property_test_SUITE:keymember_absent_case =logfile lists_property_test_suite.keymember_absent_case.html -=started 2024-09-11 11:24:52 -=ended 2024-09-11 11:24:52 +=started 2024-09-12 10:47:03 +=ended 2024-09-12 10:47:03 =result ok -=elapsed 0.06105 +=elapsed 0.057279 =case lists_property_test_SUITE:keymerge_case =logfile lists_property_test_suite.keymerge_case.html -=started 2024-09-11 11:24:52 -=ended 2024-09-11 11:24:53 +=started 2024-09-12 10:47:03 +=ended 2024-09-12 10:47:04 =result ok -=elapsed 0.536179 +=elapsed 0.502255 =case lists_property_test_SUITE:keymerge_invalid_case =logfile lists_property_test_suite.keymerge_invalid_case.html -=started 2024-09-11 11:24:53 -=ended 2024-09-11 11:24:53 +=started 2024-09-12 10:47:04 +=ended 2024-09-12 10:47:04 =result ok -=elapsed 0.275578 +=elapsed 0.315098 =case lists_property_test_SUITE:keyreplace_case =logfile lists_property_test_suite.keyreplace_case.html -=started 2024-09-11 11:24:53 -=ended 2024-09-11 11:24:54 +=started 2024-09-12 10:47:04 +=ended 2024-09-12 10:47:04 =result ok -=elapsed 0.201381 +=elapsed 0.181144 =case lists_property_test_SUITE:keyreplace_absent_case =logfile lists_property_test_suite.keyreplace_absent_case.html -=started 2024-09-11 11:24:54 -=ended 2024-09-11 11:24:54 +=started 2024-09-12 10:47:04 +=ended 2024-09-12 10:47:05 =result ok -=elapsed 0.123474 +=elapsed 0.125043 =case lists_property_test_SUITE:keysearch_case =logfile lists_property_test_suite.keysearch_case.html -=started 2024-09-11 11:24:54 -=ended 2024-09-11 11:24:54 +=started 2024-09-12 10:47:05 +=ended 2024-09-12 10:47:05 =result ok -=elapsed 0.151241 +=elapsed 0.153451 =case lists_property_test_SUITE:keysearch_absent_case =logfile lists_property_test_suite.keysearch_absent_case.html -=started 2024-09-11 11:24:54 -=ended 2024-09-11 11:24:54 +=started 2024-09-12 10:47:05 +=ended 2024-09-12 10:47:05 =result ok -=elapsed 0.062016 +=elapsed 0.066888 =case lists_property_test_SUITE:keysort_case =logfile lists_property_test_suite.keysort_case.html -=started 2024-09-11 11:24:54 -=ended 2024-09-11 11:24:54 +=started 2024-09-12 10:47:05 +=ended 2024-09-12 10:47:05 =result ok -=elapsed 0.233894 +=elapsed 0.25431 =case lists_property_test_SUITE:keystore_case =logfile lists_property_test_suite.keystore_case.html -=started 2024-09-11 11:24:54 -=ended 2024-09-11 11:24:54 +=started 2024-09-12 10:47:05 +=ended 2024-09-12 10:47:05 =result ok -=elapsed 0.180076 +=elapsed 0.211042 =case lists_property_test_SUITE:keystore_absent_case =logfile lists_property_test_suite.keystore_absent_case.html -=started 2024-09-11 11:24:54 -=ended 2024-09-11 11:24:55 +=started 2024-09-12 10:47:05 +=ended 2024-09-12 10:47:06 =result ok -=elapsed 0.120525 +=elapsed 0.11701 =case lists_property_test_SUITE:keytake_case =logfile lists_property_test_suite.keytake_case.html -=started 2024-09-11 11:24:55 -=ended 2024-09-11 11:24:55 +=started 2024-09-12 10:47:06 +=ended 2024-09-12 10:47:06 =result ok -=elapsed 0.16183 +=elapsed 0.14064 =case lists_property_test_SUITE:keytake_absent_case =logfile lists_property_test_suite.keytake_absent_case.html -=started 2024-09-11 11:24:55 -=ended 2024-09-11 11:24:55 +=started 2024-09-12 10:47:06 +=ended 2024-09-12 10:47:06 =result ok -=elapsed 0.060687 +=elapsed 0.063484 =case lists_property_test_SUITE:last_case =logfile lists_property_test_suite.last_case.html -=started 2024-09-11 11:24:55 -=ended 2024-09-11 11:24:55 +=started 2024-09-12 10:47:06 +=ended 2024-09-12 10:47:06 =result ok -=elapsed 0.065944 +=elapsed 0.053771 =case lists_property_test_SUITE:map_case =logfile lists_property_test_suite.map_case.html -=started 2024-09-11 11:24:55 -=ended 2024-09-11 11:24:55 +=started 2024-09-12 10:47:06 +=ended 2024-09-12 10:47:06 =result ok -=elapsed 0.362737 +=elapsed 0.36016 =case lists_property_test_SUITE:mapfoldl_case =logfile lists_property_test_suite.mapfoldl_case.html -=started 2024-09-11 11:24:55 -=ended 2024-09-11 11:24:56 +=started 2024-09-12 10:47:06 +=ended 2024-09-12 10:47:07 =result ok -=elapsed 0.589548 +=elapsed 0.589637 =case lists_property_test_SUITE:mapfoldr_case =logfile lists_property_test_suite.mapfoldr_case.html -=started 2024-09-11 11:24:56 -=ended 2024-09-11 11:24:57 +=started 2024-09-12 10:47:07 +=ended 2024-09-12 10:47:07 =result ok -=elapsed 0.579993 +=elapsed 0.609101 =case lists_property_test_SUITE:max_case =logfile lists_property_test_suite.max_case.html -=started 2024-09-11 11:24:57 -=ended 2024-09-11 11:24:57 +=started 2024-09-12 10:47:07 +=ended 2024-09-12 10:47:08 =result ok -=elapsed 0.132837 +=elapsed 0.135037 =case lists_property_test_SUITE:member_case =logfile lists_property_test_suite.member_case.html -=started 2024-09-11 11:24:57 -=ended 2024-09-11 11:24:57 +=started 2024-09-12 10:47:08 +=ended 2024-09-12 10:47:08 =result ok -=elapsed 0.117797 +=elapsed 0.135148 =case lists_property_test_SUITE:member_absent_case =logfile lists_property_test_suite.member_absent_case.html -=started 2024-09-11 11:24:57 -=ended 2024-09-11 11:24:57 +=started 2024-09-12 10:47:08 +=ended 2024-09-12 10:47:08 =result ok -=elapsed 0.057553 +=elapsed 0.059308 =case lists_property_test_SUITE:merge_1_case =logfile lists_property_test_suite.merge_1_case.html -=started 2024-09-11 11:24:57 -=ended 2024-09-11 11:24:58 +=started 2024-09-12 10:47:08 +=ended 2024-09-12 10:47:09 =result ok -=elapsed 0.779261 +=elapsed 0.845123 =case lists_property_test_SUITE:merge_1_invalid_case =logfile lists_property_test_suite.merge_1_invalid_case.html -=started 2024-09-11 11:24:58 -=ended 2024-09-11 11:24:59 +=started 2024-09-12 10:47:09 +=ended 2024-09-12 10:47:10 =result ok -=elapsed 0.912421 +=elapsed 0.919216 =case lists_property_test_SUITE:merge_2_case =logfile lists_property_test_suite.merge_2_case.html -=started 2024-09-11 11:24:59 -=ended 2024-09-11 11:24:59 +=started 2024-09-12 10:47:10 +=ended 2024-09-12 10:47:10 =result ok -=elapsed 0.125195 +=elapsed 0.127917 =case lists_property_test_SUITE:merge_2_invalid_case =logfile lists_property_test_suite.merge_2_invalid_case.html -=started 2024-09-11 11:24:59 -=ended 2024-09-11 11:24:59 +=started 2024-09-12 10:47:10 +=ended 2024-09-12 10:47:10 =result ok -=elapsed 0.076961 +=elapsed 0.067632 =case lists_property_test_SUITE:merge_3_case =logfile lists_property_test_suite.merge_3_case.html -=started 2024-09-11 11:24:59 -=ended 2024-09-11 11:24:59 +=started 2024-09-12 10:47:10 +=ended 2024-09-12 10:47:10 =result ok -=elapsed 0.124641 +=elapsed 0.143417 =case lists_property_test_SUITE:merge_3_invalid_case =logfile lists_property_test_suite.merge_3_invalid_case.html -=started 2024-09-11 11:24:59 -=ended 2024-09-11 11:24:59 +=started 2024-09-12 10:47:10 +=ended 2024-09-12 10:47:10 =result ok -=elapsed 0.069167 +=elapsed 0.074289 =case lists_property_test_SUITE:merge3_case =logfile lists_property_test_suite.merge3_case.html -=started 2024-09-11 11:24:59 -=ended 2024-09-11 11:24:59 +=started 2024-09-12 10:47:10 +=ended 2024-09-12 10:47:10 =result ok -=elapsed 0.193 +=elapsed 0.176394 =case lists_property_test_SUITE:merge3_invalid_case =logfile lists_property_test_suite.merge3_invalid_case.html -=started 2024-09-11 11:24:59 -=ended 2024-09-11 11:24:59 +=started 2024-09-12 10:47:10 +=ended 2024-09-12 10:47:10 =result ok -=elapsed 0.078937 +=elapsed 0.077574 =case lists_property_test_SUITE:min_case =logfile lists_property_test_suite.min_case.html -=started 2024-09-11 11:24:59 -=ended 2024-09-11 11:25:00 +=started 2024-09-12 10:47:10 +=ended 2024-09-12 10:47:11 =result ok -=elapsed 0.139917 +=elapsed 0.136397 =case lists_property_test_SUITE:nth_case =logfile lists_property_test_suite.nth_case.html -=started 2024-09-11 11:25:00 -=ended 2024-09-11 11:25:00 +=started 2024-09-12 10:47:11 +=ended 2024-09-12 10:47:11 =result ok -=elapsed 0.120637 +=elapsed 0.12265 =case lists_property_test_SUITE:nth_outofrange_case =logfile lists_property_test_suite.nth_outofrange_case.html -=started 2024-09-11 11:25:00 -=ended 2024-09-11 11:25:00 +=started 2024-09-12 10:47:11 +=ended 2024-09-12 10:47:11 =result ok -=elapsed 0.058734 +=elapsed 0.05578 =case lists_property_test_SUITE:nthtail_case =logfile lists_property_test_suite.nthtail_case.html -=started 2024-09-11 11:25:00 -=ended 2024-09-11 11:25:00 +=started 2024-09-12 10:47:11 +=ended 2024-09-12 10:47:11 =result ok -=elapsed 0.130641 +=elapsed 0.1165 =case lists_property_test_SUITE:nthtail_outofrange_case =logfile lists_property_test_suite.nthtail_outofrange_case.html -=started 2024-09-11 11:25:00 -=ended 2024-09-11 11:25:00 +=started 2024-09-12 10:47:11 +=ended 2024-09-12 10:47:11 =result ok -=elapsed 0.062802 +=elapsed 0.056688 =case lists_property_test_SUITE:partition_case =logfile lists_property_test_suite.partition_case.html -=started 2024-09-11 11:25:00 -=ended 2024-09-11 11:25:00 +=started 2024-09-12 10:47:11 +=ended 2024-09-12 10:47:11 =result ok -=elapsed 0.062164 +=elapsed 0.063126 =case lists_property_test_SUITE:prefix_case =logfile lists_property_test_suite.prefix_case.html -=started 2024-09-11 11:25:00 -=ended 2024-09-11 11:25:00 +=started 2024-09-12 10:47:11 +=ended 2024-09-12 10:47:11 =result ok -=elapsed 0.121838 +=elapsed 0.119167 =case lists_property_test_SUITE:reverse_1_case =logfile lists_property_test_suite.reverse_1_case.html -=started 2024-09-11 11:25:00 -=ended 2024-09-11 11:25:00 +=started 2024-09-12 10:47:11 +=ended 2024-09-12 10:47:11 =result ok -=elapsed 0.063941 +=elapsed 0.061068 =case lists_property_test_SUITE:reverse_2_case =logfile lists_property_test_suite.reverse_2_case.html -=started 2024-09-11 11:25:00 -=ended 2024-09-11 11:25:01 +=started 2024-09-12 10:47:11 +=ended 2024-09-12 10:47:12 =result ok -=elapsed 0.109931 +=elapsed 0.120743 =case lists_property_test_SUITE:search_case =logfile lists_property_test_suite.search_case.html -=started 2024-09-11 11:25:01 -=ended 2024-09-11 11:25:01 +=started 2024-09-12 10:47:12 +=ended 2024-09-12 10:47:12 =result ok -=elapsed 0.124261 +=elapsed 0.123967 =case lists_property_test_SUITE:search_absent_case =logfile lists_property_test_suite.search_absent_case.html -=started 2024-09-11 11:25:01 -=ended 2024-09-11 11:25:01 +=started 2024-09-12 10:47:12 +=ended 2024-09-12 10:47:12 =result ok -=elapsed 0.053565 +=elapsed 0.052881 =case lists_property_test_SUITE:seq2_case =logfile lists_property_test_suite.seq2_case.html -=started 2024-09-11 11:25:01 -=ended 2024-09-11 11:25:01 +=started 2024-09-12 10:47:12 +=ended 2024-09-12 10:47:12 =result ok -=elapsed 0.00117 +=elapsed 0.001313 =case lists_property_test_SUITE:seq3_case =logfile lists_property_test_suite.seq3_case.html -=started 2024-09-11 11:25:01 -=ended 2024-09-11 11:25:01 +=started 2024-09-12 10:47:12 +=ended 2024-09-12 10:47:12 =result ok -=elapsed 0.001198 +=elapsed 0.001356 =case lists_property_test_SUITE:sort_1_case =logfile lists_property_test_suite.sort_1_case.html -=started 2024-09-11 11:25:01 -=ended 2024-09-11 11:25:01 +=started 2024-09-12 10:47:12 +=ended 2024-09-12 10:47:12 =result ok -=elapsed 0.071923 +=elapsed 0.069787 =case lists_property_test_SUITE:sort_2_case =logfile lists_property_test_suite.sort_2_case.html -=started 2024-09-11 11:25:01 -=ended 2024-09-11 11:25:01 +=started 2024-09-12 10:47:12 +=ended 2024-09-12 10:47:12 =result ok -=elapsed 0.064662 +=elapsed 0.069277 =case lists_property_test_SUITE:split_case =logfile lists_property_test_suite.split_case.html -=started 2024-09-11 11:25:01 -=ended 2024-09-11 11:25:01 +=started 2024-09-12 10:47:12 +=ended 2024-09-12 10:47:12 =result ok -=elapsed 0.129368 +=elapsed 0.126203 =case lists_property_test_SUITE:split_outofrange_case =logfile lists_property_test_suite.split_outofrange_case.html -=started 2024-09-11 11:25:01 -=ended 2024-09-11 11:25:01 +=started 2024-09-12 10:47:12 +=ended 2024-09-12 10:47:12 =result ok -=elapsed 0.061576 +=elapsed 0.055777 =case lists_property_test_SUITE:splitwith_case =logfile lists_property_test_suite.splitwith_case.html -=started 2024-09-11 11:25:01 -=ended 2024-09-11 11:25:01 +=started 2024-09-12 10:47:12 +=ended 2024-09-12 10:47:12 =result ok -=elapsed 0.06661 +=elapsed 0.074717 =case lists_property_test_SUITE:sublist_2_case =logfile lists_property_test_suite.sublist_2_case.html -=started 2024-09-11 11:25:01 -=ended 2024-09-11 11:25:01 +=started 2024-09-12 10:47:12 +=ended 2024-09-12 10:47:12 =result ok -=elapsed 0.141316 +=elapsed 0.124519 =case lists_property_test_SUITE:sublist_3_case =logfile lists_property_test_suite.sublist_3_case.html -=started 2024-09-11 11:25:01 -=ended 2024-09-11 11:25:02 +=started 2024-09-12 10:47:12 +=ended 2024-09-12 10:47:13 =result ok -=elapsed 0.187257 +=elapsed 0.171113 =case lists_property_test_SUITE:subtract_case =logfile lists_property_test_suite.subtract_case.html -=started 2024-09-11 11:25:02 -=ended 2024-09-11 11:25:02 +=started 2024-09-12 10:47:13 +=ended 2024-09-12 10:47:13 =result ok -=elapsed 0.1827 +=elapsed 0.188052 =case lists_property_test_SUITE:suffix_case =logfile lists_property_test_suite.suffix_case.html -=started 2024-09-11 11:25:02 -=ended 2024-09-11 11:25:02 +=started 2024-09-12 10:47:13 +=ended 2024-09-12 10:47:13 =result ok -=elapsed 0.114494 +=elapsed 0.119809 =case lists_property_test_SUITE:sum_case =logfile lists_property_test_suite.sum_case.html -=started 2024-09-11 11:25:02 -=ended 2024-09-11 11:25:02 +=started 2024-09-12 10:47:13 +=ended 2024-09-12 10:47:13 =result ok -=elapsed 0.003601 +=elapsed 0.004014 =case lists_property_test_SUITE:takewhile_case =logfile lists_property_test_suite.takewhile_case.html -=started 2024-09-11 11:25:02 -=ended 2024-09-11 11:25:02 +=started 2024-09-12 10:47:13 +=ended 2024-09-12 10:47:13 =result ok -=elapsed 0.129359 +=elapsed 0.133894 =case lists_property_test_SUITE:ukeymerge_case =logfile lists_property_test_suite.ukeymerge_case.html -=started 2024-09-11 11:25:02 -=ended 2024-09-11 11:25:03 +=started 2024-09-12 10:47:13 +=ended 2024-09-12 10:47:14 =result ok -=elapsed 0.518512 +=elapsed 0.600875 =case lists_property_test_SUITE:ukeymerge_invalid_case =logfile lists_property_test_suite.ukeymerge_invalid_case.html -=started 2024-09-11 11:25:03 -=ended 2024-09-11 11:25:03 +=started 2024-09-12 10:47:14 +=ended 2024-09-12 10:47:14 =result ok -=elapsed 0.288535 +=elapsed 0.282769 =case lists_property_test_SUITE:ukeysort_case =logfile lists_property_test_suite.ukeysort_case.html -=started 2024-09-11 11:25:03 -=ended 2024-09-11 11:25:03 +=started 2024-09-12 10:47:14 +=ended 2024-09-12 10:47:14 =result ok -=elapsed 0.265384 +=elapsed 0.25396 =case lists_property_test_SUITE:umerge_1_case =logfile lists_property_test_suite.umerge_1_case.html -=started 2024-09-11 11:25:03 -=ended 2024-09-11 11:25:04 +=started 2024-09-12 10:47:14 +=ended 2024-09-12 10:47:15 =result ok -=elapsed 0.885389 +=elapsed 0.931411 =case lists_property_test_SUITE:umerge_1_invalid_case =logfile lists_property_test_suite.umerge_1_invalid_case.html -=started 2024-09-11 11:25:04 -=ended 2024-09-11 11:25:05 +=started 2024-09-12 10:47:15 +=ended 2024-09-12 10:47:16 =result ok -=elapsed 1.004268 +=elapsed 0.803228 =case lists_property_test_SUITE:umerge_2_case =logfile lists_property_test_suite.umerge_2_case.html -=started 2024-09-11 11:25:05 -=ended 2024-09-11 11:25:05 +=started 2024-09-12 10:47:16 +=ended 2024-09-12 10:47:16 =result ok -=elapsed 0.116009 +=elapsed 0.127452 =case lists_property_test_SUITE:umerge_2_invalid_case =logfile lists_property_test_suite.umerge_2_invalid_case.html -=started 2024-09-11 11:25:05 -=ended 2024-09-11 11:25:05 +=started 2024-09-12 10:47:16 +=ended 2024-09-12 10:47:16 =result ok -=elapsed 0.067883 +=elapsed 0.069435 =case lists_property_test_SUITE:umerge_3_case =logfile lists_property_test_suite.umerge_3_case.html -=started 2024-09-11 11:25:05 -=ended 2024-09-11 11:25:06 +=started 2024-09-12 10:47:16 +=ended 2024-09-12 10:47:17 =result ok -=elapsed 0.125763 +=elapsed 0.142569 =case lists_property_test_SUITE:umerge_3_invalid_case =logfile lists_property_test_suite.umerge_3_invalid_case.html -=started 2024-09-11 11:25:06 -=ended 2024-09-11 11:25:06 +=started 2024-09-12 10:47:17 +=ended 2024-09-12 10:47:17 =result ok -=elapsed 0.059936 +=elapsed 0.073473 =case lists_property_test_SUITE:umerge3_case =logfile lists_property_test_suite.umerge3_case.html -=started 2024-09-11 11:25:06 -=ended 2024-09-11 11:25:06 +=started 2024-09-12 10:47:17 +=ended 2024-09-12 10:47:17 =result ok -=elapsed 0.166971 +=elapsed 0.219718 =case lists_property_test_SUITE:umerge3_invalid_case =logfile lists_property_test_suite.umerge3_invalid_case.html -=started 2024-09-11 11:25:06 -=ended 2024-09-11 11:25:06 +=started 2024-09-12 10:47:17 +=ended 2024-09-12 10:47:17 =result ok -=elapsed 0.076068 +=elapsed 0.072561 =case lists_property_test_SUITE:uniq_1_case =logfile lists_property_test_suite.uniq_1_case.html -=started 2024-09-11 11:25:06 -=ended 2024-09-11 11:25:06 +=started 2024-09-12 10:47:17 +=ended 2024-09-12 10:47:17 =result ok -=elapsed 0.136075 +=elapsed 0.132904 =case lists_property_test_SUITE:uniq_2_case =logfile lists_property_test_suite.uniq_2_case.html -=started 2024-09-11 11:25:06 -=ended 2024-09-11 11:25:06 +=started 2024-09-12 10:47:17 +=ended 2024-09-12 10:47:17 =result ok -=elapsed 0.061441 +=elapsed 0.061344 =case lists_property_test_SUITE:unzip_case =logfile lists_property_test_suite.unzip_case.html -=started 2024-09-11 11:25:06 -=ended 2024-09-11 11:25:07 +=started 2024-09-12 10:47:17 +=ended 2024-09-12 10:47:18 =result ok -=elapsed 0.280834 +=elapsed 0.285834 =case lists_property_test_SUITE:unzip3_case =logfile lists_property_test_suite.unzip3_case.html -=started 2024-09-11 11:25:07 -=ended 2024-09-11 11:25:07 +=started 2024-09-12 10:47:18 +=ended 2024-09-12 10:47:18 =result ok -=elapsed 0.412881 +=elapsed 0.437226 =case lists_property_test_SUITE:usort_1_case =logfile lists_property_test_suite.usort_1_case.html -=started 2024-09-11 11:25:07 -=ended 2024-09-11 11:25:07 +=started 2024-09-12 10:47:18 +=ended 2024-09-12 10:47:18 =result ok -=elapsed 0.062191 +=elapsed 0.066798 =case lists_property_test_SUITE:usort_2_case =logfile lists_property_test_suite.usort_2_case.html -=started 2024-09-11 11:25:07 -=ended 2024-09-11 11:25:07 +=started 2024-09-12 10:47:18 +=ended 2024-09-12 10:47:18 =result ok -=elapsed 0.069081 +=elapsed 0.075184 =case lists_property_test_SUITE:zip_2_case =logfile lists_property_test_suite.zip_2_case.html -=started 2024-09-11 11:25:07 -=ended 2024-09-11 11:25:07 +=started 2024-09-12 10:47:18 +=ended 2024-09-12 10:47:19 =result ok -=elapsed 0.296207 +=elapsed 0.272334 =case lists_property_test_SUITE:zip_3_case =logfile lists_property_test_suite.zip_3_case.html -=started 2024-09-11 11:25:07 -=ended 2024-09-11 11:25:08 +=started 2024-09-12 10:47:19 +=ended 2024-09-12 10:47:19 =result ok -=elapsed 0.33995 +=elapsed 0.350199 =case lists_property_test_SUITE:zip3_3_case =logfile lists_property_test_suite.zip3_3_case.html -=started 2024-09-11 11:25:08 -=ended 2024-09-11 11:25:08 +=started 2024-09-12 10:47:19 +=ended 2024-09-12 10:47:19 =result ok -=elapsed 0.40975 +=elapsed 0.428132 =case lists_property_test_SUITE:zip3_4_case =logfile lists_property_test_suite.zip3_4_case.html -=started 2024-09-11 11:25:08 -=ended 2024-09-11 11:25:09 +=started 2024-09-12 10:47:19 +=ended 2024-09-12 10:47:20 =result ok -=elapsed 0.473399 +=elapsed 0.490266 =case lists_property_test_SUITE:zipwith_3_case =logfile lists_property_test_suite.zipwith_3_case.html -=started 2024-09-11 11:25:09 -=ended 2024-09-11 11:25:09 +=started 2024-09-12 10:47:20 +=ended 2024-09-12 10:47:20 =result ok -=elapsed 0.508511 +=elapsed 0.526158 =case lists_property_test_SUITE:zipwith_4_case =logfile lists_property_test_suite.zipwith_4_case.html -=started 2024-09-11 11:25:09 -=ended 2024-09-11 11:25:11 +=started 2024-09-12 10:47:20 +=ended 2024-09-12 10:47:22 =result ok -=elapsed 1.521678 +=elapsed 1.675655 =case lists_property_test_SUITE:zipwith3_4_case =logfile lists_property_test_suite.zipwith3_4_case.html -=started 2024-09-11 11:25:11 -=ended 2024-09-11 11:25:12 +=started 2024-09-12 10:47:22 +=ended 2024-09-12 10:47:23 =result ok -=elapsed 0.642577 +=elapsed 0.671321 =case lists_property_test_SUITE:zipwith3_5_case =logfile lists_property_test_suite.zipwith3_5_case.html -=started 2024-09-11 11:25:12 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:23 +=ended 2024-09-12 10:47:26 =result ok -=elapsed 3.357158 +=elapsed 3.419762 =case lists_property_test_SUITE:end_per_suite =logfile lists_property_test_suite.end_per_suite.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:26 +=ended 2024-09-12 10:47:26 =result ok =elapsed 0.0 -=group_time 33.158s +=group_time 33.235s =case log_mf_h_SUITE:init_per_suite =logfile log_mf_h_suite.init_per_suite.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:26 +=ended 2024-09-12 10:47:26 =result ok =elapsed 0.0 =case log_mf_h_SUITE:test =logfile log_mf_h_suite.test.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:26 +=ended 2024-09-12 10:47:26 =result ok -=elapsed 0.006364 +=elapsed 0.006247 =case log_mf_h_SUITE:end_per_suite =logfile log_mf_h_suite.end_per_suite.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:26 +=ended 2024-09-12 10:47:26 =result ok =elapsed 0.0 =group_time 0.058s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.481122.html +=logfile ct_framework.init_per_suite.497442.html =group_props [{suite,maps_SUITE}] -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:26 +=ended 2024-09-12 10:47:26 =result ok =elapsed 0.0 =case maps_SUITE:t_update_with_3 =logfile maps_suite.t_update_with_3.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:26 +=ended 2024-09-12 10:47:26 =result ok -=elapsed 7.0e-6 +=elapsed 6.0e-6 =case maps_SUITE:t_update_with_4 =logfile maps_suite.t_update_with_4.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:26 +=ended 2024-09-12 10:47:26 =result ok -=elapsed 4.0e-6 +=elapsed 5.0e-6 =case maps_SUITE:t_get_3 =logfile maps_suite.t_get_3.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:26 +=ended 2024-09-12 10:47:26 =result ok =elapsed 1.0e-6 =case maps_SUITE:t_filter_2 =logfile maps_suite.t_filter_2.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:26 +=ended 2024-09-12 10:47:26 =result ok -=elapsed 9.0e-6 +=elapsed 1.2e-5 =case maps_SUITE:t_filtermap_2 =logfile maps_suite.t_filtermap_2.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:26 +=ended 2024-09-12 10:47:26 =result ok -=elapsed 8.0e-6 +=elapsed 9.0e-6 =case maps_SUITE:t_fold_3 =logfile maps_suite.t_fold_3.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:26 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 5.4e-5 +=elapsed 5.5e-5 =case maps_SUITE:t_map_2 =logfile maps_suite.t_map_2.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 1.04e-4 +=elapsed 1.06e-4 =case maps_SUITE:t_size_1 =logfile maps_suite.t_size_1.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 1.47e-4 +=elapsed 1.75e-4 =case maps_SUITE:t_foreach_2 =logfile maps_suite.t_foreach_2.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 1.8e-5 +=elapsed 1.9e-5 =case maps_SUITE:t_iterator_1 =logfile maps_suite.t_iterator_1.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 0.015439 +=elapsed 0.015452 =case maps_SUITE:t_iterator_2 =logfile maps_suite.t_iterator_2.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 0.064088 +=elapsed 0.063165 =case maps_SUITE:t_iterator_valid =logfile maps_suite.t_iterator_valid.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 7.0e-6 +=elapsed 8.0e-6 =case maps_SUITE:t_put_opt =logfile maps_suite.t_put_opt.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 2.6e-5 +=elapsed 3.1e-5 =case maps_SUITE:t_merge_opt =logfile maps_suite.t_merge_opt.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok =elapsed 2.9e-5 =case maps_SUITE:t_with_2 =logfile maps_suite.t_with_2.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 2.3e-5 +=elapsed 2.5e-5 =case maps_SUITE:t_without_2 =logfile maps_suite.t_without_2.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:15 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 4.4e-5 +=elapsed 4.6e-5 =case maps_SUITE:t_intersect =logfile maps_suite.t_intersect.html -=started 2024-09-11 11:25:15 -=ended 2024-09-11 11:25:16 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 0.018851 +=elapsed 0.019317 =case maps_SUITE:t_intersect_with =logfile maps_suite.t_intersect_with.html -=started 2024-09-11 11:25:16 -=ended 2024-09-11 11:25:16 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 0.016323 +=elapsed 0.015919 =case maps_SUITE:t_merge_with =logfile maps_suite.t_merge_with.html -=started 2024-09-11 11:25:16 -=ended 2024-09-11 11:25:16 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 0.029691 +=elapsed 0.029527 =case maps_SUITE:t_from_keys =logfile maps_suite.t_from_keys.html -=started 2024-09-11 11:25:16 -=ended 2024-09-11 11:25:16 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 3.0e-6 +=elapsed 4.0e-6 =case maps_SUITE:error_info =logfile maps_suite.error_info.html -=started 2024-09-11 11:25:16 -=ended 2024-09-11 11:25:16 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 0.005641 +=elapsed 0.005695 =case maps_SUITE:t_from_list_kill_process =logfile maps_suite.t_from_list_kill_process.html -=started 2024-09-11 11:25:16 -=ended 2024-09-11 11:25:16 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 0.001468 +=elapsed 0.001676 =case maps_SUITE:t_from_keys_kill_process =logfile maps_suite.t_from_keys_kill_process.html -=started 2024-09-11 11:25:16 -=ended 2024-09-11 11:25:16 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 0.001087 +=elapsed 0.00128 =case maps_SUITE:t_values_kill_process =logfile maps_suite.t_values_kill_process.html -=started 2024-09-11 11:25:16 -=ended 2024-09-11 11:25:16 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 0.158147 +=elapsed 0.164671 =case maps_SUITE:t_keys_kill_process =logfile maps_suite.t_keys_kill_process.html -=started 2024-09-11 11:25:16 -=ended 2024-09-11 11:25:16 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 0.11583 +=elapsed 0.116906 =case maps_SUITE:t_from_list_check_trapping =logfile maps_suite.t_from_list_check_trapping.html -=started 2024-09-11 11:25:16 -=ended 2024-09-11 11:25:16 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:27 =result ok -=elapsed 0.086663 +=elapsed 0.089565 =case maps_SUITE:t_from_keys_check_trapping =logfile maps_suite.t_from_keys_check_trapping.html -=started 2024-09-11 11:25:16 -=ended 2024-09-11 11:25:17 +=started 2024-09-12 10:47:27 +=ended 2024-09-12 10:47:29 =result ok -=elapsed 1.320326 +=elapsed 1.32742 =case maps_SUITE:t_keys_trapping =logfile maps_suite.t_keys_trapping.html -=started 2024-09-11 11:25:17 -=ended 2024-09-11 11:25:19 +=started 2024-09-12 10:47:29 +=ended 2024-09-12 10:47:30 =result ok -=elapsed 1.524184 +=elapsed 1.546137 =case maps_SUITE:t_values_trapping =logfile maps_suite.t_values_trapping.html -=started 2024-09-11 11:25:19 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:30 +=ended 2024-09-12 10:47:32 =result ok -=elapsed 1.515829 +=elapsed 1.59601 =case maps_SUITE:t_groups_from_list =logfile maps_suite.t_groups_from_list.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:32 +=ended 2024-09-12 10:47:32 =result ok =elapsed 5.0e-6 =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.481186.html +=logfile ct_framework.end_per_suite.497570.html =group_props [{suite,maps_SUITE}] -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:32 +=ended 2024-09-12 10:47:32 =result ok =elapsed 0.0 -=group_time 5.578s +=group_time 5.698s =case math_SUITE:init_per_suite =logfile math_suite.init_per_suite.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:32 +=ended 2024-09-12 10:47:32 =result ok =elapsed 0.0 =case math_SUITE:floor_ceil =logfile math_suite.floor_ceil.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:32 +=ended 2024-09-12 10:47:32 =result ok =elapsed 1.0e-6 =case math_SUITE:error_info =logfile math_suite.error_info.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:32 +=ended 2024-09-12 10:47:32 =result ok -=elapsed 0.003442 +=elapsed 0.003228 =case math_SUITE:constants =logfile math_suite.constants.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:32 +=ended 2024-09-12 10:47:32 =result ok =elapsed 0.0 =case math_SUITE:end_per_suite =logfile math_suite.end_per_suite.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:32 +=ended 2024-09-12 10:47:32 =result ok =elapsed 0.0 =group_time 0.101s =case ms_transform_SUITE:init_per_suite =logfile ms_transform_suite.init_per_suite.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:32 +=ended 2024-09-12 10:47:32 =result ok =elapsed 0.0 =case ms_transform_SUITE:from_shell =logfile ms_transform_suite.from_shell.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:32 +=ended 2024-09-12 10:47:32 =result ok -=elapsed 1.72e-4 +=elapsed 1.75e-4 =case ms_transform_SUITE:basic_ets =logfile ms_transform_suite.basic_ets.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:32 +=ended 2024-09-12 10:47:32 =result ok -=elapsed 0.023164 +=elapsed 0.022568 =case ms_transform_SUITE:basic_dbg =logfile ms_transform_suite.basic_dbg.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:32 +=ended 2024-09-12 10:47:32 =result ok -=elapsed 0.037881 +=elapsed 0.039411 =case ms_transform_SUITE:records =logfile ms_transform_suite.records.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:32 +=ended 2024-09-12 10:47:32 =result ok -=elapsed 0.017163 +=elapsed 0.018931 =case ms_transform_SUITE:record_index =logfile ms_transform_suite.record_index.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:32 +=ended 2024-09-12 10:47:32 =result ok -=elapsed 0.016833 +=elapsed 0.017812 =case ms_transform_SUITE:multipass =logfile ms_transform_suite.multipass.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:32 +=ended 2024-09-12 10:47:32 =result ok -=elapsed 0.036849 +=elapsed 0.036901 =case ms_transform_SUITE:bitsyntax =logfile ms_transform_suite.bitsyntax.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:32 +=ended 2024-09-12 10:47:33 =result ok -=elapsed 0.013264 +=elapsed 0.014625 =case ms_transform_SUITE:binary_bifs =logfile ms_transform_suite.binary_bifs.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:33 +=ended 2024-09-12 10:47:33 =result ok -=elapsed 0.017316 +=elapsed 0.018167 =case ms_transform_SUITE:record_defaults =logfile ms_transform_suite.record_defaults.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:33 +=ended 2024-09-12 10:47:33 =result ok -=elapsed 0.004273 +=elapsed 0.003777 =case ms_transform_SUITE:andalso_orelse =logfile ms_transform_suite.andalso_orelse.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:33 +=ended 2024-09-12 10:47:33 =result ok -=elapsed 0.024875 +=elapsed 0.025983 =case ms_transform_SUITE:float_1_function =logfile ms_transform_suite.float_1_function.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:33 +=ended 2024-09-12 10:47:33 =result ok -=elapsed 0.053226 +=elapsed 0.051655 =case ms_transform_SUITE:action_function =logfile ms_transform_suite.action_function.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:33 +=ended 2024-09-12 10:47:33 =result ok -=elapsed 0.025173 +=elapsed 0.023924 =case ms_transform_SUITE:warnings =logfile ms_transform_suite.warnings.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:33 +=ended 2024-09-12 10:47:33 =result ok -=elapsed 0.012942 +=elapsed 0.012739 =case ms_transform_SUITE:no_warnings =logfile ms_transform_suite.no_warnings.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:33 +=ended 2024-09-12 10:47:33 =result ok -=elapsed 0.003243 +=elapsed 0.003322 =case ms_transform_SUITE:top_match =logfile ms_transform_suite.top_match.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:21 +=started 2024-09-12 10:47:33 +=ended 2024-09-12 10:47:33 =result ok -=elapsed 0.028606 +=elapsed 0.030169 =case ms_transform_SUITE:old_guards =logfile ms_transform_suite.old_guards.html -=started 2024-09-11 11:25:21 -=ended 2024-09-11 11:25:22 +=started 2024-09-12 10:47:33 +=ended 2024-09-12 10:47:33 =result ok -=elapsed 0.087358 +=elapsed 0.085671 =case ms_transform_SUITE:autoimported =logfile ms_transform_suite.autoimported.html -=started 2024-09-11 11:25:22 -=ended 2024-09-11 11:25:22 +=started 2024-09-12 10:47:33 +=ended 2024-09-12 10:47:34 =result ok -=elapsed 0.699403 +=elapsed 0.698475 =case ms_transform_SUITE:semicolon =logfile ms_transform_suite.semicolon.html -=started 2024-09-11 11:25:22 -=ended 2024-09-11 11:25:22 +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:34 =result ok -=elapsed 0.025868 +=elapsed 0.025171 =case ms_transform_SUITE:eep37 =logfile ms_transform_suite.eep37.html -=started 2024-09-11 11:25:22 -=ended 2024-09-11 11:25:22 +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:34 =result ok -=elapsed 0.003729 +=elapsed 0.003747 =case ms_transform_SUITE:otp_14454 =logfile ms_transform_suite.otp_14454.html -=started 2024-09-11 11:25:22 -=ended 2024-09-11 11:25:22 +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:34 =result ok -=elapsed 0.01094 +=elapsed 0.013036 =case ms_transform_SUITE:otp_16824 =logfile ms_transform_suite.otp_16824.html -=started 2024-09-11 11:25:22 -=ended 2024-09-11 11:25:22 +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:34 =result ok -=elapsed 8.58e-4 +=elapsed 8.64e-4 =case ms_transform_SUITE:unused_record =logfile ms_transform_suite.unused_record.html -=started 2024-09-11 11:25:22 -=ended 2024-09-11 11:25:22 +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:34 =result ok -=elapsed 0.001353 +=elapsed 0.001656 =case ms_transform_SUITE:map_pattern =logfile ms_transform_suite.map_pattern.html -=started 2024-09-11 11:25:22 -=ended 2024-09-11 11:25:22 +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:34 =result ok -=elapsed 0.004309 +=elapsed 0.004585 =case ms_transform_SUITE:map_expr_in_head =logfile ms_transform_suite.map_expr_in_head.html -=started 2024-09-11 11:25:22 -=ended 2024-09-11 11:25:22 +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:34 =result ok -=elapsed 0.004715 +=elapsed 0.005255 =case ms_transform_SUITE:map_pattern_from_shell =logfile ms_transform_suite.map_pattern_from_shell.html -=started 2024-09-11 11:25:22 -=ended 2024-09-11 11:25:23 +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:34 =result ok -=elapsed 8.1e-5 +=elapsed 6.5e-5 =case ms_transform_SUITE:map_expr_in_head_from_shell =logfile ms_transform_suite.map_expr_in_head_from_shell.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:23 +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:34 =result ok -=elapsed 4.8e-5 +=elapsed 4.3e-5 =case ms_transform_SUITE:map_exprs =logfile ms_transform_suite.map_exprs.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:23 +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:34 =result ok -=elapsed 0.010854 +=elapsed 0.011061 =case ms_transform_SUITE:map_exprs_from_shell =logfile ms_transform_suite.map_exprs_from_shell.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:23 +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:34 =result ok -=elapsed 1.06e-4 +=elapsed 1.15e-4 =case ms_transform_SUITE:end_per_suite =logfile ms_transform_suite.end_per_suite.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:23 +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:34 =result ok =elapsed 0.0 -=group_time 1.869s +=group_time 1.883s =case peer_SUITE:init_per_suite =logfile peer_suite.init_per_suite.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:23 +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:34 =result ok =elapsed 3.0e-6 =case peer_SUITE:init_per_group =logfile peer_suite.init_per_group.html =group_props [{name,dist},parallel] -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:23 +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:34 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =case peer_SUITE:errors -=logfile peer_suite.errors.374821.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:23 +=logfile peer_suite.errors.497634.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:34 =result ok =elapsed 5.0e-6 =case peer_SUITE:dist -=logfile peer_suite.dist.374853.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:37 +=logfile peer_suite.dist.497666.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:48 =result ok -=elapsed 14.288451 +=elapsed 14.09819 =case peer_SUITE:peer_down_crash -=logfile peer_suite.peer_down_crash.374885.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:24 +=logfile peer_suite.peer_down_crash.497730.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:35 =result ok -=elapsed 1.232054 +=elapsed 1.17461 =case peer_SUITE:peer_down_continue -=logfile peer_suite.peer_down_continue.374917.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:37 +=logfile peer_suite.peer_down_continue.427429.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:48 =result ok -=elapsed 14.290161 +=elapsed 14.099945 =case peer_SUITE:peer_down_boot -=logfile peer_suite.peer_down_boot.374981.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:23 +=logfile peer_suite.peer_down_boot.497602.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:34 =result ok -=elapsed 0.043666 +=elapsed 0.023841 =case peer_SUITE:dist_up_down -=logfile peer_suite.dist_up_down.374949.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:24 +=logfile peer_suite.dist_up_down.497698.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:35 =result ok -=elapsed 1.237384 +=elapsed 1.203215 =case peer_SUITE:dist_localhost -=logfile peer_suite.dist_localhost.396900.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:24 +=logfile peer_suite.dist_localhost.427461.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:36 =result ok -=elapsed 1.367667 +=elapsed 1.409054 =case peer_SUITE:post_process_args -=logfile peer_suite.post_process_args.499811.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:24 +=logfile peer_suite.post_process_args.427493.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:35 =result ok -=elapsed 1.209045 +=elapsed 1.098322 =case peer_SUITE:attached -=logfile peer_suite.attached.396932.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:24 +=logfile peer_suite.attached.427525.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:35 =result ok -=elapsed 1.190508 +=elapsed 1.207059 =case peer_SUITE:attached_cntrl_channel_handler_crash -=logfile peer_suite.attached_cntrl_channel_handler_crash.499843.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:25 +=logfile peer_suite.attached_cntrl_channel_handler_crash.427557.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:36 =result ok -=elapsed 2.274168 +=elapsed 2.275124 =case peer_SUITE:cntrl_channel_handler_crash -=logfile peer_suite.cntrl_channel_handler_crash.375013.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:24 +=logfile peer_suite.cntrl_channel_handler_crash.422564.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:35 =result ok -=elapsed 1.023009 +=elapsed 1.232669 =case peer_SUITE:cntrl_channel_handler_crash_old_release -=logfile peer_suite.cntrl_channel_handler_crash_old_release.499875.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:37 +=logfile peer_suite.cntrl_channel_handler_crash_old_release.422596.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:48 =result ok -=elapsed 14.49779 +=elapsed 14.290302 =case peer_SUITE:shutdown_halt -=logfile peer_suite.shutdown_halt.396964.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:25 +=logfile peer_suite.shutdown_halt.427589.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:36 =result ok -=elapsed 2.110762 +=elapsed 2.244045 =case peer_SUITE:shutdown_halt_timeout -=logfile peer_suite.shutdown_halt_timeout.396996.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:25 +=logfile peer_suite.shutdown_halt_timeout.427621.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:37 =result ok -=elapsed 2.759761 +=elapsed 2.688923 =case peer_SUITE:shutdown_stop -=logfile peer_suite.shutdown_stop.397028.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:26 +=logfile peer_suite.shutdown_stop.427653.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:37 =result ok -=elapsed 3.103958 +=elapsed 3.165541 =case peer_SUITE:shutdown_stop_timeout -=logfile peer_suite.shutdown_stop_timeout.499907.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:25 +=logfile peer_suite.shutdown_stop_timeout.427685.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:37 =result ok -=elapsed 2.635744 +=elapsed 2.687502 =case peer_SUITE:shutdown_close -=logfile peer_suite.shutdown_close.499939.html -=started 2024-09-11 11:25:23 -=ended 2024-09-11 11:25:24 +=logfile peer_suite.shutdown_close.422628.html +=started 2024-09-12 10:47:34 +=ended 2024-09-12 10:47:36 =result ok -=elapsed 1.682601 +=elapsed 1.588244 =case peer_SUITE:end_per_group =logfile peer_suite.end_per_group.html =group_props [{name,dist},parallel] -=started 2024-09-11 11:25:37 -=ended 2024-09-11 11:25:37 +=started 2024-09-12 10:47:48 +=ended 2024-09-12 10:47:48 =result ok =elapsed 1.0e-6 -=group_time 14.558s +=group_time 14.351s =case peer_SUITE:init_per_group -=logfile peer_suite.init_per_group.397188.html +=logfile peer_suite.init_per_group.423044.html =group_props [{name,dist_seq}] -=started 2024-09-11 11:25:37 -=ended 2024-09-11 11:25:37 +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:49 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =case peer_SUITE:dist_io_redirect =logfile peer_suite.dist_io_redirect.html -=started 2024-09-11 11:25:37 -=ended 2024-09-11 11:25:38 +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:49 =result ok -=elapsed 0.657772 +=elapsed 0.663372 =case peer_SUITE:peer_down_crash_tcp =logfile peer_suite.peer_down_crash_tcp.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:38 +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:49 =result ok -=elapsed 0.159001 +=elapsed 0.148248 =case peer_SUITE:end_per_group -=logfile peer_suite.end_per_group.397220.html +=logfile peer_suite.end_per_group.498274.html =group_props [{name,dist_seq}] -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:38 +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:49 =result ok -=elapsed 0.0 -=group_time 0.888s +=elapsed 1.0e-6 +=group_time 0.885s =case peer_SUITE:init_per_group -=logfile peer_suite.init_per_group.481826.html +=logfile peer_suite.init_per_group.423108.html =group_props [{name,tcp},parallel] -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:38 +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:49 =result ok =elapsed 0.0 =case peer_SUITE:basic -=logfile peer_suite.basic.481858.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:40 +=logfile peer_suite.basic.423140.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:51 =result ok -=elapsed 1.740381 +=elapsed 1.329851 =case peer_SUITE:peer_states -=logfile peer_suite.peer_states.481890.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:41 +=logfile peer_suite.peer_states.423172.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:52 =result ok -=elapsed 2.448623 +=elapsed 2.54851 =case peer_SUITE:cast -=logfile peer_suite.cast.481922.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:40 +=logfile peer_suite.cast.423204.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:51 =result ok -=elapsed 1.630569 +=elapsed 1.546446 =case peer_SUITE:detached -=logfile peer_suite.detached.481954.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:40 +=logfile peer_suite.detached.423268.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:51 =result ok -=elapsed 1.640773 +=elapsed 1.337193 =case peer_SUITE:dyn_peer -=logfile peer_suite.dyn_peer.481986.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:40 +=logfile peer_suite.dyn_peer.423236.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:51 =result ok -=elapsed 1.61536 +=elapsed 1.717256 =case peer_SUITE:stop_peer -=logfile peer_suite.stop_peer.482018.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:40 +=logfile peer_suite.stop_peer.427941.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:51 =result ok -=elapsed 1.74042 +=elapsed 1.636612 =case peer_SUITE:io_redirect -=logfile peer_suite.io_redirect.375141.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:40 +=logfile peer_suite.io_redirect.427973.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:51 =result ok -=elapsed 1.657755 +=elapsed 1.400164 =case peer_SUITE:multi_node -=logfile peer_suite.multi_node.375173.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:40 +=logfile peer_suite.multi_node.428005.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:51 =result ok -=elapsed 1.766222 +=elapsed 1.681113 =case peer_SUITE:duplicate_name -=logfile peer_suite.duplicate_name.375205.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:40 +=logfile peer_suite.duplicate_name.428037.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:51 =result ok -=elapsed 1.885499 +=elapsed 1.921132 =case peer_SUITE:attached -=logfile peer_suite.attached.375237.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:40 +=logfile peer_suite.attached.428069.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:51 =result ok -=elapsed 1.778746 +=elapsed 1.5756 =case peer_SUITE:attached_cntrl_channel_handler_crash -=logfile peer_suite.attached_cntrl_channel_handler_crash.397252.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:41 +=logfile peer_suite.attached_cntrl_channel_handler_crash.428101.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:52 =result ok -=elapsed 2.499187 +=elapsed 2.770671 =case peer_SUITE:cntrl_channel_handler_crash -=logfile peer_suite.cntrl_channel_handler_crash.397284.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:40 +=logfile peer_suite.cntrl_channel_handler_crash.428133.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:51 =result ok -=elapsed 1.721054 +=elapsed 1.753146 =case peer_SUITE:cntrl_channel_handler_crash_old_release -=logfile peer_suite.cntrl_channel_handler_crash_old_release.397316.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:41 +=logfile peer_suite.cntrl_channel_handler_crash_old_release.423300.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:52 =result ok -=elapsed 2.337803 +=elapsed 2.33174 =case peer_SUITE:shutdown_halt -=logfile peer_suite.shutdown_halt.500387.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:41 +=logfile peer_suite.shutdown_halt.423332.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:52 =result ok -=elapsed 2.694746 +=elapsed 2.745093 =case peer_SUITE:shutdown_halt_timeout -=logfile peer_suite.shutdown_halt_timeout.500419.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:41 +=logfile peer_suite.shutdown_halt_timeout.405251.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:53 =result ok -=elapsed 3.245584 +=elapsed 3.105512 =case peer_SUITE:shutdown_stop -=logfile peer_suite.shutdown_stop.500451.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:42 +=logfile peer_suite.shutdown_stop.428197.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:53 =result ok -=elapsed 3.688709 +=elapsed 3.740818 =case peer_SUITE:shutdown_stop_timeout -=logfile peer_suite.shutdown_stop_timeout.500483.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:41 +=logfile peer_suite.shutdown_stop_timeout.428165.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:53 =result ok -=elapsed 3.081648 +=elapsed 3.06095 =case peer_SUITE:shutdown_close -=logfile peer_suite.shutdown_close.500515.html -=started 2024-09-11 11:25:38 -=ended 2024-09-11 11:25:40 +=logfile peer_suite.shutdown_close.428229.html +=started 2024-09-12 10:47:49 +=ended 2024-09-12 10:47:52 =result ok -=elapsed 2.197742 +=elapsed 2.078159 =case peer_SUITE:end_per_group -=logfile peer_suite.end_per_group.501027.html +=logfile peer_suite.end_per_group.405571.html =group_props [{name,tcp},parallel] -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:42 +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:53 =result ok -=elapsed 0.0 -=group_time 3.760s +=elapsed 1.0e-6 +=group_time 3.804s =case peer_SUITE:init_per_group -=logfile peer_suite.init_per_group.501059.html +=logfile peer_suite.init_per_group.405603.html =group_props [{name,standard_io},parallel] -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:42 +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:53 =result ok =elapsed 0.0 =case peer_SUITE:init_debug -=logfile peer_suite.init_debug.501091.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:45 +=logfile peer_suite.init_debug.405635.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:56 =result ok -=elapsed 2.74311 +=elapsed 2.698611 =case peer_SUITE:basic -=logfile peer_suite.basic.501123.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:43 +=logfile peer_suite.basic.405667.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:55 =result ok -=elapsed 1.398472 +=elapsed 1.218756 =case peer_SUITE:peer_states -=logfile peer_suite.peer_states.501155.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:44 +=logfile peer_suite.peer_states.405699.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:55 =result ok -=elapsed 1.937953 +=elapsed 2.212839 =case peer_SUITE:cast -=logfile peer_suite.cast.375461.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:44 +=logfile peer_suite.cast.405731.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:55 =result ok -=elapsed 1.512549 +=elapsed 1.328734 =case peer_SUITE:detached -=logfile peer_suite.detached.375557.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:43 +=logfile peer_suite.detached.428293.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:55 =result ok -=elapsed 1.348898 +=elapsed 1.545623 =case peer_SUITE:dyn_peer -=logfile peer_suite.dyn_peer.375397.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:43 +=logfile peer_suite.dyn_peer.405763.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:55 =result ok -=elapsed 1.228844 +=elapsed 1.470874 =case peer_SUITE:stop_peer -=logfile peer_suite.stop_peer.375429.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:43 +=logfile peer_suite.stop_peer.428325.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:55 =result ok -=elapsed 1.47862 +=elapsed 1.415837 =case peer_SUITE:io_redirect -=logfile peer_suite.io_redirect.375525.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:43 +=logfile peer_suite.io_redirect.405795.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:55 =result ok -=elapsed 1.322885 +=elapsed 1.52972 =case peer_SUITE:multi_node -=logfile peer_suite.multi_node.375493.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:43 +=logfile peer_suite.multi_node.428357.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:55 =result ok -=elapsed 1.49444 +=elapsed 1.44882 =case peer_SUITE:duplicate_name -=logfile peer_suite.duplicate_name.375589.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:44 +=logfile peer_suite.duplicate_name.428389.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:55 =result ok -=elapsed 1.639007 +=elapsed 1.672278 =case peer_SUITE:attached -=logfile peer_suite.attached.501187.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:42 +=logfile peer_suite.attached.428421.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:53 =result ok -=elapsed 2.82e-4 +=elapsed 0.002694 =case peer_SUITE:attached_cntrl_channel_handler_crash -=logfile peer_suite.attached_cntrl_channel_handler_crash.501219.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:42 +=logfile peer_suite.attached_cntrl_channel_handler_crash.405827.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:53 =result ok -=elapsed 6.67e-4 +=elapsed 2.3e-4 =case peer_SUITE:cntrl_channel_handler_crash -=logfile peer_suite.cntrl_channel_handler_crash.501251.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:43 +=logfile peer_suite.cntrl_channel_handler_crash.405859.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:55 =result ok -=elapsed 1.465955 +=elapsed 1.527306 =case peer_SUITE:cntrl_channel_handler_crash_old_release -=logfile peer_suite.cntrl_channel_handler_crash_old_release.501283.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:44 +=logfile peer_suite.cntrl_channel_handler_crash_old_release.405891.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:55 =result ok -=elapsed 2.074408 +=elapsed 2.122944 =case peer_SUITE:shutdown_halt -=logfile peer_suite.shutdown_halt.375621.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:44 +=logfile peer_suite.shutdown_halt.405923.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:56 =result ok -=elapsed 2.405769 +=elapsed 2.581438 =case peer_SUITE:shutdown_halt_timeout -=logfile peer_suite.shutdown_halt_timeout.482146.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:45 +=logfile peer_suite.shutdown_halt_timeout.423588.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:56 =result ok -=elapsed 2.890609 +=elapsed 3.034596 =case peer_SUITE:shutdown_stop -=logfile peer_suite.shutdown_stop.482178.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:45 +=logfile peer_suite.shutdown_stop.423620.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:57 =result ok -=elapsed 3.481501 +=elapsed 3.51608 =case peer_SUITE:shutdown_stop_timeout -=logfile peer_suite.shutdown_stop_timeout.375653.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:45 +=logfile peer_suite.shutdown_stop_timeout.423652.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:56 =result ok -=elapsed 2.823548 +=elapsed 2.934104 =case peer_SUITE:shutdown_close -=logfile peer_suite.shutdown_close.375685.html -=started 2024-09-11 11:25:42 -=ended 2024-09-11 11:25:44 +=logfile peer_suite.shutdown_close.405987.html +=started 2024-09-12 10:47:53 +=ended 2024-09-12 10:47:55 =result ok -=elapsed 2.007281 +=elapsed 1.531337 =case peer_SUITE:end_per_group -=logfile peer_suite.end_per_group.376005.html +=logfile peer_suite.end_per_group.423972.html =group_props [{name,standard_io},parallel] -=started 2024-09-11 11:25:45 -=ended 2024-09-11 11:25:45 +=started 2024-09-12 10:47:57 +=ended 2024-09-12 10:47:57 =result ok -=elapsed 0.0 -=group_time 3.546s +=elapsed 1.0e-6 +=group_time 3.585s =case peer_SUITE:init_per_group -=logfile peer_suite.init_per_group.376037.html +=logfile peer_suite.init_per_group.424004.html =group_props [{name,compatibility},parallel] -=started 2024-09-11 11:25:45 -=ended 2024-09-11 11:25:46 +=started 2024-09-12 10:47:57 +=ended 2024-09-12 10:47:57 =result ok =elapsed 0.0 =case peer_SUITE:old_release -=logfile peer_suite.old_release.376069.html -=started 2024-09-11 11:25:46 -=ended 2024-09-11 11:25:59 +=logfile peer_suite.old_release.424036.html +=started 2024-09-12 10:47:57 +=ended 2024-09-12 10:48:10 =result ok -=elapsed 13.517974 +=elapsed 13.533671 =case peer_SUITE:end_per_group -=logfile peer_suite.end_per_group.376133.html +=logfile peer_suite.end_per_group.424132.html =group_props [{name,compatibility},parallel] -=started 2024-09-11 11:25:59 -=ended 2024-09-11 11:25:59 +=started 2024-09-12 10:48:10 +=ended 2024-09-12 10:48:10 =result ok =elapsed 0.0 -=group_time 13.564s +=group_time 13.579s =case peer_SUITE:init_per_group -=logfile peer_suite.init_per_group.376165.html +=logfile peer_suite.init_per_group.424164.html =group_props [{name,remote},parallel] -=started 2024-09-11 11:25:59 -=ended 2024-09-11 11:25:59 +=started 2024-09-12 10:48:10 +=ended 2024-09-12 10:48:10 =result skipped: "'ssh localhost echo ok' did not return ok" === *** SKIPPED {peer_SUITE,init_per_group} *** === =case peer_SUITE:ssh =group_props [{name,"remote"}] -=started 2024-09-11 11:25:59 +=started 2024-09-12 10:48:10 =result skipped: 'ssh localhost echo ok' did not return ok === *** Skipping test case #1450 {peer_SUITE,ssh} *** === =case peer_SUITE:end_per_group =group_props [{name,"remote"}] -=started 2024-09-11 11:25:59 +=started 2024-09-12 10:48:10 =result skipped: 'ssh localhost echo ok' did not return ok === *** Skipping {peer_SUITE,end_per_group} *** =case peer_SUITE:end_per_suite =logfile peer_suite.end_per_suite.html -=started 2024-09-11 11:25:59 -=ended 2024-09-11 11:25:59 +=started 2024-09-12 10:48:11 +=ended 2024-09-12 10:48:11 =result ok -=elapsed 2.0e-6 -=group_time 36.525s +=elapsed 3.0e-6 +=group_time 36.412s =case pool_SUITE:init_per_suite =logfile pool_suite.init_per_suite.html -=started 2024-09-11 11:25:59 -=ended 2024-09-11 11:25:59 +=started 2024-09-12 10:48:11 +=ended 2024-09-12 10:48:11 =result ok =elapsed 0.0 =case pool_SUITE:basic =logfile pool_suite.basic.html -=started 2024-09-11 11:25:59 -=ended 2024-09-11 11:25:59 +=started 2024-09-12 10:48:11 +=ended 2024-09-12 10:48:11 =result ok -=elapsed 0.167007 +=elapsed 0.162309 =case pool_SUITE:link_race =logfile pool_suite.link_race.html -=started 2024-09-11 11:25:59 -=ended 2024-09-11 11:26:00 +=started 2024-09-12 10:48:11 +=ended 2024-09-12 10:48:11 =result ok -=elapsed 0.315718 +=elapsed 0.344808 =case pool_SUITE:end_per_suite =logfile pool_suite.end_per_suite.html -=started 2024-09-11 11:26:00 -=ended 2024-09-11 11:26:00 +=started 2024-09-12 10:48:11 +=ended 2024-09-12 10:48:11 =result ok =elapsed 0.0 -=group_time 0.562s +=group_time 0.587s =case proc_lib_SUITE:init_per_suite =logfile proc_lib_suite.init_per_suite.html -=started 2024-09-11 11:26:00 -=ended 2024-09-11 11:26:00 +=started 2024-09-12 10:48:11 +=ended 2024-09-12 10:48:11 =result ok =elapsed 0.0 =case proc_lib_SUITE:crash =logfile proc_lib_suite.crash.html -=started 2024-09-11 11:26:00 -=ended 2024-09-11 11:26:00 +=started 2024-09-12 10:48:11 +=ended 2024-09-12 10:48:11 =result ok -=elapsed 0.208603 +=elapsed 0.208817 =case proc_lib_SUITE:stacktrace =logfile proc_lib_suite.stacktrace.html -=started 2024-09-11 11:26:00 -=ended 2024-09-11 11:26:00 +=started 2024-09-12 10:48:11 +=ended 2024-09-12 10:48:11 =result ok -=elapsed 0.001364 +=elapsed 0.001416 =case proc_lib_SUITE:init_per_group =logfile proc_lib_suite.init_per_group.html =group_props [{name,sync_start}] -=started 2024-09-11 11:26:00 -=ended 2024-09-11 11:26:00 +=started 2024-09-12 10:48:11 +=ended 2024-09-12 10:48:11 =result ok =elapsed 0.0 =case proc_lib_SUITE:sync_start_nolink =logfile proc_lib_suite.sync_start_nolink.html -=started 2024-09-11 11:26:00 -=ended 2024-09-11 11:26:01 +=started 2024-09-12 10:48:11 +=ended 2024-09-12 10:48:12 =result ok -=elapsed 1.00013 +=elapsed 1.000938 =case proc_lib_SUITE:sync_start_link =logfile proc_lib_suite.sync_start_link.html -=started 2024-09-11 11:26:01 -=ended 2024-09-11 11:26:02 +=started 2024-09-12 10:48:12 +=ended 2024-09-12 10:48:13 =result ok -=elapsed 1.001089 +=elapsed 1.000816 =case proc_lib_SUITE:sync_start_monitor =logfile proc_lib_suite.sync_start_monitor.html -=started 2024-09-11 11:26:02 -=ended 2024-09-11 11:26:04 +=started 2024-09-12 10:48:13 +=ended 2024-09-12 10:48:16 =result ok -=elapsed 2.002061 +=elapsed 2.001741 =case proc_lib_SUITE:sync_start_monitor_link =logfile proc_lib_suite.sync_start_monitor_link.html -=started 2024-09-11 11:26:04 -=ended 2024-09-11 11:26:05 +=started 2024-09-12 10:48:16 +=ended 2024-09-12 10:48:17 =result ok -=elapsed 1.000749 +=elapsed 1.000389 =case proc_lib_SUITE:sync_start_timeout =logfile proc_lib_suite.sync_start_timeout.html -=started 2024-09-11 11:26:05 -=ended 2024-09-11 11:26:06 +=started 2024-09-12 10:48:17 +=ended 2024-09-12 10:48:18 =result ok -=elapsed 1.002101 +=elapsed 1.002078 =case proc_lib_SUITE:sync_start_link_timeout =logfile proc_lib_suite.sync_start_link_timeout.html -=started 2024-09-11 11:26:06 -=ended 2024-09-11 11:26:07 +=started 2024-09-12 10:48:18 +=ended 2024-09-12 10:48:19 =result ok -=elapsed 1.001675 +=elapsed 1.001637 =case proc_lib_SUITE:sync_start_monitor_link_timeout =logfile proc_lib_suite.sync_start_monitor_link_timeout.html -=started 2024-09-11 11:26:07 -=ended 2024-09-11 11:26:08 +=started 2024-09-12 10:48:19 +=ended 2024-09-12 10:48:20 =result ok -=elapsed 1.001887 +=elapsed 1.00185 =case proc_lib_SUITE:end_per_group =logfile proc_lib_suite.end_per_group.html =group_props [{name,sync_start}] -=started 2024-09-11 11:26:08 -=ended 2024-09-11 11:26:08 +=started 2024-09-12 10:48:20 +=ended 2024-09-12 10:48:20 =result ok =elapsed 0.0 -=group_time 8.193s +=group_time 8.195s =case proc_lib_SUITE:spawn_opt =logfile proc_lib_suite.spawn_opt.html -=started 2024-09-11 11:26:08 -=ended 2024-09-11 11:26:08 +=started 2024-09-12 10:48:20 +=ended 2024-09-12 10:48:20 =result ok -=elapsed 0.101067 +=elapsed 0.100613 =case proc_lib_SUITE:hibernate =logfile proc_lib_suite.hibernate.html -=started 2024-09-11 11:26:08 -=ended 2024-09-11 11:26:08 +=started 2024-09-12 10:48:20 +=ended 2024-09-12 10:48:20 =result ok -=elapsed 6.77e-4 +=elapsed 5.94e-4 =case proc_lib_SUITE:init_per_group -=logfile proc_lib_suite.init_per_group.482370.html +=logfile proc_lib_suite.init_per_group.424292.html =group_props [{name,tickets}] -=started 2024-09-11 11:26:08 -=ended 2024-09-11 11:26:08 +=started 2024-09-12 10:48:20 +=ended 2024-09-12 10:48:20 =result ok =elapsed 0.0 =case proc_lib_SUITE:otp_6345 =logfile proc_lib_suite.otp_6345.html -=started 2024-09-11 11:26:08 -=ended 2024-09-11 11:26:08 +=started 2024-09-12 10:48:20 +=ended 2024-09-12 10:48:20 =result ok =elapsed 1.0e-6 =case proc_lib_SUITE:init_dont_hang =logfile proc_lib_suite.init_dont_hang.html -=started 2024-09-11 11:26:08 -=ended 2024-09-11 11:26:08 +=started 2024-09-12 10:48:20 +=ended 2024-09-12 10:48:20 =result ok -=elapsed 0.001355 +=elapsed 0.001153 =case proc_lib_SUITE:end_per_group -=logfile proc_lib_suite.end_per_group.482402.html +=logfile proc_lib_suite.end_per_group.424324.html =group_props [{name,tickets}] -=started 2024-09-11 11:26:08 -=ended 2024-09-11 11:26:08 +=started 2024-09-12 10:48:20 +=ended 2024-09-12 10:48:20 =result ok =elapsed 0.0 -=group_time 0.069s +=group_time 0.070s =case proc_lib_SUITE:stop =logfile proc_lib_suite.stop.html -=started 2024-09-11 11:26:08 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:20 +=ended 2024-09-12 10:48:26 =result ok -=elapsed 6.157731 +=elapsed 6.166278 =case proc_lib_SUITE:t_format =logfile proc_lib_suite.t_format.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:26 +=ended 2024-09-12 10:48:26 =result ok -=elapsed 0.004103 +=elapsed 0.004174 =case proc_lib_SUITE:t_format_arbitrary =logfile proc_lib_suite.t_format_arbitrary.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:26 +=ended 2024-09-12 10:48:26 =result ok -=elapsed 7.99e-4 +=elapsed 8.2e-4 =case proc_lib_SUITE:report_cb =logfile proc_lib_suite.report_cb.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:26 +=ended 2024-09-12 10:48:26 =result ok -=elapsed 0.10318 +=elapsed 0.103424 =case proc_lib_SUITE:end_per_suite =logfile proc_lib_suite.end_per_suite.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:26 +=ended 2024-09-12 10:48:26 =result ok =elapsed 0.0 -=group_time 15.100s +=group_time 15.120s =case proplists_SUITE:init_per_suite =logfile proplists_suite.init_per_suite.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:26 +=ended 2024-09-12 10:48:26 =result ok =elapsed 0.0 =case proplists_SUITE:examples =logfile proplists_suite.examples.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:26 +=ended 2024-09-12 10:48:26 =result ok -=elapsed 9.0e-6 +=elapsed 8.0e-6 =case proplists_SUITE:map_conversion =logfile proplists_suite.map_conversion.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:26 +=ended 2024-09-12 10:48:26 =result ok -=elapsed 0.031149 +=elapsed 0.031446 =case proplists_SUITE:map_conversion_normalize =logfile proplists_suite.map_conversion_normalize.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:26 +=ended 2024-09-12 10:48:26 =result ok -=elapsed 3.0e-6 +=elapsed 4.0e-6 =case proplists_SUITE:pm_fold_test =logfile proplists_suite.pm_fold_test.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:26 +=ended 2024-09-12 10:48:26 =result ok -=elapsed 3.0e-6 +=elapsed 2.0e-6 =case proplists_SUITE:end_per_suite =logfile proplists_suite.end_per_suite.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:26 +=ended 2024-09-12 10:48:26 =result ok =elapsed 0.0 -=group_time 0.156s +=group_time 0.154s =case qlc_SUITE:init_per_suite =logfile qlc_suite.init_per_suite.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:26 +=ended 2024-09-12 10:48:27 =result ok =elapsed 0.0 =case qlc_SUITE:init_per_group =logfile qlc_suite.init_per_group.html =group_props [{name,parse_transform}] -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:27 =result ok =elapsed 0.0 =case qlc_SUITE:badarg =logfile qlc_suite.badarg.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:27 =result ok -=elapsed 0.00451 +=elapsed 0.004457 =case qlc_SUITE:nested_qlc =logfile qlc_suite.nested_qlc.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:27 =result ok -=elapsed 0.094589 +=elapsed 0.093373 =case qlc_SUITE:unused_var =logfile qlc_suite.unused_var.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:27 =result ok -=elapsed 0.026396 +=elapsed 0.025706 =case qlc_SUITE:lc =logfile qlc_suite.lc.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:27 =result ok -=elapsed 0.00517 +=elapsed 0.004656 =case qlc_SUITE:fun_clauses =logfile qlc_suite.fun_clauses.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:27 =result ok -=elapsed 0.010763 +=elapsed 0.009945 =case qlc_SUITE:filter_var =logfile qlc_suite.filter_var.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:27 =result ok -=elapsed 0.021485 +=elapsed 0.020633 =case qlc_SUITE:single =logfile qlc_suite.single.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:15 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:27 =result ok -=elapsed 0.033889 +=elapsed 0.033115 =case qlc_SUITE:exported_var =logfile qlc_suite.exported_var.html -=started 2024-09-11 11:26:15 -=ended 2024-09-11 11:26:16 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:27 =result ok -=elapsed 0.006599 +=elapsed 0.006398 =case qlc_SUITE:generator_vars =logfile qlc_suite.generator_vars.html -=started 2024-09-11 11:26:16 -=ended 2024-09-11 11:26:16 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:27 =result ok -=elapsed 0.004943 +=elapsed 0.005147 =case qlc_SUITE:nomatch =logfile qlc_suite.nomatch.html -=started 2024-09-11 11:26:16 -=ended 2024-09-11 11:26:16 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:27 =result ok -=elapsed 0.121491 +=elapsed 0.126846 =case qlc_SUITE:errors =logfile qlc_suite.errors.html -=started 2024-09-11 11:26:16 -=ended 2024-09-11 11:26:16 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:27 =result ok -=elapsed 0.001297 +=elapsed 0.001816 =case qlc_SUITE:pattern =logfile qlc_suite.pattern.html -=started 2024-09-11 11:26:16 -=ended 2024-09-11 11:26:16 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:27 =result ok -=elapsed 0.089117 +=elapsed 0.091693 =case qlc_SUITE:overridden_bif =logfile qlc_suite.overridden_bif.html -=started 2024-09-11 11:26:16 -=ended 2024-09-11 11:26:16 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:27 =result ok -=elapsed 0.075887 +=elapsed 0.077554 =case qlc_SUITE:end_per_group =logfile qlc_suite.end_per_group.html =group_props [{name,parse_transform}] -=started 2024-09-11 11:26:16 -=ended 2024-09-11 11:26:16 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:27 =result ok =elapsed 0.0 -=group_time 0.815s +=group_time 0.821s =case qlc_SUITE:init_per_group -=logfile qlc_suite.init_per_group.501571.html +=logfile qlc_suite.init_per_group.424420.html =group_props [{name,evaluation}] -=started 2024-09-11 11:26:16 -=ended 2024-09-11 11:26:16 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:27 =result ok =elapsed 0.0 =case qlc_SUITE:eval =logfile qlc_suite.eval.html -=started 2024-09-11 11:26:16 -=ended 2024-09-11 11:26:17 +=started 2024-09-12 10:48:27 +=ended 2024-09-12 10:48:28 =result ok -=elapsed 0.776341 +=elapsed 0.774786 =case qlc_SUITE:cursor =logfile qlc_suite.cursor.html -=started 2024-09-11 11:26:17 -=ended 2024-09-11 11:26:17 +=started 2024-09-12 10:48:28 +=ended 2024-09-12 10:48:29 =result ok -=elapsed 0.497101 +=elapsed 0.501077 =case qlc_SUITE:fold =logfile qlc_suite.fold.html -=started 2024-09-11 11:26:17 -=ended 2024-09-11 11:26:18 +=started 2024-09-12 10:48:29 +=ended 2024-09-12 10:48:29 =result ok -=elapsed 0.525771 +=elapsed 0.532166 =case qlc_SUITE:eval_unique =logfile qlc_suite.eval_unique.html -=started 2024-09-11 11:26:18 -=ended 2024-09-11 11:26:18 +=started 2024-09-12 10:48:29 +=ended 2024-09-12 10:48:30 =result ok -=elapsed 0.595215 +=elapsed 0.616412 =case qlc_SUITE:eval_cache =logfile qlc_suite.eval_cache.html -=started 2024-09-11 11:26:18 -=ended 2024-09-11 11:26:19 +=started 2024-09-12 10:48:30 +=ended 2024-09-12 10:48:30 =result ok -=elapsed 0.563185 +=elapsed 0.58306 =case qlc_SUITE:append =logfile qlc_suite.append.html -=started 2024-09-11 11:26:19 -=ended 2024-09-11 11:26:20 +=started 2024-09-12 10:48:30 +=ended 2024-09-12 10:48:31 =result ok -=elapsed 0.63659 +=elapsed 0.662879 =case qlc_SUITE:evaluator =logfile qlc_suite.evaluator.html -=started 2024-09-11 11:26:20 -=ended 2024-09-11 11:26:20 +=started 2024-09-12 10:48:31 +=ended 2024-09-12 10:48:31 =result ok -=elapsed 0.208414 +=elapsed 0.201045 =case qlc_SUITE:string_to_handle =logfile qlc_suite.string_to_handle.html -=started 2024-09-11 11:26:20 -=ended 2024-09-11 11:26:20 +=started 2024-09-12 10:48:31 +=ended 2024-09-12 10:48:31 =result ok -=elapsed 0.029869 +=elapsed 0.029838 =case qlc_SUITE:table =logfile qlc_suite.table.html -=started 2024-09-11 11:26:20 -=ended 2024-09-11 11:26:21 +=started 2024-09-12 10:48:31 +=ended 2024-09-12 10:48:33 =result ok -=elapsed 1.09383 +=elapsed 1.115173 =case qlc_SUITE:process_dies =logfile qlc_suite.process_dies.html -=started 2024-09-11 11:26:21 -=ended 2024-09-11 11:26:22 +=started 2024-09-12 10:48:33 +=ended 2024-09-12 10:48:33 =result ok -=elapsed 0.47078 +=elapsed 0.473448 =case qlc_SUITE:sort =logfile qlc_suite.sort.html -=started 2024-09-11 11:26:22 -=ended 2024-09-11 11:26:22 +=started 2024-09-12 10:48:33 +=ended 2024-09-12 10:48:34 =result ok -=elapsed 0.5547 +=elapsed 0.571845 =case qlc_SUITE:keysort =logfile qlc_suite.keysort.html -=started 2024-09-11 11:26:22 -=ended 2024-09-11 11:26:23 +=started 2024-09-12 10:48:34 +=ended 2024-09-12 10:48:34 =result ok -=elapsed 0.747593 +=elapsed 0.753342 =case qlc_SUITE:filesort =logfile qlc_suite.filesort.html -=started 2024-09-11 11:26:23 -=ended 2024-09-11 11:26:23 +=started 2024-09-12 10:48:34 +=ended 2024-09-12 10:48:35 =result ok -=elapsed 0.044581 +=elapsed 0.044002 =case qlc_SUITE:cache =logfile qlc_suite.cache.html -=started 2024-09-11 11:26:23 -=ended 2024-09-11 11:26:24 +=started 2024-09-12 10:48:35 +=ended 2024-09-12 10:48:36 =result ok -=elapsed 0.955187 +=elapsed 0.971337 =case qlc_SUITE:cache_list =logfile qlc_suite.cache_list.html -=started 2024-09-11 11:26:24 -=ended 2024-09-11 11:26:28 +=started 2024-09-12 10:48:36 +=ended 2024-09-12 10:48:39 =result ok -=elapsed 3.691339 +=elapsed 3.678468 =case qlc_SUITE:filter =logfile qlc_suite.filter.html -=started 2024-09-11 11:26:28 -=ended 2024-09-11 11:26:29 +=started 2024-09-12 10:48:39 +=ended 2024-09-12 10:48:40 =result ok -=elapsed 0.888083 +=elapsed 0.908489 =case qlc_SUITE:info =logfile qlc_suite.info.html -=started 2024-09-11 11:26:29 -=ended 2024-09-11 11:26:30 +=started 2024-09-12 10:48:40 +=ended 2024-09-12 10:48:42 =result ok -=elapsed 1.339163 +=elapsed 1.382494 =case qlc_SUITE:nested_info =logfile qlc_suite.nested_info.html -=started 2024-09-11 11:26:30 -=ended 2024-09-11 11:26:31 +=started 2024-09-12 10:48:42 +=ended 2024-09-12 10:48:42 =result ok -=elapsed 0.515691 +=elapsed 0.527751 =case qlc_SUITE:lookup1 =logfile qlc_suite.lookup1.html -=started 2024-09-11 11:26:31 -=ended 2024-09-11 11:26:32 +=started 2024-09-12 10:48:42 +=ended 2024-09-12 10:48:43 =result ok -=elapsed 1.346505 +=elapsed 1.338784 =case qlc_SUITE:lookup2 =logfile qlc_suite.lookup2.html -=started 2024-09-11 11:26:32 -=ended 2024-09-11 11:26:36 +=started 2024-09-12 10:48:43 +=ended 2024-09-12 10:48:48 =result ok -=elapsed 4.042518 +=elapsed 4.140132 =case qlc_SUITE:lookup_rec =logfile qlc_suite.lookup_rec.html -=started 2024-09-11 11:26:36 -=ended 2024-09-11 11:26:36 +=started 2024-09-12 10:48:48 +=ended 2024-09-12 10:48:48 =result ok -=elapsed 0.389201 +=elapsed 0.391752 =case qlc_SUITE:indices =logfile qlc_suite.indices.html -=started 2024-09-11 11:26:36 -=ended 2024-09-11 11:26:37 +=started 2024-09-12 10:48:48 +=ended 2024-09-12 10:48:48 =result ok -=elapsed 0.390238 +=elapsed 0.389029 =case qlc_SUITE:pre_fun =logfile qlc_suite.pre_fun.html -=started 2024-09-11 11:26:37 -=ended 2024-09-11 11:26:37 +=started 2024-09-12 10:48:48 +=ended 2024-09-12 10:48:49 =result ok -=elapsed 0.323822 +=elapsed 0.3219 =case qlc_SUITE:skip_filters =logfile qlc_suite.skip_filters.html -=started 2024-09-11 11:26:37 -=ended 2024-09-11 11:26:39 +=started 2024-09-12 10:48:49 +=ended 2024-09-12 10:48:51 =result ok -=elapsed 2.236827 +=elapsed 2.276143 =case qlc_SUITE:eep37 =logfile qlc_suite.eep37.html -=started 2024-09-11 11:26:39 -=ended 2024-09-11 11:26:39 +=started 2024-09-12 10:48:51 +=ended 2024-09-12 10:48:51 =result ok -=elapsed 0.021113 +=elapsed 0.021438 =case qlc_SUITE:end_per_group -=logfile qlc_suite.end_per_group.398148.html +=logfile qlc_suite.end_per_group.425124.html =group_props [{name,evaluation}] -=started 2024-09-11 11:26:39 -=ended 2024-09-11 11:26:39 +=started 2024-09-12 10:48:51 +=ended 2024-09-12 10:48:51 =result ok =elapsed 0.0 -=group_time 23.495s +=group_time 23.814s =case qlc_SUITE:init_per_group -=logfile qlc_suite.init_per_group.483522.html +=logfile qlc_suite.init_per_group.425156.html =group_props [{name,table_impls}] -=started 2024-09-11 11:26:39 -=ended 2024-09-11 11:26:39 +=started 2024-09-12 10:48:51 +=ended 2024-09-12 10:48:51 =result ok =elapsed 0.0 =case qlc_SUITE:ets =logfile qlc_suite.ets.html -=started 2024-09-11 11:26:39 -=ended 2024-09-11 11:26:40 +=started 2024-09-12 10:48:51 +=ended 2024-09-12 10:48:52 =result ok -=elapsed 0.376452 +=elapsed 0.37762 =case qlc_SUITE:dets =logfile qlc_suite.dets.html -=started 2024-09-11 11:26:40 -=ended 2024-09-11 11:26:41 +=started 2024-09-12 10:48:52 +=ended 2024-09-12 10:48:52 =result ok -=elapsed 0.597839 +=elapsed 0.598526 =case qlc_SUITE:end_per_group -=logfile qlc_suite.end_per_group.501987.html +=logfile qlc_suite.end_per_group.425188.html =group_props [{name,table_impls}] -=started 2024-09-11 11:26:41 -=ended 2024-09-11 11:26:41 +=started 2024-09-12 10:48:52 +=ended 2024-09-12 10:48:52 =result ok =elapsed 0.0 -=group_time 1.043s +=group_time 1.050s =case qlc_SUITE:init_per_group -=logfile qlc_suite.init_per_group.502019.html +=logfile qlc_suite.init_per_group.425220.html =group_props [{name,join}] -=started 2024-09-11 11:26:41 -=ended 2024-09-11 11:26:41 +=started 2024-09-12 10:48:52 +=ended 2024-09-12 10:48:52 =result ok =elapsed 0.0 =case qlc_SUITE:join_option =logfile qlc_suite.join_option.html -=started 2024-09-11 11:26:41 -=ended 2024-09-11 11:26:42 +=started 2024-09-12 10:48:52 +=ended 2024-09-12 10:48:53 =result ok -=elapsed 1.13848 +=elapsed 1.153995 =case qlc_SUITE:join_filter =logfile qlc_suite.join_filter.html -=started 2024-09-11 11:26:42 -=ended 2024-09-11 11:26:42 +=started 2024-09-12 10:48:53 +=ended 2024-09-12 10:48:54 =result ok -=elapsed 0.297754 +=elapsed 0.29796 =case qlc_SUITE:join_lookup =logfile qlc_suite.join_lookup.html -=started 2024-09-11 11:26:42 -=ended 2024-09-11 11:26:43 +=started 2024-09-12 10:48:54 +=ended 2024-09-12 10:48:54 =result ok -=elapsed 0.636987 +=elapsed 0.65111 =case qlc_SUITE:join_merge =logfile qlc_suite.join_merge.html -=started 2024-09-11 11:26:43 -=ended 2024-09-11 11:26:48 +=started 2024-09-12 10:48:54 +=ended 2024-09-12 10:49:00 =result ok -=elapsed 4.849977 +=elapsed 5.052906 =case qlc_SUITE:join_sort =logfile qlc_suite.join_sort.html -=started 2024-09-11 11:26:48 -=ended 2024-09-11 11:26:50 +=started 2024-09-12 10:49:00 +=ended 2024-09-12 10:49:02 =result ok -=elapsed 2.681606 +=elapsed 2.723835 =case qlc_SUITE:join_complex =logfile qlc_suite.join_complex.html -=started 2024-09-11 11:26:50 -=ended 2024-09-11 11:26:51 +=started 2024-09-12 10:49:02 +=ended 2024-09-12 10:49:03 =result ok -=elapsed 0.304961 +=elapsed 0.307578 =case qlc_SUITE:end_per_group -=logfile qlc_suite.end_per_group.483586.html +=logfile qlc_suite.end_per_group.407043.html =group_props [{name,join}] -=started 2024-09-11 11:26:51 -=ended 2024-09-11 11:26:51 +=started 2024-09-12 10:49:03 +=ended 2024-09-12 10:49:03 =result ok =elapsed 0.0 -=group_time 10.072s +=group_time 10.351s =case qlc_SUITE:init_per_group -=logfile qlc_suite.init_per_group.483618.html +=logfile qlc_suite.init_per_group.407075.html =group_props [{name,tickets}] -=started 2024-09-11 11:26:51 -=ended 2024-09-11 11:26:51 +=started 2024-09-12 10:49:03 +=ended 2024-09-12 10:49:03 =result ok =elapsed 0.0 =case qlc_SUITE:otp_5644 =logfile qlc_suite.otp_5644.html -=started 2024-09-11 11:26:51 -=ended 2024-09-11 11:26:51 +=started 2024-09-12 10:49:03 +=ended 2024-09-12 10:49:03 =result ok -=elapsed 0.029431 +=elapsed 0.031536 =case qlc_SUITE:otp_5195 =logfile qlc_suite.otp_5195.html -=started 2024-09-11 11:26:51 -=ended 2024-09-11 11:26:51 +=started 2024-09-12 10:49:03 +=ended 2024-09-12 10:49:03 =result ok -=elapsed 0.471715 +=elapsed 0.485934 =case qlc_SUITE:otp_6038_bug =logfile qlc_suite.otp_6038_bug.html -=started 2024-09-11 11:26:51 -=ended 2024-09-11 11:26:52 +=started 2024-09-12 10:49:03 +=ended 2024-09-12 10:49:04 =result ok -=elapsed 0.320536 +=elapsed 0.316641 =case qlc_SUITE:otp_6359 =logfile qlc_suite.otp_6359.html -=started 2024-09-11 11:26:52 -=ended 2024-09-11 11:26:52 +=started 2024-09-12 10:49:04 +=ended 2024-09-12 10:49:04 =result ok -=elapsed 0.041316 +=elapsed 0.041721 =case qlc_SUITE:otp_6562 =logfile qlc_suite.otp_6562.html -=started 2024-09-11 11:26:52 -=ended 2024-09-11 11:26:52 +=started 2024-09-12 10:49:04 +=ended 2024-09-12 10:49:04 =result ok -=elapsed 0.309807 +=elapsed 0.32607 =case qlc_SUITE:otp_6590 =logfile qlc_suite.otp_6590.html -=started 2024-09-11 11:26:52 -=ended 2024-09-11 11:26:52 +=started 2024-09-12 10:49:04 +=ended 2024-09-12 10:49:04 =result ok -=elapsed 0.068593 +=elapsed 0.071389 =case qlc_SUITE:otp_6673 =logfile qlc_suite.otp_6673.html -=started 2024-09-11 11:26:52 -=ended 2024-09-11 11:26:52 +=started 2024-09-12 10:49:04 +=ended 2024-09-12 10:49:05 =result ok -=elapsed 0.412448 +=elapsed 0.42114 =case qlc_SUITE:otp_6964 =logfile qlc_suite.otp_6964.html -=started 2024-09-11 11:26:52 -=ended 2024-09-11 11:26:53 +=started 2024-09-12 10:49:05 +=ended 2024-09-12 10:49:06 =result ok -=elapsed 1.000081 +=elapsed 1.010481 =case qlc_SUITE:otp_7114 =logfile qlc_suite.otp_7114.html -=started 2024-09-11 11:26:53 -=ended 2024-09-11 11:26:54 +=started 2024-09-12 10:49:06 +=ended 2024-09-12 10:49:06 =result ok -=elapsed 0.043648 +=elapsed 0.042809 =case qlc_SUITE:otp_7232 =logfile qlc_suite.otp_7232.html -=started 2024-09-11 11:26:54 -=ended 2024-09-11 11:26:54 +=started 2024-09-12 10:49:06 +=ended 2024-09-12 10:49:06 =result ok -=elapsed 0.143922 +=elapsed 0.137451 =case qlc_SUITE:otp_7238 =logfile qlc_suite.otp_7238.html -=started 2024-09-11 11:26:54 -=ended 2024-09-11 11:26:55 +=started 2024-09-12 10:49:06 +=ended 2024-09-12 10:49:07 =result ok -=elapsed 1.203805 +=elapsed 1.216619 =case qlc_SUITE:otp_7552 =logfile qlc_suite.otp_7552.html -=started 2024-09-11 11:26:55 -=ended 2024-09-11 11:26:55 +=started 2024-09-12 10:49:07 +=ended 2024-09-12 10:49:07 =result ok -=elapsed 0.108216 +=elapsed 0.109118 =case qlc_SUITE:otp_6674 =logfile qlc_suite.otp_6674.html -=started 2024-09-11 11:26:55 -=ended 2024-09-11 11:26:58 +=started 2024-09-12 10:49:07 +=ended 2024-09-12 10:49:10 =result ok -=elapsed 2.849935 +=elapsed 2.916482 =case qlc_SUITE:otp_7714 =logfile qlc_suite.otp_7714.html -=started 2024-09-11 11:26:58 -=ended 2024-09-11 11:26:58 +=started 2024-09-12 10:49:10 +=ended 2024-09-12 10:49:10 =result ok -=elapsed 0.083095 +=elapsed 0.084191 =case qlc_SUITE:otp_11758 =logfile qlc_suite.otp_11758.html -=started 2024-09-11 11:26:58 -=ended 2024-09-11 11:26:58 +=started 2024-09-12 10:49:10 +=ended 2024-09-12 10:49:10 =result ok -=elapsed 0.050039 +=elapsed 0.047872 =case qlc_SUITE:otp_12946 =logfile qlc_suite.otp_12946.html -=started 2024-09-11 11:26:58 -=ended 2024-09-11 11:26:58 +=started 2024-09-12 10:49:10 +=ended 2024-09-12 10:49:10 =result ok -=elapsed 0.011818 +=elapsed 0.01269 =case qlc_SUITE:end_per_group -=logfile qlc_suite.end_per_group.502531.html +=logfile qlc_suite.end_per_group.425508.html =group_props [{name,tickets}] -=started 2024-09-11 11:26:58 -=ended 2024-09-11 11:26:58 +=started 2024-09-12 10:49:10 +=ended 2024-09-12 10:49:10 =result ok =elapsed 0.0 -=group_time 7.543s +=group_time 7.667s =case qlc_SUITE:manpage =logfile qlc_suite.manpage.html -=started 2024-09-11 11:26:58 -=ended 2024-09-11 11:26:59 +=started 2024-09-12 10:49:10 +=ended 2024-09-12 10:49:11 =result ok -=elapsed 0.641892 +=elapsed 0.652283 =case qlc_SUITE:init_per_group -=logfile qlc_suite.init_per_group.484034.html +=logfile qlc_suite.init_per_group.425540.html =group_props [{name,compat}] -=started 2024-09-11 11:26:59 -=ended 2024-09-11 11:26:59 +=started 2024-09-12 10:49:11 +=ended 2024-09-12 10:49:11 =result ok =elapsed 0.0 =case qlc_SUITE:backward =logfile qlc_suite.backward.html -=started 2024-09-11 11:26:59 -=ended 2024-09-11 11:26:59 +=started 2024-09-12 10:49:11 +=ended 2024-09-12 10:49:11 =result ok -=elapsed 0.057602 +=elapsed 0.060296 =case qlc_SUITE:forward =logfile qlc_suite.forward.html -=started 2024-09-11 11:26:59 -=ended 2024-09-11 11:26:59 +=started 2024-09-12 10:49:11 +=ended 2024-09-12 10:49:11 =result ok -=elapsed 0.051889 +=elapsed 0.055322 =case qlc_SUITE:end_per_group -=logfile qlc_suite.end_per_group.502563.html +=logfile qlc_suite.end_per_group.499938.html =group_props [{name,compat}] -=started 2024-09-11 11:26:59 -=ended 2024-09-11 11:26:59 +=started 2024-09-12 10:49:11 +=ended 2024-09-12 10:49:11 =result ok =elapsed 0.0 -=group_time 0.179s +=group_time 0.184s =case qlc_SUITE:end_per_suite =logfile qlc_suite.end_per_suite.html -=started 2024-09-11 11:26:59 -=ended 2024-09-11 11:26:59 +=started 2024-09-12 10:49:11 +=ended 2024-09-12 10:49:11 =result ok =elapsed 0.0 -=group_time 44.004s +=group_time 44.748s =case queue_SUITE:init_per_suite =logfile queue_suite.init_per_suite.html -=started 2024-09-11 11:26:59 -=ended 2024-09-11 11:26:59 +=started 2024-09-12 10:49:11 +=ended 2024-09-12 10:49:11 =result ok =elapsed 0.0 =case queue_SUITE:do =logfile queue_suite.do.html -=started 2024-09-11 11:26:59 -=ended 2024-09-11 11:26:59 +=started 2024-09-12 10:49:11 +=ended 2024-09-12 10:49:11 =result ok =elapsed 3.0e-6 =case queue_SUITE:to_list =logfile queue_suite.to_list.html -=started 2024-09-11 11:26:59 -=ended 2024-09-11 11:26:59 +=started 2024-09-12 10:49:11 +=ended 2024-09-12 10:49:11 =result ok -=elapsed 1.0e-6 +=elapsed 2.0e-6 =case queue_SUITE:io_test =logfile queue_suite.io_test.html -=started 2024-09-11 11:26:59 -=ended 2024-09-11 11:26:59 +=started 2024-09-12 10:49:11 +=ended 2024-09-12 10:49:11 =result ok -=elapsed 6.8e-5 +=elapsed 8.9e-5 =case queue_SUITE:op_test =logfile queue_suite.op_test.html -=started 2024-09-11 11:26:59 -=ended 2024-09-11 11:26:59 +=started 2024-09-12 10:49:11 +=ended 2024-09-12 10:49:11 =result ok -=elapsed 4.9e-5 +=elapsed 6.0e-5 =case queue_SUITE:error =logfile queue_suite.error.html -=started 2024-09-11 11:26:59 -=ended 2024-09-11 11:26:59 +=started 2024-09-12 10:49:11 +=ended 2024-09-12 10:49:11 =result ok -=elapsed 1.43e-4 +=elapsed 1.19e-4 =case queue_SUITE:oops =logfile queue_suite.oops.html -=started 2024-09-11 11:26:59 -=ended 2024-09-11 11:26:59 +=started 2024-09-12 10:49:11 +=ended 2024-09-12 10:49:12 =result ok -=elapsed 0.15178 +=elapsed 0.164248 =case queue_SUITE:end_per_suite =logfile queue_suite.end_per_suite.html -=started 2024-09-11 11:26:59 -=ended 2024-09-11 11:26:59 +=started 2024-09-12 10:49:12 +=ended 2024-09-12 10:49:12 =result ok =elapsed 0.0 -=group_time 0.325s +=group_time 0.342s =case queue_property_test_SUITE:init_per_suite =logfile queue_property_test_suite.init_per_suite.html -=started 2024-09-11 11:26:59 -=ended 2024-09-11 11:27:01 +=started 2024-09-12 10:49:12 +=ended 2024-09-12 10:49:13 =result ok -=elapsed 1.275813 +=elapsed 1.261506 =case queue_property_test_SUITE:new_case =logfile queue_property_test_suite.new_case.html -=started 2024-09-11 11:27:01 -=ended 2024-09-11 11:27:01 +=started 2024-09-12 10:49:13 +=ended 2024-09-12 10:49:13 =result ok -=elapsed 0.001255 +=elapsed 0.001319 =case queue_property_test_SUITE:is_queue_case =logfile queue_property_test_suite.is_queue_case.html -=started 2024-09-11 11:27:01 -=ended 2024-09-11 11:27:01 +=started 2024-09-12 10:49:13 +=ended 2024-09-12 10:49:13 =result ok -=elapsed 0.044214 +=elapsed 0.033056 =case queue_property_test_SUITE:list_conversion_case =logfile queue_property_test_suite.list_conversion_case.html -=started 2024-09-11 11:27:01 -=ended 2024-09-11 11:27:01 +=started 2024-09-12 10:49:13 +=ended 2024-09-12 10:49:13 =result ok -=elapsed 0.057967 +=elapsed 0.059866 =case queue_property_test_SUITE:from_list_invalid_case =logfile queue_property_test_suite.from_list_invalid_case.html -=started 2024-09-11 11:27:01 -=ended 2024-09-11 11:27:01 +=started 2024-09-12 10:49:13 +=ended 2024-09-12 10:49:13 =result ok -=elapsed 0.007539 +=elapsed 0.007116 =case queue_property_test_SUITE:to_list_invalid_case =logfile queue_property_test_suite.to_list_invalid_case.html -=started 2024-09-11 11:27:01 -=ended 2024-09-11 11:27:01 +=started 2024-09-12 10:49:13 +=ended 2024-09-12 10:49:13 =result ok -=elapsed 0.005514 +=elapsed 0.00534 =case queue_property_test_SUITE:all_case =logfile queue_property_test_suite.all_case.html -=started 2024-09-11 11:27:01 -=ended 2024-09-11 11:27:01 +=started 2024-09-12 10:49:13 +=ended 2024-09-12 10:49:13 =result ok -=elapsed 0.050875 +=elapsed 0.076664 =case queue_property_test_SUITE:all_invalid_case =logfile queue_property_test_suite.all_invalid_case.html -=started 2024-09-11 11:27:01 -=ended 2024-09-11 11:27:01 +=started 2024-09-12 10:49:13 +=ended 2024-09-12 10:49:13 =result ok -=elapsed 0.021128 +=elapsed 0.028528 =case queue_property_test_SUITE:any_case =logfile queue_property_test_suite.any_case.html -=started 2024-09-11 11:27:01 -=ended 2024-09-11 11:27:01 +=started 2024-09-12 10:49:13 +=ended 2024-09-12 10:49:13 =result ok -=elapsed 0.127022 +=elapsed 0.130296 =case queue_property_test_SUITE:any_invalid_case =logfile queue_property_test_suite.any_invalid_case.html -=started 2024-09-11 11:27:01 -=ended 2024-09-11 11:27:01 +=started 2024-09-12 10:49:13 +=ended 2024-09-12 10:49:13 =result ok -=elapsed 0.028449 +=elapsed 0.031534 =case queue_property_test_SUITE:cons_case =logfile queue_property_test_suite.cons_case.html -=started 2024-09-11 11:27:01 -=ended 2024-09-11 11:27:01 +=started 2024-09-12 10:49:13 +=ended 2024-09-12 10:49:14 =result ok -=elapsed 0.063788 +=elapsed 0.058897 =case queue_property_test_SUITE:cons_invalid_case =logfile queue_property_test_suite.cons_invalid_case.html -=started 2024-09-11 11:27:01 -=ended 2024-09-11 11:27:01 +=started 2024-09-12 10:49:14 +=ended 2024-09-12 10:49:14 =result ok -=elapsed 0.009748 +=elapsed 0.009943 =case queue_property_test_SUITE:daeh_case =logfile queue_property_test_suite.daeh_case.html -=started 2024-09-11 11:27:01 -=ended 2024-09-11 11:27:02 +=started 2024-09-12 10:49:14 +=ended 2024-09-12 10:49:14 =result ok -=elapsed 0.129639 +=elapsed 0.123617 =case queue_property_test_SUITE:daeh_invalid_case =logfile queue_property_test_suite.daeh_invalid_case.html -=started 2024-09-11 11:27:02 -=ended 2024-09-11 11:27:02 +=started 2024-09-12 10:49:14 +=ended 2024-09-12 10:49:14 =result ok -=elapsed 0.005586 +=elapsed 0.004656 =case queue_property_test_SUITE:delete_case =logfile queue_property_test_suite.delete_case.html -=started 2024-09-11 11:27:02 -=ended 2024-09-11 11:27:02 +=started 2024-09-12 10:49:14 +=ended 2024-09-12 10:49:14 =result ok -=elapsed 0.142434 +=elapsed 0.140708 =case queue_property_test_SUITE:delete_invalid_case =logfile queue_property_test_suite.delete_invalid_case.html -=started 2024-09-11 11:27:02 -=ended 2024-09-11 11:27:02 +=started 2024-09-12 10:49:14 +=ended 2024-09-12 10:49:14 =result ok -=elapsed 0.010893 +=elapsed 0.009612 =case queue_property_test_SUITE:delete_r_case =logfile queue_property_test_suite.delete_r_case.html -=started 2024-09-11 11:27:02 -=ended 2024-09-11 11:27:02 +=started 2024-09-12 10:49:14 +=ended 2024-09-12 10:49:14 =result ok -=elapsed 0.135358 +=elapsed 0.13324 =case queue_property_test_SUITE:delete_r_invalid_case =logfile queue_property_test_suite.delete_r_invalid_case.html -=started 2024-09-11 11:27:02 -=ended 2024-09-11 11:27:02 +=started 2024-09-12 10:49:14 +=ended 2024-09-12 10:49:14 =result ok -=elapsed 0.010598 +=elapsed 0.011173 =case queue_property_test_SUITE:delete_with_case =logfile queue_property_test_suite.delete_with_case.html -=started 2024-09-11 11:27:02 -=ended 2024-09-11 11:27:02 +=started 2024-09-12 10:49:14 +=ended 2024-09-12 10:49:14 =result ok -=elapsed 0.12078 +=elapsed 0.120339 =case queue_property_test_SUITE:delete_with_invalid_case =logfile queue_property_test_suite.delete_with_invalid_case.html -=started 2024-09-11 11:27:02 -=ended 2024-09-11 11:27:02 +=started 2024-09-12 10:49:14 +=ended 2024-09-12 10:49:14 =result ok -=elapsed 0.033887 +=elapsed 0.032077 =case queue_property_test_SUITE:delete_with_r_case =logfile queue_property_test_suite.delete_with_r_case.html -=started 2024-09-11 11:27:02 -=ended 2024-09-11 11:27:02 +=started 2024-09-12 10:49:14 +=ended 2024-09-12 10:49:14 =result ok -=elapsed 0.116715 +=elapsed 0.132971 =case queue_property_test_SUITE:delete_with_r_invalid_case =logfile queue_property_test_suite.delete_with_r_invalid_case.html -=started 2024-09-11 11:27:02 -=ended 2024-09-11 11:27:02 +=started 2024-09-12 10:49:14 +=ended 2024-09-12 10:49:15 =result ok -=elapsed 0.024424 +=elapsed 0.02149 =case queue_property_test_SUITE:drop_case =logfile queue_property_test_suite.drop_case.html -=started 2024-09-11 11:27:02 -=ended 2024-09-11 11:27:02 +=started 2024-09-12 10:49:15 +=ended 2024-09-12 10:49:15 =result ok -=elapsed 0.116417 +=elapsed 0.12103 =case queue_property_test_SUITE:drop_invalid_case =logfile queue_property_test_suite.drop_invalid_case.html -=started 2024-09-11 11:27:02 -=ended 2024-09-11 11:27:03 +=started 2024-09-12 10:49:15 +=ended 2024-09-12 10:49:15 =result ok -=elapsed 0.00544 +=elapsed 0.006481 =case queue_property_test_SUITE:drop_r_case =logfile queue_property_test_suite.drop_r_case.html -=started 2024-09-11 11:27:03 -=ended 2024-09-11 11:27:03 +=started 2024-09-12 10:49:15 +=ended 2024-09-12 10:49:15 =result ok -=elapsed 0.132685 +=elapsed 0.127344 =case queue_property_test_SUITE:drop_r_invalid_case =logfile queue_property_test_suite.drop_r_invalid_case.html -=started 2024-09-11 11:27:03 -=ended 2024-09-11 11:27:03 +=started 2024-09-12 10:49:15 +=ended 2024-09-12 10:49:15 =result ok -=elapsed 0.005306 +=elapsed 0.005858 =case queue_property_test_SUITE:filter_case =logfile queue_property_test_suite.filter_case.html -=started 2024-09-11 11:27:03 -=ended 2024-09-11 11:27:03 +=started 2024-09-12 10:49:15 +=ended 2024-09-12 10:49:15 =result ok -=elapsed 0.122936 +=elapsed 0.121717 =case queue_property_test_SUITE:filter_invalid_case =logfile queue_property_test_suite.filter_invalid_case.html -=started 2024-09-11 11:27:03 -=ended 2024-09-11 11:27:03 +=started 2024-09-12 10:49:15 +=ended 2024-09-12 10:49:15 =result ok -=elapsed 0.031674 +=elapsed 0.020168 =case queue_property_test_SUITE:filtermap_case =logfile queue_property_test_suite.filtermap_case.html -=started 2024-09-11 11:27:03 -=ended 2024-09-11 11:27:03 +=started 2024-09-12 10:49:15 +=ended 2024-09-12 10:49:15 =result ok -=elapsed 0.125202 +=elapsed 0.118103 =case queue_property_test_SUITE:filtermap_invalid_case =logfile queue_property_test_suite.filtermap_invalid_case.html -=started 2024-09-11 11:27:03 -=ended 2024-09-11 11:27:03 +=started 2024-09-12 10:49:15 +=ended 2024-09-12 10:49:15 =result ok -=elapsed 0.027696 +=elapsed 0.036852 =case queue_property_test_SUITE:fold_case =logfile queue_property_test_suite.fold_case.html -=started 2024-09-11 11:27:03 -=ended 2024-09-11 11:27:03 +=started 2024-09-12 10:49:15 +=ended 2024-09-12 10:49:15 =result ok -=elapsed 0.146787 +=elapsed 0.110541 =case queue_property_test_SUITE:fold_invalid_case =logfile queue_property_test_suite.fold_invalid_case.html -=started 2024-09-11 11:27:03 -=ended 2024-09-11 11:27:03 +=started 2024-09-12 10:49:15 +=ended 2024-09-12 10:49:15 =result ok -=elapsed 0.026147 +=elapsed 0.025775 =case queue_property_test_SUITE:get_case =logfile queue_property_test_suite.get_case.html -=started 2024-09-11 11:27:03 -=ended 2024-09-11 11:27:03 +=started 2024-09-12 10:49:15 +=ended 2024-09-12 10:49:16 =result ok -=elapsed 0.129183 +=elapsed 0.131393 =case queue_property_test_SUITE:get_invalid_case =logfile queue_property_test_suite.get_invalid_case.html -=started 2024-09-11 11:27:03 -=ended 2024-09-11 11:27:04 +=started 2024-09-12 10:49:16 +=ended 2024-09-12 10:49:16 =result ok -=elapsed 0.008959 +=elapsed 0.005565 =case queue_property_test_SUITE:get_r_case =logfile queue_property_test_suite.get_r_case.html -=started 2024-09-11 11:27:04 -=ended 2024-09-11 11:27:04 +=started 2024-09-12 10:49:16 +=ended 2024-09-12 10:49:16 =result ok -=elapsed 0.126974 +=elapsed 0.119998 =case queue_property_test_SUITE:get_r_invalid_case =logfile queue_property_test_suite.get_r_invalid_case.html -=started 2024-09-11 11:27:04 -=ended 2024-09-11 11:27:04 +=started 2024-09-12 10:49:16 +=ended 2024-09-12 10:49:16 =result ok -=elapsed 0.008579 +=elapsed 0.006081 =case queue_property_test_SUITE:head_case =logfile queue_property_test_suite.head_case.html -=started 2024-09-11 11:27:04 -=ended 2024-09-11 11:27:04 +=started 2024-09-12 10:49:16 +=ended 2024-09-12 10:49:16 =result ok -=elapsed 0.116987 +=elapsed 0.120189 =case queue_property_test_SUITE:head_invalid_case =logfile queue_property_test_suite.head_invalid_case.html -=started 2024-09-11 11:27:04 -=ended 2024-09-11 11:27:04 +=started 2024-09-12 10:49:16 +=ended 2024-09-12 10:49:16 =result ok -=elapsed 0.00609 +=elapsed 0.00814 =case queue_property_test_SUITE:in_case =logfile queue_property_test_suite.in_case.html -=started 2024-09-11 11:27:04 -=ended 2024-09-11 11:27:04 +=started 2024-09-12 10:49:16 +=ended 2024-09-12 10:49:16 =result ok -=elapsed 0.072603 +=elapsed 0.06564 =case queue_property_test_SUITE:in_invalid_case =logfile queue_property_test_suite.in_invalid_case.html -=started 2024-09-11 11:27:04 -=ended 2024-09-11 11:27:04 +=started 2024-09-12 10:49:16 +=ended 2024-09-12 10:49:16 =result ok -=elapsed 0.009041 +=elapsed 0.014172 =case queue_property_test_SUITE:in_r_case =logfile queue_property_test_suite.in_r_case.html -=started 2024-09-11 11:27:04 -=ended 2024-09-11 11:27:04 +=started 2024-09-12 10:49:16 +=ended 2024-09-12 10:49:16 =result ok -=elapsed 0.066337 +=elapsed 0.067375 =case queue_property_test_SUITE:in_r_invalid_case =logfile queue_property_test_suite.in_r_invalid_case.html -=started 2024-09-11 11:27:04 -=ended 2024-09-11 11:27:04 +=started 2024-09-12 10:49:16 +=ended 2024-09-12 10:49:16 =result ok -=elapsed 0.010288 +=elapsed 0.014891 =case queue_property_test_SUITE:init_case =logfile queue_property_test_suite.init_case.html -=started 2024-09-11 11:27:04 -=ended 2024-09-11 11:27:04 +=started 2024-09-12 10:49:16 +=ended 2024-09-12 10:49:16 =result ok -=elapsed 0.11442 +=elapsed 0.129116 =case queue_property_test_SUITE:init_invalid_case =logfile queue_property_test_suite.init_invalid_case.html -=started 2024-09-11 11:27:04 -=ended 2024-09-11 11:27:04 +=started 2024-09-12 10:49:16 +=ended 2024-09-12 10:49:16 =result ok -=elapsed 0.006571 +=elapsed 0.009313 =case queue_property_test_SUITE:is_empty_case =logfile queue_property_test_suite.is_empty_case.html -=started 2024-09-11 11:27:04 -=ended 2024-09-11 11:27:04 +=started 2024-09-12 10:49:16 +=ended 2024-09-12 10:49:17 =result ok -=elapsed 0.113918 +=elapsed 0.132489 =case queue_property_test_SUITE:is_empty_invalid_case =logfile queue_property_test_suite.is_empty_invalid_case.html -=started 2024-09-11 11:27:04 -=ended 2024-09-11 11:27:04 +=started 2024-09-12 10:49:17 +=ended 2024-09-12 10:49:17 =result ok -=elapsed 0.004525 +=elapsed 0.005192 =case queue_property_test_SUITE:join_case =logfile queue_property_test_suite.join_case.html -=started 2024-09-11 11:27:04 -=ended 2024-09-11 11:27:05 +=started 2024-09-12 10:49:17 +=ended 2024-09-12 10:49:17 =result ok -=elapsed 0.23067 +=elapsed 0.239247 =case queue_property_test_SUITE:join_invalid_case =logfile queue_property_test_suite.join_invalid_case.html -=started 2024-09-11 11:27:05 -=ended 2024-09-11 11:27:05 +=started 2024-09-12 10:49:17 +=ended 2024-09-12 10:49:17 =result ok -=elapsed 0.046988 +=elapsed 0.046087 =case queue_property_test_SUITE:last_case =logfile queue_property_test_suite.last_case.html -=started 2024-09-11 11:27:05 -=ended 2024-09-11 11:27:05 +=started 2024-09-12 10:49:17 +=ended 2024-09-12 10:49:17 =result ok -=elapsed 0.120736 +=elapsed 0.132569 =case queue_property_test_SUITE:last_invalid_case =logfile queue_property_test_suite.last_invalid_case.html -=started 2024-09-11 11:27:05 -=ended 2024-09-11 11:27:05 +=started 2024-09-12 10:49:17 +=ended 2024-09-12 10:49:17 =result ok -=elapsed 0.005246 +=elapsed 0.005536 =case queue_property_test_SUITE:len_case =logfile queue_property_test_suite.len_case.html -=started 2024-09-11 11:27:05 -=ended 2024-09-11 11:27:05 +=started 2024-09-12 10:49:17 +=ended 2024-09-12 10:49:17 =result ok -=elapsed 0.125758 +=elapsed 0.122559 =case queue_property_test_SUITE:len_invalid_case =logfile queue_property_test_suite.len_invalid_case.html -=started 2024-09-11 11:27:05 -=ended 2024-09-11 11:27:05 +=started 2024-09-12 10:49:17 +=ended 2024-09-12 10:49:17 =result ok -=elapsed 0.004795 +=elapsed 0.005448 =case queue_property_test_SUITE:liat_case =logfile queue_property_test_suite.liat_case.html -=started 2024-09-11 11:27:05 -=ended 2024-09-11 11:27:05 +=started 2024-09-12 10:49:17 +=ended 2024-09-12 10:49:17 =result ok -=elapsed 0.119143 +=elapsed 0.130715 =case queue_property_test_SUITE:liat_invalid_case =logfile queue_property_test_suite.liat_invalid_case.html -=started 2024-09-11 11:27:05 -=ended 2024-09-11 11:27:05 +=started 2024-09-12 10:49:17 +=ended 2024-09-12 10:49:17 =result ok -=elapsed 0.005323 +=elapsed 0.006393 =case queue_property_test_SUITE:member_case =logfile queue_property_test_suite.member_case.html -=started 2024-09-11 11:27:05 -=ended 2024-09-11 11:27:05 +=started 2024-09-12 10:49:17 +=ended 2024-09-12 10:49:18 =result ok -=elapsed 0.132053 +=elapsed 0.136151 =case queue_property_test_SUITE:member_invalid_case =logfile queue_property_test_suite.member_invalid_case.html -=started 2024-09-11 11:27:05 -=ended 2024-09-11 11:27:05 +=started 2024-09-12 10:49:18 +=ended 2024-09-12 10:49:18 =result ok -=elapsed 0.010129 +=elapsed 0.00952 =case queue_property_test_SUITE:out_case =logfile queue_property_test_suite.out_case.html -=started 2024-09-11 11:27:05 -=ended 2024-09-11 11:27:06 +=started 2024-09-12 10:49:18 +=ended 2024-09-12 10:49:18 =result ok -=elapsed 0.130093 +=elapsed 0.11988 =case queue_property_test_SUITE:out_invalid_case =logfile queue_property_test_suite.out_invalid_case.html -=started 2024-09-11 11:27:06 -=ended 2024-09-11 11:27:06 +=started 2024-09-12 10:49:18 +=ended 2024-09-12 10:49:18 =result ok -=elapsed 0.007631 +=elapsed 0.006216 =case queue_property_test_SUITE:out_r_case =logfile queue_property_test_suite.out_r_case.html -=started 2024-09-11 11:27:06 -=ended 2024-09-11 11:27:06 +=started 2024-09-12 10:49:18 +=ended 2024-09-12 10:49:18 =result ok -=elapsed 0.117925 +=elapsed 0.129887 =case queue_property_test_SUITE:out_r_invalid_case =logfile queue_property_test_suite.out_r_invalid_case.html -=started 2024-09-11 11:27:06 -=ended 2024-09-11 11:27:06 +=started 2024-09-12 10:49:18 +=ended 2024-09-12 10:49:18 =result ok -=elapsed 0.008268 +=elapsed 0.007995 =case queue_property_test_SUITE:peek_case =logfile queue_property_test_suite.peek_case.html -=started 2024-09-11 11:27:06 -=ended 2024-09-11 11:27:06 +=started 2024-09-12 10:49:18 +=ended 2024-09-12 10:49:18 =result ok -=elapsed 0.13659 +=elapsed 0.122735 =case queue_property_test_SUITE:peek_invalid_case =logfile queue_property_test_suite.peek_invalid_case.html -=started 2024-09-11 11:27:06 -=ended 2024-09-11 11:27:06 +=started 2024-09-12 10:49:18 +=ended 2024-09-12 10:49:18 =result ok -=elapsed 0.007405 +=elapsed 0.008081 =case queue_property_test_SUITE:peek_r_case =logfile queue_property_test_suite.peek_r_case.html -=started 2024-09-11 11:27:06 -=ended 2024-09-11 11:27:06 +=started 2024-09-12 10:49:18 +=ended 2024-09-12 10:49:18 =result ok -=elapsed 0.114383 +=elapsed 0.126825 =case queue_property_test_SUITE:peek_r_invalid_case =logfile queue_property_test_suite.peek_r_invalid_case.html -=started 2024-09-11 11:27:06 -=ended 2024-09-11 11:27:06 +=started 2024-09-12 10:49:18 +=ended 2024-09-12 10:49:18 =result ok -=elapsed 0.00535 +=elapsed 0.005293 =case queue_property_test_SUITE:reverse_case =logfile queue_property_test_suite.reverse_case.html -=started 2024-09-11 11:27:06 -=ended 2024-09-11 11:27:06 +=started 2024-09-12 10:49:18 +=ended 2024-09-12 10:49:19 =result ok -=elapsed 0.135848 +=elapsed 0.12602 =case queue_property_test_SUITE:reverse_invalid_case =logfile queue_property_test_suite.reverse_invalid_case.html -=started 2024-09-11 11:27:06 -=ended 2024-09-11 11:27:06 +=started 2024-09-12 10:49:19 +=ended 2024-09-12 10:49:19 =result ok -=elapsed 0.004868 +=elapsed 0.007787 =case queue_property_test_SUITE:snoc_case =logfile queue_property_test_suite.snoc_case.html -=started 2024-09-11 11:27:06 -=ended 2024-09-11 11:27:06 +=started 2024-09-12 10:49:19 +=ended 2024-09-12 10:49:19 =result ok -=elapsed 0.058095 +=elapsed 0.069327 =case queue_property_test_SUITE:snoc_invalid_case =logfile queue_property_test_suite.snoc_invalid_case.html -=started 2024-09-11 11:27:06 -=ended 2024-09-11 11:27:06 +=started 2024-09-12 10:49:19 +=ended 2024-09-12 10:49:19 =result ok -=elapsed 0.010843 +=elapsed 0.01298 =case queue_property_test_SUITE:split_case =logfile queue_property_test_suite.split_case.html -=started 2024-09-11 11:27:06 -=ended 2024-09-11 11:27:07 +=started 2024-09-12 10:49:19 +=ended 2024-09-12 10:49:19 =result ok -=elapsed 0.129771 +=elapsed 0.126914 =case queue_property_test_SUITE:split_invalid_case =logfile queue_property_test_suite.split_invalid_case.html -=started 2024-09-11 11:27:07 -=ended 2024-09-11 11:27:07 +=started 2024-09-12 10:49:19 +=ended 2024-09-12 10:49:19 =result ok -=elapsed 0.039913 +=elapsed 0.041124 =case queue_property_test_SUITE:tail_case =logfile queue_property_test_suite.tail_case.html -=started 2024-09-11 11:27:07 -=ended 2024-09-11 11:27:07 +=started 2024-09-12 10:49:19 +=ended 2024-09-12 10:49:19 =result ok -=elapsed 0.127872 +=elapsed 0.126886 =case queue_property_test_SUITE:tail_invalid_case =logfile queue_property_test_suite.tail_invalid_case.html -=started 2024-09-11 11:27:07 -=ended 2024-09-11 11:27:07 +=started 2024-09-12 10:49:19 +=ended 2024-09-12 10:49:19 =result ok -=elapsed 0.005212 +=elapsed 0.004947 =case queue_property_test_SUITE:ops_case =logfile queue_property_test_suite.ops_case.html -=started 2024-09-11 11:27:07 -=ended 2024-09-11 11:27:07 +=started 2024-09-12 10:49:19 +=ended 2024-09-12 10:49:19 =result ok -=elapsed 0.127503 +=elapsed 0.140672 =case queue_property_test_SUITE:end_per_suite =logfile queue_property_test_suite.end_per_suite.html -=started 2024-09-11 11:27:07 -=ended 2024-09-11 11:27:07 +=started 2024-09-12 10:49:19 +=ended 2024-09-12 10:49:19 =result ok =elapsed 0.0 -=group_time 7.581s +=group_time 7.639s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.486274.html +=logfile ct_framework.init_per_suite.502242.html =group_props [{suite,rand_SUITE}] -=started 2024-09-11 11:27:07 -=ended 2024-09-11 11:27:07 +=started 2024-09-12 10:49:19 +=ended 2024-09-12 10:49:19 =result ok =elapsed 0.0 =case rand_SUITE:seed =logfile rand_suite.seed.html -=started 2024-09-11 11:27:07 -=ended 2024-09-11 11:27:07 +=started 2024-09-12 10:49:19 +=ended 2024-09-12 10:49:19 =result ok -=elapsed 3.11e-4 +=elapsed 2.39e-4 =case rand_SUITE:interval_int =logfile rand_suite.interval_int.html -=started 2024-09-11 11:27:07 -=ended 2024-09-11 11:27:08 +=started 2024-09-12 10:49:19 +=ended 2024-09-12 10:49:20 =result ok -=elapsed 0.65606 +=elapsed 0.66198 =case rand_SUITE:interval_float =logfile rand_suite.interval_float.html -=started 2024-09-11 11:27:08 -=ended 2024-09-11 11:27:08 +=started 2024-09-12 10:49:20 +=ended 2024-09-12 10:49:20 =result ok -=elapsed 0.314364 +=elapsed 0.311496 =case rand_SUITE:bytes_count =logfile rand_suite.bytes_count.html -=started 2024-09-11 11:27:08 -=ended 2024-09-11 11:27:08 +=started 2024-09-12 10:49:20 +=ended 2024-09-12 10:49:20 =result ok -=elapsed 0.01089 +=elapsed 0.010814 =case rand_SUITE:api_eq =logfile rand_suite.api_eq.html -=started 2024-09-11 11:27:08 -=ended 2024-09-11 11:27:08 +=started 2024-09-12 10:49:20 +=ended 2024-09-12 10:49:20 =result ok -=elapsed 0.028082 +=elapsed 0.027998 =case rand_SUITE:mwc59_api =logfile rand_suite.mwc59_api.html -=started 2024-09-11 11:27:08 -=ended 2024-09-11 11:27:08 +=started 2024-09-12 10:49:20 +=ended 2024-09-12 10:49:20 =result ok -=elapsed 0.043389 +=elapsed 0.043399 =case rand_SUITE:exsp_next_api =logfile rand_suite.exsp_next_api.html -=started 2024-09-11 11:27:08 -=ended 2024-09-11 11:27:08 +=started 2024-09-12 10:49:20 +=ended 2024-09-12 10:49:21 =result ok -=elapsed 0.055708 +=elapsed 0.057035 =case rand_SUITE:exsp_jump_api =logfile rand_suite.exsp_jump_api.html -=started 2024-09-11 11:27:08 -=ended 2024-09-11 11:27:08 +=started 2024-09-12 10:49:21 +=ended 2024-09-12 10:49:21 =result ok -=elapsed 0.060826 +=elapsed 0.060995 =case rand_SUITE:splitmix64_next_api =logfile rand_suite.splitmix64_next_api.html -=started 2024-09-11 11:27:08 -=ended 2024-09-11 11:27:08 +=started 2024-09-12 10:49:21 +=ended 2024-09-12 10:49:21 =result ok -=elapsed 0.027901 +=elapsed 0.026709 =case rand_SUITE:reference =logfile rand_suite.reference.html -=started 2024-09-11 11:27:08 -=ended 2024-09-11 11:27:10 +=started 2024-09-12 10:49:21 +=ended 2024-09-12 10:49:22 =result ok -=elapsed 1.180287 +=elapsed 1.184378 =case ct_framework:init_per_group -=logfile ct_framework.init_per_group.488642.html +=logfile ct_framework.init_per_group.504610.html =group_props [{name,basic_stats},parallel,{suite,rand_SUITE}] -=started 2024-09-11 11:27:10 -=ended 2024-09-11 11:27:10 +=started 2024-09-12 10:49:22 +=ended 2024-09-12 10:49:22 =result ok =elapsed 3.8e-5 =case rand_SUITE:basic_stats_uniform_1 -=logfile rand_suite.basic_stats_uniform_1.488674.html -=started 2024-09-11 11:27:10 -=ended 2024-09-11 11:27:13 +=logfile rand_suite.basic_stats_uniform_1.407459.html +=started 2024-09-12 10:49:22 +=ended 2024-09-12 10:49:25 =result ok -=elapsed 3.50642 +=elapsed 3.532923 =case rand_SUITE:basic_stats_uniform_2 -=logfile rand_suite.basic_stats_uniform_2.488738.html -=started 2024-09-11 11:27:10 -=ended 2024-09-11 11:27:13 +=logfile rand_suite.basic_stats_uniform_2.504642.html +=started 2024-09-12 10:49:22 +=ended 2024-09-12 10:49:25 =result ok -=elapsed 3.209945 +=elapsed 3.313047 =case rand_SUITE:basic_stats_bytes -=logfile rand_suite.basic_stats_bytes.488706.html -=started 2024-09-11 11:27:10 -=ended 2024-09-11 11:27:12 +=logfile rand_suite.basic_stats_bytes.504674.html +=started 2024-09-12 10:49:22 +=ended 2024-09-12 10:49:24 =result ok -=elapsed 2.43257 +=elapsed 2.413912 =case rand_SUITE:basic_stats_standard_normal -=logfile rand_suite.basic_stats_standard_normal.502691.html -=started 2024-09-11 11:27:10 -=ended 2024-09-11 11:27:13 +=logfile rand_suite.basic_stats_standard_normal.504706.html +=started 2024-09-12 10:49:22 +=ended 2024-09-12 10:49:25 =result ok -=elapsed 3.099241 +=elapsed 2.873522 =case ct_framework:end_per_group -=logfile ct_framework.end_per_group.503043.html +=logfile ct_framework.end_per_group.504962.html =group_props [{name,basic_stats},parallel,{suite,rand_SUITE}] -=started 2024-09-11 11:27:13 -=ended 2024-09-11 11:27:13 +=started 2024-09-12 10:49:25 +=ended 2024-09-12 10:49:26 =result ok -=elapsed 4.0e-5 -=group_time 3.558s +=elapsed 3.9e-5 +=group_time 3.580s =case ct_framework:init_per_group -=logfile ct_framework.init_per_group.503075.html +=logfile ct_framework.init_per_group.504994.html =group_props [{name,distr_stats},parallel,{suite,rand_SUITE}] -=started 2024-09-11 11:27:13 -=ended 2024-09-11 11:27:13 +=started 2024-09-12 10:49:26 +=ended 2024-09-12 10:49:26 =result ok -=elapsed 4.1e-5 +=elapsed 4.5e-5 =case rand_SUITE:stats_standard_normal_box_muller -=logfile rand_suite.stats_standard_normal_box_muller.503107.html -=started 2024-09-11 11:27:13 -=ended 2024-09-11 11:27:21 -=result ok: {tp,7.903340006167214,op,0.6000429761841857} -=elapsed 7.793473 +=logfile rand_suite.stats_standard_normal_box_muller.505026.html +=started 2024-09-12 10:49:26 +=ended 2024-09-12 10:49:33 +=result ok: {tp,7.214729335018004,op,1.4816028301143793} +=elapsed 7.387357 =case rand_SUITE:stats_standard_normal_box_muller_2 -=logfile rand_suite.stats_standard_normal_box_muller_2.503139.html -=started 2024-09-11 11:27:13 -=ended 2024-09-11 11:27:21 -=result ok: {tp,7.736935264315239,op,1.119992882577854} -=elapsed 7.742518 +=logfile rand_suite.stats_standard_normal_box_muller_2.505058.html +=started 2024-09-12 10:49:26 +=ended 2024-09-12 10:49:33 +=result ok: {tp,8.83620275154175,op,10.610893926570208} +=elapsed 7.329903 =case rand_SUITE:stats_standard_normal -=logfile rand_suite.stats_standard_normal.503171.html -=started 2024-09-11 11:27:13 -=ended 2024-09-11 11:27:21 -=result ok: {tp,9.12599096011556,op,90.40118884611324} -=elapsed 7.710885 +=logfile rand_suite.stats_standard_normal.505090.html +=started 2024-09-12 10:49:26 +=ended 2024-09-12 10:49:33 +=result ok: {tp,7.903340006167214,op,16.069013440209282} +=elapsed 7.365339 =case ct_framework:end_per_group -=logfile ct_framework.end_per_group.503203.html +=logfile ct_framework.end_per_group.505154.html =group_props [{name,distr_stats},parallel,{suite,rand_SUITE}] -=started 2024-09-11 11:27:21 -=ended 2024-09-11 11:27:21 +=started 2024-09-12 10:49:33 +=ended 2024-09-12 10:49:33 =result ok -=elapsed 3.2e-5 -=group_time 7.841s +=elapsed 4.2e-5 +=group_time 7.436s =case rand_SUITE:uniform_real_conv =logfile rand_suite.uniform_real_conv.html -=started 2024-09-11 11:27:21 -=ended 2024-09-11 11:27:21 +=started 2024-09-12 10:49:33 +=ended 2024-09-12 10:49:33 =result ok -=elapsed 0.008102 +=elapsed 0.008107 =case rand_SUITE:plugin =logfile rand_suite.plugin.html -=started 2024-09-11 11:27:21 -=ended 2024-09-11 11:27:21 +=started 2024-09-12 10:49:33 +=ended 2024-09-12 10:49:33 =result ok -=elapsed 1.11e-4 +=elapsed 9.6e-5 =case rand_SUITE:measure =logfile rand_suite.measure.html -=started 2024-09-11 11:27:21 -=ended 2024-09-11 11:27:38 +=started 2024-09-12 10:49:33 +=ended 2024-09-12 10:49:51 =result ok -=elapsed 17.1952 +=elapsed 17.536677 =case ct_framework:init_per_group -=logfile ct_framework.init_per_group.19694146.html +=logfile ct_framework.init_per_group.19710306.html =group_props [{name,reference_jump},parallel,{suite,rand_SUITE}] -=started 2024-09-11 11:27:38 -=ended 2024-09-11 11:27:38 +=started 2024-09-12 10:49:51 +=ended 2024-09-12 10:49:51 =result ok -=elapsed 3.8e-5 +=elapsed 3.4e-5 =case rand_SUITE:reference_jump_state -=logfile rand_suite.reference_jump_state.19694178.html -=started 2024-09-11 11:27:38 -=ended 2024-09-11 11:27:40 +=logfile rand_suite.reference_jump_state.19710338.html +=started 2024-09-12 10:49:51 +=ended 2024-09-12 10:49:52 =result ok -=elapsed 1.179754 +=elapsed 1.157174 =case rand_SUITE:reference_jump_procdict -=logfile rand_suite.reference_jump_procdict.19694210.html -=started 2024-09-11 11:27:38 -=ended 2024-09-11 11:27:40 +=logfile rand_suite.reference_jump_procdict.19710370.html +=started 2024-09-12 10:49:51 +=ended 2024-09-12 10:49:52 =result ok -=elapsed 1.179272 +=elapsed 1.166871 =case ct_framework:end_per_group -=logfile ct_framework.end_per_group.19694274.html +=logfile ct_framework.end_per_group.19710434.html =group_props [{name,reference_jump},parallel,{suite,rand_SUITE}] -=started 2024-09-11 11:27:40 -=ended 2024-09-11 11:27:40 +=started 2024-09-12 10:49:52 +=ended 2024-09-12 10:49:52 =result ok -=elapsed 3.8e-5 -=group_time 1.226s +=elapsed 3.2e-5 +=group_time 1.214s =case rand_SUITE:short_jump =logfile rand_suite.short_jump.html -=started 2024-09-11 11:27:40 -=ended 2024-09-11 11:27:40 +=started 2024-09-12 10:49:52 +=ended 2024-09-12 10:49:52 =result ok -=elapsed 0.448898 +=elapsed 0.456613 =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.19694306.html +=logfile ct_framework.end_per_suite.19710466.html =group_props [{suite,rand_SUITE}] -=started 2024-09-11 11:27:40 -=ended 2024-09-11 11:27:40 +=started 2024-09-12 10:49:52 +=ended 2024-09-12 10:49:52 =result ok =elapsed 0.0 -=group_time 33.086s +=group_time 33.046s =case random_SUITE:init_per_suite =logfile random_suite.init_per_suite.html -=started 2024-09-11 11:27:40 -=ended 2024-09-11 11:27:40 +=started 2024-09-12 10:49:52 +=ended 2024-09-12 10:49:52 =result ok =elapsed 0.0 =case random_SUITE:interval_1 =logfile random_suite.interval_1.html -=started 2024-09-11 11:27:40 -=ended 2024-09-11 11:27:40 +=started 2024-09-12 10:49:52 +=ended 2024-09-12 10:49:52 =result ok -=elapsed 0.002104 +=elapsed 0.001871 =case random_SUITE:seed0 =logfile random_suite.seed0.html -=started 2024-09-11 11:27:40 -=ended 2024-09-11 11:27:40 +=started 2024-09-12 10:49:52 +=ended 2024-09-12 10:49:52 =result ok -=elapsed 1.0e-5 +=elapsed 8.0e-6 =case random_SUITE:seed =logfile random_suite.seed.html -=started 2024-09-11 11:27:40 -=ended 2024-09-11 11:27:40 +=started 2024-09-12 10:49:52 +=ended 2024-09-12 10:49:52 =result ok -=elapsed 5.5e-5 +=elapsed 4.6e-5 =case random_SUITE:end_per_suite =logfile random_suite.end_per_suite.html -=started 2024-09-11 11:27:40 -=ended 2024-09-11 11:27:40 +=started 2024-09-12 10:49:52 +=ended 2024-09-12 10:49:52 =result ok =elapsed 0.0 -=group_time 0.106s +=group_time 0.104s =case re_SUITE:init_per_suite =logfile re_suite.init_per_suite.html -=started 2024-09-11 11:27:40 -=ended 2024-09-11 11:27:40 +=started 2024-09-12 10:49:52 +=ended 2024-09-12 10:49:52 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =case re_SUITE:pcre =logfile re_suite.pcre.html -=started 2024-09-11 11:27:40 -=ended 2024-09-11 11:27:41 +=started 2024-09-12 10:49:52 +=ended 2024-09-12 10:49:53 =result ok: [{0,6786,0}, {0,4926,88}, {0,138,48}, @@ -12048,6214 +12048,6214 @@ {0,1716,0}, {0,594,8}, {0,36,0}] -=elapsed 0.648227 +=elapsed 0.652561 =case re_SUITE:compile_options =logfile re_suite.compile_options.html -=started 2024-09-11 11:27:41 -=ended 2024-09-11 11:27:41 +=started 2024-09-12 10:49:53 +=ended 2024-09-12 10:49:53 =result ok -=elapsed 9.0e-5 +=elapsed 9.2e-5 =case re_SUITE:run_options =logfile re_suite.run_options.html -=started 2024-09-11 11:27:41 -=ended 2024-09-11 11:27:41 +=started 2024-09-12 10:49:53 +=ended 2024-09-12 10:49:53 =result ok -=elapsed 1.51e-4 +=elapsed 1.53e-4 =case re_SUITE:combined_options =logfile re_suite.combined_options.html -=started 2024-09-11 11:27:41 -=ended 2024-09-11 11:27:41 +=started 2024-09-12 10:49:53 +=ended 2024-09-12 10:49:53 =result ok -=elapsed 1.24e-4 +=elapsed 1.27e-4 =case re_SUITE:replace_autogen =logfile re_suite.replace_autogen.html -=started 2024-09-11 11:27:41 -=ended 2024-09-11 11:27:41 +=started 2024-09-12 10:49:53 +=ended 2024-09-12 10:49:53 =result ok -=elapsed 0.025233 +=elapsed 0.025258 =case re_SUITE:global_capture =logfile re_suite.global_capture.html -=started 2024-09-11 11:27:41 -=ended 2024-09-11 11:27:41 +=started 2024-09-12 10:49:53 +=ended 2024-09-12 10:49:53 =result ok -=elapsed 1.57e-4 +=elapsed 1.65e-4 =case re_SUITE:replace_input_types =logfile re_suite.replace_input_types.html -=started 2024-09-11 11:27:41 -=ended 2024-09-11 11:27:41 +=started 2024-09-12 10:49:53 +=ended 2024-09-12 10:49:53 =result ok -=elapsed 1.6e-5 +=elapsed 1.5e-5 =case re_SUITE:replace_with_fun =logfile re_suite.replace_with_fun.html -=started 2024-09-11 11:27:41 -=ended 2024-09-11 11:27:41 +=started 2024-09-12 10:49:53 +=ended 2024-09-12 10:49:53 =result ok -=elapsed 4.7e-5 +=elapsed 4.6e-5 =case re_SUITE:replace_return =logfile re_suite.replace_return.html -=started 2024-09-11 11:27:41 -=ended 2024-09-11 11:27:41 +=started 2024-09-12 10:49:53 +=ended 2024-09-12 10:49:53 =result ok -=elapsed 2.59e-4 +=elapsed 2.61e-4 =case re_SUITE:split_autogen =logfile re_suite.split_autogen.html -=started 2024-09-11 11:27:41 -=ended 2024-09-11 11:27:41 +=started 2024-09-12 10:49:53 +=ended 2024-09-12 10:49:53 =result ok -=elapsed 0.038391 +=elapsed 0.038996 =case re_SUITE:split_options =logfile re_suite.split_options.html -=started 2024-09-11 11:27:41 -=ended 2024-09-11 11:27:41 +=started 2024-09-12 10:49:53 +=ended 2024-09-12 10:49:53 =result ok -=elapsed 2.34e-4 +=elapsed 2.35e-4 =case re_SUITE:split_specials =logfile re_suite.split_specials.html -=started 2024-09-11 11:27:41 -=ended 2024-09-11 11:27:41 +=started 2024-09-12 10:49:53 +=ended 2024-09-12 10:49:53 =result ok -=elapsed 3.1e-5 +=elapsed 2.2e-5 =case re_SUITE:error_handling =logfile re_suite.error_handling.html -=started 2024-09-11 11:27:41 -=ended 2024-09-11 11:27:41 +=started 2024-09-12 10:49:53 +=ended 2024-09-12 10:49:54 =result ok -=elapsed 1.23e-4 +=elapsed 1.2e-4 =case re_SUITE:pcre_cve_2008_2371 =logfile re_suite.pcre_cve_2008_2371.html -=started 2024-09-11 11:27:41 -=ended 2024-09-11 11:27:41 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok =elapsed 5.0e-6 =case re_SUITE:pcre_compile_workspace_overflow =logfile re_suite.pcre_compile_workspace_overflow.html -=started 2024-09-11 11:27:41 -=ended 2024-09-11 11:27:41 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok: Got expected error: regular expression is too complicated -=elapsed 1.55e-4 +=elapsed 1.72e-4 =case re_SUITE:re_infinite_loop =logfile re_suite.re_infinite_loop.html -=started 2024-09-11 11:27:41 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok -=elapsed 0.421766 +=elapsed 0.418422 =case re_SUITE:re_backwards_accented =logfile re_suite.re_backwards_accented.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok -=elapsed 9.0e-6 +=elapsed 1.0e-5 =case re_SUITE:opt_dupnames =logfile re_suite.opt_dupnames.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok -=elapsed 2.81e-4 +=elapsed 2.86e-4 =case re_SUITE:opt_all_names =logfile re_suite.opt_all_names.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok -=elapsed 2.72e-4 +=elapsed 2.76e-4 =case re_SUITE:inspect =logfile re_suite.inspect.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok -=elapsed 1.5e-5 +=elapsed 1.6e-5 =case re_SUITE:opt_no_start_optimize =logfile re_suite.opt_no_start_optimize.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok -=elapsed 9.0e-6 +=elapsed 1.1e-5 =case re_SUITE:opt_never_utf =logfile re_suite.opt_never_utf.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok -=elapsed 2.6e-5 +=elapsed 3.8e-5 =case re_SUITE:opt_ucp =logfile re_suite.opt_ucp.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok -=elapsed 1.2e-5 +=elapsed 1.8e-5 =case re_SUITE:match_limit =logfile re_suite.match_limit.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok -=elapsed 0.001664 +=elapsed 0.001812 =case re_SUITE:sub_binaries =logfile re_suite.sub_binaries.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok -=elapsed 1.77e-4 +=elapsed 2.68e-4 =case re_SUITE:re_version =logfile re_suite.re_version.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok -=elapsed 8.0e-6 +=elapsed 1.0e-5 =case re_SUITE:global_unicode_validation =logfile re_suite.global_unicode_validation.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok -=elapsed 0.12722 +=elapsed 0.133239 =case re_SUITE:yield_on_subject_validation =logfile re_suite.yield_on_subject_validation.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok -=elapsed 0.00105 +=elapsed 0.001187 =case re_SUITE:bad_utf8_subject =logfile re_suite.bad_utf8_subject.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok -=elapsed 0.00313 +=elapsed 0.003147 =case re_SUITE:error_info =logfile re_suite.error_info.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok -=elapsed 0.003329 +=elapsed 0.003508 =case re_SUITE:end_per_suite =logfile re_suite.end_per_suite.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:54 =result ok =elapsed 0.0 -=group_time 1.998s +=group_time 2.007s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.19694338.html +=logfile ct_framework.init_per_suite.19710498.html =group_props [{suite,select_SUITE}] -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:54 +=ended 2024-09-12 10:49:55 =result ok =elapsed 0.0 =case select_SUITE:return_values =logfile select_suite.return_values.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:42 +=started 2024-09-12 10:49:55 +=ended 2024-09-12 10:49:55 =result ok -=elapsed 0.006153 +=elapsed 0.006015 =case select_SUITE:select_test =logfile select_suite.select_test.html -=started 2024-09-11 11:27:42 -=ended 2024-09-11 11:27:55 +=started 2024-09-12 10:49:55 +=ended 2024-09-12 10:50:07 =result ok -=elapsed 12.403859 +=elapsed 12.480334 =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.19694402.html +=logfile ct_framework.end_per_suite.19710562.html =group_props [{suite,select_SUITE}] -=started 2024-09-11 11:27:55 -=ended 2024-09-11 11:27:55 +=started 2024-09-12 10:50:07 +=ended 2024-09-12 10:50:07 =result ok =elapsed 0.0 -=group_time 12.489s +=group_time 12.567s =case sets_SUITE:init_per_suite =logfile sets_suite.init_per_suite.html -=started 2024-09-11 11:27:55 -=ended 2024-09-11 11:27:55 +=started 2024-09-12 10:50:07 +=ended 2024-09-12 10:50:07 =result ok =elapsed 0.0 =case sets_SUITE:create =logfile sets_suite.create.html -=started 2024-09-11 11:27:55 -=ended 2024-09-11 11:27:55 +=started 2024-09-12 10:50:07 +=ended 2024-09-12 10:50:07 =result ok -=elapsed 2.1e-5 +=elapsed 2.3e-5 =case sets_SUITE:add_element =logfile sets_suite.add_element.html -=started 2024-09-11 11:27:55 -=ended 2024-09-11 11:27:55 +=started 2024-09-12 10:50:07 +=ended 2024-09-12 10:50:07 =result ok -=elapsed 0.154789 +=elapsed 0.155049 =case sets_SUITE:del_element =logfile sets_suite.del_element.html -=started 2024-09-11 11:27:55 -=ended 2024-09-11 11:27:55 +=started 2024-09-12 10:50:07 +=ended 2024-09-12 10:50:07 =result ok -=elapsed 0.170629 +=elapsed 0.171322 =case sets_SUITE:subtract =logfile sets_suite.subtract.html -=started 2024-09-11 11:27:55 -=ended 2024-09-11 11:27:56 +=started 2024-09-12 10:50:07 +=ended 2024-09-12 10:50:08 =result ok -=elapsed 0.403033 +=elapsed 0.401998 =case sets_SUITE:intersection =logfile sets_suite.intersection.html -=started 2024-09-11 11:27:56 -=ended 2024-09-11 11:27:56 +=started 2024-09-12 10:50:08 +=ended 2024-09-12 10:50:08 =result ok -=elapsed 0.52109 +=elapsed 0.521016 =case sets_SUITE:union =logfile sets_suite.union.html -=started 2024-09-11 11:27:56 -=ended 2024-09-11 11:27:57 +=started 2024-09-12 10:50:08 +=ended 2024-09-12 10:50:09 =result ok -=elapsed 0.625861 +=elapsed 0.626688 =case sets_SUITE:is_subset =logfile sets_suite.is_subset.html -=started 2024-09-11 11:27:57 -=ended 2024-09-11 11:27:57 +=started 2024-09-12 10:50:09 +=ended 2024-09-12 10:50:10 =result ok -=elapsed 0.557873 +=elapsed 0.554358 =case sets_SUITE:is_set =logfile sets_suite.is_set.html -=started 2024-09-11 11:27:57 -=ended 2024-09-11 11:27:57 +=started 2024-09-12 10:50:10 +=ended 2024-09-12 10:50:10 =result ok -=elapsed 7.0e-6 +=elapsed 8.0e-6 =case sets_SUITE:fold =logfile sets_suite.fold.html -=started 2024-09-11 11:27:57 -=ended 2024-09-11 11:27:58 +=started 2024-09-12 10:50:10 +=ended 2024-09-12 10:50:10 =result ok -=elapsed 0.081465 +=elapsed 0.081163 =case sets_SUITE:filter =logfile sets_suite.filter.html -=started 2024-09-11 11:27:58 -=ended 2024-09-11 11:27:58 +=started 2024-09-12 10:50:10 +=ended 2024-09-12 10:50:10 =result ok -=elapsed 0.057319 +=elapsed 0.05856 =case sets_SUITE:map =logfile sets_suite.map.html -=started 2024-09-11 11:27:58 -=ended 2024-09-11 11:27:58 +=started 2024-09-12 10:50:10 +=ended 2024-09-12 10:50:10 =result ok -=elapsed 0.086914 +=elapsed 0.087355 =case sets_SUITE:filtermap =logfile sets_suite.filtermap.html -=started 2024-09-11 11:27:58 -=ended 2024-09-11 11:27:58 +=started 2024-09-12 10:50:10 +=ended 2024-09-12 10:50:10 =result ok -=elapsed 0.048081 +=elapsed 0.047581 =case sets_SUITE:take_smallest =logfile sets_suite.take_smallest.html -=started 2024-09-11 11:27:58 -=ended 2024-09-11 11:27:58 +=started 2024-09-12 10:50:10 +=ended 2024-09-12 10:50:10 =result ok -=elapsed 0.014336 +=elapsed 0.014437 =case sets_SUITE:take_largest =logfile sets_suite.take_largest.html -=started 2024-09-11 11:27:58 -=ended 2024-09-11 11:27:58 +=started 2024-09-12 10:50:10 +=ended 2024-09-12 10:50:10 =result ok -=elapsed 0.016439 +=elapsed 0.016534 =case sets_SUITE:iterate =logfile sets_suite.iterate.html -=started 2024-09-11 11:27:58 -=ended 2024-09-11 11:27:58 +=started 2024-09-12 10:50:10 +=ended 2024-09-12 10:50:10 =result ok -=elapsed 0.070946 +=elapsed 0.073354 =case sets_SUITE:is_empty =logfile sets_suite.is_empty.html -=started 2024-09-11 11:27:58 -=ended 2024-09-11 11:27:58 +=started 2024-09-12 10:50:10 +=ended 2024-09-12 10:50:10 =result ok -=elapsed 7.0e-6 +=elapsed 8.0e-6 =case sets_SUITE:is_disjoint =logfile sets_suite.is_disjoint.html -=started 2024-09-11 11:27:58 -=ended 2024-09-11 11:27:58 +=started 2024-09-12 10:50:10 +=ended 2024-09-12 10:50:10 =result ok -=elapsed 0.022215 +=elapsed 0.022253 =case sets_SUITE:is_equal =logfile sets_suite.is_equal.html -=started 2024-09-11 11:27:58 -=ended 2024-09-11 11:27:58 +=started 2024-09-12 10:50:10 +=ended 2024-09-12 10:50:10 =result ok -=elapsed 0.049346 +=elapsed 0.049113 =case sets_SUITE:end_per_suite =logfile sets_suite.end_per_suite.html -=started 2024-09-11 11:27:58 -=ended 2024-09-11 11:27:58 +=started 2024-09-12 10:50:10 +=ended 2024-09-12 10:50:10 =result ok =elapsed 0.0 -=group_time 3.318s +=group_time 3.328s =case sets_property_test_SUITE:init_per_suite =logfile sets_property_test_suite.init_per_suite.html -=started 2024-09-11 11:27:58 -=ended 2024-09-11 11:27:59 +=started 2024-09-12 10:50:10 +=ended 2024-09-12 10:50:12 =result ok -=elapsed 1.261903 +=elapsed 1.281607 =case sets_property_test_SUITE:add_element_case =logfile sets_property_test_suite.add_element_case.html -=started 2024-09-11 11:27:59 -=ended 2024-09-11 11:28:00 +=started 2024-09-12 10:50:12 +=ended 2024-09-12 10:50:12 =result ok -=elapsed 0.583391 +=elapsed 0.500622 =case sets_property_test_SUITE:del_element_case =logfile sets_property_test_suite.del_element_case.html -=started 2024-09-11 11:28:00 -=ended 2024-09-11 11:28:01 +=started 2024-09-12 10:50:12 +=ended 2024-09-12 10:50:13 =result ok -=elapsed 0.585125 +=elapsed 0.527979 =case sets_property_test_SUITE:filter_case =logfile sets_property_test_suite.filter_case.html -=started 2024-09-11 11:28:01 -=ended 2024-09-11 11:28:01 +=started 2024-09-12 10:50:13 +=ended 2024-09-12 10:50:13 =result ok -=elapsed 0.180726 +=elapsed 0.205541 =case sets_property_test_SUITE:filtermap_case =logfile sets_property_test_suite.filtermap_case.html -=started 2024-09-11 11:28:01 -=ended 2024-09-11 11:28:01 +=started 2024-09-12 10:50:13 +=ended 2024-09-12 10:50:13 =result ok -=elapsed 0.304328 +=elapsed 0.310368 =case sets_property_test_SUITE:fold_case =logfile sets_property_test_suite.fold_case.html -=started 2024-09-11 11:28:01 -=ended 2024-09-11 11:28:01 +=started 2024-09-12 10:50:13 +=ended 2024-09-12 10:50:14 =result ok -=elapsed 0.181741 +=elapsed 0.186302 =case sets_property_test_SUITE:from_list_case =logfile sets_property_test_suite.from_list_case.html -=started 2024-09-11 11:28:01 -=ended 2024-09-11 11:28:02 +=started 2024-09-12 10:50:14 +=ended 2024-09-12 10:50:14 =result ok -=elapsed 0.189364 +=elapsed 0.182514 =case sets_property_test_SUITE:intersection_1_case =logfile sets_property_test_suite.intersection_1_case.html -=started 2024-09-11 11:28:02 -=ended 2024-09-11 11:28:04 +=started 2024-09-12 10:50:14 +=ended 2024-09-12 10:50:17 =result ok -=elapsed 2.678149 +=elapsed 2.780878 =case sets_property_test_SUITE:intersection_2_case =logfile sets_property_test_suite.intersection_2_case.html -=started 2024-09-11 11:28:04 -=ended 2024-09-11 11:28:05 +=started 2024-09-12 10:50:17 +=ended 2024-09-12 10:50:17 =result ok -=elapsed 0.574297 +=elapsed 0.519404 =case sets_property_test_SUITE:is_disjoint_case =logfile sets_property_test_suite.is_disjoint_case.html -=started 2024-09-11 11:28:05 -=ended 2024-09-11 11:28:05 +=started 2024-09-12 10:50:17 +=ended 2024-09-12 10:50:18 =result ok -=elapsed 0.557623 +=elapsed 0.589852 =case sets_property_test_SUITE:is_element_case =logfile sets_property_test_suite.is_element_case.html -=started 2024-09-11 11:28:05 -=ended 2024-09-11 11:28:06 +=started 2024-09-12 10:50:18 +=ended 2024-09-12 10:50:18 =result ok -=elapsed 0.387592 +=elapsed 0.360947 =case sets_property_test_SUITE:is_empty_case =logfile sets_property_test_suite.is_empty_case.html -=started 2024-09-11 11:28:06 -=ended 2024-09-11 11:28:06 +=started 2024-09-12 10:50:18 +=ended 2024-09-12 10:50:18 =result ok -=elapsed 0.184164 +=elapsed 0.194834 =case sets_property_test_SUITE:is_equal_case =logfile sets_property_test_suite.is_equal_case.html -=started 2024-09-11 11:28:06 -=ended 2024-09-11 11:28:06 +=started 2024-09-12 10:50:18 +=ended 2024-09-12 10:50:19 =result ok -=elapsed 0.37249 +=elapsed 0.387084 =case sets_property_test_SUITE:is_set_case =logfile sets_property_test_suite.is_set_case.html -=started 2024-09-11 11:28:06 -=ended 2024-09-11 11:28:07 +=started 2024-09-12 10:50:19 +=ended 2024-09-12 10:50:19 =result ok -=elapsed 0.107096 +=elapsed 0.095325 =case sets_property_test_SUITE:is_subset_case =logfile sets_property_test_suite.is_subset_case.html -=started 2024-09-11 11:28:07 -=ended 2024-09-11 11:28:07 +=started 2024-09-12 10:50:19 +=ended 2024-09-12 10:50:19 =result ok -=elapsed 0.447113 +=elapsed 0.448371 =case sets_property_test_SUITE:map_case =logfile sets_property_test_suite.map_case.html -=started 2024-09-11 11:28:07 -=ended 2024-09-11 11:28:08 +=started 2024-09-12 10:50:19 +=ended 2024-09-12 10:50:20 =result ok -=elapsed 0.545253 +=elapsed 0.515336 =case sets_property_test_SUITE:size_case =logfile sets_property_test_suite.size_case.html -=started 2024-09-11 11:28:08 -=ended 2024-09-11 11:28:08 +=started 2024-09-12 10:50:20 +=ended 2024-09-12 10:50:20 =result ok -=elapsed 0.182284 +=elapsed 0.199065 =case sets_property_test_SUITE:subtract_case =logfile sets_property_test_suite.subtract_case.html -=started 2024-09-11 11:28:08 -=ended 2024-09-11 11:28:08 +=started 2024-09-12 10:50:20 +=ended 2024-09-12 10:50:21 =result ok -=elapsed 0.582065 +=elapsed 0.571191 =case sets_property_test_SUITE:to_list_case =logfile sets_property_test_suite.to_list_case.html -=started 2024-09-11 11:28:08 -=ended 2024-09-11 11:28:09 +=started 2024-09-12 10:50:21 +=ended 2024-09-12 10:50:21 =result ok -=elapsed 0.199656 +=elapsed 0.19901 =case sets_property_test_SUITE:union_1_case =logfile sets_property_test_suite.union_1_case.html -=started 2024-09-11 11:28:09 -=ended 2024-09-11 11:28:12 +=started 2024-09-12 10:50:21 +=ended 2024-09-12 10:50:24 =result ok -=elapsed 3.004532 +=elapsed 2.565882 =case sets_property_test_SUITE:union_2_case =logfile sets_property_test_suite.union_2_case.html -=started 2024-09-11 11:28:12 -=ended 2024-09-11 11:28:12 +=started 2024-09-12 10:50:24 +=ended 2024-09-12 10:50:24 =result ok -=elapsed 0.544433 +=elapsed 0.542962 =case sets_property_test_SUITE:operations_case =logfile sets_property_test_suite.operations_case.html -=started 2024-09-11 11:28:12 -=ended 2024-09-11 11:28:14 +=started 2024-09-12 10:50:24 +=ended 2024-09-12 10:50:26 =result ok -=elapsed 1.874388 +=elapsed 1.74659 =case sets_property_test_SUITE:end_per_suite =logfile sets_property_test_suite.end_per_suite.html -=started 2024-09-11 11:28:14 -=ended 2024-09-11 11:28:14 +=started 2024-09-12 10:50:26 +=ended 2024-09-12 10:50:26 =result ok =elapsed 0.0 -=group_time 16.037s +=group_time 15.422s =case shell_SUITE:init_per_suite =logfile shell_suite.init_per_suite.html -=started 2024-09-11 11:28:14 -=ended 2024-09-11 11:28:14 +=started 2024-09-12 10:50:26 +=ended 2024-09-12 10:50:26 =result ok =elapsed 0.0 =case shell_SUITE:forget =logfile shell_suite.forget.html -=started 2024-09-11 11:28:14 -=ended 2024-09-11 11:28:14 +=started 2024-09-12 10:50:26 +=ended 2024-09-12 10:50:26 =result ok -=elapsed 0.007512 +=elapsed 0.00737 =case shell_SUITE:known_bugs =logfile shell_suite.known_bugs.html -=started 2024-09-11 11:28:14 -=ended 2024-09-11 11:28:14 +=started 2024-09-12 10:50:26 +=ended 2024-09-12 10:50:26 =result ok -=elapsed 0.001085 +=elapsed 0.001034 =case shell_SUITE:otp_5226 =logfile shell_suite.otp_5226.html -=started 2024-09-11 11:28:14 -=ended 2024-09-11 11:28:14 +=started 2024-09-12 10:50:26 +=ended 2024-09-12 10:50:26 =result ok -=elapsed 0.076517 +=elapsed 0.065028 =case shell_SUITE:otp_5327 =logfile shell_suite.otp_5327.html -=started 2024-09-11 11:28:14 -=ended 2024-09-11 11:28:14 +=started 2024-09-12 10:50:26 +=ended 2024-09-12 10:50:26 =result ok -=elapsed 0.025531 +=elapsed 0.031546 =case shell_SUITE:otp_5435 =logfile shell_suite.otp_5435.html -=started 2024-09-11 11:28:14 -=ended 2024-09-11 11:28:15 +=started 2024-09-12 10:50:26 +=ended 2024-09-12 10:50:26 =result ok -=elapsed 0.191838 +=elapsed 0.18567 =case shell_SUITE:otp_5195 =logfile shell_suite.otp_5195.html -=started 2024-09-11 11:28:15 -=ended 2024-09-11 11:28:15 +=started 2024-09-12 10:50:26 +=ended 2024-09-12 10:50:26 =result ok -=elapsed 0.029379 +=elapsed 0.030155 =case shell_SUITE:otp_5915 =logfile shell_suite.otp_5915.html -=started 2024-09-11 11:28:15 -=ended 2024-09-11 11:28:15 +=started 2024-09-12 10:50:26 +=ended 2024-09-12 10:50:26 =result ok -=elapsed 0.007213 +=elapsed 0.007174 =case shell_SUITE:otp_5916 =logfile shell_suite.otp_5916.html -=started 2024-09-11 11:28:15 -=ended 2024-09-11 11:28:15 +=started 2024-09-12 10:50:26 +=ended 2024-09-12 10:50:26 =result ok -=elapsed 0.001405 +=elapsed 0.001404 =case shell_SUITE:prompt_width =logfile shell_suite.prompt_width.html -=started 2024-09-11 11:28:15 -=ended 2024-09-11 11:28:15 +=started 2024-09-12 10:50:26 +=ended 2024-09-12 10:50:26 =result ok -=elapsed 1.87e-4 +=elapsed 1.65e-4 =case shell_SUITE:local_definitions_save_to_module_and_forget =logfile shell_suite.local_definitions_save_to_module_and_forget.html -=started 2024-09-11 11:28:15 -=ended 2024-09-11 11:28:15 +=started 2024-09-12 10:50:26 +=ended 2024-09-12 10:50:27 =result ok -=elapsed 0.020225 +=elapsed 0.019254 =case shell_SUITE:start_interactive =logfile shell_suite.start_interactive.html -=started 2024-09-11 11:28:15 -=ended 2024-09-11 11:29:00 +=started 2024-09-12 10:50:27 +=ended 2024-09-12 10:51:12 =result ok -=elapsed 44.920895 +=elapsed 44.947741 =case shell_SUITE:whereis =logfile shell_suite.whereis.html -=started 2024-09-11 11:29:00 -=ended 2024-09-11 11:29:13 +=started 2024-09-12 10:51:12 +=ended 2024-09-12 10:51:24 =result ok -=elapsed 12.958578 +=elapsed 12.960391 =case shell_SUITE:init_per_group =logfile shell_suite.init_per_group.html =group_props [{name,bits}] -=started 2024-09-11 11:29:13 -=ended 2024-09-11 11:29:13 +=started 2024-09-12 10:51:24 +=ended 2024-09-12 10:51:25 =result ok =elapsed 0.0 =case shell_SUITE:bs_match_misc_SUITE =logfile shell_suite.bs_match_misc_suite.html -=started 2024-09-11 11:29:13 -=ended 2024-09-11 11:29:13 +=started 2024-09-12 10:51:25 +=ended 2024-09-12 10:51:25 =result ok -=elapsed 0.00851 +=elapsed 0.009729 =case shell_SUITE:bs_match_tail_SUITE =logfile shell_suite.bs_match_tail_suite.html -=started 2024-09-11 11:29:13 -=ended 2024-09-11 11:29:13 +=started 2024-09-12 10:51:25 +=ended 2024-09-12 10:51:25 =result ok -=elapsed 0.003433 +=elapsed 0.003732 =case shell_SUITE:bs_match_bin_SUITE =logfile shell_suite.bs_match_bin_suite.html -=started 2024-09-11 11:29:13 -=ended 2024-09-11 11:29:14 +=started 2024-09-12 10:51:25 +=ended 2024-09-12 10:51:25 =result ok -=elapsed 0.75374 +=elapsed 0.768598 =case shell_SUITE:bs_construct_SUITE =logfile shell_suite.bs_construct_suite.html -=started 2024-09-11 11:29:14 -=ended 2024-09-11 11:29:14 +=started 2024-09-12 10:51:25 +=ended 2024-09-12 10:51:25 =result ok -=elapsed 0.011646 +=elapsed 0.010462 =case shell_SUITE:end_per_group =logfile shell_suite.end_per_group.html =group_props [{name,bits}] -=started 2024-09-11 11:29:14 -=ended 2024-09-11 11:29:14 +=started 2024-09-12 10:51:25 +=ended 2024-09-12 10:51:25 =result ok =elapsed 0.0 -=group_time 0.915s +=group_time 0.930s =case shell_SUITE:init_per_group -=logfile shell_suite.init_per_group.19697474.html +=logfile shell_suite.init_per_group.19713890.html =group_props [{name,refman}] -=started 2024-09-11 11:29:14 -=ended 2024-09-11 11:29:14 +=started 2024-09-12 10:51:25 +=ended 2024-09-12 10:51:25 =result ok =elapsed 0.0 =case shell_SUITE:refman_bit_syntax =logfile shell_suite.refman_bit_syntax.html -=started 2024-09-11 11:29:14 -=ended 2024-09-11 11:29:14 +=started 2024-09-12 10:51:25 +=ended 2024-09-12 10:51:26 =result ok -=elapsed 0.001488 +=elapsed 0.001826 =case shell_SUITE:end_per_group -=logfile shell_suite.end_per_group.19697506.html +=logfile shell_suite.end_per_group.19713922.html =group_props [{name,refman}] -=started 2024-09-11 11:29:14 -=ended 2024-09-11 11:29:14 +=started 2024-09-12 10:51:26 +=ended 2024-09-12 10:51:26 =result ok =elapsed 0.0 -=group_time 0.052s +=group_time 0.053s =case shell_SUITE:init_per_group -=logfile shell_suite.init_per_group.19697538.html +=logfile shell_suite.init_per_group.19713954.html =group_props [{name,progex}] -=started 2024-09-11 11:29:14 -=ended 2024-09-11 11:29:14 +=started 2024-09-12 10:51:26 +=ended 2024-09-12 10:51:26 =result ok =elapsed 0.0 =case shell_SUITE:progex_bit_syntax =logfile shell_suite.progex_bit_syntax.html -=started 2024-09-11 11:29:14 -=ended 2024-09-11 11:29:14 +=started 2024-09-12 10:51:26 +=ended 2024-09-12 10:51:26 =result ok -=elapsed 0.00267 +=elapsed 0.002982 =case shell_SUITE:progex_records =logfile shell_suite.progex_records.html -=started 2024-09-11 11:29:14 -=ended 2024-09-11 11:29:14 +=started 2024-09-12 10:51:26 +=ended 2024-09-12 10:51:26 =result ok -=elapsed 0.014656 +=elapsed 0.014759 =case shell_SUITE:progex_lc =logfile shell_suite.progex_lc.html -=started 2024-09-11 11:29:14 -=ended 2024-09-11 11:29:14 +=started 2024-09-12 10:51:26 +=ended 2024-09-12 10:51:26 =result ok -=elapsed 0.118826 +=elapsed 0.115571 =case shell_SUITE:progex_funs =logfile shell_suite.progex_funs.html -=started 2024-09-11 11:29:14 -=ended 2024-09-11 11:29:14 +=started 2024-09-12 10:51:26 +=ended 2024-09-12 10:51:26 =result ok -=elapsed 0.030988 +=elapsed 0.032533 =case shell_SUITE:end_per_group -=logfile shell_suite.end_per_group.19697570.html +=logfile shell_suite.end_per_group.19713986.html =group_props [{name,progex}] -=started 2024-09-11 11:29:14 -=ended 2024-09-11 11:29:14 +=started 2024-09-12 10:51:26 +=ended 2024-09-12 10:51:26 =result ok =elapsed 0.0 -=group_time 0.297s +=group_time 0.302s =case shell_SUITE:init_per_group -=logfile shell_suite.init_per_group.19697602.html +=logfile shell_suite.init_per_group.19714018.html =group_props [{name,tickets}] -=started 2024-09-11 11:29:14 -=ended 2024-09-11 11:29:14 +=started 2024-09-12 10:51:26 +=ended 2024-09-12 10:51:26 =result ok =elapsed 0.0 =case shell_SUITE:otp_5990 =logfile shell_suite.otp_5990.html -=started 2024-09-11 11:29:14 -=ended 2024-09-11 11:29:14 +=started 2024-09-12 10:51:26 +=ended 2024-09-12 10:51:26 =result ok -=elapsed 0.001237 +=elapsed 0.001249 =case shell_SUITE:otp_6166 =logfile shell_suite.otp_6166.html -=started 2024-09-11 11:29:14 -=ended 2024-09-11 11:29:14 +=started 2024-09-12 10:51:26 +=ended 2024-09-12 10:51:26 =result ok -=elapsed 0.002776 +=elapsed 0.002649 =case shell_SUITE:otp_6554 =logfile shell_suite.otp_6554.html -=started 2024-09-11 11:29:14 -=ended 2024-09-11 11:29:16 +=started 2024-09-12 10:51:26 +=ended 2024-09-12 10:51:28 =result ok -=elapsed 1.99496 +=elapsed 1.987647 =case shell_SUITE:otp_7184 =logfile shell_suite.otp_7184.html -=started 2024-09-11 11:29:16 -=ended 2024-09-11 11:29:16 +=started 2024-09-12 10:51:28 +=ended 2024-09-12 10:51:28 =result ok -=elapsed 0.005368 +=elapsed 0.005387 =case shell_SUITE:otp_7232 =logfile shell_suite.otp_7232.html -=started 2024-09-11 11:29:16 -=ended 2024-09-11 11:29:16 +=started 2024-09-12 10:51:28 +=ended 2024-09-12 10:51:28 =result ok -=elapsed 0.00187 +=elapsed 0.001884 =case shell_SUITE:otp_8393 =logfile shell_suite.otp_8393.html -=started 2024-09-11 11:29:16 -=ended 2024-09-11 11:29:16 +=started 2024-09-12 10:51:28 +=ended 2024-09-12 10:51:28 =result ok -=elapsed 0.016768 +=elapsed 0.016196 =case shell_SUITE:otp_10302 =logfile shell_suite.otp_10302.html -=started 2024-09-11 11:29:16 -=ended 2024-09-11 11:29:17 +=started 2024-09-12 10:51:28 +=ended 2024-09-12 10:51:28 =result ok -=elapsed 0.217507 +=elapsed 0.22171 =case shell_SUITE:otp_13719 =logfile shell_suite.otp_13719.html -=started 2024-09-11 11:29:17 -=ended 2024-09-11 11:29:17 +=started 2024-09-12 10:51:28 +=ended 2024-09-12 10:51:28 =result ok -=elapsed 0.00316 +=elapsed 0.004403 =case shell_SUITE:otp_14285 =logfile shell_suite.otp_14285.html -=started 2024-09-11 11:29:17 -=ended 2024-09-11 11:29:17 +=started 2024-09-12 10:51:28 +=ended 2024-09-12 10:51:29 =result ok -=elapsed 0.183851 +=elapsed 0.179868 =case shell_SUITE:otp_14296 =logfile shell_suite.otp_14296.html -=started 2024-09-11 11:29:17 -=ended 2024-09-11 11:29:17 +=started 2024-09-12 10:51:29 +=ended 2024-09-12 10:51:29 =result ok -=elapsed 0.008866 +=elapsed 0.013611 =case shell_SUITE:end_per_group -=logfile shell_suite.end_per_group.503715.html +=logfile shell_suite.end_per_group.19714178.html =group_props [{name,tickets}] -=started 2024-09-11 11:29:17 -=ended 2024-09-11 11:29:17 +=started 2024-09-12 10:51:29 +=ended 2024-09-12 10:51:29 =result ok =elapsed 0.0 -=group_time 2.738s +=group_time 2.737s =case shell_SUITE:init_per_group -=logfile shell_suite.init_per_group.503747.html +=logfile shell_suite.init_per_group.19714210.html =group_props [{name,restricted}] -=started 2024-09-11 11:29:17 -=ended 2024-09-11 11:29:17 +=started 2024-09-12 10:51:29 +=ended 2024-09-12 10:51:29 =result ok =elapsed 0.0 =case shell_SUITE:start_restricted_from_shell =logfile shell_suite.start_restricted_from_shell.html -=started 2024-09-11 11:29:17 -=ended 2024-09-11 11:29:17 +=started 2024-09-12 10:51:29 +=ended 2024-09-12 10:51:29 =result ok -=elapsed 0.100625 +=elapsed 0.099103 =case shell_SUITE:start_restricted_on_command_line =logfile shell_suite.start_restricted_on_command_line.html -=started 2024-09-11 11:29:17 -=ended 2024-09-11 11:29:17 +=started 2024-09-12 10:51:29 +=ended 2024-09-12 10:51:29 =result ok -=elapsed 0.383985 +=elapsed 0.391114 =case shell_SUITE:restricted_local =logfile shell_suite.restricted_local.html -=started 2024-09-11 11:29:17 -=ended 2024-09-11 11:29:19 +=started 2024-09-12 10:51:29 +=ended 2024-09-12 10:51:31 =result ok -=elapsed 1.509647 +=elapsed 1.483708 =case shell_SUITE:end_per_group -=logfile shell_suite.end_per_group.19697794.html +=logfile shell_suite.end_per_group.407971.html =group_props [{name,restricted}] -=started 2024-09-11 11:29:19 -=ended 2024-09-11 11:29:19 +=started 2024-09-12 10:51:31 +=ended 2024-09-12 10:51:31 =result ok =elapsed 0.0 -=group_time 2.107s +=group_time 2.087s =case shell_SUITE:init_per_group -=logfile shell_suite.init_per_group.19697826.html +=logfile shell_suite.init_per_group.408003.html =group_props [{name,records}] -=started 2024-09-11 11:29:19 -=ended 2024-09-11 11:29:19 +=started 2024-09-12 10:51:31 +=ended 2024-09-12 10:51:31 =result ok =elapsed 0.0 =case shell_SUITE:records =logfile shell_suite.records.html -=started 2024-09-11 11:29:19 -=ended 2024-09-11 11:29:19 +=started 2024-09-12 10:51:31 +=ended 2024-09-12 10:51:31 =result ok -=elapsed 0.181726 +=elapsed 0.196752 =case shell_SUITE:typed_records =logfile shell_suite.typed_records.html -=started 2024-09-11 11:29:19 -=ended 2024-09-11 11:29:19 +=started 2024-09-12 10:51:31 +=ended 2024-09-12 10:51:31 =result ok -=elapsed 0.015934 +=elapsed 0.01528 =case shell_SUITE:end_per_group -=logfile shell_suite.end_per_group.398500.html +=logfile shell_suite.end_per_group.408035.html =group_props [{name,records}] -=started 2024-09-11 11:29:19 -=ended 2024-09-11 11:29:19 +=started 2024-09-12 10:51:31 +=ended 2024-09-12 10:51:31 =result ok =elapsed 0.0 -=group_time 0.288s +=group_time 0.304s =case shell_SUITE:init_per_group -=logfile shell_suite.init_per_group.19697858.html +=logfile shell_suite.init_per_group.408067.html =group_props [{name,definitions}] -=started 2024-09-11 11:29:19 -=ended 2024-09-11 11:29:19 +=started 2024-09-12 10:51:31 +=ended 2024-09-12 10:51:31 =result ok =elapsed 0.0 =case shell_SUITE:types =logfile shell_suite.types.html -=started 2024-09-11 11:29:19 -=ended 2024-09-11 11:29:33 +=started 2024-09-12 10:51:31 +=ended 2024-09-12 10:51:45 =result ok -=elapsed 13.794362 +=elapsed 13.815723 =case shell_SUITE:end_per_group -=logfile shell_suite.end_per_group.19697986.html +=logfile shell_suite.end_per_group.425892.html =group_props [{name,definitions}] -=started 2024-09-11 11:29:33 -=ended 2024-09-11 11:29:33 +=started 2024-09-12 10:51:45 +=ended 2024-09-12 10:51:45 =result ok =elapsed 0.0 -=group_time 13.851s +=group_time 13.873s =case shell_SUITE:end_per_suite =logfile shell_suite.end_per_suite.html -=started 2024-09-11 11:29:33 -=ended 2024-09-11 11:29:33 +=started 2024-09-12 10:51:45 +=ended 2024-09-12 10:51:45 =result ok =elapsed 0.0 -=group_time 79.030s +=group_time 79.086s =case shell_docs_SUITE:init_per_suite =logfile shell_docs_suite.init_per_suite.html -=started 2024-09-11 11:29:33 -=ended 2024-09-11 11:29:33 +=started 2024-09-12 10:51:45 +=ended 2024-09-12 10:51:45 =result ok -=elapsed 0.102686 +=elapsed 0.102752 =case shell_docs_SUITE:render_smoke =logfile shell_docs_suite.render_smoke.html -=started 2024-09-11 11:29:33 -=ended 2024-09-11 11:30:50 +=started 2024-09-12 10:51:45 +=ended 2024-09-12 10:53:01 =result ok -=elapsed 76.153515 +=elapsed 76.019851 =case shell_docs_SUITE:render =logfile shell_docs_suite.render.html -=started 2024-09-11 11:30:50 -=ended 2024-09-11 11:30:54 +=started 2024-09-12 10:53:01 +=ended 2024-09-12 10:53:06 =result ok -=elapsed 4.803735 +=elapsed 4.891871 =case shell_docs_SUITE:render_non_native =logfile shell_docs_suite.render_non_native.html -=started 2024-09-11 11:30:54 -=ended 2024-09-11 11:30:54 +=started 2024-09-12 10:53:06 +=ended 2024-09-12 10:53:06 =result ok -=elapsed 8.0e-5 +=elapsed 6.1e-5 =case shell_docs_SUITE:links =logfile shell_docs_suite.links.html -=started 2024-09-11 11:30:54 -=ended 2024-09-11 11:30:55 +=started 2024-09-12 10:53:06 +=ended 2024-09-12 10:53:07 =result ok -=elapsed 0.922228 +=elapsed 0.914996 =case shell_docs_SUITE:normalize =logfile shell_docs_suite.normalize.html -=started 2024-09-11 11:30:55 -=ended 2024-09-11 11:30:55 +=started 2024-09-12 10:53:07 +=ended 2024-09-12 10:53:07 =result ok -=elapsed 1.01e-4 +=elapsed 9.6e-5 =case shell_docs_SUITE:init_per_group =logfile shell_docs_suite.init_per_group.html =group_props [{name,prop}] -=started 2024-09-11 11:30:55 -=ended 2024-09-11 11:30:57 +=started 2024-09-12 10:53:07 +=ended 2024-09-12 10:53:08 =result ok -=elapsed 1.284703 +=elapsed 1.316639 =case shell_docs_SUITE:render_prop =logfile shell_docs_suite.render_prop.html -=started 2024-09-11 11:30:57 -=ended 2024-09-11 11:31:08 +=started 2024-09-12 10:53:08 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 11.579191 +=elapsed 11.355754 =case shell_docs_SUITE:end_per_group =logfile shell_docs_suite.end_per_group.html =group_props [{name,prop}] -=started 2024-09-11 11:31:08 -=ended 2024-09-11 11:31:08 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok =elapsed 0.0 -=group_time 12.909s +=group_time 12.719s =case shell_docs_SUITE:ansi =logfile shell_docs_suite.ansi.html -=started 2024-09-11 11:31:08 -=ended 2024-09-11 11:31:08 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 5.6e-4 +=elapsed 5.77e-4 =case shell_docs_SUITE:columns =logfile shell_docs_suite.columns.html -=started 2024-09-11 11:31:08 -=ended 2024-09-11 11:31:08 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 0.001367 +=elapsed 0.001344 =case shell_docs_SUITE:end_per_suite =logfile shell_docs_suite.end_per_suite.html -=started 2024-09-11 11:31:08 -=ended 2024-09-11 11:31:08 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok =elapsed 0.0 -=group_time 95.117s +=group_time 94.871s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.19698050.html +=logfile ct_framework.init_per_suite.19714626.html =group_props [{suite,shell_docs_markdown_SUITE}] -=started 2024-09-11 11:31:08 -=ended 2024-09-11 11:31:08 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =case shell_docs_markdown_SUITE:init_per_group =logfile shell_docs_markdown_suite.init_per_group.html =group_props [{name,different_format_generator},sequence] -=started 2024-09-11 11:31:08 -=ended 2024-09-11 11:31:08 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok =elapsed 0.0 =case shell_docs_markdown_SUITE:convert_erlang_html =logfile shell_docs_markdown_suite.convert_erlang_html.html -=started 2024-09-11 11:31:08 -=ended 2024-09-11 11:31:08 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 2.1e-5 +=elapsed 1.6e-5 =case shell_docs_markdown_SUITE:convert_unknown_format =logfile shell_docs_markdown_suite.convert_unknown_format.html -=started 2024-09-11 11:31:08 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 2.0e-6 +=elapsed 1.0e-6 =case shell_docs_markdown_SUITE:end_per_group =logfile shell_docs_markdown_suite.end_per_group.html =group_props [{name,different_format_generator},sequence] -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok =elapsed 0.0 =group_time 0.069s =case shell_docs_markdown_SUITE:init_per_group -=logfile shell_docs_markdown_suite.init_per_group.19698082.html +=logfile shell_docs_markdown_suite.init_per_group.19714658.html =group_props [{name,module_generator},sequence] -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok =elapsed 0.0 =case shell_docs_markdown_SUITE:non_existing_moduledoc =logfile shell_docs_markdown_suite.non_existing_moduledoc.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 1.4e-5 +=elapsed 1.0e-5 =case shell_docs_markdown_SUITE:hidden_moduledoc =logfile shell_docs_markdown_suite.hidden_moduledoc.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 1.2e-5 +=elapsed 9.0e-6 =case shell_docs_markdown_SUITE:existing_moduledoc =logfile shell_docs_markdown_suite.existing_moduledoc.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 7.0e-5 +=elapsed 5.5e-5 =case shell_docs_markdown_SUITE:end_per_group -=logfile shell_docs_markdown_suite.end_per_group.19698114.html +=logfile shell_docs_markdown_suite.end_per_group.19714690.html =group_props [{name,module_generator},sequence] -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok =elapsed 0.0 -=group_time 0.092s +=group_time 0.089s =case shell_docs_markdown_SUITE:init_per_group -=logfile shell_docs_markdown_suite.init_per_group.19698146.html +=logfile shell_docs_markdown_suite.init_per_group.19714722.html =group_props [{name,doc_generator},sequence] -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok =elapsed 0.0 =case shell_docs_markdown_SUITE:non_existing_doc =logfile shell_docs_markdown_suite.non_existing_doc.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 1.4e-5 +=elapsed 1.0e-5 =case shell_docs_markdown_SUITE:hidden_doc =logfile shell_docs_markdown_suite.hidden_doc.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 7.0e-6 +=elapsed 5.0e-6 =case shell_docs_markdown_SUITE:existing_doc =logfile shell_docs_markdown_suite.existing_doc.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 4.9e-5 +=elapsed 3.8e-5 =case shell_docs_markdown_SUITE:end_per_group -=logfile shell_docs_markdown_suite.end_per_group.19698178.html +=logfile shell_docs_markdown_suite.end_per_group.19714754.html =group_props [{name,doc_generator},sequence] -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok =elapsed 0.0 -=group_time 0.091s +=group_time 0.088s =case shell_docs_markdown_SUITE:init_per_group -=logfile shell_docs_markdown_suite.init_per_group.19698210.html +=logfile shell_docs_markdown_suite.init_per_group.19714786.html =group_props [{name,header_generator},sequence] -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok =elapsed 0.0 =case shell_docs_markdown_SUITE:h1_test =logfile shell_docs_markdown_suite.h1_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 4.8e-5 +=elapsed 3.6e-5 =case shell_docs_markdown_SUITE:h2_test =logfile shell_docs_markdown_suite.h2_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 7.1e-5 +=elapsed 5.1e-5 =case shell_docs_markdown_SUITE:h3_test =logfile shell_docs_markdown_suite.h3_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 6.7e-5 +=elapsed 4.9e-5 =case shell_docs_markdown_SUITE:h4_test =logfile shell_docs_markdown_suite.h4_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 6.8e-5 +=elapsed 5.0e-5 =case shell_docs_markdown_SUITE:h5_test =logfile shell_docs_markdown_suite.h5_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 1.04e-4 +=elapsed 7.0e-5 =case shell_docs_markdown_SUITE:h6_test =logfile shell_docs_markdown_suite.h6_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 1.31e-4 +=elapsed 8.7e-5 =case shell_docs_markdown_SUITE:setext_h1 =logfile shell_docs_markdown_suite.setext_h1.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok -=elapsed 5.5e-5 +=elapsed 5.3e-5 =case shell_docs_markdown_SUITE:setext_h2 =logfile shell_docs_markdown_suite.setext_h2.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok =elapsed 5.3e-5 =case shell_docs_markdown_SUITE:end_per_group -=logfile shell_docs_markdown_suite.end_per_group.19698242.html +=logfile shell_docs_markdown_suite.end_per_group.19714818.html =group_props [{name,header_generator},sequence] -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok =elapsed 0.0 -=group_time 0.206s +=group_time 0.203s =case shell_docs_markdown_SUITE:init_per_group -=logfile shell_docs_markdown_suite.init_per_group.19698274.html +=logfile shell_docs_markdown_suite.init_per_group.19714850.html =group_props [{name,quote_generator},sequence] -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok =elapsed 0.0 =case shell_docs_markdown_SUITE:single_line_quote_test =logfile shell_docs_markdown_suite.single_line_quote_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:20 =result ok =elapsed 6.0e-5 =case shell_docs_markdown_SUITE:double_char_for_quote_test =logfile shell_docs_markdown_suite.double_char_for_quote_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:20 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 6.8e-5 +=elapsed 9.9e-5 =case shell_docs_markdown_SUITE:ignore_three_spaces_before_quote =logfile shell_docs_markdown_suite.ignore_three_spaces_before_quote.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 3.5e-5 +=elapsed 3.8e-5 =case shell_docs_markdown_SUITE:multiple_line_quote_test =logfile shell_docs_markdown_suite.multiple_line_quote_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 5.3e-5 +=elapsed 5.7e-5 =case shell_docs_markdown_SUITE:paragraph_in_between_test =logfile shell_docs_markdown_suite.paragraph_in_between_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 1.19e-4 +=elapsed 1.18e-4 =case shell_docs_markdown_SUITE:quote_with_anchor_test =logfile shell_docs_markdown_suite.quote_with_anchor_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 1.01e-4 +=elapsed 1.35e-4 =case shell_docs_markdown_SUITE:quote_without_space =logfile shell_docs_markdown_suite.quote_without_space.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 1.23e-4 +=elapsed 1.01e-4 =case shell_docs_markdown_SUITE:end_per_group -=logfile shell_docs_markdown_suite.end_per_group.19698306.html +=logfile shell_docs_markdown_suite.end_per_group.19714882.html =group_props [{name,quote_generator},sequence] -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 0.0 -=group_time 0.181s +=group_time 0.179s =case shell_docs_markdown_SUITE:init_per_group -=logfile shell_docs_markdown_suite.init_per_group.19698338.html +=logfile shell_docs_markdown_suite.init_per_group.19714914.html =group_props [{name,paragraph_generator},sequence] -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 0.0 =case shell_docs_markdown_SUITE:paragraph_after_heading_test =logfile shell_docs_markdown_suite.paragraph_after_heading_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 7.3e-5 +=elapsed 7.7e-5 =case shell_docs_markdown_SUITE:quote_before_and_after_paragraph_test =logfile shell_docs_markdown_suite.quote_before_and_after_paragraph_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 8.6e-5 +=elapsed 8.4e-5 =case shell_docs_markdown_SUITE:end_per_group -=logfile shell_docs_markdown_suite.end_per_group.19698370.html +=logfile shell_docs_markdown_suite.end_per_group.19714946.html =group_props [{name,paragraph_generator},sequence] -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 0.0 -=group_time 0.068s +=group_time 0.069s =case shell_docs_markdown_SUITE:init_per_group -=logfile shell_docs_markdown_suite.init_per_group.19698402.html +=logfile shell_docs_markdown_suite.init_per_group.19714978.html =group_props [{name,code_generator},sequence] -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 0.0 =case shell_docs_markdown_SUITE:single_line_code_test =logfile shell_docs_markdown_suite.single_line_code_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 4.2e-5 +=elapsed 4.3e-5 =case shell_docs_markdown_SUITE:multiple_line_code_test =logfile shell_docs_markdown_suite.multiple_line_code_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 3.4e-5 +=elapsed 3.6e-5 =case shell_docs_markdown_SUITE:paragraph_between_code_test =logfile shell_docs_markdown_suite.paragraph_between_code_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 8.2e-5 +=elapsed 8.3e-5 =case shell_docs_markdown_SUITE:end_per_group -=logfile shell_docs_markdown_suite.end_per_group.19698434.html +=logfile shell_docs_markdown_suite.end_per_group.19715010.html =group_props [{name,code_generator},sequence] -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 0.0 =group_time 0.091s =case shell_docs_markdown_SUITE:init_per_group -=logfile shell_docs_markdown_suite.init_per_group.19698466.html +=logfile shell_docs_markdown_suite.init_per_group.19715042.html =group_props [{name,fence_code_generator},sequence] -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 0.0 =case shell_docs_markdown_SUITE:single_line_fence_code_test =logfile shell_docs_markdown_suite.single_line_fence_code_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 3.9e-5 +=elapsed 4.2e-5 =case shell_docs_markdown_SUITE:multiple_line_fence_code_test =logfile shell_docs_markdown_suite.multiple_line_fence_code_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 4.1e-5 +=elapsed 4.0e-5 =case shell_docs_markdown_SUITE:single_line_fence_code_no_language_test =logfile shell_docs_markdown_suite.single_line_fence_code_no_language_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:09 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 3.3e-5 =case shell_docs_markdown_SUITE:single_line_fence_code_no_language_spaces_test =logfile shell_docs_markdown_suite.single_line_fence_code_no_language_spaces_test.html -=started 2024-09-11 11:31:09 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 3.2e-5 =case shell_docs_markdown_SUITE:paragraph_between_fence_code_test =logfile shell_docs_markdown_suite.paragraph_between_fence_code_test.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 6.4e-5 =case shell_docs_markdown_SUITE:fence_code_ignores_link_format_test =logfile shell_docs_markdown_suite.fence_code_ignores_link_format_test.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 6.1e-5 +=elapsed 6.4e-5 =case shell_docs_markdown_SUITE:fence_code_with_spaces =logfile shell_docs_markdown_suite.fence_code_with_spaces.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 4.0e-5 =case shell_docs_markdown_SUITE:fence_code_with_tabs =logfile shell_docs_markdown_suite.fence_code_with_tabs.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 3.8e-5 =case shell_docs_markdown_SUITE:end_per_group -=logfile shell_docs_markdown_suite.end_per_group.19698498.html +=logfile shell_docs_markdown_suite.end_per_group.19715074.html =group_props [{name,fence_code_generator},sequence] -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 0.0 -=group_time 0.204s +=group_time 0.200s =case shell_docs_markdown_SUITE:init_per_group -=logfile shell_docs_markdown_suite.init_per_group.19698530.html +=logfile shell_docs_markdown_suite.init_per_group.19715106.html =group_props [{name,br_generator},sequence] -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 0.0 =case shell_docs_markdown_SUITE:start_with_br_test =logfile shell_docs_markdown_suite.start_with_br_test.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 4.6e-5 +=elapsed 5.1e-5 =case shell_docs_markdown_SUITE:multiple_br_followed_by_paragraph_test =logfile shell_docs_markdown_suite.multiple_br_followed_by_paragraph_test.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 6.4e-5 =case shell_docs_markdown_SUITE:multiple_lines_of_a_paragraph_test =logfile shell_docs_markdown_suite.multiple_lines_of_a_paragraph_test.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 9.1e-5 =case shell_docs_markdown_SUITE:ending_br_test =logfile shell_docs_markdown_suite.ending_br_test.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 3.4e-5 +=elapsed 3.6e-5 =case shell_docs_markdown_SUITE:end_per_group -=logfile shell_docs_markdown_suite.end_per_group.19698562.html +=logfile shell_docs_markdown_suite.end_per_group.19715138.html =group_props [{name,br_generator},sequence] -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 0.0 -=group_time 0.110s +=group_time 0.111s =case shell_docs_markdown_SUITE:init_per_group -=logfile shell_docs_markdown_suite.init_per_group.19698594.html +=logfile shell_docs_markdown_suite.init_per_group.19715170.html =group_props [{name,comment_generator},sequence] -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 0.0 =case shell_docs_markdown_SUITE:begin_comment_test =logfile shell_docs_markdown_suite.begin_comment_test.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 4.1e-5 +=elapsed 4.3e-5 =case shell_docs_markdown_SUITE:after_paragraph_comment =logfile shell_docs_markdown_suite.after_paragraph_comment.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 5.1e-5 +=elapsed 5.3e-5 =case shell_docs_markdown_SUITE:forget_closing_comment =logfile shell_docs_markdown_suite.forget_closing_comment.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 1.4e-5 +=elapsed 1.5e-5 =case shell_docs_markdown_SUITE:end_per_group -=logfile shell_docs_markdown_suite.end_per_group.19698626.html +=logfile shell_docs_markdown_suite.end_per_group.19715202.html =group_props [{name,comment_generator},sequence] -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 0.0 -=group_time 0.088s +=group_time 0.089s =case shell_docs_markdown_SUITE:init_per_group -=logfile shell_docs_markdown_suite.init_per_group.19698658.html +=logfile shell_docs_markdown_suite.init_per_group.19715234.html =group_props [{name,format_generator},sequence] -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 0.0 =case shell_docs_markdown_SUITE:format_heading_test =logfile shell_docs_markdown_suite.format_heading_test.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 6.2e-5 +=elapsed 6.5e-5 =case shell_docs_markdown_SUITE:format_paragraph_test =logfile shell_docs_markdown_suite.format_paragraph_test.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 5.3e-5 =case shell_docs_markdown_SUITE:format_multiple_inline =logfile shell_docs_markdown_suite.format_multiple_inline.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 4.3e-5 +=elapsed 5.8e-5 =case shell_docs_markdown_SUITE:format_multiple_inline_format_long =logfile shell_docs_markdown_suite.format_multiple_inline_format_long.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 3.9e-5 =case shell_docs_markdown_SUITE:format_multiple_inline_format_short =logfile shell_docs_markdown_suite.format_multiple_inline_format_short.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok -=elapsed 3.8e-5 +=elapsed 3.7e-5 =case shell_docs_markdown_SUITE:format_multiple_inline_format_mixed =logfile shell_docs_markdown_suite.format_multiple_inline_format_mixed.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 5.7e-5 =case shell_docs_markdown_SUITE:unmatched_format_simple =logfile shell_docs_markdown_suite.unmatched_format_simple.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:21 =result ok =elapsed 4.3e-5 =case shell_docs_markdown_SUITE:unmatched_format_with_inline =logfile shell_docs_markdown_suite.unmatched_format_with_inline.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:21 +=ended 2024-09-12 10:53:22 =result ok =elapsed 6.0e-5 =case shell_docs_markdown_SUITE:unmatched_complex_format_with_inline =logfile shell_docs_markdown_suite.unmatched_complex_format_with_inline.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 7.6e-5 +=elapsed 7.7e-5 =case shell_docs_markdown_SUITE:format_inline_link_with_inline =logfile shell_docs_markdown_suite.format_inline_link_with_inline.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 5.0e-5 +=elapsed 5.6e-5 =case shell_docs_markdown_SUITE:complex_inline_format =logfile shell_docs_markdown_suite.complex_inline_format.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 4.5e-5 +=elapsed 5.0e-5 =case shell_docs_markdown_SUITE:skip_symbols_in_inline =logfile shell_docs_markdown_suite.skip_symbols_in_inline.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 4.5e-5 +=elapsed 6.2e-5 =case shell_docs_markdown_SUITE:format_header_identifier =logfile shell_docs_markdown_suite.format_header_identifier.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 4.0e-5 +=elapsed 4.4e-5 =case shell_docs_markdown_SUITE:italic_in_middle_word_test =logfile shell_docs_markdown_suite.italic_in_middle_word_test.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 6.2e-5 +=elapsed 6.5e-5 =case shell_docs_markdown_SUITE:italic_with_colons =logfile shell_docs_markdown_suite.italic_with_colons.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 5.0e-5 +=elapsed 5.2e-5 =case shell_docs_markdown_SUITE:list_format_with_italics_in_sentence =logfile shell_docs_markdown_suite.list_format_with_italics_in_sentence.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 7.3e-5 +=elapsed 7.7e-5 =case shell_docs_markdown_SUITE:list_format_with_bold_in_sentence =logfile shell_docs_markdown_suite.list_format_with_bold_in_sentence.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 7.2e-5 +=elapsed 7.5e-5 =case shell_docs_markdown_SUITE:new_lines_test =logfile shell_docs_markdown_suite.new_lines_test.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 4.6e-5 +=elapsed 4.7e-5 =case shell_docs_markdown_SUITE:format_separator_test =logfile shell_docs_markdown_suite.format_separator_test.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 8.9e-5 +=elapsed 9.3e-5 =case shell_docs_markdown_SUITE:list_with_format =logfile shell_docs_markdown_suite.list_with_format.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 7.0e-5 +=elapsed 7.2e-5 =case shell_docs_markdown_SUITE:multi_word_format_test =logfile shell_docs_markdown_suite.multi_word_format_test.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 6.5e-5 +=elapsed 7.0e-5 =case shell_docs_markdown_SUITE:multiline_link =logfile shell_docs_markdown_suite.multiline_link.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 6.2e-5 +=elapsed 6.6e-5 =case shell_docs_markdown_SUITE:multiline_link_not_allowed =logfile shell_docs_markdown_suite.multiline_link_not_allowed.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 6.9e-5 +=elapsed 7.4e-5 =case shell_docs_markdown_SUITE:inline_mfa_link =logfile shell_docs_markdown_suite.inline_mfa_link.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 5.9e-5 +=elapsed 6.1e-5 =case shell_docs_markdown_SUITE:escaped_character =logfile shell_docs_markdown_suite.escaped_character.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 7.8e-5 +=elapsed 7.9e-5 =case shell_docs_markdown_SUITE:parens_with_italics =logfile shell_docs_markdown_suite.parens_with_italics.html -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 1.51e-4 +=elapsed 1.61e-4 =case shell_docs_markdown_SUITE:end_per_group -=logfile shell_docs_markdown_suite.end_per_group.19698690.html +=logfile shell_docs_markdown_suite.end_per_group.19715266.html =group_props [{name,format_generator},sequence] -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:10 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok =elapsed 0.0 -=group_time 0.605s +=group_time 0.600s =case shell_docs_markdown_SUITE:init_per_group -=logfile shell_docs_markdown_suite.init_per_group.19698722.html +=logfile shell_docs_markdown_suite.init_per_group.19715298.html =group_props [{name,bullet_list_generator},sequence] -=started 2024-09-11 11:31:10 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok =elapsed 0.0 =case shell_docs_markdown_SUITE:singleton_bullet_list =logfile shell_docs_markdown_suite.singleton_bullet_list.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 4.0e-5 +=elapsed 4.2e-5 =case shell_docs_markdown_SUITE:singleton_bullet_list_followed_new_paragraph =logfile shell_docs_markdown_suite.singleton_bullet_list_followed_new_paragraph.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok =elapsed 6.6e-5 =case shell_docs_markdown_SUITE:singleton_bullet_list_with_format =logfile shell_docs_markdown_suite.singleton_bullet_list_with_format.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 4.9e-5 +=elapsed 5.1e-5 =case shell_docs_markdown_SUITE:singleton_bullet_list_followed_inner_paragraph =logfile shell_docs_markdown_suite.singleton_bullet_list_followed_inner_paragraph.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 5.7e-5 +=elapsed 5.9e-5 =case shell_docs_markdown_SUITE:singleton_bullet_list_followed_inner_paragraph2 =logfile shell_docs_markdown_suite.singleton_bullet_list_followed_inner_paragraph2.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 5.7e-5 +=elapsed 5.8e-5 =case shell_docs_markdown_SUITE:singleton_bullet_list_followed_inner_paragraph3 =logfile shell_docs_markdown_suite.singleton_bullet_list_followed_inner_paragraph3.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 1.15e-4 +=elapsed 1.42e-4 =case shell_docs_markdown_SUITE:multiline_bullet_indented_list =logfile shell_docs_markdown_suite.multiline_bullet_indented_list.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 5.5e-5 +=elapsed 5.6e-5 =case shell_docs_markdown_SUITE:multiline_bullet_indented_list2 =logfile shell_docs_markdown_suite.multiline_bullet_indented_list2.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 6.4e-5 +=elapsed 6.9e-5 =case shell_docs_markdown_SUITE:multiline_bullet_list =logfile shell_docs_markdown_suite.multiline_bullet_list.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 9.2e-5 +=elapsed 5.6e-5 =case shell_docs_markdown_SUITE:even_nested_bullet_list =logfile shell_docs_markdown_suite.even_nested_bullet_list.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 9.3e-5 +=elapsed 9.2e-5 =case shell_docs_markdown_SUITE:odd_nested_bullet_list =logfile shell_docs_markdown_suite.odd_nested_bullet_list.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 1.04e-4 +=elapsed 1.11e-4 =case shell_docs_markdown_SUITE:complex_nested_bullet_list =logfile shell_docs_markdown_suite.complex_nested_bullet_list.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 8.4e-5 +=elapsed 8.9e-5 =case shell_docs_markdown_SUITE:complex_nested_bullet_list2 =logfile shell_docs_markdown_suite.complex_nested_bullet_list2.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 1.61e-4 +=elapsed 1.6e-4 =case shell_docs_markdown_SUITE:complex_nested_bullet_list3 =logfile shell_docs_markdown_suite.complex_nested_bullet_list3.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 1.73e-4 +=elapsed 1.72e-4 =case shell_docs_markdown_SUITE:bullet_list_mix_with_number_list =logfile shell_docs_markdown_suite.bullet_list_mix_with_number_list.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 6.3e-5 +=elapsed 6.5e-5 =case shell_docs_markdown_SUITE:inline_code_list =logfile shell_docs_markdown_suite.inline_code_list.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 5.7e-5 +=elapsed 6.1e-5 =case shell_docs_markdown_SUITE:bullet_list_with_anchor =logfile shell_docs_markdown_suite.bullet_list_with_anchor.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 1.7e-4 +=elapsed 1.73e-4 =case shell_docs_markdown_SUITE:end_per_group -=logfile shell_docs_markdown_suite.end_per_group.19698754.html +=logfile shell_docs_markdown_suite.end_per_group.19715330.html =group_props [{name,bullet_list_generator},sequence] -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok =elapsed 0.0 -=group_time 0.403s +=group_time 0.404s =case shell_docs_markdown_SUITE:init_per_group -=logfile shell_docs_markdown_suite.init_per_group.19698786.html +=logfile shell_docs_markdown_suite.init_per_group.19715362.html =group_props [{name,numbered_list_generator},sequence] -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok =elapsed 0.0 =case shell_docs_markdown_SUITE:singleton_numbered_list =logfile shell_docs_markdown_suite.singleton_numbered_list.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok =elapsed 4.5e-5 =case shell_docs_markdown_SUITE:singleton_numbered_list_followed_new_paragraph =logfile shell_docs_markdown_suite.singleton_numbered_list_followed_new_paragraph.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 6.6e-5 +=elapsed 6.9e-5 =case shell_docs_markdown_SUITE:singleton_numbered_list_with_format =logfile shell_docs_markdown_suite.singleton_numbered_list_with_format.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 4.9e-5 +=elapsed 5.4e-5 =case shell_docs_markdown_SUITE:singleton_numbered_list_followed_inner_paragraph =logfile shell_docs_markdown_suite.singleton_numbered_list_followed_inner_paragraph.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 5.7e-5 +=elapsed 6.6e-5 =case shell_docs_markdown_SUITE:singleton_numbered_list_followed_inner_paragraph2 =logfile shell_docs_markdown_suite.singleton_numbered_list_followed_inner_paragraph2.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:22 =result ok -=elapsed 6.0e-5 +=elapsed 5.9e-5 =case shell_docs_markdown_SUITE:multiline_numbered_indented_list =logfile shell_docs_markdown_suite.multiline_numbered_indented_list.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:22 +=ended 2024-09-12 10:53:23 =result ok -=elapsed 6.4e-5 +=elapsed 6.3e-5 =case shell_docs_markdown_SUITE:multiline_numbered_indented_list2 =logfile shell_docs_markdown_suite.multiline_numbered_indented_list2.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok -=elapsed 6.4e-5 +=elapsed 6.8e-5 =case shell_docs_markdown_SUITE:multiline_numbered_list =logfile shell_docs_markdown_suite.multiline_numbered_list.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok -=elapsed 5.8e-5 +=elapsed 6.1e-5 =case shell_docs_markdown_SUITE:even_nested_numbered_list =logfile shell_docs_markdown_suite.even_nested_numbered_list.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok -=elapsed 9.2e-5 +=elapsed 9.0e-5 =case shell_docs_markdown_SUITE:odd_nested_numbered_list =logfile shell_docs_markdown_suite.odd_nested_numbered_list.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok =elapsed 1.04e-4 =case shell_docs_markdown_SUITE:end_per_group -=logfile shell_docs_markdown_suite.end_per_group.19698818.html +=logfile shell_docs_markdown_suite.end_per_group.19715394.html =group_props [{name,numbered_list_generator},sequence] -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok =elapsed 0.0 -=group_time 0.244s +=group_time 0.250s =case shell_docs_markdown_SUITE:init_per_group -=logfile shell_docs_markdown_suite.init_per_group.19698850.html +=logfile shell_docs_markdown_suite.init_per_group.19715426.html =group_props [{name,table_generator},sequence] -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok =elapsed 0.0 =case shell_docs_markdown_SUITE:table_with_rows =logfile shell_docs_markdown_suite.table_with_rows.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok -=elapsed 5.3e-5 +=elapsed 5.7e-5 =case shell_docs_markdown_SUITE:table_with_escaped_bars =logfile shell_docs_markdown_suite.table_with_escaped_bars.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok -=elapsed 6.3e-5 +=elapsed 9.2e-5 =case shell_docs_markdown_SUITE:fake_table_test =logfile shell_docs_markdown_suite.fake_table_test.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok -=elapsed 4.8e-5 +=elapsed 4.7e-5 =case shell_docs_markdown_SUITE:end_per_group -=logfile shell_docs_markdown_suite.end_per_group.19698882.html +=logfile shell_docs_markdown_suite.end_per_group.19715458.html =group_props [{name,table_generator},sequence] -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok =elapsed 0.0 -=group_time 0.090s +=group_time 0.088s =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.19698914.html +=logfile ct_framework.end_per_suite.19715490.html =group_props [{suite,shell_docs_markdown_SUITE}] -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok =elapsed 0.0 -=group_time 2.899s +=group_time 2.881s =case sigils_SUITE:init_per_suite =logfile sigils_suite.init_per_suite.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok =elapsed 0.0 =case sigils_SUITE:compiled_sigils =logfile sigils_suite.compiled_sigils.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok =elapsed 0.0 =case sigils_SUITE:scan_sigils =logfile sigils_suite.scan_sigils.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok -=elapsed 3.7e-5 +=elapsed 3.6e-5 =case sigils_SUITE:parse_sigils =logfile sigils_suite.parse_sigils.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok =elapsed 6.4e-5 =case sigils_SUITE:end_per_suite =logfile sigils_suite.end_per_suite.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok =elapsed 0.0 -=group_time 0.097s +=group_time 0.099s =case slave_SUITE:init_per_suite =logfile slave_suite.init_per_suite.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:11 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:23 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =case slave_SUITE:t_start_link =logfile slave_suite.t_start_link.html -=started 2024-09-11 11:31:11 -=ended 2024-09-11 11:31:13 +=started 2024-09-12 10:53:23 +=ended 2024-09-12 10:53:24 =result ok -=elapsed 1.094906 +=elapsed 1.119486 =case slave_SUITE:start_link_nodedown =logfile slave_suite.start_link_nodedown.html -=started 2024-09-11 11:31:13 -=ended 2024-09-11 11:31:13 +=started 2024-09-12 10:53:24 +=ended 2024-09-12 10:53:25 =result ok -=elapsed 0.512397 +=elapsed 0.520225 =case slave_SUITE:t_start =logfile slave_suite.t_start.html -=started 2024-09-11 11:31:13 -=ended 2024-09-11 11:31:15 +=started 2024-09-12 10:53:25 +=ended 2024-09-12 10:53:26 =result ok -=elapsed 1.606033 +=elapsed 1.622499 =case slave_SUITE:errors =logfile slave_suite.errors.html -=started 2024-09-11 11:31:15 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:26 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 32.180687 +=elapsed 32.478577 =case slave_SUITE:end_per_suite =logfile slave_suite.end_per_suite.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok =elapsed 0.0 -=group_time 35.531s +=group_time 35.879s =case sofs_SUITE:init_per_suite =logfile sofs_suite.init_per_suite.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =case sofs_SUITE:init_per_group =logfile sofs_suite.init_per_group.html =group_props [{name,sofs}] -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok =elapsed 0.0 =case sofs_SUITE:from_term_1 =logfile sofs_suite.from_term_1.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 6.3e-5 +=elapsed 4.7e-5 =case sofs_SUITE:set_1 =logfile sofs_suite.set_1.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 3.5e-5 +=elapsed 2.6e-5 =case sofs_SUITE:from_sets_1 =logfile sofs_suite.from_sets_1.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 2.6e-5 +=elapsed 2.1e-5 =case sofs_SUITE:relation_1 =logfile sofs_suite.relation_1.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 3.2e-5 +=elapsed 2.7e-5 =case sofs_SUITE:a_function_1 =logfile sofs_suite.a_function_1.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 3.5e-5 +=elapsed 2.9e-5 =case sofs_SUITE:family_1 =logfile sofs_suite.family_1.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 6.9e-5 +=elapsed 3.5e-5 =case sofs_SUITE:relation_to_family_1 =logfile sofs_suite.relation_to_family_1.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 7.0e-6 +=elapsed 5.0e-6 =case sofs_SUITE:domain_1 =logfile sofs_suite.domain_1.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 9.0e-6 +=elapsed 7.0e-6 =case sofs_SUITE:range_1 =logfile sofs_suite.range_1.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok =elapsed 6.0e-6 =case sofs_SUITE:image =logfile sofs_suite.image.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok =elapsed 1.2e-5 =case sofs_SUITE:inverse_image =logfile sofs_suite.inverse_image.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok =elapsed 1.2e-5 =case sofs_SUITE:inverse_1 =logfile sofs_suite.inverse_1.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 7.0e-6 +=elapsed 6.0e-6 =case sofs_SUITE:converse_1 =logfile sofs_suite.converse_1.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 4.0e-6 +=elapsed 5.0e-6 =case sofs_SUITE:no_elements_1 =logfile sofs_suite.no_elements_1.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 5.0e-6 +=elapsed 6.0e-6 =case sofs_SUITE:substitution =logfile sofs_suite.substitution.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 5.3e-5 +=elapsed 5.4e-5 =case sofs_SUITE:restriction =logfile sofs_suite.restriction.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 5.7e-5 +=elapsed 5.8e-5 =case sofs_SUITE:drestriction =logfile sofs_suite.drestriction.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 5.3e-5 +=elapsed 5.5e-5 =case sofs_SUITE:projection =logfile sofs_suite.projection.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 5.9e-5 +=elapsed 5.7e-5 =case sofs_SUITE:strict_relation_1 =logfile sofs_suite.strict_relation_1.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:47 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok =elapsed 4.0e-6 =case sofs_SUITE:extension =logfile sofs_suite.extension.html -=started 2024-09-11 11:31:47 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok =elapsed 1.8e-5 =case sofs_SUITE:weak_relation_1 =logfile sofs_suite.weak_relation_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 1.3e-5 +=elapsed 1.6e-5 =case sofs_SUITE:to_sets_1 =logfile sofs_suite.to_sets_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 8.0e-6 +=elapsed 1.0e-5 =case sofs_SUITE:specification =logfile sofs_suite.specification.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 1.1e-5 +=elapsed 1.4e-5 =case sofs_SUITE:union_1 =logfile sofs_suite.union_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 1.7e-5 +=elapsed 2.1e-5 =case sofs_SUITE:intersection_1 =logfile sofs_suite.intersection_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 1.0e-5 +=elapsed 1.3e-5 =case sofs_SUITE:difference =logfile sofs_suite.difference.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 7.0e-6 +=elapsed 9.0e-6 =case sofs_SUITE:symdiff =logfile sofs_suite.symdiff.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 1.1e-5 +=elapsed 1.3e-5 =case sofs_SUITE:symmetric_partition =logfile sofs_suite.symmetric_partition.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:53:59 =result ok -=elapsed 8.0e-6 +=elapsed 1.0e-5 =case sofs_SUITE:is_sofs_set_1 =logfile sofs_suite.is_sofs_set_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:53:59 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 1.0e-6 +=elapsed 2.0e-6 =case sofs_SUITE:is_set_1 =logfile sofs_suite.is_set_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok =elapsed 5.0e-6 =case sofs_SUITE:is_equal =logfile sofs_suite.is_equal.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 1.4e-5 +=elapsed 1.8e-5 =case sofs_SUITE:is_subset =logfile sofs_suite.is_subset.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 6.0e-6 +=elapsed 8.0e-6 =case sofs_SUITE:is_a_function_1 =logfile sofs_suite.is_a_function_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok =elapsed 5.0e-6 =case sofs_SUITE:is_disjoint =logfile sofs_suite.is_disjoint.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 4.0e-6 +=elapsed 5.0e-6 =case sofs_SUITE:join =logfile sofs_suite.join.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 2.6e-5 +=elapsed 3.5e-5 =case sofs_SUITE:canonical =logfile sofs_suite.canonical.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 6.0e-6 +=elapsed 7.0e-6 =case sofs_SUITE:composite_1 =logfile sofs_suite.composite_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 2.5e-5 +=elapsed 3.2e-5 =case sofs_SUITE:relative_product_1 =logfile sofs_suite.relative_product_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 1.2e-5 +=elapsed 1.5e-5 =case sofs_SUITE:relative_product_2 =logfile sofs_suite.relative_product_2.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 4.4e-5 +=elapsed 5.5e-5 =case sofs_SUITE:product_1 =logfile sofs_suite.product_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 1.3e-5 +=elapsed 1.6e-5 =case sofs_SUITE:partition_1 =logfile sofs_suite.partition_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 3.5e-5 +=elapsed 4.9e-5 =case sofs_SUITE:partition_3 =logfile sofs_suite.partition_3.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 7.9e-5 +=elapsed 1.02e-4 =case sofs_SUITE:multiple_relative_product =logfile sofs_suite.multiple_relative_product.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 2.6e-5 +=elapsed 3.1e-5 =case sofs_SUITE:digraph =logfile sofs_suite.digraph.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 8.37e-4 +=elapsed 2.29e-4 =case sofs_SUITE:constant_function =logfile sofs_suite.constant_function.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 6.0e-6 +=elapsed 1.1e-5 =case sofs_SUITE:misc =logfile sofs_suite.misc.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 5.76e-4 +=elapsed 7.15e-4 =case sofs_SUITE:end_per_group =logfile sofs_suite.end_per_group.html =group_props [{name,sofs}] -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok =elapsed 0.0 -=group_time 1.083s +=group_time 1.086s =case sofs_SUITE:init_per_group -=logfile sofs_suite.init_per_group.19699330.html +=logfile sofs_suite.init_per_group.19715874.html =group_props [{name,sofs_family}] -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok =elapsed 0.0 =case sofs_SUITE:family_specification =logfile sofs_suite.family_specification.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 1.0e-5 +=elapsed 1.9e-5 =case sofs_SUITE:family_domain_1 =logfile sofs_suite.family_domain_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 2.1e-5 +=elapsed 3.0e-5 =case sofs_SUITE:family_range_1 =logfile sofs_suite.family_range_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 1.8e-5 +=elapsed 2.4e-5 =case sofs_SUITE:family_to_relation_1 =logfile sofs_suite.family_to_relation_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 5.0e-6 +=elapsed 7.0e-6 =case sofs_SUITE:union_of_family_1 =logfile sofs_suite.union_of_family_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 9.0e-6 +=elapsed 1.3e-5 =case sofs_SUITE:intersection_of_family_1 =logfile sofs_suite.intersection_of_family_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 8.0e-6 +=elapsed 1.0e-5 =case sofs_SUITE:family_projection =logfile sofs_suite.family_projection.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 3.6e-5 +=elapsed 5.3e-5 =case sofs_SUITE:family_difference =logfile sofs_suite.family_difference.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 2.3e-5 +=elapsed 3.0e-5 =case sofs_SUITE:family_intersection_1 =logfile sofs_suite.family_intersection_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 1.2e-5 +=elapsed 1.5e-5 =case sofs_SUITE:family_intersection_2 =logfile sofs_suite.family_intersection_2.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 2.3e-5 +=elapsed 2.9e-5 =case sofs_SUITE:family_union_1 =logfile sofs_suite.family_union_1.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 8.0e-6 +=elapsed 1.6e-5 =case sofs_SUITE:family_union_2 =logfile sofs_suite.family_union_2.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 1.3e-5 +=elapsed 1.9e-5 =case sofs_SUITE:partition_family =logfile sofs_suite.partition_family.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 5.5e-5 +=elapsed 7.5e-5 =case sofs_SUITE:end_per_group -=logfile sofs_suite.end_per_group.19699362.html +=logfile sofs_suite.end_per_group.19715906.html =group_props [{name,sofs_family}] -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok =elapsed 0.0 -=group_time 0.309s +=group_time 0.321s =case sofs_SUITE:end_per_suite =logfile sofs_suite.end_per_suite.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:48 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok =elapsed 0.0 -=group_time 1.476s +=group_time 1.495s =case stdlib_SUITE:init_per_suite =logfile stdlib_suite.init_per_suite.html -=started 2024-09-11 11:31:48 -=ended 2024-09-11 11:31:49 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok =elapsed 0.0 =case stdlib_SUITE:app_test =logfile stdlib_suite.app_test.html -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 0.001519 +=elapsed 0.001781 =case stdlib_SUITE:appup_test =logfile stdlib_suite.appup_test.html -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result skipped: "This is a development version, test might fail because of incorrect version numbers" === *** SKIPPED test case 1925 *** =case stdlib_SUITE:assert_test =logfile stdlib_suite.assert_test.html -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok -=elapsed 1.9e-5 +=elapsed 2.7e-5 =case stdlib_SUITE:end_per_suite =logfile stdlib_suite.end_per_suite.html -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok =elapsed 0.0 -=group_time 0.109s +=group_time 0.112s =case stdlib_bench_SUITE:init_per_suite =logfile stdlib_bench_suite.init_per_suite.html -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 +=started 2024-09-12 10:54:00 +=ended 2024-09-12 10:54:00 =result ok =elapsed 0.0 === =case stdlib_bench_SUITE:init_per_group =group_props [{name,"unicode"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:00 =result skipped: Benchmark only === *** Skipping {stdlib_bench_SUITE,init_per_group} *** === =case stdlib_bench_SUITE:norm_nfc_list =group_props [{name,"unicode"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:00 =result skipped: Benchmark only === *** Skipping test case #1927 {stdlib_bench_SUITE,norm_nfc_list} *** === =case stdlib_bench_SUITE:norm_nfc_deep_l =group_props [{name,"unicode"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:00 =result skipped: Benchmark only === *** Skipping test case #1928 {stdlib_bench_SUITE,norm_nfc_deep_l} *** === =case stdlib_bench_SUITE:norm_nfc_binary =group_props [{name,"unicode"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:00 =result skipped: Benchmark only === *** Skipping test case #1929 {stdlib_bench_SUITE,norm_nfc_binary} *** === =case stdlib_bench_SUITE:string_lexemes_list =group_props [{name,"unicode"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:00 =result skipped: Benchmark only === *** Skipping test case #1930 {stdlib_bench_SUITE,string_lexemes_list} *** === =case stdlib_bench_SUITE:string_lexemes_binary =group_props [{name,"unicode"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:00 =result skipped: Benchmark only === *** Skipping test case #1931 {stdlib_bench_SUITE,string_lexemes_binary} *** === =case stdlib_bench_SUITE:end_per_group =group_props [{name,"unicode"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:00 =result skipped: Benchmark only === *** Skipping {stdlib_bench_SUITE,end_per_group} *** === =case stdlib_bench_SUITE:init_per_group =group_props [{name,"base64"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:00 =result skipped: Benchmark only === *** Skipping {stdlib_bench_SUITE,init_per_group} *** === =case stdlib_bench_SUITE:decode_binary =group_props [{name,"base64"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:00 =result skipped: Benchmark only === *** Skipping test case #1932 {stdlib_bench_SUITE,decode_binary} *** === =case stdlib_bench_SUITE:decode_binary_to_string =group_props [{name,"base64"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1933 {stdlib_bench_SUITE,decode_binary_to_string} *** === =case stdlib_bench_SUITE:decode_list =group_props [{name,"base64"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1934 {stdlib_bench_SUITE,decode_list} *** === =case stdlib_bench_SUITE:decode_list_to_string =group_props [{name,"base64"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1935 {stdlib_bench_SUITE,decode_list_to_string} *** === =case stdlib_bench_SUITE:encode_binary =group_props [{name,"base64"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1936 {stdlib_bench_SUITE,encode_binary} *** === =case stdlib_bench_SUITE:encode_binary_to_string =group_props [{name,"base64"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1937 {stdlib_bench_SUITE,encode_binary_to_string} *** === =case stdlib_bench_SUITE:encode_list =group_props [{name,"base64"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1938 {stdlib_bench_SUITE,encode_list} *** === =case stdlib_bench_SUITE:encode_list_to_string =group_props [{name,"base64"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1939 {stdlib_bench_SUITE,encode_list_to_string} *** === =case stdlib_bench_SUITE:mime_binary_decode =group_props [{name,"base64"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1940 {stdlib_bench_SUITE,mime_binary_decode} *** === =case stdlib_bench_SUITE:mime_binary_decode_to_string =group_props [{name,"base64"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1941 {stdlib_bench_SUITE,mime_binary_decode_to_string} *** === =case stdlib_bench_SUITE:mime_list_decode =group_props [{name,"base64"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1942 {stdlib_bench_SUITE,mime_list_decode} *** === =case stdlib_bench_SUITE:mime_list_decode_to_string =group_props [{name,"base64"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1943 {stdlib_bench_SUITE,mime_list_decode_to_string} *** === =case stdlib_bench_SUITE:end_per_group =group_props [{name,"base64"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping {stdlib_bench_SUITE,end_per_group} *** === =case stdlib_bench_SUITE:init_per_group =group_props [{name,"binary"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping {stdlib_bench_SUITE,init_per_group} *** === =case stdlib_bench_SUITE:match_single_pattern_no_match =group_props [{name,"binary"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1944 {stdlib_bench_SUITE,match_single_pattern_no_match} *** === =case stdlib_bench_SUITE:matches_single_pattern_no_match =group_props [{name,"binary"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1945 {stdlib_bench_SUITE,matches_single_pattern_no_match} *** === =case stdlib_bench_SUITE:matches_single_pattern_eventual_match =group_props [{name,"binary"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1946 {stdlib_bench_SUITE,matches_single_pattern_eventual_match} *** === =case stdlib_bench_SUITE:matches_single_pattern_frequent_match =group_props [{name,"binary"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1947 {stdlib_bench_SUITE,matches_single_pattern_frequent_match} *** === =case stdlib_bench_SUITE:end_per_group =group_props [{name,"binary"}] -=started 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping {stdlib_bench_SUITE,end_per_group} *** =case stdlib_bench_SUITE:init_per_group =logfile stdlib_bench_suite.init_per_group.html =group_props [{name,io},{repeat,5}] -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =case stdlib_bench_SUITE:double_random_to_list =logfile stdlib_bench_suite.double_random_to_list.html -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 -=result ok: 7803355 -=elapsed 0.041173 +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 +=result ok: 7279610 +=elapsed 0.041719 =case stdlib_bench_SUITE:double_random_to_list_array =logfile stdlib_bench_suite.double_random_to_list_array.html -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 -=result ok: 6641870 -=elapsed 0.040255 +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 +=result ok: 6803184 +=elapsed 0.038627 =case stdlib_bench_SUITE:end_per_group =logfile stdlib_bench_suite.end_per_group.html =group_props [{name,io},{repeat,5}] -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =group_time 0.150s =case stdlib_bench_SUITE:init_per_group -=logfile stdlib_bench_suite.init_per_group.19699394.html +=logfile stdlib_bench_suite.init_per_group.19715938.html =group_props [{repeat,4},{name,io}] -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 =result ok =elapsed 0.0 =case stdlib_bench_SUITE:double_random_to_list -=logfile stdlib_bench_suite.double_random_to_list.19699426.html -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 -=result ok: 9134088 -=elapsed 0.033068 +=logfile stdlib_bench_suite.double_random_to_list.19715970.html +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 +=result ok: 7820443 +=elapsed 0.035209 =case stdlib_bench_SUITE:double_random_to_list_array -=logfile stdlib_bench_suite.double_random_to_list_array.19699458.html -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 -=result ok: 6382028 -=elapsed 0.04262 +=logfile stdlib_bench_suite.double_random_to_list_array.19716002.html +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 +=result ok: 6273526 +=elapsed 0.043084 =case stdlib_bench_SUITE:end_per_group -=logfile stdlib_bench_suite.end_per_group.19699490.html +=logfile stdlib_bench_suite.end_per_group.19716034.html =group_props [{repeat,4},{name,io}] -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 =result ok =elapsed 0.0 -=group_time 0.144s +=group_time 0.147s =case stdlib_bench_SUITE:init_per_group -=logfile stdlib_bench_suite.init_per_group.19699522.html +=logfile stdlib_bench_suite.init_per_group.19716066.html =group_props [{repeat,3},{name,io}] -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 =result ok =elapsed 0.0 =case stdlib_bench_SUITE:double_random_to_list -=logfile stdlib_bench_suite.double_random_to_list.19699554.html -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 -=result ok: 9508415 -=elapsed 0.033047 +=logfile stdlib_bench_suite.double_random_to_list.19716098.html +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 +=result ok: 8820676 +=elapsed 0.033821 =case stdlib_bench_SUITE:double_random_to_list_array -=logfile stdlib_bench_suite.double_random_to_list_array.19699586.html -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 -=result ok: 6242977 -=elapsed 0.043026 +=logfile stdlib_bench_suite.double_random_to_list_array.19716130.html +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 +=result ok: 6028818 +=elapsed 0.043152 =case stdlib_bench_SUITE:end_per_group -=logfile stdlib_bench_suite.end_per_group.19699618.html +=logfile stdlib_bench_suite.end_per_group.19716162.html =group_props [{repeat,3},{name,io}] -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 =result ok =elapsed 0.0 -=group_time 0.144s +=group_time 0.146s =case stdlib_bench_SUITE:init_per_group -=logfile stdlib_bench_suite.init_per_group.19699650.html +=logfile stdlib_bench_suite.init_per_group.19716194.html =group_props [{repeat,2},{name,io}] -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 =result ok =elapsed 0.0 =case stdlib_bench_SUITE:double_random_to_list -=logfile stdlib_bench_suite.double_random_to_list.19699682.html -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 -=result ok: 8968610 -=elapsed 0.03334 +=logfile stdlib_bench_suite.double_random_to_list.19716226.html +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 +=result ok: 8950148 +=elapsed 0.033312 =case stdlib_bench_SUITE:double_random_to_list_array -=logfile stdlib_bench_suite.double_random_to_list_array.19699714.html -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 -=result ok: 6394680 -=elapsed 0.043227 +=logfile stdlib_bench_suite.double_random_to_list_array.19716258.html +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 +=result ok: 6073489 +=elapsed 0.043964 =case stdlib_bench_SUITE:end_per_group -=logfile stdlib_bench_suite.end_per_group.19699746.html +=logfile stdlib_bench_suite.end_per_group.19716290.html =group_props [{repeat,2},{name,io}] -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 =result ok -=elapsed 0.0 -=group_time 0.145s +=elapsed 1.0e-6 +=group_time 0.146s =case stdlib_bench_SUITE:init_per_group -=logfile stdlib_bench_suite.init_per_group.19699778.html +=logfile stdlib_bench_suite.init_per_group.19716322.html =group_props [{name,io}] -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 =result ok =elapsed 0.0 =case stdlib_bench_SUITE:double_random_to_list -=logfile stdlib_bench_suite.double_random_to_list.19699810.html -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:49 -=result ok: 8208159 -=elapsed 0.035807 +=logfile stdlib_bench_suite.double_random_to_list.19716354.html +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 +=result ok: 8274721 +=elapsed 0.037712 =case stdlib_bench_SUITE:double_random_to_list_array -=logfile stdlib_bench_suite.double_random_to_list_array.19699842.html -=started 2024-09-11 11:31:49 -=ended 2024-09-11 11:31:50 -=result ok: 6660450 -=elapsed 0.041082 +=logfile stdlib_bench_suite.double_random_to_list_array.19716386.html +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 +=result ok: 6355663 +=elapsed 0.042745 =case stdlib_bench_SUITE:end_per_group -=logfile stdlib_bench_suite.end_per_group.19699874.html +=logfile stdlib_bench_suite.end_per_group.19716418.html =group_props [{name,io}] -=started 2024-09-11 11:31:50 -=ended 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:01 =result ok -=elapsed 1.0e-6 -=group_time 0.145s +=elapsed 0.0 +=group_time 0.150s === =case stdlib_bench_SUITE:init_per_group =group_props [{name,"gen_server"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping {stdlib_bench_SUITE,init_per_group} *** === =case stdlib_bench_SUITE:simple =group_props [{name,"gen_server"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1958 {stdlib_bench_SUITE,simple} *** === =case stdlib_bench_SUITE:simple_timer =group_props [{name,"gen_server"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1959 {stdlib_bench_SUITE,simple_timer} *** === =case stdlib_bench_SUITE:simple_mon =group_props [{name,"gen_server"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1960 {stdlib_bench_SUITE,simple_mon} *** === =case stdlib_bench_SUITE:simple_timer_mon =group_props [{name,"gen_server"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1961 {stdlib_bench_SUITE,simple_timer_mon} *** === =case stdlib_bench_SUITE:generic =group_props [{name,"gen_server"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1962 {stdlib_bench_SUITE,generic} *** === =case stdlib_bench_SUITE:generic_timer =group_props [{name,"gen_server"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1963 {stdlib_bench_SUITE,generic_timer} *** === =case stdlib_bench_SUITE:end_per_group =group_props [{name,"gen_server"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping {stdlib_bench_SUITE,end_per_group} *** === =case stdlib_bench_SUITE:init_per_group =group_props [{name,"gen_statem"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping {stdlib_bench_SUITE,init_per_group} *** === =case stdlib_bench_SUITE:generic =group_props [{name,"gen_statem"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1964 {stdlib_bench_SUITE,generic} *** === =case stdlib_bench_SUITE:generic_log =group_props [{name,"gen_statem"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1965 {stdlib_bench_SUITE,generic_log} *** === =case stdlib_bench_SUITE:generic_log100 =group_props [{name,"gen_statem"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1966 {stdlib_bench_SUITE,generic_log100} *** === =case stdlib_bench_SUITE:generic_fsm =group_props [{name,"gen_statem"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1967 {stdlib_bench_SUITE,generic_fsm} *** === =case stdlib_bench_SUITE:generic_fsm_transit =group_props [{name,"gen_statem"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1968 {stdlib_bench_SUITE,generic_fsm_transit} *** === =case stdlib_bench_SUITE:generic_statem =group_props [{name,"gen_statem"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1969 {stdlib_bench_SUITE,generic_statem} *** === =case stdlib_bench_SUITE:generic_statem_log =group_props [{name,"gen_statem"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1970 {stdlib_bench_SUITE,generic_statem_log} *** === =case stdlib_bench_SUITE:generic_statem_log100 =group_props [{name,"gen_statem"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1971 {stdlib_bench_SUITE,generic_statem_log100} *** === =case stdlib_bench_SUITE:generic_statem_transit =group_props [{name,"gen_statem"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1972 {stdlib_bench_SUITE,generic_statem_transit} *** === =case stdlib_bench_SUITE:generic_statem_complex =group_props [{name,"gen_statem"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping test case #1973 {stdlib_bench_SUITE,generic_statem_complex} *** === =case stdlib_bench_SUITE:end_per_group =group_props [{name,"gen_statem"}] -=started 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 =result skipped: Benchmark only === *** Skipping {stdlib_bench_SUITE,end_per_group} *** =case stdlib_bench_SUITE:init_per_group -=logfile stdlib_bench_suite.init_per_group.19699906.html +=logfile stdlib_bench_suite.init_per_group.19716450.html =group_props [{name,gen_server_comparison}] -=started 2024-09-11 11:31:50 -=ended 2024-09-11 11:31:50 +=started 2024-09-12 10:54:01 +=ended 2024-09-12 10:54:02 =result ok -=elapsed 0.037858 +=elapsed 0.038917 =case stdlib_bench_SUITE:single_small =logfile stdlib_bench_suite.single_small.html -=started 2024-09-11 11:31:50 -=ended 2024-09-11 11:31:56 -=result ok: #parallel gen_server instances: 1, message flat size: 0 bytes: simple: 1.00 simple_timer: 1.37 simple_mon: 1.68 simple_timer_mon: 2.09 generic: 1.89 generic_timer: 2.47 -=elapsed 6.028182 +=started 2024-09-12 10:54:02 +=ended 2024-09-12 10:54:08 +=result ok: #parallel gen_server instances: 1, message flat size: 0 bytes: simple: 1.00 simple_timer: 1.34 simple_mon: 1.71 simple_timer_mon: 2.08 generic: 1.94 generic_timer: 2.53 +=elapsed 6.036802 =case stdlib_bench_SUITE:single_medium =logfile stdlib_bench_suite.single_medium.html -=started 2024-09-11 11:31:56 -=ended 2024-09-11 11:32:02 -=result ok: #parallel gen_server instances: 1, message flat size: 800 bytes: simple: 1.00 simple_timer: 1.13 simple_mon: 1.45 simple_timer_mon: 1.60 generic: 1.17 generic_timer: 1.53 -=elapsed 6.005332 +=started 2024-09-12 10:54:08 +=ended 2024-09-12 10:54:14 +=result ok: #parallel gen_server instances: 1, message flat size: 800 bytes: simple: 1.00 simple_timer: 1.11 simple_mon: 1.41 simple_timer_mon: 1.57 generic: 1.18 generic_timer: 1.50 +=elapsed 6.006128 =case stdlib_bench_SUITE:single_big =logfile stdlib_bench_suite.single_big.html -=started 2024-09-11 11:32:02 -=ended 2024-09-11 11:32:08 -=result ok: #parallel gen_server instances: 1, message flat size: 16000 bytes: simple: 1.00 simple_timer: 1.00 simple_mon: 1.09 simple_timer_mon: 1.11 generic: 0.97 generic_timer: 1.02 -=elapsed 6.005935 +=started 2024-09-12 10:54:14 +=ended 2024-09-12 10:54:20 +=result ok: #parallel gen_server instances: 1, message flat size: 16000 bytes: simple: 1.00 simple_timer: 1.03 simple_mon: 1.11 simple_timer_mon: 1.14 generic: 1.00 generic_timer: 1.01 +=elapsed 6.006064 =case stdlib_bench_SUITE:sched_small =logfile stdlib_bench_suite.sched_small.html -=started 2024-09-11 11:32:08 -=ended 2024-09-11 11:32:14 -=result ok: #parallel gen_server instances: 4, message flat size: 0 bytes: simple: 1.00 simple_timer: 1.66 simple_mon: 2.00 simple_timer_mon: 2.06 generic: 1.55 generic_timer: 2.20 -=elapsed 6.006134 +=started 2024-09-12 10:54:20 +=ended 2024-09-12 10:54:26 +=result ok: #parallel gen_server instances: 4, message flat size: 0 bytes: simple: 1.00 simple_timer: 1.27 simple_mon: 1.55 simple_timer_mon: 1.74 generic: 1.29 generic_timer: 1.72 +=elapsed 6.005998 =case stdlib_bench_SUITE:sched_medium =logfile stdlib_bench_suite.sched_medium.html -=started 2024-09-11 11:32:14 -=ended 2024-09-11 11:32:20 -=result ok: #parallel gen_server instances: 4, message flat size: 800 bytes: simple: 1.00 simple_timer: 1.07 simple_mon: 1.33 simple_timer_mon: 1.59 generic: 1.37 generic_timer: 1.49 -=elapsed 6.005551 +=started 2024-09-12 10:54:26 +=ended 2024-09-12 10:54:32 +=result ok: #parallel gen_server instances: 4, message flat size: 800 bytes: simple: 1.00 simple_timer: 1.05 simple_mon: 1.28 simple_timer_mon: 1.47 generic: 1.29 generic_timer: 1.45 +=elapsed 6.005909 =case stdlib_bench_SUITE:sched_big =logfile stdlib_bench_suite.sched_big.html -=started 2024-09-11 11:32:20 -=ended 2024-09-11 11:32:26 -=result ok: #parallel gen_server instances: 4, message flat size: 16000 bytes: simple: 1.00 simple_timer: 1.09 simple_mon: 0.98 simple_timer_mon: 1.00 generic: 0.94 generic_timer: 1.00 -=elapsed 6.00561 +=started 2024-09-12 10:54:32 +=ended 2024-09-12 10:54:38 +=result ok: #parallel gen_server instances: 4, message flat size: 16000 bytes: simple: 1.00 simple_timer: 1.13 simple_mon: 1.05 simple_timer_mon: 1.10 generic: 0.95 generic_timer: 0.99 +=elapsed 6.005938 =case stdlib_bench_SUITE:multi_small =logfile stdlib_bench_suite.multi_small.html -=started 2024-09-11 11:32:26 -=ended 2024-09-11 11:32:32 -=result ok: #parallel gen_server instances: 400, message flat size: 0 bytes: simple: 1.00 simple_timer: 1.08 simple_mon: 1.39 simple_timer_mon: 1.45 generic: 1.49 generic_timer: 1.81 -=elapsed 6.070889 +=started 2024-09-12 10:54:38 +=ended 2024-09-12 10:54:44 +=result ok: #parallel gen_server instances: 400, message flat size: 0 bytes: simple: 1.00 simple_timer: 1.06 simple_mon: 1.34 simple_timer_mon: 1.40 generic: 1.48 generic_timer: 1.75 +=elapsed 6.074452 =case stdlib_bench_SUITE:multi_medium =logfile stdlib_bench_suite.multi_medium.html -=started 2024-09-11 11:32:32 -=ended 2024-09-11 11:32:38 -=result ok: #parallel gen_server instances: 400, message flat size: 800 bytes: simple: 1.00 simple_timer: 1.09 simple_mon: 1.26 simple_timer_mon: 1.32 generic: 1.28 generic_timer: 1.43 -=elapsed 6.058794 +=started 2024-09-12 10:54:44 +=ended 2024-09-12 10:54:50 +=result ok: #parallel gen_server instances: 400, message flat size: 800 bytes: simple: 1.00 simple_timer: 1.09 simple_mon: 1.25 simple_timer_mon: 1.29 generic: 1.26 generic_timer: 1.47 +=elapsed 6.057093 =case stdlib_bench_SUITE:multi_big =logfile stdlib_bench_suite.multi_big.html -=started 2024-09-11 11:32:38 -=ended 2024-09-11 11:32:44 -=result ok: #parallel gen_server instances: 400, message flat size: 16000 bytes: simple: 1.00 simple_timer: 1.02 simple_mon: 1.02 simple_timer_mon: 1.07 generic: 1.06 generic_timer: 1.09 -=elapsed 6.048533 +=started 2024-09-12 10:54:50 +=ended 2024-09-12 10:54:56 +=result ok: #parallel gen_server instances: 400, message flat size: 16000 bytes: simple: 1.00 simple_timer: 1.00 simple_mon: 1.04 simple_timer_mon: 1.03 generic: 1.03 generic_timer: 1.03 +=elapsed 6.049427 =case stdlib_bench_SUITE:end_per_group -=logfile stdlib_bench_suite.end_per_group.504003.html +=logfile stdlib_bench_suite.end_per_group.19716482.html =group_props [{name,gen_server_comparison}] -=started 2024-09-11 11:32:44 -=ended 2024-09-11 11:32:44 +=started 2024-09-12 10:54:56 +=ended 2024-09-12 10:54:56 =result ok =elapsed 0.0 -=group_time 54.505s +=group_time 54.518s =case stdlib_bench_SUITE:init_per_group -=logfile stdlib_bench_suite.init_per_group.504035.html +=logfile stdlib_bench_suite.init_per_group.19716514.html =group_props [{name,gen_statem_comparison}] -=started 2024-09-11 11:32:44 -=ended 2024-09-11 11:32:44 +=started 2024-09-12 10:54:56 +=ended 2024-09-12 10:54:56 =result ok -=elapsed 0.038629 +=elapsed 0.038493 =case stdlib_bench_SUITE:single_small -=logfile stdlib_bench_suite.single_small.504067.html -=started 2024-09-11 11:32:44 -=ended 2024-09-11 11:32:54 -=result ok: #parallel gen_server instances: 1, message flat size: 0 bytes: generic: 1.00 generic_log: 1.11 generic_log100: 1.12 generic_fsm: 1.07 generic_fsm_transit: 1.07 generic_statem: 1.11 generic_statem_log: 1.39 generic_statem_log100: 1.27 generic_statem_transit: 1.90 generic_statem_complex: 2.88 -=elapsed 10.025853 +=logfile stdlib_bench_suite.single_small.408131.html +=started 2024-09-12 10:54:56 +=ended 2024-09-12 10:55:06 +=result ok: #parallel gen_server instances: 1, message flat size: 0 bytes: generic: 1.00 generic_log: 1.10 generic_log100: 1.10 generic_fsm: 1.03 generic_fsm_transit: 1.00 generic_statem: 1.02 generic_statem_log: 1.26 generic_statem_log100: 1.16 generic_statem_transit: 1.75 generic_statem_complex: 2.55 +=elapsed 10.024899 =case stdlib_bench_SUITE:single_big -=logfile stdlib_bench_suite.single_big.504099.html -=started 2024-09-11 11:32:54 -=ended 2024-09-11 11:33:04 -=result ok: #parallel gen_server instances: 1, message flat size: 16000 bytes: generic: 1.00 generic_log: 0.92 generic_log100: 1.29 generic_fsm: 1.03 generic_fsm_transit: 1.02 generic_statem: 1.02 generic_statem_log: 0.98 generic_statem_log100: 1.17 generic_statem_transit: 1.07 generic_statem_complex: 1.14 -=elapsed 10.009321 +=logfile stdlib_bench_suite.single_big.408163.html +=started 2024-09-12 10:55:06 +=ended 2024-09-12 10:55:16 +=result ok: #parallel gen_server instances: 1, message flat size: 16000 bytes: generic: 1.00 generic_log: 0.91 generic_log100: 1.30 generic_fsm: 1.00 generic_fsm_transit: 1.00 generic_statem: 0.99 generic_statem_log: 0.95 generic_statem_log100: 1.21 generic_statem_transit: 1.05 generic_statem_complex: 1.17 +=elapsed 10.009708 =case stdlib_bench_SUITE:sched_small -=logfile stdlib_bench_suite.sched_small.504131.html -=started 2024-09-11 11:33:04 -=ended 2024-09-11 11:33:14 -=result ok: #parallel gen_server instances: 4, message flat size: 0 bytes: generic: 1.00 generic_log: 1.00 generic_log100: 0.98 generic_fsm: 0.97 generic_fsm_transit: 0.99 generic_statem: 1.02 generic_statem_log: 1.22 generic_statem_log100: 1.13 generic_statem_transit: 2.00 generic_statem_complex: 3.39 -=elapsed 10.009744 +=logfile stdlib_bench_suite.sched_small.408195.html +=started 2024-09-12 10:55:16 +=ended 2024-09-12 10:55:26 +=result ok: #parallel gen_server instances: 4, message flat size: 0 bytes: generic: 1.00 generic_log: 1.04 generic_log100: 1.04 generic_fsm: 0.96 generic_fsm_transit: 1.00 generic_statem: 1.07 generic_statem_log: 1.25 generic_statem_log100: 1.13 generic_statem_transit: 2.13 generic_statem_complex: 3.46 +=elapsed 10.009841 =case stdlib_bench_SUITE:sched_big -=logfile stdlib_bench_suite.sched_big.504163.html -=started 2024-09-11 11:33:14 -=ended 2024-09-11 11:33:24 -=result ok: #parallel gen_server instances: 4, message flat size: 16000 bytes: generic: 1.00 generic_log: 1.09 generic_log100: 1.44 generic_fsm: 0.98 generic_fsm_transit: 0.98 generic_statem: 1.01 generic_statem_log: 1.24 generic_statem_log100: 1.54 generic_statem_transit: 1.06 generic_statem_complex: 1.15 -=elapsed 10.009576 +=logfile stdlib_bench_suite.sched_big.408227.html +=started 2024-09-12 10:55:26 +=ended 2024-09-12 10:55:36 +=result ok: #parallel gen_server instances: 4, message flat size: 16000 bytes: generic: 1.00 generic_log: 1.16 generic_log100: 1.55 generic_fsm: 1.12 generic_fsm_transit: 1.01 generic_statem: 1.09 generic_statem_log: 1.24 generic_statem_log100: 1.62 generic_statem_transit: 1.08 generic_statem_complex: 1.18 +=elapsed 10.009673 =case stdlib_bench_SUITE:multi_small -=logfile stdlib_bench_suite.multi_small.504195.html -=started 2024-09-11 11:33:24 -=ended 2024-09-11 11:33:34 -=result ok: #parallel gen_server instances: 400, message flat size: 0 bytes: generic: 1.00 generic_log: 1.23 generic_log100: 1.14 generic_fsm: 1.02 generic_fsm_transit: 1.05 generic_statem: 1.16 generic_statem_log: 1.88 generic_statem_log100: 1.54 generic_statem_transit: 2.17 generic_statem_complex: 3.67 -=elapsed 10.07048 +=logfile stdlib_bench_suite.multi_small.408259.html +=started 2024-09-12 10:55:36 +=ended 2024-09-12 10:55:46 +=result ok: #parallel gen_server instances: 400, message flat size: 0 bytes: generic: 1.00 generic_log: 1.21 generic_log100: 1.14 generic_fsm: 1.03 generic_fsm_transit: 1.05 generic_statem: 1.15 generic_statem_log: 1.83 generic_statem_log100: 1.53 generic_statem_transit: 2.12 generic_statem_complex: 3.72 +=elapsed 10.069921 =case stdlib_bench_SUITE:multi_big -=logfile stdlib_bench_suite.multi_big.504227.html -=started 2024-09-11 11:33:34 -=ended 2024-09-11 11:33:45 -=result ok: #parallel gen_server instances: 400, message flat size: 16000 bytes: generic: 1.00 generic_log: 1.04 generic_log100: 1.02 generic_fsm: 1.04 generic_fsm_transit: 1.02 generic_statem: 1.02 generic_statem_log: 1.09 generic_statem_log100: 1.03 generic_statem_transit: 1.14 generic_statem_complex: 1.29 -=elapsed 10.096432 +=logfile stdlib_bench_suite.multi_big.408291.html +=started 2024-09-12 10:55:46 +=ended 2024-09-12 10:55:56 +=result ok: #parallel gen_server instances: 400, message flat size: 16000 bytes: generic: 1.00 generic_log: 1.04 generic_log100: 1.01 generic_fsm: 1.01 generic_fsm_transit: 1.00 generic_statem: 0.98 generic_statem_log: 1.03 generic_statem_log100: 1.10 generic_statem_transit: 1.11 generic_statem_complex: 1.23 +=elapsed 10.081999 =case stdlib_bench_SUITE:end_per_group -=logfile stdlib_bench_suite.end_per_group.377093.html +=logfile stdlib_bench_suite.end_per_group.408323.html =group_props [{name,gen_statem_comparison}] -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:56 +=ended 2024-09-12 10:55:56 =result ok =elapsed 1.0e-6 -=group_time 60.423s +=group_time 60.408s =case stdlib_bench_SUITE:end_per_suite =logfile stdlib_bench_suite.end_per_suite.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:56 +=ended 2024-09-12 10:55:56 =result ok =elapsed 0.0 -=group_time 115.981s +=group_time 116.005s =case string_SUITE:init_per_suite =logfile string_suite.init_per_suite.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:56 +=ended 2024-09-12 10:55:57 =result ok =elapsed 0.0 =case string_SUITE:init_per_group =logfile string_suite.init_per_group.html =group_props [{name,chardata}] -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok =elapsed 0.0 =case string_SUITE:is_empty =logfile string_suite.is_empty.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 1.3e-5 +=elapsed 1.4e-5 =case string_SUITE:length =logfile string_suite.length.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 6.2e-5 +=elapsed 5.2e-5 =case string_SUITE:to_graphemes =logfile string_suite.to_graphemes.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 2.2e-5 +=elapsed 2.0e-5 =case string_SUITE:equal =logfile string_suite.equal.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 4.15e-4 +=elapsed 3.65e-4 =case string_SUITE:reverse =logfile string_suite.reverse.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 2.3e-5 +=elapsed 2.7e-5 =case string_SUITE:slice =logfile string_suite.slice.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 9.0e-5 +=elapsed 1.14e-4 =case string_SUITE:pad =logfile string_suite.pad.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 7.1e-5 +=elapsed 1.06e-4 =case string_SUITE:trim =logfile string_suite.trim.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 4.26e-4 +=elapsed 4.28e-4 =case string_SUITE:chomp =logfile string_suite.chomp.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 1.77e-4 +=elapsed 0.0002 =case string_SUITE:take =logfile string_suite.take.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 0.001565 +=elapsed 0.001579 =case string_SUITE:lexemes =logfile string_suite.lexemes.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 9.53e-4 +=elapsed 0.001066 =case string_SUITE:nth_lexeme =logfile string_suite.nth_lexeme.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 5.54e-4 +=elapsed 5.71e-4 =case string_SUITE:to_integer =logfile string_suite.to_integer.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 6.0e-5 +=elapsed 9.2e-5 =case string_SUITE:to_float =logfile string_suite.to_float.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 8.4e-5 +=elapsed 8.6e-5 =case string_SUITE:uppercase =logfile string_suite.uppercase.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 1.34e-4 +=elapsed 0.0001 =case string_SUITE:lowercase =logfile string_suite.lowercase.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 1.09e-4 +=elapsed 8.2e-5 =case string_SUITE:titlecase =logfile string_suite.titlecase.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 1.57e-4 +=elapsed 1.05e-4 =case string_SUITE:casefold =logfile string_suite.casefold.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 8.9e-5 +=elapsed 9.3e-5 =case string_SUITE:prefix =logfile string_suite.prefix.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 1.36e-4 +=elapsed 9.3e-5 =case string_SUITE:find =logfile string_suite.find.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 3.3e-4 +=elapsed 3.49e-4 =case string_SUITE:split =logfile string_suite.split.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 0.001213 +=elapsed 0.001037 =case string_SUITE:replace =logfile string_suite.replace.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 6.5e-5 +=elapsed 6.3e-5 =case string_SUITE:cd_gc =logfile string_suite.cd_gc.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 6.0e-6 +=elapsed 7.0e-6 =case string_SUITE:jaro_similarity =logfile string_suite.jaro_similarity.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:33:45 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:55:57 =result ok -=elapsed 1.24e-4 +=elapsed 1.23e-4 =case string_SUITE:meas =logfile string_suite.meas.html -=started 2024-09-11 11:33:45 -=ended 2024-09-11 11:34:37 +=started 2024-09-12 10:55:57 +=ended 2024-09-12 10:56:49 =result ok -=elapsed 52.243697 +=elapsed 52.280746 =case string_SUITE:end_per_group =logfile string_suite.end_per_group.html =group_props [{name,chardata}] -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:49 +=ended 2024-09-12 10:56:49 =result ok =elapsed 0.0 -=group_time 52.835s +=group_time 52.877s =case string_SUITE:init_per_group -=logfile string_suite.init_per_group.19699938.html +=logfile string_suite.init_per_group.408355.html =group_props [{name,list_string}] -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:49 +=ended 2024-09-12 10:56:49 =result ok =elapsed 0.0 =case string_SUITE:len =logfile string_suite.len.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:49 +=ended 2024-09-12 10:56:49 =result ok =elapsed 5.0e-6 =case string_SUITE:old_equal =logfile string_suite.old_equal.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:49 +=ended 2024-09-12 10:56:49 =result ok =elapsed 1.0e-6 =case string_SUITE:old_concat =logfile string_suite.old_concat.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:49 +=ended 2024-09-12 10:56:49 =result ok -=elapsed 2.0e-6 +=elapsed 4.0e-6 =case string_SUITE:chr_rchr =logfile string_suite.chr_rchr.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:49 +=ended 2024-09-12 10:56:50 =result ok -=elapsed 4.0e-6 +=elapsed 7.0e-6 =case string_SUITE:str_rstr =logfile string_suite.str_rstr.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok -=elapsed 5.0e-6 +=elapsed 7.0e-6 =case string_SUITE:span_cspan =logfile string_suite.span_cspan.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok =elapsed 6.0e-6 =case string_SUITE:substr =logfile string_suite.substr.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok =elapsed 6.0e-6 =case string_SUITE:old_tokens =logfile string_suite.old_tokens.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok -=elapsed 4.0e-5 +=elapsed 4.1e-5 =case string_SUITE:chars =logfile string_suite.chars.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok -=elapsed 2.0e-6 +=elapsed 3.0e-6 =case string_SUITE:copies =logfile string_suite.copies.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok =elapsed 4.0e-6 =case string_SUITE:words =logfile string_suite.words.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok -=elapsed 8.0e-6 +=elapsed 9.0e-6 =case string_SUITE:strip =logfile string_suite.strip.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok -=elapsed 7.0e-6 +=elapsed 6.0e-6 =case string_SUITE:sub_word =logfile string_suite.sub_word.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok -=elapsed 5.0e-6 +=elapsed 6.0e-6 =case string_SUITE:left_right =logfile string_suite.left_right.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok =elapsed 6.0e-6 =case string_SUITE:sub_string =logfile string_suite.sub_string.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok =elapsed 6.0e-6 =case string_SUITE:centre =logfile string_suite.centre.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok =elapsed 3.0e-6 =case string_SUITE:join =logfile string_suite.join.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok -=elapsed 3.0e-6 +=elapsed 4.0e-6 =case string_SUITE:old_to_integer =logfile string_suite.old_to_integer.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok -=elapsed 4.0e-5 +=elapsed 4.2e-5 =case string_SUITE:old_to_float =logfile string_suite.old_to_float.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok -=elapsed 4.9e-5 +=elapsed 5.2e-5 =case string_SUITE:to_upper_to_lower =logfile string_suite.to_upper_to_lower.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok =elapsed 6.8e-5 =case string_SUITE:end_per_group -=logfile string_suite.end_per_group.19699970.html +=logfile string_suite.end_per_group.19716546.html =group_props [{name,list_string}] -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok =elapsed 0.0 -=group_time 0.463s +=group_time 0.470s =case string_SUITE:end_per_suite =logfile string_suite.end_per_suite.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok =elapsed 0.0 -=group_time 53.384s +=group_time 53.432s =case supervisor_SUITE:init_per_suite =logfile supervisor_suite.init_per_suite.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok =elapsed 0.0 =case supervisor_SUITE:init_per_group =logfile supervisor_suite.init_per_group.html =group_props [{name,sup_start}] -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =case supervisor_SUITE:sup_start_normal =logfile supervisor_suite.sup_start_normal.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok -=elapsed 3.1e-5 +=elapsed 3.2e-5 =case supervisor_SUITE:sup_start_ignore_init =logfile supervisor_suite.sup_start_ignore_init.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok -=elapsed 0.100591 +=elapsed 0.100562 =case supervisor_SUITE:sup_start_ignore_child =logfile supervisor_suite.sup_start_ignore_child.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok -=elapsed 4.1e-5 +=elapsed 4.3e-5 =case supervisor_SUITE:sup_start_ignore_temporary_child =logfile supervisor_suite.sup_start_ignore_temporary_child.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok =elapsed 2.8e-5 =case supervisor_SUITE:sup_start_ignore_temporary_child_start_child =logfile supervisor_suite.sup_start_ignore_temporary_child_start_child.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok =elapsed 3.0e-5 =case supervisor_SUITE:sup_start_ignore_temporary_child_start_child_simple =logfile supervisor_suite.sup_start_ignore_temporary_child_start_child_simple.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok =elapsed 2.4e-5 =case supervisor_SUITE:sup_start_ignore_permanent_child_start_child_simple =logfile supervisor_suite.sup_start_ignore_permanent_child_start_child_simple.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok =elapsed 3.9e-5 =case supervisor_SUITE:sup_start_error_return =logfile supervisor_suite.sup_start_error_return.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:38 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok -=elapsed 0.100511 +=elapsed 0.101382 =case supervisor_SUITE:sup_start_fail =logfile supervisor_suite.sup_start_fail.html -=started 2024-09-11 11:34:38 -=ended 2024-09-11 11:34:39 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:50 =result ok -=elapsed 0.101204 +=elapsed 0.101365 =case supervisor_SUITE:sup_start_child_returns_error =logfile supervisor_suite.sup_start_child_returns_error.html -=started 2024-09-11 11:34:39 -=ended 2024-09-11 11:34:39 +=started 2024-09-12 10:56:50 +=ended 2024-09-12 10:56:51 =result ok -=elapsed 2.1e-5 +=elapsed 2.7e-5 =case supervisor_SUITE:sup_start_restart_child_returns_error =logfile supervisor_suite.sup_start_restart_child_returns_error.html -=started 2024-09-11 11:34:39 -=ended 2024-09-11 11:34:39 +=started 2024-09-12 10:56:51 +=ended 2024-09-12 10:56:51 =result ok -=elapsed 4.57e-4 +=elapsed 5.29e-4 =case supervisor_SUITE:sup_start_child_returns_error_simple =logfile supervisor_suite.sup_start_child_returns_error_simple.html -=started 2024-09-11 11:34:39 -=ended 2024-09-11 11:34:39 +=started 2024-09-12 10:56:51 +=ended 2024-09-12 10:56:51 =result ok -=elapsed 2.3e-5 +=elapsed 2.9e-5 =case supervisor_SUITE:end_per_group =logfile supervisor_suite.end_per_group.html =group_props [{name,sup_start}] -=started 2024-09-11 11:34:39 -=ended 2024-09-11 11:34:39 +=started 2024-09-12 10:56:51 +=ended 2024-09-12 10:56:51 =result ok =elapsed 0.0 -=group_time 0.597s +=group_time 0.596s =case supervisor_SUITE:init_per_group -=logfile supervisor_suite.init_per_group.504259.html +=logfile supervisor_suite.init_per_group.19716578.html =group_props [{name,sup_start_map}] -=started 2024-09-11 11:34:39 -=ended 2024-09-11 11:34:39 +=started 2024-09-12 10:56:51 +=ended 2024-09-12 10:56:51 =result ok =elapsed 0.0 =case supervisor_SUITE:sup_start_map =logfile supervisor_suite.sup_start_map.html -=started 2024-09-11 11:34:39 -=ended 2024-09-11 11:34:39 +=started 2024-09-12 10:56:51 +=ended 2024-09-12 10:56:51 =result ok -=elapsed 6.5e-5 +=elapsed 8.3e-5 =case supervisor_SUITE:sup_start_map_simple =logfile supervisor_suite.sup_start_map_simple.html -=started 2024-09-11 11:34:39 -=ended 2024-09-11 11:34:39 +=started 2024-09-12 10:56:51 +=ended 2024-09-12 10:56:51 =result ok -=elapsed 1.05e-4 +=elapsed 6.6e-5 =case supervisor_SUITE:sup_start_map_faulty_specs =logfile supervisor_suite.sup_start_map_faulty_specs.html -=started 2024-09-11 11:34:39 -=ended 2024-09-11 11:34:39 +=started 2024-09-12 10:56:51 +=ended 2024-09-12 10:56:51 =result ok -=elapsed 0.002036 +=elapsed 0.001222 =case supervisor_SUITE:end_per_group -=logfile supervisor_suite.end_per_group.504291.html +=logfile supervisor_suite.end_per_group.19716610.html =group_props [{name,sup_start_map}] -=started 2024-09-11 11:34:39 -=ended 2024-09-11 11:34:39 +=started 2024-09-12 10:56:51 +=ended 2024-09-12 10:56:51 =result ok =elapsed 0.0 -=group_time 0.094s +=group_time 0.093s =case supervisor_SUITE:init_per_group -=logfile supervisor_suite.init_per_group.504323.html +=logfile supervisor_suite.init_per_group.19716642.html =group_props [{name,sup_stop}] -=started 2024-09-11 11:34:39 -=ended 2024-09-11 11:34:39 +=started 2024-09-12 10:56:51 +=ended 2024-09-12 10:56:51 =result ok =elapsed 0.0 =case supervisor_SUITE:sup_stop_infinity =logfile supervisor_suite.sup_stop_infinity.html -=started 2024-09-11 11:34:39 -=ended 2024-09-11 11:34:39 +=started 2024-09-12 10:56:51 +=ended 2024-09-12 10:56:51 =result ok -=elapsed 5.1e-5 +=elapsed 5.8e-5 =case supervisor_SUITE:sup_stop_timeout =logfile supervisor_suite.sup_stop_timeout.html -=started 2024-09-11 11:34:39 -=ended 2024-09-11 11:34:40 +=started 2024-09-12 10:56:51 +=ended 2024-09-12 10:56:52 =result ok -=elapsed 1.000764 +=elapsed 1.001474 =case supervisor_SUITE:sup_stop_timeout_dynamic =logfile supervisor_suite.sup_stop_timeout_dynamic.html -=started 2024-09-11 11:34:40 -=ended 2024-09-11 11:34:41 +=started 2024-09-12 10:56:52 +=ended 2024-09-12 10:56:53 =result ok -=elapsed 1.001081 +=elapsed 1.001291 =case supervisor_SUITE:sup_stop_brutal_kill =logfile supervisor_suite.sup_stop_brutal_kill.html -=started 2024-09-11 11:34:41 -=ended 2024-09-11 11:34:41 +=started 2024-09-12 10:56:53 +=ended 2024-09-12 10:56:53 =result ok -=elapsed 5.4e-5 +=elapsed 8.6e-5 =case supervisor_SUITE:sup_stop_brutal_kill_dynamic =logfile supervisor_suite.sup_stop_brutal_kill_dynamic.html -=started 2024-09-11 11:34:41 -=ended 2024-09-11 11:34:41 +=started 2024-09-12 10:56:53 +=ended 2024-09-12 10:56:53 =result ok -=elapsed 1.21e-4 +=elapsed 1.72e-4 =case supervisor_SUITE:sup_stop_race =logfile supervisor_suite.sup_stop_race.html -=started 2024-09-11 11:34:41 -=ended 2024-09-11 11:34:42 +=started 2024-09-12 10:56:53 +=ended 2024-09-12 10:56:54 =result ok -=elapsed 1.002302 +=elapsed 1.002669 =case supervisor_SUITE:sup_stop_non_shutdown_exit_dynamic =logfile supervisor_suite.sup_stop_non_shutdown_exit_dynamic.html -=started 2024-09-11 11:34:42 -=ended 2024-09-11 11:34:42 +=started 2024-09-12 10:56:54 +=ended 2024-09-12 10:56:54 =result ok -=elapsed 0.010846 +=elapsed 0.005729 =case supervisor_SUITE:end_per_group -=logfile supervisor_suite.end_per_group.19700002.html +=logfile supervisor_suite.end_per_group.19716674.html =group_props [{name,sup_stop}] -=started 2024-09-11 11:34:42 -=ended 2024-09-11 11:34:42 +=started 2024-09-12 10:56:54 +=ended 2024-09-12 10:56:54 =result ok =elapsed 0.0 -=group_time 3.200s +=group_time 3.196s =case supervisor_SUITE:child_adm =logfile supervisor_suite.child_adm.html -=started 2024-09-11 11:34:42 -=ended 2024-09-11 11:34:42 +=started 2024-09-12 10:56:54 +=ended 2024-09-12 10:56:54 =result ok -=elapsed 1.44e-4 +=elapsed 1.31e-4 =case supervisor_SUITE:child_adm_simple =logfile supervisor_suite.child_adm_simple.html -=started 2024-09-11 11:34:42 -=ended 2024-09-11 11:34:42 +=started 2024-09-12 10:56:54 +=ended 2024-09-12 10:56:54 =result ok -=elapsed 9.9e-5 +=elapsed 1.22e-4 =case supervisor_SUITE:extra_return =logfile supervisor_suite.extra_return.html -=started 2024-09-11 11:34:42 -=ended 2024-09-11 11:34:42 +=started 2024-09-12 10:56:54 +=ended 2024-09-12 10:56:54 =result ok -=elapsed 0.001019 +=elapsed 9.2e-4 =case supervisor_SUITE:child_specs =logfile supervisor_suite.child_specs.html -=started 2024-09-11 11:34:42 -=ended 2024-09-11 11:34:42 +=started 2024-09-12 10:56:54 +=ended 2024-09-12 10:56:54 =result ok -=elapsed 0.001659 +=elapsed 0.001766 =case supervisor_SUITE:child_specs_map =logfile supervisor_suite.child_specs_map.html -=started 2024-09-11 11:34:42 -=ended 2024-09-11 11:34:42 +=started 2024-09-12 10:56:54 +=ended 2024-09-12 10:56:54 =result ok -=elapsed 0.006783 +=elapsed 0.008302 =case supervisor_SUITE:sup_flags =logfile supervisor_suite.sup_flags.html -=started 2024-09-11 11:34:42 -=ended 2024-09-11 11:34:42 +=started 2024-09-12 10:56:54 +=ended 2024-09-12 10:56:54 =result ok -=elapsed 0.004282 +=elapsed 0.004983 =case supervisor_SUITE:multiple_restarts =logfile supervisor_suite.multiple_restarts.html -=started 2024-09-11 11:34:42 -=ended 2024-09-11 11:34:49 +=started 2024-09-12 10:56:54 +=ended 2024-09-12 10:57:00 =result ok -=elapsed 6.305275 +=elapsed 6.305857 =case supervisor_SUITE:init_per_group -=logfile supervisor_suite.init_per_group.19700034.html +=logfile supervisor_suite.init_per_group.19716706.html =group_props [{name,restart_one_for_one}] -=started 2024-09-11 11:34:49 -=ended 2024-09-11 11:34:49 +=started 2024-09-12 10:57:00 +=ended 2024-09-12 10:57:00 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =case supervisor_SUITE:one_for_one =logfile supervisor_suite.one_for_one.html -=started 2024-09-11 11:34:49 -=ended 2024-09-11 11:34:49 +=started 2024-09-12 10:57:00 +=ended 2024-09-12 10:57:00 =result ok -=elapsed 0.003104 +=elapsed 0.002856 =case supervisor_SUITE:one_for_one_escalation =logfile supervisor_suite.one_for_one_escalation.html -=started 2024-09-11 11:34:49 -=ended 2024-09-11 11:34:49 +=started 2024-09-12 10:57:00 +=ended 2024-09-12 10:57:00 =result ok -=elapsed 0.004885 +=elapsed 0.005766 =case supervisor_SUITE:end_per_group -=logfile supervisor_suite.end_per_group.19700066.html +=logfile supervisor_suite.end_per_group.19716738.html =group_props [{name,restart_one_for_one}] -=started 2024-09-11 11:34:49 -=ended 2024-09-11 11:34:49 +=started 2024-09-12 10:57:00 +=ended 2024-09-12 10:57:01 =result ok =elapsed 0.0 -=group_time 0.078s +=group_time 0.079s =case supervisor_SUITE:init_per_group -=logfile supervisor_suite.init_per_group.19700098.html +=logfile supervisor_suite.init_per_group.19716770.html =group_props [{name,restart_one_for_all}] -=started 2024-09-11 11:34:49 -=ended 2024-09-11 11:34:49 +=started 2024-09-12 10:57:01 +=ended 2024-09-12 10:57:01 =result ok =elapsed 0.0 =case supervisor_SUITE:one_for_all =logfile supervisor_suite.one_for_all.html -=started 2024-09-11 11:34:49 -=ended 2024-09-11 11:34:49 +=started 2024-09-12 10:57:01 +=ended 2024-09-12 10:57:01 =result ok -=elapsed 0.002516 +=elapsed 0.003991 =case supervisor_SUITE:one_for_all_escalation =logfile supervisor_suite.one_for_all_escalation.html -=started 2024-09-11 11:34:49 -=ended 2024-09-11 11:34:49 +=started 2024-09-12 10:57:01 +=ended 2024-09-12 10:57:01 =result ok -=elapsed 0.005158 +=elapsed 0.005071 =case supervisor_SUITE:one_for_all_other_child_fails_restart =logfile supervisor_suite.one_for_all_other_child_fails_restart.html -=started 2024-09-11 11:34:49 -=ended 2024-09-11 11:34:49 +=started 2024-09-12 10:57:01 +=ended 2024-09-12 10:57:01 =result ok -=elapsed 5.82e-4 +=elapsed 7.79e-4 =case supervisor_SUITE:end_per_group -=logfile supervisor_suite.end_per_group.19700130.html +=logfile supervisor_suite.end_per_group.19716802.html =group_props [{name,restart_one_for_all}] -=started 2024-09-11 11:34:49 -=ended 2024-09-11 11:34:49 +=started 2024-09-12 10:57:01 +=ended 2024-09-12 10:57:01 =result ok =elapsed 0.0 -=group_time 0.100s +=group_time 0.102s =case supervisor_SUITE:init_per_group -=logfile supervisor_suite.init_per_group.19700162.html +=logfile supervisor_suite.init_per_group.19716834.html =group_props [{name,restart_simple_one_for_one}] -=started 2024-09-11 11:34:49 -=ended 2024-09-11 11:34:49 +=started 2024-09-12 10:57:01 +=ended 2024-09-12 10:57:01 =result ok =elapsed 0.0 =case supervisor_SUITE:simple_one_for_one =logfile supervisor_suite.simple_one_for_one.html -=started 2024-09-11 11:34:49 -=ended 2024-09-11 11:34:49 +=started 2024-09-12 10:57:01 +=ended 2024-09-12 10:57:01 =result ok -=elapsed 0.002644 +=elapsed 0.002877 =case supervisor_SUITE:simple_one_for_one_shutdown =logfile supervisor_suite.simple_one_for_one_shutdown.html -=started 2024-09-11 11:34:49 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:01 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 2.001267 +=elapsed 2.001139 =case supervisor_SUITE:simple_one_for_one_extra =logfile supervisor_suite.simple_one_for_one_extra.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 0.003693 +=elapsed 0.002566 =case supervisor_SUITE:simple_one_for_one_escalation =logfile supervisor_suite.simple_one_for_one_escalation.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 0.004166 +=elapsed 0.006926 =case supervisor_SUITE:simple_one_for_one_corruption =logfile supervisor_suite.simple_one_for_one_corruption.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 0.00404 +=elapsed 0.005249 =case supervisor_SUITE:simple_one_for_one_restart_ignore =logfile supervisor_suite.simple_one_for_one_restart_ignore.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 0.002393 +=elapsed 0.001188 =case supervisor_SUITE:end_per_group -=logfile supervisor_suite.end_per_group.19700194.html +=logfile supervisor_suite.end_per_group.19716866.html =group_props [{name,restart_simple_one_for_one}] -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok =elapsed 0.0 -=group_time 2.181s +=group_time 2.184s =case supervisor_SUITE:init_per_group -=logfile supervisor_suite.init_per_group.504355.html +=logfile supervisor_suite.init_per_group.19716898.html =group_props [{name,restart_rest_for_one}] -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok =elapsed 0.0 =case supervisor_SUITE:rest_for_one =logfile supervisor_suite.rest_for_one.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 0.003253 +=elapsed 0.004068 =case supervisor_SUITE:rest_for_one_escalation =logfile supervisor_suite.rest_for_one_escalation.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 0.004569 +=elapsed 0.004376 =case supervisor_SUITE:rest_for_one_other_child_fails_restart =logfile supervisor_suite.rest_for_one_other_child_fails_restart.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 6.71e-4 +=elapsed 7.7e-4 =case supervisor_SUITE:end_per_group -=logfile supervisor_suite.end_per_group.504387.html +=logfile supervisor_suite.end_per_group.19716930.html =group_props [{name,restart_rest_for_one}] -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok =elapsed 0.0 =group_time 0.101s =case supervisor_SUITE:init_per_group -=logfile supervisor_suite.init_per_group.504419.html +=logfile supervisor_suite.init_per_group.19716962.html =group_props [{name,normal_termination}] -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok =elapsed 0.0 =case supervisor_SUITE:external_start_no_progress_log =logfile supervisor_suite.external_start_no_progress_log.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 6.61e-4 +=elapsed 5.76e-4 =case supervisor_SUITE:permanent_normal =logfile supervisor_suite.permanent_normal.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 3.64e-4 +=elapsed 4.51e-4 =case supervisor_SUITE:transient_normal =logfile supervisor_suite.transient_normal.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 4.0e-5 +=elapsed 6.5e-5 =case supervisor_SUITE:temporary_normal =logfile supervisor_suite.temporary_normal.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 3.9e-5 +=elapsed 5.9e-5 =case supervisor_SUITE:end_per_group -=logfile supervisor_suite.end_per_group.504451.html +=logfile supervisor_suite.end_per_group.19716994.html =group_props [{name,normal_termination}] -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok =elapsed 0.0 =group_time 0.116s =case supervisor_SUITE:init_per_group -=logfile supervisor_suite.init_per_group.504483.html +=logfile supervisor_suite.init_per_group.19717026.html =group_props [{name,shutdown_termination}] -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok =elapsed 0.0 =case supervisor_SUITE:permanent_shutdown =logfile supervisor_suite.permanent_shutdown.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 0.001417 +=elapsed 7.62e-4 =case supervisor_SUITE:transient_shutdown =logfile supervisor_suite.transient_shutdown.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 5.8e-5 +=elapsed 7.7e-5 =case supervisor_SUITE:temporary_shutdown =logfile supervisor_suite.temporary_shutdown.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 7.1e-5 +=elapsed 7.3e-5 =case supervisor_SUITE:faulty_application_shutdown =logfile supervisor_suite.faulty_application_shutdown.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 0.016445 +=elapsed 0.013839 =case supervisor_SUITE:end_per_group -=logfile supervisor_suite.end_per_group.19700226.html +=logfile supervisor_suite.end_per_group.425924.html =group_props [{name,shutdown_termination}] -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok =elapsed 0.0 -=group_time 0.133s +=group_time 0.130s =case supervisor_SUITE:init_per_group -=logfile supervisor_suite.init_per_group.19700258.html +=logfile supervisor_suite.init_per_group.425956.html =group_props [{name,abnormal_termination}] -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok =elapsed 0.0 =case supervisor_SUITE:permanent_abnormal =logfile supervisor_suite.permanent_abnormal.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 0.001899 +=elapsed 0.001006 =case supervisor_SUITE:transient_abnormal =logfile supervisor_suite.transient_abnormal.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 0.001388 +=elapsed 0.001491 =case supervisor_SUITE:temporary_abnormal =logfile supervisor_suite.temporary_abnormal.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok -=elapsed 0.001257 +=elapsed 0.001079 =case supervisor_SUITE:end_per_group -=logfile supervisor_suite.end_per_group.19700290.html +=logfile supervisor_suite.end_per_group.425988.html =group_props [{name,abnormal_termination}] -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:51 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:03 =result ok =elapsed 0.0 -=group_time 0.097s +=group_time 0.096s =case supervisor_SUITE:child_unlink =logfile supervisor_suite.child_unlink.html -=started 2024-09-11 11:34:51 -=ended 2024-09-11 11:34:57 +=started 2024-09-12 10:57:03 +=ended 2024-09-12 10:57:08 =result ok -=elapsed 5.000307 +=elapsed 5.000778 =case supervisor_SUITE:tree =logfile supervisor_suite.tree.html -=started 2024-09-11 11:34:57 -=ended 2024-09-11 11:34:58 +=started 2024-09-12 10:57:08 +=ended 2024-09-12 10:57:09 =result ok -=elapsed 1.003898 +=elapsed 1.002712 =case supervisor_SUITE:init_per_group -=logfile supervisor_suite.init_per_group.504515.html +=logfile supervisor_suite.init_per_group.426020.html =group_props [{name,significant}] -=started 2024-09-11 11:34:58 -=ended 2024-09-11 11:34:58 +=started 2024-09-12 10:57:09 +=ended 2024-09-12 10:57:09 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =case supervisor_SUITE:nonsignificant_temporary =logfile supervisor_suite.nonsignificant_temporary.html -=started 2024-09-11 11:34:58 -=ended 2024-09-11 11:35:10 +=started 2024-09-12 10:57:09 +=ended 2024-09-12 10:57:21 =result ok -=elapsed 12.011878 +=elapsed 12.013976 =case supervisor_SUITE:nonsignificant_transient =logfile supervisor_suite.nonsignificant_transient.html -=started 2024-09-11 11:35:10 -=ended 2024-09-11 11:35:22 +=started 2024-09-12 10:57:21 +=ended 2024-09-12 10:57:34 =result ok -=elapsed 12.011547 +=elapsed 12.011766 =case supervisor_SUITE:significant_temporary =logfile supervisor_suite.significant_temporary.html -=started 2024-09-11 11:35:22 -=ended 2024-09-11 11:35:28 +=started 2024-09-12 10:57:34 +=ended 2024-09-12 10:57:40 =result ok -=elapsed 6.007255 +=elapsed 6.007712 =case supervisor_SUITE:significant_transient =logfile supervisor_suite.significant_transient.html -=started 2024-09-11 11:35:28 -=ended 2024-09-11 11:35:40 +=started 2024-09-12 10:57:40 +=ended 2024-09-12 10:57:52 =result ok -=elapsed 12.012656 +=elapsed 12.012786 =case supervisor_SUITE:significant_simple =logfile supervisor_suite.significant_simple.html -=started 2024-09-11 11:35:40 -=ended 2024-09-11 11:35:40 +=started 2024-09-12 10:57:52 +=ended 2024-09-12 10:57:52 =result ok -=elapsed 0.001103 +=elapsed 0.001039 =case supervisor_SUITE:significant_bystander =logfile supervisor_suite.significant_bystander.html -=started 2024-09-11 11:35:40 -=ended 2024-09-11 11:35:52 +=started 2024-09-12 10:57:52 +=ended 2024-09-12 10:58:04 =result ok -=elapsed 12.011294 +=elapsed 12.011947 =case supervisor_SUITE:significant_escalation =logfile supervisor_suite.significant_escalation.html -=started 2024-09-11 11:35:52 -=ended 2024-09-11 11:35:53 +=started 2024-09-12 10:58:04 +=ended 2024-09-12 10:58:05 =result ok -=elapsed 1.000421 +=elapsed 1.000805 =case supervisor_SUITE:significant_upgrade_never_any =logfile supervisor_suite.significant_upgrade_never_any.html -=started 2024-09-11 11:35:53 -=ended 2024-09-11 11:35:53 +=started 2024-09-12 10:58:05 +=ended 2024-09-12 10:58:05 =result ok -=elapsed 0.0001 +=elapsed 1.19e-4 =case supervisor_SUITE:significant_upgrade_any_never =logfile supervisor_suite.significant_upgrade_any_never.html -=started 2024-09-11 11:35:53 -=ended 2024-09-11 11:35:56 +=started 2024-09-12 10:58:05 +=ended 2024-09-12 10:58:08 =result ok -=elapsed 3.002564 +=elapsed 3.003104 =case supervisor_SUITE:significant_upgrade_never_all =logfile supervisor_suite.significant_upgrade_never_all.html -=started 2024-09-11 11:35:56 -=ended 2024-09-11 11:35:58 +=started 2024-09-12 10:58:08 +=ended 2024-09-12 10:58:10 =result ok -=elapsed 2.002161 +=elapsed 2.00183 =case supervisor_SUITE:significant_upgrade_all_never =logfile supervisor_suite.significant_upgrade_all_never.html -=started 2024-09-11 11:35:58 -=ended 2024-09-11 11:36:01 +=started 2024-09-12 10:58:10 +=ended 2024-09-12 10:58:13 =result ok -=elapsed 3.00317 +=elapsed 3.002775 =case supervisor_SUITE:significant_upgrade_any_all =logfile supervisor_suite.significant_upgrade_any_all.html -=started 2024-09-11 11:36:01 -=ended 2024-09-11 11:36:06 +=started 2024-09-12 10:58:13 +=ended 2024-09-12 10:58:18 =result ok -=elapsed 5.004809 +=elapsed 5.004773 =case supervisor_SUITE:significant_upgrade_all_any =logfile supervisor_suite.significant_upgrade_all_any.html -=started 2024-09-11 11:36:06 -=ended 2024-09-11 11:36:09 +=started 2024-09-12 10:58:18 +=ended 2024-09-12 10:58:21 =result ok -=elapsed 3.003105 +=elapsed 3.002905 =case supervisor_SUITE:significant_upgrade_child =logfile supervisor_suite.significant_upgrade_child.html -=started 2024-09-11 11:36:09 -=ended 2024-09-11 11:36:16 +=started 2024-09-12 10:58:21 +=ended 2024-09-12 10:58:28 =result ok -=elapsed 7.007118 +=elapsed 7.007019 =case supervisor_SUITE:end_per_group -=logfile supervisor_suite.end_per_group.19700322.html +=logfile supervisor_suite.end_per_group.19717058.html =group_props [{name,significant}] -=started 2024-09-11 11:36:16 -=ended 2024-09-11 11:36:16 +=started 2024-09-12 10:58:28 +=ended 2024-09-12 10:58:28 =result ok =elapsed 0.0 -=group_time 78.426s +=group_time 78.429s =case supervisor_SUITE:count_children =logfile supervisor_suite.count_children.html -=started 2024-09-11 11:36:16 -=ended 2024-09-11 11:36:17 +=started 2024-09-12 10:58:28 +=ended 2024-09-12 10:58:28 =result ok -=elapsed 0.521284 +=elapsed 0.56633 =case supervisor_SUITE:count_children_supervisor =logfile supervisor_suite.count_children_supervisor.html -=started 2024-09-11 11:36:17 -=ended 2024-09-11 11:36:17 +=started 2024-09-12 10:58:28 +=ended 2024-09-12 10:58:29 =result ok -=elapsed 0.381144 +=elapsed 0.394859 =case supervisor_SUITE:count_restarting_children =logfile supervisor_suite.count_restarting_children.html -=started 2024-09-11 11:36:17 -=ended 2024-09-11 11:36:27 +=started 2024-09-12 10:58:29 +=ended 2024-09-12 10:58:39 =result ok -=elapsed 10.407167 +=elapsed 10.40668 =case supervisor_SUITE:get_callback_module =logfile supervisor_suite.get_callback_module.html -=started 2024-09-11 11:36:27 -=ended 2024-09-11 11:36:27 +=started 2024-09-12 10:58:39 +=ended 2024-09-12 10:58:39 =result ok -=elapsed 2.8e-5 +=elapsed 3.9e-5 =case supervisor_SUITE:do_not_save_start_parameters_for_temporary_children =logfile supervisor_suite.do_not_save_start_parameters_for_temporary_children.html -=started 2024-09-11 11:36:27 -=ended 2024-09-11 11:36:27 +=started 2024-09-12 10:58:39 +=ended 2024-09-12 10:58:39 =result ok -=elapsed 0.013877 +=elapsed 0.013574 =case supervisor_SUITE:do_not_save_child_specs_for_temporary_children =logfile supervisor_suite.do_not_save_child_specs_for_temporary_children.html -=started 2024-09-11 11:36:27 -=ended 2024-09-11 11:36:27 +=started 2024-09-12 10:58:39 +=ended 2024-09-12 10:58:39 =result ok -=elapsed 0.014388 +=elapsed 0.018432 =case supervisor_SUITE:simple_one_for_one_scale_many_temporary_children =logfile supervisor_suite.simple_one_for_one_scale_many_temporary_children.html -=started 2024-09-11 11:36:27 -=ended 2024-09-11 11:36:28 +=started 2024-09-12 10:58:39 +=ended 2024-09-12 10:58:40 =result ok -=elapsed 0.123966 +=elapsed 0.134104 =case supervisor_SUITE:temporary_bystander =logfile supervisor_suite.temporary_bystander.html -=started 2024-09-11 11:36:28 -=ended 2024-09-11 11:36:28 +=started 2024-09-12 10:58:40 +=ended 2024-09-12 10:58:40 =result ok -=elapsed 0.350759 +=elapsed 0.350702 =case supervisor_SUITE:simple_global_supervisor =logfile supervisor_suite.simple_global_supervisor.html -=started 2024-09-11 11:36:28 -=ended 2024-09-11 11:36:29 +=started 2024-09-12 10:58:40 +=ended 2024-09-12 10:58:41 =result ok -=elapsed 1.406809 +=elapsed 1.406511 =case supervisor_SUITE:hanging_restart_loop =logfile supervisor_suite.hanging_restart_loop.html -=started 2024-09-11 11:36:29 -=ended 2024-09-11 11:36:43 +=started 2024-09-12 10:58:41 +=ended 2024-09-12 10:58:55 =result ok -=elapsed 14.010066 +=elapsed 14.012489 =case supervisor_SUITE:hanging_restart_loop_rest_for_one =logfile supervisor_suite.hanging_restart_loop_rest_for_one.html -=started 2024-09-11 11:36:43 -=ended 2024-09-11 11:36:57 +=started 2024-09-12 10:58:55 +=ended 2024-09-12 10:59:09 =result ok -=elapsed 14.009373 +=elapsed 14.012495 =case supervisor_SUITE:hanging_restart_loop_simple =logfile supervisor_suite.hanging_restart_loop_simple.html -=started 2024-09-11 11:36:57 -=ended 2024-09-11 11:37:10 +=started 2024-09-12 10:59:09 +=ended 2024-09-12 10:59:21 =result ok -=elapsed 12.008425 +=elapsed 12.013357 =case supervisor_SUITE:code_change =logfile supervisor_suite.code_change.html -=started 2024-09-11 11:37:10 -=ended 2024-09-11 11:37:10 +=started 2024-09-12 10:59:21 +=ended 2024-09-12 10:59:22 =result ok -=elapsed 1.4e-4 +=elapsed 1.96e-4 =case supervisor_SUITE:code_change_map =logfile supervisor_suite.code_change_map.html -=started 2024-09-11 11:37:10 -=ended 2024-09-11 11:37:10 +=started 2024-09-12 10:59:22 +=ended 2024-09-12 10:59:22 =result ok -=elapsed 1.78e-4 +=elapsed 1.25e-4 =case supervisor_SUITE:code_change_simple =logfile supervisor_suite.code_change_simple.html -=started 2024-09-11 11:37:10 -=ended 2024-09-11 11:37:10 +=started 2024-09-12 10:59:22 +=ended 2024-09-12 10:59:22 =result ok -=elapsed 7.5e-5 +=elapsed 5.7e-5 =case supervisor_SUITE:code_change_simple_map =logfile supervisor_suite.code_change_simple_map.html -=started 2024-09-11 11:37:10 -=ended 2024-09-11 11:37:10 +=started 2024-09-12 10:59:22 +=ended 2024-09-12 10:59:22 =result ok -=elapsed 7.0e-5 +=elapsed 5.3e-5 =case supervisor_SUITE:order_of_children =logfile supervisor_suite.order_of_children.html -=started 2024-09-11 11:37:10 -=ended 2024-09-11 11:37:10 +=started 2024-09-12 10:59:22 +=ended 2024-09-12 10:59:22 =result ok -=elapsed 0.01049 +=elapsed 0.010426 =case supervisor_SUITE:scale_start_stop_many_children =logfile supervisor_suite.scale_start_stop_many_children.html -=started 2024-09-11 11:37:10 -=ended 2024-09-11 11:37:11 +=started 2024-09-12 10:59:22 +=ended 2024-09-12 10:59:23 =result ok -=elapsed 1.394552 +=elapsed 1.326208 =case supervisor_SUITE:format_log_1 =logfile supervisor_suite.format_log_1.html -=started 2024-09-11 11:37:11 -=ended 2024-09-11 11:37:11 +=started 2024-09-12 10:59:23 +=ended 2024-09-12 10:59:23 =result ok -=elapsed 2.26e-4 +=elapsed 2.3e-4 =case supervisor_SUITE:format_log_2 =logfile supervisor_suite.format_log_2.html -=started 2024-09-11 11:37:11 -=ended 2024-09-11 11:37:11 +=started 2024-09-12 10:59:23 +=ended 2024-09-12 10:59:23 =result ok -=elapsed 8.84e-4 +=elapsed 8.97e-4 =case supervisor_SUITE:already_started_outside_supervisor =logfile supervisor_suite.already_started_outside_supervisor.html -=started 2024-09-11 11:37:11 -=ended 2024-09-11 11:37:11 +=started 2024-09-12 10:59:23 +=ended 2024-09-12 10:59:23 =result ok -=elapsed 4.9e-5 +=elapsed 5.9e-5 =case supervisor_SUITE:end_per_suite =logfile supervisor_suite.end_per_suite.html -=started 2024-09-11 11:37:11 -=ended 2024-09-11 11:37:11 +=started 2024-09-12 10:59:23 +=ended 2024-09-12 10:59:23 =result ok =elapsed 0.0 -=group_time 153.098s +=group_time 153.111s =case supervisor_bridge_SUITE:init_per_suite =logfile supervisor_bridge_suite.init_per_suite.html -=started 2024-09-11 11:37:11 -=ended 2024-09-11 11:37:11 +=started 2024-09-12 10:59:23 +=ended 2024-09-12 10:59:23 =result ok -=elapsed 1.0e-6 +=elapsed 0.0 =case supervisor_bridge_SUITE:starting =logfile supervisor_bridge_suite.starting.html -=started 2024-09-11 11:37:11 -=ended 2024-09-11 11:37:11 +=started 2024-09-12 10:59:23 +=ended 2024-09-12 10:59:23 =result ok -=elapsed 3.94e-4 +=elapsed 4.9e-4 =case supervisor_bridge_SUITE:mini_terminate =logfile supervisor_bridge_suite.mini_terminate.html -=started 2024-09-11 11:37:11 -=ended 2024-09-11 11:37:11 +=started 2024-09-12 10:59:23 +=ended 2024-09-12 10:59:23 =result ok -=elapsed 9.61e-4 +=elapsed 0.001011 =case supervisor_bridge_SUITE:mini_die =logfile supervisor_bridge_suite.mini_die.html -=started 2024-09-11 11:37:11 -=ended 2024-09-11 11:37:11 +=started 2024-09-12 10:59:23 +=ended 2024-09-12 10:59:23 =result ok -=elapsed 9.02e-4 +=elapsed 8.81e-4 =case supervisor_bridge_SUITE:badstart =logfile supervisor_bridge_suite.badstart.html -=started 2024-09-11 11:37:11 -=ended 2024-09-11 11:37:11 +=started 2024-09-12 10:59:23 +=ended 2024-09-12 10:59:23 =result ok -=elapsed 0.002852 +=elapsed 0.00203 =case supervisor_bridge_SUITE:simple_global_supervisor =logfile supervisor_bridge_suite.simple_global_supervisor.html -=started 2024-09-11 11:37:11 -=ended 2024-09-11 11:37:12 +=started 2024-09-12 10:59:23 +=ended 2024-09-12 10:59:23 =result ok -=elapsed 0.200973 +=elapsed 0.20091 =case supervisor_bridge_SUITE:format_log_1 =logfile supervisor_bridge_suite.format_log_1.html -=started 2024-09-11 11:37:12 -=ended 2024-09-11 11:37:12 +=started 2024-09-12 10:59:23 +=ended 2024-09-12 10:59:23 =result ok -=elapsed 1.61e-4 +=elapsed 1.7e-4 =case supervisor_bridge_SUITE:format_log_2 =logfile supervisor_bridge_suite.format_log_2.html -=started 2024-09-11 11:37:12 -=ended 2024-09-11 11:37:12 +=started 2024-09-12 10:59:23 +=ended 2024-09-12 10:59:23 =result ok -=elapsed 7.5e-4 +=elapsed 7.67e-4 =case supervisor_bridge_SUITE:end_per_suite =logfile supervisor_bridge_suite.end_per_suite.html -=started 2024-09-11 11:37:12 -=ended 2024-09-11 11:37:12 +=started 2024-09-12 10:59:23 +=ended 2024-09-12 10:59:23 =result ok =elapsed 0.0 =group_time 0.404s =case sys_SUITE:init_per_suite =logfile sys_suite.init_per_suite.html -=started 2024-09-11 11:37:12 -=ended 2024-09-11 11:37:12 +=started 2024-09-12 10:59:23 +=ended 2024-09-12 10:59:24 =result ok =elapsed 0.0 =case sys_SUITE:log =logfile sys_suite.log.html -=started 2024-09-11 11:37:12 -=ended 2024-09-11 11:37:12 +=started 2024-09-12 10:59:24 +=ended 2024-09-12 10:59:24 =result ok -=elapsed 5.4e-5 +=elapsed 5.6e-5 =case sys_SUITE:log_to_file =logfile sys_suite.log_to_file.html -=started 2024-09-11 11:37:12 -=ended 2024-09-11 11:37:12 +=started 2024-09-12 10:59:24 +=ended 2024-09-12 10:59:24 =result ok -=elapsed 8.09e-4 +=elapsed 8.36e-4 =case sys_SUITE:stats =logfile sys_suite.stats.html -=started 2024-09-11 11:37:12 -=ended 2024-09-11 11:37:12 +=started 2024-09-12 10:59:24 +=ended 2024-09-12 10:59:24 =result ok -=elapsed 7.7e-5 +=elapsed 7.8e-5 =case sys_SUITE:trace =logfile sys_suite.trace.html -=started 2024-09-11 11:37:12 -=ended 2024-09-11 11:37:15 +=started 2024-09-12 10:59:24 +=ended 2024-09-12 10:59:27 =result ok -=elapsed 3.002219 +=elapsed 3.002297 =case sys_SUITE:suspend =logfile sys_suite.suspend.html -=started 2024-09-11 11:37:15 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:27 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 2.00176 +=elapsed 2.00128 =case sys_SUITE:install =logfile sys_suite.install.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 0.00776 +=elapsed 0.00737 =case sys_SUITE:special_process =logfile sys_suite.special_process.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 4.48e-4 +=elapsed 4.54e-4 =case sys_SUITE:end_per_suite =logfile sys_suite.end_per_suite.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok =elapsed 0.0 -=group_time 5.214s +=group_time 5.215s =case tar_SUITE:init_per_suite =logfile tar_suite.init_per_suite.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok =elapsed 0.0 =case tar_SUITE:borderline =logfile tar_suite.borderline.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 0.15245 +=elapsed 0.148946 =case tar_SUITE:atomic =logfile tar_suite.atomic.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 0.00948 +=elapsed 0.009435 =case tar_SUITE:long_names =logfile tar_suite.long_names.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 0.003561 +=elapsed 0.003721 =case tar_SUITE:create_long_names =logfile tar_suite.create_long_names.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 0.003013 +=elapsed 0.003027 =case tar_SUITE:bad_tar =logfile tar_suite.bad_tar.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 0.001515 +=elapsed 0.001363 =case tar_SUITE:errors =logfile tar_suite.errors.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 5.27e-4 +=elapsed 5.65e-4 =case tar_SUITE:extract_from_binary =logfile tar_suite.extract_from_binary.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 0.001672 +=elapsed 0.001673 =case tar_SUITE:extract_from_binary_compressed =logfile tar_suite.extract_from_binary_compressed.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 0.005669 +=elapsed 0.005339 =case tar_SUITE:extract_from_open_file =logfile tar_suite.extract_from_open_file.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 0.008517 +=elapsed 0.007944 =case tar_SUITE:extract_filtered =logfile tar_suite.extract_filtered.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 0.001229 +=elapsed 0.001532 =case tar_SUITE:symlinks =logfile tar_suite.symlinks.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 0.006141 +=elapsed 0.00581 =case tar_SUITE:open_add_close =logfile tar_suite.open_add_close.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 0.003742 +=elapsed 0.003563 =case tar_SUITE:cooked_compressed =logfile tar_suite.cooked_compressed.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 0.012314 +=elapsed 0.01114 =case tar_SUITE:memory =logfile tar_suite.memory.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:17 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:29 =result ok -=elapsed 8.89e-4 +=elapsed 8.11e-4 =case tar_SUITE:unicode =logfile tar_suite.unicode.html -=started 2024-09-11 11:37:17 -=ended 2024-09-11 11:37:18 +=started 2024-09-12 10:59:29 +=ended 2024-09-12 10:59:30 =result ok -=elapsed 0.340691 +=elapsed 0.34663 =case tar_SUITE:read_other_implementations =logfile tar_suite.read_other_implementations.html -=started 2024-09-11 11:37:18 -=ended 2024-09-11 11:37:18 +=started 2024-09-12 10:59:30 +=ended 2024-09-12 10:59:30 =result ok -=elapsed 0.004332 +=elapsed 0.002437 =case tar_SUITE:bsdtgz =logfile tar_suite.bsdtgz.html -=started 2024-09-11 11:37:18 -=ended 2024-09-11 11:37:18 +=started 2024-09-12 10:59:30 +=ended 2024-09-12 10:59:30 =result ok -=elapsed 5.76e-4 +=elapsed 5.85e-4 =case tar_SUITE:sparse =logfile tar_suite.sparse.html -=started 2024-09-11 11:37:18 -=ended 2024-09-11 11:37:18 +=started 2024-09-12 10:59:30 +=ended 2024-09-12 10:59:30 =result ok -=elapsed 0.00889 +=elapsed 0.008274 =case tar_SUITE:init =logfile tar_suite.init.html -=started 2024-09-11 11:37:18 -=ended 2024-09-11 11:37:18 +=started 2024-09-12 10:59:30 +=ended 2024-09-12 10:59:30 =result ok -=elapsed 0.001884 +=elapsed 0.00161 =case tar_SUITE:leading_slash =logfile tar_suite.leading_slash.html -=started 2024-09-11 11:37:18 -=ended 2024-09-11 11:37:18 +=started 2024-09-12 10:59:30 +=ended 2024-09-12 10:59:30 =result ok -=elapsed 0.00143 +=elapsed 0.001053 =case tar_SUITE:dotdot =logfile tar_suite.dotdot.html -=started 2024-09-11 11:37:18 -=ended 2024-09-11 11:37:18 +=started 2024-09-12 10:59:30 +=ended 2024-09-12 10:59:30 =result ok -=elapsed 7.39e-4 +=elapsed 5.3e-4 =case tar_SUITE:roundtrip_metadata =logfile tar_suite.roundtrip_metadata.html -=started 2024-09-11 11:37:18 -=ended 2024-09-11 11:37:18 +=started 2024-09-12 10:59:30 +=ended 2024-09-12 10:59:30 =result ok -=elapsed 0.001092 +=elapsed 7.28e-4 =case tar_SUITE:apply_file_info_opts =logfile tar_suite.apply_file_info_opts.html -=started 2024-09-11 11:37:18 -=ended 2024-09-11 11:37:18 +=started 2024-09-12 10:59:30 +=ended 2024-09-12 10:59:30 =result ok -=elapsed 0.001634 +=elapsed 9.4e-4 =case tar_SUITE:incompatible_options =logfile tar_suite.incompatible_options.html -=started 2024-09-11 11:37:18 -=ended 2024-09-11 11:37:18 +=started 2024-09-12 10:59:30 +=ended 2024-09-12 10:59:30 =result ok -=elapsed 1.65e-4 +=elapsed 1.35e-4 =case tar_SUITE:end_per_suite =logfile tar_suite.end_per_suite.html -=started 2024-09-11 11:37:18 -=ended 2024-09-11 11:37:18 +=started 2024-09-12 10:59:30 +=ended 2024-09-12 10:59:30 =result ok =elapsed 0.0 -=group_time 1.161s +=group_time 1.157s =case timer_SUITE:init_per_suite =logfile timer_suite.init_per_suite.html -=started 2024-09-11 11:37:18 -=ended 2024-09-11 11:37:18 +=started 2024-09-12 10:59:30 +=ended 2024-09-12 10:59:30 =result ok =elapsed 0.0 =case timer_SUITE:do_big_test =logfile timer_suite.do_big_test.html -=started 2024-09-11 11:37:18 -=ended 2024-09-11 11:38:39 +=started 2024-09-12 10:59:30 +=ended 2024-09-12 11:00:42 =result ok -=elapsed 80.719057 +=elapsed 71.802699 =case timer_SUITE:end_per_suite =logfile timer_suite.end_per_suite.html -=started 2024-09-11 11:38:39 -=ended 2024-09-11 11:38:39 +=started 2024-09-12 11:00:42 +=ended 2024-09-12 11:00:42 =result ok =elapsed 0.0 -=group_time 80.783s +=group_time 71.867s =case timer_simple_SUITE:init_per_suite =logfile timer_simple_suite.init_per_suite.html -=started 2024-09-11 11:38:39 -=ended 2024-09-11 11:38:39 +=started 2024-09-12 11:00:42 +=ended 2024-09-12 11:00:42 =result ok =elapsed 0.0 =case timer_simple_SUITE:init_per_group =logfile timer_simple_suite.init_per_group.html =group_props [{name,apply_after}] -=started 2024-09-11 11:38:39 -=ended 2024-09-11 11:38:39 +=started 2024-09-12 11:00:42 +=ended 2024-09-12 11:00:42 =result ok =elapsed 0.0 =case timer_simple_SUITE:apply_after1 =logfile timer_simple_suite.apply_after1.html -=started 2024-09-11 11:38:39 -=ended 2024-09-11 11:38:39 +=started 2024-09-12 11:00:42 +=ended 2024-09-12 11:00:42 =result ok -=elapsed 1.4e-5 +=elapsed 1.5e-5 =case timer_simple_SUITE:apply_after2 =logfile timer_simple_suite.apply_after2.html -=started 2024-09-11 11:38:39 -=ended 2024-09-11 11:38:39 +=started 2024-09-12 11:00:42 +=ended 2024-09-12 11:00:42 =result ok -=elapsed 0.501917 +=elapsed 0.502081 =case timer_simple_SUITE:apply_after3 =logfile timer_simple_suite.apply_after3.html -=started 2024-09-11 11:38:39 -=ended 2024-09-11 11:38:40 +=started 2024-09-12 11:00:42 +=ended 2024-09-12 11:00:43 =result ok -=elapsed 0.101929 +=elapsed 0.101871 =case timer_simple_SUITE:apply_after4 =logfile timer_simple_suite.apply_after4.html -=started 2024-09-11 11:38:40 -=ended 2024-09-11 11:38:40 +=started 2024-09-12 11:00:43 +=ended 2024-09-12 11:00:43 =result ok -=elapsed 0.10186 +=elapsed 0.10205 =case timer_simple_SUITE:apply_after_invalid_args =logfile timer_simple_suite.apply_after_invalid_args.html -=started 2024-09-11 11:38:40 -=ended 2024-09-11 11:38:40 +=started 2024-09-12 11:00:43 +=ended 2024-09-12 11:00:43 =result ok =elapsed 1.0e-6 =case timer_simple_SUITE:end_per_group =logfile timer_simple_suite.end_per_group.html =group_props [{name,apply_after}] -=started 2024-09-11 11:38:40 -=ended 2024-09-11 11:38:40 +=started 2024-09-12 11:00:43 +=ended 2024-09-12 11:00:43 =result ok =elapsed 0.0 =group_time 0.844s =case timer_simple_SUITE:init_per_group -=logfile timer_simple_suite.init_per_group.19700578.html +=logfile timer_simple_suite.init_per_group.19717314.html =group_props [{name,send_after}] -=started 2024-09-11 11:38:40 -=ended 2024-09-11 11:38:40 +=started 2024-09-12 11:00:43 +=ended 2024-09-12 11:00:43 =result ok =elapsed 0.0 =case timer_simple_SUITE:send_after1 =logfile timer_simple_suite.send_after1.html -=started 2024-09-11 11:38:40 -=ended 2024-09-11 11:38:40 +=started 2024-09-12 11:00:43 +=ended 2024-09-12 11:00:43 =result ok =elapsed 1.0e-6 =case timer_simple_SUITE:send_after2 =logfile timer_simple_suite.send_after2.html -=started 2024-09-11 11:38:40 -=ended 2024-09-11 11:38:40 +=started 2024-09-12 11:00:43 +=ended 2024-09-12 11:00:43 =result ok -=elapsed 9.0e-6 +=elapsed 1.0e-5 =case timer_simple_SUITE:send_after3 =logfile timer_simple_suite.send_after3.html -=started 2024-09-11 11:38:40 -=ended 2024-09-11 11:38:40 +=started 2024-09-12 11:00:43 +=ended 2024-09-12 11:00:43 =result ok =elapsed 8.0e-6 =case timer_simple_SUITE:send_after4 =logfile timer_simple_suite.send_after4.html -=started 2024-09-11 11:38:40 -=ended 2024-09-11 11:38:40 +=started 2024-09-12 11:00:43 +=ended 2024-09-12 11:00:43 =result ok -=elapsed 0.500988 +=elapsed 0.500985 =case timer_simple_SUITE:send_after5 =logfile timer_simple_suite.send_after5.html -=started 2024-09-11 11:38:40 -=ended 2024-09-11 11:38:41 +=started 2024-09-12 11:00:43 +=ended 2024-09-12 11:00:44 =result ok -=elapsed 0.501918 +=elapsed 0.501649 =case timer_simple_SUITE:send_after6 =logfile timer_simple_suite.send_after6.html -=started 2024-09-11 11:38:41 -=ended 2024-09-11 11:38:41 +=started 2024-09-12 11:00:44 +=ended 2024-09-12 11:00:44 =result ok -=elapsed 0.501994 +=elapsed 0.501654 =case timer_simple_SUITE:send_after7 =logfile timer_simple_suite.send_after7.html -=started 2024-09-11 11:38:41 -=ended 2024-09-11 11:38:42 +=started 2024-09-12 11:00:44 +=ended 2024-09-12 11:00:45 =result ok -=elapsed 0.502013 +=elapsed 0.501725 =case timer_simple_SUITE:send_after_invalid_args =logfile timer_simple_suite.send_after_invalid_args.html -=started 2024-09-11 11:38:42 -=ended 2024-09-11 11:38:42 +=started 2024-09-12 11:00:45 +=ended 2024-09-12 11:00:45 =result ok =elapsed 1.0e-6 =case timer_simple_SUITE:end_per_group -=logfile timer_simple_suite.end_per_group.19700610.html +=logfile timer_simple_suite.end_per_group.19717346.html =group_props [{name,send_after}] -=started 2024-09-11 11:38:42 -=ended 2024-09-11 11:38:42 +=started 2024-09-12 11:00:45 +=ended 2024-09-12 11:00:45 =result ok =elapsed 0.0 =group_time 2.214s =case timer_simple_SUITE:init_per_group -=logfile timer_simple_suite.init_per_group.19700642.html +=logfile timer_simple_suite.init_per_group.19717378.html =group_props [{name,exit_after}] -=started 2024-09-11 11:38:42 -=ended 2024-09-11 11:38:42 +=started 2024-09-12 11:00:45 +=ended 2024-09-12 11:00:45 =result ok =elapsed 0.0 =case timer_simple_SUITE:exit_after1 =logfile timer_simple_suite.exit_after1.html -=started 2024-09-11 11:38:42 -=ended 2024-09-11 11:38:43 +=started 2024-09-12 11:00:45 +=ended 2024-09-12 11:00:46 =result ok -=elapsed 1.001953 +=elapsed 1.002081 =case timer_simple_SUITE:exit_after2 =logfile timer_simple_suite.exit_after2.html -=started 2024-09-11 11:38:43 -=ended 2024-09-11 11:38:44 +=started 2024-09-12 11:00:46 +=ended 2024-09-12 11:00:47 =result ok -=elapsed 1.001977 +=elapsed 1.001515 =case timer_simple_SUITE:exit_after3 =logfile timer_simple_suite.exit_after3.html -=started 2024-09-11 11:38:44 -=ended 2024-09-11 11:38:45 +=started 2024-09-12 11:00:47 +=ended 2024-09-12 11:00:48 =result ok -=elapsed 1.001993 +=elapsed 1.001695 =case timer_simple_SUITE:exit_after4 =logfile timer_simple_suite.exit_after4.html -=started 2024-09-11 11:38:45 -=ended 2024-09-11 11:38:46 +=started 2024-09-12 11:00:48 +=ended 2024-09-12 11:00:49 =result ok -=elapsed 1.000769 +=elapsed 1.000705 =case timer_simple_SUITE:end_per_group -=logfile timer_simple_suite.end_per_group.19700674.html +=logfile timer_simple_suite.end_per_group.19717410.html =group_props [{name,exit_after}] -=started 2024-09-11 11:38:46 -=ended 2024-09-11 11:38:46 +=started 2024-09-12 11:00:49 +=ended 2024-09-12 11:00:49 =result ok =elapsed 0.0 =group_time 4.122s =case timer_simple_SUITE:init_per_group -=logfile timer_simple_suite.init_per_group.19700706.html +=logfile timer_simple_suite.init_per_group.19717442.html =group_props [{name,kill_after}] -=started 2024-09-11 11:38:46 -=ended 2024-09-11 11:38:46 +=started 2024-09-12 11:00:49 +=ended 2024-09-12 11:00:49 =result ok =elapsed 0.0 =case timer_simple_SUITE:kill_after1 =logfile timer_simple_suite.kill_after1.html -=started 2024-09-11 11:38:46 -=ended 2024-09-11 11:38:47 +=started 2024-09-12 11:00:49 +=ended 2024-09-12 11:00:50 =result ok -=elapsed 1.001763 +=elapsed 1.001982 =case timer_simple_SUITE:kill_after2 =logfile timer_simple_suite.kill_after2.html -=started 2024-09-11 11:38:47 -=ended 2024-09-11 11:38:48 +=started 2024-09-12 11:00:50 +=ended 2024-09-12 11:00:51 =result ok -=elapsed 1.001573 +=elapsed 1.001745 =case timer_simple_SUITE:kill_after3 =logfile timer_simple_suite.kill_after3.html -=started 2024-09-11 11:38:48 -=ended 2024-09-11 11:38:49 +=started 2024-09-12 11:00:51 +=ended 2024-09-12 11:00:52 =result ok -=elapsed 1.001709 +=elapsed 1.001415 =case timer_simple_SUITE:end_per_group -=logfile timer_simple_suite.end_per_group.19700738.html +=logfile timer_simple_suite.end_per_group.19717474.html =group_props [{name,kill_after}] -=started 2024-09-11 11:38:49 -=ended 2024-09-11 11:38:49 +=started 2024-09-12 11:00:52 +=ended 2024-09-12 11:00:52 =result ok =elapsed 0.0 =group_time 3.098s =case timer_simple_SUITE:init_per_group -=logfile timer_simple_suite.init_per_group.19700770.html +=logfile timer_simple_suite.init_per_group.19717506.html =group_props [{name,apply_interval}] -=started 2024-09-11 11:38:49 -=ended 2024-09-11 11:38:49 +=started 2024-09-12 11:00:52 +=ended 2024-09-12 11:00:52 =result ok =elapsed 0.0 =case timer_simple_SUITE:apply_interval1 =logfile timer_simple_suite.apply_interval1.html -=started 2024-09-11 11:38:49 -=ended 2024-09-11 11:38:53 +=started 2024-09-12 11:00:52 +=ended 2024-09-12 11:00:56 =result ok -=elapsed 4.002571 +=elapsed 4.002887 =case timer_simple_SUITE:apply_interval2 =logfile timer_simple_suite.apply_interval2.html -=started 2024-09-11 11:38:53 -=ended 2024-09-11 11:38:56 +=started 2024-09-12 11:00:56 +=ended 2024-09-12 11:00:59 =result ok -=elapsed 2.801733 +=elapsed 2.8014 =case timer_simple_SUITE:apply_interval_invalid_args =logfile timer_simple_suite.apply_interval_invalid_args.html -=started 2024-09-11 11:38:56 -=ended 2024-09-11 11:38:56 +=started 2024-09-12 11:00:59 +=ended 2024-09-12 11:00:59 =result ok -=elapsed 1.0e-6 +=elapsed 2.0e-6 =case timer_simple_SUITE:end_per_group -=logfile timer_simple_suite.end_per_group.19700802.html +=logfile timer_simple_suite.end_per_group.19717538.html =group_props [{name,apply_interval}] -=started 2024-09-11 11:38:56 -=ended 2024-09-11 11:38:56 +=started 2024-09-12 11:00:59 +=ended 2024-09-12 11:00:59 =result ok =elapsed 0.0 =group_time 6.897s =case timer_simple_SUITE:init_per_group -=logfile timer_simple_suite.init_per_group.19700834.html +=logfile timer_simple_suite.init_per_group.19717570.html =group_props [{name,apply_repeatedly}] -=started 2024-09-11 11:38:56 -=ended 2024-09-11 11:38:56 +=started 2024-09-12 11:00:59 +=ended 2024-09-12 11:00:59 =result ok =elapsed 0.0 =case timer_simple_SUITE:apply_repeatedly1 =logfile timer_simple_suite.apply_repeatedly1.html -=started 2024-09-11 11:38:56 -=ended 2024-09-11 11:39:00 +=started 2024-09-12 11:00:59 +=ended 2024-09-12 11:01:03 =result ok -=elapsed 4.002413 +=elapsed 4.002877 =case timer_simple_SUITE:apply_repeatedly2 =logfile timer_simple_suite.apply_repeatedly2.html -=started 2024-09-11 11:39:00 -=ended 2024-09-11 11:39:04 +=started 2024-09-12 11:01:03 +=ended 2024-09-12 11:01:07 =result ok -=elapsed 3.501849 +=elapsed 3.501709 =case timer_simple_SUITE:apply_repeatedly_invalid_args =logfile timer_simple_suite.apply_repeatedly_invalid_args.html -=started 2024-09-11 11:39:04 -=ended 2024-09-11 11:39:04 +=started 2024-09-12 11:01:07 +=ended 2024-09-12 11:01:07 =result ok =elapsed 1.0e-6 =case timer_simple_SUITE:end_per_group -=logfile timer_simple_suite.end_per_group.19700866.html +=logfile timer_simple_suite.end_per_group.19717602.html =group_props [{name,apply_repeatedly}] -=started 2024-09-11 11:39:04 -=ended 2024-09-11 11:39:04 +=started 2024-09-12 11:01:07 +=ended 2024-09-12 11:01:07 =result ok =elapsed 0.0 -=group_time 7.598s +=group_time 7.597s =case timer_simple_SUITE:init_per_group -=logfile timer_simple_suite.init_per_group.19700898.html +=logfile timer_simple_suite.init_per_group.19717634.html =group_props [{name,send_interval}] -=started 2024-09-11 11:39:04 -=ended 2024-09-11 11:39:04 +=started 2024-09-12 11:01:07 +=ended 2024-09-12 11:01:07 =result ok =elapsed 0.0 =case timer_simple_SUITE:send_interval1 =logfile timer_simple_suite.send_interval1.html -=started 2024-09-11 11:39:04 -=ended 2024-09-11 11:39:10 +=started 2024-09-12 11:01:07 +=ended 2024-09-12 11:01:13 =result ok -=elapsed 6.002735 +=elapsed 6.002826 =case timer_simple_SUITE:send_interval2 =logfile timer_simple_suite.send_interval2.html -=started 2024-09-11 11:39:10 -=ended 2024-09-11 11:39:13 +=started 2024-09-12 11:01:13 +=ended 2024-09-12 11:01:16 =result ok -=elapsed 3.002497 +=elapsed 3.002692 =case timer_simple_SUITE:send_interval3 =logfile timer_simple_suite.send_interval3.html -=started 2024-09-11 11:39:13 -=ended 2024-09-11 11:39:16 +=started 2024-09-12 11:01:16 +=ended 2024-09-12 11:01:19 =result ok -=elapsed 3.002703 +=elapsed 3.002625 =case timer_simple_SUITE:send_interval4 =logfile timer_simple_suite.send_interval4.html -=started 2024-09-11 11:39:16 -=ended 2024-09-11 11:39:19 +=started 2024-09-12 11:01:19 +=ended 2024-09-12 11:01:22 =result ok -=elapsed 3.002496 +=elapsed 3.002693 =case timer_simple_SUITE:send_interval5 =logfile timer_simple_suite.send_interval5.html -=started 2024-09-11 11:39:19 -=ended 2024-09-11 11:39:20 +=started 2024-09-12 11:01:22 +=ended 2024-09-12 11:01:23 =result ok -=elapsed 1.102854 +=elapsed 1.102753 =case timer_simple_SUITE:send_interval_invalid_args =logfile timer_simple_suite.send_interval_invalid_args.html -=started 2024-09-11 11:39:20 -=ended 2024-09-11 11:39:20 +=started 2024-09-12 11:01:23 +=ended 2024-09-12 11:01:23 =result ok =elapsed 1.0e-6 =case timer_simple_SUITE:end_per_group -=logfile timer_simple_suite.end_per_group.19700930.html +=logfile timer_simple_suite.end_per_group.19717666.html =group_props [{name,send_interval}] -=started 2024-09-11 11:39:20 -=ended 2024-09-11 11:39:20 +=started 2024-09-12 11:01:23 +=ended 2024-09-12 11:01:23 =result ok =elapsed 0.0 -=group_time 16.276s +=group_time 16.277s =case timer_simple_SUITE:init_per_group -=logfile timer_simple_suite.init_per_group.19700962.html +=logfile timer_simple_suite.init_per_group.19717698.html =group_props [{name,cancel}] -=started 2024-09-11 11:39:20 -=ended 2024-09-11 11:39:20 +=started 2024-09-12 11:01:23 +=ended 2024-09-12 11:01:23 =result ok =elapsed 0.0 =case timer_simple_SUITE:cancel1 =logfile timer_simple_suite.cancel1.html -=started 2024-09-11 11:39:20 -=ended 2024-09-11 11:39:20 +=started 2024-09-12 11:01:23 +=ended 2024-09-12 11:01:23 =result ok =elapsed 1.0e-6 =case timer_simple_SUITE:cancel2 =logfile timer_simple_suite.cancel2.html -=started 2024-09-11 11:39:20 -=ended 2024-09-11 11:39:22 +=started 2024-09-12 11:01:23 +=ended 2024-09-12 11:01:25 =result ok -=elapsed 2.000859 +=elapsed 2.000978 =case timer_simple_SUITE:cancel3 =logfile timer_simple_suite.cancel3.html -=started 2024-09-11 11:39:22 -=ended 2024-09-11 11:39:24 +=started 2024-09-12 11:01:25 +=ended 2024-09-12 11:01:27 =result ok -=elapsed 2.000945 +=elapsed 2.000729 =case timer_simple_SUITE:cancel4 =logfile timer_simple_suite.cancel4.html -=started 2024-09-11 11:39:24 -=ended 2024-09-11 11:39:25 +=started 2024-09-12 11:01:27 +=ended 2024-09-12 11:01:28 =result ok -=elapsed 1.102766 +=elapsed 1.102173 =case timer_simple_SUITE:cancel5 =logfile timer_simple_suite.cancel5.html -=started 2024-09-11 11:39:25 -=ended 2024-09-11 11:39:26 +=started 2024-09-12 11:01:28 +=ended 2024-09-12 11:01:29 =result ok -=elapsed 1.102889 +=elapsed 1.102615 =case timer_simple_SUITE:cancel6 =logfile timer_simple_suite.cancel6.html -=started 2024-09-11 11:39:26 -=ended 2024-09-11 11:39:28 +=started 2024-09-12 11:01:29 +=ended 2024-09-12 11:01:31 =result ok -=elapsed 2.003898 +=elapsed 2.003705 =case timer_simple_SUITE:cancel_invalid_args =logfile timer_simple_suite.cancel_invalid_args.html -=started 2024-09-11 11:39:28 -=ended 2024-09-11 11:39:28 +=started 2024-09-12 11:01:31 +=ended 2024-09-12 11:01:31 =result ok =elapsed 1.0e-6 =case timer_simple_SUITE:end_per_group -=logfile timer_simple_suite.end_per_group.19700994.html +=logfile timer_simple_suite.end_per_group.19717730.html =group_props [{name,cancel}] -=started 2024-09-11 11:39:28 -=ended 2024-09-11 11:39:28 +=started 2024-09-12 11:01:31 +=ended 2024-09-12 11:01:31 =result ok =elapsed 0.0 -=group_time 8.395s +=group_time 8.396s =case timer_simple_SUITE:init_per_group -=logfile timer_simple_suite.init_per_group.19701026.html +=logfile timer_simple_suite.init_per_group.19717762.html =group_props [{name,sleep}] -=started 2024-09-11 11:39:28 -=ended 2024-09-11 11:39:28 +=started 2024-09-12 11:01:31 +=ended 2024-09-12 11:01:31 =result ok -=elapsed 0.0 +=elapsed 1.0e-6 =case timer_simple_SUITE:sleep1 =logfile timer_simple_suite.sleep1.html -=started 2024-09-11 11:39:28 -=ended 2024-09-11 11:39:30 +=started 2024-09-12 11:01:31 +=ended 2024-09-12 11:01:33 =result ok -=elapsed 1.000163 +=elapsed 1.000962 =case timer_simple_SUITE:sleep2 =logfile timer_simple_suite.sleep2.html -=started 2024-09-11 11:39:30 -=ended 2024-09-11 11:39:31 +=started 2024-09-12 11:01:33 +=ended 2024-09-12 11:01:34 =result ok -=elapsed 1.001837 +=elapsed 1.001227 =case timer_simple_SUITE:end_per_group -=logfile timer_simple_suite.end_per_group.19701058.html +=logfile timer_simple_suite.end_per_group.19717794.html =group_props [{name,sleep}] -=started 2024-09-11 11:39:31 -=ended 2024-09-11 11:39:31 +=started 2024-09-12 11:01:34 +=ended 2024-09-12 11:01:34 =result ok =elapsed 0.0 -=group_time 2.071s +=group_time 2.072s =case timer_simple_SUITE:init_per_group -=logfile timer_simple_suite.init_per_group.19701090.html +=logfile timer_simple_suite.init_per_group.19717826.html =group_props [{name,misc}] -=started 2024-09-11 11:39:31 -=ended 2024-09-11 11:39:31 +=started 2024-09-12 11:01:34 +=ended 2024-09-12 11:01:34 =result ok =elapsed 0.0 =case timer_simple_SUITE:tc =logfile timer_simple_suite.tc.html -=started 2024-09-11 11:39:31 -=ended 2024-09-11 11:39:33 +=started 2024-09-12 11:01:34 +=ended 2024-09-12 11:01:36 =result ok -=elapsed 2.003154 +=elapsed 2.004005 =case timer_simple_SUITE:unexpected1 =logfile timer_simple_suite.unexpected1.html -=started 2024-09-11 11:39:33 -=ended 2024-09-11 11:39:33 +=started 2024-09-12 11:01:36 +=ended 2024-09-12 11:01:36 =result ok -=elapsed 0.601311 +=elapsed 0.601749 =case timer_simple_SUITE:unexpected2 =logfile timer_simple_suite.unexpected2.html -=started 2024-09-11 11:39:33 -=ended 2024-09-11 11:39:34 +=started 2024-09-12 11:01:36 +=ended 2024-09-12 11:01:37 =result ok -=elapsed 0.500262 +=elapsed 0.500756 =case timer_simple_SUITE:unexpected3 =logfile timer_simple_suite.unexpected3.html -=started 2024-09-11 11:39:34 -=ended 2024-09-11 11:39:34 +=started 2024-09-12 11:01:37 +=ended 2024-09-12 11:01:37 =result ok -=elapsed 0.500285 +=elapsed 0.500791 =case timer_simple_SUITE:nonexistent1 =logfile timer_simple_suite.nonexistent1.html -=started 2024-09-11 11:39:34 -=ended 2024-09-11 11:39:35 +=started 2024-09-12 11:01:37 +=ended 2024-09-12 11:01:38 =result ok -=elapsed 1.000193 +=elapsed 1.00077 =case timer_simple_SUITE:nonexistent2 =logfile timer_simple_suite.nonexistent2.html -=started 2024-09-11 11:39:35 -=ended 2024-09-11 11:39:36 +=started 2024-09-12 11:01:38 +=ended 2024-09-12 11:01:39 =result ok -=elapsed 1.00026 +=elapsed 1.000856 =case timer_simple_SUITE:timer_perf =logfile timer_simple_suite.timer_perf.html -=started 2024-09-11 11:39:36 -=ended 2024-09-11 11:40:28 +=started 2024-09-12 11:01:39 +=ended 2024-09-12 11:02:31 =result ok -=elapsed 51.807183 +=elapsed 51.807409 =case timer_simple_SUITE:end_per_group -=logfile timer_simple_suite.end_per_group.19701122.html +=logfile timer_simple_suite.end_per_group.19717858.html =group_props [{name,misc}] -=started 2024-09-11 11:40:28 -=ended 2024-09-11 11:40:28 +=started 2024-09-12 11:02:31 +=ended 2024-09-12 11:02:31 =result ok =elapsed 0.0 -=group_time 57.595s +=group_time 57.601s =case timer_simple_SUITE:end_per_suite =logfile timer_simple_suite.end_per_suite.html -=started 2024-09-11 11:40:28 -=ended 2024-09-11 11:40:28 +=started 2024-09-12 11:02:31 +=ended 2024-09-12 11:02:31 =result ok =elapsed 0.0 -=group_time 109.383s +=group_time 109.389s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.19701154.html +=logfile ct_framework.init_per_suite.19717890.html =group_props [{suite,unicode_SUITE}] -=started 2024-09-11 11:40:28 -=ended 2024-09-11 11:40:28 +=started 2024-09-12 11:02:31 +=ended 2024-09-12 11:02:31 =result ok =elapsed 0.0 =case unicode_SUITE:utf8_illegal_sequences_bif =logfile unicode_suite.utf8_illegal_sequences_bif.html -=started 2024-09-11 11:40:28 -=ended 2024-09-11 11:40:34 +=started 2024-09-12 11:02:31 +=ended 2024-09-12 11:02:37 =result ok -=elapsed 6.022421 +=elapsed 6.148404 =case unicode_SUITE:utf16_illegal_sequences_bif =logfile unicode_suite.utf16_illegal_sequences_bif.html -=started 2024-09-11 11:40:34 -=ended 2024-09-11 11:40:36 +=started 2024-09-12 11:02:37 +=ended 2024-09-12 11:02:39 =result ok -=elapsed 2.149119 +=elapsed 2.055694 =case unicode_SUITE:random_lists =logfile unicode_suite.random_lists.html -=started 2024-09-11 11:40:36 -=ended 2024-09-11 11:40:39 +=started 2024-09-12 11:02:39 +=ended 2024-09-12 11:02:42 =result ok -=elapsed 2.498869 +=elapsed 2.531145 =case unicode_SUITE:roundtrips =logfile unicode_suite.roundtrips.html -=started 2024-09-11 11:40:39 -=ended 2024-09-11 11:40:39 +=started 2024-09-12 11:02:42 +=ended 2024-09-12 11:02:43 =result ok -=elapsed 0.42388 +=elapsed 0.430284 =case unicode_SUITE:latin1 =logfile unicode_suite.latin1.html -=started 2024-09-11 11:40:39 -=ended 2024-09-11 11:40:39 +=started 2024-09-12 11:02:43 +=ended 2024-09-12 11:02:43 =result ok -=elapsed 0.003902 +=elapsed 0.003962 =case unicode_SUITE:exceptions =logfile unicode_suite.exceptions.html -=started 2024-09-11 11:40:39 -=ended 2024-09-11 11:40:39 +=started 2024-09-12 11:02:43 +=ended 2024-09-12 11:02:43 =result ok -=elapsed 0.005582 +=elapsed 0.005508 =case unicode_SUITE:binaries_errors_limit =logfile unicode_suite.binaries_errors_limit.html -=started 2024-09-11 11:40:39 -=ended 2024-09-11 11:40:42 +=started 2024-09-12 11:02:43 +=ended 2024-09-12 11:02:45 =result ok -=elapsed 2.11701 +=elapsed 2.011247 =case unicode_SUITE:normalize =logfile unicode_suite.normalize.html -=started 2024-09-11 11:40:42 -=ended 2024-09-11 11:40:42 +=started 2024-09-12 11:02:45 +=ended 2024-09-12 11:02:45 =result ok -=elapsed 4.39e-4 +=elapsed 3.91e-4 =case ct_framework:init_per_group -=logfile ct_framework.init_per_group.19701186.html +=logfile ct_framework.init_per_group.19717922.html =group_props [{name,binaries_errors},parallel,{suite,unicode_SUITE}] -=started 2024-09-11 11:40:42 -=ended 2024-09-11 11:40:42 +=started 2024-09-12 11:02:45 +=ended 2024-09-12 11:02:45 =result ok -=elapsed 3.9e-5 +=elapsed 3.6e-5 =case unicode_SUITE:ex_binaries_errors_utf8 -=logfile unicode_suite.ex_binaries_errors_utf8.19701218.html -=started 2024-09-11 11:40:42 -=ended 2024-09-11 11:40:42 +=logfile unicode_suite.ex_binaries_errors_utf8.19717954.html +=started 2024-09-12 11:02:45 +=ended 2024-09-12 11:02:45 =result ok -=elapsed 0.633057 +=elapsed 0.737995 =case unicode_SUITE:ex_binaries_errors_utf16_little -=logfile unicode_suite.ex_binaries_errors_utf16_little.504547.html -=started 2024-09-11 11:40:42 -=ended 2024-09-11 11:40:44 +=logfile unicode_suite.ex_binaries_errors_utf16_little.19717986.html +=started 2024-09-12 11:02:45 +=ended 2024-09-12 11:02:47 =result ok -=elapsed 2.644971 +=elapsed 2.737986 =case unicode_SUITE:ex_binaries_errors_utf16_big -=logfile unicode_suite.ex_binaries_errors_utf16_big.504579.html -=started 2024-09-11 11:40:42 -=ended 2024-09-11 11:40:44 +=logfile unicode_suite.ex_binaries_errors_utf16_big.19718018.html +=started 2024-09-12 11:02:45 +=ended 2024-09-12 11:02:47 =result ok -=elapsed 2.753674 +=elapsed 2.758118 =case unicode_SUITE:ex_binaries_errors_utf32_little -=logfile unicode_suite.ex_binaries_errors_utf32_little.504611.html -=started 2024-09-11 11:40:42 -=ended 2024-09-11 11:40:44 +=logfile unicode_suite.ex_binaries_errors_utf32_little.19718050.html +=started 2024-09-12 11:02:45 +=ended 2024-09-12 11:02:47 =result ok -=elapsed 2.713702 +=elapsed 2.740274 =case unicode_SUITE:ex_binaries_errors_utf32_big -=logfile unicode_suite.ex_binaries_errors_utf32_big.504643.html -=started 2024-09-11 11:40:42 -=ended 2024-09-11 11:40:44 +=logfile unicode_suite.ex_binaries_errors_utf32_big.408387.html +=started 2024-09-12 11:02:45 +=ended 2024-09-12 11:02:47 =result ok -=elapsed 2.529292 +=elapsed 2.368242 =case ct_framework:end_per_group -=logfile ct_framework.end_per_group.19701250.html +=logfile ct_framework.end_per_group.408419.html =group_props [{name,binaries_errors},parallel,{suite,unicode_SUITE}] -=started 2024-09-11 11:40:44 -=ended 2024-09-11 11:40:44 +=started 2024-09-12 11:02:47 +=ended 2024-09-12 11:02:47 =result ok -=elapsed 4.0e-5 -=group_time 2.803s +=elapsed 4.3e-5 +=group_time 2.807s =case unicode_SUITE:huge_illegal_code_points =logfile unicode_suite.huge_illegal_code_points.html -=started 2024-09-11 11:40:44 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:47 +=ended 2024-09-12 11:02:47 =result ok -=elapsed 2.18e-4 +=elapsed 1.8e-4 =case unicode_SUITE:error_info =logfile unicode_suite.error_info.html -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:47 +=ended 2024-09-12 11:02:47 =result ok -=elapsed 0.002394 +=elapsed 0.002477 =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.19701282.html +=logfile ct_framework.end_per_suite.408451.html =group_props [{suite,unicode_SUITE}] -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:47 +=ended 2024-09-12 11:02:48 =result ok =elapsed 0.0 -=group_time 16.323s +=group_time 16.296s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.19701314.html +=logfile ct_framework.init_per_suite.408483.html =group_props [{suite,unicode_util_SUITE}] -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:48 +=ended 2024-09-12 11:02:48 =result ok =elapsed 0.0 =case unicode_util_SUITE:extra =logfile unicode_util_suite.extra.html -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:48 +=ended 2024-09-12 11:02:48 =result ok -=elapsed 3.0e-6 +=elapsed 4.0e-6 =case unicode_util_SUITE:uppercase =logfile unicode_util_suite.uppercase.html -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:48 +=ended 2024-09-12 11:02:48 =result ok -=elapsed 1.0e-6 +=elapsed 2.0e-6 =case unicode_util_SUITE:lowercase =logfile unicode_util_suite.lowercase.html -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:48 +=ended 2024-09-12 11:02:48 =result ok -=elapsed 1.0e-6 +=elapsed 2.0e-6 =case unicode_util_SUITE:titlecase =logfile unicode_util_suite.titlecase.html -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:48 +=ended 2024-09-12 11:02:48 =result ok -=elapsed 1.0e-6 +=elapsed 2.0e-6 =case unicode_util_SUITE:casefold =logfile unicode_util_suite.casefold.html -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:48 +=ended 2024-09-12 11:02:48 =result ok -=elapsed 2.0e-6 +=elapsed 3.0e-6 =case unicode_util_SUITE:cp =logfile unicode_util_suite.cp.html -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:48 +=ended 2024-09-12 11:02:48 =result ok -=elapsed 9.0e-6 +=elapsed 1.0e-5 =case unicode_util_SUITE:gc =logfile unicode_util_suite.gc.html -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:48 +=ended 2024-09-12 11:02:48 =result ok -=elapsed 0.010958 +=elapsed 0.011133 =case unicode_util_SUITE:nfd =logfile unicode_util_suite.nfd.html -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:48 +=ended 2024-09-12 11:02:48 =result ok -=elapsed 0.089071 +=elapsed 0.093222 =case unicode_util_SUITE:nfc =logfile unicode_util_suite.nfc.html -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:48 +=ended 2024-09-12 11:02:48 =result ok -=elapsed 0.091386 +=elapsed 0.094241 =case unicode_util_SUITE:nfkd =logfile unicode_util_suite.nfkd.html -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:48 +=ended 2024-09-12 11:02:48 =result ok -=elapsed 0.091946 +=elapsed 0.094296 =case unicode_util_SUITE:nfkc =logfile unicode_util_suite.nfkc.html -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:48 +=ended 2024-09-12 11:02:48 =result ok -=elapsed 0.096894 +=elapsed 0.101151 =case unicode_util_SUITE:whitespace =logfile unicode_util_suite.whitespace.html -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:48 +=ended 2024-09-12 11:02:48 =result ok -=elapsed 1.0e-6 +=elapsed 2.0e-6 =case unicode_util_SUITE:get =logfile unicode_util_suite.get.html -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:45 +=started 2024-09-12 11:02:48 +=ended 2024-09-12 11:02:48 =result ok =elapsed 0.0 =case unicode_util_SUITE:lookup =logfile unicode_util_suite.lookup.html -=started 2024-09-11 11:40:45 -=ended 2024-09-11 11:40:46 +=started 2024-09-12 11:02:48 +=ended 2024-09-12 11:02:49 =result ok -=elapsed 0.254415 +=elapsed 0.272549 =case unicode_util_SUITE:count =logfile unicode_util_suite.count.html -=started 2024-09-11 11:40:46 -=ended 2024-09-11 11:41:25 +=started 2024-09-12 11:02:49 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 39.694666 +=elapsed 40.016253 =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.19701346.html +=logfile ct_framework.end_per_suite.19718082.html =group_props [{suite,unicode_util_SUITE}] -=started 2024-09-11 11:41:25 -=ended 2024-09-11 11:41:25 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok =elapsed 0.0 -=group_time 40.712s +=group_time 41.075s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.19701378.html +=logfile ct_framework.init_per_suite.19718114.html =group_props [{suite,uri_string_SUITE}] -=started 2024-09-11 11:41:25 -=ended 2024-09-11 11:41:25 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok =elapsed 0.0 =case uri_string_SUITE:normalize =logfile uri_string_suite.normalize.html -=started 2024-09-11 11:41:25 -=ended 2024-09-11 11:41:25 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 1.42e-4 +=elapsed 2.07e-4 =case uri_string_SUITE:normalize_map =logfile uri_string_suite.normalize_map.html -=started 2024-09-11 11:41:25 -=ended 2024-09-11 11:41:25 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 9.0e-5 +=elapsed 1.29e-4 =case uri_string_SUITE:normalize_return_map =logfile uri_string_suite.normalize_return_map.html -=started 2024-09-11 11:41:25 -=ended 2024-09-11 11:41:25 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 3.7e-5 +=elapsed 4.9e-5 =case uri_string_SUITE:normalize_negative =logfile uri_string_suite.normalize_negative.html -=started 2024-09-11 11:41:25 -=ended 2024-09-11 11:41:25 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 2.8e-5 +=elapsed 3.7e-5 =case uri_string_SUITE:normalize_binary_pct_encoded_userinfo =logfile uri_string_suite.normalize_binary_pct_encoded_userinfo.html -=started 2024-09-11 11:41:25 -=ended 2024-09-11 11:41:25 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 7.1e-5 +=elapsed 9.7e-5 =case uri_string_SUITE:normalize_binary_pct_encoded_query =logfile uri_string_suite.normalize_binary_pct_encoded_query.html -=started 2024-09-11 11:41:25 -=ended 2024-09-11 11:41:25 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 2.7e-5 +=elapsed 3.8e-5 =case uri_string_SUITE:normalize_binary_pct_encoded_fragment =logfile uri_string_suite.normalize_binary_pct_encoded_fragment.html -=started 2024-09-11 11:41:25 -=ended 2024-09-11 11:41:25 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 3.8e-5 +=elapsed 4.5e-5 =case uri_string_SUITE:normalize_pct_encoded_userinfo =logfile uri_string_suite.normalize_pct_encoded_userinfo.html -=started 2024-09-11 11:41:25 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 9.0e-5 +=elapsed 1.26e-4 =case uri_string_SUITE:normalize_pct_encoded_query =logfile uri_string_suite.normalize_pct_encoded_query.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok =elapsed 4.7e-5 =case uri_string_SUITE:normalize_pct_encoded_fragment =logfile uri_string_suite.normalize_pct_encoded_fragment.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 2.5e-5 +=elapsed 3.2e-5 =case uri_string_SUITE:normalize_pct_encoded_negative =logfile uri_string_suite.normalize_pct_encoded_negative.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 2.8e-5 +=elapsed 3.6e-5 =case uri_string_SUITE:parse_binary_scheme =logfile uri_string_suite.parse_binary_scheme.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 1.7e-5 +=elapsed 2.2e-5 =case uri_string_SUITE:parse_binary_userinfo =logfile uri_string_suite.parse_binary_userinfo.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 1.7e-5 +=elapsed 2.3e-5 =case uri_string_SUITE:parse_binary_pct_encoded_userinfo =logfile uri_string_suite.parse_binary_pct_encoded_userinfo.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 1.9e-5 +=elapsed 2.6e-5 =case uri_string_SUITE:parse_binary_host =logfile uri_string_suite.parse_binary_host.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 1.1e-5 +=elapsed 1.4e-5 =case uri_string_SUITE:parse_binary_host_ipv4 =logfile uri_string_suite.parse_binary_host_ipv4.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 1.7e-5 +=elapsed 2.3e-5 =case uri_string_SUITE:parse_binary_host_ipv6 =logfile uri_string_suite.parse_binary_host_ipv6.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 2.2e-5 +=elapsed 2.9e-5 =case uri_string_SUITE:parse_binary_port =logfile uri_string_suite.parse_binary_port.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 1.9e-5 +=elapsed 2.4e-5 =case uri_string_SUITE:parse_binary_path =logfile uri_string_suite.parse_binary_path.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 1.1e-5 +=elapsed 1.6e-5 =case uri_string_SUITE:parse_binary_query =logfile uri_string_suite.parse_binary_query.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 2.3e-5 +=elapsed 3.1e-5 =case uri_string_SUITE:parse_binary_pct_encoded_query =logfile uri_string_suite.parse_binary_pct_encoded_query.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 7.0e-6 +=elapsed 9.0e-6 =case uri_string_SUITE:parse_binary_fragment =logfile uri_string_suite.parse_binary_fragment.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 1.7e-5 +=elapsed 2.4e-5 =case uri_string_SUITE:parse_binary_pct_encoded_fragment =logfile uri_string_suite.parse_binary_pct_encoded_fragment.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 7.0e-6 +=elapsed 8.0e-6 =case uri_string_SUITE:parse_scheme =logfile uri_string_suite.parse_scheme.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 1.8e-5 +=elapsed 2.4e-5 =case uri_string_SUITE:parse_userinfo =logfile uri_string_suite.parse_userinfo.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 1.9e-5 +=elapsed 2.5e-5 =case uri_string_SUITE:parse_pct_encoded_userinfo =logfile uri_string_suite.parse_pct_encoded_userinfo.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 3.1e-5 +=elapsed 4.3e-5 =case uri_string_SUITE:parse_host =logfile uri_string_suite.parse_host.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 8.0e-6 +=elapsed 1.1e-5 =case uri_string_SUITE:parse_host_ipv4 =logfile uri_string_suite.parse_host_ipv4.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 2.5e-5 +=elapsed 3.6e-5 =case uri_string_SUITE:parse_host_ipv6 =logfile uri_string_suite.parse_host_ipv6.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 2.9e-5 +=elapsed 3.8e-5 =case uri_string_SUITE:parse_port =logfile uri_string_suite.parse_port.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 2.2e-5 +=elapsed 2.9e-5 =case uri_string_SUITE:parse_path =logfile uri_string_suite.parse_path.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 1.2e-5 +=elapsed 1.6e-5 =case uri_string_SUITE:parse_query =logfile uri_string_suite.parse_query.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 3.0e-5 +=elapsed 4.1e-5 =case uri_string_SUITE:parse_pct_encoded_query =logfile uri_string_suite.parse_pct_encoded_query.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 1.3e-5 +=elapsed 1.7e-5 =case uri_string_SUITE:parse_fragment =logfile uri_string_suite.parse_fragment.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 3.3e-5 +=elapsed 4.6e-5 =case uri_string_SUITE:parse_pct_encoded_fragment =logfile uri_string_suite.parse_pct_encoded_fragment.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 1.7e-5 +=elapsed 2.2e-5 =case uri_string_SUITE:parse_list =logfile uri_string_suite.parse_list.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:29 =result ok -=elapsed 1.2e-5 +=elapsed 1.6e-5 =case uri_string_SUITE:parse_binary =logfile uri_string_suite.parse_binary.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:29 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 9.0e-6 +=elapsed 1.2e-5 =case uri_string_SUITE:parse_mixed =logfile uri_string_suite.parse_mixed.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok =elapsed 6.0e-6 =case uri_string_SUITE:parse_relative =logfile uri_string_suite.parse_relative.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok =elapsed 5.0e-6 =case uri_string_SUITE:parse_special =logfile uri_string_suite.parse_special.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 3.7e-5 +=elapsed 3.8e-5 =case uri_string_SUITE:parse_special2 =logfile uri_string_suite.parse_special2.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 1.7e-5 +=elapsed 1.8e-5 =case uri_string_SUITE:parse_negative =logfile uri_string_suite.parse_negative.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 1.9e-5 +=elapsed 2.0e-5 =case uri_string_SUITE:recompose_fragment =logfile uri_string_suite.recompose_fragment.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 7.0e-6 +=elapsed 8.0e-6 =case uri_string_SUITE:recompose_parse_fragment =logfile uri_string_suite.recompose_parse_fragment.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok =elapsed 1.5e-5 =case uri_string_SUITE:recompose_query =logfile uri_string_suite.recompose_query.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok =elapsed 1.6e-5 =case uri_string_SUITE:recompose_parse_query =logfile uri_string_suite.recompose_parse_query.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 2.4e-5 +=elapsed 3.3e-5 =case uri_string_SUITE:recompose_path =logfile uri_string_suite.recompose_path.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 2.2e-5 +=elapsed 2.3e-5 =case uri_string_SUITE:recompose_parse_path =logfile uri_string_suite.recompose_parse_path.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok =elapsed 2.1e-5 =case uri_string_SUITE:recompose_autogen =logfile uri_string_suite.recompose_autogen.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 0.009992 +=elapsed 0.009854 =case uri_string_SUITE:parse_recompose_autogen =logfile uri_string_suite.parse_recompose_autogen.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 0.014147 +=elapsed 0.014198 =case uri_string_SUITE:resolve_normal_examples =logfile uri_string_suite.resolve_normal_examples.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:26 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 1.95e-4 +=elapsed 1.87e-4 =case uri_string_SUITE:resolve_abnormal_examples =logfile uri_string_suite.resolve_abnormal_examples.html -=started 2024-09-11 11:41:26 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 2.51e-4 +=elapsed 1.89e-4 =case uri_string_SUITE:resolve_base_uri =logfile uri_string_suite.resolve_base_uri.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 5.3e-5 +=elapsed 4.6e-5 =case uri_string_SUITE:resolve_return_map =logfile uri_string_suite.resolve_return_map.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok =elapsed 1.9e-5 =case uri_string_SUITE:transcode_basic =logfile uri_string_suite.transcode_basic.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 3.3e-5 +=elapsed 2.6e-5 =case uri_string_SUITE:transcode_options =logfile uri_string_suite.transcode_options.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 2.4e-5 +=elapsed 1.9e-5 =case uri_string_SUITE:transcode_mixed =logfile uri_string_suite.transcode_mixed.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 2.5e-5 +=elapsed 2.0e-5 =case uri_string_SUITE:transcode_negative =logfile uri_string_suite.transcode_negative.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok =elapsed 4.0e-6 =case uri_string_SUITE:compose_query =logfile uri_string_suite.compose_query.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 3.5e-5 +=elapsed 3.0e-5 =case uri_string_SUITE:compose_query_latin1 =logfile uri_string_suite.compose_query_latin1.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 5.9e-5 +=elapsed 4.9e-5 =case uri_string_SUITE:compose_query_negative =logfile uri_string_suite.compose_query_negative.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 2.0e-6 +=elapsed 3.0e-6 =case uri_string_SUITE:dissect_query =logfile uri_string_suite.dissect_query.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 9.3e-5 +=elapsed 9.2e-5 =case uri_string_SUITE:dissect_query_negative =logfile uri_string_suite.dissect_query_negative.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 1.8e-5 +=elapsed 1.4e-5 =case uri_string_SUITE:interop_query_latin1 =logfile uri_string_suite.interop_query_latin1.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 3.1e-5 +=elapsed 5.0e-5 =case uri_string_SUITE:interop_query_utf8 =logfile uri_string_suite.interop_query_utf8.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 2.7e-5 +=elapsed 2.2e-5 =case uri_string_SUITE:regression_parse =logfile uri_string_suite.regression_parse.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 2.5e-5 +=elapsed 2.2e-5 =case uri_string_SUITE:regression_recompose =logfile uri_string_suite.regression_recompose.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 2.1e-5 +=elapsed 2.3e-5 =case uri_string_SUITE:regression_normalize =logfile uri_string_suite.regression_normalize.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 1.45e-4 +=elapsed 1.12e-4 =case uri_string_SUITE:recompose_host_relative_path =logfile uri_string_suite.recompose_host_relative_path.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 1.1e-5 +=elapsed 1.0e-5 =case uri_string_SUITE:recompose_host_absolute_path =logfile uri_string_suite.recompose_host_absolute_path.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 1.6e-5 +=elapsed 1.2e-5 =case uri_string_SUITE:quote =logfile uri_string_suite.quote.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok -=elapsed 2.33e-4 +=elapsed 1.67e-4 =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.19701410.html +=logfile ct_framework.end_per_suite.19718146.html =group_props [{suite,uri_string_SUITE}] -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:27 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:30 =result ok =elapsed 0.0 -=group_time 1.656s +=group_time 1.676s =case uri_string_property_test_SUITE:init_per_suite =logfile uri_string_property_test_suite.init_per_suite.html -=started 2024-09-11 11:41:27 -=ended 2024-09-11 11:41:28 +=started 2024-09-12 11:03:30 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 1.294834 +=elapsed 1.288106 =case uri_string_property_test_SUITE:recompose =logfile uri_string_property_test_suite.recompose.html -=started 2024-09-11 11:41:28 -=ended 2024-09-11 11:41:28 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 0.072139 +=elapsed 0.07361 =case uri_string_property_test_SUITE:normalize =logfile uri_string_property_test_suite.normalize.html -=started 2024-09-11 11:41:28 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 0.091759 +=elapsed 0.08048 =case uri_string_property_test_SUITE:end_per_suite =logfile uri_string_property_test_suite.end_per_suite.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok =elapsed 0.0 -=group_time 1.555s +=group_time 1.535s =case win32reg_SUITE:init_per_suite =logfile win32reg_suite.init_per_suite.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result skipped: "Doesn't run on UNIX." === *** SKIPPED {win32reg_SUITE,init_per_suite} *** === =case win32reg_SUITE:long -=started 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 =result skipped: Doesn't run on UNIX. === *** Skipping test case #2315 {win32reg_SUITE,long} *** === =case win32reg_SUITE:evil_write -=started 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 =result skipped: Doesn't run on UNIX. === *** Skipping test case #2316 {win32reg_SUITE,evil_write} *** === =case win32reg_SUITE:read_write_default_1 -=started 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 =result skipped: Doesn't run on UNIX. === *** Skipping test case #2317 {win32reg_SUITE,read_write_default_1} *** === =case win32reg_SUITE:read_write_default_2 -=started 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 =result skipped: Doesn't run on UNIX. === *** Skipping test case #2318 {win32reg_SUITE,read_write_default_2} *** === =case win32reg_SUITE:delete_key -=started 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 =result skipped: Doesn't run on UNIX. === *** Skipping test case #2319 {win32reg_SUITE,delete_key} *** === =case win32reg_SUITE:up_and_away -=started 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 =result skipped: Doesn't run on UNIX. === *** Skipping test case #2320 {win32reg_SUITE,up_and_away} *** === =case win32reg_SUITE:end_per_suite -=started 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 =result skipped: Doesn't run on UNIX. === *** Skipping {win32reg_SUITE,end_per_suite} *** =case y2k_SUITE:init_per_suite =logfile y2k_suite.init_per_suite.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok =elapsed 0.0 =case y2k_SUITE:date_1999_01_01 =logfile y2k_suite.date_1999_01_01.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 2.3e-5 +=elapsed 3.6e-5 =case y2k_SUITE:date_1999_02_28 =logfile y2k_suite.date_1999_02_28.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 2.2e-5 +=elapsed 2.1e-5 =case y2k_SUITE:date_1999_09_09 =logfile y2k_suite.date_1999_09_09.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 2.2e-5 +=elapsed 1.8e-5 =case y2k_SUITE:date_2000_01_01 =logfile y2k_suite.date_2000_01_01.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 3.8e-5 +=elapsed 3.1e-5 =case y2k_SUITE:date_2000_02_29 =logfile y2k_suite.date_2000_02_29.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 3.8e-5 +=elapsed 3.1e-5 =case y2k_SUITE:date_2001_01_01 =logfile y2k_suite.date_2001_01_01.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 2.3e-5 +=elapsed 1.8e-5 =case y2k_SUITE:date_2001_02_29 =logfile y2k_suite.date_2001_02_29.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 2.3e-5 +=elapsed 1.9e-5 =case y2k_SUITE:date_2004_02_29 =logfile y2k_suite.date_2004_02_29.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 3.8e-5 +=elapsed 3.1e-5 =case y2k_SUITE:end_per_suite =logfile y2k_suite.end_per_suite.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok =elapsed 0.0 -=group_time 0.221s +=group_time 0.213s =case zip_SUITE:init_per_suite =logfile zip_suite.init_per_suite.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 0.03347 +=elapsed 0.033977 =case zip_SUITE:borderline =logfile zip_suite.borderline.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 0.110592 +=elapsed 0.107331 =case zip_SUITE:atomic =logfile zip_suite.atomic.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 0.004327 +=elapsed 0.004092 =case zip_SUITE:bad_zip =logfile zip_suite.bad_zip.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 0.001571 +=elapsed 0.001156 =case zip_SUITE:unzip_from_binary =logfile zip_suite.unzip_from_binary.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 0.003762 +=elapsed 0.004113 =case zip_SUITE:unzip_to_binary =logfile zip_suite.unzip_to_binary.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:32 =result ok -=elapsed 7.63e-4 +=elapsed 7.71e-4 =case zip_SUITE:zip_to_binary =logfile zip_suite.zip_to_binary.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:32 +=ended 2024-09-12 11:03:33 =result ok -=elapsed 0.001057 +=elapsed 8.12e-4 =case zip_SUITE:unzip_options =logfile zip_suite.unzip_options.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:33 +=ended 2024-09-12 11:03:33 =result ok -=elapsed 0.004253 +=elapsed 0.003307 =case zip_SUITE:zip_options =logfile zip_suite.zip_options.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:33 +=ended 2024-09-12 11:03:33 =result ok -=elapsed 0.002839 +=elapsed 0.002836 =case zip_SUITE:list_dir_options =logfile zip_suite.list_dir_options.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:33 +=ended 2024-09-12 11:03:33 =result ok -=elapsed 5.01e-4 +=elapsed 2.52e-4 =case zip_SUITE:aliases =logfile zip_suite.aliases.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:33 +=ended 2024-09-12 11:03:33 =result ok -=elapsed 1.52e-4 +=elapsed 1.3e-4 =case zip_SUITE:zip_api =logfile zip_suite.zip_api.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:33 +=ended 2024-09-12 11:03:33 =result ok -=elapsed 0.003159 +=elapsed 0.003187 =case zip_SUITE:open_leak =logfile zip_suite.open_leak.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:33 +=ended 2024-09-12 11:03:33 =result ok -=elapsed 3.41e-4 +=elapsed 1.86e-4 =case zip_SUITE:unzip_jar =logfile zip_suite.unzip_jar.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:33 +=ended 2024-09-12 11:03:33 =result ok -=elapsed 0.00255 +=elapsed 0.00156 =case zip_SUITE:compress_control =logfile zip_suite.compress_control.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:33 +=ended 2024-09-12 11:03:33 =result ok -=elapsed 0.043547 +=elapsed 0.028913 =case zip_SUITE:foldl =logfile zip_suite.foldl.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:33 +=ended 2024-09-12 11:03:33 =result ok -=elapsed 7.39e-4 +=elapsed 7.27e-4 =case zip_SUITE:unzip_traversal_exploit =logfile zip_suite.unzip_traversal_exploit.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:29 +=started 2024-09-12 11:03:33 +=ended 2024-09-12 11:03:33 =result ok -=elapsed 0.008072 +=elapsed 0.007239 =case zip_SUITE:fd_leak =logfile zip_suite.fd_leak.html -=started 2024-09-11 11:41:29 -=ended 2024-09-11 11:41:31 +=started 2024-09-12 11:03:33 +=ended 2024-09-12 11:03:35 =result ok -=elapsed 1.811028 +=elapsed 1.885194 =case zip_SUITE:unicode =logfile zip_suite.unicode.html -=started 2024-09-11 11:41:31 -=ended 2024-09-11 11:41:31 +=started 2024-09-12 11:03:35 +=ended 2024-09-12 11:03:35 =result ok -=elapsed 0.11383 +=elapsed 0.117634 =case zip_SUITE:test_zip_dir =logfile zip_suite.test_zip_dir.html -=started 2024-09-11 11:41:31 -=ended 2024-09-11 11:41:31 +=started 2024-09-12 11:03:35 +=ended 2024-09-12 11:03:35 =result ok -=elapsed 0.003042 +=elapsed 0.002824 =case zip_SUITE:explicit_file_info =logfile zip_suite.explicit_file_info.html -=started 2024-09-11 11:41:31 -=ended 2024-09-11 11:41:32 +=started 2024-09-12 11:03:35 +=ended 2024-09-12 11:03:35 =result ok -=elapsed 5.9e-5 +=elapsed 5.7e-5 =case zip_SUITE:init_per_group =logfile zip_suite.init_per_group.html =group_props [{name,zip_group}] -=started 2024-09-11 11:41:32 -=ended 2024-09-11 11:41:32 +=started 2024-09-12 11:03:35 +=ended 2024-09-12 11:03:35 =result ok -=elapsed 7.0e-6 +=elapsed 6.0e-6 =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19701442.html +=logfile zip_suite.init_per_group.19718178.html =group_props [{name,zip}] -=started 2024-09-11 11:41:32 -=ended 2024-09-11 11:41:32 +=started 2024-09-12 11:03:35 +=ended 2024-09-12 11:03:35 =result ok -=elapsed 3.38e-4 +=elapsed 3.49e-4 =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19701474.html +=logfile zip_suite.init_per_group.19718210.html =group_props [{name,unzip},parallel] -=started 2024-09-11 11:41:32 -=ended 2024-09-11 11:41:32 +=started 2024-09-12 11:03:35 +=ended 2024-09-12 11:03:35 =result ok -=elapsed 3.56e-4 +=elapsed 2.06e-4 =case zip_SUITE:mode -=logfile zip_suite.mode.504675.html -=started 2024-09-11 11:41:32 -=ended 2024-09-11 11:41:32 +=logfile zip_suite.mode.408547.html +=started 2024-09-12 11:03:35 +=ended 2024-09-12 11:03:35 =result ok -=elapsed 0.008756 +=elapsed 0.00875 =case zip_SUITE:basic_timestamp -=logfile zip_suite.basic_timestamp.504707.html -=started 2024-09-11 11:41:32 -=ended 2024-09-11 11:41:34 +=logfile zip_suite.basic_timestamp.408579.html +=started 2024-09-12 11:03:35 +=ended 2024-09-12 11:03:37 =result ok -=elapsed 2.010894 +=elapsed 2.013023 =case zip_SUITE:extended_timestamp -=logfile zip_suite.extended_timestamp.504739.html -=started 2024-09-11 11:41:32 -=ended 2024-09-11 11:41:34 +=logfile zip_suite.extended_timestamp.408611.html +=started 2024-09-12 11:03:35 +=ended 2024-09-12 11:03:37 =result ok -=elapsed 2.01225 +=elapsed 2.012875 =case zip_SUITE:uid_gid -=logfile zip_suite.uid_gid.504771.html -=started 2024-09-11 11:41:32 -=ended 2024-09-11 11:41:32 +=logfile zip_suite.uid_gid.408643.html +=started 2024-09-12 11:03:35 +=ended 2024-09-12 11:03:35 =result ok -=elapsed 0.008079 +=elapsed 0.00763 =case zip_SUITE:end_per_group =logfile zip_suite.end_per_group.html =group_props [{name,unzip},parallel] -=started 2024-09-11 11:41:34 -=ended 2024-09-11 11:41:34 +=started 2024-09-12 11:03:37 +=ended 2024-09-12 11:03:37 =result ok -=elapsed 6.09e-4 -=group_time 2.062s +=elapsed 9.3e-4 +=group_time 2.064s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19701506.html +=logfile zip_suite.init_per_group.408675.html =group_props [{name,unezip},parallel] -=started 2024-09-11 11:41:34 -=ended 2024-09-11 11:41:34 +=started 2024-09-12 11:03:37 +=ended 2024-09-12 11:03:37 =result ok -=elapsed 1.28e-4 +=elapsed 1.23e-4 =case zip_SUITE:mode -=logfile zip_suite.mode.19701538.html -=started 2024-09-11 11:41:34 -=ended 2024-09-11 11:41:34 +=logfile zip_suite.mode.408707.html +=started 2024-09-12 11:03:37 +=ended 2024-09-12 11:03:37 =result ok -=elapsed 0.006631 +=elapsed 0.006493 =case zip_SUITE:basic_timestamp -=logfile zip_suite.basic_timestamp.19701570.html -=started 2024-09-11 11:41:34 -=ended 2024-09-11 11:41:36 +=logfile zip_suite.basic_timestamp.408739.html +=started 2024-09-12 11:03:37 +=ended 2024-09-12 11:03:39 =result ok -=elapsed 2.009973 +=elapsed 2.010071 =case zip_SUITE:extended_timestamp -=logfile zip_suite.extended_timestamp.19701602.html -=started 2024-09-11 11:41:34 -=ended 2024-09-11 11:41:36 +=logfile zip_suite.extended_timestamp.408771.html +=started 2024-09-12 11:03:37 +=ended 2024-09-12 11:03:39 =result ok -=elapsed 2.008746 +=elapsed 2.009845 =case zip_SUITE:uid_gid -=logfile zip_suite.uid_gid.19701634.html -=started 2024-09-11 11:41:34 -=ended 2024-09-11 11:41:34 +=logfile zip_suite.uid_gid.408803.html +=started 2024-09-12 11:03:37 +=ended 2024-09-12 11:03:37 =result ok -=elapsed 0.004634 +=elapsed 0.006257 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19701666.html +=logfile zip_suite.end_per_group.426084.html =group_props [{name,unezip},parallel] -=started 2024-09-11 11:41:36 -=ended 2024-09-11 11:41:36 +=started 2024-09-12 11:03:39 +=ended 2024-09-12 11:03:39 =result ok -=elapsed 8.93e-4 -=group_time 2.060s +=elapsed 9.2e-4 +=group_time 2.061s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19701698.html +=logfile zip_suite.init_per_group.426116.html =group_props [{name,unemzip},parallel] -=started 2024-09-11 11:41:36 -=ended 2024-09-11 11:41:36 +=started 2024-09-12 11:03:39 +=ended 2024-09-12 11:03:39 =result ok -=elapsed 1.48e-4 +=elapsed 1.5e-4 =case zip_SUITE:mode -=logfile zip_suite.mode.19701730.html -=started 2024-09-11 11:41:36 -=ended 2024-09-11 11:41:36 +=logfile zip_suite.mode.426148.html +=started 2024-09-12 11:03:39 +=ended 2024-09-12 11:03:39 =result ok -=elapsed 0.005303 +=elapsed 0.005927 =case zip_SUITE:basic_timestamp -=logfile zip_suite.basic_timestamp.19701762.html -=started 2024-09-11 11:41:36 -=ended 2024-09-11 11:41:38 +=logfile zip_suite.basic_timestamp.426180.html +=started 2024-09-12 11:03:39 +=ended 2024-09-12 11:03:41 =result ok -=elapsed 2.00888 +=elapsed 2.010633 =case zip_SUITE:extended_timestamp -=logfile zip_suite.extended_timestamp.19701794.html -=started 2024-09-11 11:41:36 -=ended 2024-09-11 11:41:38 +=logfile zip_suite.extended_timestamp.426212.html +=started 2024-09-12 11:03:39 +=ended 2024-09-12 11:03:41 =result ok -=elapsed 2.009976 +=elapsed 2.010253 =case zip_SUITE:uid_gid -=logfile zip_suite.uid_gid.504803.html -=started 2024-09-11 11:41:36 -=ended 2024-09-11 11:41:36 +=logfile zip_suite.uid_gid.426244.html +=started 2024-09-12 11:03:39 +=ended 2024-09-12 11:03:39 =result ok -=elapsed 0.004225 +=elapsed 0.004476 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.504835.html +=logfile zip_suite.end_per_group.426276.html =group_props [{name,unemzip},parallel] -=started 2024-09-11 11:41:38 -=ended 2024-09-11 11:41:38 +=started 2024-09-12 11:03:41 +=ended 2024-09-12 11:03:41 =result ok -=elapsed 7.55e-4 -=group_time 2.060s +=elapsed 9.57e-4 +=group_time 2.061s =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19701826.html +=logfile zip_suite.end_per_group.426308.html =group_props [{name,zip}] -=started 2024-09-11 11:41:38 -=ended 2024-09-11 11:41:38 +=started 2024-09-12 11:03:41 +=ended 2024-09-12 11:03:41 =result ok -=elapsed 5.8e-4 -=group_time 6.276s +=elapsed 5.77e-4 +=group_time 6.282s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19701858.html +=logfile zip_suite.init_per_group.426340.html =group_props [{name,ezip}] -=started 2024-09-11 11:41:38 -=ended 2024-09-11 11:41:38 +=started 2024-09-12 11:03:41 +=ended 2024-09-12 11:03:41 =result ok -=elapsed 1.29e-4 +=elapsed 1.88e-4 =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19701890.html +=logfile zip_suite.init_per_group.426372.html =group_props [{name,unzip},parallel] -=started 2024-09-11 11:41:38 -=ended 2024-09-11 11:41:38 +=started 2024-09-12 11:03:41 +=ended 2024-09-12 11:03:41 =result ok -=elapsed 2.76e-4 +=elapsed 2.27e-4 =case zip_SUITE:mode -=logfile zip_suite.mode.19701922.html -=started 2024-09-11 11:41:38 -=ended 2024-09-11 11:41:38 +=logfile zip_suite.mode.426404.html +=started 2024-09-12 11:03:41 +=ended 2024-09-12 11:03:41 =result ok -=elapsed 0.00591 +=elapsed 0.006201 =case zip_SUITE:basic_timestamp -=logfile zip_suite.basic_timestamp.19701954.html -=started 2024-09-11 11:41:38 -=ended 2024-09-11 11:41:40 +=logfile zip_suite.basic_timestamp.426436.html +=started 2024-09-12 11:03:41 +=ended 2024-09-12 11:03:43 =result ok -=elapsed 2.009219 +=elapsed 2.009614 =case zip_SUITE:extended_timestamp -=logfile zip_suite.extended_timestamp.504867.html -=started 2024-09-11 11:41:38 -=ended 2024-09-11 11:41:40 +=logfile zip_suite.extended_timestamp.426468.html +=started 2024-09-12 11:03:41 +=ended 2024-09-12 11:03:43 =result ok -=elapsed 2.01004 +=elapsed 2.009803 =case zip_SUITE:uid_gid -=logfile zip_suite.uid_gid.504899.html -=started 2024-09-11 11:41:38 -=ended 2024-09-11 11:41:38 +=logfile zip_suite.uid_gid.426500.html +=started 2024-09-12 11:03:41 +=ended 2024-09-12 11:03:41 =result ok -=elapsed 0.004949 +=elapsed 0.005831 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.504931.html +=logfile zip_suite.end_per_group.19718242.html =group_props [{name,unzip},parallel] -=started 2024-09-11 11:41:40 -=ended 2024-09-11 11:41:40 +=started 2024-09-12 11:03:43 +=ended 2024-09-12 11:03:43 =result ok -=elapsed 8.06e-4 -=group_time 2.060s +=elapsed 6.75e-4 +=group_time 2.061s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.504963.html +=logfile zip_suite.init_per_group.19718274.html =group_props [{name,unezip},parallel] -=started 2024-09-11 11:41:40 -=ended 2024-09-11 11:41:40 +=started 2024-09-12 11:03:43 +=ended 2024-09-12 11:03:43 =result ok -=elapsed 1.39e-4 +=elapsed 1.47e-4 =case zip_SUITE:mode -=logfile zip_suite.mode.504995.html -=started 2024-09-11 11:41:40 -=ended 2024-09-11 11:41:40 +=logfile zip_suite.mode.19718306.html +=started 2024-09-12 11:03:43 +=ended 2024-09-12 11:03:43 =result ok -=elapsed 0.002883 +=elapsed 0.003929 =case zip_SUITE:basic_timestamp -=logfile zip_suite.basic_timestamp.505027.html -=started 2024-09-11 11:41:40 -=ended 2024-09-11 11:41:42 +=logfile zip_suite.basic_timestamp.19718370.html +=started 2024-09-12 11:03:43 +=ended 2024-09-12 11:03:45 =result ok -=elapsed 2.007081 +=elapsed 2.009314 =case zip_SUITE:extended_timestamp -=logfile zip_suite.extended_timestamp.505059.html -=started 2024-09-11 11:41:40 -=ended 2024-09-11 11:41:42 +=logfile zip_suite.extended_timestamp.19718338.html +=started 2024-09-12 11:03:43 +=ended 2024-09-12 11:03:45 =result ok -=elapsed 2.007632 +=elapsed 2.008671 =case zip_SUITE:uid_gid -=logfile zip_suite.uid_gid.505091.html -=started 2024-09-11 11:41:40 -=ended 2024-09-11 11:41:40 +=logfile zip_suite.uid_gid.19718402.html +=started 2024-09-12 11:03:43 +=ended 2024-09-12 11:03:43 =result ok -=elapsed 0.001589 +=elapsed 0.003003 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.505123.html +=logfile zip_suite.end_per_group.426532.html =group_props [{name,unezip},parallel] -=started 2024-09-11 11:41:42 -=ended 2024-09-11 11:41:42 +=started 2024-09-12 11:03:45 +=ended 2024-09-12 11:03:45 =result ok -=elapsed 7.21e-4 -=group_time 2.059s +=elapsed 7.27e-4 +=group_time 2.060s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19701986.html +=logfile zip_suite.init_per_group.426564.html =group_props [{name,unemzip},parallel] -=started 2024-09-11 11:41:42 -=ended 2024-09-11 11:41:42 +=started 2024-09-12 11:03:45 +=ended 2024-09-12 11:03:45 =result ok =elapsed 1.58e-4 =case zip_SUITE:mode -=logfile zip_suite.mode.505155.html -=started 2024-09-11 11:41:42 -=ended 2024-09-11 11:41:42 +=logfile zip_suite.mode.426596.html +=started 2024-09-12 11:03:45 +=ended 2024-09-12 11:03:45 =result ok -=elapsed 0.003387 +=elapsed 0.003916 =case zip_SUITE:basic_timestamp -=logfile zip_suite.basic_timestamp.505187.html -=started 2024-09-11 11:41:42 -=ended 2024-09-11 11:41:44 +=logfile zip_suite.basic_timestamp.426628.html +=started 2024-09-12 11:03:45 +=ended 2024-09-12 11:03:47 =result ok -=elapsed 2.006366 +=elapsed 2.006595 =case zip_SUITE:extended_timestamp -=logfile zip_suite.extended_timestamp.505219.html -=started 2024-09-11 11:41:42 -=ended 2024-09-11 11:41:44 +=logfile zip_suite.extended_timestamp.426660.html +=started 2024-09-12 11:03:45 +=ended 2024-09-12 11:03:47 =result ok -=elapsed 2.006017 +=elapsed 2.006987 =case zip_SUITE:uid_gid -=logfile zip_suite.uid_gid.19702018.html -=started 2024-09-11 11:41:42 -=ended 2024-09-11 11:41:42 +=logfile zip_suite.uid_gid.408835.html +=started 2024-09-12 11:03:45 +=ended 2024-09-12 11:03:45 =result ok -=elapsed 0.001794 +=elapsed 0.003169 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19702050.html +=logfile zip_suite.end_per_group.408867.html =group_props [{name,unemzip},parallel] -=started 2024-09-11 11:41:44 -=ended 2024-09-11 11:41:44 +=started 2024-09-12 11:03:47 +=ended 2024-09-12 11:03:47 =result ok -=elapsed 6.59e-4 -=group_time 2.058s +=elapsed 7.35e-4 +=group_time 2.059s =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19702082.html +=logfile zip_suite.end_per_group.408899.html =group_props [{name,ezip}] -=started 2024-09-11 11:41:44 -=ended 2024-09-11 11:41:44 +=started 2024-09-12 11:03:47 +=ended 2024-09-12 11:03:48 =result ok -=elapsed 5.33e-4 -=group_time 6.273s +=elapsed 6.97e-4 +=group_time 6.275s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19702114.html +=logfile zip_suite.init_per_group.408931.html =group_props [{name,emzip}] -=started 2024-09-11 11:41:44 -=ended 2024-09-11 11:41:44 +=started 2024-09-12 11:03:48 +=ended 2024-09-12 11:03:48 =result ok -=elapsed 1.56e-4 +=elapsed 2.76e-4 =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19702146.html +=logfile zip_suite.init_per_group.408963.html =group_props [{name,unzip},parallel] -=started 2024-09-11 11:41:44 -=ended 2024-09-11 11:41:44 +=started 2024-09-12 11:03:48 +=ended 2024-09-12 11:03:48 =result ok -=elapsed 2.74e-4 +=elapsed 3.16e-4 =case zip_SUITE:mode -=logfile zip_suite.mode.505251.html -=started 2024-09-11 11:41:44 -=ended 2024-09-11 11:41:44 +=logfile zip_suite.mode.408995.html +=started 2024-09-12 11:03:48 +=ended 2024-09-12 11:03:48 =result ok -=elapsed 0.005143 +=elapsed 0.006655 =case zip_SUITE:basic_timestamp -=logfile zip_suite.basic_timestamp.505283.html -=started 2024-09-11 11:41:44 -=ended 2024-09-11 11:41:46 +=logfile zip_suite.basic_timestamp.409027.html +=started 2024-09-12 11:03:48 +=ended 2024-09-12 11:03:50 =result ok -=elapsed 2.010651 +=elapsed 2.009878 =case zip_SUITE:extended_timestamp -=logfile zip_suite.extended_timestamp.505315.html -=started 2024-09-11 11:41:44 -=ended 2024-09-11 11:41:46 +=logfile zip_suite.extended_timestamp.409059.html +=started 2024-09-12 11:03:48 +=ended 2024-09-12 11:03:50 =result ok -=elapsed 2.010007 +=elapsed 2.010535 =case zip_SUITE:uid_gid -=logfile zip_suite.uid_gid.505347.html -=started 2024-09-11 11:41:44 -=ended 2024-09-11 11:41:44 +=logfile zip_suite.uid_gid.19718434.html +=started 2024-09-12 11:03:48 +=ended 2024-09-12 11:03:48 =result ok -=elapsed 0.004795 +=elapsed 0.005937 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19702178.html +=logfile zip_suite.end_per_group.19718466.html =group_props [{name,unzip},parallel] -=started 2024-09-11 11:41:46 -=ended 2024-09-11 11:41:46 +=started 2024-09-12 11:03:50 +=ended 2024-09-12 11:03:50 =result ok -=elapsed 8.15e-4 -=group_time 2.060s +=elapsed 7.59e-4 +=group_time 2.063s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.398596.html +=logfile zip_suite.init_per_group.19718498.html =group_props [{name,unezip},parallel] -=started 2024-09-11 11:41:46 -=ended 2024-09-11 11:41:46 +=started 2024-09-12 11:03:50 +=ended 2024-09-12 11:03:50 =result ok -=elapsed 1.91e-4 +=elapsed 1.71e-4 =case zip_SUITE:mode -=logfile zip_suite.mode.398628.html -=started 2024-09-11 11:41:46 -=ended 2024-09-11 11:41:46 +=logfile zip_suite.mode.19718530.html +=started 2024-09-12 11:03:50 +=ended 2024-09-12 11:03:50 =result ok -=elapsed 0.004319 +=elapsed 0.004305 =case zip_SUITE:basic_timestamp -=logfile zip_suite.basic_timestamp.398660.html -=started 2024-09-11 11:41:46 -=ended 2024-09-11 11:41:48 +=logfile zip_suite.basic_timestamp.426724.html +=started 2024-09-12 11:03:50 +=ended 2024-09-12 11:03:52 =result ok -=elapsed 2.007758 +=elapsed 2.008902 =case zip_SUITE:extended_timestamp -=logfile zip_suite.extended_timestamp.398692.html -=started 2024-09-11 11:41:46 -=ended 2024-09-11 11:41:48 +=logfile zip_suite.extended_timestamp.426756.html +=started 2024-09-12 11:03:50 +=ended 2024-09-12 11:03:52 =result ok -=elapsed 2.006731 +=elapsed 2.008962 =case zip_SUITE:uid_gid -=logfile zip_suite.uid_gid.398724.html -=started 2024-09-11 11:41:46 -=ended 2024-09-11 11:41:46 +=logfile zip_suite.uid_gid.426692.html +=started 2024-09-12 11:03:50 +=ended 2024-09-12 11:03:50 =result ok -=elapsed 0.002188 +=elapsed 0.002656 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.398756.html +=logfile zip_suite.end_per_group.426788.html =group_props [{name,unezip},parallel] -=started 2024-09-11 11:41:48 -=ended 2024-09-11 11:41:48 +=started 2024-09-12 11:03:52 +=ended 2024-09-12 11:03:52 =result ok -=elapsed 6.91e-4 -=group_time 2.058s +=elapsed 0.001072 +=group_time 2.063s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.398788.html +=logfile zip_suite.init_per_group.429029.html =group_props [{name,unemzip},parallel] -=started 2024-09-11 11:41:48 -=ended 2024-09-11 11:41:48 +=started 2024-09-12 11:03:52 +=ended 2024-09-12 11:03:52 =result ok -=elapsed 1.41e-4 +=elapsed 1.55e-4 =case zip_SUITE:mode -=logfile zip_suite.mode.19702210.html -=started 2024-09-11 11:41:48 -=ended 2024-09-11 11:41:48 +=logfile zip_suite.mode.19718594.html +=started 2024-09-12 11:03:52 +=ended 2024-09-12 11:03:52 =result ok -=elapsed 0.003407 +=elapsed 0.003973 =case zip_SUITE:basic_timestamp -=logfile zip_suite.basic_timestamp.398820.html -=started 2024-09-11 11:41:48 -=ended 2024-09-11 11:41:50 +=logfile zip_suite.basic_timestamp.19718562.html +=started 2024-09-12 11:03:52 +=ended 2024-09-12 11:03:54 =result ok -=elapsed 2.007142 +=elapsed 2.006516 =case zip_SUITE:extended_timestamp -=logfile zip_suite.extended_timestamp.19702242.html -=started 2024-09-11 11:41:48 -=ended 2024-09-11 11:41:50 +=logfile zip_suite.extended_timestamp.19718658.html +=started 2024-09-12 11:03:52 +=ended 2024-09-12 11:03:54 =result ok -=elapsed 2.00696 +=elapsed 2.006455 =case zip_SUITE:uid_gid -=logfile zip_suite.uid_gid.19702274.html -=started 2024-09-11 11:41:48 -=ended 2024-09-11 11:41:48 +=logfile zip_suite.uid_gid.19718626.html +=started 2024-09-12 11:03:52 +=ended 2024-09-12 11:03:52 =result ok -=elapsed 0.002098 +=elapsed 0.00309 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19702306.html +=logfile zip_suite.end_per_group.19718690.html =group_props [{name,unemzip},parallel] -=started 2024-09-11 11:41:50 -=ended 2024-09-11 11:41:50 +=started 2024-09-12 11:03:54 +=ended 2024-09-12 11:03:54 =result ok -=elapsed 7.99e-4 -=group_time 2.059s +=elapsed 7.32e-4 +=group_time 2.060s =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19702338.html +=logfile zip_suite.end_per_group.19718722.html =group_props [{name,emzip}] -=started 2024-09-11 11:41:50 -=ended 2024-09-11 11:41:50 +=started 2024-09-12 11:03:54 +=ended 2024-09-12 11:03:54 =result ok -=elapsed 6.68e-4 -=group_time 6.272s +=elapsed 6.56e-4 +=group_time 6.283s =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19702370.html +=logfile zip_suite.end_per_group.429061.html =group_props [{name,zip_group}] -=started 2024-09-11 11:41:50 -=ended 2024-09-11 11:41:50 +=started 2024-09-12 11:03:54 +=ended 2024-09-12 11:03:54 =result ok -=elapsed 0.003588 -=group_time 18.915s +=elapsed 0.003754 +=group_time 18.934s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19702402.html +=logfile zip_suite.init_per_group.429093.html =group_props [{name,zip64_group}] -=started 2024-09-11 11:41:50 -=ended 2024-09-11 11:41:58 +=started 2024-09-12 11:03:54 +=ended 2024-09-12 11:04:02 =result ok -=elapsed 7.950193 +=elapsed 7.928808 =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19702434.html +=logfile zip_suite.init_per_group.19718754.html =group_props [{name,z64_zip},sequence] -=started 2024-09-11 11:41:58 -=ended 2024-09-11 11:41:58 +=started 2024-09-12 11:04:02 +=ended 2024-09-12 11:04:02 =result ok -=elapsed 3.08e-4 +=elapsed 2.79e-4 =case zip_SUITE:zip64_central_headers =logfile zip_suite.zip64_central_headers.html -=started 2024-09-11 11:41:58 -=ended 2024-09-11 11:43:09 +=started 2024-09-12 11:04:02 +=ended 2024-09-12 11:05:15 =result ok -=elapsed 70.090771 +=elapsed 73.310662 =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19702466.html +=logfile zip_suite.init_per_group.19718786.html =group_props [{name,z64_unzip}] -=started 2024-09-11 11:43:09 -=ended 2024-09-11 11:43:09 +=started 2024-09-12 11:05:15 +=ended 2024-09-12 11:05:15 =result ok -=elapsed 0.002145 +=elapsed 0.046473 =case zip_SUITE:unzip64_central_headers =logfile zip_suite.unzip64_central_headers.html -=started 2024-09-11 11:43:09 -=ended 2024-09-11 11:44:47 +=started 2024-09-12 11:05:15 +=ended 2024-09-12 11:06:59 =result ok -=elapsed 98.11681 +=elapsed 103.992677 =case zip_SUITE:zip64_central_directory =logfile zip_suite.zip64_central_directory.html -=started 2024-09-11 11:44:47 -=ended 2024-09-11 11:45:02 +=started 2024-09-12 11:06:59 +=ended 2024-09-12 11:07:16 =result ok -=elapsed 10.67022 +=elapsed 10.131502 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19702498.html +=logfile zip_suite.end_per_group.19718818.html =group_props [{name,z64_unzip}] -=started 2024-09-11 11:45:02 -=ended 2024-09-11 11:45:02 +=started 2024-09-12 11:07:16 +=ended 2024-09-12 11:07:16 =result ok -=elapsed 4.27e-4 -=group_time 113.530s +=elapsed 4.97e-4 +=group_time 120.307s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19702530.html +=logfile zip_suite.init_per_group.19718850.html =group_props [{name,z64_unezip}] -=started 2024-09-11 11:45:02 -=ended 2024-09-11 11:45:02 +=started 2024-09-12 11:07:16 +=ended 2024-09-12 11:07:16 =result ok -=elapsed 1.18e-4 +=elapsed 1.99e-4 =case zip_SUITE:unzip64_central_headers -=logfile zip_suite.unzip64_central_headers.19702562.html -=started 2024-09-11 11:45:02 -=ended 2024-09-11 11:46:17 +=logfile zip_suite.unzip64_central_headers.19718882.html +=started 2024-09-12 11:07:16 +=ended 2024-09-12 11:08:27 =result ok -=elapsed 75.188508 +=elapsed 71.33177 =case zip_SUITE:zip64_central_directory -=logfile zip_suite.zip64_central_directory.19702594.html -=started 2024-09-11 11:46:17 -=ended 2024-09-11 11:46:34 +=logfile zip_suite.zip64_central_directory.19718914.html +=started 2024-09-12 11:08:27 +=ended 2024-09-12 11:08:50 =result ok -=elapsed 11.900445 +=elapsed 15.915992 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19702626.html +=logfile zip_suite.end_per_group.19718946.html =group_props [{name,z64_unezip}] -=started 2024-09-11 11:46:34 -=ended 2024-09-11 11:46:34 +=started 2024-09-12 11:08:50 +=ended 2024-09-12 11:08:50 =result ok -=elapsed 5.74e-4 -=group_time 91.635s +=elapsed 5.92e-4 +=group_time 94.079s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19702658.html +=logfile zip_suite.init_per_group.19718978.html =group_props [{name,z64_unemzip}] -=started 2024-09-11 11:46:34 -=ended 2024-09-11 11:46:34 +=started 2024-09-12 11:08:50 +=ended 2024-09-12 11:08:50 =result ok -=elapsed 1.41e-4 +=elapsed 1.74e-4 =case zip_SUITE:unzip64_central_headers -=logfile zip_suite.unzip64_central_headers.19702690.html -=started 2024-09-11 11:46:34 -=ended 2024-09-11 11:47:53 +=logfile zip_suite.unzip64_central_headers.19719010.html +=started 2024-09-12 11:08:50 +=ended 2024-09-12 11:10:22 =result ok -=elapsed 79.521362 +=elapsed 91.950015 =case zip_SUITE:zip64_central_directory -=logfile zip_suite.zip64_central_directory.19703138.html -=started 2024-09-11 11:47:53 -=ended 2024-09-11 11:48:11 +=logfile zip_suite.zip64_central_directory.409123.html +=started 2024-09-12 11:10:22 +=ended 2024-09-12 11:10:41 =result ok -=elapsed 12.72571 +=elapsed 14.802929 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19703234.html +=logfile zip_suite.end_per_group.19719458.html =group_props [{name,z64_unemzip}] -=started 2024-09-11 11:48:11 -=ended 2024-09-11 11:48:11 +=started 2024-09-12 11:10:41 +=ended 2024-09-12 11:10:41 =result ok -=elapsed 0.001032 -=group_time 96.852s +=elapsed 6.87e-4 +=group_time 111.783s =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19703266.html +=logfile zip_suite.end_per_group.19719490.html =group_props [{name,z64_zip},sequence] -=started 2024-09-11 11:48:11 -=ended 2024-09-11 11:48:11 +=started 2024-09-12 11:10:41 +=ended 2024-09-12 11:10:42 =result ok -=elapsed 0.600516 -=group_time 372.231s +=elapsed 0.490496 +=group_time 399.678s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19703298.html +=logfile zip_suite.init_per_group.19719522.html =group_props [{name,z64_ezip},sequence] -=started 2024-09-11 11:48:11 -=ended 2024-09-11 11:48:11 +=started 2024-09-12 11:10:42 +=ended 2024-09-12 11:10:42 =result ok -=elapsed 8.3e-4 +=elapsed 8.11e-4 =case zip_SUITE:zip64_central_headers -=logfile zip_suite.zip64_central_headers.19703330.html -=started 2024-09-11 11:48:11 -=ended 2024-09-11 11:49:37 +=logfile zip_suite.zip64_central_headers.19719554.html +=started 2024-09-12 11:10:42 +=ended 2024-09-12 11:12:08 =result ok -=elapsed 85.773219 +=elapsed 86.386017 =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19703362.html +=logfile zip_suite.init_per_group.19719586.html =group_props [{name,z64_unzip}] -=started 2024-09-11 11:49:37 -=ended 2024-09-11 11:49:37 +=started 2024-09-12 11:12:09 +=ended 2024-09-12 11:12:09 =result ok -=elapsed 4.21e-4 +=elapsed 2.64e-4 =case zip_SUITE:unzip64_central_headers -=logfile zip_suite.unzip64_central_headers.19703394.html -=started 2024-09-11 11:49:37 -=ended 2024-09-11 11:51:34 +=logfile zip_suite.unzip64_central_headers.19719618.html +=started 2024-09-12 11:12:09 +=ended 2024-09-12 11:14:07 =result ok -=elapsed 117.172828 +=elapsed 118.054498 =case zip_SUITE:zip64_central_directory -=logfile zip_suite.zip64_central_directory.505379.html -=started 2024-09-11 11:51:34 -=ended 2024-09-11 11:51:57 +=logfile zip_suite.zip64_central_directory.19719650.html +=started 2024-09-12 11:14:07 +=ended 2024-09-12 11:14:38 =result ok -=elapsed 18.128642 +=elapsed 25.373902 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19703426.html +=logfile zip_suite.end_per_group.19719682.html =group_props [{name,z64_unzip}] -=started 2024-09-11 11:51:57 -=ended 2024-09-11 11:51:57 +=started 2024-09-12 11:14:38 +=ended 2024-09-12 11:14:38 =result ok -=elapsed 6.65e-4 -=group_time 139.914s +=elapsed 0.001252 +=group_time 149.156s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19703458.html +=logfile zip_suite.init_per_group.19719714.html =group_props [{name,z64_unezip}] -=started 2024-09-11 11:51:57 -=ended 2024-09-11 11:51:57 +=started 2024-09-12 11:14:38 +=ended 2024-09-12 11:14:38 =result ok -=elapsed 1.84e-4 +=elapsed 1.91e-4 =case zip_SUITE:unzip64_central_headers -=logfile zip_suite.unzip64_central_headers.19703490.html -=started 2024-09-11 11:51:57 -=ended 2024-09-11 11:53:21 +=logfile zip_suite.unzip64_central_headers.19719746.html +=started 2024-09-12 11:14:38 +=ended 2024-09-12 11:16:02 =result ok -=elapsed 83.925649 +=elapsed 83.831855 =case zip_SUITE:zip64_central_directory -=logfile zip_suite.zip64_central_directory.19703522.html -=started 2024-09-11 11:53:21 -=ended 2024-09-11 11:53:43 +=logfile zip_suite.zip64_central_directory.19719778.html +=started 2024-09-12 11:16:02 +=ended 2024-09-12 11:16:24 =result ok -=elapsed 17.446084 +=elapsed 17.084737 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19703554.html +=logfile zip_suite.end_per_group.19719810.html =group_props [{name,z64_unezip}] -=started 2024-09-11 11:53:43 -=ended 2024-09-11 11:53:43 +=started 2024-09-12 11:16:24 +=ended 2024-09-12 11:16:24 =result ok -=elapsed 8.97e-4 -=group_time 105.933s +=elapsed 6.72e-4 +=group_time 105.735s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19703586.html +=logfile zip_suite.init_per_group.19719842.html =group_props [{name,z64_unemzip}] -=started 2024-09-11 11:53:43 -=ended 2024-09-11 11:53:43 +=started 2024-09-12 11:16:24 +=ended 2024-09-12 11:16:24 =result ok -=elapsed 4.08e-4 +=elapsed 1.29e-4 =case zip_SUITE:unzip64_central_headers -=logfile zip_suite.unzip64_central_headers.19703618.html -=started 2024-09-11 11:53:43 -=ended 2024-09-11 11:55:16 +=logfile zip_suite.unzip64_central_headers.19719874.html +=started 2024-09-12 11:16:24 +=ended 2024-09-12 11:17:57 =result ok -=elapsed 92.532646 +=elapsed 93.422623 =case zip_SUITE:zip64_central_directory -=logfile zip_suite.zip64_central_directory.505411.html -=started 2024-09-11 11:55:16 -=ended 2024-09-11 11:55:36 +=logfile zip_suite.zip64_central_directory.19720322.html +=started 2024-09-12 11:17:57 +=ended 2024-09-12 11:18:22 =result ok -=elapsed 16.243718 +=elapsed 17.701613 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19704194.html +=logfile zip_suite.end_per_group.19720418.html =group_props [{name,z64_unemzip}] -=started 2024-09-11 11:55:36 -=ended 2024-09-11 11:55:36 +=started 2024-09-12 11:18:22 +=ended 2024-09-12 11:18:22 =result ok -=elapsed 6.2e-4 -=group_time 113.432s +=elapsed 6.06e-4 +=group_time 118.108s =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19704226.html +=logfile zip_suite.end_per_group.19720450.html =group_props [{name,z64_ezip},sequence] -=started 2024-09-11 11:55:36 -=ended 2024-09-11 11:55:37 +=started 2024-09-12 11:18:22 +=ended 2024-09-12 11:18:23 =result ok -=elapsed 0.591089 -=group_time 445.186s +=elapsed 0.671807 +=group_time 460.056s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19704258.html +=logfile zip_suite.init_per_group.19720482.html =group_props [{name,z64_emzip},sequence] -=started 2024-09-11 11:55:37 -=ended 2024-09-11 11:55:37 +=started 2024-09-12 11:18:23 +=ended 2024-09-12 11:18:23 =result ok -=elapsed 6.96e-4 +=elapsed 0.001597 =case zip_SUITE:zip64_central_headers -=logfile zip_suite.zip64_central_headers.19704290.html -=started 2024-09-11 11:55:37 -=ended 2024-09-11 11:57:17 +=logfile zip_suite.zip64_central_headers.19720514.html +=started 2024-09-12 11:18:23 +=ended 2024-09-12 11:20:11 =result ok -=elapsed 99.746507 +=elapsed 108.14465 =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.505443.html +=logfile zip_suite.init_per_group.19720642.html =group_props [{name,z64_unzip}] -=started 2024-09-11 11:57:17 -=ended 2024-09-11 11:57:17 +=started 2024-09-12 11:20:11 +=ended 2024-09-12 11:20:11 =result ok -=elapsed 2.73e-4 +=elapsed 5.08e-4 =case zip_SUITE:unzip64_central_headers -=logfile zip_suite.unzip64_central_headers.505475.html -=started 2024-09-11 11:57:17 -=ended 2024-09-11 11:59:02 +=logfile zip_suite.unzip64_central_headers.19720674.html +=started 2024-09-12 11:20:11 +=ended 2024-09-12 11:21:58 =result ok -=elapsed 104.971438 +=elapsed 106.775213 =case zip_SUITE:zip64_central_directory -=logfile zip_suite.zip64_central_directory.505507.html -=started 2024-09-11 11:59:02 -=ended 2024-09-11 11:59:23 +=logfile zip_suite.zip64_central_directory.19720706.html +=started 2024-09-12 11:21:58 +=ended 2024-09-12 11:22:24 =result ok -=elapsed 14.678961 +=elapsed 19.860435 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19704514.html +=logfile zip_suite.end_per_group.19720834.html =group_props [{name,z64_unzip}] -=started 2024-09-11 11:59:23 -=ended 2024-09-11 11:59:24 +=started 2024-09-12 11:22:24 +=ended 2024-09-12 11:22:24 =result ok -=elapsed 4.54e-4 -=group_time 126.598s +=elapsed 4.14e-4 +=group_time 133.437s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19704546.html +=logfile zip_suite.init_per_group.19720866.html =group_props [{name,z64_unezip}] -=started 2024-09-11 11:59:24 -=ended 2024-09-11 11:59:24 +=started 2024-09-12 11:22:24 +=ended 2024-09-12 11:22:24 =result ok -=elapsed 1.71e-4 +=elapsed 1.27e-4 =case zip_SUITE:unzip64_central_headers -=logfile zip_suite.unzip64_central_headers.19704578.html -=started 2024-09-11 11:59:24 -=ended 2024-09-11 12:00:29 +=logfile zip_suite.unzip64_central_headers.19720898.html +=started 2024-09-12 11:22:24 +=ended 2024-09-12 11:23:39 =result ok -=elapsed 65.772394 +=elapsed 74.80714 =case zip_SUITE:zip64_central_directory -=logfile zip_suite.zip64_central_directory.19704610.html -=started 2024-09-11 12:00:29 -=ended 2024-09-11 12:00:51 +=logfile zip_suite.zip64_central_directory.19720930.html +=started 2024-09-12 11:23:39 +=ended 2024-09-12 11:24:03 =result ok -=elapsed 16.451745 +=elapsed 17.067854 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19704706.html +=logfile zip_suite.end_per_group.19721058.html =group_props [{name,z64_unezip}] -=started 2024-09-11 12:00:51 -=ended 2024-09-11 12:00:51 +=started 2024-09-12 11:24:03 +=ended 2024-09-12 11:24:03 =result ok -=elapsed 4.72e-4 -=group_time 87.555s +=elapsed 6.81e-4 +=group_time 98.863s =case zip_SUITE:init_per_group -=logfile zip_suite.init_per_group.19704738.html +=logfile zip_suite.init_per_group.19721090.html =group_props [{name,z64_unemzip}] -=started 2024-09-11 12:00:51 -=ended 2024-09-11 12:00:51 +=started 2024-09-12 11:24:03 +=ended 2024-09-12 11:24:03 =result ok -=elapsed 1.49e-4 +=elapsed 2.13e-4 =case zip_SUITE:unzip64_central_headers -=logfile zip_suite.unzip64_central_headers.19704770.html -=started 2024-09-11 12:00:51 -=ended 2024-09-11 12:02:23 +=logfile zip_suite.unzip64_central_headers.19721122.html +=started 2024-09-12 11:24:03 +=ended 2024-09-12 11:25:34 =result ok -=elapsed 91.782931 +=elapsed 90.63484 =case zip_SUITE:zip64_central_directory -=logfile zip_suite.zip64_central_directory.19705250.html -=started 2024-09-11 12:02:23 -=ended 2024-09-11 12:02:48 +=logfile zip_suite.zip64_central_directory.19721538.html +=started 2024-09-12 11:25:34 +=ended 2024-09-12 11:25:59 =result ok -=elapsed 17.764386 +=elapsed 19.712415 =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19705442.html +=logfile zip_suite.end_per_group.19721762.html =group_props [{name,z64_unemzip}] -=started 2024-09-11 12:02:48 -=ended 2024-09-11 12:02:48 +=started 2024-09-12 11:25:59 +=ended 2024-09-12 11:25:59 =result ok -=elapsed 7.42e-4 -=group_time 116.421s +=elapsed 4.34e-4 +=group_time 115.210s =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19705474.html +=logfile zip_suite.end_per_group.19721794.html =group_props [{name,z64_emzip},sequence] -=started 2024-09-11 12:02:48 -=ended 2024-09-11 12:02:48 +=started 2024-09-12 11:25:59 +=ended 2024-09-12 11:25:59 =result ok -=elapsed 0.513953 -=group_time 430.455s +=elapsed 0.650266 +=group_time 455.782s =case zip_SUITE:end_per_group -=logfile zip_suite.end_per_group.19705506.html +=logfile zip_suite.end_per_group.19721826.html =group_props [{name,zip64_group}] -=started 2024-09-11 12:02:48 -=ended 2024-09-11 12:02:48 +=started 2024-09-12 11:25:59 +=ended 2024-09-12 11:25:59 =result ok -=elapsed 0.201328 -=group_time 1257.626s +=elapsed 0.204321 +=group_time 1325.355s =case zip_SUITE:end_per_suite =logfile zip_suite.end_per_suite.html -=started 2024-09-11 12:02:48 -=ended 2024-09-11 12:02:48 +=started 2024-09-12 11:25:59 +=ended 2024-09-12 11:25:59 =result ok -=elapsed 0.012047 -=group_time 1279.453s +=elapsed 0.01573 +=group_time 1347.256s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.19705538.html +=logfile ct_framework.init_per_suite.19721858.html =group_props [{suite,zzz_SUITE}] -=started 2024-09-11 12:02:48 -=ended 2024-09-11 12:02:48 +=started 2024-09-12 11:25:59 +=ended 2024-09-12 11:26:00 =result ok -=elapsed 4.0e-6 +=elapsed 0.0 =case zzz_SUITE:lc_graph =logfile zzz_suite.lc_graph.html -=started 2024-09-11 12:02:48 -=ended 2024-09-11 12:02:48 +=started 2024-09-12 11:26:00 +=ended 2024-09-12 11:26:00 =result ok -=elapsed 5.81e-4 +=elapsed 6.62e-4 =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.19705570.html +=logfile ct_framework.end_per_suite.19721890.html =group_props [{suite,zzz_SUITE}] -=started 2024-09-11 12:02:48 -=ended 2024-09-11 12:02:48 +=started 2024-09-12 11:26:00 +=ended 2024-09-12 11:26:00 =result ok -=elapsed 2.29e-4 -=group_time 0.086s +=elapsed 0.0 +=group_time 0.123s === TEST COMPLETE, 2358 ok, 0 failed, 48 skipped of 2406 test cases -=finished 2024-09-11 12:02:48 +=finished 2024-09-12 11:26:00 =failed 0 =successful 2358 =user_skipped 48 =auto_skipped 0 -=elapsed_time 3113804063 +=elapsed_time 3178255973 diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/suite.log.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/suite.log.html similarity index 85% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/suite.log.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/suite.log.html index 39e7a32d5f8e0..dafa6abdbdf22 100644 --- a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/suite.log.html +++ b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/suite.log.html @@ -80,9 +80,9 @@

Results for make_test_dir.stdlib_test

-

Test started at 2024-09-11 11:10:55

+

Test started at 2024-09-12 10:33:01

Host info:
-Run by otptest on 43e13ac1be0c
Used Erlang v15.0.1 in "/buildroot/otp/Erlang ∅⊤℞"

+Run by otptest on 7a1fde2d1d55
Used Erlang v15.0.1 in "/buildroot/otp/Erlang ∅⊤℞"

  • Full textual log
  • Coverage log
  • @@ -96,40 +96,40 @@

    Test started at 2024-09-11 11:10:55

    common_testinit_per_suite< >0.000sOk common_testparserinit_per_group< >0.002sOkstart of parser -1argparse_SUITEparserreadme< >0.002sOk +1argparse_SUITEparserreadme< >0.002sOk 2argparse_SUITEparserbasic< >0.002sOk -3argparse_SUITEparserlong_form_eq< >0.008sOk -4argparse_SUITEparserbuilt_in_types< >0.001sOk -5argparse_SUITEparsertype_validators< >0.009sOk -6argparse_SUITEparserinvalid_arguments< >0.002sOk -7argparse_SUITEparsercomplex_command< >0.000sOk -8argparse_SUITEparserunicode< >0.005sOk -9argparse_SUITEparserparser_error< >0.001sOk -10argparse_SUITEparsernargs< >0.002sOk -11argparse_SUITEparserargparse< >0.008sOk -12argparse_SUITEparsernegative< >0.001sOk -13argparse_SUITEparsernodigits< >0.002sOk -14argparse_SUITEparserpos_mixed_with_opt< >0.000sOk -15argparse_SUITEparserdefault_for_not_required< >0.000sOk -16argparse_SUITEparserglobal_default< >0.000sOk -17argparse_SUITEparsersubcommand< >0.000sOk -18argparse_SUITEparservery_short< >0.000sOk -19argparse_SUITEparsermulti_short< >0.000sOk -20argparse_SUITEparserproxy_arguments< >0.000sOk +3argparse_SUITEparserlong_form_eq< >0.002sOk +4argparse_SUITEparserbuilt_in_types< >0.006sOk +5argparse_SUITEparsertype_validators< >0.005sOk +6argparse_SUITEparserinvalid_arguments< >0.001sOk +7argparse_SUITEparsercomplex_command< >0.002sOk +8argparse_SUITEparserunicode< >0.002sOk +9argparse_SUITEparserparser_error< >0.002sOk +10argparse_SUITEparsernargs< >0.001sOk +11argparse_SUITEparserargparse< >0.001sOk +12argparse_SUITEparsernegative< >0.002sOk +13argparse_SUITEparsernodigits< >0.000sOk +14argparse_SUITEparserpos_mixed_with_opt< >0.000sOk +15argparse_SUITEparserdefault_for_not_required< >0.000sOk +16argparse_SUITEparserglobal_default< >0.000sOk +17argparse_SUITEparsersubcommand< >0.000sOk +18argparse_SUITEparservery_short< >0.000sOk +19argparse_SUITEparsermulti_short< >0.000sOk +20argparse_SUITEparserproxy_arguments< >0.000sOk common_testparserend_per_group< >0.000sOkend of parser -common_testvalidatorinit_per_group< >0.000sOkstart of validator -21argparse_SUITEvalidatorvalidator_exception< >0.000sOk -22argparse_SUITEvalidatorvalidator_exception_format< >0.000sOk -common_testvalidatorend_per_group< >0.000sOkend of validator -common_testusageinit_per_group< >0.000sOkstart of usage -23argparse_SUITEusageusage< >0.001sOk -24argparse_SUITEusageusage_required_args< >0.000sOk -25argparse_SUITEusageusage_template< >0.000sOk -26argparse_SUITEusageusage_args_ordering< >0.000sOk -27argparse_SUITEusageparser_error_usage< >0.000sOk -28argparse_SUITEusagecommand_usage< >0.000sOk -29argparse_SUITEusageusage_width< >0.000sOk -common_testusageend_per_group< >0.000sOkend of usage +common_testvalidatorinit_per_group< >0.000sOkstart of validator +21argparse_SUITEvalidatorvalidator_exception< >0.000sOk +22argparse_SUITEvalidatorvalidator_exception_format< >0.000sOk +common_testvalidatorend_per_group< >0.000sOkend of validator +common_testusageinit_per_group< >0.000sOkstart of usage +23argparse_SUITEusageusage< >0.001sOk +24argparse_SUITEusageusage_required_args< >0.000sOk +25argparse_SUITEusageusage_template< >0.000sOk +26argparse_SUITEusageusage_args_ordering< >0.000sOk +27argparse_SUITEusageparser_error_usage< >0.000sOk +28argparse_SUITEusagecommand_usage< >0.000sOk +29argparse_SUITEusageusage_width< >0.000sOk +common_testusageend_per_group< >0.000sOkend of usage common_testend_per_suite< >0.000sOk array_SUITEinit_per_suite< >0.000sOk 30array_SUITEnew_test< >0.002sOk @@ -142,7 +142,7 @@

    Test started at 2024-09-11 11:10:55

    37array_SUITEfrom_list_test< >0.008sOk 38array_SUITEto_orddict_test< >0.000sOk 39array_SUITEsparse_to_orddict_test< >0.000sOk -40array_SUITEfrom_orddict_test< >0.017sOk +40array_SUITEfrom_orddict_test< >0.016sOk 41array_SUITEmap_test< >0.010sOk 42array_SUITEsparse_map_test< >0.009sOk 43array_SUITEfoldl_test< >0.000sOk @@ -150,7 +150,7 @@

    Test started at 2024-09-11 11:10:55

    45array_SUITEfoldr_test< >0.000sOk 46array_SUITEsparse_foldr_test< >0.000sOk array_SUITEend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk +common_testinit_per_suite< >0.000sOk 47base64_SUITEbase64_encode< >0.002sOk 48base64_SUITEbase64_encode_to_string< >0.000sOk 49base64_SUITEbase64_encode_modes< >0.000sOk @@ -165,157 +165,157 @@

    Test started at 2024-09-11 11:10:55

    58base64_SUITEmime_decode_modes< >0.000sOk 59base64_SUITEmime_decode_to_string< >0.000sOk 60base64_SUITEmime_decode_to_string_modes< >0.000sOk -common_testroundtripinit_per_group< >0.000sOkstart of roundtrip -61base64_SUITEroundtriproundtrip_1< >0.283sOk -62base64_SUITEroundtriproundtrip_2< >0.287sOk -63base64_SUITEroundtriproundtrip_3< >0.112sOk -64base64_SUITEroundtriproundtrip_4< >0.301sOk -common_testroundtripend_per_group< >0.000sOkend of roundtrip -common_testend_per_suite< >0.000sOk -base64_property_test_SUITEinit_per_suite< >1.241sOk +common_testroundtripinit_per_group< >0.000sOkstart of roundtrip +61base64_SUITEroundtriproundtrip_1< >0.295sOk +62base64_SUITEroundtriproundtrip_2< >0.299sOk +63base64_SUITEroundtriproundtrip_3< >0.106sOk +64base64_SUITEroundtriproundtrip_4< >0.255sOk +common_testroundtripend_per_group< >0.000sOkend of roundtrip +common_testend_per_suite< >0.000sOk +base64_property_test_SUITEinit_per_suite< >1.259sOk 65base64_property_test_SUITEencode_1_case< >0.009sOk 66base64_property_test_SUITEencode_2_case< >0.002sOk -67base64_property_test_SUITEencode_to_string_1_case< >0.002sOk +67base64_property_test_SUITEencode_to_string_1_case< >0.001sOk 68base64_property_test_SUITEencode_to_string_2_case< >0.002sOk 69base64_property_test_SUITEdecode_1_case< >0.004sOk 70base64_property_test_SUITEdecode_2_case< >0.009sOk -71base64_property_test_SUITEdecode_1_malformed_case< >0.012sOk -72base64_property_test_SUITEdecode_2_malformed_case< >0.012sOk -73base64_property_test_SUITEdecode_1_noisy_case< >0.016sOk -74base64_property_test_SUITEdecode_2_noisy_case< >0.016sOk -75base64_property_test_SUITEdecode_to_string_1_case< >0.004sOk -76base64_property_test_SUITEdecode_to_string_2_case< >0.009sOk -77base64_property_test_SUITEdecode_to_string_1_malformed_case< >0.011sOk -78base64_property_test_SUITEdecode_to_string_2_malformed_case< >0.012sOk -79base64_property_test_SUITEdecode_to_string_1_noisy_case< >0.016sOk +71base64_property_test_SUITEdecode_1_malformed_case< >0.011sOk +72base64_property_test_SUITEdecode_2_malformed_case< >0.013sOk +73base64_property_test_SUITEdecode_1_noisy_case< >0.018sOk +74base64_property_test_SUITEdecode_2_noisy_case< >0.019sOk +75base64_property_test_SUITEdecode_to_string_1_case< >0.005sOk +76base64_property_test_SUITEdecode_to_string_2_case< >0.010sOk +77base64_property_test_SUITEdecode_to_string_1_malformed_case< >0.015sOk +78base64_property_test_SUITEdecode_to_string_2_malformed_case< >0.013sOk +79base64_property_test_SUITEdecode_to_string_1_noisy_case< >0.019sOk 80base64_property_test_SUITEdecode_to_string_2_noisy_case< >0.016sOk 81base64_property_test_SUITEmime_decode_1_case< >0.007sOk 82base64_property_test_SUITEmime_decode_2_case< >0.009sOk 83base64_property_test_SUITEmime_decode_1_malformed_case< >0.028sOk -84base64_property_test_SUITEmime_decode_2_malformed_case< >0.027sOk -85base64_property_test_SUITEmime_decode_to_string_1_case< >0.007sOk +84base64_property_test_SUITEmime_decode_2_malformed_case< >0.028sOk +85base64_property_test_SUITEmime_decode_to_string_1_case< >0.006sOk 86base64_property_test_SUITEmime_decode_to_string_2_case< >0.009sOk -87base64_property_test_SUITEmime_decode_to_string_1_malformed_case< >0.028sOk -88base64_property_test_SUITEmime_decode_to_string_2_malformed_case< >0.028sOk +87base64_property_test_SUITEmime_decode_to_string_1_malformed_case< >0.029sOk +88base64_property_test_SUITEmime_decode_to_string_2_malformed_case< >0.026sOk base64_property_test_SUITEend_per_suite< >0.000sOk beam_lib_SUITEinit_per_suite< >0.000sOk -89beam_lib_SUITEerror< >0.018sOk -90beam_lib_SUITEnormal< >0.007sOk -91beam_lib_SUITEcmp< >0.009sOk -92beam_lib_SUITEcmp_literals< >0.005sOk -93beam_lib_SUITEstrip< >0.033sOk -94beam_lib_SUITEstrip_add_chunks< >0.037sOk -95beam_lib_SUITEotp_6711< >0.002sOk -96beam_lib_SUITEbuilding< >0.003sOk -97beam_lib_SUITEmd5< >0.360sOk -98beam_lib_SUITEencrypted_abstr< >0.194sOk -99beam_lib_SUITEencrypted_abstr_file< >0.009sOk +89beam_lib_SUITEerror< >0.017sOk +90beam_lib_SUITEnormal< >0.005sOk +91beam_lib_SUITEcmp< >0.008sOk +92beam_lib_SUITEcmp_literals< >0.004sOk +93beam_lib_SUITEstrip< >0.031sOk +94beam_lib_SUITEstrip_add_chunks< >0.042sOk +95beam_lib_SUITEotp_6711< >0.004sOk +96beam_lib_SUITEbuilding< >0.004sOk +97beam_lib_SUITEmd5< >0.424sOk +98beam_lib_SUITEencrypted_abstr< >0.199sOk +99beam_lib_SUITEencrypted_abstr_file< >0.010sOk 100beam_lib_SUITEmissing_debug_info_backend< >0.002sOk 101beam_lib_SUITEtest_makedep_abstract_code< >0.002sOk beam_lib_SUITEend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk +common_testinit_per_suite< >0.000sOk 102binary_module_SUITEscope_return< >0.011sOk -103binary_module_SUITEinteresting< >0.171sOk -104binary_module_SUITErandom_ref_fla_comp< >0.789sOk -105binary_module_SUITErandom_ref_sr_comp< >4.451sOk -106binary_module_SUITErandom_ref_comp< >7.309sOk -107binary_module_SUITEparts< >1.145sOk -108binary_module_SUITEbin_to_list< >1.284sOk +103binary_module_SUITEinteresting< >0.170sOk +104binary_module_SUITErandom_ref_fla_comp< >0.796sOk +105binary_module_SUITErandom_ref_sr_comp< >4.442sOk +106binary_module_SUITErandom_ref_comp< >7.360sOk +107binary_module_SUITEparts< >1.159sOk +108binary_module_SUITEbin_to_list< >1.291sOk 109binary_module_SUITElist_to_bin< >0.044sOk -110binary_module_SUITEcopy< >11.508sOk +110binary_module_SUITEcopy< >11.534sOk 111binary_module_SUITEreferenced< >0.000sOk 112binary_module_SUITEguard< >0.000sOkGuard tests are run in emulator test suite 113binary_module_SUITEencode_decode< >0.028sOk 114binary_module_SUITEbadargs< >0.000sOk 115binary_module_SUITElongest_common_trap< >0.000sOk 116binary_module_SUITEcheck_no_invalid_read_bug< >0.000sOk -117binary_module_SUITEerror_info< >0.009sOk +117binary_module_SUITEerror_info< >0.011sOk 118binary_module_SUITEhex_encoding< >0.004sOk -common_testend_per_suite< >0.000sOk -binary_property_test_SUITEinit_per_suite< >1.227sOk -common_testvalid_inputinit_per_group< >0.000sOkstart of valid_input -119binary_property_test_SUITEvalid_inputat_case< >0.002sOk +common_testend_per_suite< >0.000sOk +binary_property_test_SUITEinit_per_suite< >1.206sOk +common_testvalid_inputinit_per_group< >0.000sOkstart of valid_input +119binary_property_test_SUITEvalid_inputat_case< >0.003sOk 120binary_property_test_SUITEvalid_inputbin_to_list_1_case< >0.002sOk -121binary_property_test_SUITEvalid_inputbin_to_list_2_3_case< >0.002sOk -122binary_property_test_SUITEvalid_inputcompile_pattern_case< >0.006sOk -123binary_property_test_SUITEvalid_inputcopy_case< >0.002sOk -124binary_property_test_SUITEvalid_inputdecode_hex_case< >0.002sOk -125binary_property_test_SUITEvalid_inputdecode_unsigned_case< >0.001sOk +121binary_property_test_SUITEvalid_inputbin_to_list_2_3_case< >0.003sOk +122binary_property_test_SUITEvalid_inputcompile_pattern_case< >0.010sOk +123binary_property_test_SUITEvalid_inputcopy_case< >0.003sOk +124binary_property_test_SUITEvalid_inputdecode_hex_case< >0.003sOk +125binary_property_test_SUITEvalid_inputdecode_unsigned_case< >0.002sOk 126binary_property_test_SUITEvalid_inputencode_hex_case< >0.002sOk 127binary_property_test_SUITEvalid_inputencode_unsigned_case< >0.001sOk -128binary_property_test_SUITEvalid_inputfirst_case< >0.001sOk -129binary_property_test_SUITEvalid_inputlast_case< >0.001sOk -130binary_property_test_SUITEvalid_inputlist_to_bin_case< >0.001sOk -131binary_property_test_SUITEvalid_inputlongest_common_prefix_case< >0.007sOk -132binary_property_test_SUITEvalid_inputlongest_common_suffix_case< >0.007sOk -133binary_property_test_SUITEvalid_inputmatch_case< >0.008sOk -134binary_property_test_SUITEvalid_inputmatches_case< >0.010sOk +128binary_property_test_SUITEvalid_inputfirst_case< >0.002sOk +129binary_property_test_SUITEvalid_inputlast_case< >0.002sOk +130binary_property_test_SUITEvalid_inputlist_to_bin_case< >0.002sOk +131binary_property_test_SUITEvalid_inputlongest_common_prefix_case< >0.012sOk +132binary_property_test_SUITEvalid_inputlongest_common_suffix_case< >0.012sOk +133binary_property_test_SUITEvalid_inputmatch_case< >0.022sOk +134binary_property_test_SUITEvalid_inputmatches_case< >0.013sOk 135binary_property_test_SUITEvalid_inputpart_case< >0.002sOk -136binary_property_test_SUITEvalid_inputreplace_case< >0.015sOk -137binary_property_test_SUITEvalid_inputsplit_case< >0.011sOk -common_testvalid_inputend_per_group< >0.000sOkend of valid_input -common_testinvalid_inputinit_per_group< >0.000sOkstart of invalid_input -common_testout_of_binaryinit_per_group< >0.000sOkstart of out_of_binary +136binary_property_test_SUITEvalid_inputreplace_case< >0.019sOk +137binary_property_test_SUITEvalid_inputsplit_case< >0.012sOk +common_testvalid_inputend_per_group< >0.000sOkend of valid_input +common_testinvalid_inputinit_per_group< >0.000sOkstart of invalid_input +common_testout_of_binaryinit_per_group< >0.000sOkstart of out_of_binary 138binary_property_test_SUITEout_of_binaryat_invalid_index_case< >0.002sOk 139binary_property_test_SUITEout_of_binarybin_to_list_2_3_invalid_range_case< >0.002sOk -140binary_property_test_SUITEout_of_binarymatch_3_invalid_scope_case< >0.010sOk +140binary_property_test_SUITEout_of_binarymatch_3_invalid_scope_case< >0.011sOk 141binary_property_test_SUITEout_of_binarymatches_3_invalid_scope_case< >0.008sOk -142binary_property_test_SUITEout_of_binarypart_invalid_range_case< >0.002sOk -143binary_property_test_SUITEout_of_binaryreplace_4_invalid_scope_case< >0.007sOk -144binary_property_test_SUITEout_of_binaryreplace_4_invalid_insert_replaced_case< >0.009sOk -145binary_property_test_SUITEout_of_binarysplit_3_invalid_scope_case< >0.006sOk -common_testout_of_binaryend_per_group< >0.000sOkend of out_of_binary -common_testinvalid_subjectsinit_per_group< >0.000sOkstart of invalid_subjects -146binary_property_test_SUITEinvalid_subjectsat_invalid_subject_case< >0.007sOk -147binary_property_test_SUITEinvalid_subjectsbin_to_list_invalid_subject_case< >0.006sOk -148binary_property_test_SUITEinvalid_subjectscopy_invalid_subject_case< >0.006sOk -149binary_property_test_SUITEinvalid_subjectsdecode_hex_invalid_subject_case< >0.005sOk +142binary_property_test_SUITEout_of_binarypart_invalid_range_case< >0.003sOk +143binary_property_test_SUITEout_of_binaryreplace_4_invalid_scope_case< >0.013sOk +144binary_property_test_SUITEout_of_binaryreplace_4_invalid_insert_replaced_case< >0.012sOk +145binary_property_test_SUITEout_of_binarysplit_3_invalid_scope_case< >0.012sOk +common_testout_of_binaryend_per_group< >0.000sOkend of out_of_binary +common_testinvalid_subjectsinit_per_group< >0.000sOkstart of invalid_subjects +146binary_property_test_SUITEinvalid_subjectsat_invalid_subject_case< >0.006sOk +147binary_property_test_SUITEinvalid_subjectsbin_to_list_invalid_subject_case< >0.004sOk +148binary_property_test_SUITEinvalid_subjectscopy_invalid_subject_case< >0.004sOk +149binary_property_test_SUITEinvalid_subjectsdecode_hex_invalid_subject_case< >0.004sOk 150binary_property_test_SUITEinvalid_subjectsdecode_unsigned_invalid_subject_case< >0.004sOk 151binary_property_test_SUITEinvalid_subjectsencode_hex_invalid_subject_case< >0.004sOk -152binary_property_test_SUITEinvalid_subjectsfirst_invalid_subject_case< >0.003sOk -153binary_property_test_SUITEinvalid_subjectslast_invalid_subject_case< >0.002sOk -154binary_property_test_SUITEinvalid_subjectslongest_common_prefix_invalid_subject_case< >0.006sOk +152binary_property_test_SUITEinvalid_subjectsfirst_invalid_subject_case< >0.002sOk +153binary_property_test_SUITEinvalid_subjectslast_invalid_subject_case< >0.003sOk +154binary_property_test_SUITEinvalid_subjectslongest_common_prefix_invalid_subject_case< >0.007sOk 155binary_property_test_SUITEinvalid_subjectslongest_common_suffix_invalid_subject_case< >0.006sOk 156binary_property_test_SUITEinvalid_subjectsmatch_invalid_subject_case< >0.007sOk -157binary_property_test_SUITEinvalid_subjectsmatches_invalid_subject_case< >0.009sOk +157binary_property_test_SUITEinvalid_subjectsmatches_invalid_subject_case< >0.008sOk 158binary_property_test_SUITEinvalid_subjectspart_invalid_subject_case< >0.004sOk -159binary_property_test_SUITEinvalid_subjectsreplace_invalid_subject_case< >0.008sOk -160binary_property_test_SUITEinvalid_subjectssplit_invalid_subject_case< >0.008sOk -common_testinvalid_subjectsend_per_group< >0.000sOkend of invalid_subjects -common_testinvalid_patternsinit_per_group< >0.000sOkstart of invalid_patterns -161binary_property_test_SUITEinvalid_patternscompile_pattern_invalid_pattern_case< >0.026sOk -162binary_property_test_SUITEinvalid_patternsmatch_invalid_pattern_case< >0.027sOk -163binary_property_test_SUITEinvalid_patternsmatches_invalid_pattern_case< >0.032sOk +159binary_property_test_SUITEinvalid_subjectsreplace_invalid_subject_case< >0.009sOk +160binary_property_test_SUITEinvalid_subjectssplit_invalid_subject_case< >0.009sOk +common_testinvalid_subjectsend_per_group< >0.000sOkend of invalid_subjects +common_testinvalid_patternsinit_per_group< >0.000sOkstart of invalid_patterns +161binary_property_test_SUITEinvalid_patternscompile_pattern_invalid_pattern_case< >0.024sOk +162binary_property_test_SUITEinvalid_patternsmatch_invalid_pattern_case< >0.028sOk +163binary_property_test_SUITEinvalid_patternsmatches_invalid_pattern_case< >0.023sOk 164binary_property_test_SUITEinvalid_patternsreplace_invalid_pattern_case< >0.033sOk -165binary_property_test_SUITEinvalid_patternssplit_invalid_pattern_case< >0.027sOk -common_testinvalid_patternsend_per_group< >0.000sOkend of invalid_patterns -common_testmisc_invalidinit_per_group< >0.000sOkstart of misc_invalid -166binary_property_test_SUITEmisc_invalidcopy_2_invalid_n_case< >0.001sOk -167binary_property_test_SUITEmisc_invaliddecode_hex_invalid_chars_case< >0.001sOk -168binary_property_test_SUITEmisc_invaliddecode_unsigned_2_invalid_endianness_case< >0.005sOk -169binary_property_test_SUITEmisc_invalidencode_hex_2_invalid_case_case< >0.006sOk +165binary_property_test_SUITEinvalid_patternssplit_invalid_pattern_case< >0.029sOk +common_testinvalid_patternsend_per_group< >0.000sOkend of invalid_patterns +common_testmisc_invalidinit_per_group< >0.000sOkstart of misc_invalid +166binary_property_test_SUITEmisc_invalidcopy_2_invalid_n_case< >0.002sOk +167binary_property_test_SUITEmisc_invaliddecode_hex_invalid_chars_case< >0.002sOk +168binary_property_test_SUITEmisc_invaliddecode_unsigned_2_invalid_endianness_case< >0.006sOk +169binary_property_test_SUITEmisc_invalidencode_hex_2_invalid_case_case< >0.005sOk 170binary_property_test_SUITEmisc_invalidencode_unsigned_invalid_integer_case< >0.001sOk 171binary_property_test_SUITEmisc_invalidencode_unsigned_2_invalid_endianness_case< >0.005sOk 172binary_property_test_SUITEmisc_invalidlist_to_bin_invalid_bytes_case< >0.002sOk 173binary_property_test_SUITEmisc_invalidreplace_invalid_replacement_case< >0.011sOk -common_testmisc_invalidend_per_group< >0.000sOkend of misc_invalid -common_testinvalid_inputend_per_group< >0.000sOkend of invalid_input +common_testmisc_invalidend_per_group< >0.000sOkend of misc_invalid +common_testinvalid_inputend_per_group< >0.000sOkend of invalid_input binary_property_test_SUITEend_per_suite< >0.000sOk c_SUITEinit_per_suite< >0.000sOk 174c_SUITEc_1< >0.003sOk 175c_SUITEc_2< >0.002sOk 176c_SUITEc_3< >0.005sOk -177c_SUITEc_4< >0.004sOk -178c_SUITEnc_1< >0.001sOk +177c_SUITEc_4< >0.006sOk +178c_SUITEnc_1< >0.002sOk 179c_SUITEnc_2< >0.002sOk 180c_SUITEnc_3< >0.002sOk 181c_SUITEnc_4< >0.002sOk -182c_SUITEc_default_outdir_1< >0.004sOk +182c_SUITEc_default_outdir_1< >0.006sOk 183c_SUITEc_default_outdir_2< >0.006sOk 184c_SUITEnc_default_outdir_1< >0.002sOk 185c_SUITEnc_default_outdir_2< >0.002sOk -186c_SUITEls< >0.001sOk -187c_SUITEmemory< >0.001sOk +186c_SUITEls< >0.000sOk +187c_SUITEmemory< >0.002sOk c_SUITEend_per_suite< >0.000sOk calendar_SUITEinit_per_suite< >0.000sOk 188calendar_SUITEgregorian_days< >0.004sOk @@ -333,60 +333,60 @@

    Test started at 2024-09-11 11:10:55

    dets_SUITEinit_per_suite< >0.000sOk 199dets_SUITEbasic< >0.017sOk 200dets_SUITEopen< >0.610sOk -201dets_SUITEsets< >0.346sOk -202dets_SUITEbags< >0.439sOk -203dets_SUITEduplicate_bags< >0.539sOk -204dets_SUITEnewly_started< >0.156sOk -205dets_SUITEopen_file< >0.066sOk -206dets_SUITEinit_table< >1.603sOk -207dets_SUITErepair< >2.395sOk -208dets_SUITEaccess< >0.008sOk +201dets_SUITEsets< >0.351sOk +202dets_SUITEbags< >0.445sOk +203dets_SUITEduplicate_bags< >0.600sOk +204dets_SUITEnewly_started< >0.157sOk +205dets_SUITEopen_file< >0.072sOk +206dets_SUITEinit_table< >1.394sOk +207dets_SUITErepair< >1.607sOk +208dets_SUITEaccess< >0.004sOk 209dets_SUITEoldbugs< >0.002sOk -210dets_SUITEtruncated_segment_array< >0.004sOk -211dets_SUITEdirty_mark< >0.177sOk -212dets_SUITEdirty_mark2< >2.286sOk -213dets_SUITEbag_next< >0.004sOk +210dets_SUITEtruncated_segment_array< >0.003sOk +211dets_SUITEdirty_mark< >0.172sOk +212dets_SUITEdirty_mark2< >2.285sOk +213dets_SUITEbag_next< >0.005sOk 214dets_SUITEphash< >0.005sOk 215dets_SUITEfold< >0.005sOk 216dets_SUITEfixtable< >0.024sOk -217dets_SUITEmatch< >0.019sOk +217dets_SUITEmatch< >0.024sOk 218dets_SUITEselect< >0.011sOk 219dets_SUITEupdate_counter< >0.003sOk 220dets_SUITEbadarg< >0.003sOk -221dets_SUITEcache_sets< >4.229sOk -222dets_SUITEcache_bags< >5.041sOk -223dets_SUITEcache_duplicate_bags< >5.085sOk +221dets_SUITEcache_sets< >4.220sOk +222dets_SUITEcache_bags< >5.089sOk +223dets_SUITEcache_duplicate_bags< >5.092sOk 224dets_SUITEotp_4208< >0.001sOk -225dets_SUITEotp_4989< >0.223sOk -226dets_SUITEmany_clients< >0.068sOk -227dets_SUITEotp_4906< >5.428sOk +225dets_SUITEotp_4989< >0.220sOk +226dets_SUITEmany_clients< >0.069sOk +227dets_SUITEotp_4906< >5.412sOk 228dets_SUITEotp_5402< >5.001sOk -229dets_SUITEsimultaneous_open< >9.809sOk +229dets_SUITEsimultaneous_open< >9.879sOk 230dets_SUITEinsert_new< >0.001sOk -231dets_SUITErepair_continuation< >0.006sOk -232dets_SUITEotp_5487< >0.003sOk -233dets_SUITEotp_6206< >0.366sOk +231dets_SUITErepair_continuation< >0.005sOk +232dets_SUITEotp_5487< >0.004sOk +233dets_SUITEotp_6206< >0.400sOk 234dets_SUITEotp_6359< >0.000sOk -235dets_SUITEotp_4738< >0.008sOk -236dets_SUITEotp_7146< >0.032sOk +235dets_SUITEotp_4738< >0.012sOk +236dets_SUITEotp_7146< >0.120sOk 237dets_SUITEotp_8070< >0.000sOk 238dets_SUITEotp_8856< >0.001sOk 239dets_SUITEotp_8898< >0.008sOk -240dets_SUITEotp_8899< >0.009sOk +240dets_SUITEotp_8899< >0.008sOk 241dets_SUITEotp_8903< >0.001sOk -242dets_SUITEotp_8923< >0.004sOk -243dets_SUITEotp_9282< >0.001sOk -244dets_SUITEotp_11245< >0.020sOk +242dets_SUITEotp_8923< >0.005sOk +243dets_SUITEotp_9282< >0.002sOk +244dets_SUITEotp_11245< >0.059sOk 245dets_SUITEotp_11709< >0.030sOk 246dets_SUITEotp_13229< >0.000sOk -247dets_SUITEotp_13260< >0.204sOk +247dets_SUITEotp_13260< >0.305sOk 248dets_SUITEotp_13830< >0.001sOk 249dets_SUITEreceive_optimisation< >0.147sOk dets_SUITEend_per_suite< >0.000sOk dict_SUITEinit_per_suite< >0.000sOk 250dict_SUITEcreate< >0.000sOk -251dict_SUITEstore< >0.482sOk -252dict_SUITEremove< >0.577sOk +251dict_SUITEstore< >0.456sOk +252dict_SUITEremove< >0.553sOk 253dict_SUITEiterate< >0.107sOk dict_SUITEend_per_suite< >0.000sOk digraph_SUITEinit_per_suite< >0.000sOk @@ -400,12 +400,12 @@

    Test started at 2024-09-11 11:10:55

    260digraph_SUITEmiscdata< >0.000sOk 261digraph_SUITEmiscvertex_names< >0.000sOk digraph_SUITEmiscend_per_group< >0.000sOk -digraph_SUITEticketsinit_per_group< >0.000sOk +digraph_SUITEticketsinit_per_group< >0.000sOk 262digraph_SUITEticketsotp_3522< >0.000sOk 263digraph_SUITEticketsotp_3630< >0.000sOk 264digraph_SUITEticketsotp_8066< >0.000sOk -digraph_SUITEticketsend_per_group< >0.000sOk -265digraph_SUITEvertex_names< >0.000sOk +digraph_SUITEticketsend_per_group< >0.000sOk +265digraph_SUITEvertex_names< >0.000sOk digraph_SUITEend_per_suite< >0.000sOk digraph_utils_SUITEinit_per_suite< >0.000sOk 266digraph_utils_SUITEsimple< >0.000sOk @@ -417,25 +417,25 @@

    Test started at 2024-09-11 11:10:55

    272digraph_utils_SUITEtree< >0.000sOk digraph_utils_SUITEend_per_suite< >0.000sOk edlin_context_SUITEinit_per_suite< >0.000sOk -273edlin_context_SUITEget_context< >0.013sOk +273edlin_context_SUITEget_context< >0.012sOk edlin_context_SUITEend_per_suite< >0.000sOk edlin_expand_SUITEinit_per_suite< >0.000sOk -274edlin_expand_SUITEnormal< >0.035sOk -275edlin_expand_SUITEfilename_completion< >0.039sOk +274edlin_expand_SUITEnormal< >0.033sOk +275edlin_expand_SUITEfilename_completion< >0.036sOk 276edlin_expand_SUITEbinding_completion< >0.010sOk -277edlin_expand_SUITEget_coverage< >1.863sOk -278edlin_expand_SUITEtype_completion< >5.418sSKIPPEDExpansion too slow (5417815) on this machine -279edlin_expand_SUITErecord_completion< >0.061sOk -280edlin_expand_SUITEfun_completion< >0.045sOk +277edlin_expand_SUITEget_coverage< >1.808sOk +278edlin_expand_SUITEtype_completion< >5.407sSKIPPEDExpansion too slow (5407207) on this machine +279edlin_expand_SUITErecord_completion< >0.067sOk +280edlin_expand_SUITEfun_completion< >0.043sOk 281edlin_expand_SUITEmap_completion< >0.009sOk -282edlin_expand_SUITEfunction_parameter_completion< >0.115sOk +282edlin_expand_SUITEfunction_parameter_completion< >0.114sOk 283edlin_expand_SUITEno_completion< >0.006sOk -284edlin_expand_SUITEquoted_fun< >0.042sOk -285edlin_expand_SUITEquoted_module< >0.019sOk -286edlin_expand_SUITEquoted_both< >0.031sOk +284edlin_expand_SUITEquoted_fun< >0.046sOk +285edlin_expand_SUITEquoted_module< >0.020sOk +286edlin_expand_SUITEquoted_both< >0.032sOk 287edlin_expand_SUITEerl_1152< >0.000sOk 288edlin_expand_SUITEcheck_trailing< >0.000sOk -289edlin_expand_SUITEinvalid_module< >0.033sOk +289edlin_expand_SUITEinvalid_module< >0.031sOk 290edlin_expand_SUITEunicode< >0.011sOk edlin_expand_SUITEend_per_suite< >0.003sOk epp_SUITEinit_per_suite< >0.000sOk @@ -446,44 +446,44 @@

    Test started at 2024-09-11 11:10:55

    epp_SUITEupcase_macend_per_group< >0.000sOk 294epp_SUITEinclude_local< >0.001sOk 295epp_SUITEpredef_mac< >0.000sOk -epp_SUITEvariableinit_per_group< >0.000sOk +epp_SUITEvariableinit_per_group< >0.000sOk 296epp_SUITEvariablevariable_1< >0.001sOk -epp_SUITEvariableend_per_group< >0.000sOk +epp_SUITEvariableend_per_group< >0.000sOk 297epp_SUITEotp_4870< >0.001sOk 298epp_SUITEotp_4871< >0.004sOk -299epp_SUITEotp_5362< >0.009sOk +299epp_SUITEotp_5362< >0.010sOk 300epp_SUITEpmod< >0.000sOk -301epp_SUITEnot_circular< >0.158sOk +301epp_SUITEnot_circular< >0.157sOk 302epp_SUITEskip_header< >0.000sOk 303epp_SUITEotp_6277< >0.001sOk 304epp_SUITEgh_4995< >0.001sOk -305epp_SUITEotp_7702< >0.003sOk -306epp_SUITEotp_8130< >2.669sOk -307epp_SUITEoverload_mac< >0.480sOk -308epp_SUITEotp_8388< >0.006sOk +305epp_SUITEotp_7702< >0.002sOk +306epp_SUITEotp_8130< >2.632sOk +307epp_SUITEoverload_mac< >0.468sOk +308epp_SUITEotp_8388< >0.007sOk 309epp_SUITEotp_8470< >0.000sOk 310epp_SUITEotp_8562< >0.001sOk 311epp_SUITEotp_8665< >0.001sOk 312epp_SUITEotp_8911< >0.013sOk -313epp_SUITEotp_10302< >0.132sOk -314epp_SUITEotp_10820< >0.652sOk +313epp_SUITEotp_10302< >0.136sOk +314epp_SUITEotp_10820< >0.660sOk 315epp_SUITEotp_11728< >0.001sOk 316epp_SUITEencoding< >0.002sOk -317epp_SUITEextends< >0.154sOk -318epp_SUITEfunction_macro< >0.635sOk +317epp_SUITEextends< >0.157sOk +318epp_SUITEfunction_macro< >0.653sOk 319epp_SUITEtest_error< >0.003sOk -320epp_SUITEtest_warning< >0.006sOk +320epp_SUITEtest_warning< >0.007sOk 321epp_SUITEotp_14285< >0.001sOk -322epp_SUITEtest_if< >1.140sOk +322epp_SUITEtest_if< >1.171sOk 323epp_SUITEsource_name< >0.001sOk -324epp_SUITEotp_16978< >0.474sOk -325epp_SUITEotp_16824< >0.041sOk +324epp_SUITEotp_16978< >0.487sOk +325epp_SUITEotp_16824< >0.048sOk 326epp_SUITEscan_file< >0.001sOk 327epp_SUITEfile_macro< >0.001sOk 328epp_SUITEdeterministic_include< >0.001sOk 329epp_SUITEnondeterministic_include< >0.001sOk -330epp_SUITEgh_8268< >0.309sOk -331epp_SUITEmoduledoc_include< >0.002sOk +330epp_SUITEgh_8268< >0.318sOk +331epp_SUITEmoduledoc_include< >0.001sOk epp_SUITEend_per_suite< >0.000sOk erl_anno_SUITEinit_per_suite< >0.000sOk erl_anno_SUITEannoinit_per_group< >0.000sOk @@ -498,10 +498,10 @@

    Test started at 2024-09-11 11:10:55

    340erl_anno_SUITEannotext< >0.000sOk 341erl_anno_SUITEannobad< >0.000sOk erl_anno_SUITEannoend_per_group< >0.000sOk -erl_anno_SUITEparseinit_per_group< >0.000sOk +erl_anno_SUITEparseinit_per_group< >0.000sOk 342erl_anno_SUITEparseparse_abstract< >0.000sOk 343erl_anno_SUITEparsemapfold_anno< >0.000sOk -erl_anno_SUITEparseend_per_group< >0.000sOk +erl_anno_SUITEparseend_per_group< >0.000sOk erl_anno_SUITEend_per_suite< >0.000sOk erl_eval_SUITEinit_per_suite< >0.000sOk 344erl_eval_SUITEguard_1< >0.000sOk @@ -527,7 +527,7 @@

    Test started at 2024-09-11 11:10:55

    364erl_eval_SUITEotp_10622< >0.001sOk 365erl_eval_SUITEotp_13228< >0.000sOk 366erl_eval_SUITEotp_14826< >0.002sOk -367erl_eval_SUITEfuns< >0.072sOk +367erl_eval_SUITEfuns< >0.071sOk 368erl_eval_SUITEcustom_stacktrace< >0.000sOk 369erl_eval_SUITEtry_catch< >0.002sOk 370erl_eval_SUITEeval_expr_5< >0.000sOk @@ -545,126 +545,126 @@

    Test started at 2024-09-11 11:10:55

    erl_eval_SUITEend_per_suite< >0.000sOk erl_expand_records_SUITEinit_per_suite< >0.000sOk 382erl_expand_records_SUITEattributes< >0.003sOk -383erl_expand_records_SUITEexpr< >0.081sOk +383erl_expand_records_SUITEexpr< >0.087sOk 384erl_expand_records_SUITEguard< >0.002sOk -385erl_expand_records_SUITEinit< >0.019sOk +385erl_expand_records_SUITEinit< >0.026sOk 386erl_expand_records_SUITEpattern< >0.019sOk -387erl_expand_records_SUITEstrict< >0.012sOk +387erl_expand_records_SUITEstrict< >0.014sOk 388erl_expand_records_SUITEupdate< >0.009sOk -389erl_expand_records_SUITEmaps< >0.008sOk +389erl_expand_records_SUITEmaps< >0.009sOk 390erl_expand_records_SUITEside_effects< >0.000sOk erl_expand_records_SUITEticketsinit_per_group< >0.000sOk 391erl_expand_records_SUITEticketsotp_5915< >0.053sOk -392erl_expand_records_SUITEticketsotp_7931< >0.022sOk -393erl_expand_records_SUITEticketsotp_5990< >0.018sOk -394erl_expand_records_SUITEticketsotp_7078< >0.013sOk +392erl_expand_records_SUITEticketsotp_7931< >0.021sOk +393erl_expand_records_SUITEticketsotp_5990< >0.019sOk +394erl_expand_records_SUITEticketsotp_7078< >0.011sOk erl_expand_records_SUITEticketsend_per_group< >0.000sOk erl_expand_records_SUITEend_per_suite< >0.000sOk erl_internal_SUITEinit_per_suite< >0.000sOk 395erl_internal_SUITEbehav< >0.002sOk erl_internal_SUITEend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk -common_testunused_vars_warninit_per_group< >0.000sOkstart of unused_vars_warn -396erl_lint_SUITEunused_vars_warnunused_vars_warn_basic< >0.016sOk -397erl_lint_SUITEunused_vars_warnunused_vars_warn_lc< >0.130sOk -398erl_lint_SUITEunused_vars_warnunused_vars_warn_rec< >0.016sOk +common_testinit_per_suite< >0.000sOk +common_testunused_vars_warninit_per_group< >0.000sOkstart of unused_vars_warn +396erl_lint_SUITEunused_vars_warnunused_vars_warn_basic< >0.017sOk +397erl_lint_SUITEunused_vars_warnunused_vars_warn_lc< >0.131sOk +398erl_lint_SUITEunused_vars_warnunused_vars_warn_rec< >0.017sOk 399erl_lint_SUITEunused_vars_warnunused_vars_warn_fun< >0.013sOk 400erl_lint_SUITEunused_vars_warnunused_vars_OTP_4858< >0.002sOk -401erl_lint_SUITEunused_vars_warnunused_unsafe_vars_warn< >0.008sOk -common_testunused_vars_warnend_per_group< >0.000sOkend of unused_vars_warn -402erl_lint_SUITEexport_vars_warn< >0.007sOk -403erl_lint_SUITEshadow_vars< >0.003sOk +401erl_lint_SUITEunused_vars_warnunused_unsafe_vars_warn< >0.009sOk +common_testunused_vars_warnend_per_group< >0.000sOkend of unused_vars_warn +402erl_lint_SUITEexport_vars_warn< >0.009sOk +403erl_lint_SUITEshadow_vars< >0.004sOk 404erl_lint_SUITEunused_import< >0.003sOk 405erl_lint_SUITEunused_function< >0.008sOk 406erl_lint_SUITEunsafe_vars< >0.014sOk 407erl_lint_SUITEunsafe_vars2< >0.002sOk 408erl_lint_SUITEunsafe_vars_try< >0.012sOk -409erl_lint_SUITEguard< >0.031sOk +409erl_lint_SUITEguard< >0.032sOk 410erl_lint_SUITEunsized_binary_in_bin_gen_pattern< >0.003sOk 411erl_lint_SUITEotp_4886< >0.001sOk 412erl_lint_SUITEotp_4988< >0.002sOk -413erl_lint_SUITEotp_5091< >0.086sOk +413erl_lint_SUITEotp_5091< >0.085sOk 414erl_lint_SUITEotp_5276< >0.002sOk 415erl_lint_SUITEotp_5338< >0.001sOk 416erl_lint_SUITEotp_5362< >0.145sOk 417erl_lint_SUITEotp_5371< >0.017sOk -418erl_lint_SUITEotp_7227< >0.030sOk +418erl_lint_SUITEotp_7227< >0.031sOk 419erl_lint_SUITEbinary_aliases< >0.011sOk 420erl_lint_SUITEotp_5494< >0.002sOk 421erl_lint_SUITEotp_5644< >0.003sOk -422erl_lint_SUITEotp_5878< >0.063sOk +422erl_lint_SUITEotp_5878< >0.068sOk 423erl_lint_SUITEotp_5917< >0.002sOk -424erl_lint_SUITEotp_6585< >0.003sOk -425erl_lint_SUITEotp_6885< >0.002sOk -426erl_lint_SUITEotp_10436< >0.002sOk -427erl_lint_SUITEotp_11254< >0.001sOk -428erl_lint_SUITEotp_11772< >0.002sOk -429erl_lint_SUITEotp_11771< >0.002sOk -430erl_lint_SUITEotp_11872< >0.001sOk -431erl_lint_SUITEexport_all< >0.004sOk -432erl_lint_SUITEbif_clash< >0.050sOk -433erl_lint_SUITEbehaviour_basic< >0.009sOk -434erl_lint_SUITEbehaviour_multiple< >0.016sOk -435erl_lint_SUITEotp_11861< >0.047sOk +424erl_lint_SUITEotp_6585< >0.004sOk +425erl_lint_SUITEotp_6885< >0.003sOk +426erl_lint_SUITEotp_10436< >0.003sOk +427erl_lint_SUITEotp_11254< >0.002sOk +428erl_lint_SUITEotp_11772< >0.003sOk +429erl_lint_SUITEotp_11771< >0.004sOk +430erl_lint_SUITEotp_11872< >0.002sOk +431erl_lint_SUITEexport_all< >0.005sOk +432erl_lint_SUITEbif_clash< >0.061sOk +433erl_lint_SUITEbehaviour_basic< >0.010sOk +434erl_lint_SUITEbehaviour_multiple< >0.019sOk +435erl_lint_SUITEotp_11861< >0.049sOk 436erl_lint_SUITEotp_7550< >0.002sOk 437erl_lint_SUITEotp_8051< >0.001sOk -438erl_lint_SUITEformat_warn< >0.038sOk -common_teston_loadinit_per_group< >0.000sOkstart of on_load -439erl_lint_SUITEon_loadon_load_successful< >0.007sOk -440erl_lint_SUITEon_loadon_load_failing< >0.006sOk -common_teston_loadend_per_group< >0.000sOkend of on_load -441erl_lint_SUITEtoo_many_arguments< >0.002sOk -442erl_lint_SUITEbasic_errors< >0.011sOk -443erl_lint_SUITEbin_syntax_errors< >0.004sOk -444erl_lint_SUITEpredef< >0.009sOk -445erl_lint_SUITEmaps< >0.021sOk -446erl_lint_SUITEmaps_type< >0.006sOk -447erl_lint_SUITEmaps_parallel_match< >0.019sOk -448erl_lint_SUITEotp_11851< >0.008sOk +438erl_lint_SUITEformat_warn< >0.036sOk +common_teston_loadinit_per_group< >0.000sOkstart of on_load +439erl_lint_SUITEon_loadon_load_successful< >0.006sOk +440erl_lint_SUITEon_loadon_load_failing< >0.005sOk +common_teston_loadend_per_group< >0.000sOkend of on_load +441erl_lint_SUITEtoo_many_arguments< >0.001sOk +442erl_lint_SUITEbasic_errors< >0.007sOk +443erl_lint_SUITEbin_syntax_errors< >0.003sOk +444erl_lint_SUITEpredef< >0.008sOk +445erl_lint_SUITEmaps< >0.017sOk +446erl_lint_SUITEmaps_type< >0.005sOk +447erl_lint_SUITEmaps_parallel_match< >0.016sOk +448erl_lint_SUITEotp_11851< >0.006sOk 449erl_lint_SUITEotp_11879< >0.000sOk -450erl_lint_SUITEotp_13230< >0.002sOk -451erl_lint_SUITErecord_errors< >0.002sOk -452erl_lint_SUITEotp_11879_cont< >0.011sOk -453erl_lint_SUITEnon_latin1_module< >0.007sOk +450erl_lint_SUITEotp_13230< >0.001sOk +451erl_lint_SUITErecord_errors< >0.001sOk +452erl_lint_SUITEotp_11879_cont< >0.008sOk +453erl_lint_SUITEnon_latin1_module< >0.005sOk 454erl_lint_SUITEillegal_module_name< >0.006sOk -455erl_lint_SUITEotp_14323< >0.005sOk -456erl_lint_SUITEstacktrace_syntax< >0.005sOk -457erl_lint_SUITEotp_14285< >0.006sOk +455erl_lint_SUITEotp_14323< >0.003sOk +456erl_lint_SUITEstacktrace_syntax< >0.004sOk +457erl_lint_SUITEotp_14285< >0.004sOk 458erl_lint_SUITEotp_14378< >0.002sOk 459erl_lint_SUITEexternal_funs< >0.003sOk -460erl_lint_SUITEotp_15456< >0.006sOk -461erl_lint_SUITEotp_15563< >0.002sOk -462erl_lint_SUITEunused_type< >0.007sOk -463erl_lint_SUITEbinary_types< >0.005sOk +460erl_lint_SUITEotp_15456< >0.005sOk +461erl_lint_SUITEotp_15563< >0.001sOk +462erl_lint_SUITEunused_type< >0.005sOk +463erl_lint_SUITEbinary_types< >0.004sOk 464erl_lint_SUITEremoved< >0.002sOk -465erl_lint_SUITEotp_16516< >0.013sOk +465erl_lint_SUITEotp_16516< >0.009sOk 466erl_lint_SUITEundefined_nifs< >0.001sOk 467erl_lint_SUITEno_load_nif< >0.002sOk -468erl_lint_SUITEinline_nifs< >0.011sOk -469erl_lint_SUITEwarn_missing_spec< >0.018sOk +468erl_lint_SUITEinline_nifs< >0.012sOk +469erl_lint_SUITEwarn_missing_spec< >0.017sOk 470erl_lint_SUITEotp_16824< >0.004sOk 471erl_lint_SUITEunderscore_match< >0.028sOk 472erl_lint_SUITEunused_record< >0.004sOk 473erl_lint_SUITEunused_type2< >0.014sOk -474erl_lint_SUITEeep49< >0.006sOk -475erl_lint_SUITEredefined_builtin_type< >0.022sOk +474erl_lint_SUITEeep49< >0.007sOk +475erl_lint_SUITEredefined_builtin_type< >0.024sOk 476erl_lint_SUITEtilde_k< >0.008sOk -477erl_lint_SUITEsingleton_type_var_errors< >0.018sOk +477erl_lint_SUITEsingleton_type_var_errors< >0.016sOk 478erl_lint_SUITEdocumentation_attributes< >0.015sOk -479erl_lint_SUITEmatch_float_zero< >0.010sOk +479erl_lint_SUITEmatch_float_zero< >0.009sOk 480erl_lint_SUITEundefined_module< >0.001sOk -481erl_lint_SUITEupdate_literal< >0.008sOk -482erl_lint_SUITEmessages_with_jaro_suggestions< >0.010sOk -common_testend_per_suite< >0.000sOk +481erl_lint_SUITEupdate_literal< >0.007sOk +482erl_lint_SUITEmessages_with_jaro_suggestions< >0.008sOk +common_testend_per_suite< >0.000sOk erl_pp_SUITEinit_per_suite< >0.000sOk erl_pp_SUITEexprinit_per_group< >0.000sOk -483erl_pp_SUITEexprfunc< >0.026sOk -484erl_pp_SUITEexprcall< >0.003sOk +483erl_pp_SUITEexprfunc< >0.024sOk +484erl_pp_SUITEexprcall< >0.002sOk 485erl_pp_SUITEexprrecs< >0.062sOk 486erl_pp_SUITEexprtry_catch< >0.041sOk 487erl_pp_SUITEexprif_then< >0.007sOk 488erl_pp_SUITEexprreceive_after< >0.014sOk -489erl_pp_SUITEexprbits< >0.023sOk +489erl_pp_SUITEexprbits< >0.027sOk 490erl_pp_SUITEexprhead_tail< >0.012sOk 491erl_pp_SUITEexprcond1< >0.000sOk 492erl_pp_SUITEexprblock< >0.002sOk @@ -674,16 +674,16 @@

    Test started at 2024-09-11 11:10:55

    496erl_pp_SUITEexprmaps_syntax< >0.006sOk 497erl_pp_SUITEexprquoted_atom_types< >0.000sOk 498erl_pp_SUITEexprformat_options< >0.000sOk -499erl_pp_SUITEexprform_vars< >0.003sOk +499erl_pp_SUITEexprform_vars< >0.004sOk erl_pp_SUITEexprend_per_group< >0.000sOk -erl_pp_SUITEattributesinit_per_group< >0.000sOk +erl_pp_SUITEattributesinit_per_group< >0.000sOk 500erl_pp_SUITEattributesmisc_attrs< >0.000sOk -501erl_pp_SUITEattributesimport_export< >0.010sOk +501erl_pp_SUITEattributesimport_export< >0.011sOk 502erl_pp_SUITEattributesdialyzer_attrs< >0.000sOk -erl_pp_SUITEattributesend_per_group< >0.000sOk +erl_pp_SUITEattributesend_per_group< >0.000sOk 503erl_pp_SUITEhook< >0.001sOk 504erl_pp_SUITEneg_indent< >0.001sOk -erl_pp_SUITEticketsinit_per_group< >0.000sOk +erl_pp_SUITEticketsinit_per_group< >0.000sOk 505erl_pp_SUITEticketsotp_6321< >0.000sOk 506erl_pp_SUITEticketsotp_6911< >0.000sOk 507erl_pp_SUITEticketsotp_6914< >0.000sOk @@ -695,7 +695,7 @@

    Test started at 2024-09-11 11:10:55

    513erl_pp_SUITEticketsotp_8664< >0.002sOk 514erl_pp_SUITEticketsotp_9147< >0.001sOk 515erl_pp_SUITEticketsotp_10302< >0.004sOk -516erl_pp_SUITEticketsotp_10820< >0.741sOk +516erl_pp_SUITEticketsotp_10820< >0.736sOk 517erl_pp_SUITEticketsotp_11100< >0.000sOk 518erl_pp_SUITEticketsotp_11861< >0.000sOk 519erl_pp_SUITEticketspr_1014< >0.001sOk @@ -708,7 +708,7 @@

    Test started at 2024-09-11 11:10:55

    526erl_pp_SUITEticketsgh_5093< >0.000sOk 527erl_pp_SUITEticketseep49< >0.000sOk 528erl_pp_SUITEticketseep58< >0.000sOk -erl_pp_SUITEticketsend_per_group< >0.000sOk +erl_pp_SUITEticketsend_per_group< >0.000sOk erl_pp_SUITEend_per_suite< >0.000sOk erl_scan_SUITEinit_per_suite< >0.000sOk erl_scan_SUITEerrorinit_per_group< >0.000sOk @@ -727,28 +727,28 @@

    Test started at 2024-09-11 11:10:55

    540erl_scan_SUITEtriple_quoted_string< >0.000sOk erl_scan_SUITEend_per_suite< >0.000sOk error_logger_h_SUITEinit_per_suite< >0.000sOk -541error_logger_h_SUITElogfile< >1.934sOk -542error_logger_h_SUITElogfile_truncated< >0.393sOk +541error_logger_h_SUITElogfile< >1.933sOk +542error_logger_h_SUITElogfile_truncated< >0.394sOk 543error_logger_h_SUITEtty< >1.930sOk -544error_logger_h_SUITEtty_truncated< >0.393sOk +544error_logger_h_SUITEtty_truncated< >0.395sOk error_logger_h_SUITEend_per_suite< >0.000sOk escript_SUITEinit_per_suite< >0.000sOk -545escript_SUITEbasic< >2.911sOk -546escript_SUITEerrors< >0.682sOk -547escript_SUITEstrange_name< >0.256sOk -548escript_SUITEemulator_flags< >0.258sOk -549escript_SUITEemulator_flags_no_shebang< >0.257sOk -550escript_SUITEtwo_lines< >0.274sOk -551escript_SUITEmodule_script< >1.317sOk -552escript_SUITEbeam_script< >0.742sOk -553escript_SUITEarchive_script< >0.871sOk -554escript_SUITEepp< >0.259sOk -555escript_SUITEcreate_and_extract< >24.700sOk -556escript_SUITEfoldl< >0.020sOk -557escript_SUITEoverflow< >0.475sOk -558escript_SUITEarchive_script_file_access< >0.507sOk -559escript_SUITEunicode< >1.541sOk -560escript_SUITEbad_io_server< >0.245sOk +545escript_SUITEbasic< >2.913sOk +546escript_SUITEerrors< >0.667sOk +547escript_SUITEstrange_name< >0.260sOk +548escript_SUITEemulator_flags< >0.261sOk +549escript_SUITEemulator_flags_no_shebang< >0.272sOk +550escript_SUITEtwo_lines< >0.260sOk +551escript_SUITEmodule_script< >1.320sOk +552escript_SUITEbeam_script< >0.730sOk +553escript_SUITEarchive_script< >0.845sOk +554escript_SUITEepp< >0.255sOk +555escript_SUITEcreate_and_extract< >24.706sOk +556escript_SUITEfoldl< >0.021sOk +557escript_SUITEoverflow< >0.481sOk +558escript_SUITEarchive_script_file_access< >0.492sOk +559escript_SUITEunicode< >1.556sOk +560escript_SUITEbad_io_server< >0.244sOk escript_SUITEend_per_suite< >0.000sOk ets_SUITEinit_per_suite< >0.000sOk ets_SUITEnewinit_per_group< >0.000sOk @@ -756,225 +756,225 @@

    Test started at 2024-09-11 11:10:55

    562ets_SUITEnewsetbag< >0.002sOk 563ets_SUITEnewbadnew< >0.001sOk 564ets_SUITEnewverybadnew< >0.001sOk -565ets_SUITEnewnamed< >0.001sOk -566ets_SUITEnewkeypos2< >0.001sOk -567ets_SUITEnewprivacy< >0.027sOk +565ets_SUITEnewnamed< >0.002sOk +566ets_SUITEnewkeypos2< >0.002sOk +567ets_SUITEnewprivacy< >0.025sOk ets_SUITEnewend_per_group< >0.000sOk -ets_SUITEinsertinit_per_group< >0.000sOk +ets_SUITEinsertinit_per_group< >0.000sOk 568ets_SUITEinsertempty< >0.100sOk -569ets_SUITEinsertbadinsert< >0.111sOk -ets_SUITEinsertend_per_group< >0.000sOk -ets_SUITElookupinit_per_group< >0.000sOk +569ets_SUITEinsertbadinsert< >0.110sOk +ets_SUITEinsertend_per_group< >0.000sOk +ets_SUITElookupinit_per_group< >0.000sOk 570ets_SUITElookupbadlookup< >0.001sOk -571ets_SUITElookuplookup_order< >0.061sOk -ets_SUITElookupend_per_group< >0.000sOk -ets_SUITEdeleteinit_per_group< >0.000sOk -572ets_SUITEdeletedelete_elem< >0.026sOk -573ets_SUITEdeletedelete_tab< >0.024sOk -574ets_SUITEdeletedelete_large_tab< >4.396sOk -575ets_SUITEdeletedelete_large_named_table< >4.156sOk -576ets_SUITEdeleteevil_delete< >3.099sOk -577ets_SUITEdeletetable_leak< >39.995sOk +571ets_SUITElookuplookup_order< >0.058sOk +ets_SUITElookupend_per_group< >0.000sOk +ets_SUITEdeleteinit_per_group< >0.000sOk +572ets_SUITEdeletedelete_elem< >0.025sOk +573ets_SUITEdeletedelete_tab< >0.026sOk +574ets_SUITEdeletedelete_large_tab< >4.856sOk +575ets_SUITEdeletedelete_large_named_table< >4.308sOk +576ets_SUITEdeleteevil_delete< >3.122sOk +577ets_SUITEdeletetable_leak< >40.358sOk 578ets_SUITEdeletebaddelete< >0.002sOk -579ets_SUITEdeletematch_delete< >0.028sOk -580ets_SUITEdeletematch_delete3< >0.022sOk -ets_SUITEdeleteend_per_group< >0.000sOk -581ets_SUITEfirstnext< >0.058sOk +579ets_SUITEdeletematch_delete< >0.026sOk +580ets_SUITEdeletematch_delete3< >0.023sOk +ets_SUITEdeleteend_per_group< >0.000sOk +581ets_SUITEfirstnext< >0.059sOk 582ets_SUITEfirstnext_concurrent< >15.003sOk -583ets_SUITEfirstnext_lookup< >0.078sOk -584ets_SUITEfirstnext_lookup_concurrent< >15.002sOk -585ets_SUITEslot< >0.062sOk +583ets_SUITEfirstnext_lookup< >0.061sOk +584ets_SUITEfirstnext_lookup_concurrent< >15.003sOk +585ets_SUITEslot< >0.061sOk 586ets_SUITEhash_clash< >0.000sOk -ets_SUITEmatchinit_per_group< >0.000sOk -587ets_SUITEmatchmatch1< >0.062sOk +ets_SUITEmatchinit_per_group< >0.000sOk +587ets_SUITEmatchmatch1< >0.060sOk 588ets_SUITEmatchmatch2< >0.023sOk -589ets_SUITEmatchmatch_object< >0.075sOk -590ets_SUITEmatchmatch_object2< >0.715sOk -ets_SUITEmatchend_per_group< >0.000sOk +589ets_SUITEmatchmatch_object< >0.078sOk +590ets_SUITEmatchmatch_object2< >0.716sOk +ets_SUITEmatchend_per_group< >0.000sOk 591ets_SUITEt_match_spec_run< >0.935sOk -ets_SUITElookup_elementinit_per_group< >0.000sOk -592ets_SUITElookup_elementlookup_element_mult< >0.025sOk -593ets_SUITElookup_elementlookup_element_default< >0.002sOk -ets_SUITElookup_elementend_per_group< >0.000sOk -ets_SUITEmiscinit_per_group< >0.000sOk -594ets_SUITEmiscmisc1< >0.101sOk -595ets_SUITEmiscsafe_fixtable< >0.232sOk -596ets_SUITEmiscinfo< >0.463sOk -597ets_SUITEmiscinfo_binary_stress< >4.014sOk -598ets_SUITEmiscinfo_whereis_busy< >0.040sOk -599ets_SUITEmiscdups< >0.033sOk -600ets_SUITEmisctab2list< >0.005sOk -ets_SUITEmiscend_per_group< >0.000sOk -ets_SUITEfilesinit_per_group< >0.000sOk +ets_SUITElookup_elementinit_per_group< >0.000sOk +592ets_SUITElookup_elementlookup_element_mult< >0.026sOk +593ets_SUITElookup_elementlookup_element_default< >0.001sOk +ets_SUITElookup_elementend_per_group< >0.000sOk +ets_SUITEmiscinit_per_group< >0.000sOk +594ets_SUITEmiscmisc1< >0.099sOk +595ets_SUITEmiscsafe_fixtable< >0.231sOk +596ets_SUITEmiscinfo< >0.448sOk +597ets_SUITEmiscinfo_binary_stress< >4.013sOk +598ets_SUITEmiscinfo_whereis_busy< >0.041sOk +599ets_SUITEmiscdups< >0.032sOk +600ets_SUITEmisctab2list< >0.004sOk +ets_SUITEmiscend_per_group< >0.000sOk +ets_SUITEfilesinit_per_group< >0.000sOk 601ets_SUITEfilestab2file< >0.023sOk -602ets_SUITEfilestab2file2< >0.196sOk -603ets_SUITEfilestabfile_ext1< >0.099sOk -604ets_SUITEfilestabfile_ext2< >0.093sOk -605ets_SUITEfilestabfile_ext3< >0.006sOk -606ets_SUITEfilestabfile_ext4< >7.092sOk +602ets_SUITEfilestab2file2< >0.200sOk +603ets_SUITEfilestabfile_ext1< >0.091sOk +604ets_SUITEfilestabfile_ext2< >0.099sOk +605ets_SUITEfilestabfile_ext3< >0.007sOk +606ets_SUITEfilestabfile_ext4< >6.853sOk 607ets_SUITEfilesbadfile< >0.001sOk -ets_SUITEfilesend_per_group< >0.000sOk -ets_SUITEheavyinit_per_group< >0.000sOk -608ets_SUITEheavyheavy_lookup< >2.912sOk -609ets_SUITEheavyheavy_lookup_element< >14.532sOk -610ets_SUITEheavyheavy_concurrent< >30.049sOk -ets_SUITEheavyend_per_group< >0.000sOk -ets_SUITEinsert_listinit_per_group< >0.000sOk -611ets_SUITEinsert_listt_insert_list< >0.131sOk +ets_SUITEfilesend_per_group< >0.000sOk +ets_SUITEheavyinit_per_group< >0.000sOk +608ets_SUITEheavyheavy_lookup< >2.940sOk +609ets_SUITEheavyheavy_lookup_element< >14.578sOk +610ets_SUITEheavyheavy_concurrent< >30.138sOk +ets_SUITEheavyend_per_group< >0.000sOk +ets_SUITEinsert_listinit_per_group< >0.000sOk +611ets_SUITEinsert_listt_insert_list< >0.152sOk 612ets_SUITEinsert_listt_insert_list_set< >0.002sOk -613ets_SUITEinsert_listt_insert_list_bag< >0.207sOk +613ets_SUITEinsert_listt_insert_list_bag< >0.212sOk 614ets_SUITEinsert_listt_insert_list_duplicate_bag< >0.012sOk -615ets_SUITEinsert_listt_insert_list_delete_set< >19.861sOk -616ets_SUITEinsert_listt_insert_list_parallel< >1.443sOk -617ets_SUITEinsert_listt_insert_list_delete_parallel< >0.781sOk -618ets_SUITEinsert_listt_insert_list_kill_process< >3.311sOk -619ets_SUITEinsert_listt_insert_list_insert_order_preserved< >4.451sOk -620ets_SUITEinsert_listinsert_trap_delete< >12.175sOk -621ets_SUITEinsert_listinsert_trap_rename< >6.326sOk -ets_SUITEinsert_listend_per_group< >0.000sOk -622ets_SUITEordered< >0.020sOk -623ets_SUITEordered_match< >0.045sOk -624ets_SUITEinterface_equality< >0.038sOk -625ets_SUITEfixtable_next< >0.030sOk +615ets_SUITEinsert_listt_insert_list_delete_set< >19.859sOk +616ets_SUITEinsert_listt_insert_list_parallel< >1.544sOk +617ets_SUITEinsert_listt_insert_list_delete_parallel< >0.775sOk +618ets_SUITEinsert_listt_insert_list_kill_process< >3.331sOk +619ets_SUITEinsert_listt_insert_list_insert_order_preserved< >4.029sOk +620ets_SUITEinsert_listinsert_trap_delete< >12.663sOk +621ets_SUITEinsert_listinsert_trap_rename< >6.743sOk +ets_SUITEinsert_listend_per_group< >0.000sOk +622ets_SUITEordered< >0.017sOk +623ets_SUITEordered_match< >0.044sOk +624ets_SUITEinterface_equality< >0.036sOk +625ets_SUITEfixtable_next< >0.027sOk 626ets_SUITEfixtable_iter_bag< >0.016sOk 627ets_SUITEfixtable_insert< >0.000sOk -628ets_SUITErename< >0.023sOk +628ets_SUITErename< >0.026sOk 629ets_SUITErename_unnamed< >0.024sOk -630ets_SUITEevil_rename< >0.288sOk -631ets_SUITEupdate_element< >7.088sOk -632ets_SUITEupdate_element_default< >0.005sOk -633ets_SUITEupdate_counter< >0.882sOk -634ets_SUITEevil_update_counter< >2.493sOk -635ets_SUITEupdate_counter_with_default< >0.002sOk +630ets_SUITEevil_rename< >0.311sOk +631ets_SUITEupdate_element< >7.158sOk +632ets_SUITEupdate_element_default< >0.004sOk +633ets_SUITEupdate_counter< >0.873sOk +634ets_SUITEevil_update_counter< >2.511sOk +635ets_SUITEupdate_counter_with_default< >0.003sOk 636ets_SUITEupdate_counter_with_default_bad_pos< >0.000sOk -637ets_SUITEpartly_bound< >0.717sOk -638ets_SUITEupdate_counter_table_growth< >0.088sOk -639ets_SUITEmatch_heavy< >1.772sOk -ets_SUITEfoldinit_per_group< >0.000sOk -640ets_SUITEfoldfoldl_ordered< >0.039sOk -641ets_SUITEfoldfoldr_ordered< >0.079sOk -642ets_SUITEfoldfoldl< >0.143sOk -643ets_SUITEfoldfoldr< >0.118sOk +637ets_SUITEpartly_bound< >0.731sOk +638ets_SUITEupdate_counter_table_growth< >0.091sOk +639ets_SUITEmatch_heavy< >1.733sOk +ets_SUITEfoldinit_per_group< >0.000sOk +640ets_SUITEfoldfoldl_ordered< >0.035sOk +641ets_SUITEfoldfoldr_ordered< >0.034sOk +642ets_SUITEfoldfoldl< >0.103sOk +643ets_SUITEfoldfoldr< >0.105sOk 644ets_SUITEfoldfold_empty< >0.057sOk 645ets_SUITEfoldfold_badarg< >0.000sOk -ets_SUITEfoldend_per_group< >0.000sOk -646ets_SUITEmember< >0.080sOk -647ets_SUITEt_delete_object< >1.258sOk +ets_SUITEfoldend_per_group< >0.000sOk +646ets_SUITEmember< >0.082sOk +647ets_SUITEt_delete_object< >1.274sOk 648ets_SUITEselect_bound_chunk< >0.000sOk -649ets_SUITEt_init_table< >0.133sOk -650ets_SUITEt_whitebox< >0.011sOk -651ets_SUITEt_delete_all_objects< >3.039sOk -652ets_SUITEt_delete_all_objects_trap< >2.506sOk +649ets_SUITEt_init_table< >0.131sOk +650ets_SUITEt_whitebox< >0.010sOk +651ets_SUITEt_delete_all_objects< >3.142sOk +652ets_SUITEt_delete_all_objects_trap< >2.540sOk 653ets_SUITEt_test_ms< >0.001sOk -654ets_SUITEt_select_delete< >5.741sOk -655ets_SUITEt_select_replace< >1.746sOk +654ets_SUITEt_select_delete< >5.676sOk +655ets_SUITEt_select_replace< >1.799sOk 656ets_SUITEt_select_replace_next_bug< >0.000sOk 657ets_SUITEt_select_pam_stack_overflow_bug< >0.000sOk 658ets_SUITEt_select_flatmap_term_copy_bug< >0.000sOk 659ets_SUITEt_select_hashmap_term_copy_bug< >0.030sOk 660ets_SUITEt_ets_dets< >0.147sOk -661ets_SUITEmemory< >0.007sOk +661ets_SUITEmemory< >0.005sOk 662ets_SUITEt_select_reverse< >0.002sOk -663ets_SUITEt_bucket_disappears< >0.028sOk -664ets_SUITEt_named_select< >0.023sOk +663ets_SUITEt_bucket_disappears< >0.033sOk +664ets_SUITEt_named_select< >0.026sOk 665ets_SUITEselect_fixtab_owner_change< >0.001sOk 666ets_SUITEselect_fail< >0.003sOk -667ets_SUITEt_insert_new< >0.007sOk +667ets_SUITEt_insert_new< >0.008sOk 668ets_SUITEt_repair_continuation< >0.072sOk -669ets_SUITEotp_5340< >0.108sOk -670ets_SUITEotp_6338< >0.003sOk -671ets_SUITEotp_6842_select_1000< >0.489sOk -672ets_SUITEotp_7665< >0.004sOk +669ets_SUITEotp_5340< >0.113sOk +670ets_SUITEotp_6338< >0.002sOk +671ets_SUITEotp_6842_select_1000< >0.491sOk +672ets_SUITEotp_7665< >0.003sOk 673ets_SUITEselect_mbuf_trapping< >0.001sOk 674ets_SUITEotp_8732< >0.002sOk -675ets_SUITEmeta_wb< >0.494sOk -676ets_SUITEgrow_shrink< >0.253sOk -677ets_SUITEgrow_pseudo_deleted< >0.134sOk -678ets_SUITEshrink_pseudo_deleted< >0.038sOk -ets_SUITEmeta_smpinit_per_group< >0.000sOk +675ets_SUITEmeta_wb< >0.491sOk +676ets_SUITEgrow_shrink< >0.258sOk +677ets_SUITEgrow_pseudo_deleted< >0.140sOk +678ets_SUITEshrink_pseudo_deleted< >0.039sOk +ets_SUITEmeta_smpinit_per_group< >0.000sOk 679ets_SUITEmeta_smpmeta_lookup_unnamed_read< >0.002sOk 680ets_SUITEmeta_smpmeta_lookup_unnamed_write< >0.002sOk 681ets_SUITEmeta_smpmeta_lookup_named_read< >0.003sOk 682ets_SUITEmeta_smpmeta_lookup_named_write< >0.003sOk -683ets_SUITEmeta_smpmeta_newdel_unnamed< >0.017sOk -684ets_SUITEmeta_smpmeta_newdel_named< >0.021sOk -ets_SUITEmeta_smpend_per_group< >0.000sOk -685ets_SUITEsmp_insert< >0.160sOk -686ets_SUITEsmp_fixed_delete< >0.068sOk -687ets_SUITEsmp_unfix_fix< >0.070sOk -688ets_SUITEsmp_select_replace< >24.020sOk -689ets_SUITEsmp_ordered_iteration< >2.021sOk -690ets_SUITEsmp_select_delete< >1.311sOk -691ets_SUITEotp_8166< >0.271sOk -692ets_SUITEexit_large_table_owner< >10.576sOk -693ets_SUITEexit_many_large_table_owner< >20.222sOk -694ets_SUITEexit_many_tables_owner< >0.013sOk -695ets_SUITEexit_many_many_tables_owner< >1.078sOk -696ets_SUITEwrite_concurrency< >0.003sOk -697ets_SUITEheir< >0.195sOk -698ets_SUITEgive_away< >0.003sOk -699ets_SUITEsetopts< >0.001sOk -700ets_SUITEbad_table< >0.189sOk -701ets_SUITEtypes< >0.034sOk -702ets_SUITEotp_10182< >0.008sOk +683ets_SUITEmeta_smpmeta_newdel_unnamed< >0.018sOk +684ets_SUITEmeta_smpmeta_newdel_named< >0.022sOk +ets_SUITEmeta_smpend_per_group< >0.000sOk +685ets_SUITEsmp_insert< >0.164sOk +686ets_SUITEsmp_fixed_delete< >0.079sOk +687ets_SUITEsmp_unfix_fix< >0.075sOk +688ets_SUITEsmp_select_replace< >24.017sOk +689ets_SUITEsmp_ordered_iteration< >2.022sOk +690ets_SUITEsmp_select_delete< >1.313sOk +691ets_SUITEotp_8166< >0.238sOk +692ets_SUITEexit_large_table_owner< >12.235sOk +693ets_SUITEexit_many_large_table_owner< >19.978sOk +694ets_SUITEexit_many_tables_owner< >0.012sOk +695ets_SUITEexit_many_many_tables_owner< >1.109sOk +696ets_SUITEwrite_concurrency< >0.002sOk +697ets_SUITEheir< >0.205sOk +698ets_SUITEgive_away< >0.005sOk +699ets_SUITEsetopts< >0.002sOk +700ets_SUITEbad_table< >0.180sOk +701ets_SUITEtypes< >0.033sOk +702ets_SUITEotp_10182< >0.010sOk 703ets_SUITEotp_9932< >0.000sOk -704ets_SUITEotp_9423< >0.171sOk +704ets_SUITEotp_9423< >0.176sOk 705ets_SUITEcompress_magic_ref< >0.000sOk -706ets_SUITEets_all< >3.001sOk +706ets_SUITEets_all< >3.000sOk 707ets_SUITEmassive_ets_all< >0.007sOk 708ets_SUITEtake< >0.000sOk 709ets_SUITEwhereis_table< >0.000sOk -710ets_SUITEdelete_unfix_race< >0.043sOk -711ets_SUITEtest_throughput_benchmark< >30.999sOkResult visualization +710ets_SUITEdelete_unfix_race< >0.029sOk +711ets_SUITEtest_throughput_benchmark< >31.031sOkResult visualization ets_SUITEbenchmarkinit_per_group< >0.000sSKIPPEDBenchmark only 712ets_SUITEbenchmarklong_throughput_benchmark< >0.000sSKIPPEDBenchmark only ets_SUITEbenchmarkend_per_group< >0.000sSKIPPEDBenchmark only -713ets_SUITEtest_table_size_concurrency< >1.193sOk -714ets_SUITEtest_table_memory_concurrency< >1.264sOk -715ets_SUITEtest_delete_table_while_size_snapshot< >0.508sOk +713ets_SUITEtest_table_size_concurrency< >1.324sOk +714ets_SUITEtest_table_memory_concurrency< >1.320sOk +715ets_SUITEtest_delete_table_while_size_snapshot< >0.496sOk 716ets_SUITEtest_decentralized_counters_setting< >0.002sOk -717ets_SUITEms_excessive_nesting< >0.174sOkmatch_spec_compile() got system_limit; select_replace(_,[ordered_set]) got system_limit; select_replace(_,[set]) got system_limit -718ets_SUITEerror_info< >0.116sOk +717ets_SUITEms_excessive_nesting< >0.169sOkmatch_spec_compile() got system_limit; select_replace(_,[ordered_set]) got system_limit; select_replace(_,[set]) got system_limit +718ets_SUITEerror_info< >0.097sOk 719ets_SUITEbound_maps< >0.000sOk ets_SUITEend_per_suite< >0.000sOk -ets_property_test_SUITEinit_per_suite< >1.281sOk -720ets_property_test_SUITEfirst_case< >0.135sOk -721ets_property_test_SUITEnext_case< >0.136sOk -722ets_property_test_SUITElast_case< >0.117sOk -723ets_property_test_SUITEprev_case< >0.114sOk +ets_property_test_SUITEinit_per_suite< >1.275sOk +720ets_property_test_SUITEfirst_case< >0.116sOk +721ets_property_test_SUITEnext_case< >0.100sOk +722ets_property_test_SUITElast_case< >0.131sOk +723ets_property_test_SUITEprev_case< >0.122sOk ets_property_test_SUITEend_per_suite< >0.000sOk ets_tough_SUITEinit_per_suite< >0.000sOk -724ets_tough_SUITEex1< >0.832sOk +724ets_tough_SUITEex1< >0.851sOk ets_tough_SUITEend_per_suite< >0.000sOk file_sorter_SUITEinit_per_suite< >0.000sOk 725file_sorter_SUITEbasic< >0.006sOk 726file_sorter_SUITEbadarg< >0.004sOk -727file_sorter_SUITEterm_sort< >0.052sOk -728file_sorter_SUITEterm_keysort< >0.026sOk -729file_sorter_SUITEbinary_term_sort< >0.056sOk -730file_sorter_SUITEbinary_term_keysort< >0.024sOk -731file_sorter_SUITEbinary_sort< >0.053sOk -732file_sorter_SUITEterm_merge< >0.016sOk -733file_sorter_SUITEterm_keymerge< >0.059sOk -734file_sorter_SUITEbinary_term_merge< >0.011sOk -735file_sorter_SUITEbinary_term_keymerge< >0.053sOk -736file_sorter_SUITEbinary_merge< >0.010sOk -737file_sorter_SUITEterm_check< >0.039sOk +727file_sorter_SUITEterm_sort< >0.064sOk +728file_sorter_SUITEterm_keysort< >0.030sOk +729file_sorter_SUITEbinary_term_sort< >0.055sOk +730file_sorter_SUITEbinary_term_keysort< >0.025sOk +731file_sorter_SUITEbinary_sort< >0.056sOk +732file_sorter_SUITEterm_merge< >0.020sOk +733file_sorter_SUITEterm_keymerge< >0.073sOk +734file_sorter_SUITEbinary_term_merge< >0.013sOk +735file_sorter_SUITEbinary_term_keymerge< >0.059sOk +736file_sorter_SUITEbinary_merge< >0.013sOk +737file_sorter_SUITEterm_check< >0.042sOk 738file_sorter_SUITEbinary_term_keycheck< >0.003sOk 739file_sorter_SUITEbinary_term_check< >0.008sOk -740file_sorter_SUITEbinary_term_keycheck< >0.003sOk +740file_sorter_SUITEbinary_term_keycheck< >0.003sOk 741file_sorter_SUITEbinary_check< >0.007sOk 742file_sorter_SUITEinout< >0.002sOk 743file_sorter_SUITEmisc< >0.016sOk -744file_sorter_SUITEmany< >0.761sOk +744file_sorter_SUITEmany< >0.840sOk file_sorter_SUITEend_per_suite< >0.000sOk filelib_SUITEinit_per_suite< >0.000sOk -745filelib_SUITEwildcard_one< >0.080sOk -746filelib_SUITEwildcard_two< >0.095sOk +745filelib_SUITEwildcard_one< >0.082sOk +746filelib_SUITEwildcard_two< >0.093sOk 747filelib_SUITEwildcard_errors< >0.000sOk -748filelib_SUITEfold_files< >0.003sOk -749filelib_SUITEotp_5960< >0.000sOk -750filelib_SUITEensure_dir_eexist< >0.000sOk +748filelib_SUITEfold_files< >0.005sOk +749filelib_SUITEotp_5960< >0.001sOk +750filelib_SUITEensure_dir_eexist< >0.001sOk 751filelib_SUITEensure_dir_symlink< >0.000sOk 752filelib_SUITEensure_path_single_dir< >0.000sOk 753filelib_SUITEensure_path_nested_dirs< >0.000sOk @@ -982,13 +982,13 @@

    Test started at 2024-09-11 11:10:55

    755filelib_SUITEensure_path_symlink< >0.000sOk 756filelib_SUITEensure_path_relative_path< >0.000sOk 757filelib_SUITEensure_path_relative_path_dot_dot< >0.000sOk -758filelib_SUITEensure_path_invalid_path< >0.000sOk +758filelib_SUITEensure_path_invalid_path< >0.001sOk 759filelib_SUITEwildcard_symlink< >0.001sOk 760filelib_SUITEis_file_symlink< >0.001sOk -761filelib_SUITEfile_props_symlink< >0.000sOk -762filelib_SUITEfind_source< >0.001sOk -763filelib_SUITEfind_source_subdir< >0.001sOk -764filelib_SUITEfind_source_otp< >0.408sOk +761filelib_SUITEfile_props_symlink< >0.001sOk +762filelib_SUITEfind_source< >0.002sOk +763filelib_SUITEfind_source_subdir< >0.002sOk +764filelib_SUITEfind_source_otp< >0.392sOk 765filelib_SUITEsafe_relative_path< >0.007sOk 766filelib_SUITEsafe_relative_path_links< >0.011sOk filelib_SUITEend_per_suite< >0.000sOk @@ -998,25 +998,25 @@

    Test started at 2024-09-11 11:10:55

    769filename_SUITEabsname_bin< >0.000sOk 770filename_SUITEabsname_bin_2< >0.000sOk filename_SUITEpinit_per_group< >0.000sOk -771filename_SUITEpdirname< >0.000sOk -772filename_SUITEpextension< >0.000sOk -773filename_SUITEpextension_bin< >0.000sOk -774filename_SUITEpjoin< >0.000sOk -775filename_SUITEppathtype< >0.000sOk -776filename_SUITEprootname< >0.000sOk -777filename_SUITEpsplit< >0.000sOk -778filename_SUITEpt_nativename< >0.000sOk -779filename_SUITEpbasename_1< >0.000sOk -780filename_SUITEpbasename_2< >0.000sOk -781filename_SUITEpbasename_bin_1< >0.000sOk -782filename_SUITEpbasename_bin_2< >0.000sOk -783filename_SUITEpdirname_bin< >0.000sOk -784filename_SUITEpjoin_bin< >0.000sOk -785filename_SUITEppathtype_bin< >0.000sOk -786filename_SUITEprootname_bin< >0.000sOk -787filename_SUITEpsplit_bin< >0.000sOk -788filename_SUITEpt_nativename_bin< >0.000sOk -789filename_SUITEpt_basedir_api< >0.000sOk +771filename_SUITEpdirname< >0.000sOk +772filename_SUITEpextension< >0.000sOk +773filename_SUITEpextension_bin< >0.000sOk +774filename_SUITEpjoin< >0.000sOk +775filename_SUITEppathtype< >0.000sOk +776filename_SUITEprootname< >0.000sOk +777filename_SUITEpsplit< >0.000sOk +778filename_SUITEpt_nativename< >0.000sOk +779filename_SUITEpbasename_1< >0.000sOk +780filename_SUITEpbasename_2< >0.000sOk +781filename_SUITEpbasename_bin_1< >0.000sOk +782filename_SUITEpbasename_bin_2< >0.000sOk +783filename_SUITEpdirname_bin< >0.000sOk +784filename_SUITEpjoin_bin< >0.000sOk +785filename_SUITEppathtype_bin< >0.000sOk +786filename_SUITEprootname_bin< >0.000sOk +787filename_SUITEpsplit_bin< >0.000sOk +788filename_SUITEpt_nativename_bin< >0.000sOk +789filename_SUITEpt_basedir_api< >0.000sOk filename_SUITEpend_per_group< >0.000sOk 790filename_SUITEt_basedir_xdg< >0.001sOk 791filename_SUITEt_basedir_windows< >0.001sOk @@ -1025,7 +1025,7 @@

    Test started at 2024-09-11 11:10:55

    792fixtable_SUITEmultiple_fixes< >0.000sOk 793fixtable_SUITEmultiple_processes< >4.012sOk 794fixtable_SUITEother_process_deletes< >0.002sOk -795fixtable_SUITEowner_dies< >0.007sOk +795fixtable_SUITEowner_dies< >0.008sOk 796fixtable_SUITEother_process_closes< >0.002sOk 797fixtable_SUITEinsert_same_key< >0.001sOk 798fixtable_SUITEfixbag< >0.000sOk @@ -1033,37 +1033,37 @@

    Test started at 2024-09-11 11:10:55

    format_SUITEinit_per_suite< >0.000sOk 799format_SUITEhang_1< >0.000sOk format_SUITEend_per_suite< >0.000sOk -gb_sets_property_test_SUITEinit_per_suite< >1.264sOk -800gb_sets_property_test_SUITEadd_case< >0.123sOk -801gb_sets_property_test_SUITEbalance_case< >0.138sOk -802gb_sets_property_test_SUITEdelete_case< >0.128sOk -803gb_sets_property_test_SUITEdelete_any_case< >0.131sOk -804gb_sets_property_test_SUITEdifference_case< >0.181sOk -805gb_sets_property_test_SUITEfrom_ordset_case< >0.056sOk -806gb_sets_property_test_SUITEinsert_case< >0.140sOk -807gb_sets_property_test_SUITEis_member_case< >0.124sOk -808gb_sets_property_test_SUITEiterator_case< >0.073sOk -809gb_sets_property_test_SUITEiterator_from_case< >0.078sOk -810gb_sets_property_test_SUITElarger_case< >0.133sOk -811gb_sets_property_test_SUITElargest_case< >0.084sOk +gb_sets_property_test_SUITEinit_per_suite< >1.256sOk +800gb_sets_property_test_SUITEadd_case< >0.136sOk +801gb_sets_property_test_SUITEbalance_case< >0.139sOk +802gb_sets_property_test_SUITEdelete_case< >0.133sOk +803gb_sets_property_test_SUITEdelete_any_case< >0.130sOk +804gb_sets_property_test_SUITEdifference_case< >0.190sOk +805gb_sets_property_test_SUITEfrom_ordset_case< >0.067sOk +806gb_sets_property_test_SUITEinsert_case< >0.130sOk +807gb_sets_property_test_SUITEis_member_case< >0.130sOk +808gb_sets_property_test_SUITEiterator_case< >0.074sOk +809gb_sets_property_test_SUITEiterator_from_case< >0.064sOk +810gb_sets_property_test_SUITElarger_case< >0.123sOk +811gb_sets_property_test_SUITElargest_case< >0.067sOk 812gb_sets_property_test_SUITEsingleton_case< >0.006sOk -813gb_sets_property_test_SUITEsmaller_case< >0.124sOk -814gb_sets_property_test_SUITEsmallest_case< >0.057sOk -815gb_sets_property_test_SUITEtake_largest_case< >0.066sOk -816gb_sets_property_test_SUITEtake_smallest_case< >0.062sOk +813gb_sets_property_test_SUITEsmaller_case< >0.123sOk +814gb_sets_property_test_SUITEsmallest_case< >0.061sOk +815gb_sets_property_test_SUITEtake_largest_case< >0.063sOk +816gb_sets_property_test_SUITEtake_smallest_case< >0.067sOk gb_sets_property_test_SUITEend_per_suite< >0.000sOk gen_event_SUITEinit_per_suite< >0.000sOk -817gen_event_SUITEstart< >0.000sOk +817gen_event_SUITEstart< >0.001sOk gen_event_SUITEtest_allinit_per_group< >0.000sOk 818gen_event_SUITEtest_alladd_handler< >0.000sOk 819gen_event_SUITEtest_alladd_sup_handler< >1.000sOk 820gen_event_SUITEtest_alldelete_handler< >0.000sOk 821gen_event_SUITEtest_allswap_handler< >0.000sOk 822gen_event_SUITEtest_allswap_sup_handler< >0.000sOk -823gen_event_SUITEtest_allnotify< >0.001sOk +823gen_event_SUITEtest_allnotify< >0.002sOk 824gen_event_SUITEtest_allsync_notify< >0.001sOk 825gen_event_SUITEtest_allcall< >0.002sOk -826gen_event_SUITEtest_allinfo< >0.002sOk +826gen_event_SUITEtest_allinfo< >0.001sOk gen_event_SUITEtest_allend_per_group< >0.000sOk 827gen_event_SUITEhibernate< >1.039sOk 828gen_event_SUITEauto_hibernate< >0.521sOk @@ -1073,73 +1073,73 @@

    Test started at 2024-09-11 11:10:55

    832gen_event_SUITEget_state< >0.000sOk 833gen_event_SUITEreplace_state< >0.000sOk 834gen_event_SUITEstart_opt< >0.000sOk -gen_event_SUITEundef_callbacksinit_per_group< >0.002sOk +gen_event_SUITEundef_callbacksinit_per_group< >0.002sOk 835gen_event_SUITEundef_callbacksundef_init< >0.001sOk 836gen_event_SUITEundef_callbacksundef_handle_call< >0.000sOk 837gen_event_SUITEundef_callbacksundef_handle_event< >0.001sOk 838gen_event_SUITEundef_callbacksundef_handle_info< >0.101sOk 839gen_event_SUITEundef_callbacksundef_code_change< >0.000sOk 840gen_event_SUITEundef_callbacksundef_terminate< >0.000sOk -gen_event_SUITEundef_callbacksend_per_group< >0.000sOk +gen_event_SUITEundef_callbacksend_per_group< >0.000sOk 841gen_event_SUITEundef_in_terminate< >0.000sOk 842gen_event_SUITEformat_log_1< >0.000sOk 843gen_event_SUITEformat_log_2< >0.001sOk 844gen_event_SUITEformat_log_with_process_label< >0.000sOk 845gen_event_SUITEsend_request_receive_reqid_collection< >1.903sOk -846gen_event_SUITEsend_request_wait_reqid_collection< >1.803sOk -847gen_event_SUITEsend_request_check_reqid_collection< >1.003sOk +846gen_event_SUITEsend_request_wait_reqid_collection< >1.802sOk +847gen_event_SUITEsend_request_check_reqid_collection< >1.004sOk gen_event_SUITEend_per_suite< >0.000sOk gen_fsm_SUITEinit_per_suite< >0.000sOk gen_fsm_SUITEstartinit_per_group< >0.000sOk -848gen_fsm_SUITEstartstart1< >1.204sOk +848gen_fsm_SUITEstartstart1< >1.205sOk 849gen_fsm_SUITEstartstart2< >1.205sOk -850gen_fsm_SUITEstartstart3< >1.211sOk -851gen_fsm_SUITEstartstart4< >0.001sOk +850gen_fsm_SUITEstartstart3< >1.210sOk +851gen_fsm_SUITEstartstart4< >0.002sOk 852gen_fsm_SUITEstartstart5< >0.002sOk -853gen_fsm_SUITEstartstart6< >1.205sOk +853gen_fsm_SUITEstartstart6< >1.204sOk 854gen_fsm_SUITEstartstart7< >2.408sOk 855gen_fsm_SUITEstartstart8< >2.408sOk 856gen_fsm_SUITEstartstart9< >2.408sOk 857gen_fsm_SUITEstartstart10< >2.408sOk 858gen_fsm_SUITEstartstart11< >0.004sOk -859gen_fsm_SUITEstartstart12< >2.408sOk +859gen_fsm_SUITEstartstart12< >2.407sOk gen_fsm_SUITEstartend_per_group< >0.000sOk -gen_fsm_SUITEabnormalinit_per_group< >0.000sOk +gen_fsm_SUITEabnormalinit_per_group< >0.000sOk 860gen_fsm_SUITEabnormalabnormal1< >0.005sOk 861gen_fsm_SUITEabnormalabnormal2< >0.002sOk -gen_fsm_SUITEabnormalend_per_group< >0.000sOk +gen_fsm_SUITEabnormalend_per_group< >0.000sOk 862gen_fsm_SUITEshutdown< >1.704sOk -gen_fsm_SUITEsysinit_per_group< >0.000sOk -863gen_fsm_SUITEsyssys1< >5.000sOk -864gen_fsm_SUITEsyscall_format_status< >0.000sOk +gen_fsm_SUITEsysinit_per_group< >0.000sOk +863gen_fsm_SUITEsyssys1< >5.001sOk +864gen_fsm_SUITEsyscall_format_status< >0.001sOk 865gen_fsm_SUITEsyserror_format_status< >0.001sOk 866gen_fsm_SUITEsysterminate_crash_format< >0.001sOk 867gen_fsm_SUITEsysget_state< >0.000sOk 868gen_fsm_SUITEsysreplace_state< >0.000sOk -gen_fsm_SUITEsysend_per_group< >0.000sOk +gen_fsm_SUITEsysend_per_group< >0.000sOk 869gen_fsm_SUITEhibernate< >2.059sOk -870gen_fsm_SUITEauto_hibernate< >0.422sOk +870gen_fsm_SUITEauto_hibernate< >0.421sOk 871gen_fsm_SUITEenter_loop< >0.003sOk -gen_fsm_SUITEundef_callbacksinit_per_group< >0.002sOk -872gen_fsm_SUITEundef_callbacksundef_handle_event< >0.002sOk +gen_fsm_SUITEundef_callbacksinit_per_group< >0.003sOk +872gen_fsm_SUITEundef_callbacksundef_handle_event< >0.003sOk 873gen_fsm_SUITEundef_callbacksundef_handle_sync_event< >0.001sOk 874gen_fsm_SUITEundef_callbacksundef_handle_info< >0.501sOk 875gen_fsm_SUITEundef_callbacksundef_init< >0.001sOk 876gen_fsm_SUITEundef_callbacksundef_code_change< >0.000sOk 877gen_fsm_SUITEundef_callbacksundef_terminate1< >0.000sOk 878gen_fsm_SUITEundef_callbacksundef_terminate2< >0.001sOk -gen_fsm_SUITEundef_callbacksend_per_group< >0.000sOk +gen_fsm_SUITEundef_callbacksend_per_group< >0.000sOk 879gen_fsm_SUITEundef_in_handle_info< >0.001sOk -880gen_fsm_SUITEundef_in_terminate< >0.001sOk -gen_fsm_SUITEformat_loginit_per_group< >0.000sOk +880gen_fsm_SUITEundef_in_terminate< >0.002sOk +gen_fsm_SUITEformat_loginit_per_group< >0.000sOk 881gen_fsm_SUITEformat_logformat_log_1< >0.000sOk 882gen_fsm_SUITEformat_logformat_log_2< >0.001sOk 883gen_fsm_SUITEformat_logformat_log_with_process_label< >0.000sOk -gen_fsm_SUITEformat_logend_per_group< >0.000sOk +gen_fsm_SUITEformat_logend_per_group< >0.000sOk 884gen_fsm_SUITEreply_by_alias_with_payload< >0.000sOk gen_fsm_SUITEend_per_suite< >0.000sOk gen_server_SUITEinit_per_suite< >0.004sOk -885gen_server_SUITEstart< >0.516sOk +885gen_server_SUITEstart< >0.518sOk gen_server_SUITEstopinit_per_group< >0.000sOk 886gen_server_SUITEstopstop1< >0.000sOk 887gen_server_SUITEstopstop2< >0.001sOk @@ -1148,36 +1148,36 @@

    Test started at 2024-09-11 11:10:55

    890gen_server_SUITEstopstop5< >0.000sOk 891gen_server_SUITEstopstop6< >0.000sOk 892gen_server_SUITEstopstop7< >0.000sOk -893gen_server_SUITEstopstop8< >0.160sOk -894gen_server_SUITEstopstop9< >0.152sOk -895gen_server_SUITEstopstop10< >0.351sOk +893gen_server_SUITEstopstop8< >0.152sOk +894gen_server_SUITEstopstop9< >0.165sOk +895gen_server_SUITEstopstop10< >0.341sOk gen_server_SUITEstopend_per_group< >0.000sOk 896gen_server_SUITEcrash< >0.501sOk -897gen_server_SUITEloop_start_fail< >5.062sOk +897gen_server_SUITEloop_start_fail< >5.068sOk 898gen_server_SUITEcall< >2.009sOk -899gen_server_SUITEsend_request< >1.574sOk +899gen_server_SUITEsend_request< >1.571sOk 900gen_server_SUITEsend_request_receive_reqid_collection< >1.903sOk 901gen_server_SUITEsend_request_wait_reqid_collection< >1.803sOk 902gen_server_SUITEsend_request_check_reqid_collection< >1.004sOk 903gen_server_SUITEcast< >0.002sOk -904gen_server_SUITEcast_fast< >1.338sOk +904gen_server_SUITEcast_fast< >1.340sOk 905gen_server_SUITEinfo< >0.002sOk 906gen_server_SUITEabcast< >0.002sOk 907gen_server_SUITEcontinue< >0.000sOk -gen_server_SUITEmulti_callinit_per_group< >0.000sOk -gen_server_SUITEmulti_call_parallelinit_per_group< >0.000sOk +gen_server_SUITEmulti_callinit_per_group< >0.000sOk +gen_server_SUITEmulti_call_parallelinit_per_group< >0.000sOk 911gen_server_SUITEmulti_call_parallelmulticall_remote_old1< >0.000sSKIPPEDBroken in docker -908gen_server_SUITEmulti_call_parallelmulticall< >2.006sOk -909gen_server_SUITEmulti_call_parallelmulticall_down< >0.010sOk -910gen_server_SUITEmulti_call_parallelmulticall_remote< >2.790sOk -912gen_server_SUITEmulti_call_parallelmulticall_remote_old2< >31.736sOk -gen_server_SUITEmulti_call_parallelend_per_group< >0.000sOk -gen_server_SUITEmulti_call_sequenceinit_per_group< >0.000sOk -913gen_server_SUITEmulti_call_sequencemulticall_recv_opt_success< >0.629sOkRatio: 1.08272809802733482876e+00 -914gen_server_SUITEmulti_call_sequencemulticall_recv_opt_timeout< >4.609sOkRatio: 9.99957039460168117806e-01 -915gen_server_SUITEmulti_call_sequencemulticall_recv_opt_noconnection< >1.429sOkRatio: 9.86144722207283108695e-01 -gen_server_SUITEmulti_call_sequenceend_per_group< >0.000sOk -gen_server_SUITEmulti_callend_per_group< >0.000sOk +908gen_server_SUITEmulti_call_parallelmulticall< >2.005sOk +909gen_server_SUITEmulti_call_parallelmulticall_down< >0.007sOk +910gen_server_SUITEmulti_call_parallelmulticall_remote< >2.812sOk +912gen_server_SUITEmulti_call_parallelmulticall_remote_old2< >31.719sOk +gen_server_SUITEmulti_call_parallelend_per_group< >0.000sOk +gen_server_SUITEmulti_call_sequenceinit_per_group< >0.000sOk +913gen_server_SUITEmulti_call_sequencemulticall_recv_opt_success< >0.614sOkRatio: 1.05760937470734606158e+00 +914gen_server_SUITEmulti_call_sequencemulticall_recv_opt_timeout< >4.595sOkRatio: 9.99852047222122064518e-01 +915gen_server_SUITEmulti_call_sequencemulticall_recv_opt_noconnection< >1.414sOkRatio: 9.88034566373387601601e-01 +gen_server_SUITEmulti_call_sequenceend_per_group< >0.000sOk +gen_server_SUITEmulti_callend_per_group< >0.000sOk 916gen_server_SUITEcall_remote1< >0.007sOk 917gen_server_SUITEcall_remote2< >0.007sOk 918gen_server_SUITEcalling_self< >0.000sOk @@ -1185,34 +1185,34 @@

    Test started at 2024-09-11 11:10:55

    920gen_server_SUITEcall_remote_n1< >0.006sOk 921gen_server_SUITEcall_remote_n2< >0.006sOk 922gen_server_SUITEcall_remote_n3< >0.006sOk -923gen_server_SUITEspec_init< >1.008sOk +923gen_server_SUITEspec_init< >1.011sOk 924gen_server_SUITEspec_init_local_registered_parent< >0.000sOk 925gen_server_SUITEspec_init_global_registered_parent< >0.000sOk -926gen_server_SUITEotp_5854< >0.002sOk -927gen_server_SUITEhibernate< >3.023sOk -928gen_server_SUITEauto_hibernate< >0.422sOk -929gen_server_SUITEotp_7669< >0.028sOk -gen_server_SUITEformat_statusinit_per_group< >0.000sOk -930gen_server_SUITEformat_statuscall_format_status< >0.011sOk -931gen_server_SUITEformat_statuserror_format_status< >0.002sOk +926gen_server_SUITEotp_5854< >0.001sOk +927gen_server_SUITEhibernate< >3.022sOk +928gen_server_SUITEauto_hibernate< >0.423sOk +929gen_server_SUITEotp_7669< >0.031sOk +gen_server_SUITEformat_statusinit_per_group< >0.000sOk +930gen_server_SUITEformat_statuscall_format_status< >0.016sOk +931gen_server_SUITEformat_statuserror_format_status< >0.004sOk 932gen_server_SUITEformat_statusterminate_crash_format< >0.003sOk 933gen_server_SUITEformat_statuscrash_in_format_status< >0.002sOk 934gen_server_SUITEformat_statusthrow_in_format_status< >0.002sOk -935gen_server_SUITEformat_statusformat_all_status< >0.014sOk -gen_server_SUITEformat_statusend_per_group< >0.000sOk +935gen_server_SUITEformat_statusformat_all_status< >0.012sOk +gen_server_SUITEformat_statusend_per_group< >0.000sOk 936gen_server_SUITEget_state< >0.000sOk 937gen_server_SUITEreplace_state< >0.000sOk -938gen_server_SUITEcall_with_huge_message_queue< >0.124sOk -gen_server_SUITEundef_callbacksinit_per_group< >0.003sOk +938gen_server_SUITEcall_with_huge_message_queue< >0.122sOk +gen_server_SUITEundef_callbacksinit_per_group< >0.003sOk 939gen_server_SUITEundef_callbacksundef_handle_call< >0.003sOk 940gen_server_SUITEundef_callbacksundef_handle_cast< >0.001sOk 941gen_server_SUITEundef_callbacksundef_handle_info< >0.101sOk 942gen_server_SUITEundef_callbacksundef_handle_continue< >0.001sOk -943gen_server_SUITEundef_callbacksundef_init< >0.502sOk +943gen_server_SUITEundef_callbacksundef_init< >0.503sOk 944gen_server_SUITEundef_callbacksundef_code_change< >0.000sOk 945gen_server_SUITEundef_callbacksundef_terminate1< >0.000sOk 946gen_server_SUITEundef_callbacksundef_terminate2< >0.001sOk -gen_server_SUITEundef_callbacksend_per_group< >0.000sOk +gen_server_SUITEundef_callbacksend_per_group< >0.000sOk 947gen_server_SUITEundef_in_terminate< >0.001sOk 948gen_server_SUITEundef_in_handle_info< >0.001sOk 949gen_server_SUITEformat_log_1< >0.000sOk @@ -1226,7 +1226,7 @@

    Test started at 2024-09-11 11:10:55

    954gen_statem_SUITEstartstart2< >1.403sOk 955gen_statem_SUITEstartstart3< >1.409sOk 956gen_statem_SUITEstartstart4< >0.501sOk -957gen_statem_SUITEstartstart5a< >0.501sOk +957gen_statem_SUITEstartstart5a< >0.502sOk 958gen_statem_SUITEstartstart5b< >0.501sOk 959gen_statem_SUITEstartstart6< >1.403sOk 960gen_statem_SUITEstartstart7< >4.610sOk @@ -1237,23 +1237,23 @@

    Test started at 2024-09-11 11:10:55

    965gen_statem_SUITEstartstart12< >2.305sOk 966gen_statem_SUITEstartnext_events< >0.000sOk gen_statem_SUITEstartend_per_group< >0.000sOk -gen_statem_SUITEstart_handle_eventinit_per_group< >0.000sOk -967gen_statem_SUITEstart_handle_eventstart1< >2.809sOk -968gen_statem_SUITEstart_handle_eventstart2< >1.403sOk -969gen_statem_SUITEstart_handle_eventstart3< >1.409sOk -970gen_statem_SUITEstart_handle_eventstart4< >0.501sOk -971gen_statem_SUITEstart_handle_eventstart5a< >0.501sOk -972gen_statem_SUITEstart_handle_eventstart5b< >0.501sOk -973gen_statem_SUITEstart_handle_eventstart6< >1.403sOk -974gen_statem_SUITEstart_handle_eventstart7< >4.610sOk -975gen_statem_SUITEstart_handle_eventstart8< >2.305sOk -976gen_statem_SUITEstart_handle_eventstart9< >4.610sOk -977gen_statem_SUITEstart_handle_eventstart10< >2.305sOk -978gen_statem_SUITEstart_handle_eventstart11< >0.503sOk -979gen_statem_SUITEstart_handle_eventstart12< >2.305sOk -980gen_statem_SUITEstart_handle_eventnext_events< >0.000sOk -gen_statem_SUITEstart_handle_eventend_per_group< >0.000sOk -gen_statem_SUITEstopinit_per_group< >0.000sOk +gen_statem_SUITEstart_handle_eventinit_per_group< >0.000sOk +967gen_statem_SUITEstart_handle_eventstart1< >2.809sOk +968gen_statem_SUITEstart_handle_eventstart2< >1.403sOk +969gen_statem_SUITEstart_handle_eventstart3< >1.409sOk +970gen_statem_SUITEstart_handle_eventstart4< >0.501sOk +971gen_statem_SUITEstart_handle_eventstart5a< >0.501sOk +972gen_statem_SUITEstart_handle_eventstart5b< >0.501sOk +973gen_statem_SUITEstart_handle_eventstart6< >1.403sOk +974gen_statem_SUITEstart_handle_eventstart7< >4.610sOk +975gen_statem_SUITEstart_handle_eventstart8< >2.305sOk +976gen_statem_SUITEstart_handle_eventstart9< >4.610sOk +977gen_statem_SUITEstart_handle_eventstart10< >2.305sOk +978gen_statem_SUITEstart_handle_eventstart11< >0.503sOk +979gen_statem_SUITEstart_handle_eventstart12< >2.305sOk +980gen_statem_SUITEstart_handle_eventnext_events< >0.000sOk +gen_statem_SUITEstart_handle_eventend_per_group< >0.000sOk +gen_statem_SUITEstopinit_per_group< >0.000sOk 981gen_statem_SUITEstopstop1< >0.000sOk 982gen_statem_SUITEstopstop2< >0.001sOk 983gen_statem_SUITEstopstop3< >0.000sOk @@ -1261,40 +1261,40 @@

    Test started at 2024-09-11 11:10:55

    985gen_statem_SUITEstopstop5< >0.000sOk 986gen_statem_SUITEstopstop6< >0.000sOk 987gen_statem_SUITEstopstop7< >0.000sOk -988gen_statem_SUITEstopstop8< >0.171sOk -989gen_statem_SUITEstopstop9< >0.174sOk +988gen_statem_SUITEstopstop8< >0.170sOk +989gen_statem_SUITEstopstop9< >0.158sOk 990gen_statem_SUITEstopstop10< >0.344sOk -gen_statem_SUITEstopend_per_group< >0.000sOk -gen_statem_SUITEstop_handle_eventinit_per_group< >0.000sOk -991gen_statem_SUITEstop_handle_eventstop1< >0.000sOk -992gen_statem_SUITEstop_handle_eventstop2< >0.001sOk -993gen_statem_SUITEstop_handle_eventstop3< >0.000sOk -994gen_statem_SUITEstop_handle_eventstop4< >0.000sOk -995gen_statem_SUITEstop_handle_eventstop5< >0.000sOk -996gen_statem_SUITEstop_handle_eventstop6< >0.000sOk -997gen_statem_SUITEstop_handle_eventstop7< >0.000sOk -998gen_statem_SUITEstop_handle_eventstop8< >0.160sOk -999gen_statem_SUITEstop_handle_eventstop9< >0.162sOk -1000gen_statem_SUITEstop_handle_eventstop10< >0.351sOk -gen_statem_SUITEstop_handle_eventend_per_group< >0.000sOk -gen_statem_SUITEabnormalinit_per_group< >0.000sOk +gen_statem_SUITEstopend_per_group< >0.000sOk +gen_statem_SUITEstop_handle_eventinit_per_group< >0.000sOk +991gen_statem_SUITEstop_handle_eventstop1< >0.000sOk +992gen_statem_SUITEstop_handle_eventstop2< >0.001sOk +993gen_statem_SUITEstop_handle_eventstop3< >0.000sOk +994gen_statem_SUITEstop_handle_eventstop4< >0.000sOk +995gen_statem_SUITEstop_handle_eventstop5< >0.000sOk +996gen_statem_SUITEstop_handle_eventstop6< >0.000sOk +997gen_statem_SUITEstop_handle_eventstop7< >0.000sOk +998gen_statem_SUITEstop_handle_eventstop8< >0.161sOk +999gen_statem_SUITEstop_handle_eventstop9< >0.164sOk +1000gen_statem_SUITEstop_handle_eventstop10< >0.352sOk +gen_statem_SUITEstop_handle_eventend_per_group< >0.000sOk +gen_statem_SUITEabnormalinit_per_group< >0.000sOk 1001gen_statem_SUITEabnormalabnormal1< >3.704sOk 1002gen_statem_SUITEabnormalabnormal1clean< >2.605sOk 1003gen_statem_SUITEabnormalabnormal1dirty< >2.605sOk 1004gen_statem_SUITEabnormalabnormal2< >0.502sOk 1005gen_statem_SUITEabnormalabnormal3< >0.502sOk 1006gen_statem_SUITEabnormalabnormal4< >0.502sOk -gen_statem_SUITEabnormalend_per_group< >0.000sOk -gen_statem_SUITEabnormal_handle_eventinit_per_group< >0.000sOk -1007gen_statem_SUITEabnormal_handle_eventabnormal1< >3.704sOk -1008gen_statem_SUITEabnormal_handle_eventabnormal1clean< >2.605sOk -1009gen_statem_SUITEabnormal_handle_eventabnormal1dirty< >2.605sOk -1010gen_statem_SUITEabnormal_handle_eventabnormal2< >0.502sOk -1011gen_statem_SUITEabnormal_handle_eventabnormal3< >0.502sOk -1012gen_statem_SUITEabnormal_handle_eventabnormal4< >0.502sOk -gen_statem_SUITEabnormal_handle_eventend_per_group< >0.000sOk +gen_statem_SUITEabnormalend_per_group< >0.000sOk +gen_statem_SUITEabnormal_handle_eventinit_per_group< >0.000sOk +1007gen_statem_SUITEabnormal_handle_eventabnormal1< >3.704sOk +1008gen_statem_SUITEabnormal_handle_eventabnormal1clean< >2.605sOk +1009gen_statem_SUITEabnormal_handle_eventabnormal1dirty< >2.605sOk +1010gen_statem_SUITEabnormal_handle_eventabnormal2< >0.502sOk +1011gen_statem_SUITEabnormal_handle_eventabnormal3< >0.502sOk +1012gen_statem_SUITEabnormal_handle_eventabnormal4< >0.502sOk +gen_statem_SUITEabnormal_handle_eventend_per_group< >0.000sOk 1013gen_statem_SUITEshutdown< >1.403sOk -1014gen_statem_SUITEloop_start_fail< >5.101sOk +1014gen_statem_SUITEloop_start_fail< >5.095sOk 1015gen_statem_SUITEstop_and_reply< >1.003sOk 1016gen_statem_SUITEstate_enter< >3.509sOk 1017gen_statem_SUITEevent_order< >1.003sOk @@ -1303,41 +1303,41 @@

    Test started at 2024-09-11 11:10:55

    1020gen_statem_SUITEevent_types< >0.502sOk 1021gen_statem_SUITEgeneric_timers< >1.502sOk 1022gen_statem_SUITEcode_change< >0.000sOk -gen_statem_SUITEsysinit_per_group< >0.004sOk +gen_statem_SUITEsysinit_per_group< >0.004sOk 1023gen_statem_SUITEsyssys1< >3.001sOk -gen_statem_SUITEformat_statusinit_per_group< >0.000sOk -1024gen_statem_SUITEformat_statuscall_format_status< >0.006sOk -1025gen_statem_SUITEformat_statuserror_format_status< >1.004sOk +gen_statem_SUITEformat_statusinit_per_group< >0.000sOk +1024gen_statem_SUITEformat_statuscall_format_status< >0.004sOk +1025gen_statem_SUITEformat_statuserror_format_status< >1.005sOk 1026gen_statem_SUITEformat_statusterminate_crash_format< >1.512sOk -1027gen_statem_SUITEformat_statusformat_all_status< >0.001sOk -gen_statem_SUITEformat_statusend_per_group< >0.000sOk +1027gen_statem_SUITEformat_statusformat_all_status< >0.002sOk +gen_statem_SUITEformat_statusend_per_group< >0.000sOk 1028gen_statem_SUITEsysget_state< >0.501sOk 1029gen_statem_SUITEsysreplace_state< >0.501sOk -gen_statem_SUITEsysend_per_group< >0.000sOk +gen_statem_SUITEsysend_per_group< >0.000sOk 1030gen_statem_SUITEhibernate< >1.310sOk 1031gen_statem_SUITEauto_hibernate< >4.787sOk 1032gen_statem_SUITEenter_loop< >0.504sOk -gen_statem_SUITEundef_callbacksinit_per_group< >0.007sOk +gen_statem_SUITEundef_callbacksinit_per_group< >0.007sOk 1033gen_statem_SUITEundef_callbacksundef_code_change< >0.002sOk 1034gen_statem_SUITEundef_callbacksundef_terminate1< >0.000sOk 1035gen_statem_SUITEundef_callbacksundef_terminate2< >0.001sOk 1036gen_statem_SUITEundef_callbackspop_too_many< >0.002sOk -gen_statem_SUITEundef_callbacksend_per_group< >0.000sOk +gen_statem_SUITEundef_callbacksend_per_group< >0.000sOk 1037gen_statem_SUITEundef_in_terminate< >0.001sOk -gen_statem_SUITEformat_loginit_per_group< >0.000sOk +gen_statem_SUITEformat_loginit_per_group< >0.000sOk 1038gen_statem_SUITEformat_logformat_log_1< >0.000sOk 1039gen_statem_SUITEformat_logformat_log_2< >0.001sOk 1040gen_statem_SUITEformat_logformat_log_with_process_label< >0.000sOk -gen_statem_SUITEformat_logend_per_group< >0.000sOk +gen_statem_SUITEformat_logend_per_group< >0.000sOk 1041gen_statem_SUITEreply_by_alias_with_payload< >0.000sOk 1042gen_statem_SUITEsend_request_receive_reqid_collection< >1.903sOk 1043gen_statem_SUITEsend_request_wait_reqid_collection< >1.803sOk 1044gen_statem_SUITEsend_request_check_reqid_collection< >1.004sOk gen_statem_SUITEend_per_suite< >0.000sOk id_transform_SUITEinit_per_suite< >0.000sOk -1045id_transform_SUITEid_transform< >3.322sOk +1045id_transform_SUITEid_transform< >3.374sOk id_transform_SUITEend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk +common_testinit_per_suite< >0.000sOk 1046io_SUITEerror_1< >0.003sOk 1047io_SUITEfloat_g< >0.000sOk 1048io_SUITEfloat_w< >0.000sOk @@ -1358,15 +1358,15 @@

    Test started at 2024-09-11 11:10:55

    1063io_SUITEio_fread_newlines< >0.010sOk 1064io_SUITEotp_8989< >0.000sOk 1065io_SUITEio_lib_fread_literal< >0.000sOk -1066io_SUITEprintable_range< >0.823sOk +1066io_SUITEprintable_range< >0.843sOk 1067io_SUITEbad_printable_range< >0.009sOk 1068io_SUITEformat_neg_zero< >0.000sOk 1069io_SUITEio_lib_print_binary_depth_one< >0.000sOk -1070io_SUITEotp_10302< >0.326sOk -1071io_SUITEotp_10755< >0.003sOk +1070io_SUITEotp_10302< >0.328sOk +1071io_SUITEotp_10755< >0.002sOk 1072io_SUITEotp_10836< >0.000sOk 1073io_SUITEio_lib_width_too_small< >0.000sOk -1074io_SUITEio_with_huge_message_queue< >0.438sOk +1074io_SUITEio_with_huge_message_queue< >0.436sOk 1075io_SUITEcalling_self< >0.000sOk 1076io_SUITEformat_string< >0.000sOk 1077io_SUITEmaps< >0.001sOk @@ -1375,7 +1375,7 @@

    Test started at 2024-09-11 11:10:55

    1080io_SUITEotp_14175< >0.000sOk 1081io_SUITEotp_14285< >0.001sOk 1082io_SUITElimit_term< >0.000sOk -1083io_SUITEotp_14983< >0.169sOk +1083io_SUITEotp_14983< >0.163sOk 1084io_SUITEotp_15103< >0.000sOk 1085io_SUITEotp_15076< >0.002sOk 1086io_SUITEotp_15159< >0.000sOk @@ -1384,292 +1384,292 @@

    Test started at 2024-09-11 11:10:55

    1089io_SUITEotp_15847< >0.000sOk 1090io_SUITEotp_15875< >0.000sOk 1091io_SUITEgithub_4801< >0.000sOk -1092io_SUITEchars_limit< >0.314sOk -1093io_SUITEerror_info< >0.068sOk +1092io_SUITEchars_limit< >0.310sOk +1093io_SUITEerror_info< >0.067sOk 1094io_SUITEotp_17525< >0.000sOk 1095io_SUITEunscan_format_without_maps_order< >0.000sOk 1096io_SUITEbuild_text_without_maps_order< >0.000sOk -common_testend_per_suite< >0.000sOk -io_proto_SUITEinit_per_suite< >2.703sOk -1097io_proto_SUITEsetopts_getopts< >6.565sOk -1098io_proto_SUITEunicode_options< >5.409sOk -1099io_proto_SUITEunicode_options_gen< >16.003sOk -1100io_proto_SUITEbinary_options< >5.397sOk -1101io_proto_SUITEread_modes_gl< >3.212sOk -1102io_proto_SUITEread_modes_ogl< >3.213sOk -1103io_proto_SUITEbroken_unicode< >0.190sOk -1104io_proto_SUITEeof_on_pipe< >2.338sOk -1105io_proto_SUITEunicode_prompt< >5.379sOk -1106io_proto_SUITEshell_slogan< >8.061sOk -1107io_proto_SUITEraw_stdout< >0.141sOk -1108io_proto_SUITEraw_stdout_isatty< >2.695sOk -1109io_proto_SUITEfile_read_stdin_binary_mode< >0.153sOk -1110io_proto_SUITEfile_read_stdin_list_mode< >0.151sOk -1111io_proto_SUITEfile_read_stdin_unicode_translation_error_binary_mode< >0.156sOk -1112io_proto_SUITEfile_read_stdin_unicode_translation_error_list_mode< >0.153sOk -1113io_proto_SUITEfile_read_line_stdin_unicode_translation_error_binary_mode< >0.142sOk +common_testend_per_suite< >0.000sOk +io_proto_SUITEinit_per_suite< >2.699sOk +1097io_proto_SUITEsetopts_getopts< >6.595sOk +1098io_proto_SUITEunicode_options< >5.418sOk +1099io_proto_SUITEunicode_options_gen< >16.243sOk +1100io_proto_SUITEbinary_options< >5.412sOk +1101io_proto_SUITEread_modes_gl< >3.220sOk +1102io_proto_SUITEread_modes_ogl< >3.230sOk +1103io_proto_SUITEbroken_unicode< >0.197sOk +1104io_proto_SUITEeof_on_pipe< >2.350sOk +1105io_proto_SUITEunicode_prompt< >5.408sOk +1106io_proto_SUITEshell_slogan< >8.081sOk +1107io_proto_SUITEraw_stdout< >0.151sOk +1108io_proto_SUITEraw_stdout_isatty< >2.696sOk +1109io_proto_SUITEfile_read_stdin_binary_mode< >0.146sOk +1110io_proto_SUITEfile_read_stdin_list_mode< >0.149sOk +1111io_proto_SUITEfile_read_stdin_unicode_translation_error_binary_mode< >0.147sOk +1112io_proto_SUITEfile_read_stdin_unicode_translation_error_list_mode< >0.159sOk +1113io_proto_SUITEfile_read_line_stdin_unicode_translation_error_binary_mode< >0.148sOk 1114io_proto_SUITEfile_read_line_stdin_unicode_translation_error_list_mode< >0.148sOk -1115io_proto_SUITEio_get_chars_stdin_binary_mode< >0.144sOk -1116io_proto_SUITEio_get_chars_stdin_list_mode< >0.154sOk -1117io_proto_SUITEio_get_until_stdin_binary_mode< >0.880sOk -1118io_proto_SUITEio_get_until_stdin_list_mode< >1.430sOk -1119io_proto_SUITEio_get_chars_file_read_stdin_binary_mode< >0.470sOk -1120io_proto_SUITEfile_read_stdin_latin1_binary_mode< >0.816sOk -1121io_proto_SUITEfile_read_stdin_latin1_list_mode< >0.314sOk -1122io_proto_SUITEio_fwrite_stdin_latin1_mode< >0.151sOk +1115io_proto_SUITEio_get_chars_stdin_binary_mode< >0.151sOk +1116io_proto_SUITEio_get_chars_stdin_list_mode< >0.147sOk +1117io_proto_SUITEio_get_until_stdin_binary_mode< >0.852sOk +1118io_proto_SUITEio_get_until_stdin_list_mode< >1.460sOk +1119io_proto_SUITEio_get_chars_file_read_stdin_binary_mode< >0.444sOk +1120io_proto_SUITEfile_read_stdin_latin1_binary_mode< >0.792sOk +1121io_proto_SUITEfile_read_stdin_latin1_list_mode< >0.310sOk +1122io_proto_SUITEio_fwrite_stdin_latin1_mode< >0.157sOk io_proto_SUITEend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk +common_testinit_per_suite< >0.000sOk json_SUITEencodeinit_per_group< >0.000sOk -1123json_SUITEencodetest_encode_atom< >0.003sOk -1124json_SUITEencodetest_encode_integer< >0.002sOk -1125json_SUITEencodetest_encode_float< >0.003sOk -1126json_SUITEencodetest_encode_binary< >0.005sOk -1127json_SUITEencodetest_encode_map< >0.002sOk -1128json_SUITEencodetest_encode_list< >0.002sOk -1129json_SUITEencodetest_encode_proplist< >0.001sOk -1130json_SUITEencodetest_encode_escape_all< >0.003sOk +1123json_SUITEencodetest_encode_atom< >0.003sOk +1124json_SUITEencodetest_encode_integer< >0.003sOk +1125json_SUITEencodetest_encode_float< >0.002sOk +1126json_SUITEencodetest_encode_binary< >0.003sOk +1127json_SUITEencodetest_encode_map< >0.003sOk +1128json_SUITEencodetest_encode_list< >0.003sOk +1129json_SUITEencodetest_encode_proplist< >0.003sOk +1130json_SUITEencodetest_encode_escape_all< >0.003sOk json_SUITEencodeend_per_group< >0.000sOk -json_SUITEdecodeinit_per_group< >0.000sOk -1131json_SUITEdecodetest_decode_atoms< >0.000sOk -1132json_SUITEdecodetest_decode_numbers< >0.000sOk -1133json_SUITEdecodetest_decode_strings< >0.000sOk -1134json_SUITEdecodetest_decode_arrays< >0.000sOk -1135json_SUITEdecodetest_decode_objects< >0.000sOk -1136json_SUITEdecodetest_decode_whitespace< >0.000sOk -1137json_SUITEdecodetest_decode_api< >0.000sOk -1138json_SUITEdecodetest_decode_api_stream< >0.000sOk -json_SUITEdecodeend_per_group< >0.000sOk -json_SUITEformatinit_per_group< >0.000sOk -1139json_SUITEformattest_format_list< >0.000sOk -1140json_SUITEformattest_format_map< >0.000sOk -1141json_SUITEformattest_format_fun< >0.000sOk -json_SUITEformatend_per_group< >0.000sOk +json_SUITEdecodeinit_per_group< >0.000sOk +1131json_SUITEdecodetest_decode_atoms< >0.000sOk +1132json_SUITEdecodetest_decode_numbers< >0.000sOk +1133json_SUITEdecodetest_decode_strings< >0.000sOk +1134json_SUITEdecodetest_decode_arrays< >0.000sOk +1135json_SUITEdecodetest_decode_objects< >0.000sOk +1136json_SUITEdecodetest_decode_whitespace< >0.000sOk +1137json_SUITEdecodetest_decode_api< >0.000sOk +1138json_SUITEdecodetest_decode_api_stream< >0.000sOk +json_SUITEdecodeend_per_group< >0.000sOk +json_SUITEformatinit_per_group< >0.000sOk +1139json_SUITEformattest_format_list< >0.000sOk +1140json_SUITEformattest_format_map< >0.000sOk +1141json_SUITEformattest_format_fun< >0.000sOk +json_SUITEformatend_per_group< >0.000sOk 1142json_SUITEtest_json_test_suite< >0.542sOk -json_SUITEpropertiesinit_per_group< >1.250sOk -1143json_SUITEpropertiesproperty_string_roundtrip< >0.009sOk -1144json_SUITEpropertiesproperty_integer_roundtrip< >0.005sOk -1145json_SUITEpropertiesproperty_float_roundtrip< >0.008sOk -1146json_SUITEpropertiesproperty_object_roundtrip< >0.009sOk -1147json_SUITEpropertiesproperty_escape_all< >0.010sOk -json_SUITEpropertiesend_per_group< >0.000sOk +json_SUITEpropertiesinit_per_group< >1.254sOk +1143json_SUITEpropertiesproperty_string_roundtrip< >0.010sOk +1144json_SUITEpropertiesproperty_integer_roundtrip< >0.007sOk +1145json_SUITEpropertiesproperty_float_roundtrip< >0.007sOk +1146json_SUITEpropertiesproperty_object_roundtrip< >0.009sOk +1147json_SUITEpropertiesproperty_escape_all< >0.009sOk +json_SUITEpropertiesend_per_group< >0.000sOk 1148json_SUITEcounterexamples< >0.000sOk -common_testend_per_suite< >0.000sOk +common_testend_per_suite< >0.000sOk lists_SUITEinit_per_suite< >0.000sOk lists_SUITEappendinit_per_group< >0.000sOk -1149lists_SUITEappendappend_1< >0.000sOk -1150lists_SUITEappendappend_2< >0.090sOk +1149lists_SUITEappendappend_1< >0.000sOk +1150lists_SUITEappendappend_2< >0.091sOk lists_SUITEappendend_per_group< >0.000sOk -lists_SUITEkeyinit_per_group< >0.000sOk -1151lists_SUITEkeykeymember< >0.015sOk -1152lists_SUITEkeykeysearch_keyfind< >0.016sOk -1153lists_SUITEkeykeystore< >0.000sOk -1154lists_SUITEkeykeytake< >0.000sOk -1155lists_SUITEkeykeyreplace< >0.000sOk -lists_SUITEkeyend_per_group< >0.000sOk -lists_SUITEsortinit_per_group< >0.000sOk -1156lists_SUITEsortmerge< >0.000sOk -1157lists_SUITEsortrmerge< >0.000sOk -1158lists_SUITEsortsort_1< >0.025sOk -1159lists_SUITEsortsort_rand< >0.007sOk -lists_SUITEsortend_per_group< >0.000sOk -lists_SUITEusortinit_per_group< >0.000sOk -1160lists_SUITEusortumerge< >0.000sOk -1161lists_SUITEusortrumerge< >0.000sOk -1162lists_SUITEusortusort_1< >0.024sOk -1163lists_SUITEusortusort_rand< >0.011sOk -lists_SUITEusortend_per_group< >0.000sOk -lists_SUITEkeysortinit_per_group< >0.000sOk -1164lists_SUITEkeysortkeymerge< >0.000sOk -1165lists_SUITEkeysortrkeymerge< >0.000sOk -1166lists_SUITEkeysortkeysort_1< >0.035sOk -1167lists_SUITEkeysortkeysort_rand< >0.010sOk -1168lists_SUITEkeysortkeysort_i< >0.000sOk -1169lists_SUITEkeysortkeysort_error< >0.000sOk -lists_SUITEkeysortend_per_group< >0.000sOk -lists_SUITEukeysortinit_per_group< >0.000sOk -1170lists_SUITEukeysortukeymerge< >0.000sOk -1171lists_SUITEukeysortrukeymerge< >0.000sOk -1172lists_SUITEukeysortukeysort_1< >0.030sOk -1173lists_SUITEukeysortukeysort_rand< >0.009sOk -1174lists_SUITEukeysortukeysort_i< >0.000sOk -1175lists_SUITEukeysortukeysort_error< >0.000sOk -lists_SUITEukeysortend_per_group< >0.000sOk -lists_SUITEuniqinit_per_group< >0.000sOk -1176lists_SUITEuniquniq_1< >0.000sOk -1177lists_SUITEuniquniq_2< >0.000sOk -lists_SUITEuniqend_per_group< >0.000sOk -lists_SUITEsublistinit_per_group< >0.000sOk -1178lists_SUITEsublistsublist_2< >0.000sOk -1179lists_SUITEsublistsublist_3< >0.000sOk -1180lists_SUITEsublistsublist_2_e< >0.000sOk -1181lists_SUITEsublistsublist_3_e< >0.000sOk -lists_SUITEsublistend_per_group< >0.000sOk -lists_SUITEflatteninit_per_group< >0.000sOk -1182lists_SUITEflattenflatten_1< >0.000sOk -1183lists_SUITEflattenflatten_2< >0.000sOk -1184lists_SUITEflattenflatten_1_e< >0.000sOk -1185lists_SUITEflattenflatten_2_e< >0.000sOk -lists_SUITEflattenend_per_group< >0.000sOk -lists_SUITEseqinit_per_group< >0.000sOk -1186lists_SUITEseqseq_loop< >0.000sOk -1187lists_SUITEseqseq_2< >0.000sOk -1188lists_SUITEseqseq_3< >0.000sOk -1189lists_SUITEseqseq_2_e< >0.000sOk -1190lists_SUITEseqseq_3_e< >0.000sOk -lists_SUITEseqend_per_group< >0.000sOk -lists_SUITEticketsinit_per_group< >0.000sOk -1191lists_SUITEticketsotp_5939< >0.000sOk -1192lists_SUITEticketsotp_6023< >0.000sOk -1193lists_SUITEticketsotp_6606< >0.000sOk -1194lists_SUITEticketsotp_7230< >0.003sOk -lists_SUITEticketsend_per_group< >0.000sOk -lists_SUITEzipinit_per_group< >0.000sOk -1195lists_SUITEzipzip_unzip< >0.000sOk -1196lists_SUITEzipzip_unzip3< >0.000sOk -1197lists_SUITEzipzipwith< >0.000sOk -1198lists_SUITEzipzipwith3< >0.000sOk -1199lists_SUITEzipzip_fail< >0.000sOk -1200lists_SUITEzipzip_trim< >0.000sOk -1201lists_SUITEzipzip_pad< >0.000sOk -1202lists_SUITEzipzip3_fail< >0.000sOk -1203lists_SUITEzipzip3_trim< >0.000sOk -1204lists_SUITEzipzip3_pad< >0.000sOk -1205lists_SUITEzipzipwith_fail< >0.000sOk -1206lists_SUITEzipzipwith_trim< >0.000sOk -1207lists_SUITEzipzipwith_pad< >0.000sOk -1208lists_SUITEzipzipwith3_fail< >0.000sOk -1209lists_SUITEzipzipwith3_trim< >0.000sOk -1210lists_SUITEzipzipwith3_pad< >0.000sOk -lists_SUITEzipend_per_group< >0.000sOk -lists_SUITEmiscinit_per_group< >0.000sOk -1211lists_SUITEmiscreverse< >0.010sOk -1212lists_SUITEmiscmember< >0.008sOk -1213lists_SUITEmiscdropwhile< >0.000sOk -1214lists_SUITEmisctakewhile< >0.000sOk -1215lists_SUITEmiscfilter_partition< >0.000sOk -1216lists_SUITEmiscsuffix< >0.025sOk -1217lists_SUITEmiscsubtract< >3.167sOk -1218lists_SUITEmiscjoin< >0.000sOk -1219lists_SUITEmischof< >0.000sOk -1220lists_SUITEmiscdroplast< >0.000sOk -1221lists_SUITEmiscsearch< >0.000sOk -1222lists_SUITEmiscenumerate< >0.000sOk -1223lists_SUITEmiscerror_info< >0.002sOk -lists_SUITEmiscend_per_group< >0.000sOk +lists_SUITEkeyinit_per_group< >0.000sOk +1151lists_SUITEkeykeymember< >0.015sOk +1152lists_SUITEkeykeysearch_keyfind< >0.016sOk +1153lists_SUITEkeykeystore< >0.000sOk +1154lists_SUITEkeykeytake< >0.000sOk +1155lists_SUITEkeykeyreplace< >0.000sOk +lists_SUITEkeyend_per_group< >0.000sOk +lists_SUITEsortinit_per_group< >0.000sOk +1156lists_SUITEsortmerge< >0.000sOk +1157lists_SUITEsortrmerge< >0.000sOk +1158lists_SUITEsortsort_1< >0.025sOk +1159lists_SUITEsortsort_rand< >0.007sOk +lists_SUITEsortend_per_group< >0.000sOk +lists_SUITEusortinit_per_group< >0.000sOk +1160lists_SUITEusortumerge< >0.000sOk +1161lists_SUITEusortrumerge< >0.000sOk +1162lists_SUITEusortusort_1< >0.021sOk +1163lists_SUITEusortusort_rand< >0.011sOk +lists_SUITEusortend_per_group< >0.000sOk +lists_SUITEkeysortinit_per_group< >0.000sOk +1164lists_SUITEkeysortkeymerge< >0.000sOk +1165lists_SUITEkeysortrkeymerge< >0.000sOk +1166lists_SUITEkeysortkeysort_1< >0.036sOk +1167lists_SUITEkeysortkeysort_rand< >0.010sOk +1168lists_SUITEkeysortkeysort_i< >0.000sOk +1169lists_SUITEkeysortkeysort_error< >0.000sOk +lists_SUITEkeysortend_per_group< >0.000sOk +lists_SUITEukeysortinit_per_group< >0.000sOk +1170lists_SUITEukeysortukeymerge< >0.000sOk +1171lists_SUITEukeysortrukeymerge< >0.000sOk +1172lists_SUITEukeysortukeysort_1< >0.029sOk +1173lists_SUITEukeysortukeysort_rand< >0.011sOk +1174lists_SUITEukeysortukeysort_i< >0.000sOk +1175lists_SUITEukeysortukeysort_error< >0.000sOk +lists_SUITEukeysortend_per_group< >0.000sOk +lists_SUITEuniqinit_per_group< >0.000sOk +1176lists_SUITEuniquniq_1< >0.000sOk +1177lists_SUITEuniquniq_2< >0.000sOk +lists_SUITEuniqend_per_group< >0.000sOk +lists_SUITEsublistinit_per_group< >0.000sOk +1178lists_SUITEsublistsublist_2< >0.000sOk +1179lists_SUITEsublistsublist_3< >0.000sOk +1180lists_SUITEsublistsublist_2_e< >0.000sOk +1181lists_SUITEsublistsublist_3_e< >0.000sOk +lists_SUITEsublistend_per_group< >0.000sOk +lists_SUITEflatteninit_per_group< >0.000sOk +1182lists_SUITEflattenflatten_1< >0.000sOk +1183lists_SUITEflattenflatten_2< >0.000sOk +1184lists_SUITEflattenflatten_1_e< >0.000sOk +1185lists_SUITEflattenflatten_2_e< >0.000sOk +lists_SUITEflattenend_per_group< >0.000sOk +lists_SUITEseqinit_per_group< >0.000sOk +1186lists_SUITEseqseq_loop< >0.000sOk +1187lists_SUITEseqseq_2< >0.000sOk +1188lists_SUITEseqseq_3< >0.000sOk +1189lists_SUITEseqseq_2_e< >0.000sOk +1190lists_SUITEseqseq_3_e< >0.000sOk +lists_SUITEseqend_per_group< >0.000sOk +lists_SUITEticketsinit_per_group< >0.000sOk +1191lists_SUITEticketsotp_5939< >0.000sOk +1192lists_SUITEticketsotp_6023< >0.000sOk +1193lists_SUITEticketsotp_6606< >0.000sOk +1194lists_SUITEticketsotp_7230< >0.004sOk +lists_SUITEticketsend_per_group< >0.000sOk +lists_SUITEzipinit_per_group< >0.000sOk +1195lists_SUITEzipzip_unzip< >0.000sOk +1196lists_SUITEzipzip_unzip3< >0.000sOk +1197lists_SUITEzipzipwith< >0.000sOk +1198lists_SUITEzipzipwith3< >0.000sOk +1199lists_SUITEzipzip_fail< >0.000sOk +1200lists_SUITEzipzip_trim< >0.000sOk +1201lists_SUITEzipzip_pad< >0.000sOk +1202lists_SUITEzipzip3_fail< >0.000sOk +1203lists_SUITEzipzip3_trim< >0.000sOk +1204lists_SUITEzipzip3_pad< >0.000sOk +1205lists_SUITEzipzipwith_fail< >0.000sOk +1206lists_SUITEzipzipwith_trim< >0.000sOk +1207lists_SUITEzipzipwith_pad< >0.000sOk +1208lists_SUITEzipzipwith3_fail< >0.000sOk +1209lists_SUITEzipzipwith3_trim< >0.000sOk +1210lists_SUITEzipzipwith3_pad< >0.000sOk +lists_SUITEzipend_per_group< >0.000sOk +lists_SUITEmiscinit_per_group< >0.000sOk +1211lists_SUITEmiscreverse< >0.013sOk +1212lists_SUITEmiscmember< >0.006sOk +1213lists_SUITEmiscdropwhile< >0.000sOk +1214lists_SUITEmisctakewhile< >0.000sOk +1215lists_SUITEmiscfilter_partition< >0.000sOk +1216lists_SUITEmiscsuffix< >0.029sOk +1217lists_SUITEmiscsubtract< >3.161sOk +1218lists_SUITEmiscjoin< >0.000sOk +1219lists_SUITEmischof< >0.000sOk +1220lists_SUITEmiscdroplast< >0.000sOk +1221lists_SUITEmiscsearch< >0.000sOk +1222lists_SUITEmiscenumerate< >0.000sOk +1223lists_SUITEmiscerror_info< >0.001sOk +lists_SUITEmiscend_per_group< >0.000sOk lists_SUITEend_per_suite< >0.000sOk -lists_property_test_SUITEinit_per_suite< >1.262sOk -1224lists_property_test_SUITEall_true_case< >0.071sOk -1225lists_property_test_SUITEall_false_case< >0.119sOk -1226lists_property_test_SUITEany_true_case< >0.117sOk -1227lists_property_test_SUITEany_false_case< >0.051sOk -1228lists_property_test_SUITEappend_1_case< >0.874sOk -1229lists_property_test_SUITEappend_2_case< >0.128sOk -1230lists_property_test_SUITEconcat_case< >0.027sOk -1231lists_property_test_SUITEdelete_case< >0.134sOk -1232lists_property_test_SUITEdelete_absent_case< >0.072sOk -1233lists_property_test_SUITEdroplast_case< >0.072sOk -1234lists_property_test_SUITEdropwhile_case< >0.154sOk +lists_property_test_SUITEinit_per_suite< >1.256sOk +1224lists_property_test_SUITEall_true_case< >0.066sOk +1225lists_property_test_SUITEall_false_case< >0.116sOk +1226lists_property_test_SUITEany_true_case< >0.127sOk +1227lists_property_test_SUITEany_false_case< >0.068sOk +1228lists_property_test_SUITEappend_1_case< >0.732sOk +1229lists_property_test_SUITEappend_2_case< >0.130sOk +1230lists_property_test_SUITEconcat_case< >0.023sOk +1231lists_property_test_SUITEdelete_case< >0.116sOk +1232lists_property_test_SUITEdelete_absent_case< >0.058sOk +1233lists_property_test_SUITEdroplast_case< >0.057sOk +1234lists_property_test_SUITEdropwhile_case< >0.156sOk 1235lists_property_test_SUITEduplicate_case< >0.011sOk -1236lists_property_test_SUITEenumerate_1_case< >0.143sOk -1237lists_property_test_SUITEenumerate_2_case< >0.149sOk -1238lists_property_test_SUITEenumerate_3_case< >0.148sOk -1239lists_property_test_SUITEfilter_case< >0.156sOk +1236lists_property_test_SUITEenumerate_1_case< >0.150sOk +1237lists_property_test_SUITEenumerate_2_case< >0.151sOk +1238lists_property_test_SUITEenumerate_3_case< >0.152sOk +1239lists_property_test_SUITEfilter_case< >0.143sOk 1240lists_property_test_SUITEfiltermap_case< >0.227sOk -1241lists_property_test_SUITEflatlength_case< >0.068sOk -1242lists_property_test_SUITEflatmap_case< >3.413sOk -1243lists_property_test_SUITEflatten_1_case< >0.072sOk -1244lists_property_test_SUITEflatten_2_case< >0.133sOk -1245lists_property_test_SUITEfoldl_case< >0.361sOk -1246lists_property_test_SUITEfoldr_case< >0.369sOk -1247lists_property_test_SUITEforeach_case< >0.067sOk -1248lists_property_test_SUITEjoin_case< >0.066sOk -1249lists_property_test_SUITEkeydelete_case< >0.154sOk -1250lists_property_test_SUITEkeydelete_absent_case< >0.064sOk -1251lists_property_test_SUITEkeyfind_case< >0.156sOk -1252lists_property_test_SUITEkeyfind_absent_case< >0.061sOk -1253lists_property_test_SUITEkeymap_case< >0.902sOk -1254lists_property_test_SUITEkeymember_case< >0.133sOk -1255lists_property_test_SUITEkeymember_absent_case< >0.061sOk -1256lists_property_test_SUITEkeymerge_case< >0.536sOk -1257lists_property_test_SUITEkeymerge_invalid_case< >0.276sOk -1258lists_property_test_SUITEkeyreplace_case< >0.201sOk -1259lists_property_test_SUITEkeyreplace_absent_case< >0.123sOk -1260lists_property_test_SUITEkeysearch_case< >0.151sOk -1261lists_property_test_SUITEkeysearch_absent_case< >0.062sOk -1262lists_property_test_SUITEkeysort_case< >0.234sOk -1263lists_property_test_SUITEkeystore_case< >0.180sOk -1264lists_property_test_SUITEkeystore_absent_case< >0.121sOk -1265lists_property_test_SUITEkeytake_case< >0.162sOk -1266lists_property_test_SUITEkeytake_absent_case< >0.061sOk -1267lists_property_test_SUITElast_case< >0.066sOk -1268lists_property_test_SUITEmap_case< >0.363sOk +1241lists_property_test_SUITEflatlength_case< >0.046sOk +1242lists_property_test_SUITEflatmap_case< >3.385sOk +1243lists_property_test_SUITEflatten_1_case< >0.056sOk +1244lists_property_test_SUITEflatten_2_case< >0.096sOk +1245lists_property_test_SUITEfoldl_case< >0.353sOk +1246lists_property_test_SUITEfoldr_case< >0.362sOk +1247lists_property_test_SUITEforeach_case< >0.077sOk +1248lists_property_test_SUITEjoin_case< >0.063sOk +1249lists_property_test_SUITEkeydelete_case< >0.148sOk +1250lists_property_test_SUITEkeydelete_absent_case< >0.060sOk +1251lists_property_test_SUITEkeyfind_case< >0.146sOk +1252lists_property_test_SUITEkeyfind_absent_case< >0.058sOk +1253lists_property_test_SUITEkeymap_case< >0.842sOk +1254lists_property_test_SUITEkeymember_case< >0.142sOk +1255lists_property_test_SUITEkeymember_absent_case< >0.057sOk +1256lists_property_test_SUITEkeymerge_case< >0.502sOk +1257lists_property_test_SUITEkeymerge_invalid_case< >0.315sOk +1258lists_property_test_SUITEkeyreplace_case< >0.181sOk +1259lists_property_test_SUITEkeyreplace_absent_case< >0.125sOk +1260lists_property_test_SUITEkeysearch_case< >0.153sOk +1261lists_property_test_SUITEkeysearch_absent_case< >0.067sOk +1262lists_property_test_SUITEkeysort_case< >0.254sOk +1263lists_property_test_SUITEkeystore_case< >0.211sOk +1264lists_property_test_SUITEkeystore_absent_case< >0.117sOk +1265lists_property_test_SUITEkeytake_case< >0.141sOk +1266lists_property_test_SUITEkeytake_absent_case< >0.063sOk +1267lists_property_test_SUITElast_case< >0.054sOk +1268lists_property_test_SUITEmap_case< >0.360sOk 1269lists_property_test_SUITEmapfoldl_case< >0.590sOk -1270lists_property_test_SUITEmapfoldr_case< >0.580sOk -1271lists_property_test_SUITEmax_case< >0.133sOk -1272lists_property_test_SUITEmember_case< >0.118sOk -1273lists_property_test_SUITEmember_absent_case< >0.058sOk -1274lists_property_test_SUITEmerge_1_case< >0.779sOk -1275lists_property_test_SUITEmerge_1_invalid_case< >0.912sOk -1276lists_property_test_SUITEmerge_2_case< >0.125sOk -1277lists_property_test_SUITEmerge_2_invalid_case< >0.077sOk -1278lists_property_test_SUITEmerge_3_case< >0.125sOk -1279lists_property_test_SUITEmerge_3_invalid_case< >0.069sOk -1280lists_property_test_SUITEmerge3_case< >0.193sOk -1281lists_property_test_SUITEmerge3_invalid_case< >0.079sOk -1282lists_property_test_SUITEmin_case< >0.140sOk -1283lists_property_test_SUITEnth_case< >0.121sOk -1284lists_property_test_SUITEnth_outofrange_case< >0.059sOk -1285lists_property_test_SUITEnthtail_case< >0.131sOk -1286lists_property_test_SUITEnthtail_outofrange_case< >0.063sOk -1287lists_property_test_SUITEpartition_case< >0.062sOk -1288lists_property_test_SUITEprefix_case< >0.122sOk -1289lists_property_test_SUITEreverse_1_case< >0.064sOk -1290lists_property_test_SUITEreverse_2_case< >0.110sOk +1270lists_property_test_SUITEmapfoldr_case< >0.609sOk +1271lists_property_test_SUITEmax_case< >0.135sOk +1272lists_property_test_SUITEmember_case< >0.135sOk +1273lists_property_test_SUITEmember_absent_case< >0.059sOk +1274lists_property_test_SUITEmerge_1_case< >0.845sOk +1275lists_property_test_SUITEmerge_1_invalid_case< >0.919sOk +1276lists_property_test_SUITEmerge_2_case< >0.128sOk +1277lists_property_test_SUITEmerge_2_invalid_case< >0.068sOk +1278lists_property_test_SUITEmerge_3_case< >0.143sOk +1279lists_property_test_SUITEmerge_3_invalid_case< >0.074sOk +1280lists_property_test_SUITEmerge3_case< >0.176sOk +1281lists_property_test_SUITEmerge3_invalid_case< >0.078sOk +1282lists_property_test_SUITEmin_case< >0.136sOk +1283lists_property_test_SUITEnth_case< >0.123sOk +1284lists_property_test_SUITEnth_outofrange_case< >0.056sOk +1285lists_property_test_SUITEnthtail_case< >0.117sOk +1286lists_property_test_SUITEnthtail_outofrange_case< >0.057sOk +1287lists_property_test_SUITEpartition_case< >0.063sOk +1288lists_property_test_SUITEprefix_case< >0.119sOk +1289lists_property_test_SUITEreverse_1_case< >0.061sOk +1290lists_property_test_SUITEreverse_2_case< >0.121sOk 1291lists_property_test_SUITEsearch_case< >0.124sOk -1292lists_property_test_SUITEsearch_absent_case< >0.054sOk +1292lists_property_test_SUITEsearch_absent_case< >0.053sOk 1293lists_property_test_SUITEseq2_case< >0.001sOk 1294lists_property_test_SUITEseq3_case< >0.001sOk -1295lists_property_test_SUITEsort_1_case< >0.072sOk -1296lists_property_test_SUITEsort_2_case< >0.065sOk -1297lists_property_test_SUITEsplit_case< >0.129sOk -1298lists_property_test_SUITEsplit_outofrange_case< >0.062sOk -1299lists_property_test_SUITEsplitwith_case< >0.067sOk -1300lists_property_test_SUITEsublist_2_case< >0.141sOk -1301lists_property_test_SUITEsublist_3_case< >0.187sOk -1302lists_property_test_SUITEsubtract_case< >0.183sOk -1303lists_property_test_SUITEsuffix_case< >0.114sOk +1295lists_property_test_SUITEsort_1_case< >0.070sOk +1296lists_property_test_SUITEsort_2_case< >0.069sOk +1297lists_property_test_SUITEsplit_case< >0.126sOk +1298lists_property_test_SUITEsplit_outofrange_case< >0.056sOk +1299lists_property_test_SUITEsplitwith_case< >0.075sOk +1300lists_property_test_SUITEsublist_2_case< >0.125sOk +1301lists_property_test_SUITEsublist_3_case< >0.171sOk +1302lists_property_test_SUITEsubtract_case< >0.188sOk +1303lists_property_test_SUITEsuffix_case< >0.120sOk 1304lists_property_test_SUITEsum_case< >0.004sOk -1305lists_property_test_SUITEtakewhile_case< >0.129sOk -1306lists_property_test_SUITEukeymerge_case< >0.519sOk -1307lists_property_test_SUITEukeymerge_invalid_case< >0.289sOk -1308lists_property_test_SUITEukeysort_case< >0.265sOk -1309lists_property_test_SUITEumerge_1_case< >0.885sOk -1310lists_property_test_SUITEumerge_1_invalid_case< >1.004sOk -1311lists_property_test_SUITEumerge_2_case< >0.116sOk -1312lists_property_test_SUITEumerge_2_invalid_case< >0.068sOk -1313lists_property_test_SUITEumerge_3_case< >0.126sOk -1314lists_property_test_SUITEumerge_3_invalid_case< >0.060sOk -1315lists_property_test_SUITEumerge3_case< >0.167sOk -1316lists_property_test_SUITEumerge3_invalid_case< >0.076sOk -1317lists_property_test_SUITEuniq_1_case< >0.136sOk +1305lists_property_test_SUITEtakewhile_case< >0.134sOk +1306lists_property_test_SUITEukeymerge_case< >0.601sOk +1307lists_property_test_SUITEukeymerge_invalid_case< >0.283sOk +1308lists_property_test_SUITEukeysort_case< >0.254sOk +1309lists_property_test_SUITEumerge_1_case< >0.931sOk +1310lists_property_test_SUITEumerge_1_invalid_case< >0.803sOk +1311lists_property_test_SUITEumerge_2_case< >0.127sOk +1312lists_property_test_SUITEumerge_2_invalid_case< >0.069sOk +1313lists_property_test_SUITEumerge_3_case< >0.143sOk +1314lists_property_test_SUITEumerge_3_invalid_case< >0.073sOk +1315lists_property_test_SUITEumerge3_case< >0.220sOk +1316lists_property_test_SUITEumerge3_invalid_case< >0.073sOk +1317lists_property_test_SUITEuniq_1_case< >0.133sOk 1318lists_property_test_SUITEuniq_2_case< >0.061sOk -1319lists_property_test_SUITEunzip_case< >0.281sOk -1320lists_property_test_SUITEunzip3_case< >0.413sOk -1321lists_property_test_SUITEusort_1_case< >0.062sOk -1322lists_property_test_SUITEusort_2_case< >0.069sOk -1323lists_property_test_SUITEzip_2_case< >0.296sOk -1324lists_property_test_SUITEzip_3_case< >0.340sOk -1325lists_property_test_SUITEzip3_3_case< >0.410sOk -1326lists_property_test_SUITEzip3_4_case< >0.473sOk -1327lists_property_test_SUITEzipwith_3_case< >0.509sOk -1328lists_property_test_SUITEzipwith_4_case< >1.522sOk -1329lists_property_test_SUITEzipwith3_4_case< >0.643sOk -1330lists_property_test_SUITEzipwith3_5_case< >3.357sOk +1319lists_property_test_SUITEunzip_case< >0.286sOk +1320lists_property_test_SUITEunzip3_case< >0.437sOk +1321lists_property_test_SUITEusort_1_case< >0.067sOk +1322lists_property_test_SUITEusort_2_case< >0.075sOk +1323lists_property_test_SUITEzip_2_case< >0.272sOk +1324lists_property_test_SUITEzip_3_case< >0.350sOk +1325lists_property_test_SUITEzip3_3_case< >0.428sOk +1326lists_property_test_SUITEzip3_4_case< >0.490sOk +1327lists_property_test_SUITEzipwith_3_case< >0.526sOk +1328lists_property_test_SUITEzipwith_4_case< >1.676sOk +1329lists_property_test_SUITEzipwith3_4_case< >0.671sOk +1330lists_property_test_SUITEzipwith3_5_case< >3.420sOk lists_property_test_SUITEend_per_suite< >0.000sOk log_mf_h_SUITEinit_per_suite< >0.000sOk 1331log_mf_h_SUITEtest< >0.006sOk log_mf_h_SUITEend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk +common_testinit_per_suite< >0.000sOk 1332maps_SUITEt_update_with_3< >0.000sOk 1333maps_SUITEt_update_with_4< >0.000sOk 1334maps_SUITEt_get_3< >0.000sOk @@ -1680,7 +1680,7 @@

    Test started at 2024-09-11 11:10:55

    1339maps_SUITEt_size_1< >0.000sOk 1340maps_SUITEt_foreach_2< >0.000sOk 1341maps_SUITEt_iterator_1< >0.015sOk -1342maps_SUITEt_iterator_2< >0.064sOk +1342maps_SUITEt_iterator_2< >0.063sOk 1343maps_SUITEt_iterator_valid< >0.000sOk 1344maps_SUITEt_put_opt< >0.000sOk 1345maps_SUITEt_merge_opt< >0.000sOk @@ -1691,16 +1691,16 @@

    Test started at 2024-09-11 11:10:55

    1350maps_SUITEt_merge_with< >0.030sOk 1351maps_SUITEt_from_keys< >0.000sOk 1352maps_SUITEerror_info< >0.006sOk -1353maps_SUITEt_from_list_kill_process< >0.001sOk +1353maps_SUITEt_from_list_kill_process< >0.002sOk 1354maps_SUITEt_from_keys_kill_process< >0.001sOk -1355maps_SUITEt_values_kill_process< >0.158sOk -1356maps_SUITEt_keys_kill_process< >0.116sOk -1357maps_SUITEt_from_list_check_trapping< >0.087sOk -1358maps_SUITEt_from_keys_check_trapping< >1.320sOk -1359maps_SUITEt_keys_trapping< >1.524sOk -1360maps_SUITEt_values_trapping< >1.516sOk +1355maps_SUITEt_values_kill_process< >0.165sOk +1356maps_SUITEt_keys_kill_process< >0.117sOk +1357maps_SUITEt_from_list_check_trapping< >0.090sOk +1358maps_SUITEt_from_keys_check_trapping< >1.327sOk +1359maps_SUITEt_keys_trapping< >1.546sOk +1360maps_SUITEt_values_trapping< >1.596sOk 1361maps_SUITEt_groups_from_list< >0.000sOk -common_testend_per_suite< >0.000sOk +common_testend_per_suite< >0.000sOk math_SUITEinit_per_suite< >0.000sOk 1362math_SUITEfloor_ceil< >0.000sOk 1363math_SUITEerror_info< >0.003sOk @@ -1709,27 +1709,27 @@

    Test started at 2024-09-11 11:10:55

    ms_transform_SUITEinit_per_suite< >0.000sOk 1365ms_transform_SUITEfrom_shell< >0.000sOk 1366ms_transform_SUITEbasic_ets< >0.023sOk -1367ms_transform_SUITEbasic_dbg< >0.038sOk -1368ms_transform_SUITErecords< >0.017sOk -1369ms_transform_SUITErecord_index< >0.017sOk +1367ms_transform_SUITEbasic_dbg< >0.039sOk +1368ms_transform_SUITErecords< >0.019sOk +1369ms_transform_SUITErecord_index< >0.018sOk 1370ms_transform_SUITEmultipass< >0.037sOk -1371ms_transform_SUITEbitsyntax< >0.013sOk -1372ms_transform_SUITEbinary_bifs< >0.017sOk +1371ms_transform_SUITEbitsyntax< >0.015sOk +1372ms_transform_SUITEbinary_bifs< >0.018sOk 1373ms_transform_SUITErecord_defaults< >0.004sOk -1374ms_transform_SUITEandalso_orelse< >0.025sOk -1375ms_transform_SUITEfloat_1_function< >0.053sOk -1376ms_transform_SUITEaction_function< >0.025sOk +1374ms_transform_SUITEandalso_orelse< >0.026sOk +1375ms_transform_SUITEfloat_1_function< >0.052sOk +1376ms_transform_SUITEaction_function< >0.024sOk 1377ms_transform_SUITEwarnings< >0.013sOk 1378ms_transform_SUITEno_warnings< >0.003sOk -1379ms_transform_SUITEtop_match< >0.029sOk -1380ms_transform_SUITEold_guards< >0.087sOk -1381ms_transform_SUITEautoimported< >0.699sOk -1382ms_transform_SUITEsemicolon< >0.026sOk +1379ms_transform_SUITEtop_match< >0.030sOk +1380ms_transform_SUITEold_guards< >0.086sOk +1381ms_transform_SUITEautoimported< >0.698sOk +1382ms_transform_SUITEsemicolon< >0.025sOk 1383ms_transform_SUITEeep37< >0.004sOk -1384ms_transform_SUITEotp_14454< >0.011sOk +1384ms_transform_SUITEotp_14454< >0.013sOk 1385ms_transform_SUITEotp_16824< >0.001sOk -1386ms_transform_SUITEunused_record< >0.001sOk -1387ms_transform_SUITEmap_pattern< >0.004sOk +1386ms_transform_SUITEunused_record< >0.002sOk +1387ms_transform_SUITEmap_pattern< >0.005sOk 1388ms_transform_SUITEmap_expr_in_head< >0.005sOk 1389ms_transform_SUITEmap_pattern_from_shell< >0.000sOk 1390ms_transform_SUITEmap_expr_in_head_from_shell< >0.000sOk @@ -1738,99 +1738,99 @@

    Test started at 2024-09-11 11:10:55

    ms_transform_SUITEend_per_suite< >0.000sOk peer_SUITEinit_per_suite< >0.000sOk peer_SUITEdistinit_per_group< >0.000sOk -1393peer_SUITEdisterrors< >0.000sOk -1394peer_SUITEdistdist< >14.288sOk -1395peer_SUITEdistpeer_down_crash< >1.232sOk -1396peer_SUITEdistpeer_down_continue< >14.290sOk -1397peer_SUITEdistpeer_down_boot< >0.044sOk -1398peer_SUITEdistdist_up_down< >1.237sOk -1399peer_SUITEdistdist_localhost< >1.368sOk -1400peer_SUITEdistpost_process_args< >1.209sOk -1401peer_SUITEdistattached< >1.191sOk -1402peer_SUITEdistattached_cntrl_channel_handler_crash< >2.274sOk -1403peer_SUITEdistcntrl_channel_handler_crash< >1.023sOk -1404peer_SUITEdistcntrl_channel_handler_crash_old_release< >14.498sOk -1405peer_SUITEdistshutdown_halt< >2.111sOk -1406peer_SUITEdistshutdown_halt_timeout< >2.760sOk -1407peer_SUITEdistshutdown_stop< >3.104sOk -1408peer_SUITEdistshutdown_stop_timeout< >2.636sOk -1409peer_SUITEdistshutdown_close< >1.683sOk +1393peer_SUITEdisterrors< >0.000sOk +1394peer_SUITEdistdist< >14.098sOk +1395peer_SUITEdistpeer_down_crash< >1.175sOk +1396peer_SUITEdistpeer_down_continue< >14.100sOk +1397peer_SUITEdistpeer_down_boot< >0.024sOk +1398peer_SUITEdistdist_up_down< >1.203sOk +1399peer_SUITEdistdist_localhost< >1.409sOk +1400peer_SUITEdistpost_process_args< >1.098sOk +1401peer_SUITEdistattached< >1.207sOk +1402peer_SUITEdistattached_cntrl_channel_handler_crash< >2.275sOk +1403peer_SUITEdistcntrl_channel_handler_crash< >1.233sOk +1404peer_SUITEdistcntrl_channel_handler_crash_old_release< >14.290sOk +1405peer_SUITEdistshutdown_halt< >2.244sOk +1406peer_SUITEdistshutdown_halt_timeout< >2.689sOk +1407peer_SUITEdistshutdown_stop< >3.166sOk +1408peer_SUITEdistshutdown_stop_timeout< >2.688sOk +1409peer_SUITEdistshutdown_close< >1.588sOk peer_SUITEdistend_per_group< >0.000sOk -peer_SUITEdist_seqinit_per_group< >0.000sOk -1410peer_SUITEdist_seqdist_io_redirect< >0.658sOk -1411peer_SUITEdist_seqpeer_down_crash_tcp< >0.159sOk -peer_SUITEdist_seqend_per_group< >0.000sOk -peer_SUITEtcpinit_per_group< >0.000sOk -1412peer_SUITEtcpbasic< >1.740sOk -1413peer_SUITEtcppeer_states< >2.449sOk -1414peer_SUITEtcpcast< >1.631sOk -1415peer_SUITEtcpdetached< >1.641sOk -1416peer_SUITEtcpdyn_peer< >1.615sOk -1417peer_SUITEtcpstop_peer< >1.740sOk -1418peer_SUITEtcpio_redirect< >1.658sOk -1419peer_SUITEtcpmulti_node< >1.766sOk -1420peer_SUITEtcpduplicate_name< >1.885sOk -1421peer_SUITEtcpattached< >1.779sOk -1422peer_SUITEtcpattached_cntrl_channel_handler_crash< >2.499sOk -1423peer_SUITEtcpcntrl_channel_handler_crash< >1.721sOk -1424peer_SUITEtcpcntrl_channel_handler_crash_old_release< >2.338sOk -1425peer_SUITEtcpshutdown_halt< >2.695sOk -1426peer_SUITEtcpshutdown_halt_timeout< >3.246sOk -1427peer_SUITEtcpshutdown_stop< >3.689sOk -1428peer_SUITEtcpshutdown_stop_timeout< >3.082sOk -1429peer_SUITEtcpshutdown_close< >2.198sOk -peer_SUITEtcpend_per_group< >0.000sOk -peer_SUITEstandard_ioinit_per_group< >0.000sOk -1430peer_SUITEstandard_ioinit_debug< >2.743sOk -1431peer_SUITEstandard_iobasic< >1.398sOk -1432peer_SUITEstandard_iopeer_states< >1.938sOk -1433peer_SUITEstandard_iocast< >1.513sOk -1434peer_SUITEstandard_iodetached< >1.349sOk -1435peer_SUITEstandard_iodyn_peer< >1.229sOk -1436peer_SUITEstandard_iostop_peer< >1.479sOk -1437peer_SUITEstandard_ioio_redirect< >1.323sOk -1438peer_SUITEstandard_iomulti_node< >1.494sOk -1439peer_SUITEstandard_ioduplicate_name< >1.639sOk -1440peer_SUITEstandard_ioattached< >0.000sOk -1441peer_SUITEstandard_ioattached_cntrl_channel_handler_crash< >0.001sOk -1442peer_SUITEstandard_iocntrl_channel_handler_crash< >1.466sOk -1443peer_SUITEstandard_iocntrl_channel_handler_crash_old_release< >2.074sOk -1444peer_SUITEstandard_ioshutdown_halt< >2.406sOk -1445peer_SUITEstandard_ioshutdown_halt_timeout< >2.891sOk -1446peer_SUITEstandard_ioshutdown_stop< >3.482sOk -1447peer_SUITEstandard_ioshutdown_stop_timeout< >2.824sOk -1448peer_SUITEstandard_ioshutdown_close< >2.007sOk -peer_SUITEstandard_ioend_per_group< >0.000sOk -peer_SUITEcompatibilityinit_per_group< >0.000sOk -1449peer_SUITEcompatibilityold_release< >13.518sOk -peer_SUITEcompatibilityend_per_group< >0.000sOk -peer_SUITEremoteinit_per_group< >0.023sSKIPPED'ssh localhost echo ok' did not return ok +peer_SUITEdist_seqinit_per_group< >0.000sOk +1410peer_SUITEdist_seqdist_io_redirect< >0.663sOk +1411peer_SUITEdist_seqpeer_down_crash_tcp< >0.148sOk +peer_SUITEdist_seqend_per_group< >0.000sOk +peer_SUITEtcpinit_per_group< >0.000sOk +1412peer_SUITEtcpbasic< >1.330sOk +1413peer_SUITEtcppeer_states< >2.549sOk +1414peer_SUITEtcpcast< >1.546sOk +1415peer_SUITEtcpdetached< >1.337sOk +1416peer_SUITEtcpdyn_peer< >1.717sOk +1417peer_SUITEtcpstop_peer< >1.637sOk +1418peer_SUITEtcpio_redirect< >1.400sOk +1419peer_SUITEtcpmulti_node< >1.681sOk +1420peer_SUITEtcpduplicate_name< >1.921sOk +1421peer_SUITEtcpattached< >1.576sOk +1422peer_SUITEtcpattached_cntrl_channel_handler_crash< >2.771sOk +1423peer_SUITEtcpcntrl_channel_handler_crash< >1.753sOk +1424peer_SUITEtcpcntrl_channel_handler_crash_old_release< >2.332sOk +1425peer_SUITEtcpshutdown_halt< >2.745sOk +1426peer_SUITEtcpshutdown_halt_timeout< >3.106sOk +1427peer_SUITEtcpshutdown_stop< >3.741sOk +1428peer_SUITEtcpshutdown_stop_timeout< >3.061sOk +1429peer_SUITEtcpshutdown_close< >2.078sOk +peer_SUITEtcpend_per_group< >0.000sOk +peer_SUITEstandard_ioinit_per_group< >0.000sOk +1430peer_SUITEstandard_ioinit_debug< >2.699sOk +1431peer_SUITEstandard_iobasic< >1.219sOk +1432peer_SUITEstandard_iopeer_states< >2.213sOk +1433peer_SUITEstandard_iocast< >1.329sOk +1434peer_SUITEstandard_iodetached< >1.546sOk +1435peer_SUITEstandard_iodyn_peer< >1.471sOk +1436peer_SUITEstandard_iostop_peer< >1.416sOk +1437peer_SUITEstandard_ioio_redirect< >1.530sOk +1438peer_SUITEstandard_iomulti_node< >1.449sOk +1439peer_SUITEstandard_ioduplicate_name< >1.672sOk +1440peer_SUITEstandard_ioattached< >0.003sOk +1441peer_SUITEstandard_ioattached_cntrl_channel_handler_crash< >0.000sOk +1442peer_SUITEstandard_iocntrl_channel_handler_crash< >1.527sOk +1443peer_SUITEstandard_iocntrl_channel_handler_crash_old_release< >2.123sOk +1444peer_SUITEstandard_ioshutdown_halt< >2.581sOk +1445peer_SUITEstandard_ioshutdown_halt_timeout< >3.035sOk +1446peer_SUITEstandard_ioshutdown_stop< >3.516sOk +1447peer_SUITEstandard_ioshutdown_stop_timeout< >2.934sOk +1448peer_SUITEstandard_ioshutdown_close< >1.531sOk +peer_SUITEstandard_ioend_per_group< >0.000sOk +peer_SUITEcompatibilityinit_per_group< >0.000sOk +1449peer_SUITEcompatibilityold_release< >13.534sOk +peer_SUITEcompatibilityend_per_group< >0.000sOk +peer_SUITEremoteinit_per_group< >0.023sSKIPPED'ssh localhost echo ok' did not return ok 1450peer_SUITEremotessh< >0.000sSKIPPED'ssh localhost echo ok' did not return ok peer_SUITEremoteend_per_group< >0.000sSKIPPED'ssh localhost echo ok' did not return ok peer_SUITEend_per_suite< >0.000sOk pool_SUITEinit_per_suite< >0.000sOk -1451pool_SUITEbasic< >0.167sOk -1452pool_SUITElink_race< >0.316sOk +1451pool_SUITEbasic< >0.162sOk +1452pool_SUITElink_race< >0.345sOk pool_SUITEend_per_suite< >0.000sOk proc_lib_SUITEinit_per_suite< >0.000sOk 1453proc_lib_SUITEcrash< >0.209sOk 1454proc_lib_SUITEstacktrace< >0.001sOk proc_lib_SUITEsync_startinit_per_group< >0.000sOk -1455proc_lib_SUITEsync_startsync_start_nolink< >1.000sOk +1455proc_lib_SUITEsync_startsync_start_nolink< >1.001sOk 1456proc_lib_SUITEsync_startsync_start_link< >1.001sOk 1457proc_lib_SUITEsync_startsync_start_monitor< >2.002sOk -1458proc_lib_SUITEsync_startsync_start_monitor_link< >1.001sOk +1458proc_lib_SUITEsync_startsync_start_monitor_link< >1.000sOk 1459proc_lib_SUITEsync_startsync_start_timeout< >1.002sOk 1460proc_lib_SUITEsync_startsync_start_link_timeout< >1.002sOk 1461proc_lib_SUITEsync_startsync_start_monitor_link_timeout< >1.002sOk proc_lib_SUITEsync_startend_per_group< >0.000sOk 1462proc_lib_SUITEspawn_opt< >0.101sOk 1463proc_lib_SUITEhibernate< >0.001sOk -proc_lib_SUITEticketsinit_per_group< >0.000sOk +proc_lib_SUITEticketsinit_per_group< >0.000sOk 1464proc_lib_SUITEticketsotp_6345< >0.000sOk 1465proc_lib_SUITEticketsinit_dont_hang< >0.001sOk -proc_lib_SUITEticketsend_per_group< >0.000sOk -1466proc_lib_SUITEstop< >6.158sOk +proc_lib_SUITEticketsend_per_group< >0.000sOk +1466proc_lib_SUITEstop< >6.166sOk 1467proc_lib_SUITEt_format< >0.004sOk 1468proc_lib_SUITEt_format_arbitrary< >0.001sOk 1469proc_lib_SUITEreport_cb< >0.103sOk @@ -1843,82 +1843,82 @@

    Test started at 2024-09-11 11:10:55

    proplists_SUITEend_per_suite< >0.000sOk qlc_SUITEinit_per_suite< >0.000sOk qlc_SUITEparse_transforminit_per_group< >0.000sOk -1474qlc_SUITEparse_transformbadarg< >0.005sOk -1475qlc_SUITEparse_transformnested_qlc< >0.095sOk +1474qlc_SUITEparse_transformbadarg< >0.004sOk +1475qlc_SUITEparse_transformnested_qlc< >0.093sOk 1476qlc_SUITEparse_transformunused_var< >0.026sOk 1477qlc_SUITEparse_transformlc< >0.005sOk -1478qlc_SUITEparse_transformfun_clauses< >0.011sOk +1478qlc_SUITEparse_transformfun_clauses< >0.010sOk 1479qlc_SUITEparse_transformfilter_var< >0.021sOk -1480qlc_SUITEparse_transformsingle< >0.034sOk -1481qlc_SUITEparse_transformexported_var< >0.007sOk +1480qlc_SUITEparse_transformsingle< >0.033sOk +1481qlc_SUITEparse_transformexported_var< >0.006sOk 1482qlc_SUITEparse_transformgenerator_vars< >0.005sOk -1483qlc_SUITEparse_transformnomatch< >0.121sOk -1484qlc_SUITEparse_transformerrors< >0.001sOk -1485qlc_SUITEparse_transformpattern< >0.089sOk -1486qlc_SUITEparse_transformoverridden_bif< >0.076sOk +1483qlc_SUITEparse_transformnomatch< >0.127sOk +1484qlc_SUITEparse_transformerrors< >0.002sOk +1485qlc_SUITEparse_transformpattern< >0.092sOk +1486qlc_SUITEparse_transformoverridden_bif< >0.078sOk qlc_SUITEparse_transformend_per_group< >0.000sOk -qlc_SUITEevaluationinit_per_group< >0.000sOk -1487qlc_SUITEevaluationeval< >0.776sOk -1488qlc_SUITEevaluationcursor< >0.497sOk -1489qlc_SUITEevaluationfold< >0.526sOk -1490qlc_SUITEevaluationeval_unique< >0.595sOk -1491qlc_SUITEevaluationeval_cache< >0.563sOk -1492qlc_SUITEevaluationappend< >0.637sOk -1493qlc_SUITEevaluationevaluator< >0.208sOk +qlc_SUITEevaluationinit_per_group< >0.000sOk +1487qlc_SUITEevaluationeval< >0.775sOk +1488qlc_SUITEevaluationcursor< >0.501sOk +1489qlc_SUITEevaluationfold< >0.532sOk +1490qlc_SUITEevaluationeval_unique< >0.616sOk +1491qlc_SUITEevaluationeval_cache< >0.583sOk +1492qlc_SUITEevaluationappend< >0.663sOk +1493qlc_SUITEevaluationevaluator< >0.201sOk 1494qlc_SUITEevaluationstring_to_handle< >0.030sOk -1495qlc_SUITEevaluationtable< >1.094sOk -1496qlc_SUITEevaluationprocess_dies< >0.471sOk -1497qlc_SUITEevaluationsort< >0.555sOk -1498qlc_SUITEevaluationkeysort< >0.748sOk -1499qlc_SUITEevaluationfilesort< >0.045sOk -1500qlc_SUITEevaluationcache< >0.955sOk -1501qlc_SUITEevaluationcache_list< >3.691sOk -1502qlc_SUITEevaluationfilter< >0.888sOk -1503qlc_SUITEevaluationinfo< >1.339sOk -1504qlc_SUITEevaluationnested_info< >0.516sOk -1505qlc_SUITEevaluationlookup1< >1.347sOk -1506qlc_SUITEevaluationlookup2< >4.043sOk -1507qlc_SUITEevaluationlookup_rec< >0.389sOk -1508qlc_SUITEevaluationindices< >0.390sOk -1509qlc_SUITEevaluationpre_fun< >0.324sOk -1510qlc_SUITEevaluationskip_filters< >2.237sOk +1495qlc_SUITEevaluationtable< >1.115sOk +1496qlc_SUITEevaluationprocess_dies< >0.473sOk +1497qlc_SUITEevaluationsort< >0.572sOk +1498qlc_SUITEevaluationkeysort< >0.753sOk +1499qlc_SUITEevaluationfilesort< >0.044sOk +1500qlc_SUITEevaluationcache< >0.971sOk +1501qlc_SUITEevaluationcache_list< >3.678sOk +1502qlc_SUITEevaluationfilter< >0.908sOk +1503qlc_SUITEevaluationinfo< >1.382sOk +1504qlc_SUITEevaluationnested_info< >0.528sOk +1505qlc_SUITEevaluationlookup1< >1.339sOk +1506qlc_SUITEevaluationlookup2< >4.140sOk +1507qlc_SUITEevaluationlookup_rec< >0.392sOk +1508qlc_SUITEevaluationindices< >0.389sOk +1509qlc_SUITEevaluationpre_fun< >0.322sOk +1510qlc_SUITEevaluationskip_filters< >2.276sOk 1511qlc_SUITEevaluationeep37< >0.021sOk -qlc_SUITEevaluationend_per_group< >0.000sOk -qlc_SUITEtable_implsinit_per_group< >0.000sOk -1512qlc_SUITEtable_implsets< >0.376sOk -1513qlc_SUITEtable_implsdets< >0.598sOk -qlc_SUITEtable_implsend_per_group< >0.000sOk -qlc_SUITEjoininit_per_group< >0.000sOk -1514qlc_SUITEjoinjoin_option< >1.138sOk +qlc_SUITEevaluationend_per_group< >0.000sOk +qlc_SUITEtable_implsinit_per_group< >0.000sOk +1512qlc_SUITEtable_implsets< >0.378sOk +1513qlc_SUITEtable_implsdets< >0.599sOk +qlc_SUITEtable_implsend_per_group< >0.000sOk +qlc_SUITEjoininit_per_group< >0.000sOk +1514qlc_SUITEjoinjoin_option< >1.154sOk 1515qlc_SUITEjoinjoin_filter< >0.298sOk -1516qlc_SUITEjoinjoin_lookup< >0.637sOk -1517qlc_SUITEjoinjoin_merge< >4.850sOk -1518qlc_SUITEjoinjoin_sort< >2.682sOk -1519qlc_SUITEjoinjoin_complex< >0.305sOk -qlc_SUITEjoinend_per_group< >0.000sOk -qlc_SUITEticketsinit_per_group< >0.000sOk -1520qlc_SUITEticketsotp_5644< >0.029sOk -1521qlc_SUITEticketsotp_5195< >0.472sOk -1522qlc_SUITEticketsotp_6038_bug< >0.321sOk -1523qlc_SUITEticketsotp_6359< >0.041sOk -1524qlc_SUITEticketsotp_6562< >0.310sOk -1525qlc_SUITEticketsotp_6590< >0.069sOk -1526qlc_SUITEticketsotp_6673< >0.412sOk -1527qlc_SUITEticketsotp_6964< >1.000sOk -1528qlc_SUITEticketsotp_7114< >0.044sOk -1529qlc_SUITEticketsotp_7232< >0.144sOk -1530qlc_SUITEticketsotp_7238< >1.204sOk -1531qlc_SUITEticketsotp_7552< >0.108sOk -1532qlc_SUITEticketsotp_6674< >2.850sOk -1533qlc_SUITEticketsotp_7714< >0.083sOk -1534qlc_SUITEticketsotp_11758< >0.050sOk -1535qlc_SUITEticketsotp_12946< >0.012sOk -qlc_SUITEticketsend_per_group< >0.000sOk -1536qlc_SUITEmanpage< >0.642sOk -qlc_SUITEcompatinit_per_group< >0.000sOk -1537qlc_SUITEcompatbackward< >0.058sOk -1538qlc_SUITEcompatforward< >0.052sOk -qlc_SUITEcompatend_per_group< >0.000sOk +1516qlc_SUITEjoinjoin_lookup< >0.651sOk +1517qlc_SUITEjoinjoin_merge< >5.053sOk +1518qlc_SUITEjoinjoin_sort< >2.724sOk +1519qlc_SUITEjoinjoin_complex< >0.308sOk +qlc_SUITEjoinend_per_group< >0.000sOk +qlc_SUITEticketsinit_per_group< >0.000sOk +1520qlc_SUITEticketsotp_5644< >0.032sOk +1521qlc_SUITEticketsotp_5195< >0.486sOk +1522qlc_SUITEticketsotp_6038_bug< >0.317sOk +1523qlc_SUITEticketsotp_6359< >0.042sOk +1524qlc_SUITEticketsotp_6562< >0.326sOk +1525qlc_SUITEticketsotp_6590< >0.071sOk +1526qlc_SUITEticketsotp_6673< >0.421sOk +1527qlc_SUITEticketsotp_6964< >1.010sOk +1528qlc_SUITEticketsotp_7114< >0.043sOk +1529qlc_SUITEticketsotp_7232< >0.137sOk +1530qlc_SUITEticketsotp_7238< >1.217sOk +1531qlc_SUITEticketsotp_7552< >0.109sOk +1532qlc_SUITEticketsotp_6674< >2.916sOk +1533qlc_SUITEticketsotp_7714< >0.084sOk +1534qlc_SUITEticketsotp_11758< >0.048sOk +1535qlc_SUITEticketsotp_12946< >0.013sOk +qlc_SUITEticketsend_per_group< >0.000sOk +1536qlc_SUITEmanpage< >0.652sOk +qlc_SUITEcompatinit_per_group< >0.000sOk +1537qlc_SUITEcompatbackward< >0.060sOk +1538qlc_SUITEcompatforward< >0.055sOk +qlc_SUITEcompatend_per_group< >0.000sOk qlc_SUITEend_per_suite< >0.000sOk queue_SUITEinit_per_suite< >0.000sOk 1539queue_SUITEdo< >0.000sOk @@ -1926,120 +1926,120 @@

    Test started at 2024-09-11 11:10:55

    1541queue_SUITEio_test< >0.000sOk 1542queue_SUITEop_test< >0.000sOk 1543queue_SUITEerror< >0.000sOk -1544queue_SUITEoops< >0.152sOk +1544queue_SUITEoops< >0.164sOk queue_SUITEend_per_suite< >0.000sOk -queue_property_test_SUITEinit_per_suite< >1.276sOk +queue_property_test_SUITEinit_per_suite< >1.262sOk 1545queue_property_test_SUITEnew_case< >0.001sOk -1546queue_property_test_SUITEis_queue_case< >0.044sOk -1547queue_property_test_SUITElist_conversion_case< >0.058sOk -1548queue_property_test_SUITEfrom_list_invalid_case< >0.008sOk -1549queue_property_test_SUITEto_list_invalid_case< >0.006sOk -1550queue_property_test_SUITEall_case< >0.051sOk -1551queue_property_test_SUITEall_invalid_case< >0.021sOk -1552queue_property_test_SUITEany_case< >0.127sOk -1553queue_property_test_SUITEany_invalid_case< >0.028sOk -1554queue_property_test_SUITEcons_case< >0.064sOk +1546queue_property_test_SUITEis_queue_case< >0.033sOk +1547queue_property_test_SUITElist_conversion_case< >0.060sOk +1548queue_property_test_SUITEfrom_list_invalid_case< >0.007sOk +1549queue_property_test_SUITEto_list_invalid_case< >0.005sOk +1550queue_property_test_SUITEall_case< >0.077sOk +1551queue_property_test_SUITEall_invalid_case< >0.029sOk +1552queue_property_test_SUITEany_case< >0.130sOk +1553queue_property_test_SUITEany_invalid_case< >0.032sOk +1554queue_property_test_SUITEcons_case< >0.059sOk 1555queue_property_test_SUITEcons_invalid_case< >0.010sOk -1556queue_property_test_SUITEdaeh_case< >0.130sOk -1557queue_property_test_SUITEdaeh_invalid_case< >0.006sOk -1558queue_property_test_SUITEdelete_case< >0.142sOk -1559queue_property_test_SUITEdelete_invalid_case< >0.011sOk -1560queue_property_test_SUITEdelete_r_case< >0.135sOk +1556queue_property_test_SUITEdaeh_case< >0.124sOk +1557queue_property_test_SUITEdaeh_invalid_case< >0.005sOk +1558queue_property_test_SUITEdelete_case< >0.141sOk +1559queue_property_test_SUITEdelete_invalid_case< >0.010sOk +1560queue_property_test_SUITEdelete_r_case< >0.133sOk 1561queue_property_test_SUITEdelete_r_invalid_case< >0.011sOk -1562queue_property_test_SUITEdelete_with_case< >0.121sOk -1563queue_property_test_SUITEdelete_with_invalid_case< >0.034sOk -1564queue_property_test_SUITEdelete_with_r_case< >0.117sOk -1565queue_property_test_SUITEdelete_with_r_invalid_case< >0.024sOk -1566queue_property_test_SUITEdrop_case< >0.116sOk -1567queue_property_test_SUITEdrop_invalid_case< >0.005sOk -1568queue_property_test_SUITEdrop_r_case< >0.133sOk -1569queue_property_test_SUITEdrop_r_invalid_case< >0.005sOk -1570queue_property_test_SUITEfilter_case< >0.123sOk -1571queue_property_test_SUITEfilter_invalid_case< >0.032sOk -1572queue_property_test_SUITEfiltermap_case< >0.125sOk -1573queue_property_test_SUITEfiltermap_invalid_case< >0.028sOk -1574queue_property_test_SUITEfold_case< >0.147sOk +1562queue_property_test_SUITEdelete_with_case< >0.120sOk +1563queue_property_test_SUITEdelete_with_invalid_case< >0.032sOk +1564queue_property_test_SUITEdelete_with_r_case< >0.133sOk +1565queue_property_test_SUITEdelete_with_r_invalid_case< >0.021sOk +1566queue_property_test_SUITEdrop_case< >0.121sOk +1567queue_property_test_SUITEdrop_invalid_case< >0.006sOk +1568queue_property_test_SUITEdrop_r_case< >0.127sOk +1569queue_property_test_SUITEdrop_r_invalid_case< >0.006sOk +1570queue_property_test_SUITEfilter_case< >0.122sOk +1571queue_property_test_SUITEfilter_invalid_case< >0.020sOk +1572queue_property_test_SUITEfiltermap_case< >0.118sOk +1573queue_property_test_SUITEfiltermap_invalid_case< >0.037sOk +1574queue_property_test_SUITEfold_case< >0.111sOk 1575queue_property_test_SUITEfold_invalid_case< >0.026sOk -1576queue_property_test_SUITEget_case< >0.129sOk -1577queue_property_test_SUITEget_invalid_case< >0.009sOk -1578queue_property_test_SUITEget_r_case< >0.127sOk -1579queue_property_test_SUITEget_r_invalid_case< >0.009sOk -1580queue_property_test_SUITEhead_case< >0.117sOk -1581queue_property_test_SUITEhead_invalid_case< >0.006sOk -1582queue_property_test_SUITEin_case< >0.073sOk -1583queue_property_test_SUITEin_invalid_case< >0.009sOk -1584queue_property_test_SUITEin_r_case< >0.066sOk -1585queue_property_test_SUITEin_r_invalid_case< >0.010sOk -1586queue_property_test_SUITEinit_case< >0.114sOk -1587queue_property_test_SUITEinit_invalid_case< >0.007sOk -1588queue_property_test_SUITEis_empty_case< >0.114sOk +1576queue_property_test_SUITEget_case< >0.131sOk +1577queue_property_test_SUITEget_invalid_case< >0.006sOk +1578queue_property_test_SUITEget_r_case< >0.120sOk +1579queue_property_test_SUITEget_r_invalid_case< >0.006sOk +1580queue_property_test_SUITEhead_case< >0.120sOk +1581queue_property_test_SUITEhead_invalid_case< >0.008sOk +1582queue_property_test_SUITEin_case< >0.066sOk +1583queue_property_test_SUITEin_invalid_case< >0.014sOk +1584queue_property_test_SUITEin_r_case< >0.067sOk +1585queue_property_test_SUITEin_r_invalid_case< >0.015sOk +1586queue_property_test_SUITEinit_case< >0.129sOk +1587queue_property_test_SUITEinit_invalid_case< >0.009sOk +1588queue_property_test_SUITEis_empty_case< >0.132sOk 1589queue_property_test_SUITEis_empty_invalid_case< >0.005sOk -1590queue_property_test_SUITEjoin_case< >0.231sOk -1591queue_property_test_SUITEjoin_invalid_case< >0.047sOk -1592queue_property_test_SUITElast_case< >0.121sOk -1593queue_property_test_SUITElast_invalid_case< >0.005sOk -1594queue_property_test_SUITElen_case< >0.126sOk +1590queue_property_test_SUITEjoin_case< >0.239sOk +1591queue_property_test_SUITEjoin_invalid_case< >0.046sOk +1592queue_property_test_SUITElast_case< >0.133sOk +1593queue_property_test_SUITElast_invalid_case< >0.006sOk +1594queue_property_test_SUITElen_case< >0.123sOk 1595queue_property_test_SUITElen_invalid_case< >0.005sOk -1596queue_property_test_SUITEliat_case< >0.119sOk -1597queue_property_test_SUITEliat_invalid_case< >0.005sOk -1598queue_property_test_SUITEmember_case< >0.132sOk +1596queue_property_test_SUITEliat_case< >0.131sOk +1597queue_property_test_SUITEliat_invalid_case< >0.006sOk +1598queue_property_test_SUITEmember_case< >0.136sOk 1599queue_property_test_SUITEmember_invalid_case< >0.010sOk -1600queue_property_test_SUITEout_case< >0.130sOk -1601queue_property_test_SUITEout_invalid_case< >0.008sOk -1602queue_property_test_SUITEout_r_case< >0.118sOk +1600queue_property_test_SUITEout_case< >0.120sOk +1601queue_property_test_SUITEout_invalid_case< >0.006sOk +1602queue_property_test_SUITEout_r_case< >0.130sOk 1603queue_property_test_SUITEout_r_invalid_case< >0.008sOk -1604queue_property_test_SUITEpeek_case< >0.137sOk -1605queue_property_test_SUITEpeek_invalid_case< >0.007sOk -1606queue_property_test_SUITEpeek_r_case< >0.114sOk +1604queue_property_test_SUITEpeek_case< >0.123sOk +1605queue_property_test_SUITEpeek_invalid_case< >0.008sOk +1606queue_property_test_SUITEpeek_r_case< >0.127sOk 1607queue_property_test_SUITEpeek_r_invalid_case< >0.005sOk -1608queue_property_test_SUITEreverse_case< >0.136sOk -1609queue_property_test_SUITEreverse_invalid_case< >0.005sOk -1610queue_property_test_SUITEsnoc_case< >0.058sOk -1611queue_property_test_SUITEsnoc_invalid_case< >0.011sOk -1612queue_property_test_SUITEsplit_case< >0.130sOk -1613queue_property_test_SUITEsplit_invalid_case< >0.040sOk -1614queue_property_test_SUITEtail_case< >0.128sOk +1608queue_property_test_SUITEreverse_case< >0.126sOk +1609queue_property_test_SUITEreverse_invalid_case< >0.008sOk +1610queue_property_test_SUITEsnoc_case< >0.069sOk +1611queue_property_test_SUITEsnoc_invalid_case< >0.013sOk +1612queue_property_test_SUITEsplit_case< >0.127sOk +1613queue_property_test_SUITEsplit_invalid_case< >0.041sOk +1614queue_property_test_SUITEtail_case< >0.127sOk 1615queue_property_test_SUITEtail_invalid_case< >0.005sOk -1616queue_property_test_SUITEops_case< >0.128sOk +1616queue_property_test_SUITEops_case< >0.141sOk queue_property_test_SUITEend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk +common_testinit_per_suite< >0.000sOk 1617rand_SUITEseed< >0.000sOk -1618rand_SUITEinterval_int< >0.656sOk -1619rand_SUITEinterval_float< >0.314sOk +1618rand_SUITEinterval_int< >0.662sOk +1619rand_SUITEinterval_float< >0.311sOk 1620rand_SUITEbytes_count< >0.011sOk 1621rand_SUITEapi_eq< >0.028sOk 1622rand_SUITEmwc59_api< >0.043sOk -1623rand_SUITEexsp_next_api< >0.056sOk +1623rand_SUITEexsp_next_api< >0.057sOk 1624rand_SUITEexsp_jump_api< >0.061sOk -1625rand_SUITEsplitmix64_next_api< >0.028sOk -1626rand_SUITEreference< >1.180sOk -common_testbasic_statsinit_per_group< >0.000sOkstart of basic_stats -1627rand_SUITEbasic_statsbasic_stats_uniform_1< >3.506sOk -1628rand_SUITEbasic_statsbasic_stats_uniform_2< >3.210sOk -1629rand_SUITEbasic_statsbasic_stats_bytes< >2.433sOk -1630rand_SUITEbasic_statsbasic_stats_standard_normal< >3.099sOk -common_testbasic_statsend_per_group< >0.000sOkend of basic_stats -common_testdistr_statsinit_per_group< >0.000sOkstart of distr_stats -1631rand_SUITEdistr_statsstats_standard_normal_box_muller< >7.793sOk{tp,7.903340006167214,op,0.6000429761841857} -1632rand_SUITEdistr_statsstats_standard_normal_box_muller_2< >7.743sOk{tp,7.736935264315239,op,1.119992882577854} -1633rand_SUITEdistr_statsstats_standard_normal< >7.711sOk{tp,9.12599096011556,op,90.40118884611324} -common_testdistr_statsend_per_group< >0.000sOkend of distr_stats +1625rand_SUITEsplitmix64_next_api< >0.027sOk +1626rand_SUITEreference< >1.184sOk +common_testbasic_statsinit_per_group< >0.000sOkstart of basic_stats +1627rand_SUITEbasic_statsbasic_stats_uniform_1< >3.533sOk +1628rand_SUITEbasic_statsbasic_stats_uniform_2< >3.313sOk +1629rand_SUITEbasic_statsbasic_stats_bytes< >2.414sOk +1630rand_SUITEbasic_statsbasic_stats_standard_normal< >2.874sOk +common_testbasic_statsend_per_group< >0.000sOkend of basic_stats +common_testdistr_statsinit_per_group< >0.000sOkstart of distr_stats +1631rand_SUITEdistr_statsstats_standard_normal_box_muller< >7.387sOk{tp,7.214729335018004,op,1.4816028301143793} +1632rand_SUITEdistr_statsstats_standard_normal_box_muller_2< >7.330sOk{tp,8.83620275154175,op,10.610893926570208} +1633rand_SUITEdistr_statsstats_standard_normal< >7.365sOk{tp,7.903340006167214,op,16.069013440209282} +common_testdistr_statsend_per_group< >0.000sOkend of distr_stats 1634rand_SUITEuniform_real_conv< >0.008sOk 1635rand_SUITEplugin< >0.000sOk -1636rand_SUITEmeasure< >17.195sOk -common_testreference_jumpinit_per_group< >0.000sOkstart of reference_jump -1637rand_SUITEreference_jumpreference_jump_state< >1.180sOk -1638rand_SUITEreference_jumpreference_jump_procdict< >1.179sOk -common_testreference_jumpend_per_group< >0.000sOkend of reference_jump -1639rand_SUITEshort_jump< >0.449sOk -common_testend_per_suite< >0.000sOk +1636rand_SUITEmeasure< >17.537sOk +common_testreference_jumpinit_per_group< >0.000sOkstart of reference_jump +1637rand_SUITEreference_jumpreference_jump_state< >1.157sOk +1638rand_SUITEreference_jumpreference_jump_procdict< >1.167sOk +common_testreference_jumpend_per_group< >0.000sOkend of reference_jump +1639rand_SUITEshort_jump< >0.457sOk +common_testend_per_suite< >0.000sOk random_SUITEinit_per_suite< >0.000sOk 1640random_SUITEinterval_1< >0.002sOk 1641random_SUITEseed0< >0.000sOk 1642random_SUITEseed< >0.000sOk random_SUITEend_per_suite< >0.000sOk re_SUITEinit_per_suite< >0.000sOk -1643re_SUITEpcre< >0.648sOk[{0,6786,0}, +1643re_SUITEpcre< >0.653sOk[{0,6786,0}, {0,4926,88}, {0,138,48}, {0,924,0}, @@ -2063,13 +2063,13 @@

    Test started at 2024-09-11 11:10:55

    1649re_SUITEreplace_input_types< >0.000sOk 1650re_SUITEreplace_with_fun< >0.000sOk 1651re_SUITEreplace_return< >0.000sOk -1652re_SUITEsplit_autogen< >0.038sOk +1652re_SUITEsplit_autogen< >0.039sOk 1653re_SUITEsplit_options< >0.000sOk 1654re_SUITEsplit_specials< >0.000sOk 1655re_SUITEerror_handling< >0.000sOk 1656re_SUITEpcre_cve_2008_2371< >0.000sOk 1657re_SUITEpcre_compile_workspace_overflow< >0.000sOkGot expected error: regular expression is too complicated -1658re_SUITEre_infinite_loop< >0.422sOk +1658re_SUITEre_infinite_loop< >0.418sOk 1659re_SUITEre_backwards_accented< >0.000sOk 1660re_SUITEopt_dupnames< >0.000sOk 1661re_SUITEopt_all_names< >0.000sOk @@ -2080,139 +2080,139 @@

    Test started at 2024-09-11 11:10:55

    1666re_SUITEmatch_limit< >0.002sOk 1667re_SUITEsub_binaries< >0.000sOk 1668re_SUITEre_version< >0.000sOk -1669re_SUITEglobal_unicode_validation< >0.127sOk +1669re_SUITEglobal_unicode_validation< >0.133sOk 1670re_SUITEyield_on_subject_validation< >0.001sOk 1671re_SUITEbad_utf8_subject< >0.003sOk -1672re_SUITEerror_info< >0.003sOk +1672re_SUITEerror_info< >0.004sOk re_SUITEend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk +common_testinit_per_suite< >0.000sOk 1673select_SUITEreturn_values< >0.006sOk -1674select_SUITEselect_test< >12.404sOk -common_testend_per_suite< >0.000sOk +1674select_SUITEselect_test< >12.480sOk +common_testend_per_suite< >0.000sOk sets_SUITEinit_per_suite< >0.000sOk 1675sets_SUITEcreate< >0.000sOk 1676sets_SUITEadd_element< >0.155sOk 1677sets_SUITEdel_element< >0.171sOk -1678sets_SUITEsubtract< >0.403sOk +1678sets_SUITEsubtract< >0.402sOk 1679sets_SUITEintersection< >0.521sOk -1680sets_SUITEunion< >0.626sOk -1681sets_SUITEis_subset< >0.558sOk +1680sets_SUITEunion< >0.627sOk +1681sets_SUITEis_subset< >0.554sOk 1682sets_SUITEis_set< >0.000sOk 1683sets_SUITEfold< >0.081sOk -1684sets_SUITEfilter< >0.057sOk +1684sets_SUITEfilter< >0.059sOk 1685sets_SUITEmap< >0.087sOk 1686sets_SUITEfiltermap< >0.048sOk 1687sets_SUITEtake_smallest< >0.014sOk -1688sets_SUITEtake_largest< >0.016sOk -1689sets_SUITEiterate< >0.071sOk +1688sets_SUITEtake_largest< >0.017sOk +1689sets_SUITEiterate< >0.073sOk 1690sets_SUITEis_empty< >0.000sOk 1691sets_SUITEis_disjoint< >0.022sOk 1692sets_SUITEis_equal< >0.049sOk sets_SUITEend_per_suite< >0.000sOk -sets_property_test_SUITEinit_per_suite< >1.262sOk -1693sets_property_test_SUITEadd_element_case< >0.583sOk -1694sets_property_test_SUITEdel_element_case< >0.585sOk -1695sets_property_test_SUITEfilter_case< >0.181sOk -1696sets_property_test_SUITEfiltermap_case< >0.304sOk -1697sets_property_test_SUITEfold_case< >0.182sOk -1698sets_property_test_SUITEfrom_list_case< >0.189sOk -1699sets_property_test_SUITEintersection_1_case< >2.678sOk -1700sets_property_test_SUITEintersection_2_case< >0.574sOk -1701sets_property_test_SUITEis_disjoint_case< >0.558sOk -1702sets_property_test_SUITEis_element_case< >0.388sOk -1703sets_property_test_SUITEis_empty_case< >0.184sOk -1704sets_property_test_SUITEis_equal_case< >0.372sOk -1705sets_property_test_SUITEis_set_case< >0.107sOk -1706sets_property_test_SUITEis_subset_case< >0.447sOk -1707sets_property_test_SUITEmap_case< >0.545sOk -1708sets_property_test_SUITEsize_case< >0.182sOk -1709sets_property_test_SUITEsubtract_case< >0.582sOk -1710sets_property_test_SUITEto_list_case< >0.200sOk -1711sets_property_test_SUITEunion_1_case< >3.005sOk -1712sets_property_test_SUITEunion_2_case< >0.544sOk -1713sets_property_test_SUITEoperations_case< >1.874sOk +sets_property_test_SUITEinit_per_suite< >1.282sOk +1693sets_property_test_SUITEadd_element_case< >0.501sOk +1694sets_property_test_SUITEdel_element_case< >0.528sOk +1695sets_property_test_SUITEfilter_case< >0.206sOk +1696sets_property_test_SUITEfiltermap_case< >0.310sOk +1697sets_property_test_SUITEfold_case< >0.186sOk +1698sets_property_test_SUITEfrom_list_case< >0.183sOk +1699sets_property_test_SUITEintersection_1_case< >2.781sOk +1700sets_property_test_SUITEintersection_2_case< >0.519sOk +1701sets_property_test_SUITEis_disjoint_case< >0.590sOk +1702sets_property_test_SUITEis_element_case< >0.361sOk +1703sets_property_test_SUITEis_empty_case< >0.195sOk +1704sets_property_test_SUITEis_equal_case< >0.387sOk +1705sets_property_test_SUITEis_set_case< >0.095sOk +1706sets_property_test_SUITEis_subset_case< >0.448sOk +1707sets_property_test_SUITEmap_case< >0.515sOk +1708sets_property_test_SUITEsize_case< >0.199sOk +1709sets_property_test_SUITEsubtract_case< >0.571sOk +1710sets_property_test_SUITEto_list_case< >0.199sOk +1711sets_property_test_SUITEunion_1_case< >2.566sOk +1712sets_property_test_SUITEunion_2_case< >0.543sOk +1713sets_property_test_SUITEoperations_case< >1.747sOk sets_property_test_SUITEend_per_suite< >0.000sOk shell_SUITEinit_per_suite< >0.000sOk -1714shell_SUITEforget< >0.008sOk +1714shell_SUITEforget< >0.007sOk 1715shell_SUITEknown_bugs< >0.001sOk -1716shell_SUITEotp_5226< >0.077sOk -1717shell_SUITEotp_5327< >0.026sOk -1718shell_SUITEotp_5435< >0.192sOk -1719shell_SUITEotp_5195< >0.029sOk +1716shell_SUITEotp_5226< >0.065sOk +1717shell_SUITEotp_5327< >0.032sOk +1718shell_SUITEotp_5435< >0.186sOk +1719shell_SUITEotp_5195< >0.030sOk 1720shell_SUITEotp_5915< >0.007sOk 1721shell_SUITEotp_5916< >0.001sOk 1722shell_SUITEprompt_width< >0.000sOk -1723shell_SUITElocal_definitions_save_to_module_and_forget< >0.020sOk -1724shell_SUITEstart_interactive< >44.921sOk -1725shell_SUITEwhereis< >12.959sOk +1723shell_SUITElocal_definitions_save_to_module_and_forget< >0.019sOk +1724shell_SUITEstart_interactive< >44.948sOk +1725shell_SUITEwhereis< >12.960sOk shell_SUITEbitsinit_per_group< >0.000sOk -1726shell_SUITEbitsbs_match_misc_SUITE< >0.009sOk -1727shell_SUITEbitsbs_match_tail_SUITE< >0.003sOk -1728shell_SUITEbitsbs_match_bin_SUITE< >0.754sOk -1729shell_SUITEbitsbs_construct_SUITE< >0.012sOk +1726shell_SUITEbitsbs_match_misc_SUITE< >0.010sOk +1727shell_SUITEbitsbs_match_tail_SUITE< >0.004sOk +1728shell_SUITEbitsbs_match_bin_SUITE< >0.769sOk +1729shell_SUITEbitsbs_construct_SUITE< >0.010sOk shell_SUITEbitsend_per_group< >0.000sOk -shell_SUITErefmaninit_per_group< >0.000sOk -1730shell_SUITErefmanrefman_bit_syntax< >0.001sOk -shell_SUITErefmanend_per_group< >0.000sOk -shell_SUITEprogexinit_per_group< >0.000sOk +shell_SUITErefmaninit_per_group< >0.000sOk +1730shell_SUITErefmanrefman_bit_syntax< >0.002sOk +shell_SUITErefmanend_per_group< >0.000sOk +shell_SUITEprogexinit_per_group< >0.000sOk 1731shell_SUITEprogexprogex_bit_syntax< >0.003sOk 1732shell_SUITEprogexprogex_records< >0.015sOk -1733shell_SUITEprogexprogex_lc< >0.119sOk -1734shell_SUITEprogexprogex_funs< >0.031sOk -shell_SUITEprogexend_per_group< >0.000sOk -shell_SUITEticketsinit_per_group< >0.000sOk +1733shell_SUITEprogexprogex_lc< >0.116sOk +1734shell_SUITEprogexprogex_funs< >0.033sOk +shell_SUITEprogexend_per_group< >0.000sOk +shell_SUITEticketsinit_per_group< >0.000sOk 1735shell_SUITEticketsotp_5990< >0.001sOk 1736shell_SUITEticketsotp_6166< >0.003sOk -1737shell_SUITEticketsotp_6554< >1.995sOk +1737shell_SUITEticketsotp_6554< >1.988sOk 1738shell_SUITEticketsotp_7184< >0.005sOk 1739shell_SUITEticketsotp_7232< >0.002sOk -1740shell_SUITEticketsotp_8393< >0.017sOk -1741shell_SUITEticketsotp_10302< >0.218sOk -1742shell_SUITEticketsotp_13719< >0.003sOk -1743shell_SUITEticketsotp_14285< >0.184sOk -1744shell_SUITEticketsotp_14296< >0.009sOk -shell_SUITEticketsend_per_group< >0.000sOk -shell_SUITErestrictedinit_per_group< >0.000sOk -1745shell_SUITErestrictedstart_restricted_from_shell< >0.101sOk -1746shell_SUITErestrictedstart_restricted_on_command_line< >0.384sOk -1747shell_SUITErestrictedrestricted_local< >1.510sOk -shell_SUITErestrictedend_per_group< >0.000sOk -shell_SUITErecordsinit_per_group< >0.000sOk -1748shell_SUITErecordsrecords< >0.182sOk -1749shell_SUITErecordstyped_records< >0.016sOk -shell_SUITErecordsend_per_group< >0.000sOk -shell_SUITEdefinitionsinit_per_group< >0.000sOk -1750shell_SUITEdefinitionstypes< >13.794sOk -shell_SUITEdefinitionsend_per_group< >0.000sOk +1740shell_SUITEticketsotp_8393< >0.016sOk +1741shell_SUITEticketsotp_10302< >0.222sOk +1742shell_SUITEticketsotp_13719< >0.004sOk +1743shell_SUITEticketsotp_14285< >0.180sOk +1744shell_SUITEticketsotp_14296< >0.014sOk +shell_SUITEticketsend_per_group< >0.000sOk +shell_SUITErestrictedinit_per_group< >0.000sOk +1745shell_SUITErestrictedstart_restricted_from_shell< >0.099sOk +1746shell_SUITErestrictedstart_restricted_on_command_line< >0.391sOk +1747shell_SUITErestrictedrestricted_local< >1.484sOk +shell_SUITErestrictedend_per_group< >0.000sOk +shell_SUITErecordsinit_per_group< >0.000sOk +1748shell_SUITErecordsrecords< >0.197sOk +1749shell_SUITErecordstyped_records< >0.015sOk +shell_SUITErecordsend_per_group< >0.000sOk +shell_SUITEdefinitionsinit_per_group< >0.000sOk +1750shell_SUITEdefinitionstypes< >13.816sOk +shell_SUITEdefinitionsend_per_group< >0.000sOk shell_SUITEend_per_suite< >0.000sOk shell_docs_SUITEinit_per_suite< >0.103sOk -1751shell_docs_SUITErender_smoke< >76.154sOk -1752shell_docs_SUITErender< >4.804sOk +1751shell_docs_SUITErender_smoke< >76.020sOk +1752shell_docs_SUITErender< >4.892sOk 1753shell_docs_SUITErender_non_native< >0.000sOk -1754shell_docs_SUITElinks< >0.922sOk +1754shell_docs_SUITElinks< >0.915sOk 1755shell_docs_SUITEnormalize< >0.000sOk -shell_docs_SUITEpropinit_per_group< >1.285sOk -1756shell_docs_SUITEproprender_prop< >11.579sOk +shell_docs_SUITEpropinit_per_group< >1.317sOk +1756shell_docs_SUITEproprender_prop< >11.356sOk shell_docs_SUITEpropend_per_group< >0.000sOk 1757shell_docs_SUITEansi< >0.001sOk 1758shell_docs_SUITEcolumns< >0.001sOk shell_docs_SUITEend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk +common_testinit_per_suite< >0.000sOk shell_docs_markdown_SUITEdifferent_format_generatorinit_per_group< >0.000sOk 1759shell_docs_markdown_SUITEdifferent_format_generatorconvert_erlang_html< >0.000sOk 1760shell_docs_markdown_SUITEdifferent_format_generatorconvert_unknown_format< >0.000sOk shell_docs_markdown_SUITEdifferent_format_generatorend_per_group< >0.000sOk -shell_docs_markdown_SUITEmodule_generatorinit_per_group< >0.000sOk +shell_docs_markdown_SUITEmodule_generatorinit_per_group< >0.000sOk 1761shell_docs_markdown_SUITEmodule_generatornon_existing_moduledoc< >0.000sOk 1762shell_docs_markdown_SUITEmodule_generatorhidden_moduledoc< >0.000sOk 1763shell_docs_markdown_SUITEmodule_generatorexisting_moduledoc< >0.000sOk -shell_docs_markdown_SUITEmodule_generatorend_per_group< >0.000sOk -shell_docs_markdown_SUITEdoc_generatorinit_per_group< >0.000sOk +shell_docs_markdown_SUITEmodule_generatorend_per_group< >0.000sOk +shell_docs_markdown_SUITEdoc_generatorinit_per_group< >0.000sOk 1764shell_docs_markdown_SUITEdoc_generatornon_existing_doc< >0.000sOk 1765shell_docs_markdown_SUITEdoc_generatorhidden_doc< >0.000sOk 1766shell_docs_markdown_SUITEdoc_generatorexisting_doc< >0.000sOk -shell_docs_markdown_SUITEdoc_generatorend_per_group< >0.000sOk -shell_docs_markdown_SUITEheader_generatorinit_per_group< >0.000sOk +shell_docs_markdown_SUITEdoc_generatorend_per_group< >0.000sOk +shell_docs_markdown_SUITEheader_generatorinit_per_group< >0.000sOk 1767shell_docs_markdown_SUITEheader_generatorh1_test< >0.000sOk 1768shell_docs_markdown_SUITEheader_generatorh2_test< >0.000sOk 1769shell_docs_markdown_SUITEheader_generatorh3_test< >0.000sOk @@ -2221,8 +2221,8 @@

    Test started at 2024-09-11 11:10:55

    1772shell_docs_markdown_SUITEheader_generatorh6_test< >0.000sOk 1773shell_docs_markdown_SUITEheader_generatorsetext_h1< >0.000sOk 1774shell_docs_markdown_SUITEheader_generatorsetext_h2< >0.000sOk -shell_docs_markdown_SUITEheader_generatorend_per_group< >0.000sOk -shell_docs_markdown_SUITEquote_generatorinit_per_group< >0.000sOk +shell_docs_markdown_SUITEheader_generatorend_per_group< >0.000sOk +shell_docs_markdown_SUITEquote_generatorinit_per_group< >0.000sOk 1775shell_docs_markdown_SUITEquote_generatorsingle_line_quote_test< >0.000sOk 1776shell_docs_markdown_SUITEquote_generatordouble_char_for_quote_test< >0.000sOk 1777shell_docs_markdown_SUITEquote_generatorignore_three_spaces_before_quote< >0.000sOk @@ -2230,17 +2230,17 @@

    Test started at 2024-09-11 11:10:55

    1779shell_docs_markdown_SUITEquote_generatorparagraph_in_between_test< >0.000sOk 1780shell_docs_markdown_SUITEquote_generatorquote_with_anchor_test< >0.000sOk 1781shell_docs_markdown_SUITEquote_generatorquote_without_space< >0.000sOk -shell_docs_markdown_SUITEquote_generatorend_per_group< >0.000sOk -shell_docs_markdown_SUITEparagraph_generatorinit_per_group< >0.000sOk +shell_docs_markdown_SUITEquote_generatorend_per_group< >0.000sOk +shell_docs_markdown_SUITEparagraph_generatorinit_per_group< >0.000sOk 1782shell_docs_markdown_SUITEparagraph_generatorparagraph_after_heading_test< >0.000sOk 1783shell_docs_markdown_SUITEparagraph_generatorquote_before_and_after_paragraph_test< >0.000sOk -shell_docs_markdown_SUITEparagraph_generatorend_per_group< >0.000sOk -shell_docs_markdown_SUITEcode_generatorinit_per_group< >0.000sOk +shell_docs_markdown_SUITEparagraph_generatorend_per_group< >0.000sOk +shell_docs_markdown_SUITEcode_generatorinit_per_group< >0.000sOk 1784shell_docs_markdown_SUITEcode_generatorsingle_line_code_test< >0.000sOk 1785shell_docs_markdown_SUITEcode_generatormultiple_line_code_test< >0.000sOk 1786shell_docs_markdown_SUITEcode_generatorparagraph_between_code_test< >0.000sOk -shell_docs_markdown_SUITEcode_generatorend_per_group< >0.000sOk -shell_docs_markdown_SUITEfence_code_generatorinit_per_group< >0.000sOk +shell_docs_markdown_SUITEcode_generatorend_per_group< >0.000sOk +shell_docs_markdown_SUITEfence_code_generatorinit_per_group< >0.000sOk 1787shell_docs_markdown_SUITEfence_code_generatorsingle_line_fence_code_test< >0.000sOk 1788shell_docs_markdown_SUITEfence_code_generatormultiple_line_fence_code_test< >0.000sOk 1789shell_docs_markdown_SUITEfence_code_generatorsingle_line_fence_code_no_language_test< >0.000sOk @@ -2249,19 +2249,19 @@

    Test started at 2024-09-11 11:10:55

    1792shell_docs_markdown_SUITEfence_code_generatorfence_code_ignores_link_format_test< >0.000sOk 1793shell_docs_markdown_SUITEfence_code_generatorfence_code_with_spaces< >0.000sOk 1794shell_docs_markdown_SUITEfence_code_generatorfence_code_with_tabs< >0.000sOk -shell_docs_markdown_SUITEfence_code_generatorend_per_group< >0.000sOk -shell_docs_markdown_SUITEbr_generatorinit_per_group< >0.000sOk +shell_docs_markdown_SUITEfence_code_generatorend_per_group< >0.000sOk +shell_docs_markdown_SUITEbr_generatorinit_per_group< >0.000sOk 1795shell_docs_markdown_SUITEbr_generatorstart_with_br_test< >0.000sOk 1796shell_docs_markdown_SUITEbr_generatormultiple_br_followed_by_paragraph_test< >0.000sOk 1797shell_docs_markdown_SUITEbr_generatormultiple_lines_of_a_paragraph_test< >0.000sOk 1798shell_docs_markdown_SUITEbr_generatorending_br_test< >0.000sOk -shell_docs_markdown_SUITEbr_generatorend_per_group< >0.000sOk -shell_docs_markdown_SUITEcomment_generatorinit_per_group< >0.000sOk +shell_docs_markdown_SUITEbr_generatorend_per_group< >0.000sOk +shell_docs_markdown_SUITEcomment_generatorinit_per_group< >0.000sOk 1799shell_docs_markdown_SUITEcomment_generatorbegin_comment_test< >0.000sOk 1800shell_docs_markdown_SUITEcomment_generatorafter_paragraph_comment< >0.000sOk 1801shell_docs_markdown_SUITEcomment_generatorforget_closing_comment< >0.000sOk -shell_docs_markdown_SUITEcomment_generatorend_per_group< >0.000sOk -shell_docs_markdown_SUITEformat_generatorinit_per_group< >0.000sOk +shell_docs_markdown_SUITEcomment_generatorend_per_group< >0.000sOk +shell_docs_markdown_SUITEformat_generatorinit_per_group< >0.000sOk 1802shell_docs_markdown_SUITEformat_generatorformat_heading_test< >0.000sOk 1803shell_docs_markdown_SUITEformat_generatorformat_paragraph_test< >0.000sOk 1804shell_docs_markdown_SUITEformat_generatorformat_multiple_inline< >0.000sOk @@ -2288,8 +2288,8 @@

    Test started at 2024-09-11 11:10:55

    1825shell_docs_markdown_SUITEformat_generatorinline_mfa_link< >0.000sOk 1826shell_docs_markdown_SUITEformat_generatorescaped_character< >0.000sOk 1827shell_docs_markdown_SUITEformat_generatorparens_with_italics< >0.000sOk -shell_docs_markdown_SUITEformat_generatorend_per_group< >0.000sOk -shell_docs_markdown_SUITEbullet_list_generatorinit_per_group< >0.000sOk +shell_docs_markdown_SUITEformat_generatorend_per_group< >0.000sOk +shell_docs_markdown_SUITEbullet_list_generatorinit_per_group< >0.000sOk 1828shell_docs_markdown_SUITEbullet_list_generatorsingleton_bullet_list< >0.000sOk 1829shell_docs_markdown_SUITEbullet_list_generatorsingleton_bullet_list_followed_new_paragraph< >0.000sOk 1830shell_docs_markdown_SUITEbullet_list_generatorsingleton_bullet_list_with_format< >0.000sOk @@ -2307,8 +2307,8 @@

    Test started at 2024-09-11 11:10:55

    1842shell_docs_markdown_SUITEbullet_list_generatorbullet_list_mix_with_number_list< >0.000sOk 1843shell_docs_markdown_SUITEbullet_list_generatorinline_code_list< >0.000sOk 1844shell_docs_markdown_SUITEbullet_list_generatorbullet_list_with_anchor< >0.000sOk -shell_docs_markdown_SUITEbullet_list_generatorend_per_group< >0.000sOk -shell_docs_markdown_SUITEnumbered_list_generatorinit_per_group< >0.000sOk +shell_docs_markdown_SUITEbullet_list_generatorend_per_group< >0.000sOk +shell_docs_markdown_SUITEnumbered_list_generatorinit_per_group< >0.000sOk 1845shell_docs_markdown_SUITEnumbered_list_generatorsingleton_numbered_list< >0.000sOk 1846shell_docs_markdown_SUITEnumbered_list_generatorsingleton_numbered_list_followed_new_paragraph< >0.000sOk 1847shell_docs_markdown_SUITEnumbered_list_generatorsingleton_numbered_list_with_format< >0.000sOk @@ -2319,23 +2319,23 @@

    Test started at 2024-09-11 11:10:55

    1852shell_docs_markdown_SUITEnumbered_list_generatormultiline_numbered_list< >0.000sOk 1853shell_docs_markdown_SUITEnumbered_list_generatoreven_nested_numbered_list< >0.000sOk 1854shell_docs_markdown_SUITEnumbered_list_generatorodd_nested_numbered_list< >0.000sOk -shell_docs_markdown_SUITEnumbered_list_generatorend_per_group< >0.000sOk -shell_docs_markdown_SUITEtable_generatorinit_per_group< >0.000sOk +shell_docs_markdown_SUITEnumbered_list_generatorend_per_group< >0.000sOk +shell_docs_markdown_SUITEtable_generatorinit_per_group< >0.000sOk 1855shell_docs_markdown_SUITEtable_generatortable_with_rows< >0.000sOk 1856shell_docs_markdown_SUITEtable_generatortable_with_escaped_bars< >0.000sOk 1857shell_docs_markdown_SUITEtable_generatorfake_table_test< >0.000sOk -shell_docs_markdown_SUITEtable_generatorend_per_group< >0.000sOk -common_testend_per_suite< >0.000sOk +shell_docs_markdown_SUITEtable_generatorend_per_group< >0.000sOk +common_testend_per_suite< >0.000sOk sigils_SUITEinit_per_suite< >0.000sOk 1858sigils_SUITEcompiled_sigils< >0.000sOk 1859sigils_SUITEscan_sigils< >0.000sOk 1860sigils_SUITEparse_sigils< >0.000sOk sigils_SUITEend_per_suite< >0.000sOk slave_SUITEinit_per_suite< >0.000sOk -1861slave_SUITEt_start_link< >1.095sOk -1862slave_SUITEstart_link_nodedown< >0.512sOk -1863slave_SUITEt_start< >1.606sOk -1864slave_SUITEerrors< >32.181sOk +1861slave_SUITEt_start_link< >1.119sOk +1862slave_SUITEstart_link_nodedown< >0.520sOk +1863slave_SUITEt_start< >1.622sOk +1864slave_SUITEerrors< >32.479sOk slave_SUITEend_per_suite< >0.000sOk sofs_SUITEinit_per_suite< >0.000sOk sofs_SUITEsofsinit_per_group< >0.000sOk @@ -2382,11 +2382,11 @@

    Test started at 2024-09-11 11:10:55

    1905sofs_SUITEsofspartition_1< >0.000sOk 1906sofs_SUITEsofspartition_3< >0.000sOk 1907sofs_SUITEsofsmultiple_relative_product< >0.000sOk -1908sofs_SUITEsofsdigraph< >0.001sOk +1908sofs_SUITEsofsdigraph< >0.000sOk 1909sofs_SUITEsofsconstant_function< >0.000sOk 1910sofs_SUITEsofsmisc< >0.001sOk sofs_SUITEsofsend_per_group< >0.000sOk -sofs_SUITEsofs_familyinit_per_group< >0.000sOk +sofs_SUITEsofs_familyinit_per_group< >0.000sOk 1911sofs_SUITEsofs_familyfamily_specification< >0.000sOk 1912sofs_SUITEsofs_familyfamily_domain_1< >0.000sOk 1913sofs_SUITEsofs_familyfamily_range_1< >0.000sOk @@ -2400,7 +2400,7 @@

    Test started at 2024-09-11 11:10:55

    1921sofs_SUITEsofs_familyfamily_union_1< >0.000sOk 1922sofs_SUITEsofs_familyfamily_union_2< >0.000sOk 1923sofs_SUITEsofs_familypartition_family< >0.000sOk -sofs_SUITEsofs_familyend_per_group< >0.000sOk +sofs_SUITEsofs_familyend_per_group< >0.000sOk sofs_SUITEend_per_suite< >0.000sOk stdlib_SUITEinit_per_suite< >0.000sOk 1924stdlib_SUITEapp_test< >0.002sOk @@ -2436,25 +2436,25 @@

    Test started at 2024-09-11 11:10:55

    1947stdlib_bench_SUITEbinarymatches_single_pattern_frequent_match< >0.000sSKIPPEDBenchmark only stdlib_bench_SUITEbinaryend_per_group< >0.000sSKIPPEDBenchmark only stdlib_bench_SUITEioinit_per_group< >0.000sOk -1948stdlib_bench_SUITEiodouble_random_to_list< >0.041sOk7803355 -1949stdlib_bench_SUITEiodouble_random_to_list_array< >0.040sOk6641870 +1948stdlib_bench_SUITEiodouble_random_to_list< >0.042sOk7279610 +1949stdlib_bench_SUITEiodouble_random_to_list_array< >0.039sOk6803184 stdlib_bench_SUITEioend_per_group< >0.000sOk -stdlib_bench_SUITEioinit_per_group< >0.000sOk -1950stdlib_bench_SUITEiodouble_random_to_list< >0.033sOk9134088 -1951stdlib_bench_SUITEiodouble_random_to_list_array< >0.043sOk6382028 -stdlib_bench_SUITEioend_per_group< >0.000sOk -stdlib_bench_SUITEioinit_per_group< >0.000sOk -1952stdlib_bench_SUITEiodouble_random_to_list< >0.033sOk9508415 -1953stdlib_bench_SUITEiodouble_random_to_list_array< >0.043sOk6242977 -stdlib_bench_SUITEioend_per_group< >0.000sOk -stdlib_bench_SUITEioinit_per_group< >0.000sOk -1954stdlib_bench_SUITEiodouble_random_to_list< >0.033sOk8968610 -1955stdlib_bench_SUITEiodouble_random_to_list_array< >0.043sOk6394680 -stdlib_bench_SUITEioend_per_group< >0.000sOk -stdlib_bench_SUITEioinit_per_group< >0.000sOk -1956stdlib_bench_SUITEiodouble_random_to_list< >0.036sOk8208159 -1957stdlib_bench_SUITEiodouble_random_to_list_array< >0.041sOk6660450 -stdlib_bench_SUITEioend_per_group< >0.000sOk +stdlib_bench_SUITEioinit_per_group< >0.000sOk +1950stdlib_bench_SUITEiodouble_random_to_list< >0.035sOk7820443 +1951stdlib_bench_SUITEiodouble_random_to_list_array< >0.043sOk6273526 +stdlib_bench_SUITEioend_per_group< >0.000sOk +stdlib_bench_SUITEioinit_per_group< >0.000sOk +1952stdlib_bench_SUITEiodouble_random_to_list< >0.034sOk8820676 +1953stdlib_bench_SUITEiodouble_random_to_list_array< >0.043sOk6028818 +stdlib_bench_SUITEioend_per_group< >0.000sOk +stdlib_bench_SUITEioinit_per_group< >0.000sOk +1954stdlib_bench_SUITEiodouble_random_to_list< >0.033sOk8950148 +1955stdlib_bench_SUITEiodouble_random_to_list_array< >0.044sOk6073489 +stdlib_bench_SUITEioend_per_group< >0.000sOk +stdlib_bench_SUITEioinit_per_group< >0.000sOk +1956stdlib_bench_SUITEiodouble_random_to_list< >0.038sOk8274721 +1957stdlib_bench_SUITEiodouble_random_to_list_array< >0.043sOk6355663 +stdlib_bench_SUITEioend_per_group< >0.000sOk stdlib_bench_SUITEgen_serverinit_per_group< >0.000sSKIPPEDBenchmark only 1958stdlib_bench_SUITEgen_serversimple< >0.000sSKIPPEDBenchmark only 1959stdlib_bench_SUITEgen_serversimple_timer< >0.000sSKIPPEDBenchmark only @@ -2475,25 +2475,25 @@

    Test started at 2024-09-11 11:10:55

    1972stdlib_bench_SUITEgen_statemgeneric_statem_transit< >0.000sSKIPPEDBenchmark only 1973stdlib_bench_SUITEgen_statemgeneric_statem_complex< >0.000sSKIPPEDBenchmark only stdlib_bench_SUITEgen_statemend_per_group< >0.000sSKIPPEDBenchmark only -stdlib_bench_SUITEgen_server_comparisoninit_per_group< >0.038sOk -1974stdlib_bench_SUITEgen_server_comparisonsingle_small< >6.028sOk#parallel gen_server instances: 1, message flat size: 0 bytes: simple: 1.00 simple_timer: 1.37 simple_mon: 1.68 simple_timer_mon: 2.09 generic: 1.89 generic_timer: 2.47 -1975stdlib_bench_SUITEgen_server_comparisonsingle_medium< >6.005sOk#parallel gen_server instances: 1, message flat size: 800 bytes: simple: 1.00 simple_timer: 1.13 simple_mon: 1.45 simple_timer_mon: 1.60 generic: 1.17 generic_timer: 1.53 -1976stdlib_bench_SUITEgen_server_comparisonsingle_big< >6.006sOk#parallel gen_server instances: 1, message flat size: 16000 bytes: simple: 1.00 simple_timer: 1.00 simple_mon: 1.09 simple_timer_mon: 1.11 generic: 0.97 generic_timer: 1.02 -1977stdlib_bench_SUITEgen_server_comparisonsched_small< >6.006sOk#parallel gen_server instances: 4, message flat size: 0 bytes: simple: 1.00 simple_timer: 1.66 simple_mon: 2.00 simple_timer_mon: 2.06 generic: 1.55 generic_timer: 2.20 -1978stdlib_bench_SUITEgen_server_comparisonsched_medium< >6.006sOk#parallel gen_server instances: 4, message flat size: 800 bytes: simple: 1.00 simple_timer: 1.07 simple_mon: 1.33 simple_timer_mon: 1.59 generic: 1.37 generic_timer: 1.49 -1979stdlib_bench_SUITEgen_server_comparisonsched_big< >6.006sOk#parallel gen_server instances: 4, message flat size: 16000 bytes: simple: 1.00 simple_timer: 1.09 simple_mon: 0.98 simple_timer_mon: 1.00 generic: 0.94 generic_timer: 1.00 -1980stdlib_bench_SUITEgen_server_comparisonmulti_small< >6.071sOk#parallel gen_server instances: 400, message flat size: 0 bytes: simple: 1.00 simple_timer: 1.08 simple_mon: 1.39 simple_timer_mon: 1.45 generic: 1.49 generic_timer: 1.81 -1981stdlib_bench_SUITEgen_server_comparisonmulti_medium< >6.059sOk#parallel gen_server instances: 400, message flat size: 800 bytes: simple: 1.00 simple_timer: 1.09 simple_mon: 1.26 simple_timer_mon: 1.32 generic: 1.28 generic_timer: 1.43 -1982stdlib_bench_SUITEgen_server_comparisonmulti_big< >6.049sOk#parallel gen_server instances: 400, message flat size: 16000 bytes: simple: 1.00 simple_timer: 1.02 simple_mon: 1.02 simple_timer_mon: 1.07 generic: 1.06 generic_timer: 1.09 -stdlib_bench_SUITEgen_server_comparisonend_per_group< >0.000sOk -stdlib_bench_SUITEgen_statem_comparisoninit_per_group< >0.039sOk -1983stdlib_bench_SUITEgen_statem_comparisonsingle_small< >10.026sOk#parallel gen_server instances: 1, message flat size: 0 bytes: generic: 1.00 generic_log: 1.11 generic_log100: 1.12 generic_fsm: 1.07 generic_fsm_transit: 1.07 generic_statem: 1.11 generic_statem_log: 1.39 generic_statem_log100: 1.27 generic_statem_transit: 1.90 generic_statem_complex: 2.88 -1984stdlib_bench_SUITEgen_statem_comparisonsingle_big< >10.009sOk#parallel gen_server instances: 1, message flat size: 16000 bytes: generic: 1.00 generic_log: 0.92 generic_log100: 1.29 generic_fsm: 1.03 generic_fsm_transit: 1.02 generic_statem: 1.02 generic_statem_log: 0.98 generic_statem_log100: 1.17 generic_statem_transit: 1.07 generic_statem_complex: 1.14 -1985stdlib_bench_SUITEgen_statem_comparisonsched_small< >10.010sOk#parallel gen_server instances: 4, message flat size: 0 bytes: generic: 1.00 generic_log: 1.00 generic_log100: 0.98 generic_fsm: 0.97 generic_fsm_transit: 0.99 generic_statem: 1.02 generic_statem_log: 1.22 generic_statem_log100: 1.13 generic_statem_transit: 2.00 generic_statem_complex: 3.39 -1986stdlib_bench_SUITEgen_statem_comparisonsched_big< >10.010sOk#parallel gen_server instances: 4, message flat size: 16000 bytes: generic: 1.00 generic_log: 1.09 generic_log100: 1.44 generic_fsm: 0.98 generic_fsm_transit: 0.98 generic_statem: 1.01 generic_statem_log: 1.24 generic_statem_log100: 1.54 generic_statem_transit: 1.06 generic_statem_complex: 1.15 -1987stdlib_bench_SUITEgen_statem_comparisonmulti_small< >10.070sOk#parallel gen_server instances: 400, message flat size: 0 bytes: generic: 1.00 generic_log: 1.23 generic_log100: 1.14 generic_fsm: 1.02 generic_fsm_transit: 1.05 generic_statem: 1.16 generic_statem_log: 1.88 generic_statem_log100: 1.54 generic_statem_transit: 2.17 generic_statem_complex: 3.67 -1988stdlib_bench_SUITEgen_statem_comparisonmulti_big< >10.096sOk#parallel gen_server instances: 400, message flat size: 16000 bytes: generic: 1.00 generic_log: 1.04 generic_log100: 1.02 generic_fsm: 1.04 generic_fsm_transit: 1.02 generic_statem: 1.02 generic_statem_log: 1.09 generic_statem_log100: 1.03 generic_statem_transit: 1.14 generic_statem_complex: 1.29 -stdlib_bench_SUITEgen_statem_comparisonend_per_group< >0.000sOk +stdlib_bench_SUITEgen_server_comparisoninit_per_group< >0.039sOk +1974stdlib_bench_SUITEgen_server_comparisonsingle_small< >6.037sOk#parallel gen_server instances: 1, message flat size: 0 bytes: simple: 1.00 simple_timer: 1.34 simple_mon: 1.71 simple_timer_mon: 2.08 generic: 1.94 generic_timer: 2.53 +1975stdlib_bench_SUITEgen_server_comparisonsingle_medium< >6.006sOk#parallel gen_server instances: 1, message flat size: 800 bytes: simple: 1.00 simple_timer: 1.11 simple_mon: 1.41 simple_timer_mon: 1.57 generic: 1.18 generic_timer: 1.50 +1976stdlib_bench_SUITEgen_server_comparisonsingle_big< >6.006sOk#parallel gen_server instances: 1, message flat size: 16000 bytes: simple: 1.00 simple_timer: 1.03 simple_mon: 1.11 simple_timer_mon: 1.14 generic: 1.00 generic_timer: 1.01 +1977stdlib_bench_SUITEgen_server_comparisonsched_small< >6.006sOk#parallel gen_server instances: 4, message flat size: 0 bytes: simple: 1.00 simple_timer: 1.27 simple_mon: 1.55 simple_timer_mon: 1.74 generic: 1.29 generic_timer: 1.72 +1978stdlib_bench_SUITEgen_server_comparisonsched_medium< >6.006sOk#parallel gen_server instances: 4, message flat size: 800 bytes: simple: 1.00 simple_timer: 1.05 simple_mon: 1.28 simple_timer_mon: 1.47 generic: 1.29 generic_timer: 1.45 +1979stdlib_bench_SUITEgen_server_comparisonsched_big< >6.006sOk#parallel gen_server instances: 4, message flat size: 16000 bytes: simple: 1.00 simple_timer: 1.13 simple_mon: 1.05 simple_timer_mon: 1.10 generic: 0.95 generic_timer: 0.99 +1980stdlib_bench_SUITEgen_server_comparisonmulti_small< >6.074sOk#parallel gen_server instances: 400, message flat size: 0 bytes: simple: 1.00 simple_timer: 1.06 simple_mon: 1.34 simple_timer_mon: 1.40 generic: 1.48 generic_timer: 1.75 +1981stdlib_bench_SUITEgen_server_comparisonmulti_medium< >6.057sOk#parallel gen_server instances: 400, message flat size: 800 bytes: simple: 1.00 simple_timer: 1.09 simple_mon: 1.25 simple_timer_mon: 1.29 generic: 1.26 generic_timer: 1.47 +1982stdlib_bench_SUITEgen_server_comparisonmulti_big< >6.049sOk#parallel gen_server instances: 400, message flat size: 16000 bytes: simple: 1.00 simple_timer: 1.00 simple_mon: 1.04 simple_timer_mon: 1.03 generic: 1.03 generic_timer: 1.03 +stdlib_bench_SUITEgen_server_comparisonend_per_group< >0.000sOk +stdlib_bench_SUITEgen_statem_comparisoninit_per_group< >0.038sOk +1983stdlib_bench_SUITEgen_statem_comparisonsingle_small< >10.025sOk#parallel gen_server instances: 1, message flat size: 0 bytes: generic: 1.00 generic_log: 1.10 generic_log100: 1.10 generic_fsm: 1.03 generic_fsm_transit: 1.00 generic_statem: 1.02 generic_statem_log: 1.26 generic_statem_log100: 1.16 generic_statem_transit: 1.75 generic_statem_complex: 2.55 +1984stdlib_bench_SUITEgen_statem_comparisonsingle_big< >10.010sOk#parallel gen_server instances: 1, message flat size: 16000 bytes: generic: 1.00 generic_log: 0.91 generic_log100: 1.30 generic_fsm: 1.00 generic_fsm_transit: 1.00 generic_statem: 0.99 generic_statem_log: 0.95 generic_statem_log100: 1.21 generic_statem_transit: 1.05 generic_statem_complex: 1.17 +1985stdlib_bench_SUITEgen_statem_comparisonsched_small< >10.010sOk#parallel gen_server instances: 4, message flat size: 0 bytes: generic: 1.00 generic_log: 1.04 generic_log100: 1.04 generic_fsm: 0.96 generic_fsm_transit: 1.00 generic_statem: 1.07 generic_statem_log: 1.25 generic_statem_log100: 1.13 generic_statem_transit: 2.13 generic_statem_complex: 3.46 +1986stdlib_bench_SUITEgen_statem_comparisonsched_big< >10.010sOk#parallel gen_server instances: 4, message flat size: 16000 bytes: generic: 1.00 generic_log: 1.16 generic_log100: 1.55 generic_fsm: 1.12 generic_fsm_transit: 1.01 generic_statem: 1.09 generic_statem_log: 1.24 generic_statem_log100: 1.62 generic_statem_transit: 1.08 generic_statem_complex: 1.18 +1987stdlib_bench_SUITEgen_statem_comparisonmulti_small< >10.070sOk#parallel gen_server instances: 400, message flat size: 0 bytes: generic: 1.00 generic_log: 1.21 generic_log100: 1.14 generic_fsm: 1.03 generic_fsm_transit: 1.05 generic_statem: 1.15 generic_statem_log: 1.83 generic_statem_log100: 1.53 generic_statem_transit: 2.12 generic_statem_complex: 3.72 +1988stdlib_bench_SUITEgen_statem_comparisonmulti_big< >10.082sOk#parallel gen_server instances: 400, message flat size: 16000 bytes: generic: 1.00 generic_log: 1.04 generic_log100: 1.01 generic_fsm: 1.01 generic_fsm_transit: 1.00 generic_statem: 0.98 generic_statem_log: 1.03 generic_statem_log100: 1.10 generic_statem_transit: 1.11 generic_statem_complex: 1.23 +stdlib_bench_SUITEgen_statem_comparisonend_per_group< >0.000sOk stdlib_bench_SUITEend_per_suite< >0.000sOk string_SUITEinit_per_suite< >0.000sOk string_SUITEchardatainit_per_group< >0.000sOk @@ -2521,9 +2521,9 @@

    Test started at 2024-09-11 11:10:55

    2010string_SUITEchardatareplace< >0.000sOk 2011string_SUITEchardatacd_gc< >0.000sOk 2012string_SUITEchardatajaro_similarity< >0.000sOk -2013string_SUITEchardatameas< >52.244sOk +2013string_SUITEchardatameas< >52.281sOk string_SUITEchardataend_per_group< >0.000sOk -string_SUITElist_stringinit_per_group< >0.000sOk +string_SUITElist_stringinit_per_group< >0.000sOk 2014string_SUITElist_stringlen< >0.000sOk 2015string_SUITElist_stringold_equal< >0.000sOk 2016string_SUITElist_stringold_concat< >0.000sOk @@ -2544,7 +2544,7 @@

    Test started at 2024-09-11 11:10:55

    2031string_SUITElist_stringold_to_integer< >0.000sOk 2032string_SUITElist_stringold_to_float< >0.000sOk 2033string_SUITElist_stringto_upper_to_lower< >0.000sOk -string_SUITElist_stringend_per_group< >0.000sOk +string_SUITElist_stringend_per_group< >0.000sOk string_SUITEend_per_suite< >0.000sOk supervisor_SUITEinit_per_suite< >0.000sOk supervisor_SUITEsup_startinit_per_group< >0.000sOk @@ -2558,79 +2558,79 @@

    Test started at 2024-09-11 11:10:55

    2041supervisor_SUITEsup_startsup_start_error_return< >0.101sOk 2042supervisor_SUITEsup_startsup_start_fail< >0.101sOk 2043supervisor_SUITEsup_startsup_start_child_returns_error< >0.000sOk -2044supervisor_SUITEsup_startsup_start_restart_child_returns_error< >0.000sOk +2044supervisor_SUITEsup_startsup_start_restart_child_returns_error< >0.001sOk 2045supervisor_SUITEsup_startsup_start_child_returns_error_simple< >0.000sOk supervisor_SUITEsup_startend_per_group< >0.000sOk -supervisor_SUITEsup_start_mapinit_per_group< >0.000sOk +supervisor_SUITEsup_start_mapinit_per_group< >0.000sOk 2046supervisor_SUITEsup_start_mapsup_start_map< >0.000sOk 2047supervisor_SUITEsup_start_mapsup_start_map_simple< >0.000sOk -2048supervisor_SUITEsup_start_mapsup_start_map_faulty_specs< >0.002sOk -supervisor_SUITEsup_start_mapend_per_group< >0.000sOk -supervisor_SUITEsup_stopinit_per_group< >0.000sOk +2048supervisor_SUITEsup_start_mapsup_start_map_faulty_specs< >0.001sOk +supervisor_SUITEsup_start_mapend_per_group< >0.000sOk +supervisor_SUITEsup_stopinit_per_group< >0.000sOk 2049supervisor_SUITEsup_stopsup_stop_infinity< >0.000sOk 2050supervisor_SUITEsup_stopsup_stop_timeout< >1.001sOk 2051supervisor_SUITEsup_stopsup_stop_timeout_dynamic< >1.001sOk 2052supervisor_SUITEsup_stopsup_stop_brutal_kill< >0.000sOk 2053supervisor_SUITEsup_stopsup_stop_brutal_kill_dynamic< >0.000sOk -2054supervisor_SUITEsup_stopsup_stop_race< >1.002sOk -2055supervisor_SUITEsup_stopsup_stop_non_shutdown_exit_dynamic< >0.011sOk -supervisor_SUITEsup_stopend_per_group< >0.000sOk +2054supervisor_SUITEsup_stopsup_stop_race< >1.003sOk +2055supervisor_SUITEsup_stopsup_stop_non_shutdown_exit_dynamic< >0.006sOk +supervisor_SUITEsup_stopend_per_group< >0.000sOk 2056supervisor_SUITEchild_adm< >0.000sOk 2057supervisor_SUITEchild_adm_simple< >0.000sOk 2058supervisor_SUITEextra_return< >0.001sOk 2059supervisor_SUITEchild_specs< >0.002sOk -2060supervisor_SUITEchild_specs_map< >0.007sOk -2061supervisor_SUITEsup_flags< >0.004sOk -2062supervisor_SUITEmultiple_restarts< >6.305sOk -supervisor_SUITErestart_one_for_oneinit_per_group< >0.000sOk +2060supervisor_SUITEchild_specs_map< >0.008sOk +2061supervisor_SUITEsup_flags< >0.005sOk +2062supervisor_SUITEmultiple_restarts< >6.306sOk +supervisor_SUITErestart_one_for_oneinit_per_group< >0.000sOk 2063supervisor_SUITErestart_one_for_oneone_for_one< >0.003sOk -2064supervisor_SUITErestart_one_for_oneone_for_one_escalation< >0.005sOk -supervisor_SUITErestart_one_for_oneend_per_group< >0.000sOk -supervisor_SUITErestart_one_for_allinit_per_group< >0.000sOk -2065supervisor_SUITErestart_one_for_allone_for_all< >0.003sOk +2064supervisor_SUITErestart_one_for_oneone_for_one_escalation< >0.006sOk +supervisor_SUITErestart_one_for_oneend_per_group< >0.000sOk +supervisor_SUITErestart_one_for_allinit_per_group< >0.000sOk +2065supervisor_SUITErestart_one_for_allone_for_all< >0.004sOk 2066supervisor_SUITErestart_one_for_allone_for_all_escalation< >0.005sOk 2067supervisor_SUITErestart_one_for_allone_for_all_other_child_fails_restart< >0.001sOk -supervisor_SUITErestart_one_for_allend_per_group< >0.000sOk -supervisor_SUITErestart_simple_one_for_oneinit_per_group< >0.000sOk +supervisor_SUITErestart_one_for_allend_per_group< >0.000sOk +supervisor_SUITErestart_simple_one_for_oneinit_per_group< >0.000sOk 2068supervisor_SUITErestart_simple_one_for_onesimple_one_for_one< >0.003sOk 2069supervisor_SUITErestart_simple_one_for_onesimple_one_for_one_shutdown< >2.001sOk -2070supervisor_SUITErestart_simple_one_for_onesimple_one_for_one_extra< >0.004sOk -2071supervisor_SUITErestart_simple_one_for_onesimple_one_for_one_escalation< >0.004sOk -2072supervisor_SUITErestart_simple_one_for_onesimple_one_for_one_corruption< >0.004sOk -2073supervisor_SUITErestart_simple_one_for_onesimple_one_for_one_restart_ignore< >0.002sOk -supervisor_SUITErestart_simple_one_for_oneend_per_group< >0.000sOk -supervisor_SUITErestart_rest_for_oneinit_per_group< >0.000sOk -2074supervisor_SUITErestart_rest_for_onerest_for_one< >0.003sOk -2075supervisor_SUITErestart_rest_for_onerest_for_one_escalation< >0.005sOk +2070supervisor_SUITErestart_simple_one_for_onesimple_one_for_one_extra< >0.003sOk +2071supervisor_SUITErestart_simple_one_for_onesimple_one_for_one_escalation< >0.007sOk +2072supervisor_SUITErestart_simple_one_for_onesimple_one_for_one_corruption< >0.005sOk +2073supervisor_SUITErestart_simple_one_for_onesimple_one_for_one_restart_ignore< >0.001sOk +supervisor_SUITErestart_simple_one_for_oneend_per_group< >0.000sOk +supervisor_SUITErestart_rest_for_oneinit_per_group< >0.000sOk +2074supervisor_SUITErestart_rest_for_onerest_for_one< >0.004sOk +2075supervisor_SUITErestart_rest_for_onerest_for_one_escalation< >0.004sOk 2076supervisor_SUITErestart_rest_for_onerest_for_one_other_child_fails_restart< >0.001sOk -supervisor_SUITErestart_rest_for_oneend_per_group< >0.000sOk -supervisor_SUITEnormal_terminationinit_per_group< >0.000sOk +supervisor_SUITErestart_rest_for_oneend_per_group< >0.000sOk +supervisor_SUITEnormal_terminationinit_per_group< >0.000sOk 2077supervisor_SUITEnormal_terminationexternal_start_no_progress_log< >0.001sOk 2078supervisor_SUITEnormal_terminationpermanent_normal< >0.000sOk 2079supervisor_SUITEnormal_terminationtransient_normal< >0.000sOk 2080supervisor_SUITEnormal_terminationtemporary_normal< >0.000sOk -supervisor_SUITEnormal_terminationend_per_group< >0.000sOk -supervisor_SUITEshutdown_terminationinit_per_group< >0.000sOk +supervisor_SUITEnormal_terminationend_per_group< >0.000sOk +supervisor_SUITEshutdown_terminationinit_per_group< >0.000sOk 2081supervisor_SUITEshutdown_terminationpermanent_shutdown< >0.001sOk 2082supervisor_SUITEshutdown_terminationtransient_shutdown< >0.000sOk 2083supervisor_SUITEshutdown_terminationtemporary_shutdown< >0.000sOk -2084supervisor_SUITEshutdown_terminationfaulty_application_shutdown< >0.016sOk -supervisor_SUITEshutdown_terminationend_per_group< >0.000sOk -supervisor_SUITEabnormal_terminationinit_per_group< >0.000sOk -2085supervisor_SUITEabnormal_terminationpermanent_abnormal< >0.002sOk +2084supervisor_SUITEshutdown_terminationfaulty_application_shutdown< >0.014sOk +supervisor_SUITEshutdown_terminationend_per_group< >0.000sOk +supervisor_SUITEabnormal_terminationinit_per_group< >0.000sOk +2085supervisor_SUITEabnormal_terminationpermanent_abnormal< >0.001sOk 2086supervisor_SUITEabnormal_terminationtransient_abnormal< >0.001sOk 2087supervisor_SUITEabnormal_terminationtemporary_abnormal< >0.001sOk -supervisor_SUITEabnormal_terminationend_per_group< >0.000sOk -2088supervisor_SUITEchild_unlink< >5.000sOk -2089supervisor_SUITEtree< >1.004sOk -supervisor_SUITEsignificantinit_per_group< >0.000sOk -2090supervisor_SUITEsignificantnonsignificant_temporary< >12.012sOk +supervisor_SUITEabnormal_terminationend_per_group< >0.000sOk +2088supervisor_SUITEchild_unlink< >5.001sOk +2089supervisor_SUITEtree< >1.003sOk +supervisor_SUITEsignificantinit_per_group< >0.000sOk +2090supervisor_SUITEsignificantnonsignificant_temporary< >12.014sOk 2091supervisor_SUITEsignificantnonsignificant_transient< >12.012sOk -2092supervisor_SUITEsignificantsignificant_temporary< >6.007sOk +2092supervisor_SUITEsignificantsignificant_temporary< >6.008sOk 2093supervisor_SUITEsignificantsignificant_transient< >12.013sOk 2094supervisor_SUITEsignificantsignificant_simple< >0.001sOk -2095supervisor_SUITEsignificantsignificant_bystander< >12.011sOk -2096supervisor_SUITEsignificantsignificant_escalation< >1.000sOk +2095supervisor_SUITEsignificantsignificant_bystander< >12.012sOk +2096supervisor_SUITEsignificantsignificant_escalation< >1.001sOk 2097supervisor_SUITEsignificantsignificant_upgrade_never_any< >0.000sOk 2098supervisor_SUITEsignificantsignificant_upgrade_any_never< >3.003sOk 2099supervisor_SUITEsignificantsignificant_upgrade_never_all< >2.002sOk @@ -2638,25 +2638,25 @@

    Test started at 2024-09-11 11:10:55

    2101supervisor_SUITEsignificantsignificant_upgrade_any_all< >5.005sOk 2102supervisor_SUITEsignificantsignificant_upgrade_all_any< >3.003sOk 2103supervisor_SUITEsignificantsignificant_upgrade_child< >7.007sOk -supervisor_SUITEsignificantend_per_group< >0.000sOk -2104supervisor_SUITEcount_children< >0.521sOk -2105supervisor_SUITEcount_children_supervisor< >0.381sOk +supervisor_SUITEsignificantend_per_group< >0.000sOk +2104supervisor_SUITEcount_children< >0.566sOk +2105supervisor_SUITEcount_children_supervisor< >0.395sOk 2106supervisor_SUITEcount_restarting_children< >10.407sOk 2107supervisor_SUITEget_callback_module< >0.000sOk 2108supervisor_SUITEdo_not_save_start_parameters_for_temporary_children< >0.014sOk -2109supervisor_SUITEdo_not_save_child_specs_for_temporary_children< >0.014sOk -2110supervisor_SUITEsimple_one_for_one_scale_many_temporary_children< >0.124sOk +2109supervisor_SUITEdo_not_save_child_specs_for_temporary_children< >0.018sOk +2110supervisor_SUITEsimple_one_for_one_scale_many_temporary_children< >0.134sOk 2111supervisor_SUITEtemporary_bystander< >0.351sOk 2112supervisor_SUITEsimple_global_supervisor< >1.407sOk -2113supervisor_SUITEhanging_restart_loop< >14.010sOk -2114supervisor_SUITEhanging_restart_loop_rest_for_one< >14.009sOk -2115supervisor_SUITEhanging_restart_loop_simple< >12.008sOk +2113supervisor_SUITEhanging_restart_loop< >14.012sOk +2114supervisor_SUITEhanging_restart_loop_rest_for_one< >14.012sOk +2115supervisor_SUITEhanging_restart_loop_simple< >12.013sOk 2116supervisor_SUITEcode_change< >0.000sOk 2117supervisor_SUITEcode_change_map< >0.000sOk 2118supervisor_SUITEcode_change_simple< >0.000sOk 2119supervisor_SUITEcode_change_simple_map< >0.000sOk 2120supervisor_SUITEorder_of_children< >0.010sOk -2121supervisor_SUITEscale_start_stop_many_children< >1.395sOk +2121supervisor_SUITEscale_start_stop_many_children< >1.326sOk 2122supervisor_SUITEformat_log_1< >0.000sOk 2123supervisor_SUITEformat_log_2< >0.001sOk 2124supervisor_SUITEalready_started_outside_supervisor< >0.000sOk @@ -2665,7 +2665,7 @@

    Test started at 2024-09-11 11:10:55

    2125supervisor_bridge_SUITEstarting< >0.000sOk 2126supervisor_bridge_SUITEmini_terminate< >0.001sOk 2127supervisor_bridge_SUITEmini_die< >0.001sOk -2128supervisor_bridge_SUITEbadstart< >0.003sOk +2128supervisor_bridge_SUITEbadstart< >0.002sOk 2129supervisor_bridge_SUITEsimple_global_supervisor< >0.201sOk 2130supervisor_bridge_SUITEformat_log_1< >0.000sOk 2131supervisor_bridge_SUITEformat_log_2< >0.001sOk @@ -2675,38 +2675,38 @@

    Test started at 2024-09-11 11:10:55

    2133sys_SUITElog_to_file< >0.001sOk 2134sys_SUITEstats< >0.000sOk 2135sys_SUITEtrace< >3.002sOk -2136sys_SUITEsuspend< >2.002sOk -2137sys_SUITEinstall< >0.008sOk +2136sys_SUITEsuspend< >2.001sOk +2137sys_SUITEinstall< >0.007sOk 2138sys_SUITEspecial_process< >0.000sOk sys_SUITEend_per_suite< >0.000sOk tar_SUITEinit_per_suite< >0.000sOk -2139tar_SUITEborderline< >0.152sOk +2139tar_SUITEborderline< >0.149sOk 2140tar_SUITEatomic< >0.009sOk 2141tar_SUITElong_names< >0.004sOk 2142tar_SUITEcreate_long_names< >0.003sOk -2143tar_SUITEbad_tar< >0.002sOk +2143tar_SUITEbad_tar< >0.001sOk 2144tar_SUITEerrors< >0.001sOk 2145tar_SUITEextract_from_binary< >0.002sOk -2146tar_SUITEextract_from_binary_compressed< >0.006sOk -2147tar_SUITEextract_from_open_file< >0.009sOk -2148tar_SUITEextract_filtered< >0.001sOk +2146tar_SUITEextract_from_binary_compressed< >0.005sOk +2147tar_SUITEextract_from_open_file< >0.008sOk +2148tar_SUITEextract_filtered< >0.002sOk 2149tar_SUITEsymlinks< >0.006sOk 2150tar_SUITEopen_add_close< >0.004sOk -2151tar_SUITEcooked_compressed< >0.012sOk +2151tar_SUITEcooked_compressed< >0.011sOk 2152tar_SUITEmemory< >0.001sOk -2153tar_SUITEunicode< >0.341sOk -2154tar_SUITEread_other_implementations< >0.004sOk +2153tar_SUITEunicode< >0.347sOk +2154tar_SUITEread_other_implementations< >0.002sOk 2155tar_SUITEbsdtgz< >0.001sOk -2156tar_SUITEsparse< >0.009sOk +2156tar_SUITEsparse< >0.008sOk 2157tar_SUITEinit< >0.002sOk 2158tar_SUITEleading_slash< >0.001sOk 2159tar_SUITEdotdot< >0.001sOk 2160tar_SUITEroundtrip_metadata< >0.001sOk -2161tar_SUITEapply_file_info_opts< >0.002sOk +2161tar_SUITEapply_file_info_opts< >0.001sOk 2162tar_SUITEincompatible_options< >0.000sOk tar_SUITEend_per_suite< >0.000sOk timer_SUITEinit_per_suite< >0.000sOk -2163timer_SUITEdo_big_test< >80.719sOk +2163timer_SUITEdo_big_test< >71.803sOk timer_SUITEend_per_suite< >0.000sOk timer_simple_SUITEinit_per_suite< >0.000sOk timer_simple_SUITEapply_afterinit_per_group< >0.000sOk @@ -2716,7 +2716,7 @@

    Test started at 2024-09-11 11:10:55

    2167timer_simple_SUITEapply_afterapply_after4< >0.102sOk 2168timer_simple_SUITEapply_afterapply_after_invalid_args< >0.000sOk timer_simple_SUITEapply_afterend_per_group< >0.000sOk -timer_simple_SUITEsend_afterinit_per_group< >0.000sOk +timer_simple_SUITEsend_afterinit_per_group< >0.000sOk 2169timer_simple_SUITEsend_aftersend_after1< >0.000sOk 2170timer_simple_SUITEsend_aftersend_after2< >0.000sOk 2171timer_simple_SUITEsend_aftersend_after3< >0.000sOk @@ -2725,79 +2725,79 @@

    Test started at 2024-09-11 11:10:55

    2174timer_simple_SUITEsend_aftersend_after6< >0.502sOk 2175timer_simple_SUITEsend_aftersend_after7< >0.502sOk 2176timer_simple_SUITEsend_aftersend_after_invalid_args< >0.000sOk -timer_simple_SUITEsend_afterend_per_group< >0.000sOk -timer_simple_SUITEexit_afterinit_per_group< >0.000sOk +timer_simple_SUITEsend_afterend_per_group< >0.000sOk +timer_simple_SUITEexit_afterinit_per_group< >0.000sOk 2177timer_simple_SUITEexit_afterexit_after1< >1.002sOk 2178timer_simple_SUITEexit_afterexit_after2< >1.002sOk 2179timer_simple_SUITEexit_afterexit_after3< >1.002sOk 2180timer_simple_SUITEexit_afterexit_after4< >1.001sOk -timer_simple_SUITEexit_afterend_per_group< >0.000sOk -timer_simple_SUITEkill_afterinit_per_group< >0.000sOk +timer_simple_SUITEexit_afterend_per_group< >0.000sOk +timer_simple_SUITEkill_afterinit_per_group< >0.000sOk 2181timer_simple_SUITEkill_afterkill_after1< >1.002sOk 2182timer_simple_SUITEkill_afterkill_after2< >1.002sOk -2183timer_simple_SUITEkill_afterkill_after3< >1.002sOk -timer_simple_SUITEkill_afterend_per_group< >0.000sOk -timer_simple_SUITEapply_intervalinit_per_group< >0.000sOk +2183timer_simple_SUITEkill_afterkill_after3< >1.001sOk +timer_simple_SUITEkill_afterend_per_group< >0.000sOk +timer_simple_SUITEapply_intervalinit_per_group< >0.000sOk 2184timer_simple_SUITEapply_intervalapply_interval1< >4.003sOk -2185timer_simple_SUITEapply_intervalapply_interval2< >2.802sOk +2185timer_simple_SUITEapply_intervalapply_interval2< >2.801sOk 2186timer_simple_SUITEapply_intervalapply_interval_invalid_args< >0.000sOk -timer_simple_SUITEapply_intervalend_per_group< >0.000sOk -timer_simple_SUITEapply_repeatedlyinit_per_group< >0.000sOk -2187timer_simple_SUITEapply_repeatedlyapply_repeatedly1< >4.002sOk +timer_simple_SUITEapply_intervalend_per_group< >0.000sOk +timer_simple_SUITEapply_repeatedlyinit_per_group< >0.000sOk +2187timer_simple_SUITEapply_repeatedlyapply_repeatedly1< >4.003sOk 2188timer_simple_SUITEapply_repeatedlyapply_repeatedly2< >3.502sOk 2189timer_simple_SUITEapply_repeatedlyapply_repeatedly_invalid_args< >0.000sOk -timer_simple_SUITEapply_repeatedlyend_per_group< >0.000sOk -timer_simple_SUITEsend_intervalinit_per_group< >0.000sOk +timer_simple_SUITEapply_repeatedlyend_per_group< >0.000sOk +timer_simple_SUITEsend_intervalinit_per_group< >0.000sOk 2190timer_simple_SUITEsend_intervalsend_interval1< >6.003sOk -2191timer_simple_SUITEsend_intervalsend_interval2< >3.002sOk +2191timer_simple_SUITEsend_intervalsend_interval2< >3.003sOk 2192timer_simple_SUITEsend_intervalsend_interval3< >3.003sOk -2193timer_simple_SUITEsend_intervalsend_interval4< >3.002sOk +2193timer_simple_SUITEsend_intervalsend_interval4< >3.003sOk 2194timer_simple_SUITEsend_intervalsend_interval5< >1.103sOk 2195timer_simple_SUITEsend_intervalsend_interval_invalid_args< >0.000sOk -timer_simple_SUITEsend_intervalend_per_group< >0.000sOk -timer_simple_SUITEcancelinit_per_group< >0.000sOk +timer_simple_SUITEsend_intervalend_per_group< >0.000sOk +timer_simple_SUITEcancelinit_per_group< >0.000sOk 2196timer_simple_SUITEcancelcancel1< >0.000sOk 2197timer_simple_SUITEcancelcancel2< >2.001sOk 2198timer_simple_SUITEcancelcancel3< >2.001sOk -2199timer_simple_SUITEcancelcancel4< >1.103sOk +2199timer_simple_SUITEcancelcancel4< >1.102sOk 2200timer_simple_SUITEcancelcancel5< >1.103sOk 2201timer_simple_SUITEcancelcancel6< >2.004sOk 2202timer_simple_SUITEcancelcancel_invalid_args< >0.000sOk -timer_simple_SUITEcancelend_per_group< >0.000sOk -timer_simple_SUITEsleepinit_per_group< >0.000sOk -2203timer_simple_SUITEsleepsleep1< >1.000sOk -2204timer_simple_SUITEsleepsleep2< >1.002sOk -timer_simple_SUITEsleepend_per_group< >0.000sOk -timer_simple_SUITEmiscinit_per_group< >0.000sOk -2205timer_simple_SUITEmisctc< >2.003sOk -2206timer_simple_SUITEmiscunexpected1< >0.601sOk -2207timer_simple_SUITEmiscunexpected2< >0.500sOk -2208timer_simple_SUITEmiscunexpected3< >0.500sOk -2209timer_simple_SUITEmiscnonexistent1< >1.000sOk -2210timer_simple_SUITEmiscnonexistent2< >1.000sOk +timer_simple_SUITEcancelend_per_group< >0.000sOk +timer_simple_SUITEsleepinit_per_group< >0.000sOk +2203timer_simple_SUITEsleepsleep1< >1.001sOk +2204timer_simple_SUITEsleepsleep2< >1.001sOk +timer_simple_SUITEsleepend_per_group< >0.000sOk +timer_simple_SUITEmiscinit_per_group< >0.000sOk +2205timer_simple_SUITEmisctc< >2.004sOk +2206timer_simple_SUITEmiscunexpected1< >0.602sOk +2207timer_simple_SUITEmiscunexpected2< >0.501sOk +2208timer_simple_SUITEmiscunexpected3< >0.501sOk +2209timer_simple_SUITEmiscnonexistent1< >1.001sOk +2210timer_simple_SUITEmiscnonexistent2< >1.001sOk 2211timer_simple_SUITEmisctimer_perf< >51.807sOk -timer_simple_SUITEmiscend_per_group< >0.000sOk +timer_simple_SUITEmiscend_per_group< >0.000sOk timer_simple_SUITEend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk -2212unicode_SUITEutf8_illegal_sequences_bif< >6.022sOk -2213unicode_SUITEutf16_illegal_sequences_bif< >2.149sOk -2214unicode_SUITErandom_lists< >2.499sOk -2215unicode_SUITEroundtrips< >0.424sOk +common_testinit_per_suite< >0.000sOk +2212unicode_SUITEutf8_illegal_sequences_bif< >6.148sOk +2213unicode_SUITEutf16_illegal_sequences_bif< >2.056sOk +2214unicode_SUITErandom_lists< >2.531sOk +2215unicode_SUITEroundtrips< >0.430sOk 2216unicode_SUITElatin1< >0.004sOk 2217unicode_SUITEexceptions< >0.006sOk -2218unicode_SUITEbinaries_errors_limit< >2.117sOk +2218unicode_SUITEbinaries_errors_limit< >2.011sOk 2219unicode_SUITEnormalize< >0.000sOk -common_testbinaries_errorsinit_per_group< >0.000sOkstart of binaries_errors -2220unicode_SUITEbinaries_errorsex_binaries_errors_utf8< >0.633sOk -2221unicode_SUITEbinaries_errorsex_binaries_errors_utf16_little< >2.645sOk -2222unicode_SUITEbinaries_errorsex_binaries_errors_utf16_big< >2.754sOk -2223unicode_SUITEbinaries_errorsex_binaries_errors_utf32_little< >2.714sOk -2224unicode_SUITEbinaries_errorsex_binaries_errors_utf32_big< >2.529sOk -common_testbinaries_errorsend_per_group< >0.000sOkend of binaries_errors +common_testbinaries_errorsinit_per_group< >0.000sOkstart of binaries_errors +2220unicode_SUITEbinaries_errorsex_binaries_errors_utf8< >0.738sOk +2221unicode_SUITEbinaries_errorsex_binaries_errors_utf16_little< >2.738sOk +2222unicode_SUITEbinaries_errorsex_binaries_errors_utf16_big< >2.758sOk +2223unicode_SUITEbinaries_errorsex_binaries_errors_utf32_little< >2.740sOk +2224unicode_SUITEbinaries_errorsex_binaries_errors_utf32_big< >2.368sOk +common_testbinaries_errorsend_per_group< >0.000sOkend of binaries_errors 2225unicode_SUITEhuge_illegal_code_points< >0.000sOk 2226unicode_SUITEerror_info< >0.002sOk -common_testend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk +common_testend_per_suite< >0.000sOk +common_testinit_per_suite< >0.000sOk 2227unicode_util_SUITEextra< >0.000sOk 2228unicode_util_SUITEuppercase< >0.000sOk 2229unicode_util_SUITElowercase< >0.000sOk @@ -2805,16 +2805,16 @@

    Test started at 2024-09-11 11:10:55

    2231unicode_util_SUITEcasefold< >0.000sOk 2232unicode_util_SUITEcp< >0.000sOk 2233unicode_util_SUITEgc< >0.011sOk -2234unicode_util_SUITEnfd< >0.089sOk -2235unicode_util_SUITEnfc< >0.091sOk -2236unicode_util_SUITEnfkd< >0.092sOk -2237unicode_util_SUITEnfkc< >0.097sOk +2234unicode_util_SUITEnfd< >0.093sOk +2235unicode_util_SUITEnfc< >0.094sOk +2236unicode_util_SUITEnfkd< >0.094sOk +2237unicode_util_SUITEnfkc< >0.101sOk 2238unicode_util_SUITEwhitespace< >0.000sOk 2239unicode_util_SUITEget< >0.000sOk -2240unicode_util_SUITElookup< >0.254sOk -2241unicode_util_SUITEcount< >39.695sOk -common_testend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk +2240unicode_util_SUITElookup< >0.273sOk +2241unicode_util_SUITEcount< >40.016sOk +common_testend_per_suite< >0.000sOk +common_testinit_per_suite< >0.000sOk 2242uri_string_SUITEnormalize< >0.000sOk 2243uri_string_SUITEnormalize_map< >0.000sOk 2244uri_string_SUITEnormalize_return_map< >0.000sOk @@ -2886,10 +2886,10 @@

    Test started at 2024-09-11 11:10:55

    2310uri_string_SUITErecompose_host_relative_path< >0.000sOk 2311uri_string_SUITErecompose_host_absolute_path< >0.000sOk 2312uri_string_SUITEquote< >0.000sOk -common_testend_per_suite< >0.000sOk -uri_string_property_test_SUITEinit_per_suite< >1.295sOk -2313uri_string_property_test_SUITErecompose< >0.072sOk -2314uri_string_property_test_SUITEnormalize< >0.092sOk +common_testend_per_suite< >0.000sOk +uri_string_property_test_SUITEinit_per_suite< >1.288sOk +2313uri_string_property_test_SUITErecompose< >0.074sOk +2314uri_string_property_test_SUITEnormalize< >0.080sOk uri_string_property_test_SUITEend_per_suite< >0.000sOk win32reg_SUITEinit_per_suite< >0.000sSKIPPEDDoesn't run on UNIX. 2315win32reg_SUITElong< >0.000sSKIPPEDDoesn't run on UNIX. @@ -2909,144 +2909,144 @@

    Test started at 2024-09-11 11:10:55

    2327y2k_SUITEdate_2001_02_29< >0.000sOk 2328y2k_SUITEdate_2004_02_29< >0.000sOk y2k_SUITEend_per_suite< >0.000sOk -zip_SUITEinit_per_suite< >0.033sOk -2329zip_SUITEborderline< >0.111sOk +zip_SUITEinit_per_suite< >0.034sOk +2329zip_SUITEborderline< >0.107sOk 2330zip_SUITEatomic< >0.004sOk -2331zip_SUITEbad_zip< >0.002sOk +2331zip_SUITEbad_zip< >0.001sOk 2332zip_SUITEunzip_from_binary< >0.004sOk 2333zip_SUITEunzip_to_binary< >0.001sOk 2334zip_SUITEzip_to_binary< >0.001sOk -2335zip_SUITEunzip_options< >0.004sOk +2335zip_SUITEunzip_options< >0.003sOk 2336zip_SUITEzip_options< >0.003sOk -2337zip_SUITElist_dir_options< >0.001sOk +2337zip_SUITElist_dir_options< >0.000sOk 2338zip_SUITEaliases< >0.000sOk 2339zip_SUITEzip_api< >0.003sOk 2340zip_SUITEopen_leak< >0.000sOk -2341zip_SUITEunzip_jar< >0.003sOk -2342zip_SUITEcompress_control< >0.044sOk +2341zip_SUITEunzip_jar< >0.002sOk +2342zip_SUITEcompress_control< >0.029sOk 2343zip_SUITEfoldl< >0.001sOk -2344zip_SUITEunzip_traversal_exploit< >0.008sOk -2345zip_SUITEfd_leak< >1.811sOk -2346zip_SUITEunicode< >0.114sOk +2344zip_SUITEunzip_traversal_exploit< >0.007sOk +2345zip_SUITEfd_leak< >1.885sOk +2346zip_SUITEunicode< >0.118sOk 2347zip_SUITEtest_zip_dir< >0.003sOk 2348zip_SUITEexplicit_file_info< >0.000sOk zip_SUITEzip_groupinit_per_group< >0.000sOk -zip_SUITEzipinit_per_group< >0.000sOk -zip_SUITEunzipinit_per_group< >0.000sOk -2349zip_SUITEunzipmode< >0.009sOk -2350zip_SUITEunzipbasic_timestamp< >2.011sOk -2351zip_SUITEunzipextended_timestamp< >2.012sOk -2352zip_SUITEunzipuid_gid< >0.008sOk +zip_SUITEzipinit_per_group< >0.000sOk +zip_SUITEunzipinit_per_group< >0.000sOk +2349zip_SUITEunzipmode< >0.009sOk +2350zip_SUITEunzipbasic_timestamp< >2.013sOk +2351zip_SUITEunzipextended_timestamp< >2.013sOk +2352zip_SUITEunzipuid_gid< >0.008sOk zip_SUITEunzipend_per_group< >0.001sOk -zip_SUITEunezipinit_per_group< >0.000sOk -2353zip_SUITEunezipmode< >0.007sOk -2354zip_SUITEunezipbasic_timestamp< >2.010sOk -2355zip_SUITEunezipextended_timestamp< >2.009sOk -2356zip_SUITEunezipuid_gid< >0.005sOk -zip_SUITEunezipend_per_group< >0.001sOk -zip_SUITEunemzipinit_per_group< >0.000sOk -2357zip_SUITEunemzipmode< >0.005sOk -2358zip_SUITEunemzipbasic_timestamp< >2.009sOk -2359zip_SUITEunemzipextended_timestamp< >2.010sOk -2360zip_SUITEunemzipuid_gid< >0.004sOk -zip_SUITEunemzipend_per_group< >0.001sOk -zip_SUITEzipend_per_group< >0.001sOk -zip_SUITEezipinit_per_group< >0.000sOk -zip_SUITEunzipinit_per_group< >0.000sOk -2361zip_SUITEunzipmode< >0.006sOk -2362zip_SUITEunzipbasic_timestamp< >2.009sOk -2363zip_SUITEunzipextended_timestamp< >2.010sOk -2364zip_SUITEunzipuid_gid< >0.005sOk -zip_SUITEunzipend_per_group< >0.001sOk -zip_SUITEunezipinit_per_group< >0.000sOk -2365zip_SUITEunezipmode< >0.003sOk -2366zip_SUITEunezipbasic_timestamp< >2.007sOk -2367zip_SUITEunezipextended_timestamp< >2.008sOk -2368zip_SUITEunezipuid_gid< >0.002sOk -zip_SUITEunezipend_per_group< >0.001sOk -zip_SUITEunemzipinit_per_group< >0.000sOk -2369zip_SUITEunemzipmode< >0.003sOk -2370zip_SUITEunemzipbasic_timestamp< >2.006sOk -2371zip_SUITEunemzipextended_timestamp< >2.006sOk -2372zip_SUITEunemzipuid_gid< >0.002sOk -zip_SUITEunemzipend_per_group< >0.001sOk -zip_SUITEezipend_per_group< >0.001sOk -zip_SUITEemzipinit_per_group< >0.000sOk -zip_SUITEunzipinit_per_group< >0.000sOk -2373zip_SUITEunzipmode< >0.005sOk -2374zip_SUITEunzipbasic_timestamp< >2.011sOk -2375zip_SUITEunzipextended_timestamp< >2.010sOk -2376zip_SUITEunzipuid_gid< >0.005sOk -zip_SUITEunzipend_per_group< >0.001sOk -zip_SUITEunezipinit_per_group< >0.000sOk -2377zip_SUITEunezipmode< >0.004sOk -2378zip_SUITEunezipbasic_timestamp< >2.008sOk -2379zip_SUITEunezipextended_timestamp< >2.007sOk -2380zip_SUITEunezipuid_gid< >0.002sOk -zip_SUITEunezipend_per_group< >0.001sOk -zip_SUITEunemzipinit_per_group< >0.000sOk -2381zip_SUITEunemzipmode< >0.003sOk -2382zip_SUITEunemzipbasic_timestamp< >2.007sOk -2383zip_SUITEunemzipextended_timestamp< >2.007sOk -2384zip_SUITEunemzipuid_gid< >0.002sOk -zip_SUITEunemzipend_per_group< >0.001sOk -zip_SUITEemzipend_per_group< >0.001sOk -zip_SUITEzip_groupend_per_group< >0.004sOk -zip_SUITEzip64_groupinit_per_group< >7.950sOk -zip_SUITEz64_zipinit_per_group< >0.000sOk -2385zip_SUITEz64_zipzip64_central_headers< >70.091sOk -zip_SUITEz64_unzipinit_per_group< >0.002sOk -2386zip_SUITEz64_unzipunzip64_central_headers< >98.117sOk -2387zip_SUITEz64_unzipzip64_central_directory< >10.670sOk -zip_SUITEz64_unzipend_per_group< >0.000sOk -zip_SUITEz64_unezipinit_per_group< >0.000sOk -2388zip_SUITEz64_unezipunzip64_central_headers< >75.189sOk -2389zip_SUITEz64_unezipzip64_central_directory< >11.900sOk -zip_SUITEz64_unezipend_per_group< >0.001sOk -zip_SUITEz64_unemzipinit_per_group< >0.000sOk -2390zip_SUITEz64_unemzipunzip64_central_headers< >79.521sOk -2391zip_SUITEz64_unemzipzip64_central_directory< >12.726sOk -zip_SUITEz64_unemzipend_per_group< >0.001sOk -zip_SUITEz64_zipend_per_group< >0.601sOk -zip_SUITEz64_ezipinit_per_group< >0.001sOk -2392zip_SUITEz64_ezipzip64_central_headers< >85.773sOk -zip_SUITEz64_unzipinit_per_group< >0.000sOk -2393zip_SUITEz64_unzipunzip64_central_headers< >117.173sOk -2394zip_SUITEz64_unzipzip64_central_directory< >18.129sOk -zip_SUITEz64_unzipend_per_group< >0.001sOk -zip_SUITEz64_unezipinit_per_group< >0.000sOk -2395zip_SUITEz64_unezipunzip64_central_headers< >83.926sOk -2396zip_SUITEz64_unezipzip64_central_directory< >17.446sOk -zip_SUITEz64_unezipend_per_group< >0.001sOk -zip_SUITEz64_unemzipinit_per_group< >0.000sOk -2397zip_SUITEz64_unemzipunzip64_central_headers< >92.533sOk -2398zip_SUITEz64_unemzipzip64_central_directory< >16.244sOk -zip_SUITEz64_unemzipend_per_group< >0.001sOk -zip_SUITEz64_ezipend_per_group< >0.591sOk -zip_SUITEz64_emzipinit_per_group< >0.001sOk -2399zip_SUITEz64_emzipzip64_central_headers< >99.747sOk -zip_SUITEz64_unzipinit_per_group< >0.000sOk -2400zip_SUITEz64_unzipunzip64_central_headers< >104.971sOk -2401zip_SUITEz64_unzipzip64_central_directory< >14.679sOk -zip_SUITEz64_unzipend_per_group< >0.000sOk -zip_SUITEz64_unezipinit_per_group< >0.000sOk -2402zip_SUITEz64_unezipunzip64_central_headers< >65.772sOk -2403zip_SUITEz64_unezipzip64_central_directory< >16.452sOk -zip_SUITEz64_unezipend_per_group< >0.000sOk -zip_SUITEz64_unemzipinit_per_group< >0.000sOk -2404zip_SUITEz64_unemzipunzip64_central_headers< >91.783sOk -2405zip_SUITEz64_unemzipzip64_central_directory< >17.764sOk -zip_SUITEz64_unemzipend_per_group< >0.001sOk -zip_SUITEz64_emzipend_per_group< >0.514sOk -zip_SUITEzip64_groupend_per_group< >0.201sOk -zip_SUITEend_per_suite< >0.012sOk -common_testinit_per_suite< >0.000sOk +zip_SUITEunezipinit_per_group< >0.000sOk +2353zip_SUITEunezipmode< >0.006sOk +2354zip_SUITEunezipbasic_timestamp< >2.010sOk +2355zip_SUITEunezipextended_timestamp< >2.010sOk +2356zip_SUITEunezipuid_gid< >0.006sOk +zip_SUITEunezipend_per_group< >0.001sOk +zip_SUITEunemzipinit_per_group< >0.000sOk +2357zip_SUITEunemzipmode< >0.006sOk +2358zip_SUITEunemzipbasic_timestamp< >2.011sOk +2359zip_SUITEunemzipextended_timestamp< >2.010sOk +2360zip_SUITEunemzipuid_gid< >0.004sOk +zip_SUITEunemzipend_per_group< >0.001sOk +zip_SUITEzipend_per_group< >0.001sOk +zip_SUITEezipinit_per_group< >0.000sOk +zip_SUITEunzipinit_per_group< >0.000sOk +2361zip_SUITEunzipmode< >0.006sOk +2362zip_SUITEunzipbasic_timestamp< >2.010sOk +2363zip_SUITEunzipextended_timestamp< >2.010sOk +2364zip_SUITEunzipuid_gid< >0.006sOk +zip_SUITEunzipend_per_group< >0.001sOk +zip_SUITEunezipinit_per_group< >0.000sOk +2365zip_SUITEunezipmode< >0.004sOk +2366zip_SUITEunezipbasic_timestamp< >2.009sOk +2367zip_SUITEunezipextended_timestamp< >2.009sOk +2368zip_SUITEunezipuid_gid< >0.003sOk +zip_SUITEunezipend_per_group< >0.001sOk +zip_SUITEunemzipinit_per_group< >0.000sOk +2369zip_SUITEunemzipmode< >0.004sOk +2370zip_SUITEunemzipbasic_timestamp< >2.007sOk +2371zip_SUITEunemzipextended_timestamp< >2.007sOk +2372zip_SUITEunemzipuid_gid< >0.003sOk +zip_SUITEunemzipend_per_group< >0.001sOk +zip_SUITEezipend_per_group< >0.001sOk +zip_SUITEemzipinit_per_group< >0.000sOk +zip_SUITEunzipinit_per_group< >0.000sOk +2373zip_SUITEunzipmode< >0.007sOk +2374zip_SUITEunzipbasic_timestamp< >2.010sOk +2375zip_SUITEunzipextended_timestamp< >2.011sOk +2376zip_SUITEunzipuid_gid< >0.006sOk +zip_SUITEunzipend_per_group< >0.001sOk +zip_SUITEunezipinit_per_group< >0.000sOk +2377zip_SUITEunezipmode< >0.004sOk +2378zip_SUITEunezipbasic_timestamp< >2.009sOk +2379zip_SUITEunezipextended_timestamp< >2.009sOk +2380zip_SUITEunezipuid_gid< >0.003sOk +zip_SUITEunezipend_per_group< >0.001sOk +zip_SUITEunemzipinit_per_group< >0.000sOk +2381zip_SUITEunemzipmode< >0.004sOk +2382zip_SUITEunemzipbasic_timestamp< >2.007sOk +2383zip_SUITEunemzipextended_timestamp< >2.006sOk +2384zip_SUITEunemzipuid_gid< >0.003sOk +zip_SUITEunemzipend_per_group< >0.001sOk +zip_SUITEemzipend_per_group< >0.001sOk +zip_SUITEzip_groupend_per_group< >0.004sOk +zip_SUITEzip64_groupinit_per_group< >7.929sOk +zip_SUITEz64_zipinit_per_group< >0.000sOk +2385zip_SUITEz64_zipzip64_central_headers< >73.311sOk +zip_SUITEz64_unzipinit_per_group< >0.046sOk +2386zip_SUITEz64_unzipunzip64_central_headers< >103.993sOk +2387zip_SUITEz64_unzipzip64_central_directory< >10.132sOk +zip_SUITEz64_unzipend_per_group< >0.000sOk +zip_SUITEz64_unezipinit_per_group< >0.000sOk +2388zip_SUITEz64_unezipunzip64_central_headers< >71.332sOk +2389zip_SUITEz64_unezipzip64_central_directory< >15.916sOk +zip_SUITEz64_unezipend_per_group< >0.001sOk +zip_SUITEz64_unemzipinit_per_group< >0.000sOk +2390zip_SUITEz64_unemzipunzip64_central_headers< >91.950sOk +2391zip_SUITEz64_unemzipzip64_central_directory< >14.803sOk +zip_SUITEz64_unemzipend_per_group< >0.001sOk +zip_SUITEz64_zipend_per_group< >0.490sOk +zip_SUITEz64_ezipinit_per_group< >0.001sOk +2392zip_SUITEz64_ezipzip64_central_headers< >86.386sOk +zip_SUITEz64_unzipinit_per_group< >0.000sOk +2393zip_SUITEz64_unzipunzip64_central_headers< >118.054sOk +2394zip_SUITEz64_unzipzip64_central_directory< >25.374sOk +zip_SUITEz64_unzipend_per_group< >0.001sOk +zip_SUITEz64_unezipinit_per_group< >0.000sOk +2395zip_SUITEz64_unezipunzip64_central_headers< >83.832sOk +2396zip_SUITEz64_unezipzip64_central_directory< >17.085sOk +zip_SUITEz64_unezipend_per_group< >0.001sOk +zip_SUITEz64_unemzipinit_per_group< >0.000sOk +2397zip_SUITEz64_unemzipunzip64_central_headers< >93.423sOk +2398zip_SUITEz64_unemzipzip64_central_directory< >17.702sOk +zip_SUITEz64_unemzipend_per_group< >0.001sOk +zip_SUITEz64_ezipend_per_group< >0.672sOk +zip_SUITEz64_emzipinit_per_group< >0.002sOk +2399zip_SUITEz64_emzipzip64_central_headers< >108.145sOk +zip_SUITEz64_unzipinit_per_group< >0.001sOk +2400zip_SUITEz64_unzipunzip64_central_headers< >106.775sOk +2401zip_SUITEz64_unzipzip64_central_directory< >19.860sOk +zip_SUITEz64_unzipend_per_group< >0.000sOk +zip_SUITEz64_unezipinit_per_group< >0.000sOk +2402zip_SUITEz64_unezipunzip64_central_headers< >74.807sOk +2403zip_SUITEz64_unezipzip64_central_directory< >17.068sOk +zip_SUITEz64_unezipend_per_group< >0.001sOk +zip_SUITEz64_unemzipinit_per_group< >0.000sOk +2404zip_SUITEz64_unemzipunzip64_central_headers< >90.635sOk +2405zip_SUITEz64_unemzipzip64_central_directory< >19.712sOk +zip_SUITEz64_unemzipend_per_group< >0.000sOk +zip_SUITEz64_emzipend_per_group< >0.650sOk +zip_SUITEzip64_groupend_per_group< >0.204sOk +zip_SUITEend_per_suite< >0.016sOk +common_testinit_per_suite< >0.000sOk 2406zzz_SUITElc_graph< >0.001sOk -common_testend_per_suite< >0.000sOk +common_testend_per_suite< >0.000sOk -TOTAL5947.002s
    Ok2358 Ok, 0 Failed, 48 Skipped of 2406
    Elapsed Time: 3113.804s +TOTAL6055.792s
    Ok2358 Ok, 0 Failed, 48 Skipped of 2406
    Elapsed Time: 3178.256s @@ -3057,7 +3057,7 @@

    Test started at 2024-09-11 11:10:55

    | Latest test result

    diff --git a/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/suite.summary b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/suite.summary new file mode 100644 index 0000000000000..027fa5f590de6 --- /dev/null +++ b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/suite.summary @@ -0,0 +1 @@ +{summary,{2358,0,48,0,3178255973}}. diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_projection.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.badstart.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_projection.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.badstart.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_range_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_range_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_specification.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.format_log_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_specification.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.format_log_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_to_relation_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.format_log_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_to_relation_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.format_log_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_union_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_union_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_union_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.mini_die.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.family_union_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.mini_die.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.from_sets_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.mini_terminate.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.from_sets_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.mini_terminate.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.from_term_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.simple_global_supervisor.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.from_term_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.simple_global_supervisor.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.image.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.image.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.init_per_group.19699330.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.starting.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.init_per_group.19699330.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_bridge_suite.starting.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.already_started_outside_supervisor.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.already_started_outside_supervisor.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.child_adm.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.child_adm.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.intersection_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.child_adm_simple.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.intersection_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.child_adm_simple.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.intersection_of_family_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.child_specs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.intersection_of_family_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.child_specs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.inverse_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.child_specs_map.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.inverse_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.child_specs_map.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.inverse_image.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.child_unlink.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.inverse_image.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.child_unlink.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.is_a_function_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.code_change.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.is_a_function_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.code_change.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.is_disjoint.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.code_change_map.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.is_disjoint.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.code_change_map.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.is_equal.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.code_change_simple.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.is_equal.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.code_change_simple.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.is_set_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.code_change_simple_map.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.is_set_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.code_change_simple_map.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.is_sofs_set_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.count_children.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.is_sofs_set_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.count_children.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.is_subset.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.count_children_supervisor.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.is_subset.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.count_children_supervisor.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.join.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.count_restarting_children.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.join.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.count_restarting_children.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.misc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.do_not_save_child_specs_for_temporary_children.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.misc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.do_not_save_child_specs_for_temporary_children.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.multiple_relative_product.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.do_not_save_start_parameters_for_temporary_children.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.multiple_relative_product.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.do_not_save_start_parameters_for_temporary_children.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.no_elements_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.19716610.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.no_elements_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.19716610.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.partition_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.19716674.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.partition_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.19716674.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.partition_3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.19716738.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.partition_3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.19716738.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.partition_family.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.19716802.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.partition_family.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.19716802.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.product_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.19716866.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.product_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.19716866.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.projection.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.19716930.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.projection.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.19716930.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.range_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.19716994.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.range_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.19716994.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.relation_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.19717058.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.relation_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.19717058.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.relation_to_family_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.425924.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.relation_to_family_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.425924.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.relative_product_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.425988.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.relative_product_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.425988.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.relative_product_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.relative_product_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.restriction.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.restriction.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.set_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.external_start_no_progress_log.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.set_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.external_start_no_progress_log.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.specification.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.extra_return.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.specification.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.extra_return.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.faulty_application_shutdown.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.faulty_application_shutdown.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.strict_relation_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.format_log_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.strict_relation_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.format_log_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.substitution.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.format_log_2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.substitution.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.format_log_2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.symdiff.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.get_callback_module.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.symdiff.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.get_callback_module.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.symmetric_partition.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.hanging_restart_loop.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.symmetric_partition.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.hanging_restart_loop.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.to_sets_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.hanging_restart_loop_rest_for_one.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.to_sets_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.hanging_restart_loop_rest_for_one.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.union_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.hanging_restart_loop_simple.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.union_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.hanging_restart_loop_simple.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.union_of_family_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.19716578.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.union_of_family_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.19716578.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.weak_relation_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.19716642.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sofs_suite.weak_relation_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.19716642.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list.19699426.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.19716706.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list.19699426.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.19716706.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list.19699554.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.19716770.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list.19699554.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.19716770.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list.19699682.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.19716834.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list.19699682.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.19716834.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list.19699810.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.19716898.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list.19699810.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.19716898.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.19716962.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.19716962.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list_array.19699458.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.19717026.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list_array.19699458.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.19717026.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list_array.19699586.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.425956.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list_array.19699586.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.425956.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list_array.19699714.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.426020.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list_array.19699714.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.426020.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list_array.19699842.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list_array.19699842.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list_array.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.double_random_to_list_array.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.end_per_group.19699490.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.multiple_restarts.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.end_per_group.19699490.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.multiple_restarts.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.end_per_group.19699618.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.nonsignificant_temporary.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.end_per_group.19699618.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.nonsignificant_temporary.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.end_per_group.19699746.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.nonsignificant_transient.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.end_per_group.19699746.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.nonsignificant_transient.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.end_per_group.19699874.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.one_for_all.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.end_per_group.19699874.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.one_for_all.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.end_per_group.377093.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.one_for_all_escalation.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.end_per_group.377093.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.one_for_all_escalation.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.end_per_group.504003.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.one_for_all_other_child_fails_restart.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.end_per_group.504003.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.one_for_all_other_child_fails_restart.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.one_for_one.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.one_for_one.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.one_for_one_escalation.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.one_for_one_escalation.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.init_per_group.19699394.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.order_of_children.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.init_per_group.19699394.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.order_of_children.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.init_per_group.19699522.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.permanent_abnormal.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.init_per_group.19699522.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.permanent_abnormal.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.init_per_group.19699650.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.permanent_normal.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.init_per_group.19699650.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.permanent_normal.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.init_per_group.19699778.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.permanent_shutdown.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.init_per_group.19699778.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.permanent_shutdown.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.init_per_group.19699906.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.rest_for_one.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.init_per_group.19699906.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.rest_for_one.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.init_per_group.504035.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.rest_for_one_escalation.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.init_per_group.504035.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.rest_for_one_escalation.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.rest_for_one_other_child_fails_restart.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.rest_for_one_other_child_fails_restart.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.scale_start_stop_many_children.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.scale_start_stop_many_children.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.multi_big.504227.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_bystander.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.multi_big.504227.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_bystander.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.multi_big.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_escalation.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.multi_big.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_escalation.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.multi_medium.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_simple.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.multi_medium.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_simple.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.multi_small.504195.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_temporary.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.multi_small.504195.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_temporary.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.multi_small.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_transient.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.multi_small.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_transient.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.sched_big.504163.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_upgrade_all_any.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.sched_big.504163.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_upgrade_all_any.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.sched_big.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_upgrade_all_never.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.sched_big.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_upgrade_all_never.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.sched_medium.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_upgrade_any_all.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.sched_medium.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_upgrade_any_all.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.sched_small.504131.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_upgrade_any_never.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.sched_small.504131.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_upgrade_any_never.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.sched_small.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_upgrade_child.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.sched_small.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_upgrade_child.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.single_big.504099.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_upgrade_never_all.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.single_big.504099.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_upgrade_never_all.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.single_big.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_upgrade_never_any.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.single_big.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.significant_upgrade_never_any.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.single_medium.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.simple_global_supervisor.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.single_medium.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.simple_global_supervisor.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.single_small.504067.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.simple_one_for_one.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.single_small.504067.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.simple_one_for_one.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.single_small.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.simple_one_for_one_corruption.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.single_small.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.simple_one_for_one_corruption.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.simple_one_for_one_escalation.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_bench_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.simple_one_for_one_escalation.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_suite.app_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.simple_one_for_one_extra.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_suite.app_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.simple_one_for_one_extra.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_suite.appup_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.simple_one_for_one_restart_ignore.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_suite.appup_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.simple_one_for_one_restart_ignore.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_suite.assert_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.simple_one_for_one_scale_many_temporary_children.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_suite.assert_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.simple_one_for_one_scale_many_temporary_children.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.simple_one_for_one_shutdown.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.simple_one_for_one_shutdown.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_flags.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/stdlib_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_flags.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.casefold.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_child_returns_error.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.casefold.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_child_returns_error.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.cd_gc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_child_returns_error_simple.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.cd_gc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_child_returns_error_simple.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.centre.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_error_return.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.centre.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_error_return.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.chars.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_fail.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.chars.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_fail.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.chomp.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_ignore_child.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.chomp.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_ignore_child.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.chr_rchr.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_ignore_init.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.chr_rchr.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_ignore_init.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.copies.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_ignore_permanent_child_start_child_simple.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.copies.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_ignore_permanent_child_start_child_simple.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.end_per_group.19699970.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_ignore_temporary_child.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.end_per_group.19699970.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_ignore_temporary_child.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_ignore_temporary_child_start_child.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_ignore_temporary_child_start_child.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_ignore_temporary_child_start_child_simple.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_ignore_temporary_child_start_child_simple.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.equal.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_map.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.equal.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_map.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.find.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_map_faulty_specs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.find.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_map_faulty_specs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.init_per_group.19699938.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_map_simple.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.init_per_group.19699938.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_map_simple.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_normal.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_normal.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_restart_child_returns_error.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_start_restart_child_returns_error.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.is_empty.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_stop_brutal_kill.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.is_empty.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_stop_brutal_kill.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.jaro_similarity.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_stop_brutal_kill_dynamic.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.jaro_similarity.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_stop_brutal_kill_dynamic.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.join.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_stop_infinity.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.join.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_stop_infinity.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.left_right.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_stop_non_shutdown_exit_dynamic.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.left_right.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_stop_non_shutdown_exit_dynamic.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.len.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_stop_race.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.len.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_stop_race.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.length.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_stop_timeout.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.length.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_stop_timeout.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.lexemes.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_stop_timeout_dynamic.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.lexemes.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.sup_stop_timeout_dynamic.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.lowercase.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.temporary_abnormal.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.lowercase.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.temporary_abnormal.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.meas.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.temporary_bystander.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.meas.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.temporary_bystander.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.nth_lexeme.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.temporary_normal.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.nth_lexeme.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.temporary_normal.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.old_concat.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.temporary_shutdown.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.old_concat.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.temporary_shutdown.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.old_equal.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.transient_abnormal.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.old_equal.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.transient_abnormal.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.old_to_float.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.transient_normal.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.old_to_float.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.transient_normal.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.old_to_integer.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.transient_shutdown.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.old_to_integer.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.transient_shutdown.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.old_tokens.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.tree.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.old_tokens.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/supervisor_suite.tree.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.pad.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.pad.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.prefix.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.prefix.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.replace.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.install.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.replace.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.install.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.reverse.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.log.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.reverse.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.log.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.slice.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.log_to_file.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.slice.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.log_to_file.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.span_cspan.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.special_process.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.span_cspan.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.special_process.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.split.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.split.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.stats.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.stats.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.str_rstr.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.suspend.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.str_rstr.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.suspend.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.strip.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.trace.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.strip.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/sys_suite.trace.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.sub_string.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.apply_file_info_opts.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.sub_string.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.apply_file_info_opts.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.sub_word.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.atomic.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.sub_word.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.atomic.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.substr.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.bad_tar.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.substr.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.bad_tar.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.take.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.borderline.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.take.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.borderline.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.titlecase.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.bsdtgz.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.titlecase.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.bsdtgz.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.to_float.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.cooked_compressed.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.to_float.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.cooked_compressed.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.to_graphemes.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.create_long_names.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.to_graphemes.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.create_long_names.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.to_integer.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.dotdot.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.to_integer.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.dotdot.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.to_upper_to_lower.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.to_upper_to_lower.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.trim.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.errors.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.trim.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.errors.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.uppercase.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.extract_filtered.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.uppercase.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.extract_filtered.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.words.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.extract_from_binary.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/string_suite.words.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.extract_from_binary.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.badstart.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.extract_from_binary_compressed.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.badstart.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.extract_from_binary_compressed.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.extract_from_open_file.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.extract_from_open_file.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.format_log_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.incompatible_options.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.format_log_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.incompatible_options.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.format_log_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.init.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.format_log_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.init.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.mini_die.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.leading_slash.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.mini_die.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.leading_slash.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.mini_terminate.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.long_names.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.mini_terminate.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.long_names.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.simple_global_supervisor.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.memory.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.simple_global_supervisor.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.memory.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.open_add_close.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.open_add_close.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.starting.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.read_other_implementations.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_bridge_suite.starting.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.read_other_implementations.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.already_started_outside_supervisor.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.roundtrip_metadata.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.already_started_outside_supervisor.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.roundtrip_metadata.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.child_adm.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.sparse.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.child_adm.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.sparse.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.child_adm_simple.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.child_adm_simple.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.child_specs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.symlinks.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.child_specs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.symlinks.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.child_specs_map.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.unicode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.child_specs_map.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/tar_suite.unicode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.child_unlink.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_after1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.child_unlink.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_after1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.code_change.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_after2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.code_change.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_after2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.code_change_map.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_after3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.code_change_map.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_after3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.code_change_simple.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_after4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.code_change_simple.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_after4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.code_change_simple_map.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_after_invalid_args.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.code_change_simple_map.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_after_invalid_args.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.count_children.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_interval1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.count_children.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_interval1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.count_children_supervisor.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_interval2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.count_children_supervisor.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_interval2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.count_restarting_children.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_interval_invalid_args.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.count_restarting_children.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_interval_invalid_args.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.do_not_save_child_specs_for_temporary_children.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_repeatedly1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.do_not_save_child_specs_for_temporary_children.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_repeatedly1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.do_not_save_start_parameters_for_temporary_children.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_repeatedly2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.do_not_save_start_parameters_for_temporary_children.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_repeatedly2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.19700002.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_repeatedly_invalid_args.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.19700002.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.apply_repeatedly_invalid_args.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.19700066.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.cancel1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.19700066.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.cancel1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.19700130.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.cancel2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.19700130.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.cancel2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.19700194.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.cancel3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.19700194.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.cancel3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.19700226.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.cancel4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.19700226.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.cancel4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.19700290.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.cancel5.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.19700290.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.cancel5.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.19700322.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.cancel6.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.19700322.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.cancel6.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.504291.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.cancel_invalid_args.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.504291.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.cancel_invalid_args.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.504387.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717346.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.504387.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717346.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.504451.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717410.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.504451.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717410.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717474.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717474.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717538.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717538.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.external_start_no_progress_log.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717602.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.external_start_no_progress_log.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717602.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.extra_return.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717666.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.extra_return.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717666.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.faulty_application_shutdown.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717730.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.faulty_application_shutdown.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717730.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.format_log_1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717794.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.format_log_1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717794.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.format_log_2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717858.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.format_log_2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.19717858.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.get_callback_module.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.get_callback_module.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.hanging_restart_loop.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.hanging_restart_loop.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.hanging_restart_loop_rest_for_one.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.exit_after1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.hanging_restart_loop_rest_for_one.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.exit_after1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.hanging_restart_loop_simple.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.exit_after2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.hanging_restart_loop_simple.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.exit_after2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.19700034.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.exit_after3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.19700034.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.exit_after3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.19700098.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.exit_after4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.19700098.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.exit_after4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.19700162.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717314.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.19700162.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717314.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.19700258.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717378.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.19700258.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717378.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.504259.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717442.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.504259.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717442.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.504323.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717506.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.504323.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717506.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.504355.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717570.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.504355.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717570.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.504419.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717634.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.504419.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717634.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.504483.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717698.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.504483.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717698.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.504515.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717762.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.504515.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717762.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717826.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.19717826.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.multiple_restarts.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.multiple_restarts.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.nonsignificant_temporary.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.kill_after1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.nonsignificant_temporary.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.kill_after1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.nonsignificant_transient.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.kill_after2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.nonsignificant_transient.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.kill_after2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.one_for_all.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.kill_after3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.one_for_all.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.kill_after3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.one_for_all_escalation.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.nonexistent1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.one_for_all_escalation.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.nonexistent1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.one_for_all_other_child_fails_restart.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.nonexistent2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.one_for_all_other_child_fails_restart.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.nonexistent2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.one_for_one.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_after1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.one_for_one.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_after1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.one_for_one_escalation.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_after2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.one_for_one_escalation.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_after2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.order_of_children.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_after3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.order_of_children.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_after3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.permanent_abnormal.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_after4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.permanent_abnormal.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_after4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.permanent_normal.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_after5.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.permanent_normal.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_after5.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.permanent_shutdown.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_after6.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.permanent_shutdown.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_after6.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.rest_for_one.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_after7.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.rest_for_one.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_after7.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.rest_for_one_escalation.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_after_invalid_args.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.rest_for_one_escalation.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_after_invalid_args.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.rest_for_one_other_child_fails_restart.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_interval1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.rest_for_one_other_child_fails_restart.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_interval1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.scale_start_stop_many_children.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_interval2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.scale_start_stop_many_children.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_interval2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_bystander.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_interval3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_bystander.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_interval3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_escalation.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_interval4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_escalation.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_interval4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_simple.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_interval5.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_simple.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_interval5.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_temporary.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_interval_invalid_args.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_temporary.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.send_interval_invalid_args.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_transient.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.sleep1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_transient.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.sleep1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_upgrade_all_any.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.sleep2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_upgrade_all_any.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.sleep2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_upgrade_all_never.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_upgrade_all_never.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_upgrade_any_all.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.tc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_upgrade_any_all.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.tc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_upgrade_any_never.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.timer_perf.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_upgrade_any_never.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.timer_perf.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_upgrade_child.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.unexpected1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_upgrade_child.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.unexpected1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_upgrade_never_all.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.unexpected2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_upgrade_never_all.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.unexpected2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_upgrade_never_any.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.unexpected3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.significant_upgrade_never_any.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_simple_suite.unexpected3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.simple_global_supervisor.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_suite.do_big_test.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.simple_global_supervisor.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_suite.do_big_test.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.simple_one_for_one.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.simple_one_for_one.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.simple_one_for_one_corruption.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.simple_one_for_one_corruption.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.simple_one_for_one_escalation.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.simple_one_for_one_escalation.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/timer_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unexpected_io.log.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unexpected_io.log.html similarity index 58% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unexpected_io.log.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unexpected_io.log.html index 8d38858d39efb..428fccf1fdcc8 100644 --- a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unexpected_io.log.html +++ b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unexpected_io.log.html @@ -16,38 +16,14 @@

    Unexpected I/O

     
     
    -
    *** System report during gen_server_SUITE:abcast/1 2024-09-11 11:19:58.248 ***
    -=CRASH REPORT==== 11-Sep-2024::11:19:58.248249 ===
    -  crasher:
    -    initial call: gen_server_SUITE:init/1
    -    pid: <0.243992.0>
    -    registered_name: my_test_name
    -    exception exit: {<0.243990.0>,stopped}
    -      in function  gen_server:handle_common_reply/8 (gen_server.erl, line 2476)
    -    ancestors: [<0.243990.0>]
    -    message_queue_len: 0
    -    messages: []
    -    links: []
    -    dictionary: []
    -    trap_exit: false
    -    status: running
    -    heap_size: 2586
    -    stack_size: 29
    -    reductions: 3453
    -  neighbours:
    -
    -
    -
    -
    -
    -
    *** System report during multi_call_parallel in gen_server_SUITE 2024-09-11 11:20:00.347 ***
    -=ERROR REPORT==== 11-Sep-2024::11:20:00.347801 ===
    +
    *** System report during multi_call_parallel in gen_server_SUITE 2024-09-12 10:42:11.305 ***
    +=ERROR REPORT==== 12-Sep-2024::10:42:11.305603 ===
     ** Generic server my_test_name terminating 
     ** Last message in was stop
     ** When Server state == {formatted,[]}
     ** Reason for termination ==
     ** stopped
    -** Client <0.244017.0> stacktrace
    +** Client <0.244118.0> stacktrace
     ** [{gen_server,mc_recv,5,[{file,"gen_server.erl"},{line,1973}]},
         {gen_server,multi_call,4,[{file,"gen_server.erl"},{line,1934}]},
         {gen_server_SUITE,multicall,1,[{file,"gen_server_SUITE.erl"},{line,1487}]},
    @@ -59,18 +35,18 @@ 

    Unexpected I/O

     
    -
    *** System report during multi_call_parallel in gen_server_SUITE 2024-09-11 11:20:00.348 ***
    -=CRASH REPORT==== 11-Sep-2024::11:20:00.348266 ===
    +
    *** System report during multi_call_parallel in gen_server_SUITE 2024-09-12 10:42:11.306 ***
    +=CRASH REPORT==== 12-Sep-2024::10:42:11.306117 ===
       crasher:
         initial call: gen_server_SUITE:init/1
    -    pid: <0.244020.0>
    +    pid: <0.244125.0>
         registered_name: my_test_name
         exception exit: stopped
           in function  gen_server:handle_msg/6 (gen_server.erl, line 2426)
    -    ancestors: [<0.244017.0>]
    +    ancestors: [<0.244118.0>]
         message_queue_len: 0
         messages: []
    -    links: [<0.244017.0>]
    +    links: [<0.244118.0>]
         dictionary: []
         trap_exit: false
         status: running
    @@ -83,17 +59,17 @@ 

    Unexpected I/O

     
    -
    *** System report during gen_server_SUITE:spec_init/1 2024-09-11 11:20:40.224 ***
    -=ERROR REPORT==== 11-Sep-2024::11:20:40.224564 ===
    +
    *** System report during gen_server_SUITE:spec_init/1 2024-09-12 10:42:51.106 ***
    +=ERROR REPORT==== 12-Sep-2024::10:42:51.106044 ===
     ** Generic server hurra terminating 
    -** Last message in was {'EXIT',<0.248368.0>,
    -                               {#Ref<0.513239895.2896429057.249864>,1007658,
    +** Last message in was {'EXIT',<0.248471.0>,
    +                               {#Ref<0.3436431406.2308440065.58455>,1010937,
                                     ok,
                                     [{gen_server_SUITE,spec_init}],
                                     []}}
     ** When Server state == {formatted,{}}
     ** Reason for termination ==
    -** {#Ref<0.513239895.2896429057.249864>,1007658,ok,
    +** {#Ref<0.3436431406.2308440065.58455>,1010937,ok,
         [{gen_server_SUITE,spec_init}],
         []}
     
    @@ -101,17 +77,17 @@ 

    Unexpected I/O

     
    -
    *** System report during gen_server_SUITE:spec_init/1 2024-09-11 11:20:40.225 ***
    -=CRASH REPORT==== 11-Sep-2024::11:20:40.224899 ===
    +
    *** System report during gen_server_SUITE:spec_init/1 2024-09-12 10:42:51.106 ***
    +=CRASH REPORT==== 12-Sep-2024::10:42:51.106406 ===
       crasher:
         initial call: gen_server_SUITE:spec_init_global_default_timeout/2
    -    pid: <0.248389.0>
    +    pid: <0.248492.0>
         registered_name: []
    -    exception exit: {#Ref<0.513239895.2896429057.249864>,1007658,ok,
    +    exception exit: {#Ref<0.3436431406.2308440065.58455>,1010937,ok,
                          [{gen_server_SUITE,spec_init}],
                          []}
           in function  gen_server:decode_msg/9 (gen_server.erl, line 2299)
    -    ancestors: [<0.248368.0>]
    +    ancestors: [<0.248471.0>]
         message_queue_len: 0
         messages: []
         links: []
    @@ -127,72 +103,72 @@ 

    Unexpected I/O

     
    -
    *** System report during log_mf_h_SUITE:test/1 2024-09-11 11:25:15.463 ***
    -=CRASH REPORT==== 11-Sep-2024::11:25:15.463695 ===
    +
    *** System report during log_mf_h_SUITE:test/1 2024-09-12 10:47:26.801 ***
    +=CRASH REPORT==== 12-Sep-2024::10:47:26.801589 ===
       crasher:
         initial call: gen_event:init_it/6
    -    pid: <0.254153.0>
    +    pid: <0.254256.0>
         registered_name: []
    -    exception exit: {#Ref<0.513239895.2898001921.12538>,6364,
    +    exception exit: {#Ref<0.3436431406.2309750785.143076>,6247,
                          {ok,3},
                          [{log_mf_h_SUITE,test}],
                          []}
           in function  gen_event:terminate_server/4 (gen_event.erl, line 1694)
    -    ancestors: [<0.254151.0>]
    +    ancestors: [<0.254254.0>]
         message_queue_len: 0
         messages: []
         links: []
         dictionary: []
         trap_exit: true
         status: running
    -    heap_size: 4185
    +    heap_size: 6772
         stack_size: 29
    -    reductions: 28657
    +    reductions: 28119
       neighbours:
     
     
     
     
    -
    *** System report during dist in peer_SUITE 2024-09-11 11:25:24.425 ***
    -=ERROR REPORT==== 11-Sep-2024::11:25:24.425599 ===
    -** Generic server <0.255439.0> terminating 
    -** Last message in was {nodedown,'peer_down_crash-499971-11743@43e13ac1be0c'}
    +
    *** System report during dist in peer_SUITE 2024-09-12 10:47:35.838 ***
    +=ERROR REPORT==== 12-Sep-2024::10:47:35.837910 ===
    +** Generic server <0.255544.0> terminating 
    +** Last message in was {nodedown,'peer_down_crash-427717-11810@7a1fde2d1d55'}
     ** When Server state == {peer_state,
                                 #{args => ["-connect_all","false"],
    -                              name => "peer_down_crash-499971-11743",
    +                              name => "peer_down_crash-427717-11810",
                                   peer_down => crash},
    -                            'peer_down_crash-499971-11743@43e13ac1be0c',
    +                            'peer_down_crash-427717-11810@7a1fde2d1d55',
                                 [47,98,117,105,108,100,114,111,111,116,47,111,116,
                                  112,47,69,114,108,97,110,103,32,8709,8868,8478,
                                  47,101,114,116,115,45,49,53,46,48,46,49,47,98,
                                  105,110,47,101,114,108],
    -                            ["-sname","peer_down_crash-499971-11743",
    +                            ["-sname","peer_down_crash-427717-11810",
                                  "-connect_all","false","-detached",
                                  "-peer_detached","-user","peer","-origin",
    -                             "g1h3GHRlc3Rfc2VydmVyQDQzZTEzYWMxYmUwYwAD5c8AAAAAZuFeew=="],
    +                             "g1h3GHRlc3Rfc2VydmVyQDdhMWZkZTJkMWQ1NQAD5jgAAAAAZuKnGA=="],
                                 undefined,undefined,<<>>,
                                 {down,
                                     {nodedown,
    -                                    'peer_down_crash-499971-11743@43e13ac1be0c'}},
    -                            {<0.255416.0>,#Ref<0.513239895.2891186178.34938>},
    +                                    'peer_down_crash-427717-11810@7a1fde2d1d55'}},
    +                            {<0.255521.0>,#Ref<0.3436431406.2302410756.80599>},
                                 0,#{}}
     ** Reason for termination ==
    -** {nodedown,'peer_down_crash-499971-11743@43e13ac1be0c'}
    +** {nodedown,'peer_down_crash-427717-11810@7a1fde2d1d55'}
     
     
     
     
    -
    *** System report during dist in peer_SUITE 2024-09-11 11:25:24.426 ***
    -=CRASH REPORT==== 11-Sep-2024::11:25:24.426038 ===
    +
    *** System report during dist in peer_SUITE 2024-09-12 10:47:35.838 ***
    +=CRASH REPORT==== 12-Sep-2024::10:47:35.838438 ===
       crasher:
         initial call: peer:init/1
    -    pid: <0.255439.0>
    +    pid: <0.255544.0>
         registered_name: []
    -    exception exit: {nodedown,'peer_down_crash-499971-11743@43e13ac1be0c'}
    +    exception exit: {nodedown,'peer_down_crash-427717-11810@7a1fde2d1d55'}
           in function  gen_server:handle_common_reply/8 (gen_server.erl, line 2476)
    -    ancestors: [<0.255416.0>]
    +    ancestors: [<0.255521.0>]
         message_queue_len: 0
         messages: []
         links: []
    @@ -201,16 +177,16 @@ 

    Unexpected I/O

    status: running heap_size: 6772 stack_size: 29 - reductions: 11230 + reductions: 11232 neighbours:
     
    -
    *** System report during dist in peer_SUITE 2024-09-11 11:25:25.297 ***
    -=WARNING REPORT==== 11-Sep-2024::11:25:24.295693 ===
    -Process <0.91.0> on node 'peer_SUITE-shutdown_stop-397060-11743@43e13ac1be0c' enabled access to the emulator internal state.
    +
    *** System report during dist in peer_SUITE 2024-09-12 10:47:36.832 ***
    +=WARNING REPORT==== 12-Sep-2024::10:47:35.830536 ===
    +Process <0.91.0> on node 'peer_SUITE-shutdown_stop-497890-11810@7a1fde2d1d55' enabled access to the emulator internal state.
     NOTE: This is an erts internal test feature and should *only* be used by OTP test-suites.
     
     
    @@ -218,23 +194,23 @@ 

    Unexpected I/O

     
    -
    *** System report during dist in peer_SUITE 2024-09-11 11:25:25.830 ***
    -=WARNING REPORT==== 11-Sep-2024::11:25:25.830613 ===
    -peer:stop() timed out waiting for disconnect from node 'peer_SUITE-shutdown_stop_timeout-500131-11743@43e13ac1be0c'. The connection was forcefully taken down.
    +
    *** System report during dist in peer_SUITE 2024-09-12 10:47:37.356 ***
    +=WARNING REPORT==== 12-Sep-2024::10:47:37.356541 ===
    +peer:stop() timed out waiting for disconnect from node 'peer_SUITE-shutdown_halt_timeout-497826-11810@7a1fde2d1d55'. The connection was forcefully taken down.
     
     
     
    -
    *** System report during dist in peer_SUITE 2024-09-11 11:25:25.955 ***
    -=WARNING REPORT==== 11-Sep-2024::11:25:25.955014 ===
    -peer:stop() timed out waiting for disconnect from node 'peer_SUITE-shutdown_halt_timeout-500067-11743@43e13ac1be0c'. The connection was forcefully taken down.
    +
    *** System report during dist in peer_SUITE 2024-09-12 10:47:37.365 ***
    +=WARNING REPORT==== 12-Sep-2024::10:47:37.365497 ===
    +peer:stop() timed out waiting for disconnect from node 'peer_SUITE-shutdown_stop_timeout-405219-11810@7a1fde2d1d55'. The connection was forcefully taken down.
     
     
     
    -
    *** System report during tcp in peer_SUITE 2024-09-11 11:25:41.387 ***
    -=WARNING REPORT==== 11-Sep-2024::11:25:40.386026 ===
    -Process <0.88.0> on node 'peer_SUITE-shutdown_stop-482050-11743@43e13ac1be0c' enabled access to the emulator internal state.
    +
    *** System report during tcp in peer_SUITE 2024-09-12 10:47:52.691 ***
    +=WARNING REPORT==== 12-Sep-2024::10:47:51.689472 ===
    +Process <0.88.0> on node 'peer_SUITE-shutdown_stop-498338-11810@7a1fde2d1d55' enabled access to the emulator internal state.
     NOTE: This is an erts internal test feature and should *only* be used by OTP test-suites.
     
     
    @@ -242,45 +218,46 @@ 

    Unexpected I/O

     
    -
    *** System report during tcp in peer_SUITE 2024-09-11 11:25:41.782 ***
    -=WARNING REPORT==== 11-Sep-2024::11:25:41.782045 ===
    -peer:stop() timed out waiting for disconnect from node 'peer_SUITE-shutdown_stop_timeout-500803-11743@43e13ac1be0c'. The connection was forcefully taken down.
    +
    *** System report during tcp in peer_SUITE 2024-09-12 10:47:53.013 ***
    +=WARNING REPORT==== 12-Sep-2024::10:47:53.013657 ===
    +peer:stop() timed out waiting for disconnect from node 'peer_SUITE-shutdown_stop_timeout-405443-11810@7a1fde2d1d55'. The connection was forcefully taken down.
     
     
     
    -
    *** System report during tcp in peer_SUITE 2024-09-11 11:25:41.943 ***
    -=WARNING REPORT==== 11-Sep-2024::11:25:41.942984 ===
    -peer:stop() timed out waiting for disconnect from node 'peer_SUITE-shutdown_halt_timeout-500707-11743@43e13ac1be0c'. The connection was forcefully taken down.
    +
    *** System report during tcp in peer_SUITE 2024-09-12 10:47:53.057 ***
    +=WARNING REPORT==== 12-Sep-2024::10:47:53.057469 ===
    +peer:stop() timed out waiting for disconnect from node 'peer_SUITE-shutdown_halt_timeout-405315-11810@7a1fde2d1d55'. The connection was forcefully taken down.
     
     
     
    -
    *** System report during standard_io in peer_SUITE 2024-09-11 11:25:43.941 ***
    -=ERROR REPORT==== 11-Sep-2024::11:25:43.941668 ===
    -** Generic server <0.255801.0> terminating 
    -** Last message in was {'EXIT',<0.255781.0>,
    -                               {#Ref<0.513239895.2890661892.33376>,1465955,ok,
    +
    *** System report during standard_io in peer_SUITE 2024-09-12 10:47:55.313 ***
    +=ERROR REPORT==== 12-Sep-2024::10:47:55.313337 ===
    +** Generic server <0.255892.0> terminating 
    +** Last message in was {'EXIT',<0.255886.0>,
    +                               {#Ref<0.3436431406.2302672899.170465>,1527306,
    +                                ok,
                                     [{peer_SUITE,cntrl_channel_handler_crash}],
                                     []}}
     ** When Server state == {peer_state,#{name =>
    -                                          "peer_SUITE-cntrl_channel_handler_crash-375781-11743",
    +                                          "peer_SUITE-cntrl_channel_handler_crash-423684-11810",
                                           connection => standard_io},
    -                                    'peer_SUITE-cntrl_channel_handler_crash-375781-11743@43e13ac1be0c',
    +                                    'peer_SUITE-cntrl_channel_handler_crash-423684-11810@7a1fde2d1d55',
                                         [47,98,117,105,108,100,114,111,111,116,47,
                                          111,116,112,47,69,114,108,97,110,103,32,
                                          8709,8868,8478,47,101,114,116,115,45,49,
                                          53,46,48,46,49,47,98,105,110,47,101,114,
                                          108],
                                         ["-sname",
    -                                     "peer_SUITE-cntrl_channel_handler_crash-375781-11743",
    +                                     "peer_SUITE-cntrl_channel_handler_crash-423684-11810",
                                          "-user","peer"],
    -                                    #Port<0.3122>,undefined,<<>>,running,
    -                                    {<0.255781.0>,
    -                                     #Ref<0.513239895.2890661892.33710>},
    +                                    #Port<0.3118>,undefined,<<>>,running,
    +                                    {<0.255886.0>,
    +                                     #Ref<0.3436431406.2302672899.170595>},
                                         0,#{}}
     ** Reason for termination ==
    -** {#Ref<0.513239895.2890661892.33376>,1465955,ok,
    +** {#Ref<0.3436431406.2302672899.170465>,1527306,ok,
         [{peer_SUITE,cntrl_channel_handler_crash}],
         []}
     
    @@ -288,73 +265,73 @@ 

    Unexpected I/O

     
    -
    *** System report during standard_io in peer_SUITE 2024-09-11 11:25:43.943 ***
    -=CRASH REPORT==== 11-Sep-2024::11:25:43.943322 ===
    +
    *** System report during standard_io in peer_SUITE 2024-09-12 10:47:55.314 ***
    +=CRASH REPORT==== 12-Sep-2024::10:47:55.313896 ===
       crasher:
         initial call: peer:init/1
    -    pid: <0.255801.0>
    +    pid: <0.255892.0>
         registered_name: []
    -    exception exit: {#Ref<0.513239895.2890661892.33376>,1465955,ok,
    +    exception exit: {#Ref<0.3436431406.2302672899.170465>,1527306,ok,
                          [{peer_SUITE,cntrl_channel_handler_crash}],
                          []}
           in function  gen_server:decode_msg/9 (gen_server.erl, line 2299)
    -    ancestors: [<0.255781.0>]
    +    ancestors: [<0.255886.0>]
         message_queue_len: 1
    -    messages: [{'EXIT',#Port<0.3122>,normal}]
    +    messages: [{'EXIT',#Port<0.3118>,normal}]
         links: []
         dictionary: []
         trap_exit: true
         status: running
    -    heap_size: 2586
    +    heap_size: 4185
         stack_size: 29
    -    reductions: 13809
    +    reductions: 13993
       neighbours:
     
     
     
     
    -
    *** System report during standard_io in peer_SUITE 2024-09-11 11:25:44.551 ***
    -=ERROR REPORT==== 11-Sep-2024::11:25:44.551406 ===
    -** Generic server <0.255824.0> terminating 
    -** Last message in was {'EXIT',<0.255784.0>,
    -                           {#Ref<0.513239895.2890661892.33432>,2074408,ok,
    +
    *** System report during standard_io in peer_SUITE 2024-09-12 10:47:55.910 ***
    +=ERROR REPORT==== 12-Sep-2024::10:47:55.909710 ===
    +** Generic server <0.255927.0> terminating 
    +** Last message in was {'EXIT',<0.255890.0>,
    +                           {#Ref<0.3436431406.2303197186.10081>,2122944,ok,
                                 [{peer_SUITE,
                                      cntrl_channel_handler_crash_old_release}],
                                 []}}
     ** When Server state == {peer_state,#{args =>
                                               ["-setcookie",
    -                                           "SLBZTKMFSLKEULNNNCEK","-pa",
    +                                           "GQFRJKBXLTEOKPQLYCNW","-pa",
                                                "/buildroot/otp/lib/stdlib/make_test_dir/stdlib_test",
                                                "-env","ERL_CRASH_DUMP",
    -                                           "/buildroot/otp/lib/stdlib/make_test_dir/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/erl_crash_dump.peer_SUITE-cntrl_channel_handler_crash_old_release-375941-11743",
    +                                           "/buildroot/otp/lib/stdlib/make_test_dir/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/erl_crash_dump.peer_SUITE-cntrl_channel_handler_crash_old_release-423748-11810",
                                                "-pa",
    -                                           "/buildroot/otp/lib/stdlib/make_test_dir/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/log_private/"],
    +                                           "/buildroot/otp/lib/stdlib/make_test_dir/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/log_private/"],
                                           env => [{"ERL_AFLAGS",false}],
                                           name =>
    -                                          "peer_SUITE-cntrl_channel_handler_crash_old_release-375941-11743",
    +                                          "peer_SUITE-cntrl_channel_handler_crash_old_release-423748-11810",
                                           connection => standard_io,
                                           exec =>
                                               "/usr/local/lib/erlang-26.2.5.3/bin/erl",
                                           start_cover => false},
    -                                    'peer_SUITE-cntrl_channel_handler_crash_old_release-375941-11743@43e13ac1be0c',
    +                                    'peer_SUITE-cntrl_channel_handler_crash_old_release-423748-11810@7a1fde2d1d55',
                                         "/usr/local/lib/erlang-26.2.5.3/bin/erl",
                                         ["-sname",
    -                                     "peer_SUITE-cntrl_channel_handler_crash_old_release-375941-11743",
    -                                     "-setcookie","SLBZTKMFSLKEULNNNCEK",
    +                                     "peer_SUITE-cntrl_channel_handler_crash_old_release-423748-11810",
    +                                     "-setcookie","GQFRJKBXLTEOKPQLYCNW",
                                          "-pa",
                                          "/buildroot/otp/lib/stdlib/make_test_dir/stdlib_test",
                                          "-env","ERL_CRASH_DUMP",
    -                                     "/buildroot/otp/lib/stdlib/make_test_dir/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/erl_crash_dump.peer_SUITE-cntrl_channel_handler_crash_old_release-375941-11743",
    +                                     "/buildroot/otp/lib/stdlib/make_test_dir/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/erl_crash_dump.peer_SUITE-cntrl_channel_handler_crash_old_release-423748-11810",
                                          "-pa",
    -                                     "/buildroot/otp/lib/stdlib/make_test_dir/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/log_private/",
    +                                     "/buildroot/otp/lib/stdlib/make_test_dir/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/log_private/",
                                          "-user","peer"],
    -                                    #Port<0.3146>,undefined,<<>>,running,
    -                                    {<0.255784.0>,
    -                                     #Ref<0.513239895.2890661892.34243>},
    +                                    #Port<0.3144>,undefined,<<>>,running,
    +                                    {<0.255890.0>,
    +                                     #Ref<0.3436431406.2309750785.163069>},
                                         0,#{}}
     ** Reason for termination ==
    -** {#Ref<0.513239895.2890661892.33432>,2074408,ok,
    +** {#Ref<0.3436431406.2303197186.10081>,2122944,ok,
         [{peer_SUITE,cntrl_channel_handler_crash_old_release}],
         []}
     
    @@ -362,35 +339,35 @@ 

    Unexpected I/O

     
    -
    *** System report during standard_io in peer_SUITE 2024-09-11 11:25:44.552 ***
    -=CRASH REPORT==== 11-Sep-2024::11:25:44.552377 ===
    +
    *** System report during standard_io in peer_SUITE 2024-09-12 10:47:55.910 ***
    +=CRASH REPORT==== 12-Sep-2024::10:47:55.910404 ===
       crasher:
         initial call: peer:init/1
    -    pid: <0.255824.0>
    +    pid: <0.255927.0>
         registered_name: []
    -    exception exit: {#Ref<0.513239895.2890661892.33432>,2074408,ok,
    +    exception exit: {#Ref<0.3436431406.2303197186.10081>,2122944,ok,
                          [{peer_SUITE,cntrl_channel_handler_crash_old_release}],
                          []}
           in function  gen_server:decode_msg/9 (gen_server.erl, line 2299)
    -    ancestors: [<0.255784.0>]
    +    ancestors: [<0.255890.0>]
         message_queue_len: 1
    -    messages: [{'EXIT',#Port<0.3146>,normal}]
    +    messages: [{'EXIT',#Port<0.3144>,normal}]
         links: []
         dictionary: []
         trap_exit: true
         status: running
         heap_size: 10958
         stack_size: 29
    -    reductions: 20913
    +    reductions: 20920
       neighbours:
     
     
     
     
    -
    *** System report during standard_io in peer_SUITE 2024-09-11 11:25:44.950 ***
    -=WARNING REPORT==== 11-Sep-2024::11:25:43.949050 ===
    -Process <0.88.0> on node 'peer_SUITE-shutdown_stop-397476-11743@43e13ac1be0c' enabled access to the emulator internal state.
    +
    *** System report during standard_io in peer_SUITE 2024-09-12 10:47:56.296 ***
    +=WARNING REPORT==== 12-Sep-2024::10:47:55.294657 ===
    +Process <0.88.0> on node 'peer_SUITE-shutdown_stop-498594-11810@7a1fde2d1d55' enabled access to the emulator internal state.
     NOTE: This is an erts internal test feature and should *only* be used by OTP test-suites.
     
     
    @@ -398,50 +375,50 @@ 

    Unexpected I/O

     
    -
    *** System report during standard_io in peer_SUITE 2024-09-11 11:25:45.214 ***
    -=WARNING REPORT==== 11-Sep-2024::11:25:45.214047 ===
    -peer:stop() timed out waiting for disconnect from node 'init_debug-397380-11743@43e13ac1be0c'. The connection was forcefully taken down.
    +
    *** System report during standard_io in peer_SUITE 2024-09-12 10:47:56.465 ***
    +=WARNING REPORT==== 12-Sep-2024::10:47:56.465660 ===
    +peer:stop() timed out waiting for disconnect from node 'init_debug-405955-11810@7a1fde2d1d55'. The connection was forcefully taken down.
     
     
     
    -
    *** System report during standard_io in peer_SUITE 2024-09-11 11:25:45.299 ***
    -=WARNING REPORT==== 11-Sep-2024::11:25:45.298976 ===
    -peer:stop() timed out waiting for disconnect from node 'peer_SUITE-shutdown_stop_timeout-375909-11743@43e13ac1be0c'. The connection was forcefully taken down.
    +
    *** System report during standard_io in peer_SUITE 2024-09-12 10:47:56.720 ***
    +=WARNING REPORT==== 12-Sep-2024::10:47:56.720590 ===
    +peer:stop() timed out waiting for disconnect from node 'peer_SUITE-shutdown_stop_timeout-498562-11810@7a1fde2d1d55'. The connection was forcefully taken down.
     
     
     
    -
    *** System report during standard_io in peer_SUITE 2024-09-11 11:25:45.365 ***
    -=WARNING REPORT==== 11-Sep-2024::11:25:45.365029 ===
    -peer:stop() timed out waiting for disconnect from node 'peer_SUITE-shutdown_halt_timeout-375749-11743@43e13ac1be0c'. The connection was forcefully taken down.
    +
    *** System report during standard_io in peer_SUITE 2024-09-12 10:47:56.821 ***
    +=WARNING REPORT==== 12-Sep-2024::10:47:56.821534 ===
    +peer:stop() timed out waiting for disconnect from node 'peer_SUITE-shutdown_halt_timeout-498626-11810@7a1fde2d1d55'. The connection was forcefully taken down.
     
     
     
    -
    *** System report during supervisor_SUITE:temporary_bystander/1 2024-09-11 11:36:28.463 ***
    -=ERROR REPORT==== 11-Sep-2024::11:36:28.463228 ===
    -** Generic server <0.302528.0> terminating 
    -** Last message in was {'EXIT',<0.302525.0>,
    -                               {#Ref<0.513239895.2907176962.121021>,350759,
    -                                [{child1,<0.302534.0>,worker,[]}],
    +
    *** System report during supervisor_SUITE:temporary_bystander/1 2024-09-12 10:58:40.429 ***
    +=ERROR REPORT==== 12-Sep-2024::10:58:40.428950 ===
    +** Generic server <0.302631.0> terminating 
    +** Last message in was {'EXIT',<0.302628.0>,
    +                               {#Ref<0.3436431406.2344353793.8107>,350702,
    +                                [{child1,<0.302637.0>,worker,[]}],
                                     [{supervisor_SUITE,temporary_bystander}],
                                     []}}
     ** When Server state == {state,
    -                            {<0.302528.0>,supervisor_SUITE},
    +                            {<0.302631.0>,supervisor_SUITE},
                                 rest_for_one,
                                 {[child1],
                                  #{child1 =>
    -                                   {child,<0.302534.0>,child1,
    +                                   {child,<0.302637.0>,child1,
                                            {supervisor_1,start_child,[]},
                                            permanent,false,100,worker,[]}}},
                                 undefined,2,300,
    -                            [-576459183],
    +                            [-576459176],
                                 1,0,never,supervisor_SUITE,
                                 {ok,{{rest_for_one,2,300},[]}}}
     ** Reason for termination ==
    -** {#Ref<0.513239895.2907176962.121021>,350759,
    -    [{child1,<0.302534.0>,worker,[]}],
    +** {#Ref<0.3436431406.2344353793.8107>,350702,
    +    [{child1,<0.302637.0>,worker,[]}],
         [{supervisor_SUITE,temporary_bystander}],
         []}
     
    @@ -449,29 +426,29 @@ 

    Unexpected I/O

     
    -
    *** System report during supervisor_SUITE:temporary_bystander/1 2024-09-11 11:36:28.463 ***
    -=ERROR REPORT==== 11-Sep-2024::11:36:28.463240 ===
    -** Generic server <0.302527.0> terminating 
    -** Last message in was {'EXIT',<0.302525.0>,
    -                               {#Ref<0.513239895.2907176962.121021>,350759,
    -                                [{child1,<0.302534.0>,worker,[]}],
    +
    *** System report during supervisor_SUITE:temporary_bystander/1 2024-09-12 10:58:40.429 ***
    +=ERROR REPORT==== 12-Sep-2024::10:58:40.428951 ===
    +** Generic server <0.302630.0> terminating 
    +** Last message in was {'EXIT',<0.302628.0>,
    +                               {#Ref<0.3436431406.2344353793.8107>,350702,
    +                                [{child1,<0.302637.0>,worker,[]}],
                                     [{supervisor_SUITE,temporary_bystander}],
                                     []}}
     ** When Server state == {state,
    -                            {<0.302527.0>,supervisor_SUITE},
    +                            {<0.302630.0>,supervisor_SUITE},
                                 one_for_all,
                                 {[child1],
                                  #{child1 =>
    -                                   {child,<0.302533.0>,child1,
    +                                   {child,<0.302636.0>,child1,
                                            {supervisor_1,start_child,[]},
                                            permanent,false,100,worker,[]}}},
                                 undefined,2,300,
    -                            [-576459183],
    +                            [-576459176],
                                 1,0,never,supervisor_SUITE,
                                 {ok,{{one_for_all,2,300},[]}}}
     ** Reason for termination ==
    -** {#Ref<0.513239895.2907176962.121021>,350759,
    -    [{child1,<0.302534.0>,worker,[]}],
    +** {#Ref<0.3436431406.2344353793.8107>,350702,
    +    [{child1,<0.302637.0>,worker,[]}],
         [{supervisor_SUITE,temporary_bystander}],
         []}
     
    @@ -479,18 +456,18 @@ 

    Unexpected I/O

     
    -
    *** System report during supervisor_SUITE:temporary_bystander/1 2024-09-11 11:36:28.463 ***
    -=CRASH REPORT==== 11-Sep-2024::11:36:28.463586 ===
    +
    *** System report during supervisor_SUITE:temporary_bystander/1 2024-09-12 10:58:40.429 ***
    +=CRASH REPORT==== 12-Sep-2024::10:58:40.429531 ===
       crasher:
         initial call: supervisor:supervisor_SUITE/1
    -    pid: <0.302528.0>
    +    pid: <0.302631.0>
         registered_name: []
    -    exception exit: {#Ref<0.513239895.2907176962.121021>,350759,
    -                     [{child1,<0.302534.0>,worker,[]}],
    +    exception exit: {#Ref<0.3436431406.2344353793.8107>,350702,
    +                     [{child1,<0.302637.0>,worker,[]}],
                          [{supervisor_SUITE,temporary_bystander}],
                          []}
           in function  gen_server:decode_msg/9 (gen_server.erl, line 2299)
    -    ancestors: [<0.302525.0>]
    +    ancestors: [<0.302628.0>]
         message_queue_len: 0
         messages: []
         links: []
    @@ -499,25 +476,25 @@ 

    Unexpected I/O

    status: running heap_size: 4185 stack_size: 29 - reductions: 14895 + reductions: 14902 neighbours:
     
    -
    *** System report during supervisor_SUITE:temporary_bystander/1 2024-09-11 11:36:28.463 ***
    -=CRASH REPORT==== 11-Sep-2024::11:36:28.463733 ===
    +
    *** System report during supervisor_SUITE:temporary_bystander/1 2024-09-12 10:58:40.430 ***
    +=CRASH REPORT==== 12-Sep-2024::10:58:40.429850 ===
       crasher:
         initial call: supervisor:supervisor_SUITE/1
    -    pid: <0.302527.0>
    +    pid: <0.302630.0>
         registered_name: []
    -    exception exit: {#Ref<0.513239895.2907176962.121021>,350759,
    -                     [{child1,<0.302534.0>,worker,[]}],
    +    exception exit: {#Ref<0.3436431406.2344353793.8107>,350702,
    +                     [{child1,<0.302637.0>,worker,[]}],
                          [{supervisor_SUITE,temporary_bystander}],
                          []}
           in function  gen_server:decode_msg/9 (gen_server.erl, line 2299)
    -    ancestors: [<0.302525.0>]
    +    ancestors: [<0.302628.0>]
         message_queue_len: 0
         messages: []
         links: []
    @@ -526,10 +503,48 @@ 

    Unexpected I/O

    status: running heap_size: 2586 stack_size: 29 - reductions: 14982 + reductions: 14989 neighbours: +
    +
    +
    +
    *** System report during supervisor_bridge_SUITE:simple_global_supervisor/1 2024-09-12 10:59:23.895 ***
    +=CRASH REPORT==== 12-Sep-2024::10:59:23.894806 ===
    +  crasher:
    +    initial call: supervisor_bridge:supervisor_bridge_SUITE/1
    +    pid: <0.402788.0>
    +    registered_name: []
    +    exception exit: killed
    +      in function  gen_server:decode_msg/9 (gen_server.erl, line 2299)
    +    ancestors: [bridge9212,<0.402783.0>]
    +    message_queue_len: 0
    +    messages: []
    +    links: [<0.402789.0>]
    +    dictionary: []
    +    trap_exit: true
    +    status: running
    +    heap_size: 2586
    +    stack_size: 29
    +    reductions: 4058
    +  neighbours:
    +    neighbour:
    +      pid: <0.402789.0>
    +      registered_name: work_supervisor_bridge_SUITE_server
    +      initial_call: {supervisor_bridge_SUITE,internal_loop_init,1}
    +      current_function: {supervisor_bridge_SUITE,internal_loop,1}
    +      ancestors: []
    +      message_queue_len: 0
    +      links: [<0.402788.0>]
    +      trap_exit: false
    +      status: waiting
    +      heap_size: 233
    +      stack_size: 3
    +      reductions: 9
    +      current_stacktrace: [{supervisor_bridge_SUITE,internal_loop,1,
    +                      [{file,"supervisor_bridge_SUITE.erl"},{line,152}]}]
    +
     
     
    @@ -540,7 +555,7 @@

    Unexpected I/O

    | Latest test result

    diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.simple_one_for_one_extra.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.binaries_errors_limit.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.simple_one_for_one_extra.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.binaries_errors_limit.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.simple_one_for_one_restart_ignore.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.error_info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.simple_one_for_one_restart_ignore.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.error_info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.simple_one_for_one_scale_many_temporary_children.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.ex_binaries_errors_utf16_big.19718018.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.simple_one_for_one_scale_many_temporary_children.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.ex_binaries_errors_utf16_big.19718018.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.simple_one_for_one_shutdown.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.ex_binaries_errors_utf16_little.19717986.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.simple_one_for_one_shutdown.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.ex_binaries_errors_utf16_little.19717986.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.ex_binaries_errors_utf32_big.408387.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.ex_binaries_errors_utf32_big.408387.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_flags.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.ex_binaries_errors_utf32_little.19718050.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_flags.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.ex_binaries_errors_utf32_little.19718050.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_child_returns_error.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.ex_binaries_errors_utf8.19717954.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_child_returns_error.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.ex_binaries_errors_utf8.19717954.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_child_returns_error_simple.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.exceptions.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_child_returns_error_simple.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.exceptions.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_error_return.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.huge_illegal_code_points.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_error_return.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.huge_illegal_code_points.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_fail.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.latin1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_fail.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.latin1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_ignore_child.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.normalize.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_ignore_child.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.normalize.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_ignore_init.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.random_lists.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_ignore_init.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.random_lists.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_ignore_permanent_child_start_child_simple.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.roundtrips.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_ignore_permanent_child_start_child_simple.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.roundtrips.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_ignore_temporary_child.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_ignore_temporary_child.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_ignore_temporary_child_start_child.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.utf16_illegal_sequences_bif.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_ignore_temporary_child_start_child.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.utf16_illegal_sequences_bif.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_ignore_temporary_child_start_child_simple.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.utf8_illegal_sequences_bif.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_ignore_temporary_child_start_child_simple.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_suite.utf8_illegal_sequences_bif.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_map.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.casefold.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_map.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.casefold.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_map_faulty_specs.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.count.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_map_faulty_specs.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.count.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_map_simple.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.cp.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_map_simple.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.cp.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_normal.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.extra.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_normal.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.extra.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_restart_child_returns_error.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.gc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_start_restart_child_returns_error.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.gc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_stop_brutal_kill.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.get.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_stop_brutal_kill.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.get.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_stop_brutal_kill_dynamic.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.lookup.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_stop_brutal_kill_dynamic.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.lookup.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_stop_infinity.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.lowercase.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_stop_infinity.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.lowercase.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_stop_non_shutdown_exit_dynamic.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.nfc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_stop_non_shutdown_exit_dynamic.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.nfc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_stop_race.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.nfd.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_stop_race.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.nfd.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_stop_timeout.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.nfkc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_stop_timeout.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.nfkc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_stop_timeout_dynamic.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.nfkd.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.sup_stop_timeout_dynamic.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.nfkd.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.temporary_abnormal.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.temporary_abnormal.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.temporary_bystander.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.titlecase.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.temporary_bystander.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.titlecase.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.temporary_normal.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.uppercase.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.temporary_normal.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.uppercase.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.temporary_shutdown.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.whitespace.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.temporary_shutdown.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/unicode_util_suite.whitespace.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.transient_abnormal.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_property_test_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.transient_abnormal.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_property_test_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.transient_normal.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_property_test_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.transient_normal.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_property_test_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.transient_shutdown.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_property_test_suite.normalize.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.transient_shutdown.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_property_test_suite.normalize.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.tree.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_property_test_suite.recompose.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/supervisor_suite.tree.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_property_test_suite.recompose.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_property_test_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_property_test_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.compose_query.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.compose_query.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.install.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.compose_query_latin1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.install.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.compose_query_latin1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.log.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.compose_query_negative.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.log.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.compose_query_negative.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.log_to_file.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.dissect_query.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.log_to_file.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.dissect_query.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.special_process.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.dissect_query_negative.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.special_process.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.dissect_query_negative.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.interop_query_latin1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.interop_query_latin1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.stats.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.interop_query_utf8.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.stats.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.interop_query_utf8.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.suspend.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.suspend.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.trace.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_binary_pct_encoded_fragment.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/sys_suite.trace.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_binary_pct_encoded_fragment.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.apply_file_info_opts.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_binary_pct_encoded_query.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.apply_file_info_opts.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_binary_pct_encoded_query.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.atomic.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_binary_pct_encoded_userinfo.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.atomic.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_binary_pct_encoded_userinfo.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.bad_tar.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_map.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.bad_tar.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_map.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.borderline.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_negative.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.borderline.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_negative.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.bsdtgz.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_pct_encoded_fragment.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.bsdtgz.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_pct_encoded_fragment.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.cooked_compressed.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_pct_encoded_negative.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.cooked_compressed.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_pct_encoded_negative.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.create_long_names.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_pct_encoded_query.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.create_long_names.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_pct_encoded_query.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.dotdot.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_pct_encoded_userinfo.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.dotdot.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_pct_encoded_userinfo.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_return_map.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.normalize_return_map.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.errors.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.errors.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.extract_filtered.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_fragment.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.extract_filtered.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_fragment.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.extract_from_binary.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_host.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.extract_from_binary.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_host.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.extract_from_binary_compressed.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_host_ipv4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.extract_from_binary_compressed.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_host_ipv4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.extract_from_open_file.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_host_ipv6.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.extract_from_open_file.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_host_ipv6.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.incompatible_options.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_path.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.incompatible_options.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_path.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.init.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_pct_encoded_fragment.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.init.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_pct_encoded_fragment.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_pct_encoded_query.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_pct_encoded_query.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.leading_slash.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_pct_encoded_userinfo.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.leading_slash.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_pct_encoded_userinfo.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.long_names.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_port.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.long_names.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_port.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.memory.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_query.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.memory.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_query.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.open_add_close.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_scheme.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.open_add_close.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_scheme.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.read_other_implementations.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_userinfo.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.read_other_implementations.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_binary_userinfo.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.roundtrip_metadata.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_fragment.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.roundtrip_metadata.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_fragment.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.sparse.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_host.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.sparse.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_host.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_host_ipv4.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_host_ipv4.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.symlinks.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_host_ipv6.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.symlinks.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_host_ipv6.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.unicode.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_list.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/tar_suite.unicode.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_list.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_after1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_mixed.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_after1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_mixed.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_after2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_negative.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_after2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_negative.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_after3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_path.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_after3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_path.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_after4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_pct_encoded_fragment.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_after4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_pct_encoded_fragment.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_after_invalid_args.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_pct_encoded_query.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_after_invalid_args.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_pct_encoded_query.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_interval1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_pct_encoded_userinfo.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_interval1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_pct_encoded_userinfo.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_interval2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_port.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_interval2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_port.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_interval_invalid_args.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_query.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_interval_invalid_args.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_query.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_repeatedly1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_recompose_autogen.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_repeatedly1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_recompose_autogen.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_repeatedly2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_relative.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_repeatedly2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_relative.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_repeatedly_invalid_args.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_scheme.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.apply_repeatedly_invalid_args.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_scheme.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.cancel1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_special.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.cancel1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_special.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.cancel2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_special2.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.cancel2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_special2.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.cancel3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_userinfo.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.cancel3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.parse_userinfo.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.cancel4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.quote.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.cancel4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.quote.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.cancel5.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_autogen.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.cancel5.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_autogen.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.cancel6.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_fragment.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.cancel6.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_fragment.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.cancel_invalid_args.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_host_absolute_path.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.cancel_invalid_args.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_host_absolute_path.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19700610.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_host_relative_path.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19700610.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_host_relative_path.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19700674.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_parse_fragment.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19700674.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_parse_fragment.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19700738.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_parse_path.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19700738.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_parse_path.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19700802.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_parse_query.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19700802.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_parse_query.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19700866.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_path.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19700866.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_path.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19700930.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_query.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19700930.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.recompose_query.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19700994.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.regression_normalize.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19700994.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.regression_normalize.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19701058.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.regression_parse.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19701058.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.regression_parse.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19701122.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.regression_recompose.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.19701122.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.regression_recompose.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.resolve_abnormal_examples.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.resolve_abnormal_examples.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.resolve_base_uri.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.resolve_base_uri.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.exit_after1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.resolve_normal_examples.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.exit_after1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.resolve_normal_examples.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.exit_after2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.resolve_return_map.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.exit_after2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.resolve_return_map.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.exit_after3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.exit_after3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.exit_after4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.transcode_basic.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.exit_after4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.transcode_basic.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19700578.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.transcode_mixed.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19700578.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.transcode_mixed.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19700642.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.transcode_negative.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19700642.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.transcode_negative.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19700706.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.transcode_options.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19700706.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/uri_string_suite.transcode_options.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19700770.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/win32reg_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19700770.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/win32reg_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19700834.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/win32reg_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19700834.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/win32reg_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19700898.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.date_1999_01_01.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19700898.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.date_1999_01_01.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19700962.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.date_1999_02_28.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19700962.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.date_1999_02_28.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19701026.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.date_1999_09_09.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19701026.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.date_1999_09_09.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19701090.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.date_2000_01_01.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.19701090.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.date_2000_01_01.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.date_2000_02_29.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.date_2000_02_29.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.date_2001_01_01.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.date_2001_01_01.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.kill_after1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.date_2001_02_29.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.kill_after1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.date_2001_02_29.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.kill_after2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.date_2004_02_29.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.kill_after2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.date_2004_02_29.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.kill_after3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.kill_after3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.nonexistent1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.nonexistent1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.nonexistent2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.nonexistent2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/y2k_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_after1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.aliases.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_after1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.aliases.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_after2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.atomic.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_after2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.atomic.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_after3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.bad_zip.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_after3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.bad_zip.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_after4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.19718370.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_after4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.19718370.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_after5.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.19718562.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_after5.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.19718562.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_after6.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.408579.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_after6.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.408579.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_after7.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.408739.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_after7.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.408739.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_after_invalid_args.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.409027.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_after_invalid_args.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.409027.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_interval1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.426180.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_interval1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.426180.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_interval2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.426436.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_interval2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.426436.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_interval3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.426628.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_interval3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.426628.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_interval4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.426724.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_interval4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.basic_timestamp.426724.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_interval5.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.borderline.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_interval5.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.borderline.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_interval_invalid_args.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.compress_control.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.send_interval_invalid_args.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.compress_control.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.sleep1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19718242.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.sleep1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19718242.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.sleep2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19718466.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.sleep2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19718466.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19718690.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19718690.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.tc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19718722.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.tc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19718722.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.timer_perf.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19718818.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.timer_perf.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19718818.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.unexpected1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19718946.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.unexpected1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19718946.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.unexpected2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19719458.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.unexpected2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19719458.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.unexpected3.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19719490.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_simple_suite.unexpected3.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19719490.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_suite.do_big_test.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19719682.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_suite.do_big_test.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19719682.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19719810.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19719810.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19720418.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19720418.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19720450.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/timer_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19720450.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.binaries_errors_limit.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19720834.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.binaries_errors_limit.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19720834.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.error_info.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19721058.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.error_info.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19721058.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.ex_binaries_errors_utf16_big.504579.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19721762.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.ex_binaries_errors_utf16_big.504579.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19721762.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.ex_binaries_errors_utf16_little.504547.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19721794.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.ex_binaries_errors_utf16_little.504547.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19721794.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.ex_binaries_errors_utf32_big.504643.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19721826.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.ex_binaries_errors_utf32_big.504643.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.19721826.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.ex_binaries_errors_utf32_little.504611.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.408867.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.ex_binaries_errors_utf32_little.504611.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.408867.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.ex_binaries_errors_utf8.19701218.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.408899.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.ex_binaries_errors_utf8.19701218.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.408899.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.exceptions.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.426084.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.exceptions.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.426084.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.huge_illegal_code_points.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.426276.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.huge_illegal_code_points.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.426276.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.latin1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.426308.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.latin1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.426308.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.normalize.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.426532.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.normalize.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.426532.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.random_lists.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.426788.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.random_lists.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.426788.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.roundtrips.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.429061.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.roundtrips.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.429061.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.utf16_illegal_sequences_bif.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.utf16_illegal_sequences_bif.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.utf8_illegal_sequences_bif.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.explicit_file_info.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_suite.utf8_illegal_sequences_bif.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.explicit_file_info.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.casefold.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.19718338.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.casefold.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.19718338.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.count.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.19718658.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.count.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.19718658.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.cp.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.408611.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.cp.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.408611.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.extra.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.408771.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.extra.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.408771.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.gc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.409059.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.gc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.409059.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.get.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.426212.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.get.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.426212.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.lookup.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.426468.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.lookup.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.426468.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.lowercase.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.426660.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.lowercase.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.426660.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.nfc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.426756.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.nfc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.extended_timestamp.426756.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.nfd.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.fd_leak.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.nfd.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.fd_leak.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.nfkc.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.foldl.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.nfkc.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.foldl.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.nfkd.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19718178.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.nfkd.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19718178.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19718210.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19718210.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.titlecase.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19718274.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.titlecase.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19718274.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.uppercase.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19718498.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.uppercase.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19718498.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.whitespace.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19718754.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/unicode_util_suite.whitespace.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19718754.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_property_test_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19718786.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_property_test_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19718786.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_property_test_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19718850.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_property_test_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19718850.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_property_test_suite.normalize.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19718978.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_property_test_suite.normalize.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19718978.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_property_test_suite.recompose.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19719522.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_property_test_suite.recompose.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19719522.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_property_test_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19719586.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_property_test_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19719586.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.compose_query.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19719714.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.compose_query.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19719714.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.compose_query_latin1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19719842.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.compose_query_latin1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19719842.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.compose_query_negative.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19720482.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.compose_query_negative.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19720482.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.dissect_query.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19720642.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.dissect_query.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19720642.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.dissect_query_negative.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19720866.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.dissect_query_negative.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19720866.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.interop_query_latin1.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19721090.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.interop_query_latin1.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.19721090.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.interop_query_utf8.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.408675.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.interop_query_utf8.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.408675.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.408931.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.408931.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_binary_pct_encoded_fragment.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.408963.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_binary_pct_encoded_fragment.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.408963.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_binary_pct_encoded_query.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.426116.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_binary_pct_encoded_query.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.426116.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_binary_pct_encoded_userinfo.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.426340.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_binary_pct_encoded_userinfo.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.426340.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_map.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.426372.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_map.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.426372.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_negative.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.426564.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_negative.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.426564.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_pct_encoded_fragment.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.429029.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_pct_encoded_fragment.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.429029.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_pct_encoded_negative.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.429093.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_pct_encoded_negative.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.429093.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_pct_encoded_query.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_pct_encoded_query.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_pct_encoded_userinfo.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_pct_encoded_userinfo.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_return_map.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.list_dir_options.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.normalize_return_map.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.list_dir_options.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.19718306.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.19718306.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_fragment.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.19718530.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_fragment.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.19718530.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_host.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.19718594.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_host.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.19718594.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_host_ipv4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.408547.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_host_ipv4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.408547.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_host_ipv6.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.408707.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_host_ipv6.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.408707.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_path.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.408995.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_path.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.408995.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_pct_encoded_fragment.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.426148.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_pct_encoded_fragment.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.426148.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_pct_encoded_query.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.426404.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_pct_encoded_query.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.426404.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_pct_encoded_userinfo.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.426596.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_pct_encoded_userinfo.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.mode.426596.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_port.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.open_leak.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_port.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.open_leak.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_query.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_query.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_scheme.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.test_zip_dir.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_scheme.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.test_zip_dir.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_userinfo.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.19718402.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_binary_userinfo.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.19718402.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_fragment.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.19718434.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_fragment.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.19718434.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_host.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.19718626.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_host.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.19718626.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_host_ipv4.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.408643.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_host_ipv4.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.408643.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_host_ipv6.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.408803.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_host_ipv6.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.408803.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_list.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.408835.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_list.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.408835.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_mixed.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.426244.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_mixed.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.426244.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_negative.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.426500.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_negative.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.426500.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_path.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.426692.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_path.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.uid_gid.426692.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_pct_encoded_fragment.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unicode.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_pct_encoded_fragment.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unicode.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_pct_encoded_query.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.19718882.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_pct_encoded_query.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.19718882.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_pct_encoded_userinfo.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.19719010.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_pct_encoded_userinfo.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.19719010.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_port.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.19719618.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_port.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.19719618.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_query.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.19719746.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_query.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.19719746.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_recompose_autogen.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.19719874.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_recompose_autogen.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.19719874.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_relative.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.19720674.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_relative.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.19720674.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_scheme.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.19720898.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_scheme.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.19720898.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_special.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.19721122.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_special.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.19721122.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_special2.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_special2.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip64_central_headers.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_userinfo.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip_from_binary.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.parse_userinfo.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip_from_binary.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.quote.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip_jar.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.quote.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip_jar.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_autogen.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip_options.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_autogen.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip_options.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_fragment.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip_to_binary.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_fragment.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip_to_binary.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_host_absolute_path.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip_traversal_exploit.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_host_absolute_path.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.unzip_traversal_exploit.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_host_relative_path.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.19718914.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_host_relative_path.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.19718914.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_parse_fragment.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.19719650.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_parse_fragment.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.19719650.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_parse_path.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.19719778.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_parse_path.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.19719778.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_parse_query.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.19720322.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_parse_query.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.19720322.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_path.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.19720706.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_path.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.19720706.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_query.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.19720930.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.recompose_query.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.19720930.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.regression_normalize.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.19721538.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.regression_normalize.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.19721538.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.regression_parse.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.409123.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.regression_parse.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.409123.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.regression_recompose.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.regression_recompose.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_directory.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.resolve_abnormal_examples.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_headers.19719554.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.resolve_abnormal_examples.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_headers.19719554.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.resolve_base_uri.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_headers.19720514.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.resolve_base_uri.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_headers.19720514.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.resolve_normal_examples.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_headers.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.resolve_normal_examples.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip64_central_headers.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.resolve_return_map.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip_api.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.resolve_return_map.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip_api.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip_options.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip_options.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.transcode_basic.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip_to_binary.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.transcode_basic.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zip_suite.zip_to_binary.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.transcode_mixed.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zzz_suite.lc_graph.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.transcode_mixed.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zzz_suite.lc_graph.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.transcode_negative.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zzz_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.transcode_negative.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/run.2024-09-12_10.33.01/zzz_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/select_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/select_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/select_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/select_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/sets_property_test_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/sets_property_test_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/sets_property_test_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/sets_property_test_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/sets_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/sets_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/sets_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/sets_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/shell_docs_markdown_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/shell_docs_markdown_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/shell_docs_markdown_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/shell_docs_markdown_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/shell_docs_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/shell_docs_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/shell_docs_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/shell_docs_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/shell_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/shell_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/shell_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/shell_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/sigils_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/sigils_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/sigils_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/sigils_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/slave_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/slave_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/slave_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/slave_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/sofs_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/sofs_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/sofs_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/sofs_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/stdlib_bench_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/stdlib_bench_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/stdlib_bench_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/stdlib_bench_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/stdlib_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/stdlib_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/stdlib_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/stdlib_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/string_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/string_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/string_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/string_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/supervisor_bridge_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/supervisor_bridge_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/supervisor_bridge_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/supervisor_bridge_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/supervisor_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/supervisor_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/supervisor_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/supervisor_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/sys_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/sys_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/sys_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/sys_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/tar_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/tar_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/tar_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/tar_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/timer_simple_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/timer_simple_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/timer_simple_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/timer_simple_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/timer_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/timer_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/timer_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/timer_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/unicode_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/unicode_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/unicode_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/unicode_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/unicode_util_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/unicode_util_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/unicode_util_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/unicode_util_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/uri_string_property_test_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/uri_string_property_test_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/uri_string_property_test_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/uri_string_property_test_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/uri_string_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/uri_string_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/uri_string_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/uri_string_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/win32reg_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/win32reg_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/win32reg_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/win32reg_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/y2k_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/y2k_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/y2k_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/y2k_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/zip_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/zip_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/zip_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/zip_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/zzz_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/zzz_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/zzz_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/make_test_dir.stdlib_test.logs/zzz_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/misc_io.log.html b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/misc_io.log.html similarity index 95% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/misc_io.log.html rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/misc_io.log.html index 7f2ff583f0f42..dfe17147b7de6 100644 --- a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/misc_io.log.html +++ b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/misc_io.log.html @@ -30,7 +30,7 @@

    POST-TEST LOG

    | Latest test result

    diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/oc_event.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/oc_event.beam similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/oc_event.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/oc_event.beam diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/oc_fsm.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/oc_fsm.beam similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/oc_fsm.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/oc_fsm.beam diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/oc_server.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/oc_server.beam similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/oc_server.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/oc_server.beam diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/oc_statem.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/oc_statem.beam similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/oc_statem.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/oc_statem.beam diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/simple_server.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/simple_server.beam similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/simple_server.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/simple_server.beam diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/simple_server_mon.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/simple_server_mon.beam similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/simple_server_mon.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/simple_server_mon.beam diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/simple_server_timer.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/simple_server_timer.beam similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/simple_server_timer.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/simple_server_timer.beam diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/simple_server_timer_mon.beam b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/simple_server_timer_mon.beam similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/simple_server_timer_mon.beam rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/simple_server_timer_mon.beam diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/t b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/t similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/t rename to prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/t diff --git a/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/totals.info b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/totals.info new file mode 100644 index 0000000000000..dbc2eed736a90 Binary files /dev/null and b/prs/8803/ct_logs/ct_run.test_server@7a1fde2d1d55.2024-09-12_10.32.23/totals.info differ diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/ct_default.css b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/ct_default.css similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/ct_default.css rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/ct_default.css diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/ctlog.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/ctlog.html similarity index 92% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/ctlog.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/ctlog.html index b9726e2d5b487..266249d88dd7c 100644 --- a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/ctlog.html +++ b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/ctlog.html @@ -118,33 +118,33 @@

    PRE/POST TEST I/O LOG

    PROGRESS LOG

     
    -
    *** CT 2024-09-11 12:06:30.128 *** Common Test Logger started
    +
    *** CT 2024-09-12 11:29:20.623 *** Common Test Logger started
     VERBOSITY LEVELS:
     general level            100
     default                  100
     
     
    -
    *** CT 2024-09-11 12:06:30.132 *** Test Specification file(s)
    +
    *** CT 2024-09-12 11:29:20.627 *** Test Specification file(s)
     /buildroot/otp/erts/make_test_dir/system_test/system.spec 
     
    
    -
    *** CT 2024-09-11 12:06:30.424 *** TEST INFO
    +
    *** CT 2024-09-12 11:29:20.910 *** TEST INFO
     1 test(s), 109 case(s) in 11 suite(s)
     
    
    -
    *** CT 2024-09-11 12:06:30.424 *** TEST INFO
    +
    *** CT 2024-09-12 11:29:20.910 *** TEST INFO
     Timetrap time multiplier = 1
     Timetrap scaling enabled = false
     
    
    -
    *** CT 2024-09-11 12:10:39.615 *** Common Test Logger finished
    +
    *** CT 2024-09-12 11:34:46.147 *** Common Test Logger finished
     


    diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/index.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/index.html similarity index 92% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/index.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/index.html index 3b1d37e8c340c..660de94f8ebaf 100644 --- a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/index.html +++ b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/index.html @@ -3,7 +3,7 @@ -Test Results Wed Sep 11 2024 12:06:30 +Test Results Thu Sep 12 2024 11:29:20 @@ -81,7 +81,7 @@

    Test Results

    -

    Wed Sep 11 2024 12:06:30

    +

    Thu Sep 12 2024 11:29:20


    @@ -103,12 +103,12 @@

    Wed Sep 11 2024 12:06:30

    -make_test_dir.system_test +make_test_dir.system_test 107 0 2 (2/0) 0 -247.875s +323.920s @@ -118,7 +118,7 @@

    Wed Sep 11 2024 12:06:30

    0 2 (2/0) 0 -247.875s +323.920s @@ -130,7 +130,7 @@

    Wed Sep 11 2024 12:06:30

    diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/jquery-latest.js b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/jquery-latest.js similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/jquery-latest.js rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/jquery-latest.js diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/jquery.tablesorter.min.js b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/jquery.tablesorter.min.js similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/jquery.tablesorter.min.js rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/jquery.tablesorter.min.js diff --git a/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/last_name b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/last_name new file mode 100644 index 0000000000000..4a403ee50881d --- /dev/null +++ b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/last_name @@ -0,0 +1 @@ +/buildroot/otp/erts/make_test_dir/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21 diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/last_test.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/last_test.html similarity index 87% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/last_test.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/last_test.html index 9e960d61d65e5..4f6409002f65d 100644 --- a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/last_test.html +++ b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/last_test.html @@ -8,6 +8,6 @@

    Last test

    -make_test_dir.system_test.logs +make_test_dir.system_test.logs diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/erl_print_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/erl_print_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/erl_print_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/erl_print_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/erlc_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/erlc_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/erlc_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/erlc_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/erlexec_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/erlexec_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/erlexec_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/erlexec_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/ethread_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/ethread_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/ethread_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/ethread_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/install_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/install_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/install_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/install_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/last_link.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/last_link.html similarity index 87% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/last_link.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/last_link.html index 2c20f03e41853..7c121bc73f863 100644 --- a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/last_link.html +++ b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/last_link.html @@ -8,6 +8,6 @@

    Last test

    -make_test_dir.system_test.logs +make_test_dir.system_test.logs diff --git a/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/last_name b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/last_name new file mode 100644 index 0000000000000..4a403ee50881d --- /dev/null +++ b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/last_name @@ -0,0 +1 @@ +/buildroot/otp/erts/make_test_dir/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21 diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/nt_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/nt_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/nt_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/nt_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/otp_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/otp_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/otp_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/otp_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/parallel_messages_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/parallel_messages_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/parallel_messages_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/parallel_messages_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/cover.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/cover.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/cover.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/cover.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.transcode_options.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.end_per_suite.4098.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/uri_string_suite.transcode_options.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.end_per_suite.4098.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/win32reg_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.end_per_suite.4162.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/win32reg_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.end_per_suite.4162.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/win32reg_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.end_per_suite.4482.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/win32reg_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.end_per_suite.4482.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.date_1999_01_01.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.end_per_suite.4674.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.date_1999_01_01.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.end_per_suite.4674.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.date_1999_02_28.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.end_per_suite.5122.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.date_1999_02_28.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.end_per_suite.5122.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.date_1999_09_09.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.date_1999_09_09.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.date_2000_01_01.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.init_per_suite.4066.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.date_2000_01_01.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.init_per_suite.4066.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.date_2000_02_29.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.init_per_suite.4130.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.date_2000_02_29.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.init_per_suite.4130.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.date_2001_01_01.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.init_per_suite.4514.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.date_2001_01_01.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.init_per_suite.4514.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.date_2001_02_29.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.init_per_suite.5.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.date_2001_02_29.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.init_per_suite.5.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.date_2004_02_29.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.init_per_suite.5090.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.date_2004_02_29.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.init_per_suite.5090.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ct_framework.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erl_print_suite.character.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erl_print_suite.character.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erl_print_suite.erlang_display.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/y2k_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erl_print_suite.erlang_display.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.aliases.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erl_print_suite.float.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.aliases.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erl_print_suite.float.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.atomic.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erl_print_suite.integer.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.atomic.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erl_print_suite.integer.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.bad_zip.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erl_print_suite.quote.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.bad_zip.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erl_print_suite.quote.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.19701570.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erl_print_suite.snprintf.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.19701570.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erl_print_suite.snprintf.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.19701762.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erl_print_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.19701762.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erl_print_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.19701954.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erl_print_suite.string.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.19701954.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erl_print_suite.string.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.398660.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.arg_overflow.163.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.398660.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.arg_overflow.163.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.398820.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.arg_overflow.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.398820.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.arg_overflow.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.504707.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.compile_erl.1218.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.504707.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.compile_erl.1218.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.505027.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.compile_erl.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.505027.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.compile_erl.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.505187.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.compile_mib.67.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.505187.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.compile_mib.67.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.505283.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.compile_mib.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.basic_timestamp.505283.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.compile_mib.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.borderline.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.compile_script.35.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.borderline.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.compile_script.35.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.compress_control.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.compile_script.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.compress_control.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.compile_script.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19701666.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.compile_yecc.3.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19701666.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.compile_yecc.3.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19701826.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.compile_yecc.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19701826.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.compile_yecc.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19702050.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.deep_cwd.131.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19702050.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.deep_cwd.131.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19702082.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.deep_cwd.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19702082.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.deep_cwd.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19702178.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.end_per_group.2338.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19702178.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.end_per_group.2338.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19702306.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.end_per_group.3842.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19702306.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.end_per_group.3842.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19702338.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.end_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19702338.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.end_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19702370.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19702370.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19702498.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features.3810.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19702498.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features.3810.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19702626.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19702626.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19703234.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_all.2978.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19703234.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_all.2978.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19703266.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_all.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19703266.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_all.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19703426.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_atom_warnings.2498.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19703426.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_atom_warnings.2498.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19703554.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_atom_warnings.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19703554.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_atom_warnings.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19704194.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_directives.2466.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19704194.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_directives.2466.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19704226.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_directives.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19704226.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_directives.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19704514.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_disable.2882.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19704514.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_disable.2882.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19704706.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_disable.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19704706.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_disable.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19705442.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_erlc_describe.2402.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19705442.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_erlc_describe.2402.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19705474.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_erlc_describe.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19705474.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_erlc_describe.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19705506.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_erlc_unknown.2434.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.19705506.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_erlc_unknown.2434.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.398756.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_erlc_unknown.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.398756.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_erlc_unknown.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.504835.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_include.3522.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.504835.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_include.3522.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.504931.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_include.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.504931.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_include.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.505123.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_load.3202.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.505123.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_load.3202.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_load.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_load.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_macros.2530.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.end_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_macros.2530.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.explicit_file_info.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_macros.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.explicit_file_info.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_macros.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.19701602.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_runtime.3298.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.19701602.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_runtime.3298.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.19701794.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_runtime.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.19701794.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.features_runtime.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.19702242.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.good_citizen.99.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.19702242.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.good_citizen.99.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.398692.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.good_citizen.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.398692.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.good_citizen.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.504739.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.init_per_group.1186.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.504739.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.init_per_group.1186.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.504867.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.init_per_group.2370.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.504867.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.init_per_group.2370.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.505059.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.init_per_group.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.505059.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.init_per_group.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.505219.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.505219.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.505315.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.make_dep_options.195.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.extended_timestamp.505315.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.make_dep_options.195.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.fd_leak.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.make_dep_options.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.fd_leak.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.make_dep_options.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.foldl.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.foldl.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19701442.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.unicode_paths.227.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19701442.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.unicode_paths.227.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19701474.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.unicode_paths.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19701474.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlc_suite.unicode_paths.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19701506.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.args_file.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19701506.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.args_file.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19701698.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.args_file_env.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19701698.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.args_file_env.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19701858.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.argument_separation.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19701858.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.argument_separation.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19701890.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.argument_with_option.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19701890.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.argument_with_option.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19701986.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19701986.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19702114.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.env.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19702114.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.env.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19702146.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.evil_args_file.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19702146.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.evil_args_file.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19702402.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19702402.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19702434.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.missing_args_file.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19702434.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.missing_args_file.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19702466.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.otp_7461.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19702466.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.otp_7461.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19702530.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19702530.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19702658.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.zdbbl_dist_buf_busy_limit.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19702658.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/erlexec_suite.zdbbl_dist_buf_busy_limit.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19703298.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.atomic.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19703298.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.atomic.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19703362.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.broadcast.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19703362.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.broadcast.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19703458.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.cond_wait.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19703458.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.cond_wait.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19703586.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.create_join_thread.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19703586.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.create_join_thread.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19704258.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.detached_thread.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19704258.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.detached_thread.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19704546.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.dw_atomic_massage.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19704546.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.dw_atomic_massage.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19704738.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.equal_tids.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.19704738.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.equal_tids.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.398596.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.max_threads.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.398596.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.max_threads.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.398788.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.mutex.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.398788.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.mutex.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.504963.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.rwmutex.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.504963.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.rwmutex.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.505443.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.rwspinlock.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.505443.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.rwspinlock.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.spinlock.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_group.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.spinlock.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_suite.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.init_per_suite.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.list_dir_options.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.thread_name.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.list_dir_options.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.thread_name.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.19701538.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.try_lock_mutex.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.19701538.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.try_lock_mutex.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.19701730.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.tsd.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.19701730.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/ethread_suite.tsd.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.19701922.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.'bin white space'.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.19701922.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.'bin white space'.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.19702210.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_default.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.19702210.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_default.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.398628.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_default_dirty.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.398628.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_default_dirty.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.504675.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_dirname_fail.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.504675.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_dirname_fail.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.504995.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_no_srcfile.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.504995.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_no_srcfile.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.505155.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_no_use_dirname_fail.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.505155.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_no_use_dirname_fail.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.505251.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_not_abs.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.mode.505251.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_not_abs.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.open_leak.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_ok_symlink.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.open_leak.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_ok_symlink.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_outside_eprfx.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_outside_eprfx.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.test_zip_dir.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_outside_eprfx_dirty.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.test_zip_dir.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_outside_eprfx_dirty.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.19701634.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_same_dir.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.19701634.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_same_dir.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.19702018.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_unreachable_absolute.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.19702018.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_unreachable_absolute.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.19702274.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_unreachable_relative.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.19702274.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_unreachable_relative.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.398724.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_unreasonable_path.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.398724.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.bin_unreasonable_path.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.504771.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.504771.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.504803.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.504803.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.504899.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.504899.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/install_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.505091.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/nt_suite.nt.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.505091.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/nt_suite.nt.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.505347.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/nt_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.uid_gid.505347.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/nt_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unicode.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.call_to_deprecated.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unicode.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.call_to_deprecated.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.19702562.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.call_to_now_0.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.19702562.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.call_to_now_0.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.19702690.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.call_to_size_1.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.19702690.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.call_to_size_1.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.19703394.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.deprecated_not_in_obsolete.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.19703394.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.deprecated_not_in_obsolete.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.19703490.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.19703490.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.19703618.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.erl_file_encoding.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.19703618.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.erl_file_encoding.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.19704578.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.19704578.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.19704770.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.obsolete_but_not_deprecated.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.19704770.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.obsolete_but_not_deprecated.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.505475.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.runtime_dependencies_functions.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.505475.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.runtime_dependencies_functions.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.runtime_dependencies_modules.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip64_central_headers.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.runtime_dependencies_modules.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip_from_binary.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip_from_binary.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip_jar.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.strong_components.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip_jar.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.strong_components.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip_options.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.test_runtime_dependencies_versions.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip_options.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.test_runtime_dependencies_versions.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip_to_binary.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.undefined_functions.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip_to_binary.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.undefined_functions.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip_traversal_exploit.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.xml_file_encoding.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.unzip_traversal_exploit.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/otp_suite.xml_file_encoding.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.19702594.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/parallel_messages_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.19702594.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/parallel_messages_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.19703138.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/parallel_messages_suite.test_message_queue_data_switching.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.19703138.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/parallel_messages_suite.test_message_queue_data_switching.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.19703522.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/parallel_messages_suite.test_throughput_benchmark.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.19703522.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/parallel_messages_suite.test_throughput_benchmark.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.19704610.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/run_erl_suite.basic.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.19704610.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/run_erl_suite.basic.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.19705250.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/run_erl_suite.defunct.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.19705250.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/run_erl_suite.defunct.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.505379.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/run_erl_suite.heavier.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.505379.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/run_erl_suite.heavier.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.505411.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/run_erl_suite.heavy.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.505411.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/run_erl_suite.heavy.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.505507.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/run_erl_suite.sleepy_child.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.505507.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/run_erl_suite.sleepy_child.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/run_erl_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_directory.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/run_erl_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/suite.log b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/suite.log similarity index 58% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/suite.log rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/suite.log index 015f079c8fecf..a10a5bb08d2c5 100644 --- a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/suite.log +++ b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/suite.log @@ -1,722 +1,722 @@ -=== Suite started at 2024-09-11 12:06:30 +=== Suite started at 2024-09-12 11:29:21 === Starting test, 109 test cases =cases 109 =user otptest -=host 27af2e7fa355 -=hosts 27af2e7fa355 +=host a4cca6e7dcb5 +=hosts a4cca6e7dcb5 =emulator_vsn 15.0.1 =emulator beam =otp_release 28 -=started 2024-09-11 12:06:30 +=started 2024-09-12 11:29:21 =case ct_framework:init_per_suite =logfile ct_framework.init_per_suite.html =group_props [{suite,erl_print_SUITE}] -=started 2024-09-11 12:06:30 -=ended 2024-09-11 12:06:30 +=started 2024-09-12 11:29:21 +=ended 2024-09-12 11:29:21 =result ok =elapsed 0.0 =case erl_print_SUITE:erlang_display =logfile erl_print_suite.erlang_display.html -=started 2024-09-11 12:06:30 -=ended 2024-09-11 12:06:30 +=started 2024-09-12 11:29:21 +=ended 2024-09-12 11:29:21 =result ok -=elapsed 0.003527 +=elapsed 0.003706 =case erl_print_SUITE:integer =logfile erl_print_suite.integer.html -=started 2024-09-11 12:06:30 -=ended 2024-09-11 12:06:30 +=started 2024-09-12 11:29:21 +=ended 2024-09-12 11:29:21 =result ok -=elapsed 0.031239 +=elapsed 0.028629 =case erl_print_SUITE:float =logfile erl_print_suite.float.html -=started 2024-09-11 12:06:30 -=ended 2024-09-11 12:06:30 +=started 2024-09-12 11:29:21 +=ended 2024-09-12 11:29:21 =result ok -=elapsed 0.002298 +=elapsed 0.002376 =case erl_print_SUITE:string =logfile erl_print_suite.string.html -=started 2024-09-11 12:06:30 -=ended 2024-09-11 12:06:30 +=started 2024-09-12 11:29:21 +=ended 2024-09-12 11:29:21 =result ok -=elapsed 0.00212 +=elapsed 0.001889 =case erl_print_SUITE:character =logfile erl_print_suite.character.html -=started 2024-09-11 12:06:30 -=ended 2024-09-11 12:06:30 +=started 2024-09-12 11:29:21 +=ended 2024-09-12 11:29:21 =result ok -=elapsed 0.027928 +=elapsed 0.019523 =case erl_print_SUITE:snprintf =logfile erl_print_suite.snprintf.html -=started 2024-09-11 12:06:30 -=ended 2024-09-11 12:06:30 +=started 2024-09-12 11:29:21 +=ended 2024-09-12 11:29:21 =result ok -=elapsed 0.002359 +=elapsed 0.002534 =case erl_print_SUITE:quote =logfile erl_print_suite.quote.html -=started 2024-09-11 12:06:30 -=ended 2024-09-11 12:06:30 +=started 2024-09-12 11:29:21 +=ended 2024-09-12 11:29:21 =result ok -=elapsed 0.002439 +=elapsed 0.002383 =case ct_framework:end_per_suite =logfile ct_framework.end_per_suite.html =group_props [{suite,erl_print_SUITE}] -=started 2024-09-11 12:06:30 -=ended 2024-09-11 12:06:30 +=started 2024-09-12 11:29:21 +=ended 2024-09-12 11:29:21 =result ok =elapsed 0.0 -=group_time 0.258s +=group_time 0.251s =case erlc_SUITE:init_per_suite =logfile erlc_suite.init_per_suite.html -=started 2024-09-11 12:06:30 -=ended 2024-09-11 12:06:30 +=started 2024-09-12 11:29:21 +=ended 2024-09-12 11:29:21 =result ok =elapsed 0.0 =case erlc_SUITE:init_per_group =logfile erlc_suite.init_per_group.html =group_props [{name,with_server}] -=started 2024-09-11 12:06:30 -=ended 2024-09-11 12:06:31 +=started 2024-09-12 11:29:21 +=ended 2024-09-12 11:29:21 =result ok -=elapsed 1.0e-6 +=elapsed 2.0e-6 =case erlc_SUITE:compile_erl =logfile erlc_suite.compile_erl.html -=started 2024-09-11 12:06:31 -=ended 2024-09-11 12:06:32 +=started 2024-09-12 11:29:21 +=ended 2024-09-12 11:29:22 =result ok -=elapsed 1.106841 +=elapsed 1.099824 =case erlc_SUITE:compile_yecc =logfile erlc_suite.compile_yecc.html -=started 2024-09-11 12:06:32 -=ended 2024-09-11 12:06:32 +=started 2024-09-12 11:29:22 +=ended 2024-09-12 11:29:23 =result ok -=elapsed 0.434279 +=elapsed 0.436471 =case erlc_SUITE:compile_script =logfile erlc_suite.compile_script.html -=started 2024-09-11 12:06:32 -=ended 2024-09-11 12:06:32 +=started 2024-09-12 11:29:23 +=ended 2024-09-12 11:29:23 =result ok -=elapsed 0.357021 +=elapsed 0.382476 =case erlc_SUITE:compile_mib =logfile erlc_suite.compile_mib.html -=started 2024-09-11 12:06:32 -=ended 2024-09-11 12:06:33 +=started 2024-09-12 11:29:23 +=ended 2024-09-12 11:29:24 =result ok -=elapsed 0.973544 +=elapsed 1.009859 =case erlc_SUITE:good_citizen =logfile erlc_suite.good_citizen.html -=started 2024-09-11 12:06:33 -=ended 2024-09-11 12:06:34 +=started 2024-09-12 11:29:24 +=ended 2024-09-12 11:29:24 =result ok -=elapsed 0.269783 +=elapsed 0.262983 =case erlc_SUITE:deep_cwd =logfile erlc_suite.deep_cwd.html -=started 2024-09-11 12:06:34 -=ended 2024-09-11 12:06:34 +=started 2024-09-12 11:29:24 +=ended 2024-09-12 11:29:25 =result ok -=elapsed 0.253474 +=elapsed 0.291681 =case erlc_SUITE:arg_overflow =logfile erlc_suite.arg_overflow.html -=started 2024-09-11 12:06:34 -=ended 2024-09-11 12:06:34 +=started 2024-09-12 11:29:25 +=ended 2024-09-12 11:29:25 =result ok -=elapsed 0.372669 +=elapsed 0.358822 =case erlc_SUITE:make_dep_options =logfile erlc_suite.make_dep_options.html -=started 2024-09-11 12:06:34 -=ended 2024-09-11 12:06:39 +=started 2024-09-12 11:29:25 +=ended 2024-09-12 11:29:30 =result ok -=elapsed 4.802697 +=elapsed 4.937044 =case erlc_SUITE:unicode_paths =logfile erlc_suite.unicode_paths.html -=started 2024-09-11 12:06:39 -=ended 2024-09-11 12:06:40 +=started 2024-09-12 11:29:30 +=ended 2024-09-12 11:29:30 =result ok -=elapsed 0.231504 +=elapsed 0.29017 =case erlc_SUITE:end_per_group =logfile erlc_suite.end_per_group.html =group_props [{name,with_server}] -=started 2024-09-11 12:06:40 -=ended 2024-09-11 12:06:40 +=started 2024-09-12 11:29:30 +=ended 2024-09-12 11:29:30 =result ok =elapsed 2.0e-6 -=group_time 9.034s +=group_time 9.297s =case erlc_SUITE:init_per_group -=logfile erlc_suite.init_per_group.2.html +=logfile erlc_suite.init_per_group.1186.html =group_props [{name,without_server}] -=started 2024-09-11 12:06:40 -=ended 2024-09-11 12:06:40 +=started 2024-09-12 11:29:30 +=ended 2024-09-12 11:29:30 =result ok =elapsed 1.0e-6 =case erlc_SUITE:compile_erl -=logfile erlc_suite.compile_erl.34.html -=started 2024-09-11 12:06:40 -=ended 2024-09-11 12:06:41 +=logfile erlc_suite.compile_erl.1218.html +=started 2024-09-12 11:29:30 +=ended 2024-09-12 11:29:31 =result ok -=elapsed 0.999439 +=elapsed 0.983536 =case erlc_SUITE:compile_yecc -=logfile erlc_suite.compile_yecc.66.html -=started 2024-09-11 12:06:41 -=ended 2024-09-11 12:06:41 +=logfile erlc_suite.compile_yecc.3.html +=started 2024-09-12 11:29:31 +=ended 2024-09-12 11:29:32 =result ok -=elapsed 0.321557 +=elapsed 0.319999 =case erlc_SUITE:compile_script -=logfile erlc_suite.compile_script.98.html -=started 2024-09-11 12:06:41 -=ended 2024-09-11 12:06:41 +=logfile erlc_suite.compile_script.35.html +=started 2024-09-12 11:29:32 +=ended 2024-09-12 11:29:32 =result ok -=elapsed 0.273699 +=elapsed 0.284701 =case erlc_SUITE:compile_mib -=logfile erlc_suite.compile_mib.130.html -=started 2024-09-11 12:06:41 -=ended 2024-09-11 12:06:42 +=logfile erlc_suite.compile_mib.67.html +=started 2024-09-12 11:29:32 +=ended 2024-09-12 11:29:33 =result ok -=elapsed 0.716468 +=elapsed 0.749252 =case erlc_SUITE:good_citizen -=logfile erlc_suite.good_citizen.162.html -=started 2024-09-11 12:06:42 -=ended 2024-09-11 12:06:42 +=logfile erlc_suite.good_citizen.99.html +=started 2024-09-12 11:29:33 +=ended 2024-09-12 11:29:33 =result ok -=elapsed 0.24317 +=elapsed 0.23603 =case erlc_SUITE:deep_cwd -=logfile erlc_suite.deep_cwd.194.html -=started 2024-09-11 12:06:42 -=ended 2024-09-11 12:06:43 +=logfile erlc_suite.deep_cwd.131.html +=started 2024-09-12 11:29:33 +=ended 2024-09-12 11:29:33 =result ok -=elapsed 0.258963 +=elapsed 0.258074 =case erlc_SUITE:arg_overflow -=logfile erlc_suite.arg_overflow.226.html -=started 2024-09-11 12:06:43 -=ended 2024-09-11 12:06:43 +=logfile erlc_suite.arg_overflow.163.html +=started 2024-09-12 11:29:33 +=ended 2024-09-12 11:29:34 =result ok -=elapsed 0.323715 +=elapsed 0.341634 =case erlc_SUITE:make_dep_options -=logfile erlc_suite.make_dep_options.258.html -=started 2024-09-11 12:06:43 -=ended 2024-09-11 12:06:47 +=logfile erlc_suite.make_dep_options.195.html +=started 2024-09-12 11:29:34 +=ended 2024-09-12 11:29:38 =result ok -=elapsed 4.242504 +=elapsed 4.232799 =case erlc_SUITE:unicode_paths -=logfile erlc_suite.unicode_paths.290.html -=started 2024-09-11 12:06:47 -=ended 2024-09-11 12:06:47 +=logfile erlc_suite.unicode_paths.227.html +=started 2024-09-12 11:29:38 +=ended 2024-09-12 11:29:38 =result ok -=elapsed 0.238736 +=elapsed 0.231634 =case erlc_SUITE:features_erlc_describe =logfile erlc_suite.features_erlc_describe.html -=started 2024-09-11 12:06:47 -=ended 2024-09-11 12:06:48 +=started 2024-09-12 11:29:38 +=ended 2024-09-12 11:29:39 =result ok -=elapsed 0.410172 +=elapsed 0.416931 =case erlc_SUITE:features_erlc_unknown =logfile erlc_suite.features_erlc_unknown.html -=started 2024-09-11 12:06:48 -=ended 2024-09-11 12:06:51 +=started 2024-09-12 11:29:39 +=ended 2024-09-12 11:29:42 =result ok -=elapsed 3.656958 +=elapsed 3.796412 =case erlc_SUITE:features_directives =logfile erlc_suite.features_directives.html -=started 2024-09-11 12:06:51 -=ended 2024-09-11 12:06:53 +=started 2024-09-12 11:29:42 +=ended 2024-09-12 11:29:44 =result ok -=elapsed 1.192064 +=elapsed 1.198474 =case erlc_SUITE:features_atom_warnings =logfile erlc_suite.features_atom_warnings.html -=started 2024-09-11 12:06:53 -=ended 2024-09-11 12:06:53 +=started 2024-09-12 11:29:44 +=ended 2024-09-12 11:29:44 =result ok -=elapsed 0.717924 +=elapsed 0.720367 =case erlc_SUITE:features_macros =logfile erlc_suite.features_macros.html -=started 2024-09-11 12:06:53 -=ended 2024-09-11 12:06:55 +=started 2024-09-12 11:29:44 +=ended 2024-09-12 11:29:46 =result ok -=elapsed 1.712729 +=elapsed 1.759152 =case erlc_SUITE:features_disable =logfile erlc_suite.features_disable.html -=started 2024-09-11 12:06:55 -=ended 2024-09-11 12:06:56 +=started 2024-09-12 11:29:46 +=ended 2024-09-12 11:29:47 =result ok -=elapsed 0.395145 +=elapsed 0.383835 =case erlc_SUITE:features_all =logfile erlc_suite.features_all.html -=started 2024-09-11 12:06:56 -=ended 2024-09-11 12:06:57 +=started 2024-09-12 11:29:47 +=ended 2024-09-12 11:29:48 =result ok -=elapsed 1.208563 +=elapsed 1.184773 =case erlc_SUITE:features_load =logfile erlc_suite.features_load.html -=started 2024-09-11 12:06:57 -=ended 2024-09-11 12:06:57 +=started 2024-09-12 11:29:48 +=ended 2024-09-12 11:29:48 =result ok -=elapsed 0.156946 +=elapsed 0.154986 =case erlc_SUITE:features_runtime =logfile erlc_suite.features_runtime.html -=started 2024-09-11 12:06:57 -=ended 2024-09-11 12:06:57 +=started 2024-09-12 11:29:48 +=ended 2024-09-12 11:29:48 =result ok -=elapsed 0.450961 +=elapsed 0.458869 =case erlc_SUITE:features_include =logfile erlc_suite.features_include.html -=started 2024-09-11 12:06:57 -=ended 2024-09-11 12:07:00 +=started 2024-09-12 11:29:48 +=ended 2024-09-12 11:29:51 =result ok -=elapsed 2.801643 +=elapsed 2.834265 =case erlc_SUITE:features =logfile erlc_suite.features.html -=started 2024-09-11 12:07:00 -=ended 2024-09-11 12:07:02 +=started 2024-09-12 11:29:51 +=ended 2024-09-12 11:29:53 =result ok -=elapsed 1.931827 +=elapsed 1.939845 =case erlc_SUITE:end_per_group -=logfile erlc_suite.end_per_group.1410.html +=logfile erlc_suite.end_per_group.2338.html =group_props [{name,without_server}] -=started 2024-09-11 12:07:02 -=ended 2024-09-11 12:07:02 +=started 2024-09-12 11:29:53 +=ended 2024-09-12 11:29:53 =result ok =elapsed 2.0e-6 -=group_time 22.732s +=group_time 22.964s =case erlc_SUITE:init_per_group -=logfile erlc_suite.init_per_group.1442.html +=logfile erlc_suite.init_per_group.2370.html =group_props [{name,features_with_server}] -=started 2024-09-11 12:07:02 -=ended 2024-09-11 12:07:14 +=started 2024-09-12 11:29:53 +=ended 2024-09-12 11:30:05 =result ok -=elapsed 12.000661 +=elapsed 12.000163 =case erlc_SUITE:features_erlc_describe -=logfile erlc_suite.features_erlc_describe.1474.html -=started 2024-09-11 12:07:14 -=ended 2024-09-11 12:07:15 +=logfile erlc_suite.features_erlc_describe.2402.html +=started 2024-09-12 11:30:05 +=ended 2024-09-12 11:30:06 =result ok -=elapsed 0.560103 +=elapsed 0.552859 =case erlc_SUITE:features_erlc_unknown -=logfile erlc_suite.features_erlc_unknown.1506.html -=started 2024-09-11 12:07:15 -=ended 2024-09-11 12:07:19 +=logfile erlc_suite.features_erlc_unknown.2434.html +=started 2024-09-12 11:30:06 +=ended 2024-09-12 11:30:10 =result ok -=elapsed 4.215588 +=elapsed 4.257164 =case erlc_SUITE:features_directives -=logfile erlc_suite.features_directives.1538.html -=started 2024-09-11 12:07:19 -=ended 2024-09-11 12:07:21 +=logfile erlc_suite.features_directives.2466.html +=started 2024-09-12 11:30:10 +=ended 2024-09-12 11:30:12 =result ok -=elapsed 1.3478 +=elapsed 1.349351 =case erlc_SUITE:features_atom_warnings -=logfile erlc_suite.features_atom_warnings.1570.html -=started 2024-09-11 12:07:21 -=ended 2024-09-11 12:07:21 +=logfile erlc_suite.features_atom_warnings.2498.html +=started 2024-09-12 11:30:12 +=ended 2024-09-12 11:30:12 =result ok -=elapsed 0.822699 +=elapsed 0.8172 =case erlc_SUITE:features_macros -=logfile erlc_suite.features_macros.1602.html -=started 2024-09-11 12:07:21 -=ended 2024-09-11 12:07:23 +=logfile erlc_suite.features_macros.2530.html +=started 2024-09-12 11:30:12 +=ended 2024-09-12 11:30:14 =result ok -=elapsed 1.877233 +=elapsed 1.90334 =case erlc_SUITE:features_disable -=logfile erlc_suite.features_disable.1954.html -=started 2024-09-11 12:07:23 -=ended 2024-09-11 12:07:24 +=logfile erlc_suite.features_disable.2882.html +=started 2024-09-12 11:30:14 +=ended 2024-09-12 11:30:15 =result ok -=elapsed 0.424801 +=elapsed 0.419408 =case erlc_SUITE:features_all -=logfile erlc_suite.features_all.2050.html -=started 2024-09-11 12:07:24 -=ended 2024-09-11 12:07:25 +=logfile erlc_suite.features_all.2978.html +=started 2024-09-12 11:30:15 +=ended 2024-09-12 11:30:16 =result ok -=elapsed 1.281528 +=elapsed 1.302448 =case erlc_SUITE:features_load -=logfile erlc_suite.features_load.2274.html -=started 2024-09-11 12:07:25 -=ended 2024-09-11 12:07:25 +=logfile erlc_suite.features_load.3202.html +=started 2024-09-12 11:30:16 +=ended 2024-09-12 11:30:16 =result ok -=elapsed 0.15831 +=elapsed 0.155669 =case erlc_SUITE:features_runtime -=logfile erlc_suite.features_runtime.2370.html -=started 2024-09-11 12:07:25 -=ended 2024-09-11 12:07:26 +=logfile erlc_suite.features_runtime.3298.html +=started 2024-09-12 11:30:16 +=ended 2024-09-12 11:30:17 =result ok -=elapsed 0.464774 +=elapsed 0.463203 =case erlc_SUITE:features_include -=logfile erlc_suite.features_include.2594.html -=started 2024-09-11 12:07:26 -=ended 2024-09-11 12:07:29 +=logfile erlc_suite.features_include.3522.html +=started 2024-09-12 11:30:17 +=ended 2024-09-12 11:30:20 =result ok -=elapsed 3.045691 +=elapsed 3.117751 =case erlc_SUITE:features -=logfile erlc_suite.features.2882.html -=started 2024-09-11 12:07:29 -=ended 2024-09-11 12:07:31 +=logfile erlc_suite.features.3810.html +=started 2024-09-12 11:30:20 +=ended 2024-09-12 11:30:22 =result ok -=elapsed 2.166539 +=elapsed 2.243747 =case erlc_SUITE:end_per_group -=logfile erlc_suite.end_per_group.2914.html +=logfile erlc_suite.end_per_group.3842.html =group_props [{name,features_with_server}] -=started 2024-09-11 12:07:31 -=ended 2024-09-11 12:07:31 +=started 2024-09-12 11:30:22 +=ended 2024-09-12 11:30:22 =result ok -=elapsed 2.0e-6 -=group_time 28.644s +=elapsed 4.0e-6 +=group_time 28.856s =case erlc_SUITE:end_per_suite =logfile erlc_suite.end_per_suite.html -=started 2024-09-11 12:07:31 -=ended 2024-09-11 12:07:31 +=started 2024-09-12 11:30:22 +=ended 2024-09-12 11:30:22 =result ok =elapsed 0.0 -=group_time 60.504s +=group_time 61.211s =case erlexec_SUITE:init_per_suite =logfile erlexec_suite.init_per_suite.html -=started 2024-09-11 12:07:31 -=ended 2024-09-11 12:07:31 +=started 2024-09-12 11:30:22 +=ended 2024-09-12 11:30:22 =result ok -=elapsed 3.0e-6 +=elapsed 4.0e-6 =case erlexec_SUITE:args_file =logfile erlexec_suite.args_file.html -=started 2024-09-11 12:07:31 -=ended 2024-09-11 12:07:31 +=started 2024-09-12 11:30:22 +=ended 2024-09-12 11:30:22 =result ok -=elapsed 0.232833 +=elapsed 0.232625 =case erlexec_SUITE:evil_args_file =logfile erlexec_suite.evil_args_file.html -=started 2024-09-11 12:07:31 -=ended 2024-09-11 12:07:31 +=started 2024-09-12 11:30:22 +=ended 2024-09-12 11:30:23 =result ok -=elapsed 0.059467 +=elapsed 0.068742 =case erlexec_SUITE:missing_args_file =logfile erlexec_suite.missing_args_file.html -=started 2024-09-11 12:07:31 -=ended 2024-09-11 12:07:31 +=started 2024-09-12 11:30:23 +=ended 2024-09-12 11:30:23 =result ok -=elapsed 0.006589 +=elapsed 0.006629 =case erlexec_SUITE:env =logfile erlexec_suite.env.html -=started 2024-09-11 12:07:31 -=ended 2024-09-11 12:07:31 +=started 2024-09-12 11:30:23 +=ended 2024-09-12 11:30:23 =result ok -=elapsed 0.007542 +=elapsed 0.006678 =case erlexec_SUITE:args_file_env =logfile erlexec_suite.args_file_env.html -=started 2024-09-11 12:07:31 -=ended 2024-09-11 12:07:31 +=started 2024-09-12 11:30:23 +=ended 2024-09-12 11:30:23 =result ok -=elapsed 0.007021 +=elapsed 0.007091 =case erlexec_SUITE:otp_7461 =logfile erlexec_suite.otp_7461.html -=started 2024-09-11 12:07:31 -=ended 2024-09-11 12:07:32 +=started 2024-09-12 11:30:23 +=ended 2024-09-12 11:30:23 =result ok -=elapsed 0.180352 +=elapsed 0.179716 =case erlexec_SUITE:argument_separation =logfile erlexec_suite.argument_separation.html -=started 2024-09-11 12:07:32 -=ended 2024-09-11 12:07:33 +=started 2024-09-12 11:30:23 +=ended 2024-09-12 11:30:24 =result ok -=elapsed 1.5239 +=elapsed 1.523031 =case erlexec_SUITE:argument_with_option =logfile erlexec_suite.argument_with_option.html -=started 2024-09-11 12:07:33 -=ended 2024-09-11 12:07:34 +=started 2024-09-12 11:30:24 +=ended 2024-09-12 11:30:25 =result ok -=elapsed 0.457336 +=elapsed 0.456981 =case erlexec_SUITE:zdbbl_dist_buf_busy_limit =logfile erlexec_suite.zdbbl_dist_buf_busy_limit.html -=started 2024-09-11 12:07:34 -=ended 2024-09-11 12:07:35 +=started 2024-09-12 11:30:25 +=ended 2024-09-12 11:30:26 =result ok -=elapsed 1.52463 +=elapsed 1.526665 =case erlexec_SUITE:end_per_suite =logfile erlexec_suite.end_per_suite.html -=started 2024-09-11 12:07:35 -=ended 2024-09-11 12:07:35 +=started 2024-09-12 11:30:26 +=ended 2024-09-12 11:30:26 =result ok -=elapsed 2.0e-6 -=group_time 4.237s +=elapsed 4.0e-6 +=group_time 4.246s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.3138.html +=logfile ct_framework.init_per_suite.4066.html =group_props [{suite,ethread_SUITE}] -=started 2024-09-11 12:07:35 -=ended 2024-09-11 12:07:35 +=started 2024-09-12 11:30:26 +=ended 2024-09-12 11:30:26 =result ok =elapsed 0.0 =case ethread_SUITE:create_join_thread =logfile ethread_suite.create_join_thread.html -=started 2024-09-11 12:07:35 -=ended 2024-09-11 12:07:35 +=started 2024-09-12 11:30:26 +=ended 2024-09-12 11:30:27 =result ok -=elapsed 0.005221 +=elapsed 0.005904 =case ethread_SUITE:equal_tids =logfile ethread_suite.equal_tids.html -=started 2024-09-11 12:07:35 -=ended 2024-09-11 12:07:35 +=started 2024-09-12 11:30:27 +=ended 2024-09-12 11:30:27 =result ok -=elapsed 0.046405 +=elapsed 0.046122 =case ethread_SUITE:mutex =logfile ethread_suite.mutex.html -=started 2024-09-11 12:07:35 -=ended 2024-09-11 12:07:38 +=started 2024-09-12 11:30:27 +=ended 2024-09-12 11:30:30 =result ok -=elapsed 3.00568 +=elapsed 3.005503 =case ethread_SUITE:try_lock_mutex =logfile ethread_suite.try_lock_mutex.html -=started 2024-09-11 12:07:38 -=ended 2024-09-11 12:07:38 +=started 2024-09-12 11:30:30 +=ended 2024-09-12 11:30:30 =result ok -=elapsed 0.001864 +=elapsed 0.001948 =case ethread_SUITE:cond_wait =logfile ethread_suite.cond_wait.html -=started 2024-09-11 12:07:38 -=ended 2024-09-11 12:07:46 +=started 2024-09-12 11:30:30 +=ended 2024-09-12 11:30:38 =result ok -=elapsed 8.010558 +=elapsed 8.01045 =case ethread_SUITE:broadcast =logfile ethread_suite.broadcast.html -=started 2024-09-11 12:07:46 -=ended 2024-09-11 12:07:47 +=started 2024-09-12 11:30:38 +=ended 2024-09-12 11:30:38 =result ok -=elapsed 0.075083 +=elapsed 0.076988 =case ethread_SUITE:detached_thread =logfile ethread_suite.detached_thread.html -=started 2024-09-11 12:07:47 -=ended 2024-09-11 12:07:49 +=started 2024-09-12 11:30:38 +=ended 2024-09-12 11:30:40 =result ok -=elapsed 2.094962 +=elapsed 2.114922 =case ethread_SUITE:max_threads =logfile ethread_suite.max_threads.html -=started 2024-09-11 12:07:49 -=ended 2024-09-11 12:07:49 +=started 2024-09-12 11:30:40 +=ended 2024-09-12 11:30:40 =result ok: Max created threads: 466, 466, 466, 466, 466, 466, 466, 466, 466, 466 -=elapsed 0.246961 +=elapsed 0.292115 =case ethread_SUITE:tsd =logfile ethread_suite.tsd.html -=started 2024-09-11 12:07:49 -=ended 2024-09-11 12:07:49 +=started 2024-09-12 11:30:40 +=ended 2024-09-12 11:30:40 =result ok -=elapsed 0.002315 +=elapsed 0.002496 =case ethread_SUITE:spinlock =logfile ethread_suite.spinlock.html -=started 2024-09-11 12:07:49 -=ended 2024-09-11 12:07:52 +=started 2024-09-12 11:30:40 +=ended 2024-09-12 11:30:43 =result ok -=elapsed 3.005107 +=elapsed 3.005551 =case ethread_SUITE:rwspinlock =logfile ethread_suite.rwspinlock.html -=started 2024-09-11 12:07:52 -=ended 2024-09-11 12:07:55 +=started 2024-09-12 11:30:43 +=ended 2024-09-12 11:30:46 =result ok -=elapsed 3.005314 +=elapsed 3.005612 =case ethread_SUITE:rwmutex =logfile ethread_suite.rwmutex.html -=started 2024-09-11 12:07:55 -=ended 2024-09-11 12:07:58 +=started 2024-09-12 11:30:46 +=ended 2024-09-12 11:30:49 =result ok -=elapsed 3.005554 +=elapsed 3.005759 =case ethread_SUITE:atomic =logfile ethread_suite.atomic.html -=started 2024-09-11 12:07:58 -=ended 2024-09-11 12:07:58 +=started 2024-09-12 11:30:49 +=ended 2024-09-12 11:30:49 =result ok -=elapsed 0.035454 +=elapsed 0.031791 =case ethread_SUITE:dw_atomic_massage =logfile ethread_suite.dw_atomic_massage.html -=started 2024-09-11 12:07:58 -=ended 2024-09-11 12:08:01 +=started 2024-09-12 11:30:49 +=ended 2024-09-12 11:30:52 =result ok -=elapsed 2.822462 +=elapsed 2.649104 =case ethread_SUITE:thread_name =logfile ethread_suite.thread_name.html -=started 2024-09-11 12:08:01 -=ended 2024-09-11 12:08:01 +=started 2024-09-12 11:30:52 +=ended 2024-09-12 11:30:52 =result ok -=elapsed 0.002215 +=elapsed 0.002084 =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.3170.html +=logfile ct_framework.end_per_suite.4098.html =group_props [{suite,ethread_SUITE}] -=started 2024-09-11 12:08:01 -=ended 2024-09-11 12:08:01 +=started 2024-09-12 11:30:52 +=ended 2024-09-12 11:30:52 =result ok =elapsed 0.0 -=group_time 25.741s +=group_time 25.633s =case install_SUITE:init_per_suite =logfile install_suite.init_per_suite.html -=started 2024-09-11 12:08:01 -=ended 2024-09-11 12:08:01 +=started 2024-09-12 11:30:52 +=ended 2024-09-12 11:30:52 =result ok -=elapsed 6.3e-5 +=elapsed 7.4e-5 =case install_SUITE:bin_default =logfile install_suite.bin_default.html -=started 2024-09-11 12:08:01 -=ended 2024-09-11 12:08:01 +=started 2024-09-12 11:30:52 +=ended 2024-09-12 11:30:52 =result ok -=elapsed 0.27128 +=elapsed 0.273373 =case install_SUITE:bin_default_dirty =logfile install_suite.bin_default_dirty.html -=started 2024-09-11 12:08:01 -=ended 2024-09-11 12:08:02 +=started 2024-09-12 11:30:52 +=ended 2024-09-12 11:30:53 =result ok -=elapsed 0.322041 +=elapsed 0.317555 =case install_SUITE:bin_outside_eprfx =logfile install_suite.bin_outside_eprfx.html -=started 2024-09-11 12:08:02 -=ended 2024-09-11 12:08:02 +=started 2024-09-12 11:30:53 +=ended 2024-09-12 11:30:53 =result ok -=elapsed 0.273327 +=elapsed 0.271898 =case install_SUITE:bin_outside_eprfx_dirty =logfile install_suite.bin_outside_eprfx_dirty.html -=started 2024-09-11 12:08:02 -=ended 2024-09-11 12:08:02 +=started 2024-09-12 11:30:53 +=ended 2024-09-12 11:30:53 =result ok -=elapsed 0.282138 +=elapsed 0.282837 =case install_SUITE:bin_not_abs =logfile install_suite.bin_not_abs.html -=started 2024-09-11 12:08:02 -=ended 2024-09-11 12:08:02 +=started 2024-09-12 11:30:53 +=ended 2024-09-12 11:30:54 =result ok -=elapsed 0.164441 +=elapsed 0.166324 =case install_SUITE:bin_unreasonable_path =logfile install_suite.bin_unreasonable_path.html -=started 2024-09-11 12:08:02 -=ended 2024-09-11 12:08:03 +=started 2024-09-12 11:30:54 +=ended 2024-09-12 11:30:54 =result ok -=elapsed 0.289144 +=elapsed 0.29064 =case install_SUITE:'bin white space' =logfile install_suite.'bin white space'.html -=started 2024-09-11 12:08:03 -=ended 2024-09-11 12:08:03 +=started 2024-09-12 11:30:54 +=ended 2024-09-12 11:30:54 =result ok -=elapsed 0.265483 +=elapsed 0.268912 =case install_SUITE:bin_no_srcfile =logfile install_suite.bin_no_srcfile.html -=started 2024-09-11 12:08:03 -=ended 2024-09-11 12:08:03 +=started 2024-09-12 11:30:54 +=ended 2024-09-12 11:30:54 =result ok -=elapsed 0.219136 +=elapsed 0.224399 =case install_SUITE:bin_unreachable_absolute =logfile install_suite.bin_unreachable_absolute.html -=started 2024-09-11 12:08:03 -=ended 2024-09-11 12:08:04 +=started 2024-09-12 11:30:54 +=ended 2024-09-12 11:30:55 =result ok -=elapsed 0.276723 +=elapsed 0.274287 =case install_SUITE:bin_unreachable_relative =logfile install_suite.bin_unreachable_relative.html -=started 2024-09-11 12:08:04 -=ended 2024-09-11 12:08:04 +=started 2024-09-12 11:30:55 +=ended 2024-09-12 11:30:55 =result ok -=elapsed 0.269817 +=elapsed 0.271564 =case install_SUITE:bin_same_dir =logfile install_suite.bin_same_dir.html -=started 2024-09-11 12:08:04 -=ended 2024-09-11 12:08:04 +=started 2024-09-12 11:30:55 +=ended 2024-09-12 11:30:55 =result ok -=elapsed 0.206632 +=elapsed 0.205642 =case install_SUITE:bin_ok_symlink =logfile install_suite.bin_ok_symlink.html -=started 2024-09-11 12:08:04 -=ended 2024-09-11 12:08:04 +=started 2024-09-12 11:30:55 +=ended 2024-09-12 11:30:56 =result ok -=elapsed 0.268252 +=elapsed 0.267641 =case install_SUITE:bin_dirname_fail =logfile install_suite.bin_dirname_fail.html -=started 2024-09-11 12:08:04 -=ended 2024-09-11 12:08:05 +=started 2024-09-12 11:30:56 +=ended 2024-09-12 11:30:56 =result ok -=elapsed 0.274169 +=elapsed 0.27861 =case install_SUITE:bin_no_use_dirname_fail =logfile install_suite.bin_no_use_dirname_fail.html -=started 2024-09-11 12:08:05 -=ended 2024-09-11 12:08:05 +=started 2024-09-12 11:30:56 +=ended 2024-09-12 11:30:56 =result ok -=elapsed 0.269308 +=elapsed 0.274265 =case install_SUITE:end_per_suite =logfile install_suite.end_per_suite.html -=started 2024-09-11 12:08:05 -=ended 2024-09-11 12:08:05 +=started 2024-09-12 11:30:56 +=ended 2024-09-12 11:30:56 =result ok =elapsed 0.0 -=group_time 4.010s +=group_time 4.023s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.3202.html +=logfile ct_framework.init_per_suite.4130.html =group_props [{suite,nt_SUITE}] -=started 2024-09-11 12:08:05 -=ended 2024-09-11 12:08:05 +=started 2024-09-12 11:30:56 +=ended 2024-09-12 11:30:56 =result ok =elapsed 0.0 =case nt_SUITE:nt =logfile nt_suite.nt.html -=started 2024-09-11 12:08:05 -=ended 2024-09-11 12:08:05 +=started 2024-09-12 11:30:56 +=ended 2024-09-12 11:30:56 =result skipped: "This test case is intended for Win NT only." === *** SKIPPED test case 86 of 109 *** =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.3234.html +=logfile ct_framework.end_per_suite.4162.html =group_props [{suite,nt_SUITE}] -=started 2024-09-11 12:08:05 -=ended 2024-09-11 12:08:05 +=started 2024-09-12 11:30:56 +=ended 2024-09-12 11:30:56 =result ok =elapsed 0.0 =group_time 0.053s =case otp_SUITE:init_per_suite =logfile otp_suite.init_per_suite.html -=started 2024-09-11 12:08:05 -=ended 2024-09-11 12:08:08 +=started 2024-09-12 11:30:56 +=ended 2024-09-12 11:30:59 =result ok -=elapsed 2.775182 +=elapsed 2.912863 =case otp_SUITE:undefined_functions =logfile otp_suite.undefined_functions.html -=started 2024-09-11 12:08:08 -=ended 2024-09-11 12:08:09 +=started 2024-09-12 11:30:59 +=ended 2024-09-12 11:31:00 =result ok -=elapsed 1.086329 +=elapsed 1.253548 =case otp_SUITE:deprecated_not_in_obsolete =logfile otp_suite.deprecated_not_in_obsolete.html -=started 2024-09-11 12:08:09 -=ended 2024-09-11 12:08:09 +=started 2024-09-12 11:31:00 +=ended 2024-09-12 11:31:00 =result ok -=elapsed 2.28e-4 +=elapsed 2.36e-4 =case otp_SUITE:obsolete_but_not_deprecated =logfile otp_suite.obsolete_but_not_deprecated.html -=started 2024-09-11 12:08:09 -=ended 2024-09-11 12:08:09 +=started 2024-09-12 11:31:00 +=ended 2024-09-12 11:31:01 =result ok -=elapsed 0.00648 +=elapsed 0.008103 =case otp_SUITE:call_to_deprecated =logfile otp_suite.call_to_deprecated.html -=started 2024-09-11 12:08:09 -=ended 2024-09-11 12:08:09 +=started 2024-09-12 11:31:01 +=ended 2024-09-12 11:31:01 =result ok: 47 calls to deprecated functions -=elapsed 0.381815 +=elapsed 0.448258 =case otp_SUITE:call_to_size_1 =logfile otp_suite.call_to_size_1.html -=started 2024-09-11 12:08:09 -=ended 2024-09-11 12:08:10 +=started 2024-09-12 11:31:01 +=ended 2024-09-12 11:31:01 =result ok -=elapsed 0.304928 +=elapsed 0.381578 =case otp_SUITE:call_to_now_0 =logfile otp_suite.call_to_now_0.html -=started 2024-09-11 12:08:10 -=ended 2024-09-11 12:08:10 +=started 2024-09-12 11:31:01 +=ended 2024-09-12 11:31:02 =result ok -=elapsed 0.302416 +=elapsed 0.370781 =case otp_SUITE:strong_components =logfile otp_suite.strong_components.html -=started 2024-09-11 12:08:10 -=ended 2024-09-11 12:08:10 +=started 2024-09-12 11:31:02 +=ended 2024-09-12 11:31:02 =result ok -=elapsed 6.45e-4 +=elapsed 5.94e-4 =case otp_SUITE:erl_file_encoding =logfile otp_suite.erl_file_encoding.html -=started 2024-09-11 12:08:10 -=ended 2024-09-11 12:08:10 +=started 2024-09-12 11:31:02 +=ended 2024-09-12 11:31:02 =result ok -=elapsed 0.264632 +=elapsed 0.260781 =case otp_SUITE:xml_file_encoding =logfile otp_suite.xml_file_encoding.html -=started 2024-09-11 12:08:10 -=ended 2024-09-11 12:08:11 +=started 2024-09-12 11:31:02 +=ended 2024-09-12 11:31:02 =result ok -=elapsed 0.077772 +=elapsed 0.042661 =case otp_SUITE:runtime_dependencies_functions =logfile otp_suite.runtime_dependencies_functions.html -=started 2024-09-11 12:08:11 -=ended 2024-09-11 12:08:11 +=started 2024-09-12 11:31:02 +=ended 2024-09-12 11:31:02 =result ok: Ignored applications: [diameter] Ignored failures: [{missing_runtime_dependency, [47,98,117,105,108,100, 114,111,111,116,47,111, @@ -747,11 +747,11 @@ 100,105,97,109,101,116, 101,114,46,97,112,112], runtime_tools}] -=elapsed 0.013068 +=elapsed 0.011479 =case otp_SUITE:runtime_dependencies_modules =logfile otp_suite.runtime_dependencies_modules.html -=started 2024-09-11 12:08:11 -=ended 2024-09-11 12:08:11 +=started 2024-09-12 11:31:02 +=ended 2024-09-12 11:31:03 =result ok: Ignored applications: [diameter] Ignored failures: [{missing_runtime_dependency, [47,98,117,105,108,100, 114,111,111,116,47,111, @@ -782,157 +782,157 @@ 100,105,97,109,101,116, 101,114,46,97,112,112], runtime_tools}] -=elapsed 0.439328 +=elapsed 0.46272 =case otp_SUITE:test_runtime_dependencies_versions =logfile otp_suite.test_runtime_dependencies_versions.html -=started 2024-09-11 12:08:11 -=ended 2024-09-11 12:08:11 +=started 2024-09-12 11:31:03 +=ended 2024-09-12 11:31:03 =result skipped: "This test case is designed to run in the Erlang/OTP teams test system for daily tests. The test case depends on that app versions have been set correctly by scripts that are executed before creating builds for the daily tests." === *** SKIPPED test case 98 of 109 *** =case otp_SUITE:end_per_suite =logfile otp_suite.end_per_suite.html -=started 2024-09-11 12:08:11 -=ended 2024-09-11 12:08:11 +=started 2024-09-12 11:31:03 +=ended 2024-09-12 11:31:03 =result ok -=elapsed 1.6e-5 -=group_time 5.968s +=elapsed 2.4e-5 +=group_time 6.466s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.3266.html +=logfile ct_framework.init_per_suite.5.html =group_props [{suite,parallel_messages_SUITE}] -=started 2024-09-11 12:08:11 -=ended 2024-09-11 12:08:11 +=started 2024-09-12 11:31:03 +=ended 2024-09-12 11:31:03 =result ok =elapsed 0.0 =case parallel_messages_SUITE:test_throughput_benchmark =logfile parallel_messages_suite.test_throughput_benchmark.html -=started 2024-09-11 12:08:11 -=ended 2024-09-11 12:08:32 -=result ok: Result visualization -=elapsed 20.409693 +=started 2024-09-12 11:31:03 +=ended 2024-09-12 11:31:23 +=result ok: Result visualization +=elapsed 20.347075 =case parallel_messages_SUITE:test_message_queue_data_switching =logfile parallel_messages_suite.test_message_queue_data_switching.html -=started 2024-09-11 12:08:32 -=ended 2024-09-11 12:08:34 -=result ok: Result visualization -=elapsed 2.654152 +=started 2024-09-12 11:31:23 +=ended 2024-09-12 11:32:46 +=result ok: Result visualization +=elapsed 82.400039 =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.3746.html +=logfile ct_framework.end_per_suite.4482.html =group_props [{suite,parallel_messages_SUITE}] -=started 2024-09-11 12:08:34 -=ended 2024-09-11 12:08:34 +=started 2024-09-12 11:32:46 +=ended 2024-09-12 11:32:46 =result ok =elapsed 0.0 -=group_time 23.135s +=group_time 102.819s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.3778.html +=logfile ct_framework.init_per_suite.4514.html =group_props [{suite,run_erl_SUITE}] -=started 2024-09-11 12:08:34 -=ended 2024-09-11 12:08:34 +=started 2024-09-12 11:32:46 +=ended 2024-09-12 11:32:46 =result ok =elapsed 0.0 =case run_erl_SUITE:basic =logfile run_erl_suite.basic.html -=started 2024-09-11 12:08:34 -=ended 2024-09-11 12:08:35 +=started 2024-09-12 11:32:46 +=ended 2024-09-12 11:32:46 =result ok -=elapsed 0.187203 +=elapsed 0.193485 =case run_erl_SUITE:sleepy_child =logfile run_erl_suite.sleepy_child.html -=started 2024-09-11 12:08:35 -=ended 2024-09-11 12:08:36 +=started 2024-09-12 11:32:46 +=ended 2024-09-12 11:32:47 =result ok -=elapsed 1.188275 +=elapsed 1.181595 =case run_erl_SUITE:heavy =logfile run_erl_suite.heavy.html -=started 2024-09-11 12:08:36 -=ended 2024-09-11 12:08:37 +=started 2024-09-12 11:32:47 +=ended 2024-09-12 11:32:48 =result ok -=elapsed 1.219514 +=elapsed 1.217663 =case run_erl_SUITE:heavier =logfile run_erl_suite.heavier.html -=started 2024-09-11 12:08:37 -=ended 2024-09-11 12:08:39 +=started 2024-09-12 11:32:48 +=ended 2024-09-12 11:32:50 =result ok -=elapsed 1.920728 +=elapsed 1.951775 =case run_erl_SUITE:defunct =logfile run_erl_suite.defunct.html -=started 2024-09-11 12:08:39 -=ended 2024-09-11 12:08:49 +=started 2024-09-12 11:32:50 +=ended 2024-09-12 11:32:55 =result ok -=elapsed 10.007828 +=elapsed 5.009234 =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.3970.html +=logfile ct_framework.end_per_suite.4674.html =group_props [{suite,run_erl_SUITE}] -=started 2024-09-11 12:08:49 -=ended 2024-09-11 12:08:49 +=started 2024-09-12 11:32:55 +=ended 2024-09-12 11:32:55 =result ok =elapsed 0.0 -=group_time 14.661s +=group_time 9.693s =case upgrade_SUITE:init_per_suite =logfile upgrade_suite.init_per_suite.html -=started 2024-09-11 12:08:49 -=ended 2024-09-11 12:08:49 +=started 2024-09-12 11:32:55 +=ended 2024-09-12 11:32:55 =result ok -=elapsed 4.0e-5 +=elapsed 3.9e-5 =case upgrade_SUITE:minor =logfile upgrade_suite.minor.html -=started 2024-09-11 12:08:49 -=node_start 'otp-28@27af2e7fa355' -=node_stop 'otp-28@27af2e7fa355' -=ended 2024-09-11 12:09:07 +=started 2024-09-12 11:32:55 +=node_start 'otp-28@a4cca6e7dcb5' +=node_stop 'otp-28@a4cca6e7dcb5' +=ended 2024-09-12 11:33:13 =result ok -=elapsed 17.971508 +=elapsed 17.860544 =case upgrade_SUITE:major =logfile upgrade_suite.major.html -=started 2024-09-11 12:09:07 -=node_start 'otp-27@27af2e7fa355' +=started 2024-09-12 11:33:13 +=node_start 'otp-27@a4cca6e7dcb5' WARNING: Started node reports different system version than current node! Current node version: "28", "Erlang/OTP 28 [DEVELOPMENT] [erts-15.0.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit:ns]\n" Started node version: "27", "Erlang/OTP 27 [erts-15.0.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit:ns]\n" -=node_stop 'otp-27@27af2e7fa355' -=ended 2024-09-11 12:09:49 +=node_stop 'otp-27@a4cca6e7dcb5' +=ended 2024-09-12 11:33:55 =result ok -=elapsed 41.41203 +=elapsed 41.526557 =case upgrade_SUITE:ancient_major =logfile upgrade_suite.ancient_major.html -=started 2024-09-11 12:09:49 -=node_start 'otp-26@27af2e7fa355' +=started 2024-09-12 11:33:55 +=node_start 'otp-26@a4cca6e7dcb5' WARNING: Started node reports different system version than current node! Current node version: "28", "Erlang/OTP 28 [DEVELOPMENT] [erts-15.0.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit:ns]\n" Started node version: "26", "Erlang/OTP 26 [erts-14.2.5.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit:ns]\n" -=node_stop 'otp-26@27af2e7fa355' -=ended 2024-09-11 12:10:37 +=node_stop 'otp-26@a4cca6e7dcb5' +=ended 2024-09-12 11:34:44 =result ok -=elapsed 48.387121 +=elapsed 48.405491 =case upgrade_SUITE:end_per_suite =logfile upgrade_suite.end_per_suite.html -=started 2024-09-11 12:10:37 -=ended 2024-09-11 12:10:37 +=started 2024-09-12 11:34:44 +=ended 2024-09-12 11:34:44 =result ok =elapsed 0.0 -=group_time 108.434s +=group_time 108.435s =case ct_framework:init_per_suite -=logfile ct_framework.init_per_suite.4450.html +=logfile ct_framework.init_per_suite.5090.html =group_props [{suite,z_SUITE}] -=started 2024-09-11 12:10:37 -=ended 2024-09-11 12:10:37 +=started 2024-09-12 11:34:44 +=ended 2024-09-12 11:34:44 =result ok =elapsed 0.0 =case z_SUITE:core_files =logfile z_suite.core_files.html -=started 2024-09-11 12:10:37 -=ended 2024-09-11 12:10:38 +=started 2024-09-12 11:34:44 +=ended 2024-09-12 11:34:44 =result ok -=elapsed 0.41917 +=elapsed 0.620831 =case ct_framework:end_per_suite -=logfile ct_framework.end_per_suite.4482.html +=logfile ct_framework.end_per_suite.5122.html =group_props [{suite,z_SUITE}] -=started 2024-09-11 12:10:38 -=ended 2024-09-11 12:10:38 +=started 2024-09-12 11:34:44 +=ended 2024-09-12 11:34:44 =result ok =elapsed 0.0 -=group_time 0.467s +=group_time 0.670s === TEST COMPLETE, 107 ok, 0 failed, 2 skipped of 109 test cases -=finished 2024-09-11 12:10:38 +=finished 2024-09-12 11:34:44 =failed 0 =successful 107 =user_skipped 2 =auto_skipped 0 -=elapsed_time 247874758 +=elapsed_time 323920054 diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/suite.log.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/suite.log.html similarity index 81% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/suite.log.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/suite.log.html index e672f28fc52ab..f46c8b65871af 100644 --- a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/suite.log.html +++ b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/suite.log.html @@ -80,9 +80,9 @@

    Results for make_test_dir.system_test

    -

    Test started at 2024-09-11 12:06:30

    +

    Test started at 2024-09-12 11:29:21

    Host info:
    -Run by otptest on 27af2e7fa355
    Used Erlang v15.0.1 in "/buildroot/otp/erts/make_test_dir/Erlang ∅⊤℞"

    +Run by otptest on a4cca6e7dcb5
    Used Erlang v15.0.1 in "/buildroot/otp/erts/make_test_dir/Erlang ∅⊤℞"

    • Full textual log
    • Coverage log
    • @@ -98,119 +98,119 @@

      Test started at 2024-09-11 12:06:30

      common_testinit_per_suite< >0.000sOk 1erl_print_SUITEerlang_display< >0.004sOk -2erl_print_SUITEinteger< >0.031sOk +2erl_print_SUITEinteger< >0.029sOk 3erl_print_SUITEfloat< >0.002sOk 4erl_print_SUITEstring< >0.002sOk -5erl_print_SUITEcharacter< >0.028sOk -6erl_print_SUITEsnprintf< >0.002sOk +5erl_print_SUITEcharacter< >0.020sOk +6erl_print_SUITEsnprintf< >0.003sOk 7erl_print_SUITEquote< >0.002sOk common_testend_per_suite< >0.000sOk erlc_SUITEinit_per_suite< >0.000sOk erlc_SUITEwith_serverinit_per_group< >0.000sOk -8erlc_SUITEwith_servercompile_erl< >1.107sOk -9erlc_SUITEwith_servercompile_yecc< >0.434sOk -10erlc_SUITEwith_servercompile_script< >0.357sOk -11erlc_SUITEwith_servercompile_mib< >0.974sOk -12erlc_SUITEwith_servergood_citizen< >0.270sOk -13erlc_SUITEwith_serverdeep_cwd< >0.253sOk -14erlc_SUITEwith_serverarg_overflow< >0.373sOk -15erlc_SUITEwith_servermake_dep_options< >4.803sOk -16erlc_SUITEwith_serverunicode_paths< >0.232sOk +8erlc_SUITEwith_servercompile_erl< >1.100sOk +9erlc_SUITEwith_servercompile_yecc< >0.436sOk +10erlc_SUITEwith_servercompile_script< >0.382sOk +11erlc_SUITEwith_servercompile_mib< >1.010sOk +12erlc_SUITEwith_servergood_citizen< >0.263sOk +13erlc_SUITEwith_serverdeep_cwd< >0.292sOk +14erlc_SUITEwith_serverarg_overflow< >0.359sOk +15erlc_SUITEwith_servermake_dep_options< >4.937sOk +16erlc_SUITEwith_serverunicode_paths< >0.290sOk erlc_SUITEwith_serverend_per_group< >0.000sOk -erlc_SUITEwithout_serverinit_per_group< >0.000sOk -17erlc_SUITEwithout_servercompile_erl< >0.999sOk -18erlc_SUITEwithout_servercompile_yecc< >0.322sOk -19erlc_SUITEwithout_servercompile_script< >0.274sOk -20erlc_SUITEwithout_servercompile_mib< >0.716sOk -21erlc_SUITEwithout_servergood_citizen< >0.243sOk -22erlc_SUITEwithout_serverdeep_cwd< >0.259sOk -23erlc_SUITEwithout_serverarg_overflow< >0.324sOk -24erlc_SUITEwithout_servermake_dep_options< >4.243sOk -25erlc_SUITEwithout_serverunicode_paths< >0.239sOk -26erlc_SUITEwithout_serverfeatures_erlc_describe< >0.410sOk -27erlc_SUITEwithout_serverfeatures_erlc_unknown< >3.657sOk -28erlc_SUITEwithout_serverfeatures_directives< >1.192sOk -29erlc_SUITEwithout_serverfeatures_atom_warnings< >0.718sOk -30erlc_SUITEwithout_serverfeatures_macros< >1.713sOk -31erlc_SUITEwithout_serverfeatures_disable< >0.395sOk -32erlc_SUITEwithout_serverfeatures_all< >1.209sOk -33erlc_SUITEwithout_serverfeatures_load< >0.157sOk -34erlc_SUITEwithout_serverfeatures_runtime< >0.451sOk -35erlc_SUITEwithout_serverfeatures_include< >2.802sOk -36erlc_SUITEwithout_serverfeatures< >1.932sOk -erlc_SUITEwithout_serverend_per_group< >0.000sOk -erlc_SUITEfeatures_with_serverinit_per_group< >12.001sOk -37erlc_SUITEfeatures_with_serverfeatures_erlc_describe< >0.560sOk -38erlc_SUITEfeatures_with_serverfeatures_erlc_unknown< >4.216sOk -39erlc_SUITEfeatures_with_serverfeatures_directives< >1.348sOk -40erlc_SUITEfeatures_with_serverfeatures_atom_warnings< >0.823sOk -41erlc_SUITEfeatures_with_serverfeatures_macros< >1.877sOk -42erlc_SUITEfeatures_with_serverfeatures_disable< >0.425sOk -43erlc_SUITEfeatures_with_serverfeatures_all< >1.282sOk -44erlc_SUITEfeatures_with_serverfeatures_load< >0.158sOk -45erlc_SUITEfeatures_with_serverfeatures_runtime< >0.465sOk -46erlc_SUITEfeatures_with_serverfeatures_include< >3.046sOk -47erlc_SUITEfeatures_with_serverfeatures< >2.167sOk -erlc_SUITEfeatures_with_serverend_per_group< >0.000sOk +erlc_SUITEwithout_serverinit_per_group< >0.000sOk +17erlc_SUITEwithout_servercompile_erl< >0.984sOk +18erlc_SUITEwithout_servercompile_yecc< >0.320sOk +19erlc_SUITEwithout_servercompile_script< >0.285sOk +20erlc_SUITEwithout_servercompile_mib< >0.749sOk +21erlc_SUITEwithout_servergood_citizen< >0.236sOk +22erlc_SUITEwithout_serverdeep_cwd< >0.258sOk +23erlc_SUITEwithout_serverarg_overflow< >0.342sOk +24erlc_SUITEwithout_servermake_dep_options< >4.233sOk +25erlc_SUITEwithout_serverunicode_paths< >0.232sOk +26erlc_SUITEwithout_serverfeatures_erlc_describe< >0.417sOk +27erlc_SUITEwithout_serverfeatures_erlc_unknown< >3.796sOk +28erlc_SUITEwithout_serverfeatures_directives< >1.198sOk +29erlc_SUITEwithout_serverfeatures_atom_warnings< >0.720sOk +30erlc_SUITEwithout_serverfeatures_macros< >1.759sOk +31erlc_SUITEwithout_serverfeatures_disable< >0.384sOk +32erlc_SUITEwithout_serverfeatures_all< >1.185sOk +33erlc_SUITEwithout_serverfeatures_load< >0.155sOk +34erlc_SUITEwithout_serverfeatures_runtime< >0.459sOk +35erlc_SUITEwithout_serverfeatures_include< >2.834sOk +36erlc_SUITEwithout_serverfeatures< >1.940sOk +erlc_SUITEwithout_serverend_per_group< >0.000sOk +erlc_SUITEfeatures_with_serverinit_per_group< >12.000sOk +37erlc_SUITEfeatures_with_serverfeatures_erlc_describe< >0.553sOk +38erlc_SUITEfeatures_with_serverfeatures_erlc_unknown< >4.257sOk +39erlc_SUITEfeatures_with_serverfeatures_directives< >1.349sOk +40erlc_SUITEfeatures_with_serverfeatures_atom_warnings< >0.817sOk +41erlc_SUITEfeatures_with_serverfeatures_macros< >1.903sOk +42erlc_SUITEfeatures_with_serverfeatures_disable< >0.419sOk +43erlc_SUITEfeatures_with_serverfeatures_all< >1.302sOk +44erlc_SUITEfeatures_with_serverfeatures_load< >0.156sOk +45erlc_SUITEfeatures_with_serverfeatures_runtime< >0.463sOk +46erlc_SUITEfeatures_with_serverfeatures_include< >3.118sOk +47erlc_SUITEfeatures_with_serverfeatures< >2.244sOk +erlc_SUITEfeatures_with_serverend_per_group< >0.000sOk erlc_SUITEend_per_suite< >0.000sOk erlexec_SUITEinit_per_suite< >0.000sOk 48erlexec_SUITEargs_file< >0.233sOk -49erlexec_SUITEevil_args_file< >0.059sOk +49erlexec_SUITEevil_args_file< >0.069sOk 50erlexec_SUITEmissing_args_file< >0.007sOk -51erlexec_SUITEenv< >0.008sOk +51erlexec_SUITEenv< >0.007sOk 52erlexec_SUITEargs_file_env< >0.007sOk 53erlexec_SUITEotp_7461< >0.180sOk -54erlexec_SUITEargument_separation< >1.524sOk +54erlexec_SUITEargument_separation< >1.523sOk 55erlexec_SUITEargument_with_option< >0.457sOk -56erlexec_SUITEzdbbl_dist_buf_busy_limit< >1.525sOk +56erlexec_SUITEzdbbl_dist_buf_busy_limit< >1.527sOk erlexec_SUITEend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk -57ethread_SUITEcreate_join_thread< >0.005sOk +common_testinit_per_suite< >0.000sOk +57ethread_SUITEcreate_join_thread< >0.006sOk 58ethread_SUITEequal_tids< >0.046sOk 59ethread_SUITEmutex< >3.006sOk 60ethread_SUITEtry_lock_mutex< >0.002sOk -61ethread_SUITEcond_wait< >8.011sOk -62ethread_SUITEbroadcast< >0.075sOk -63ethread_SUITEdetached_thread< >2.095sOk -64ethread_SUITEmax_threads< >0.247sOkMax created threads: 466, 466, 466, 466, 466, 466, 466, 466, 466, 466 +61ethread_SUITEcond_wait< >8.010sOk +62ethread_SUITEbroadcast< >0.077sOk +63ethread_SUITEdetached_thread< >2.115sOk +64ethread_SUITEmax_threads< >0.292sOkMax created threads: 466, 466, 466, 466, 466, 466, 466, 466, 466, 466 65ethread_SUITEtsd< >0.002sOk -66ethread_SUITEspinlock< >3.005sOk -67ethread_SUITErwspinlock< >3.005sOk +66ethread_SUITEspinlock< >3.006sOk +67ethread_SUITErwspinlock< >3.006sOk 68ethread_SUITErwmutex< >3.006sOk -69ethread_SUITEatomic< >0.035sOk -70ethread_SUITEdw_atomic_massage< >2.822sOk +69ethread_SUITEatomic< >0.032sOk +70ethread_SUITEdw_atomic_massage< >2.649sOk 71ethread_SUITEthread_name< >0.002sOk -common_testend_per_suite< >0.000sOk +common_testend_per_suite< >0.000sOk install_SUITEinit_per_suite< >0.000sOk -72install_SUITEbin_default< >0.271sOk -73install_SUITEbin_default_dirty< >0.322sOk -74install_SUITEbin_outside_eprfx< >0.273sOk -75install_SUITEbin_outside_eprfx_dirty< >0.282sOk -76install_SUITEbin_not_abs< >0.164sOk -77install_SUITEbin_unreasonable_path< >0.289sOk -78install_SUITE'bin white space'< >0.265sOk -79install_SUITEbin_no_srcfile< >0.219sOk -80install_SUITEbin_unreachable_absolute< >0.277sOk -81install_SUITEbin_unreachable_relative< >0.270sOk -82install_SUITEbin_same_dir< >0.207sOk +72install_SUITEbin_default< >0.273sOk +73install_SUITEbin_default_dirty< >0.318sOk +74install_SUITEbin_outside_eprfx< >0.272sOk +75install_SUITEbin_outside_eprfx_dirty< >0.283sOk +76install_SUITEbin_not_abs< >0.166sOk +77install_SUITEbin_unreasonable_path< >0.291sOk +78install_SUITE'bin white space'< >0.269sOk +79install_SUITEbin_no_srcfile< >0.224sOk +80install_SUITEbin_unreachable_absolute< >0.274sOk +81install_SUITEbin_unreachable_relative< >0.272sOk +82install_SUITEbin_same_dir< >0.206sOk 83install_SUITEbin_ok_symlink< >0.268sOk -84install_SUITEbin_dirname_fail< >0.274sOk -85install_SUITEbin_no_use_dirname_fail< >0.269sOk +84install_SUITEbin_dirname_fail< >0.279sOk +85install_SUITEbin_no_use_dirname_fail< >0.274sOk install_SUITEend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk +common_testinit_per_suite< >0.000sOk 86nt_SUITEnt< >0.000sSKIPPEDThis test case is intended for Win NT only. -common_testend_per_suite< >0.000sOk -otp_SUITEinit_per_suite< >2.775sOk -87otp_SUITEundefined_functions< >1.086sOk +common_testend_per_suite< >0.000sOk +otp_SUITEinit_per_suite< >2.913sOk +87otp_SUITEundefined_functions< >1.254sOk 88otp_SUITEdeprecated_not_in_obsolete< >0.000sOk -89otp_SUITEobsolete_but_not_deprecated< >0.006sOk -90otp_SUITEcall_to_deprecated< >0.382sOk47 calls to deprecated functions -91otp_SUITEcall_to_size_1< >0.305sOk -92otp_SUITEcall_to_now_0< >0.302sOk +89otp_SUITEobsolete_but_not_deprecated< >0.008sOk +90otp_SUITEcall_to_deprecated< >0.448sOk47 calls to deprecated functions +91otp_SUITEcall_to_size_1< >0.382sOk +92otp_SUITEcall_to_now_0< >0.371sOk 93otp_SUITEstrong_components< >0.001sOk -94otp_SUITEerl_file_encoding< >0.265sOk -95otp_SUITExml_file_encoding< >0.078sOk -96otp_SUITEruntime_dependencies_functions< >0.013sOkIgnored applications: [diameter] Ignored failures: [{missing_runtime_dependency, +94otp_SUITEerl_file_encoding< >0.261sOk +95otp_SUITExml_file_encoding< >0.043sOk +96otp_SUITEruntime_dependencies_functions< >0.011sOkIgnored applications: [diameter] Ignored failures: [{missing_runtime_dependency, [47,98,117,105,108,100, 114,111,111,116,47,111, 116,112,47,101,114,116, @@ -240,7 +240,7 @@

      Test started at 2024-09-11 12:06:30

      100,105,97,109,101,116, 101,114,46,97,112,112], runtime_tools}]
      -97otp_SUITEruntime_dependencies_modules< >0.439sOkIgnored applications: [diameter] Ignored failures: [{missing_runtime_dependency, +97otp_SUITEruntime_dependencies_modules< >0.463sOkIgnored applications: [diameter] Ignored failures: [{missing_runtime_dependency, [47,98,117,105,108,100, 114,111,111,116,47,111, 116,112,47,101,114,116, @@ -270,31 +270,31 @@

      Test started at 2024-09-11 12:06:30

      100,105,97,109,101,116, 101,114,46,97,112,112], runtime_tools}]
      -98otp_SUITEtest_runtime_dependencies_versions< >0.010sSKIPPEDThis test case is designed to run in the Erlang/OTP teams test system for dai... +98otp_SUITEtest_runtime_dependencies_versions< >0.011sSKIPPEDThis test case is designed to run in the Erlang/OTP teams test system for dai... otp_SUITEend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk -99parallel_messages_SUITEtest_throughput_benchmark< >20.410sOkResult visualization -100parallel_messages_SUITEtest_message_queue_data_switching< >2.654sOkResult visualization -common_testend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk -101run_erl_SUITEbasic< >0.187sOk -102run_erl_SUITEsleepy_child< >1.188sOk -103run_erl_SUITEheavy< >1.220sOk -104run_erl_SUITEheavier< >1.921sOk -105run_erl_SUITEdefunct< >10.008sOk -common_testend_per_suite< >0.000sOk +common_testinit_per_suite< >0.000sOk +99parallel_messages_SUITEtest_throughput_benchmark< >20.347sOkResult visualization +100parallel_messages_SUITEtest_message_queue_data_switching< >82.400sOkResult visualization +common_testend_per_suite< >0.000sOk +common_testinit_per_suite< >0.000sOk +101run_erl_SUITEbasic< >0.193sOk +102run_erl_SUITEsleepy_child< >1.182sOk +103run_erl_SUITEheavy< >1.218sOk +104run_erl_SUITEheavier< >1.952sOk +105run_erl_SUITEdefunct< >5.009sOk +common_testend_per_suite< >0.000sOk upgrade_SUITEinit_per_suite< >0.000sOk -106upgrade_SUITEminor< >17.972sOk -107upgrade_SUITEmajor< >41.412sOk -108upgrade_SUITEancient_major< >48.387sOk +106upgrade_SUITEminor< >17.861sOk +107upgrade_SUITEmajor< >41.527sOk +108upgrade_SUITEancient_major< >48.405sOk upgrade_SUITEend_per_suite< >0.000sOk -common_testinit_per_suite< >0.000sOk -109z_SUITEcore_files< >0.419sOk -common_testend_per_suite< >0.000sOk +common_testinit_per_suite< >0.000sOk +109z_SUITEcore_files< >0.621sOk +common_testend_per_suite< >0.000sOk -TOTAL473.113s
      Ok107 Ok, 0 Failed, 2 Skipped of 109
      Elapsed Time: 247.875s +TOTAL625.095s
      Ok107 Ok, 0 Failed, 2 Skipped of 109
      Elapsed Time: 323.920s @@ -305,7 +305,7 @@

      Test started at 2024-09-11 12:06:30

      | Latest test result

      diff --git a/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/suite.summary b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/suite.summary new file mode 100644 index 0000000000000..f09bcadeb825f --- /dev/null +++ b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/suite.summary @@ -0,0 +1 @@ +{summary,{107,0,2,0,323920054}}. diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/unexpected_io.log.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/unexpected_io.log.html similarity index 94% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/unexpected_io.log.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/unexpected_io.log.html index e2875256c5723..49180caefffdd 100644 --- a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run.2024-09-11_12.06.30/unexpected_io.log.html +++ b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/unexpected_io.log.html @@ -23,7 +23,7 @@

      Unexpected I/O

      | Latest test result

      diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_headers.19703330.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/upgrade_suite.ancient_major.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_headers.19703330.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/upgrade_suite.ancient_major.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_headers.19704290.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/upgrade_suite.end_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_headers.19704290.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/upgrade_suite.end_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_headers.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/upgrade_suite.init_per_suite.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip64_central_headers.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/upgrade_suite.init_per_suite.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip_api.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/upgrade_suite.major.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip_api.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/upgrade_suite.major.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip_options.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/upgrade_suite.minor.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip_options.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/upgrade_suite.minor.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip_to_binary.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/upgrade_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zip_suite.zip_to_binary.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/upgrade_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zzz_suite.lc_graph.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/z_suite.core_files.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zzz_suite.lc_graph.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/z_suite.core_files.html diff --git a/prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zzz_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/z_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@43e13ac1be0c.2024-09-11_11.10.18/make_test_dir.stdlib_test.logs/run.2024-09-11_11.10.55/zzz_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run.2024-09-12_11.29.21/z_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run_erl_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run_erl_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/run_erl_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/run_erl_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/upgrade_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/upgrade_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/upgrade_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/upgrade_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/z_suite.src.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/z_suite.src.html similarity index 100% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/make_test_dir.system_test.logs/z_suite.src.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/make_test_dir.system_test.logs/z_suite.src.html diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/misc_io.log.html b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/misc_io.log.html similarity index 94% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/misc_io.log.html rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/misc_io.log.html index b8d20a8334d72..1923fc14ed93d 100644 --- a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/misc_io.log.html +++ b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/misc_io.log.html @@ -30,7 +30,7 @@

      POST-TEST LOG

      | Latest test result

      diff --git a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/test.beam b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/test.beam similarity index 60% rename from prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/test.beam rename to prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/test.beam index 6518f5642d06e..84a380a455f0d 100644 Binary files a/prs/8803/ct_logs/ct_run.test_server@27af2e7fa355.2024-09-11_12.06.30/test.beam and b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/test.beam differ diff --git a/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/totals.info b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/totals.info new file mode 100644 index 0000000000000..2fd8ccaec368a Binary files /dev/null and b/prs/8803/ct_logs/ct_run.test_server@a4cca6e7dcb5.2024-09-12_11.29.20/totals.info differ diff --git a/prs/8803/ct_logs/index.html b/prs/8803/ct_logs/index.html index b46fd3d0ab8dc..895578a927908 100644 --- a/prs/8803/ct_logs/index.html +++ b/prs/8803/ct_logs/index.html @@ -107,27 +107,27 @@

      Test Results

      -make_test_dir.stdlib_test +make_test_dir.stdlib_test - -Wed Sep 11 2024 11:10:18 +Thu Sep 12 2024 10:32:23 2358 0 48 (48/0) 0 -test_server@43e13ac1be0c -CT Log +test_server@7a1fde2d1d55 +CT Log none -make_test_dir.system_test +make_test_dir.system_test - -Wed Sep 11 2024 12:06:30 +Thu Sep 12 2024 11:29:20 107 0 2 (2/0) 0 -test_server@27af2e7fa355 -CT Log +test_server@a4cca6e7dcb5 +CT Log none @@ -150,7 +150,7 @@

      Test Results



      diff --git a/prs/8803/ct_logs/suite.log.latest.html b/prs/8803/ct_logs/suite.log.latest.html index e351801b411c4..6781c4a4f5215 100644 --- a/prs/8803/ct_logs/suite.log.latest.html +++ b/prs/8803/ct_logs/suite.log.latest.html @@ -3,6 +3,6 @@ redirect - + diff --git a/prs/8803/ct_logs/variables-test_server@43e13ac1be0c b/prs/8803/ct_logs/variables-test_server@7a1fde2d1d55 similarity index 100% rename from prs/8803/ct_logs/variables-test_server@43e13ac1be0c rename to prs/8803/ct_logs/variables-test_server@7a1fde2d1d55 diff --git a/prs/8803/ct_logs/variables-test_server@27af2e7fa355 b/prs/8803/ct_logs/variables-test_server@a4cca6e7dcb5 similarity index 100% rename from prs/8803/ct_logs/variables-test_server@27af2e7fa355 rename to prs/8803/ct_logs/variables-test_server@a4cca6e7dcb5 diff --git a/prs/8803/doc/system/.build b/prs/8803/doc/system/.build index f62c5dd0e288a..bca9e4c90f345 100644 --- a/prs/8803/doc/system/.build +++ b/prs/8803/doc/system/.build @@ -41,7 +41,7 @@ dist/lato-latin-ext-300-normal-VPGGJKJL.woff2 dist/lato-latin-ext-400-normal-N27NCBWW.woff2 dist/lato-latin-ext-700-normal-Q2L5DVMW.woff2 dist/remixicon-NKANDIL5.woff2 -dist/search_data-9BDB5A32.js +dist/search_data-0DC1A4B6.js dist/sidebar_items-4A143270.js distributed.html distributed_applications.html diff --git a/prs/8803/doc/system/Erlang System Documentation.epub b/prs/8803/doc/system/Erlang System Documentation.epub index 533cf1d7321d0..b7e6b5259aa22 100644 Binary files a/prs/8803/doc/system/Erlang System Documentation.epub and b/prs/8803/doc/system/Erlang System Documentation.epub differ diff --git a/prs/8803/doc/system/applications.html b/prs/8803/doc/system/applications.html index 613922a65281a..67b0a9752876f 100644 --- a/prs/8803/doc/system/applications.html +++ b/prs/8803/doc/system/applications.html @@ -139,8 +139,8 @@

      Application Callback Module

      How to start and stop the code for the application, including its supervision -tree, is described by two callback functions:

      start(StartType, StartArgs) -> {ok, Pid} | {ok, Pid, State}
      -stop(State)
      • start/2 is called when starting the application and is to create the +tree, is described by two callback functions:

        start(StartType, StartArgs) -> {ok, Pid} | {ok, Pid, State}
        +stop(State)
        • start/2 is called when starting the application and is to create the supervision tree by starting the top supervisor. It is expected to return the pid of the top supervisor and an optional term, State, which defaults to []. This term is passed as is to stop/1.
        • StartType is usually the atom normal. It has other values only in the case @@ -150,15 +150,15 @@

          necessary cleaning up. The actual stopping of the application, that is, shutting down the supervision tree, is handled automatically as described in Starting and Stopping Applications.

        Example of an application callback module for packaging the supervision tree -from Supervisor Behaviour:

        -module(ch_app).
        --behaviour(application).
        +from Supervisor Behaviour:

        -module(ch_app).
        +-behaviour(application).
         
        --export([start/2, stop/1]).
        +-export([start/2, stop/1]).
         
        -start(_Type, _Args) ->
        -    ch_sup:start_link().
        +start(_Type, _Args) ->
        +    ch_sup:start_link().
         
        -stop(_State) ->
        +stop(_State) ->
             ok.

        A library application that cannot be started or stopped does not need any application callback module.

        @@ -177,14 +177,14 @@

        in this case ch_app and [], respectively. This means that the following is called when the application is to be started:

        ch_app:start(normal, [])

        The following is called when the application is stopped:

        ch_app:stop([])

        When using systools, the Erlang/OTP tools for packaging code (see Section Releases), the keys description, vsn, modules, -registered, and applications are also to be specified:

        {application, ch_app,
        - [{description, "Channel allocator"},
        -  {vsn, "1"},
        -  {modules, [ch_app, ch_sup, ch3]},
        -  {registered, [ch3]},
        -  {applications, [kernel, stdlib, sasl]},
        -  {mod, {ch_app,[]}}
        - ]}.
        • description - A short description, a string. Defaults to "".
        • vsn - Version number, a string. Defaults to "".
        • modules - All modules introduced by this application. systools uses +registered, and applications are also to be specified:

          {application, ch_app,
          + [{description, "Channel allocator"},
          +  {vsn, "1"},
          +  {modules, [ch_app, ch_sup, ch3]},
          +  {registered, [ch3]},
          +  {applications, [kernel, stdlib, sasl]},
          +  {mod, {ch_app,[]}}
          + ]}.
          • description - A short description, a string. Defaults to "".
          • vsn - Version number, a string. Defaults to "".
          • modules - All modules introduced by this application. systools uses this list when generating boot scripts and tar files. A module must only be included in one application. Defaults to [].
          • registered - All names of registered processes in the application. systools uses this list to detect name clashes between applications. @@ -304,30 +304,30 @@

            Loading and Unloading Applications

            Before an application can be started, it must be loaded. The application -controller reads and stores the information from the .app file:

            1> application:load(ch_app).
            +controller reads and stores the information from the .app file:

            1> application:load(ch_app).
             ok
            -2> application:loaded_applications().
            -[{kernel,"ERTS  CXC 138 10","2.8.1.3"},
            - {stdlib,"ERTS  CXC 138 10","1.11.4.3"},
            - {ch_app,"Channel allocator","1"}]

            An application that has been stopped, or has never been started, can be +2> application:loaded_applications(). +[{kernel,"ERTS CXC 138 10","2.8.1.3"}, + {stdlib,"ERTS CXC 138 10","1.11.4.3"}, + {ch_app,"Channel allocator","1"}]

            An application that has been stopped, or has never been started, can be unloaded. The information about the application is erased from the internal -database of the application controller.

            3> application:unload(ch_app).
            +database of the application controller.

            3> application:unload(ch_app).
             ok
            -4> application:loaded_applications().
            -[{kernel,"ERTS  CXC 138 10","2.8.1.3"},
            - {stdlib,"ERTS  CXC 138 10","1.11.4.3"}]

            Note

            Loading/unloading an application does not load/unload the code used by the +4> application:loaded_applications(). +[{kernel,"ERTS CXC 138 10","2.8.1.3"}, + {stdlib,"ERTS CXC 138 10","1.11.4.3"}]

            Note

            Loading/unloading an application does not load/unload the code used by the application. Code loading is handled in the usual way by the code server.

            Starting and Stopping Applications

            -

            An application is started by calling:

            5> application:start(ch_app).
            +

            An application is started by calling:

            5> application:start(ch_app).
             ok
            -6> application:which_applications().
            -[{kernel,"ERTS  CXC 138 10","2.8.1.3"},
            - {stdlib,"ERTS  CXC 138 10","1.11.4.3"},
            - {ch_app,"Channel allocator","1"}]

            If the application is not already loaded, the application controller first loads +6> application:which_applications(). +[{kernel,"ERTS CXC 138 10","2.8.1.3"}, + {stdlib,"ERTS CXC 138 10","1.11.4.3"}, + {ch_app,"Channel allocator","1"}]

            If the application is not already loaded, the application controller first loads it using application:load/1. It checks the value of the applications key to ensure that all applications that are to be started before this application are running.

            Following that, the application controller creates an application master for @@ -351,47 +351,47 @@

            Configuring an Application

            An application can be configured using configuration parameters. These are a -list of {Par,Val} tuples specified by a key env in the .app file:

            {application, ch_app,
            - [{description, "Channel allocator"},
            -  {vsn, "1"},
            -  {modules, [ch_app, ch_sup, ch3]},
            -  {registered, [ch3]},
            -  {applications, [kernel, stdlib, sasl]},
            -  {mod, {ch_app,[]}},
            -  {env, [{file, "/usr/local/log"}]}
            - ]}.

            Par is to be an atom. Val is any term. The application can retrieve the +list of {Par,Val} tuples specified by a key env in the .app file:

            {application, ch_app,
            + [{description, "Channel allocator"},
            +  {vsn, "1"},
            +  {modules, [ch_app, ch_sup, ch3]},
            +  {registered, [ch3]},
            +  {applications, [kernel, stdlib, sasl]},
            +  {mod, {ch_app,[]}},
            +  {env, [{file, "/usr/local/log"}]}
            + ]}.

            Par is to be an atom. Val is any term. The application can retrieve the value of a configuration parameter by calling application:get_env(App, Par) or a number of similar functions. For more information, see module application in Kernel.

            Example:

            % erl
            -Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
            +Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
             
            -Eshell V5.2.3.6  (abort with ^G)
            -1> application:start(ch_app).
            +Eshell V5.2.3.6  (abort with ^G)
            +1> application:start(ch_app).
             ok
            -2> application:get_env(ch_app, file).
            -{ok,"/usr/local/log"}

            The values in the .app file can be overridden by values in a system +2> application:get_env(ch_app, file). +{ok,"/usr/local/log"}

        The values in the .app file can be overridden by values in a system configuration file. This is a file that contains configuration parameters for -relevant applications:

        [{Application1, [{Par11,Val11},...]},
        +relevant applications:

        [{Application1, [{Par11,Val11},...]},
          ...,
        - {ApplicationN, [{ParN1,ValN1},...]}].

        The system configuration is to be called Name.config and Erlang is to be + {ApplicationN, [{ParN1,ValN1},...]}].

        The system configuration is to be called Name.config and Erlang is to be started with the command-line argument -config Name. For details, see config in Kernel.

        Example:

        A file test.config is created with the following contents:

        [{ch_app, [{file, "testlog"}]}].

        The value of file overrides the value of file as defined in the .app file:

        % erl -config test
        -Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
        +Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
         
        -Eshell V5.2.3.6  (abort with ^G)
        -1> application:start(ch_app).
        +Eshell V5.2.3.6  (abort with ^G)
        +1> application:start(ch_app).
         ok
        -2> application:get_env(ch_app, file).
        -{ok,"testlog"}

        If release handling is used, exactly one system +2> application:get_env(ch_app, file). +{ok,"testlog"}

    If release handling is used, exactly one system configuration file is to be used and that file is to be called sys.config.

    The values in the .app file and the values in a system configuration file can be overridden directly from the command line:

    % erl -ApplName Par1 Val1 ... ParN ValN

    Example:

    % erl -ch_app file '"testlog"'
    -Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
    +Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
     
    -Eshell V5.2.3.6  (abort with ^G)
    -1> application:start(ch_app).
    +Eshell V5.2.3.6  (abort with ^G)
    +1> application:start(ch_app).
     ok
    -2> application:get_env(ch_app, file).
    -{ok,"testlog"}

    +2> application:get_env(ch_app, file). +{ok,"testlog"}

    diff --git a/prs/8803/doc/system/appup_cookbook.html b/prs/8803/doc/system/appup_cookbook.html index f2d0ab7228a98..6d134a1d91e2f 100644 --- a/prs/8803/doc/system/appup_cookbook.html +++ b/prs/8803/doc/system/appup_cookbook.html @@ -124,10 +124,10 @@

    When a functional module has been changed, for example, if a new function has been added or a bug has been corrected, simple code replacement is sufficient, -for example:

    {"2",
    - [{"1", [{load_module, m}]}],
    - [{"1", [{load_module, m}]}]
    -}.

    +for example:

    {"2",
    + [{"1", [{load_module, m}]}],
    + [{"1", [{load_module, m}]}]
    +}.

    @@ -146,10 +146,10 @@

    A callback module is a functional module, and for code extensions simple code replacement is sufficient.

    Example

    When adding a function to ch3, as described in the example in -Release Handling, ch_app.appup looks as follows:

    {"2",
    - [{"1", [{load_module, ch3}]}],
    - [{"1", [{load_module, ch3}]}]
    -}.

    OTP also supports changing the internal state of behaviour processes; see +Release Handling, ch_app.appup looks as follows:

    {"2",
    + [{"1", [{load_module, ch3}]}],
    + [{"1", [{load_module, ch3}]}]
    +}.

    OTP also supports changing the internal state of behaviour processes; see Changing Internal State.

    @@ -163,21 +163,21 @@

    gen_server Behaviour. The internal state is a term Chs representing the available channels. Assume you want to add a counter N, which keeps track of the number of alloc requests so far. This means that the -format must be changed to {Chs,N}.

    The .appup file can look as follows:

    {"2",
    - [{"1", [{update, ch3, {advanced, []}}]}],
    - [{"1", [{update, ch3, {advanced, []}}]}]
    -}.

    The third element of the update instruction is a tuple {advanced,Extra}, +format must be changed to {Chs,N}.

    The .appup file can look as follows:

    {"2",
    + [{"1", [{update, ch3, {advanced, []}}]}],
    + [{"1", [{update, ch3, {advanced, []}}]}]
    +}.

    The third element of the update instruction is a tuple {advanced,Extra}, which says that the affected processes are to do a state transformation before loading the new version of the module. This is done by the processes calling the callback function code_change/3 (see gen_server in STDLIB). -The term Extra, in this case [], is passed as is to the function:

    -module(ch3).
    +The term Extra, in this case [], is passed as is to the function:

    -module(ch3).
     ...
    --export([code_change/3]).
    +-export([code_change/3]).
     ...
    -code_change({down, _Vsn}, {Chs, N}, _Extra) ->
    -    {ok, Chs};
    -code_change(_Vsn, Chs, _Extra) ->
    -    {ok, {Chs, 0}}.

    The first argument is {down,Vsn} if there is a downgrade, or Vsn if there is +code_change({down, _Vsn}, {Chs, N}, _Extra) -> + {ok, Chs}; +code_change(_Vsn, Chs, _Extra) -> + {ok, {Chs, 0}}.

    The first argument is {down,Vsn} if there is a downgrade, or Vsn if there is a upgrade. The term Vsn is fetched from the 'original' version of the module, that is, the version you are upgrading from, or downgrading to.

    The version is defined by the module attribute vsn, if any. There is no such attribute in ch3, so in this case the version is the checksum (a huge integer) @@ -194,29 +194,29 @@

    can occur during release upgrade if the new version of m1 is loaded first and calls ch3:available/0 before the new version of ch3 is loaded.

    Thus, ch3 must be loaded before m1, in the upgrade case, and conversely in the downgrade case. m1 is said to be dependent on ch3. In a release -handling instruction, this is expressed by the DepMods element:

    {load_module, Module, DepMods}
    -{update, Module, {advanced, Extra}, DepMods}

    DepMods is a list of modules, on which Module is dependent.

    Example

    The module m1 in application myapp is dependent on ch3 when +handling instruction, this is expressed by the DepMods element:

    {load_module, Module, DepMods}
    +{update, Module, {advanced, Extra}, DepMods}

    DepMods is a list of modules, on which Module is dependent.

    Example

    The module m1 in application myapp is dependent on ch3 when upgrading from "1" to "2", or downgrading from "2" to "1":

    myapp.appup:
     
    -{"2",
    - [{"1", [{load_module, m1, [ch3]}]}],
    - [{"1", [{load_module, m1, [ch3]}]}]
    -}.
    +{"2",
    + [{"1", [{load_module, m1, [ch3]}]}],
    + [{"1", [{load_module, m1, [ch3]}]}]
    +}.
     
     ch_app.appup:
     
    -{"2",
    - [{"1", [{load_module, ch3}]}],
    - [{"1", [{load_module, ch3}]}]
    -}.

    If instead m1 and ch3 belong to the same application, the .appup file can -look as follows:

    {"2",
    - [{"1",
    -   [{load_module, ch3},
    -    {load_module, m1, [ch3]}]}],
    - [{"1",
    -   [{load_module, ch3},
    -    {load_module, m1, [ch3]}]}]
    -}.

    m1 is dependent on ch3 also when downgrading. systools knows the +{"2", + [{"1", [{load_module, ch3}]}], + [{"1", [{load_module, ch3}]}] +}.

    If instead m1 and ch3 belong to the same application, the .appup file can +look as follows:

    {"2",
    + [{"1",
    +   [{load_module, ch3},
    +    {load_module, m1, [ch3]}]}],
    + [{"1",
    +   [{load_module, ch3},
    +    {load_module, m1, [ch3]}]}]
    +}.

    m1 is dependent on ch3 also when downgrading. systools knows the difference between up- and downgrading and generates a correct relup, where ch3 is loaded before m1 when upgrading, but m1 is loaded before ch3 when downgrading.

    @@ -231,22 +231,22 @@

    synchronized code replacement must be used.

    Note

    The name(s) of the user-defined residence module(s) must be listed in the Modules part of the child specification for the special process. Otherwise the release handler cannot find the process.

    Example

    Consider the example ch4 in sys and proc_lib. -When started by a supervisor, the child specification can look as follows:

    {ch4, {ch4, start_link, []},
    - permanent, brutal_kill, worker, [ch4]}

    If ch4 is part of the application sp_app and a new version of the module is +When started by a supervisor, the child specification can look as follows:

    {ch4, {ch4, start_link, []},
    + permanent, brutal_kill, worker, [ch4]}

    If ch4 is part of the application sp_app and a new version of the module is to be loaded when upgrading from version "1" to "2" of this application, -sp_app.appup can look as follows:

    {"2",
    - [{"1", [{update, ch4, {advanced, []}}]}],
    - [{"1", [{update, ch4, {advanced, []}}]}]
    -}.

    The update instruction must contain the tuple {advanced,Extra}. The +sp_app.appup can look as follows:

    {"2",
    + [{"1", [{update, ch4, {advanced, []}}]}],
    + [{"1", [{update, ch4, {advanced, []}}]}]
    +}.

    The update instruction must contain the tuple {advanced,Extra}. The instruction makes the special process call the callback function system_code_change/4, a function the user must implement. The term Extra, in -this case [], is passed as is to system_code_change/4:

    -module(ch4).
    +this case [], is passed as is to system_code_change/4:

    -module(ch4).
     ...
    --export([system_code_change/4]).
    +-export([system_code_change/4]).
     ...
     
    -system_code_change(Chs, _Module, _OldVsn, _Extra) ->
    -    {ok, Chs}.
    • The first argument is the internal state State, passed from +system_code_change(Chs, _Module, _OldVsn, _Extra) -> + {ok, Chs}.
    • The first argument is the internal state State, passed from function sys:handle_system_msg(Request, From, Parent, Module, Deb, State), and called by the special process when a system message is received. In ch4, the internal state is the set of available channels Chs.
    • The second argument is the name of the module (ch4).
    • The third argument is Vsn or {down,Vsn}, as described for @@ -275,24 +275,24 @@

      of upgrade and downgrade. Then the new return value of init/1 can be checked and the internal state be changed accordingly.

      The following upgrade instruction is used for supervisors:

      {update, Module, supervisor}

      Example

      To change the restart strategy of ch_sup (from Supervisor Behaviour) from one_for_one to one_for_all, -change the callback function init/1 in ch_sup.erl:

      -module(ch_sup).
      +change the callback function init/1 in ch_sup.erl:

      -module(ch_sup).
       ...
       
      -init(_Args) ->
      -    {ok, {#{strategy => one_for_all, ...}, ...}}.

      The file ch_app.appup:

      {"2",
      - [{"1", [{update, ch_sup, supervisor}]}],
      - [{"1", [{update, ch_sup, supervisor}]}]
      -}.

      +init(_Args) -> + {ok, {#{strategy => one_for_all, ...}, ...}}.

      The file ch_app.appup:

      {"2",
      + [{"1", [{update, ch_sup, supervisor}]}],
      + [{"1", [{update, ch_sup, supervisor}]}]
      +}.

      Changing Child Specifications

      The instruction, and thus the .appup file, when changing an existing child -specification, is the same as when changing properties as described earlier:

      {"2",
      - [{"1", [{update, ch_sup, supervisor}]}],
      - [{"1", [{update, ch_sup, supervisor}]}]
      -}.

      The changes do not affect existing child processes. For example, changing the +specification, is the same as when changing properties as described earlier:

      {"2",
      + [{"1", [{update, ch_sup, supervisor}]}],
      + [{"1", [{update, ch_sup, supervisor}]}]
      +}.

      The changes do not affect existing child processes. For example, changing the start function only specifies how the child process is to be restarted, if needed later on.

      The id of the child specification cannot be changed.

      Changing the Modules field of the child specification can affect the release handling process itself, as this field is used to identify which processes are @@ -307,34 +307,34 @@

      Child processes are not automatically started or terminated, this must be done using apply instructions.

      Example

      Assume a new child process m1 is to be added to ch_sup when upgrading ch_app from "1" to "2". This means m1 is to be deleted when -downgrading from "2" to "1":

      {"2",
      - [{"1",
      -   [{update, ch_sup, supervisor},
      -    {apply, {supervisor, restart_child, [ch_sup, m1]}}
      -   ]}],
      - [{"1",
      -   [{apply, {supervisor, terminate_child, [ch_sup, m1]}},
      -    {apply, {supervisor, delete_child, [ch_sup, m1]}},
      -    {update, ch_sup, supervisor}
      -   ]}]
      -}.

      The order of the instructions is important.

      The supervisor must be registered as ch_sup for the script to work. If the +downgrading from "2" to "1":

      {"2",
      + [{"1",
      +   [{update, ch_sup, supervisor},
      +    {apply, {supervisor, restart_child, [ch_sup, m1]}}
      +   ]}],
      + [{"1",
      +   [{apply, {supervisor, terminate_child, [ch_sup, m1]}},
      +    {apply, {supervisor, delete_child, [ch_sup, m1]}},
      +    {update, ch_sup, supervisor}
      +   ]}]
      +}.

      The order of the instructions is important.

      The supervisor must be registered as ch_sup for the script to work. If the supervisor is not registered, it cannot be accessed directly from the script. Instead a help function that finds the pid of the supervisor and calls supervisor:restart_child, and so on, must be written. This function is then to be called from the script using the apply instruction.

      If the module m1 is introduced in version "2" of ch_app, it must also be -loaded when upgrading and deleted when downgrading:

      {"2",
      - [{"1",
      -   [{add_module, m1},
      -    {update, ch_sup, supervisor},
      -    {apply, {supervisor, restart_child, [ch_sup, m1]}}
      -   ]}],
      - [{"1",
      -   [{apply, {supervisor, terminate_child, [ch_sup, m1]}},
      -    {apply, {supervisor, delete_child, [ch_sup, m1]}},
      -    {update, ch_sup, supervisor},
      -    {delete_module, m1}
      -   ]}]
      -}.

      As stated earlier, the order of the instructions is important. When upgrading, +loaded when upgrading and deleted when downgrading:

      {"2",
      + [{"1",
      +   [{add_module, m1},
      +    {update, ch_sup, supervisor},
      +    {apply, {supervisor, restart_child, [ch_sup, m1]}}
      +   ]}],
      + [{"1",
      +   [{apply, {supervisor, terminate_child, [ch_sup, m1]}},
      +    {apply, {supervisor, delete_child, [ch_sup, m1]}},
      +    {update, ch_sup, supervisor},
      +    {delete_module, m1}
      +   ]}]
      +}.

      As stated earlier, the order of the instructions is important. When upgrading, m1 must be loaded, and the supervisor child specification changed, before the new child process can be started. When downgrading, the child process must be terminated before the child specification is changed and the module is deleted.

      @@ -343,9 +343,9 @@

      Adding or Deleting a Module

      -

      _Example

      _ A new functional module m is added to ch_app:

      {"2",
      - [{"1", [{add_module, m}]}],
      - [{"1", [{delete_module, m}]}]

      +

      _Example

      _ A new functional module m is added to ch_app:

      {"2",
      + [{"1", [{add_module, m}]}],
      + [{"1", [{delete_module, m}]}]

      @@ -373,10 +373,10 @@

      been restructured.

      Example

      When adding a child m1 to ch_sup, as in Adding and Deleting Child Processes in Changing a Supervisor, an alternative to updating the supervisor is to restart the entire -application:

      {"2",
      - [{"1", [{restart_application, ch_app}]}],
      - [{"1", [{restart_application, ch_app}]}]
      -}.

      +application:

      {"2",
      + [{"1", [{restart_application, ch_app}]}],
      + [{"1", [{restart_application, ch_app}]}]
      +}.

      @@ -384,10 +384,10 @@

      When installing a release, the application specifications are automatically updated before evaluating the relup script. Thus, no instructions are needed -in the .appup file:

      {"2",
      - [{"1", []}],
      - [{"1", []}]
      -}.

      +in the .appup file:

      {"2",
      + [{"1", []}],
      + [{"1", []}]
      +}.

      @@ -410,18 +410,18 @@

      manually created.

      Example

      Assume there is a release containing an application prim_app, which have a supervisor prim_sup in its supervision tree.

      In a new version of the release, the application ch_app is to be included in prim_app. That is, its topmost supervisor ch_sup is to be started as a child -process to prim_sup.

      The workflow is as follows:

      Step 1) Edit the code for prim_sup:

      init(...) ->
      -    {ok, {...supervisor flags...,
      -          [...,
      -           {ch_sup, {ch_sup,start_link,[]},
      -            permanent,infinity,supervisor,[ch_sup]},
      -           ...]}}.

      Step 2) Edit the .app file for prim_app:

      {application, prim_app,
      - [...,
      -  {vsn, "2"},
      +process to prim_sup.

      The workflow is as follows:

      Step 1) Edit the code for prim_sup:

      init(...) ->
      +    {ok, {...supervisor flags...,
      +          [...,
      +           {ch_sup, {ch_sup,start_link,[]},
      +            permanent,infinity,supervisor,[ch_sup]},
      +           ...]}}.

      Step 2) Edit the .app file for prim_app:

      {application, prim_app,
      + [...,
      +  {vsn, "2"},
         ...,
      -  {included_applications, [ch_app]},
      +  {included_applications, [ch_app]},
         ...
      - ]}.

      Step 3) Create a new .rel file, including ch_app:

      {release,
      + ]}.

      Step 3) Create a new .rel file, including ch_app:

      {release,
        ...,
        [...,
         {prim_app, "2"},
      @@ -440,38 +440,38 @@ 

      the case of downgrade). This is because ch_app is included in the new .rel file, but not in the old one.

      Instead, a correct relup file can be created manually, either from scratch or by editing the generated version. The instructions for starting/stopping -ch_app are replaced by instructions for loading/unloading the application:

      {"B",
      - [{"A",
      -   [],
      -   [{load_object_code,{ch_app,"1",[ch_sup,ch3]}},
      -    {load_object_code,{prim_app,"2",[prim_app,prim_sup]}},
      +ch_app are replaced by instructions for loading/unloading the application:

      {"B",
      + [{"A",
      +   [],
      +   [{load_object_code,{ch_app,"1",[ch_sup,ch3]}},
      +    {load_object_code,{prim_app,"2",[prim_app,prim_sup]}},
           point_of_no_return,
      -    {apply,{application,stop,[prim_app]}},
      -    {remove,{prim_app,brutal_purge,brutal_purge}},
      -    {remove,{prim_sup,brutal_purge,brutal_purge}},
      -    {purge,[prim_app,prim_sup]},
      -    {load,{prim_app,brutal_purge,brutal_purge}},
      -    {load,{prim_sup,brutal_purge,brutal_purge}},
      -    {load,{ch_sup,brutal_purge,brutal_purge}},
      -    {load,{ch3,brutal_purge,brutal_purge}},
      -    {apply,{application,load,[ch_app]}},
      -    {apply,{application,start,[prim_app,permanent]}}]}],
      - [{"A",
      -   [],
      -   [{load_object_code,{prim_app,"1",[prim_app,prim_sup]}},
      +    {apply,{application,stop,[prim_app]}},
      +    {remove,{prim_app,brutal_purge,brutal_purge}},
      +    {remove,{prim_sup,brutal_purge,brutal_purge}},
      +    {purge,[prim_app,prim_sup]},
      +    {load,{prim_app,brutal_purge,brutal_purge}},
      +    {load,{prim_sup,brutal_purge,brutal_purge}},
      +    {load,{ch_sup,brutal_purge,brutal_purge}},
      +    {load,{ch3,brutal_purge,brutal_purge}},
      +    {apply,{application,load,[ch_app]}},
      +    {apply,{application,start,[prim_app,permanent]}}]}],
      + [{"A",
      +   [],
      +   [{load_object_code,{prim_app,"1",[prim_app,prim_sup]}},
           point_of_no_return,
      -    {apply,{application,stop,[prim_app]}},
      -    {apply,{application,unload,[ch_app]}},
      -    {remove,{ch_sup,brutal_purge,brutal_purge}},
      -    {remove,{ch3,brutal_purge,brutal_purge}},
      -    {purge,[ch_sup,ch3]},
      -    {remove,{prim_app,brutal_purge,brutal_purge}},
      -    {remove,{prim_sup,brutal_purge,brutal_purge}},
      -    {purge,[prim_app,prim_sup]},
      -    {load,{prim_app,brutal_purge,brutal_purge}},
      -    {load,{prim_sup,brutal_purge,brutal_purge}},
      -    {apply,{application,start,[prim_app,permanent]}}]}]
      -}.

      + {apply,{application,stop,[prim_app]}}, + {apply,{application,unload,[ch_app]}}, + {remove,{ch_sup,brutal_purge,brutal_purge}}, + {remove,{ch3,brutal_purge,brutal_purge}}, + {purge,[ch_sup,ch3]}, + {remove,{prim_app,brutal_purge,brutal_purge}}, + {remove,{prim_sup,brutal_purge,brutal_purge}}, + {purge,[prim_app,prim_sup]}, + {load,{prim_app,brutal_purge,brutal_purge}}, + {load,{prim_sup,brutal_purge,brutal_purge}}, + {apply,{application,start,[prim_app,permanent]}}]}] +}.

      @@ -484,35 +484,35 @@

      generated version. Load all code for ch_app first, and also load the application specification, before prim_sup is updated. When downgrading, prim_sup is to updated first, before the code for ch_app and its application -specification are unloaded.

      {"B",
      - [{"A",
      -   [],
      -   [{load_object_code,{ch_app,"1",[ch_sup,ch3]}},
      -    {load_object_code,{prim_app,"2",[prim_sup]}},
      +specification are unloaded.

      {"B",
      + [{"A",
      +   [],
      +   [{load_object_code,{ch_app,"1",[ch_sup,ch3]}},
      +    {load_object_code,{prim_app,"2",[prim_sup]}},
           point_of_no_return,
      -    {load,{ch_sup,brutal_purge,brutal_purge}},
      -    {load,{ch3,brutal_purge,brutal_purge}},
      -    {apply,{application,load,[ch_app]}},
      -    {suspend,[prim_sup]},
      -    {load,{prim_sup,brutal_purge,brutal_purge}},
      -    {code_change,up,[{prim_sup,[]}]},
      -    {resume,[prim_sup]},
      -    {apply,{supervisor,restart_child,[prim_sup,ch_sup]}}]}],
      - [{"A",
      -   [],
      -   [{load_object_code,{prim_app,"1",[prim_sup]}},
      +    {load,{ch_sup,brutal_purge,brutal_purge}},
      +    {load,{ch3,brutal_purge,brutal_purge}},
      +    {apply,{application,load,[ch_app]}},
      +    {suspend,[prim_sup]},
      +    {load,{prim_sup,brutal_purge,brutal_purge}},
      +    {code_change,up,[{prim_sup,[]}]},
      +    {resume,[prim_sup]},
      +    {apply,{supervisor,restart_child,[prim_sup,ch_sup]}}]}],
      + [{"A",
      +   [],
      +   [{load_object_code,{prim_app,"1",[prim_sup]}},
           point_of_no_return,
      -    {apply,{supervisor,terminate_child,[prim_sup,ch_sup]}},
      -    {apply,{supervisor,delete_child,[prim_sup,ch_sup]}},
      -    {suspend,[prim_sup]},
      -    {load,{prim_sup,brutal_purge,brutal_purge}},
      -    {code_change,down,[{prim_sup,[]}]},
      -    {resume,[prim_sup]},
      -    {remove,{ch_sup,brutal_purge,brutal_purge}},
      -    {remove,{ch3,brutal_purge,brutal_purge}},
      -    {purge,[ch_sup,ch3]},
      -    {apply,{application,unload,[ch_app]}}]}]
      -}.

      + {apply,{supervisor,terminate_child,[prim_sup,ch_sup]}}, + {apply,{supervisor,delete_child,[prim_sup,ch_sup]}}, + {suspend,[prim_sup]}, + {load,{prim_sup,brutal_purge,brutal_purge}}, + {code_change,down,[{prim_sup,[]}]}, + {resume,[prim_sup]}, + {remove,{ch_sup,brutal_purge,brutal_purge}}, + {remove,{ch3,brutal_purge,brutal_purge}}, + {purge,[ch_sup,ch3]}, + {apply,{application,unload,[ch_app]}}]}] +}.

      @@ -522,28 +522,28 @@

      for example, a port program, is application-dependent and OTP provides no special support.

      Example

      When changing code for a port program, assume that the Erlang process controlling the port is a gen_server portc and that the port is opened in -the callback function init/1:

      init(...) ->
      +the callback function init/1:

      init(...) ->
           ...,
      -    PortPrg = filename:join(code:priv_dir(App), "portc"),
      -    Port = open_port({spawn,PortPrg}, [...]),
      +    PortPrg = filename:join(code:priv_dir(App), "portc"),
      +    Port = open_port({spawn,PortPrg}, [...]),
           ...,
      -    {ok, #state{port=Port, ...}}.

      If the port program is to be updated, the code for the gen_server can be + {ok, #state{port=Port, ...}}.

      If the port program is to be updated, the code for the gen_server can be extended with a code_change/3 function, which closes the old port and opens a new port. (If necessary, the gen_server can first request data that must be -saved from the port program and pass this data to the new port):

      code_change(_OldVsn, State, port) ->
      +saved from the port program and pass this data to the new port):

      code_change(_OldVsn, State, port) ->
           State#state.port ! close,
           receive
      -        {Port,close} ->
      +        {Port,close} ->
                   true
           end,
      -    PortPrg = filename:join(code:priv_dir(App), "portc"),
      -    Port = open_port({spawn,PortPrg}, [...]),
      -    {ok, #state{port=Port, ...}}.

      Update the application version number in the .app file and write an .appup -file:

      ["2",
      - [{"1", [{update, portc, {advanced,port}}]}],
      - [{"1", [{update, portc, {advanced,port}}]}]
      -].

      Ensure that the priv directory, where the C program is located, is included in -the new release package:

      1> systools:make_tar("my_release", [{dirs,[priv]}]).
      +    PortPrg = filename:join(code:priv_dir(App), "portc"),
      +    Port = open_port({spawn,PortPrg}, [...]),
      +    {ok, #state{port=Port, ...}}.

      Update the application version number in the .app file and write an .appup +file:

      ["2",
      + [{"1", [{update, portc, {advanced,port}}]}],
      + [{"1", [{update, portc, {advanced,port}}]}]
      +].

      Ensure that the priv directory, where the C program is located, is included in +the new release package:

      1> systools:make_tar("my_release", [{dirs,[priv]}]).
       ...

      @@ -559,14 +559,14 @@

      restart_emulator (Low-Level) in Release Handling Instructions.

    If a runtime system restart is necessary and no upgrade instructions are needed, that is, if the restart itself is enough for the upgraded applications to start -running the new versions, a simple .relup file can be created manually:

    {"B",
    - [{"A",
    -   [],
    -   [restart_emulator]}],
    - [{"A",
    -   [],
    -   [restart_emulator]}]
    -}.

    In this case, the release handler framework with automatic packing and unpacking +running the new versions, a simple .relup file can be created manually:

    {"B",
    + [{"A",
    +   [],
    +   [restart_emulator]}],
    + [{"A",
    +   [],
    +   [restart_emulator]}]
    +}.

    In this case, the release handler framework with automatic packing and unpacking of release packages, automatic path updates, and so on, can be used without having to specify .appup files.

    diff --git a/prs/8803/doc/system/benchmarking.html b/prs/8803/doc/system/benchmarking.html index 522502d672893..426d72d544ac5 100644 --- a/prs/8803/doc/system/benchmarking.html +++ b/prs/8803/doc/system/benchmarking.html @@ -148,8 +148,8 @@

    crypto:strong_rand_bytes(100). 1 1915 Ki 522 ns 90%

    rand:bytes/1 is still faster when we generate 100 bytes at the time, but the relative difference is smaller.

    % erlperf 'rand:bytes(1000).' 'crypto:strong_rand_bytes(1000).'
     Code                                    ||        QPS       Time   Rel
    -crypto:strong_rand_bytes(1000).          1    1518 Ki     658 ns  100%
    -rand:bytes(1000).                        1     284 Ki    3521 ns   19%

    When we generate 1000 bytes at the time, crypto:strong_rand_bytes/1 is +crypto:strong_rand_bytes(1000). 1 1518 Ki 658 ns 100% +rand:bytes(1000). 1 284 Ki 3521 ns 19%

    When we generate 1000 bytes at the time, crypto:strong_rand_bytes/1 is now the fastest.

    diff --git a/prs/8803/doc/system/binaryhandling.html b/prs/8803/doc/system/binaryhandling.html index 7fb8d88564ca3..6853c1a4c4cf4 100644 --- a/prs/8803/doc/system/binaryhandling.html +++ b/prs/8803/doc/system/binaryhandling.html @@ -118,35 +118,35 @@

    This section gives a few examples on how to handle binaries in an efficient way. The sections that follow take an in-depth look at how binaries are implemented and how to best take advantages of the optimizations done by the compiler and -runtime system.

    Binaries can be efficiently built in the following way:

    DO

    my_list_to_binary(List) ->
    -    my_list_to_binary(List, <<>>).
    +runtime system.

    Binaries can be efficiently built in the following way:

    DO

    my_list_to_binary(List) ->
    +    my_list_to_binary(List, <<>>).
     
    -my_list_to_binary([H|T], Acc) ->
    -    my_list_to_binary(T, <<Acc/binary,H>>);
    -my_list_to_binary([], Acc) ->
    +my_list_to_binary([H|T], Acc) ->
    +    my_list_to_binary(T, <<Acc/binary,H>>);
    +my_list_to_binary([], Acc) ->
         Acc.

    Appending data to a binary as in the example is efficient because it is specially optimized by the runtime system to avoid copying the Acc binary -every time.

    Prepending data to a binary in a loop is not efficient:

    DO NOT

    rev_list_to_binary(List) ->
    -    rev_list_to_binary(List, <<>>).
    +every time.

    Prepending data to a binary in a loop is not efficient:

    DO NOT

    rev_list_to_binary(List) ->
    +    rev_list_to_binary(List, <<>>).
     
    -rev_list_to_binary([H|T], Acc) ->
    -    rev_list_to_binary(T, <<H,Acc/binary>>);
    -rev_list_to_binary([], Acc) ->
    +rev_list_to_binary([H|T], Acc) ->
    +    rev_list_to_binary(T, <<H,Acc/binary>>);
    +rev_list_to_binary([], Acc) ->
         Acc.

    This is not efficient for long lists because the Acc binary is copied every -time. One way to make the function more efficient is like this:

    DO NOT

    rev_list_to_binary(List) ->
    -    rev_list_to_binary(lists:reverse(List), <<>>).
    -
    -rev_list_to_binary([H|T], Acc) ->
    -    rev_list_to_binary(T, <<Acc/binary,H>>);
    -rev_list_to_binary([], Acc) ->
    -    Acc.

    Another way to avoid copying the binary each time is like this:

    DO

    rev_list_to_binary([H|T]) ->
    -    RevTail = rev_list_to_binary(T),
    +time. One way to make the function more efficient is like this:

    DO NOT

    rev_list_to_binary(List) ->
    +    rev_list_to_binary(lists:reverse(List), <<>>).
    +
    +rev_list_to_binary([H|T], Acc) ->
    +    rev_list_to_binary(T, <<Acc/binary,H>>);
    +rev_list_to_binary([], Acc) ->
    +    Acc.

    Another way to avoid copying the binary each time is like this:

    DO

    rev_list_to_binary([H|T]) ->
    +    RevTail = rev_list_to_binary(T),
         <<RevTail/binary,H>>;
    -rev_list_to_binary([]) ->
    +rev_list_to_binary([]) ->
         <<>>.

    Note that in each of the DO examples, the binary to be appended to is always -given as the first segment.

    Binaries can be efficiently matched in the following way:

    DO

    my_binary_to_list(<<H,T/binary>>) ->
    -    [H|my_binary_to_list(T)];
    -my_binary_to_list(<<>>) -> [].

    +given as the first segment.

    Binaries can be efficiently matched in the following way:

    DO

    my_binary_to_list(<<H,T/binary>>) ->
    +    [H|my_binary_to_list(T)];
    +my_binary_to_list(<<>>) -> [].

    @@ -223,7 +223,7 @@

    Bin2 = <<Bin1/binary,4,5,6>>, %% 3 Bin3 = <<Bin2/binary,7,8,9>>, %% 4 Bin4 = <<Bin1/binary,17>>, %% 5 !!! -{Bin4,Bin3} %% 6

    • Line 1 (marked with the %% 1 comment), assigns a +{Bin4,Bin3} %% 6

    • Line 1 (marked with the %% 1 comment), assigns a heap binary to the Bin0 variable.

    • Line 2 is an append operation. As Bin0 has not been involved in an append operation, a new refc binary is created and the contents of Bin0 is copied into it. The ProcBin part of the refc @@ -257,15 +257,15 @@

      for every append operation, the runtime system must create a sub binary.

      When the compiler can determine that none of those situations need to be handled and that the append operation cannot possibly fail, the compiler generates code that causes the runtime system to apply a more efficient variant of the -optimization.

      Example:

      -module(repack).
      --export([repack/1]).
      +optimization.

      Example:

      -module(repack).
      +-export([repack/1]).
       
      -repack(Bin) when is_binary(Bin) ->
      -    repack(Bin, <<>>).
      +repack(Bin) when is_binary(Bin) ->
      +    repack(Bin, <<>>).
       
      -repack(<<C:8,T/binary>>, Result) ->
      -    repack(T, <<Result/binary,C:16>>);
      -repack(<<>>, Result) ->
      +repack(<<C:8,T/binary>>, Result) ->
      +    repack(T, <<Result/binary,C:16>>);
      +repack(<<>>, Result) ->
           Result.

      The repack/2 function only keeps a single version of the binary, so there is never any need to copy the binary. The compiler rewrites the creation of the empty binary in repack/1 to instead create a refc binary with 256 bytes @@ -308,9 +308,9 @@

      Matching Binaries

      -

      Let us revisit the example in the beginning of the previous section:

      DO

      my_binary_to_list(<<H,T/binary>>) ->
      -    [H|my_binary_to_list(T)];
      -my_binary_to_list(<<>>) -> [].

      The first time my_binary_to_list/1 is called, a +

      Let us revisit the example in the beginning of the previous section:

      DO

      my_binary_to_list(<<H,T/binary>>) ->
      +    [H|my_binary_to_list(T)];
      +my_binary_to_list(<<>>) -> [].

      The first time my_binary_to_list/1 is called, a match context is created. The match context points to the first byte of the binary. 1 byte is matched out and the match context is updated to point to the second byte in the binary.

      At this point it would make sense to create a @@ -325,24 +325,24 @@

      there is no longer any reference to it).

      To summarize, my_binary_to_list/1 only needs to create one match context and no sub binaries.

      Notice that the match context in my_binary_to_list/1 was discarded when the entire binary had been traversed. What happens if the iteration stops before it -has reached the end of the binary? Will the optimization still work?

      after_zero(<<0,T/binary>>) ->
      +has reached the end of the binary? Will the optimization still work?

      after_zero(<<0,T/binary>>) ->
           T;
      -after_zero(<<_,T/binary>>) ->
      -    after_zero(T);
      -after_zero(<<>>) ->
      +after_zero(<<_,T/binary>>) ->
      +    after_zero(T);
      +after_zero(<<>>) ->
           <<>>.

      Yes, it will. The compiler will remove the building of the sub binary in the second clause:

      ...
      -after_zero(<<_,T/binary>>) ->
      -    after_zero(T);
      -...

      But it will generate code that builds a sub binary in the first clause:

      after_zero(<<0,T/binary>>) ->
      +after_zero(<<_,T/binary>>) ->
      +    after_zero(T);
      +...

      But it will generate code that builds a sub binary in the first clause:

      after_zero(<<0,T/binary>>) ->
           T;
       ...

      Therefore, after_zero/1 builds one match context and one sub binary (assuming -it is passed a binary that contains a zero byte).

      Code like the following will also be optimized:

      all_but_zeroes_to_list(Buffer, Acc, 0) ->
      -    {lists:reverse(Acc),Buffer};
      -all_but_zeroes_to_list(<<0,T/binary>>, Acc, Remaining) ->
      -    all_but_zeroes_to_list(T, Acc, Remaining-1);
      -all_but_zeroes_to_list(<<Byte,T/binary>>, Acc, Remaining) ->
      -    all_but_zeroes_to_list(T, [Byte|Acc], Remaining-1).

      The compiler removes building of sub binaries in the second and third clauses, +it is passed a binary that contains a zero byte).

      Code like the following will also be optimized:

      all_but_zeroes_to_list(Buffer, Acc, 0) ->
      +    {lists:reverse(Acc),Buffer};
      +all_but_zeroes_to_list(<<0,T/binary>>, Acc, Remaining) ->
      +    all_but_zeroes_to_list(T, Acc, Remaining-1);
      +all_but_zeroes_to_list(<<Byte,T/binary>>, Acc, Remaining) ->
      +    all_but_zeroes_to_list(T, [Byte|Acc], Remaining-1).

      The compiler removes building of sub binaries in the second and third clauses, and it adds an instruction to the first clause that converts Buffer from a match context to a sub binary (or do nothing if Buffer is a binary already).

      But in more complicated code, how can one know whether the optimization is applied or not?

      @@ -358,13 +358,13 @@

      practical approach.

      The warnings look as follows:

      ./efficiency_guide.erl:60: Warning: NOT OPTIMIZED: binary is returned from the function
       ./efficiency_guide.erl:62: Warning: OPTIMIZED: match context reused

      To make it clearer exactly what code the warnings refer to, the warnings in the following examples are inserted as comments after the clause they refer to, for -example:

      after_zero(<<0,T/binary>>) ->
      +example:

      after_zero(<<0,T/binary>>) ->
                %% BINARY CREATED: binary is returned from the function
           T;
      -after_zero(<<_,T/binary>>) ->
      +after_zero(<<_,T/binary>>) ->
                %% OPTIMIZED: match context reused
      -    after_zero(T);
      -after_zero(<<>>) ->
      +    after_zero(T);
      +after_zero(<<>>) ->
           <<>>.

      The warning for the first clause says that the creation of a sub binary cannot be delayed, because it will be returned. The warning for the second clause says that a sub binary will not be created (yet).

      @@ -374,14 +374,14 @@

      Unused Variables

      The compiler figures out if a variable is unused. The same code is generated for -each of the following functions:

      count1(<<_,T/binary>>, Count) -> count1(T, Count+1);
      -count1(<<>>, Count) -> Count.
      +each of the following functions:

      count1(<<_,T/binary>>, Count) -> count1(T, Count+1);
      +count1(<<>>, Count) -> Count.
       
      -count2(<<H,T/binary>>, Count) -> count2(T, Count+1);
      -count2(<<>>, Count) -> Count.
      +count2(<<H,T/binary>>, Count) -> count2(T, Count+1);
      +count2(<<>>, Count) -> Count.
       
      -count3(<<_H,T/binary>>, Count) -> count3(T, Count+1);
      -count3(<<>>, Count) -> Count.

      In each iteration, the first 8 bits in the binary will be skipped, not matched +count3(<<_H,T/binary>>, Count) -> count3(T, Count+1); +count3(<<>>, Count) -> Count.

      In each iteration, the first 8 bits in the binary will be skipped, not matched out.

    diff --git a/prs/8803/doc/system/bit_syntax.html b/prs/8803/doc/system/bit_syntax.html index 02a94d6e7afd6..9f71df44287cb 100644 --- a/prs/8803/doc/system/bit_syntax.html +++ b/prs/8803/doc/system/bit_syntax.html @@ -145,17 +145,17 @@

    variables, and Bin2 is bound, as in Example 2:

    <<D:16, E, F/binary>> = Bin2

    This gives D = 273, E = 00, and F binds to a binary of size 1: binary_to_list(F) = [42].

    Example 4: The following is a more elaborate example of matching. Here, Dgram is bound to the consecutive bytes of an IP datagram of IP protocol -version 4. The ambition is to extract the header and the data of the datagram:

    -define(IP_VERSION, 4).
    --define(IP_MIN_HDR_LEN, 5).
    +version 4. The ambition is to extract the header and the data of the datagram:

    -define(IP_VERSION, 4).
    +-define(IP_MIN_HDR_LEN, 5).
     
    -DgramSize = byte_size(Dgram),
    +DgramSize = byte_size(Dgram),
     case Dgram of
         <<?IP_VERSION:4, HLen:4, SrvcType:8, TotLen:16,
           ID:16, Flgs:3, FragOff:13,
           TTL:8, Proto:8, HdrChkSum:16,
           SrcIP:32,
           DestIP:32, RestDgram/binary>> when HLen>=5, 4*HLen=<DgramSize ->
    -        OptsLen = 4*(HLen - ?IP_MIN_HDR_LEN),
    +        OptsLen = 4*(HLen - ?IP_MIN_HDR_LEN),
             <<Opts:OptsLen/binary,Data/binary>> = RestDgram,
         ...
     end.

    Here, the segment corresponding to the Opts variable has a type modifier, @@ -233,7 +233,7 @@

    However, for syntactical reasons, both Value and Size must be enclosed in parenthesis if the expression consists of anything more than a single literal or a variable. The following gives a compiler syntax error:

    <<X+1:8>>

    This expression must be rewritten into the following, to be accepted by the -compiler:

    <<(X+1):8>>

    +compiler:

    <<(X+1):8>>

    @@ -253,11 +253,11 @@

    restrictions on the size. A segment of type float must have size 64 or 32.

    As mentioned earlier, segments have the following general syntax:

    Value:Size/TypeSpecifierList

    When matching Value, value must be either a variable or an integer, or a floating point literal. Expressions are not allowed.

    Size must be a guard expression, which can use -literals and previously bound variables. The following is not allowed:

    foo(N, <<X:N,T/binary>>) ->
    -   {X,T}.

    The two occurrences of N are not related. The compiler will complain that the -N in the size field is unbound.

    The correct way to write this example is as follows:

    foo(N, Bin) ->
    +literals and previously bound variables. The following is not allowed:

    foo(N, <<X:N,T/binary>>) ->
    +   {X,T}.

    The two occurrences of N are not related. The compiler will complain that the +N in the size field is unbound.

    The correct way to write this example is as follows:

    foo(N, Bin) ->
        <<X:N,T/binary>> = Bin,
    -   {X,T}.

    Note

    Before OTP 23, Size was restricted to be an integer or a variable bound to + {X,T}.

    Note

    Before OTP 23, Size was restricted to be an integer or a variable bound to an integer.

    @@ -266,28 +266,28 @@

    There is one exception to the rule that a variable that is used as size must be previously bound. It is possible to match and bind a variable, and use it as a -size within the same binary pattern. For example:

    bar(<<Sz:8,Payload:Sz/binary-unit:8,Rest/binary>>) ->
    -   {Payload,Rest}.

    Here Sz is bound to the value in the first byte of the binary. Sz is then -used at the number of bytes to match out as a binary.

    Starting in OTP 23, the size can be a guard expression:

    bar(<<Sz:8,Payload:((Sz-1)*8)/binary,Rest/binary>>) ->
    -   {Payload,Rest}.

    Here Sz is the combined size of the header and the payload, so we will need to +size within the same binary pattern. For example:

    bar(<<Sz:8,Payload:Sz/binary-unit:8,Rest/binary>>) ->
    +   {Payload,Rest}.

    Here Sz is bound to the value in the first byte of the binary. Sz is then +used at the number of bytes to match out as a binary.

    Starting in OTP 23, the size can be a guard expression:

    bar(<<Sz:8,Payload:((Sz-1)*8)/binary,Rest/binary>>) ->
    +   {Payload,Rest}.

    Here Sz is the combined size of the header and the payload, so we will need to subtract one byte to get the size of the payload.

    Getting the Rest of the Binary or Bitstring

    -

    To match out the rest of a binary, specify a binary field without size:

    foo(<<A:8,Rest/binary>>) ->

    The size of the tail must be evenly divisible by 8.

    To match out the rest of a bitstring, specify a field without size:

    foo(<<A:8,Rest/bitstring>>) ->

    There are no restrictions on the number of bits in the tail.

    +

    To match out the rest of a binary, specify a binary field without size:

    foo(<<A:8,Rest/binary>>) ->

    The size of the tail must be evenly divisible by 8.

    To match out the rest of a bitstring, specify a field without size:

    foo(<<A:8,Rest/bitstring>>) ->

    There are no restrictions on the number of bits in the tail.

    Appending to a Binary

    -

    Appending to a binary in an efficient way can be done as follows:

    triples_to_bin(T) ->
    -    triples_to_bin(T, <<>>).
    +

    Appending to a binary in an efficient way can be done as follows:

    triples_to_bin(T) ->
    +    triples_to_bin(T, <<>>).
     
    -triples_to_bin([{X,Y,Z} | T], Acc) ->
    -    triples_to_bin(T, <<Acc/binary,X:32,Y:32,Z:32>>);
    -triples_to_bin([], Acc) ->
    +triples_to_bin([{X,Y,Z} | T], Acc) ->
    +    triples_to_bin(T, <<Acc/binary,X:32,Y:32,Z:32>>);
    +triples_to_bin([], Acc) ->
         Acc.

    diff --git a/prs/8803/doc/system/c_port.html b/prs/8803/doc/system/c_port.html index 780ab192141f3..8fc004eda6f93 100644 --- a/prs/8803/doc/system/c_port.html +++ b/prs/8803/doc/system/c_port.html @@ -152,93 +152,93 @@

    length indicator is to be used to simplify the communication between C and Erlang. The Erlang port automatically adds the length indicator, but this must be done explicitly in the external C program.

    The process is also set to trap exits, which enables detection of failure of the -external program:

    -module(complex1).
    --export([start/1, init/1]).
    -
    -start(ExtPrg) ->
    -  spawn(?MODULE, init, [ExtPrg]).
    -
    -init(ExtPrg) ->
    -  register(complex, self()),
    -  process_flag(trap_exit, true),
    -  Port = open_port({spawn, ExtPrg}, [{packet, 2}]),
    -  loop(Port).

    Now complex1:foo/1 and complex1:bar/1 can be implemented. Both send a -message to the complex process and receive the following replies:

    foo(X) ->
    -  call_port({foo, X}).
    -bar(Y) ->
    -  call_port({bar, Y}).
    -
    -call_port(Msg) ->
    -  complex ! {call, self(), Msg},
    +external program:

    -module(complex1).
    +-export([start/1, init/1]).
    +
    +start(ExtPrg) ->
    +  spawn(?MODULE, init, [ExtPrg]).
    +
    +init(ExtPrg) ->
    +  register(complex, self()),
    +  process_flag(trap_exit, true),
    +  Port = open_port({spawn, ExtPrg}, [{packet, 2}]),
    +  loop(Port).

    Now complex1:foo/1 and complex1:bar/1 can be implemented. Both send a +message to the complex process and receive the following replies:

    foo(X) ->
    +  call_port({foo, X}).
    +bar(Y) ->
    +  call_port({bar, Y}).
    +
    +call_port(Msg) ->
    +  complex ! {call, self(), Msg},
       receive
    -    {complex, Result} ->
    +    {complex, Result} ->
           Result
    -  end.

    The complex process does the following:

    • Encodes the message into a sequence of bytes.
    • Sends it to the port.
    • Waits for a reply.
    • Decodes the reply.
    • Sends it back to the caller:
    loop(Port) ->
    +  end.

    The complex process does the following:

    • Encodes the message into a sequence of bytes.
    • Sends it to the port.
    • Waits for a reply.
    • Decodes the reply.
    • Sends it back to the caller:
    loop(Port) ->
       receive
    -    {call, Caller, Msg} ->
    -      Port ! {self(), {command, encode(Msg)}},
    +    {call, Caller, Msg} ->
    +      Port ! {self(), {command, encode(Msg)}},
           receive
    -        {Port, {data, Data}} ->
    -          Caller ! {complex, decode(Data)}
    +        {Port, {data, Data}} ->
    +          Caller ! {complex, decode(Data)}
           end,
    -      loop(Port)
    +      loop(Port)
       end.

    Assuming that both the arguments and the results from the C functions are less than 256, a simple encoding/decoding scheme is employed. In this scheme, foo is represented by byte 1, bar is represented by 2, and the argument/result is -represented by a single byte as well:

    encode({foo, X}) -> [1, X];
    -encode({bar, Y}) -> [2, Y].
    +represented by a single byte as well:

    encode({foo, X}) -> [1, X];
    +encode({bar, Y}) -> [2, Y].
     
    -decode([Int]) -> Int.

    The resulting Erlang program, including functionality for stopping the port and -detecting port failures, is as follows:

    -module(complex1).
    --export([start/1, stop/0, init/1]).
    --export([foo/1, bar/1]).
    +decode([Int]) -> Int.

    The resulting Erlang program, including functionality for stopping the port and +detecting port failures, is as follows:

    -module(complex1).
    +-export([start/1, stop/0, init/1]).
    +-export([foo/1, bar/1]).
     
    -start(ExtPrg) ->
    -    spawn(?MODULE, init, [ExtPrg]).
    -stop() ->
    +start(ExtPrg) ->
    +    spawn(?MODULE, init, [ExtPrg]).
    +stop() ->
         complex ! stop.
     
    -foo(X) ->
    -    call_port({foo, X}).
    -bar(Y) ->
    -    call_port({bar, Y}).
    +foo(X) ->
    +    call_port({foo, X}).
    +bar(Y) ->
    +    call_port({bar, Y}).
     
    -call_port(Msg) ->
    -    complex ! {call, self(), Msg},
    +call_port(Msg) ->
    +    complex ! {call, self(), Msg},
         receive
    -	{complex, Result} ->
    +	{complex, Result} ->
     	    Result
         end.
     
    -init(ExtPrg) ->
    -    register(complex, self()),
    -    process_flag(trap_exit, true),
    -    Port = open_port({spawn, ExtPrg}, [{packet, 2}]),
    -    loop(Port).
    +init(ExtPrg) ->
    +    register(complex, self()),
    +    process_flag(trap_exit, true),
    +    Port = open_port({spawn, ExtPrg}, [{packet, 2}]),
    +    loop(Port).
     
    -loop(Port) ->
    +loop(Port) ->
         receive
    -	{call, Caller, Msg} ->
    -	    Port ! {self(), {command, encode(Msg)}},
    +	{call, Caller, Msg} ->
    +	    Port ! {self(), {command, encode(Msg)}},
     	    receive
    -		{Port, {data, Data}} ->
    -		    Caller ! {complex, decode(Data)}
    +		{Port, {data, Data}} ->
    +		    Caller ! {complex, decode(Data)}
     	    end,
    -	    loop(Port);
    +	    loop(Port);
     	stop ->
    -	    Port ! {self(), close},
    +	    Port ! {self(), close},
     	    receive
    -		{Port, closed} ->
    -		    exit(normal)
    +		{Port, closed} ->
    +		    exit(normal)
     	    end;
    -	{'EXIT', Port, Reason} ->
    -	    exit(port_terminated)
    +	{'EXIT', Port, Reason} ->
    +	    exit(port_terminated)
         end.
     
    -encode({foo, X}) -> [1, X];
    -encode({bar, Y}) -> [2, Y].
    +encode({foo, X}) -> [1, X];
    +encode({bar, Y}) -> [2, Y].
     
    -decode([Int]) -> Int.

    +decode([Int]) -> Int.

    @@ -255,55 +255,55 @@

    typedef unsigned char byte; -int read_exact(byte *buf, int len) -{ +int read_exact(byte *buf, int len) +{ int i, got=0; - do { - if ((i = read(0, buf+got, len-got)) <= 0){ - return(i); - } + do { + if ((i = read(0, buf+got, len-got)) <= 0){ + return(i); + } got += i; - } while (got<len); + } while (got<len); - return(len); -} + return(len); +} -int write_exact(byte *buf, int len) -{ +int write_exact(byte *buf, int len) +{ int i, wrote = 0; - do { - if ((i = write(1, buf+wrote, len-wrote)) <= 0) - return (i); + do { + if ((i = write(1, buf+wrote, len-wrote)) <= 0) + return (i); wrote += i; - } while (wrote<len); + } while (wrote<len); - return (len); -} + return (len); +} -int read_cmd(byte *buf) -{ +int read_cmd(byte *buf) +{ int len; - if (read_exact(buf, 2) != 2) - return(-1); - len = (buf[0] << 8) | buf[1]; - return read_exact(buf, len); -} + if (read_exact(buf, 2) != 2) + return(-1); + len = (buf[0] << 8) | buf[1]; + return read_exact(buf, len); +} -int write_cmd(byte *buf, int len) -{ +int write_cmd(byte *buf, int len) +{ byte li; - li = (len >> 8) & 0xff; - write_exact(&li, 1); + li = (len >> 8) & 0xff; + write_exact(&li, 1); li = len & 0xff; - write_exact(&li, 1); + write_exact(&li, 1); - return write_exact(buf, len); -}

    Notice that stdin and stdout are for buffered input/output and must not be + return write_exact(buf, len); +}

    Notice that stdin and stdout are for buffered input/output and must not be used for the communication with Erlang.

    In the main function, the C program is to listen for a message from Erlang and, according to the selected encoding/decoding scheme, use the first byte to determine which function to call and the second byte as argument to the @@ -311,24 +311,24 @@

    typedef unsigned char byte; -int main() { +int main() { int fn, arg, res; - byte buf[100]; - - while (read_cmd(buf) > 0) { - fn = buf[0]; - arg = buf[1]; - - if (fn == 1) { - res = foo(arg); - } else if (fn == 2) { - res = bar(arg); - } - - buf[0] = res; - write_cmd(buf, 1); - } -}

    Notice that the C program is in a while-loop, checking for the return value + byte buf[100]; + + while (read_cmd(buf) > 0) { + fn = buf[0]; + arg = buf[1]; + + if (fn == 1) { + res = foo(arg); + } else if (fn == 2) { + res = bar(arg); + } + + buf[0] = res; + write_cmd(buf, 1); + } +}

    Notice that the C program is in a while-loop, checking for the return value of read_cmd/1. This is because the C program must detect when the port closes and terminates.

    @@ -337,17 +337,17 @@

    Running the Example

    Step 1. Compile the C code:

    $ gcc -o extprg complex.c erl_comm.c port.c

    Step 2. Start Erlang and compile the Erlang code:

    $ erl
    -Erlang/OTP 26 [erts-14.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]
    +Erlang/OTP 26 [erts-14.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]
     
    -Eshell V14.2 (press Ctrl+G to abort, type help(). for help)
    -1> c(complex1).
    -{ok,complex1}

    Step 3. Run the example:

    2> complex1:start("./extprg").
    +Eshell V14.2 (press Ctrl+G to abort, type help(). for help)
    +1> c(complex1).
    +{ok,complex1}

    Step 3. Run the example:

    2> complex1:start("./extprg").
     <0.34.0>
    -3> complex1:foo(3).
    +3> complex1:foo(3).
     4
    -4> complex1:bar(5).
    +4> complex1:bar(5).
     10
    -5> complex1:stop().
    +5> complex1:stop().
     stop

    diff --git a/prs/8803/doc/system/c_portdriver.html b/prs/8803/doc/system/c_portdriver.html index 2e9d960b6e092..ba7cbf179807b 100644 --- a/prs/8803/doc/system/c_portdriver.html +++ b/prs/8803/doc/system/c_portdriver.html @@ -155,104 +155,104 @@

    argument.

    The port is then created using the BIF open_port/2, with the tuple {spawn, DriverName} as the first argument. The string SharedLib is the name of the port driver. The second argument is a list of options, none in this -case:

    -module(complex5).
    --export([start/1, init/1]).
    +case:

    -module(complex5).
    +-export([start/1, init/1]).
     
    -start(SharedLib) ->
    -    case erl_ddll:load_driver(".", SharedLib) of
    +start(SharedLib) ->
    +    case erl_ddll:load_driver(".", SharedLib) of
             ok -> ok;
    -        {error, already_loaded} -> ok;
    -        _ -> exit({error, could_not_load_driver})
    +        {error, already_loaded} -> ok;
    +        _ -> exit({error, could_not_load_driver})
         end,
    -    spawn(?MODULE, init, [SharedLib]).
    -
    -init(SharedLib) ->
    -  register(complex, self()),
    -  Port = open_port({spawn, SharedLib}, []),
    -  loop(Port).

    Now complex5:foo/1 and complex5:bar/1 can be implemented. Both send a -message to the complex process and receive the following reply:

    foo(X) ->
    -    call_port({foo, X}).
    -bar(Y) ->
    -    call_port({bar, Y}).
    -
    -call_port(Msg) ->
    -    complex ! {call, self(), Msg},
    +    spawn(?MODULE, init, [SharedLib]).
    +
    +init(SharedLib) ->
    +  register(complex, self()),
    +  Port = open_port({spawn, SharedLib}, []),
    +  loop(Port).

    Now complex5:foo/1 and complex5:bar/1 can be implemented. Both send a +message to the complex process and receive the following reply:

    foo(X) ->
    +    call_port({foo, X}).
    +bar(Y) ->
    +    call_port({bar, Y}).
    +
    +call_port(Msg) ->
    +    complex ! {call, self(), Msg},
         receive
    -        {complex, Result} ->
    +        {complex, Result} ->
                 Result
    -    end.

    The complex process performs the following:

    • Encodes the message into a sequence of bytes.
    • Sends it to the port.
    • Waits for a reply.
    • Decodes the reply.
    • Sends it back to the caller:
    loop(Port) ->
    +    end.

    The complex process performs the following:

    • Encodes the message into a sequence of bytes.
    • Sends it to the port.
    • Waits for a reply.
    • Decodes the reply.
    • Sends it back to the caller:
    loop(Port) ->
         receive
    -        {call, Caller, Msg} ->
    -            Port ! {self(), {command, encode(Msg)}},
    +        {call, Caller, Msg} ->
    +            Port ! {self(), {command, encode(Msg)}},
                 receive
    -                {Port, {data, Data}} ->
    -                    Caller ! {complex, decode(Data)}
    +                {Port, {data, Data}} ->
    +                    Caller ! {complex, decode(Data)}
                 end,
    -            loop(Port)
    +            loop(Port)
         end.

    Assuming that both the arguments and the results from the C functions are less than 256, a simple encoding/decoding scheme is employed. In this scheme, foo is represented by byte 1, bar is represented by 2, and the argument/result is -represented by a single byte as well:

    encode({foo, X}) -> [1, X];
    -encode({bar, Y}) -> [2, Y].
    +represented by a single byte as well:

    encode({foo, X}) -> [1, X];
    +encode({bar, Y}) -> [2, Y].
     
    -decode([Int]) -> Int.

    The resulting Erlang program, including functions for stopping the port and +decode([Int]) -> Int.

    The resulting Erlang program, including functions for stopping the port and detecting port failures, is as follows:

    
    --module(complex5).
    --export([start/1, stop/0, init/1]).
    --export([foo/1, bar/1]).
    +-module(complex5).
    +-export([start/1, stop/0, init/1]).
    +-export([foo/1, bar/1]).
     
    -start(SharedLib) ->
    -    case erl_ddll:load_driver(".", SharedLib) of
    +start(SharedLib) ->
    +    case erl_ddll:load_driver(".", SharedLib) of
     	ok -> ok;
    -	{error, already_loaded} -> ok;
    -	_ -> exit({error, could_not_load_driver})
    +	{error, already_loaded} -> ok;
    +	_ -> exit({error, could_not_load_driver})
         end,
    -    spawn(?MODULE, init, [SharedLib]).
    +    spawn(?MODULE, init, [SharedLib]).
     
    -init(SharedLib) ->
    -    register(complex, self()),
    -    Port = open_port({spawn, SharedLib}, []),
    -    loop(Port).
    +init(SharedLib) ->
    +    register(complex, self()),
    +    Port = open_port({spawn, SharedLib}, []),
    +    loop(Port).
     
    -stop() ->
    +stop() ->
         complex ! stop.
     
    -foo(X) ->
    -    call_port({foo, X}).
    -bar(Y) ->
    -    call_port({bar, Y}).
    +foo(X) ->
    +    call_port({foo, X}).
    +bar(Y) ->
    +    call_port({bar, Y}).
     
    -call_port(Msg) ->
    -    complex ! {call, self(), Msg},
    +call_port(Msg) ->
    +    complex ! {call, self(), Msg},
         receive
    -	{complex, Result} ->
    +	{complex, Result} ->
     	    Result
         end.
     
    -loop(Port) ->
    +loop(Port) ->
         receive
    -	{call, Caller, Msg} ->
    -	    Port ! {self(), {command, encode(Msg)}},
    +	{call, Caller, Msg} ->
    +	    Port ! {self(), {command, encode(Msg)}},
     	    receive
    -		{Port, {data, Data}} ->
    -		    Caller ! {complex, decode(Data)}
    +		{Port, {data, Data}} ->
    +		    Caller ! {complex, decode(Data)}
     	    end,
    -	    loop(Port);
    +	    loop(Port);
     	stop ->
    -	    Port ! {self(), close},
    +	    Port ! {self(), close},
     	    receive
    -		{Port, closed} ->
    -		    exit(normal)
    +		{Port, closed} ->
    +		    exit(normal)
     	    end;
    -	{'EXIT', Port, Reason} ->
    -	    io:format("~p ~n", [Reason]),
    -	    exit(port_terminated)
    +	{'EXIT', Port, Reason} ->
    +	    io:format("~p ~n", [Reason]),
    +	    exit(port_terminated)
         end.
     
    -encode({foo, X}) -> [1, X];
    -encode({bar, Y}) -> [2, Y].
    +encode({foo, X}) -> [1, X];
    +encode({bar, Y}) -> [2, Y].
     
    -decode([Int]) -> Int.

    +decode([Int]) -> Int.

    @@ -277,36 +277,36 @@

    #include <stdio.h> #include "erl_driver.h" -typedef struct { +typedef struct { ErlDrvPort port; -} example_data; +} example_data; -static ErlDrvData example_drv_start(ErlDrvPort port, char *buff) -{ - example_data* d = (example_data*)driver_alloc(sizeof(example_data)); +static ErlDrvData example_drv_start(ErlDrvPort port, char *buff) +{ + example_data* d = (example_data*)driver_alloc(sizeof(example_data)); d->port = port; - return (ErlDrvData)d; -} - -static void example_drv_stop(ErlDrvData handle) -{ - driver_free((char*)handle); -} - -static void example_drv_output(ErlDrvData handle, char *buff, - ErlDrvSizeT bufflen) -{ - example_data* d = (example_data*)handle; - char fn = buff[0], arg = buff[1], res; - if (fn == 1) { - res = foo(arg); - } else if (fn == 2) { - res = bar(arg); - } - driver_output(d->port, &res, 1); -} - -ErlDrvEntry example_driver_entry = { + return (ErlDrvData)d; +} + +static void example_drv_stop(ErlDrvData handle) +{ + driver_free((char*)handle); +} + +static void example_drv_output(ErlDrvData handle, char *buff, + ErlDrvSizeT bufflen) +{ + example_data* d = (example_data*)handle; + char fn = buff[0], arg = buff[1], res; + if (fn == 1) { + res = foo(arg); + } else if (fn == 2) { + res = bar(arg); + } + driver_output(d->port, &res, 1); +} + +ErlDrvEntry example_driver_entry = { NULL, /* F_PTR init, called when driver is loaded */ example_drv_start, /* L_PTR start, called when port is opened */ example_drv_stop, /* F_PTR stop, called when port is closed */ @@ -338,12 +338,12 @@

    monitored process dies */ NULL /* F_PTR stop_select, called to close an event object */ -}; +}; -DRIVER_INIT(example_drv) /* must match name in driver_entry */ -{ +DRIVER_INIT(example_drv) /* must match name in driver_entry */ +{ return &example_driver_entry; -}

    +}

    @@ -351,17 +351,17 @@

    Step 1. Compile the C code:

    unix> gcc -o example_drv.so -fpic -shared complex.c port_driver.c
     windows> cl -LD -MD -Fe example_drv.dll complex.c port_driver.c

    Step 2. Start Erlang and compile the Erlang code:

    > erl
    -Erlang/OTP 26 [erts-14.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]
    +Erlang/OTP 26 [erts-14.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]
     
    -Eshell V14.2 (press Ctrl+G to abort, type help(). for help)
    -1> c(complex5).
    -{ok,complex5}

    Step 3. Run the example:

    2> complex5:start("example_drv").
    +Eshell V14.2 (press Ctrl+G to abort, type help(). for help)
    +1> c(complex5).
    +{ok,complex5}

    Step 3. Run the example:

    2> complex5:start("example_drv").
     <0.34.0>
    -3> complex5:foo(3).
    +3> complex5:foo(3).
     4
    -4> complex5:bar(5).
    +4> complex5:bar(5).
     10
    -5> complex5:stop().
    +5> complex5:stop().
     stop

    diff --git a/prs/8803/doc/system/code_loading.html b/prs/8803/doc/system/code_loading.html index 6ccdb83912774..759c0d49ef45c 100644 --- a/prs/8803/doc/system/code_loading.html +++ b/prs/8803/doc/system/code_loading.html @@ -126,8 +126,8 @@

    Erlang programs must be compiled to object code. The compiler can generate a new file that contains the object code. The current abstract machine, which runs the object code, is called BEAM, therefore the object files get the suffix -.beam. The compiler can also generate a binary which can be loaded directly.

    The compiler is located in the module compile in Compiler.

    compile:file(Module)
    -compile:file(Module, Options)

    The Erlang shell understands the command c(Module), which both compiles and +.beam. The compiler can also generate a binary which can be loaded directly.

    The compiler is located in the module compile in Compiler.

    compile:file(Module)
    +compile:file(Module, Options)

    The Erlang shell understands the command c(Module), which both compiles and loads Module.

    There is also a module make, which provides a set of functions similar to the UNIX type Make functions, see module make in Tools.

    The compiler can also be accessed from the OS prompt using the erl executable in ERTS.

    % erl -compile Module1...ModuleN
    @@ -160,16 +160,16 @@ 

    evaluated because of processes lingering in the old code.

    If a third instance of the module is loaded, the code server removes (purges) the old code and any processes lingering in it is terminated. Then the third instance becomes 'current' and the previously current code becomes 'old'.

    To change from old code to current code, a process must make a fully qualified -function call.

    Example:

    -module(m).
    --export([loop/0]).
    +function call.

    Example:

    -module(m).
    +-export([loop/0]).
     
    -loop() ->
    +loop() ->
         receive
             code_switch ->
    -            m:loop();
    +            m:loop();
             Msg ->
                 ...
    -            loop()
    +            loop()
         end.

    To make the process change code, send the message code_switch to it. The process then makes a fully qualified call to m:loop() and changes to current code. Notice that m:loop/0 must be exported.

    For code replacement of funs to work, use the syntax @@ -180,7 +180,7 @@

    Running a Function When a Module is Loaded

    The -on_load() directive names a function that is to be run automatically when -a module is loaded.

    Its syntax is as follows:

    -on_load(Name/0).

    It is not necessary to export the function. It is called in a freshly spawned +a module is loaded.

    Its syntax is as follows:

    -on_load(Name/0).

    It is not necessary to export the function. It is called in a freshly spawned process (which terminates as soon as the function returns).

    The function must return ok if the module is to become the new current code for the module and become callable.

    Returning any other value or generating an exception causes the new code to be unloaded. If the return value is not an atom, a warning error report is sent to @@ -193,13 +193,13 @@

    code would become old, essentially leaving the system without any working and reachable instance of the module.

    In embedded mode, first all modules are loaded. Then all on_load functions are called. The system is terminated unless all of the on_load functions return -ok.

    Example:

    -module(m).
    --on_load(load_my_nifs/0).
    +ok.

    Example:

    -module(m).
    +-on_load(load_my_nifs/0).
     
    -load_my_nifs() ->
    +load_my_nifs() ->
         NifPath = ...,    %Set up the path to the NIF library.
         Info = ...,       %Initialize the Info term
    -    erlang:load_nif(NifPath, Info).

    If the call to erlang:load_nif/2 fails, the module is unloaded and a warning + erlang:load_nif(NifPath, Info).

    If the call to erlang:load_nif/2 fails, the module is unloaded and a warning report is sent to the error loader.

    diff --git a/prs/8803/doc/system/commoncaveats.html b/prs/8803/doc/system/commoncaveats.html index f80c89f28bfc8..523a19cf41100 100644 --- a/prs/8803/doc/system/commoncaveats.html +++ b/prs/8803/doc/system/commoncaveats.html @@ -122,23 +122,23 @@

    Operator ++

    The ++ operator copies its left-hand side operand. That is clearly -seen if we do our own implementation in Erlang:

    my_plus_plus([H|T], Tail) ->
    -    [H|my_plus_plus(T, Tail)];
    -my_plus_plus([], Tail) ->
    -    Tail.

    We must be careful how we use ++ in a loop. First is how not to use it:

    DO NOT

    naive_reverse([H|T]) ->
    -    naive_reverse(T) ++ [H];
    -naive_reverse([]) ->
    -    [].

    As the ++ operator copies its left-hand side operand, the growing -result is copied repeatedly, leading to quadratic complexity.

    On the other hand, using ++ in loop like this is perfectly fine:

    OK

    naive_but_ok_reverse(List) ->
    -    naive_but_ok_reverse(List, []).
    -
    -naive_but_ok_reverse([H|T], Acc) ->
    -    naive_but_ok_reverse(T, [H] ++ Acc);
    -naive_but_ok_reverse([], Acc) ->
    +seen if we do our own implementation in Erlang:

    my_plus_plus([H|T], Tail) ->
    +    [H|my_plus_plus(T, Tail)];
    +my_plus_plus([], Tail) ->
    +    Tail.

    We must be careful how we use ++ in a loop. First is how not to use it:

    DO NOT

    naive_reverse([H|T]) ->
    +    naive_reverse(T) ++ [H];
    +naive_reverse([]) ->
    +    [].

    As the ++ operator copies its left-hand side operand, the growing +result is copied repeatedly, leading to quadratic complexity.

    On the other hand, using ++ in loop like this is perfectly fine:

    OK

    naive_but_ok_reverse(List) ->
    +    naive_but_ok_reverse(List, []).
    +
    +naive_but_ok_reverse([H|T], Acc) ->
    +    naive_but_ok_reverse(T, [H] ++ Acc);
    +naive_but_ok_reverse([], Acc) ->
         Acc.

    Each list element is copied only once. The growing result Acc is the right-hand -side operand, which it is not copied.

    Experienced Erlang programmers would probably write as follows:

    DO

    vanilla_reverse([H|T], Acc) ->
    -    vanilla_reverse(T, [H|Acc]);
    -vanilla_reverse([], Acc) ->
    +side operand, which it is not copied.

    Experienced Erlang programmers would probably write as follows:

    DO

    vanilla_reverse([H|T], Acc) ->
    +    vanilla_reverse(T, [H|Acc]);
    +vanilla_reverse([], Acc) ->
         Acc.

    In principle, this is slightly more efficient because the list element [H] is not built before being copied and discarded. In practice, the compiler rewrites [H] ++ Acc to [H|Acc].

    @@ -164,41 +164,41 @@

    Accidental Copying and Loss of Sharing

    When spawning a new process using a fun, one can accidentally copy more data to -the process than intended. For example:

    DO NOT

    accidental1(State) ->
    -    spawn(fun() ->
    -                  io:format("~p\n", [State#state.info])
    -          end).

    The code in the fun will extract one element from the record and print it. The +the process than intended. For example:

    DO NOT

    accidental1(State) ->
    +    spawn(fun() ->
    +                  io:format("~p\n", [State#state.info])
    +          end).

    The code in the fun will extract one element from the record and print it. The rest of the state record is not used. However, when the spawn/1 -function is executed, the entire record is copied to the newly created process.

    The same kind of problem can happen with a map:

    DO NOT

    accidental2(State) ->
    -    spawn(fun() ->
    -                  io:format("~p\n", [map_get(info, State)])
    -          end).

    In the following example (part of a module implementing the gen_server -behavior) the created fun is sent to another process:

    DO NOT

    handle_call(give_me_a_fun, _From, State) ->
    -    Fun = fun() -> State#state.size =:= 42 end,
    -    {reply, Fun, State}.

    How bad that unnecessary copy is depends on the contents of the record or the -map.

    For example, if the state record is initialized like this:

    init1() ->
    -    #state{data=lists:seq(1, 10000)}.

    a list with 10000 elements (or about 20000 heap words) will be copied to the +function is executed, the entire record is copied to the newly created process.

    The same kind of problem can happen with a map:

    DO NOT

    accidental2(State) ->
    +    spawn(fun() ->
    +                  io:format("~p\n", [map_get(info, State)])
    +          end).

    In the following example (part of a module implementing the gen_server +behavior) the created fun is sent to another process:

    DO NOT

    handle_call(give_me_a_fun, _From, State) ->
    +    Fun = fun() -> State#state.size =:= 42 end,
    +    {reply, Fun, State}.

    How bad that unnecessary copy is depends on the contents of the record or the +map.

    For example, if the state record is initialized like this:

    init1() ->
    +    #state{data=lists:seq(1, 10000)}.

    a list with 10000 elements (or about 20000 heap words) will be copied to the newly created process.

    An unnecessary copy of 10000 element list can be bad enough, but it can get even worse if the state record contains shared subterms. Here is a simple example -of a term with a shared subterm:

    {SubTerm, SubTerm}

    When a term is copied to another process, sharing of subterms will be lost and -the copied term can be many times larger than the original term. For example:

    init2() ->
    -    SharedSubTerms = lists:foldl(fun(_, A) -> [A|A] end, [0], lists:seq(1, 15)),
    -    #state{data=Shared}.

    In the process that calls init2/0, the size of the data field in the state +of a term with a shared subterm:

    {SubTerm, SubTerm}

    When a term is copied to another process, sharing of subterms will be lost and +the copied term can be many times larger than the original term. For example:

    init2() ->
    +    SharedSubTerms = lists:foldl(fun(_, A) -> [A|A] end, [0], lists:seq(1, 15)),
    +    #state{data=Shared}.

    In the process that calls init2/0, the size of the data field in the state record will be 32 heap words. When the record is copied to the newly created process, sharing will be lost and the size of the copied data field will be 131070 heap words. More details about loss off sharing are found in a later section.

    To avoid the problem, outside of the fun extract only the fields of the record -that are actually used:

    DO

    fixed_accidental1(State) ->
    +that are actually used:

    DO

    fixed_accidental1(State) ->
         Info = State#state.info,
    -    spawn(fun() ->
    -                  io:format("~p\n", [Info])
    -          end).

    Similarly, outside of the fun extract only the map elements that are actually -used:

    DO

    fixed_accidental2(State) ->
    -    Info = map_get(info, State),
    -    spawn(fun() ->
    -                  io:format("~p\n", [Info])
    -          end).

    + spawn(fun() -> + io:format("~p\n", [Info]) + end).

    Similarly, outside of the fun extract only the map elements that are actually +used:

    DO

    fixed_accidental2(State) ->
    +    Info = map_get(info, State),
    +    spawn(fun() ->
    +                  io:format("~p\n", [Info])
    +          end).

    @@ -213,7 +213,7 @@

    to guard against a denial-of-service attack. (All atoms that are allowed must have been created earlier, for example, by using all of them in a module and loading that module.)

    Using list_to_atom/1 to construct an atom that -is passed to apply/3 is quite expensive.

    DO NOT

    apply(list_to_atom("some_prefix"++Var), foo, Args)

    +is passed to apply/3 is quite expensive.

    DO NOT

    apply(list_to_atom("some_prefix"++Var), foo, Args)

    @@ -225,8 +225,8 @@

    execute in constant time.

    Normally, there is no need to worry about the speed of length/1, because it is efficiently implemented in C. In time-critical code, you might want to avoid it if the input list could potentially be very long.

    Some uses of length/1 can be replaced by matching. For example, -the following code:

    foo(L) when length(L) >= 3 ->
    -    ...

    can be rewritten to:

    foo([_,_,_|_]=L) ->
    +the following code:

    foo(L) when length(L) >= 3 ->
    +    ...

    can be rewritten to:

    foo([_,_,_|_]=L) ->
        ...

    One slight difference is that length(L) fails if L is an improper list, while the pattern in the second code fragment accepts an improper list.

    @@ -242,10 +242,10 @@

    as if the tuple was copied, the call to setelement/3 is replaced with a special destructive setelement instruction. In the following code sequence, the first setelement/3 call copies the tuple -and modifies the ninth element:

    multiple_setelement(T0) when tuple_size(T0) =:= 9 ->
    -    T1 = setelement(9, T0, bar),
    -    T2 = setelement(7, T1, foobar),
    -    setelement(5, T2, new_value).

    The two following setelement/3 calls modify the tuple in +and modifies the ninth element:

    multiple_setelement(T0) when tuple_size(T0) =:= 9 ->
    +    T1 = setelement(9, T0, bar),
    +    T2 = setelement(7, T1, foobar),
    +    setelement(5, T2, new_value).

    The two following setelement/3 calls modify the tuple in place.

    For the optimization to be applied, all the following conditions must be true:

    • The tuple argument must be known to be a tuple of a known size.
    • The indices must be integer literals, not variables or expressions.
    • The indices must be given in descending order.
    • There must be no calls to another function in between the calls to setelement/3.
    • The tuple returned from one setelement/3 call must only be used in the subsequent call to setelement/3.

    If the code cannot be structured as in the multiple_setelement/1 example, the diff --git a/prs/8803/doc/system/conc_prog.html b/prs/8803/doc/system/conc_prog.html index 9ee178b877b25..904e31262c699 100644 --- a/prs/8803/doc/system/conc_prog.html +++ b/prs/8803/doc/system/conc_prog.html @@ -136,21 +136,21 @@

    Threads of execution in Erlang share no data, that is why they are called processes).

    The Erlang BIF spawn is used to create a new process: spawn(Module, Exported_Function, List of Arguments). Consider the following -module:

    -module(tut14).
    +module:

    -module(tut14).
     
    --export([start/0, say_something/2]).
    +-export([start/0, say_something/2]).
     
    -say_something(What, 0) ->
    +say_something(What, 0) ->
         done;
    -say_something(What, Times) ->
    -    io:format("~p~n", [What]),
    -    say_something(What, Times - 1).
    -
    -start() ->
    -    spawn(tut14, say_something, [hello, 3]),
    -    spawn(tut14, say_something, [goodbye, 3]).
    5> c(tut14).
    -{ok,tut14}
    -6> tut14:say_something(hello, 3).
    +say_something(What, Times) ->
    +    io:format("~p~n", [What]),
    +    say_something(What, Times - 1).
    +
    +start() ->
    +    spawn(tut14, say_something, [hello, 3]),
    +    spawn(tut14, say_something, [goodbye, 3]).
    5> c(tut14).
    +{ok,tut14}
    +6> tut14:say_something(hello, 3).
     hello
     hello
     hello
    @@ -159,7 +159,7 @@ 

    processes, one that writes "hello" three times and one that writes "goodbye" three times. Both processes use the function say_something. Notice that a function used in this way by spawn, to start a process, must be exported from -the module (that is, in the -export at the start of the module).

    9> tut14:start().
    +the module (that is, in the -export at the start of the module).

    9> tut14:start().
     hello
     goodbye
     <0.63.0>
    @@ -170,7 +170,7 @@ 

    Instead, the first process wrote a "hello", the second a "goodbye", the first another "hello" and so forth. But where did the <0.63.0> come from? The return value of a function is the return value of the last "thing" in the function. The -last thing in the function start is

    spawn(tut14, say_something, [goodbye, 3]).

    spawn returns a process identifier, or pid, which uniquely identifies the +last thing in the function start is

    spawn(tut14, say_something, [goodbye, 3]).

    spawn returns a process identifier, or pid, which uniquely identifies the process. So <0.63.0> is the pid of the spawn function call above. The next example shows how to use pids.

    Notice also that ~p is used instead of ~w in io:format/2. To quote the manual:

    ~p Writes the data with standard syntax in the same way as ~w, but breaks terms whose printed representation is longer than one line into many lines and indents @@ -182,37 +182,37 @@

    Message Passing

    In the following example two processes are created and they send messages to -each other a number of times.

    -module(tut15).
    +each other a number of times.

    -module(tut15).
     
    --export([start/0, ping/2, pong/0]).
    +-export([start/0, ping/2, pong/0]).
     
    -ping(0, Pong_PID) ->
    +ping(0, Pong_PID) ->
         Pong_PID ! finished,
    -    io:format("ping finished~n", []);
    +    io:format("ping finished~n", []);
     
    -ping(N, Pong_PID) ->
    -    Pong_PID ! {ping, self()},
    +ping(N, Pong_PID) ->
    +    Pong_PID ! {ping, self()},
         receive
             pong ->
    -            io:format("Ping received pong~n", [])
    +            io:format("Ping received pong~n", [])
         end,
    -    ping(N - 1, Pong_PID).
    +    ping(N - 1, Pong_PID).
     
    -pong() ->
    +pong() ->
         receive
             finished ->
    -            io:format("Pong finished~n", []);
    -        {ping, Ping_PID} ->
    -            io:format("Pong received ping~n", []),
    +            io:format("Pong finished~n", []);
    +        {ping, Ping_PID} ->
    +            io:format("Pong received ping~n", []),
                 Ping_PID ! pong,
    -            pong()
    +            pong()
         end.
     
    -start() ->
    -    Pong_PID = spawn(tut15, pong, []),
    -    spawn(tut15, ping, [3, Pong_PID]).
    1> c(tut15).
    -{ok,tut15}
    -2> tut15: start().
    +start() ->
    +    Pong_PID = spawn(tut15, pong, []),
    +    spawn(tut15, ping, [3, Pong_PID]).
    1> c(tut15).
    +{ok,tut15}
    +2> tut15: start().
     <0.36.0>
     Pong received ping
     Ping received pong
    @@ -221,14 +221,14 @@ 

    Pong received ping Ping received pong ping finished -Pong finished

    The function start first creates a process, let us call it "pong":

    Pong_PID = spawn(tut15, pong, [])

    This process executes tut15:pong(). Pong_PID is the process identity of the -"pong" process. The function start now creates another process "ping":

    spawn(tut15, ping, [3, Pong_PID]),

    This process executes:

    tut15:ping(3, Pong_PID)

    <0.36.0> is the return value from the start function.

    The process "pong" now does:

    receive
    +Pong finished

    The function start first creates a process, let us call it "pong":

    Pong_PID = spawn(tut15, pong, [])

    This process executes tut15:pong(). Pong_PID is the process identity of the +"pong" process. The function start now creates another process "ping":

    spawn(tut15, ping, [3, Pong_PID]),

    This process executes:

    tut15:ping(3, Pong_PID)

    <0.36.0> is the return value from the start function.

    The process "pong" now does:

    receive
         finished ->
    -        io:format("Pong finished~n", []);
    -    {ping, Ping_PID} ->
    -        io:format("Pong received ping~n", []),
    +        io:format("Pong finished~n", []);
    +    {ping, Ping_PID} ->
    +        io:format("Pong received ping~n", []),
             Ping_PID ! pong,
    -        pong()
    +        pong()
     end.

    The receive construct is used to allow processes to wait for messages from other processes. It has the following format:

    receive
        pattern1 ->
    @@ -257,21 +257,21 @@ 

    procedure is repeated.

    The Erlang implementation is "clever" and minimizes the number of times each message is tested against the patterns in each receive.

    Now back to the ping pong example.

    "Pong" is waiting for messages. If the atom finished is received, "pong" writes "Pong finished" to the output and, as it has nothing more to do, -terminates. If it receives a message with the format:

    {ping, Ping_PID}

    it writes "Pong received ping" to the output and sends the atom pong to the +terminates. If it receives a message with the format:

    {ping, Ping_PID}

    it writes "Pong received ping" to the output and sends the atom pong to the process "ping":

    Ping_PID ! pong

    Notice how the operator "!" is used to send messages. The syntax of "!" is:

    Pid ! Message

    That is, Message (any Erlang term) is sent to the process with identity Pid.

    After sending the message pong to the process "ping", "pong" calls the pong function again, which causes it to get back to the receive again and wait for -another message.

    Now let us look at the process "ping". Recall that it was started by executing:

    tut15:ping(3, Pong_PID)

    Looking at the function ping/2, the second clause of ping/2 is executed +another message.

    Now let us look at the process "ping". Recall that it was started by executing:

    tut15:ping(3, Pong_PID)

    Looking at the function ping/2, the second clause of ping/2 is executed since the value of the first argument is 3 (not 0) (first clause head is -ping(0,Pong_PID), second clause head is ping(N,Pong_PID), so N becomes 3).

    The second clause sends a message to "pong":

    Pong_PID ! {ping, self()},

    self/0 returns the pid of the process that executes self/0, in this case the +ping(0,Pong_PID), second clause head is ping(N,Pong_PID), so N becomes 3).

    The second clause sends a message to "pong":

    Pong_PID ! {ping, self()},

    self/0 returns the pid of the process that executes self/0, in this case the pid of "ping". (Recall the code for "pong", this lands up in the variable Ping_PID in the receive previously explained.)

    "Ping" now waits for a reply from "pong":

    receive
         pong ->
    -        io:format("Ping received pong~n", [])
    +        io:format("Ping received pong~n", [])
     end,

    It writes "Ping received pong" when this reply arrives, after which "ping" calls -the ping function again.

    ping(N - 1, Pong_PID)

    N-1 causes the first argument to be decremented until it becomes 0. When this -occurs, the first clause of ping/2 is executed:

    ping(0, Pong_PID) ->
    +the ping function again.

    ping(N - 1, Pong_PID)

    N-1 causes the first argument to be decremented until it becomes 0. When this +occurs, the first clause of ping/2 is executed:

    ping(0, Pong_PID) ->
         Pong_PID !  finished,
    -    io:format("ping finished~n", []);

    The atom finished is sent to "pong" (causing it to terminate as described + io:format("ping finished~n", []);

    The atom finished is sent to "pong" (causing it to terminate as described above) and "ping finished" is written to the output. "Ping" then terminates as it has nothing left to do.

    @@ -285,38 +285,38 @@

    processes which need to know each other's identities are started independently of each other. Erlang thus provides a mechanism for processes to be given names so that these names can be used as identities instead of pids. This is done by -using the register BIF:

    register(some_atom, Pid)

    Let us now rewrite the ping pong example using this and give the name pong to -the "pong" process:

    -module(tut16).
    +using the register BIF:

    register(some_atom, Pid)

    Let us now rewrite the ping pong example using this and give the name pong to +the "pong" process:

    -module(tut16).
     
    --export([start/0, ping/1, pong/0]).
    +-export([start/0, ping/1, pong/0]).
     
    -ping(0) ->
    +ping(0) ->
         pong ! finished,
    -    io:format("ping finished~n", []);
    +    io:format("ping finished~n", []);
     
    -ping(N) ->
    -    pong ! {ping, self()},
    +ping(N) ->
    +    pong ! {ping, self()},
         receive
             pong ->
    -            io:format("Ping received pong~n", [])
    +            io:format("Ping received pong~n", [])
         end,
    -    ping(N - 1).
    +    ping(N - 1).
     
    -pong() ->
    +pong() ->
         receive
             finished ->
    -            io:format("Pong finished~n", []);
    -        {ping, Ping_PID} ->
    -            io:format("Pong received ping~n", []),
    +            io:format("Pong finished~n", []);
    +        {ping, Ping_PID} ->
    +            io:format("Pong received ping~n", []),
                 Ping_PID ! pong,
    -            pong()
    +            pong()
         end.
     
    -start() ->
    -    register(pong, spawn(tut16, pong, [])),
    -    spawn(tut16, ping, [3]).
    2> c(tut16).
    -{ok, tut16}
    -3> tut16:start().
    +start() ->
    +    register(pong, spawn(tut16, pong, [])),
    +    spawn(tut16, ping, [3]).
    2> c(tut16).
    +{ok, tut16}
    +3> tut16:start().
     <0.38.0>
     Pong received ping
     Ping received pong
    @@ -325,8 +325,8 @@ 

    Pong received ping Ping received pong ping finished -Pong finished

    Here the start/0 function,

    register(pong, spawn(tut16, pong, [])),

    both spawns the "pong" process and gives it the name pong. In the "ping" -process, messages can be sent to pong by:

    pong ! {ping, self()},

    ping/2 now becomes ping/1 as the argument Pong_PID is not needed.

    +Pong finished

    Here the start/0 function,

    register(pong, spawn(tut16, pong, [])),

    both spawns the "pong" process and gives it the name pong. In the "ping" +process, messages can be sent to pong by:

    pong ! {ping, self()},

    ping/2 now becomes ping/1 as the argument Pong_PID is not needed.

    @@ -354,37 +354,37 @@

    Erlang system running on a computer is called an Erlang node.

    (Note: erl -sname assumes that all nodes are in the same IP domain and we can use only the first component of the IP address, if we want to use nodes in different domains we use -name instead, but then all IP address must be given -in full.)

    Here is the ping pong example modified to run on two separate nodes:

    -module(tut17).
    +in full.)

    Here is the ping pong example modified to run on two separate nodes:

    -module(tut17).
     
    --export([start_ping/1, start_pong/0,  ping/2, pong/0]).
    +-export([start_ping/1, start_pong/0,  ping/2, pong/0]).
     
    -ping(0, Pong_Node) ->
    -    {pong, Pong_Node} ! finished,
    -    io:format("ping finished~n", []);
    +ping(0, Pong_Node) ->
    +    {pong, Pong_Node} ! finished,
    +    io:format("ping finished~n", []);
     
    -ping(N, Pong_Node) ->
    -    {pong, Pong_Node} ! {ping, self()},
    +ping(N, Pong_Node) ->
    +    {pong, Pong_Node} ! {ping, self()},
         receive
             pong ->
    -            io:format("Ping received pong~n", [])
    +            io:format("Ping received pong~n", [])
         end,
    -    ping(N - 1, Pong_Node).
    +    ping(N - 1, Pong_Node).
     
    -pong() ->
    +pong() ->
         receive
             finished ->
    -            io:format("Pong finished~n", []);
    -        {ping, Ping_PID} ->
    -            io:format("Pong received ping~n", []),
    +            io:format("Pong finished~n", []);
    +        {ping, Ping_PID} ->
    +            io:format("Pong received ping~n", []),
                 Ping_PID ! pong,
    -            pong()
    +            pong()
         end.
     
    -start_pong() ->
    -    register(pong, spawn(tut17, pong, [])).
    +start_pong() ->
    +    register(pong, spawn(tut17, pong, [])).
     
    -start_ping(Pong_Node) ->
    -    spawn(tut17, ping, [3, Pong_Node]).

    Let us assume there are two computers called gollum and kosken. First a node is +start_ping(Pong_Node) -> + spawn(tut17, ping, [3, Pong_Node]).

    Let us assume there are two computers called gollum and kosken. First a node is started on kosken, called ping, and then a node on gollum, called pong.

    On kosken (on a Linux/UNIX system):

    kosken> erl -sname ping
     Erlang (BEAM) emulator version 5.2.3.7 [hipe] [threads:0]
     
    @@ -393,10 +393,10 @@ 

    Erlang (BEAM) emulator version 5.2.3.7 [hipe] [threads:0] Eshell V5.2.3.7 (abort with ^G) -(pong@gollum)1>

    Now the "pong" process on gollum is started:

    (pong@gollum)1> tut17:start_pong().
    +(pong@gollum)1>

    Now the "pong" process on gollum is started:

    (pong@gollum)1> tut17:start_pong().
     true

    And the "ping" process on kosken is started (from the code above you can see that a parameter of the start_ping function is the node name of the Erlang -system where "pong" is running):

    (ping@kosken)1> tut17:start_ping(pong@gollum).
    +system where "pong" is running):

    (ping@kosken)1> tut17:start_ping(pong@gollum).
     <0.37.0>
     Ping received pong
     Ping received pong
    @@ -406,46 +406,46 @@ 

    Pong received ping Pong received ping Pong finished -(pong@gollum)2>

    Looking at the tut17 code, you see that the pong function itself is +(pong@gollum)2>

    Looking at the tut17 code, you see that the pong function itself is unchanged, the following lines work in the same way irrespective of on which -node the "ping" process is executes:

    {ping, Ping_PID} ->
    -    io:format("Pong received ping~n", []),
    +node the "ping" process is executes:

    {ping, Ping_PID} ->
    +    io:format("Pong received ping~n", []),
         Ping_PID ! pong,

    Thus, Erlang pids contain information about where the process executes. So if you know the pid of a process, the ! operator can be used to send it a -message disregarding if the process is on the same node or on a different node.

    A difference is how messages are sent to a registered process on another node:

    {pong, Pong_Node} ! {ping, self()},

    A tuple {registered_name,node_name} is used instead of just the +message disregarding if the process is on the same node or on a different node.

    A difference is how messages are sent to a registered process on another node:

    {pong, Pong_Node} ! {ping, self()},

    A tuple {registered_name,node_name} is used instead of just the registered_name.

    In the previous example, "ping" and "pong" were started from the shells of two separate Erlang nodes. spawn can also be used to start processes in other nodes.

    The next example is the ping pong program, yet again, but this time "ping" is -started in another node:

    -module(tut18).
    +started in another node:

    -module(tut18).
     
    --export([start/1,  ping/2, pong/0]).
    +-export([start/1,  ping/2, pong/0]).
     
    -ping(0, Pong_Node) ->
    -    {pong, Pong_Node} ! finished,
    -    io:format("ping finished~n", []);
    +ping(0, Pong_Node) ->
    +    {pong, Pong_Node} ! finished,
    +    io:format("ping finished~n", []);
     
    -ping(N, Pong_Node) ->
    -    {pong, Pong_Node} ! {ping, self()},
    +ping(N, Pong_Node) ->
    +    {pong, Pong_Node} ! {ping, self()},
         receive
             pong ->
    -            io:format("Ping received pong~n", [])
    +            io:format("Ping received pong~n", [])
         end,
    -    ping(N - 1, Pong_Node).
    +    ping(N - 1, Pong_Node).
     
    -pong() ->
    +pong() ->
         receive
             finished ->
    -            io:format("Pong finished~n", []);
    -        {ping, Ping_PID} ->
    -            io:format("Pong received ping~n", []),
    +            io:format("Pong finished~n", []);
    +        {ping, Ping_PID} ->
    +            io:format("Pong received ping~n", []),
                 Ping_PID ! pong,
    -            pong()
    +            pong()
         end.
     
    -start(Ping_Node) ->
    -    register(pong, spawn(tut18, pong, [])),
    -    spawn(Ping_Node, tut18, ping, [3, node()]).

    Assuming an Erlang system called ping (but not the "ping" process) has already -been started on kosken, then on gollum this is done:

    (pong@gollum)1> tut18:start(ping@kosken).
    +start(Ping_Node) ->
    +    register(pong, spawn(tut18, pong, [])),
    +    spawn(Ping_Node, tut18, ping, [3, node()]).

    Assuming an Erlang system called ping (but not the "ping" process) has already +been started on kosken, then on gollum this is done:

    (pong@gollum)1> tut18:start(ping@kosken).
     <3934.39.0>
     Pong received ping
     Ping received pong
    @@ -520,140 +520,140 @@ 

    %%% Configuration: change the server_node() function to return the %%% name of the node where the messenger server runs --module(messenger). --export([start_server/0, server/1, logon/1, logoff/0, message/2, client/2]). +-module(messenger). +-export([start_server/0, server/1, logon/1, logoff/0, message/2, client/2]). %%% Change the function below to return the name of the node where the %%% messenger server runs -server_node() -> +server_node() -> messenger@super. %%% This is the server process for the "messenger" %%% the user list has the format [{ClientPid1, Name1},{ClientPid22, Name2},...] -server(User_List) -> +server(User_List) -> receive - {From, logon, Name} -> - New_User_List = server_logon(From, Name, User_List), - server(New_User_List); - {From, logoff} -> - New_User_List = server_logoff(From, User_List), - server(New_User_List); - {From, message_to, To, Message} -> - server_transfer(From, To, Message, User_List), - io:format("list is now: ~p~n", [User_List]), - server(User_List) + {From, logon, Name} -> + New_User_List = server_logon(From, Name, User_List), + server(New_User_List); + {From, logoff} -> + New_User_List = server_logoff(From, User_List), + server(New_User_List); + {From, message_to, To, Message} -> + server_transfer(From, To, Message, User_List), + io:format("list is now: ~p~n", [User_List]), + server(User_List) end. %%% Start the server -start_server() -> - register(messenger, spawn(messenger, server, [[]])). +start_server() -> + register(messenger, spawn(messenger, server, [[]])). %%% Server adds a new user to the user list -server_logon(From, Name, User_List) -> +server_logon(From, Name, User_List) -> %% check if logged on anywhere else - case lists:keymember(Name, 2, User_List) of + case lists:keymember(Name, 2, User_List) of true -> - From ! {messenger, stop, user_exists_at_other_node}, %reject logon + From ! {messenger, stop, user_exists_at_other_node}, %reject logon User_List; false -> - From ! {messenger, logged_on}, - [{From, Name} | User_List] %add user to the list + From ! {messenger, logged_on}, + [{From, Name} | User_List] %add user to the list end. %%% Server deletes a user from the user list -server_logoff(From, User_List) -> - lists:keydelete(From, 1, User_List). +server_logoff(From, User_List) -> + lists:keydelete(From, 1, User_List). %%% Server transfers a message between user -server_transfer(From, To, Message, User_List) -> +server_transfer(From, To, Message, User_List) -> %% check that the user is logged on and who he is - case lists:keysearch(From, 1, User_List) of + case lists:keysearch(From, 1, User_List) of false -> - From ! {messenger, stop, you_are_not_logged_on}; - {value, {From, Name}} -> - server_transfer(From, Name, To, Message, User_List) + From ! {messenger, stop, you_are_not_logged_on}; + {value, {From, Name}} -> + server_transfer(From, Name, To, Message, User_List) end. %%% If the user exists, send the message -server_transfer(From, Name, To, Message, User_List) -> +server_transfer(From, Name, To, Message, User_List) -> %% Find the receiver and send the message - case lists:keysearch(To, 2, User_List) of + case lists:keysearch(To, 2, User_List) of false -> - From ! {messenger, receiver_not_found}; - {value, {ToPid, To}} -> - ToPid ! {message_from, Name, Message}, - From ! {messenger, sent} + From ! {messenger, receiver_not_found}; + {value, {ToPid, To}} -> + ToPid ! {message_from, Name, Message}, + From ! {messenger, sent} end. %%% User Commands -logon(Name) -> - case whereis(mess_client) of +logon(Name) -> + case whereis(mess_client) of undefined -> - register(mess_client, - spawn(messenger, client, [server_node(), Name])); + register(mess_client, + spawn(messenger, client, [server_node(), Name])); _ -> already_logged_on end. -logoff() -> +logoff() -> mess_client ! logoff. -message(ToName, Message) -> - case whereis(mess_client) of % Test if the client is running +message(ToName, Message) -> + case whereis(mess_client) of % Test if the client is running undefined -> not_logged_on; - _ -> mess_client ! {message_to, ToName, Message}, + _ -> mess_client ! {message_to, ToName, Message}, ok end. %%% The client process which runs on each server node -client(Server_Node, Name) -> - {messenger, Server_Node} ! {self(), logon, Name}, - await_result(), - client(Server_Node). +client(Server_Node, Name) -> + {messenger, Server_Node} ! {self(), logon, Name}, + await_result(), + client(Server_Node). -client(Server_Node) -> +client(Server_Node) -> receive logoff -> - {messenger, Server_Node} ! {self(), logoff}, - exit(normal); - {message_to, ToName, Message} -> - {messenger, Server_Node} ! {self(), message_to, ToName, Message}, - await_result(); - {message_from, FromName, Message} -> - io:format("Message from ~p: ~p~n", [FromName, Message]) + {messenger, Server_Node} ! {self(), logoff}, + exit(normal); + {message_to, ToName, Message} -> + {messenger, Server_Node} ! {self(), message_to, ToName, Message}, + await_result(); + {message_from, FromName, Message} -> + io:format("Message from ~p: ~p~n", [FromName, Message]) end, - client(Server_Node). + client(Server_Node). %%% wait for a response from the server -await_result() -> +await_result() -> receive - {messenger, stop, Why} -> % Stop the client - io:format("~p~n", [Why]), - exit(normal); - {messenger, What} -> % Normal response - io:format("~p~n", [What]) + {messenger, stop, Why} -> % Stop the client + io:format("~p~n", [Why]), + exit(normal); + {messenger, What} -> % Normal response + io:format("~p~n", [What]) end.

    To use this program, you need to:

    • Configure the server_node() function.
    • Copy the compiled code (messenger.beam) to the directory on each computer where you start Erlang.

    In the following example using this program, nodes are started on four different computers. If you do not have that many machines available on your network, you can start several nodes on the same machine.

    Four Erlang nodes are started up: messenger@super, c1@bilbo, c2@kosken, -c3@gollum.

    First the server at messenger@super is started up:

    (messenger@super)1> messenger:start_server().
    -true

    Now Peter logs on at c1@bilbo:

    (c1@bilbo)1> messenger:logon(peter).
    +c3@gollum.

    First the server at messenger@super is started up:

    (messenger@super)1> messenger:start_server().
    +true

    Now Peter logs on at c1@bilbo:

    (c1@bilbo)1> messenger:logon(peter).
     true
    -logged_on

    James logs on at c2@kosken:

    (c2@kosken)1> messenger:logon(james).
    +logged_on

    James logs on at c2@kosken:

    (c2@kosken)1> messenger:logon(james).
     true
    -logged_on

    And Fred logs on at c3@gollum:

    (c3@gollum)1> messenger:logon(fred).
    +logged_on

    And Fred logs on at c3@gollum:

    (c3@gollum)1> messenger:logon(fred).
     true
    -logged_on

    Now Peter sends Fred a message:

    (c1@bilbo)2> messenger:message(fred, "hello").
    +logged_on

    Now Peter sends Fred a message:

    (c1@bilbo)2> messenger:message(fred, "hello").
     ok
     sent

    Fred receives the message and sends a message to Peter and logs off:

    Message from peter: "hello"
    -(c3@gollum)2> messenger:message(peter, "go away, I'm busy").
    +(c3@gollum)2> messenger:message(peter, "go away, I'm busy").
     ok
     sent
    -(c3@gollum)3> messenger:logoff().
    -logoff

    James now tries to send a message to Fred:

    (c2@kosken)2> messenger:message(fred, "peter doesn't like you").
    +(c3@gollum)3> messenger:logoff().
    +logoff

    James now tries to send a message to Fred:

    (c2@kosken)2> messenger:message(fred, "peter doesn't like you").
     ok
     receiver_not_found

    But this fails as Fred has already logged off.

    First let us look at some of the new concepts that have been introduced.

    There are two versions of the server_transfer function: one with four arguments (server_transfer/4) and one with five (server_transfer/5). These @@ -667,12 +667,12 @@

    lists:keymember(Key,Position,Lists) looks through a list of tuples and looks at Position in each tuple to see if it is the same as Key. The first element is position 1. If it finds a tuple where the element at Position is the same -as Key, it returns true, otherwise false.

    3> lists:keymember(a, 2, [{x,y,z},{b,b,b},{b,a,c},{q,r,s}]).
    +as Key, it returns true, otherwise false.

    3> lists:keymember(a, 2, [{x,y,z},{b,b,b},{b,a,c},{q,r,s}]).
     true
    -4> lists:keymember(p, 2, [{x,y,z},{b,b,b},{b,a,c},{q,r,s}]).
    +4> lists:keymember(p, 2, [{x,y,z},{b,b,b},{b,a,c},{q,r,s}]).
     false

    lists:keydelete works in the same way but deletes the first tuple found (if -any) and returns the remaining list:

    5> lists:keydelete(a, 2, [{x,y,z},{b,b,b},{b,a,c},{q,r,s}]).
    -[{x,y,z},{b,b,b},{q,r,s}]

    lists:keysearch is like lists:keymember, but it returns +any) and returns the remaining list:

    5> lists:keydelete(a, 2, [{x,y,z},{b,b,b},{b,a,c},{q,r,s}]).
    +[{x,y,z},{b,b,b},{q,r,s}]

    lists:keysearch is like lists:keymember, but it returns {value,Tuple_Found} or the atom false.

    There are many very useful functions in the lists module.

    An Erlang process (conceptually) runs until it does a receive and there is no message which it wants to receive in the message queue. "conceptually" is used here because the Erlang system shares the CPU time between the active processes @@ -685,15 +685,15 @@

    of name RegisteredName exists. If it exists, the pid of that process is returned. If it does not exist, the atom undefined is returned.

    You should by now be able to understand most of the code in the messenger-module. Let us study one case in detail: a message is sent from one -user to another.

    The first user "sends" the message in the example above by:

    messenger:message(fred, "hello")

    After testing that the client process exists:

    whereis(mess_client)

    And a message is sent to mess_client:

    mess_client ! {message_to, fred, "hello"}

    The client sends the message to the server by:

    {messenger, messenger@super} ! {self(), message_to, fred, "hello"},

    And waits for a reply from the server.

    The server receives this message and calls:

    server_transfer(From, fred, "hello", User_List),

    This checks that the pid From is in the User_List:

    lists:keysearch(From, 1, User_List)

    If keysearch returns the atom false, some error has occurred and the server -sends back the message:

    From ! {messenger, stop, you_are_not_logged_on}

    This is received by the client, which in turn does exit(normal) +user to another.

    The first user "sends" the message in the example above by:

    messenger:message(fred, "hello")

    After testing that the client process exists:

    whereis(mess_client)

    And a message is sent to mess_client:

    mess_client ! {message_to, fred, "hello"}

    The client sends the message to the server by:

    {messenger, messenger@super} ! {self(), message_to, fred, "hello"},

    And waits for a reply from the server.

    The server receives this message and calls:

    server_transfer(From, fred, "hello", User_List),

    This checks that the pid From is in the User_List:

    lists:keysearch(From, 1, User_List)

    If keysearch returns the atom false, some error has occurred and the server +sends back the message:

    From ! {messenger, stop, you_are_not_logged_on}

    This is received by the client, which in turn does exit(normal) and terminates. If keysearch returns {value,{From,Name}} it is certain that -the user is logged on and that his name (peter) is in variable Name.

    Let us now call:

    server_transfer(From, peter, fred, "hello", User_List)

    Notice that as this is server_transfer/5, it is not the same as the previous +the user is logged on and that his name (peter) is in variable Name.

    Let us now call:

    server_transfer(From, peter, fred, "hello", User_List)

    Notice that as this is server_transfer/5, it is not the same as the previous function server_transfer/4. Another keysearch is done on User_List to find -the pid of the client corresponding to fred:

    lists:keysearch(fred, 2, User_List)

    This time argument 2 is used, which is the second element in the tuple. If this +the pid of the client corresponding to fred:

    lists:keysearch(fred, 2, User_List)

    This time argument 2 is used, which is the second element in the tuple. If this returns the atom false, fred is not logged on and the following message is -sent:

    From ! {messenger, receiver_not_found};

    This is received by the client.

    If keysearch returns:

    {value, {ToPid, fred}}

    The following message is sent to fred's client:

    ToPid ! {message_from, peter, "hello"},

    The following message is sent to peter's client:

    From ! {messenger, sent}

    Fred's client receives the message and prints it:

    {message_from, peter, "hello"} ->
    -    io:format("Message from ~p: ~p~n", [peter, "hello"])

    Peter's client receives the message in the await_result function.

    +sent:

    From ! {messenger, receiver_not_found};

    This is received by the client.

    If keysearch returns:

    {value, {ToPid, fred}}

    The following message is sent to fred's client:

    ToPid ! {message_from, peter, "hello"},

    The following message is sent to peter's client:

    From ! {messenger, sent}

    Fred's client receives the message and prints it:

    {message_from, peter, "hello"} ->
    +    io:format("Message from ~p: ~p~n", [peter, "hello"])

    Peter's client receives the message in the await_result function.

    diff --git a/prs/8803/doc/system/create_target.html b/prs/8803/doc/system/create_target.html index 50f6a38bd6a29..bf76a424aa6b4 100644 --- a/prs/8803/doc/system/create_target.html +++ b/prs/8803/doc/system/create_target.html @@ -142,13 +142,13 @@

    SASL), which specifies the ERTS version and lists all applications that are to be included in the new basic target system. An example is the following mysystem.rel file:

    %% mysystem.rel
    -{release,
    - {"MYSYSTEM", "FIRST"},
    - {erts, "5.10.4"},
    - [{kernel, "2.16.4"},
    -  {stdlib, "1.19.4"},
    -  {sasl, "2.3.4"},
    -  {pea, "1.0"}]}.

    The listed applications are not only original Erlang/OTP applications but +{release, + {"MYSYSTEM", "FIRST"}, + {erts, "5.10.4"}, + [{kernel, "2.16.4"}, + {stdlib, "1.19.4"}, + {sasl, "2.3.4"}, + {pea, "1.0"}]}.

    The listed applications are not only original Erlang/OTP applications but possibly also new applications that you have written (here exemplified by the application Pea (pea)).

    Step 2. Start Erlang/OTP from the directory where the mysystem.rel file resides:

    % erl -pa /home/user/target_system/myapps/pea-1.0/ebin

    The -pa argument prepends the path to the ebin directory for @@ -246,17 +246,17 @@

    In this example the Pea application has been changed, and so are the applications ERTS, Kernel, STDLIB and SASL.

    Step 1. Create the file .rel:

    %% mysystem2.rel
    -{release,
    - {"MYSYSTEM", "SECOND"},
    - {erts, "6.0"},
    - [{kernel, "3.0"},
    -  {stdlib, "2.0"},
    -  {sasl, "2.4"},
    -  {pea, "2.0"}]}.

    Step 2. Create the application upgrade file (see +{release, + {"MYSYSTEM", "SECOND"}, + {erts, "6.0"}, + [{kernel, "3.0"}, + {stdlib, "2.0"}, + {sasl, "2.4"}, + {pea, "2.0"}]}.

    Step 2. Create the application upgrade file (see appup in SASL) for Pea, for example:

    %% pea.appup
    -{"2.0",
    - [{"1.0",[{load_module,pea_lib}]}],
    - [{"1.0",[{load_module,pea_lib}]}]}.

    Step 3. From the directory where the file mysystem2.rel resides, start the +{"2.0", + [{"1.0",[{load_module,pea_lib}]}], + [{"1.0",[{load_module,pea_lib}]}]}.

    Step 3. From the directory where the file mysystem2.rel resides, start the Erlang/OTP system, giving the path to the new version of Pea:

    % erl -pa /home/user/target_system/myapps/pea-2.0/ebin

    Step 4. Create the release upgrade file (see relup in SASL):

    1> systools:make_relup("mysystem2",["mysystem"],["mysystem"],
         [{path,["/home/user/target_system/myapps/pea-1.0/ebin",
    @@ -296,21 +296,21 @@ 

    release_handler:install_release/1 means that the release_handler has restarted the node by using heart. This is always done when the upgrade involves a change of the applications ERTS, Kernel, STDLIB, or SASL. For more -information, see Upgrade when Erlang/OTP has Changed.

    The node is accessible through a new pipe:

    % /usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.2

    List the available releases in the system:

    1> release_handler:which_releases().
    -[{"MYSYSTEM","SECOND",
    -  ["kernel-3.0","stdlib-2.0","sasl-2.4","pea-2.0"],
    -  current},
    - {"MYSYSTEM","FIRST",
    -  ["kernel-2.16.4","stdlib-1.19.4","sasl-2.3.4","pea-1.0"],
    -  permanent}]

    Our new release, "SECOND", is now the current release, but we can also see that +information, see Upgrade when Erlang/OTP has Changed.

    The node is accessible through a new pipe:

    % /usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.2

    List the available releases in the system:

    1> release_handler:which_releases().
    +[{"MYSYSTEM","SECOND",
    +  ["kernel-3.0","stdlib-2.0","sasl-2.4","pea-2.0"],
    +  current},
    + {"MYSYSTEM","FIRST",
    +  ["kernel-2.16.4","stdlib-1.19.4","sasl-2.3.4","pea-1.0"],
    +  permanent}]

    Our new release, "SECOND", is now the current release, but we can also see that our "FIRST" release is still permanent. This means that if the node would be -restarted now, it would come up running the "FIRST" release again.

    Step 3. Make the new release permanent:

    2> release_handler:make_permanent("SECOND").

    Check the releases again:

    3> release_handler:which_releases().
    -[{"MYSYSTEM","SECOND",
    -  ["kernel-3.0","stdlib-2.0","sasl-2.4","pea-2.0"],
    -  permanent},
    - {"MYSYSTEM","FIRST",
    -  ["kernel-2.16.4","stdlib-1.19.4","sasl-2.3.4","pea-1.0"],
    -  old}]

    We see that the new release version is permanent, so it would be safe to +restarted now, it would come up running the "FIRST" release again.

    Step 3. Make the new release permanent:

    2> release_handler:make_permanent("SECOND").

    Check the releases again:

    3> release_handler:which_releases().
    +[{"MYSYSTEM","SECOND",
    +  ["kernel-3.0","stdlib-2.0","sasl-2.4","pea-2.0"],
    +  permanent},
    + {"MYSYSTEM","FIRST",
    +  ["kernel-2.16.4","stdlib-1.19.4","sasl-2.3.4","pea-1.0"],
    +  old}]

    We see that the new release version is permanent, so it would be safe to restart the node.

    @@ -319,8 +319,8 @@

    This module can also be found in the examples directory of the SASL application.

    
    --module(target_system).
    --export([create/1, create/2, install/2]).
    +-module(target_system).
    +-export([create/1, create/2, install/2]).
     
     %% Note: RelFileName below is the *stem* without trailing .rel,
     %% .script etc.
    @@ -328,176 +328,176 @@ 

    %% create(RelFileName) %% -create(RelFileName) -> - create(RelFileName,[]). +create(RelFileName) -> + create(RelFileName,[]). -create(RelFileName,SystoolsOpts) -> +create(RelFileName,SystoolsOpts) -> RelFile = RelFileName ++ ".rel", - Dir = filename:dirname(RelFileName), - PlainRelFileName = filename:join(Dir,"plain"), + Dir = filename:dirname(RelFileName), + PlainRelFileName = filename:join(Dir,"plain"), PlainRelFile = PlainRelFileName ++ ".rel", - io:fwrite("Reading file: ~ts ...~n", [RelFile]), - {ok, [RelSpec]} = file:consult(RelFile), - io:fwrite("Creating file: ~ts from ~ts ...~n", - [PlainRelFile, RelFile]), - {release, - {RelName, RelVsn}, - {erts, ErtsVsn}, - AppVsns} = RelSpec, - PlainRelSpec = {release, - {RelName, RelVsn}, - {erts, ErtsVsn}, - lists:filter(fun({kernel, _}) -> + io:fwrite("Reading file: ~ts ...~n", [RelFile]), + {ok, [RelSpec]} = file:consult(RelFile), + io:fwrite("Creating file: ~ts from ~ts ...~n", + [PlainRelFile, RelFile]), + {release, + {RelName, RelVsn}, + {erts, ErtsVsn}, + AppVsns} = RelSpec, + PlainRelSpec = {release, + {RelName, RelVsn}, + {erts, ErtsVsn}, + lists:filter(fun({kernel, _}) -> true; - ({stdlib, _}) -> + ({stdlib, _}) -> true; - (_) -> + (_) -> false - end, AppVsns) - }, - {ok, Fd} = file:open(PlainRelFile, [write]), - io:fwrite(Fd, "~p.~n", [PlainRelSpec]), - file:close(Fd), + end, AppVsns) + }, + {ok, Fd} = file:open(PlainRelFile, [write]), + io:fwrite(Fd, "~p.~n", [PlainRelSpec]), + file:close(Fd), - io:fwrite("Making \"~ts.script\" and \"~ts.boot\" files ...~n", - [PlainRelFileName,PlainRelFileName]), - make_script(PlainRelFileName,SystoolsOpts), + io:fwrite("Making \"~ts.script\" and \"~ts.boot\" files ...~n", + [PlainRelFileName,PlainRelFileName]), + make_script(PlainRelFileName,SystoolsOpts), - io:fwrite("Making \"~ts.script\" and \"~ts.boot\" files ...~n", - [RelFileName, RelFileName]), - make_script(RelFileName,SystoolsOpts), + io:fwrite("Making \"~ts.script\" and \"~ts.boot\" files ...~n", + [RelFileName, RelFileName]), + make_script(RelFileName,SystoolsOpts), TarFileName = RelFileName ++ ".tar.gz", - io:fwrite("Creating tar file ~ts ...~n", [TarFileName]), - make_tar(RelFileName,SystoolsOpts), + io:fwrite("Creating tar file ~ts ...~n", [TarFileName]), + make_tar(RelFileName,SystoolsOpts), - TmpDir = filename:join(Dir,"tmp"), - io:fwrite("Creating directory ~tp ...~n",[TmpDir]), - file:make_dir(TmpDir), + TmpDir = filename:join(Dir,"tmp"), + io:fwrite("Creating directory ~tp ...~n",[TmpDir]), + file:make_dir(TmpDir), - io:fwrite("Extracting ~ts into directory ~ts ...~n", [TarFileName,TmpDir]), - extract_tar(TarFileName, TmpDir), + io:fwrite("Extracting ~ts into directory ~ts ...~n", [TarFileName,TmpDir]), + extract_tar(TarFileName, TmpDir), - TmpBinDir = filename:join([TmpDir, "bin"]), - ErtsBinDir = filename:join([TmpDir, "erts-" ++ ErtsVsn, "bin"]), - io:fwrite("Deleting \"erl\" and \"start\" in directory ~ts ...~n", - [ErtsBinDir]), - file:delete(filename:join([ErtsBinDir, "erl"])), - file:delete(filename:join([ErtsBinDir, "start"])), + TmpBinDir = filename:join([TmpDir, "bin"]), + ErtsBinDir = filename:join([TmpDir, "erts-" ++ ErtsVsn, "bin"]), + io:fwrite("Deleting \"erl\" and \"start\" in directory ~ts ...~n", + [ErtsBinDir]), + file:delete(filename:join([ErtsBinDir, "erl"])), + file:delete(filename:join([ErtsBinDir, "start"])), - io:fwrite("Creating temporary directory ~ts ...~n", [TmpBinDir]), - file:make_dir(TmpBinDir), + io:fwrite("Creating temporary directory ~ts ...~n", [TmpBinDir]), + file:make_dir(TmpBinDir), - io:fwrite("Copying file \"~ts.boot\" to ~ts ...~n", - [PlainRelFileName, filename:join([TmpBinDir, "start.boot"])]), - copy_file(PlainRelFileName++".boot",filename:join([TmpBinDir, "start.boot"])), + io:fwrite("Copying file \"~ts.boot\" to ~ts ...~n", + [PlainRelFileName, filename:join([TmpBinDir, "start.boot"])]), + copy_file(PlainRelFileName++".boot",filename:join([TmpBinDir, "start.boot"])), - io:fwrite("Copying files \"epmd\", \"run_erl\" and \"to_erl\" from \n" + io:fwrite("Copying files \"epmd\", \"run_erl\" and \"to_erl\" from \n" "~ts to ~ts ...~n", - [ErtsBinDir, TmpBinDir]), - copy_file(filename:join([ErtsBinDir, "epmd"]), - filename:join([TmpBinDir, "epmd"]), [preserve]), - copy_file(filename:join([ErtsBinDir, "run_erl"]), - filename:join([TmpBinDir, "run_erl"]), [preserve]), - copy_file(filename:join([ErtsBinDir, "to_erl"]), - filename:join([TmpBinDir, "to_erl"]), [preserve]), + [ErtsBinDir, TmpBinDir]), + copy_file(filename:join([ErtsBinDir, "epmd"]), + filename:join([TmpBinDir, "epmd"]), [preserve]), + copy_file(filename:join([ErtsBinDir, "run_erl"]), + filename:join([TmpBinDir, "run_erl"]), [preserve]), + copy_file(filename:join([ErtsBinDir, "to_erl"]), + filename:join([TmpBinDir, "to_erl"]), [preserve]), %% This is needed if 'start' script created from 'start.src' shall %% be used as it points out this directory as log dir for 'run_erl' - TmpLogDir = filename:join([TmpDir, "log"]), - io:fwrite("Creating temporary directory ~ts ...~n", [TmpLogDir]), - ok = file:make_dir(TmpLogDir), - - StartErlDataFile = filename:join([TmpDir, "releases", "start_erl.data"]), - io:fwrite("Creating ~ts ...~n", [StartErlDataFile]), - StartErlData = io_lib:fwrite("~s ~s~n", [ErtsVsn, RelVsn]), - write_file(StartErlDataFile, StartErlData), - - io:fwrite("Recreating tar file ~ts from contents in directory ~ts ...~n", - [TarFileName,TmpDir]), - {ok, Tar} = erl_tar:open(TarFileName, [write, compressed]), + TmpLogDir = filename:join([TmpDir, "log"]), + io:fwrite("Creating temporary directory ~ts ...~n", [TmpLogDir]), + ok = file:make_dir(TmpLogDir), + + StartErlDataFile = filename:join([TmpDir, "releases", "start_erl.data"]), + io:fwrite("Creating ~ts ...~n", [StartErlDataFile]), + StartErlData = io_lib:fwrite("~s ~s~n", [ErtsVsn, RelVsn]), + write_file(StartErlDataFile, StartErlData), + + io:fwrite("Recreating tar file ~ts from contents in directory ~ts ...~n", + [TarFileName,TmpDir]), + {ok, Tar} = erl_tar:open(TarFileName, [write, compressed]), %% {ok, Cwd} = file:get_cwd(), %% file:set_cwd("tmp"), ErtsDir = "erts-"++ErtsVsn, - erl_tar:add(Tar, filename:join(TmpDir,"bin"), "bin", []), - erl_tar:add(Tar, filename:join(TmpDir,ErtsDir), ErtsDir, []), - erl_tar:add(Tar, filename:join(TmpDir,"releases"), "releases", []), - erl_tar:add(Tar, filename:join(TmpDir,"lib"), "lib", []), - erl_tar:add(Tar, filename:join(TmpDir,"log"), "log", []), - erl_tar:close(Tar), + erl_tar:add(Tar, filename:join(TmpDir,"bin"), "bin", []), + erl_tar:add(Tar, filename:join(TmpDir,ErtsDir), ErtsDir, []), + erl_tar:add(Tar, filename:join(TmpDir,"releases"), "releases", []), + erl_tar:add(Tar, filename:join(TmpDir,"lib"), "lib", []), + erl_tar:add(Tar, filename:join(TmpDir,"log"), "log", []), + erl_tar:close(Tar), %% file:set_cwd(Cwd), - io:fwrite("Removing directory ~ts ...~n",[TmpDir]), - remove_dir_tree(TmpDir), + io:fwrite("Removing directory ~ts ...~n",[TmpDir]), + remove_dir_tree(TmpDir), ok. -install(RelFileName, RootDir) -> +install(RelFileName, RootDir) -> TarFile = RelFileName ++ ".tar.gz", - io:fwrite("Extracting ~ts ...~n", [TarFile]), - extract_tar(TarFile, RootDir), - StartErlDataFile = filename:join([RootDir, "releases", "start_erl.data"]), - {ok, StartErlData} = read_txt_file(StartErlDataFile), - [ErlVsn, _RelVsn| _] = string:tokens(StartErlData, " \n"), - ErtsBinDir = filename:join([RootDir, "erts-" ++ ErlVsn, "bin"]), - BinDir = filename:join([RootDir, "bin"]), - io:fwrite("Substituting in erl.src, start.src and start_erl.src to " - "form erl, start and start_erl ...\n"), - subst_src_scripts(["erl", "start", "start_erl"], ErtsBinDir, BinDir, - [{"FINAL_ROOTDIR", RootDir}, {"EMU", "beam"}], - [preserve]), + io:fwrite("Extracting ~ts ...~n", [TarFile]), + extract_tar(TarFile, RootDir), + StartErlDataFile = filename:join([RootDir, "releases", "start_erl.data"]), + {ok, StartErlData} = read_txt_file(StartErlDataFile), + [ErlVsn, _RelVsn| _] = string:tokens(StartErlData, " \n"), + ErtsBinDir = filename:join([RootDir, "erts-" ++ ErlVsn, "bin"]), + BinDir = filename:join([RootDir, "bin"]), + io:fwrite("Substituting in erl.src, start.src and start_erl.src to " + "form erl, start and start_erl ...\n"), + subst_src_scripts(["erl", "start", "start_erl"], ErtsBinDir, BinDir, + [{"FINAL_ROOTDIR", RootDir}, {"EMU", "beam"}], + [preserve]), %%! Workaround for pre OTP 17.0: start.src and start_erl.src did %%! not have correct permissions, so the above 'preserve' option did not help - ok = file:change_mode(filename:join(BinDir,"start"),8#0755), - ok = file:change_mode(filename:join(BinDir,"start_erl"),8#0755), + ok = file:change_mode(filename:join(BinDir,"start"),8#0755), + ok = file:change_mode(filename:join(BinDir,"start_erl"),8#0755), - io:fwrite("Creating the RELEASES file ...\n"), - create_RELEASES(RootDir, filename:join([RootDir, "releases", - filename:basename(RelFileName)])). + io:fwrite("Creating the RELEASES file ...\n"), + create_RELEASES(RootDir, filename:join([RootDir, "releases", + filename:basename(RelFileName)])). %% LOCALS %% make_script(RelFileName,Opts) %% -make_script(RelFileName,Opts) -> - systools:make_script(RelFileName, [no_module_tests, - {outdir,filename:dirname(RelFileName)} - |Opts]). +make_script(RelFileName,Opts) -> + systools:make_script(RelFileName, [no_module_tests, + {outdir,filename:dirname(RelFileName)} + |Opts]). %% make_tar(RelFileName,Opts) %% -make_tar(RelFileName,Opts) -> - RootDir = code:root_dir(), - systools:make_tar(RelFileName, [{erts, RootDir}, - {outdir,filename:dirname(RelFileName)} - |Opts]). +make_tar(RelFileName,Opts) -> + RootDir = code:root_dir(), + systools:make_tar(RelFileName, [{erts, RootDir}, + {outdir,filename:dirname(RelFileName)} + |Opts]). %% extract_tar(TarFile, DestDir) %% -extract_tar(TarFile, DestDir) -> - erl_tar:extract(TarFile, [{cwd, DestDir}, compressed]). - -create_RELEASES(DestDir, RelFileName) -> - release_handler:create_RELEASES(DestDir, RelFileName ++ ".rel"). - -subst_src_scripts(Scripts, SrcDir, DestDir, Vars, Opts) -> - lists:foreach(fun(Script) -> - subst_src_script(Script, SrcDir, DestDir, - Vars, Opts) - end, Scripts). - -subst_src_script(Script, SrcDir, DestDir, Vars, Opts) -> - subst_file(filename:join([SrcDir, Script ++ ".src"]), - filename:join([DestDir, Script]), - Vars, Opts). - -subst_file(Src, Dest, Vars, Opts) -> - {ok, Conts} = read_txt_file(Src), - NConts = subst(Conts, Vars), - write_file(Dest, NConts), - case lists:member(preserve, Opts) of +extract_tar(TarFile, DestDir) -> + erl_tar:extract(TarFile, [{cwd, DestDir}, compressed]). + +create_RELEASES(DestDir, RelFileName) -> + release_handler:create_RELEASES(DestDir, RelFileName ++ ".rel"). + +subst_src_scripts(Scripts, SrcDir, DestDir, Vars, Opts) -> + lists:foreach(fun(Script) -> + subst_src_script(Script, SrcDir, DestDir, + Vars, Opts) + end, Scripts). + +subst_src_script(Script, SrcDir, DestDir, Vars, Opts) -> + subst_file(filename:join([SrcDir, Script ++ ".src"]), + filename:join([DestDir, Script]), + Vars, Opts). + +subst_file(Src, Dest, Vars, Opts) -> + {ok, Conts} = read_txt_file(Src), + NConts = subst(Conts, Vars), + write_file(Dest, NConts), + case lists:member(preserve, Opts) of true -> - {ok, FileInfo} = file:read_file_info(Src), - file:write_file_info(Dest, FileInfo); + {ok, FileInfo} = file:read_file_info(Src), + file:write_file_info(Dest, FileInfo); false -> ok end. @@ -508,71 +508,71 @@

    %% Substitute all occurrences of %Var% for Val in Str, using the list %% of variables in Vars. %% -subst(Str, Vars) -> - subst(Str, Vars, []). - -subst([$%, C| Rest], Vars, Result) when $A =< C, C =< $Z -> - subst_var([C| Rest], Vars, Result, []); -subst([$%, C| Rest], Vars, Result) when $a =< C, C =< $z -> - subst_var([C| Rest], Vars, Result, []); -subst([$%, C| Rest], Vars, Result) when C == $_ -> - subst_var([C| Rest], Vars, Result, []); -subst([C| Rest], Vars, Result) -> - subst(Rest, Vars, [C| Result]); -subst([], _Vars, Result) -> - lists:reverse(Result). - -subst_var([$%| Rest], Vars, Result, VarAcc) -> - Key = lists:reverse(VarAcc), - case lists:keysearch(Key, 1, Vars) of - {value, {Key, Value}} -> - subst(Rest, Vars, lists:reverse(Value, Result)); +subst(Str, Vars) -> + subst(Str, Vars, []). + +subst([$%, C| Rest], Vars, Result) when $A =< C, C =< $Z -> + subst_var([C| Rest], Vars, Result, []); +subst([$%, C| Rest], Vars, Result) when $a =< C, C =< $z -> + subst_var([C| Rest], Vars, Result, []); +subst([$%, C| Rest], Vars, Result) when C == $_ -> + subst_var([C| Rest], Vars, Result, []); +subst([C| Rest], Vars, Result) -> + subst(Rest, Vars, [C| Result]); +subst([], _Vars, Result) -> + lists:reverse(Result). + +subst_var([$%| Rest], Vars, Result, VarAcc) -> + Key = lists:reverse(VarAcc), + case lists:keysearch(Key, 1, Vars) of + {value, {Key, Value}} -> + subst(Rest, Vars, lists:reverse(Value, Result)); false -> - subst(Rest, Vars, [$%| VarAcc ++ [$%| Result]]) + subst(Rest, Vars, [$%| VarAcc ++ [$%| Result]]) end; -subst_var([C| Rest], Vars, Result, VarAcc) -> - subst_var(Rest, Vars, Result, [C| VarAcc]); -subst_var([], Vars, Result, VarAcc) -> - subst([], Vars, [VarAcc ++ [$%| Result]]). +subst_var([C| Rest], Vars, Result, VarAcc) -> + subst_var(Rest, Vars, Result, [C| VarAcc]); +subst_var([], Vars, Result, VarAcc) -> + subst([], Vars, [VarAcc ++ [$%| Result]]). -copy_file(Src, Dest) -> - copy_file(Src, Dest, []). +copy_file(Src, Dest) -> + copy_file(Src, Dest, []). -copy_file(Src, Dest, Opts) -> - {ok,_} = file:copy(Src, Dest), - case lists:member(preserve, Opts) of +copy_file(Src, Dest, Opts) -> + {ok,_} = file:copy(Src, Dest), + case lists:member(preserve, Opts) of true -> - {ok, FileInfo} = file:read_file_info(Src), - file:write_file_info(Dest, FileInfo); + {ok, FileInfo} = file:read_file_info(Src), + file:write_file_info(Dest, FileInfo); false -> ok end. -write_file(FName, Conts) -> - Enc = file:native_name_encoding(), - {ok, Fd} = file:open(FName, [write]), - file:write(Fd, unicode:characters_to_binary(Conts,Enc,Enc)), - file:close(Fd). +write_file(FName, Conts) -> + Enc = file:native_name_encoding(), + {ok, Fd} = file:open(FName, [write]), + file:write(Fd, unicode:characters_to_binary(Conts,Enc,Enc)), + file:close(Fd). -read_txt_file(File) -> - {ok, Bin} = file:read_file(File), - {ok, binary_to_list(Bin)}. +read_txt_file(File) -> + {ok, Bin} = file:read_file(File), + {ok, binary_to_list(Bin)}. -remove_dir_tree(Dir) -> - remove_all_files(".", [Dir]). +remove_dir_tree(Dir) -> + remove_all_files(".", [Dir]). -remove_all_files(Dir, Files) -> - lists:foreach(fun(File) -> - FilePath = filename:join([Dir, File]), - case filelib:is_dir(FilePath) of +remove_all_files(Dir, Files) -> + lists:foreach(fun(File) -> + FilePath = filename:join([Dir, File]), + case filelib:is_dir(FilePath) of true -> - {ok, DirFiles} = file:list_dir(FilePath), - remove_all_files(FilePath, DirFiles), - file:del_dir(FilePath); + {ok, DirFiles} = file:list_dir(FilePath), + remove_all_files(FilePath, DirFiles), + file:del_dir(FilePath); _ -> - file:delete(FilePath) + file:delete(FilePath) end - end, Files).

    + end, Files).

    diff --git a/prs/8803/doc/system/data_types.html b/prs/8803/doc/system/data_types.html index cb970dc4c74df..5ee04d05101ae 100644 --- a/prs/8803/doc/system/data_types.html +++ b/prs/8803/doc/system/data_types.html @@ -196,10 +196,10 @@

    arithmetic operations. This is because floats are represented by a fixed number of bits in a base-2 system while printed floats are represented with a base-10 system. Erlang uses 64-bit floats. Here are examples of this phenomenon:

    1> 0.1+0.2.
    -0.30000000000000004

    The real numbers 0.1 and 0.2 cannot be represented exactly as floats.

    1> {36028797018963968.0, 36028797018963968 == 36028797018963968.0,
    -  36028797018963970.0, 36028797018963970 == 36028797018963970.0}.
    -{3.602879701896397e16, true,
    - 3.602879701896397e16, false}.

    The value 36028797018963968 can be represented exactly as a float value but +0.30000000000000004

    The real numbers 0.1 and 0.2 cannot be represented exactly as floats.

    1> {36028797018963968.0, 36028797018963968 == 36028797018963968.0,
    +  36028797018963970.0, 36028797018963970 == 36028797018963970.0}.
    +{3.602879701896397e16, true,
    + 3.602879701896397e16, false}.

    The value 36028797018963968 can be represented exactly as a float value but Erlang's pretty printer rounds 36028797018963968.0 to 3.602879701896397e16 (=36028797018963970.0) as all values in the range [36028797018963966.0, 36028797018963972.0] are represented by @@ -241,11 +241,11 @@

    3> <<1:1,0:1>>. <<2:2>>

    The is_bitstring/1 BIF tests whether a term is a bit string, and the is_binary/1 -BIF tests whether a term is a binary.

    Examples:

    1> is_bitstring(<<1:1>>).
    +BIF tests whether a term is a binary.

    Examples:

    1> is_bitstring(<<1:1>>).
     true
    -2> is_binary(<<1:1>>).
    +2> is_binary(<<1:1>>).
     false
    -3> is_binary(<<42>>).
    +3> is_binary(<<42>>).
     true
     

    For more examples, see Programming Examples.

    @@ -257,9 +257,9 @@

    among connected nodes. A reference is created by calling the make_ref/0 BIF. The is_reference/1 BIF tests whether a term -is a reference.

    Examples:

    1> Ref = make_ref().
    +is a reference.

    Examples:

    1> Ref = make_ref().
     #Ref<0.76482849.3801088007.198204>
    -2> is_reference(Ref).
    +2> is_reference(Ref).
     true

    @@ -268,17 +268,17 @@

    A fun is a functional object. Funs make it possible to create an anonymous function and pass the function itself — not its name — as argument to other -functions.

    Examples:

    1> Fun1 = fun (X) -> X+1 end.
    +functions.

    Examples:

    1> Fun1 = fun (X) -> X+1 end.
     #Fun<erl_eval.6.39074546>
    -2> Fun1(2).
    +2> Fun1(2).
     3

    The is_function/1 and is_function/2 -BIFs tests whether a term is a fun.

    Examples:

    1> F = fun() -> ok end.
    +BIFs tests whether a term is a fun.

    Examples:

    1> F = fun() -> ok end.
     #Fun<erl_eval.43.105768164>
    -2> is_function(F).
    +2> is_function(F).
     true
    -3> is_function(F, 0).
    +3> is_function(F, 0).
     true
    -4> is_function(F, 1).
    +4> is_function(F, 1).
     false

    Read more about funs in Fun Expressions. For more examples, see Programming Examples.

    @@ -304,17 +304,17 @@

    a message, which is the case when calling the spawn_request/5 BIF. A Pid is typically used when when sending a process a signal. The -is_pid/1 BIF tests whether a term is a Pid.

    Example:

    -module(m).
    --export([loop/0]).
    +is_pid/1 BIF tests whether a term is a Pid.

    Example:

    -module(m).
    +-export([loop/0]).
     
    -loop() ->
    +loop() ->
         receive
             who_are_you ->
    -            io:format("I am ~p~n", [self()]),
    -            loop()
    +            io:format("I am ~p~n", [self()]),
    +            loop()
         end.
     
    -1> P = spawn(m, loop, []).
    +1> P = spawn(m, loop, []).
     <0.58.0>
     2> P ! who_are_you.
     I am <0.58.0>
    @@ -325,19 +325,19 @@ 

    Tuple

    A tuple is a compound data type with a fixed number of terms:

    {Term1,...,TermN}

    Each term Term in the tuple is called an element. The number of elements is -said to be the size of the tuple.

    There exists a number of BIFs to manipulate tuples.

    Examples:

    1> P = {adam,24,{july,29}}.
    -{adam,24,{july,29}}
    -2> element(1,P).
    +said to be the size of the tuple.

    There exists a number of BIFs to manipulate tuples.

    Examples:

    1> P = {adam,24,{july,29}}.
    +{adam,24,{july,29}}
    +2> element(1,P).
     adam
    -3> element(3,P).
    -{july,29}
    -4> P2 = setelement(2,P,25).
    -{adam,25,{july,29}}
    -5> tuple_size(P).
    +3> element(3,P).
    +{july,29}
    +4> P2 = setelement(2,P,25).
    +{adam,25,{july,29}}
    +5> tuple_size(P).
     3
    -6> tuple_size({}).
    +6> tuple_size({}).
     0
    -7> is_tuple({a,b,c}).
    +7> is_tuple({a,b,c}).
     true

    @@ -346,17 +346,17 @@

    A map is a compound data type with a variable number of key-value associations:

    #{Key1 => Value1, ..., KeyN => ValueN}

    Each key-value association in the map is called an association pair. The key and value parts of the pair are called elements. The number of association -pairs is said to be the size of the map.

    There exists a number of BIFs to manipulate maps.

    Examples:

    1> M1 = #{name => adam, age => 24, date => {july,29}}.
    -#{age => 24,date => {july,29},name => adam}
    -2> maps:get(name, M1).
    +pairs is said to be the size of the map.

    There exists a number of BIFs to manipulate maps.

    Examples:

    1> M1 = #{name => adam, age => 24, date => {july,29}}.
    +#{age => 24,date => {july,29},name => adam}
    +2> maps:get(name, M1).
     adam
    -3> maps:get(date, M1).
    -{july,29}
    -4> M2 = maps:update(age, 25, M1).
    -#{age => 25,date => {july,29},name => adam}
    -5> map_size(M).
    +3> maps:get(date, M1).
    +{july,29}
    +4> M2 = maps:update(age, 25, M1).
    +#{age => 25,date => {july,29},name => adam}
    +5> map_size(M).
     3
    -6> map_size(#{}).
    +6> map_size(#{}).
     0

    A collection of maps processing functions are found in module maps in STDLIB.

    Read more about maps in Map Expressions.

    Change

    Maps were introduced as an experimental feature in Erlang/OTP R17. Their functionality was extended and became fully supported in Erlang/OTP 18.

    @@ -371,19 +371,19 @@

    latter can be expressed as [H|T]. The notation [Term1,...,TermN] above is equivalent with the list [Term1|[...|[TermN|[]]]].

    Example:

    [] is a list, thus
    [c|[]] is a list, thus
    [b|[c|[]]] is a list, thus
    [a|[b|[c|[]]]] is a list, or in short [a,b,c]

    A list where the tail is a list is sometimes called a proper list. It is allowed to have a list where the tail is not a list, for example, [a|b]. -However, this type of list is of little practical use.

    Examples:

    1> L1 = [a,2,{c,4}].
    -[a,2,{c,4}]
    -2> [H|T] = L1.
    -[a,2,{c,4}]
    +However, this type of list is of little practical use.

    Examples:

    1> L1 = [a,2,{c,4}].
    +[a,2,{c,4}]
    +2> [H|T] = L1.
    +[a,2,{c,4}]
     3> H.
     a
     4> T.
    -[2,{c,4}]
    -5> L2 = [d|T].
    -[d,2,{c,4}]
    -6> length(L1).
    +[2,{c,4}]
    +5> L2 = [d|T].
    +[d,2,{c,4}]
    +6> length(L1).
     3
    -7> length([]).
    +7> length([]).
     0

    A collection of list processing functions are found in module lists in STDLIB.

    @@ -511,16 +511,16 @@

    data type. Instead, record expressions are translated to tuple expressions during compilation. Therefore, record expressions are not understood by the shell unless special actions are taken. For details, see module shell -in STDLIB.

    Examples:

    -module(person).
    --export([new/2]).
    +in STDLIB.

    Examples:

    -module(person).
    +-export([new/2]).
     
    --record(person, {name, age}).
    +-record(person, {name, age}).
     
    -new(Name, Age) ->
    -    #person{name=Name, age=Age}.
    +new(Name, Age) ->
    +    #person{name=Name, age=Age}.
     
    -1> person:new(ernie, 44).
    -{person,ernie,44}

    Read more about records in Records. More examples are +1> person:new(ernie, 44). +{person,ernie,44}

    Read more about records in Records. More examples are found in Programming Examples.

    @@ -533,11 +533,11 @@

    true 2> true or false. true -3> is_boolean(true). +3> is_boolean(true). true -4> is_boolean(false). +4> is_boolean(false). true -5> is_boolean(ok). +5> is_boolean(ok). false

    @@ -563,39 +563,39 @@

    Type Conversions

    -

    There are a number of BIFs for type conversions.

    Examples:

    1> atom_to_list(hello).
    +

    There are a number of BIFs for type conversions.

    Examples:

    1> atom_to_list(hello).
     "hello"
    -2> list_to_atom("hello").
    +2> list_to_atom("hello").
     hello
    -3> binary_to_list(<<"hello">>).
    +3> binary_to_list(<<"hello">>).
     "hello"
    -4> binary_to_list(<<104,101,108,108,111>>).
    +4> binary_to_list(<<104,101,108,108,111>>).
     "hello"
    -5> list_to_binary("hello").
    +5> list_to_binary("hello").
     <<104,101,108,108,111>>
    -6> float_to_list(7.0).
    +6> float_to_list(7.0).
     "7.00000000000000000000e+00"
    -7> list_to_float("7.000e+00").
    +7> list_to_float("7.000e+00").
     7.0
    -8> integer_to_list(77).
    +8> integer_to_list(77).
     "77"
    -9> list_to_integer("77").
    +9> list_to_integer("77").
     77
    -10> tuple_to_list({a,b,c}).
    -[a,b,c]
    -11> list_to_tuple([a,b,c]).
    -{a,b,c}
    -12> term_to_binary({a,b,c}).
    +10> tuple_to_list({a,b,c}).
    +[a,b,c]
    +11> list_to_tuple([a,b,c]).
    +{a,b,c}
    +12> term_to_binary({a,b,c}).
     <<131,104,3,100,0,1,97,100,0,1,98,100,0,1,99>>
    -13> binary_to_term(<<131,104,3,100,0,1,97,100,0,1,98,100,0,1,99>>).
    -{a,b,c}
    -14> binary_to_integer(<<"77">>).
    +13> binary_to_term(<<131,104,3,100,0,1,97,100,0,1,98,100,0,1,99>>).
    +{a,b,c}
    +14> binary_to_integer(<<"77">>).
     77
    -15> integer_to_binary(77).
    +15> integer_to_binary(77).
     <<"77">>
    -16> float_to_binary(7.0).
    +16> float_to_binary(7.0).
     <<"7.00000000000000000000e+00">>
    -17> binary_to_float(<<"7.000e+00">>).
    +17> binary_to_float(<<"7.000e+00">>).
     7.0

    diff --git a/prs/8803/doc/system/design_principles.html b/prs/8803/doc/system/design_principles.html index 9b08e3de58371..1d68ee53e5f59 100644 --- a/prs/8803/doc/system/design_principles.html +++ b/prs/8803/doc/system/design_principles.html @@ -156,94 +156,94 @@

    specific part. Consider the following code (written in plain Erlang) for a simple server, which keeps track of a number of "channels". Other processes can allocate and free the channels by calling the functions alloc/0 and free/1, -respectively.

    -module(ch1).
    --export([start/0]).
    --export([alloc/0, free/1]).
    --export([init/0]).
    +respectively.

    -module(ch1).
    +-export([start/0]).
    +-export([alloc/0, free/1]).
    +-export([init/0]).
     
    -start() ->
    -    spawn(ch1, init, []).
    +start() ->
    +    spawn(ch1, init, []).
     
    -alloc() ->
    -    ch1 ! {self(), alloc},
    +alloc() ->
    +    ch1 ! {self(), alloc},
         receive
    -        {ch1, Res} ->
    +        {ch1, Res} ->
                 Res
         end.
     
    -free(Ch) ->
    -    ch1 ! {free, Ch},
    +free(Ch) ->
    +    ch1 ! {free, Ch},
         ok.
     
    -init() ->
    -    register(ch1, self()),
    -    Chs = channels(),
    -    loop(Chs).
    +init() ->
    +    register(ch1, self()),
    +    Chs = channels(),
    +    loop(Chs).
     
    -loop(Chs) ->
    +loop(Chs) ->
         receive
    -        {From, alloc} ->
    -            {Ch, Chs2} = alloc(Chs),
    -            From ! {ch1, Ch},
    -            loop(Chs2);
    -        {free, Ch} ->
    -            Chs2 = free(Ch, Chs),
    -            loop(Chs2)
    -    end.

    The code for the server can be rewritten into a generic part server.erl:

    -module(server).
    --export([start/1]).
    --export([call/2, cast/2]).
    --export([init/1]).
    -
    -start(Mod) ->
    -    spawn(server, init, [Mod]).
    -
    -call(Name, Req) ->
    -    Name ! {call, self(), Req},
    +        {From, alloc} ->
    +            {Ch, Chs2} = alloc(Chs),
    +            From ! {ch1, Ch},
    +            loop(Chs2);
    +        {free, Ch} ->
    +            Chs2 = free(Ch, Chs),
    +            loop(Chs2)
    +    end.

    The code for the server can be rewritten into a generic part server.erl:

    -module(server).
    +-export([start/1]).
    +-export([call/2, cast/2]).
    +-export([init/1]).
    +
    +start(Mod) ->
    +    spawn(server, init, [Mod]).
    +
    +call(Name, Req) ->
    +    Name ! {call, self(), Req},
         receive
    -        {Name, Res} ->
    +        {Name, Res} ->
                 Res
         end.
     
    -cast(Name, Req) ->
    -    Name ! {cast, Req},
    +cast(Name, Req) ->
    +    Name ! {cast, Req},
         ok.
     
    -init(Mod) ->
    -    register(Mod, self()),
    -    State = Mod:init(),
    -    loop(Mod, State).
    +init(Mod) ->
    +    register(Mod, self()),
    +    State = Mod:init(),
    +    loop(Mod, State).
     
    -loop(Mod, State) ->
    +loop(Mod, State) ->
         receive
    -        {call, From, Req} ->
    -            {Res, State2} = Mod:handle_call(Req, State),
    -            From ! {Mod, Res},
    -            loop(Mod, State2);
    -        {cast, Req} ->
    -            State2 = Mod:handle_cast(Req, State),
    -            loop(Mod, State2)
    -    end.

    And a callback module ch2.erl:

    -module(ch2).
    --export([start/0]).
    --export([alloc/0, free/1]).
    --export([init/0, handle_call/2, handle_cast/2]).
    -
    -start() ->
    -    server:start(ch2).
    -
    -alloc() ->
    -    server:call(ch2, alloc).
    -
    -free(Ch) ->
    -    server:cast(ch2, {free, Ch}).
    -
    -init() ->
    -    channels().
    -
    -handle_call(alloc, Chs) ->
    -    alloc(Chs). % => {Ch,Chs2}
    -
    -handle_cast({free, Ch}, Chs) ->
    -    free(Ch, Chs). % => Chs2

    Notice the following:

    • The code in server can be reused to build many different servers.
    • The server name, in this example the atom ch2, is hidden from the users of + {call, From, Req} -> + {Res, State2} = Mod:handle_call(Req, State), + From ! {Mod, Res}, + loop(Mod, State2); + {cast, Req} -> + State2 = Mod:handle_cast(Req, State), + loop(Mod, State2) + end.

    And a callback module ch2.erl:

    -module(ch2).
    +-export([start/0]).
    +-export([alloc/0, free/1]).
    +-export([init/0, handle_call/2, handle_cast/2]).
    +
    +start() ->
    +    server:start(ch2).
    +
    +alloc() ->
    +    server:call(ch2, alloc).
    +
    +free(Ch) ->
    +    server:cast(ch2, {free, Ch}).
    +
    +init() ->
    +    channels().
    +
    +handle_call(alloc, Chs) ->
    +    alloc(Chs). % => {Ch,Chs2}
    +
    +handle_cast({free, Ch}, Chs) ->
    +    free(Ch, Chs). % => Chs2

    Notice the following:

    • The code in server can be reused to build many different servers.
    • The server name, in this example the atom ch2, is hidden from the users of the client functions. This means that the name can be changed without affecting them.
    • The protocol (messages sent to and received from the server) is also hidden. This is good programming practice and allows one to change the protocol @@ -252,16 +252,16 @@

      and free/2 has been intentionally left out, as it is not relevant to the example. For completeness, one way to write these functions is given below. This is an example only, a realistic implementation must be able to handle situations -like running out of channels to allocate, and so on.

      channels() ->
      -   {_Allocated = [], _Free = lists:seq(1, 100)}.
      +like running out of channels to allocate, and so on.

      channels() ->
      +   {_Allocated = [], _Free = lists:seq(1, 100)}.
       
      -alloc({Allocated, [H|T] = _Free}) ->
      -   {H, {[H|Allocated], T}}.
      +alloc({Allocated, [H|T] = _Free}) ->
      +   {H, {[H|Allocated], T}}.
       
      -free(Ch, {Alloc, Free} = Channels) ->
      -   case lists:member(Ch, Alloc) of
      +free(Ch, {Alloc, Free} = Channels) ->
      +   case lists:member(Ch, Alloc) of
             true ->
      -         {lists:delete(Ch, Alloc), [Ch|Free]};
      +         {lists:delete(Ch, Alloc), [Ch|Free]};
             false ->
                Channels
          end.

      Code written without using behaviours can be more efficient, but the increased @@ -270,13 +270,13 @@

      other programmers. Improvised programming structures, while possibly more efficient, are always more difficult to understand.

      The server module corresponds, greatly simplified, to the Erlang/OTP behaviour gen_server.

      The standard Erlang/OTP behaviours are:

      • gen_server

        For implementing the server of a client-server relation

      • gen_statem

        For implementing state machines

      • gen_event

        For implementing event handling functionality

      • supervisor

        For implementing a supervisor in a supervision tree

      The compiler understands the module attribute -behaviour(Behaviour) and issues -warnings about missing callback functions, for example:

      -module(chs3).
      --behaviour(gen_server).
      +warnings about missing callback functions, for example:

      -module(chs3).
      +-behaviour(gen_server).
       ...
       
      -3> c(chs3).
      +3> c(chs3).
       ./chs3.erl:10: Warning: undefined call-back function handle_call/3
      -{ok,chs3}

      +{ok,chs3}

      diff --git a/prs/8803/doc/system/dist/search_data-0DC1A4B6.js b/prs/8803/doc/system/dist/search_data-0DC1A4B6.js new file mode 100644 index 0000000000000..150d96a0d1495 --- /dev/null +++ b/prs/8803/doc/system/dist/search_data-0DC1A4B6.js @@ -0,0 +1 @@ +searchData={"items":[{"type":"extras","title":"Erlang/OTP System Documentation","doc":"# Erlang/OTP System Documentation\n\nThe Erlang/OTP system documentation is a collection of guides describing how\nto use Erlang/OTP and different aspects of working with Erlang/OTP. The guides are:\n\n* [Installation Guide](installation_guide/installation_guide.md) -\n Describes how to build and install Erlang/OTP on Unix and Windows.\n* [Getting Started With Erlang](getting_started/getting_started.md) -\n Describes how to get up and running with programming Erlang.\n* [System Principles](system_principles/system_principles.md) -\n Describes how to build Erlang/OTP systems.\n* [OTP Design Principles](design_principles/design_principles.md) -\n Describes how to build Erlang/OTP applications.\n* [Programming Examples](programming_examples/programming_examples.md) -\n Examples on using records, funs, list comprehensions, and the bit syntax.\n* [Erlang Reference Manual](reference_manual/reference_manual.md) -\n This section is the Erlang reference manual. It describes the Erlang programming language.\n* [Efficiency Guide](efficiency_guide/efficiency_guide.md) -\n Describes how to write efficient code in Erlang-\n* [Interoperability Tutorial](tutorial/tutorial.md) -\n This section informs on interoperability, that is, information exchange, between\n Erlang and other programming languages. The included examples mainly treat\n interoperability between Erlang and C.\n* [Embedded Systems User's Guide](embedded/embedded.md) -\n This section describes the issues that are specific for running Erlang on an embedded system.","ref":"readme.html"},{"type":"extras","title":"Introduction","doc":"# Introduction\n\nThis section describes how to build, install and patch Erlang/OTP on UNIX and Windows.\n\n* **[Building and Installing Erlang/OTP](INSTALL.md)** - Describes how to build and install Erlang/OTP\n on any UNIX platform, that is Linux, macOS, any BSD, Solaris and so on.\n* **[Cross Compiling Erlang/OTP](INSTALL-CROSS.md)** - Describes how to use a [cross compiler] to build\n Erlang/OTP on any UNIX platform.\n* **[Building Erlang/OTP on Windows](INSTALL-WIN32.md)** - Describes how to build Erlang/OTP for on\n Windows 10 using WSL.\n\nThere are also various other guides for other OS located in the\n[Erlang/OTP HOWTO folder](https://github.com/erlang/otp/blob/master/HOWTO/).\n\n> #### Note {: .info }\n>\n> Depending on the Operating System and how familiar you are with using GNU configure/make\n> it can be difficult to build Erlang/OTP. Therefore it is recommended to first go to\n> and check if a pre-built Erlang/OTP can be used.\n\nIf the purpose of building Erlang/OTP is to contribute to its development it is recommended\nto have a look at\n[Contributing to Erlang/OTP](https://github.com/erlang/otp/blob/master/CONTRIBUTING.md)\nand [Developing Erlang/OTP](https://github.com/erlang/otp/blob/master/HOWTO/DEVELOPMENT.md).\n\n[cross compiler]: https://en.wikipedia.org/wiki/Cross_compiler","ref":"installation_guide.html"},{"type":"extras","title":"Building and Installing Erlang/OTP","doc":"Building and Installing Erlang/OTP\n==================================\n\nIntroduction\n------------\n\nThis document describes how to build and install Erlang/OTP-28.\nErlang/OTP should be possible to build from source on any Unix/Linux system,\nincluding macOS. You are advised to read the whole document\nbefore attempting to build and install Erlang/OTP.\n\nThe source code can be downloaded from the official site of Erlang/OTP or GitHub.\n* \n* \n\nRequired Utilities\n------------------\n\nThese are the tools you need in order to unpack and build Erlang/OTP.","ref":"install.html"},{"type":"extras","title":"Unpacking ### - Building and Installing Erlang/OTP","doc":"* GNU unzip, or a modern uncompress.\n* A TAR program that understands the GNU TAR format for long filenames.","ref":"install.html#unpacking"},{"type":"extras","title":"Building ### - Building and Installing Erlang/OTP","doc":"* GNU `make`\n* Compiler -- GNU C Compiler, `gcc` or the C compiler frontend for LLVM, `clang`.\n* Perl 5\n* `ncurses`, `termcap`, or `termlib` -- The development headers and\n libraries are needed, often known as `ncurses-devel`. Use\n `--without-termcap` to build without any of these libraries. Note that\n in this case only the old shell (without any line editing) can be used.\n* `sed` -- Stream Editor for basic text transformation.\n\n#### Building in Git ####\n\nBuild the same way as when building the unpacked tar file.\n\n#### Building on macOS ####\n\n* Xcode -- Download and install via the Mac App Store.\n Read about [Building on a Mac][] before proceeding.","ref":"install.html#building"},{"type":"extras","title":"Installing ### - Building and Installing Erlang/OTP","doc":"* An `install` program that can take multiple file names.\n\nOptional Utilities\n------------------\n\nSome applications are automatically skipped if the dependencies aren't met.\nHere is a list of utilities needed for those applications. You will\nalso find the utilities needed for building the documentation.","ref":"install.html#installing"},{"type":"extras","title":"Building ### - Building and Installing Erlang/OTP","doc":"* OpenSSL -- The opensource toolkit for Secure Socket Layer\n and Transport Layer Security.\n Required for building the application `crypto`.\n Further, `ssl` and `ssh` require a working crypto application and\n will also be skipped if OpenSSL is missing. The `public_key`\n application is available without `crypto`, but the functionality\n will be very limited.\n\n The development package of OpenSSL including the header files are needed as well\n as the binary command program `openssl`. At least version 0.9.8 of OpenSSL is required.\n Read more and download from .\n* Oracle Java SE JDK -- The Java Development Kit (Standard Edition).\n Required for building the application `jinterface`.\n At least version 1.6.0 of the JDK is required.\n\n Download from .\n We have also tested with IBM's JDK 1.6.0.\n* `flex` -- Headers and libraries are needed to build the flex\n scanner for the `megaco` application on Unix/Linux.\n* wxWidgets -- Toolkit for GUI applications.\n Required for building the `wx` application. At least\n version 3.0 of wxWidgets is required.\n\n Download from \n or get it from GitHub: \n\n Further instructions on wxWidgets, read [Building with Wx][].","ref":"install.html#building"},{"type":"extras","title":"Building Documentation ### - Building and Installing Erlang/OTP","doc":"* `ex_doc` -- [ExDoc](https://hexdocs.pm/ex_doc/readme.html) is a tool to\n generate html and epub documentation for Erlang and Elixir projects.\n \n Download as an [escript from github](https://github.com/elixir-lang/ex_doc/releases/latest)\n or get it from GitHub: and build\n your self.\n \n ExDoc v0.34.1 was used to build the documentation for this release,\n but any version after that should work just as well.\n\n You can also use `./otp_build download_ex_doc` to download the correct version\n from github. One of the following dependencies are needed to check the documentation:\n \n - sha256sum, or\n - sha1sum, or\n - shasum\n\nHow to Build and Install Erlang/OTP\n-----------------------------------\n\nThe following instructions are for building [the released source tar ball][]\nor from a [git clone](https://github.com/erlang/otp).\n\nThe variable `$ERL_TOP` will be mentioned a lot of times. It refers to\nthe top directory in the source tree. More information about `$ERL_TOP`\ncan be found in the [make and $ERL_TOP][] section below.","ref":"install.html#building-documentation"},{"type":"extras","title":"Unpacking ### - Building and Installing Erlang/OTP","doc":"Start by unpacking the Erlang/OTP distribution file with your GNU\ncompatible TAR program.\n\n $ tar -zxf otp_src_28.0-rc0.tar.gz # Assuming bash/sh\n\nor clone from github:\n\n $ git clone https://github.com/erlang/otp otp_src_28.0-rc0\n\nNow change directory into the base directory and set the `$ERL_TOP` variable.\n\n $ cd otp_src_28.0-rc0\n $ export ERL_TOP=`pwd` # Assuming bash/sh","ref":"install.html#unpacking"},{"type":"extras","title":"Configuring ### - Building and Installing Erlang/OTP","doc":"Run the following commands to configure the build:\n\n $ ./configure [ options ]\n\nBy default, Erlang/OTP release will be installed in `/usr/local/{bin,lib/erlang}`.\nIf you for instance don't have the permission to install in the standard location,\n you can install Erlang/OTP somewhere else. For example, to install in\n`/opt/erlang/28.0-rc0/{bin,lib/erlang}`, use the `--prefix=/opt/erlang/28.0-rc0` option.\n\nOn some platforms Perl may behave strangely if certain locales are\nset. If you get errors when building, try setting the LANG variable:\n\n $ export LANG=C # Assuming bash/sh","ref":"install.html#configuring"},{"type":"extras","title":"Building ### - Building and Installing Erlang/OTP","doc":"Build the Erlang/OTP release.\n\n $ make","ref":"install.html#building"},{"type":"extras","title":"Testing ### - Building and Installing Erlang/OTP","doc":"Before installation you should test whether your build is working properly\nby running our smoke test. The smoke test is a subset of the complete Erlang/OTP test suites.\nFirst you will need to build and release the test suites.\n\n $ make release_tests\n\nThis creates an additional folder in `$ERL_TOP/release` called `tests`.\nNow, it's time to start the smoke test.\n\n $ cd release/tests/test_server\n $ $ERL_TOP/bin/erl -s ts install -s ts smoke_test batch -s init stop\n\nTo verify that everything is ok you should open `$ERL_TOP/release/tests/test_server/index.html`\nin your web browser and make sure that there are zero failed test cases.\n\n> #### Note {: .info }\n>\n> On builds without `crypto`, `ssl` and `ssh` there is a failed test case\n> for undefined functions. Verify that the failed test case log only shows calls\n> to skipped applications.","ref":"install.html#testing"},{"type":"extras","title":"Installing ### - Building and Installing Erlang/OTP","doc":"You are now ready to install the Erlang/OTP release!\nThe following command will install the release on your system.\n\n $ make install","ref":"install.html#installing"},{"type":"extras","title":"Running ### - Building and Installing Erlang/OTP","doc":"You should now have a working release of Erlang/OTP!\nJump to [System Principles][] for instructions on running Erlang/OTP.\n\n[](){: #How-to-Build-and-Install-Erlang-OTP_How-to-Build-the-Documentation }","ref":"install.html#running"},{"type":"extras","title":"How to Build the Documentation ### - Building and Installing Erlang/OTP","doc":"Make sure you're in the top directory in the source tree.\n\n $ cd $ERL_TOP\n\nIf you have just built Erlang/OTP in the current source tree, you have\nalready ran `configure` and do not need to do this again; otherwise, run\n`configure`.\n\n $ ./configure [Configure Args]\n\nWhen building the documentation you need a full Erlang/OTP-28.0-rc0 system in\nthe `$PATH`.\n\n $ export PATH=$ERL_TOP/bin:$PATH # Assuming bash/sh\n\nTo build `html` and `epub` docs you need to have [ExDoc v0.34.1](https://github.com/elixir-lang/ex_doc).\nSee [Building Documentation](#building-documentation) for information on how to\ninstall ExDoc.\n\nBuild the documentation using:\n\n $ make docs\n\nIt is possible to limit which types of documentation is build by passing the `DOC_TARGETS`\nenvironment variable to `make docs`.\n\n_Example_:\n\n $ make docs DOC_TARGETS=chunks\n\nThe currently available types are: `html` and `chunks`. Where:\n\n* *chunks* - Build [EEP-48](`e:kernel:eep48_chapter.md`) documentation chunks.\n* *html* - Build html and epub documentation.","ref":"install.html#how-to-build-the-documentation"},{"type":"extras","title":"How to Install the Documentation ### - Building and Installing Erlang/OTP","doc":"The documentation can be installed either using the `install-docs` target,\nor using the `release_docs` target.\n\n* If you have installed Erlang/OTP using the `install` target, install\n the documentation using the `install-docs` target. Install locations\n determined by `configure` will be used. `$DESTDIR` can be used the\n same way as when doing `make install`.\n\n $ make install-docs\n\n* If you have installed Erlang/OTP using the `release` target, install\n the documentation using the `release_docs` target. You typically want\n to use the same `RELEASE_ROOT` as when invoking `make release`.\n\n $ make release_docs RELEASE_ROOT= \n\nIt is possible to limit which types of documentation is released using the same `DOC_TARGETS`\nenvironment variable as when building documentation.","ref":"install.html#how-to-install-the-documentation"},{"type":"extras","title":"Accessing the Documentation ### - Building and Installing Erlang/OTP","doc":"After installation you can access the documentation by\n\n* Browsing the html pages by loading the page `/usr/local/lib/erlang/doc/erlang/index.html`\n or ` /lib/erlang/doc/erlang/index.html` if the prefix option has been used.\n\n* Read the embedded documentation by using the built-in shell functions `h/1,2,3` or\n `ht/1,2,3`.","ref":"install.html#accessing-the-documentation"},{"type":"extras","title":"How to Install the Pre-formatted Documentation ### - Building and Installing Erlang/OTP","doc":"Pre-formatted [html documentation][] can be downloaded from .\n\nExtract the html archive in the installation directory.\n\n $ cd \n $ tar -zxf otp_html_28.0-rc0.tar.gz\n\nWhere ` ` is\n\n* ` /lib/erlang` if you have installed Erlang/OTP using\n `make install`.\n* `$DESTDIR /lib/erlang` if you have installed Erlang/OTP\n using `make install DESTDIR= `.\n* `RELEASE_ROOT` if you have installed using\n `make release RELEASE_ROOT= `.\n\n\nAdvanced configuration and build of Erlang/OTP\n----------------------------------------------\n\nIf you want to tailor your Erlang/OTP build and installation, please read\non for detailed information about the individual steps.\n\n[](){: #advanced-configuration-and-build-of-erlang-otp_make-and-ERLTOP }","ref":"install.html#how-to-install-the-pre-formatted-documentation"},{"type":"extras","title":"make and $ERL_TOP ### - Building and Installing Erlang/OTP","doc":"All the makefiles in the entire directory tree use the environment\nvariable `ERL_TOP` to find the absolute path of the installation. The\n`configure` script will figure this out and set it in the top level\nMakefile (which, when building, it will pass on). However, when\ndeveloping it is sometimes convenient to be able to run make in a\nsubdirectory. To do this you must set the `ERL_TOP` variable\nbefore you run make.\n\nFor example, assume your GNU make program is called `make` and you\nwant to rebuild the application `STDLIB`, then you could do:\n\n $ cd lib/stdlib; env ERL_TOP= make\n\nwhere ` ` would be what you find `ERL_TOP` is set to in the top level\nMakefile.","ref":"install.html#make-and-erl_top"},{"type":"extras","title":"otp_build vs configure/make ### - Building and Installing Erlang/OTP","doc":"Building Erlang/OTP can be done either by using the `$ERL_TOP/otp_build`\nscript, or by invoking `$ERL_TOP/configure` and `make` directly. Building using\n`otp_build` is easier since it involves fewer steps, but the `otp_build` build\nprocedure is not as flexible as the `configure`/`make` build procedure. The binary\nreleases for Windows that we deliver are built using `otp_build`.\n\n[]() {: #advanced-configuration-and-build-of-erlang-otp_configuring }","ref":"install.html#otp_build-vs-configure-make"},{"type":"extras","title":"Configuring ### - Building and Installing Erlang/OTP","doc":"The configure script is created by the GNU autoconf utility, which\nchecks for system specific features and then creates a number of makefiles.\n\nThe configure script allows you to customize a number of parameters;\ntype `./configure --help` or `./configure --help=recursive` for details.\n`./configure --help=recursive` will give help for all `configure` scripts in\nall applications.\n\nOne of the things you can specify is where Erlang/OTP should be installed. By\ndefault Erlang/OTP will be installed in `/usr/local/{bin,lib/erlang}`.\nTo keep the same structure but install in a different place, ` ` say,\nuse the `--prefix` argument like this: `./configure --prefix= `.\n\nSome of the available `configure` options are:\n\n* `--prefix=PATH` - Specify installation prefix.\n* `--disable-parallel-configure` - Disable parallel execution of\n `configure` scripts (parallel execution is enabled by default)\n* `--{enable,disable}-jit` - Force enabling or disabling of the JIT.\n* `--{enable,disable}-kernel-poll` - Kernel poll support (enabled by\n default if possible)\n* `--enable-m64-build` - Build 64-bit binaries using the `-m64` flag to\n `(g)cc`\n* `--enable-m32-build` - Build 32-bit binaries using the `-m32` flag to\n `(g)cc`\n* `--{enable,disable}-pie` - Build position independent executable binaries.\n* `--with-assumed-cache-line-size=SIZE` - Set assumed cache-line size in\n bytes. Default is 64. Valid values are powers of two between and\n including 16 and 8192. The runtime system use this value in order to\n try to avoid false sharing. A too large value wastes memory. A to\n small value will increase the amount of false sharing.\n* `--{with,without}-termcap` - termcap (without implies that only the old\n Erlang shell can be used)\n* `--with-javac=JAVAC` - Specify Java compiler to use\n* `--{with,without}-javac` - Java compiler (without implies that the\n `jinterface` application won't be built)\n* `--{enable,disable}-builtin-zlib` - Use the built-in source for zlib.\n* `--{enable,disable}-dynamic-ssl-lib` - Enable or disable dynamic OpenSSL\n libraries when linking the crypto NIF. By default dynamic linking is\n done unless it does not work or is if it is a Windows system.\n* `--{with,without}-ssl` - OpenSSL (without implies that the `crypto`,\n `ssh`, and `ssl` won't be built)\n* `--with-ssl=PATH` - Specify base location of OpenSSL include and lib\n directories.\n* `--with-ssl-incl=PATH` - Specify base location of OpenSSL `include`\n directory (if different than base location specified by --with-ssl=PATH).\n* `--with-ssl-zlib=PATH` - Path to static zlib library to link the\n crypto NIF with. This zlib library is most often not necessary but\n might be needed in order to link the NIF in some cases.\n* `--with-ssl-lib-subdir=RELATIVE_PATH` - Specify extra OpenSSL lib\n sub-directory to search in (relative to base directory).\n* `--with-ssl-rpath=yes|no|PATHS` - Runtime library path for OpenSSL.\n Default is `yes`, which equates to a number of standard locations. If\n `no`, then no runtime library paths will be used. Anything else should be\n a comma or colon separated list of paths.\n* `--with-libatomic_ops=PATH` - Use the `libatomic_ops` library for atomic\n memory accesses. If `configure` should inform you about no native atomic\n implementation available, you typically want to try using the\n `libatomic_ops` library. It can be downloaded from\n .\n* `--disable-smp-require-native-atomics` - By default `configure` will\n fail if an SMP runtime system is about to be built, and no implementation\n for native atomic memory accesses can be found. If this happens, you are\n encouraged to find a native atomic implementation that can be used, e.g.,\n using `libatomic_ops`, but by passing `--disable-smp-require-native-atomics`\n you can build using a fallback implementation based on mutexes or spinlocks.\n Performance of the SMP runtime system will however suffer immensely without\n an implementation for native atomic memory accesses.\n* `--enable-static-{nifs,drivers}` - To allow usage of nifs and drivers on OSs\n that do not support dynamic linking of libraries it is possible to statically\n link nifs and drivers with the main Erlang VM binary. This is done by passing\n a comma separated list to the archives that you want to statically link. e.g.\n `--enable-static-nifs=/home/$USER/my_nif.a`. The paths have to be absolute.\n For drivers, the driver name has to be the same as the filename. You also\n have to define `STATIC_ERLANG_NIF_LIBNAME` (see `erl_nif` documentation) or\n `STATIC_ERLANG_DRIVER` when compiling the .o files for the nif/driver.\n If your nif/driver depends on some other dynamic library, you now have to link\n that to the Erlang VM binary. This is easily achieved by passing `LIBS=-llibname`\n to configure.\n* `--without-$app` - By default all applications in Erlang/OTP will be included\n\tin a release. If this is not wanted it is possible to specify that Erlang/OTP\n\tshould be compiled without one or more applications, i.e. `--without-wx`. There is\n\tno automatic dependency handling between applications. If you disable\n\tan application that another application depends on, you also have to disable the\n\tdependent application.\n* `--enable-gettimeofday-as-os-system-time` - Force usage of `gettimeofday()` for\n OS system time.\n* `--enable-prefer-elapsed-monotonic-time-during-suspend` - Prefer an OS monotonic\n time source with elapsed time during suspend.\n* `--disable-prefer-elapsed-monotonic-time-during-suspend` - Do not prefer an OS\n monotonic time source with elapsed time during suspend.\n* `--with-clock-resolution=high|low` - Try to find clock sources for OS system\n time, and OS monotonic time with higher or lower resolution than chosen by\n default. Note that both alternatives may have a negative impact on the performance\n and scalability compared to the default clock sources chosen.\n* `--enable-ensure-os-monotonic-time` - Enable functionality ensuring the\n monotonicity of monotonic timestamps delivered by the OS. When a\n non-monotonic timestamp is detected, it will be replaced by the last\n delivered monotonic timestamp before being used by Erlang's time\n functionality. Note that you do *not* want to enable this unless the OS\n monotonic time source on the system fails to produce monotonic timestamps.\n This since ensuring the monotonicity of OS monotonic timestamps will hurt\n scalability and performance of the system.\n* `--disable-saved-compile-time` - Disable saving of compile date and time\n in the emulator binary.\n* `--enable-ei-dynamic-lib` - Make erl_interface build a shared library in addition\n to the archive normally built.\n* `--disable-year2038` - Don't support timestamps after mid-January 2038. By\n default `configure` will try to enable support for timestamps after\n mid-January 2038. If it cannot figure out how to do that, it will fail and\n abort with an error. If you anyway want to build the system knowing that the\n system won't function properly after mid-January 2038, you can pass this\n option which will enable `configure` to continue without support for\n timestamps after mid-January 2038. This is typically only an issue on 32-bit\n platforms.\n\nIf you or your system has special requirements please read the `Makefile` for\nadditional configuration information.\n\n[](){: #advanced-configuration-and-build-of-erlang-otp_Configuring_Important-Variables-Inspected-by-configure }\n\n#### Important Variables Inspected by configure ####\n\n##### Compiler and Linker #####\n\n* `CC` - C compiler.\n* `CFLAGS` - C compiler flags. Defaults to \"-g -O2\". If you set it,\n these will be removed.\n* `STATIC_CFLAGS` - Static C compiler flags.\n* `CFLAG_RUNTIME_LIBRARY_PATH` - This flag should set runtime library\n search path for the shared libraries. Note that this actually is a\n linker flag, but it needs to be passed via the compiler.\n* `CPP` - C pre-processor.\n* `CPPFLAGS` - C pre-processor flags.\n* `CXX` - C++ compiler.\n* `CXXFLAGS` - C++ compiler flags.\n* `LD` - Linker.\n* `LDFLAGS` - Linker flags.\n* `LIBS` - Libraries.\n\n##### Dynamic Erlang Driver Linking #####\n\n> #### Note {: .info }\n>\n> Either set all or none of the `DED_LD*` variables (with the exception\n> of `DED_LDFLAGS_CONFTEST`).\n\n* `DED_LD` - Linker for Dynamically loaded Erlang Drivers.\n* `DED_LDFLAGS` - Linker flags to use with `DED_LD`.\n* `DED_LDFLAGS_CONFTEST` - Linker flags to use with `DED_LD` in configure\n link tests if `DED_LDFLAGS` cannot be used in such tests. If not set,\n `DED_LDFLAGS` will be used in configure tests.\n* `DED_LD_FLAG_RUNTIME_LIBRARY_PATH` - This flag should set runtime library\n search path for shared libraries when linking with `DED_LD`.\n\n##### Large File Support #####\n\n> #### Note {: .info }\n>\n> Either set all or none of the `LFS_*` variables.\n\n* `LFS_CFLAGS` - Large file support C compiler flags.\n* `LFS_LDFLAGS` - Large file support linker flags.\n* `LFS_LIBS` - Large file support libraries.\n\n##### Other Tools #####\n\n* `RANLIB` - `ranlib` archive index tool.\n* `AR` - `ar` archiving tool.\n* `GETCONF` - `getconf` system configuration inspection tool. `getconf` is\n currently used for finding out large file support flags to use, and\n on Linux systems for finding out if we have an NPTL thread library or\n not.\n\n#### Updating configure Scripts ####\n\nGenerated `configure` scripts are nowadays included in the git repository.\n\nIf you modify any `configure.in` files or the `erts/aclocal.m4` file, you need\nto regenerate `configure` scripts before the changes will take effect. First\nensure that you have GNU `autoconf` of version 2.69 in your path. Then execute\n`./otp_build update_configure [--no-commit]` in the `$ERL_TOP` directory. The\n`otp_build` script will verify that `autoconf` is of correct version and will\nrefuse to update the `configure` scripts if it is of any other version.\n\n[](){: #advanced-configuration-and-build-of-erlang-otp_configuring_atomic-memory-operations-and-the-vm }\n\n#### Atomic Memory Operations and the VM ####\n\nThe VM with SMP support makes quite a heavy use of atomic memory operations.\nAn implementation providing native atomic memory operations is therefore very\nimportant when building Erlang/OTP. By default the VM will refuse to build\nif native atomic memory operations are not available.\n\nErlang/OTP itself provides implementations of native atomic memory operations\nthat can be used when compiling with a `gcc` compatible compiler for 32/64-bit\nx86, 32/64-bit SPARC V9, 32-bit PowerPC, or 32-bit Tile. When compiling with\na `gcc` compatible compiler for other architectures, the VM may be able to make\nuse of native atomic operations using the `__atomic_*` builtins (may be\navailable when using a `gcc` of at least version 4.7) and/or using the\n`__sync_*` builtins (may be available when using a `gcc` of at least version\n4.1). If only the `gcc`'s `__sync_*` builtins are available, the performance\nwill suffer. Such a configuration should only be used as a last resort. When\ncompiling on Windows using a MicroSoft Visual C++ compiler native atomic\nmemory operations are provided by Windows APIs.\n\nNative atomic implementation in the order preferred:\n1. The implementation provided by Erlang/OTP.\n2. The API provided by Windows.\n3. The implementation based on the `gcc` `__atomic_*` builtins.\n4. If none of the above are available for your architecture/compiler, you\n are recommended to build and install [libatomic_ops][] before building\n Erlang/OTP. The `libatomic_ops` library provides native atomic memory\n operations for a variety of architectures and compilers. When building\n Erlang/OTP you need to inform the build system of where the\n `libatomic_ops` library is installed using the\n `--with-libatomic_ops=PATH` `configure` switch.\n5. As a last resort, the implementation solely based on the `gcc`\n `__sync_*` builtins. This will however cause lots of expensive and\n unnecessary memory barrier instructions to be issued. That is,\n performance will suffer. The `configure` script will warn at the end\n of its execution if it cannot find any other alternative than this.","ref":"install.html#configuring"},{"type":"extras","title":"Building ### - Building and Installing Erlang/OTP","doc":"Building Erlang/OTP on a relatively fast computer takes approximately\n5 minutes. To speed it up, you can utilize parallel make with the `-j ` option.\n\n $ export MAKEFLAGS=-j8 # Assuming bash/sh\n $ make\n\nIf you've upgraded the source with a patch you may need to clean up from previous\nbuilds before the new build.\nMake sure to read the [Pre-built Source Release][] section below before doing a `make clean`.\n\nOther useful information can be found here:\n* [Erlang/OTP GitHub wiki](https://github.com/erlang/otp/wiki)\n* [Contributing to Erlang/OTP](https://github.com/erlang/otp/blob/master/CONTRIBUTING.md)\n* [Developing Erlang/OTP](https://github.com/erlang/otp/blob/master/HOWTO/DEVELOPMENT.md)\n\n[](){: #advanced-configuration-and-build-of-erlang-otp_Building_macOS-Darwin }\n\n#### macOS (Darwin) ####\n\nMake sure that the command `hostname` returns a valid fully qualified host\nname (this is configured in `/etc/hostconfig`). Otherwise you might experience\nproblems when running distributed systems.\n\nIf you develop linked-in drivers (shared library) you need to link using\n`gcc` and the flags `-bundle -flat_namespace -undefined suppress`. You also\ninclude `-fno-common` in `CFLAGS` when compiling. Use `.so` as the library\nsuffix.\n\nIf you have Xcode 4.3, or later, you will also need to download\n\"Command Line Tools\" via the Downloads preference pane in Xcode.\n\n[](){: #advanced-configuration-and-build-of-erlang-otp_Building_Building-with-Wx }\n\n#### Building with Wx ####\n\nwxWidgets-3.2.x is recommended for building the `wx` application\n(wxWidgets-3.0.x will also work). Download it from\n or from\n . It is recommended to use the\nlatest release in the 3.2 series, which at the time of writing\nis 3.2.2.1.\n\nNote that the wxWidgets-3.3 versions are experimental, but they should\nalso work if 3.0 compatibility is enabled by adding\n`--enable-compat30` to the `configure` commands below.\n\nOn all other platforms, a shared library is built as follows:\n\n $ ./configure --prefix=/usr/local\n $ make && sudo make install\n $ export PATH=/usr/local/bin:$PATH\n\nOn Linux, a static library is built as follows:\n\n $ export CFLAGS=-fPIC\n $ export CXXFLAGS=-fPIC\n $ ./configure --prefix=/usr/local --disable-shared\n $ make && sudo make install\n $ export PATH=/usr/local/bin:$PATH\n\nOn macOs, a static library compatible with macOS 13 (Ventura) and later is built\nas follows:\n\n $ ./configure --prefix=/usr/local --with-macosx-version-min=13.0 --disable-shared\n $ make\n $ sudo make install\n $ export PATH=/usr/local/bin:$PATH\n\nVerify that the build and installation succeeded:\n\n $ which wx-config && wx-config --version-full\n\nExpected output is `/usr/local/bin/wx-config` on one line, followed by the full\nversion number. For example, if you built version 3.2.2.1, the expected output is:\n\n /usr/local/bin/wx-config\n 3.2.2.1\n\nBuild Erlang/OTP in the usual way. To verify that `wx` application is\nworking run the following command:\n\n $ erl -run wx demo\n\n\n[](){: #advanced-configuration-and-build-of-erlang-otp_Building_Prebuilt-Source-Release }\n\n#### Pre-built Source Release ####\n\nThe source release is delivered with a lot of platform independent\nbuild results already pre-built. If you want to remove these pre-built\nfiles, invoke `./otp_build remove_prebuilt_files` from the `$ERL_TOP`\ndirectory. After you have done this, you can build exactly the same way\nas before, but the build process will take a much longer time.\n\n> #### Warning {: .warning }\n>\n> Doing `make clean` in an arbitrary directory of the source\n> tree, may remove files needed for bootstrapping the build.\n>\n> Doing `./otp_build save_bootstrap` from the `$ERL_TOP` directory before\n> doing `make clean` will ensure that it will be possible to build after\n> doing `make clean`. `./otp_build save_bootstrap` will be invoked\n> automatically when `make` is invoked from `$ERL_TOP` with either the\n> `clean` target, or the default target. It is also automatically invoked\n> if `./otp_build remove_prebuilt_files` is invoked.\n>\n> If you need to verify the bootstrap beam files match the provided\n> source files, use `./otp_build update_primary` to create a new commit that\n> contains differences, if any exist.\n\n[](){: #advanced-configuration-and-build-of-erlang-otp_building_how-to-build-a-debug-enabled-erlang-runtime-system }\n\n#### How to Build a Debug Enabled Erlang RunTime System ####\n\nAfter completing all the normal building steps described above a debug\nenabled runtime system can be built. To do this you have to change\ndirectory to `$ERL_TOP/erts/emulator` and execute:\n\n $ (cd $ERL_TOP/erts/emulator && make debug)\n\nThis will produce a `beam.debug.smp` executable. The\nfile are installed along side with the normal (opt) version `beam.smp`.\n\nTo start the debug enabled runtime system execute:\n\n $ $ERL_TOP/bin/cerl -debug\n\nThe debug enabled runtime system features lock violation checking,\nassert checking and various sanity checks to help a developer ensure\ncorrectness. Some of these features can be enabled on a normal beam\nusing appropriate configure options.\n\nThere are other types of runtime systems that can be built as well\nusing the similar steps just described.\n\n $ (cd $ERL_TOP/erts/emulator && make $TYPE)\n\nwhere `$TYPE` is `opt`, `gcov`, `gprof`, `debug`, `valgrind`, `asan` or `lcnt`.\nThese different beam types are useful for debugging and profiling\npurposes.","ref":"install.html#building"},{"type":"extras","title":"Installing ### - Building and Installing Erlang/OTP","doc":"* Staged install using [DESTDIR][]. You can perform the install\n phase in a temporary directory and later move the installation into\n its correct location by use of the `DESTDIR` variable:\n\n $ make DESTDIR= install\n\n The installation will be created in a location prefixed by `$DESTDIR`.\n It can, however, not be run from there. It needs to be moved into the\n correct location before it can be run. If `DESTDIR` have not been set\n but `INSTALL_PREFIX` has been set, `DESTDIR` will be set to\n `INSTALL_PREFIX`. Note that `INSTALL_PREFIX` in pre R13B04 was buggy\n and behaved as `EXTRA_PREFIX` (see below). There are lots of areas of\n use for an installation procedure using `DESTDIR`, e.g. when creating\n a package, cross compiling, etc. Here is an example where the\n installation should be located under `/opt/local`:\n\n $ ./configure --prefix=/opt/local\n $ make\n $ make DESTDIR=/tmp/erlang-build install\n $ cd /tmp/erlang-build/opt/local\n $ # gnu-tar is used in this example\n $ tar -zcf /home/me/my-erlang-build.tgz *\n $ su -\n Password: *****\n $ cd /opt/local\n $ tar -zxf /home/me/my-erlang-build.tgz\n\n* Install using the `release` target. Instead of doing `make install` you\n can create the installation in whatever directory you like using the\n `release` target and run the `Install` script yourself. `RELEASE_ROOT`\n is used for specifying the directory where the installation should be\n created. This is what by default ends up under `/usr/local/lib/erlang`\n if you do the install using `make install`. All installation paths\n provided in the `configure` phase are ignored, as well as `DESTDIR`,\n and `INSTALL_PREFIX`. If you want links from a specific `bin` directory\n to the installation you have to set those up yourself. An example where\n Erlang/OTP should be located at `/home/me/OTP`:\n\n $ ./configure\n $ make\n $ make RELEASE_ROOT=/home/me/OTP release\n $ cd /home/me/OTP\n $ ./Install -minimal /home/me/OTP\n $ mkdir -p /home/me/bin\n $ cd /home/me/bin\n $ ln -s /home/me/OTP/bin/erl erl\n $ ln -s /home/me/OTP/bin/erlc erlc\n $ ln -s /home/me/OTP/bin/escript escript\n ...\n\n The `Install` script should currently be invoked as follows in the\n directory where it resides (the top directory):\n\n $ ./Install [-cross] [-minimal|-sasl] \n\n where:\n\n * `-minimal` Creates an installation that starts up a minimal amount\n of applications, i.e., only `kernel` and `stdlib` are started. The\n minimal system is normally enough, and is what `make install` uses.\n * `-sasl` Creates an installation that also starts up the `sasl`\n application.\n * `-cross` For cross compilation. Informs the install script that it\n is run on the build machine.\n * ` ` - The absolute path to the Erlang installation to use\n at run time. This is often the same as the current working directory,\n but does not have to be. It can follow any other path through the\n file system to the same directory.\n\n If neither `-minimal`, nor `-sasl` is passed as argument you will be\n prompted.\n\n* Test install using `EXTRA_PREFIX`. The content of the `EXTRA_PREFIX`\n variable will prefix all installation paths when doing `make install`.\n Note that `EXTRA_PREFIX` is similar to `DESTDIR`, but it does *not* have\n the same effect as `DESTDIR`. The installation can and have to be run\n from the location specified by `EXTRA_PREFIX`. That is, it can be useful\n if you want to try the system out, running test suites, etc, before doing\n the real install without `EXTRA_PREFIX`.\n\n#### Symbolic Links in --bindir ####\n\nWhen doing `make install` and the default installation prefix is used,\nrelative symbolic links will be created from `/usr/local/bin` to all public\nErlang/OTP executables in `/usr/local/lib/erlang/bin`. The installation phase\nwill try to create relative symbolic links as long as `--bindir` and the\nErlang bin directory, located under `--libdir`, both have `--exec-prefix` as\nprefix. Where `--exec-prefix` defaults to `--prefix`. `--prefix`,\n`--exec-prefix`, `--bindir`, and `--libdir` are all arguments that can be\npassed to `configure`. One can force relative, or absolute links by passing\n`BINDIR_SYMLINKS=relative|absolute` as arguments to `make` during the install\nphase. Note that such a request might cause a failure if the request cannot\nbe satisfied.","ref":"install.html#installing"},{"type":"extras","title":"Erlang/OTP test architectures ## - Building and Installing Erlang/OTP","doc":"Erlang/OTP are currently tested on the following hardware and operating systems.\nThis is not an exhaustive list, but we try to keep it as up to date as possible.\n\nArchitecture\n\n* x86, x86-64\n* Aarch32, Aarch64\n* powerpc, powerpc64le\n* Apple M1, M2, M2 Pro\n\nOperating system\n\n* Fedora 31\n* FreeBSD\n* macOS 13 - 14\n* MontaVista 4\n* NetBSD\n* OpenBSD\n* SLES 10, 11, 12\n* SunOS 5.11\n* Ubuntu 10.04 - 22.04\n* Windows 11, Windows 10, Windows Server 2019\n\n[DESTDIR]: http://www.gnu.org/prep/standards/html_node/DESTDIR.html\n[Building in Git]: #advanced-configuration-and-build-of-erlang-otp_Building_Within-Git\n[Advanced Configure]: #advanced-configuration-and-build-of-erlang-otp_Configuring\n[Pre-built Source Release]: #advanced-configuration-and-build-of-erlang-otp_Building_Prebuilt-Source-Release\n[make and $ERL_TOP]: #advanced-configuration-and-build-of-erlang-otp_make-and-ERLTOP\n[html documentation]: https://github.com/erlang/otp/releases/download/OTP-28.0-rc0/otp_doc_html_28.0-rc0.tar.gz\n[the released source tar ball]: https://github.com/erlang/otp/releases/download/OTP-28.0-rc0/otp_src_28.0-rc0.tar.gz\n[System Principles]: `e:system:system_principles.md`\n[native build]: #how-to-build-and-install-erlang-otp\n[cross build]: INSTALL-CROSS.md\n[Required Utilities]: #Required-Utilities\n[Optional Utilities]: #Optional-Utilities\n[Building on a Mac]: #advanced-configuration-and-build-of-erlang-otp_Building_macOS-Darwin\n[Building with Wx]: #advanced-configuration-and-build-of-erlang-otp_Building_Building-with-Wx\n[libatomic_ops]: https://github.com/ivmai/libatomic_ops/","ref":"install.html#erlang-otp-test-architectures"},{"type":"extras","title":"Cross Compiling Erlang/OTP","doc":"Cross Compiling Erlang/OTP\n==========================\n\nIntroduction\n------------\n\nThis document describes how to cross compile Erlang/OTP-28. \nYou are advised to read the whole document before attempting to cross\ncompile Erlang/OTP. However, before reading this document, you should read\n[Building and Installing Erlang/OTP][] which describes building\nand installing Erlang/OTP in general.\n\nIn the text below `$ERL_TOP` is the top directory in the Erlang/OTP source tree.","ref":"install-cross.html"},{"type":"extras","title":"otp_build Versus configure/make ### - Cross Compiling Erlang/OTP","doc":"Building Erlang/OTP can be done either by using the `$ERL_TOP/otp_build`\nscript, or by invoking `$ERL_TOP/configure` and `make` directly. Building using\n`otp_build` is easier since it involves fewer steps, but the `otp_build` build\nprocedure is not as flexible as the `configure`/`make` build procedure. Note\nthat `otp_build configure` will produce a default configuration that differs\nfrom what `configure` will produce by default. For example, currently\n`--disable-dynamic-ssl-lib` is added to the `configure` command line arguments\nunless `--enable-dynamic-ssl-lib` has been explicitly passed. The defaults used by\n`otp_build configure` may change at any time without prior notice.","ref":"install-cross.html#otp_build-versus-configure-make"},{"type":"extras","title":"Cross Configuration ### - Cross Compiling Erlang/OTP","doc":"The `$ERL_TOP/xcomp/erl-xcomp.conf.template` file contains all available cross\nconfiguration variables and can be used as a template when creating a cross\ncompilation configuration. All [cross configuration variables][] are also\nlisted at the end of this document. For examples of working cross\nconfigurations see the `$ERL_TOP/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf`\nfile and the `$ERL_TOP/xcomp/erl-xcomp-x86_64-saf-linux-gnu.conf` file. If the\ndefault behavior of a variable is satisfactory, the variable does not need to\nbe set. However, the `configure` script will issue a warning when a default\nvalue is used. When a variable has been set, no warning will be issued.\n\nA cross configuration file can be passed to `otp_build configure` using the\n`--xcomp-conf` command line argument. Note that `configure` does not accept\nthis command line argument. When using the `configure` script directly, pass\nthe configuration variables as arguments to `configure` using a\n` = ` syntax. Variables can also be passed as environment\nvariables to `configure`. However, if you pass the configuration in the\nenvironment, make sure to unset all of these environment variables before\ninvoking `make`; otherwise, the environment variables might set make variables\nin some applications, or parts of some applications, and you may end up with\nan erroneously configured build.","ref":"install-cross.html#cross-configuration"},{"type":"extras","title":"What can be Cross Compiled? ### - Cross Compiling Erlang/OTP","doc":"All Erlang/OTP applications except the `wx` application can be cross compiled.\nThe build of the `wx` driver will currently be automatically disabled when\ncross compiling.","ref":"install-cross.html#what-can-be-cross-compiled"},{"type":"extras","title":"Compatibility ### - Cross Compiling Erlang/OTP","doc":"The build system, including cross compilation configuration variables used,\nmay be subject to non backward compatible changes without prior notice.\nCurrent cross build system has been tested when cross compiling some Linux/GNU\nsystems, but has only been partly tested on other platforms.","ref":"install-cross.html#compatibility"},{"type":"extras","title":"Patches ### - Cross Compiling Erlang/OTP","doc":"Please submit any patches for cross compiling in a way consistent with this\nsystem. All input is welcome as we have a very limited set of cross compiling\nenvironments to test with. If a new configuration variable is needed, add it\nto `$ERL_TOP/xcomp/erl-xcomp.conf.template`, and use it in `configure.in`.\nOther files that might need to be updated are:\n\n- `$ERL_TOP/xcomp/erl-xcomp-vars.sh`\n- `$ERL_TOP/erl-build-tool-vars.sh`\n- `$ERL_TOP/erts/aclocal.m4`\n- `$ERL_TOP/xcomp/README.md`\n- `$ERL_TOP/xcomp/erl-xcomp-*.conf`\n\nNote that this might be an incomplete list of files that need to be updated.\n\nGeneral information on how to submit patches can be found at:\n \n\nBuild and Install Procedure\n---------------------------\n\nWe will first go through the `configure`/`make` build procedure which people\nprobably are most familiar with.","ref":"install-cross.html#patches"},{"type":"extras","title":"Building With configure/make Directly ### - Cross Compiling Erlang/OTP","doc":"Change directory into the top directory of the Erlang/OTP source tree.\n\n $ cd $ERL_TOP\n\nIn order to compile Erlang code, a small Erlang bootstrap system has to be\nbuilt, or an Erlang/OTP system of the same release as the one being built\nhas to be provided in the `$PATH`. The Erlang/OTP for the target system will\nbe built using this Erlang system, together with the cross compilation tools\nprovided.\n\nIf you want to build using a compatible Erlang/OTP system in the `$PATH`,\njump to [Cross Building the System].\n\n#### Building a Bootstrap System ####\n\n $ ./configure --enable-bootstrap-only\n $ make\n\nThe `--enable-bootstrap-only` argument to `configure` isn't strictly necessary,\nbut will speed things up. It will only run `configure` in applications\nnecessary for the bootstrap, and will disable a lot of things not needed by\nthe bootstrap system. If you run `configure` without `--enable-boostrap-only`\nyou also have to run make as `make bootstrap`; otherwise, the whole system will\nbe built.\n\n#### Cross Building the System #### {: #cross-building-the-system }\n\n $ ./configure --host= --build= [Other Config Args]\n $ make\n\n` ` is the host/target system that you build for. It does not have to be\na full `CPU-VENDOR-OS` triplet, but can be. The full canonicalized\n`CPU-VENDOR-OS` triplet will be created by executing\n`$ERL_TOP/make/autoconf/config.sub `. If `config.sub` fails, you need\nto be more specific.\n\n` ` should equal the `CPU-VENDOR-OS` triplet of the system that you\nbuild on. If you execute `$ERL_TOP/make/autoconf/config.guess`, it will in\nmost cases print the triplet you want to use for this.\n\nThe use of ` ` and ` ` values that differ will trigger cross\ncompilation. Note that if ` ` and ` ` differ, the canonicalized\nvalues of ` ` and ` ` must also differ. If they do not, the\nconfiguration will fail.\n\nPass the cross compilation variables as command line arguments to `configure`\nusing a ` = ` syntax.\n\n> #### Note {: .info }\n>\n> You can *not* pass a configuration file using the `--xcomp-conf`\n> argument when you invoke `configure` directly. The `--xcomp-conf` argument\n> can only be passed to `otp_build configure`.\n\n`make` will verify that the Erlang/OTP system used when building is of the\nsame release as the system being built, and will fail if this is not the case.\nIt is possible, however not recommended, to force the cross compilation even\nthough the wrong Erlang/OTP system is used. This by invoking `make` like this:\n`make ERL_XCOMP_FORCE_DIFFERENT_OTP=yes`.\n\n> #### Warning {: .warning }\n>\n> Invoking `make ERL_XCOMP_FORCE_DIFFERENT_OTP=yes` might fail,\n> silently produce suboptimal code, or silently produce erroneous code.\n\n#### Installing ####\n\nYou can either install using the [Installing Using Paths Determined by configure](#installing-using-paths-determined-by-configure), or [install manually](#installing-manually).\n\n[](){: #installing-using-paths-determined-by-configure }\n\n##### Installing Using Paths Determined by configure #####\n\n $ make install DESTDIR= \n\n`make install` will install at a location specified when doing `configure`.\n`configure` arguments specifying where the installation should reside are for\nexample: `--prefix`, `--exec-prefix`, `--libdir`, `--bindir`, etc. By default\nit will install under `/usr/local`. You typically do not want to install your\ncross build under `/usr/local` on your build machine. Using [DESTDIR][]\nwill cause the installation paths to be prefixed by `$DESTDIR`. This makes it\npossible to install and package the installation on the build machine without\nhaving to place the installation in the same directory on the build machine as\nit should be executed from on the target machine.\n\nWhen `make install` has finished, change directory into `$DESTDIR`, package\nthe system, move it to the target machine, and unpack it. Note that the\ninstallation will only be working on the target machine at the location\ndetermined by `configure`.\n\n[](){: #installing-manually }\n\n##### Installing Manually #####\n\n $ make release RELEASE_ROOT= \n\n`make release` will copy what you have built for the target machine to\n` `. The `Install` script will not be run. The content of\n` ` is what by default ends up in `/usr/local/lib/erlang`.\n\nThe `Install` script used when installing Erlang/OTP requires common Unix\ntools such as `sed` to be present in your `$PATH`. If your target system\ndoes not have such tools, you need to run the `Install` script on your\nbuild machine before packaging Erlang/OTP. The `Install` script should\ncurrently be invoked as follows in the directory where it resides\n(the top directory):\n\n $ ./Install [-cross] [-minimal|-sasl] \n\nwhere:\n\n* `-minimal` Creates an installation that starts up a minimal amount\n of applications, i.e., only `kernel` and `stdlib` are started. The\n minimal system is normally enough, and is what `make install` uses.\n* `-sasl` Creates an installation that also starts up the `sasl`\n application.\n* `-cross` For cross compilation. Informs the install script that it\n is run on the build machine.\n* ` ` - The absolute path to the Erlang installation to use\n at run time. This is often the same as the current working directory,\n but does not have to be. It can follow any other path through the file\n system to the same directory.\n\nIf neither `-minimal`, nor `-sasl` is passed as argument you will be\nprompted.\n\n[](){: #install-release }\n\nYou can now either do:\n\n* Decide where the installation should be located on the target machine,\n run the `Install` script on the build machine, and package the installed\n installation. The installation just need to be unpacked at the right\n location on the target machine:\n\n $ cd \n $ ./Install -cross [-minimal|-sasl] \n\nor:\n\n* Package the installation in ` `, place it wherever you want\n on your target machine, and run the `Install` script on your target\n machine:\n\n $ cd \n $ ./Install [-minimal|-sasl]","ref":"install-cross.html#building-with-configure-make-directly"},{"type":"extras","title":"Building With the otp_build Script ### - Cross Compiling Erlang/OTP","doc":"$ cd $ERL_TOP\n\n $ ./otp_build configure --xcomp-conf= [Other Config Args]\n\nalternatively:\n\n $ ./otp_build configure --host= --build= [Other Config Args]\n\nIf you have your cross compilation configuration in a file, pass it using the\n`--xcomp-conf= ` command line argument. If not, pass `--host= `,\n`--build= `, and the configuration variables using a ` = `\nsyntax on the command line (same as in [Cross Building the System]). Note that ` ` and ` `\nhave to be passed one way or the other; either by using `erl_xcomp_host= `\nand `erl_xcomp_build= ` in the configuration file, or by using the\n`--host= `, and `--build= ` command line arguments.\n\n`otp_build configure` will configure both for the bootstrap system on the\nbuild machine and the cross host system.\n\n $ ./otp_build boot -a\n\n`otp_build boot -a` will first build a bootstrap system for the build machine\nand then do the cross build of the system.\n\n $ ./otp_build release -a \n\n`otp_build release -a` will do the same as `make release` in [Installing Manually],\nand you will after this have to do a [manual ./Install](#install-release) on either\nthe host or target.\n\nBuilding and Installing the Documentation\n-----------------------------------------\n\nAfter the system has been cross built you can build and install the\ndocumentation the same way as after a native build of the system. See the\n[How to Build the Documentation][] section in the [Building and Installing Erlang/OTP][]\ndocument for information on how to build the documentation.\n\nTesting the cross compiled system\n---------------------------------\n\nSome of the tests that come with erlang use native code to test. This means\nthat when cross compiling erlang you also have to cross compile test suites\nin order to run tests on the target host. To do this you first have to release\nthe tests as usual.\n\n $ make release_tests\n\nor\n\n $ ./otp_build tests\n\nThe tests will be released into `$ERL_TOP/release/tests`. After releasing the\ntests you have to install the tests on the build machine. You supply the same\nxcomp file as to `./otp_build` in [Building With the otp_build Script](#building-with-the-otp_build-script).\n\n $ cd $ERL_TOP/release/tests/test_server/\n $ $ERL_TOP/bootstrap/bin/erl -eval 'ts:install([{xcomp,\" \"}])' -s ts compile_testcases -s init stop\n\nYou should get a lot of printouts as the testcases are compiled. Once done you\nshould copy the entire `$ERL_TOP/release/tests` folder to the cross host system.\n\nThen go to the cross host system and setup the erlang installed\nto be in your `$PATH`. Then go to what previously was\n`$ERL_TOP/release/tests/test_server` and issue the following command.\n\n $ erl -s ts install -s ts run all_tests -s init stop\n\nThe configure should be skipped and all tests should hopefully pass. For more\ndetails about how to use ts run `erl -s ts help -s init stop`\n\nCurrently Used Configuration Variables\n--------------------------------------\n\nNote that you cannot define arbitrary variables in a cross compilation\nconfiguration file. Only the ones listed below will be guaranteed to be\nvisible throughout the whole execution of all `configure` scripts. Other\nvariables needs to be defined as arguments to `configure` or exported in\nthe environment.","ref":"install-cross.html#building-with-the-otp_build-script"},{"type":"extras","title":"Variables for otp_build Only ### - Cross Compiling Erlang/OTP","doc":"Variables in this section are only used, when configuring Erlang/OTP for\ncross compilation using `$ERL_TOP/otp_build configure`.\n\n> #### Note {: .info }\n>\n> These variables currently have *no* effect if you configure using\n> the `configure` script directly.\n\n* `erl_xcomp_build` - The build system used. This value will be passed as\n `--build=$erl_xcomp_build` argument to the `configure` script. It does\n not have to be a full `CPU-VENDOR-OS` triplet, but can be. The full\n `CPU-VENDOR-OS` triplet will be created by\n `$ERL_TOP/make/autoconf/config.sub $erl_xcomp_build`. If set to `guess`,\n the build system will be guessed using\n `$ERL_TOP/make/autoconf/config.guess`.\n\n* `erl_xcomp_host` - Cross host/target system to build for. This value will\n be passed as `--host=$erl_xcomp_host` argument to the `configure` script.\n It does not have to be a full `CPU-VENDOR-OS` triplet, but can be. The\n full `CPU-VENDOR-OS` triplet will be created by\n `$ERL_TOP/make/autoconf/config.sub $erl_xcomp_host`.\n\n* `erl_xcomp_configure_flags` - Extra configure flags to pass to the\n `configure` script.","ref":"install-cross.html#variables-for-otp_build-only"},{"type":"extras","title":"Cross Compiler and Other Tools ### - Cross Compiling Erlang/OTP","doc":"If the cross compilation tools are prefixed by ` -` you probably do\nnot need to set these variables (where ` ` is what has been passed as\n`--host= ` argument to `configure`). Compiler and other tools can\notherwise be identified via variables passed as arguments on the command\nline to `configure`, in then xcomp file, or as environment variables. For\nmore information see the [Important Variables Inspected by configure][]\nsection in [Building and Installing Erlang/OTP][].","ref":"install-cross.html#cross-compiler-and-other-tools"},{"type":"extras","title":"Cross System Root Locations ### - Cross Compiling Erlang/OTP","doc":"* `erl_xcomp_sysroot` - The absolute path to the system root of the cross\n compilation environment. Currently, the `crypto`, `odbc`, `ssh` and\n `ssl` applications need the system root. These applications will be\n skipped if the system root has not been set. The system root might be\n needed for other things too. If this is the case and the system root\n has not been set, `configure` will fail and request you to set it.\n\n* `erl_xcomp_isysroot` - The absolute path to the system root for includes\n of the cross compilation environment. If not set, this value defaults\n to `$erl_xcomp_sysroot`, i.e., only set this value if the include system\n root path is not the same as the system root path.","ref":"install-cross.html#cross-system-root-locations"},{"type":"extras","title":"Optional Feature, and Bug Tests ### - Cross Compiling Erlang/OTP","doc":"These tests cannot (always) be done automatically when cross compiling. You\nusually do not need to set these variables.\n\n> #### Warning {: .warning }\n>\n> Setting these variables wrong may cause hard to detect\n> runtime errors. If you need to change these values, *really* make sure\n> that the values are correct.\n\n> #### Note {: .info }\n>\n> Some of these values will override results of tests performed\n> by `configure`, and some will not be used until `configure` is sure that\n> it cannot figure the result out.\n\nThe `configure` script will issue a warning when a default value is used.\nWhen a variable has been set, no warning will be issued.\n\n* `erl_xcomp_after_morecore_hook` - `yes|no`. Defaults to `no`. If `yes`,\n the target system must have a working `__after_morecore_hook` that can be\n used for tracking used `malloc()` implementations core memory usage.\n This is currently only used by unsupported features.\n\n* `erl_xcomp_bigendian` - `yes|no`. No default. If `yes`, the target system\n must be big endian. If `no`, little endian. This can often be\n automatically detected, but not always. If not automatically detected,\n `configure` will fail unless this variable is set. Since no default\n value is used, `configure` will try to figure this out automatically.\n\t\n* `erl_xcomp_double_middle` - `yes|no`. Defaults to `no`. \n\tIf `yes`, the target system must have doubles in \"middle-endian\" format. If\n `no`, it has \"regular\" endianness. \t\n\n* `erl_xcomp_clock_gettime_cpu_time` - `yes|no`. Defaults to `no`. If `yes`,\n the target system must have a working `clock_gettime()` implementation\n that can be used for retrieving process CPU time.\n\n* `erl_xcomp_getaddrinfo` - `yes|no`. Defaults to `no`. If `yes`, the target\n system must have a working `getaddrinfo()` implementation that can\n handle both IPv4 and IPv6.\n\n* `erl_xcomp_gethrvtime_procfs_ioctl` - `yes|no`. Defaults to `no`. If `yes`,\n the target system must have a working `gethrvtime()` implementation and\n is used with procfs `ioctl()`.\n\n* `erl_xcomp_dlsym_brk_wrappers` - `yes|no`. Defaults to `no`. If `yes`, the\n target system must have a working `dlsym(RTLD_NEXT, )` implementation\n that can be used on `brk` and `sbrk` symbols used by the `malloc()`\n implementation in use, and by this track the `malloc()` implementations\n core memory usage. This is currently only used by unsupported features.\n\n* `erl_xcomp_kqueue` - `yes|no`. Defaults to `no`. If `yes`, the target\n system must have a working `kqueue()` implementation that returns a file\n descriptor which can be used by `poll()` and/or `select()`. If `no` and\n the target system has not got `epoll()` or `/dev/poll`, the kernel-poll\n feature will be disabled.\n\n* `erl_xcomp_linux_clock_gettime_correction` - `yes|no`. Defaults to `yes` on\n Linux; otherwise, `no`. If `yes`, `clock_gettime(CLOCK_MONOTONIC, _)` on\n the target system must work. This variable is recommended to be set to\n `no` on Linux systems with kernel versions less than 2.6.\n\n* `erl_xcomp_linux_nptl` - `yes|no`. Defaults to `yes` on Linux; otherwise,\n `no`. If `yes`, the target system must have NPTL (Native POSIX Thread\n Library). Older Linux systems have LinuxThreads instead of NPTL (Linux\n kernel versions typically less than 2.6).\n\n* `erl_xcomp_linux_usable_sigaltstack` - `yes|no`. Defaults to `yes` on Linux;\n otherwise, `no`. If `yes`, `sigaltstack()` must be usable on the target\n system. `sigaltstack()` on Linux kernel versions less than 2.4 are\n broken.\n\n* `erl_xcomp_linux_usable_sigusrx` - `yes|no`. Defaults to `yes`. If `yes`,\n the `SIGUSR1` and `SIGUSR2` signals must be usable by the ERTS. Old\n LinuxThreads thread libraries (Linux kernel versions typically less than\n 2.2) used these signals and made them unusable by the ERTS.\n\n* `erl_xcomp_poll` - `yes|no`. Defaults to `no` on Darwin/MacOSX; otherwise,\n `yes`. If `yes`, the target system must have a working `poll()`\n implementation that also can handle devices. If `no`, `select()` will be\n used instead of `poll()`.\n\n* `erl_xcomp_putenv_copy` - `yes|no`. Defaults to `no`. If `yes`, the target\n system must have a `putenv()` implementation that stores a copy of the\n key/value pair.\n\n* `erl_xcomp_reliable_fpe` - `yes|no`. Defaults to `no`. If `yes`, the target\n system must have reliable floating point exceptions.\n\n* `erl_xcomp_posix_memalign` - `yes|no`. Defaults to `yes` if `posix_memalign`\n system call exists; otherwise `no`. If `yes`, the target system must have a\n `posix_memalign` implementation that accepts larger than page size\n alignment.\n\n* `erl_xcomp_code_model_small` - `yes|no`. Default to `no`. If `yes`, the target\n system must place the beam.smp executable in the lower 2 GB of memory. That is it\n should not use position independent executable.\n\n\n[Building and Installing Erlang/OTP]: INSTALL.md\n[How to Build the Documentation]: INSTALL.md#How-to-Build-and-Install-Erlang-OTP_How-to-Build-the-Documentation\n[Important Variables Inspected by configure]: INSTALL.md#advanced-configuration-and-build-of-erlang-otp_Configuring_Important-Variables-Inspected-by-configure\n[cross configuration variables]: #currently-used-configuration-variables\n[DESTDIR]: http://www.gnu.org/prep/standards/html_node/DESTDIR.html\n[?TOC]: true\n[Cross Building the System]: #cross-building-the-system","ref":"install-cross.html#optional-feature-and-bug-tests"},{"type":"extras","title":"Building Erlang/OTP on Windows","doc":"Building Erlang/OTP on Windows\n==============================\n\nIntroduction\n------------\n\nThis section describes how to build the Erlang emulator and the OTP\nlibraries on Windows. Note that the Windows binary releases are still\na preferred alternative if one does not have Microsoft’s development\ntools and/or don’t want to install WSL. You can download the binary\nreleases from .\n\nThe instructions apply to Windows 10 (v.1809 and later) supporting the\nWSL.1 (Windows Subsystem for Linux v.1) and using Ubuntu 18.04 release.\n\nThe procedure described uses WSL as a build environment. You run the\nbash shell in WSL and use the gnu configure/make etc to do\nthe build. The emulator C-source code is, however, mostly compiled\nwith Microsoft Visual C++™, producing a native Windows binary. This is\nthe same procedure as we use to build the pre-built binaries. Why we\nuse VC++ and not gcc is explained further in the FAQ section.\n\nThese instructions apply for both 32-bit and 64-bit Windows. Note that\neven if you build a 64-bit version of Erlang, most of the directories\nand files involved are still named win32. Some occurrences of the name\nwin64 are however present. The installation file for a 64-bit Windows\nversion of Erlang, for example, is `otp_win64_28.exe`.\n\nIf you feel comfortable with the environment and build\nsystem, and have all the necessary tools, you have a great opportunity\nto make the Erlang/OTP distribution for Windows better. Please submit\nany suggestions or patches to our [git project] [1] to let\nthem find their way into the next version of Erlang. If making changes\nto the build system (like makefiles etc) please bear in mind that the\nsame makefiles are used on Unix, so that your changes\ndon't break other platforms. That of course goes for C-code too; system\nspecific code resides in the `$ERL_TOP/erts/emulator/sys/win32` and\n`$ERL_TOP/erts/etc/win32` directories mostly. The\n`$ERL_TOP/erts/emulator/beam` directory is for common code.\n\n\nShort Version\n-------------\n\nIn the following sections, we've described as much as we could about\nthe installation of the tools needed. Once the tools are installed,\nbuilding is quite easy. We have also tried to make these instructions\nunderstandable for people with limited Unix experience. WSL is a whole\nnew environment to some Windows users, why careful explanation of\nenvironment variables etc seemed to be in place.\n\nThis is the short story though, for the experienced and impatient:\n\n* Get and install complete WSL environment\n\n* Install Visual Studio 2019\n\n* Get and install windows JDK-8\n\n* Get and install windows NSIS 3.05 or later (3.05 tried and working)\n\n* Get, build and install OpenSSL v1.1.1d or later (up to 1.1.1d\n tried & working) with static libs.\n\n* Get, build and install wxWidgets-3.2.2.1 or later (up to that\n version tried & working) with static libs.\n\n* Get the Erlang source distribution (from\n ) and unpack with `tar`\n to the windows disk for example to: /mnt/c/src/\n\n* Install mingw-gcc, and make: `sudo apt update && sudo apt install g++-mingw-w64 gcc-mingw-w64 make`\n\n* `$ cd UNPACK_DIR`\n\n* Modify PATH and other environment variables so that all these tools\n are runnable from a bash shell. Still standing in `$ERL_TOP`, issue\n the following commands (for 32-bit Windows, remove the x64 from the\n first row and change `otp_win64_28` to `otp_win32_28` on\n the last row):\n\n $ eval `./otp_build env_win32 x64`\n $ ./otp_build configure\n $ ./otp_build boot -a\n $ ./otp_build release -a\n $ ./otp_build installer_win32\n $ release/win32/otp_win64_28 /S\n\nVoila! `Start->Programs->Erlang OTP 28->Erlang` starts the Erlang\nWindows shell.\n\n\nTools you Need and Their Environment\n------------------------------------\n\nYou need some tools to be able to build Erlang/OTP on Windows. Most\nnotably you'll need WSL (with ubuntu), Visual Studio and\nMicrosofts Windows SDK, but you might also want a Java compiler, the\nNSIS install system, OpenSSL and wxWidgets. Well, here's some information about\nthe different tools:\n\n* WSL: Install WSL and Ubuntu in Windows 10\n \n\n We have used and tested with WSL-1, WSL-2 was not available and may\n not be preferred when building Erlang/OTP since access to the windows\n disk is (currently) slower WSL-2.\n\n* Visual Studio 2019\n Download and run the installer from:\n \n Install C++ and SDK packages to the default installation directory.\n\n* Java JDK 8 or later (optional)\n If you don't care about Java, you can skip this step. The\n result will be that jinterface is not built.\n\n Our Java code (jinterface, ic) is tested on windows with JDK 8.\n Get it for Windows and install it, the JRE is not enough.\n\n URL: \n\n Add javac to your path environment, in my case this means:\n\n `PATH=\"/mnt/c/Program\\ Files/Java/jdk1.8.0_241/bin:$PATH`\n\n No `CLASSPATH` or anything is needed. Type `javac.exe` in the bash prompt\n and you should get a list of available Java options.\n\n* Nullsoft NSIS installer system (optional)\n You need this to build the self installing package.\n\n Download and run the installer from:\n URL: \n\n Add 'makensis.exe' to your path environment:\n\n `PATH=\"/mnt/c/Program\\ Files/NSIS/Bin:$PATH`\n\n Type `which makensis.exe` in the bash prompt and you should get the\n path to the program.\n\n* OpenSSL (optional)\n You need this to build crypto, ssh and ssl libs.\n\n We recommend v1.1.1d or later.\n There are prebuilt available binaries, which you can just\n download and install, available here:\n URL: \n\n Install into `C:/OpenSSL-Win64` (or `C:/OpenSSL-Win32`)\n\n* wxWidgets (optional)\n You need this to build wx to use gui's in debugger and observer.\n\n We recommend v3.2.2.1 or later.\n Unpack into `c:/opt/local64/pgm/wxWidgets-3.2.2.1`\n\n If the `wxUSE_POSTSCRIPT` isn't enabled in `c:/opt/local64/pgm/wxWidgets-3.2.2.1/include/wx/msw/setup.h`,\n enable it.\n\n We recommend to enable for wxWebView wxUSE_WEBVIEW_EDGE.\n * Download the nuget package 'Microsoft.Web.WebView2' (Version 0.9.488 or newer)\n * Extract the package (it's a zip archive) to wxWidgets/3rdparty/webview2 (you should have 3rdparty/webview2/build/native/include/WebView2.h file after unpacking it)\n * Enable wxUSE_WEBVIEW_EDGE in `c:/opt/local64/pgm/wxWidgets-3.2.2.1/include/wx/msw/setup.h`\n\n Build with:\n\n ```text\n C:\\...\\> cd c:\\opt\\local64\\pgm\\wxWidgets-3.2.2.1\\build\\msw\n C:\\...\\> nmake TARGET_CPU=amd64 BUILD=release SHARED=0 DIR_SUFFIX_CPU= -f makefile.vc\n ```\n\n Remove the `TARGET_CPU=amd64` for 32bit build.\n\n* Get the Erlang source distribution (from ).\n The same as for Unix platforms. Preferably use tar to\n unpack the source tar.gz (`tar zxf otp_src_28.tar.gz`) to somewhere\n on the windows disk, `/mnt/c/path/to/otp_src`\n\n NOTE: It is important that source on the windows disk.\n\n Set the environment `ERL_TOP` to point to the root directory of the\n source distribution. Let's say I stood in `/mnt/c/src` and unpacked\n `otp_src_28.tar.gz`, I then add the following to `.profile`:\n \n ```text\n ERL_TOP=/mnt/c/src/otp_src_28\n export ERL_TOP\n ```\n\n\nThe Shell Environment\n---------------------\n\nThe path variable should now contain the windows paths to javac.exe and makensis.exe.\n\nSetup the environment with:\n\n $ export PATH\n $ cd /mnt/c/path/to/otp_src/\n $ eval `./otp_build env_win32 x64`\n\nThis should setup the additional environment variables.\n\nThis should do the final touch to the environment and building should\nbe easy after this. You could run `./otp_build env_win32` without\n`eval` just to see what it does, and to see that the environment it\nsets seems OK. The path is cleaned of spaces if possible (using DOS\nstyle short names instead), the variables `OVERRIDE_TARGET`, `CC`, `CXX`,\n`AR` and `RANLIB` are set to their respective wrappers and the directories\n`$ERL_TOP/erts/etc/win32/wsl_tools/vc` and\n`$ERL_TOP/erts/etc/win32/wsl_tools` are added first in the PATH.\n\nNow you can check which erlc you have by writing `type erlc` in your shell.\nIt should reside in `$ERL_TOP/erts/etc/win32/wsl_tools`.\n\nAnd running `cl.exe` should print the Microsoft compiler usage message.\n\nThe needed compiler environment variables are setup inside `otp_build`\nvia `erts/etc/win32/wsl_tools/SetupWSLcross.bat`. It contains some\nhardcoded paths, if your installation path is different it can be added\nto that file.\n\n\nBuilding and Installing\n-----------------------\n\nBuilding is easiest using the `otp_build` script:\n\n $ ./otp_build configure \n $ ./otp_build boot -a\n $ ./otp_build release -a \n $ ./otp_build installer_win32 # optional\n\nNow you will have a file called `otp_win32_28.exe` or `otp_win64_28.exe`\nin the ` `, i.e. `$ERL_TOP/release/win32`.\n\nLets get into more detail:\n\n1. `$ ./otp_build configure` - This runs the newly generated configure\n scripts with options making configure behave nicely. The target machine\n type is plainly `win32`, so a lot of the configure-scripts recognize\n this awkward target name and behave accordingly. The CC variable also\n makes the compiler be `cc.sh`, which wraps MSVC++, so all configure\n tests regarding the C compiler gets to run the right compiler. A lot of\n the tests are not needed on Windows, but we thought it best to run the\n whole configure anyway.\n\n2. `$ ./otp_build boot -a` - This uses the bootstrap directory (shipped\n with the source, `$ERL_TOP/bootstrap`) to build a complete OTP\n system. When this is done you can run erl from within the source tree;\n just type `$ERL_TOP/bin/erl` and you should have the prompt.\n\n3. `$ ./otp_build release -a` - Builds a commercial release tree from the\n source tree. The default is to put it in `$ERL_TOP/release/win32`. You can\n give any directory as parameter, but it doesn't really\n matter if you're going to build a self extracting installer too.\n\n4. `$ ./otp_build installer_win32` - Creates the self extracting installer executable.\n The executable `otp_win32_28.exe` or `otp_win64_28.exe` will be placed\n in the top directory of the release created in the previous step. If\n no release directory is specified, the release is expected to have\n been built to `$ERL_TOP/release/win32`, which also will be the place\n where the installer executable will be placed. If you specified some\n other directory for the release (i.e. `./otp_build release -a\n /tmp/erl_release`), you're expected to give the same parameter here,\n (i.e. `./otp_build installer_win32 /tmp/erl_release`). You need to have\n a full NSIS installation and `makensis.exe` in your path for this to\n work. Once you have created the installer, you can run it to\n install Erlang/OTP in the regular way, just run the executable and\n follow the steps in the installation wizard. To get all default settings\n in the installation without any questions asked, you run the executable\n with the parameter `/S` (capital S) like in:\n\n $ cd $ERL_TOP\n $ release/win32/otp_win32_28 /S\n ...\n\n or\n\n $ cd $ERL_TOP\n $ release/win32/otp_win64_28 /S\n ...\n\n\n and after a while Erlang/OTP-28 will have been installed in\n `C:\\Program Files\\erl%ERTS-VSN%\\`, with shortcuts in the menu etc.\n\n\nDevelopment\n-----------\n\nOnce the system is built, you might want to change it. Having a test\nrelease in some nice directory might be useful, but you can also run\nErlang from within the source tree. The target `local_setup`, makes\nthe program `$ERL_TOP/bin/erl.exe` usable and it also uses all the OTP\nlibraries in the source tree.\n\nIf you hack the emulator, you can build the emulator executable\nby standing in `$ERL_TOP/erts/emulator` and do a simple\n\n $ make opt\n\nNote that you need to have run ``(cd $ERL_TOP && eval `./otp_build env_win32`)``\nin the particular shell before building anything on Windows. After\ndoing a make opt you can test your result by running `$ERL_TOP/bin/erl`.\nIf you want to copy the result to a release directory (say\n`/tmp/erl_release`), you do this (still in `$ERL_TOP/erts/emulator`)\n\n $ make TESTROOT=/tmp/erl_release release\n\nThat will copy the emulator executables.\n\nTo make a debug build of the emulator, you need to recompile both\n`beam.dll` (the actual runtime system) and `erlexec.dll`. Do like this\n\n $ cd $ERL_TOP\n $ rm bin/win32/erlexec.dll\n $ cd erts/emulator\n $ make debug\n $ cd ../etc\n $ make debug\n\nand sometimes\n\n $ cd $ERL_TOP\n $ make local_setup\n\nSo now when you run `$ERL_TOP/erl.exe`, you should have a debug compiled\nemulator, which you will see if you do a:\n\n 1> erlang:system_info(system_version).\n\nin the erlang shell. If the returned string contains `[debug]`, you\ngot a debug compiled emulator.\n\nTo hack the erlang libraries, you simply do a `make opt` in the\nspecific \"applications\" directory, like:\n\n $ cd $ERL_TOP/lib/stdlib\n $ make opt\n\nor even in the source directory...\n\n $ cd $ERL_TOP/lib/stdlib/src\n $ make opt\n\nNote that you're expected to have a fresh Erlang in your path when\ndoing this, preferably the plain 28 you have built in the previous\nsteps. You could also add `$ERL_TOP/bootstrap/bin` to your `PATH` before\nrebuilding specific libraries. That would give you a good enough\nErlang system to compile any OTP erlang code. Setting up the path\ncorrectly is a little bit tricky. You still need to have\n`$ERL_TOP/erts/etc/win32/wsl_tools/vc` and\n`$ERL_TOP/erts/etc/win32/wsl_tools` *before* the actual emulator\nin the path. A typical setting of the path for using the bootstrap\ncompiler would be:\n\n $ export PATH=$ERL_TOP/erts/etc/win32/wsl_tools/vc\\\n :$ERL_TOP/erts/etc/win32/wsl_tools:$ERL_TOP/bootstrap/bin:$PATH\n\nThat should make it possible to rebuild any library without hassle...\n\nIf you want to copy a library (an application) newly built, to a\nrelease area, you do like with the emulator:\n\n $ cd $ERL_TOP/lib/stdlib\n $ make TESTROOT=/tmp/erlang_release release\n\nRemember that:\n\n* Windows specific C-code goes in the `$ERL_TOP/erts/emulator/sys/win32`,\n `$ERL_TOP/erts/emulator/drivers/win32` or `$ERL_TOP/erts/etc/win32`.\n\n* Windows specific erlang code should be used conditionally and the\n host OS tested in *runtime*, the exactly same beam files should be\n distributed for every platform! So write code like:\n\n case os:type() of\n {win32,_} ->\n do_windows_specific();\n Other ->\n do_fallback_or_exit()\n end,\n\nThat's basically all you need to get going.\n\n\n\nFrequently Asked Questions\n--------------------------\n\n* Q: So, now I can build Erlang using GCC on Windows?\n\n A: No, unfortunately not. You'll need Microsoft's Visual C++\n still. A Bourne-shell script (cc.sh) wraps the Visual C++ compiler\n and runs it from within the WSL environment. All other tools\n needed to build Erlang are free-ware/open source, but not the C\n compiler.\n\n* Q: Why haven't you got rid of VC++ then, you \\*\\*\\*\\*\\*\\*?\n\n A: Well, partly because it's a good compiler - really! Actually it's\n been possible in late R11-releases to build using mingw instead of\n visual C++ (you might see the remnants of that in some scripts and\n directories). Unfortunately the development of the SMP version for\n Windows broke the mingw build and we chose to focus on the VC++ build\n as the performance has been much better in the VC++ versions. The\n mingw build will possibly be back, but as long as VC++ gives better\n performance, the commercial build will be a VC++ one.\n\n* Q: Hah, I saw you, you used GCC even though you said you didn't!\n\n A: OK, I admit, one of the files is compiled using\n MinGW's GCC and the resulting object code is then converted to MS\n VC++ compatible coff using a small C hack. It's because that\n particular file, `beam_emu.c` benefits immensely from being able\n to use the GCC labels-as-values extension, which boosts emulator\n performance by up to 50%. That does unfortunately not (yet) mean\n that all of OTP could be compiled using GCC. That particular\n source code does not do anything system specific and actually is\n adopted to the fact that GCC is used to compile it on Windows.\n\n* Q: So now there's a MS VC++ project file somewhere and I can build OTP\n using the nifty VC++ GUI?\n\n A: No, never. The hassle of keeping the project files up to date and\n do all the steps that constitute an OTP build from within the VC++ GUI\n is simply not worth it, maybe even impossible. A VC++ project\n file for Erlang/OTP will never happen.\n\n* Q: So how does it all work then?\n\n A: WSL/Ubuntu is the environment, it's almost like you had a\n virtual Unix machine inside Windows. Configure, given certain\n parameters, then creates makefiles that are used by the\n environment's gnu-make to built the system. Most of the actual\n compilers etc are not, however, WSL tools, so we've written\n a couple of wrappers (Bourne-shell scripts), which reside in\n `$ERL_TOP/etc/win32/wsl_tools`. They all do conversion of\n parameters and switches common in the Unix environment to fit the\n native Windows tools. Most notable is of course the paths, which\n in WSL are Unix-like paths with \"forward slashes\" (/) and\n no drive letters. The WSL specific command `wslpath` is used\n for most of the path conversions in a WSL environment.\n Luckily most compilers accept forward slashes instead\n of backslashes as path separators, but one still have to get the drive\n letters etc right, though. The wrapper scripts are not general in\n the sense that, for example, cc.sh would understand and translate\n every possible gcc option and pass correct options to\n cl.exe. The principle is that the scripts are powerful enough to\n allow building of Erlang/OTP, no more, no less. They might need\n extensions to cope with changes during the development of Erlang, and\n that's one of the reasons we made them into shell-scripts and not\n Perl-scripts. We believe they are easier to understand and change\n that way.\n\n In `$ERL_TOP`, there is a script called `otp_build`. That script handles\n the hassle of giving all the right parameters to `configure`/`make` and\n also helps you set up the correct environment variables to work with\n the Erlang source under WSL.\n\n* Q: Can I build something that looks exactly as the commercial release?\n\n A: Yes, we use the exact same build procedure.\n\n* Q: Which version of WSL and other tools do you use then?\n\n A: We use WSL 1 with Ubuntu 18.04.\n The GCC we used for 28 was version 7.3-win32.\n We used Visual studio 2019, Sun's JDK 1.8.0\\_241,\n NSIS 3.05, Win32 OpenSSL 1.1.1d and wxWidgets-3.1.3.\n\n\n [1]: https://github.com/erlang/otp\n\n [?TOC]: true","ref":"install-win32.html"},{"type":"extras","title":"Patching OTP Applications","doc":"Patching OTP Applications\n=========================\n\nIntroduction\n------------\n\nThis document describes the process of patching an existing OTP\ninstallation with one or more Erlang/OTP applications of newer versions\nthan already installed. The tool `otp_patch_apply` is available for this\nspecific purpose. It resides in the top directory of the Erlang/OTP\nsource tree.\n\nThe `otp_patch_apply` tool utilizes the [runtime_dependencies][] tag in\nthe [application resource file][]. This information is used to determine\nif the patch can be installed in the given Erlang/OTP installation\ndirectory.\n\nRead more about the [version handling][] introduced in Erlang/OTP release\n17, which also describes how to determine if an installation includes one\nor more patched applications.\n\nIf you want to apply patches of multiple OTP applications that resides\nin different OTP versions, you have to apply these patches in multiple\nsteps. It is only possible to apply multiple OTP applications from the\nsame OTP version at once.\n\nPrerequisites\n-------------\n\nIt's assumed that the reader is familiar with\n[building and installing Erlang/OTP][]. To be able to patch an\napplication, the following must exist:\n\n* An Erlang/OTP installation.\n\n* An Erlang/OTP source tree containing the updated applications that\n you want to patch into the existing Erlang/OTP installation.\n\nUsing otp\\_patch\\_apply\n-----------------------\n\n> #### Warning {: .warning }\n>\n> Patching applications is a one-way process.\n> Create a backup of your OTP installation directory before\n> proceeding.\n\nFirst of all, build the OTP source tree at `$ERL_TOP` containing\nthe updated applications.\n\n> #### Note {: .info }\n>\n> Before applying a patch you need to do a *full* build\n> of OTP in the source directory.\n\nConfigure and build all applications in OTP:\n\n\t$ configure\n\t$ make\n\nor\n\n\t$ ./otp_build configure\n\t$ ./otp_build boot -a\n\nIf you have installed documentation in the OTP installation, also\nbuild the documentation:\n\n\t$ make docs\n\nAfter the successful build it's time to patch. The source tree directory,\nthe directory of the installation and the applications to patch are given\nas arguments to `otp_patch_apply`. The dependencies of each application\nare validated against the applications in the installation and the other\napplications given as arguments. If a dependency error is detected, the\nscript will be aborted.\n\nThe `otp_patch_apply` syntax:\n\n\t$ otp_patch_apply -s -i [-l ] [-c] [-f] [-h] \\\n [-n] [-v] [... ]\n\t\n\t-s -- OTP source directory that contains build results.\n\t-i -- OTP installation directory to patch.\n\t-l -- Alternative OTP source library directory path(s)\n\t containing build results of OTP applications.\n\t Multiple paths should be colon separated.\n\t-c -- Cleanup (remove) old versions of applications\n\t patched in the installation.\n\t-f -- Force patch of application(s) even though\n\t dependencies are not fulfilled (should only be\n\t considered in a test environment).\n\t-h -- Print help then exit.\n\t-n -- Do not install documentation.\n\t-v -- Print version then exit.\n\t -- Application to patch.\n\t\n\tEnvironment Variable:\n\t ERL_LIBS -- Alternative OTP source library directory path(s)\n\t containing build results of OTP applications.\n\t Multiple paths should be colon separated.\n\n> #### Note {: .info }\n>\n> The complete build environment is required while running\n> `otp_patch_apply`.\n\n> #### Note {: .info }\n>\n> All source directories identified by `-s` and `-l` should\n> contain build results of OTP applications.\n\nFor example, if the user wants to install patched versions of `mnesia`\nand `ssl` built in `/home/me/git/otp` into the OTP installation\nlocated in `/opt/erlang/my_otp` type\n\n\t$ otp_patch_apply -s /home/me/git/otp -i /opt/erlang/my_otp \\\n\t mnesia ssl\n\n> #### Note {: .info }\n>\n> If the list of applications contains core applications,\n> i.e `erts`, `kernel`, `stdlib` or `sasl`, the `Install` script in\n> the patched Erlang/OTP installation must be rerun.\n\nThe patched applications are appended to the list of installed\napplications. Take a look at\n` /releases/OTP-REL/installed_application_versions`.\n\nSanity check\n------------\n\nThe application dependencies can be checked using the Erlang shell.\nApplication dependencies are verified among installed applications by\n`otp_patch_apply`, but these are not necessarily those actually loaded.\nBy calling `system_information:sanity_check()` one can validate\ndependencies among applications actually loaded.\n\n```\n1> system_information:sanity_check().\nok\n```\n\nPlease take a look at the reference of [sanity_check()][] for more\ninformation.\n\n[application resource file]: `e:kernel:app.md`\n[runtime_dependencies]: `e:kernel:app.md#runtime_dependencies`\n[building and installing Erlang/OTP]: INSTALL.md\n[version handling]: `e:system:versions.md`\n[sanity_check()]: `system_information:sanity_check/0`","ref":"otp-patch-apply.html"},{"type":"extras","title":"Introduction","doc":"\n# Introduction\n\nThis section is a quick start tutorial to get you started with Erlang.\nEverything in this section is true, but only part of the truth. For example,\nonly the simplest form of the syntax is shown, not all esoteric forms. Also,\nparts that are greatly simplified are indicated with _manual_. This means that a\nlot more information on the subject is to be found in the Erlang book or in\n[Erlang Reference Manual](`e:system:reference_manual.md`).","ref":"getting_started.html"},{"type":"extras","title":"Prerequisites - Introduction","doc":"The reader of this section is assumed to be familiar with the following:\n\n- Computers in general\n- Basics on how computers are programmed","ref":"getting_started.html#prerequisites"},{"type":"extras","title":"Omitted Topics - Introduction","doc":"The following topics are not treated in this section:\n\n- References.\n- Local error handling (catch/throw).\n- Single direction links (monitor).\n- Handling of binary data (binaries / bit syntax).\n- List comprehensions.\n- How to communicate with the outside world and software written in other\n languages (ports); this is described in\n [Interoperability Tutorial](`e:system:tutorial.md`).\n- Erlang libraries (for example, file handling).\n- OTP and (in consequence) the Mnesia database.\n- Hash tables for Erlang terms (ETS).\n- Changing code in running systems.","ref":"getting_started.html#omitted-topics"},{"type":"extras","title":"Sequential Programming","doc":"\n# Sequential Programming","ref":"seq_prog.html"},{"type":"extras","title":"The Erlang Shell - Sequential Programming","doc":"Most operating systems have a command interpreter or shell, UNIX and Linux have\nmany, Windows has the command prompt, powershell and more. Erlang has its own shell\nwhere bits of Erlang code can be written directly, and be evaluated to see what happens (see\nthe `m:shell` manual page in STDLIB).\n\nStart the Erlang shell (in Linux or UNIX) by starting a shell or command\ninterpreter in your operating system and typing `erl`. You will see something\nlike this.\n\n```text\n$ erl\nErlang R15B (erts-5.9.1) [source] [smp:8:8] [rq:8] [async-threads:0] [hipe] [kernel-poll:false]\n\nEshell V5.9.1 (abort with ^G)\n1>\n```\n\nType `2 + 5.` in the shell and then press Enter (carriage return). Notice that\nyou tell the shell you are done entering code by finishing with a full stop `.`\nand a carriage return.\n\n```erlang\n1> 2 + 5.\n7\n2> \n```\n\nAs shown, the Erlang shell numbers the lines that can be entered, (as 1> 2>) and\nthat it correctly says that 2 + 5 is 7. If you make writing mistakes in the\nshell, you can delete with the backspace key, as in most shells. There are many\nmore editing commands in the shell (see\n[tty - A command line interface](`e:erts:tty.md`) in ERTS User's Guide).\n\n(Notice that many line numbers given by the shell in the following examples are\nout of sequence. This is because this tutorial was written and code-tested in\nseparate sessions).\n\nHere is a bit more complex calculation:\n\n```erlang\n2> (42 + 77) * 66 / 3.\n2618.0\n```\n\nNotice the use of brackets, the multiplication operator `*`, and the division\noperator `/`, as in normal arithmetic (see\n[Expressions](`e:system:expressions.md`)).\n\nPress Control-C to shut down the Erlang system and the Erlang shell.\n\nThe following output is shown:\n\n```text\nBREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded\n (v)ersion (k)ill (D)b-tables (d)istribution\na\n$\n```\n\nType `a` to leave the Erlang system.\n\nAnother way to shut down the Erlang system is by entering `halt/0`:\n\n```erlang\n3> halt().\n$\n```","ref":"seq_prog.html#the-erlang-shell"},{"type":"extras","title":"Modules and Functions - Sequential Programming","doc":"A programming language is not much use if you only can run code from the shell.\nSo here is a small Erlang program. Enter it into a file named `tut.erl` using a\nsuitable text editor. The file name `tut.erl` is important, and also that it is\nin the same directory as the one where you started `erl`). If you are lucky your\neditor has an Erlang mode that makes it easier for you to enter and format your\ncode nicely (see [The Erlang mode for Emacs](`e:tools:erlang_mode_chapter.md`)\nin Tools User's Guide), but you can manage perfectly well without. Here is the\ncode to enter:\n\n```erlang\n-module(tut).\n-export([double/1]).\n\ndouble(X) ->\n 2 * X.\n```\n\nIt is not hard to guess that this program doubles the value of numbers. The\nfirst two lines of the code are described later. Let us compile the program.\nThis can be done in an Erlang shell as follows, where `c` means compile:\n\n```erlang\n3> c(tut).\n{ok,tut}\n```\n\nThe `{ok,tut}` means that the compilation is OK. If it says `error` it means\nthat there is some mistake in the text that you entered. Additional error\nmessages gives an idea to what is wrong so you can modify the text and then try\nto compile the program again.\n\nNow run the program:\n\n```erlang\n4> tut:double(10).\n20\n```\n\nAs expected, double of 10 is 20.\n\nNow let us get back to the first two lines of the code. Erlang programs are\nwritten in files. Each file contains an Erlang _module_. The first line of code\nin the module is the module name (see [Modules](`e:system:modules.md`)):\n\n```erlang\n-module(tut).\n```\n\nThus, the module is called _tut_. Notice the full stop `.` at the end of the\nline. The files which are used to store the module must have the same name as\nthe module but with the extension `.erl`. In this case the file name is\n`tut.erl`. When using a function in another module, the syntax\n`module_name:function_name(arguments)` is used. So the following means call\nfunction `double` in module `tut` with argument `10`.\n\n```erlang\n4> tut:double(10).\n```\n\nThe second line says that the module `tut` contains a function called `double`,\nwhich takes one argument (`X` in our example):\n\n```erlang\n-export([double/1]).\n```\n\nThe second line also says that this function can be called from outside the\nmodule `tut`. More about this later. Again, notice the `.` at the end of the\nline.\n\nNow for a more complicated example, the factorial of a number. For example, the\nfactorial of 4 is 4 _ 3 _ 2 * 1, which equals 24.\n\nEnter the following code in a file named `tut1.erl`:\n\n```erlang\n-module(tut1).\n-export([fac/1]).\n\nfac(1) ->\n 1;\nfac(N) ->\n N * fac(N - 1).\n```\n\nSo this is a module, called `tut1` that contains a function called `fac>`, which\ntakes one argument, `N`.\n\nThe first part says that the factorial of 1 is 1.:\n\n```erlang\nfac(1) ->\n 1;\n```\n\nNotice that this part ends with a semicolon `;` that indicates that there is\nmore of the function `fac>` to come.\n\nThe second part says that the factorial of N is N multiplied by the factorial of\nN - 1:\n\n```erlang\nfac(N) ->\n N * fac(N - 1).\n```\n\nNotice that this part ends with a `.` saying that there are no more parts of\nthis function.\n\nCompile the file:\n\n```erlang\n5> c(tut1).\n{ok,tut1}\n```\n\nAnd now calculate the factorial of 4.\n\n```erlang\n6> tut1:fac(4).\n24\n```\n\nHere the function `fac>` in module `tut1` is called with argument `4`.\n\nA function can have many arguments. Let us expand the module `tut1` with the\nfunction to multiply two numbers:\n\n```erlang\n-module(tut1).\n-export([fac/1, mult/2]).\n\nfac(1) ->\n 1;\nfac(N) ->\n N * fac(N - 1).\n\nmult(X, Y) ->\n X * Y.\n```\n\nNotice that it is also required to expand the `-export` line with the\ninformation that there is another function `mult` with two arguments.\n\nCompile:\n\n```erlang\n7> c(tut1).\n{ok,tut1}\n```\n\nTry out the new function `mult`:\n\n```erlang\n8> tut1:mult(3,4).\n12\n```\n\nIn this example the numbers are integers and the arguments in the functions in\nthe code `N`, `X`, and `Y` are called variables. Variables must start with a\ncapital letter (see [Variables](`e:system:expressions.md`)). Examples of\nvariables are `Number`, `ShoeSize`, and `Age`.","ref":"seq_prog.html#modules-and-functions"},{"type":"extras","title":"Atoms - Sequential Programming","doc":"Atom is another data type in Erlang. Atoms start with a small letter (see\n[Atom](`e:system:data_types.md`)), for example, `charles`, `centimeter`, and\n`inch`. Atoms are simply names, nothing else. They are not like variables, which\ncan have a value.\n\nEnter the next program in a file named `tut2.erl`). It can be useful for\nconverting from inches to centimeters and conversely:\n\n```erlang\n-module(tut2).\n-export([convert/2]).\n\nconvert(M, inch) ->\n M / 2.54;\n\nconvert(N, centimeter) ->\n N * 2.54.\n```\n\nCompile:\n\n```erlang\n9> c(tut2).\n{ok,tut2}\n```\n\nTest:\n\n```erlang\n10> tut2:convert(3, inch).\n1.1811023622047243\n11> tut2:convert(7, centimeter).\n17.78\n```\n\nNotice the introduction of decimals (floating point numbers) without any\nexplanation. Hopefully you can cope with that.\n\nLet us see what happens if something other than `centimeter` or `inch` is\nentered in the `convert` function:\n\n```erlang\n12> tut2:convert(3, miles).\n** exception error: no function clause matching tut2:convert(3,miles) (tut2.erl, line 4)\n```\n\nThe two parts of the `convert` function are called its clauses. As shown,\n`miles` is not part of either of the clauses. The Erlang system cannot _match_\neither of the clauses so an error message `function_clause` is returned. The\nshell formats the error message nicely, but the error tuple is saved in the\nshell's history list and can be output by the shell command `v/1`:\n\n```erlang\n13> v(12).\n{'EXIT',{function_clause,[{tut2,convert,\n [3,miles],\n [{file,\"tut2.erl\"},{line,4}]},\n {erl_eval,do_apply,6,\n [{file,\"erl_eval.erl\"},{line,677}]},\n {shell,exprs,7,[{file,\"shell.erl\"},{line,687}]},\n {shell,eval_exprs,7,[{file,\"shell.erl\"},{line,642}]},\n {shell,eval_loop,3,\n [{file,\"shell.erl\"},{line,627}]}]}}\n```","ref":"seq_prog.html#atoms"},{"type":"extras","title":"Tuples - Sequential Programming","doc":"Now the `tut2` program is hardly good programming style. Consider:\n\n```erlang\ntut2:convert(3, inch).\n```\n\nDoes this mean that 3 is in inches? Or does it mean that 3 is in centimeters and\nis to be converted to inches? Erlang has a way to group things together to make\nthings more understandable. These are called _tuples_ and are surrounded by\ncurly brackets, `{` and `}`.\n\nSo, `{inch,3}` denotes 3 inches and `{centimeter,5}` denotes 5 centimeters. Now\nlet us write a new program that converts centimeters to inches and conversely.\nEnter the following code in a file called `tut3.erl`):\n\n```erlang\n-module(tut3).\n-export([convert_length/1]).\n\nconvert_length({centimeter, X}) ->\n {inch, X / 2.54};\nconvert_length({inch, Y}) ->\n {centimeter, Y * 2.54}.\n```\n\nCompile and test:\n\n```erlang\n14> c(tut3).\n{ok,tut3}\n15> tut3:convert_length({inch, 5}).\n{centimeter,12.7}\n16> tut3:convert_length(tut3:convert_length({inch, 5})).\n{inch,5.0}\n```\n\nNotice on line 16 that 5 inches is converted to centimeters and back again and\nreassuringly get back to the original value. That is, the argument to a function\ncan be the result of another function. Consider how line 16 (above) works. The\nargument given to the function `{inch,5}` is first matched against the first\nhead clause of `convert_length`, that is, `convert_length({centimeter,X})`. It\ncan be seen that `{centimeter,X}` does not match `{inch,5}` (the head is the bit\nbefore the `->`). This having failed, let us try the head of the next clause\nthat is, `convert_length({inch,Y})`. This matches, and `Y` gets the value 5.\n\nTuples can have more than two parts, in fact as many parts as you want, and\ncontain any valid Erlang _term_. For example, to represent the temperature of\nvarious cities of the world:\n\n```erlang\n{moscow, {c, -10}}\n{cape_town, {f, 70}}\n{paris, {f, 28}}\n```\n\nTuples have a fixed number of items in them. Each item in a tuple is called an\n_element_. In the tuple `{moscow,{c,-10}}`, element 1 is `moscow` and element 2\nis `{c,-10}`. Here `c` represents Celsius and `f` Fahrenheit.","ref":"seq_prog.html#tuples"},{"type":"extras","title":"Lists - Sequential Programming","doc":"Whereas tuples group things together, it is also needed to represent lists of\nthings. Lists in Erlang are surrounded by square brackets, `[` and `]`. For\nexample, a list of the temperatures of various cities in the world can be:\n\n```erlang\n[{moscow, {c, -10}}, {cape_town, {f, 70}}, {stockholm, {c, -4}},\n {paris, {f, 28}}, {london, {f, 36}}]\n```\n\nNotice that this list was so long that it did not fit on one line. This does not\nmatter, Erlang allows line breaks at all \"sensible places\" but not, for example,\nin the middle of atoms, integers, and others.\n\nA useful way of looking at parts of lists, is by using `|`. This is best\nexplained by an example using the shell:\n\n```erlang\n17> [First |TheRest] = [1,2,3,4,5].\n[1,2,3,4,5]\n18> First.\n1\n19> TheRest.\n[2,3,4,5]\n```\n\nTo separate the first elements of the list from the rest of the list, `|` is\nused. `First` has got value `1` and `TheRest` has got the value `[2,3,4,5]`.\n\nAnother example:\n\n```erlang\n20> [E1, E2 | R] = [1,2,3,4,5,6,7].\n[1,2,3,4,5,6,7]\n21> E1.\n1\n22> E2.\n2\n23> R.\n[3,4,5,6,7]\n```\n\nHere you see the use of `|` to get the first two elements from the list. If you\ntry to get more elements from the list than there are elements in the list, an\nerror is returned. Notice also the special case of the list with no elements,\n`[]`:\n\n```erlang\n24> [A, B | C] = [1, 2].\n[1,2]\n25> A.\n1\n26> B.\n2\n27> C.\n[]\n```\n\nIn the previous examples, new variable names are used, instead of reusing the\nold ones: `First`, `TheRest`, `E1`, `E2`, `R`, `A`, `B`, and `C`. The reason for\nthis is that a variable can only be given a value once in its context (scope).\nMore about this later.\n\nThe following example shows how to find the length of a list. Enter the\nfollowing code in a file named `tut4.erl`:\n\n```erlang\n-module(tut4).\n\n-export([list_length/1]).\n\nlist_length([]) ->\n 0;\nlist_length([First | Rest]) ->\n 1 + list_length(Rest).\n```\n\nCompile and test:\n\n```erlang\n28> c(tut4).\n{ok,tut4}\n29> tut4:list_length([1,2,3,4,5,6,7]).\n7\n```\n\nExplanation:\n\n```erlang\nlist_length([]) ->\n 0;\n```\n\nThe length of an empty list is obviously 0.\n\n```erlang\nlist_length([First | Rest]) ->\n 1 + list_length(Rest).\n```\n\nThe length of a list with the first element `First` and the remaining elements\n`Rest` is 1 + the length of `Rest`.\n\n(Advanced readers only: This is not tail recursive, there is a better way to\nwrite this function.)\n\nIn general, tuples are used where \"records\" or \"structs\" are used in other\nlanguages. Also, lists are used when representing things with varying sizes,\nthat is, where linked lists are used in other languages.\n\nErlang does not have a string data type. Instead, strings can be represented by\nlists of Unicode characters. This implies for example that the list `[97,98,99]`\nis equivalent to `\"abc\"`. The Erlang shell is \"clever\" and guesses what list you\nmean and outputs it in what it thinks is the most appropriate form, for example:\n\n```erlang\n30> [97,98,99].\n\"abc\"\n```","ref":"seq_prog.html#lists"},{"type":"extras","title":"Maps - Sequential Programming","doc":"Maps are a set of key to value associations. These associations are encapsulated\nwith `#{` and `}`. To create an association from `\"key\"` to value `42`:\n\n```erlang\n> #{ \"key\" => 42 }.\n#{\"key\" => 42}\n```\n\nLet us jump straight into the deep end with an example using some interesting\nfeatures.\n\nThe following example shows how to calculate alpha blending using maps to\nreference color and alpha channels. Enter the code in a file named `color.erl`):\n\n```erlang\n-module(color).\n\n-export([new/4, blend/2]).\n\n-define(is_channel(V), (is_float(V) andalso V >= 0.0 andalso V =< 1.0)).\n\nnew(R,G,B,A) when ?is_channel(R), ?is_channel(G),\n ?is_channel(B), ?is_channel(A) ->\n #{red => R, green => G, blue => B, alpha => A}.\n\nblend(Src,Dst) ->\n blend(Src,Dst,alpha(Src,Dst)).\n\nblend(Src,Dst,Alpha) when Alpha > 0.0 ->\n Dst#{\n red := red(Src,Dst) / Alpha,\n green := green(Src,Dst) / Alpha,\n blue := blue(Src,Dst) / Alpha,\n alpha := Alpha\n };\nblend(_,Dst,_) ->\n Dst#{\n red := 0.0,\n green := 0.0,\n blue := 0.0,\n alpha := 0.0\n }.\n\nalpha(#{alpha := SA}, #{alpha := DA}) ->\n SA + DA*(1.0 - SA).\n\nred(#{red := SV, alpha := SA}, #{red := DV, alpha := DA}) ->\n SV*SA + DV*DA*(1.0 - SA).\ngreen(#{green := SV, alpha := SA}, #{green := DV, alpha := DA}) ->\n SV*SA + DV*DA*(1.0 - SA).\nblue(#{blue := SV, alpha := SA}, #{blue := DV, alpha := DA}) ->\n SV*SA + DV*DA*(1.0 - SA).\n```\n\nCompile and test:\n\n```erlang\n> c(color).\n{ok,color}\n> C1 = color:new(0.3,0.4,0.5,1.0).\n#{alpha => 1.0,blue => 0.5,green => 0.4,red => 0.3}\n> C2 = color:new(1.0,0.8,0.1,0.3).\n#{alpha => 0.3,blue => 0.1,green => 0.8,red => 1.0}\n> color:blend(C1,C2).\n#{alpha => 1.0,blue => 0.5,green => 0.4,red => 0.3}\n> color:blend(C2,C1).\n#{alpha => 1.0,blue => 0.38,green => 0.52,red => 0.51}\n```\n\nThis example warrants some explanation:\n\n```erlang\n-define(is_channel(V), (is_float(V) andalso V >= 0.0 andalso V =< 1.0)).\n```\n\nFirst a macro `is_channel` is defined to help with the guard tests. This is only\nhere for convenience and to reduce syntax cluttering. For more information about\nmacros, see [The Preprocessor](`e:system:macros.md`).\n\n```erlang\nnew(R,G,B,A) when ?is_channel(R), ?is_channel(G),\n ?is_channel(B), ?is_channel(A) ->\n #{red => R, green => G, blue => B, alpha => A}.\n```\n\nThe function `new/4` creates a new map term and lets the keys `red`, `green`,\n`blue`, and `alpha` be associated with an initial value. In this case, only\nfloat values between and including 0.0 and 1.0 are allowed, as ensured by the\n`?is_channel/1` macro for each argument. Only the `=>` operator is allowed when\ncreating a new map.\n\nBy calling `blend/2` on any color term created by `new/4`, the resulting color\ncan be calculated as determined by the two map terms.\n\nThe first thing `blend/2` does is to calculate the resulting alpha channel:\n\n```erlang\nalpha(#{alpha := SA}, #{alpha := DA}) ->\n SA + DA*(1.0 - SA).\n```\n\nThe value associated with key `alpha` is fetched for both arguments using the\n`:=` operator. The other keys in the map are ignored, only the key `alpha` is\nrequired and checked for.\n\nThis is also the case for functions `red/2`, `blue/2`, and `green/2`.\n\n```erlang\nred(#{red := SV, alpha := SA}, #{red := DV, alpha := DA}) ->\n SV*SA + DV*DA*(1.0 - SA).\n```\n\nThe difference here is that a check is made for two keys in each map argument.\nThe other keys are ignored.\n\nFinally, let us return the resulting color in `blend/3`:\n\n```erlang\nblend(Src,Dst,Alpha) when Alpha > 0.0 ->\n Dst#{\n red := red(Src,Dst) / Alpha,\n green := green(Src,Dst) / Alpha,\n blue := blue(Src,Dst) / Alpha,\n alpha := Alpha\n };\n```\n\nThe `Dst` map is updated with new channel values. The syntax for updating an\nexisting key with a new value is with the `:=` operator.","ref":"seq_prog.html#maps"},{"type":"extras","title":"Standard Modules and Manual Pages - Sequential Programming","doc":"Erlang has many standard modules to help you do things. For example, the module\n`m:io` contains many functions that help in doing formatted input/output. To look\nup information about standard modules, the command `h(..)` can be used at the\nerlang shell. Try the erlang shell command:\n\n```text\n1> h(io).\n\n\tio\n\n Standard I/O server interface functions.\n \n This module provides an interface to standard Erlang I/O servers. The output\n functions all return `ok` if they are successful, or exit if they are not.\n ...\n```\n\nIf this does not work on your system, the documentation is included as HTML in\nthe Erlang/OTP release. You can also read the documentation as HTML or download\nit as epub from .","ref":"seq_prog.html#standard-modules-and-manual-pages"},{"type":"extras","title":"Writing Output to a Terminal - Sequential Programming","doc":"It is nice to be able to do formatted output in examples, so the next example\nshows a simple way to use the `io:format/2` function. Like all other exported\nfunctions, you can test the `io:format/2` function in the shell:\n\n```erlang\n31> io:format(\"hello world~n\", []).\nhello world\nok\n32> io:format(\"this outputs one Erlang term: ~w~n\", [hello]).\nthis outputs one Erlang term: hello\nok\n33> io:format(\"this outputs two Erlang terms: ~w~w~n\", [hello, world]).\nthis outputs two Erlang terms: helloworld\nok\n34> io:format(\"this outputs two Erlang terms: ~w ~w~n\", [hello, world]).\nthis outputs two Erlang terms: hello world\nok\n```\n\nThe function `io:format/2` (that is, `format` with two arguments) takes two lists.\nThe first one is nearly always a list written between `\" \"`. This list is printed\nout as it is, except that each `~w` is replaced by a term taken in order from the\nsecond list. Each ~n is replaced by a new line. The `io:format/2` function\nitself returns the atom `ok` if everything goes as planned. Like other functions\nin Erlang, it crashes if an error occurs. This is not a fault in Erlang, it is a\ndeliberate policy. Erlang has sophisticated mechanisms to handle errors which\nare shown later. As an exercise, try to make `io:format/2` crash, it should not be\ndifficult. But notice that although `io:format/2` crashes, the Erlang shell itself\ndoes not crash.","ref":"seq_prog.html#writing-output-to-a-terminal"},{"type":"extras","title":"A Larger Example - Sequential Programming","doc":"Now for a larger example to consolidate what you have learnt so far. Assume that\nyou have a list of temperature readings from a number of cities in the world.\nSome of them are in Celsius and some in Fahrenheit (as in the previous list).\nFirst let us convert them all to Celsius, then let us print the data neatly.\n\n```erlang\n%% This module is in file tut5.erl\n\n-module(tut5).\n-export([format_temps/1]).\n\n%% Only this function is exported\nformat_temps([])-> % No output for an empty list\n ok;\nformat_temps([City | Rest]) ->\n print_temp(convert_to_celsius(City)),\n format_temps(Rest).\n\nconvert_to_celsius({Name, {c, Temp}}) -> % No conversion needed\n {Name, {c, Temp}};\nconvert_to_celsius({Name, {f, Temp}}) -> % Do the conversion\n {Name, {c, (Temp - 32) * 5 / 9}}.\n\nprint_temp({Name, {c, Temp}}) ->\n io:format(\"~-15w ~w c~n\", [Name, Temp]).\n```\n\n```erlang\n35> c(tut5).\n{ok,tut5}\n36> tut5:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},\n{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).\nmoscow -10 c\ncape_town 21.11111111111111 c\nstockholm -4 c\nparis -2.2222222222222223 c\nlondon 2.2222222222222223 c\nok\n```\n\nBefore looking at how this program works, notice that a few comments are added\nto the code. A comment starts with a %-character and goes on to the end of the\nline. Notice also that the `-export([format_temps/1]).` line only includes the\nfunction `format_temps/1`. The other functions are _local_ functions, that is,\nthey are not visible from outside the module `tut5`.\n\nNotice also that when testing the program from the shell, the input is spread\nover two lines as the line was too long.\n\nWhen `format_temps` is called the first time, `City` gets the value\n`{moscow,{c,-10}}` and `Rest` is the rest of the list. So the function\n`print_temp(convert_to_celsius({moscow,{c,-10}}))` is called.\n\nHere is a function call as `convert_to_celsius({moscow,{c,-10}})` as the\nargument to the function `print_temp`. When function calls are _nested_ like\nthis, they execute (evaluate) from the inside out. That is, first\n`convert_to_celsius({moscow,{c,-10}})` is evaluated, which gives the value\n`{moscow,{c,-10}}` as the temperature is already in Celsius. Then\n`print_temp({moscow,{c,-10}})` is evaluated. The function `convert_to_celsius`\nworks in a similar way to the `convert_length` function in the previous example.\n\n`print_temp` simply calls `io:format` in a similar way to what has been\ndescribed above. Notice that `~-15w` says to print the \"term\" with a field length\n(width) of 15 and left justify it. (see `io:fwrite/1` manual page in STDLIB).\n\nNow `format_temps(Rest)` is called with the rest of the list as an argument.\nThis way of doing things is similar to the loop constructs in other languages.\n(Yes, this is recursion, but do not let that worry you.) So the same\n`format_temps` function is called again, this time `City` gets the value\n`{cape_town,{f,70}}` and the same procedure is repeated as before. This is done\nuntil the list becomes empty, that is [], which causes the first clause\n`format_temps([])` to match. This simply returns (results in) the atom `ok`, so\nthe program ends.","ref":"seq_prog.html#a-larger-example"},{"type":"extras","title":"Matching, Guards, and Scope of Variables - Sequential Programming","doc":"It can be useful to find the maximum and minimum temperature in lists like this.\nBefore extending the program to do this, let us look at functions for finding\nthe maximum value of the elements in a list:\n\n```erlang\n-module(tut6).\n-export([list_max/1]).\n\nlist_max([Head|Rest]) ->\n list_max(Rest, Head).\n\nlist_max([], Res) ->\n Res;\nlist_max([Head|Rest], Result_so_far) when Head > Result_so_far ->\n list_max(Rest, Head);\nlist_max([Head|Rest], Result_so_far) ->\n list_max(Rest, Result_so_far).\n```\n\n```erlang\n37> c(tut6).\n{ok,tut6}\n38> tut6:list_max([1,2,3,4,5,7,4,3,2,1]).\n7\n```\n\nFirst notice that two functions have the same name, `list_max`. However, each of\nthese takes a different number of arguments (parameters). In Erlang these are\nregarded as completely different functions. Where you need to distinguish\nbetween these functions, you write Name/Arity, where Name is the function name\nand Arity is the number of arguments, in this case `list_max/1` and\n`list_max/2`.\n\nIn this example you walk through a list \"carrying\" a value, in this case\n`Result_so_far`. `list_max/1` simply assumes that the max value of the list is\nthe head of the list and calls `list_max/2` with the rest of the list and the\nvalue of the head of the list. In the above this would be\n`list_max([2,3,4,5,7,4,3,2,1],1)`. If you tried to use `list_max/1` with an\nempty list or tried to use it with something that is not a list at all, you\nwould cause an error. Notice that the Erlang philosophy is not to handle errors\nof this type in the function they occur, but to do so elsewhere. More about this\nlater.\n\nIn `list_max/2`, you walk down the list and use `Head` instead of\n`Result_so_far` when `Head` > `Result_so_far`. `when` is a special word used\nbefore the -> in the function to say that you only use this part of the function\nif the test that follows is true. A test of this type is called _guard_. If the\nguard is false (that is, the guard fails), the next part of the function is\ntried. In this case, if `Head` is not greater than `Result_so_far`, then it must\nbe smaller or equal to it. This means that a guard on the next part of the\nfunction is not needed.\n\nSome useful operators in guards are:\n\n- `<` less than\n- `>` greater than\n- `==` equal\n- `>=` greater or equal\n- `=<` less or equal\n- `/=` not equal\n\n(see [Guard Sequences](`e:system:expressions.md`)).\n\nTo change the above program to one that works out the minimum value of the\nelement in a list, you only need to write . (But it would be wise\nto change the name of the function to `list_min`.)\n\nEarlier it was mentioned that a variable can only be given a value once in its\nscope. In the above you see that `Result_so_far` is given several values. This\nis OK since every time you call `list_max/2` you create a new scope and one can\nregard `Result_so_far` as a different variable in each scope.\n\nAnother way of creating and giving a variable a value is by using the match\noperator = . So if you write `M = 5`, a variable called `M` is created with the\nvalue 5. If, in the same scope, you then write `M = 6`, an error is returned.\nTry this out in the shell:\n\n```erlang\n39> M = 5.\n5\n40> M = 6.\n** exception error: no match of right hand side value 6\n41> M = M + 1.\n** exception error: no match of right hand side value 6\n42> N = M + 1.\n6\n```\n\nThe use of the match operator is particularly useful for pulling apart Erlang\nterms and creating new ones.\n\n```erlang\n43> {X, Y} = {paris, {f, 28}}.\n{paris,{f,28}}\n44> X.\nparis\n45> Y.\n{f,28}\n```\n\nHere `X` gets the value `paris` and `Y` the value `{f,28}`.\n\nIf you try to do the same again with another city, an error is returned:\n\n```erlang\n46> {X, Y} = {london, {f, 36}}.\n** exception error: no match of right hand side value {london,{f,36}}\n```\n\nVariables can also be used to improve the readability of programs. For example,\nin function `list_max/2` above, you can write:\n\n```erlang\nlist_max([Head|Rest], Result_so_far) when Head > Result_so_far ->\n New_result_far = Head,\n list_max(Rest, New_result_far);\n```\n\nThis is possibly a little clearer.","ref":"seq_prog.html#matching-guards-and-scope-of-variables"},{"type":"extras","title":"More About Lists - Sequential Programming","doc":"Remember that the `|` operator can be used to get the head of a list:\n\n```erlang\n47> [M1|T1] = [paris, london, rome].\n[paris,london,rome]\n48> M1.\nparis\n49> T1.\n[london,rome]\n```\n\nThe `|` operator can also be used to add a head to a list:\n\n```erlang\n50> L1 = [madrid | T1].\n[madrid,london,rome]\n51> L1.\n[madrid,london,rome]\n```\n\nNow an example of this when working with lists - reversing the order of a list:\n\n```erlang\n-module(tut8).\n\n-export([reverse/1]).\n\nreverse(List) ->\n reverse(List, []).\n\nreverse([Head | Rest], Reversed_List) ->\n reverse(Rest, [Head | Reversed_List]);\nreverse([], Reversed_List) ->\n Reversed_List.\n```\n\n```erlang\n52> c(tut8).\n{ok,tut8}\n53> tut8:reverse([1,2,3]).\n[3,2,1]\n```\n\nConsider how `Reversed_List` is built. It starts as [], then successively the\nheads are taken off of the list to be reversed and added to the the\n`Reversed_List`, as shown in the following:\n\n```erlang\nreverse([1|2,3], []) =>\n reverse([2,3], [1|[]])\n\nreverse([2|3], [1]) =>\n reverse([3], [2|[1])\n\nreverse([3|[]], [2,1]) =>\n reverse([], [3|[2,1]])\n\nreverse([], [3,2,1]) =>\n [3,2,1]\n```\n\nThe module `lists` contains many functions for manipulating lists, for example,\nfor reversing them. So before writing a list-manipulating function it is a good\nidea to check if one not already is written for you (see the `m:lists` manual\npage in STDLIB).\n\nNow let us get back to the cities and temperatures, but take a more structured\napproach this time. First let us convert the whole list to Celsius as follows:\n\n```erlang\n-module(tut7).\n-export([format_temps/1]).\n\nformat_temps(List_of_cities) ->\n convert_list_to_c(List_of_cities).\n\nconvert_list_to_c([{Name, {f, F}} | Rest]) ->\n Converted_City = {Name, {c, (F -32)* 5 / 9}},\n [Converted_City | convert_list_to_c(Rest)];\n\nconvert_list_to_c([City | Rest]) ->\n [City | convert_list_to_c(Rest)];\n\nconvert_list_to_c([]) ->\n [].\n```\n\nTest the function:\n\n```erlang\n54> c(tut7).\n{ok, tut7}.\n55> tut7:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},\n{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).\n[{moscow,{c,-10}},\n {cape_town,{c,21.11111111111111}},\n {stockholm,{c,-4}},\n {paris,{c,-2.2222222222222223}},\n {london,{c,2.2222222222222223}}]\n```\n\nExplanation:\n\n```erlang\nformat_temps(List_of_cities) ->\n convert_list_to_c(List_of_cities).\n```\n\nHere `format_temps/1` calls `convert_list_to_c/1`. `convert_list_to_c/1` takes\noff the head of the `List_of_cities`, converts it to Celsius if needed. The `|`\noperator is used to add the (maybe) converted to the converted rest of the list:\n\n```erlang\n[Converted_City | convert_list_to_c(Rest)];\n```\n\nor:\n\n```erlang\n[City | convert_list_to_c(Rest)];\n```\n\nThis is done until the end of the list is reached, that is, the list is empty:\n\n```erlang\nconvert_list_to_c([]) ->\n [].\n```\n\nNow when the list is converted, a function to print it is added:\n\n```erlang\n-module(tut7).\n-export([format_temps/1]).\n\nformat_temps(List_of_cities) ->\n Converted_List = convert_list_to_c(List_of_cities),\n print_temp(Converted_List).\n\nconvert_list_to_c([{Name, {f, F}} | Rest]) ->\n Converted_City = {Name, {c, (F -32)* 5 / 9}},\n [Converted_City | convert_list_to_c(Rest)];\n\nconvert_list_to_c([City | Rest]) ->\n [City | convert_list_to_c(Rest)];\n\nconvert_list_to_c([]) ->\n [].\n\nprint_temp([{Name, {c, Temp}} | Rest]) ->\n io:format(\"~-15w ~w c~n\", [Name, Temp]),\n print_temp(Rest);\nprint_temp([]) ->\n ok.\n```\n\n```erlang\n56> c(tut7).\n{ok,tut7}\n57> tut7:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},\n{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).\nmoscow -10 c\ncape_town 21.11111111111111 c\nstockholm -4 c\nparis -2.2222222222222223 c\nlondon 2.2222222222222223 c\nok\n```\n\nNow a function has to be added to find the cities with the maximum and minimum\ntemperatures. The following program is not the most efficient way of doing this\nas you walk through the list of cities four times. But it is better to first\nstrive for clarity and correctness and to make programs efficient only if\nneeded.\n\n```erlang\n-module(tut7).\n-export([format_temps/1]).\n\nformat_temps(List_of_cities) ->\n Converted_List = convert_list_to_c(List_of_cities),\n print_temp(Converted_List),\n {Max_city, Min_city} = find_max_and_min(Converted_List),\n print_max_and_min(Max_city, Min_city).\n\nconvert_list_to_c([{Name, {f, Temp}} | Rest]) ->\n Converted_City = {Name, {c, (Temp -32)* 5 / 9}},\n [Converted_City | convert_list_to_c(Rest)];\n\nconvert_list_to_c([City | Rest]) ->\n [City | convert_list_to_c(Rest)];\n\nconvert_list_to_c([]) ->\n [].\n\nprint_temp([{Name, {c, Temp}} | Rest]) ->\n io:format(\"~-15w ~w c~n\", [Name, Temp]),\n print_temp(Rest);\nprint_temp([]) ->\n ok.\n\nfind_max_and_min([City | Rest]) ->\n find_max_and_min(Rest, City, City).\n\nfind_max_and_min([{Name, {c, Temp}} | Rest],\n {Max_Name, {c, Max_Temp}},\n {Min_Name, {c, Min_Temp}}) ->\n if\n Temp > Max_Temp ->\n Max_City = {Name, {c, Temp}}; % Change\n true ->\n Max_City = {Max_Name, {c, Max_Temp}} % Unchanged\n end,\n if\n Temp \n Min_City = {Name, {c, Temp}}; % Change\n true ->\n Min_City = {Min_Name, {c, Min_Temp}} % Unchanged\n end,\n find_max_and_min(Rest, Max_City, Min_City);\n\nfind_max_and_min([], Max_City, Min_City) ->\n {Max_City, Min_City}.\n\nprint_max_and_min({Max_name, {c, Max_temp}}, {Min_name, {c, Min_temp}}) ->\n io:format(\"Max temperature was ~w c in ~w~n\", [Max_temp, Max_name]),\n io:format(\"Min temperature was ~w c in ~w~n\", [Min_temp, Min_name]).\n```\n\n```erlang\n58> c(tut7).\n{ok, tut7}\n59> tut7:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},\n{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).\nmoscow -10 c\ncape_town 21.11111111111111 c\nstockholm -4 c\nparis -2.2222222222222223 c\nlondon 2.2222222222222223 c\nMax temperature was 21.11111111111111 c in cape_town\nMin temperature was -10 c in moscow\nok\n```","ref":"seq_prog.html#more-about-lists"},{"type":"extras","title":"If and Case - Sequential Programming","doc":"The function `find_max_and_min` works out the maximum and minimum temperature. A\nnew construct, `if`, is introduced here. If works as follows:\n\n```c\nif\n Condition 1 ->\n Action 1;\n Condition 2 ->\n Action 2;\n Condition 3 ->\n Action 3;\n Condition 4 ->\n Action 4\nend\n```\n\nNotice that there is no `;` before `end`. Conditions do the same as guards, that\nis, tests that succeed or fail. Erlang starts at the top and tests until it\nfinds a condition that succeeds. Then it evaluates (performs) the action\nfollowing the condition and ignores all other conditions and actions before the\n`end`. If no condition matches, a run-time failure occurs. A condition that\nalways succeeds is the atom `true`. This is often used last in an `if`, meaning,\ndo the action following the `true` if all other conditions have failed.\n\nThe following is a short program to show the workings of `if`.\n\n```erlang\n-module(tut9).\n-export([test_if/2]).\n\ntest_if(A, B) ->\n if\n A == 5 ->\n io:format(\"A == 5~n\", []),\n a_equals_5;\n B == 6 ->\n io:format(\"B == 6~n\", []),\n b_equals_6;\n A == 2, B == 3 -> %That is A equals 2 and B equals 3\n io:format(\"A == 2, B == 3~n\", []),\n a_equals_2_b_equals_3;\n A == 1 ; B == 7 -> %That is A equals 1 or B equals 7\n io:format(\"A == 1 ; B == 7~n\", []),\n a_equals_1_or_b_equals_7\n end.\n```\n\nTesting this program gives:\n\n```erlang\n60> c(tut9).\n{ok,tut9}\n61> tut9:test_if(5,33).\nA == 5\na_equals_5\n62> tut9:test_if(33,6).\nB == 6\nb_equals_6\n63> tut9:test_if(2, 3).\nA == 2, B == 3\na_equals_2_b_equals_3\n64> tut9:test_if(1, 33).\nA == 1 ; B == 7\na_equals_1_or_b_equals_7\n65> tut9:test_if(33, 7).\nA == 1 ; B == 7\na_equals_1_or_b_equals_7\n66> tut9:test_if(33, 33).\n** exception error: no true branch found when evaluating an if expression\n in function tut9:test_if/2 (tut9.erl, line 5)\n```\n\nNotice that `tut9:test_if(33,33)` does not cause any condition to succeed. This\nleads to the run time error `if_clause`, here nicely formatted by the shell. See\n[Guard Sequences](`e:system:expressions.md`) for details of the many guard tests\navailable.\n\n`case` is another construct in Erlang. Recall that the `convert_length` function\nwas written as:\n\n```erlang\nconvert_length({centimeter, X}) ->\n {inch, X / 2.54};\nconvert_length({inch, Y}) ->\n {centimeter, Y * 2.54}.\n```\n\nThe same program can also be written as:\n\n```erlang\n-module(tut10).\n-export([convert_length/1]).\n\nconvert_length(Length) ->\n case Length of\n {centimeter, X} ->\n {inch, X / 2.54};\n {inch, Y} ->\n {centimeter, Y * 2.54}\n end.\n```\n\n```erlang\n67> c(tut10).\n{ok,tut10}\n68> tut10:convert_length({inch, 6}).\n{centimeter,15.24}\n69> tut10:convert_length({centimeter, 2.5}).\n{inch,0.984251968503937}\n```\n\nBoth `case` and `if` have _return values_, that is, in the above example `case`\nreturned either `{inch,X/2.54}` or `{centimeter,Y*2.54}`. The behaviour of\n`case` can also be modified by using guards. The following example clarifies\nthis. It tells us the length of a month, given the year. The year must be known,\nsince February has 29 days in a leap year.\n\n```erlang\n-module(tut11).\n-export([month_length/2]).\n\nmonth_length(Year, Month) ->\n %% All years divisible by 400 are leap\n %% Years divisible by 100 are not leap (except the 400 rule above)\n %% Years divisible by 4 are leap (except the 100 rule above)\n Leap = if\n trunc(Year / 400) * 400 == Year ->\n leap;\n trunc(Year / 100) * 100 == Year ->\n not_leap;\n trunc(Year / 4) * 4 == Year ->\n leap;\n true ->\n not_leap\n end,\n case Month of\n sep -> 30;\n apr -> 30;\n jun -> 30;\n nov -> 30;\n feb when Leap == leap -> 29;\n feb -> 28;\n jan -> 31;\n mar -> 31;\n may -> 31;\n jul -> 31;\n aug -> 31;\n oct -> 31;\n dec -> 31\n end.\n```\n\n```erlang\n70> c(tut11).\n{ok,tut11}\n71> tut11:month_length(2004, feb).\n29\n72> tut11:month_length(2003, feb).\n28\n73> tut11:month_length(1947, aug).\n31\n```","ref":"seq_prog.html#if-and-case"},{"type":"extras","title":"Built-In Functions (BIFs) - Sequential Programming","doc":"BIFs are functions that for some reason are built-in to the Erlang virtual\nmachine. BIFs often implement functionality that is impossible or is too\ninefficient to implement in Erlang. Some BIFs can be called using the function\nname only but they are by default belonging to the `erlang` module. For example,\nthe call to the BIF `trunc` below is equivalent to a call to `erlang:trunc`.\n\nAs shown, first it is checked if a year is leap. If a year is divisible by 400,\nit is a leap year. To determine this, first divide the year by 400 and use the\nBIF `trunc` (more about this later) to cut off any decimals. Then multiply by\n400 again and see if the same value is returned again. For example, year 2004:\n\n```erlang\n2004 / 400 = 5.01\ntrunc(5.01) = 5\n5 * 400 = 2000\n```\n\n2000 is not the same as 2004, so 2004 is not divisible by 400. Year 2000:\n\n```erlang\n2000 / 400 = 5.0\ntrunc(5.0) = 5\n5 * 400 = 2000\n```\n\nThat is, a leap year. The next two `trunc`\\-tests evaluate if the year is\ndivisible by 100 or 4 in the same way. The first `if` returns `leap` or\n`not_leap`, which lands up in the variable `Leap`. This variable is used in the\nguard for `feb` in the following `case` that tells us how long the month is.\n\nThis example showed the use of `trunc`. It is easier to use the Erlang operator\n`rem` that gives the remainder after division, for example:\n\n```erlang\n74> 2004 rem 400.\n4\n```\n\nSo instead of writing:\n\n```erlang\ntrunc(Year / 400) * 400 == Year ->\n leap;\n```\n\nit can be written:\n\n```erlang\nYear rem 400 == 0 ->\n leap;\n```\n\nThere are many other BIFs such as `trunc`. Only a few BIFs can be used in\nguards, and you cannot use functions you have defined yourself in guards. (see\n[Guard Sequences](`e:system:expressions.md`)) (For advanced readers: This is to\nensure that guards do not have side effects.) Let us play with a few of these\nfunctions in the shell:\n\n```erlang\n75> trunc(5.6).\n5\n76> round(5.6).\n6\n77> length([a,b,c,d]).\n4\n78> float(5).\n5.0\n79> is_atom(hello).\ntrue\n80> is_atom(\"hello\").\nfalse\n81> is_tuple({paris, {c, 30}}).\ntrue\n82> is_tuple([paris, {c, 30}]).\nfalse\n```\n\nAll of these can be used in guards. Now for some BIFs that cannot be used in\nguards:\n\n```erlang\n83> atom_to_list(hello).\n\"hello\"\n84> list_to_atom(\"goodbye\").\ngoodbye\n85> integer_to_list(22).\n\"22\"\n```\n\nThese three BIFs do conversions that would be difficult (or impossible) to do in\nErlang.","ref":"seq_prog.html#built-in-functions-bifs"},{"type":"extras","title":"Higher-Order Functions (Funs) - Sequential Programming","doc":"Erlang, like most modern functional programming languages, has higher-order\nfunctions. Here is an example using the shell:\n\n```erlang\n86> Xf = fun(X) -> X * 2 end.\n#Fun \n87> Xf(5).\n10\n```\n\nHere is defined a function that doubles the value of a number and assigned this\nfunction to a variable. Thus `Xf(5)` returns value 10. Two useful functions when\nworking with lists are `foreach` and `map`, which are defined as follows:\n\n```erlang\nforeach(Fun, [First|Rest]) ->\n Fun(First),\n foreach(Fun, Rest);\nforeach(Fun, []) ->\n ok.\n\nmap(Fun, [First|Rest]) ->\n [Fun(First)|map(Fun,Rest)];\nmap(Fun, []) ->\n [].\n```\n\nThese two functions are provided in the standard module `lists`. `foreach` takes\na list and applies a fun to every element in the list. `map` creates a new list\nby applying a fun to every element in a list. Going back to the shell, `map` is\nused and a fun to add 3 to every element of a list:\n\n```erlang\n88> Add_3 = fun(X) -> X + 3 end.\n#Fun \n89> lists:map(Add_3, [1,2,3]).\n[4,5,6]\n```\n\nLet us (again) print the temperatures in a list of cities:\n\n```erlang\n90> Print_City = fun({City, {X, Temp}}) -> io:format(\"~-15w ~w ~w~n\",\n[City, X, Temp]) end.\n#Fun \n91> lists:foreach(Print_City, [{moscow, {c, -10}}, {cape_town, {f, 70}},\n{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).\nmoscow c -10\ncape_town f 70\nstockholm c -4\nparis f 28\nlondon f 36\nok\n```\n\nLet us now define a fun that can be used to go through a list of cities and\ntemperatures and transform them all to Celsius.\n\n```erlang\n-module(tut13).\n\n-export([convert_list_to_c/1]).\n\nconvert_to_c({Name, {f, Temp}}) ->\n {Name, {c, trunc((Temp - 32) * 5 / 9)}};\nconvert_to_c({Name, {c, Temp}}) ->\n {Name, {c, Temp}}.\n\nconvert_list_to_c(List) ->\n lists:map(fun convert_to_c/1, List).\n```\n\n```erlang\n92> tut13:convert_list_to_c([{moscow, {c, -10}}, {cape_town, {f, 70}},\n{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).\n[{moscow,{c,-10}},\n {cape_town,{c,21}},\n {stockholm,{c,-4}},\n {paris,{c,-2}},\n {london,{c,2}}]\n```\n\nThe `convert_to_c` function is the same as before, but here it is used as a fun:\n\n```erlang\nlists:map(fun convert_to_c/1, List)\n```\n\nWhen a function defined elsewhere is used as a fun, it can be referred to as\n`Function/Arity` (remember that `Arity` = number of arguments). So in the\n`map`\\-call `lists:map(fun convert_to_c/1, List)` is written. As shown,\n`convert_list_to_c` becomes much shorter and easier to understand.\n\nThe standard module `lists` also contains a function `sort(Fun, List)` where\n`Fun` is a fun with two arguments. This fun returns `true` if the first argument\nis less than the second argument, or else `false`. Sorting is added to the\n`convert_list_to_c`:\n\n```erlang\n-module(tut13).\n\n-export([convert_list_to_c/1]).\n\nconvert_to_c({Name, {f, Temp}}) ->\n {Name, {c, trunc((Temp - 32) * 5 / 9)}};\nconvert_to_c({Name, {c, Temp}}) ->\n {Name, {c, Temp}}.\n\nconvert_list_to_c(List) ->\n New_list = lists:map(fun convert_to_c/1, List),\n lists:sort(fun({_, {c, Temp1}}, {_, {c, Temp2}}) ->\n Temp1 c(tut13).\n{ok,tut13}\n94> tut13:convert_list_to_c([{moscow, {c, -10}}, {cape_town, {f, 70}},\n{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).\n[{moscow,{c,-10}},\n {stockholm,{c,-4}},\n {paris,{c,-2}},\n {london,{c,2}},\n {cape_town,{c,21}}]\n```\n\nIn `sort` the fun is used:\n\n```erlang\nfun({_, {c, Temp1}}, {_, {c, Temp2}}) -> Temp1 < Temp2 end,\n```\n\nHere the concept of an _anonymous variable_ `_` is introduced. This is simply\nshorthand for a variable that gets a value, but the value is ignored. This can\nbe used anywhere suitable, not just in funs. `Temp1 < Temp2` returns `true` if\n`Temp1` is less than `Temp2`.","ref":"seq_prog.html#higher-order-functions-funs"},{"type":"extras","title":"Concurrent Programming","doc":"\n# Concurrent Programming","ref":"conc_prog.html"},{"type":"extras","title":"Processes - Concurrent Programming","doc":"One of the main reasons for using Erlang instead of other functional languages\nis Erlang's ability to handle concurrency and distributed programming. By\nconcurrency is meant programs that can handle several threads of execution at\nthe same time. For example, modern operating systems allow you to use a word\nprocessor, a spreadsheet, a mail client, and a print job all running at the same\ntime. Each processor (CPU) in the system is probably only handling one thread\n(or job) at a time, but it swaps between the jobs at such a rate that it gives\nthe illusion of running them all at the same time. It is easy to create parallel\nthreads of execution in an Erlang program and to allow these threads to\ncommunicate with each other. In Erlang, each thread of execution is called a\n_process_.\n\n(Aside: the term \"process\" is usually used when the threads of execution share\nno data with each other and the term \"thread\" when they share data in some way.\nThreads of execution in Erlang share no data, that is why they are called\nprocesses).\n\nThe Erlang BIF `spawn` is used to create a new process:\n`spawn(Module, Exported_Function, List of Arguments)`. Consider the following\nmodule:\n\n```erlang\n-module(tut14).\n\n-export([start/0, say_something/2]).\n\nsay_something(What, 0) ->\n done;\nsay_something(What, Times) ->\n io:format(\"~p~n\", [What]),\n say_something(What, Times - 1).\n\nstart() ->\n spawn(tut14, say_something, [hello, 3]),\n spawn(tut14, say_something, [goodbye, 3]).\n```\n\n```erlang\n5> c(tut14).\n{ok,tut14}\n6> tut14:say_something(hello, 3).\nhello\nhello\nhello\ndone\n```\n\nAs shown, the function `say_something` writes its first argument the number of\ntimes specified by second argument. The function `start` starts two Erlang\nprocesses, one that writes \"hello\" three times and one that writes \"goodbye\"\nthree times. Both processes use the function `say_something`. Notice that a\nfunction used in this way by `spawn`, to start a process, must be exported from\nthe module (that is, in the `-export` at the start of the module).\n\n```erlang\n9> tut14:start().\nhello\ngoodbye\n<0.63.0>\nhello\ngoodbye\nhello\ngoodbye\n```\n\nNotice that it did not write \"hello\" three times and then \"goodbye\" three times.\nInstead, the first process wrote a \"hello\", the second a \"goodbye\", the first\nanother \"hello\" and so forth. But where did the `<0.63.0>` come from? The return\nvalue of a function is the return value of the last \"thing\" in the function. The\nlast thing in the function `start` is\n\n```erlang\nspawn(tut14, say_something, [goodbye, 3]).\n```\n\n`spawn` returns a _process identifier_, or _pid_, which uniquely identifies the\nprocess. So `<0.63.0>` is the pid of the `spawn` function call above. The next\nexample shows how to use pids.\n\nNotice also that ~p is used instead of ~w in `io:format/2`. To quote [the manual](`m:io#tilde_p`):\n\n> ~p Writes the data with standard syntax in the same way as ~w, but breaks terms\n> whose printed representation is longer than one line into many lines and indents\n> each line sensibly. It also tries to detect flat lists of printable characters and\n> to output these as strings","ref":"conc_prog.html#processes"},{"type":"extras","title":"Message Passing - Concurrent Programming","doc":"In the following example two processes are created and they send messages to\neach other a number of times.\n\n```erlang\n-module(tut15).\n\n-export([start/0, ping/2, pong/0]).\n\nping(0, Pong_PID) ->\n Pong_PID ! finished,\n io:format(\"ping finished~n\", []);\n\nping(N, Pong_PID) ->\n Pong_PID ! {ping, self()},\n receive\n pong ->\n io:format(\"Ping received pong~n\", [])\n end,\n ping(N - 1, Pong_PID).\n\npong() ->\n receive\n finished ->\n io:format(\"Pong finished~n\", []);\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong()\n end.\n\nstart() ->\n Pong_PID = spawn(tut15, pong, []),\n spawn(tut15, ping, [3, Pong_PID]).\n```\n\n```erlang\n1> c(tut15).\n{ok,tut15}\n2> tut15: start().\n<0.36.0>\nPong received ping\nPing received pong\nPong received ping\nPing received pong\nPong received ping\nPing received pong\nping finished\nPong finished\n```\n\nThe function `start` first creates a process, let us call it \"pong\":\n\n```erlang\nPong_PID = spawn(tut15, pong, [])\n```\n\nThis process executes `tut15:pong()`. `Pong_PID` is the process identity of the\n\"pong\" process. The function `start` now creates another process \"ping\":\n\n```erlang\nspawn(tut15, ping, [3, Pong_PID]),\n```\n\nThis process executes:\n\n```erlang\ntut15:ping(3, Pong_PID)\n```\n\n`<0.36.0>` is the return value from the `start` function.\n\nThe process \"pong\" now does:\n\n```erlang\nreceive\n finished ->\n io:format(\"Pong finished~n\", []);\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong()\nend.\n```\n\nThe `receive` construct is used to allow processes to wait for messages from\nother processes. It has the following format:\n\n```erlang\nreceive\n pattern1 ->\n actions1;\n pattern2 ->\n actions2;\n ....\n patternN\n actionsN\nend.\n```\n\nNotice there is no \";\" before the `end`.\n\nMessages between Erlang processes are simply valid Erlang terms. That is, they\ncan be lists, tuples, integers, atoms, pids, and so on.\n\nEach process has its own input queue for messages it receives. New messages\nreceived are put at the end of the queue. When a process executes a `receive`,\nthe first message in the queue is matched against the first pattern in the\n`receive`. If this matches, the message is removed from the queue and the\nactions corresponding to the pattern are executed.\n\nHowever, if the first pattern does not match, the second pattern is tested. If\nthis matches, the message is removed from the queue and the actions\ncorresponding to the second pattern are executed. If the second pattern does not\nmatch, the third is tried and so on until there are no more patterns to test. If\nthere are no more patterns to test, the first message is kept in the queue and\nthe second message is tried instead. If this matches any pattern, the\nappropriate actions are executed and the second message is removed from the\nqueue (keeping the first message and any other messages in the queue). If the\nsecond message does not match, the third message is tried, and so on, until the\nend of the queue is reached. If the end of the queue is reached, the process\nblocks (stops execution) and waits until a new message is received and this\nprocedure is repeated.\n\nThe Erlang implementation is \"clever\" and minimizes the number of times each\nmessage is tested against the patterns in each `receive`.\n\nNow back to the ping pong example.\n\n\"Pong\" is waiting for messages. If the atom `finished` is received, \"pong\"\nwrites \"Pong finished\" to the output and, as it has nothing more to do,\nterminates. If it receives a message with the format:\n\n```erlang\n{ping, Ping_PID}\n```\n\nit writes \"Pong received ping\" to the output and sends the atom `pong` to the\nprocess \"ping\":\n\n```erlang\nPing_PID ! pong\n```\n\nNotice how the operator \"\\!\" is used to send messages. The syntax of \"\\!\" is:\n\n```erlang\nPid ! Message\n```\n\nThat is, `Message` (any Erlang term) is sent to the process with identity `Pid`.\n\nAfter sending the message `pong` to the process \"ping\", \"pong\" calls the `pong`\nfunction again, which causes it to get back to the `receive` again and wait for\nanother message.\n\nNow let us look at the process \"ping\". Recall that it was started by executing:\n\n```erlang\ntut15:ping(3, Pong_PID)\n```\n\nLooking at the function `ping/2`, the second clause of `ping/2` is executed\nsince the value of the first argument is 3 (not 0) (first clause head is\n`ping(0,Pong_PID)`, second clause head is `ping(N,Pong_PID)`, so `N` becomes 3).\n\nThe second clause sends a message to \"pong\":\n\n```erlang\nPong_PID ! {ping, self()},\n```\n\n`self/0` returns the pid of the process that executes `self/0`, in this case the\npid of \"ping\". (Recall the code for \"pong\", this lands up in the variable\n`Ping_PID` in the `receive` previously explained.)\n\n\"Ping\" now waits for a reply from \"pong\":\n\n```erlang\nreceive\n pong ->\n io:format(\"Ping received pong~n\", [])\nend,\n```\n\nIt writes \"Ping received pong\" when this reply arrives, after which \"ping\" calls\nthe `ping` function again.\n\n```erlang\nping(N - 1, Pong_PID)\n```\n\n`N-1` causes the first argument to be decremented until it becomes 0. When this\noccurs, the first clause of `ping/2` is executed:\n\n```erlang\nping(0, Pong_PID) ->\n Pong_PID ! finished,\n io:format(\"ping finished~n\", []);\n```\n\nThe atom `finished` is sent to \"pong\" (causing it to terminate as described\nabove) and \"ping finished\" is written to the output. \"Ping\" then terminates as\nit has nothing left to do.","ref":"conc_prog.html#message-passing"},{"type":"extras","title":"Registered Process Names - Concurrent Programming","doc":"In the above example, \"pong\" was first created to be able to give the identity\nof \"pong\" when \"ping\" was started. That is, in some way \"ping\" must be able to\nknow the identity of \"pong\" to be able to send a message to it. Sometimes\nprocesses which need to know each other's identities are started independently\nof each other. Erlang thus provides a mechanism for processes to be given names\nso that these names can be used as identities instead of pids. This is done by\nusing the `register` BIF:\n\n```erlang\nregister(some_atom, Pid)\n```\n\nLet us now rewrite the ping pong example using this and give the name `pong` to\nthe \"pong\" process:\n\n```erlang\n-module(tut16).\n\n-export([start/0, ping/1, pong/0]).\n\nping(0) ->\n pong ! finished,\n io:format(\"ping finished~n\", []);\n\nping(N) ->\n pong ! {ping, self()},\n receive\n pong ->\n io:format(\"Ping received pong~n\", [])\n end,\n ping(N - 1).\n\npong() ->\n receive\n finished ->\n io:format(\"Pong finished~n\", []);\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong()\n end.\n\nstart() ->\n register(pong, spawn(tut16, pong, [])),\n spawn(tut16, ping, [3]).\n```\n\n```erlang\n2> c(tut16).\n{ok, tut16}\n3> tut16:start().\n<0.38.0>\nPong received ping\nPing received pong\nPong received ping\nPing received pong\nPong received ping\nPing received pong\nping finished\nPong finished\n```\n\nHere the `start/0` function,\n\n```erlang\nregister(pong, spawn(tut16, pong, [])),\n```\n\nboth spawns the \"pong\" process and gives it the name `pong`. In the \"ping\"\nprocess, messages can be sent to `pong` by:\n\n```erlang\npong ! {ping, self()},\n```\n\n`ping/2` now becomes `ping/1` as the argument `Pong_PID` is not needed.","ref":"conc_prog.html#registered-process-names"},{"type":"extras","title":"Distributed Programming - Concurrent Programming","doc":"Let us rewrite the ping pong program with \"ping\" and \"pong\" on different\ncomputers. First a few things are needed to set up to get this to work. The\ndistributed Erlang implementation provides a very basic authentication mechanism\nto prevent unintentional access to an Erlang system on another computer. Erlang\nsystems which talk to each other must have the same _magic cookie_. The easiest\nway to achieve this is by having a file called `.erlang.cookie` in your home\ndirectory on all machines on which you are going to run Erlang systems\ncommunicating with each other:\n\n- On Windows systems the home directory is the directory pointed out by the\n environment variable $HOME - you may need to set this.\n- On Linux or UNIX you can safely ignore this and simply create a file called\n `.erlang.cookie` in the directory you get to after executing the command `cd`\n without any argument.\n\nThe `.erlang.cookie` file is to contain a line with the same atom. For example,\non Linux or UNIX, in the OS shell:\n\n```text\n$ cd\n$ cat > .erlang.cookie\nthis_is_very_secret\n$ chmod 400 .erlang.cookie\n```\n\nThe `chmod` above makes the `.erlang.cookie` file accessible only by the owner\nof the file. This is a requirement.\n\nWhen you start an Erlang system that is going to talk to other Erlang systems,\nyou must give it a name, for example:\n\n```text\n$ erl -sname my_name\n```\n\nWe will see more details of this later. If you want to experiment with\ndistributed Erlang, but you only have one computer to work on, you can start two\nseparate Erlang systems on the same computer but give them different names. Each\nErlang system running on a computer is called an _Erlang node_.\n\n(Note: `erl -sname` assumes that all nodes are in the same IP domain and we can\nuse only the first component of the IP address, if we want to use nodes in\ndifferent domains we use `-name` instead, but then all IP address must be given\nin full.)\n\nHere is the ping pong example modified to run on two separate nodes:\n\n```erlang\n-module(tut17).\n\n-export([start_ping/1, start_pong/0, ping/2, pong/0]).\n\nping(0, Pong_Node) ->\n {pong, Pong_Node} ! finished,\n io:format(\"ping finished~n\", []);\n\nping(N, Pong_Node) ->\n {pong, Pong_Node} ! {ping, self()},\n receive\n pong ->\n io:format(\"Ping received pong~n\", [])\n end,\n ping(N - 1, Pong_Node).\n\npong() ->\n receive\n finished ->\n io:format(\"Pong finished~n\", []);\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong()\n end.\n\nstart_pong() ->\n register(pong, spawn(tut17, pong, [])).\n\nstart_ping(Pong_Node) ->\n spawn(tut17, ping, [3, Pong_Node]).\n```\n\nLet us assume there are two computers called gollum and kosken. First a node is\nstarted on kosken, called ping, and then a node on gollum, called pong.\n\nOn kosken (on a Linux/UNIX system):\n\n```text\nkosken> erl -sname ping\nErlang (BEAM) emulator version 5.2.3.7 [hipe] [threads:0]\n\nEshell V5.2.3.7 (abort with ^G)\n(ping@kosken)1>\n```\n\nOn gollum:\n\n```text\ngollum> erl -sname pong\nErlang (BEAM) emulator version 5.2.3.7 [hipe] [threads:0]\n\nEshell V5.2.3.7 (abort with ^G)\n(pong@gollum)1>\n```\n\nNow the \"pong\" process on gollum is started:\n\n```erlang\n(pong@gollum)1> tut17:start_pong().\ntrue\n```\n\nAnd the \"ping\" process on kosken is started (from the code above you can see\nthat a parameter of the `start_ping` function is the node name of the Erlang\nsystem where \"pong\" is running):\n\n```erlang\n(ping@kosken)1> tut17:start_ping(pong@gollum).\n<0.37.0>\nPing received pong\nPing received pong\nPing received pong\nping finished\n```\n\nAs shown, the ping pong program has run. On the \"pong\" side:\n\n```erlang\n(pong@gollum)2> \nPong received ping\nPong received ping\nPong received ping\nPong finished\n(pong@gollum)2> \n```\n\nLooking at the `tut17` code, you see that the `pong` function itself is\nunchanged, the following lines work in the same way irrespective of on which\nnode the \"ping\" process is executes:\n\n```erlang\n{ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n```\n\nThus, Erlang pids contain information about where the process executes. So if\nyou know the pid of a process, the `!` operator can be used to send it a\nmessage disregarding if the process is on the same node or on a different node.\n\nA difference is how messages are sent to a registered process on another node:\n\n```erlang\n{pong, Pong_Node} ! {ping, self()},\n```\n\nA tuple `{registered_name,node_name}` is used instead of just the\n`registered_name`.\n\nIn the previous example, \"ping\" and \"pong\" were started from the shells of two\nseparate Erlang nodes. `spawn` can also be used to start processes in other\nnodes.\n\nThe next example is the ping pong program, yet again, but this time \"ping\" is\nstarted in another node:\n\n```erlang\n-module(tut18).\n\n-export([start/1, ping/2, pong/0]).\n\nping(0, Pong_Node) ->\n {pong, Pong_Node} ! finished,\n io:format(\"ping finished~n\", []);\n\nping(N, Pong_Node) ->\n {pong, Pong_Node} ! {ping, self()},\n receive\n pong ->\n io:format(\"Ping received pong~n\", [])\n end,\n ping(N - 1, Pong_Node).\n\npong() ->\n receive\n finished ->\n io:format(\"Pong finished~n\", []);\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong()\n end.\n\nstart(Ping_Node) ->\n register(pong, spawn(tut18, pong, [])),\n spawn(Ping_Node, tut18, ping, [3, node()]).\n```\n\nAssuming an Erlang system called ping (but not the \"ping\" process) has already\nbeen started on kosken, then on gollum this is done:\n\n```erlang\n(pong@gollum)1> tut18:start(ping@kosken).\n<3934.39.0>\nPong received ping\nPing received pong\nPong received ping\nPing received pong\nPong received ping\nPing received pong\nPong finished\nping finished\n```\n\nNotice that all the output is received on gollum. This is because the I/O system\nfinds out where the process is spawned from and sends all output there.","ref":"conc_prog.html#distributed-programming"},{"type":"extras","title":"A Larger Example - Concurrent Programming","doc":"Now for a larger example with a simple \"messenger\". The messenger is a program\nthat allows users to log in on different nodes and send simple messages to each\nother.\n\nBefore starting, notice the following:\n\n- This example only shows the message passing logic - no attempt has been made\n to provide a nice graphical user interface, although this can also be done in\n Erlang.\n- This sort of problem can be solved easier by use of the facilities in OTP,\n which also provide methods for updating code on the fly and so on (see\n [OTP Design Principles](`e:system:design_principles.md`)).\n- The first program contains some inadequacies regarding handling of nodes which\n disappear. These are corrected in a later version of the program.\n\nThe messenger is set up by allowing \"clients\" to connect to a central server and\nsay who and where they are. That is, a user does not need to know the name of\nthe Erlang node where another user is located to send a message.\n\nFile `messenger.erl`:\n\n[](){: #ex }\n\n```erlang\n%%% Message passing utility.\n%%% User interface:\n%%% logon(Name)\n%%% One user at a time can log in from each Erlang node in the\n%%% system messenger: and choose a suitable Name. If the Name\n%%% is already logged in at another node or if someone else is\n%%% already logged in at the same node, login will be rejected\n%%% with a suitable error message.\n%%% logoff()\n%%% Logs off anybody at that node\n%%% message(ToName, Message)\n%%% sends Message to ToName. Error messages if the user of this\n%%% function is not logged on or if ToName is not logged on at\n%%% any node.\n%%%\n%%% One node in the network of Erlang nodes runs a server which maintains\n%%% data about the logged on users. The server is registered as \"messenger\"\n%%% Each node where there is a user logged on runs a client process registered\n%%% as \"mess_client\"\n%%%\n%%% Protocol between the client processes and the server\n%%% ----------------------------------------------------\n%%%\n%%% To server: {ClientPid, logon, UserName}\n%%% Reply {messenger, stop, user_exists_at_other_node} stops the client\n%%% Reply {messenger, logged_on} logon was successful\n%%%\n%%% To server: {ClientPid, logoff}\n%%% Reply: {messenger, logged_off}\n%%%\n%%% To server: {ClientPid, logoff}\n%%% Reply: no reply\n%%%\n%%% To server: {ClientPid, message_to, ToName, Message} send a message\n%%% Reply: {messenger, stop, you_are_not_logged_on} stops the client\n%%% Reply: {messenger, receiver_not_found} no user with this name logged on\n%%% Reply: {messenger, sent} Message has been sent (but no guarantee)\n%%%\n%%% To client: {message_from, Name, Message},\n%%%\n%%% Protocol between the \"commands\" and the client\n%%% ----------------------------------------------\n%%%\n%%% Started: messenger:client(Server_Node, Name)\n%%% To client: logoff\n%%% To client: {message_to, ToName, Message}\n%%%\n%%% Configuration: change the server_node() function to return the\n%%% name of the node where the messenger server runs\n\n-module(messenger).\n-export([start_server/0, server/1, logon/1, logoff/0, message/2, client/2]).\n\n%%% Change the function below to return the name of the node where the\n%%% messenger server runs\nserver_node() ->\n messenger@super.\n\n%%% This is the server process for the \"messenger\"\n%%% the user list has the format [{ClientPid1, Name1},{ClientPid22, Name2},...]\nserver(User_List) ->\n receive\n {From, logon, Name} ->\n New_User_List = server_logon(From, Name, User_List),\n server(New_User_List);\n {From, logoff} ->\n New_User_List = server_logoff(From, User_List),\n server(New_User_List);\n {From, message_to, To, Message} ->\n server_transfer(From, To, Message, User_List),\n io:format(\"list is now: ~p~n\", [User_List]),\n server(User_List)\n end.\n\n%%% Start the server\nstart_server() ->\n register(messenger, spawn(messenger, server, [[]])).\n\n\n%%% Server adds a new user to the user list\nserver_logon(From, Name, User_List) ->\n %% check if logged on anywhere else\n case lists:keymember(Name, 2, User_List) of\n true ->\n From ! {messenger, stop, user_exists_at_other_node}, %reject logon\n User_List;\n false ->\n From ! {messenger, logged_on},\n [{From, Name} | User_List] %add user to the list\n end.\n\n%%% Server deletes a user from the user list\nserver_logoff(From, User_List) ->\n lists:keydelete(From, 1, User_List).\n\n\n%%% Server transfers a message between user\nserver_transfer(From, To, Message, User_List) ->\n %% check that the user is logged on and who he is\n case lists:keysearch(From, 1, User_List) of\n false ->\n From ! {messenger, stop, you_are_not_logged_on};\n {value, {From, Name}} ->\n server_transfer(From, Name, To, Message, User_List)\n end.\n%%% If the user exists, send the message\nserver_transfer(From, Name, To, Message, User_List) ->\n %% Find the receiver and send the message\n case lists:keysearch(To, 2, User_List) of\n false ->\n From ! {messenger, receiver_not_found};\n {value, {ToPid, To}} ->\n ToPid ! {message_from, Name, Message},\n From ! {messenger, sent}\n end.\n\n\n%%% User Commands\nlogon(Name) ->\n case whereis(mess_client) of\n undefined ->\n register(mess_client,\n spawn(messenger, client, [server_node(), Name]));\n _ -> already_logged_on\n end.\n\nlogoff() ->\n mess_client ! logoff.\n\nmessage(ToName, Message) ->\n case whereis(mess_client) of % Test if the client is running\n undefined ->\n not_logged_on;\n _ -> mess_client ! {message_to, ToName, Message},\n ok\nend.\n\n\n%%% The client process which runs on each server node\nclient(Server_Node, Name) ->\n {messenger, Server_Node} ! {self(), logon, Name},\n await_result(),\n client(Server_Node).\n\nclient(Server_Node) ->\n receive\n logoff ->\n {messenger, Server_Node} ! {self(), logoff},\n exit(normal);\n {message_to, ToName, Message} ->\n {messenger, Server_Node} ! {self(), message_to, ToName, Message},\n await_result();\n {message_from, FromName, Message} ->\n io:format(\"Message from ~p: ~p~n\", [FromName, Message])\n end,\n client(Server_Node).\n\n%%% wait for a response from the server\nawait_result() ->\n receive\n {messenger, stop, Why} -> % Stop the client\n io:format(\"~p~n\", [Why]),\n exit(normal);\n {messenger, What} -> % Normal response\n io:format(\"~p~n\", [What])\n end.\n```\n\nTo use this program, you need to:\n\n- Configure the `server_node()` function.\n- Copy the compiled code (`messenger.beam`) to the directory on each computer\n where you start Erlang.\n\nIn the following example using this program, nodes are started on four different\ncomputers. If you do not have that many machines available on your network, you\ncan start several nodes on the same machine.\n\nFour Erlang nodes are started up: messenger@super, c1@bilbo, c2@kosken,\nc3@gollum.\n\nFirst the server at messenger@super is started up:\n\n```erlang\n(messenger@super)1> messenger:start_server().\ntrue\n```\n\nNow Peter logs on at c1@bilbo:\n\n```erlang\n(c1@bilbo)1> messenger:logon(peter).\ntrue\nlogged_on\n```\n\nJames logs on at c2@kosken:\n\n```erlang\n(c2@kosken)1> messenger:logon(james).\ntrue\nlogged_on\n```\n\nAnd Fred logs on at c3@gollum:\n\n```erlang\n(c3@gollum)1> messenger:logon(fred).\ntrue\nlogged_on\n```\n\nNow Peter sends Fred a message:\n\n```erlang\n(c1@bilbo)2> messenger:message(fred, \"hello\").\nok\nsent\n```\n\nFred receives the message and sends a message to Peter and logs off:\n\n```erlang\nMessage from peter: \"hello\"\n(c3@gollum)2> messenger:message(peter, \"go away, I'm busy\").\nok\nsent\n(c3@gollum)3> messenger:logoff().\nlogoff\n```\n\nJames now tries to send a message to Fred:\n\n```erlang\n(c2@kosken)2> messenger:message(fred, \"peter doesn't like you\").\nok\nreceiver_not_found\n```\n\nBut this fails as Fred has already logged off.\n\nFirst let us look at some of the new concepts that have been introduced.\n\nThere are two versions of the `server_transfer` function: one with four\narguments (`server_transfer/4`) and one with five (`server_transfer/5`). These\nare regarded by Erlang as two separate functions.\n\nNotice how to write the `server` function so that it calls itself, through\n`server(User_List)`, and thus creates a loop. The Erlang compiler is \"clever\"\nand optimizes the code so that this really is a sort of loop and not a proper\nfunction call. But this only works if there is no code after the call.\nOtherwise, the compiler expects the call to return and make a proper function\ncall. This would result in the process getting bigger and bigger for every loop.\n\nFunctions in the `lists` module are used. This is a very useful module and a\nstudy of the manual page is recommended (`erl -man lists`).\n`lists:keymember(Key,Position,Lists)` looks through a list of tuples and looks\nat `Position` in each tuple to see if it is the same as `Key`. The first element\nis position 1. If it finds a tuple where the element at `Position` is the same\nas `Key`, it returns `true`, otherwise `false`.\n\n```erlang\n3> lists:keymember(a, 2, [{x,y,z},{b,b,b},{b,a,c},{q,r,s}]).\ntrue\n4> lists:keymember(p, 2, [{x,y,z},{b,b,b},{b,a,c},{q,r,s}]).\nfalse\n```\n\n`lists:keydelete` works in the same way but deletes the first tuple found (if\nany) and returns the remaining list:\n\n```erlang\n5> lists:keydelete(a, 2, [{x,y,z},{b,b,b},{b,a,c},{q,r,s}]).\n[{x,y,z},{b,b,b},{q,r,s}]\n```\n\n`lists:keysearch` is like `lists:keymember`, but it returns\n`{value,Tuple_Found}` or the atom `false`.\n\nThere are many very useful functions in the `lists` module.\n\nAn Erlang process (conceptually) runs until it does a `receive` and there is no\nmessage which it wants to receive in the message queue. \"conceptually\" is used\nhere because the Erlang system shares the CPU time between the active processes\nin the system.\n\nA process terminates when there is nothing more for it to do, that is, the last\nfunction it calls simply returns and does not call another function. Another way\nfor a process to terminate is for it to call [`exit/1`](`exit/1`). The argument\nto [`exit/1`](`exit/1`) has a special meaning, which is discussed later. In this\nexample, [`exit(normal)`](`exit/1`) is done, which has the same effect as a\nprocess running out of functions to call.\n\nThe BIF [`whereis(RegisteredName)`](`whereis/1`) checks if a registered process\nof name `RegisteredName` exists. If it exists, the pid of that process is\nreturned. If it does not exist, the atom `undefined` is returned.\n\nYou should by now be able to understand most of the code in the\nmessenger-module. Let us study one case in detail: a message is sent from one\nuser to another.\n\nThe first user \"sends\" the message in the example above by:\n\n```erlang\nmessenger:message(fred, \"hello\")\n```\n\nAfter testing that the client process exists:\n\n```erlang\nwhereis(mess_client)\n```\n\nAnd a message is sent to `mess_client`:\n\n```erlang\nmess_client ! {message_to, fred, \"hello\"}\n```\n\nThe client sends the message to the server by:\n\n```erlang\n{messenger, messenger@super} ! {self(), message_to, fred, \"hello\"},\n```\n\nAnd waits for a reply from the server.\n\nThe server receives this message and calls:\n\n```erlang\nserver_transfer(From, fred, \"hello\", User_List),\n```\n\nThis checks that the pid `From` is in the `User_List`:\n\n```erlang\nlists:keysearch(From, 1, User_List)\n```\n\nIf `keysearch` returns the atom `false`, some error has occurred and the server\nsends back the message:\n\n```erlang\nFrom ! {messenger, stop, you_are_not_logged_on}\n```\n\nThis is received by the client, which in turn does [`exit(normal)`](`exit/1`)\nand terminates. If `keysearch` returns `{value,{From,Name}}` it is certain that\nthe user is logged on and that his name (peter) is in variable `Name`.\n\nLet us now call:\n\n```erlang\nserver_transfer(From, peter, fred, \"hello\", User_List)\n```\n\nNotice that as this is `server_transfer/5`, it is not the same as the previous\nfunction `server_transfer/4`. Another `keysearch` is done on `User_List` to find\nthe pid of the client corresponding to fred:\n\n```erlang\nlists:keysearch(fred, 2, User_List)\n```\n\nThis time argument 2 is used, which is the second element in the tuple. If this\nreturns the atom `false`, fred is not logged on and the following message is\nsent:\n\n```erlang\nFrom ! {messenger, receiver_not_found};\n```\n\nThis is received by the client.\n\nIf `keysearch` returns:\n\n```erlang\n{value, {ToPid, fred}}\n```\n\nThe following message is sent to fred's client:\n\n```erlang\nToPid ! {message_from, peter, \"hello\"},\n```\n\nThe following message is sent to peter's client:\n\n```erlang\nFrom ! {messenger, sent}\n```\n\nFred's client receives the message and prints it:\n\n```erlang\n{message_from, peter, \"hello\"} ->\n io:format(\"Message from ~p: ~p~n\", [peter, \"hello\"])\n```\n\nPeter's client receives the message in the `await_result` function.","ref":"conc_prog.html#a-larger-example"},{"type":"extras","title":"Robustness","doc":"\n# Robustness\n\nSeveral things are wrong with the messenger example in\n[A Larger Example](conc_prog.md#ex). For example, if a node where a user is\nlogged on goes down without doing a logoff, the user remains in the server's\n`User_List`, but the client disappears. This makes it impossible for the user to\nlog on again as the server thinks the user already is logged on.\n\nOr what happens if the server goes down in the middle of sending a message,\nleaving the sending client hanging forever in the `await_result` function?","ref":"robustness.html"},{"type":"extras","title":"Time-outs - Robustness","doc":"Before improving the messenger program, let us look at some general principles,\nusing the ping pong program as an example. Recall that when \"ping\" finishes, it\ntells \"pong\" that it has done so by sending the atom `finished` as a message to\n\"pong\" so that \"pong\" can also finish. Another way to let \"pong\" finish is to\nmake \"pong\" exit if it does not receive a message from ping within a certain\ntime. This can be done by adding a _time-out_ to `pong` as shown in the\nfollowing example:\n\n```erlang\n-module(tut19).\n\n-export([start_ping/1, start_pong/0, ping/2, pong/0]).\n\nping(0, Pong_Node) ->\n io:format(\"ping finished~n\", []);\n\nping(N, Pong_Node) ->\n {pong, Pong_Node} ! {ping, self()},\n receive\n pong ->\n io:format(\"Ping received pong~n\", [])\n end,\n ping(N - 1, Pong_Node).\n\npong() ->\n receive\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong()\n after 5000 ->\n io:format(\"Pong timed out~n\", [])\n end.\n\nstart_pong() ->\n register(pong, spawn(tut19, pong, [])).\n\nstart_ping(Pong_Node) ->\n spawn(tut19, ping, [3, Pong_Node]).\n```\n\nAfter this is compiled and the file `tut19.beam` is copied to the necessary\ndirectories, the following is seen on (pong@kosken):\n\n```text\n(pong@kosken)1> tut19:start_pong().\ntrue\nPong received ping\nPong received ping\nPong received ping\nPong timed out\n```\n\nAnd the following is seen on (ping@gollum):\n\n```text\n(ping@gollum)1> tut19:start_ping(pong@kosken).\n<0.36.0>\nPing received pong\nPing received pong\nPing received pong\nping finished\n```\n\nThe time-out is set in:\n\n```erlang\npong() ->\n receive\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong()\n after 5000 ->\n io:format(\"Pong timed out~n\", [])\n end.\n```\n\nThe time-out (`after 5000`) is started when `receive` is entered. The time-out\nis canceled if `{ping,Ping_PID}` is received. If `{ping,Ping_PID}` is not\nreceived, the actions following the time-out are done after 5000 milliseconds.\n`after` must be last in the `receive`, that is, preceded by all other message\nreception specifications in the `receive`. It is also possible to call a\nfunction that returned an integer for the time-out:\n\n```erlang\nafter pong_timeout() ->\n```\n\nIn general, there are better ways than using time-outs to supervise parts of a\ndistributed Erlang system. Time-outs are usually appropriate to supervise\nexternal events, for example, if you have expected a message from some external\nsystem within a specified time. For example, a time-out can be used to log a\nuser out of the messenger system if they have not accessed it for, say, ten\nminutes.","ref":"robustness.html#time-outs"},{"type":"extras","title":"Error Handling - Robustness","doc":"Before going into details of the supervision and error handling in an Erlang\nsystem, let us see how Erlang processes terminate, or in Erlang terminology,\n_exit_.\n\nA process which executes [`exit(normal)`](`exit/1`) or simply runs out of things\nto do has a _normal_ exit.\n\nA process which encounters a runtime error (for example, divide by zero, bad\nmatch, trying to call a function that does not exist and so on) exits with an\nerror, that is, has an _abnormal_ exit. A process which executes\n[exit(Reason)](`erlang:exit/1`) where `Reason` is any Erlang term except the\natom `normal`, also has an abnormal exit.\n\nAn Erlang process can set up links to other Erlang processes. If a process calls\n[link(Other_Pid)](`erlang:link/1`) it sets up a bidirectional link between\nitself and the process called `Other_Pid`. When a process terminates, it sends\nsomething called a _signal_ to all the processes it has links to.\n\nThe signal carries information about the pid it was sent from and the exit\nreason.\n\nThe default behaviour of a process that receives a normal exit is to ignore the\nsignal.\n\nThe default behaviour in the two other cases (that is, abnormal exit) above is\nto:\n\n- Bypass all messages to the receiving process.\n- Kill the receiving process.\n- Propagate the same error signal to the links of the killed process.\n\nIn this way you can connect all processes in a transaction together using links.\nIf one of the processes exits abnormally, all the processes in the transaction\nare killed. As it is often wanted to create a process and link to it at the same\ntime, there is a special BIF, [spawn_link](`erlang:spawn_link/1`) that does the\nsame as `spawn`, but also creates a link to the spawned process.\n\nNow an example of the ping pong example using links to terminate \"pong\":\n\n```erlang\n-module(tut20).\n\n-export([start/1, ping/2, pong/0]).\n\nping(N, Pong_Pid) ->\n link(Pong_Pid),\n ping1(N, Pong_Pid).\n\nping1(0, _) ->\n exit(ping);\n\nping1(N, Pong_Pid) ->\n Pong_Pid ! {ping, self()},\n receive\n pong ->\n io:format(\"Ping received pong~n\", [])\n end,\n ping1(N - 1, Pong_Pid).\n\npong() ->\n receive\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong()\n end.\n\nstart(Ping_Node) ->\n PongPID = spawn(tut20, pong, []),\n spawn(Ping_Node, tut20, ping, [3, PongPID]).\n```\n\n```text\n(s1@bill)3> tut20:start(s2@kosken).\nPong received ping\n<3820.41.0>\nPing received pong\nPong received ping\nPing received pong\nPong received ping\nPing received pong\n```\n\nThis is a slight modification of the ping pong program where both processes are\nspawned from the same `start/1` function, and the \"ping\" process can be spawned\non a separate node. Notice the use of the `link` BIF. \"Ping\" calls\n[`exit(ping)`](`exit/1`) when it finishes and this causes an exit signal to be\nsent to \"pong\", which also terminates.\n\nIt is possible to modify the default behaviour of a process so that it does not\nget killed when it receives abnormal exit signals. Instead, all signals are\nturned into normal messages on the format `{'EXIT',FromPID,Reason}` and added to\nthe end of the receiving process' message queue. This behaviour is set by:\n\n```erlang\nprocess_flag(trap_exit, true)\n```\n\nThere are several other process flags, see [erlang(3)](`erlang:process_flag/2`).\nChanging the default behaviour of a process in this way is usually not done in\nstandard user programs, but is left to the supervisory programs in OTP. However,\nthe ping pong program is modified to illustrate exit trapping.\n\n```erlang\n-module(tut21).\n\n-export([start/1, ping/2, pong/0]).\n\nping(N, Pong_Pid) ->\n link(Pong_Pid),\n ping1(N, Pong_Pid).\n\nping1(0, _) ->\n exit(ping);\n\nping1(N, Pong_Pid) ->\n Pong_Pid ! {ping, self()},\n receive\n pong ->\n io:format(\"Ping received pong~n\", [])\n end,\n ping1(N - 1, Pong_Pid).\n\npong() ->\n process_flag(trap_exit, true),\n pong1().\n\npong1() ->\n receive\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong1();\n {'EXIT', From, Reason} ->\n io:format(\"pong exiting, got ~p~n\", [{'EXIT', From, Reason}])\n end.\n\nstart(Ping_Node) ->\n PongPID = spawn(tut21, pong, []),\n spawn(Ping_Node, tut21, ping, [3, PongPID]).\n```\n\n```text\n(s1@bill)1> tut21:start(s2@gollum).\n<3820.39.0>\nPong received ping\nPing received pong\nPong received ping\nPing received pong\nPong received ping\nPing received pong\npong exiting, got {'EXIT',<3820.39.0>,ping}\n```","ref":"robustness.html#error-handling"},{"type":"extras","title":"The Larger Example with Robustness Added - Robustness","doc":"Let us return to the messenger program and add changes to make it more robust:\n\n```erlang\n%%% Message passing utility.\n%%% User interface:\n%%% login(Name)\n%%% One user at a time can log in from each Erlang node in the\n%%% system messenger: and choose a suitable Name. If the Name\n%%% is already logged in at another node or if someone else is\n%%% already logged in at the same node, login will be rejected\n%%% with a suitable error message.\n%%% logoff()\n%%% Logs off anybody at that node\n%%% message(ToName, Message)\n%%% sends Message to ToName. Error messages if the user of this\n%%% function is not logged on or if ToName is not logged on at\n%%% any node.\n%%%\n%%% One node in the network of Erlang nodes runs a server which maintains\n%%% data about the logged on users. The server is registered as \"messenger\"\n%%% Each node where there is a user logged on runs a client process registered\n%%% as \"mess_client\"\n%%%\n%%% Protocol between the client processes and the server\n%%% ----------------------------------------------------\n%%%\n%%% To server: {ClientPid, logon, UserName}\n%%% Reply {messenger, stop, user_exists_at_other_node} stops the client\n%%% Reply {messenger, logged_on} logon was successful\n%%%\n%%% When the client terminates for some reason\n%%% To server: {'EXIT', ClientPid, Reason}\n%%%\n%%% To server: {ClientPid, message_to, ToName, Message} send a message\n%%% Reply: {messenger, stop, you_are_not_logged_on} stops the client\n%%% Reply: {messenger, receiver_not_found} no user with this name logged on\n%%% Reply: {messenger, sent} Message has been sent (but no guarantee)\n%%%\n%%% To client: {message_from, Name, Message},\n%%%\n%%% Protocol between the \"commands\" and the client\n%%% ----------------------------------------------\n%%%\n%%% Started: messenger:client(Server_Node, Name)\n%%% To client: logoff\n%%% To client: {message_to, ToName, Message}\n%%%\n%%% Configuration: change the server_node() function to return the\n%%% name of the node where the messenger server runs\n\n-module(messenger).\n-export([start_server/0, server/0,\n logon/1, logoff/0, message/2, client/2]).\n\n%%% Change the function below to return the name of the node where the\n%%% messenger server runs\nserver_node() ->\n messenger@super.\n\n%%% This is the server process for the \"messenger\"\n%%% the user list has the format [{ClientPid1, Name1},{ClientPid22, Name2},...]\nserver() ->\n process_flag(trap_exit, true),\n server([]).\n\nserver(User_List) ->\n receive\n {From, logon, Name} ->\n New_User_List = server_logon(From, Name, User_List),\n server(New_User_List);\n {'EXIT', From, _} ->\n New_User_List = server_logoff(From, User_List),\n server(New_User_List);\n {From, message_to, To, Message} ->\n server_transfer(From, To, Message, User_List),\n io:format(\"list is now: ~p~n\", [User_List]),\n server(User_List)\n end.\n\n%%% Start the server\nstart_server() ->\n register(messenger, spawn(messenger, server, [])).\n\n%%% Server adds a new user to the user list\nserver_logon(From, Name, User_List) ->\n %% check if logged on anywhere else\n case lists:keymember(Name, 2, User_List) of\n true ->\n From ! {messenger, stop, user_exists_at_other_node}, %reject logon\n User_List;\n false ->\n From ! {messenger, logged_on},\n link(From),\n [{From, Name} | User_List] %add user to the list\n end.\n\n%%% Server deletes a user from the user list\nserver_logoff(From, User_List) ->\n lists:keydelete(From, 1, User_List).\n\n\n%%% Server transfers a message between user\nserver_transfer(From, To, Message, User_List) ->\n %% check that the user is logged on and who he is\n case lists:keysearch(From, 1, User_List) of\n false ->\n From ! {messenger, stop, you_are_not_logged_on};\n {value, {_, Name}} ->\n server_transfer(From, Name, To, Message, User_List)\n end.\n\n%%% If the user exists, send the message\nserver_transfer(From, Name, To, Message, User_List) ->\n %% Find the receiver and send the message\n case lists:keysearch(To, 2, User_List) of\n false ->\n From ! {messenger, receiver_not_found};\n {value, {ToPid, To}} ->\n ToPid ! {message_from, Name, Message},\n From ! {messenger, sent}\n end.\n\n%%% User Commands\nlogon(Name) ->\n case whereis(mess_client) of\n undefined ->\n register(mess_client,\n spawn(messenger, client, [server_node(), Name]));\n _ -> already_logged_on\n end.\n\nlogoff() ->\n mess_client ! logoff.\n\nmessage(ToName, Message) ->\n case whereis(mess_client) of % Test if the client is running\n undefined ->\n not_logged_on;\n _ -> mess_client ! {message_to, ToName, Message},\n ok\nend.\n\n%%% The client process which runs on each user node\nclient(Server_Node, Name) ->\n {messenger, Server_Node} ! {self(), logon, Name},\n await_result(),\n client(Server_Node).\n\nclient(Server_Node) ->\n receive\n logoff ->\n exit(normal);\n {message_to, ToName, Message} ->\n {messenger, Server_Node} ! {self(), message_to, ToName, Message},\n await_result();\n {message_from, FromName, Message} ->\n io:format(\"Message from ~p: ~p~n\", [FromName, Message])\n end,\n client(Server_Node).\n\n%%% wait for a response from the server\nawait_result() ->\n receive\n {messenger, stop, Why} -> % Stop the client\n io:format(\"~p~n\", [Why]),\n exit(normal);\n {messenger, What} -> % Normal response\n io:format(\"~p~n\", [What])\n after 5000 ->\n io:format(\"No response from server~n\", []),\n exit(timeout)\n end.\n```\n\nThe following changes are added:\n\nThe messenger server traps exits. If it receives an exit signal,\n`{'EXIT',From,Reason}`, this means that a client process has terminated or is\nunreachable for one of the following reasons:\n\n- The user has logged off (the \"logoff\" message is removed).\n- The network connection to the client is broken.\n- The node on which the client process resides has gone down.\n- The client processes has done some illegal operation.\n\nIf an exit signal is received as above, the tuple `{From,Name}` is deleted from\nthe servers `User_List` using the `server_logoff` function. If the node on which\nthe server runs goes down, an exit signal (automatically generated by the\nsystem) is sent to all of the client processes:\n`{'EXIT',MessengerPID,noconnection}` causing all the client processes to\nterminate.\n\nAlso, a time-out of five seconds has been introduced in the `await_result`\nfunction. That is, if the server does not reply within five seconds (5000 ms),\nthe client terminates. This is only needed in the logon sequence before the\nclient and the server are linked.\n\nAn interesting case is if the client terminates before the server links to it.\nThis is taken care of because linking to a non-existent process causes an exit\nsignal, `{'EXIT',From,noproc}`, to be automatically generated. This is as if the\nprocess terminated immediately after the link operation.","ref":"robustness.html#the-larger-example-with-robustness-added"},{"type":"extras","title":"Records and Macros","doc":"\n# Records and Macros\n\nLarger programs are usually written as a collection of files with a well-defined\ninterface between the various parts.","ref":"records_macros.html"},{"type":"extras","title":"The Larger Example Divided into Several Files - Records and Macros","doc":"To illustrate this, the messenger example from the previous section is divided\ninto the following five files:\n\n- `mess_config.hrl`\n\n Header file for configuration data\n\n- `mess_interface.hrl`\n\n Interface definitions between the client and the messenger\n\n- `user_interface.erl`\n\n Functions for the user interface\n\n- `mess_client.erl`\n\n Functions for the client side of the messenger\n\n- `mess_server.erl`\n\n Functions for the server side of the messenger\n\nWhile doing this, the message passing interface between the shell, the client,\nand the server is cleaned up and is defined using _records_. Also, _macros_ are\nintroduced:\n\n```erlang\n%%%----FILE mess_config.hrl----\n\n%%% Configure the location of the server node,\n-define(server_node, messenger@super).\n\n%%%----END FILE----\n```\n\n```erlang\n%%%----FILE mess_interface.hrl----\n\n%%% Message interface between client and server and client shell for\n%%% messenger program\n\n%%%Messages from Client to server received in server/1 function.\n-record(logon,{client_pid, username}).\n-record(message,{client_pid, to_name, message}).\n%%% {'EXIT', ClientPid, Reason} (client terminated or unreachable.\n\n%%% Messages from Server to Client, received in await_result/0 function\n-record(abort_client,{message}).\n%%% Messages are: user_exists_at_other_node,\n%%% you_are_not_logged_on\n-record(server_reply,{message}).\n%%% Messages are: logged_on\n%%% receiver_not_found\n%%% sent (Message has been sent (no guarantee)\n%%% Messages from Server to Client received in client/1 function\n-record(message_from,{from_name, message}).\n\n%%% Messages from shell to Client received in client/1 function\n%%% spawn(mess_client, client, [server_node(), Name])\n-record(message_to,{to_name, message}).\n%%% logoff\n\n%%%----END FILE----\n```\n\n```erlang\n%%%----FILE user_interface.erl----\n\n%%% User interface to the messenger program\n%%% login(Name)\n%%% One user at a time can log in from each Erlang node in the\n%%% system messenger: and choose a suitable Name. If the Name\n%%% is already logged in at another node or if someone else is\n%%% already logged in at the same node, login will be rejected\n%%% with a suitable error message.\n\n%%% logoff()\n%%% Logs off anybody at that node\n\n%%% message(ToName, Message)\n%%% sends Message to ToName. Error messages if the user of this\n%%% function is not logged on or if ToName is not logged on at\n%%% any node.\n\n-module(user_interface).\n-export([logon/1, logoff/0, message/2]).\n-include(\"mess_interface.hrl\").\n-include(\"mess_config.hrl\").\n\nlogon(Name) ->\n case whereis(mess_client) of\n undefined ->\n register(mess_client,\n spawn(mess_client, client, [?server_node, Name]));\n _ -> already_logged_on\n end.\n\nlogoff() ->\n mess_client ! logoff.\n\nmessage(ToName, Message) ->\n case whereis(mess_client) of % Test if the client is running\n undefined ->\n not_logged_on;\n _ -> mess_client ! #message_to{to_name=ToName, message=Message},\n ok\nend.\n\n%%%----END FILE----\n```\n\n```erlang\n%%%----FILE mess_client.erl----\n\n%%% The client process which runs on each user node\n\n-module(mess_client).\n-export([client/2]).\n-include(\"mess_interface.hrl\").\n\nclient(Server_Node, Name) ->\n {messenger, Server_Node} ! #logon{client_pid=self(), username=Name},\n await_result(),\n client(Server_Node).\n\nclient(Server_Node) ->\n receive\n logoff ->\n exit(normal);\n #message_to{to_name=ToName, message=Message} ->\n {messenger, Server_Node} !\n #message{client_pid=self(), to_name=ToName, message=Message},\n await_result();\n {message_from, FromName, Message} ->\n io:format(\"Message from ~p: ~p~n\", [FromName, Message])\n end,\n client(Server_Node).\n\n%%% wait for a response from the server\nawait_result() ->\n receive\n #abort_client{message=Why} ->\n io:format(\"~p~n\", [Why]),\n exit(normal);\n #server_reply{message=What} ->\n io:format(\"~p~n\", [What])\n after 5000 ->\n io:format(\"No response from server~n\", []),\n exit(timeout)\n end.\n\n%%%----END FILE---\n```\n\n```erlang\n%%%----FILE mess_server.erl----\n\n%%% This is the server process of the messenger service\n\n-module(mess_server).\n-export([start_server/0, server/0]).\n-include(\"mess_interface.hrl\").\n\nserver() ->\n process_flag(trap_exit, true),\n server([]).\n\n%%% the user list has the format [{ClientPid1, Name1},{ClientPid22, Name2},...]\nserver(User_List) ->\n io:format(\"User list = ~p~n\", [User_List]),\n receive\n #logon{client_pid=From, username=Name} ->\n New_User_List = server_logon(From, Name, User_List),\n server(New_User_List);\n {'EXIT', From, _} ->\n New_User_List = server_logoff(From, User_List),\n server(New_User_List);\n #message{client_pid=From, to_name=To, message=Message} ->\n server_transfer(From, To, Message, User_List),\n server(User_List)\n end.\n\n%%% Start the server\nstart_server() ->\n register(messenger, spawn(?MODULE, server, [])).\n\n%%% Server adds a new user to the user list\nserver_logon(From, Name, User_List) ->\n %% check if logged on anywhere else\n case lists:keymember(Name, 2, User_List) of\n true ->\n From ! #abort_client{message=user_exists_at_other_node},\n User_List;\n false ->\n From ! #server_reply{message=logged_on},\n link(From),\n [{From, Name} | User_List] %add user to the list\n end.\n\n%%% Server deletes a user from the user list\nserver_logoff(From, User_List) ->\n lists:keydelete(From, 1, User_List).\n\n%%% Server transfers a message between user\nserver_transfer(From, To, Message, User_List) ->\n %% check that the user is logged on and who he is\n case lists:keysearch(From, 1, User_List) of\n false ->\n From ! #abort_client{message=you_are_not_logged_on};\n {value, {_, Name}} ->\n server_transfer(From, Name, To, Message, User_List)\n end.\n%%% If the user exists, send the message\nserver_transfer(From, Name, To, Message, User_List) ->\n %% Find the receiver and send the message\n case lists:keysearch(To, 2, User_List) of\n false ->\n From ! #server_reply{message=receiver_not_found};\n {value, {ToPid, To}} ->\n ToPid ! #message_from{from_name=Name, message=Message},\n From ! #server_reply{message=sent}\n end.\n\n%%%----END FILE---\n```","ref":"records_macros.html#the-larger-example-divided-into-several-files"},{"type":"extras","title":"Header Files - Records and Macros","doc":"As shown above, some files have extension `.hrl`. These are header files that\nare included in the `.erl` files by:\n\n```erlang\n-include(\"File_Name\").\n```\n\nfor example:\n\n```erlang\n-include(\"mess_interface.hrl\").\n```\n\nIn the case above the file is fetched from the same directory as all the other\nfiles in the messenger example. (_manual_).\n\n.hrl files can contain any valid Erlang code but are most often used for record\nand macro definitions.","ref":"records_macros.html#header-files"},{"type":"extras","title":"Records - Records and Macros","doc":"A record is defined as:\n\n```erlang\n-record(name_of_record,{field_name1, field_name2, field_name3, ......}).\n```\n\nFor example:\n\n```erlang\n-record(message_to,{to_name, message}).\n```\n\nThis is equivalent to:\n\n```erlang\n{message_to, To_Name, Message}\n```\n\nCreating a record is best illustrated by an example:\n\n```erlang\n#message_to{message=\"hello\", to_name=fred)\n```\n\nThis creates:\n\n```erlang\n{message_to, fred, \"hello\"}\n```\n\nNotice that you do not have to worry about the order you assign values to the\nvarious parts of the records when you create it. The advantage of using records\nis that by placing their definitions in header files you can conveniently define\ninterfaces that are easy to change. For example, if you want to add a new field\nto the record, you only have to change the code where the new field is used and\nnot at every place the record is referred to. If you leave out a field when\ncreating a record, it gets the value of the atom `undefined`. (_manual_)\n\nPattern matching with records is very similar to creating records. For example,\ninside a `case` or `receive`:\n\n```erlang\n#message_to{to_name=ToName, message=Message} ->\n```\n\nThis is the same as:\n\n```erlang\n{message_to, ToName, Message}\n```","ref":"records_macros.html#records"},{"type":"extras","title":"Macros - Records and Macros","doc":"Another thing that has been added to the messenger is a macro. The file\n`mess_config.hrl` contains the definition:\n\n```erlang\n%%% Configure the location of the server node,\n-define(server_node, messenger@super).\n```\n\nThis file is included in `mess_server.erl`:\n\n```erlang\n-include(\"mess_config.hrl\").\n```\n\nEvery occurrence of `?server_node` in `mess_server.erl` is now replaced by\n`messenger@super`.\n\nA macro is also used when spawning the server process:\n\n```erlang\nspawn(?MODULE, server, [])\n```\n\nThis is a standard macro (that is, defined by the system, not by the user).\n`?MODULE` is always replaced by the name of the current module (that is, the\n`-module` definition near the start of the file). There are more advanced ways\nof using macros with, for example, [parameters](macros.md#defining-and-using-macros).\n\nThe three Erlang (`.erl`) files in the messenger example are individually\ncompiled into object code file (`.beam`). The Erlang system loads and links\nthese files into the system when they are referred to during execution of the\ncode. In this case, they are simply put in our current working directory (that\nis, the place you have done \"cd\" to). There are ways of putting the `.beam`\nfiles in other directories.\n\nIn the messenger example, no assumptions have been made about what the message\nbeing sent is. It can be any valid Erlang term.","ref":"records_macros.html#macros"},{"type":"extras","title":"System Principles","doc":"\n# System Principles\n\n[](){: #system-principles }","ref":"system_principles.html"},{"type":"extras","title":"Starting the System - System Principles","doc":"An Erlang runtime system is started with command `erl`:\n\n```text\n% erl\nErlang/OTP 27 [erts-15.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]\n\nEshell V15.0 (press Ctrl+G to abort, type help(). for help)\n1>\n```\n\n`erl` understands a number of command-line arguments; see\n[erl](`e:erts:erl_cmd.md`) in the ERTS application. Some arguments are\nalso described in this chapter.\n\nApplication programs can access the values of the command-line arguments by\ncalling one of the following functions:\n\n* [`init:get_argument(Key)`](https://www.erlang.org/doc/man/init#get_argument-1)\n* [`init:get_arguments()`](https://www.erlang.org/doc/man/init#get_arguments-0)\n* [`init:get_plain_arguments()`](https://www.erlang.org/doc/man/init#get_plain_arguments-0)","ref":"system_principles.html#starting-the-system"},{"type":"extras","title":"Restarting and Stopping the System - System Principles","doc":"The runtime system is halted by calling\n[`halt/0,1,2`](https://www.erlang.org/doc/man/erlang#halt-2).\n\nModule `m:init` contains functions for restarting, rebooting, and stopping the\nruntime system:\n\n* [`init:restart()`](https://www.erlang.org/doc/man/init#restart-0)\n* [`init:reboot()`](https://www.erlang.org/doc/man/init#reboot-0)\n* [`init:stop()`](https://www.erlang.org/doc/man/init#stop-0)\n\nThe runtime system terminates if the Erlang shell is terminated.\n\n[](){: #BOOTSCRIPT }","ref":"system_principles.html#restarting-and-stopping-the-system"},{"type":"extras","title":"Boot Scripts - System Principles","doc":"The runtime system is started using a _boot script_. The boot script contains\ninstructions on which code to load and which processes and applications to\nstart.\n\nA boot script file has the extension `.script`. The runtime system uses a binary\nversion of the script. This _binary boot script_ file has the extension `.boot`.\n\nWhich boot script to use is specified by the command-line flag `-boot`. The\nextension `.boot` is to be omitted. For example, using the boot script\n`start_all.boot`:\n\n```text\n% erl -boot start_all\n```\n\nIf no boot script is specified, it defaults to `ROOT/bin/start`, where\n`ROOT` is the installation directory of Erlang/OTP. See [Default Boot\nScripts](system_principles.md#default_boot_scripts).\n\nWhen the command-line flag `-init_debug` is used, the `init` process will\noutput debug information while interpreting the boot script.\n\n```text\n% erl -init_debug\n{progress,preloaded}\n{progress,kernel_load_completed}\n{progress,modules_loaded}\n{start,heart}\n{start,logger}\n .\n .\n .\n```\n\nFor a detailed description of the syntax and contents of the boot script, see\n[`script`](https://www.erlang.org/doc/man/script) in the SASL application.\n\n[](){: #default_boot_scripts }","ref":"system_principles.html#boot-scripts"},{"type":"extras","title":"Default Boot Scripts - System Principles","doc":"Erlang/OTP comes with these boot scripts:\n\n- `start_clean.boot` \\- Loads the code for and starts the applications Kernel\n and STDLIB.\n- `start_sasl.boot` \\- Loads the code for and starts the applications Kernel,\n STDLIB, and SASL.\n- `no_dot_erlang.boot` \\- Loads the code for and starts the applications Kernel\n and STDLIB. Skips loading the file `.erlang`. Useful for scripts and other\n tools that are to behave the same irrespective of user preferences.\n\nWhich of `start_clean` and `start_sasl` to use as default is decided by the user\nwhen installing Erlang/OTP using `Install`. The user is asked:\n\n```text\nDo you want to use a minimal system startup instead of the SASL startup?\n```\n\nIf the answer is yes, `start_clean` is used, otherwise `start_sasl` is\nused. The chosen boot script is copied and renamed as `start.boot`,\nthen placed into directory `ROOT/bin`.","ref":"system_principles.html#default-boot-scripts"},{"type":"extras","title":"User-Defined Boot Scripts - System Principles","doc":"It is sometimes useful or necessary to create a user-defined boot script. This\nis true especially when running Erlang in embedded mode; see\n[Code Loading Strategy](system_principles.md#code_loading).\n\nWhile it is possible to manually create a boot script, it is\npreferable to generate it from a release resource file called\n`Name.rel` using the function\n[`systools:make_script/1,2`](https://www.erlang.org/doc/man/systools#make_script-2).\nThis requires that the source code is structured as applications\naccording to the OTP design principles.\n\nFor more information about `.rel` files, see\n[OTP Design Principles](`e:system:release_handling.md`) and the\n[rel](`e:sasl:rel.md`) page in SASL.\n\nTo generate the binary boot script file `Name.boot` the boot script file\n`Name.script`, use the\n[`systools:script2boot(File)`](https://www.erlang.org/doc/man/systools#script2boot-1)\nfunction.\n\n[](){: #code_loading }","ref":"system_principles.html#user-defined-boot-scripts"},{"type":"extras","title":"Code Loading Strategy - System Principles","doc":"The runtime system can be started in either _embedded_ or _interactive_ mode.\nWhich one is decided by the command-line flag `-mode`:\n\n```text\n% erl -mode embedded\n```\n\nThe default mode is `interactive`. If more than one `-mode` flag is given,\nthe first one will be used.\n\nThe mode properties are as follows:\n\n- In embedded mode, all code is loaded during system startup according\n to the boot script. (Code can be loaded later by **explicitly**\n ordering the code server to load it.)\n\n- In interactive mode, code is dynamically loaded when first required,\n which means that when an attempt is made to call a function in a\n module that is not loaded, the code server searches the code path\n and loads the module into the system.\n\nInitially, the code path consists of the current working directory and\nall object code directories under `ROOT/lib`, where `ROOT` is the\ninstallation directory of Erlang/OTP. Directories can be named\n`Name[-Vsn]`, where the `-Vsn` suffix is optional. By default, the\ncode server chooses the directory with the highest version number\namong those which have the same `Name`. If an `ebin` directory exists\nunder the `Name[-Vsn]` directory, this directory is added to the code\npath.\n\nThe code path can be extended by using the command-line flags `-pa Directories`\nand `-pz Directories`. These add `Directories` to the head or the end of the\ncode path, respectively. Example:\n\n```text\n% erl -pa /home/arne/mycode\n```\n\nThe `m:code` module contains a number of functions for modifying and\nquerying the search path.","ref":"system_principles.html#code-loading-strategy"},{"type":"extras","title":"File Types - System Principles","doc":"The following file types are defined in Erlang/OTP:\n\n| _File Type_ | _File Name/Extension_ | _Documented in_ |\n| ------------------------- | --------------------- | --------------------------------------------------- |\n| Module | `.erl` | [Erlang Reference Manual](`e:system:modules.md`) |\n| Include file | `.hrl` | [Erlang Reference Manual](`e:system:modules.md`) |\n| Release resource file | `.rel` | [rel](`e:sasl:rel.md`) in SASL |\n| Application resource file | `.app` | [app](`e:kernel:app.md`) in Kernel |\n| Boot script | `.script` | [script](`e:sasl:script.md`) in SASL |\n| Binary boot script | `.boot` | - |\n| Configuration file | `.config` | [config](`e:kernel:config.md`) in Kernel |\n| Application upgrade file | `.appup` | [appup](`e:sasl:appup.md`) in SASL |\n| Release upgrade file | `relup` | [relup](`e:sasl:relup.md`) in SASL |\n\n_Table: File Types_","ref":"system_principles.html#file-types"},{"type":"extras","title":"Error Logging","doc":"\n# Error Logging\n\n[](){: #error-logging }","ref":"error_logging.html"},{"type":"extras","title":"Error Information From the Runtime System - Error Logging","doc":"Error information from the runtime system, that is, information about a process\nterminating because of an uncaught error exception, is by default written to\nthe terminal (TTY):\n\n```text\n=ERROR REPORT==== 9-Dec-2003::13:25:02 ===\nError in process <0.27.0> with exit value: {{badmatch,[1,2,3]},[{m,f,1},{shell,eval_loop,2}]}\n```\n\nThe error information is handled by Logger, which is part of the Kernel\napplication.\n\nThe exit reasons (such as `badarg`) used by the runtime system are described in\n[Errors and Error Handling](`e:system:errors.md#exit_reasons`).\n\nFor information about Logger and its user interface, see the `m:logger` manual\npage and the [Logging](`e:kernel:logger_chapter.md`) section in the Kernel\nUser's Guide. The system can be configured so that log events are written to\nfile or to the TTY, or both. In addition, user-defined applications can send and\nformat log events using Logger.","ref":"error_logging.html#error-information-from-the-runtime-system"},{"type":"extras","title":"Log events from OTP behaviours - Error Logging","doc":"The standard behaviours (`supervisor`, `gen_server`, and so on) send progress\nand error information to Logger. Progress reports are by default not logged, but\ncan be enabled by setting the primary log level to `info`, for example by using\nthe Kernel configuration parameter `logger_level`. Supervisor reports, crash\nreports and other error and information reports are by default logged through\nthe log handler which is set up when the Kernel application is started.\n\nPrior to Erlang/OTP 21.0, supervisor, crash, and progress reports were only\nlogged when the SASL application was running. This behaviour can, for backwards\ncompatibility, be enabled by setting the Kernel configuration parameter\n[`logger_sasl_compatible`](`e:kernel:kernel_app.md#logger_sasl_compatible`) to\n`true`. For more information, see\n[SASL Error Logging](`e:sasl:error_logging.md`) in the SASL User's Guide.\n\n```erlang\n% erl -kernel logger_level info\nErlang/OTP 21 [erts-10.0] [source-13c50db] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]\n\n=PROGRESS REPORT==== 8-Jun-2018::16:54:19.916404 ===\n application: kernel\n started_at: nonode@nohost\n=PROGRESS REPORT==== 8-Jun-2018::16:54:19.922908 ===\n application: stdlib\n started_at: nonode@nohost\n=PROGRESS REPORT==== 8-Jun-2018::16:54:19.925755 ===\n supervisor: {local,kernel_safe_sup}\n started: [{pid,<0.74.0>},\n {id,disk_log_sup},\n {mfargs,{disk_log_sup,start_link,[]}},\n {restart_type,permanent},\n {shutdown,1000},\n {child_type,supervisor}]\n=PROGRESS REPORT==== 8-Jun-2018::16:54:19.926056 ===\n supervisor: {local,kernel_safe_sup}\n started: [{pid,<0.75.0>},\n {id,disk_log_server},\n {mfargs,{disk_log_server,start_link,[]}},\n {restart_type,permanent},\n {shutdown,2000},\n {child_type,worker}]\nEshell V10.0 (abort with ^G)\n1>\n```","ref":"error_logging.html#log-events-from-otp-behaviours"},{"type":"extras","title":"Creating and Upgrading a Target System","doc":"\n# Creating and Upgrading a Target System\n\n[](){: #creating-upgrading-target-system }\n\nWhen creating a system using Erlang/OTP, the simplest way is to install\nErlang/OTP somewhere, install the application-specific code somewhere else, and\nthen start the Erlang runtime system, making sure the code path includes the\napplication-specific code.\n\nIt is often not desirable to use an Erlang/OTP system as is. A developer can\ncreate new Erlang/OTP-compliant applications for a particular purpose, and\nseveral original Erlang/OTP applications can be irrelevant for the purpose in\nquestion. Thus, there is a need to be able to create a new system based on a\ngiven Erlang/OTP system, where dispensable applications are removed and new\napplications are included. Documentation and source code is irrelevant and is\ntherefore not included in the new system.\n\nThis chapter is about creating such a system, which is called a _target system_.\n\nThe following sections deal with target systems with different requirements of\nfunctionality:\n\n- A _basic target system_ that can be started by calling the ordinary `erl`\n script.\n- A _simple target system_ that also supports code replacement in runtime.\n- An _embedded target system_ that also supports starting automatically\n at boot time, and logging output from the system files for later inspection.\n\nHere is only considered the case when Erlang/OTP is running on a UNIX system.\n\nThe `sasl` application includes the example Erlang module `target_system.erl`,\nwhich contains functions for creating and installing a target system. This\nmodule is used in the following examples. The source code of the module is\nlisted in\n[Listing of target_system.erl](create_target.md#listing-of-target-system)\n\n[](){: #create }","ref":"create_target.html"},{"type":"extras","title":"Creating a Target System - Creating and Upgrading a Target System","doc":"It is assumed that you have a working Erlang/OTP system structured according to\nthe OTP design principles.\n\n_Step 1._ Create a `.rel` file (see the [rel(4)](`e:sasl:rel.md`) manual page in\nSASL), which specifies the ERTS version and lists all applications that are to\nbe included in the new basic target system. An example is the following\n`mysystem.rel` file:\n\n```erlang\n%% mysystem.rel\n{release,\n {\"MYSYSTEM\", \"FIRST\"},\n {erts, \"5.10.4\"},\n [{kernel, \"2.16.4\"},\n {stdlib, \"1.19.4\"},\n {sasl, \"2.3.4\"},\n {pea, \"1.0\"}]}.\n```\n\nThe listed applications are not only original Erlang/OTP applications but\npossibly also new applications that you have written (here exemplified by the\napplication Pea (`pea`)).\n\n_Step 2._ Start Erlang/OTP from the directory where the `mysystem.rel` file\nresides:\n\n```text\n% erl -pa /home/user/target_system/myapps/pea-1.0/ebin\n```\n\nThe `-pa` argument prepends the path to the `ebin` directory for\nthe Pea application to the code path.\n\n_Step 3._ Create the target system:\n\n```text\n1> target_system:create(\"mysystem\").\n```\n\nThe function `target_system:create/1` performs the following:\n\n1. Reads the file `mysystem.rel` and creates a new file `plain.rel`.\n The new file is identical to the original, except that it only\n lists the Kernel and STDLIB applications.\n\n1. From the files `mysystem.rel` and `plain.rel` creates the files\n `mysystem.script`, `mysystem.boot`, `plain.script`, and `plain.boot`\n by calling `systools:make_script/2`.\n\n1. Creates the file `mysystem.tar.gz` by calling `systools:make_tar/2`. That\n file has the following contents:\n\n```text\nerts-5.10.4/bin/\nreleases/FIRST/start.boot\nreleases/FIRST/mysystem.rel\nreleases/mysystem.rel\nlib/kernel-2.16.4/\nlib/stdlib-1.19.4/\nlib/sasl-2.3.4/\nlib/pea-1.0/\n```\n\nThe file `releases/FIRST/start.boot` is a copy of our `mysystem.boot`\n\nThe release resource file `mysystem.rel` is duplicated in the tar file.\nOriginally, this file was only stored in the `releases` directory to make it\npossible for the `release_handler` to extract this file separately. After\nunpacking the tar file, `release_handler` would automatically copy the file to\n`releases/FIRST`. However, sometimes the tar file is unpacked without involving\nthe `release_handler` (for example, when unpacking the first target system).\nHence, the file is now duplicated within the tar archive, eliminating the\nneed for manual copying.\n\n1. Creates the temporary directory `tmp` and extracts the tar file\n `mysystem.tar.gz` into that directory.\n1. Deletes the files `erl` and `start` from `tmp/erts-5.10.4/bin`. These files\n are created again from source when installing the release.\n1. Creates the directory `tmp/bin`.\n1. Copies the previously created file `plain.boot` to `tmp/bin/start.boot`.\n1. Copies the files `epmd`, `run_erl`, and `to_erl` from the directory\n `tmp/erts-5.10.4/bin` to the directory `tmp/bin`.\n1. Creates the directory `tmp/log`, which is used if the system is started as\n embedded with the `bin/start` script.\n1. Creates the file `tmp/releases/start_erl.data` with the contents \"5.10.4\n FIRST\". This file is to be passed as data file to the `start_erl` script.\n1. Recreates the file `mysystem.tar.gz` from the directories in the directory\n `tmp` and removes `tmp`.","ref":"create_target.html#creating-a-target-system"},{"type":"extras","title":"Installing a Target System - Creating and Upgrading a Target System","doc":"_Step 4._ Install the created target system in a suitable directory.\n\n```text\n2> target_system:install(\"mysystem\", \"/usr/local/erl-target\").\n```\n\nThe function `target_system:install/2` performs the following:\n\n1. Extracts the tar file `mysystem.tar.gz` into the target directory\n `/usr/local/erl-target`.\n1. In the target directory reads the file `releases/start_erl.data` to find the\n Erlang runtime system version (\"5.10.4\").\n1. Substitutes `%FINAL_ROOTDIR%` and `%EMU%` for `/usr/local/erl-target` and\n `beam`, respectively, in the files `erl.src`, `start.src`, and\n `start_erl.src` of the target `erts-5.10.4/bin` directory, and puts the\n resulting files `erl`, `start`, and `run_erl` in the target `bin` directory.\n1. Finally the target `releases/RELEASES` file is created from data in the file\n `releases/mysystem.rel`.\n\n[](){: #start }","ref":"create_target.html#installing-a-target-system"},{"type":"extras","title":"Starting a Target System - Creating and Upgrading a Target System","doc":"Now we have a target system that can be started in various ways. We start it as\na _basic target system_ by invoking:\n\n```text\n% /usr/local/erl-target/bin/erl\n```\n\nHere only the Kernel and STDLIB applications are started, that is, the system is\nstarted as an ordinary development system. Only two files are needed for all\nthis to work:\n\n1. `bin/erl` (obtained from `erts-5.10.4/bin/erl.src`)\n1. `bin/start.boot` (a copy of `plain.boot`)\n\nWe can also start a distributed system (requires `bin/epmd`).\n\nTo start all applications specified in the original `mysystem.rel` file, use\nflag `-boot` as follows:\n\n```text\n% /usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FIRST/start\n```\n\nWe start a _simple target system_ as above. The only difference is that also the\nfile `releases/RELEASES` is present for code replacement in runtime to work.\n\nTo start an _embedded target system_, the shell script `bin/start` is used. The\nscript calls `bin/run_erl`, which in turn calls `bin/start_erl` (roughly,\n`start_erl` is an embedded variant of `erl`).\n\nThe shell script `start`, which is generated from `erts-5.10.4/bin/start.src`\nduring installation, is merely an example. Edit it to suite your needs. Typically\nit is executed when the UNIX system boots.\n\n`run_erl` is a wrapper that provides logging of output from the runtime system\nto file. It also provides a simple mechanism for attaching to the Erlang shell\n(`to_erl`).\n\n`start_erl` requires:\n\n1. The root directory (`\"/usr/local/erl-target\"`)\n1. The releases directory (`\"/usr/local/erl-target/releases\"`\n1. The location of the file `start_erl.data`\n\nIt performs the following:\n\n1. Reads the runtime system version (`\"5.10.4\"`) and release version (`\"FIRST\"`)\n from the file `start_erl.data`.\n1. Starts the runtime system of the version found.\n1. Provides the flag `-boot` specifying the boot file of the release version\n found (`\"releases/FIRST/start.boot\"`).\n\n`start_erl` also assumes that there is `sys.config` in the release version\ndirectory (`\"releases/FIRST/sys.config\"`). That is the topic of the next\nsection.\n\nThe `start_erl` shell script is normally not to be altered by the user.","ref":"create_target.html#starting-a-target-system"},{"type":"extras","title":"System Configuration Parameters - Creating and Upgrading a Target System","doc":"As was mentioned in the previous section, `start_erl` requires a `sys.config` in\nthe release version directory (`\"releases/FIRST/sys.config\"`). If there is no\nsuch file, the system start fails. Such a file must therefore also be added.\n\nIf you have system configuration data that is neither file-location-dependent\nnor site-dependent, it can be convenient to create `sys.config` early, so it\nbecomes part of the target system tar file created by `target_system:create/1`.\nIn fact, if you in the current directory create not only the file\n`mysystem.rel`, but also file `sys.config`, the latter file is tacitly put in\nthe appropriate directory.\n\nHowever, it can also be convenient to replace variables in within a `sys.config`\non the target after unpacking but before running the release. If you have a\n`sys.config.src` it will be included and is not required to be a valid Erlang\nterm file like `sys.config`. Before running the release you must have a valid\n`sys.config` in the same directory, so using `sys.config.src` requires having\nsome tool to populate what is needed and write `sys.config` to disk before\nbooting the release.","ref":"create_target.html#system-configuration-parameters"},{"type":"extras","title":"Differences From the Install Script - Creating and Upgrading a Target System","doc":"The previous `install/2` procedure differs somewhat from that of the ordinary\n`Install` shell script. In fact, `create/1` makes the release package as\ncomplete as possible, and leave to the `install/2` procedure to finish by only\nconsidering location-dependent files.","ref":"create_target.html#differences-from-the-install-script"},{"type":"extras","title":"Creating the Next Version - Creating and Upgrading a Target System","doc":"In this example the Pea application has been changed, and so are the\napplications ERTS, Kernel, STDLIB and SASL.\n\n_Step 1._ Create the file `.rel`:\n\n```erlang\n%% mysystem2.rel\n{release,\n {\"MYSYSTEM\", \"SECOND\"},\n {erts, \"6.0\"},\n [{kernel, \"3.0\"},\n {stdlib, \"2.0\"},\n {sasl, \"2.4\"},\n {pea, \"2.0\"}]}.\n```\n\n_Step 2._ Create the application upgrade file (see\n[appup](`e:sasl:appup.md`) in SASL) for Pea, for example:\n\n```erlang\n%% pea.appup\n{\"2.0\",\n [{\"1.0\",[{load_module,pea_lib}]}],\n [{\"1.0\",[{load_module,pea_lib}]}]}.\n```\n\n_Step 3._ From the directory where the file `mysystem2.rel` resides, start the\nErlang/OTP system, giving the path to the new version of Pea:\n\n```text\n% erl -pa /home/user/target_system/myapps/pea-2.0/ebin\n```\n\n_Step 4._ Create the release upgrade file (see [relup](`e:sasl:relup.md`)\nin SASL):\n\n```text\n1> systools:make_relup(\"mysystem2\",[\"mysystem\"],[\"mysystem\"],\n [{path,[\"/home/user/target_system/myapps/pea-1.0/ebin\",\n \"/my/old/erlang/lib/*/ebin\"]}]).\n```\n\nHere `\"mysystem\"` is the base release and `\"mysystem2\"` is the release to\nupgrade to.\n\nThe `path` option is used for pointing out the old version of all applications.\n(The new versions are already in the code path - assuming of course that the\nErlang node on which this is executed is running the correct version of\nErlang/OTP.)\n\n_Step 5._ Create the new release:\n\n```text\n2> target_system:create(\"mysystem2\").\n```\n\nGiven that the file `relup` generated in Step 4 is now located in the current\ndirectory, it is automatically included in the release package.","ref":"create_target.html#creating-the-next-version"},{"type":"extras","title":"Upgrading the Target System - Creating and Upgrading a Target System","doc":"This part is done on the target node, and for this example we want the node to\nbe running as an embedded system with the `-heart` option, allowing automatic\nrestart of the node. For more information, see\n[Starting a Target System](create_target.md#start).\n\nWe add `-heart` to `bin/start`:\n\n```text\n#!/bin/sh\nROOTDIR=/usr/local/erl-target/\n\nif [ -z \"$RELDIR\" ]\nthen\n RELDIR=$ROOTDIR/releases\nfi\n\nSTART_ERL_DATA=${1:-$RELDIR/start_erl.data}\n\n$ROOTDIR/bin/run_erl -daemon /tmp/ $ROOTDIR/log \"exec $ROOTDIR/bin/start_erl $ROOTDIR\\\n$RELDIR $START_ERL_DATA -heart\"\n```\n\nWe use the simplest possible `sys.config`, which we store in `releases/FIRST`:\n\n```text\n%% sys.config\n[].\n```\n\nFinally, to prepare the upgrade, we must put the new release package in the\n`releases` directory of the first target system:\n\n```text\n% cp mysystem2.tar.gz /usr/local/erl-target/releases\n```\n\nAssuming that the node has been started as follows:\n\n```text\n% /usr/local/erl-target/bin/start\n```\n\nIt can be accessed as follows:\n\n```text\n% /usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.1\n```\n\nLogs can be found in `/usr/local/erl-target/log`. This directory is specified as\nan argument to `run_erl`in the start script listed above.\n\n_Step 1._ Unpack the release:\n\n```text\n1> {ok,Vsn} = release_handler:unpack_release(\"mysystem2\").\n```\n\n_Step 2._ Install the release:\n\n```text\n2> release_handler:install_release(Vsn).\n{continue_after_restart,\"FIRST\",[]}\nheart: Tue Apr 1 12:15:10 2014: Erlang has closed.\nheart: Tue Apr 1 12:15:11 2014: Executed \"/usr/local/erl-target/bin/start /usr/local/erl-target/releases/new_start_erl.data\" -> 0. Terminating.\n[End]\n```\n\nThe above return value and output after the call to\n`release_handler:install_release/1` means that the `release_handler` has\nrestarted the node by using `heart`. This is always done when the upgrade\ninvolves a change of the applications ERTS, Kernel, STDLIB, or SASL. For more\ninformation, see [Upgrade when Erlang/OTP has Changed](upgrade.md).\n\nThe node is accessible through a new pipe:\n\n```text\n% /usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.2\n```\n\nList the available releases in the system:\n\n```erlang\n1> release_handler:which_releases().\n[{\"MYSYSTEM\",\"SECOND\",\n [\"kernel-3.0\",\"stdlib-2.0\",\"sasl-2.4\",\"pea-2.0\"],\n current},\n {\"MYSYSTEM\",\"FIRST\",\n [\"kernel-2.16.4\",\"stdlib-1.19.4\",\"sasl-2.3.4\",\"pea-1.0\"],\n permanent}]\n```\n\nOur new release, \"SECOND\", is now the current release, but we can also see that\nour \"FIRST\" release is still permanent. This means that if the node would be\nrestarted now, it would come up running the \"FIRST\" release again.\n\n_Step 3._ Make the new release permanent:\n\n```text\n2> release_handler:make_permanent(\"SECOND\").\n```\n\nCheck the releases again:\n\n```c\n3> release_handler:which_releases().\n[{\"MYSYSTEM\",\"SECOND\",\n [\"kernel-3.0\",\"stdlib-2.0\",\"sasl-2.4\",\"pea-2.0\"],\n permanent},\n {\"MYSYSTEM\",\"FIRST\",\n [\"kernel-2.16.4\",\"stdlib-1.19.4\",\"sasl-2.3.4\",\"pea-1.0\"],\n old}]\n```\n\nWe see that the new release version is `permanent`, so it would be safe to\nrestart the node.\n\n[](){: #listing-of-target-system }","ref":"create_target.html#upgrading-the-target-system"},{"type":"extras","title":"Listing of target_system.erl - Creating and Upgrading a Target System","doc":"This module can also be found in the `examples` directory of the SASL\napplication.\n\n```erlang\n\n-module(target_system).\n-export([create/1, create/2, install/2]).\n\n%% Note: RelFileName below is the *stem* without trailing .rel,\n%% .script etc.\n%%\n\n%% create(RelFileName)\n%%\ncreate(RelFileName) ->\n create(RelFileName,[]).\n\ncreate(RelFileName,SystoolsOpts) ->\n RelFile = RelFileName ++ \".rel\",\n Dir = filename:dirname(RelFileName),\n PlainRelFileName = filename:join(Dir,\"plain\"),\n PlainRelFile = PlainRelFileName ++ \".rel\",\n io:fwrite(\"Reading file: ~ts ...~n\", [RelFile]),\n {ok, [RelSpec]} = file:consult(RelFile),\n io:fwrite(\"Creating file: ~ts from ~ts ...~n\",\n [PlainRelFile, RelFile]),\n {release,\n {RelName, RelVsn},\n {erts, ErtsVsn},\n AppVsns} = RelSpec,\n PlainRelSpec = {release,\n {RelName, RelVsn},\n {erts, ErtsVsn},\n lists:filter(fun({kernel, _}) ->\n true;\n ({stdlib, _}) ->\n true;\n (_) ->\n false\n end, AppVsns)\n },\n {ok, Fd} = file:open(PlainRelFile, [write]),\n io:fwrite(Fd, \"~p.~n\", [PlainRelSpec]),\n file:close(Fd),\n\n io:fwrite(\"Making \\\"~ts.script\\\" and \\\"~ts.boot\\\" files ...~n\",\n\t [PlainRelFileName,PlainRelFileName]),\n make_script(PlainRelFileName,SystoolsOpts),\n\n io:fwrite(\"Making \\\"~ts.script\\\" and \\\"~ts.boot\\\" files ...~n\",\n [RelFileName, RelFileName]),\n make_script(RelFileName,SystoolsOpts),\n\n TarFileName = RelFileName ++ \".tar.gz\",\n io:fwrite(\"Creating tar file ~ts ...~n\", [TarFileName]),\n make_tar(RelFileName,SystoolsOpts),\n\n TmpDir = filename:join(Dir,\"tmp\"),\n io:fwrite(\"Creating directory ~tp ...~n\",[TmpDir]),\n file:make_dir(TmpDir),\n\n io:fwrite(\"Extracting ~ts into directory ~ts ...~n\", [TarFileName,TmpDir]),\n extract_tar(TarFileName, TmpDir),\n\n TmpBinDir = filename:join([TmpDir, \"bin\"]),\n ErtsBinDir = filename:join([TmpDir, \"erts-\" ++ ErtsVsn, \"bin\"]),\n io:fwrite(\"Deleting \\\"erl\\\" and \\\"start\\\" in directory ~ts ...~n\",\n [ErtsBinDir]),\n file:delete(filename:join([ErtsBinDir, \"erl\"])),\n file:delete(filename:join([ErtsBinDir, \"start\"])),\n\n io:fwrite(\"Creating temporary directory ~ts ...~n\", [TmpBinDir]),\n file:make_dir(TmpBinDir),\n\n io:fwrite(\"Copying file \\\"~ts.boot\\\" to ~ts ...~n\",\n [PlainRelFileName, filename:join([TmpBinDir, \"start.boot\"])]),\n copy_file(PlainRelFileName++\".boot\",filename:join([TmpBinDir, \"start.boot\"])),\n\n io:fwrite(\"Copying files \\\"epmd\\\", \\\"run_erl\\\" and \\\"to_erl\\\" from \\n\"\n \"~ts to ~ts ...~n\",\n [ErtsBinDir, TmpBinDir]),\n copy_file(filename:join([ErtsBinDir, \"epmd\"]),\n filename:join([TmpBinDir, \"epmd\"]), [preserve]),\n copy_file(filename:join([ErtsBinDir, \"run_erl\"]),\n filename:join([TmpBinDir, \"run_erl\"]), [preserve]),\n copy_file(filename:join([ErtsBinDir, \"to_erl\"]),\n filename:join([TmpBinDir, \"to_erl\"]), [preserve]),\n\n %% This is needed if 'start' script created from 'start.src' shall\n %% be used as it points out this directory as log dir for 'run_erl'\n TmpLogDir = filename:join([TmpDir, \"log\"]),\n io:fwrite(\"Creating temporary directory ~ts ...~n\", [TmpLogDir]),\n ok = file:make_dir(TmpLogDir),\n\n StartErlDataFile = filename:join([TmpDir, \"releases\", \"start_erl.data\"]),\n io:fwrite(\"Creating ~ts ...~n\", [StartErlDataFile]),\n StartErlData = io_lib:fwrite(\"~s ~s~n\", [ErtsVsn, RelVsn]),\n write_file(StartErlDataFile, StartErlData),\n\n io:fwrite(\"Recreating tar file ~ts from contents in directory ~ts ...~n\",\n\t [TarFileName,TmpDir]),\n {ok, Tar} = erl_tar:open(TarFileName, [write, compressed]),\n %% {ok, Cwd} = file:get_cwd(),\n %% file:set_cwd(\"tmp\"),\n ErtsDir = \"erts-\"++ErtsVsn,\n erl_tar:add(Tar, filename:join(TmpDir,\"bin\"), \"bin\", []),\n erl_tar:add(Tar, filename:join(TmpDir,ErtsDir), ErtsDir, []),\n erl_tar:add(Tar, filename:join(TmpDir,\"releases\"), \"releases\", []),\n erl_tar:add(Tar, filename:join(TmpDir,\"lib\"), \"lib\", []),\n erl_tar:add(Tar, filename:join(TmpDir,\"log\"), \"log\", []),\n erl_tar:close(Tar),\n %% file:set_cwd(Cwd),\n io:fwrite(\"Removing directory ~ts ...~n\",[TmpDir]),\n remove_dir_tree(TmpDir),\n ok.\n\n\ninstall(RelFileName, RootDir) ->\n TarFile = RelFileName ++ \".tar.gz\",\n io:fwrite(\"Extracting ~ts ...~n\", [TarFile]),\n extract_tar(TarFile, RootDir),\n StartErlDataFile = filename:join([RootDir, \"releases\", \"start_erl.data\"]),\n {ok, StartErlData} = read_txt_file(StartErlDataFile),\n [ErlVsn, _RelVsn| _] = string:tokens(StartErlData, \" \\n\"),\n ErtsBinDir = filename:join([RootDir, \"erts-\" ++ ErlVsn, \"bin\"]),\n BinDir = filename:join([RootDir, \"bin\"]),\n io:fwrite(\"Substituting in erl.src, start.src and start_erl.src to \"\n \"form erl, start and start_erl ...\\n\"),\n subst_src_scripts([\"erl\", \"start\", \"start_erl\"], ErtsBinDir, BinDir,\n [{\"FINAL_ROOTDIR\", RootDir}, {\"EMU\", \"beam\"}],\n [preserve]),\n %%! Workaround for pre OTP 17.0: start.src and start_erl.src did\n %%! not have correct permissions, so the above 'preserve' option did not help\n ok = file:change_mode(filename:join(BinDir,\"start\"),8#0755),\n ok = file:change_mode(filename:join(BinDir,\"start_erl\"),8#0755),\n\n io:fwrite(\"Creating the RELEASES file ...\\n\"),\n create_RELEASES(RootDir, filename:join([RootDir, \"releases\",\n\t\t\t\t\t filename:basename(RelFileName)])).\n\n%% LOCALS\n\n%% make_script(RelFileName,Opts)\n%%\nmake_script(RelFileName,Opts) ->\n systools:make_script(RelFileName, [no_module_tests,\n\t\t\t\t {outdir,filename:dirname(RelFileName)}\n\t\t\t\t |Opts]).\n\n%% make_tar(RelFileName,Opts)\n%%\nmake_tar(RelFileName,Opts) ->\n RootDir = code:root_dir(),\n systools:make_tar(RelFileName, [{erts, RootDir},\n\t\t\t\t {outdir,filename:dirname(RelFileName)}\n\t\t\t\t |Opts]).\n\n%% extract_tar(TarFile, DestDir)\n%%\nextract_tar(TarFile, DestDir) ->\n erl_tar:extract(TarFile, [{cwd, DestDir}, compressed]).\n\ncreate_RELEASES(DestDir, RelFileName) ->\n release_handler:create_RELEASES(DestDir, RelFileName ++ \".rel\").\n\nsubst_src_scripts(Scripts, SrcDir, DestDir, Vars, Opts) ->\n lists:foreach(fun(Script) ->\n subst_src_script(Script, SrcDir, DestDir,\n Vars, Opts)\n end, Scripts).\n\nsubst_src_script(Script, SrcDir, DestDir, Vars, Opts) ->\n subst_file(filename:join([SrcDir, Script ++ \".src\"]),\n filename:join([DestDir, Script]),\n Vars, Opts).\n\nsubst_file(Src, Dest, Vars, Opts) ->\n {ok, Conts} = read_txt_file(Src),\n NConts = subst(Conts, Vars),\n write_file(Dest, NConts),\n case lists:member(preserve, Opts) of\n true ->\n {ok, FileInfo} = file:read_file_info(Src),\n file:write_file_info(Dest, FileInfo);\n false ->\n ok\n end.\n\n%% subst(Str, Vars)\n%% Vars = [{Var, Val}]\n%% Var = Val = string()\n%% Substitute all occurrences of %Var% for Val in Str, using the list\n%% of variables in Vars.\n%%\nsubst(Str, Vars) ->\n subst(Str, Vars, []).\n\nsubst([$%, C| Rest], Vars, Result) when $A = \n subst_var([C| Rest], Vars, Result, []);\nsubst([$%, C| Rest], Vars, Result) when $a = \n subst_var([C| Rest], Vars, Result, []);\nsubst([$%, C| Rest], Vars, Result) when C == $_ ->\n subst_var([C| Rest], Vars, Result, []);\nsubst([C| Rest], Vars, Result) ->\n subst(Rest, Vars, [C| Result]);\nsubst([], _Vars, Result) ->\n lists:reverse(Result).\n\nsubst_var([$%| Rest], Vars, Result, VarAcc) ->\n Key = lists:reverse(VarAcc),\n case lists:keysearch(Key, 1, Vars) of\n {value, {Key, Value}} ->\n subst(Rest, Vars, lists:reverse(Value, Result));\n false ->\n subst(Rest, Vars, [$%| VarAcc ++ [$%| Result]])\n end;\nsubst_var([C| Rest], Vars, Result, VarAcc) ->\n subst_var(Rest, Vars, Result, [C| VarAcc]);\nsubst_var([], Vars, Result, VarAcc) ->\n subst([], Vars, [VarAcc ++ [$%| Result]]).\n\ncopy_file(Src, Dest) ->\n copy_file(Src, Dest, []).\n\ncopy_file(Src, Dest, Opts) ->\n {ok,_} = file:copy(Src, Dest),\n case lists:member(preserve, Opts) of\n true ->\n {ok, FileInfo} = file:read_file_info(Src),\n file:write_file_info(Dest, FileInfo);\n false ->\n ok\n end.\n\nwrite_file(FName, Conts) ->\n Enc = file:native_name_encoding(),\n {ok, Fd} = file:open(FName, [write]),\n file:write(Fd, unicode:characters_to_binary(Conts,Enc,Enc)),\n file:close(Fd).\n\nread_txt_file(File) ->\n {ok, Bin} = file:read_file(File),\n {ok, binary_to_list(Bin)}.\n\nremove_dir_tree(Dir) ->\n remove_all_files(\".\", [Dir]).\n\nremove_all_files(Dir, Files) ->\n lists:foreach(fun(File) ->\n FilePath = filename:join([Dir, File]),\n case filelib:is_dir(FilePath) of\n true ->\n {ok, DirFiles} = file:list_dir(FilePath),\n remove_all_files(FilePath, DirFiles),\n file:del_dir(FilePath);\n _ ->\n file:delete(FilePath)\n end\n end, Files).\n```","ref":"create_target.html#listing-of-target_system-erl"},{"type":"extras","title":"Upgrade when Erlang/OTP has Changed","doc":"\n# Upgrade when Erlang/OTP has Changed\n\n[](){: #upgrade-section }","ref":"upgrade.html"},{"type":"extras","title":"Introduction - Upgrade when Erlang/OTP has Changed","doc":"[](){: #upgrade }\n\nAs of Erlang/OTP 17, most applications deliver a valid application upgrade file\n(`appup`). Many of the applications use the `restart_application`\ninstruction. These are applications for which it is not crucial to support real\nsoft upgrade, for example, tools and library applications. The\n`restart_application` instruction ensures that all modules in the application\nare reloaded and thereby running the new code.","ref":"upgrade.html#introduction"},{"type":"extras","title":"Upgrade of Core Applications - Upgrade when Erlang/OTP has Changed","doc":"The core applications ERTS, Kernel, STDLIB, and SASL never allow real\nsoft upgrade, but require the Erlang runtime system to be\nrestarted. This is indicated to the `release_handler` by the upgrade\ninstruction `restart_new_emulator`. This instruction is always the\nvery first instruction executed, and it restarts the runtime system\nwith the new versions of the previously mentioned core applications\nand the old versions of all other applications. When the node is back\nup, all other upgrade instructions are executed, making sure each\napplication is finally running its new version.\n\nIt might seem strange to do a two-step upgrade instead of just\nrestarting the runtime system with the new version of all\napplications. The reason for this design decision is to allow\n`code_change` functions to have side effects, for example, changing\ndata on disk. It also guarantees that the upgrade mechanism for\nnon-core applications does not differ depending on whether or not core\napplications are changed at the same time.\n\nIf, however, the more brutal variant is preferred, the release\nupgrade file can be handwritten using only the single upgrade\ninstruction `restart_emulator`. This instruction, in contrast to\n`restart_new_emulator`, causes the runtime system to restart with the\nnew versions of _all_ applications.\n\n_Note:_ If other instructions are included before `restart_emulator`\nin the handwritten `relup` file, they are executed in the old runtime\nsystem. This is a big risk since there is no guarantee that new BEAM\ncode can be loaded into the old runtime system. Adding instructions\nafter `restart_emulator` has no effect as the `release_handler` will\nnot execute them.\n\nFor information about the release upgrade file, see\n[relup](`e:sasl:relup.md`) in SASL. For more information about\nupgrade instructions, see [appup](`e:sasl:appup.md`) in SASL.","ref":"upgrade.html#upgrade-of-core-applications"},{"type":"extras","title":"Applications that Still do Not Allow Code Upgrade - Upgrade when Erlang/OTP has Changed","doc":"A few applications, such as Erl_interface, do not support upgrade. This is\nindicated by an application upgrade file containing only `{Vsn,[],[]}`. Any\nattempt at creating a release upgrade file with such input fails. The only way\nto force an upgrade involving applications like this is to handwrite the file\n`relup`, preferably as described above with only the `restart_emulator`\ninstruction.","ref":"upgrade.html#applications-that-still-do-not-allow-code-upgrade"},{"type":"extras","title":"Versions","doc":"\n# Versions\n\n[](){: #versions-section }","ref":"versions.html"},{"type":"extras","title":"OTP Version - Versions","doc":"As of OTP release 17, the OTP release number corresponds to the major part of\nthe OTP version. The OTP version as a concept was introduced in OTP 17. The\nversion scheme used is described in detail in\n[Version Scheme](versions.md#version_scheme).\n\nOTP of a specific version is a set of applications of specific versions. The\napplication versions identified by an OTP version corresponds to application\nversions that have been tested together by the Erlang/OTP team at Ericsson AB.\nAn OTP system can, however, be put together with applications from different OTP\nversions. Such a combination of application versions has not been tested by the\nErlang/OTP team. It is therefore _always preferred to use OTP applications from\none single OTP version_.\n\nRelease candidates have an `-rc ` suffix. The suffix `-rc0` is used during\ndevelopment up to the first release candidate.","ref":"versions.html#otp-version"},{"type":"extras","title":"Retrieving Current OTP Version - Versions","doc":"In an OTP source code tree, the OTP version can be read from the text file\n` /OTP_VERSION`. The absolute path to the file can be\nconstructed by calling\n`filename:join([`[`code:root_dir()`](`code:root_dir/0`)`, \"OTP_VERSION\"])`.\n\nIn an installed OTP development system, the OTP version can be read from the\ntext file ` /releases/ /OTP_VERSION`.\nThe absolute path to the file can by constructed by calling\n`filename:join([`[`code:root_dir()`](`code:root_dir/0`)`, \"releases\", `[`erlang:system_info(otp_release)`](`m:erlang#system_info_otp_release`)`, \"OTP_VERSION\"]).`\n\nIf the version read from the `OTP_VERSION` file in a development system has a\n`**` suffix, the system has been patched using the\n[`otp_patch_apply`](`e:system:otp-patch-apply.md`) tool. In this case, the\nsystem consists of application versions from multiple OTP versions. The version\npreceding the `**` suffix corresponds to the OTP version of the base system that\nhas been patched. Note that if a development system is updated by other means\nthan `otp_patch_apply`, the file `OTP_VERSION` can identify an incorrect OTP\nversion.\n\nNo `OTP_VERSION` file is placed in a [target system](create_target.md) created\nby OTP tools, because one can easily create a target system where it is hard\nto even determine the base OTP version. However, it is allowed to place such\na file there if one knows the OTP version.","ref":"versions.html#retrieving-current-otp-version"},{"type":"extras","title":"OTP Versions Table - Versions","doc":"The text file ` /otp_versions.table`, which is part of the\nsource code, contains information about all OTP versions from OTP 17.0 up to the\ncurrent OTP version. Each line contains information about application versions\nthat are part of a specific OTP version, and has the following format:\n\n```text\n : # :\n```\n\n` ` has the format `OTP- `, that is, the same as the git tag used\nto identify the source.\n\n` ` and ` ` are space-separated lists of\napplication versions and has the format ` - `.\n\n- ` ` corresponds to changed applications with new version\n numbers in this OTP version.\n- ` ` corresponds to unchanged application versions in this\n OTP version.\n\nBoth of them can be empty, but not at the same time. If ` `\nis empty, no changes have been made that change the build result of any\napplication. This could, for example, be a pure bug fix of the build system. The\norder of lines is undefined. All white-space characters in this file are either\nspace (character 32) or line-break (character 10).\n\nBy using ordinary UNIX tools like `sed` and `grep` one can easily find answers\nto various questions like:\n\n- Which OTP versions are `kernel-3.0` part of?\n\n `$ grep ' kernel-3\\.0 ' otp_versions.table`\n\n- In which OTP version was `kernel-3.0` introduced?\n\n `$ sed 's/#.*//;/ kernel-3\\.0 /!d' otp_versions.table`\n\nThe above commands give a bit more information than the exact answers, but\nadequate information when manually searching for answers to these questions.","ref":"versions.html#otp-versions-table"},{"type":"extras","title":"Application Version - Versions","doc":"As of OTP 17.0 application versions use the same [version\nscheme](versions.md#version_scheme) as the OTP version, except that\napplication versions never include the `-rc ` suffix. Also\nnote that a major increment in an application version does not\nnecessarily imply a major increment of the OTP version. This depends\non whether the major change in the application is considered a\nmajor change for OTP as a whole or not.\n\n[](){: #version_scheme }","ref":"versions.html#application-version"},{"type":"extras","title":"Version Scheme - Versions","doc":"> #### Change {: .info }\n>\n> The version scheme was changed as of OTP 17.0.\n> [A list of application versions used in OTP 17.0](versions.md#otp_17_0_app_versions)\n> is included at the end of this section.\n\nNormally, a version is constructed as ` . . `, where\n` ` is the most significant part. However, versions with more than three\ndot-separated parts are possible.\n\nThe dot-separated parts consist of non-negative integers. If all parts\nless significant than ` ` equals `0`, they are omitted. The\nthree normal parts ` . . ` are changed as follows:\n\n- ` ` - Increases when major changes, including incompatibilities, are\n made.\n- ` ` - Increases when new functionality is added.\n- ` ` - Increases when pure bug fixes are made.\n\nWhen a part in the version number increases, all less significant parts are set\nto `0`.\n\nAn application version or an OTP version identifies source code versions. That\nis, it implies nothing about how the application or OTP has been built.","ref":"versions.html#version-scheme"},{"type":"extras","title":"Order of Versions - Versions","doc":"Version numbers in general are only partially ordered. However, normal version\nnumbers (with three parts) as of OTP 17.0 have a total or linear order. This\napplies both to normal OTP versions and normal application versions.\n\nWhen comparing two version numbers with a defined order, one compares\neach part as standard integers, starting from the most significant\npart and moving towards the less significant parts. The order is\ndetermined by the first parts of the same significance that differ. A\nlarger OTP version encompasses all changes present in a smaller OTP\nversion. The same principle applies to application versions.\n\nVersions can have more than three parts, resulting in partial\nordering. Such versions are only used when branching off from another\nbranch. When an extra part (apart from the normal three parts) is added to\na version number, a new branch of versions is made. The new branch has\na linear order against the base version. However, versions on\ndifferent branches have no order, and therefore one can only conclude\nthat they all include what is included in their closest common\nancestor. When branching multiple times from the same base version,\n`0` parts are added between the base version and the least significant\n`1` part until a unique version is found. Versions that have an order\ncan be compared as described in the previous paragraph.\n\nAn example of branched versions: The version `6.0.2.1` is a branched version\nfrom the base version `6.0.2`. Versions on the form `6.0.2. ` can be compared\nwith normal versions smaller than or equal to `6.0.2`, and other versions on the\nform `6.0.2. `. The version `6.0.2.1` will include all changes in `6.0.2`.\nHowever, `6.0.3` will most likely _not_ include all changes in `6.0.2.1` (note\nthat these versions have no order). A second branched version from the base\nversion `6.0.2` will be version `6.0.2.0.1`, and a third branched version will\nbe `6.0.2.0.0.1`.\n\n[](){: #releases_and_patches }","ref":"versions.html#order-of-versions"},{"type":"extras","title":"Releases and Patches - Versions","doc":"When a new OTP release is released it will have an OTP version on the form\n` .0` where the major OTP version number equals the release number. The\nmajor version number is increased one step since the last major version. All\nother OTP versions with the same major OTP version number are patches on that\nOTP release.\n\nPatches are either released as maintenance patch packages or emergency patch\npackages. The only difference is that maintenance patch packages are planned and\nusually contain more changes than emergency patch packages. Emergency patch\npackages are released to solve one or more specific issues when such are\ndiscovered.\n\nThe release of a maintenance patch package usually imply an increase\nof the OTP ` ` version, while the release of an emergency patch\npackage usually imply an increase of the OTP ` `\nversion. However, this is not always the case, as changes in OTP\nversions are determined by actual code modifications rather than\nwhether the patch was planned or not. For more information see\n[Version Scheme](versions.md#version_scheme).\n\n[](){: #otp_versions_tree }","ref":"versions.html#releases-and-patches"},{"type":"extras","title":"OTP Versions Tree - Versions","doc":"All released OTP versions can be found in the [OTP Versions\nTree](http://www.erlang.org/download/otp_versions_tree.html), which is\nautomatically updated whenever we release a new OTP version. Note that\neach version number explicitly determines its position in the version\ntree. All that is required to build the tree are the version numbers\nthemselves.\n\nThe root of the tree is OTP version 17.0 which is when we introduced the new\n[version scheme](versions.md#version_scheme). The green versions are normal\nversions released on the main track. Old\n[OTP releases](versions.md#releases_and_patches) will be maintained for a while\non `maint` branches that have branched off from the main track. Old `maint`\nbranches always branch off from the main track when the next OTP release is\nintroduced into the main track. Versions on these old `maint` branches are\nmarked blue.\n\nApart from the green and blue versions, there are also gray\nversions. These denote versions established on branches to resolve a\nparticular issue for a specific customer based on a specific base\nversion. Branches with gray versions will typically become dead ends\nvery quickly if not immediately.\n\n[](){: #otp_17_0_app_versions }","ref":"versions.html#otp-versions-tree"},{"type":"extras","title":"OTP 17.0 Application Versions - Versions","doc":"The following list details the application versions that were part of\nOTP 17.0.\n\nIf the normal part of an application version number is smaller than\nthe corresponding application version in the list, the version number\ndoes not adhere to the versioning scheme introduced in OTP\n17.0. Consequently, it is not regarded as having an order against\nversions used from OTP 17.0 onwards.\n\n- `asn1-3.0`\n- `common_test-1.8`\n- `compiler-5.0`\n- `cosEvent-2.1.15`\n- `cosEventDomain-1.1.14`\n- `cosFileTransfer-1.1.16`\n- `cosNotification-1.1.21`\n- `cosProperty-1.1.17`\n- `cosTime-1.1.14`\n- `cosTransactions-1.2.14`\n- `crypto-3.3`\n- `debugger-4.0`\n- `dialyzer-2.7`\n- `diameter-1.6`\n- `edoc-0.7.13`\n- `eldap-1.0.3`\n- `erl_docgen-0.3.5`\n- `erl_interface-3.7.16`\n- `erts-6.0`\n- `et-1.5`\n- `eunit-2.2.7`\n- `gs-1.5.16`\n- `hipe-3.10.3`\n- `ic-4.3.5`\n- `inets-5.10`\n- `jinterface-1.5.9`\n- `kernel-3.0`\n- `megaco-3.17.1`\n- `mnesia-4.12`\n- `observer-2.0`\n- `odbc-2.10.20`\n- `orber-3.6.27`\n- `os_mon-2.2.15`\n- `ose-1.0`\n- `otp_mibs-1.0.9`\n- `parsetools-2.0.11`\n- `percept-0.8.9`\n- `public_key-0.22`\n- `reltool-0.6.5`\n- `runtime_tools-1.8.14`\n- `sasl-2.4`\n- `snmp-4.25.1`\n- `ssh-3.0.1`\n- `ssl-5.3.4`\n- `stdlib-2.0`\n- `syntax_tools-1.6.14`\n- `test_server-3.7`\n- `tools-2.6.14`\n- `typer-0.9.6`\n- `webtool-0.8.10`\n- `wx-1.2`\n- `xmerl-1.3.7`","ref":"versions.html#otp-17-0-application-versions"},{"type":"extras","title":"Support, Compatibility, Deprecations, and Removal","doc":"\n# Support, Compatibility, Deprecations, and Removal","ref":"misc.html"},{"type":"extras","title":"Introduction - Support, Compatibility, Deprecations, and Removal","doc":"This document describes the strategy regarding supported Releases,\ncompatibility, deprecations, and removal of functionality.\n\n> #### Change {: .info }\n>\n> This document and the strategy it describes was introduced in\n> Erlang/OTP 21.\n\n[](){: #supported_releases }","ref":"misc.html#introduction"},{"type":"extras","title":"Supported Releases - Support, Compatibility, Deprecations, and Removal","doc":"In general, bugs are only fixed on the latest\n[release](versions.md#releases_and_patches), and new features are introduced in\nthe upcoming release that is under development. However, when we, for\ninternal reasons, fix bugs on older releases, these will be available and\nannounced as well.\n\nPull requests are only accepted on the `maint` and the `master`\nbranches in our [git repository](https://github.com/erlang/otp). The\n`maint` branch contains changes planned for the next [maintenance\npatch package](versions.md#releases_and_patches) on the latest OTP\nrelease and the `master` branch contain changes planned for the\nupcoming OTP release.","ref":"misc.html#supported-releases"},{"type":"extras","title":"Compatibility - Support, Compatibility, Deprecations, and Removal","doc":"We strive to remain as compatible as possible, even in cases where we\ngive no compatibility guarantees.\n\nDifferent parts of the system will be handled differently regarding\ncompatibility. The following items describe how different parts of the system\nare handled.\n\n- **Erlang Distribution** - Erlang nodes can communicate across at least two\n preceding and two subsequent releases.\n\n- **Compiled BEAM Code, NIF Libraries, and Drivers** - Compiled code\n can be loaded on at least two subsequent releases. To achive the\n highest possible performance for Erlang code, ensure it is compiled\n using the same release as the one it will be deployed on.\n\n Loading on previous releases is _not_ supported.\n\n- **APIs** - Compatible between releases.\n\n- **Compiler Warnings** - New warnings may be issued between releases.\n\n- **Command Line Arguments** - Incompatible changes may occur between releases.\n\n- **OTP Build Procedures** - Incompatible changes may occur between releases.\n\nUnder certain circumstances incompatible changes might be introduced even in\nparts of the system that should be compatible between releases. Things that\nmight trigger incompatible changes like this are:\n\n- **Security Issues** - It might be necessary to introduce incompatible changes\n in order to solve a security issue. This kind of incompatibility might occur\n in a patch.\n\n- **Bug Fixes** - We will not be bug-compatible. A bug fix might introduce\n incompatible changes. This kind of incompatibility might occur in a patch.\n\n- **Severe Previous Design Issues** - Some parts of OTP were designed\n a very long time ago and did not necessarily take today's computing\n environments into account. Consequently, the ramifications of these\n design choices can be quite significant, impacting performance,\n scalability, and more. If we determine that these consequences are\n too substantial, we may implement incompatible changes. Such changes\n are never introduced in a patch, but in the subsequent release.\n\nPeripheral, trace, and debug functionality is at greater risk of being changed\nin an incompatible way than functionality in the language itself and core\nlibraries used during operation.\n\nThere is a page in the documentation regarding incompatibilities:\n\n* [Upcoming Potential Incompatibilities](`e:general_info:upcoming_incompatibilities.md`) -\n lists all upcoming potential incompatibilities.","ref":"misc.html#compatibility"},{"type":"extras","title":"Deprecation - Support, Compatibility, Deprecations, and Removal","doc":"Deprecation of functionality occurs when newer, preferred alternatives\nare introduced. The deprecation does **not** imply future removal of the\nfunctionality unless an upcoming removal is explicitly stated in the\ndeprecation notice.\n\nDeprecated functionality will be documented as deprecated and highlighted\nin a release note as early possible. If appropriate, the compiler will\nissue warnings when the deprecated functionality is used.\n\nThere is a page in the documentation regarding deprecations:\n\n* [Deprecations](`e:general_info:deprecations.md`) - lists all\n deprecated functionality.","ref":"misc.html#deprecation"},{"type":"extras","title":"Removal - Support, Compatibility, Deprecations, and Removal","doc":"It can become necessary to remove legacy solutions. In such instances,\nthey will be gradually phased out over a sufficient period to allow\nusers to adjust. Before functionality is removed, it will be\ndeprecated for at least one release, with an explicit announcement\nabout the upcoming removal.\n\nPeripheral, trace, and debug functionality is at greater risk of removal than\nfunctionality in the language itself and core libraries used during operation.\n\nThere are two pages in the documentation regarding removal:\n\n* [Scheduled for Removal](`e:general_info:scheduled_for_removal.md`) - lists\n all functionality that is schedule for removal in upcoming releases.\n\n* [Removed Functionality](`e:general_info:removed.md`) - lists\n functionality that has been removed.","ref":"misc.html#removal"},{"type":"extras","title":"Overview","doc":"\n# Overview\n\n[](){: #otp-design-principles }\n\nThe _OTP Design Principles_ define how to structure Erlang code in terms of\nprocesses, modules, and directories.","ref":"design_principles.html"},{"type":"extras","title":"Supervision Trees - Overview","doc":"A basic concept in Erlang/OTP is the _supervision tree_. This is a process\nstructuring model based on the idea of _workers_ and _supervisors_:\n\n- Workers are processes that perform computations and other actual work.\n- Supervisors are processes that monitor workers. A supervisor\n can restart a worker if something goes wrong.\n- The supervision tree is a hierarchical arrangement of code into supervisors\n and workers, which makes it possible to design and program fault-tolerant\n software.\n\nIn the following figure, square boxes represents supervisors and circles\nrepresent workers:\n\n[](){: #sup6 }\n\n```mermaid\n---\ntitle: Supervision Tree\n---\nflowchart\n sup1[Type 1 Supervisor] --- sup2[Type 1 Supervisor] --- worker1((worker))\n sup1 --- sup1a[Type A Supervisor]\n\n sup1a --- sup2a[Type A Supervisor] --- worker2((worker))\n sup1a --- sup3[Type 1 Supervisor]\n\n sup3 --- worker3((worker))\n sup3 --- worker4((worker))\n```","ref":"design_principles.html#supervision-trees"},{"type":"extras","title":"Behaviours - Overview","doc":"In a supervision tree, many of the processes have similar structures\nand follow similar patterns. For example, the supervisors share a\nsimilar structure, with the sole distinction lying in the child\nprocesses they supervise. Many of the workers are servers in a\nserver-client relation, finite-state machines, or event handlers.\n\n_Behaviours_ are formalizations of these common patterns. The idea is to divide\nthe code for a process in a generic part (a behaviour module) and a specific\npart (a _callback module_).\n\nThe behaviour module is part of Erlang/OTP. To implement a process such as a\nsupervisor, the user only needs to implement the callback module, which is to\nexport a pre-defined set of functions, the _callback functions_.\n\nThe following example illustrate how code can be divided into a generic and a\nspecific part. Consider the following code (written in plain Erlang) for a\nsimple server, which keeps track of a number of \"channels\". Other processes can\nallocate and free the channels by calling the functions `alloc/0` and `free/1`,\nrespectively.\n\n[](){: #ch1 }\n\n```erlang\n-module(ch1).\n-export([start/0]).\n-export([alloc/0, free/1]).\n-export([init/0]).\n\nstart() ->\n spawn(ch1, init, []).\n\nalloc() ->\n ch1 ! {self(), alloc},\n receive\n {ch1, Res} ->\n Res\n end.\n\nfree(Ch) ->\n ch1 ! {free, Ch},\n ok.\n\ninit() ->\n register(ch1, self()),\n Chs = channels(),\n loop(Chs).\n\nloop(Chs) ->\n receive\n {From, alloc} ->\n {Ch, Chs2} = alloc(Chs),\n From ! {ch1, Ch},\n loop(Chs2);\n {free, Ch} ->\n Chs2 = free(Ch, Chs),\n loop(Chs2)\n end.\n```\n\nThe code for the server can be rewritten into a generic part `server.erl`:\n\n```erlang\n-module(server).\n-export([start/1]).\n-export([call/2, cast/2]).\n-export([init/1]).\n\nstart(Mod) ->\n spawn(server, init, [Mod]).\n\ncall(Name, Req) ->\n Name ! {call, self(), Req},\n receive\n {Name, Res} ->\n Res\n end.\n\ncast(Name, Req) ->\n Name ! {cast, Req},\n ok.\n\ninit(Mod) ->\n register(Mod, self()),\n State = Mod:init(),\n loop(Mod, State).\n\nloop(Mod, State) ->\n receive\n {call, From, Req} ->\n {Res, State2} = Mod:handle_call(Req, State),\n From ! {Mod, Res},\n loop(Mod, State2);\n {cast, Req} ->\n State2 = Mod:handle_cast(Req, State),\n loop(Mod, State2)\n end.\n```\n\nAnd a callback module `ch2.erl`:\n\n```erlang\n-module(ch2).\n-export([start/0]).\n-export([alloc/0, free/1]).\n-export([init/0, handle_call/2, handle_cast/2]).\n\nstart() ->\n server:start(ch2).\n\nalloc() ->\n server:call(ch2, alloc).\n\nfree(Ch) ->\n server:cast(ch2, {free, Ch}).\n\ninit() ->\n channels().\n\nhandle_call(alloc, Chs) ->\n alloc(Chs). % => {Ch,Chs2}\n\nhandle_cast({free, Ch}, Chs) ->\n free(Ch, Chs). % => Chs2\n```\n\nNotice the following:\n\n- The code in `server` can be reused to build many different servers.\n- The server name, in this example the atom `ch2`, is hidden from the users of\n the client functions. This means that the name can be changed without\n affecting them.\n- The protocol (messages sent to and received from the server) is also hidden.\n This is good programming practice and allows one to change the protocol\n without changing the code using the interface functions.\n- The functionality of `server` can be extended without having to change `ch2`\n or any other callback module.\n\nIn `ch1.erl` and `ch2.erl` above, the implementation of `channels/0`, `alloc/1`,\nand `free/2` has been intentionally left out, as it is not relevant to the\nexample. For completeness, one way to write these functions is given below. This\nis an example only, a realistic implementation must be able to handle situations\nlike running out of channels to allocate, and so on.\n\n[](){: #channels-implementation }\n\n```erlang\nchannels() ->\n {_Allocated = [], _Free = lists:seq(1, 100)}.\n\nalloc({Allocated, [H|T] = _Free}) ->\n {H, {[H|Allocated], T}}.\n\nfree(Ch, {Alloc, Free} = Channels) ->\n case lists:member(Ch, Alloc) of\n true ->\n {lists:delete(Ch, Alloc), [Ch|Free]};\n false ->\n Channels\n end.\n```\n\nCode written without using behaviours can be more efficient, but the increased\nefficiency is at the expense of generality. The ability to manage all\napplications in the system in a consistent manner is important.\n\nUsing behaviours also makes it easier to read and understand code written by\nother programmers. Improvised programming structures, while possibly more\nefficient, are always more difficult to understand.\n\nThe `server` module corresponds, greatly simplified, to the Erlang/OTP behaviour\n`gen_server`.\n\nThe standard Erlang/OTP behaviours are:\n\n- [gen_server](gen_server_concepts.md)\n\n For implementing the server of a client-server relation\n\n- [gen_statem](statem.md)\n\n For implementing state machines\n\n- [gen_event](events.md)\n\n For implementing event handling functionality\n\n- [supervisor](sup_princ.md)\n\n For implementing a supervisor in a supervision tree\n\nThe compiler understands the module attribute `-behaviour(Behaviour)` and issues\nwarnings about missing callback functions, for example:\n\n```erlang\n-module(chs3).\n-behaviour(gen_server).\n...\n\n3> c(chs3).\n./chs3.erl:10: Warning: undefined call-back function handle_call/3\n{ok,chs3}\n```","ref":"design_principles.html#behaviours"},{"type":"extras","title":"Applications - Overview","doc":"Erlang/OTP comes with a number of components, each implementing some specific\nfunctionality. Components are with Erlang/OTP terminology called _applications_.\nExamples of Erlang/OTP applications are Mnesia, which has everything needed for\nprogramming database services, and Debugger, which is used to debug Erlang\nprograms. The minimal system based on Erlang/OTP consists of the following two\napplications:\n\n- Kernel - Functionality necessary to run Erlang\n- STDLIB - Erlang standard libraries\n\nThe application concept applies both to program structure (processes) and\ndirectory structure (modules).\n\nThe simplest applications do not have any processes, but consist of a collection\nof functional modules. Such an application is called a _library application_. An\nexample of a library application is STDLIB.\n\nAn application with processes is easiest implemented as a supervision tree using\nthe standard behaviours.\n\nHow to program applications is described in [Applications](applications.md).","ref":"design_principles.html#applications"},{"type":"extras","title":"Releases - Overview","doc":"A _release_ is a complete system made out from a subset of Erlang/OTP\napplications and a set of user-specific applications.\n\nHow to program releases is described in [Releases](release_structure.md).\n\nHow to install a release in a target environment is described in\n[Creating and Upgrading a Target System](`e:system:create_target.md`) in System Principles.","ref":"design_principles.html#releases"},{"type":"extras","title":"Release Handling - Overview","doc":"_Release handling_ is upgrading and downgrading between different versions of a\nrelease, in a (possibly) running system. How to do this is described in\n[Release Handling](release_handling.md).","ref":"design_principles.html#release-handling"},{"type":"extras","title":"gen_server Behaviour","doc":"\n\n[](){: #gen_server }gen_server Behaviour\n========================================\n\nIt is recommended to read this section alongside `m:gen_server` in STDLIB.\n\nClient-Server Principles\n------------------------\n\nThe client-server model is characterized by a central server and an arbitrary\nnumber of clients. The client-server model is used for resource management\noperations, where several different clients want to share a common resource.\nThe server is responsible for managing this resource.\n\n[](){: #clientserver }\n\n```mermaid\n---\ntitle: Client Server Model\n---\n\nflowchart LR\n client1((Client))\n client2((Client))\n client3((Client))\n server((Server))\n\n client1 --> server\n server -.-> client1\n\n client2 --> server\n server -.-> client2\n\n client3 --> server\n server -.-> client3\n\n subgraph Legend\n direction LR\n\n start1[ ] -->|Query| stop1[ ]\n style start1 height:0px;\n style stop1 height:0px;\n\n start2[ ] -.->|Reply| stop2[ ]\n style start2 height:0px;\n style stop2 height:0px;\n end\n```\n\nExample\n-------\n\nAn example of a simple server written in plain Erlang is provided in\n[Overview](design_principles.md#ch1). The server can be reimplemented using\n`gen_server`, resulting in this callback module:\n\n[](){: #ex }\n\n```erlang\n-module(ch3).\n-behaviour(gen_server).\n\n-export([start_link/0]).\n-export([alloc/0, free/1]).\n-export([init/1, handle_call/3, handle_cast/2]).\n\nstart_link() ->\n gen_server:start_link({local, ch3}, ch3, [], []).\n\nalloc() ->\n gen_server:call(ch3, alloc).\n\nfree(Ch) ->\n gen_server:cast(ch3, {free, Ch}).\n\ninit(_Args) ->\n {ok, channels()}.\n\nhandle_call(alloc, _From, Chs) ->\n {Ch, Chs2} = alloc(Chs),\n {reply, Ch, Chs2}.\n\nhandle_cast({free, Ch}, Chs) ->\n Chs2 = free(Ch, Chs),\n {noreply, Chs2}.\n```\n\nThe code is explained in the next sections.\n\nStarting a Gen_Server\n---------------------\n\nIn the example in the previous section, `gen_server` is started by calling\n`ch3:start_link()`:\n\n```erlang\nstart_link() ->\n gen_server:start_link({local, ch3}, ch3, [], []) => {ok, Pid}\n```\n\n`start_link/0` calls function `gen_server:start_link/4`. This function\nspawns and links to a new process, a `gen_server`.\n\n- The first argument, `{local, ch3}`, specifies the name.\n The gen_server is then locally registered as `ch3`.\n\n If the name is omitted, the `gen_server` is not registered. Instead its pid\n must be used. The name can also be given as `{global, Name}`, in which case\n the `gen_server` is registered using `global:register_name/2`.\n\n- The second argument, `ch3`, is the name of the callback module, which is\n the module where the callback functions are located.\n\n The interface functions (`start_link/0`, `alloc/0`, and `free/1`) are located\n in the same module as the callback functions (`init/1`, `handle_call/3`, and\n `handle_cast/2`). It is usually good programming practice to have the code\n corresponding to one process contained in a single module.\n\n- The third argument, `[]`, is a term that is passed as is to the callback\n function `init`. Here, `init` does not need any indata and ignores the\n argument.\n\n- The fourth argument, `[]`, is a list of options. See `m:gen_server`\n for the available options.\n\nIf name registration succeeds, the new `gen_server` process calls the callback\nfunction `ch3:init([])`. `init` is expected to return `{ok, State}`, where\n`State` is the internal state of the `gen_server`. In this case, the state is\nthe available channels.\n\n```erlang\ninit(_Args) ->\n {ok, channels()}.\n```\n\n`gen_server:start_link/4` is synchronous. It does not return until the\n`gen_server` has been initialized and is ready to receive requests.\n\n`gen_server:start_link/4` must be used if the `gen_server` is part of\na supervision tree, meaning that it was started by a supervisor. There\nis another function, `gen_server:start/4`, to start a standalone\n`gen_server` that is not part of a supervision tree.\n\nSynchronous Requests - Call\n---------------------------\n\nThe synchronous request `alloc()` is implemented using `gen_server:call/2`:\n\n```text\nalloc() ->\n gen_server:call(ch3, alloc).\n```\n\n`ch3` is the name of the `gen_server` and must agree with the name\nused to start it. `alloc` is the actual request.\n\nThe request is made into a message and sent to the `gen_server`.\nWhen the request is received, the `gen_server` calls\n`handle_call(Request, From, State)`, which is expected to return\na tuple `{reply,Reply,State1}`. `Reply` is the reply that is to be sent back\nto the client, and `State1` is a new value for the state of the `gen_server`.\n\n```erlang\nhandle_call(alloc, _From, Chs) ->\n {Ch, Chs2} = alloc(Chs),\n {reply, Ch, Chs2}.\n```\n\nIn this case, the reply is the allocated channel `Ch` and the new state is the\nset of remaining available channels `Chs2`.\n\nThus, the call `ch3:alloc()` returns the allocated channel `Ch` and the\n`gen_server` then waits for new requests, now with an updated list of\navailable channels.\n\nAsynchronous Requests - Cast\n----------------------------\n\nThe asynchronous request `free(Ch)` is implemented using `gen_server:cast/2`:\n\n```erlang\nfree(Ch) ->\n gen_server:cast(ch3, {free, Ch}).\n```\n\n`ch3` is the name of the `gen_server`. `{free, Ch}` is the actual request.\n\nThe request is made into a message and sent to the `gen_server`.\n`cast`, and thus `free`, then returns `ok`.\n\nWhen the request is received, the `gen_server` calls\n`handle_cast(Request, State)`, which is expected to return a tuple\n`{noreply,State1}`. `State1` is a new value for the state of the `gen_server`.\n\n```erlang\nhandle_cast({free, Ch}, Chs) ->\n Chs2 = free(Ch, Chs),\n {noreply, Chs2}.\n```\n\nIn this case, the new state is the updated list of available channels `Chs2`.\nThe `gen_server` is now ready for new requests.\n\nStopping\n--------","ref":"gen_server_concepts.html"},{"type":"extras","title":"In a Supervision Tree - gen_server Behaviour","doc":"If the `gen_server` is part of a supervision tree, no stop function is needed.\nThe `gen_server` is automatically terminated by its supervisor. Exactly how\nthis is done is defined by a [shutdown strategy](sup_princ.md#shutdown)\nset in the supervisor.\n\nIf it is necessary to clean up before termination, the shutdown strategy\nmust be a time-out value and the `gen_server` must be set to trap exit signals\nin function `init`. When ordered to shutdown, the `gen_server` then calls\nthe callback function `terminate(shutdown, State)`:\n\n```erlang\ninit(Args) ->\n ...,\n process_flag(trap_exit, true),\n ...,\n {ok, State}.\n\n...\n\nterminate(shutdown, State) ->\n %% Code for cleaning up here\n ...\n ok.\n```","ref":"gen_server_concepts.html#in-a-supervision-tree"},{"type":"extras","title":"Standalone Gen_Servers - gen_server Behaviour","doc":"If the `gen_server` is not part of a supervision tree, a stop function\ncan be useful, for example:\n\n```erlang\n...\nexport([stop/0]).\n...\n\nstop() ->\n gen_server:cast(ch3, stop).\n...\n\nhandle_cast(stop, State) ->\n {stop, normal, State};\nhandle_cast({free, Ch}, State) ->\n ...\n\n...\n\nterminate(normal, State) ->\n ok.\n```\n\nThe callback function handling the `stop` request returns a tuple\n`{stop,normal,State1}`, where `normal` specifies that it is\na normal termination and `State1` is a new value for the state\nof the `gen_server`. This causes the `gen_server` to call\n`terminate(normal, State1)` and then it terminates gracefully.\n\nHandling Other Messages\n-----------------------\n\nIf the `gen_server` is to be able to receive other messages than requests,\nthe callback function `handle_info(Info, State)` must be implemented\nto handle them. Examples of other messages are exit messages,\nif the `gen_server` is linked to other processes than the supervisor\nand it is trapping exit signals.\n\n```erlang\nhandle_info({'EXIT', Pid, Reason}, State) ->\n %% Code to handle exits here.\n ...\n {noreply, State1}.\n```\n\nThe final function to implement is `code_change/3`:\n\n```erlang\ncode_change(OldVsn, State, Extra) ->\n %% Code to convert state (and more) during code change.\n ...\n {ok, NewState}.\n```","ref":"gen_server_concepts.html#standalone-gen_servers"},{"type":"extras","title":"gen_statem Behaviour","doc":"\n\n`gen_statem` Behaviour\n======================\n\nIt is recommended to read this section alongside\nthe `m:gen_statem` reference manual in STDLIB.\n\nEvent-Driven State Machines\n---------------------------\n\nEstablished Automata Theory does not deal much with how a _state transition_\nis triggered, but assumes that the output is a function of the input\n(and the state) and that they are some kind of values.\n\nFor an Event-Driven State Machine, the input is an _event_ that triggers\na _state transition_ and the output is actions executed during\nthe _state transition_. Analogously to the mathematical model\nof a Finite State Machine, it can be described as a set of relations\nof the following form:\n\n```erlang\nState(S) x Event(E) -> Actions(A), State(S')\n```\n\nThese relations are interpreted as follows: if we are in state `S`,\nand event `E` occurs, we are to perform actions `A`, and make a transition\nto state `S'`. Notice that `S'` can be equal to `S`,\nand that `A` can be empty.\n\nIn `gen_statem` we define a _state change_ as a _state transition_ in which the\nnew state `S'` is different from the current state `S`, where \"different\" means\nErlang's strict inequality: `=/=` also known as \"does not match\". `gen_statem`\ndoes more things during _state changes_ than during other _state transitions_.\n\nAs `A` and `S'` depend only on `S` and `E`, the kind of state machine described\nhere is a Mealy machine (see, for example, the Wikipedia article\n[Mealy machine](https://en.wikipedia.org/wiki/Mealy_machine)).\n\nSimilar to most `gen_` behaviours, `gen_statem` keeps a server `Data`\nitem besides the state. Because of this data item, and since there is\nno restriction on the number of states (assuming sufficient virtual\nmachine memory), or on the number of distinct input events, a state\nmachine implemented with this behaviour is Turing complete. But it\nfeels mostly like an Event-Driven Mealy machine.","ref":"statem.html"},{"type":"extras","title":"Everyday State Machine - gen_statem Behaviour","doc":"An example of an everyday device that can be modelled as a state machine\nis a classic ballpoint pen, the retractable type where you push the end\nto expose the tip and push the side to retract it. (A push-push pen\nwould also be an example but that type has only one event, so it is\nless interesting)\n\n![Ballpoint Pen](assets/ballpoint-pen.svg \"Ballpoint Pen\")\n\n```mermaid\n---\ntitle: Ballpoint Pen State Diagram\n---\nstateDiagram-v2\n [*] --> Retracted\n Retracted --> Retracted : push-side\n Retracted --> Exposed : push-end\\n* Expose tip\n Exposed --> Retracted : push-side\\n* Retract tip\n Exposed --> Exposed : push-end\n```\n\nThe state diagram shows the states, events, and state transitions\nwith transition actions. Note that pushing the end when the tip is exposed,\nor pushing the side when the tip is retracted, does not change the state\nnor cause any actions, which is modeled by an arrow back to the same state.\n\nWhen to use gen_statem\n----------------------\n\nYou should consider using `m:gen_statem` over `m:gen_server` if your\nprocess logic is convenient to describe as a state machine and you\nneed any of these `m:gen_statem` key features:\n\n- Co-located callback code for each state, for all\n [_event types_](#event-types-and-event-content), such as _call_,\n _cast_, and _info_\n- [_Postponing events_](#postponing-events) - a substitute for selective\n receive\n- [_Inserted events_](#inserted-events) - events from the state\n machine to itself; for purely internal events in particular\n- [_State enter calls_](#state-enter-calls) - callback on state entry\n co-located with the rest of each state's callback code\n- Easy-to-use time-outs - [_state time-outs_](#state-time-outs),\n [_event time-outs_](#event-time-outs), and\n [_generic time-outs_](#generic-time-outs) (named time-outs)\n\nFor simple state machines not needing these features, `m:gen_server`\nis perfectly suitable. It also has a smaller call overhead, but we are\ntalking about something like 2 vs 3.3 microseconds call roundtrip time\nhere, so if the server callback does just a little bit more than just\nreplying, or if calls are not extremely frequent, that difference\nwill be hard to notice.\n\nCallback Module\n---------------\n\nThe _callback module_ contains functions that implement the state\nmachine. When an event occurs, the `gen_statem` behaviour engine calls\na function in the _callback module_ with the event, current state, and\nserver data. This callback function performs the actions for the\nevent, and returns the new state and server data as well as actions to\nbe performed by the behaviour engine.\n\nThe behaviour engine holds the state machine state, server data, timer\nreferences, a queue of postponed messages, and other metadata. It receives all\nprocess messages, handles the system messages, and calls the _callback module_\nwith state machine specific events.\n\nThe _callback module_ can be changed for a running server using any of the\n[_transition actions_](#transition-actions)\n[`{change_callback_module, NewModule}`](`t:gen_statem:action/0`),\n[`{push_callback_module, NewModule}`](`t:gen_statem:action/0`), or\n[`pop_callback_module`](`t:gen_statem:action/0`).\n\n> #### Note {: .info }\n>\n> Switching the callback module is a pretty esoteric thing to do...\n>\n> The origin for this feature is a protocol that after version\n> negotiation branches off into quite different state machines depending\n> on the protocol version. There _might_ be other use cases. _Beware_\n> that the new callback module completely replaces the previous callback\n> module, so all relevant callback functions have to handle the state\n> and data from the previous callback module.\n\nCallback Modes\n--------------\n\nThe `gen_statem` behaviour supports two _callback modes_:\n\n- **[`state_functions`](`t:gen_statem:callback_mode/0`)** - Events are handled\n by one callback function per state.\n\n- **[`handle_event_function`](`t:gen_statem:callback_mode/0`)** - Events are\n handled by one single callback function.\n\nThe _callback mode_ is a property of the _callback module_ and is set at server\nstart. It may be changed due to a code upgrade/downgrade, or when changing the\n_callback module_.\n\nSee the section [_State Callback_](#state-callback) that describes the\nevent handling callback function(s).\n\nThe _callback mode_ is selected by implementing a mandatory callback function\n[`Module:callback_mode()`](`c:gen_statem:callback_mode/0`) that returns one of\nthe _callback modes_.\n\nThe [`Module:callback_mode()`](`c:gen_statem:callback_mode/0`) function\nmay also return a list containing the _callback mode_ and the atom\n`state_enter` in which case [_state enter calls_](#state-enter-calls)\nare activated for the _callback mode_.","ref":"statem.html#everyday-state-machine"},{"type":"extras","title":"Choosing the Callback Mode - gen_statem Behaviour","doc":"The short version: choose `state_functions` - it is the one most like\n`m:gen_fsm`. But if you do not want the restriction that the state must be an\natom, or if you do not want to write one _state callback_ function per state,\nplease read on...\n\nThe two [_callback modes_](#callback-modes) give different\npossibilities and restrictions, with one common goal: to handle all possible\ncombinations of events and states.\n\nThis can be done, for example, by focusing on one state at the time and for\nevery state ensure that all events are handled. Alternatively, you can focus\non one event at the time and ensure that it is handled in every state.\nYou can also use a mix of these strategies.\n\nWith `state_functions`, you are restricted to use atom-only states, and the\n`m:gen_statem` engine branches depending on state name for you.\nThis encourages the _callback module_ to co-locate the implementation\nof all event actions particular to one state in the same place in the code,\nhence to focus on one state at the time.\n\nThis mode fits well when you have a regular state diagram, like the ones\nin this chapter, which describes all events and actions belonging to a state\nvisually around that state, and each state has its unique name.\n\nWith `handle_event_function`, you are free to mix strategies, as all events\nand states are handled in the same callback function.\n\nThis mode works equally well when you want to focus on one event\nat the time or on one state at the time, but function\n[`Module:handle_event/4`](`c:gen_statem:handle_event/4`) quickly grows\ntoo large to handle without branching to helper functions.\n\nThe mode enables the use of non-atom states, for example, complex states,\nor even hierarchical states. See section [_Complex State_](#complex-state).\nIf, for example, a state diagram is largely alike for the client side\nand the server side of a protocol, you can have a state `{StateName, server}`,\nor `{StateName, client}`, and make `StateName` determine where in the code\nto handle most events in the state. The second element of the tuple\nis then used to select whether to handle special client-side\nor server-side events.\n\nState Callback\n--------------\n\nThe _state callback_ is the callback function that handles an event in the\ncurrent state, and which function that is depends on the _callback mode_:\n\n- **`state_functions`** - The event is handled by:\n [`Module:StateName(EventType, EventContent,\n Data)`](`c:gen_statem:'StateName'/3`)\n\n This form is the one mostly used in the [_Example_](#example) section.\n\n- **`handle_event_function`** - The event is handled by:\n [`Module:handle_event(EventType, EventContent, State,\n Data)`](`c:gen_statem:handle_event/4`)\n\n See section [_One State Callback_](#one-state-callback) for an example.\n\nThe state is either the name of the state callback itself, or an argument\nto the [`handle_event()`](`c:gen_statem:handle_event/4`) callback. The\nother arguments are the `EventType` and the event dependent `EventContent`,\nboth described in section\n[_Event Types and Event Content_](#event-types-and-event-content),\nand the the last argument is the current server `Data`.\n\n[_State Enter Calls_](#state-enter-calls) (see that section)\nare also handled by the event handler and have slightly different arguments.\n\nThe _state callback_ return values are defined in the description of\n[`Module:StateName/3`](`c:gen_statem:'StateName'/3`) in `m:gen_statem`.\nHere is a maybe more readable list:\n\n- **`{next_state, NextState, NewData [, Actions]}`**\n Set next state and update the server data. If the `Actions` field is used,\n execute [_Transition Actions_](#transition-actions)\n (see that section). An empty `Actions` list is equivalent to not\n returning the field.\n\n If `NextState =/= State` it's a _state change_ and `gen_statem`\n does some extra things: the event queue is restarted from the oldest\n [postponed event](#postponing-events), any current\n [_state time-out_](#state-time-outs) is canceled, and a\n [_state enter call_](#state-enter-calls) is performed, if enabled.\n The current `State` becomes `OldState` in a _state enter call_.\n\n- **`{keep_state, NewData [, Actions]}`**\n Same as the `next_state` values with `NextState =:= State`, that is,\n no _state change_.\n\n- **`keep_state_and_data | {keep_state_and_data, Actions}`**\n Same as the `keep_state` values with `NextData =:= Data`, that is, no change\n in server data.\n\n- **`{repeat_state, NewData [, Actions]} |\n repeat_state_and_data |{repeat_state_and_data, Actions}`**\n Same as the `keep_state` or `keep_state_and_data` values, but if\n [_state enter calls_](#state-enter-calls) are enabled;\n repeat it as if this state was entered again. In this case `State`\n and `OldState` becomes equal in the repeated _state enter call_\n since the state is re-entered from itself.\n\n- **`{stop, Reason [, NewData]}`**\n Stop the server with reason `Reason`. If the `NewData` field is used,\n first update the server data.\n\n- **`{stop_and_reply, Reason, [NewData, ] ReplyActions}`**\n Same as the `stop` values, but first execute the given\n [_transition actions_](#transition-actions)\n that may only be reply actions.","ref":"statem.html#choosing-the-callback-mode"},{"type":"extras","title":"The First State - gen_statem Behaviour","doc":"To decide the first state the\n[`Module:init(Args)`](`c:gen_statem:init/1`) callback function is called\nbefore any [_state callback_](#state-callback) is called. This function\nbehaves like a _state callback_ function, but gets its only argument `Args`\nfrom the `gen_statem` [`start/3,4`](`gen_statem:start/3`) or\n[`start_link/3,4`](`gen_statem:start_link/3`) function, and returns\n`{ok, State, Data}` or `{ok, State, Data, Actions}`. If you use the\n[`postpone`](#postponing-events) action from this function, that action\nis ignored, since there is no event to postpone.\n\nTransition Actions\n------------------\n\nIn the first section\n([_Event-Driven State Machines_](#event-driven-state-machines)), actions\nwere mentioned as a part of the general state machine model. These general\nactions are implemented with the code that _callback module_ `gen_statem`\nexecutes in an event-handling callback function before returning to the\n`m:gen_statem` engine.\n\nThere are more specific _transition actions_ that a callback function can\ncommand the `gen_statem` engine to do after the callback function return.\nThese are commanded by returning a list of [_actions_](`t:gen_statem:action/0`)\nin the [return value](`t:gen_statem:state_callback_result/2`) from the\n[_callback function_](`c:gen_statem:'StateName'/3`). These are the possible\n_transition actions_:\n\n- **[`{postpone, Boolean}`](`t:gen_statem:postpone/0`)** -\n If `true` postpone the current event, see section\n [_Postponing Events_](#postponing-events).\n\n- **[`{hibernate, Boolean`](`t:gen_statem:hibernate/0`)** -\n If `true` hibernate the `gen_statem`, treated in section\n [_Hibernation_](#hibernation).\n\n- **[`{state_timeout, Time, EventContent\n [, Opts]}`](`t:gen_statem:state_timeout/0`)` |`**\\\n **[`{state_timeout, update,\n EventContent}`](`t:gen_statem:timeout_update_action/0`)` |`**\\\n **[`{state_timeout, cancel}`](`t:gen_statem:timeout_cancel_action/0`)** -\n Start, update, or cancel a _state time-out_, read more in sections\n [_Time-Outs_](#time-outs) and\n [_State Time-Outs_](#state-time-outs).\n\n- **[`{{timeout, Name}, Time, EventContent\n [, Opts]}`](`t:gen_statem:generic_timeout/0`)` |`**\\\n **[`{{timeout, Name}, update,\n EventContent}`](`t:gen_statem:timeout_update_action/0`)` |`**\\\n **[`{{timeout, Name}, cancel}`](`t:gen_statem:timeout_cancel_action/0`)** -\n Start, update, or cancel a _generic time-out_, read more in sections\n [_Time-Outs_](#time-outs) and\n [_Generic Time-Outs_](#generic-time-outs).\n\n- **[`{timeout, Time, EventContent\n [, Opts]}`](`t:gen_statem:event_timeout/0`)** -\n Start an _event time-out_, see more in sections [_Time-Outs_](#time-outs)\n and [_Event Time-Outs_](#event-time-outs).\n\n- **[`{reply, From, Reply}`](`t:gen_statem:reply_action/0`)** - Reply to a\n caller, mentioned at the end of section\n [_All State Events_](#all-state-events).\n\n- **[`{next_event, EventType, EventContent}`](`t:gen_statem:action/0`)** -\n Generate the next event to handle, see section\n [_Inserted Events_](#inserted-events).\n\n- **[`{change_callback_module, NewModule}`](`t:gen_statem:action/0`)** -\n Change the [_callback module_](#callback-module) for the running server.\n This can be done during any _state transition_, whether it is\n a _state change_ or not, but it _cannot_ be done from a\n [_state enter call_](#state-enter-calls).\n\n- **[`{push_callback_module, NewModule}`](`t:gen_statem:action/0`)** -\n Push the current _callback module_ to the top of an internal stack\n of callback modules and set the new [_callback module_](#callback-module)\n for the running server. Otherwise like\n `{change_callback_module, NewModule}` above.\n\n- **[`pop_callback_module`](`t:gen_statem:action/0`)** - Pop the top module\n from the internal stack of callback modules and set it to be the new\n [_callback module_](#callback-module) for the running server. If the\n stack is empty the server fails. Otherwise like\n `{change_callback_module, NewModule}` above.\n\nFor details, see module `m:gen_statem` for type\n[`action()`](`t:gen_statem:action/0`). You can, for example, reply to many\ncallers, generate multiple next events, and set a time-out to use absolute\ninstead of relative time (using the `Opts` field).\n\nOut of these _transition actions_, the only immediate action is\n`reply` for replying to a caller. The other actions are collected and\nhandled later during the _state transition_.\n[_Inserted events_](#inserted-events) are stored and inserted all\ntogether, and the rest set transition options where the last of a\nspecific type override the previous. See the description of a _state\ntransition_ in module `m:gen_statem` for type\n[`transition_option()`](`t:gen_statem:transition_option/0`).\n\nThe different [_Time-Outs_](#time-outs) and\n[`next_event`](#inserted-events) actions generate new events with\ncorresponding\n[_event types and event content_](#event-types-and-event-content).\n\nEvent Types and Event Content\n-----------------------------\n\nEvents are categorized in different\n[_event types_](`t:gen_statem:event_type/0`). Events of all types are for a\ngiven state handled in the same callback function, and that function gets\n`EventType` and `EventContent` as arguments. The meaning of the `EventContent`\ndepends on the `EventType`.\n\nThe following is a complete list of _event types_ and from where they come:\n\n- **[`cast`](`t:gen_statem:external_event_type/0`)** - Generated by\n [`gen_statem:cast(ServerRef, Msg)`](`gen_statem:cast/2`) where `Msg` becomes\n the `EventContent`.\n\n- **[`{call, From}`](`t:gen_statem:external_event_type/0`)** - Generated by\n [`gen_statem:call(ServerRef, Request)`](`gen_statem:call/2`),\n [`gen_statem:send_request(ServerRef,\n Request)`](`gen_statem:send_request/2`), or\n [`gen_statem:send_request(ServerRef, Request,\n _, _)`](`gen_statem:send_request/4`) where `Request` becomes\n the `EventContent`. `From` is the reply address to use when replying\n either through the _transition action_ `{reply, From, Reply}`,\n or by calling [`gen_statem:reply(From, Reply)`](`gen_statem:reply/1`)\n from the _callback module_.\n\n- **[`info`](`t:gen_statem:external_event_type/0`)** - Generated by\n any regular process message sent to the `gen_statem` process.\n The process message becomes the `EventContent`.\n\n- **[`state_timeout`](`t:gen_statem:timeout_event_type/0`)** - Generated by\n _transition action_\n [`{state_timeout, Time, EventContent}`](`t:gen_statem:timeout_action/0`)\n when the time-out expires. Read more in sections [_Time-Outs_](#time-outs)\n and [_State Time-Outs_](#state-time-outs).\n\n- **[`{timeout, Name}`](`t:gen_statem:timeout_event_type/0`)** - Generated by\n _transition action_\n [`{{timeout, Name},Time, EventContent}`](`t:gen_statem:timeout_action/0`)\n when the time-out expires. Read more in sections [_Time-Outs_](#time-outs)\n and [_Generic Time-Outs_](#generic-time-outs).\n\n- **[`timeout`](`t:gen_statem:timeout_event_type/0`)** - Generated by\n _transition action_\n [`{timeout, Time, EventContent}`](`t:gen_statem:timeout_action/0`)\n (or its short form `Time`) when the time-out expires. Read more in sections\n [_Time-Outs_](#time-outs) and [_Event Time-Outs_](#event-time-outs).\n\n- **[`internal`](`t:gen_statem:event_type/0`)** - Generated by _transition\n action_ [`{next_event, internal, EventContent}`](`t:gen_statem:action/0`).\n All _event types_ above can also be generated using the `next_event` action:\n `{next_event, EventType, EventContent}`.\n\nState Enter Calls\n-----------------\n\nThe `gen_statem` behaviour can, if this is enabled, regardless of _callback\nmode_, automatically call the [_state callback_](`t:gen_statem:state_enter/0`)\nwith special arguments whenever the state changes, so you can write\nstate enter actions near the rest of the _state transition_ rules.\nIt typically looks like this:\n\n```erlang\nStateName(enter, OldState, Data) ->\n ... code for state enter actions here ...\n {keep_state, NewData};\nStateName(EventType, EventContent, Data) ->\n ... code for actions here ...\n {next_state, NewStateName, NewData}.\n```\n\nSince the _state enter call_ is not an event there are restrictions on the\nallowed return value and state [_transition actions_](#transition-actions).\nYou must not change the state, [postpone](#postponing-events) this non-event,\n[insert any events](#inserted-events), or change the\n[_callback module_](#callback-module).\n\nThe first state that is entered after `c:gen_statem:init/1` will get\na _state enter call_ with `OldState` equal to the current state.\n\nYou may repeat the _state enter call_ using the `{repeat_state,...}` return\nvalue from the [_state callback_](#state-callback). In this case\n`OldState` will also be equal to the current state.\n\nDepending on how your state machine is specified, this can be a very useful\nfeature, but it forces you to handle the _state enter calls_ in all states.\nSee also the [_State Enter Actions_](#state-enter-actions) section.\n\nTime-Outs\n---------\n\nTime-outs in `gen_statem` are started from a\n[_transition action_](#transition-actions) during a state transition\nthat is when exiting from the [_state callback_](#state-callback).\n\nThere are 3 types of time-outs in `gen_statem`:\n\n- **[`state_timeout`](`t:gen_statem:state_timeout/0`)** - There is one\n [_state time-out_](#state-time-outs) that is automatically canceled by\n a _state change_.\n\n- **[`{timeout, Name}`](`t:gen_statem:generic_timeout/0`)** - There are any\n number of [_generic time-outs_](#generic-time-outs) differing by their\n `Name`. They have no automatic canceling.\n\n- **[`timeout`](`t:gen_statem:event_timeout/0`)** - There is one\n [_event time-out_](#event-time-outs) that is automatically canceled by\n any event. Note that [postponed](#postponing-events) and\n [inserted](#inserted-events) events cancel this time-out just as\n external events do.\n\nWhen a time-out is started, any running time-out of the same type\n(`state_timeout`, `{timeout, Name}`, or `timeout`) is canceled, that is,\nthe time-out is restarted with the new time and event content.\n\nAll time-outs have an `EventContent` that is part of the\n[_transition action_](#transition-actions) that starts the time-out.\nDifferent `EventContent`s does not create different time-outs. The\n`EventContent` is delivered to the [_state callback_](#state-callback)\nwhen the time-out expires.","ref":"statem.html#the-first-state"},{"type":"extras","title":"Canceling a Time-Out - gen_statem Behaviour","doc":"Starting a time-out with the `infinity` time value would never time out,\nwhich is optimized by not even starting it, and any running\ntime-out with the same tag will be canceled. The `EventContent` will\nin this case be ignored, so it makes sense to set it to `undefined`.\n\nA more explicit way to cancel a time-out is to use a\n[_transition action_](#transition-actions) on the form\n[`{TimeoutType, cancel}`](`t:gen_statem:timeout_cancel_action/0`).","ref":"statem.html#canceling-a-time-out"},{"type":"extras","title":"Updating a Time-Out - gen_statem Behaviour","doc":"While a time-out is running, its `EventContent` can be updated using a\n[_transition action_](#transition-actions) on the form\n[`{TimeoutType, update,\nNewEventContent}`](`t:gen_statem:timeout_update_action/0`).\n\nIf this feature is used while no such `TimeoutType` is running, a time-out\nevent is immediately delivered as when starting a\n[zero time-out](#zero-time-out).","ref":"statem.html#updating-a-time-out"},{"type":"extras","title":"Zero Time-Out - gen_statem Behaviour","doc":"If a time-out is started with the time `0` it will actually not be started.\nInstead the time-out event will immediately be inserted to be processed after\nany events already enqueued, and before any not yet received external events.\n\nNote that some time-outs are automatically canceled so if you for example\ncombine [postponing](#postponing-events) an event in a _state change_\nwith starting an [_event time-out_](#event-time-outs) with time `0` there\nwill be no time-out event inserted since the _event time-out_ is canceled by\nthe postponed event that is delivered due to the state change.\n\nExample\n-------\n\nA door with a code lock can be seen as a state machine. Initially,\nthe door is locked. When someone presses a button, a `{button, Button}`\nevent is generated. In the state diagram below, \"Collect Buttons\" means\nto store buttons up to as many as in the correct code; append to\na length capped list. If correct, the door is unlocked for 10 seconds.\nIf incorrect, we wait for a new button to be pressed.\n\n```mermaid\n---\ntitle: Code Lock State Diagram\n---\nstateDiagram-v2\n state check_code < >\n\n [*] --> locked : * do_lock()\\n* Clear Buttons\n\n locked --> check_code : {button, Button}\\n* Collect Buttons\n check_code --> locked : Incorrect code\n check_code --> open : Correct code\\n* do_unlock()\\n* Clear Buttons\\n* Set state_timeout 10 s\n\n open --> open : {button, Digit}\n open --> locked : state_timeout\\n* do_lock()\n```\n\nThis code lock state machine can be implemented using `m:gen_statem` with\nthe following _callback module_:\n\n```erlang\n-module(code_lock).\n-behaviour(gen_statem).\n-define(NAME, code_lock).\n\n-export([start_link/1]).\n-export([button/1]).\n-export([init/1,callback_mode/0,terminate/3]).\n-export([locked/3,open/3]).\n\nstart_link(Code) ->\n gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).\n\nbutton(Button) ->\n gen_statem:cast(?NAME, {button,Button}).\n\ninit(Code) ->\n do_lock(),\n Data = #{code => Code, length => length(Code), buttons => []},\n {ok, locked, Data}.\n\ncallback_mode() ->\n state_functions.\n```\n\n```erlang\nlocked(\n cast, {button,Button},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n NewButtons =\n if\n length(Buttons) \n Buttons;\n true ->\n tl(Buttons)\n end ++ [Button],\n if\n NewButtons =:= Code -> % Correct\n\t do_unlock(),\n {next_state, open, Data#{buttons := []},\n [{state_timeout,10_000,lock}]}; % Time in milliseconds\n\ttrue -> % Incomplete | Incorrect\n {next_state, locked, Data#{buttons := NewButtons}}\n end.\n```\n\n```erlang\nopen(state_timeout, lock, Data) ->\n do_lock(),\n {next_state, locked, Data};\nopen(cast, {button,_}, Data) ->\n {next_state, open, Data}.\n```\n\n```erlang\ndo_lock() ->\n io:format(\"Lock~n\", []).\ndo_unlock() ->\n io:format(\"Unlock~n\", []).\n\nterminate(_Reason, State, _Data) ->\n State =/= locked andalso do_lock(),\n ok.\n```\n\nThe code is explained in the next sections.\n\nStarting gen_statem\n-------------------\n\nIn the example in the previous section, `gen_statem` is started by calling\n`code_lock:start_link(Code)`:\n\n```erlang\nstart_link(Code) ->\n gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).\n```\n\n`start_link/1` calls function `gen_statem:start_link/4`,\nwhich spawns and links to a new process, a `gen_statem`.\n\n- The first argument, `{local,?NAME}`, specifies the name. In this case, the\n `gen_statem` is locally registered as `code_lock` through the macro `?NAME`.\n\n If the name is omitted, the `gen_statem` is not registered. Instead its pid\n must be used. The name can also be specified as `{global, Name}`, then the\n `gen_statem` is registered using `global:register_name/2` in Kernel.\n\n- The second argument, `?MODULE`, is the name of the _callback module_,\n that is, the module where the callback functions are located,\n which is this module.\n\n The interface functions (`start_link/1` and `button/1`) are located in the\n same module as the callback functions (`init/1`, `locked/3`, and `open/3`).\n It is normally good programming practice to have the client-side code\n and the server-side code contained in the same module.\n\n- The third argument, `Code`, is a list of digits, which is the correct\n unlock code that is passed to callback function `init/1`.\n\n- The fourth argument, `[]`, is a list of options. For the available options,\n see `gen_statem:start_link/3`.\n\nIf name registration succeeds, the new `gen_statem` process calls callback\nfunction `code_lock:init(Code)`. This function is expected to return\n`{ok, State, Data}`, where `State` is the initial state of the `gen_statem`,\nin this case `locked`; assuming that the door is locked to begin with.\n`Data` is the internal server data of the `gen_statem`. Here the server data\nis a [`map()`](`m:maps`) with key `code` that stores the correct\nbutton sequence, key `length` store its length, and key `buttons`\nthat stores the collected buttons up to the same length.\n\n```erlang\ninit(Code) ->\n do_lock(),\n Data = #{code => Code, length => length(Code), buttons => []},\n {ok, locked, Data}.\n```\n\nFunction [`gen_statem:start_link/3,4`](`gen_statem:start_link/3`)\nis synchronous. It does not return until the `gen_statem` is initialized\nand is ready to receive events.\n\nFunction [`gen_statem:start_link/3,4`](`gen_statem:start_link/3`)\nmust be used if the `gen_statem` is part of a supervision tree, that is,\nstarted by a supervisor. Function,\n[`gen_statem:start/3,4`](`gen_statem:start/3`) can be used to start\na standalone `gen_statem`, meaning it is not part of a supervision tree.\n\nFunction [`Module:callback_mode/0`](`c:gen_statem:callback_mode/0`) selects\nthe [`CallbackMode`](#callback-modes) for the _callback module_,\nin this case [`state_functions`](`t:gen_statem:callback_mode/0`).\nThat is, each state has its own handler function:\n\n```erlang\ncallback_mode() ->\n state_functions.\n```\n\nHandling Events\n---------------\n\nThe function notifying the code lock about a button event is implemented using\n`gen_statem:cast/2`:\n\n```erlang\nbutton(Button) ->\n gen_statem:cast(?NAME, {button,Button}).\n```\n\nThe first argument is the name of the `gen_statem` and must agree with\nthe name used to start it. So, we use the same macro `?NAME` as when starting.\n`{button, Button}` is the event content.\n\nThe event is sent to the `gen_statem`. When the event is received, the\n`gen_statem` calls `StateName(cast, Event, Data)`, which is expected\nto return a tuple `{next_state, NewStateName, NewData}`, or\n`{next_state, NewStateName, NewData, Actions}`. `StateName` is the name\nof the current state and `NewStateName` is the name of the next state.\n`NewData` is a new value for the server data of the `gen_statem`,\nand `Actions` is a list of actions to be performed by the `gen_statem` engine.\n\n```erlang\nlocked(\n cast, {button,Button},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n NewButtons =\n if\n length(Buttons) \n Buttons;\n true ->\n tl(Buttons)\n end ++ [Button],\n if\n NewButtons =:= Code -> % Correct\n\t do_unlock(),\n {next_state, open, Data#{buttons := []},\n [{state_timeout,10_000,lock}]}; % Time in milliseconds\n\ttrue -> % Incomplete | Incorrect\n {next_state, locked, Data#{buttons := NewButtons}}\n end.\n```\n\nIn state `locked`, when a button is pressed, it is collected with the\npreviously pressed buttons up to the length of the correct code, then\ncompared with the correct code. Depending on the result, the door is\neither unlocked and the `gen_statem` goes to state `open`, or the door\nremains in state `locked`.\n\nWhen changing to state `open`, the collected buttons are reset, the lock\nunlocked, and a _state time-out_ for 10 seconds is started.\n\n```erlang\nopen(cast, {button,_}, Data) ->\n {next_state, open, Data}.\n```\n\nIn state `open`, a button event is ignored by staying in the same state.\nThis can also be done by returning `{keep_state, Data}`, or in this case\nsince `Data` is unchanged, by returning `keep_state_and_data`.\n\nState Time-Outs\n---------------\n\nWhen a correct code has been given, the door is unlocked and the following\ntuple is returned from `locked/2`:\n\n```erlang\n{next_state, open, Data#{buttons := []},\n [{state_timeout,10_000,lock}]}; % Time in milliseconds\n```\n\n10,000 is a time-out value in milliseconds. After this time (10 seconds),\na time-out occurs. Then, `StateName(state_timeout, lock, Data)` is called.\nThe time-out occurs when the door has been in state `open` for 10 seconds.\nAfter that the door is locked again:\n\n```erlang\nopen(state_timeout, lock, Data) ->\n do_lock(),\n {next_state, locked, Data};\n```\n\nThe timer for a _state time-out_ is automatically canceled when\nthe state machine does a _state change_.\n\nYou can restart, cancel, or update a _state time-out_. See section\n[_Time-Outs_](#time-outs) for details.\n\nAll State Events\n----------------\n\nSometimes events can arrive in any state of the `gen_statem`. It is convenient\nto handle these in a common state handler function that all state functions\ncall for events not specific to the state.\n\nConsider a `code_length/0` function that returns the length\nof the correct code. We dispatch all events that are not state-specific\nto the common function `handle_common/3`:\n\n```erlang\n...\n-export([button/1,code_length/0]).\n...\n\ncode_length() ->\n gen_statem:call(?NAME, code_length).\n\n...\nlocked(...) -> ... ;\nlocked(EventType, EventContent, Data) ->\n handle_common(EventType, EventContent, Data).\n\n...\nopen(...) -> ... ;\nopen(EventType, EventContent, Data) ->\n handle_common(EventType, EventContent, Data).\n\nhandle_common({call,From}, code_length, #{code := Code} = Data) ->\n {keep_state, Data,\n [{reply,From,length(Code)}]}.\n```\n\nAnother way to do it is through a convenience macro `?HANDLE_COMMON/0`:\n\n```erlang\n...\n-export([button/1,code_length/0]).\n...\n\ncode_length() ->\n gen_statem:call(?NAME, code_length).\n\n-define(HANDLE_COMMON,\n ?FUNCTION_NAME(T, C, D) -> handle_common(T, C, D)).\n%%\nhandle_common({call,From}, code_length, #{code := Code} = Data) ->\n {keep_state, Data,\n [{reply,From,length(Code)}]}.\n\n...\nlocked(...) -> ... ;\n?HANDLE_COMMON.\n\n...\nopen(...) -> ... ;\n?HANDLE_COMMON.\n```\n\nThis example uses `gen_statem:call/2`, which waits for a reply from the server.\nThe reply is sent with a `{reply, From, Reply}` tuple in an action list in the\n`{keep_state, ...}` tuple that retains the current state. This return form is\nconvenient when you want to stay in the current state but do not know or care\nabout what it is.\n\nIf the common _state callback_ needs to know the current state a function\n`handle_common/4` can be used instead:\n\n```erlang\n-define(HANDLE_COMMON,\n ?FUNCTION_NAME(T, C, D) -> handle_common(T, C, ?FUNCTION_NAME, D)).\n```\n\nOne State Callback\n------------------\n\nIf [_callback mode_](#callback-modes) `handle_event_function` is used,\nall events are handled in\n[`Module:handle_event/4`](`c:gen_statem:handle_event/4`) and we can\n(but do not have to) use an event-centered approach where we first branch\ndepending on event and then depending on state:\n\n```erlang\n...\n-export([handle_event/4]).\n\n...\ncallback_mode() ->\n handle_event_function.\n\nhandle_event(cast, {button,Button}, State, #{code := Code} = Data) ->\n case State of\n\tlocked ->\n #{length := Length, buttons := Buttons} = Data,\n NewButtons =\n if\n length(Buttons) \n Buttons;\n true ->\n tl(Buttons)\n end ++ [Button],\n if\n NewButtons =:= Code -> % Correct\n do_unlock(),\n {next_state, open, Data#{buttons := []},\n [{state_timeout,10_000,lock}]}; % Time in milliseconds\n true -> % Incomplete | Incorrect\n {keep_state, Data#{buttons := NewButtons}}\n end;\n\topen ->\n keep_state_and_data\n end;\nhandle_event(state_timeout, lock, open, Data) ->\n do_lock(),\n {next_state, locked, Data};\nhandle_event(\n {call,From}, code_length, _State, #{code := Code} = Data) ->\n {keep_state, Data,\n [{reply,From,length(Code)}]}.\n\n...\n```\n\nStopping\n--------","ref":"statem.html#zero-time-out"},{"type":"extras","title":"In a Supervision Tree - gen_statem Behaviour","doc":"If the `gen_statem` is part of a supervision tree, no stop function is needed.\nThe `gen_statem` is automatically terminated by its supervisor. Exactly how\nthis is done is defined by a [shutdown strategy](sup_princ.md#shutdown)\nset in the supervisor.\n\nIf it is necessary to clean up before termination, the shutdown strategy\nmust be a time-out value and the `gen_statem` must in function `init/1`\nset itself to trap exit signals by calling\n[`process_flag(trap_exit, true)`](`erlang:process_flag/2`):\n\n```erlang\ninit(Args) ->\n process_flag(trap_exit, true),\n do_lock(),\n ...\n```\n\nWhen ordered to shut down, the `gen_statem` then calls callback function\n`terminate(shutdown, State, Data)`.\n\nIn this example, function `terminate/3` locks the door if it is open,\nso we do not accidentally leave the door open\nwhen the supervision tree terminates:\n\n```erlang\nterminate(_Reason, State, _Data) ->\n State =/= locked andalso do_lock(),\n ok.\n```","ref":"statem.html#in-a-supervision-tree"},{"type":"extras","title":"Standalone gen_statem - gen_statem Behaviour","doc":"If the `gen_statem` is not part of a supervision tree, it can be stopped\nusing [`gen_statem:stop/1`](`gen_statem:stop/1`), preferably through\nan API function:\n\n```erlang\n...\n-export([start_link/1,stop/0]).\n\n...\nstop() ->\n gen_statem:stop(?NAME).\n```\n\nThis makes the `gen_statem` call callback function `terminate/3` just like\nfor a supervised server and waits for the process to terminate.\n\nEvent Time-Outs\n---------------\n\nA time-out feature inherited from `gen_statem`'s predecessor `m:gen_fsm`,\nis an _event time-out_, that is, if an event arrives the timer is canceled.\nYou get either an event or a time-out, but not both.\n\nIt is ordered by the\n[_transition action_](#transition-actions) `{timeout, Time, EventContent}`,\nor just an integer `Time`, even without the enclosing actions list (the latter\nis a form inherited from `gen_fsm`).\n\nThis type of time-out is useful, for example, to act on inactivity.\nLet's restart the code sequence if no button is pressed for say 30 seconds:\n\n```erlang\n...\n\nlocked(timeout, _, Data) ->\n {next_state, locked, Data#{buttons := []}};\nlocked(\n cast, {button,Button},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n...\n\ttrue -> % Incomplete | Incorrect\n {next_state, locked, Data#{buttons := NewButtons},\n 30_000} % Time in milliseconds\n...\n```\n\nWhenever we receive a button event we start an _event time-out_ of 30 seconds,\nand if we get an _event type_ of `timeout` we reset the remaining\ncode sequence.\n\nAn _event time-out_ is canceled by any other event so you either get\nsome other event or the time-out event. Therefore, canceling,\nrestarting, or updating an _event time-out_ is neither possible nor\nnecessary. Whatever event you act on has already canceled\nthe _event time-out_, so there is never a running _event time-out_\nwhile the _state callback_ executes.\n\nNote that an _event time-out_ does not work well when you have for example a\nstatus call as in section [_All State Events_](#all-state-events), or\nhandle unknown events, since all kinds of events will cancel\nthe _event time-out_.\n\nGeneric Time-Outs\n-----------------\n\nThe previous example of _state time-outs_ only work if the state machine stays\nin the same state during the time-out time. And _event time-outs_ only work\nif no disturbing unrelated events occur.\n\nYou may want to start a timer in one state and respond to the time-out in\nanother, maybe cancel the time-out without changing states, or perhaps run\nmultiple time-outs in parallel. All this can be accomplished with\n[_generic time-outs_](`t:gen_statem:generic_timeout/0`). They may look a little\nbit like [_event time-outs_](`t:gen_statem:event_timeout/0`) but contain\na name to allow for any number of them simultaneously and they are\nnot automatically canceled.\n\nHere is how to accomplish the _state time-out_ in the previous example\nby instead using a _generic time-out_ named for example `open`:\n\n```erlang\n...\nlocked(\n cast, {button,Button},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n...\n if\n NewButtons =:= Code -> % Correct\n\t do_unlock(),\n {next_state, open, Data#{buttons := []},\n [{{timeout,open},10_000,lock}]}; % Time in milliseconds\n...\n\nopen({timeout,open}, lock, Data) ->\n do_lock(),\n {next_state,locked,Data};\nopen(cast, {button,_}, Data) ->\n {keep_state,Data};\n...\n```\n\nSpecific _generic time-outs_ can just as [_state time-outs_](#state-time-outs)\nbe restarted or canceled by setting it to a new time or `infinity`.\n\nIn this particular case we do not need to cancel the time-out since\nthe time-out event is the only possible reason to do a _state change_\nfrom `open` to `locked`.\n\nInstead of bothering with when to cancel a time-out, a late time-out event\ncan be handled by ignoring it if it arrives in a state\nwhere it is known to be late.\n\nYou can restart, cancel, or update a _generic time-out_.\nSee section [_Time-Outs_](#time-outs) for details.\n\nErlang Timers\n-------------\n\nThe most versatile way to handle time-outs is to use Erlang Timers; see\n[`erlang:start_timer/3,4`](`erlang:start_timer/4`). Most time-out tasks\ncan be performed with the time-out features in `m:gen_statem`,\nbut an example of one that cannot is if you should need the return value\nfrom [`erlang:cancel_timer(Tref)`](`erlang:cancel_timer/2`), that is,\nthe remaining time of the timer.\n\nHere is how to accomplish the _state time-out_ in the previous example\nby instead using an Erlang Timer:\n\n```erlang\n...\nlocked(\n cast, {button,Button},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n...\n if\n NewButtons =:= Code -> % Correct\n\t do_unlock(),\n\t Tref =\n erlang:start_timer(\n 10_000, self(), lock), % Time in milliseconds\n {next_state, open, Data#{buttons := [], timer => Tref}};\n...\n\nopen(info, {timeout,Tref,lock}, #{timer := Tref} = Data) ->\n do_lock(),\n {next_state,locked,maps:remove(timer, Data)};\nopen(cast, {button,_}, Data) ->\n {keep_state,Data};\n...\n```\n\nRemoving the `timer` key from the map when we do a _state change_ to `locked`\nis not strictly necessary since we can only get into state `open`\nwith an updated `timer` map value. But it can be nice to not have\noutdated values in the state `Data`.\n\nIf you need to cancel a timer because of some other event, you can use\n[`erlang:cancel_timer(Tref)`](`erlang:cancel_timer/2`). Note that no time-out\nmessage will arrive after this (because the timer has been\nexplicitly canceled), unless you have already postponed one earlier\n(see the next section), so ensure that you do not accidentally\npostpone such messages. Also note that a time-out message may arrive\nduring a _state callback_ that is canceling the timer, so you may have to\nread out such a message from the process mailbox, depending on\nthe return value from [`erlang:cancel_timer(Tref)`](`erlang:cancel_timer/2`).\n\nAnother way to handle a late time-out can be to not cancel it, but to ignore it\nif it arrives in a state where it is known to be late.\n\nPostponing Events\n-----------------\n\nIf you want to ignore a particular event in the current state and handle it\nin a future state, you can postpone the event. A postponed event\nis retried after a _state change_, that is, `OldState =/= NewState`.\n\nPostponing is ordered by the\n[_transition action_](#transition-actions) `postpone`.\n\nIn this example, instead of ignoring button events while in the `open` state,\nwe can postpone them handle them later in the `locked` state:\n\n```erlang\n...\nopen(cast, {button,_}, Data) ->\n {keep_state,Data,[postpone]};\n...\n```\n\nSince a postponed event is only retried after a _state change_, you have to\nthink about where to keep a state data item. You can keep it in the server\n`Data` or in the `State` itself, for example by having two more or less\nidentical states to keep a boolean value, or by using a complex state (see\nsection [_Complex State_](#complex-state)) with\n[_callback mode_](#callback-modes)\n[`handle_event_function`](`t:gen_statem:callback_mode/0`). If a change\nin the value changes the set of events that is handled, the value\nshould be in the State. Otherwise no postponed events will be retried\nsince only the server `Data` changes.\n\nThis is important if events are postponed. But remember that an incorrect\ndesign decision of what belongs in the state, may become a hard to find bug\nsome time later, when event postponing is introduced.","ref":"statem.html#standalone-gen_statem"},{"type":"extras","title":"Fuzzy State Diagrams - gen_statem Behaviour","doc":"It is not uncommon that a state diagram does not specify how to handle events\nthat are not illustrated in a particular state in the diagram.\nHopefully this is described in an associated text or from the context.\n\nPossible actions: ignore as in drop the event (maybe log it) or deal with\nthe event in some other state as in postpone it.","ref":"statem.html#fuzzy-state-diagrams"},{"type":"extras","title":"Selective Receive - gen_statem Behaviour","doc":"Erlang's selective `receive` statement is often used to describe simple state\nmachine examples in straightforward Erlang code. The following is a possible\nimplementation of the first example:\n\n```erlang\n-module(code_lock).\n-define(NAME, code_lock_1).\n-export([start_link/1,button/1]).\n\nstart_link(Code) ->\n spawn(\n fun () ->\n\t true = register(?NAME, self()),\n\t do_lock(),\n\t locked(Code, length(Code), [])\n end).\n\nbutton(Button) ->\n ?NAME ! {button,Button}.\n```\n\n```erlang\nlocked(Code, Length, Buttons) ->\n receive\n {button,Button} ->\n NewButtons =\n if\n length(Buttons) \n Buttons;\n true ->\n tl(Buttons)\n end ++ [Button],\n if\n NewButtons =:= Code -> % Correct\n do_unlock(),\n\t\t open(Code, Length);\n true -> % Incomplete | Incorrect\n locked(Code, Length, NewButtons)\n end\n end.\n```\n\n```erlang\nopen(Code, Length) ->\n receive\n after 10_000 -> % Time in milliseconds\n\t do_lock(),\n\t locked(Code, Length, [])\n end.\n\ndo_lock() ->\n io:format(\"Locked~n\", []).\ndo_unlock() ->\n io:format(\"Open~n\", []).\n```\n\nThe selective receive in this case causes `open` to implicitly postpone any\nevents to the `locked` state.\n\nA catch-all receive should never be used from a `gen_statem` behaviour\n(or from any `gen_*` behaviour), as the receive statement is within\nthe `gen_*` engine itself. `m:sys`-compatible behaviours must respond to\nsystem messages and therefore do that in their engine receive loop,\npassing non-system messages to the _callback module_. Using a catch-all\nreceive can result in system messages being discarded, which in turn\ncan lead to unexpected behaviour. If a selective receive must be used,\ngreat care should be taken to ensure that only messages pertinent\nto the operation are received. Likewise, a callback must return\nin due time to let the engine receive loop handle system messages,\nor they might time out, also leading to unexpected behaviour.\n\nThe [_transition action_](#transition-actions) `postpone` is\ndesigned to model selective receives. A selective receive implicitly\npostpones any events not yet received, but the `postpone` _transition\naction_ explicitly postpones a single received event.\n\nBoth mechanisms have the same theoretical time and memory complexity,\nbut note that the selective receive language construct has smaller\nconstant factors.\n\nState Enter Actions\n-------------------\n\nSay you have a state machine specification that uses state enter actions.\nAlthough you can code this using inserted events (described in the next\nsection), especially if only one or a few states have state enter actions,\nthis is a perfect use case for the built in\n[_state enter calls_](#state-enter-calls).\n\nYou return a list containing `state_enter` from your\n[`callback_mode/0`](`c:gen_statem:callback_mode/0`) function and the\n`gen_statem` engine will call your _state callback_ once with an event\n`(enter, OldState, ...)` whenever it does a _state change_. Then you\njust need to handle these event-like calls in all states.\n\n```erlang\n...\ninit(Code) ->\n process_flag(trap_exit, true),\n Data = #{code => Code, length = length(Code)},\n {ok, locked, Data}.\n\ncallback_mode() ->\n [state_functions,state_enter].\n\nlocked(enter, _OldState, Data) ->\n do_lock(),\n {keep_state,Data#{buttons => []}};\nlocked(\n cast, {button,Button},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n...\n if\n NewButtons =:= Code -> % Correct\n {next_state, open, Data};\n...\n\nopen(enter, _OldState, _Data) ->\n do_unlock(),\n {keep_state_and_data,\n [{state_timeout,10_000,lock}]}; % Time in milliseconds\nopen(state_timeout, lock, Data) ->\n {next_state, locked, Data};\n...\n```\n\nYou can repeat the state enter code by returning one of\n`{repeat_state, ...}`,`{repeat_state_and_data, _}`,\nor `repeat_state_and_data` that otherwise behaves exactly like their\n`keep_state` siblings. See the type\n[`state_callback_result()`](`t:gen_statem:state_callback_result/2`)\nin the Reference Manual.\n\nInserted Events\n---------------\n\nIt can sometimes be beneficial to be able to generate events to your own\nstate machine. This can be done with the\n[_transition action_](#transition-actions)\n[`{next_event, EventType, EventContent}`](`t:gen_statem:action/0`).\n\nYou can generate events of any existing [type](`t:gen_statem:action/0`),\nbut the`internal` type can only be generated through action `next_event`.\nHence, it cannot come from an external source, so you can be certain\nthat an `internal` event is an event from your state machine to itself.\n\nOne example for this is to pre-process incoming data, for example decrypting\nchunks or collecting characters up to a line break.\n\nPurists may argue that this should be modeled with a separate state machine\nthat sends pre-processed events to the main state machine.\n\nHowever, for efficiency's sake, the small pre-processing state machine\ncan be integrated into the common event handling of the main state\nmachine. This integration involves using a few state data items\nto dispatch pre-processed events as internal events to the main state\nmachine.\n\nUsing internal events also can make it easier to synchronize the state\nmachines.\n\nA variant of this is to use a [complex state](#complex-state) with\n[one state callback](#one-state-callback), modeling the state\nwith, for example, a tuple `{MainFSMState, SubFSMState}`.\n\nTo illustrate this we make up an example where the buttons instead generate\ndown and up (press and release) events, and the lock responds\nto an up event only after the corresponding down event.\n\n```erlang\n...\n-export([down/1, up/1]).\n...\ndown(Button) ->\n gen_statem:cast(?NAME, {down,Button}).\n\nup(Button) ->\n gen_statem:cast(?NAME, {up,Button}).\n\n...\n\nlocked(enter, _OldState, Data) ->\n do_lock(),\n {keep_state,Data#{buttons => []}};\nlocked(\n internal, {button,Button},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n...\n```\n\n```erlang\nhandle_common(cast, {down,Button}, Data) ->\n {keep_state, Data#{button => Button}};\nhandle_common(cast, {up,Button}, Data) ->\n case Data of\n #{button := Button} ->\n {keep_state,maps:remove(button, Data),\n [{next_event,internal,{button,Button}}]};\n #{} ->\n keep_state_and_data\n end;\n...\n\nopen(internal, {button,_}, Data) ->\n {keep_state,Data,[postpone]};\n...\n```\n\nIf you start this program with `code_lock:start([17])` you can unlock with\n`code_lock:down(17), code_lock:up(17).`\n\nExample Revisited\n-----------------\n\nThis section includes the example after most of the mentioned modifications\nand some more using _state enter calls_, which deserves a new state diagram:\n\n```mermaid\n---\ntitle: Code Lock State Diagram Revisited\n---\nstateDiagram-v2\n state enter_locked < >\n state enter_open < >\n state check_code < >\n\n [*] --> enter_locked\n\n enter_locked --> locked : * do_lock()\\n* Clear Buttons\n locked --> check_code : {button, Button}\\n* Collect Buttons\n locked --> locked : state_timeout\\n* Clear Buttons\n check_code --> locked : Incorrect code\\n* Set state_timeout 30 s\n check_code --> enter_open : Correct code\n\n enter_open --> open : * do_unlock()\\n* Set state_timeout 10 s\n open --> enter_locked : state_timeout\n```\n\nNotice that this state diagram does not specify how to handle a button event\nin the state `open`. So, you need to read in some side notes, that is, here:\nthat unspecified events shall be postponed (handled in some later state).\nAlso, the state diagram does not show that the `code_length/0` call\nmust be handled in every state.","ref":"statem.html#selective-receive"},{"type":"extras","title":"Callback Mode: state_functions - gen_statem Behaviour","doc":"Using state functions:\n\n```erlang\n-module(code_lock).\n-behaviour(gen_statem).\n-define(NAME, code_lock_2).\n\n-export([start_link/1,stop/0]).\n-export([down/1,up/1,code_length/0]).\n-export([init/1,callback_mode/0,terminate/3]).\n-export([locked/3,open/3]).\n\nstart_link(Code) ->\n gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).\nstop() ->\n gen_statem:stop(?NAME).\n\ndown(Button) ->\n gen_statem:cast(?NAME, {down,Button}).\nup(Button) ->\n gen_statem:cast(?NAME, {up,Button}).\ncode_length() ->\n gen_statem:call(?NAME, code_length).\n```\n\n```erlang\ninit(Code) ->\n process_flag(trap_exit, true),\n Data = #{code => Code, length => length(Code), buttons => []},\n {ok, locked, Data}.\n\ncallback_mode() ->\n [state_functions,state_enter].\n\n-define(HANDLE_COMMON,\n ?FUNCTION_NAME(T, C, D) -> handle_common(T, C, D)).\n%%\nhandle_common(cast, {down,Button}, Data) ->\n {keep_state, Data#{button => Button}};\nhandle_common(cast, {up,Button}, Data) ->\n case Data of\n #{button := Button} ->\n {keep_state, maps:remove(button, Data),\n [{next_event,internal,{button,Button}}]};\n #{} ->\n keep_state_and_data\n end;\nhandle_common({call,From}, code_length, #{code := Code}) ->\n {keep_state_and_data,\n [{reply,From,length(Code)}]}.\n```\n\n```erlang\nlocked(enter, _OldState, Data) ->\n do_lock(),\n {keep_state, Data#{buttons := []}};\nlocked(state_timeout, button, Data) ->\n {keep_state, Data#{buttons := []}};\nlocked(\n internal, {button,Button},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n NewButtons =\n if\n length(Buttons) \n Buttons;\n true ->\n tl(Buttons)\n end ++ [Button],\n if\n NewButtons =:= Code -> % Correct\n {next_state, open, Data};\n\ttrue -> % Incomplete | Incorrect\n {keep_state, Data#{buttons := NewButtons},\n [{state_timeout,30_000,button}]} % Time in milliseconds\n end;\n?HANDLE_COMMON.\n```\n\n```erlang\nopen(enter, _OldState, _Data) ->\n do_unlock(),\n {keep_state_and_data,\n [{state_timeout,10_000,lock}]}; % Time in milliseconds\nopen(state_timeout, lock, Data) ->\n {next_state, locked, Data};\nopen(internal, {button,_}, _) ->\n {keep_state_and_data, [postpone]};\n?HANDLE_COMMON.\n\ndo_lock() ->\n io:format(\"Locked~n\", []).\ndo_unlock() ->\n io:format(\"Open~n\", []).\n\nterminate(_Reason, State, _Data) ->\n State =/= locked andalso do_lock(),\n ok.\n```","ref":"statem.html#callback-mode-state_functions"},{"type":"extras","title":"Callback Mode: handle_event_function - gen_statem Behaviour","doc":"This section describes what to change in the example to use one\n`handle_event/4` function. The previously used approach to first branch\ndepending on event does not work that well here because of\nthe _state enter calls_, so this example first branches depending on state:\n\n```erlang\n-export([handle_event/4]).\n```\n\n```erlang\ncallback_mode() ->\n [handle_event_function,state_enter].\n```\n\n```erlang\n%%\n%% State: locked\nhandle_event(enter, _OldState, locked, Data) ->\n do_lock(),\n {keep_state, Data#{buttons := []}};\nhandle_event(state_timeout, button, locked, Data) ->\n {keep_state, Data#{buttons := []}};\nhandle_event(\n internal, {button,Button}, locked,\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n NewButtons =\n if\n length(Buttons) \n Buttons;\n true ->\n tl(Buttons)\n end ++ [Button],\n if\n NewButtons =:= Code -> % Correct\n {next_state, open, Data};\n\ttrue -> % Incomplete | Incorrect\n {keep_state, Data#{buttons := NewButtons},\n [{state_timeout,30_000,button}]} % Time in milliseconds\n end;\n```\n\n```erlang\n%%\n%% State: open\nhandle_event(enter, _OldState, open, _Data) ->\n do_unlock(),\n {keep_state_and_data,\n [{state_timeout,10_000,lock}]}; % Time in milliseconds\nhandle_event(state_timeout, lock, open, Data) ->\n {next_state, locked, Data};\nhandle_event(internal, {button,_}, open, _) ->\n {keep_state_and_data,[postpone]};\n```\n\n```erlang\n%% Common events\nhandle_event(cast, {down,Button}, _State, Data) ->\n {keep_state, Data#{button => Button}};\nhandle_event(cast, {up,Button}, _State, Data) ->\n case Data of\n #{button := Button} ->\n {keep_state, maps:remove(button, Data),\n [{next_event,internal,{button,Button}},\n {state_timeout,30_000,button}]}; % Time in milliseconds\n #{} ->\n keep_state_and_data\n end;\nhandle_event({call,From}, code_length, _State, #{length := Length}) ->\n {keep_state_and_data,\n [{reply,From,Length}]}.\n```\n\nNotice that postponing buttons from the `open` state to the `locked` state\nseems like a strange thing to do for a code lock, but it at least\nillustrates event postponing.\n\nFilter the State\n----------------\n\nThe example servers so far in this chapter print the full internal state\nin the error log, for example, when killed by an exit signal or because of\nan internal error. The state contains both the code lock code\nand which digits that remain to unlock.\n\nThis state data can be regarded as sensitive, and maybe not what you want\nin the error log because of some unpredictable event.\n\nAnother reason to filter the state can be that the state is too large to print,\nas it fills the error log with uninteresting details.\n\nTo avoid this, you can format the internal state that gets in the error log\nand gets returned from [`sys:get_status/1,2`](`sys:get_status/1`)\nby implementing function\n[`Module:format_status/2`](`c:gen_statem:format_status/2`),\nfor example like this:\n\n```erlang\n...\n-export([init/1,terminate/3,format_status/2]).\n...\n\nformat_status(Opt, [_PDict,State,Data]) ->\n StateData =\n\t{State,\n\t maps:filter(\n\t fun (code, _) -> false;\n\t (_, _) -> true\n\t end,\n\t Data)},\n case Opt of\n\tterminate ->\n\t StateData;\n\tnormal ->\n\t [{data,[{\"State\",StateData}]}]\n end.\n```\n\nIt is not mandatory to implement a\n[`Module:format_status/2`](`c:gen_statem:format_status/2`) function.\nIf you do not, a default implementation is used that does the same\nas this example function without filtering the `Data` term, that is,\n`StateData = {State, Data}`, in this example containing sensitive information.\n\nComplex State\n-------------\n\nThe _callback mode_ [`handle_event_function`](`t:gen_statem:callback_mode/0`)\nenables using a non-atom state as described in section\n[_Callback Modes_](#callback-modes), for example, a complex state term\nlike a tuple.\n\nOne reason to use this is when you have a state item that when changed\nshould cancel the [_state time-out_](#state-time-outs), or one that affects\nthe event handling in combination with postponing events. We will go for\nthe latter and complicate the previous example by introducing\na configurable lock button (this is the state item in question),\nwhich in the `open` state immediately locks the door, and an API function\n`set_lock_button/1` to set the lock button.\n\nSuppose now that we call `set_lock_button` while the door is open,\nand we have already postponed a button event that was the new lock button:\n\n```erlang\n1> code_lock:start_link([a,b,c], x).\n{ok,<0.666.0>}\n2> code_lock:button(a).\nok\n3> code_lock:button(b).\nok\n4> code_lock:button(c).\nok\nOpen\n5> code_lock:button(y).\nok\n6> code_lock:set_lock_button(y).\nx\n% What should happen here? Immediate lock or nothing?\n```\n\nWe could say that the button was pressed too early so it should not be\nrecognized as the lock button. Or we can make the lock button part of\nthe state so when we then change the lock button in the locked state,\nthe change becomes a _state change_ and all postponed events are retried,\ntherefore the lock is immediately locked\\!\n\nWe define the state as `{StateName, LockButton}`, where `StateName`\nis as before and `LockButton` is the current lock button:\n\n```erlang\n-module(code_lock).\n-behaviour(gen_statem).\n-define(NAME, code_lock_3).\n\n-export([start_link/2,stop/0]).\n-export([button/1,set_lock_button/1]).\n-export([init/1,callback_mode/0,terminate/3]).\n-export([handle_event/4]).\n\nstart_link(Code, LockButton) ->\n gen_statem:start_link(\n {local,?NAME}, ?MODULE, {Code,LockButton}, []).\nstop() ->\n gen_statem:stop(?NAME).\n\nbutton(Button) ->\n gen_statem:cast(?NAME, {button,Button}).\nset_lock_button(LockButton) ->\n gen_statem:call(?NAME, {set_lock_button,LockButton}).\n```\n\n```erlang\ninit({Code,LockButton}) ->\n process_flag(trap_exit, true),\n Data = #{code => Code, length => length(Code), buttons => []},\n {ok, {locked,LockButton}, Data}.\n\ncallback_mode() ->\n [handle_event_function,state_enter].\n\n%% State: locked\nhandle_event(enter, _OldState, {locked,_}, Data) ->\n do_lock(),\n {keep_state, Data#{buttons := []}};\nhandle_event(state_timeout, button, {locked,_}, Data) ->\n {keep_state, Data#{buttons := []}};\nhandle_event(\n cast, {button,Button}, {locked,LockButton},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n NewButtons =\n if\n length(Buttons) \n Buttons;\n true ->\n tl(Buttons)\n end ++ [Button],\n if\n NewButtons =:= Code -> % Correct\n {next_state, {open,LockButton}, Data};\n\ttrue -> % Incomplete | Incorrect\n {keep_state, Data#{buttons := NewButtons},\n [{state_timeout,30_000,button}]} % Time in milliseconds\n end;\n```\n\n```erlang\n%%\n%% State: open\nhandle_event(enter, _OldState, {open,_}, _Data) ->\n do_unlock(),\n {keep_state_and_data,\n [{state_timeout,10_000,lock}]}; % Time in milliseconds\nhandle_event(state_timeout, lock, {open,LockButton}, Data) ->\n {next_state, {locked,LockButton}, Data};\nhandle_event(cast, {button,LockButton}, {open,LockButton}, Data) ->\n {next_state, {locked,LockButton}, Data};\nhandle_event(cast, {button,_}, {open,_}, _Data) ->\n {keep_state_and_data,[postpone]};\n```\n\n```erlang\n%%\n%% Common events\nhandle_event(\n {call,From}, {set_lock_button,NewLockButton},\n {StateName,OldLockButton}, Data) ->\n {next_state, {StateName,NewLockButton}, Data,\n [{reply,From,OldLockButton}]}.\n```\n\n```erlang\ndo_lock() ->\n io:format(\"Locked~n\", []).\ndo_unlock() ->\n io:format(\"Open~n\", []).\n\nterminate(_Reason, State, _Data) ->\n State =/= locked andalso do_lock(),\n ok.\n```\n\nHibernation\n-----------\n\nIf you have many servers in one node and they have some state(s) in their\nlifetime in which the servers can be expected to idle for a while, and the\namount of heap memory all these servers need is a problem, then the memory\nfootprint of a server can be minimized by hibernating it through\n`proc_lib:hibernate/3`.\n\n> #### Note {: .info }\n>\n> It is rather costly to hibernate a process; see `erlang:hibernate/3`. It is\n> not something you want to do after every event.\n\nWe can in this example hibernate in the `{open, _}` state,\nbecause what normally occurs in that state is that the _state time-out_\nafter a while triggers a transition to `{locked, _}`:\n\n```erlang\n...\n%%\n%% State: open\nhandle_event(enter, _OldState, {open,_}, _Data) ->\n do_unlock(),\n {keep_state_and_data,\n [{state_timeout,10_000,lock}, % Time in milliseconds\n hibernate]};\n...\n```\n\nThe atom [`hibernate`](`t:gen_statem:hibernate/0`) in the action list on the\nlast line when entering the `{open, _}` state is the only change. If any event\narrives in the `{open, _},` state, we do not bother to rehibernate,\nso the server stays awake after any event.\n\nTo change that we would need to insert action `hibernate` in more places.\nFor example, the state-independent `set_lock_button` operation\nwould have to use `hibernate` but only in the `{open, _}` state,\nwhich would clutter the code.\n\nAnother not uncommon scenario is to use the\n[_event time-out_](#event-time-outs) to trigger hibernation after a\ncertain time of inactivity. There is also a server start option\n[`{hibernate_after, Timeout}`](`t:gen_statem:enter_loop_opt/0`) for\n[`start/3,4`](`gen_statem:start/3`),\n[`start_link/3,4`](`gen_statem:start_link/3`), or\n[`enter_loop/4,5,6`](`gen_statem:enter_loop/4`) that may be used to\nautomatically hibernate the server.\n\nThis particular server probably does not use heap memory worth hibernating for.\nTo gain anything from hibernation, your server would have to produce\nnon-insignificant garbage during callback execution, for which this example\nserver can serve as a bad example.","ref":"statem.html#callback-mode-handle_event_function"},{"type":"extras","title":"gen_event Behaviour","doc":"\n# gen_event Behaviour\n\n[](){: #gen_event }\n\nIt is recommended to read this section alongside `m:gen_event` in STDLIB.","ref":"events.html"},{"type":"extras","title":"Event Handling Principles - gen_event Behaviour","doc":"In OTP, an _event manager_ is a named object to which events can be sent. An\n_event_ can be, for example, an error, an alarm, or some information that is to\nbe logged.\n\nIn the event manager, zero, one, or many _event handlers_ are installed. When\nthe event manager is notified about an event, the event is processed by all the\ninstalled event handlers. For example, an event manager for handling errors can\nby default have a handler installed that writes error messages to the\nterminal. If the error messages during a certain period are to be saved to a\nfile as well, the user adds another event handler that does this. When logging\nto the file is no longer necessary, this event handler is deleted.\n\nAn event manager is implemented as a process and each event handler is\nimplemented as a callback module.\n\nThe event manager essentially maintains a list of `{Module, State}` pairs, where\neach `Module` is an event handler, and `State` is the internal state of that\nevent handler.","ref":"events.html#event-handling-principles"},{"type":"extras","title":"Example - gen_event Behaviour","doc":"The callback module for the event handler writing error messages to the terminal\ncan look as follows:\n\n```erlang\n-module(terminal_logger).\n-behaviour(gen_event).\n\n-export([init/1, handle_event/2, terminate/2]).\n\ninit(_Args) ->\n {ok, []}.\n\nhandle_event(ErrorMsg, State) ->\n io:format(\"***Error*** ~p~n\", [ErrorMsg]),\n {ok, State}.\n\nterminate(_Args, _State) ->\n ok.\n```\n\nThe callback module for the event handler writing error messages to a file can\nlook as follows:\n\n```erlang\n-module(file_logger).\n-behaviour(gen_event).\n\n-export([init/1, handle_event/2, terminate/2]).\n\ninit(File) ->\n {ok, Fd} = file:open(File, read),\n {ok, Fd}.\n\nhandle_event(ErrorMsg, Fd) ->\n io:format(Fd, \"***Error*** ~p~n\", [ErrorMsg]),\n {ok, Fd}.\n\nterminate(_Args, Fd) ->\n file:close(Fd).\n```\n\nThe code is explained in the next sections.\n\n[](){: #mgr }","ref":"events.html#example"},{"type":"extras","title":"Starting an Event Manager - gen_event Behaviour","doc":"To start an event manager for handling errors, as described in the previous\nexample, call the following function:\n\n```text\ngen_event:start_link({local, error_man})\n```\n\n`gen_event:start_link/1` spawns and links to a new event manager process.\n\nThe argument, `{local, error_man}`, specifies the name under which the\nevent manager should be locally registered. The name can also be given\nas `{global, Name}` to register the event manager globally using\n`global:register_name/2`.\n\nIf the name is omitted, the event manager is not registered. Instead its pid\nmust be used.\n\n`gen_event:start_link/1` must be used if the event manager is part of\na supervision tree, meaning that it was started by a supervisor. There\nis another function, `gen_event:start/1`, to start a standalone event\nmanager that is not part of a supervision tree.","ref":"events.html#starting-an-event-manager"},{"type":"extras","title":"Adding an Event Handler - gen_event Behaviour","doc":"The following example shows how to start an event manager and add an event\nhandler to it by using the shell:\n\n```erlang\n1> gen_event:start({local, error_man}).\n{ok,<0.31.0>}\n2> gen_event:add_handler(error_man, terminal_logger, []).\nok\n```\n\nThis function sends a message to the event manager registered as `error_man`,\ntelling it to add the event handler `terminal_logger`. The event manager calls\nthe callback function `terminal_logger:init([])`, where the argument `[]` is the\nthird argument to `add_handler`. `init/1` is expected to return `{ok, State}`,\nwhere `State` is the internal state of the event handler.\n\n```erlang\ninit(_Args) ->\n {ok, []}.\n```\n\nHere, `init/1` does not need any input data and ignores its argument. For\n`terminal_logger`, the internal state is not used. For `file_logger`, the\ninternal state is used to save the open file descriptor.\n\n```erlang\ninit(File) ->\n {ok, Fd} = file:open(File, read),\n {ok, Fd}.\n```","ref":"events.html#adding-an-event-handler"},{"type":"extras","title":"Notifying about Events - gen_event Behaviour","doc":"```text\n3> gen_event:notify(error_man, no_reply).\n***Error*** no_reply\nok\n```\n\n`error_man` is the name of the event manager and `no_reply` is the event.\n\nThe event is made into a message and sent to the event manager. When the event\nis received, the event manager calls `handle_event(Event, State)` for each\ninstalled event handler, in the same order as they were added. The function is\nexpected to return a tuple `{ok,State1}`, where `State1` is a new value for the\nstate of the event handler.\n\nIn `terminal_logger`:\n\n```erlang\nhandle_event(ErrorMsg, State) ->\n io:format(\"***Error*** ~p~n\", [ErrorMsg]),\n {ok, State}.\n```\n\nIn `file_logger`:\n\n```erlang\nhandle_event(ErrorMsg, Fd) ->\n io:format(Fd, \"***Error*** ~p~n\", [ErrorMsg]),\n {ok, Fd}.\n```","ref":"events.html#notifying-about-events"},{"type":"extras","title":"Deleting an Event Handler - gen_event Behaviour","doc":"```erlang\n4> gen_event:delete_handler(error_man, terminal_logger, []).\nok\n```\n\nThis function sends a message to the event manager registered as `error_man`,\ntelling it to delete the event handler `terminal_logger`. The event manager\ncalls the callback function `terminal_logger:terminate([], State)`, where the\nargument `[]` is the third argument to `delete_handler`. `terminate/2` is to be\nthe opposite of `init/1` and do any necessary cleaning up. Its return value is\nignored.\n\nFor `terminal_logger`, no cleaning up is necessary:\n\n```erlang\nterminate(_Args, _State) ->\n ok.\n```\n\nFor `file_logger`, the file descriptor opened in `init` must be closed:\n\n```erlang\nterminate(_Args, Fd) ->\n file:close(Fd).\n```","ref":"events.html#deleting-an-event-handler"},{"type":"extras","title":"Stopping - gen_event Behaviour","doc":"When an event manager is stopped, it gives each of the installed event handlers\nthe chance to clean up by calling `terminate/2`, the same way as when deleting a\nhandler.","ref":"events.html#stopping"},{"type":"extras","title":"In a Supervision Tree - gen_event Behaviour","doc":"If the event manager is part of a supervision tree, no stop function is needed.\nThe event manager is automatically terminated by its supervisor. Exactly how\nthis is done is defined by a [shutdown strategy](sup_princ.md#shutdown) set in\nthe supervisor.","ref":"events.html#in-a-supervision-tree"},{"type":"extras","title":"Standalone Event Managers - gen_event Behaviour","doc":"An event manager can also be stopped by calling:\n\n```erlang\n1> gen_event:stop(error_man).\nok\n```","ref":"events.html#standalone-event-managers"},{"type":"extras","title":"Handling Other Messages - gen_event Behaviour","doc":"If the `gen_event` process is to be able to receive other messages\nthan events, the callback function `handle_info(Info, State)` must be\nimplemented to handle them. Examples of other messages are exit\nmessages if the event manager is linked to other processes than the\nsupervisor (for example via `gen_event:add_sup_handler/3`) and is\ntrapping exit signals.\n\n```erlang\nhandle_info({'EXIT', Pid, Reason}, State) ->\n %% Code to handle exits here.\n ...\n {noreply, State1}.\n```\n\nThe final function to implement is `code_change/3`:\n\n```erlang\ncode_change(OldVsn, State, Extra) ->\n %% Code to convert state (and more) during code change.\n ...\n {ok, NewState}.\n```","ref":"events.html#handling-other-messages"},{"type":"extras","title":"Supervisor Behaviour","doc":"\n# Supervisor Behaviour\n\nIt is recommended to read this section alongside `m:supervisor` in STDLIB.","ref":"sup_princ.html"},{"type":"extras","title":"Supervision Principles - Supervisor Behaviour","doc":"A supervisor is responsible for starting, stopping, and monitoring its child\nprocesses. The basic idea of a supervisor is that it is to keep its child\nprocesses alive by restarting them when necessary.\n\nWhich child processes to start and monitor is specified by a list of\n[child specifications](sup_princ.md#spec). The child processes are started in\nthe order specified by this list, and are terminated in the reverse order.","ref":"sup_princ.html#supervision-principles"},{"type":"extras","title":"Example - Supervisor Behaviour","doc":"The callback module for a supervisor starting the server from\n[gen_server Behaviour](gen_server_concepts.md#ex) can look as follows:\n\n[](){: #ex }\n\n```erlang\n-module(ch_sup).\n-behaviour(supervisor).\n\n-export([start_link/0]).\n-export([init/1]).\n\nstart_link() ->\n supervisor:start_link(ch_sup, []).\n\ninit(_Args) ->\n SupFlags = #{strategy => one_for_one, intensity => 1, period => 5},\n ChildSpecs = [#{id => ch3,\n start => {ch3, start_link, []},\n restart => permanent,\n shutdown => brutal_kill,\n type => worker,\n modules => [ch3]}],\n {ok, {SupFlags, ChildSpecs}}.\n```\n\nThe `SupFlags` variable in the return value from `init/1` represents the\n[supervisor flags](sup_princ.md#flags).\n\nThe `ChildSpecs` variable in the return value from `init/1` is a list of\n[child specifications](sup_princ.md#spec).\n\n[](){: #flags }","ref":"sup_princ.html#example"},{"type":"extras","title":"Supervisor Flags - Supervisor Behaviour","doc":"This is the type definition for the supervisor flags:\n\n```erlang\nsup_flags() = #{strategy => strategy(), % optional\n intensity => non_neg_integer(), % optional\n period => pos_integer(), % optional\n auto_shutdown => auto_shutdown()} % optional\n strategy() = one_for_all\n | one_for_one\n | rest_for_one\n | simple_one_for_one\n auto_shutdown() = never\n | any_significant\n | all_significant\n```\n\n- `strategy` specifies the [restart strategy](sup_princ.md#strategy).\n- `intensity` and `period` specify the\n [maximum restart intensity](sup_princ.md#max_intensity).\n- `auto_shutdown` specifies whether and when a supervisor should\n [automatically shut itself down](sup_princ.md#automatic-shutdown).\n\n[](){: #strategy }","ref":"sup_princ.html#supervisor-flags"},{"type":"extras","title":"Restart Strategy - Supervisor Behaviour","doc":"The restart strategy is specified by the `strategy` key in the supervisor flags\nmap returned by the callback function `init`:\n\n```text\nSupFlags = #{strategy => Strategy, ...}\n```\n\nThe `strategy` key is optional in this map. If it is not given, it defaults to\n`one_for_one`.\n\n> #### Note {: .info }\n>\n> For simplicity, the diagrams shown in this section display a setup where all\n> the depicted children are assumed to have a\n> [restart type](sup_princ.md#restart) of `permanent`.","ref":"sup_princ.html#restart-strategy"},{"type":"extras","title":"one_for_one - Supervisor Behaviour","doc":"If a child process terminates, only that process is restarted.\n\n```mermaid\n---\ntitle: One For One Supervision\n---\nflowchart TD\n subgraph Legend\n direction LR\n t(( )) ~~~ l1[Terminated Process]\n p(( )) ~~~ l2[Process Restarted by the Supervisor]\n end\n\n subgraph graph[\" \"]\n s[Supervisor]\n s --- p1((P1))\n s --- p2((P2))\n s --- p3((P3))\n s --- pn((Pn))\n end\n\n classDef term fill:#ff8888,color:black;\n classDef restarted stroke:#00aa00,stroke-width:3px;\n classDef legend fill-opacity:0,stroke-width:0px;\n\n class p2,t term;\n class p2,p restarted;\n class l1,l2 legend;\n```","ref":"sup_princ.html#one_for_one"},{"type":"extras","title":"one_for_all - Supervisor Behaviour","doc":"If a child process terminates, all remaining child processes are\nterminated. Subsequently, all child processes, including the\nterminated one, are restarted.\n\n```mermaid\n---\ntitle: One For All Supervision\n---\nflowchart TD\n subgraph Legend\n direction LR\n t(( )) ~~~ l1[Terminated Process]\n st(( )) ~~~ l2[Process Terminated by the Supervisor]\n p(( )) ~~~ l3[Process Restarted by the Supervisor]\n l4[\"Note:\n\n Processes are terminated right to left\n Processes are restarted left to right\"]\n\n end\n\n subgraph graph[\" \"]\n s[Supervisor]\n s --- p1((P1))\n s --- p2((P2))\n s --- p3((P3))\n s --- pn((Pn))\n end\n\n classDef term fill:#ff8888,color:black;\n classDef sterm fill:#ffaa00,color:black;\n classDef restarted stroke:#00aa00,stroke-width:3px;\n classDef legend fill-opacity:0,stroke-width:0px;\n\n class p2,t term;\n class p1,p3,pn,st sterm;\n class p1,p2,p3,pn,p restarted;\n class l1,l2,l3,l4 legend;\n```","ref":"sup_princ.html#one_for_all"},{"type":"extras","title":"rest_for_one - Supervisor Behaviour","doc":"If a child process terminates, the child processes after the\nterminated process in start order are terminated. Subsequently, the\nterminated child process and the remaining child processes are\nrestarted.\n\n\n```mermaid\n---\ntitle: Rest For One Supervision\n---\nflowchart TD\n subgraph Legend\n direction LR\n t(( )) ~~~ l1[Terminated Process]\n st(( )) ~~~ l2[Process Terminated by the Supervisor]\n p(( )) ~~~ l3[Process Restarted by the Supervisor]\n l4[\"Note:\n\n Processes are terminated right to left\n Processes are restarted left to right\"]\n\n end\n\n subgraph graph[\" \"]\n s[Supervisor]\n s --- p1((P1))\n s --- p2((P2))\n s --- p3((P3))\n s --- pn((Pn))\n end\n\n classDef term fill:#ff8888,color:black;\n classDef sterm fill:#ffaa00,color:black;\n classDef restarted stroke:#00aa00,stroke-width:3px;\n classDef legend fill-opacity:0,stroke-width:0px;\n\n class p2,t term;\n class p3,pn,st sterm;\n class p2,p3,pn,p restarted;\n class l1,l2,l3,l4 legend;\n```","ref":"sup_princ.html#rest_for_one"},{"type":"extras","title":"simple_one_for_one - Supervisor Behaviour","doc":"See [simple-one-for-one supervisors](sup_princ.md#simple).\n\n[](){: #max_intensity }","ref":"sup_princ.html#simple_one_for_one"},{"type":"extras","title":"Maximum Restart Intensity - Supervisor Behaviour","doc":"The supervisors have a built-in mechanism to limit the number of restarts which\ncan occur in a given time interval. This is specified by the two keys\n`intensity` and `period` in the supervisor flags map returned by the callback\nfunction `init`:\n\n```text\nSupFlags = #{intensity => MaxR, period => MaxT, ...}\n```\n\nIf more than `MaxR` number of restarts occur in the last `MaxT` seconds, the\nsupervisor terminates all the child processes and then itself. The termination\nreason for the supervisor itself in that case will be `shutdown`.\n\nWhen the supervisor terminates, then the next higher-level supervisor takes some\naction. It either restarts the terminated supervisor or terminates itself.\n\nThe intention of the restart mechanism is to prevent a situation where a process\nrepeatedly dies for the same reason, only to be restarted again.\n\nThe keys `intensity` and `period` are optional in the supervisor flags map. If\nthey are not given, they default to `1` and `5`, respectively.","ref":"sup_princ.html#maximum-restart-intensity"},{"type":"extras","title":"Tuning the intensity and period - Supervisor Behaviour","doc":"The default values were chosen to be safe for most systems, even with\ndeep supervision hierarchies, but you will probably want to tune the\nsettings for your particular use case.\n\nFirst, the intensity decides how big bursts of restarts you want to tolerate.\nFor example, you might want to accept a burst of at most 5 or 10 attempts, even\nwithin the same second, if it results in a successful restart.\n\nSecond, you need to consider the sustained failure rate, if crashes keep\nhappening but not often enough to make the supervisor give up. If you set\nintensity to 10 and set the period as low as 1, the supervisor will allow child\nprocesses to keep restarting up to 10 times per second, forever, filling your\nlogs with crash reports until someone intervenes manually.\n\nYou should therefore set the period to be long enough that you can accept that\nthe supervisor keeps going at that rate. For example, if an intensity value\nof 5 is chosen, setting the period to 30 seconds will give you at\nmost one restart per 6 seconds for any longer period of time, which means that\nyour logs will not fill up too quickly, and you will have a chance to observe the\nfailures and apply a fix.\n\nThese choices depend a lot on your problem domain. If you do not have real time\nmonitoring and ability to fix problems quickly, for example in an embedded\nsystem, you might want to accept at most one restart per minute before the\nsupervisor should give up and escalate to the next level to try to clear the\nerror automatically. On the other hand, if it is more important that you keep\ntrying even at a high failure rate, you might want a sustained rate of as much\nas 1-2 restarts per second.\n\nAvoiding common mistakes:\n\n- Do not forget to consider the burst rate. If you set intensity to 1 and period\n to 6, it gives the same sustained error rate as 5/30 or 10/60, but will not\n allow even 2 restart attempts in quick succession. This is probably not what\n you wanted.\n- Do not set the period to a very high value if you want to tolerate bursts. If\n you set intensity to 5 and period to 3600 (one hour), the supervisor will\n allow a short burst of 5 restarts, but then gives up if it sees another single\n restart almost an hour later. You probably want to regard those crashes as\n separate incidents, so setting the period to 5 or 10 minutes will be more\n reasonable.\n- If your application has multiple levels of supervision, do not set\n the restart intensities to the same values on all levels. Keep in mind that\n the total number of restarts (before the top level supervisor gives up and\n terminates the application) will be the product of the intensity values of all\n the supervisors above the failing child process.\n\n For example, if the top level allows 10 restarts, and the next level also\n allows 10, a crashing child below that level will be restarted 100 times,\n which is probably excessive. Allowing at most 3 restarts for the top level\n supervisor might be a better choice in this case.","ref":"sup_princ.html#tuning-the-intensity-and-period"},{"type":"extras","title":"Automatic Shutdown - Supervisor Behaviour","doc":"A supervisor can be configured to automatically shut itself down when\n[significant children](sup_princ.md#significant_child) terminate.\n\nThis is useful when a supervisor represents a work unit of cooperating children,\nas opposed to independent workers. When the work unit has finished its work,\nthat is, when any or all significant child processes have terminated, the\nsupervisor should then shut down by terminating all remaining child processes in\nreverse start order according to the respective shutdown specifications, and\nthen itself.\n\nAutomatic shutdown is specified by the `auto_shutdown` key in the supervisor\nflags map returned by the callback function `init`:\n\n```text\nSupFlags = #{auto_shutdown => AutoShutdown, ...}\n```\n\nThe `auto_shutdown` key is optional in this map. If it is not given, it defaults\nto `never`.\n\n> #### Note {: .info }\n>\n> The automatic shutdown facility only applies when significant children\n> terminate by themselves, not when their termination was caused by\n> the supervisor. Specifically, neither the termination of a child as a\n> consequence of a sibling's termination in the `one_for_all` or `rest_for_one`\n> strategies nor the manual termination of a child by\n> `supervisor:terminate_child/2` will trigger an automatic shutdown.","ref":"sup_princ.html#automatic-shutdown"},{"type":"extras","title":"never - Supervisor Behaviour","doc":"Automatic shutdown is disabled.\n\nIn this mode, specifying significant children is not accepted. If the\nchild specs returned from `init` contain significant children, the\nsupervisor will refuse to start. Attempts to start significant\nchildren dynamically will be rejected.\n\nThis is the default setting.","ref":"sup_princ.html#never"},{"type":"extras","title":"any_significant - Supervisor Behaviour","doc":"The supervisor will automatically shut itself down when _any_ significant child\nterminates, that is, when a transient significant child terminates normally or\nwhen a temporary significant child terminates normally or abnormally.","ref":"sup_princ.html#any_significant"},{"type":"extras","title":"all_significant - Supervisor Behaviour","doc":"The supervisor will automatically shut itself down when _all_ significant\nchildren have terminated, that is, when the _last active_ significant child\nterminates. The same rules as for `any_significant` apply.\n\n> #### Warning {: .warning }\n>\n> The automatic shutdown feature was introduced in OTP 24.0, but applications\n> using this feature will also compile and run with older OTP versions.\n>\n> However, such applications, when compiled with an OTP version that predates\n> the appearance of the automatic shutdown feature, will leak processes because\n> the automatic shutdowns they rely on will not happen.\n>\n> It is up to implementors to take proper precautions if they expect that their\n> applications may be compiled with older OTP versions.\n\n> #### Warning {: .warning }\n>\n> Top supervisors of [Applications](applications.md) should not be configured\n> for automatic shutdown, because when the top supervisor exits, the application\n> terminates. If the application is `permanent`, all other applications and the\n> runtime system are terminated as well.\n\n> #### Warning {: .warning }\n>\n> Supervisors configured for automatic shutdown should not be made\n> [permanent](sup_princ.md#restart) children of their respective parent\n> supervisors, as they would be restarted immediately after having automatically\n> shut down, only to shut down automatically again after a while, and may thus\n> exhaust the [Maximum Restart Intensity](sup_princ.md#max_intensity) of the\n> parent supervisor.\n\n[](){: #spec }","ref":"sup_princ.html#all_significant"},{"type":"extras","title":"Child Specification - Supervisor Behaviour","doc":"The type definition for a child specification is as follows:\n\n```erlang\nchild_spec() = #{id => child_id(), % mandatory\n start => mfargs(), % mandatory\n restart => restart(), % optional\n significant => significant(), % optional\n shutdown => shutdown(), % optional\n type => worker(), % optional\n modules => modules()} % optional\n child_id() = term()\n mfargs() = {M :: module(), F :: atom(), A :: [term()]}\n modules() = [module()] | dynamic\n restart() = permanent | transient | temporary\n significant() = boolean()\n shutdown() = brutal_kill | timeout()\n worker() = worker | supervisor\n```\n\n- `id` is used to identify the child specification internally by the supervisor.\n\n The `id` key is mandatory.\n\n Note that this identifier occasionally has been called \"name\". As far as\n possible, the terms \"identifier\" or \"id\" are now used but in order to keep\n backwards compatibility, some occurrences of \"name\" can still be found, for\n example in error messages.\n\n- `start` defines the function call used to start the child process. It is a\n module-function-arguments tuple used as [`apply(M, F, A)`](`apply/3`).\n\n It is to be (or result in) a call to any of the following:\n\n - [`supervisor:start_link/2,3`](`supervisor:start_link/3`)\n - [`gen_server:start_link/3,4`](`gen_server:start_link/4`)\n - [`gen_statem:start_link/3,4`](`gen_statem:start_link/4`)\n - [`gen_event:start_link/0,1,2`](`gen_event:start_link/2`)\n - A function compliant with these functions. For details, see\n `m:supervisor`.\n\n The `start` key is mandatory.\n\n- [](){: #restart } `restart` defines when a terminated child process is to be\n restarted.\n\n - A `permanent` child process is always restarted.\n - A `temporary` child process is never restarted (not even when the supervisor\n restart strategy is `rest_for_one` or `one_for_all` and a sibling death\n causes the temporary process to be terminated).\n - A `transient` child process is restarted only if it terminates abnormally,\n that is, with an exit reason other than `normal`, `shutdown`, or\n `{shutdown,Term}`.\n\n The `restart` key is optional. If it is not given, the default value\n `permanent` will be used.\n\n- [](){: #significant_child } `significant` defines whether a child is considered\n significant for [automatic self-shutdown](sup_princ.md#automatic-shutdown) of\n the supervisor.\n\n It is invalid to set this option to `true` for a child with\n [restart type](sup_princ.md#restart) `permanent` or in a supervisor with\n [auto_shutdown](sup_princ.md#automatic-shutdown) set to `never`.\n\n- [](){: #shutdown } `shutdown` defines how a child process is to be terminated.\n\n - `brutal_kill` means that the child process is unconditionally terminated\n using [`exit(Child, kill)`](`exit/2`).\n - An integer time-out value means that the supervisor tells the child process\n to terminate by calling [`exit(Child, shutdown)`](`exit/2`) and then waits\n for an exit signal back. If no exit signal is received within the specified\n time, the child process is unconditionally terminated using\n [`exit(Child, kill)`](`exit/2`).\n - If the child process is another supervisor, it should be set to `infinity`\n to give the subtree enough time to shut down. It is also allowed to set it\n to `infinity` if the child process is a worker.\n\n > #### Warning {: .warning }\n >\n > Setting the shutdown time to anything other than `infinity` for a child of\n > type `supervisor` can cause a race condition where the child in question\n > unlinks its own children, but fails to terminate them before it is killed.\n >\n > Be careful when setting the shutdown time to `infinity` when the child\n > process is a worker. Because, in this situation, the termination of the\n > supervision tree depends on the child process; it must be implemented in a\n > safe way and its cleanup procedure must always return.\n\n The `shutdown` key is optional. If it is not given, and the child is of type\n `worker`, the default value `5000` will be used; if the child is of type\n `supervisor`, the default value `infinity` will be used.\n\n- `type` specifies whether the child process is a supervisor or a worker.\n\n The `type` key is optional. If it is not given, the default value `worker`\n will be used.\n\n- `modules` has to be a list consisting of a single element. The value\n of that element depends on the behaviour of the process:\n\n * If the child process is a `gen_event`, the element has to be the atom\n `dynamic`.\n * Otherwise, the element should be `Module`, where `Module` is the\n name of the callback module.\n\n This information is used by the release handler during upgrades and\n downgrades; see [Release Handling](release_handling.md).\n\n The `modules` key is optional. If it is not given, it defaults to `[M]`, where\n `M` comes from the child's start `{M,F,A}`.\n\n_Example:_ The child specification to start the server `ch3` in the previous\nexample look as follows:\n\n```erlang\n#{id => ch3,\n start => {ch3, start_link, []},\n restart => permanent,\n shutdown => brutal_kill,\n type => worker,\n modules => [ch3]}\n```\n\nor simplified, relying on the default values:\n\n```text\n#{id => ch3,\n start => {ch3, start_link, []},\n shutdown => brutal_kill}\n```\n\nExample: A child specification to start the event manager from the chapter about\n[gen_event](events.md#mgr):\n\n```erlang\n#{id => error_man,\n start => {gen_event, start_link, [{local, error_man}]},\n modules => dynamic}\n```\n\nBoth server and event manager are registered processes which can be expected to\nbe always accessible. Thus they are specified to be `permanent`.\n\n`ch3` does not need to do any cleaning up before termination. Thus, no shutdown\ntime is needed, but `brutal_kill` is sufficient. `error_man` can need some time\nfor the event handlers to clean up, thus the shutdown time is set to 5000 ms\n(which is the default value).\n\nExample: A child specification to start another supervisor:\n\n```erlang\n#{id => sup,\n start => {sup, start_link, []},\n restart => transient,\n type => supervisor} % will cause default shutdown=>infinity\n```\n\n[](){: #super_tree }","ref":"sup_princ.html#child-specification"},{"type":"extras","title":"Starting a Supervisor - Supervisor Behaviour","doc":"In the previous example, the supervisor is started by calling\n`ch_sup:start_link()`:\n\n```erlang\nstart_link() ->\n supervisor:start_link(ch_sup, []).\n```\n\n`ch_sup:start_link` calls function `supervisor:start_link/2`, which spawns and\nlinks to a new process, a supervisor.\n\n- The first argument, `ch_sup`, is the name of the callback module, that is, the\n module where the `init` callback function is located.\n- The second argument, `[]`, is a term that is passed as is to the callback\n function `init`. Here, `init` does not need any data and ignores the argument.\n\nIn this case, the supervisor is not registered. Instead its pid must be used. A\nname can be specified by calling\n[`supervisor:start_link({local, Name}, Module, Args)`](`supervisor:start_link/3`)\nor\n[`supervisor:start_link({global, Name}, Module, Args)`](`supervisor:start_link/3`).\n\nThe new supervisor process calls the callback function `ch_sup:init([])`. `init`\nhas to return `{ok, {SupFlags, ChildSpecs}}`:\n\n```erlang\ninit(_Args) ->\n SupFlags = #{},\n ChildSpecs = [#{id => ch3,\n start => {ch3, start_link, []},\n shutdown => brutal_kill}],\n {ok, {SupFlags, ChildSpecs}}.\n```\n\nSubsequently, the supervisor starts its child processes according to the child\nspecifications in the start specification. In this case there is a single child\nprocess, called `ch3`.\n\n`supervisor:start_link/3` is synchronous. It does not return until all child\nprocesses have been started.","ref":"sup_princ.html#starting-a-supervisor"},{"type":"extras","title":"Adding a Child Process - Supervisor Behaviour","doc":"In addition to the static supervision tree as defined by the child\nspecifications, dynamic child processes can be added to an existing\nsupervisor by calling [`supervisor:start_child(Sup,\nChildSpec)`](`supervisor:start_child/2`).\n\n`Sup` is the pid, or name, of the supervisor. `ChildSpec` is a\n[child specification](sup_princ.md#spec).\n\nChild processes added using `start_child/2` behave in the same way as the other\nchild processes, with one important exception: if a supervisor dies and is\nrecreated, then all child processes that were dynamically added to the\nsupervisor are lost.","ref":"sup_princ.html#adding-a-child-process"},{"type":"extras","title":"Stopping a Child Process - Supervisor Behaviour","doc":"Any child process, static or dynamic, can be stopped in accordance with the\nshutdown specification by calling\n[`supervisor:terminate_child(Sup, Id)`](`supervisor:terminate_child/2`).\n\nStopping a [significant child](sup_princ.md#significant_child) of a supervisor\nconfigured for [automatic shutdown](sup_princ.md#automatic-shutdown) will not\ntrigger an automatic shutdown.\n\nThe child specification for a stopped child process is deleted by\ncalling [`supervisor:delete_child(Sup, Id)`](`supervisor:delete_child/2`).\n\n`Sup` is the pid, or name, of the supervisor. `Id` is the value associated with\nthe `id` key in the [child specification](sup_princ.md#spec).\n\nAs with dynamically added child processes, the effects of deleting a static\nchild process are lost if the supervisor itself restarts.\n\n[](){: #simple }","ref":"sup_princ.html#stopping-a-child-process"},{"type":"extras","title":"Simplified one_for_one Supervisors - Supervisor Behaviour","doc":"A supervisor with restart strategy `simple_one_for_one` is a simplified\n`one_for_one` supervisor, where all child processes are dynamically added\ninstances of the same process.\n\nThe following is an example of a callback module for a `simple_one_for_one`\nsupervisor:\n\n```erlang\n-module(simple_sup).\n-behaviour(supervisor).\n\n-export([start_link/0]).\n-export([init/1]).\n\nstart_link() ->\n supervisor:start_link(simple_sup, []).\n\ninit(_Args) ->\n SupFlags = #{strategy => simple_one_for_one,\n intensity => 0,\n period => 1},\n ChildSpecs = [#{id => call,\n start => {call, start_link, []},\n shutdown => brutal_kill}],\n {ok, {SupFlags, ChildSpecs}}.\n```\n\nWhen started, the supervisor does not start any child\nprocesses. Instead, all child processes need to be added dynamically by\ncalling [`supervisor:start_child(Sup, List)`](`supervisor:start_child/2`).\n\n`Sup` is the pid, or name, of the supervisor. `List` is an arbitrary list of\nterms, which are added to the list of arguments specified in the child\nspecification. If the start function is specified as `{M, F, A}`, the child\nprocess is started by calling [`apply(M, F, A++List)`](`apply/3`).\n\nFor example, adding a child to `simple_sup` above:\n\n```text\nsupervisor:start_child(Pid, [id1])\n```\n\nThe result is that the child process is started by calling\n[`apply(call, start_link, []++[id1])`](`apply/3`), or actually:\n\n```text\ncall:start_link(id1)\n```\n\nA child under a `simple_one_for_one` supervisor can be terminated with the\nfollowing:\n\n```text\nsupervisor:terminate_child(Sup, Pid)\n```\n\n`Sup` is the pid, or name, of the supervisor and `Pid` is the pid of the child.\n\nBecause a `simple_one_for_one` supervisor can have many children, it shuts them\nall down asynchronously. This means that the children will do their cleanup in\nparallel and therefore the order in which they are stopped is not defined.\n\nStarting, restarting, and manually terminating children are synchronous operations\nwhich are executed in the context of the supervisor process. This means\nthat the supervisor process will be blocked while it is performing any of those\noperations. Child processes are responsible for keeping their start and shutdown\nphases as short as possible.","ref":"sup_princ.html#simplified-one_for_one-supervisors"},{"type":"extras","title":"Stopping - Supervisor Behaviour","doc":"Since the supervisor is part of a supervision tree, it is\nautomatically terminated by its supervisor. When asked to shut down, a\nsupervisor terminates all child processes in reverse start order\naccording to the respective shutdown specifications before terminating\nitself.\n\nIf the supervisor is configured for\n[automatic shutdown](sup_princ.md#automatic-shutdown) on termination of any or\nall [significant children](sup_princ.md#significant_child), it will shut down\nitself when any or the last active significant child terminates, respectively.\nThe shutdown itself follows the same procedure as described above, that is, the\nsupervisor terminates all remaining child processes in reverse start order\nbefore terminating itself.","ref":"sup_princ.html#stopping"},{"type":"extras","title":"Manual stopping versus Automatic Shutdown - Supervisor Behaviour","doc":"For several reasons, a supervisor should not be stopped manually via\n`supervisor:terminate_child/2` from a child located in its own tree.\n\n1. The child process will have to know the pids or registered names not only of\n the supervisor it wants to stop, but also that of the supervisor's parent\n supervisor, in order to tell the parent supervisor to stop the supervisor it\n wants to stop. This can make restructuring a supervision tree difficult.\n1. `supervisor:terminate_child/2` is a blocking call that will only return after\n the parent supervisor has finished the shutdown of the supervisor that should\n be stopped. Unless the call is made from a spawned process, this will result\n in a deadlock, as the supervisor waits for the child to exit as part of its\n shutdown procedure, whereas the child waits for the supervisor to shut down.\n If the child is trapping exits, this deadlock will last until the\n [shutdown](sup_princ.md#shutdown) timeout for the child expires.\n1. When a supervisor is stopping a child, it will wait for the shutdown to\n complete before accepting other calls, that is, the supervisor will be\n unresponsive until then. If the termination takes some time to complete,\n especially when the considerations outlined in the previous point were not\n taken into account carefully, said supervisor might become unresponsive for a\n long time.\n\nInstead, it is generally a better approach to rely on\n[Automatic Shutdown](sup_princ.md#automatic-shutdown).\n\n1. A child process does not need to know anything about its supervisor and its\n respective parent, not even that it is part of a supervision tree in the\n first place. It is instead only the supervisor which hosts the child who must\n know which of its children are [significant](sup_princ.md#significant_child)\n ones, and when to shut itself down.\n1. A child process does not need to do anything special to shut down the work\n unit it is part of. All it needs to do is terminate normally when it has\n finished the task it was started for.\n1. A supervisor that is automatically shutting itself down will perform the\n required shutdown steps fully independent of its parent supervisor. The\n parent supervisor will only notice that its child supervisor has terminated\n in the end. As the parent supervisor is not involved in the shutdown process,\n it will not be blocked.","ref":"sup_princ.html#manual-stopping-versus-automatic-shutdown"},{"type":"extras","title":"sys and proc_lib","doc":"\n# sys and proc_lib\n\n[](){: #sys-and-proc_lib }\n\nThe `m:sys` module has functions for simple debugging of processes implemented\nusing behaviours. It also has functions that, together with functions in the\n`proc_lib` module, can be used to implement a _special process_ that complies to\nthe OTP design principles without using a standard behaviour. These functions\ncan also be used to implement user-defined (non-standard) behaviours.\n\nBoth `m:sys` and `m:proc_lib` belong to the STDLIB application.","ref":"spec_proc.html"},{"type":"extras","title":"Simple Debugging - sys and proc_lib","doc":"The `m:sys` module has functions for simple debugging of processes implemented\nusing behaviours. The `code_lock` example from\n[gen_statem Behaviour](statem.md#example) is used to illustrate this:\n\n```erlang\nErlang/OTP 27 [erts-15.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]\n\nEshell V15.0 (press Ctrl+G to abort, type help(). for help)\n1> code_lock:start_link([1,2,3,4]).\nLock\n{ok,<0.90.0>}\n2> sys:statistics(code_lock, true).\nok\n3> sys:trace(code_lock, true).\nok\n4> code_lock:button(1).\n*DBG* code_lock receive cast {button,1} in state locked\nok\n*DBG* code_lock consume cast {button,1} in state locked\n5> code_lock:button(2).\n*DBG* code_lock receive cast {button,2} in state locked\nok\n*DBG* code_lock consume cast {button,2} in state locked\n6> code_lock:button(3).\n*DBG* code_lock receive cast {button,3} in state locked\nok\n*DBG* code_lock consume cast {button,3} in state locked\n7> code_lock:button(4).\n*DBG* code_lock receive cast {button,4} in state locked\nok\nUnlock\n*DBG* code_lock consume cast {button,4} in state locked => open\n*DBG* code_lock start_timer {state_timeout,10000,lock,[]} in state open\n*DBG* code_lock receive state_timeout lock in state open\nLock\n*DBG* code_lock consume state_timeout lock in state open => locked\n8> sys:statistics(code_lock, get).\n{ok,[{start_time,{{2024,5,3},{8,11,1}}},\n {current_time,{{2024,5,3},{8,11,48}}},\n {reductions,4098},\n {messages_in,5},\n {messages_out,0}]}\n9> sys:statistics(code_lock, false).\nok\n10> sys:trace(code_lock, false).\nok\n11> sys:get_status(code_lock).\n{status,<0.90.0>,\n {module,gen_statem},\n [[{'$initial_call',{code_lock,init,1}},\n {'$ancestors',[<0.88.0>,<0.87.0>,<0.70.0>,<0.65.0>,<0.69.0>,\n <0.64.0>,kernel_sup,<0.47.0>]}],\n running,<0.88.0>,[],\n [{header,\"Status for state machine code_lock\"},\n {data,[{\"Status\",running},\n {\"Parent\",<0.88.0>},\n {\"Modules\",[code_lock]},\n {\"Time-outs\",{0,[]}},\n {\"Logged Events\",[]},\n {\"Postponed\",[]}]},\n {data,[{\"State\",\n {locked,#{code => [1,2,3,4],\n length => 4,buttons => []}}}]}]]}\n```","ref":"spec_proc.html#simple-debugging"},{"type":"extras","title":"Special Processes - sys and proc_lib","doc":"This section describes how to write a process that complies to the OTP design\nprinciples, without using a standard behaviour. Such a process is to:\n\n- Be started in a way that makes the process fit into a supervision tree\n- Support the `sys` [debug facilities](spec_proc.md#debug)\n- Take care of [system messages](spec_proc.md#msg).\n\nSystem messages are messages with a special meaning, used in the supervision\ntree. Typical system messages are requests for trace output, and requests to\nsuspend or resume process execution (used during release handling). Processes\nimplemented using standard behaviours automatically understand these messages.","ref":"spec_proc.html#special-processes"},{"type":"extras","title":"Example - sys and proc_lib","doc":"Here follows the simple server from\n[Overview](design_principles.md#ch1),\nimplemented using `sys` and `proc_lib` to fit into a supervision tree:\n\n```erlang\n-module(ch4).\n-export([start_link/0]).\n-export([alloc/0, free/1]).\n-export([init/1]).\n-export([system_continue/3, system_terminate/4,\n write_debug/3,\n system_get_state/1, system_replace_state/2]).\n\nstart_link() ->\n proc_lib:start_link(ch4, init, [self()]).\n\nalloc() ->\n ch4 ! {self(), alloc},\n receive\n {ch4, Res} ->\n Res\n end.\n\nfree(Ch) ->\n ch4 ! {free, Ch},\n ok.\n\ninit(Parent) ->\n register(ch4, self()),\n Chs = channels(),\n Deb = sys:debug_options([]),\n proc_lib:init_ack(Parent, {ok, self()}),\n loop(Chs, Parent, Deb).\n\nloop(Chs, Parent, Deb) ->\n receive\n {From, alloc} ->\n Deb2 = sys:handle_debug(Deb, fun ch4:write_debug/3,\n ch4, {in, alloc, From}),\n {Ch, Chs2} = alloc(Chs),\n From ! {ch4, Ch},\n Deb3 = sys:handle_debug(Deb2, fun ch4:write_debug/3,\n ch4, {out, {ch4, Ch}, From}),\n loop(Chs2, Parent, Deb3);\n {free, Ch} ->\n Deb2 = sys:handle_debug(Deb, fun ch4:write_debug/3,\n ch4, {in, {free, Ch}}),\n Chs2 = free(Ch, Chs),\n loop(Chs2, Parent, Deb2);\n\n {system, From, Request} ->\n sys:handle_system_msg(Request, From, Parent,\n ch4, Deb, Chs)\n end.\n\nsystem_continue(Parent, Deb, Chs) ->\n loop(Chs, Parent, Deb).\n\nsystem_terminate(Reason, _Parent, _Deb, _Chs) ->\n exit(Reason).\n\nsystem_get_state(Chs) ->\n {ok, Chs}.\n\nsystem_replace_state(StateFun, Chs) ->\n NChs = StateFun(Chs),\n {ok, NChs, NChs}.\n\nwrite_debug(Dev, Event, Name) ->\n io:format(Dev, \"~p event = ~p~n\", [Name, Event]).\n```\n\nAs it is not relevant to the example, the channel handling functions have been\nomitted. To compile this example, the\n[implementation of channel handling](design_principles.md#channels-implementation)\nneeds to be added to the module.\n\n{: #ex }\n\nHere is an example showing how the debugging functions in the `sys`\nmodule can be used for `ch4`:\n\n```erlang\n% erl\nErlang/OTP 27 [erts-15.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]\n\nEshell V15.0 (press Ctrl+G to abort, type help(). for help)\n1> ch4:start_link().\n{ok,<0.90.0>}\n2> sys:statistics(ch4, true).\nok\n3> sys:trace(ch4, true).\nok\n4> ch4:alloc().\nch4 event = {in,alloc,<0.88.0>}\nch4 event = {out,{ch4,1},<0.88.0>}\n1\n5> ch4:free(ch1).\nch4 event = {in,{free,ch1}}\nok\n6> sys:statistics(ch4, get).\n{ok,[{start_time,{{2024,5,3},{8,26,13}}},\n {current_time,{{2024,5,3},{8,26,49}}},\n {reductions,202},\n {messages_in,2},\n {messages_out,1}]}\n7> sys:statistics(ch4, false).\nok\n8> sys:trace(ch4, false).\nok\n9> sys:get_status(ch4).\n{status,<0.90.0>,\n {module,ch4},\n [[{'$initial_call',{ch4,init,1}},\n {'$ancestors',[<0.88.0>,<0.87.0>,<0.70.0>,<0.65.0>,<0.69.0>,\n <0.64.0>,kernel_sup,<0.47.0>]}],\n running,<0.88.0>,[],\n {[1],[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19|...]}]}\n```","ref":"spec_proc.html#example"},{"type":"extras","title":"Starting the Process - sys and proc_lib","doc":"A function in the `m:proc_lib` module is to be used to start the process. Several\nfunctions are available, for example,\n[`proc_lib:spawn_link/3,4`](`proc_lib:spawn_link/4`)\nfor asynchronous start and\n[`proc_lib:start_link/3,4,5`](`proc_lib:start_link/5`) for synchronous start.\n\nInformation necessary for a process within a supervision tree, such as\ndetails on ancestors and the initial call, is stored when a process\nis started through one of these functions.\n\nIf the process terminates with a reason other than `normal` or `shutdown`, a\ncrash report is generated. For more information about the crash report, see\n[Logging](`e:kernel:logger_chapter.md`) in Kernel User's Guide.\n\nIn the example, synchronous start is used. The process starts by calling\n`ch4:start_link()`:\n\n```erlang\nstart_link() ->\n proc_lib:start_link(ch4, init, [self()]).\n```\n\n`ch4:start_link/0` calls `proc_lib:start_link/3`, which takes a module\nname, a function name, and an argument list as arguments. It then\nspawns a new process and establishes a link. The new process starts\nby executing the given function, here `ch4:init(Pid)`, where `Pid` is\nthe pid of the parent process (obtained by the call to\n[`self()`](`erlang:self/0`) in the call to `proc_lib:start_link/3`).\n\nAll initialization, including name registration, is done in `init/1`. The new\nprocess has to acknowledge that it has been started to the parent:\n\n```erlang\ninit(Parent) ->\n ...\n proc_lib:init_ack(Parent, {ok, self()}),\n loop(...).\n```\n\n`proc_lib:start_link/3` is synchronous and does not return until\n[`proc_lib:init_ack/1,2`](`proc_lib:init_ack/2`) or\n[`proc_lib:init_fail/2,3`](`proc_lib:init_fail/3`) has been called,\nor the process has exited.\n\n[](){: #debug }","ref":"spec_proc.html#starting-the-process"},{"type":"extras","title":"Debugging - sys and proc_lib","doc":"To support the debug facilities in `sys`, a _debug structure_ is needed. The\n`Deb` term is initialized using `sys:debug_options/1`:\n\n```erlang\ninit(Parent) ->\n ...\n Deb = sys:debug_options([]),\n ...\n loop(Chs, Parent, Deb).\n```\n\n`sys:debug_options/1` takes a list of options. Given an empty list as in this\nexample means that debugging is initially disabled. For information about the\npossible options, see `m:sys` in STDLIB.\n\nFor each _system event_ to be logged or traced, the following function\nis to be called:\n\n```erlang\nsys:handle_debug(Deb, Func, Info, Event) => Deb1\n```\n\nThe arguments have the follow meaning:\n\n- `Deb` is the debug structure as returned from `sys:debug_options/1`.\n- `Func` is a fun specifying a (user-defined) function used to format trace\n output. For each system event, the format function is called as\n `Func(Dev, Event, Info)`, where:\n - `Dev` is the I/O device to which the output is to be printed. See `m:io`\n in STDLIB.\n - `Event` and `Info` are passed as-is from the call to `sys:handle_debug/4`.\n- `Info` is used to pass more information to `Func`. It can be any term, and it\n is passed as-is.\n- `Event` is the system event. It is up to the user to define what a system\n event is and how it is to be represented. Typically, at least incoming and\n outgoing messages are considered system events and represented by the tuples\n `{in,Msg[,From]}` and `{out,Msg,To[,State]}`, respectively.\n\n`sys:handle_debug/4` returns an updated debug structure `Deb1`.\n\nIn the example, `sys:handle_debug/4` is called for each incoming and\noutgoing message. The format function `Func` is the function\n`ch4:write_debug/3`, which prints the message using `io:format/3`.\n\n```erlang\nloop(Chs, Parent, Deb) ->\n receive\n {From, alloc} ->\n Deb2 = sys:handle_debug(Deb, fun ch4:write_debug/3,\n ch4, {in, alloc, From}),\n {Ch, Chs2} = alloc(Chs),\n From ! {ch4, Ch},\n Deb3 = sys:handle_debug(Deb2, fun ch4:write_debug/3,\n ch4, {out, {ch4, Ch}, From}),\n loop(Chs2, Parent, Deb3);\n {free, Ch} ->\n Deb2 = sys:handle_debug(Deb, fun ch4:write_debug/3,\n ch4, {in, {free, Ch}}),\n Chs2 = free(Ch, Chs),\n loop(Chs2, Parent, Deb2);\n ...\n end.\n\nwrite_debug(Dev, Event, Name) ->\n io:format(Dev, \"~p event = ~p~n\", [Name, Event]).\n```\n\n[](){: #msg }","ref":"spec_proc.html#debugging"},{"type":"extras","title":"Handling System Messages - sys and proc_lib","doc":"_System messages_ are received as:\n\n```text\n{system, From, Request}\n```\n\nThe content and meaning of these messages are not to be interpreted by the\nprocess. Instead the following function is to be called:\n\n```erlang\nsys:handle_system_msg(Request, From, Parent, Module, Deb, State)\n```\n\nThe arguments have the following meaning:\n\n- `Request` and `From` from the received system message are to be\n passed as-is to the call to `sys:handle_system_msg/6`.\n- `Parent` is the pid of the parent process.\n- `Module` is the name of the module implementing the speciall process.\n- `Deb` is the debug structure.\n- `State` is a term describing the internal state and is passed on to\n `Module:system_continue/3`, `Module:system_terminate/4`/\n `Module:system_get_state/1`, and `Module:system_replace_state/2`.\n\n`sys:handle_system_msg/6` does not return. It handles the system\nmessage and *eventually* calls either of the following functions:\n\n* `Module:system_continue(Parent, Deb, State)` - if process execution is to\n continue.\n\n* `Module:system_terminate(Reason, Parent, Deb, State)` - if the\n process is to terminate.\n\nWhile handling the system message, `sys:handle_system_msg/6` can call\none of the following functions:\n\n* `Module:system_get_state(State)` - if the process is to return its state.\n\n* `Module:system_replace_state(StateFun, State)` - if the process is\n to replace its state using the fun `StateFun` fun. See `sys:replace_state/3`\n for more information.\n\n* `system_code_change(Misc, Module, OldVsn, Extra)` - if the process is to\n perform a code change.\n\nA process in a supervision tree is expected to terminate with the same reason as\nits parent.\n\nIn the example, system messages are handed by the following code:\n\n```erlang\nloop(Chs, Parent, Deb) ->\n receive\n ...\n\n {system, From, Request} ->\n sys:handle_system_msg(Request, From, Parent,\n ch4, Deb, Chs)\n end.\n\nsystem_continue(Parent, Deb, Chs) ->\n loop(Chs, Parent, Deb).\n\nsystem_terminate(Reason, Parent, Deb, Chs) ->\n exit(Reason).\n\nsystem_get_state(Chs) ->\n {ok, Chs, Chs}.\n\nsystem_replace_state(StateFun, Chs) ->\n NChs = StateFun(Chs),\n {ok, NChs, NChs}.\n```\n\nIf a special process is configured to trap exits, it must take notice\nof 'EXIT' messages from its parent process and terminate using the\nsame exit reason once the parent process has terminated.\n\nHere is an example:\n\n```erlang\ninit(Parent) ->\n ...,\n process_flag(trap_exit, true),\n ...,\n loop(Parent).\n\nloop(Parent) ->\n receive\n ...\n {'EXIT', Parent, Reason} ->\n %% Clean up here, if needed.\n exit(Reason);\n ...\n end.\n```","ref":"spec_proc.html#handling-system-messages"},{"type":"extras","title":"User-Defined Behaviours - sys and proc_lib","doc":"[](){: #behaviours } To implement a user-defined behaviour, write code similar\nto code for a special process, but call functions in a callback module for\nhandling specific tasks.\n\nIf the compiler is to warn for missing callback functions, as it does for the\nOTP behaviours, add `-callback` attributes in the behaviour module to describe\nthe expected callbacks:\n\n```text\n-callback Name1(Arg1_1, Arg1_2, ..., Arg1_N1) -> Res1.\n-callback Name2(Arg2_1, Arg2_2, ..., Arg2_N2) -> Res2.\n...\n-callback NameM(ArgM_1, ArgM_2, ..., ArgM_NM) -> ResM.\n```\n\n`NameX` are the names of the expected callbacks. `ArgX_Y` and `ResX` are types\nas they are described in\n[Types and Function Specifications](`e:system:typespec.md`). The whole syntax of\nthe `-spec` attribute is supported by the `-callback` attribute.\n\nCallback functions that are optional for the user of the behaviour to implement\nare specified by use of the `-optional_callbacks` attribute:\n\n```text\n-optional_callbacks([OptName1/OptArity1, ..., OptNameK/OptArityK]).\n```\n\nwhere each `OptName/OptArity` specifies the name and arity of a callback\nfunction. Note that the `-optional_callbacks` attribute is to be used together\nwith the `-callback` attribute; it cannot be combined with the\n`behaviour_info()` function described below.\n\nTools that need to know about optional callback functions can call\n`Behaviour:behaviour_info(optional_callbacks)` to get a list of all optional\ncallback functions.\n\n> #### Note {: .info }\n>\n> We recommend using the `-callback` attribute rather than the\n> `behaviour_info()` function. The reason is that the extra type information can\n> be used by tools to produce documentation or find discrepancies.\n\nAs an alternative to the `-callback` and `-optional_callbacks` attributes you\nmay directly implement and export `behaviour_info()`:\n\n```erlang\nbehaviour_info(callbacks) ->\n [{Name1, Arity1},...,{NameN, ArityN}].\n```\n\nwhere each `{Name, Arity}` specifies the name and arity of a callback function.\nThis function is otherwise automatically generated by the compiler using the\n`-callback` attributes.\n\nWhen the compiler encounters the module attribute `-behaviour(Behaviour).` in a\nmodule `Mod`, it calls `Behaviour:behaviour_info(callbacks)` and compares the\nresult with the set of functions actually exported from `Mod`, and issues a\nwarning if any callback function is missing.\n\n_Example:_\n\n```erlang\n%% User-defined behaviour module\n-module(simple_server).\n-export([start_link/2, init/3, ...]).\n\n-callback init(State :: term()) -> 'ok'.\n-callback handle_req(Req :: term(), State :: term()) -> {'ok', Reply :: term()}.\n-callback terminate() -> 'ok'.\n-callback format_state(State :: term()) -> term().\n\n-optional_callbacks([format_state/1]).\n\n%% Alternatively you may define:\n%%\n%% -export([behaviour_info/1]).\n%% behaviour_info(callbacks) ->\n%% [{init,1},\n%% {handle_req,2},\n%% {terminate,0}].\n\nstart_link(Name, Module) ->\n proc_lib:start_link(?MODULE, init, [self(), Name, Module]).\n\ninit(Parent, Name, Module) ->\n register(Name, self()),\n ...,\n Dbg = sys:debug_options([]),\n proc_lib:init_ack(Parent, {ok, self()}),\n loop(Parent, Module, Deb, ...).\n\n...\n```\n\nIn a callback module:\n\n```erlang\n-module(db).\n-behaviour(simple_server).\n\n-export([init/1, handle_req/2, terminate/0]).\n\n...\n```\n\nThe contracts specified with `-callback` attributes in behaviour modules can be\nfurther refined by adding `-spec` attributes in callback modules. This can be\nuseful as `-callback` contracts are usually generic. The same callback module\nwith contracts for the callbacks:\n\n```erlang\n-module(db).\n-behaviour(simple_server).\n\n-export([init/1, handle_req/2, terminate/0]).\n\n-record(state, {field1 :: [atom()], field2 :: integer()}).\n\n-type state() :: #state{}.\n-type request() :: {'store', term(), term()};\n {'lookup', term()}.\n\n...\n\n-spec handle_req(request(), state()) -> {'ok', term()}.\n\n...\n```\n\nEach `-spec` contract is to be a subtype of the respective `-callback` contract.","ref":"spec_proc.html#user-defined-behaviours"},{"type":"extras","title":"Applications","doc":"\n# Applications\n\n[](){: #appl }\n\nIt is recommended to read this section alongside [`app`](`e:kernel:app.md`)\nand `m:application` in Kernel.","ref":"applications.html"},{"type":"extras","title":"Application Concept - Applications","doc":"After creating code to implement a specific functionality, you might\nconsider transforming it into an *application* — a component that can be\nstarted and stopped as a unit, as well as reused in other systems.\n\nThe steps to create an application is as follows:\n\n* Create an [application callback\n module](applications.md#callback_module) that describes how the\n application is to be started and stopped.\n\n* Create an _application specification_ and place it in an\n [application resource file](applications.md#appl_res_file). Among\n other things, this file specifies which modules the application\n consists of and the name of the callback module.\n\nIf you use `m:systools`, the Erlang/OTP tools for packaging code (see\n[Releases](release_structure.md)), the code for each application is placed in a\nseparate directory following a pre-defined\n[directory structure](applications.md#app_dir).\n\n[](){: #callback_module }","ref":"applications.html#application-concept"},{"type":"extras","title":"Application Callback Module - Applications","doc":"How to start and stop the code for the application, including its supervision\ntree, is described by two callback functions:\n\n```erlang\nstart(StartType, StartArgs) -> {ok, Pid} | {ok, Pid, State}\nstop(State)\n```\n\n- `start/2` is called when starting the application and is to create the\n supervision tree by starting the top supervisor. It is expected to return the\n pid of the top supervisor and an optional term, `State`, which defaults to\n `[]`. This term is passed as is to `stop/1`.\n- `StartType` is usually the atom `normal`. It has other values only in the case\n of a takeover or failover; see\n [Distributed Applications](distributed_applications.md).\n- `StartArgs` is defined by the key `mod` in the\n [application resource file](applications.md#appl_res_file).\n- `stop/1` is called _after_ the application has been stopped and is to do any\n necessary cleaning up. The actual stopping of the application, that is,\n shutting down the supervision tree, is handled automatically as described in\n [Starting and Stopping Applications](applications.md#stopping).\n\n[](){: #ch_app }\n\nExample of an application callback module for packaging the supervision tree\nfrom [Supervisor Behaviour](sup_princ.md#ex):\n\n```erlang\n-module(ch_app).\n-behaviour(application).\n\n-export([start/2, stop/1]).\n\nstart(_Type, _Args) ->\n ch_sup:start_link().\n\nstop(_State) ->\n ok.\n```\n\nA library application that cannot be started or stopped does not need any\napplication callback module.\n\n[](){: #appl_res_file }","ref":"applications.html#application-callback-module"},{"type":"extras","title":"Application Resource File - Applications","doc":"To define an application, an _application specification_ is created, which is\nput in an _application resource file_, or in short an `.app` file:\n\n```text\n{application, Application, [Opt1,...,OptN]}.\n```\n\n- `Application`, an atom, is the name of the application. The file must be named\n `Application.app`.\n- Each `Opt` is a tuple `{Key,Value}`, which defines a certain property of the\n application. All keys are optional. Default values are used for any omitted\n keys.\n\nThe contents of a minimal `.app` file for a library application `libapp` looks\nas follows:\n\n```text\n{application, libapp, []}.\n```\n\nThe contents of a minimal `.app` file `ch_app.app` for a supervision tree\napplication like `ch_app` looks as follows:\n\n```text\n{application, ch_app,\n [{mod, {ch_app,[]}}]}.\n```\n\nThe key `mod` defines the callback module and start argument of the application,\nin this case `ch_app` and `[]`, respectively. This means that the following is\ncalled when the application is to be started:\n\n```text\nch_app:start(normal, [])\n```\n\nThe following is called when the application is stopped:\n\n```text\nch_app:stop([])\n```\n\nWhen using `m:systools`, the Erlang/OTP tools for packaging code (see Section\n[Releases](release_structure.md)), the keys `description`, `vsn`, `modules`,\n`registered`, and `applications` are also to be specified:\n\n```erlang\n{application, ch_app,\n [{description, \"Channel allocator\"},\n {vsn, \"1\"},\n {modules, [ch_app, ch_sup, ch3]},\n {registered, [ch3]},\n {applications, [kernel, stdlib, sasl]},\n {mod, {ch_app,[]}}\n ]}.\n```\n\n- `description` - A short description, a string. Defaults to `\"\"`.\n- `vsn` - Version number, a string. Defaults to `\"\"`.\n- `modules` - All modules _introduced_ by this application. `m:systools` uses\n this list when generating boot scripts and tar files. A module must only\n be included in one application. Defaults to `[]`.\n- `registered` - All names of registered processes in the application.\n `m:systools` uses this list to detect name clashes between applications.\n Defaults to `[]`.\n- `applications` - All applications that must be started before this\n application is started. `m:systools` uses this list to generate correct boot\n scripts. Defaults to `[]`. Notice that all applications have dependencies to\n at least Kernel and STDLIB.\n\n> #### Note {: .info }\n>\n> For details about the syntax and contents of the application resource file,\n> see [app](`e:kernel:app.md`) in Kernel.\n\n[](){: #app_dir }","ref":"applications.html#application-resource-file"},{"type":"extras","title":"Directory Structure - Applications","doc":"When packaging code using `m:systools`, the code for each application is placed in\na separate directory, `lib/Application-Vsn`, where `Vsn` is the version number.\n\nThis can be useful to know, even if `m:systools` is not used, since Erlang/OTP is\npackaged according to the OTP principles and thus comes with a specific\ndirectory structure. The code server (see module `m:code` in Kernel)\nautomatically uses code from the directory with the highest version number, if\nmore than one version of an application is present.","ref":"applications.html#directory-structure"},{"type":"extras","title":"Directory Structure Guidelines for a Development Environment - Applications","doc":"Any directory structure for development will suffice as long as the released\ndirectory structure adheres to the\n[description below](applications.md#app_dir_released), but it is encouraged that\nthe same directory structure also be used in a development environment. The\nversion number should be omitted from the application directory name since this\nis an artifact of the release step.\n\nSome sub-directories are _required_. Some sub-directories are _optional_,\nmeaning that it should only be used if the application itself requires it.\nFinally, some sub-directories are _recommended_, meaning it is encouraged that\nit is used and used as described here. For example, both documentation and tests\nare encouraged to exist in an application for it to be deemed a proper OTP\napplication.\n\n```text\n ─ ${application}\n   ├── doc\n │   ├── internal\n │   ├── examples\n │   └── src\n   ├── include\n   ├── priv\n   ├── src\n │   └── ${application}.app.src\n   └── test\n```\n\n- `src` - Required. Contains the Erlang source code, the source of the `.app`\n file and internal include files used by the application itself. Additional\n sub-directories within `src` can be used as namespaces to organize source\n files. These directories should never be deeper than one level.\n- `priv` - Optional. Used for application specific files.\n- `include` - Optional. Used for public include files that must be reachable\n from other applications.\n- `doc` - Recommended. Any source documentation should be placed in\n sub-directories here.\n- `doc/internal` - Recommended. Any documentation that describes implementation\n details about this application, not intended for publication, should be placed\n here.\n- `doc/examples` - Recommended. Source code for examples on how to use this\n application should be placed here. It is encouraged that examples are sourced\n to the public documentation from this directory.\n- `doc/src` - Recommended. All source files for documentation, such as\n Markdown, AsciiDoc, or XML-files, should be placed here.\n- `test` - Recommended. All files regarding tests, such as test suites and test\n specifications, should be placed here.\n\nOther directories in the development environment may be needed. If source code\nfrom languages other than Erlang is used, for instance C-code for NIFs, that\ncode should be placed in a separate directory. By convention it is recommended\nto prefix such directories with the language name, for example `c_src` for C,\n`java_src` for Java or `go_src` for Go. Directories with `_src` suffix indicates\nthat it is a part of the application and the compilation step. The final build\nartifacts should target the `priv/lib` or `priv/bin` directories.\n\nThe `priv` directory holds assets that the application needs during runtime.\nExecutables should reside in `priv/bin` and dynamically-linked libraries should\nreside in `priv/lib`. Other assets are free to reside within the `priv`\ndirectory but it is recommended they do so in a structured manner.\n\nSource files from other languages that generate Erlang code, such as ASN.1 or\nMibs, should be placed in directories, at the top level or in `src`, with the\nsame name as the source language, for example `asn1` and `mibs`. Build artifacts\nshould be placed in their respective language directory, such as `src` for\nErlang code or `java_src` for Java code.\n\nIn a development environment, it is acceptable that the `.app` file for\nthe release resides in the `ebin` directory, but it is recommended that\nit is an artifact of the build step. By convention a `.app.src`\nlocated in the `src` directory is used. This file is nearly identical\nto the `.app` file, but certain fields, such as the application\nversion, are replaced during the build step.\n\nDirectory names should not be capitalized.\n\nIt is encouraged to omit empty directories.\n\n[](){: #app_dir_released }","ref":"applications.html#directory-structure-guidelines-for-a-development-environment"},{"type":"extras","title":"Directory Structure for a Released System - Applications","doc":"A released application must follow a certain structure.\n\n```text\n ─ ${application}-${version}\n   ├── bin\n   ├── doc\n │   ├── html\n │   ├── man[1-9]\n │   ├── pdf\n │   ├── internal\n │   └── examples\n   ├── ebin\n │   └── ${application}.app\n   ├── include\n   ├── priv\n │   ├── lib\n │   └── bin\n   └── src\n```\n\n- `src` - Optional. Contains the Erlang source code and internal include files\n used by the application itself.\n- `ebin` - Required. Contains the Erlang object code, the `.beam` files. The\n `.app` file must also be placed here.\n- `priv` - Optional. Used for application specific files. `code:priv_dir/1` is\n to be used to access this directory.\n- `priv/lib` - Recommended. Any shared-object files that are used by the\n application, such as NIFs or linked-in-drivers, should be placed here.\n- `priv/bin` - Recommended. Any executable that is used by the application,\n such as port programs, should be placed here.\n- `include` - Optional. Used for public include files that must be reachable\n from other applications.\n- `bin` - Optional. Any executable that is a product of the application, such\n as escripts or shell scripts, should be placed here.\n- `doc` - Optional. Any released documentation should be placed in\n sub-directories here.\n\nThe `src` directory could be useful to release for debugging purposes,\nbut this is not required. The `include` directory should only be\nreleased if the applications has public include files.\n\nIt is encouraged to omit empty directories.\n\n[](){: #application_controller }","ref":"applications.html#directory-structure-for-a-released-system"},{"type":"extras","title":"Application Controller - Applications","doc":"When an Erlang runtime system is started, a number of processes are started as\npart of the Kernel application. One of these processes is the _application\ncontroller_ process, registered as `application_controller`.\n\nAll operations on applications are coordinated by the application\ncontroller. Use module `m:application` in Kernel to load, unload, start, and\nstop applications.","ref":"applications.html#application-controller"},{"type":"extras","title":"Loading and Unloading Applications - Applications","doc":"Before an application can be started, it must be _loaded_. The application\ncontroller reads and stores the information from the `.app` file:\n\n```erlang\n1> application:load(ch_app).\nok\n2> application:loaded_applications().\n[{kernel,\"ERTS CXC 138 10\",\"2.8.1.3\"},\n {stdlib,\"ERTS CXC 138 10\",\"1.11.4.3\"},\n {ch_app,\"Channel allocator\",\"1\"}]\n```\n\nAn application that has been stopped, or has never been started, can be\nunloaded. The information about the application is erased from the internal\ndatabase of the application controller.\n\n```erlang\n3> application:unload(ch_app).\nok\n4> application:loaded_applications().\n[{kernel,\"ERTS CXC 138 10\",\"2.8.1.3\"},\n {stdlib,\"ERTS CXC 138 10\",\"1.11.4.3\"}]\n```\n\n> #### Note {: .info }\n>\n> Loading/unloading an application does not load/unload the code used by the\n> application. Code loading is handled in the usual way by the code server.\n\n[](){: #stopping }","ref":"applications.html#loading-and-unloading-applications"},{"type":"extras","title":"Starting and Stopping Applications - Applications","doc":"An application is started by calling:\n\n```erlang\n5> application:start(ch_app).\nok\n6> application:which_applications().\n[{kernel,\"ERTS CXC 138 10\",\"2.8.1.3\"},\n {stdlib,\"ERTS CXC 138 10\",\"1.11.4.3\"},\n {ch_app,\"Channel allocator\",\"1\"}]\n```\n\nIf the application is not already loaded, the application controller first loads\nit using `application:load/1`. It checks the value of the `applications` key to\nensure that all applications that are to be started before this application are\nrunning.\n\n[](){: #application_master }\n\nFollowing that, the application controller creates an _application master_ for\nthe application.\n\nThe application master establishes itself as the [group\nleader](`erlang:group_leader/0`) of all processes in the application\nand will forward I/O to the previous group leader.\n\n> #### Note {: .info }\n>\n> The purpose of the application master being the group leader is to easily\n> keep track of which processes that belong to the application. That is needed\n> to support the `application:get_application/0` and `application:get_env/1`\n> functions, and also when stopping an application to ensure that all processes\n> belonging to the application are terminated.\n\nThe application master starts the application by calling the application\ncallback function `start/2` in the module with the start argument defined\nby the `mod` key in the `.app` file.\n\nAn application is stopped, but not unloaded, by calling:\n\n```text\n7> application:stop(ch_app).\nok\n```\n\nThe application master stops the application by telling the top supervisor to\nshut down. The top supervisor tells all its child processes to shut down, and so\non; the entire tree is terminated in reversed start order. The application\nmaster then calls the application callback function `stop/1` in the module\ndefined by the `mod` key.","ref":"applications.html#starting-and-stopping-applications"},{"type":"extras","title":"Configuring an Application - Applications","doc":"An application can be configured using _configuration parameters_. These are a\nlist of `{Par,Val}` tuples specified by a key `env` in the `.app` file:\n\n```erlang\n{application, ch_app,\n [{description, \"Channel allocator\"},\n {vsn, \"1\"},\n {modules, [ch_app, ch_sup, ch3]},\n {registered, [ch3]},\n {applications, [kernel, stdlib, sasl]},\n {mod, {ch_app,[]}},\n {env, [{file, \"/usr/local/log\"}]}\n ]}.\n```\n\n`Par` is to be an atom. `Val` is any term. The application can retrieve the\nvalue of a configuration parameter by calling `application:get_env(App, Par)` or\na number of similar functions. For more information, see module `m:application`\nin Kernel.\n\n_Example:_\n\n```erlang\n% erl\nErlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]\n\nEshell V5.2.3.6 (abort with ^G)\n1> application:start(ch_app).\nok\n2> application:get_env(ch_app, file).\n{ok,\"/usr/local/log\"}\n```\n\nThe values in the `.app` file can be overridden by values in a _system\nconfiguration file_. This is a file that contains configuration parameters for\nrelevant applications:\n\n```erlang\n[{Application1, [{Par11,Val11},...]},\n ...,\n {ApplicationN, [{ParN1,ValN1},...]}].\n```\n\nThe system configuration is to be called `Name.config` and Erlang is to be\nstarted with the command-line argument `-config Name`. For details, see\n[`config`](`e:kernel:config.md`) in Kernel.\n\n_Example:_\n\nA file `test.config` is created with the following contents:\n\n```text\n[{ch_app, [{file, \"testlog\"}]}].\n```\n\nThe value of `file` overrides the value of `file` as defined in the `.app` file:\n\n```erlang\n% erl -config test\nErlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]\n\nEshell V5.2.3.6 (abort with ^G)\n1> application:start(ch_app).\nok\n2> application:get_env(ch_app, file).\n{ok,\"testlog\"}\n```\n\nIf [release handling](release_handling.md#sys) is used, exactly one system\nconfiguration file is to be used and that file is to be called `sys.config`.\n\nThe values in the `.app` file and the values in a system configuration file can\nbe overridden directly from the command line:\n\n```text\n% erl -ApplName Par1 Val1 ... ParN ValN\n```\n\n_Example:_\n\n```erlang\n% erl -ch_app file '\"testlog\"'\nErlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]\n\nEshell V5.2.3.6 (abort with ^G)\n1> application:start(ch_app).\nok\n2> application:get_env(ch_app, file).\n{ok,\"testlog\"}\n```","ref":"applications.html#configuring-an-application"},{"type":"extras","title":"Application Start Types - Applications","doc":"A _start type_ is defined when starting the application:\n\n```text\napplication:start(Application, Type)\n```\n\n`application:start(Application)` is the same as calling\n`application:start(Application, temporary)`. The type can also be `permanent` or\n`transient`:\n\n- If a permanent application terminates, all other applications and the runtime\n system are also terminated.\n- If a transient application terminates with reason `normal`, this is reported\n but no other applications are terminated. If a transient application\n terminates abnormally, that is with any other reason than `normal`, all other\n applications and the runtime system are also terminated.\n- If a temporary application terminates, this is reported but no other\n applications are terminated.\n\nAn application can always be stopped explicitly by calling `application:stop/1`.\nRegardless of the mode, no other applications are affected.\n\nThe transient mode is of little practical use, since when a supervision tree\nterminates, the reason is set to `shutdown`, not `normal`.","ref":"applications.html#application-start-types"},{"type":"extras","title":"Included Applications","doc":"\n# Included Applications\n\n[](){: #included-appl }","ref":"included_applications.html"},{"type":"extras","title":"Introduction - Included Applications","doc":"An application can _include_ other applications. An _included application_ has\nits own application directory and `.app` file, but it is started as part of the\nsupervisor tree of another application.\n\nAn application can only be included by one other application.\n\nAn included application can include other applications.\n\nAn application that is not included by any other application is called a\n_primary application_.\n\n[](){: #inclappls }\n\n```mermaid\n---\ntitle: Primary Application and Included Applications\n---\nflowchart TD\n prim_app((Primary Application))\n\n subgraph Included Applications\n app1((App))\n app2((App))\n app3((App))\n app4((App))\n app5((App))\n\n subgraph Included Applications\n app11((App))\n end\n subgraph Included Applications\n app31((App))\n app32((App))\n end\n end\n\n prim_app --- app1 --- app11\n prim_app --- app2\n prim_app --- app3\n prim_app --- app4\n prim_app --- app5\n\n app3 --- app31\n app3 --- app32\n```\n\nThe application controller automatically loads any included applications when\nloading a primary application, but does not start them. Instead, the top\nsupervisor of the included application must be started by a supervisor in the\nincluding application.\n\nThis means that when running, an included application is in fact part of the\nprimary application, and a process in an included application considers itself\nbelonging to the primary application.","ref":"included_applications.html#introduction"},{"type":"extras","title":"Specifying Included Applications - Included Applications","doc":"Which applications to include is defined by the `included_applications` key in\nthe `.app` file:\n\n```erlang\n{application, prim_app,\n [{description, \"Tree application\"},\n {vsn, \"1\"},\n {modules, [prim_app_cb, prim_app_sup, prim_app_server]},\n {registered, [prim_app_server]},\n {included_applications, [incl_app]},\n {applications, [kernel, stdlib, sasl]},\n {mod, {prim_app_cb,[]}},\n {env, [{file, \"/usr/local/log\"}]}\n ]}.\n```","ref":"included_applications.html#specifying-included-applications"},{"type":"extras","title":"Synchronizing Processes during Startup - Included Applications","doc":"The supervisor tree of an included application is started as part of the\nsupervisor tree of the including application. If there is a need for\nsynchronization between processes in the including and included applications,\nthis can be achieved by using _start phases_.\n\nStart phases are defined by the `start_phases` key in the `.app` file as a list\nof tuples `{Phase,PhaseArgs}`, where `Phase` is an atom and `PhaseArgs` is a\nterm.\n\nThe value of the `mod` key of the including application must be set to\n`{application_starter,[Module,StartArgs]}`, where `Module` as usual is the\napplication callback module. `StartArgs` is a term provided as argument to the\ncallback function `Module:start/2`:\n\n```erlang\n{application, prim_app,\n [{description, \"Tree application\"},\n {vsn, \"1\"},\n {modules, [prim_app_cb, prim_app_sup, prim_app_server]},\n {registered, [prim_app_server]},\n {included_applications, [incl_app]},\n {start_phases, [{init,[]}, {go,[]}]},\n {applications, [kernel, stdlib, sasl]},\n {mod, {application_starter,[prim_app_cb,[]]}},\n {env, [{file, \"/usr/local/log\"}]}\n ]}.\n\n{application, incl_app,\n [{description, \"Included application\"},\n {vsn, \"1\"},\n {modules, [incl_app_cb, incl_app_sup, incl_app_server]},\n {registered, []},\n {start_phases, [{go,[]}]},\n {applications, [kernel, stdlib, sasl]},\n {mod, {incl_app_cb,[]}}\n ]}.\n```\n\nWhen starting a primary application with included applications, the primary\napplication is started the normal way, that is:\n\n- The application controller creates an application master for the application\n- The application master calls `Module:start(normal, StartArgs)` to start the\n top supervisor.\n\nThen, for the primary application and each included application in top-down,\nleft-to-right order, the application master calls\n`Module:start_phase(Phase, Type, PhaseArgs)` for each phase defined for the\nprimary application, in that order. If a phase is not defined for an included\napplication, the function is not called for this phase and application.\n\nThe following requirements apply to the `.app` file for an included application:\n\n- The `{mod, {Module,StartArgs}}` option must be included. This option is used\n to find the callback module `Module` of the application. `StartArgs` is\n ignored, as `Module:start/2` is called only for the primary application.\n- If the included application itself contains included applications, instead the\n `{mod, {application_starter, [Module,StartArgs]}}` option must be included.\n- The `{start_phases, [{Phase,PhaseArgs}]}` option must be included, and the set\n of specified phases must be a subset of the set of phases specified for the\n primary application.\n\nWhen starting `prim_app` as defined above, the application controller calls the\nfollowing callback functions before `application:start(prim_app)` returns a\nvalue:\n\n```erlang\napplication:start(prim_app)\n => prim_app_cb:start(normal, [])\n => prim_app_cb:start_phase(init, normal, [])\n => prim_app_cb:start_phase(go, normal, [])\n => incl_app_cb:start_phase(go, normal, [])\nok\n```","ref":"included_applications.html#synchronizing-processes-during-startup"},{"type":"extras","title":"Distributed Applications","doc":"\n# Distributed Applications\n\n[](){: #distributed-appl }","ref":"distributed_applications.html"},{"type":"extras","title":"Introduction - Distributed Applications","doc":"In a distributed system with several Erlang nodes, it can be necessary to\ncontrol applications in a distributed manner. If the node, where a certain\napplication is running, goes down, the application is to be restarted at another\nnode.\n\nSuch an application is called a _distributed application_. Note that it is the\ncontrol of the application that is distributed. All applications can be\ndistributed in the sense that they, for example, use services on other nodes.\n\nSince a distributed application can move between nodes, some addressing\nmechanism is required to ensure that it can be addressed by other applications,\nregardless on which node it currently executes. This issue is not addressed\nhere, but the `m:global` or `m:pg` modules in Kernel can be used for this purpose.","ref":"distributed_applications.html#introduction"},{"type":"extras","title":"Specifying Distributed Applications - Distributed Applications","doc":"Distributed applications are controlled by both the application\ncontroller and a distributed application controller process called\n`dist_ac`. Both processes are part of the Kernel application.\nDistributed applications are thus specified by\nconfiguring the Kernel application, using the following configuration\nparameter (see also [Kernel](`e:kernel:kernel_app.md`)):\n\n`distributed = [{Application, [Timeout,] NodeDesc}]`\n\n- Specifies where the application `Application = atom()` can execute.\n- `NodeDesc = [Node | {Node,...,Node}]` is a list of node names in priority\n order. The order between nodes in a tuple is undefined.\n- `Timeout = integer()` specifies how many milliseconds to wait before\n restarting the application at another node. It defaults to 0.\n\nFor distribution of application control to work properly, the nodes where a\ndistributed application can run must contact each other and negotiate where to\nstart the application. This is done using the following configuration parameters\nin Kernel:\n\n- `sync_nodes_mandatory = [Node]` - Specifies which other nodes must be started\n (within the time-out specified by `sync_nodes_timeout`).\n- `sync_nodes_optional = [Node]` - Specifies which other nodes can be started\n (within the time-out specified by `sync_nodes_timeout`).\n- `sync_nodes_timeout = integer() | infinity` - Specifies how many milliseconds\n to wait for the other nodes to start.\n\nWhen started, the node waits for all nodes specified by `sync_nodes_mandatory`\nand `sync_nodes_optional` to come up. When all nodes are up, or when all\nmandatory nodes are up and the time specified by `sync_nodes_timeout` has\nelapsed, all applications start. If not all mandatory nodes are up, the node\nterminates.\n\n_Example:_\n\nAn application `myapp` is to run at the node `cp1@cave`. If this node goes down,\n`myapp` is to be restarted at `cp2@cave` or `cp3@cave`. A system configuration\nfile `cp1.config` for `cp1@cave` can look as follows:\n\n```erlang\n[{kernel,\n [{distributed, [{myapp, 5000, [cp1@cave, {cp2@cave, cp3@cave}]}]},\n {sync_nodes_mandatory, [cp2@cave, cp3@cave]},\n {sync_nodes_timeout, 5000}\n ]\n }\n].\n```\n\nThe system configuration files for `cp2@cave` and `cp3@cave` are identical,\nexcept for the list of mandatory nodes, which is to be `[cp1@cave, cp3@cave]`\nfor `cp2@cave` and `[cp1@cave, cp2@cave]` for `cp3@cave`.\n\n> #### Note {: .info }\n>\n> All involved nodes must have the same value for `distributed` and\n> `sync_nodes_timeout`. Otherwise the system behavior is undefined.","ref":"distributed_applications.html#specifying-distributed-applications"},{"type":"extras","title":"Starting and Stopping Distributed Applications - Distributed Applications","doc":"When all involved (mandatory) nodes have been started, the distributed\napplication can be started by calling `application:start(Application)` at _all\nof these nodes._\n\nA boot script (see [Releases](release_structure.md)) can be used that\nautomatically starts the application.\n\nThe application is started at the first operational node that is listed in the\nlist of nodes in the `distributed` configuration parameter. The application is\nstarted as usual. That is, an application master is created and calls the\napplication callback function:\n\n```erlang\nModule:start(normal, StartArgs)\n```\n\nExample:\n\nContinuing the example from the previous section, the three nodes are started,\nspecifying the system configuration file:\n\n```text\n> erl -sname cp1 -config cp1\n> erl -sname cp2 -config cp2\n> erl -sname cp3 -config cp3\n```\n\nWhen all nodes are operational, `myapp` can be started. This is achieved by\ncalling `application:start(myapp)` at all three nodes. It is then started at\n`cp1`, as shown in the following figure:\n\n[](){: #dist1 }\n\n![Application myapp - Situation 1](assets/dist1.gif \"Application myapp - Situation 1\")\n\nSimilarly, the application must be stopped by calling\n`application:stop(Application)` at all involved nodes.","ref":"distributed_applications.html#starting-and-stopping-distributed-applications"},{"type":"extras","title":"Failover - Distributed Applications","doc":"If the node where the application is running goes down, the application is\nrestarted (after the specified time-out) at the first operational node that is\nlisted in the list of nodes in the `distributed` configuration parameter. This\nis called a _failover_.\n\nThe application is started the normal way at the new node, that is, by the\napplication master calling:\n\n```erlang\nModule:start(normal, StartArgs)\n```\n\nAn exception is if the application has the `start_phases` key defined (see\n[Included Applications](included_applications.md)). The application is then\ninstead started by calling:\n\n```erlang\nModule:start({failover, Node}, StartArgs)\n```\n\nHere `Node` is the terminated node.\n\n_Example:_\n\nIf `cp1` goes down, the system checks which one of the other nodes, `cp2` or\n`cp3`, has the least number of running applications, but waits for 5 seconds for\n`cp1` to restart. If `cp1` does not restart and `cp2` runs fewer applications\nthan `cp3`, `myapp` is restarted on `cp2`.\n\n[](){: #dist2 }\n\n![Application myapp - Situation 2](assets/dist2.gif \"Application myapp - Situation 2\")\n\nSuppose now that `cp2` goes also down and does not restart within 5 seconds.\n`myapp` is now restarted on `cp3`.\n\n[](){: #dist3 }\n\n![Application myapp - Situation 3](assets/dist3.gif \"Application myapp - Situation 3\")","ref":"distributed_applications.html#failover"},{"type":"extras","title":"Takeover - Distributed Applications","doc":"If a node is started, which has higher priority according to `distributed` than\nthe node where a distributed application is running, the application is\nrestarted at the new node and stopped at the old node. This is called a\n_takeover_.\n\nThe application is started by the application master calling:\n\n```erlang\nModule:start({takeover, Node}, StartArgs)\n```\n\nHere `Node` is the old node.\n\n_Example:_\n\nIf `myapp` is running at `cp3`, and if `cp2` now restarts, it does not restart\n`myapp`, as the order between the `cp2` and `cp3` nodes is undefined.\n\n[](){: #dist4 }\n\n![Application myapp - Situation 4](assets/dist4.gif \"Application myapp - Situation 4\")\n\nHowever, if `cp1` also restarts, the function `application:takeover/2` moves\n`myapp` to `cp1`, as `cp1` has a higher priority than `cp3` for this\napplication. In this case, `Module:start({takeover, cp3@cave}, StartArgs)` is\nexecuted at `cp1` to start the application.\n\n[](){: #dist5 }\n\n![Application myapp - Situation 5](assets/dist5.gif \"Application myapp - Situation 5\")","ref":"distributed_applications.html#takeover"},{"type":"extras","title":"Releases","doc":"\n# Releases\n\n[](){: #releases-section }\n\nIt is recommended to read this section alongside\n[`rel`](`e:sasl:rel.md`), `m:systools`, and\n[`script`](`e:sasl:script.md`) in SASL.","ref":"release_structure.html"},{"type":"extras","title":"Release Concept - Releases","doc":"When you have written one or more applications, you might want to create a\ncomplete system with these applications and a subset of the Erlang/OTP\napplications. This is called a _release_.\n\nTo do this, create a [release resource file](release_structure.md#res_file) that\ndefines which applications are included in the release.\n\nThe release resource file is used to generate\n[boot scripts](release_structure.md#boot) and\n[release packages](release_structure.md#pack). A system that is transferred to\nand installed at another site is called a _target system_. How to use a release\npackage to create a target system is described in\n[Creating and Upgrading a Target System](`e:system:create_target.md`)\nin System Principles.\n\n[](){: #res_file }","ref":"release_structure.html#release-concept"},{"type":"extras","title":"Release Resource File - Releases","doc":"To define a release, create a _release resource file_, or in short a `.rel`\nfile. In the file, specify the name and version of the release, which ERTS\nversion it is based on, and which applications it consists of:\n\n```erlang\n{release, {Name,Vsn}, {erts, EVsn},\n [{Application1, AppVsn1},\n ...\n {ApplicationN, AppVsnN}]}.\n```\n\n`Name`, `Vsn`, `EVsn`, and `AppVsn` are strings.\n\nThe file must be named `Rel.rel`, where `Rel` is a unique name.\n\nEach `Application` (atom) and `AppVsn` is the name and version of an application\nincluded in the release. The minimal release based on Erlang/OTP consists of the\nKernel and STDLIB applications, so these applications must be included in the\nlist.\n\nIf the release is to be upgraded, it must also include the SASL application.\n\n[](){: #ch_rel }\n\nHere is an example showing the `.app` file for a release of `ch_app` from\nthe [Applications](applications.md#ch_app) section:\n\n```erlang\n{application, ch_app,\n [{description, \"Channel allocator\"},\n {vsn, \"1\"},\n {modules, [ch_app, ch_sup, ch3]},\n {registered, [ch3]},\n {applications, [kernel, stdlib, sasl]},\n {mod, {ch_app,[]}}\n ]}.\n```\n\nThe `.rel` file must also contain `kernel`, `stdlib`, and `sasl`, as these\napplications are required by `ch_app`. The file is called `ch_rel-1.rel`:\n\n```erlang\n{release,\n {\"ch_rel\", \"A\"},\n {erts, \"14.2.5\"},\n [{kernel, \"9.2.4\"},\n {stdlib, \"5.2.3\"},\n {sasl, \"4.2.1\"},\n {ch_app, \"1\"}]\n}.\n```\n\n[](){: #boot }","ref":"release_structure.html#release-resource-file"},{"type":"extras","title":"Generating Boot Scripts - Releases","doc":"`m:systools` in the SASL application includes tools to build and check\nreleases. The functions read the `.rel` and `.app` files and perform\nsyntax and dependency checks. The\n[`systools:make_script/1,2`](`systools:make_script/2`) function is\nused to generate a boot script:\n\n```text\n1> systools:make_script(\"ch_rel-1\", [local]).\nok\n```\n\nThis call creates both the human-readable boot script,\n`ch_rel-1.script`, and the binary boot script, `ch_rel-1.boot`, used\nby the runtime system.\n\n- `\"ch_rel-1\"` is the name of the `.rel` file, minus the extension.\n- `local` is an option that means that the directories where the applications\n are found are used in the boot script, instead of `$ROOT/lib` (`$ROOT` is the\n root directory of the installed release).\n\nThis is a useful way to test a generated boot script locally.\n\nWhen starting Erlang/OTP using the boot script, all applications from the `.rel`\nfile are automatically loaded and started:\n\n```text\n% erl -boot ch_rel-1\nErlang/OTP 26 [erts-14.2.5] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]\n\nEshell V14.2.5 (press Ctrl+G to abort, type help(). for help)\n1> application:which_applications().\n[{ch_app,\"Channel allocator\",\"1\"},\n {sasl,\"SASL CXC 138 11\",\"4.2.1\"},\n {stdlib,\"ERTS CXC 138 10\",\"5.2.3\"},\n {kernel,\"ERTS CXC 138 10\",\"9.2.4\"}]\n```\n\n[](){: #pack }","ref":"release_structure.html#generating-boot-scripts"},{"type":"extras","title":"Creating a Release Package - Releases","doc":"The [`systools:make_tar/1,2`](`systools:make_tar/2`) function takes a\n`.rel` file as input and creates a zipped tar file with the code for\nthe specified applications, a _release package_:\n\n```erlang\n1> systools:make_script(\"ch_rel-1\").\nok\n2> systools:make_tar(\"ch_rel-1\").\nok\n```\n\nThe release package by default contains:\n\n- The `.app` files\n- The `.rel` file\n- The object code for all applications, structured according to the\n [application directory structure](applications.md#app_dir)\n- The binary boot script renamed to `start.boot`\n\n```text\n% tar tf ch_rel-1.tar\nlib/kernel-9.2.4/ebin/kernel.app\nlib/kernel-9.2.4/ebin/application.beam\n...\nlib/stdlib-5.2.3/ebin/stdlib.app\nlib/stdlib-5.2.3/ebin/argparse.beam\n...\nlib/sasl-4.2.1/ebin/sasl.app\nlib/sasl-4.2.1/ebin/sasl.beam\n...\nlib/ch_app-1/ebin/ch_app.app\nlib/ch_app-1/ebin/ch_app.beam\nlib/ch_app-1/ebin/ch_sup.beam\nlib/ch_app-1/ebin/ch3.beam\nreleases/ch_rel-1.rel\nreleases/A/ch_rel-1.rel\nreleases/A/start.boot\n```\n\nA new boot script was generated, without the `local` option set, before the\nrelease package was made. In the release package, all application directories\nare placed under `lib`. You do not know where the release package will be\ninstalled, so no hard-coded absolute paths are allowed.\n\nThe release resource file `mysystem.rel` is duplicated in the tar file.\nOriginally, this file was only stored in the `releases` directory to make it\npossible for the `release_handler` to extract this file separately. After\nunpacking the tar file, `release_handler` would automatically copy the file to\n`releases/FIRST`. However, sometimes the tar file is unpacked without involving\nthe `release_handler` (for example, when unpacking the first target system) and\nthe file is therefore now instead duplicated in the tar file so no manual\ncopying is necessary.\n\nIf a `relup` file and/or a system configuration file called `sys.config`, or a\n`sys.config.src`, is found, these files are also included in the release\npackage. See [Release Handling](release_handling.md#req).\n\nOptions can be set to make the release package include source code and the ERTS\nbinary as well.\n\nFor information on how to install the first target system, using a release\npackage, see System Principles. For information on how to install a new release\npackage in an existing system, see [Release Handling](release_handling.md).\n\n[](){: #reldir }","ref":"release_structure.html#creating-a-release-package"},{"type":"extras","title":"Directory Structure - Releases","doc":"The directory structure for the code installed by the release handler from a\nrelease package is as follows:\n\n```text\n$ROOT/lib/App1-AVsn1/ebin\n /priv\n /App2-AVsn2/ebin\n /priv\n ...\n /AppN-AVsnN/ebin\n /priv\n /erts-EVsn/bin\n /releases/Vsn\n /bin\n```\n\n- `lib` \\- Application directories\n- `erts-EVsn/bin` \\- Erlang runtime system executables\n- `releases/Vsn` \\- `.rel` file and boot script `start.boot`; if present in the\n release package, `relup` and/or `sys.config` or `sys.config.src`\n- `bin` \\- Top-level Erlang runtime system executables\n\nApplications are not required to be located under directory `$ROOT/lib`. Several\ninstallation directories, which contain different parts of a system, can thus\nexist. For example, the previous example can be extended as follows:\n\n```text\n$SECOND_ROOT/.../SApp1-SAVsn1/ebin\n /priv\n /SApp2-SAVsn2/ebin\n /priv\n ...\n /SAppN-SAVsnN/ebin\n /priv\n\n$THIRD_ROOT/TApp1-TAVsn1/ebin\n /priv\n /TApp2-TAVsn2/ebin\n /priv\n ...\n /TAppN-TAVsnN/ebin\n /priv\n```\n\n`$SECOND_ROOT` and `$THIRD_ROOT` are introduced as `variables` in the call to\nthe `systools:make_script/2` function.","ref":"release_structure.html#directory-structure"},{"type":"extras","title":"Disk-Less and/or Read-Only Clients - Releases","doc":"If a complete system consists of disk-less and/or read-only client nodes, a\n`clients` directory is to be added to the `$ROOT` directory. A read-only node is\na node with a read-only file system.\n\nThe `clients` directory is to have one subdirectory per supported client node.\nThe name of each client directory is to be the name of the corresponding client\nnode. As a minimum, each client directory is to contain the `bin` and `releases`\nsubdirectories. These directories are used to store information about installed\nreleases and to appoint the current release to the client. The `$ROOT` directory\nthus contains the following:\n\n```text\n$ROOT/...\n /clients/ClientName1/bin\n /releases/Vsn\n /ClientName2/bin\n /releases/Vsn\n ...\n /ClientNameN/bin\n /releases/Vsn\n```\n\nThis structure is to be used if all clients are running the same type of Erlang\nmachine. If there are clients running different types of Erlang machines, or on\ndifferent operating systems, the `clients` directory can be divided into one\nsubdirectory per type of Erlang machine. Alternatively, one `$ROOT` can be set\nup per type of machine. For each type, some of the directories specified for the\n`$ROOT` directory are to be included:\n\n```text\n$ROOT/...\n /clients/Type1/lib\n /erts-EVsn\n /bin\n /ClientName1/bin\n /releases/Vsn\n /ClientName2/bin\n /releases/Vsn\n ...\n /ClientNameN/bin\n /releases/Vsn\n ...\n /TypeN/lib\n /erts-EVsn\n /bin\n ...\n```\n\nWith this structure, the root directory for clients of `Type1` is\n`$ROOT/clients/Type1`.","ref":"release_structure.html#disk-less-and-or-read-only-clients"},{"type":"extras","title":"Release Handling","doc":"\n# Release Handling\n\n[](){: #release-handling }","ref":"release_handling.html"},{"type":"extras","title":"Release Handling Principles - Release Handling","doc":"An important feature of the Erlang programming language is the ability to change\nmodule code at runtime, _code replacement_, as described in\n[Code Replacement](code_loading.md#code-replacement) in the Erlang Reference\nManual.\n\nBased on this feature, the OTP application SASL provides a framework for\nupgrading and downgrading between different versions of an entire release in\nruntime. This is called _release handling_.\n\nThe framework consists of:\n\n- Offline support - `systools` for generating scripts and building release\n packages\n- Online support - `release_handler` for unpacking and installing release\n packages\n\nThe minimal system based on Erlang/OTP, enabling release handling, thus consists\nof the Kernel, STDLIB, and SASL applications.","ref":"release_handling.html#release-handling-principles"},{"type":"extras","title":"Release Handling Workflow - Release Handling","doc":"_Step 1_) A release is created as described in [Releases](release_structure.md).\n\n_Step 2_) The release is transferred to and installed at target environment. For\ninformation of how to install the first target system, see\n[System Principles](`e:system:create_target.md`).\n\n_Step 3_) Modifications, for example, error corrections, are made to the code in\nthe development environment.\n\n_Step 4_) At some point, it is time to make a new version of release. The\nrelevant `.app` files are updated and a new `.rel` file is written.\n\n_Step 5_) For each modified application, an\n[application upgrade file](release_handling.md#appup), `.appup`, is created. In\nthis file, it is described how to upgrade and/or downgrade between the old and\nnew version of the application.\n\n_Step 6_) Based on the `.appup` files, a\n[release upgrade file](release_handling.md#relup) called `relup`, is created.\nThis file describes how to upgrade and/or downgrade between the old and new\nversion of the entire release.\n\n_Step 7_) A new release package is made and transferred to the target system.\n\n_Step 8_) The new release package is unpacked using the release handler.\n\n_Step 9_) The new version of the release is installed, also using the release\nhandler. This is done by evaluating the instructions in `relup`. Modules can be\nadded, deleted, or reloaded, applications can be started, stopped, or restarted,\nand so on. In some cases, it is even necessary to restart the runtime system.\n\n- If the installation fails, the system can be rebooted. The old release version\n is then automatically used.\n- If the installation succeeds, the new version is made the default version,\n which is to now be used if there is a system reboot.","ref":"release_handling.html#release-handling-workflow"},{"type":"extras","title":"Release Handling Aspects - Release Handling","doc":"[Appup Cookbook](appup_cookbook.md), contains examples of `.appup` files for\ntypical cases of upgrades/downgrades that are normally easy to handle in\nruntime. However, many aspects can make release handling complicated, for\nexample:\n\n- Complicated or circular dependencies can make it difficult or even impossible\n to decide in which order things must be done without risking runtime errors\n during an upgrade or downgrade. Dependencies can be:\n\n - Between nodes\n - Between processes\n - Between modules\n\n- During release handling, non-affected processes continue normal execution.\n This can lead to time-outs or other problems. For example, new processes\n created in the time window between suspending processes using a certain\n module, and loading a new version of this module, can execute old code.\n\nIt is thus recommended that code is changed in as small steps as possible, and\nalways kept backwards compatible.\n\n[](){: #req }","ref":"release_handling.html#release-handling-aspects"},{"type":"extras","title":"Requirements - Release Handling","doc":"For release handling to work properly, the runtime system must have knowledge\nabout which release it is running. It must also be able to change (in runtime)\nwhich boot script and system configuration file to use if the system is\nrebooted, for example, by `heart` after a failure. Thus, Erlang must be started\nas an embedded system; for information on how to do this, see Embedded System.\n\nFor system reboots to work properly, it is also required that the system is\nstarted with heartbeat monitoring; see [`erl`](`e:erts:erl_cmd.md`)\nin ERTS and module `m:heart` in Kernel.\n\nOther requirements:\n\n- The boot script included in a release package must be generated from the same\n `.rel` file as the release package itself.\n\n Information about applications is fetched from the script when an upgrade or\n downgrade is performed.\n\n- The system must be configured using only one system configuration file, called\n `sys.config`.\n\n If found, this file is automatically included when a release package is\n created.\n\n- All versions of a release, except the first one, must contain a `relup` file.\n\n If found, this file is automatically included when a release package is\n created.","ref":"release_handling.html#requirements"},{"type":"extras","title":"Distributed Systems - Release Handling","doc":"If the system consists of several Erlang nodes, each node can use its own\nversion of the release. The release handler is a locally registered process and\nmust be called at each node where an upgrade or downgrade is required. A release\nhandling instruction, `sync_nodes`, can be used to synchronize the release\nhandler processes at a number of nodes; see [`appup`](`e:sasl:appup`) in SASL.\n\n[](){: #instr }","ref":"release_handling.html#distributed-systems"},{"type":"extras","title":"Release Handling Instructions - Release Handling","doc":"OTP supports a set of _release handling instructions_ that are used when\ncreating `.appup` files. The release handler understands a subset of these, the\n_low-level_ instructions. To make it easier for the user, there are also a\nnumber of _high-level_ instructions, which are translated to low-level\ninstructions by `systools:make_relup`.\n\nSome of the most frequently used instructions are described in this section. The\ncomplete list of instructions is included in [`appup`](`e:sasl:appup`) in SASL.\n\nFirst, some definitions:\n\n- _Residence module_ - The module where a process has its tail-recursive loop\n function(s). If these functions are implemented in several modules, all those\n modules are residence modules for the process.\n- _Functional module_ - A module that is not a residence module for any\n process.\n\nFor a process implemented using an OTP behaviour, the behaviour module is the\nresidence module for that process. The callback module is a functional module.","ref":"release_handling.html#release-handling-instructions"},{"type":"extras","title":"load_module - Release Handling","doc":"If a simple extension has been made to a functional module, it is sufficient to\nload the new version of the module into the system, and remove the old version.\nThis is called _simple code replacement_ and for this the following instruction\nis used:\n\n```text\n{load_module, Module}\n```","ref":"release_handling.html#load_module"},{"type":"extras","title":"update - Release Handling","doc":"If a more complex change has been made, for example, a change to the format of\nthe internal state of a `m:gen_server`, simple code replacement is not sufficient.\nInstead, it is necessary to:\n\n- Suspend the processes using the module (to avoid that they try to handle any\n requests before the code replacement is completed).\n- Ask them to transform the internal state format and switch to the new version\n of the module.\n- Remove the old version.\n- Resume the processes.\n\nThis is called _synchronized code replacement_ and for this the following\ninstructions are used:\n\n```erlang\n{update, Module, {advanced, Extra}}\n{update, Module, supervisor}\n```\n\n`update` with argument `{advanced,Extra}` is used when changing the internal\nstate of a behaviour as described above. It causes behaviour processes to call\nthe callback function `code_change/3`, passing the term `Extra` and some other\ninformation as arguments. See the manual pages for the respective behaviours and\n[Appup Cookbook](appup_cookbook.md#int_state).\n\n`update` with argument `supervisor` is used when changing the start\nspecification of a supervisor. See [Appup Cookbook](appup_cookbook.md#sup).\n\nWhen a module is to be updated, the release handler finds which processes that\nare _using_ the module by traversing the supervision tree of each running\napplication and checking all the child specifications:\n\n```erlang\n{Id, StartFunc, Restart, Shutdown, Type, Modules}\n```\n\nA process uses a module if the name is listed in `Modules` in the child\nspecification for the process.\n\nIf `Modules=dynamic`, which is the case for event managers, the event manager\nprocess informs the release handler about the list of currently installed event\nhandlers (`gen_event`), and it is checked if the module name is in this list\ninstead.\n\nThe release handler suspends, asks for code change, and resumes processes by\ncalling the functions `sys:suspend/1,2`, `sys:change_code/4,5`, and\n`sys:resume/1,2`, respectively.","ref":"release_handling.html#update"},{"type":"extras","title":"add_module and delete_module - Release Handling","doc":"If a new module is introduced, the following instruction is used:\n\n```erlang\n{add_module, Module}\n```\n\nThis instruction loads module `Module`. When running Erlang in\nembedded mode it is necessary to use this this instruction. It is not\nstrictly required when running Erlang in interactive mode, since the\ncode server automatically searches for and loads unloaded modules.\n\nThe opposite of `add_module` is `delete_module`, which unloads a module:\n\n```erlang\n{delete_module, Module}\n```\n\nAny process, in any application, with `Module` as residence module, is\nkilled when the instruction is evaluated. Therefore, the user must\nensure that all such processes are terminated before deleting module\n`Module` to avoid a situation with failing supervisor restarts.","ref":"release_handling.html#add_module-and-delete_module"},{"type":"extras","title":"Application Instructions - Release Handling","doc":"The following is the instruction for adding an application:\n\n```text\n{add_application, Application}\n```\n\nAdding an application means that the modules defined by the `modules` key in the\n`.app` file are loaded using a number of `add_module` instructions, and then the\napplication is started.\n\nThe following is the instruction for removing an application:\n\n```text\n{remove_application, Application}\n```\n\nRemoving an application means that the application is stopped, the modules are\nunloaded using a number of `delete_module` instructions, and then the\napplication specification is unloaded from the application controller.\n\nThe following is the instruction for restarting an application:\n\n```text\n{restart_application, Application}\n```\n\nRestarting an application means that the application is stopped and then started\nagain similar to using the instructions `remove_application` and\n`add_application` in sequence.","ref":"release_handling.html#application-instructions"},{"type":"extras","title":"apply (Low-Level) - Release Handling","doc":"To call an arbitrary function from the release handler, the following\ninstruction is used:\n\n```text\n{apply, {M, F, A}}\n```\n\nThe release handler evaluates [`apply(M, F, A)`](`apply/3`).\n\n[](){: #restart_new_emulator_instr }","ref":"release_handling.html#apply-low-level"},{"type":"extras","title":"restart_new_emulator (Low-Level) - Release Handling","doc":"This instruction is used when changing to a new version of the runtime\nsystem, or when any of the core applications Kernel, STDLIB, or SASL\nis upgraded. If a system reboot is needed for another reason, the\n`restart_emulator` instruction is to be used instead.\n\nThis instruction requires that the system is started with heartbeat monitoring;\nsee [`erl`](`e:erts:erl_cmd.md`) in ERTS and module `m:heart` in Kernel.\n\nThe `restart_new_emulator` instruction must always be the first instruction in a\nrelup. If the relup is generated by\n[`systools:make_relup/3,4`](`systools:make_relup/4`),\nthis condition is automatically met.\n\nWhen the release handler encounters this instruction, it first generates a\ntemporary boot file that starts the new versions of the runtime system and the\ncore applications, and the old version of all other applications. Then it shuts\ndown the current instance of the runtime system by calling `init:reboot/0`.\nAll processes are terminated gracefully and the system is rebooted by\nthe `heart` program, using the temporary boot file. After the reboot, the rest\nof the relup instructions are executed. This is done as a part of the temporary\nboot script.\n\n> #### Warning {: .warning }\n>\n> This mechanism causes the new versions of the runtime system and core\n> applications to run with the old version of other applications during startup.\n> Thus, take extra care to avoid incompatibility. Incompatible changes in the\n> core applications can in some situations be necessary. If possible, such changes\n> are preceded by deprecation over two major releases before the actual change.\n> To ensure the application is not crashed by an incompatible change, always\n> remove any call to deprecated functions as soon as possible.\n\nAn info report is written when the upgrade is completed. To programmatically\nfind out if the upgrade is complete, call\n[`release_handler:which_releases(current)`](`release_handler:which_releases/1`)\nand check whether it returns the expected (that is, the new) release.\n\nThe new release version must be made permanent when the new runtime system is\noperational. Otherwise, the old version will be used if there is a new system\nreboot.\n\nOn UNIX, the release handler tells the `heart` program which command to use to\nreboot the system. The environment variable `HEART_COMMAND`, normally used by\nthe `heart` program, is ignored in this case. The command instead defaults to\n`$ROOT/bin/start`. Another command can be set by using the SASL configuration\nparameter `start_prg`. For more information, see [SASL](`e:sasl:sasl_app.md`).\n\n[](){: #restart_emulator_instr }","ref":"release_handling.html#restart_new_emulator-low-level"},{"type":"extras","title":"restart_emulator (Low-Level) - Release Handling","doc":"This instruction is not related to upgrades of ERTS or any of the core\napplications. It can be used by any application to force a restart of the\nruntime system after all upgrade instructions are executed.\n\nA relup script can only contain one `restart_emulator` instruction, and it must\nalways be placed at the end. If the relup is generated by\n[`systools:make_relup/3,4`](`systools:make_relup/4`),\nthis condition is automatically met.\n\nWhen the release handler encounters this instruction, it shuts down\nthe runtime system by calling `init:reboot/0`. All processes are terminated\ngracefully and the system can then be rebooted by the `heart` program\nusing the new release version. No more upgrade instruction is executed\nafter the restart.\n\n[](){: #appup }","ref":"release_handling.html#restart_emulator-low-level"},{"type":"extras","title":"Application Upgrade File - Release Handling","doc":"To define how to upgrade/downgrade between the current version and previous\nversions of an application, an _application upgrade file_, or in short\n`.appup` file is created. The file is to be called `Application.appup`, where\n`Application` is the application name:\n\n```c\n{Vsn,\n [{UpFromVsn1, InstructionsU1},\n ...,\n {UpFromVsnK, InstructionsUK}],\n [{DownToVsn1, InstructionsD1},\n ...,\n {DownToVsnK, InstructionsDK}]}.\n```\n\n- `Vsn`, a string, is the current version of the application, as defined in the\n `.app` file.\n- Each `UpFromVsn` is a previous version of the application to upgrade from.\n- Each `DownToVsn` is a previous version of the application to downgrade to.\n- Each `Instructions` is a list of release handling instructions.\n\n`UpFromVsn` and `DownToVsn` can also be specified as regular expressions. For\nmore information about the syntax and contents of the `.appup` file, see\n[`appup`](`e:sasl:appup.md`) in SASL.\n\n[Appup Cookbook](appup_cookbook.md) includes examples of `.appup` files for\ntypical upgrade/downgrade cases.\n\n_Example:_ Consider the release `ch_rel-1` from\n[Releases](release_structure.md#ch_rel). Assume you want to add a function\n`available/0` to server `ch3`, which returns the number of available channels\n(when trying out the example, make the change in a copy of the original\ndirectory, to ensure that the first version is still available):\n\n```erlang\n-module(ch3).\n-behaviour(gen_server).\n\n-export([start_link/0]).\n-export([alloc/0, free/1]).\n-export([available/0]).\n-export([init/1, handle_call/3, handle_cast/2]).\n\nstart_link() ->\n gen_server:start_link({local, ch3}, ch3, [], []).\n\nalloc() ->\n gen_server:call(ch3, alloc).\n\nfree(Ch) ->\n gen_server:cast(ch3, {free, Ch}).\n\navailable() ->\n gen_server:call(ch3, available).\n\ninit(_Args) ->\n {ok, channels()}.\n\nhandle_call(alloc, _From, Chs) ->\n {Ch, Chs2} = alloc(Chs),\n {reply, Ch, Chs2};\nhandle_call(available, _From, Chs) ->\n N = available(Chs),\n {reply, N, Chs}.\n\nhandle_cast({free, Ch}, Chs) ->\n Chs2 = free(Ch, Chs),\n {noreply, Chs2}.\n```\n\nA new version of the `ch_app.app` file must now be created, where the version is\nupdated:\n\n```erlang\n{application, ch_app,\n [{description, \"Channel allocator\"},\n {vsn, \"2\"},\n {modules, [ch_app, ch_sup, ch3]},\n {registered, [ch3]},\n {applications, [kernel, stdlib, sasl]},\n {mod, {ch_app,[]}}\n ]}.\n```\n\nTo upgrade `ch_app` from `\"1\"` to `\"2\"` (and to downgrade from `\"2\"` to `\"1\"`),\nyou only need to load the new (old) version of the `ch3` callback module. Create\nthe application upgrade file `ch_app.appup` in the `ebin` directory:\n\n```erlang\n{\"2\",\n [{\"1\", [{load_module, ch3}]}],\n [{\"1\", [{load_module, ch3}]}]\n}.\n```\n\n[](){: #relup }","ref":"release_handling.html#application-upgrade-file"},{"type":"extras","title":"Release Upgrade File - Release Handling","doc":"To define how to upgrade/downgrade between the new version and previous versions\nof a release, a _release upgrade file_, or in short `.relup` file, is to be\ncreated.\n\nThis file does not need to be created manually. It can be generated by\n[`systools:make_relup/3,4`](`systools:make_relup/4`).\nThe relevant versions of the `.rel` file, `.app`\nfiles, and `.appup` files are used as input. It is deduced which applications\nare to be added and deleted, and which applications that must be upgraded and/or\ndowngraded. The instructions for this are fetched from the `.appup` files and\ntransformed into a single list of low-level instructions in the right order.\n\nIf the `relup` file is relatively simple, it can be created manually. It is only\nto contain low-level instructions.\n\nFor details about the syntax and contents of the release upgrade file, see\n[`relup`](`e:sasl:relup.md`) in SASL.\n\n_Example, continued from the previous section:_ You have a new version \"2\" of\n`ch_app` and an `.appup` file. A new version of the `.rel` file is also needed.\nThis time the file is called `ch_rel-2.rel` and the release version string is\nchanged from \"A\" to \"B\":\n\n```erlang\n{release,\n {\"ch_rel\", \"B\"},\n {erts, \"14.2.5\"},\n [{kernel, \"9.2.4\"},\n {stdlib, \"5.2.3\"},\n {sasl, \"4.2.1\"},\n {ch_app, \"2\"}]\n}.\n```\n\nNow the `relup` file can be generated:\n\n```text\n1> systools:make_relup(\"ch_rel-2\", [\"ch_rel-1\"], [\"ch_rel-1\"]).\nok\n```\n\nThis generates a `relup` file with instructions for how to upgrade from version\n\"A\" (\"ch_rel-1\") to version \"B\" (\"ch_rel-2\") and how to downgrade from version\n\"B\" to version \"A\".\n\nBoth the old and new versions of the `.app` and `.rel` files must be in the code\npath, as well as the `.appup` and (new) `.beam` files. The code path can be\nextended by using the option `path`:\n\n```text\n1> systools:make_relup(\"ch_rel-2\", [\"ch_rel-1\"], [\"ch_rel-1\"],\n[{path,[\"../ch_rel-1\",\n\"../ch_rel-1/lib/ch_app-1/ebin\"]}]).\nok\n```\n\n[](){: #rel_handler }","ref":"release_handling.html#release-upgrade-file"},{"type":"extras","title":"Installing a Release - Release Handling","doc":"When you have made a new version of a release, a release package can be created\nwith this new version and transferred to the target environment.\n\nTo install the new version of the release in runtime, the _release\nhandler_ is used. This is a process belonging to the SASL application,\nwhich handles unpacking, installation, and removal of release\npackages. The `m:release_handler` module communicates with this process.\n\nAssuming there is an operational target system with installation root directory\n`$ROOT`, the release package with the new version of the release is to be copied\nto `$ROOT/releases`.\n\nFirst, _unpack_ the release package. The files are then extracted from the\npackage:\n\n```erlang\nrelease_handler:unpack_release(ReleaseName) => {ok, Vsn}\n```\n\n- `ReleaseName` is the name of the release package except the `.tar.gz`\n extension.\n- `Vsn` is the version of the unpacked release, as defined in its `.rel` file.\n\nA directory `$ROOT/lib/releases/Vsn` is created, where the `.rel` file, the boot\nscript `start.boot`, the system configuration file `sys.config`, and `relup` are\nplaced. For applications with new version numbers, the application directories\nare placed under `$ROOT/lib`. Unchanged applications are not affected.\n\nAn unpacked release can be _installed_. The release handler then evaluates the\ninstructions in `relup`, step by step:\n\n```erlang\nrelease_handler:install_release(Vsn) => {ok, FromVsn, []}\n```\n\nIf an error occurs during the installation, the system is rebooted using the old\nversion of the release. If installation succeeds, the system is afterwards using\nthe new version of the release, but if anything happens and the system is\nrebooted, it starts using the previous version again.\n\nTo be made the default version, the newly installed release must be made\n_permanent_, which means the previous version becomes _old_:\n\n```text\nrelease_handler:make_permanent(Vsn) => ok\n```\n\nThe system keeps information about which versions are old and permanent in the\nfiles `$ROOT/releases/RELEASES` and `$ROOT/releases/start_erl.data`.\n\nTo downgrade from `Vsn` to `FromVsn`, `install_release` must be called again:\n\n```erlang\nrelease_handler:install_release(FromVsn) => {ok, Vsn, []}\n```\n\nAn installed, but not permanent, release can be _removed_. Information about the\nrelease is then deleted from `$ROOT/releases/RELEASES` and the release-specific\ncode, that is, the new application directories and the `$ROOT/releases/Vsn`\ndirectory, are removed.\n\n```text\nrelease_handler:remove_release(Vsn) => ok\n```","ref":"release_handling.html#installing-a-release"},{"type":"extras","title":"Example (continued from the previous sections) - Release Handling","doc":"_Step 1)_ Create a target system as described in System Principles of the first\nversion `\"A\"` of `ch_rel` from [Releases](release_structure.md#ch_rel). This\ntime `sys.config` must be included in the release package. If no configuration\nis needed, the file is to contain the empty list:\n\n```text\n[].\n```\n\n_Step 2)_ Start the system as a simple target system. In reality, it is to be\nstarted as an embedded system. However, using `erl` with the correct boot script\nand config file is enough for illustration purposes:\n\n```text\n% cd $ROOT\n% bin/erl -boot $ROOT/releases/A/start -config $ROOT/releases/A/sys\n...\n```\n\n`$ROOT` is the installation directory of the target system.\n\n_Step 3)_ In another Erlang shell, generate start scripts and create a release\npackage for the new version `\"B\"`. Remember to include (a possible updated)\n`sys.config` and the `relup` file. For more information, see\n[Release Upgrade File](release_handling.md#relup).\n\n```erlang\n1> systools:make_script(\"ch_rel-2\").\nok\n2> systools:make_tar(\"ch_rel-2\").\nok\n```\n\nThe new release package now also contains version \"2\" of `ch_app` and the\n`relup` file:\n\n```text\n% tar tf ch_rel-2.tar\nlib/kernel-9.2.4/ebin/kernel.app\nlib/kernel-9.2.4/ebin/application.beam\n...\nlib/stdlib-5.2.3/ebin/stdlib.app\nlib/stdlib-5.2.3/ebin/argparse.beam\n...\nlib/sasl-4.2.1/ebin/sasl.app\nlib/sasl-4.2.1/ebin/sasl.beam\n...\nlib/ch_app-2/ebin/ch_app.app\nlib/ch_app-2/ebin/ch_app.beam\nlib/ch_app-2/ebin/ch_sup.beam\nlib/ch_app-2/ebin/ch3.beam\nreleases/B/start.boot\nreleases/B/relup\nreleases/B/sys.config\nreleases/B/ch_rel-2.rel\nreleases/ch_rel-2.rel\n```\n\n_Step 4)_ Copy the release package `ch_rel-2.tar.gz` to the `$ROOT/releases`\ndirectory.\n\n_Step 5)_ In the running target system, unpack the release package:\n\n```erlang\n1> release_handler:unpack_release(\"ch_rel-2\").\n{ok,\"B\"}\n```\n\nThe new application version `ch_app-2` is installed under `$ROOT/lib` next to\n`ch_app-1`. The `kernel`, `stdlib`, and `sasl` directories are not affected, as\nthey have not changed.\n\nUnder `$ROOT/releases`, a new directory `B` is created, containing\n`ch_rel-2.rel`, `start.boot`, `sys.config`, and `relup`.\n\n_Step 6)_ Check if the function `ch3:available/0` is available:\n\n```erlang\n2> ch3:available().\n** exception error: undefined function ch3:available/0\n```\n\n_Step 7)_ Install the new release. The instructions in `$ROOT/releases/B/relup`\nare executed one by one, resulting in the new version of `ch3` being loaded. The\nfunction `ch3:available/0` is now available:\n\n```erlang\n3> release_handler:install_release(\"B\").\n{ok,\"A\",[]}\n4> ch3:available().\n3\n5> code:which(ch3).\n\".../lib/ch_app-2/ebin/ch3.beam\"\n6> code:which(ch_sup).\n\".../lib/ch_app-1/ebin/ch_sup.beam\"\n```\n\nProcesses in `ch_app` for which code have not been updated, for example, the\nsupervisor, are still evaluating code from `ch_app-1`.\n\n_Step 8)_ If the target system is now rebooted, it uses version \"A\" again. The\n\"B\" version must be made permanent, to be used when the system is rebooted.\n\n```erlang\n7> release_handler:make_permanent(\"B\").\nok\n```\n\n[](){: #sys }","ref":"release_handling.html#example-continued-from-the-previous-sections"},{"type":"extras","title":"Updating Application Specifications - Release Handling","doc":"When a new version of a release is installed, the application specifications are\nautomatically updated for all loaded applications.\n\n> #### Note {: .info }\n>\n> The information about the new application specifications is fetched from the\n> boot script included in the release package. Thus, it is important that the\n> boot script is generated from the same `.rel` file as is used to build the\n> release package itself.\n\nSpecifically, the application configuration parameters are automatically updated\naccording to (in increasing priority order):\n\n- The data in the boot script, fetched from the new application resource file\n `App.app`\n- The new `sys.config`\n- Command-line arguments `-App Par Val`\n\nThis means that parameter values set in the other system configuration files and\nvalues set using `application:set_env/3` are disregarded.\n\nWhen an installed release is made permanent, the system process `init` is set to\npoint out the new `sys.config`.\n\nAfter the installation, the application controller compares the old and new\nconfiguration parameters for all running applications and call the callback\nfunction:\n\n```erlang\nModule:config_change(Changed, New, Removed)\n```\n\n- `Module` is the application callback module as defined by the `mod` key in the\n `.app` file.\n- `Changed` and `New` are lists of `{Par,Val}` for all changed and added\n configuration parameters, respectively.\n- `Removed` is a list of all parameters `Par` that have been removed.\n\nThe function is optional and can be omitted when implementing an application\ncallback module.","ref":"release_handling.html#updating-application-specifications"},{"type":"extras","title":"Appup Cookbook","doc":"\n# Appup Cookbook\n\n[](){: #appup-cookbook }\n\nThis section includes examples of `.appup` files for typical cases of\nupgrades/downgrades done in runtime.","ref":"appup_cookbook.html"},{"type":"extras","title":"Changing a Functional Module - Appup Cookbook","doc":"When a functional module has been changed, for example, if a new function has\nbeen added or a bug has been corrected, simple code replacement is sufficient,\nfor example:\n\n```erlang\n{\"2\",\n [{\"1\", [{load_module, m}]}],\n [{\"1\", [{load_module, m}]}]\n}.\n```","ref":"appup_cookbook.html#changing-a-functional-module"},{"type":"extras","title":"Changing a Residence Module - Appup Cookbook","doc":"In a system implemented according to the OTP design principles, all processes,\nexcept system processes and special processes, reside in one of the behaviours\n`m:supervisor`, `m:gen_server`, `m:gen_statem`, `m:gen_event`, or `m:gen_fsm`.\nThese belong to the STDLIB application and upgrading/downgrading normally\nrequires a runtime system restart.\n\nThus, OTP provides no support for changing residence modules except in the case\nof [special processes](appup_cookbook.md#spec).","ref":"appup_cookbook.html#changing-a-residence-module"},{"type":"extras","title":"Changing a Callback Module - Appup Cookbook","doc":"A callback module is a functional module, and for code extensions simple code\nreplacement is sufficient.\n\n_Example_\n\nWhen adding a function to `ch3`, as described in the example in\n[Release Handling](release_handling.md#appup), `ch_app.appup` looks as follows:\n\n```erlang\n{\"2\",\n [{\"1\", [{load_module, ch3}]}],\n [{\"1\", [{load_module, ch3}]}]\n}.\n```\n\nOTP also supports changing the internal state of behaviour processes; see\n[Changing Internal State](appup_cookbook.md#int_state).\n\n[](){: #int_state }","ref":"appup_cookbook.html#changing-a-callback-module"},{"type":"extras","title":"Changing Internal State - Appup Cookbook","doc":"In this case, simple code replacement is not sufficient. The process must\nexplicitly transform its state using the callback function `code_change/3` before\nswitching to the new version of the callback module. Thus, synchronized code\nreplacement is used.\n\n_Example_\n\nConsider the `ch3` module from\n[gen_server Behaviour](gen_server_concepts.md#ex). The internal state is a term\n`Chs` representing the available channels. Assume you want to add a counter `N`,\nwhich keeps track of the number of `alloc` requests so far. This means that the\nformat must be changed to `{Chs,N}`.\n\nThe `.appup` file can look as follows:\n\n```erlang\n{\"2\",\n [{\"1\", [{update, ch3, {advanced, []}}]}],\n [{\"1\", [{update, ch3, {advanced, []}}]}]\n}.\n```\n\nThe third element of the `update` instruction is a tuple `{advanced,Extra}`,\nwhich says that the affected processes are to do a state transformation before\nloading the new version of the module. This is done by the processes calling the\ncallback function `code_change/3` (see `m:gen_server` in STDLIB).\nThe term `Extra`, in this case `[]`, is passed as is to the function:\n\n[](){: #code_change }\n\n```erlang\n-module(ch3).\n...\n-export([code_change/3]).\n...\ncode_change({down, _Vsn}, {Chs, N}, _Extra) ->\n {ok, Chs};\ncode_change(_Vsn, Chs, _Extra) ->\n {ok, {Chs, 0}}.\n```\n\nThe first argument is `{down,Vsn}` if there is a downgrade, or `Vsn` if there is\na upgrade. The term `Vsn` is fetched from the 'original' version of the module,\nthat is, the version you are upgrading from, or downgrading to.\n\nThe version is defined by the module attribute `vsn`, if any. There is no such\nattribute in `ch3`, so in this case the version is the checksum (a huge integer)\nof the beam file, an uninteresting value, which is ignored.\n\nThe other callback functions of `ch3` must also be modified and perhaps a new\ninterface function must be added, but this is not shown here.","ref":"appup_cookbook.html#changing-internal-state"},{"type":"extras","title":"Module Dependencies - Appup Cookbook","doc":"Assume that a module is extended by adding an interface function, as in the\nexample in [Release Handling](release_handling.md#appup), where a function\n`available/0` is added to `ch3`.\n\nIf a call is added to this function, say in module `m1`, a runtime error could\ncan occur during release upgrade if the new version of `m1` is loaded first and\ncalls `ch3:available/0` before the new version of `ch3` is loaded.\n\nThus, `ch3` must be loaded before `m1`, in the upgrade case, and conversely in\nthe downgrade case. `m1` is said to be _dependent on_ `ch3`. In a release\nhandling instruction, this is expressed by the `DepMods` element:\n\n```erlang\n{load_module, Module, DepMods}\n{update, Module, {advanced, Extra}, DepMods}\n```\n\n`DepMods` is a list of modules, on which `Module` is dependent.\n\n_Example_\n\nThe module `m1` in application `myapp` is dependent on `ch3` when\nupgrading from \"1\" to \"2\", or downgrading from \"2\" to \"1\":\n\n```erlang\nmyapp.appup:\n\n{\"2\",\n [{\"1\", [{load_module, m1, [ch3]}]}],\n [{\"1\", [{load_module, m1, [ch3]}]}]\n}.\n\nch_app.appup:\n\n{\"2\",\n [{\"1\", [{load_module, ch3}]}],\n [{\"1\", [{load_module, ch3}]}]\n}.\n```\n\nIf instead `m1` and `ch3` belong to the same application, the `.appup` file can\nlook as follows:\n\n```erlang\n{\"2\",\n [{\"1\",\n [{load_module, ch3},\n {load_module, m1, [ch3]}]}],\n [{\"1\",\n [{load_module, ch3},\n {load_module, m1, [ch3]}]}]\n}.\n```\n\n`m1` is dependent on `ch3` also when downgrading. `systools` knows the\ndifference between up- and downgrading and generates a correct `relup`, where\n`ch3` is loaded before `m1` when upgrading, but `m1` is loaded before `ch3` when\ndowngrading.\n\n[](){: #spec }","ref":"appup_cookbook.html#module-dependencies"},{"type":"extras","title":"Changing Code for a Special Process - Appup Cookbook","doc":"In this case, simple code replacement is not sufficient. When a new version of a\nresidence module for a special process is loaded, the process must make a fully\nqualified call to its loop function to switch to the new code. Thus,\nsynchronized code replacement must be used.\n\n> #### Note {: .info }\n>\n> The name(s) of the user-defined residence module(s) must be listed in the\n> `Modules` part of the child specification for the special process. Otherwise\n> the release handler cannot find the process.\n\n_Example_\n\nConsider the example `ch4` in [sys and proc_lib](spec_proc.md#ex).\nWhen started by a supervisor, the child specification can look as follows:\n\n```erlang\n{ch4, {ch4, start_link, []},\n permanent, brutal_kill, worker, [ch4]}\n```\n\nIf `ch4` is part of the application `sp_app` and a new version of the module is\nto be loaded when upgrading from version \"1\" to \"2\" of this application,\n`sp_app.appup` can look as follows:\n\n```erlang\n{\"2\",\n [{\"1\", [{update, ch4, {advanced, []}}]}],\n [{\"1\", [{update, ch4, {advanced, []}}]}]\n}.\n```\n\nThe `update` instruction must contain the tuple `{advanced,Extra}`. The\ninstruction makes the special process call the callback function\n`system_code_change/4`, a function the user must implement. The term `Extra`, in\nthis case `[]`, is passed as is to `system_code_change/4`:\n\n```erlang\n-module(ch4).\n...\n-export([system_code_change/4]).\n...\n\nsystem_code_change(Chs, _Module, _OldVsn, _Extra) ->\n {ok, Chs}.\n```\n\n- The first argument is the internal state `State`, passed from\n function [`sys:handle_system_msg(Request, From, Parent, Module, Deb,\n State)`](`sys:handle_system_msg/6`), and called by the special\n process when a system message is received. In `ch4`, the internal\n state is the set of available channels `Chs`.\n- The second argument is the name of the module (`ch4`).\n- The third argument is `Vsn` or `{down,Vsn}`, as described for\n `c:gen_server:code_change/3` in\n [Changing Internal State](appup_cookbook.md#code_change).\n\nIn this case, all arguments but the first are ignored and the function simply\nreturns the internal state again. This is enough if the code only has been\nextended. If instead the internal state is changed (similar to the example in\n[Changing Internal State](appup_cookbook.md#int_state)), this is done in this\nfunction and `{ok,Chs2}` returned.\n\n[](){: #sup }","ref":"appup_cookbook.html#changing-code-for-a-special-process"},{"type":"extras","title":"Changing a Supervisor - Appup Cookbook","doc":"The supervisor behaviour supports changing the internal state, that is, changing\nthe restart strategy and maximum restart frequency properties, as well as\nchanging the existing child specifications.\n\nChild processes can be added or deleted, but this is not handled automatically.\nInstructions must be given by in the `.appup` file.","ref":"appup_cookbook.html#changing-a-supervisor"},{"type":"extras","title":"Changing Properties - Appup Cookbook","doc":"Since the supervisor is to change its internal state, synchronized code\nreplacement is required. However, a special `update` instruction must be used.\n\nFirst, the new version of the callback module must be loaded, both in the case\nof upgrade and downgrade. Then the new return value of `init/1` can be checked\nand the internal state be changed accordingly.\n\nThe following `upgrade` instruction is used for supervisors:\n\n```text\n{update, Module, supervisor}\n```\n\n_Example_\n\nTo change the restart strategy of `ch_sup` (from\n[Supervisor Behaviour](sup_princ.md#ex)) from `one_for_one` to `one_for_all`,\nchange the callback function `init/1` in `ch_sup.erl`:\n\n```erlang\n-module(ch_sup).\n...\n\ninit(_Args) ->\n {ok, {#{strategy => one_for_all, ...}, ...}}.\n```\n\nThe file `ch_app.appup`:\n\n```erlang\n{\"2\",\n [{\"1\", [{update, ch_sup, supervisor}]}],\n [{\"1\", [{update, ch_sup, supervisor}]}]\n}.\n```","ref":"appup_cookbook.html#changing-properties"},{"type":"extras","title":"Changing Child Specifications - Appup Cookbook","doc":"The instruction, and thus the `.appup` file, when changing an existing child\nspecification, is the same as when changing properties as described earlier:\n\n```erlang\n{\"2\",\n [{\"1\", [{update, ch_sup, supervisor}]}],\n [{\"1\", [{update, ch_sup, supervisor}]}]\n}.\n```\n\nThe changes do not affect existing child processes. For example, changing the\nstart function only specifies how the child process is to be restarted, if\nneeded later on.\n\nThe id of the child specification cannot be changed.\n\nChanging the `Modules` field of the child specification can affect the release\nhandling process itself, as this field is used to identify which processes are\naffected when doing a synchronized code replacement.\n\n[](){: #sup_add }","ref":"appup_cookbook.html#changing-child-specifications"},{"type":"extras","title":"Adding and Deleting Child Processes - Appup Cookbook","doc":"As stated earlier, changing child specifications does not affect existing child\nprocesses. New child specifications are automatically added, but not deleted.\nChild processes are not automatically started or terminated, this must be done\nusing `apply` instructions.\n\n_Example_\n\nAssume a new child process `m1` is to be added to `ch_sup` when\nupgrading `ch_app` from \"1\" to \"2\". This means `m1` is to be deleted when\ndowngrading from \"2\" to \"1\":\n\n```erlang\n{\"2\",\n [{\"1\",\n [{update, ch_sup, supervisor},\n {apply, {supervisor, restart_child, [ch_sup, m1]}}\n ]}],\n [{\"1\",\n [{apply, {supervisor, terminate_child, [ch_sup, m1]}},\n {apply, {supervisor, delete_child, [ch_sup, m1]}},\n {update, ch_sup, supervisor}\n ]}]\n}.\n```\n\nThe order of the instructions is important.\n\nThe supervisor must be registered as `ch_sup` for the script to work. If the\nsupervisor is not registered, it cannot be accessed directly from the script.\nInstead a help function that finds the pid of the supervisor and calls\n`supervisor:restart_child`, and so on, must be written. This function is then to\nbe called from the script using the `apply` instruction.\n\nIf the module `m1` is introduced in version \"2\" of `ch_app`, it must also be\nloaded when upgrading and deleted when downgrading:\n\n```erlang\n{\"2\",\n [{\"1\",\n [{add_module, m1},\n {update, ch_sup, supervisor},\n {apply, {supervisor, restart_child, [ch_sup, m1]}}\n ]}],\n [{\"1\",\n [{apply, {supervisor, terminate_child, [ch_sup, m1]}},\n {apply, {supervisor, delete_child, [ch_sup, m1]}},\n {update, ch_sup, supervisor},\n {delete_module, m1}\n ]}]\n}.\n```\n\nAs stated earlier, the order of the instructions is important. When upgrading,\n`m1` must be loaded, and the supervisor child specification changed, before the\nnew child process can be started. When downgrading, the child process must be\nterminated before the child specification is changed and the module is deleted.","ref":"appup_cookbook.html#adding-and-deleting-child-processes"},{"type":"extras","title":"Adding or Deleting a Module - Appup Cookbook","doc":"_Example\n\n_ A new functional module `m` is added to `ch_app`:\n\n```erlang\n{\"2\",\n [{\"1\", [{add_module, m}]}],\n [{\"1\", [{delete_module, m}]}]\n```","ref":"appup_cookbook.html#adding-or-deleting-a-module"},{"type":"extras","title":"Starting or Terminating a Process - Appup Cookbook","doc":"In a system structured according to the OTP design principles, any process would\nbe a child process belonging to a supervisor, see\n[Adding and Deleting Child Processes](appup_cookbook.md#sup_add) in Changing a\nSupervisor.","ref":"appup_cookbook.html#starting-or-terminating-a-process"},{"type":"extras","title":"Adding or Removing an Application - Appup Cookbook","doc":"When adding or removing an application, no `.appup` file is needed. When\ngenerating `relup`, the `.rel` files are compared and the `add_application` and\n`remove_application` instructions are added automatically.","ref":"appup_cookbook.html#adding-or-removing-an-application"},{"type":"extras","title":"Restarting an Application - Appup Cookbook","doc":"Restarting an application is useful when a change is too complicated to be made\nwithout restarting the processes, for example, if the supervisor hierarchy has\nbeen restructured.\n\n_Example_\n\nWhen adding a child `m1` to `ch_sup`, as in\n[Adding and Deleting Child Processes](appup_cookbook.md#sup_add) in Changing a\nSupervisor, an alternative to updating the supervisor is to restart the entire\napplication:\n\n```erlang\n{\"2\",\n [{\"1\", [{restart_application, ch_app}]}],\n [{\"1\", [{restart_application, ch_app}]}]\n}.\n```\n\n[](){: #app_spec }","ref":"appup_cookbook.html#restarting-an-application"},{"type":"extras","title":"Changing an Application Specification - Appup Cookbook","doc":"When installing a release, the application specifications are automatically\nupdated before evaluating the `relup` script. Thus, no instructions are needed\nin the `.appup` file:\n\n```erlang\n{\"2\",\n [{\"1\", []}],\n [{\"1\", []}]\n}.\n```","ref":"appup_cookbook.html#changing-an-application-specification"},{"type":"extras","title":"Changing Application Configuration - Appup Cookbook","doc":"Changing an application configuration by updating the `env` key in the `.app`\nfile is an instance of changing an application specification, see the previous\nsection.\n\nAlternatively, application configuration parameters can be added or updated in\n`sys.config`.","ref":"appup_cookbook.html#changing-application-configuration"},{"type":"extras","title":"Changing Included Applications - Appup Cookbook","doc":"The release handling instructions for adding, removing, and restarting\napplications apply to primary applications only. There are no corresponding\ninstructions for included applications. However, since an included application\nis really a supervision tree with a topmost supervisor, started as a child\nprocess to a supervisor in the including application, a `.relup` file can be\nmanually created.\n\n_Example_\n\nAssume there is a release containing an application `prim_app`, which\nhave a supervisor `prim_sup` in its supervision tree.\n\nIn a new version of the release, the application `ch_app` is to be included in\n`prim_app`. That is, its topmost supervisor `ch_sup` is to be started as a child\nprocess to `prim_sup`.\n\nThe workflow is as follows:\n\n_Step 1)_ Edit the code for `prim_sup`:\n\n```erlang\ninit(...) ->\n {ok, {...supervisor flags...,\n [...,\n {ch_sup, {ch_sup,start_link,[]},\n permanent,infinity,supervisor,[ch_sup]},\n ...]}}.\n```\n\n_Step 2)_ Edit the `.app` file for `prim_app`:\n\n```erlang\n{application, prim_app,\n [...,\n {vsn, \"2\"},\n ...,\n {included_applications, [ch_app]},\n ...\n ]}.\n```\n\n_Step 3)_ Create a new `.rel` file, including `ch_app`:\n\n```text\n{release,\n ...,\n [...,\n {prim_app, \"2\"},\n {ch_app, \"1\"}]}.\n```\n\nThe included application can be started in two ways. This is described in the\nnext two sections.","ref":"appup_cookbook.html#changing-included-applications"},{"type":"extras","title":"Application Restart - Appup Cookbook","doc":"_Step 4a)_ One way to start the included application is to restart the entire\n`prim_app` application. Normally, the `restart_application` instruction in the\n`.appup` file for `prim_app` would be used.\n\nHowever, if this is done and a `.relup` file is generated, not only would it\ncontain instructions for restarting (that is, removing and adding) `prim_app`,\nit would also contain instructions for starting `ch_app` (and stopping it, in\nthe case of downgrade). This is because `ch_app` is included in the new `.rel`\nfile, but not in the old one.\n\nInstead, a correct `relup` file can be created manually, either from scratch or\nby editing the generated version. The instructions for starting/stopping\n`ch_app` are replaced by instructions for loading/unloading the application:\n\n```c\n{\"B\",\n [{\"A\",\n [],\n [{load_object_code,{ch_app,\"1\",[ch_sup,ch3]}},\n {load_object_code,{prim_app,\"2\",[prim_app,prim_sup]}},\n point_of_no_return,\n {apply,{application,stop,[prim_app]}},\n {remove,{prim_app,brutal_purge,brutal_purge}},\n {remove,{prim_sup,brutal_purge,brutal_purge}},\n {purge,[prim_app,prim_sup]},\n {load,{prim_app,brutal_purge,brutal_purge}},\n {load,{prim_sup,brutal_purge,brutal_purge}},\n {load,{ch_sup,brutal_purge,brutal_purge}},\n {load,{ch3,brutal_purge,brutal_purge}},\n {apply,{application,load,[ch_app]}},\n {apply,{application,start,[prim_app,permanent]}}]}],\n [{\"A\",\n [],\n [{load_object_code,{prim_app,\"1\",[prim_app,prim_sup]}},\n point_of_no_return,\n {apply,{application,stop,[prim_app]}},\n {apply,{application,unload,[ch_app]}},\n {remove,{ch_sup,brutal_purge,brutal_purge}},\n {remove,{ch3,brutal_purge,brutal_purge}},\n {purge,[ch_sup,ch3]},\n {remove,{prim_app,brutal_purge,brutal_purge}},\n {remove,{prim_sup,brutal_purge,brutal_purge}},\n {purge,[prim_app,prim_sup]},\n {load,{prim_app,brutal_purge,brutal_purge}},\n {load,{prim_sup,brutal_purge,brutal_purge}},\n {apply,{application,start,[prim_app,permanent]}}]}]\n}.\n```","ref":"appup_cookbook.html#application-restart"},{"type":"extras","title":"Supervisor Change - Appup Cookbook","doc":"_Step 4b)_ Another way to start the included application (or stop it in the case\nof downgrade) is by combining instructions for adding and removing child\nprocesses to/from `prim_sup` with instructions for loading/unloading all\n`ch_app` code and its application specification.\n\nAgain, the `.relup` file is created manually, either from scratch or by editing a\ngenerated version. Load all code for `ch_app` first, and also load the\napplication specification, before `prim_sup` is updated. When downgrading,\n`prim_sup` is to updated first, before the code for `ch_app` and its application\nspecification are unloaded.\n\n```erlang\n{\"B\",\n [{\"A\",\n [],\n [{load_object_code,{ch_app,\"1\",[ch_sup,ch3]}},\n {load_object_code,{prim_app,\"2\",[prim_sup]}},\n point_of_no_return,\n {load,{ch_sup,brutal_purge,brutal_purge}},\n {load,{ch3,brutal_purge,brutal_purge}},\n {apply,{application,load,[ch_app]}},\n {suspend,[prim_sup]},\n {load,{prim_sup,brutal_purge,brutal_purge}},\n {code_change,up,[{prim_sup,[]}]},\n {resume,[prim_sup]},\n {apply,{supervisor,restart_child,[prim_sup,ch_sup]}}]}],\n [{\"A\",\n [],\n [{load_object_code,{prim_app,\"1\",[prim_sup]}},\n point_of_no_return,\n {apply,{supervisor,terminate_child,[prim_sup,ch_sup]}},\n {apply,{supervisor,delete_child,[prim_sup,ch_sup]}},\n {suspend,[prim_sup]},\n {load,{prim_sup,brutal_purge,brutal_purge}},\n {code_change,down,[{prim_sup,[]}]},\n {resume,[prim_sup]},\n {remove,{ch_sup,brutal_purge,brutal_purge}},\n {remove,{ch3,brutal_purge,brutal_purge}},\n {purge,[ch_sup,ch3]},\n {apply,{application,unload,[ch_app]}}]}]\n}.\n```","ref":"appup_cookbook.html#supervisor-change"},{"type":"extras","title":"Changing Non-Erlang Code - Appup Cookbook","doc":"Changing code for a program written in another programming language than Erlang,\nfor example, a port program, is application-dependent and OTP provides no\nspecial support.\n\n_Example_\n\nWhen changing code for a port program, assume that the Erlang process\ncontrolling the port is a `gen_server` `portc` and that the port is opened in\nthe callback function `init/1`:\n\n```erlang\ninit(...) ->\n ...,\n PortPrg = filename:join(code:priv_dir(App), \"portc\"),\n Port = open_port({spawn,PortPrg}, [...]),\n ...,\n {ok, #state{port=Port, ...}}.\n```\n\nIf the port program is to be updated, the code for the `gen_server` can be\nextended with a `code_change/3` function, which closes the old port and opens a\nnew port. (If necessary, the `gen_server` can first request data that must be\nsaved from the port program and pass this data to the new port):\n\n```erlang\ncode_change(_OldVsn, State, port) ->\n State#state.port ! close,\n receive\n {Port,close} ->\n true\n end,\n PortPrg = filename:join(code:priv_dir(App), \"portc\"),\n Port = open_port({spawn,PortPrg}, [...]),\n {ok, #state{port=Port, ...}}.\n```\n\nUpdate the application version number in the `.app` file and write an `.appup`\nfile:\n\n```erlang\n[\"2\",\n [{\"1\", [{update, portc, {advanced,port}}]}],\n [{\"1\", [{update, portc, {advanced,port}}]}]\n].\n```\n\nEnsure that the `priv` directory, where the C program is located, is included in\nthe new release package:\n\n```erlang\n1> systools:make_tar(\"my_release\", [{dirs,[priv]}]).\n...\n```","ref":"appup_cookbook.html#changing-non-erlang-code"},{"type":"extras","title":"Runtime System Restart and Upgrade - Appup Cookbook","doc":"Two upgrade instructions restart the runtime system:\n\n- `restart_new_emulator`\n\n Intended when ERTS, Kernel, STDLIB, or SASL is upgraded. It is automatically\n added when the `relup` file is generated by `systools:make_relup/3,4`. It is\n executed before all other upgrade instructions. For more information about\n this instruction, see restart_new_emulator (Low-Level) in\n [Release Handling Instructions](release_handling.md#restart_new_emulator_instr).\n\n- `restart_emulator`\n\n Used when a restart of the runtime system is required after all other upgrade\n instructions are executed. For more information about this instruction, see\n restart_emulator (Low-Level) in\n [Release Handling Instructions](release_handling.md#restart_emulator_instr).\n\nIf a runtime system restart is necessary and no upgrade instructions are needed,\nthat is, if the restart itself is enough for the upgraded applications to start\nrunning the new versions, a simple `.relup` file can be created manually:\n\n```erlang\n{\"B\",\n [{\"A\",\n [],\n [restart_emulator]}],\n [{\"A\",\n [],\n [restart_emulator]}]\n}.\n```\n\nIn this case, the release handler framework with automatic packing and unpacking\nof release packages, automatic path updates, and so on, can be used without\nhaving to specify `.appup` files.","ref":"appup_cookbook.html#runtime-system-restart-and-upgrade"},{"type":"extras","title":"Introduction","doc":"# Introduction\n\n[](){: #programming-examples }\n\nThis section contains examples on using records, funs, list comprehensions, and\nthe bit syntax.","ref":"programming_examples.html"},{"type":"extras","title":"Records","doc":"\n# Records","ref":"prog_ex_records.html"},{"type":"extras","title":"Records and Tuples - Records","doc":"The main advantage of using records rather than tuples is that fields in a\nrecord are accessed by name, whereas fields in a tuple are accessed by position.\nTo illustrate these differences, suppose that you want to represent a person\nwith the tuple `{Name, Address, Phone}`.\n\nTo write functions that manipulate this data, remember the following:\n\n- The `Name` field is the first element of the tuple.\n- The `Address` field is the second element.\n- The `Phone` field is the third element.\n\nFor example, to extract data from a variable `P` that contains such a tuple, you\ncan write the following code and then use pattern matching to extract the\nrelevant fields:\n\n```erlang\nName = element(1, P),\nAddress = element(2, P),\n...\n```\n\nSuch code is difficult to read and understand, and errors occur if the numbering\nof the elements in the tuple is wrong. If the data representation of the fields\nis changed, by re-ordering, adding, or removing fields, all references to the\nperson tuple must be checked and possibly modified.\n\nRecords allow references to the fields by name, instead of by position. In the\nfollowing example, a record instead of a tuple is used to store the data:\n\n```erlang\n-record(person, {name, phone, address}).\n```\n\nThis enables references to the fields of the record by name. For example, if `P`\nis a variable whose value is a `person` record, the following code access the\nname and address fields of the records:\n\n```erlang\nName = P#person.name,\nAddress = P#person.address,\n...\n```\n\nInternally, records are represented using tagged tuples:\n\n```erlang\n{person, Name, Phone, Address}\n```","ref":"prog_ex_records.html#records-and-tuples"},{"type":"extras","title":"Defining a Record - Records","doc":"This following definition of a `person` is used in several examples in this\nsection. Three fields are included, `name`, `phone`, and `address`. The default\nvalues for `name` and `phone` is \"\" and [], respectively. The default value for\n`address` is the atom `undefined`, since no default value is supplied for this\nfield:\n\n```erlang\n-record(person, {name = \"\", phone = [], address}).\n```\n\nThe record must be defined in the shell to enable use of the record syntax in\nthe examples:\n\n```erlang\n> rd(person, {name = \"\", phone = [], address}).\nperson\n```\n\nThis is because record definitions are only available at compile time, not at\nruntime. For details on records in the shell, see the `m:shell` manual page in\nSTDLIB.","ref":"prog_ex_records.html#defining-a-record"},{"type":"extras","title":"Creating a Record - Records","doc":"A new `person` record is created as follows:\n\n```erlang\n> #person{phone=[0,8,2,3,4,3,1,2], name=\"Robert\"}.\n#person{name = \"Robert\",phone = [0,8,2,3,4,3,1,2],address = undefined}\n```\n\nAs the `address` field was omitted, its default value is used.\n\nFrom Erlang 5.1/OTP R8B, a value to all fields in a record can be set with the\nspecial field `_`. `_` means \"all fields not explicitly specified\".\n\n_Example:_\n\n```erlang\n> #person{name = \"Jakob\", _ = '_'}.\n#person{name = \"Jakob\",phone = '_',address = '_'}\n```\n\nIt is primarily intended to be used in `ets:match/2` and\n`mnesia:match_object/3`, to set record fields to the atom `'_'`. (This is a\nwildcard in `ets:match/2`.)","ref":"prog_ex_records.html#creating-a-record"},{"type":"extras","title":"Accessing a Record Field - Records","doc":"The following example shows how to access a record field:\n\n```erlang\n> P = #person{name = \"Joe\", phone = [0,8,2,3,4,3,1,2]}.\n#person{name = \"Joe\",phone = [0,8,2,3,4,3,1,2],address = undefined}\n> P#person.name.\n\"Joe\"\n```","ref":"prog_ex_records.html#accessing-a-record-field"},{"type":"extras","title":"Updating a Record - Records","doc":"The following example shows how to update a record:\n\n```erlang\n> P1 = #person{name=\"Joe\", phone=[1,2,3], address=\"A street\"}.\n#person{name = \"Joe\",phone = [1,2,3],address = \"A street\"}\n> P2 = P1#person{name=\"Robert\"}.\n#person{name = \"Robert\",phone = [1,2,3],address = \"A street\"}\n```","ref":"prog_ex_records.html#updating-a-record"},{"type":"extras","title":"Type Testing - Records","doc":"The following example shows that the guard succeeds if `P` is record of type\n`person`:\n\n```erlang\nfoo(P) when is_record(P, person) -> a_person;\nfoo(_) -> not_a_person.\n```","ref":"prog_ex_records.html#type-testing"},{"type":"extras","title":"Pattern Matching - Records","doc":"Matching can be used in combination with records, as shown in the following\nexample:\n\n```erlang\n> P3 = #person{name=\"Joe\", phone=[0,0,7], address=\"A street\"}.\n#person{name = \"Joe\",phone = [0,0,7],address = \"A street\"}\n> #person{name = Name} = P3, Name.\n\"Joe\"\n```\n\nThe following function takes a list of `person` records and searches for the\nphone number of a person with a particular name:\n\n```erlang\nfind_phone([#person{name=Name, phone=Phone} | _], Name) ->\n {found, Phone};\nfind_phone([_| T], Name) ->\n find_phone(T, Name);\nfind_phone([], Name) ->\n not_found.\n```\n\nThe fields referred to in the pattern can be given in any order.","ref":"prog_ex_records.html#pattern-matching"},{"type":"extras","title":"Nested Records - Records","doc":"The value of a field in a record can be an instance of a record. Retrieval of\nnested data can be done stepwise, or in a single step, as shown in the following\nexample:\n\n```erlang\n-record(name, {first = \"Robert\", last = \"Ericsson\"}).\n-record(person, {name = #name{}, phone}).\n\ndemo() ->\n P = #person{name= #name{first=\"Robert\",last=\"Virding\"}, phone=123},\n First = (P#person.name)#name.first.\n```\n\nHere, `demo()` evaluates to `\"Robert\"`.","ref":"prog_ex_records.html#nested-records"},{"type":"extras","title":"A Longer Example - Records","doc":"Comments are embedded in the following example:\n\n```erlang\n%% File: person.hrl\n\n%%-----------------------------------------------------------\n%% Data Type: person\n%% where:\n%% name: A string (default is undefined).\n%% age: An integer (default is undefined).\n%% phone: A list of integers (default is []).\n%% dict: A dictionary containing various information\n%% about the person.\n%% A {Key, Value} list (default is the empty list).\n%%------------------------------------------------------------\n-record(person, {name, age, phone = [], dict = []}).\n```\n\n```erlang\n-module(person).\n-include(\"person.hrl\").\n-compile(export_all). % For test purposes only.\n\n%% This creates an instance of a person.\n%% Note: The phone number is not supplied so the\n%% default value [] will be used.\n\nmake_hacker_without_phone(Name, Age) ->\n #person{name = Name, age = Age,\n dict = [{computer_knowledge, excellent},\n {drinks, coke}]}.\n\n%% This demonstrates matching in arguments\n\nprint(#person{name = Name, age = Age,\n phone = Phone, dict = Dict}) ->\n io:format(\"Name: ~s, Age: ~w, Phone: ~w ~n\"\n \"Dictionary: ~w.~n\", [Name, Age, Phone, Dict]).\n\n%% Demonstrates type testing, selector, updating.\n\nbirthday(P) when is_record(P, person) ->\n P#person{age = P#person.age + 1}.\n\nregister_two_hackers() ->\n Hacker1 = make_hacker_without_phone(\"Joe\", 29),\n OldHacker = birthday(Hacker1),\n % The central_register_server should have\n % an interface function for this.\n central_register_server ! {register_person, Hacker1},\n central_register_server ! {register_person,\n OldHacker#person{name = \"Robert\",\n phone = [0,8,3,2,4,5,3,1]}}.\n```","ref":"prog_ex_records.html#a-longer-example"},{"type":"extras","title":"Funs","doc":"\n# Funs","ref":"funs.html"},{"type":"extras","title":"map - Funs","doc":"The following function, `double`, doubles every element in a list:\n\n```erlang\ndouble([H|T]) -> [2*H|double(T)];\ndouble([]) -> [].\n```\n\nHence, the argument entered as input is doubled as follows:\n\n```erlang\n> double([1,2,3,4]).\n[2,4,6,8]\n```\n\nThe following function, `add_one`, adds one to every element in a list:\n\n```erlang\nadd_one([H|T]) -> [H+1|add_one(T)];\nadd_one([]) -> [].\n```\n\nThe functions `double` and `add_one` have a similar structure. This can be used\nby writing a function `map` that expresses this similarity:\n\n```erlang\nmap(F, [H|T]) -> [F(H)|map(F, T)];\nmap(F, []) -> [].\n```\n\nThe functions `double` and `add_one` can now be expressed in terms of `map` as\nfollows:\n\n```erlang\ndouble(L) -> map(fun(X) -> 2*X end, L).\nadd_one(L) -> map(fun(X) -> 1 + X end, L).\n```\n\n`map(F, List)` is a function that takes a function `F` and a list `L` as\narguments and returns a new list, obtained by applying `F` to each of the\nelements in `L`.\n\nThe process of abstracting out the common features of a number of different\nprograms is called _procedural abstraction_. Procedural abstraction can be used\nto write several different functions that have a similar structure, but differ\nin some minor detail. This is done as follows:\n\n1. _Step 1._ Write one function that represents the common features of these\n functions.\n1. _Step 2._ Parameterize the difference in terms of functions that are passed\n as arguments to the common function.","ref":"funs.html#map"},{"type":"extras","title":"foreach - Funs","doc":"This section illustrates procedural abstraction. Initially, the following two\nexamples are written as conventional functions.\n\nThis function prints all elements of a list onto a stream:\n\n```erlang\nprint_list(Stream, [H|T]) ->\n io:format(Stream, \"~p~n\", [H]),\n print_list(Stream, T);\nprint_list(Stream, []) ->\n true.\n```\n\nThis function broadcasts a message to a list of processes:\n\n```erlang\nbroadcast(Msg, [Pid|Pids]) ->\n Pid ! Msg,\n broadcast(Msg, Pids);\nbroadcast(_, []) ->\n true.\n```\n\nThese two functions have a similar structure. They both iterate over a list and\ndo something to each element in the list. The \"something\" is passed on as an\nextra argument to the function that does this.\n\nThe function `foreach` expresses this similarity:\n\n```erlang\nforeach(F, [H|T]) ->\n F(H),\n foreach(F, T);\nforeach(F, []) ->\n ok.\n```\n\nUsing the function `foreach`, the function `print_list` becomes:\n\n```erlang\nforeach(fun(H) -> io:format(S, \"~p~n\",[H]) end, L)\n```\n\nUsing the function `foreach`, the function `broadcast` becomes:\n\n```erlang\nforeach(fun(Pid) -> Pid ! M end, L)\n```\n\n`foreach` is evaluated for its side-effect and not its value. `foreach(Fun ,L)`\ncalls `Fun(X)` for each element `X` in `L` and the processing occurs in the\norder that the elements were defined in `L`. `map` does not define the order in\nwhich its elements are processed.","ref":"funs.html#foreach"},{"type":"extras","title":"Syntax of Funs - Funs","doc":"Funs are written with the following syntax (see\n[Fun Expressions ](`e:system:expressions.md#fun-expressions`)for full description):\n\n```erlang\nF = fun (Arg1, Arg2, ... ArgN) ->\n ...\n end\n```\n\nThis creates an anonymous function of `N` arguments and binds it to the variable\n`F`.\n\nAnother function, `FunctionName`, written in the same module, can be passed as\nan argument, using the following syntax:\n\n```erlang\nF = fun FunctionName/Arity\n```\n\nWith this form of function reference, the function that is referred to does not\nneed to be exported from the module.\n\nIt is also possible to refer to a function defined in a different module, with\nthe following syntax:\n\n```erlang\nF = fun Module:FunctionName/Arity\n```\n\nIn this case, the function must be exported from the module in question.\n\nThe following program illustrates the different ways of creating funs:\n\n```erlang\n-module(fun_test).\n-export([t1/0, t2/0]).\n-import(lists, [map/2]).\n\nt1() -> map(fun(X) -> 2 * X end, [1,2,3,4,5]).\n\nt2() -> map(fun double/1, [1,2,3,4,5]).\n\ndouble(X) -> X * 2.\n```\n\nThe fun `F` can be evaluated with the following syntax:\n\n```erlang\nF(Arg1, Arg2, ..., Argn)\n```\n\nTo check whether a term is a fun, use the test\n[`is_function/1`](`is_function/1`) in a guard.\n\n_Example:_\n\n```erlang\nf(F, Args) when is_function(F) ->\n apply(F, Args);\nf(N, _) when is_integer(N) ->\n N.\n```\n\nFuns are a distinct type. The BIFs `erlang:fun_info/1,2` can be used to retrieve\ninformation about a fun, and the BIF `erlang:fun_to_list/1` returns a textual\nrepresentation of a fun. The [`check_process_code/2`](`check_process_code/2`)\nBIF returns `true` if the process contains funs that depend on the old version\nof a module.","ref":"funs.html#syntax-of-funs"},{"type":"extras","title":"Variable Bindings Within a Fun - Funs","doc":"The scope rules for variables that occur in funs are as follows:\n\n- All variables that occur in the head of a fun are assumed to be \"fresh\"\n variables.\n- Variables that are defined before the fun, and that occur in function calls or\n guard tests within the fun, have the values they had outside the fun.\n- Variables cannot be exported from a fun.\n\nThe following examples illustrate these rules:\n\n```erlang\nprint_list(File, List) ->\n {ok, Stream} = file:open(File, write),\n foreach(fun(X) -> io:format(Stream,\"~p~n\",[X]) end, List),\n file:close(Stream).\n```\n\nHere, the variable `X`, defined in the head of the fun, is a new variable. The\nvariable `Stream`, which is used within the fun, gets its value from the\n`file:open` line.\n\nAs any variable that occurs in the head of a fun is considered a new variable,\nit is equally valid to write as follows:\n\n```erlang\nprint_list(File, List) ->\n {ok, Stream} = file:open(File, write),\n foreach(fun(File) ->\n io:format(Stream,\"~p~n\",[File])\n end, List),\n file:close(Stream).\n```\n\nHere, `File` is used as the new variable instead of `X`. This is not so wise\nbecause code in the fun body cannot refer to the variable `File`, which is\ndefined outside of the fun. Compiling this example gives the following\ndiagnostic:\n\n```text\n./FileName.erl:Line: Warning: variable 'File'\n shadowed in 'fun'\n```\n\nThis indicates that the variable `File`, which is defined inside the fun,\ncollides with the variable `File`, which is defined outside the fun.\n\nThe rules for importing variables into a fun has the consequence that certain\npattern matching operations must be moved into guard expressions and cannot be\nwritten in the head of the fun. For example, you might write the following code\nif you intend the first clause of `F` to be evaluated when the value of its\nargument is `Y`:\n\n```erlang\nf(...) ->\n Y = ...\n map(fun(X) when X == Y ->\n ;\n (_) ->\n ...\n end, ...)\n ...\n```\n\ninstead of writing the following code:\n\n```erlang\nf(...) ->\n Y = ...\n map(fun(Y) ->\n ;\n (_) ->\n ...\n end, ...)\n ...\n```","ref":"funs.html#variable-bindings-within-a-fun"},{"type":"extras","title":"Funs and Module Lists - Funs","doc":"The following examples show a dialogue with the Erlang shell. All the higher\norder functions discussed are exported from the module `m:lists`.","ref":"funs.html#funs-and-module-lists"},{"type":"extras","title":"map - Funs","doc":"`lists:map/2` takes a function of one argument and a list of terms:\n\n```erlang\nmap(F, [H|T]) -> [F(H)|map(F, T)];\nmap(F, []) -> [].\n```\n\nIt returns the list obtained by applying the function to every argument in the\nlist.\n\nWhen a new fun is defined in the shell, the value of the fun is printed as\n`Fun# `:\n\n```erlang\n> Double = fun(X) -> 2 * X end.\n#Fun \n> lists:map(Double, [1,2,3,4,5]).\n[2,4,6,8,10]\n```","ref":"funs.html#map"},{"type":"extras","title":"any - Funs","doc":"`lists:any/2` takes a predicate `P` of one argument and a list of terms:\n\n```erlang\nany(Pred, [H|T]) ->\n case Pred(H) of\n true -> true;\n false -> any(Pred, T)\n end;\nany(Pred, []) ->\n false.\n```\n\nA predicate is a function that returns `true` or `false`. `any` is `true` if\nthere is a term `X` in the list such that `P(X)` is `true`.\n\nA predicate `Big(X)` is defined, which is `true` if its argument is greater that\n10:\n\n```erlang\n> Big = fun(X) -> if X > 10 -> true; true -> false end end.\n#Fun \n> lists:any(Big, [1,2,3,4]).\nfalse\n> lists:any(Big, [1,2,3,12,5]).\ntrue\n```","ref":"funs.html#any"},{"type":"extras","title":"all - Funs","doc":"`lists:all/2` has the same arguments as `any`:\n\n```erlang\nall(Pred, [H|T]) ->\n case Pred(H) of\n true -> all(Pred, T);\n false -> false\n end;\nall(Pred, []) ->\n true.\n```\n\nIt is `true` if the predicate applied to all elements in the list is `true`.\n\n```erlang\n> lists:all(Big, [1,2,3,4,12,6]).\nfalse\n> lists:all(Big, [12,13,14,15]).\ntrue\n```","ref":"funs.html#all"},{"type":"extras","title":"foreach - Funs","doc":"`lists:foreach/2` takes a function of one argument and a list of terms:\n\n```erlang\nforeach(F, [H|T]) ->\n F(H),\n foreach(F, T);\nforeach(F, []) ->\n ok.\n```\n\nThe function is applied to each argument in the list. `foreach` returns `ok`. It\nis only used for its side-effect:\n\n```erlang\n> lists:foreach(fun(X) -> io:format(\"~w~n\",[X]) end, [1,2,3,4]).\n1\n2\n3\n4\nok\n```","ref":"funs.html#foreach"},{"type":"extras","title":"foldl - Funs","doc":"`lists:foldl/3` takes a function of two arguments, an accumulator and a list:\n\n```erlang\nfoldl(F, Accu, [Hd|Tail]) ->\n foldl(F, F(Hd, Accu), Tail);\nfoldl(F, Accu, []) -> Accu.\n```\n\nThe function is called with two arguments. The first argument is the successive\nelements in the list. The second argument is the accumulator. The function must\nreturn a new accumulator, which is used the next time the function is called.\n\nIf you have a list of lists `L = [\"I\",\"like\",\"Erlang\"]`, then you can sum the\nlengths of all the strings in `L` as follows:\n\n```erlang\n> L = [\"I\",\"like\",\"Erlang\"].\n[\"I\",\"like\",\"Erlang\"]\n10> lists:foldl(fun(X, Sum) -> length(X) + Sum end, 0, L).\n11\n```\n\n`lists:foldl/3` works like a `while` loop in an imperative language:\n\n```erlang\nL = [\"I\",\"like\",\"Erlang\"],\nSum = 0,\nwhile( L != []){\n Sum += length(head(L)),\n L = tail(L)\nend\n```","ref":"funs.html#foldl"},{"type":"extras","title":"mapfoldl - Funs","doc":"`lists:mapfoldl/3` simultaneously maps and folds over a list:\n\n```erlang\nmapfoldl(F, Accu0, [Hd|Tail]) ->\n {R,Accu1} = F(Hd, Accu0),\n {Rs,Accu2} = mapfoldl(F, Accu1, Tail),\n {[R|Rs], Accu2};\nmapfoldl(F, Accu, []) -> {[], Accu}.\n```\n\nThe following example shows how to change all letters in `L` to upper case and\nthen count them.\n\nFirst the change to upper case:\n\n```erlang\n> Upcase = fun(X) when $a = X + $A - $a;\n(X) -> X\nend.\n#Fun \n> Upcase_word =\nfun(X) ->\nlists:map(Upcase, X)\nend.\n#Fun \n> Upcase_word(\"Erlang\").\n\"ERLANG\"\n> lists:map(Upcase_word, L).\n[\"I\",\"LIKE\",\"ERLANG\"]\n```\n\nNow, the fold and the map can be done at the same time:\n\n```erlang\n> lists:mapfoldl(fun(Word, Sum) ->\n{Upcase_word(Word), Sum + length(Word)}\nend, 0, L).\n{[\"I\",\"LIKE\",\"ERLANG\"],11}\n```","ref":"funs.html#mapfoldl"},{"type":"extras","title":"filter - Funs","doc":"`lists:filter/2` takes a predicate of one argument and a list and returns all elements\nin the list that satisfy the predicate:\n\n```erlang\nfilter(F, [H|T]) ->\n case F(H) of\n true -> [H|filter(F, T)];\n false -> filter(F, T)\n end;\nfilter(F, []) -> [].\n```\n\n```erlang\n> lists:filter(Big, [500,12,2,45,6,7]).\n[500,12,45]\n```\n\nCombining maps and filters enables writing of very succinct code. For example,\nto define a set difference function `diff(L1, L2)` to be the difference between\nthe lists `L1` and `L2`, the code can be written as follows:\n\n```erlang\ndiff(L1, L2) ->\n filter(fun(X) -> not member(X, L2) end, L1).\n```\n\nThis gives the list of all elements in L1 that are not contained in L2.\n\nThe AND intersection of the list `L1` and `L2` is also easily defined:\n\n```erlang\nintersection(L1,L2) -> filter(fun(X) -> member(X,L1) end, L2).\n```","ref":"funs.html#filter"},{"type":"extras","title":"takewhile - Funs","doc":"`lists:takewhile/2` takes elements `X` from a list `L` as long as the predicate\n`P(X)` is true:\n\n```erlang\ntakewhile(Pred, [H|T]) ->\n case Pred(H) of\n true -> [H|takewhile(Pred, T)];\n false -> []\n end;\ntakewhile(Pred, []) ->\n [].\n```\n\n```erlang\n> lists:takewhile(Big, [200,500,45,5,3,45,6]).\n[200,500,45]\n```","ref":"funs.html#takewhile"},{"type":"extras","title":"dropwhile - Funs","doc":"`lists:dropwhile/2` is the complement of `takewhile`:\n\n```erlang\ndropwhile(Pred, [H|T]) ->\n case Pred(H) of\n true -> dropwhile(Pred, T);\n false -> [H|T]\n end;\ndropwhile(Pred, []) ->\n [].\n```\n\n```erlang\n> lists:dropwhile(Big, [200,500,45,5,3,45,6]).\n[5,3,45,6]\n```","ref":"funs.html#dropwhile"},{"type":"extras","title":"splitwith - Funs","doc":"`lists:splitwith/2` splits the list `L` into the two sublists `{L1, L2}`, where\n`L = takewhile(P, L)` and `L2 = dropwhile(P, L)`:\n\n```erlang\nsplitwith(Pred, L) ->\n splitwith(Pred, L, []).\n\nsplitwith(Pred, [H|T], L) ->\n case Pred(H) of\n true -> splitwith(Pred, T, [H|L]);\n false -> {reverse(L), [H|T]}\n end;\nsplitwith(Pred, [], L) ->\n {reverse(L), []}.\n```\n\n```erlang\n> lists:splitwith(Big, [200,500,45,5,3,45,6]).\n{[200,500,45],[5,3,45,6]}\n```","ref":"funs.html#splitwith"},{"type":"extras","title":"Funs Returning Funs - Funs","doc":"So far, only functions that take funs as arguments have been described. More\npowerful functions, that themselves return funs, can also be written. The\nfollowing examples illustrate these type of functions.","ref":"funs.html#funs-returning-funs"},{"type":"extras","title":"Simple Higher Order Functions - Funs","doc":"`Adder(X)` is a function that given `X`, returns a new function `G` such that\n`G(K)` returns `K + X`:\n\n```erlang\n> Adder = fun(X) -> fun(Y) -> X + Y end end.\n#Fun \n> Add6 = Adder(6).\n#Fun \n> Add6(10).\n16\n```","ref":"funs.html#simple-higher-order-functions"},{"type":"extras","title":"Infinite Lists - Funs","doc":"The idea is to write something like:\n\n```erlang\n-module(lazy).\n-export([ints_from/1]).\nints_from(N) ->\n fun() ->\n [N|ints_from(N+1)]\n end.\n```\n\nThen proceed as follows:\n\n```erlang\n> XX = lazy:ints_from(1).\n#Fun \n> XX().\n[1|#Fun ]\n> hd(XX()).\n1\n> Y = tl(XX()).\n#Fun \n> hd(Y()).\n2\n```\n\nAnd so on. This is an example of \"lazy embedding\".","ref":"funs.html#infinite-lists"},{"type":"extras","title":"Parsing - Funs","doc":"The following examples show parsers of the following type:\n\n```erlang\nParser(Toks) -> {ok, Tree, Toks1} | fail\n```\n\n`Toks` is the list of tokens to be parsed. A successful parse returns\n`{ok, Tree, Toks1}`.\n\n- `Tree` is a parse tree.\n- `Toks1` is a tail of `Tree` that contains symbols encountered after the\n structure that was correctly parsed.\n\nAn unsuccessful parse returns `fail`.\n\nThe following example illustrates a simple, functional parser that parses the\ngrammar:\n\n```text\n(a | b) & (c | d)\n```\n\nThe following code defines a function `pconst(X)` in the module `funparse`,\nwhich returns a fun that parses a list of tokens:\n\n```erlang\npconst(X) ->\n fun (T) ->\n case T of\n [X|T1] -> {ok, {const, X}, T1};\n _ -> fail\n end\n end.\n```\n\nThis function can be used as follows:\n\n```erlang\n> P1 = funparse:pconst(a).\n#Fun \n> P1([a,b,c]).\n{ok,{const,a},[b,c]}\n> P1([x,y,z]).\nfail\n```\n\nNext, the two higher order functions `pand` and `por` are defined. They combine\nprimitive parsers to produce more complex parsers.\n\nFirst `pand`:\n\n```erlang\npand(P1, P2) ->\n fun (T) ->\n case P1(T) of\n {ok, R1, T1} ->\n case P2(T1) of\n {ok, R2, T2} ->\n {ok, {'and', R1, R2}};\n fail ->\n fail\n end;\n fail ->\n fail\n end\n end.\n```\n\nGiven a parser `P1` for grammar `G1`, and a parser `P2` for grammar `G2`,\n`pand(P1, P2)` returns a parser for the grammar, which consists of sequences of\ntokens that satisfy `G1`, followed by sequences of tokens that satisfy `G2`.\n\n`por(P1, P2)` returns a parser for the language described by the grammar `G1` or\n`G2`:\n\n```erlang\npor(P1, P2) ->\n fun (T) ->\n case P1(T) of\n {ok, R, T1} ->\n {ok, {'or',1,R}, T1};\n fail ->\n case P2(T) of\n {ok, R1, T1} ->\n {ok, {'or',2,R1}, T1};\n fail ->\n fail\n end\n end\n end.\n```\n\nThe original problem was to parse the grammar `(a | b) & (c | d)`. The following\ncode addresses this problem:\n\n```erlang\ngrammar() ->\n pand(\n por(pconst(a), pconst(b)),\n por(pconst(c), pconst(d))).\n```\n\nThe following code adds a parser interface to the grammar:\n\n```erlang\nparse(List) ->\n (grammar())(List).\n```\n\nThe parser can be tested as follows:\n\n```erlang\n> funparse:parse([a,c]).\n{ok,{'and',{'or',1,{const,a}},{'or',1,{const,c}}}}\n> funparse:parse([a,d]).\n{ok,{'and',{'or',1,{const,a}},{'or',2,{const,d}}}}\n> funparse:parse([b,c]).\n{ok,{'and',{'or',2,{const,b}},{'or',1,{const,c}}}}\n> funparse:parse([b,d]).\n{ok,{'and',{'or',2,{const,b}},{'or',2,{const,d}}}}\n> funparse:parse([a,b]).\nfail\n```","ref":"funs.html#parsing"},{"type":"extras","title":"List Comprehensions","doc":"\n# List Comprehensions","ref":"list_comprehensions.html"},{"type":"extras","title":"Simple Examples - List Comprehensions","doc":"This section starts with a simple example, showing a generator and a filter:\n\n```erlang\n> [X || X <- [1,2,a,3,4,b,5,6], X > 3].\n[a,4,b,5,6]\n```\n\nThis is read as follows: The list of X such that X is taken from the list\n`[1,2,a,...]` and X is greater than 3.\n\nThe notation `X <- [1,2,a,...]` is a generator and the expression `X > 3` is a\nfilter.\n\nAn additional filter, [`is_integer(X)`](`is_integer/1`), can be added to\nrestrict the result to integers:\n\n```erlang\n> [X || X <- [1,2,a,3,4,b,5,6], is_integer(X), X > 3].\n[4,5,6]\n```\n\nGenerators can be combined. For example, the Cartesian product of two lists can\nbe written as follows:\n\n```erlang\n> [{X, Y} || X <- [1,2,3], Y <- [a,b]].\n[{1,a},{1,b},{2,a},{2,b},{3,a},{3,b}]\n```","ref":"list_comprehensions.html#simple-examples"},{"type":"extras","title":"Quick Sort - List Comprehensions","doc":"The well-known quick sort routine can be written as follows:\n\n```erlang\nsort([]) -> [];\nsort([_] = L) -> L;\nsort([Pivot|T]) ->\n sort([ X || X <- T, X = Pivot]).\n```\n\nThe expression `[X || X <- T, X = Pivot]` is the list of all elements in `T` that are greater\nthan or equal to `Pivot`.\n\nWith the algorithm above, a list is sorted as follows:\n\n- A list with zero or one element is trivially sorted.\n- For lists with more than one element:\n 1. The first element in the list is isolated as the pivot element.\n 1. The remaining list is partitioned into two sublists, such that:\n - The first sublist contains all elements that are smaller than the pivot\n element.\n - The second sublist contains all elements that are greater than or equal to\n the pivot element.\n 1. The sublists are recursively sorted by the same algorithm and the results\n are combined, resulting in a list consisting of:\n - All elements from the first sublist, that is all elements smaller than the\n pivot element, in sorted order.\n - The pivot element.\n - All elements from the second sublist, that is all elements greater than or\n equal to the pivot element, in sorted order.\n\n> #### Note {: .info }\n>\n> While the sorting algorithm as shown above serves as a nice example to\n> illustrate list comprehensions with filters, for real world use cases the\n> `m:lists` module contains sorting functions that are implemented in a more\n> efficient way.","ref":"list_comprehensions.html#quick-sort"},{"type":"extras","title":"Permutations - List Comprehensions","doc":"The following example generates all permutations of the elements in a list:\n\n```erlang\nperms([]) -> [[]];\nperms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].\n```\n\nThis takes `H` from `L` in all possible ways. The result is the set of all lists\n`[H|T]`, where `T` is the set of all possible permutations of `L`, with `H`\nremoved:\n\n```erlang\n> perms([b,u,g]).\n[[b,u,g],[b,g,u],[u,b,g],[u,g,b],[g,b,u],[g,u,b]]\n```","ref":"list_comprehensions.html#permutations"},{"type":"extras","title":"Pythagorean Triplets - List Comprehensions","doc":"Pythagorean triplets are sets of integers `{A,B,C}` such that\n`A**2 + B**2 = C**2`.\n\nThe function `pyth(N)` generates a list of all integers `{A,B,C}` such that\n`A**2 + B**2 = C**2` and where the sum of the sides is equal to, or less than,\n`N`:\n\n```erlang\npyth(N) ->\n [ {A,B,C} ||\n A <- lists:seq(1,N),\n B <- lists:seq(1,N),\n C <- lists:seq(1,N),\n A+B+C = pyth(3).\n[].\n> pyth(11).\n[].\n> pyth(12).\n[{3,4,5},{4,3,5}]\n> pyth(50).\n[{3,4,5},\n {4,3,5},\n {5,12,13},\n {6,8,10},\n {8,6,10},\n {8,15,17},\n {9,12,15},\n {12,5,13},\n {12,9,15},\n {12,16,20},\n {15,8,17},\n {16,12,20}]\n```\n\nThe following code reduces the search space and is more efficient:\n\n```erlang\npyth1(N) ->\n [{A,B,C} ||\n A <- lists:seq(1,N-2),\n B <- lists:seq(A+1,N-1),\n C <- lists:seq(B+1,N),\n A+B+C =< N,\n A*A+B*B == C*C ].\n```","ref":"list_comprehensions.html#pythagorean-triplets"},{"type":"extras","title":"Simplifications With List Comprehensions - List Comprehensions","doc":"As an example, list comprehensions can be used to simplify some of the functions\nin `lists.erl`:\n\n```erlang\nappend(L) -> [X || L1 <- L, X <- L1].\nmap(Fun, L) -> [Fun(X) || X <- L].\nfilter(Pred, L) -> [X || X <- L, Pred(X)].\n```","ref":"list_comprehensions.html#simplifications-with-list-comprehensions"},{"type":"extras","title":"Variable Bindings in List Comprehensions - List Comprehensions","doc":"The scope rules for variables that occur in list comprehensions are as follows:\n\n- All variables that occur in a generator pattern are assumed to be \"fresh\"\n variables.\n- Any variables that are defined before the list comprehension, and that are\n used in filters, have the values they had before the list comprehension.\n- Variables cannot be exported from a list comprehension.\n\nAs an example of these rules, suppose you want to write the function `select`,\nwhich selects certain elements from a list of tuples. Suppose you write\n`select(X, L) -> [Y || {X, Y} <- L].` with the intention of extracting all\ntuples from `L`, where the first item is `X`.\n\nCompiling this gives the following diagnostic:\n\n```text\n./FileName.erl:Line: Warning: variable 'X' shadowed in generate\n```\n\nThis diagnostic warns that the variable `X` in the pattern is not the same as\nthe variable `X` that occurs in the function head.\n\nEvaluating `select` gives the following result:\n\n```erlang\n> select(b,[{a,1},{b,2},{c,3},{b,7}]).\n[1,2,3,7]\n```\n\nThis is not the wanted result. To achieve the desired effect, `select` must be\nwritten as follows:\n\n```erlang\nselect(X, L) -> [Y || {X1, Y} <- L, X == X1].\n```\n\nThe generator now contains unbound variables and the test has been moved into\nthe filter.\n\nThis now works as expected:\n\n```erlang\n> select(b,[{a,1},{b,2},{c,3},{b,7}]).\n[2,7]\n```\n\nAlso note that a variable in a generator pattern will shadow a variable with the\nsame name bound in a previous generator pattern. For example:\n\n```erlang\n> [{X,Y} || X <- [1,2,3], X=Y <- [a,b,c]].\n[{a,a},{b,b},{c,c},{a,a},{b,b},{c,c},{a,a},{b,b},{c,c}]\n```\n\nA consequence of the rules for importing variables into a list comprehensions is\nthat certain pattern matching operations must be moved into the filters and\ncannot be written directly in the generators.\n\nTo illustrate this, do _not_ write as follows:\n\n```erlang\nf(...) ->\n Y = ...\n [ Expression || PatternInvolving Y <- Expr, ...]\n ...\n```\n\nInstead, write as follows:\n\n```erlang\nf(...) ->\n Y = ...\n [ Expression || PatternInvolving Y1 <- Expr, Y == Y1, ...]\n ...\n```","ref":"list_comprehensions.html#variable-bindings-in-list-comprehensions"},{"type":"extras","title":"Bit Syntax","doc":"\n# Bit Syntax","ref":"bit_syntax.html"},{"type":"extras","title":"Introduction - Bit Syntax","doc":"The complete specification for the bit syntax appears in the\n[Reference Manual](`e:system:expressions.md#bit-syntax-expressions`).\n\nIn Erlang, a Bin is used for constructing binaries and matching binary patterns.\nA Bin is written with the following syntax:\n\n```erlang\n< >\n```\n\nA Bin is a low-level sequence of bits or bytes. The purpose of a Bin is to\nenable construction of binaries:\n\n```erlang\nBin = < >\n```\n\nAll elements must be bound. Or match a binary:\n\n```erlang\n< > = Bin\n```\n\nHere, `Bin` is bound and the elements are bound or unbound, as in any match.\n\nA Bin does not need to consist of a whole number of bytes.\n\nA _bitstring_ is a sequence of zero or more bits, where the number of bits does\nnot need to be divisible by 8. If the number of bits is divisible by 8, the\nbitstring is also a binary.\n\nEach element specifies a certain _segment_ of the bitstring. A segment is a set\nof contiguous bits of the binary (not necessarily on a byte boundary). The first\nelement specifies the initial segment, the second element specifies the\nfollowing segment, and so on.\n\nThe following examples illustrate how binaries are constructed, or matched, and\nhow elements and tails are specified.","ref":"bit_syntax.html#introduction"},{"type":"extras","title":"Examples - Bit Syntax","doc":"_Example 1:_ A binary can be constructed from a set of constants or a string\nliteral:\n\n```erlang\nBin11 = <<1, 17, 42>>,\nBin12 = <<\"abc\">>\n```\n\nThis gives two binaries of size 3, with the following evaluations:\n\n- [`binary_to_list(Bin11)`](`binary_to_list/1`) evaluates to `[1, 17, 42]`.\n- [`binary_to_list(Bin12)`](`binary_to_list/1`) evaluates to `[97, 98, 99]`.\n\n*Example 2:*Similarly, a binary can be constructed from a set of bound\nvariables:\n\n```erlang\nA = 1, B = 17, C = 42,\nBin2 = < >\n```\n\nThis gives a binary of size 4. Here, a _size expression_ is used for the\nvariable `C` to specify a 16-bits segment of `Bin2`.\n\n[`binary_to_list(Bin2)`](`binary_to_list/1`) evaluates to `[1, 17, 00, 42]`.\n\n_Example 3:_ A Bin can also be used for matching. `D`, `E`, and `F` are unbound\nvariables, and `Bin2` is bound, as in Example 2:\n\n```erlang\n< > = Bin2\n```\n\nThis gives `D = 273`, `E = 00`, and F binds to a binary of size 1:\n`binary_to_list(F) = [42]`.\n\n_Example 4:_ The following is a more elaborate example of matching. Here,\n`Dgram` is bound to the consecutive bytes of an IP datagram of IP protocol\nversion 4. The ambition is to extract the header and the data of the datagram:\n\n```erlang\n-define(IP_VERSION, 4).\n-define(IP_MIN_HDR_LEN, 5).\n\nDgramSize = byte_size(Dgram),\ncase Dgram of\n <> when HLen>=5, 4*HLen= \n OptsLen = 4*(HLen - ?IP_MIN_HDR_LEN),\n < > = RestDgram,\n ...\nend.\n```\n\nHere, the segment corresponding to the `Opts` variable has a _type modifier_,\nspecifying that `Opts` is to bind to a binary. All other variables have the\ndefault type equal to unsigned integer.\n\nAn IP datagram header is of variable length. This length is measured in the\nnumber of 32-bit words and is given in the segment corresponding to `HLen`. The\nminimum value of `HLen` is 5. It is the segment corresponding to `Opts` that is\nvariable, so if `HLen` is equal to 5, `Opts` becomes an empty binary.\n\nThe tail variables `RestDgram` and `Data` bind to binaries, as all tail\nvariables do. Both can bind to empty binaries.\n\nThe match of `Dgram` fails if one of the following occurs:\n\n- The first 4-bits segment of `Dgram` is not equal to 4.\n- `HLen` is less than 5.\n- The size of `Dgram` is less than `4*HLen`.","ref":"bit_syntax.html#examples"},{"type":"extras","title":"Lexical Note - Bit Syntax","doc":"Notice that \"`B=<<1>>`\" will be interpreted as \"`B =< <1>>`\", which is a syntax\nerror. The correct way to write the expression is: `B = <<1>>`.","ref":"bit_syntax.html#lexical-note"},{"type":"extras","title":"Segments - Bit Syntax","doc":"Each segment has the following general syntax:\n\n`Value:Size/TypeSpecifierList`\n\nThe `Size` or the `TypeSpecifier`, or both, can be omitted. Thus, the following\nvariants are allowed:\n\n- `Value`\n- `Value:Size`\n- `Value/TypeSpecifierList`\n\nDefault values are used when specifications are missing. The default values are\ndescribed in [Defaults](#defaults).\n\nThe `Value` part is any expression, when used in binary construction. Used in\nbinary matching, the `Value` part must be a literal or a variable. For more\ninformation about the `Value` part, see\n[Constructing Binaries and Bitstrings](#constructing-binaries-and-bitstrings)\nand [Matching Binaries](#matching-binaries).\n\nThe `Size` part of the segment multiplied by the unit in `TypeSpecifierList`\n(described later) gives the number of bits for the segment. In construction,\n`Size` is any expression that evaluates to an integer. In matching, `Size` must\nbe a constant expression or a variable.\n\nThe `TypeSpecifierList` is a list of type specifiers separated by hyphens.\n\n- **Type** - The most commonly used types are `integer`, `float`, and `binary`.\n See\n [Bit Syntax Expressions in the Reference Manual](`e:system:expressions.md#bit-syntax-expressions`)\n for a complete description.\n\n- **Signedness** - The signedness specification can be either `signed` or\n `unsigned`. Notice that signedness only matters for matching.\n\n- **Endianness** - The endianness specification can be either `big`, `little`,\n or `native`. Native-endian means that the endian is resolved at load time, to\n be either big-endian or little-endian, depending on what is \"native\" for the\n CPU that the Erlang machine is run on.\n\n- **Unit** - The unit size is given as `unit:IntegerLiteral`. The allowed range\n is 1-256. It is multiplied by the `Size` specifier to give the effective size\n of the segment. The unit size specifies the alignment for binary segments\n without size.\n\n_Example:_\n\n```text\nX:4/little-signed-integer-unit:8\n```\n\nThis element has a total size of 4\\*8 = 32 bits, and it contains a signed\ninteger in little-endian order.","ref":"bit_syntax.html#segments"},{"type":"extras","title":"Defaults - Bit Syntax","doc":"The default type for a segment is integer. The default type\ndoes not depend on the value, even if the value is a literal. For example, the\ndefault type in `<<3.14>>` is integer, not float.\n\nThe default `Size` depends on the type. For integer it is 8. For float it is 64.\nFor binary it is all of the binary. In matching, this default value is only\nvalid for the last element. All other binary elements in matching must have a\nsize specification.\n\nThe default unit depends on the type. For `integer`, `float`, and `bitstring` it\nis 1. For binary it is 8.\n\nThe default signedness is `unsigned`.\n\nThe default endianness is `big`.","ref":"bit_syntax.html#defaults"},{"type":"extras","title":"Constructing Binaries and Bitstrings - Bit Syntax","doc":"This section describes the rules for constructing binaries using the bit syntax.\nUnlike when constructing lists or tuples, the construction of a binary can fail\nwith a `badarg` exception.\n\nThere can be zero or more segments in a binary to be constructed. The expression\n`<<>>` constructs a zero length binary.\n\nEach segment in a binary can consist of zero or more bits. There are no\nalignment rules for individual segments of type `integer` and `float`. For\nbinaries and bitstrings without size, the unit specifies the alignment. Since\nthe default alignment for the `binary` type is 8, the size of a binary segment\nmust be a multiple of 8 bits, that is, only whole bytes.\n\n_Example:_\n\n```erlang\n< >\n```\n\nThe variable `Bin` must contain a whole number of bytes, because the `binary`\ntype defaults to `unit:8`. A `badarg` exception is generated if `Bin` consist\nof, for example, 17 bits.\n\nThe `Bitstring` variable can consist of any number of bits, for example, 0, 1,\n8, 11, 17, 42, and so on. This is because the default `unit` for bitstrings\nis 1.\n\nFor clarity, it is recommended not to change the unit size for binaries.\nInstead, use `binary` when you need byte alignment and `bitstring` when you need\nbit alignment.\n\nThe following example successfully constructs a bitstring of 7 bits, provided\nthat all of X and Y are integers:\n\n```erlang\n< >\n```\n\nAs mentioned earlier, segments have the following general syntax:\n\n`Value:Size/TypeSpecifierList`\n\nWhen constructing binaries, `Value` and `Size` can be any Erlang expression.\nHowever, for syntactical reasons, both `Value` and `Size` must be enclosed in\nparenthesis if the expression consists of anything more than a single literal or\na variable. The following gives a compiler syntax error:\n\n```erlang\n< >\n```\n\nThis expression must be rewritten into the following, to be accepted by the\ncompiler:\n\n```erlang\n<<(X+1):8>>\n```","ref":"bit_syntax.html#constructing-binaries-and-bitstrings"},{"type":"extras","title":"Including Literal Strings - Bit Syntax","doc":"A literal string can be written instead of an element:\n\n```erlang\n<<\"hello\">>\n```\n\nThis is syntactic sugar for the following:\n\n```erlang\n<<$h,$e,$l,$l,$o>>\n```","ref":"bit_syntax.html#including-literal-strings"},{"type":"extras","title":"Matching Binaries - Bit Syntax","doc":"This section describes the rules for matching binaries, using the bit syntax.\n\nThere can be zero or more segments in a binary pattern. A binary pattern can\noccur wherever patterns are allowed, including inside other patterns. Binary\npatterns cannot be nested. The pattern `<<>>` matches a zero length binary.\n\nEach segment in a binary can consist of zero or more bits. A segment of type\n`binary` must have a size evenly divisible by 8 (or divisible by the unit size,\nif the unit size has been changed). A segment of type `bitstring` has no\nrestrictions on the size. A segment of type `float` must have size 64 or 32.\n\nAs mentioned earlier, segments have the following general syntax:\n\n`Value:Size/TypeSpecifierList`\n\nWhen matching `Value`, value must be either a variable or an integer, or a\nfloating point literal. Expressions are not allowed.\n\n`Size` must be a\n[guard expression](`e:system:expressions.md#guard-expressions`), which can use\nliterals and previously bound variables. The following is not allowed:\n\n```erlang\nfoo(N, < >) ->\n {X,T}.\n```\n\nThe two occurrences of `N` are not related. The compiler will complain that the\n`N` in the size field is unbound.\n\nThe correct way to write this example is as follows:\n\n```erlang\nfoo(N, Bin) ->\n < > = Bin,\n {X,T}.\n```\n\n> #### Note {: .info }\n>\n> Before OTP 23, `Size` was restricted to be an integer or a variable bound to\n> an integer.","ref":"bit_syntax.html#matching-binaries"},{"type":"extras","title":"Binding and Using a Size Variable - Bit Syntax","doc":"There is one exception to the rule that a variable that is used as size must be\npreviously bound. It is possible to match and bind a variable, and use it as a\nsize within the same binary pattern. For example:\n\n```erlang\nbar(< >) ->\n {Payload,Rest}.\n```\n\nHere `Sz` is bound to the value in the first byte of the binary. `Sz` is then\nused at the number of bytes to match out as a binary.\n\nStarting in OTP 23, the size can be a guard expression:\n\n```erlang\nbar(< >) ->\n {Payload,Rest}.\n```\n\nHere `Sz` is the combined size of the header and the payload, so we will need to\nsubtract one byte to get the size of the payload.","ref":"bit_syntax.html#binding-and-using-a-size-variable"},{"type":"extras","title":"Getting the Rest of the Binary or Bitstring - Bit Syntax","doc":"To match out the rest of a binary, specify a binary field without size:\n\n```erlang\nfoo(< >) ->\n```\n\nThe size of the tail must be evenly divisible by 8.\n\nTo match out the rest of a bitstring, specify a field without size:\n\n```erlang\nfoo(< >) ->\n```\n\nThere are no restrictions on the number of bits in the tail.","ref":"bit_syntax.html#getting-the-rest-of-the-binary-or-bitstring"},{"type":"extras","title":"Appending to a Binary - Bit Syntax","doc":"Appending to a binary in an efficient way can be done as follows:\n\n```erlang\ntriples_to_bin(T) ->\n triples_to_bin(T, <<>>).\n\ntriples_to_bin([{X,Y,Z} | T], Acc) ->\n triples_to_bin(T, < >);\ntriples_to_bin([], Acc) ->\n Acc.\n```","ref":"bit_syntax.html#appending-to-a-binary"},{"type":"extras","title":"Introduction","doc":"\n# Introduction\n\n[](){: #erlang-ref-manual }\n\nThis section is the Erlang reference manual. It describes the Erlang programming\nlanguage.","ref":"reference_manual.html"},{"type":"extras","title":"Purpose - Introduction","doc":"The focus of the Erlang reference manual is on the language itself, not the\nimplementation of it. The language constructs are described in text and with\nexamples rather than formally specified. This is to make the manual more\nreadable. The Erlang reference manual is not intended as a tutorial.\n\nInformation about implementation of Erlang can, for example, be found, in the\nfollowing:\n\n- [System Principles](`e:system:system_principles.md`)\n\n Starting and stopping, boot scripts, code loading,\n [logging](`e:system:error_logging.md`),\n [creating target systems](`e:system:create_target.md`)\n\n- [Efficiency Guide](`e:system:efficiency_guide.md`)\n\n [Memory consumption](`e:system:memory.md`) and\n [system limits](`e:system:system_limits.md`).\n\n- ERTS User's Guide\n\n [Crash dumps](`e:erts:crash_dump.md`), [NIFs](`e:erts:erl_nif.md`),\n [drivers](`e:erts:driver.md`)","ref":"reference_manual.html#purpose"},{"type":"extras","title":"Prerequisites - Introduction","doc":"It is assumed that the reader has done some programming and is familiar with\nconcepts such as data types and programming language syntax.","ref":"reference_manual.html#prerequisites"},{"type":"extras","title":"Document Conventions - Introduction","doc":"In this section, the following terminology is used:\n\n- A _sequence_ is one or more items. For example, a clause body consists of a\n sequence of expressions. This means that there must be at least one\n expression.\n- A _list_ is any number of items. For example, an argument list can consist of\n zero, one, or more arguments.\n\nIf a feature has been added in R13A or later, this is mentioned in the text.","ref":"reference_manual.html#document-conventions"},{"type":"extras","title":"Complete List of BIFs - Introduction","doc":"For a complete list of BIFs, their arguments and return values, see module `m:erlang`\nin ERTS.","ref":"reference_manual.html#complete-list-of-bifs"},{"type":"extras","title":"Reserved Words - Introduction","doc":"The following are reserved words in Erlang:\n\n`after and andalso band begin bnot bor bsl bsr bxor case catch cond div else end fun if let maybe not of or orelse receive rem try when xor`\n\n**Note**: `cond` and `let`, while reserved, are currently not used by the\nlanguage.\n\n> #### Change {: .info }\n>\n> `maybe` is a reserved word only if feature `maybe_expr` is enabled. In\n> Erlang/OTP 25 and 26, `maybe_expr` is disabled by default. Starting from\n> Erlang/OTP 27, `maybe_expr` is enabled by default.","ref":"reference_manual.html#reserved-words"},{"type":"extras","title":"Character Set and Source File Encoding","doc":"\n# Character Set and Source File Encoding","ref":"character_set.html"},{"type":"extras","title":"Character Set - Character Set and Source File Encoding","doc":"The syntax of Erlang tokens allow the use of the full ISO-8859-1 (Latin-1)\ncharacter set. This is noticeable in the following ways:\n\n- All the Latin-1 printable characters can be used and are shown without the\n escape backslash convention.\n- Unquoted atoms and variables can use all Latin-1 letters.\n\n| _Octal_ | _Decimal_ |   | _Class_ |\n| --------- | --------- | ----- | ---------------------- |\n| 200 - 237 | 128 - 159 |   | Control characters |\n| 240 - 277 | 160 - 191 | \\- ¿ | Punctuation characters |\n| 300 - 326 | 192 - 214 | À - Ö | Uppercase letters |\n| 327 | 215 | × | Punctuation character |\n| 330 - 336 | 216 - 222 | Ø - Þ | Uppercase letters |\n| 337 - 366 | 223 - 246 | ß - ö | Lowercase letters |\n| 367 | 247 | ÷ | Punctuation character |\n| 370 - 377 | 248 - 255 | ø - ÿ | Lowercase letters |\n\n_Table: Character Classes_\n\nThe following tokens are allowed to also use Unicode characters outside of the\nLatin-1 range:\n\n- String literals. Example: `\"√π\"`\n- Character literals. Example: `$∑`\n- Comments in code.\n- Quoted atoms. Example: `'μs'`\n- Function names. Example: `'s_to_μs'(S) -> S * 1_000_000.`\n\nAtoms used as module names, application names, and node names are restricted to\nthe Latin-1 range.\n\n> #### Change {: .info }\n>\n> Support for Unicode in string literals, character literals, and comments was\n> introduced in Erlang/OTP R16B. Support for Unicode in atom and function names\n> was introduced in Erlang/OTP 20.","ref":"character_set.html#character-set"},{"type":"extras","title":"Source File Encoding - Character Set and Source File Encoding","doc":"[](){: #encoding }\n\nThe Erlang source file `encoding` is selected by a comment in one of the first\ntwo lines of the source file. The first string that matches the regular\nexpression `coding\\s*[:=]\\s*([-a-zA-Z0-9])+` selects the encoding. If the\nmatching string is an invalid encoding, it is ignored. The valid encodings are\n`Latin-1` and `UTF-8`, where the case of the characters can be chosen freely.\n\nThe default Erlang source file encoding if no valid `coding` comment is present\nis UTF-8.\n\nTwo examples, both selecting Latin-1 as the source file encoding:\n\n```text\n%% For this file we have chosen encoding = Latin-1\n```\n\n```erlang\n%% -*- coding: latin-1 -*-\n```\n\n> #### Change {: .info }\n>\n> The default encoding for Erlang source files was changed from Latin-1 to UTF-8\n> in Erlang/OTP 17.0.","ref":"character_set.html#source-file-encoding"},{"type":"extras","title":"Data Types","doc":"\n# Data Types\n\nErlang provides a number of data types, which are listed in this section.\n\n[](){: #no_user_types }\n\nNote that Erlang has no user defined types, only composite types (data\nstructures) made of Erlang terms. This means that any function testing for a\ncomposite type, typically named `is_type/1`, might return `true` for a term that\ncoincides with the chosen representation. The corresponding functions for built\nin types do not suffer from this.","ref":"data_types.html"},{"type":"extras","title":"Terms - Data Types","doc":"A piece of data of any data type is called a _term_.","ref":"data_types.html#terms"},{"type":"extras","title":"Number - Data Types","doc":"There are two types of numeric literals, _integers_ and _floats_. Besides the\nconventional notation, there are two Erlang-specific notations:\n\n- `$`_`char`_ \n ASCII value or unicode code-point of the character _`char`_.\n- _`base`_`#`_`value`_ \n Integer with the base _`base`_, which must be an integer in the range 2\n through 36.\n\nLeading zeroes are ignored. Single underscore characters (`_`) can be\ninserted between digits as a visual separator.\n\n_Examples:_\n\n```text\n1> 42.\n42\n2> -1_234_567_890.\n-1234567890\n3> $A.\n65\n4> $\\n.\n10\n5> 2#101.\n5\n6> 16#1f.\n31\n7> 16#4865_316F_774F_6C64.\n5216630098191412324\n8> 2.3.\n2.3\n9> 2.3e3.\n2.3e3\n10> 2.3e-3.\n0.0023\n11> 1_234.333_333\n1234.333333\n12> 36#helloworld.\n1767707668033969\n```\n\n[](){: #numeric_comparisons }","ref":"data_types.html#number"},{"type":"extras","title":"Comparisons - Data Types","doc":"Both integers and floats share the same linear order. That is, `1` compares less\nthan `2.4`, `3` compares greater than `2.99999`, and `5` is equal to `5.0`.\n\nWhen wanting to compare an integer with another integer or a float with another\nfloat, it may be tempting to use the term equivalence operators (`=:=`, `=/=`)\nor pattern matching. This works for integers which has a distinct representation\nfor every number, but there's a surprising edge case for floating-point as the\nlatter has two representations for zero which are considered different by the\nterm equivalence operators and pattern matching.\n\nIf you wish to compare floating-point numbers _numerically_, use the regular\ncomparison operators (such as `==`) and add guards that require both the\narguments to be floating-point.\n\n> #### Note {: .info }\n>\n> Prior to OTP 27, the term equivalence operators had a bug where they\n> considered `0.0` and `-0.0` to be the same term. Legacy code that makes\n> equality comparisons on floating-point zero should migrate to using the\n> equal-to (`==`) operator with [`is_float/1`](`is_float/1`) guards, and\n> compiler warnings have been added to that effect. These can be silenced by\n> writing `+0.0` instead, which is the same as `0.0` but makes the compiler\n> interpret the comparison as being purposely made against `0.0`.\n>\n> Note that this does _not_ break compatibility with IEEE 754 which mandates\n> that `0.0` and `-0.0` should compare equal: they are equal when interpreted as\n> numbers (`==`), and unequal when interpreted as opaque terms (`=:=`).\n\n[](){: #float_representation_problem }\n\n_Examples_:\n\n```erlang\n1> 0.0 =:= +0.0.\ntrue\n2> 0.0 =:= -0.0.\nfalse\n3> +0.0 =:= -0.0.\nfalse\n4> +0.0 == -0.0.\ntrue\n```","ref":"data_types.html#comparisons"},{"type":"extras","title":"Representation of Floating Point Numbers - Data Types","doc":"When working with floats you may not see what you expect when printing or doing\narithmetic operations. This is because floats are represented by a fixed number\nof bits in a base-2 system while printed floats are represented with a base-10\nsystem. Erlang uses 64-bit floats. Here are examples of this phenomenon:\n\n```erlang\n1> 0.1+0.2.\n0.30000000000000004\n```\n\nThe real numbers `0.1` and `0.2` cannot be represented exactly as floats.\n\n```erlang\n1> {36028797018963968.0, 36028797018963968 == 36028797018963968.0,\n 36028797018963970.0, 36028797018963970 == 36028797018963970.0}.\n{3.602879701896397e16, true,\n 3.602879701896397e16, false}.\n```\n\nThe value `36028797018963968` can be represented exactly as a float value but\nErlang's pretty printer rounds `36028797018963968.0` to `3.602879701896397e16`\n(`=36028797018963970.0`) as all values in the range\n`[36028797018963966.0, 36028797018963972.0]` are represented by\n`36028797018963968.0`.\n\nFor more information about floats and issues with them see:\n\n- [What Every Programmer Should Know About Floating-Point Arithmetic](https://floating-point-gui.de/)\n- [0\\.30000000000000004.com/](https://0.30000000000000004.com/)\n- [Floating Point Arithmetic: Issues and Limitations](https://docs.python.org/3/tutorial/floatingpoint.html)\n\nIf you need to work with exact decimal fractions, for instance to represent\nmoney, it is recommended to use a library that handles that, or work in\ncents instead of dollars or euros so that decimal fractions are not needed.\n\nAlso note that Erlang's floats do not exactly match IEEE 754 floats,\nin that neither _Inf_ nor _NaN_ are supported in Erlang. Any\noperation that would result in _NaN_, _+Inf_, or _-Inf_, will instead raise\na `badarith` exception.\n\n_Examples_:\n\n```erlang\n1> 1.0 / 0.0.\n** exception error: an error occurred when evaluating an arithmetic expression\n in operator '/'/2\n called as 1.0 / 0.0\n2> 0.0 / 0.0.\n** exception error: an error occurred when evaluating an arithmetic expression\n in operator '/'/2\n called as 0.0 / 0.0\n```","ref":"data_types.html#representation-of-floating-point-numbers"},{"type":"extras","title":"Atom - Data Types","doc":"An atom is a literal, a constant with name. An atom is to be enclosed in single\nquotes (`'`) if it does not begin with a lower-case letter or if it contains other\ncharacters than alphanumeric characters, underscore (`_`), or `@`.\n\n_Examples:_\n\n```text\nhello\nphone_number\nname@node\n'Monday'\n'phone number'\n```","ref":"data_types.html#atom"},{"type":"extras","title":"Bit Strings and Binaries - Data Types","doc":"A bit string is used to store an area of untyped memory.\n\nBit strings are expressed using the [bit syntax](expressions.md#bit-syntax-expressions).\n\nBit strings that consist of a number of bits that are evenly divisible\nby eight are called _binaries_.\n\n_Examples:_\n\n```text\n1> <<10,20>>.\n<<10,20>>\n2> <<\"ABC\">>.\n<<\"ABC\">>\n3> <<1:1,0:1>>.\n<<2:2>>\n```\n\nThe [`is_bitstring/1`](`erlang:is_bitstring/1`) BIF tests whether a\nterm is a bit string, and the [`is_binary/1`](`erlang:is_binary/1`)\nBIF tests whether a term is a binary.\n\n_Examples:_\n\n```erlang\n1> is_bitstring(<<1:1>>).\ntrue\n2> is_binary(<<1:1>>).\nfalse\n3> is_binary(<<42>>).\ntrue\n\n```\n\nFor more examples, see [Programming Examples](`e:system:bit_syntax.md`).","ref":"data_types.html#bit-strings-and-binaries"},{"type":"extras","title":"Reference - Data Types","doc":"A term that is [unique](`e:system:system_limits.md#unique_references`)\namong connected nodes. A reference is created by calling the\n[`make_ref/0`](`erlang:make_ref/0`) BIF. The\n[`is_reference/1`](`erlang:is_reference/1`) BIF tests whether a term\nis a reference.\n\n_Examples:_\n\n```erlang\n1> Ref = make_ref().\n#Ref<0.76482849.3801088007.198204>\n2> is_reference(Ref).\ntrue\n```","ref":"data_types.html#reference"},{"type":"extras","title":"Fun - Data Types","doc":"A fun is a functional object. Funs make it possible to create an anonymous\nfunction and pass the function itself — not its name — as argument to other\nfunctions.\n\n_Examples:_\n\n```erlang\n1> Fun1 = fun (X) -> X+1 end.\n#Fun \n2> Fun1(2).\n3\n```\n\nThe [`is_function/1`](`erlang:is_function/1`) and [`is_function/2`](`erlang:is_function/2`)\nBIFs tests whether a term is a fun.\n\n_Examples_:\n\n```erlang\n1> F = fun() -> ok end.\n#Fun \n2> is_function(F).\ntrue\n3> is_function(F, 0).\ntrue\n4> is_function(F, 1).\nfalse\n```\n\nRead more about funs in [Fun Expressions](expressions.md#fun-expressions). For more\nexamples, see [Programming Examples](`e:system:funs.md`).","ref":"data_types.html#fun"},{"type":"extras","title":"Port Identifier - Data Types","doc":"A port identifier identifies an Erlang port.\n\n[`open_port/2`](`open_port/2`) returns a port identifier. The\n[`is_port/1`](`erlang:is_port/1`) BIF tests whether a term is a port\nidentifier.\n\nRead more about ports in [Ports and Port Drivers](ports.md).","ref":"data_types.html#port-identifier"},{"type":"extras","title":"Pid - Data Types","doc":"Pid is an abbreviation for process identifier. Each process has a Pid which\nidentifies the process. Pids are unique among processes that are alive on\nconnected nodes. However, a Pid of a terminated process may be reused as a Pid\nfor a new process after a while.\n\nThe BIF [`self/0`](`erlang:self/0`) returns the Pid of the calling process. When\n[creating a new process](ref_man_processes.md#process-creation), the parent\nprocess will be able to get the Pid of the child process either via the return\nvalue, as is the case when calling the [`spawn/3`](`erlang:spawn/3`) BIF, or via\na message, which is the case when calling the\n[`spawn_request/5`](`erlang:spawn_request/5`) BIF. A Pid is typically used when\nwhen sending a process a [signal](ref_man_processes.md#signals). The\n[`is_pid/1`](`erlang:is_pid/1`) BIF tests whether a term is a Pid.\n\n_Example:_\n\n```erlang\n-module(m).\n-export([loop/0]).\n\nloop() ->\n receive\n who_are_you ->\n io:format(\"I am ~p~n\", [self()]),\n loop()\n end.\n\n1> P = spawn(m, loop, []).\n<0.58.0>\n2> P ! who_are_you.\nI am <0.58.0>\nwho_are_you\n```\n\nRead more about processes in [Processes](ref_man_processes.md).","ref":"data_types.html#pid"},{"type":"extras","title":"Tuple - Data Types","doc":"A tuple is a compound data type with a fixed number of terms:\n\n```text\n{Term1,...,TermN}\n```\n\nEach term `Term` in the tuple is called an _element_. The number of elements is\nsaid to be the _size_ of the tuple.\n\nThere exists a number of BIFs to manipulate tuples.\n\n_Examples:_\n\n```erlang\n1> P = {adam,24,{july,29}}.\n{adam,24,{july,29}}\n2> element(1,P).\nadam\n3> element(3,P).\n{july,29}\n4> P2 = setelement(2,P,25).\n{adam,25,{july,29}}\n5> tuple_size(P).\n3\n6> tuple_size({}).\n0\n7> is_tuple({a,b,c}).\ntrue\n```","ref":"data_types.html#tuple"},{"type":"extras","title":"Map - Data Types","doc":"A map is a compound data type with a variable number of key-value associations:\n\n```text\n#{Key1 => Value1, ..., KeyN => ValueN}\n```\n\nEach key-value association in the map is called an _association pair_. The key\nand value parts of the pair are called _elements_. The number of association\npairs is said to be the _size_ of the map.\n\nThere exists a number of BIFs to manipulate maps.\n\n_Examples:_\n\n```erlang\n1> M1 = #{name => adam, age => 24, date => {july,29}}.\n#{age => 24,date => {july,29},name => adam}\n2> maps:get(name, M1).\nadam\n3> maps:get(date, M1).\n{july,29}\n4> M2 = maps:update(age, 25, M1).\n#{age => 25,date => {july,29},name => adam}\n5> map_size(M).\n3\n6> map_size(#{}).\n0\n```\n\nA collection of maps processing functions are found in module `m:maps`\nin STDLIB.\n\nRead more about maps in [Map Expressions](expressions.md#map-expressions).\n\n> #### Change {: .info }\n>\n> Maps were introduced as an experimental feature in Erlang/OTP R17. Their\n> functionality was extended and became fully supported in Erlang/OTP 18.","ref":"data_types.html#map"},{"type":"extras","title":"List - Data Types","doc":"A list is a compound data type with a variable number of terms.\n\n```text\n[Term1,...,TermN]\n```\n\nEach term `Term` in the list is called an _element_. The number of elements is\nsaid to be the _length_ of the list.\n\nFormally, a list is either the empty list `[]` or consists of a _head_ (first\nelement) and a _tail_ (remainder of the list). The _tail_ is also a list. The\nlatter can be expressed as `[H|T]`. The notation `[Term1,...,TermN]` above is\nequivalent with the list `[Term1|[...|[TermN|[]]]]`.\n\n_Example:_\n\n`[]` is a list, thus \n`[c|[]]` is a list, thus \n`[b|[c|[]]]` is a list, thus \n`[a|[b|[c|[]]]]` is a list, or in short `[a,b,c]`\n\nA list where the tail is a list is sometimes called a _proper list_. It is\nallowed to have a list where the tail is not a list, for example, `[a|b]`.\nHowever, this type of list is of little practical use.\n\n_Examples:_\n\n```erlang\n1> L1 = [a,2,{c,4}].\n[a,2,{c,4}]\n2> [H|T] = L1.\n[a,2,{c,4}]\n3> H.\na\n4> T.\n[2,{c,4}]\n5> L2 = [d|T].\n[d,2,{c,4}]\n6> length(L1).\n3\n7> length([]).\n0\n```\n\nA collection of list processing functions are found in module\n`m:lists` in STDLIB.","ref":"data_types.html#list"},{"type":"extras","title":"String - Data Types","doc":"Strings are enclosed in double quotes (\"), but is not a data type in Erlang.\nInstead, a string `\"hello\"` is shorthand for the list `[$h,$e,$l,$l,$o]`, that\nis, `[104,101,108,108,111]`.\n\nTwo adjacent string literals are concatenated into one. This is done in the\ncompilation.\n\n_Example:_\n\n```text\n\"string\" \"42\"\n```\n\nis equivalent to\n\n```text\n\"string42\"\n```\n\n> #### Change {: .info }\n>\n> Starting with Erlang/OTP 27 two adjacent string literals have to be separated\n> by white space, or otherwise it is a syntax error. This avoids possible confusion\n> with _triple-quoted strings_.\n\n[](){: #tqstring } Strings can also be written as _triple-quoted strings_, which\ncan be _indented_ over multiple lines to follow the indentation of the\nsurrounding code. They are also _verbatim_, that is, they do not allow escape\nsequences, and thereby do not need double quote characters to be escaped.\n\n> #### Change {: .info }\n>\n> Triple-quoted strings were added in Erlang/OTP 27. Before that 3 consecutive\n> double quote characters had a different meaning. There were absolutely no good\n> reason to write such a character sequence before triple-quoted strings\n> existed, but there _are_ some gotchas; see the\n> [Warning ](data_types.md#triple-quoted-strings-warning) at the end of this\n> description of triple-quoted strings.\n\nExample, with verbatim double quote characters:\n\n```text\n\"\"\"\n Line \"1\"\n Line \"2\"\n \"\"\"\n```\n\nThat is equivalent to the normal single quoted string (which also allows\nnewlines):\n\n```text\n\"Line \\\"1\\\"\nLine \\\"2\\\"\"\n```\n\nThe opening and the closing line has got the delimiters: the `\"\"\"` characters.\nThe lines between them are the content lines. The newline on the opening line is\nnot regarded as string content, nor is the newline on the last content line.\n\nThe indentation is defined by the white space character sequence preceding the\ndelimiter on the closing line. That character sequence is stripped from all\ncontent lines. There can only be white space before the delimiter on the closing\nline, or else it is regarded as a content line.\n\nThe opening line is not allowed to have any characters other than white space\nafter the delimiter, and all content lines must start with the defined\nindentation character sequence, otherwise the string has a syntax error.\n\nHere is a larger example:\n\n```text\nX = \"\"\"\n First line starting with two spaces\n Not escaped: \"\\t \\r \\xFF\" and \"\"\"\n\n \"\"\"\n```\n\nThat corresponds to the normal string:\n\n```text\nX = \" First line starting with two spaces\nNot escaped: \\\"\\\\t \\\\r \\\\xFF\\\" and \\\"\\\"\\\"\n\"\n```\n\nIt is possible to write consecutive double quote characters on the\nbeginning of a content line by using more double quote characters as\ndelimiters. This is a string that contains exactly four double quote\ncharacters, using a delimiter with five double quote characters:\n\n```text\n\"\"\"\"\"\n\"\"\"\"\n\"\"\"\"\"\n```\n\nThese strings are all the empty string:\n\n```text\n\"\"\n```\n\n```text\n\"\"\"\n\"\"\"\n```\n\n```text\n\"\"\"\n\n \"\"\"\n```\n\n[](){: #triple-quoted-strings-warning }\n\n> #### Warning {: .warning }\n>\n> Before Erlang/OTP 27, when triple-quoted strings were added, the character\n> sequence `\"\"\"` was interpreted as `\"\" \"`, which means concatenating the empty\n> string to the string that follows. All sequences of an odd number of double\n> quote characters had this meaning.\n>\n> Any even number of double quote characters was interpreted as a sequence of\n> empty strings, that were concatenated (to the empty string).\n>\n> There was no reason to write such character sequences. But should that have\n> happened, the meaning has probably changed with the introduction of triple-quoted\n> strings.\n>\n> The compiler preprocessor was patched in Erlang/OTP 26.1 to warn about 3 or\n> more sequential double quote characters. In Erlang/OTP 26.2 this was improved\n> to warn about adjacent string literals without intervening white space, which\n> also covers the same problem at a string end.\n>\n> If the compiler should emit such a warning, please change such double quote\n> character sequences to have a whitespace after every second quote character,\n> remove redundant empty strings, or write them as one string. This makes the\n> code more readable, and means the same thing in all releases.","ref":"data_types.html#string"},{"type":"extras","title":"Sigil - Data Types","doc":"A _sigil_ is a prefix to a string literal. It is not a data type in Erlang, but\na shorthand notation that indicates how to interpret the string literal. Sigils\noffer mainly two things: a compact way to create UTF-8 encoded binary strings,\nand a way to write verbatim strings (not having to escape `\\` characters),\nuseful for regular expressions, for example.\n\nA sigil starts with the Tilde character (`~`) followed by a name defining the\nsigil type.\n\nImmediately after follows the sigil content; a character sequence between\ncontent delimiters. The allowed delimiters are these start-end delimiter pairs:\n`() [] {} <>`, or these characters that are both start and end delimiters:\n``/ | ' \" ` #``. [Triple-quote](data_types.md#tqstring) string delimiters may\nalso be used.\n\nThe [character escaping rules ](data_types.md#escape-sequences)for the sigil\ncontent depends on the sigil type. When the sigil content is _verbatim_, there\nis no escape character. The sigil content simply ends when the end delimiter is\nfound, so it is impossible to have the end delimiter character in the string\ncontent. The set of delimiters is fairly generous, and in most cases it is\npossible to choose an end delimiter that's not in the literal string content.\n\n[Triple-quote](data_types.md#tqstring) string delimiters allow choosing a larger\nnumber of quote characters in the end delimiter, than whatever is in the string\ncontent, which thereby facilitates any content also with a sequence of `\"`\ncharacters at the start of a line even for a _verbatim_ string.\n\nThe Sigils are:\n\n- **`~`** - The Vanilla (default) Sigil. Shorthand for a UTF-8 encoded\n `t:binary/0`. This sigil does not affect the character escaping rules, so with\n triple-quoted string delimiters they are the same as for `~B`, and for other\n string delimiters they are the same as for `~b`.\n\n- **`~b`** - The Binary Sigil. Shorthand for a\n [UTF-8 encoded `binary()`](`t:unicode:unicode_binary/0`), as if calling\n [`unicode:characters_to_binary/1` ](`unicode:characters_to_binary/1`)on the\n sigil content. Character escaping rules are the same as for `~s`.\n\n- **`~B`** - The Verbatim Binary Sigil. As `~b`, but the sigil content is\n verbatim.\n\n- **`~s`** - The String Sigil. Shorthand for a\n [`string()`](`t:erlang:string/0`), that is, a `[char()]` which is a list of\n Unicode codepoints.\n [Character escaping rules ](data_types.md#escape-sequences)are the same as for\n a normal `t:string/0`. Using this sigil on a regular string does effectively\n nothing.\n\n- **`~S`** - The Verbatim String Sigil. As `~s`, but the sigil content is\n verbatim. Using this sigil on a triple-quoted string does effectively nothing.\n\nExamples\n\n```text\n<<\"\\\"\\\\µA\\\"\"/utf8>> = <<$\",$\\\\,194,181,$A,$\">> =\n ~b\"\"\"\n \"\\\\µA\"\n \"\"\" = ~b'\"\\\\µA\"' =\n ~B\"\"\"\n \"\\µA\"\n \"\"\" = ~B<\"\\µA\"> =\n ~\"\"\"\n \"\\µA\"\n \"\"\" = ~\"\\\"\\\\µA\\\"\" = ~/\"\\\\µA\"/\n```\n\n```text\n[$\",$\\\\,$µ,$A,$\"] =\n ~s\"\"\"\n \"\\\\µA\"\n \"\"\" = ~s\"\\\"\\\\µA\\\"\" = ~s[\"\\\\µA\"] =\n ~S\"\"\"\n \"\\µA\"\n \"\"\" = ~S(\"\\µA\") =\n \"\"\"\n \"\\µA\"\n \"\"\" = \"\\\"\\\\µA\\\"\"\n```\n\nAdjacent strings are concatenated in the compilation, but that is not possible\nwith sigils, since they are transformed into terms that in general may not be\nconcatenated. So, `\"a\" \"b\"` is equivalent to `\"ab\"`, but `~s\"a\" \"b\"` or\n`~s\"a\" ~s\"b\"` is a syntax error. `~s\"a\" ++ \"b\"`, however, evaluates to `\"ab\"`\nsince both operands to the `++` operator are strings.\n\n> #### Change {: .info }\n>\n> Sigils were introduced in Erlang/OTP 27","ref":"data_types.html#sigil"},{"type":"extras","title":"Record - Data Types","doc":"A record is a data structure for storing a fixed number of elements. It has\nnamed fields and is similar to a struct in C. However, a record is not a true\ndata type. Instead, record expressions are translated to tuple expressions\nduring compilation. Therefore, record expressions are not understood by the\nshell unless special actions are taken. For details, see module `m:shell`\nin STDLIB.\n\n_Examples:_\n\n```erlang\n-module(person).\n-export([new/2]).\n\n-record(person, {name, age}).\n\nnew(Name, Age) ->\n #person{name=Name, age=Age}.\n\n1> person:new(ernie, 44).\n{person,ernie,44}\n```\n\nRead more about records in [Records](ref_man_records.md). More examples are\nfound in [Programming Examples](`e:system:prog_ex_records.md`).","ref":"data_types.html#record"},{"type":"extras","title":"Boolean - Data Types","doc":"There is no Boolean data type in Erlang. Instead the atoms `true` and `false`\nare used to denote Boolean values. The [`is_boolean/1`](`erlang:is_boolean/1`)\nBIF tests whether a term is a boolean.\n\n_Examples:_\n\n```erlang\n1> 2 =< 3.\ntrue\n2> true or false.\ntrue\n3> is_boolean(true).\ntrue\n4> is_boolean(false).\ntrue\n5> is_boolean(ok).\nfalse\n```","ref":"data_types.html#boolean"},{"type":"extras","title":"Escape Sequences - Data Types","doc":"Within strings (`\"`\\-delimited), quoted atoms, and the content of\n[`~b` and `~s` sigils](data_types.md#sigil), the following escape sequences are\nrecognized:\n\n| _Sequence_ | _Description_ |\n| --------------------------- | ------------------------------------------------------------------------------------- |\n| `\\b` | Backspace (ASCII code 8) |\n| `\\d` | Delete (ASCII code 127) |\n| `\\e` | Escape (ASCII code 27) |\n| `\\f` | Form Feed (ASCII code 12) |\n| `\\n` | Line Feed/Newline (ASCII code 10) |\n| `\\r` | Carriage Return (ASCII code 13) |\n| `\\s` | Space (ASCII code 32) |\n| `\\t` | (Horizontal) Tab (ASCII code 9) |\n| `\\v` | Vertical Tab (ASCII code 11) |\n| `\\`XYZ, `\\`YZ, `\\`Z | Character with octal representation XYZ, YZ or Z |\n| `\\xXY` | Character with hexadecimal representation XY |\n| `\\x{`X...`}` | Character with hexadecimal representation; X... is one or more hexadecimal characters |\n| `\\^a`...`\\^z` `\\^A`...`\\^Z` | Control A to control Z |\n| `\\^@` | NUL (ASCII code 0) |\n| `\\^[` | Escape (ASCII code 27) |\n| `\\^\\` | File Separator (ASCII code 28) |\n| `\\^]` | Group Separator (ASCII code 29) |\n| `\\^^` | Record Separator (ASCII code 30) |\n| `\\^_` | Unit Separator (ASCII code 31) |\n| `\\^?` | Delete (ASCII code 127) |\n| `\\'` | Single quote |\n| `\\\"` | Double quote |\n| `\\\\` | Backslash |\n\n_Table: Recognized Escape Sequences_\n\n> #### Change {: .info }\n>\n> As of Erlang/OTP 26, the value of `$\\^?` has been changed to be 127 (Delete),\n> instead of 31. Previous releases would allow any character following `$\\^`; as\n> of Erlang/OTP 26, only the documented characters are allowed.\n\nWithin [triple-quoted strings](data_types.md#tqstring), escape sequences are not\nrecognized. The only text that cannot be written in a triple-quoted string is\nthree consecutive double quote characters at the beginning of a line (preceded\nonly by whitespace). This limitation can be worked around by using more double\nquote characters for the string delimiters than in the string. Any number three\nor above is allowed for the start delimiter and the end delimiter is the same as\nthe start delimiter.\n\nWhen triple-quote string delimiters are used with the\n[`~`, `~B` or `~S` sigils ](data_types.md#sigil)the same applies, but for the\n[`~b` or `~s` sigils ](data_types.md#sigil)the escape sequences for normal\nstrings, above, are used.\n\n> #### Change {: .info }\n>\n> Triple-quoted strings and sigils were introduced in Erlang/OTP 27.","ref":"data_types.html#escape-sequences"},{"type":"extras","title":"Type Conversions - Data Types","doc":"There are a number of BIFs for type conversions.\n\n_Examples:_\n\n```erlang\n1> atom_to_list(hello).\n\"hello\"\n2> list_to_atom(\"hello\").\nhello\n3> binary_to_list(<<\"hello\">>).\n\"hello\"\n4> binary_to_list(<<104,101,108,108,111>>).\n\"hello\"\n5> list_to_binary(\"hello\").\n<<104,101,108,108,111>>\n6> float_to_list(7.0).\n\"7.00000000000000000000e+00\"\n7> list_to_float(\"7.000e+00\").\n7.0\n8> integer_to_list(77).\n\"77\"\n9> list_to_integer(\"77\").\n77\n10> tuple_to_list({a,b,c}).\n[a,b,c]\n11> list_to_tuple([a,b,c]).\n{a,b,c}\n12> term_to_binary({a,b,c}).\n<<131,104,3,100,0,1,97,100,0,1,98,100,0,1,99>>\n13> binary_to_term(<<131,104,3,100,0,1,97,100,0,1,98,100,0,1,99>>).\n{a,b,c}\n14> binary_to_integer(<<\"77\">>).\n77\n15> integer_to_binary(77).\n<<\"77\">>\n16> float_to_binary(7.0).\n<<\"7.00000000000000000000e+00\">>\n17> binary_to_float(<<\"7.000e+00\">>).\n7.0\n```","ref":"data_types.html#type-conversions"},{"type":"extras","title":"Pattern Matching","doc":"\n# Pattern Matching","ref":"patterns.html"},{"type":"extras","title":"Pattern Matching - Pattern Matching","doc":"Variables are bound to values through the _pattern matching_ mechanism. Pattern\nmatching occurs when evaluating the `case`, `receive`, `try`, and\nthe match operator (`=`) expressions.\n\nIn pattern matching, a left-hand side [pattern](expressions.md#patterns) is\nmatched against a right-hand side [term](expressions.md#terms). If the matching\nsucceeds, any unbound variables in the pattern become bound. If the matching\nfails, an exception is raised.\n\n_Examples:_\n\n```erlang\n1> X.\n** 1:1: variable 'X' is unbound **\n2> X = 2.\n2\n3> X + 1.\n3\n4> {X, Y} = {1, 2}.\n** exception error: no match of right hand side value {1,2}\n5> {X, Y} = {2, 3}.\n{2,3}\n6> Y.\n3\n```","ref":"patterns.html#pattern-matching"},{"type":"extras","title":"Modules","doc":"\n# Modules","ref":"modules.html"},{"type":"extras","title":"Module Syntax - Modules","doc":"Erlang code is divided into _modules_. A module consists of a sequence of\nattributes and function declarations, each terminated by a period (`.`).\n\n_Example:_\n\n```erlang\n-module(m). % module attribute\n-export([fact/1]). % module attribute\n\nfact(N) when N>0 -> % beginning of function declaration\n N * fact(N-1); % |\nfact(0) -> % |\n 1. % end of function declaration\n```\n\nFor a description of function declarations, see\n[Function Declaration Syntax](ref_man_functions.md).","ref":"modules.html#module-syntax"},{"type":"extras","title":"Module Attributes - Modules","doc":"A _module attribute_ defines a certain property of a module.\n\nA module attribute consists of a tag and a value:\n\n```text\n-Tag(Value).\n```\n\n`Tag` must be an atom, while `Value` must be a literal term. As a convenience in\nuser-defined attributes, if the literal term `Value` has the syntax `Name/Arity`\n(where `Name` is an atom and `Arity` a positive integer), the term `Name/Arity`\nis translated to `{Name,Arity}`.\n\nAny module attribute can be specified. The attributes are stored in the compiled\ncode and can be retrieved by calling `Module:module_info(attributes)`, or by\nusing the module [beam_lib](`beam_lib:chunks/2`) in STDLIB.\n\nSeveral module attributes have predefined meanings. Some of them have arity two,\nbut user-defined module attributes must have arity one.","ref":"modules.html#module-attributes"},{"type":"extras","title":"Pre-Defined Module Attributes - Modules","doc":"Pre-defined module attributes is to be placed before any function declaration.\n\n- **`-module(Module).`** - Module declaration, defining the name of the module.\n The name `Module`, an atom, is to be same as the file name minus the extension\n `.erl`. Otherwise [code loading](code_loading.md#loading) does not work as\n intended.\n\n This attribute is to be specified first and is the only mandatory attribute.\n\n- **`-export(Functions).`** - Exported functions. Specifies which of the\n functions, defined within the module, that are visible from outside the\n module.\n\n `Functions` is a list `[Name1/Arity1, ..., NameN/ArityN]`, where each `NameI`\n is an atom and `ArityI` an integer.\n\n- **`-import(Module, Functions).`** - Imported functions. Can be called the same\n way as local functions, that is, without any module prefix.\n\n `Module`, an atom, specifies which module to import functions from.\n `Functions` is a list similar as for `export`.\n\n- **`-moduledoc(Documentation).` or `-moduledoc Documentation.`** - The user\n documentation for this module. The allowed values for `Documentation` are the\n same as for [`-doc`](modules.md#documentation-attributes).\n\n See the [Documentation](documentation.md) for more details about how\n to use `-moduledoc`.\n\n- **`-compile(Options).`** - Compiler options. `Options` is a single option or a\n list of options. This attribute is added to the option list when compiling the\n module. See module `m:compile` in Compiler.\n\n- **`-vsn(Vsn).`** - Module version. `Vsn` is any literal term and can be\n retrieved using `beam_lib:version/1`.\n\n If this attribute is not specified, the version defaults to the MD5 checksum\n of the module.\n\n- **`-on_load(Function).`** - This attribute names a function that is to be run\n automatically when a module is loaded. For more information, see\n [Running a Function When a Module is Loaded](code_loading.md#on_load).\n\n- **`-nifs(Functions).`{: #nifs_attribute }** - Specifies which of the\n functions, defined within the module, that may be loaded as NIFs with\n `erlang:load_nif/2`.\n\n `Functions` is a list `[Name1/Arity1, ..., NameN/ArityN]`, where each `NameI`\n is an atom and `ArityI` an integer.\n\n While not strictly necessary, it is recommended to use `-nifs()` attribute in\n any module that load NIFs, to allow the compiler to make better decisions\n regarding optimizations.\n\n There is no need to add `-nifs([])` in modules that do not load NIFs. The lack\n of any call to `erlang:load_nif/2`, from within the module, is enough for the\n compiler to draw the same conclusion.\n\n > #### Change {: .info }\n >\n > The special meaning for the `-nifs()` attribute was introduced in Erlang/OTP\n > 25.0. In previous releases, `-nifs()` was accepted, but had no special\n > meaning.","ref":"modules.html#pre-defined-module-attributes"},{"type":"extras","title":"Behaviour Module Attribute - Modules","doc":"It is possible to specify that the module is the callback module for a\n_behaviour_:\n\n```erlang\n-behaviour(Behaviour).\n```\n\nThe atom `Behaviour` gives the name of the behaviour, which can be a\nuser-defined behaviour or one of the following OTP standard behaviours:\n\n- `gen_server`\n- `gen_statem`\n- `gen_event`\n- `supervisor`\n\nThe spelling `behavior` is also accepted.\n\nThe callback functions of the module can be specified either directly by the\nexported function `behaviour_info/1`:\n\n```erlang\nbehaviour_info(callbacks) -> Callbacks.\n```\n\nor by a `-callback` attribute for each callback function:\n\n```erlang\n-callback Name(Arguments) -> Result.\n```\n\nHere, `Arguments` is a list of zero or more arguments. The `-callback` attribute\nis to be preferred since the extra type information can be used by tools to\nproduce documentation or find discrepancies.\n\nRead more about behaviours and callback modules in\n[OTP Design Principles](`e:system:spec_proc.md#behaviours`).","ref":"modules.html#behaviour-module-attribute"},{"type":"extras","title":"Record Definitions - Modules","doc":"The same syntax as for module attributes is used for record definitions:\n\n```erlang\n-record(Record, Fields).\n```\n\nRecord definitions are allowed anywhere in a module, also among the function\ndeclarations. Read more in [Records](ref_man_records.md).","ref":"modules.html#record-definitions"},{"type":"extras","title":"Preprocessor - Modules","doc":"The same syntax as for module attributes is used by the preprocessor, which\nsupports file inclusion, macros, and conditional compilation:\n\n```erlang\n-include(\"SomeFile.hrl\").\n-define(Macro, Replacement).\n```\n\nRead more in [Preprocessor](macros.md).","ref":"modules.html#preprocessor"},{"type":"extras","title":"Setting File and Line - Modules","doc":"The same syntax as for module attributes is used for changing the pre-defined\nmacros `?FILE` and `?LINE`:\n\n```erlang\n-file(File, Line).\n```\n\nThis attribute is used by tools, such as Yecc, to inform the compiler that the\nsource program is generated by another tool. It also indicates the\ncorrespondence of source files to lines of the original user-written file, from\nwhich the source program is produced.","ref":"modules.html#setting-file-and-line"},{"type":"extras","title":"Types and function specifications - Modules","doc":"A similar syntax as for module attributes is used for specifying types and\nfunction specifications:\n\n```erlang\n-type my_type() :: atom() | integer().\n-spec my_function(integer()) -> integer().\n```\n\nRead more in [Types and Function specifications](typespec.md).\n\nThe description is based on\n[EEP8 - Types and function specifications](http://www.erlang.org/eeps/eep-0008.html),\nwhich is not to be further updated.","ref":"modules.html#types-and-function-specifications"},{"type":"extras","title":"Documentation attributes - Modules","doc":"The module attribute `-doc(Documentation)` is used to provide user documentation\nfor a function/type/callback:\n\n```erlang\n-doc(\"Example documentation\").\nexample() -> ok.\n```\n\nThe attribute should be placed just before the entity it documents.The\nparenthesis are optional around `Documentation`. The allowed values for\n`Documentation` are:\n\n- **[literal string](data_types.md#string) or\n [utf-8 encoded binary string](expressions.md#unicode-segments)** - The string\n documenting the entity. Any literal string is allowed, so both\n [triple quoted strings](data_types.md#tqstring) and\n [sigils](data_types.md#sigil) that translate to literal strings can be used.\n The following examples are equivalent:\n\n ```erlang\n -doc(\"Example \\\"docs\\\"\").\n -doc(<<\"Example \\\"docs\\\"\"/utf8>>).\n -doc ~S/Example \"docs\"/.\n -doc \"\"\"\n Example \"docs\"\n \"\"\"\n -doc ~B|Example \"docs\"|.\n ```\n\n For clarity it is recommended to use either normal `\"strings\"` or triple\n quoted strings for documentation attributes.\n\n- **`{file, ` `t:file:name/0` `}`** - Read the contents of filename and use\n that as the documentation string.\n\n- **`false`** - Set the current entity as hidden, that is, it should not be\n listed as an available function and has no documentation.\n\n- **`Metadata :: `[`map()`](`t:erlang:map/0`)** - Metadata about the current\n entity. Some of the keys in the metadata have a special meaning. See\n [Moduledoc metadata](`e:system:documentation.md#moduledoc-metadata`) and\n [Doc metadata](`e:system:documentation.md#doc-metadata`) for more details.\n\nIt is possible to have multiple Metadata doc attributes per entity, but only a\nsingle documentation string entry is allowed.\n\nSee the [Documentation](documentation.md) guide in the Erlang Reference Manual\nfor more details.","ref":"modules.html#documentation-attributes"},{"type":"extras","title":"The feature directive - Modules","doc":"While not a module attribute, but rather a directive (since it might affect\nsyntax), there is the `-feature(..)` directive used for enabling and disabling\n[features](`e:system:features.md#features`).\n\nThe syntax is similar to that of an attribute, but has two arguments:\n\n```erlang\n-feature(FeatureName, enable | disable).\n```\n\nNote that the [feature directive](macros.md#feature-directive) can only appear\nin a prefix of the module.","ref":"modules.html#the-feature-directive"},{"type":"extras","title":"Comments - Modules","doc":"Comments can be placed anywhere in a module except within strings and\nquoted atoms. A comment begins with the character `%`, and continues\nup to but not including the next end of line. A comment has no effect,\nbeing essentially equivalent to white space.","ref":"modules.html#comments"},{"type":"extras","title":"module_info/0 and module_info/1 functions - Modules","doc":"The compiler automatically inserts the two special, exported functions into each\nmodule:\n\n- `Module:module_info/0`\n- `Module:module_info/1`\n\nWhen called, these functions retrieve information about the module.","ref":"modules.html#module_info-0-and-module_info-1-functions"},{"type":"extras","title":"module_info/0 - Modules","doc":"The `module_info/0` function in each module returns a list of\n`{Key,Value}` tuples with information about the module. At the time\nwriting, the list contain tuples having the following `Key`s:\n`module`, `attributes`, `compile`, `exports`, and `md5`. The order\nand number of tuples may change without prior notice.","ref":"modules.html#module_info-0"},{"type":"extras","title":"module_info/1 - Modules","doc":"The call `module_info(Key)`, where `Key` is an atom, returns a single piece of\ninformation about the module.\n\nThe following values are allowed for `Key`:\n\n- **`module`** - Returns an atom representing the module name.\n\n- **`attributes`** - Returns a list of `{AttributeName,ValueList}` tuples, where\n `AttributeName` is the name of an attribute, and `ValueList` is a list of\n values. Notice that a given attribute can occur more than once in the list\n with different values if the attribute occurs more than once in the module.\n\n The list of attributes becomes empty if the module is stripped with\n `beam_lib:strip/1`.\n\n- **`compile`** - Returns a list of tuples with information about how the module\n was compiled. This list is empty if the module has been stripped with\n `beam_lib:strip/1`.\n\n- **`md5`** - Returns a binary representing the MD5 checksum of the module.\n\n- **`exports`** - Returns a list of `{Name,Arity}` tuples with all exported\n functions in the module.\n\n- **`functions`** - Returns a list of `{Name,Arity}` tuples with all functions\n in the module.\n\n- **`nifs`** - Returns a list of `{Name,Arity}` tuples with all NIF functions in\n the module.","ref":"modules.html#module_info-1"},{"type":"extras","title":"Documentation","doc":"\n# Documentation\n\nDocumentation in Erlang is done through the `-moduledoc` and `-doc`\n[attributes](modules.md#module-attributes). For example:\n\n```erlang\n-module(arith).\n-moduledoc \"\"\"\nA module for basic arithmetic.\n\"\"\".\n\n-export([add/2]).\n\n-doc \"Adds two numbers.\".\nadd(One, Two) -> One + Two.\n```\n\nThe `-moduledoc` attribute has to be located before the first `-doc` attribute\nor function declaration. It documents the overall purpose of the module.\n\nThe `-doc` attribute always precedes the [function](ref_man_functions.md) or\n[attribute](modules.md#module-attributes) it documents. The\nattributes that can be documented are\n[user-defined types](typespec.md#type-declarations-of-user-defined-types)\n(`-type` and `-opaque`) and\n[behaviour module attributes](modules.md#behaviour-module-attribute)\n(`-callback`).\n\nBy default the format used for documentation attributes is\n[Markdown](https://en.wikipedia.org/wiki/Markdown) but that can be changed by\nsetting\n[module documentation metadata](#moduledoc-metadata).\n\nA good starting point to writing Markdown is\n[Basic writing and formatting syntax](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax).\n\nFor details on what is allowed to be part of the `-moduledoc` and `-doc`\nattributes, see\n[Documentation Attributes](modules.md#documentation-attributes).\n\n`-doc` attributes have been available since Erlang/OTP 27.","ref":"documentation.html"},{"type":"extras","title":"Documentation metadata - Documentation","doc":"It is possible to add metadata to the documentation entry. You do this by adding\na `-moduledoc` or `-doc` attribute with a map as argument. For example:\n\n```erlang\n-module(arith).\n-moduledoc \"\"\"\nA module for basic arithmetic.\n\"\"\".\n-moduledoc #{since => \"1.0\"}.\n\n-export([add/2]).\n\n-doc \"Adds two numbers.\".\n-doc(#{since => \"1.0\"}).\nadd(One, Two) -> One + Two.\n```\n\nThe metadata is used by documentation tools to provide extra information to the\nuser. There can be multiple metadata documentation entries, in which case the\nmaps will be merged with the latest taking precedence if there are duplicate\nkeys. Example:\n\n```erlang\n-doc \"Adds two numbers.\".\n-doc #{since => \"1.0\", author => \"Joe\"}.\n-doc #{since => \"2.0\"}.\nadd(One, Two) -> One + Two.\n```\n\nThis will result in a metadata entry of `#{since => \"2.0\", author => \"Joe\"}`.\n\nThe keys and values in the metadata map can be any type, but it is recommended\nthat only [atoms](data_types.md#atom) are used for keys and\n[strings](data_types.md#string) for the values.","ref":"documentation.html#documentation-metadata"},{"type":"extras","title":"External documentation files - Documentation","doc":"The `-moduledoc` and `-doc` can also be placed in external files. To do so use\n`-doc {file, \"path/to/doc.md\"}` to point to the documentation. The path used is\nrelative to the file where the `-doc` attribute is located. For example:\n\n```markdown\n%% doc/add.md\nAdds two numbers.\n```\n\nand\n\n```erlang\n%% src/arith.erl\n-doc({file, \"../doc/add.md\"}).\nadd(One, Two) -> One + Two.\n```","ref":"documentation.html#external-documentation-files"},{"type":"extras","title":"Documenting a module - Documentation","doc":"The module description should include details on how to use the API and examples\nof the different functions working together. Here is a good place to use images\nand other diagrams to better show the usage of the module. Instead of writing a\nlong text in the `moduledoc` attribute, it could be better to break it out into\nan external page.\n\nThe `moduledoc` attribute should start with a short paragraph describing the\nmodule and then go into greater details. For example:\n\n````erlang\n-module(arith).\n-moduledoc \"\"\"\n A module for basic arithmetic.\n\n This module can be used to add and subtract values. For example:\n\n ```erlang\n 1> arith:substract(arith:add(2, 3), 1).\n 4\n ```\n \"\"\".\n````","ref":"documentation.html#documenting-a-module"},{"type":"extras","title":"Moduledoc metadata - Documentation","doc":"There are three reserved metadata keys for `-moduledoc`:\n\n- `since` - Shows in which version of the application the module was added.\n If this is added, all functions, types, and callbacks within will also receive\n the same `since` value unless specified in the metadata of the function, type\n or callback.\n- `deprecated` - Shows a text in the documentation explaining that it is\n deprecated and what to use instead.\n- `format` - The format to use for all documentation in this module. The\n default is `text/markdown`. It should be written using the\n [mime type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types)\n of the format.\n\nExample:\n\n```erlang\n-moduledoc {file, \"../doc/arith.asciidoc\"}.\n-moduledoc #{since => \"0.1\", format => \"text/asciidoc\"}.\n-moduledoc #{deprecated => \"Use the Erlang arithmetic operators instead.\"}.\n```","ref":"documentation.html#moduledoc-metadata"},{"type":"extras","title":"Documenting functions, user-defined types, and callbacks - Documentation","doc":"Functions, types, and callbacks can be documented using the `-doc` attribute.\nEach entry should start with a short paragraph describing the purpose of entity,\nand then go into greater detail in needed.\n\nIt is not recommended to include images or diagrams in this documentation as it\nis used by IDEs and `\\c:h/1` to show the documentation to the user.\n\nFor example:\n\n````erlang\n-doc \"\"\"\nA number that can be used by the arith module.\n\nWe use a special number here so that we know\nthat this number comes from this module.\n\"\"\".\n-opaque number() :: {arith, erlang:number()}.\n\n-doc \"\"\"\nAdds two numbers.","ref":"documentation.html#documenting-functions-user-defined-types-and-callbacks"},{"type":"extras","title":"Example: - Documentation","doc":"```\n1> arith:add(arith:number(1), arith:number(2)). {number, 3}\n```\n\"\"\".\n-spec add(number(), number()) -> number().\nadd({number, One}, {number, Two}) -> {number, One + Two}.\n````","ref":"documentation.html#example"},{"type":"extras","title":"Doc metadata - Documentation","doc":"There are four reserved metadata keys for `-doc`:\n\n- `since => unicode:chardata()` - Shows which version of the application the\n module was added.\n- `deprecated => unicode:chardata()` - Shows a text in the documentation\n explaining that it is deprecated and what to use instead. The compiler will\n automatically insert this key if there is a `-deprecated` attribute marking a\n function as deprecated.\n- `equiv => unicode:chardata() | F/A | F(...)` - Notes that this function is equivalent to\n another function in this module. The equivalence can be described using either\n `Func/Arity`, `Func(Args)` or a [unicode string](`t:unicode:chardata/0`). For example:\n\n ```erlang\n -doc #{equiv => add/3}.\n add(One, Two) -> add(One, Two, []).\n add(One, Two, Options) -> ...\n ```\n\n or\n\n ```erlang\n -doc #{equiv => add(One, Two, [])}.\n -spec add(One :: number(), Two :: number()) -> number().\n add(One, Two) -> add(One, Two, []).\n add(One, Two, Options) -> ...\n ```\n\n The entry into the [EEP-48](`e:kernel:eep48_chapter.md`) doc chunk metadata is\n the value converted to a string.\n\n- `exported => boolean()` - A `t:boolean/0` signifying if the entry is `exported`\n or not. This value is automatically set by the compiler and should not be set\n by the user.","ref":"documentation.html#doc-metadata"},{"type":"extras","title":"Doc signatures - Documentation","doc":"The doc signature is a short text shown to describe the function and its arguments.\nBy default it is determined by looking at the names of the arguments in the\n`-spec` or function. For example:\n\n```erlang\nadd(One, Two) -> One + Two.\n\n-spec sub(One :: integer(), Two :: integer()) -> integer().\nsub(X, Y) -> X - Y.\n```\n\nwill have a signature of `add(One, Two)` and `sub(One, Two)`.\n\nFor types or callbacks, the signature is derived from the type or callback\nspecification. For example:\n\n```erlang\n-type number(Value) :: {number, Value}.\n%% signature will be `number(Value)`\n\n-opaque number() :: {number, number()}.\n%% signature will be `number()`\n\n-callback increment(In :: number()) -> Out.\n%% signature will be `increment(In)`\n\n-callback increment(In) -> Out when In :: number().\n%% signature will be `increment(In)`\n```\n\nIf it is not possible to \"easily\" figure out a nice signature from the code, the\nMFA syntax is used instead. For example: `add/2`, `number/1`, `increment/1`\n\nIt is possible to supply a custom signature by placing it as the first line of the\n`-doc` attribute. The provided signature must be in the form of a function\ndeclaration up until the `->`. For example:\n\n```erlang\n-doc \"\"\"\nadd(One, Two)\n\nAdds two numbers.\n\"\"\".\nadd(A, B) -> A + B.\n```\n\nWill create the signature `add(One, Two)`. The signature will be removed from the\ndocumentation string, so in the example above only the text `\"Adds two numbers\"`\nwill be part of the documentation. This works for functions, types, and\ncallbacks.","ref":"documentation.html#doc-signatures"},{"type":"extras","title":"Links in Markdown - Documentation","doc":"When writing documentation in Markdown, links are automatically found in any\ninline code segment that looks like an MFA. For example:\n\n```erlang\n-doc \"See `sub/2` for more details\".\n```\n\nwill create a link to the `sub/2` function in the current module if it exists.\nOne can also use `` `sub/2` ``as the link target. For example:\n\n```erlang\n-doc \"See [subtract](`sub/2`) for more details\".\n-doc \"See [`sub/2`] for more details\".\n-doc \"\"\"\nSee [subtract] for more details\n\n[subtract]: `sub/2`\n\"\"\".\n-doc \"\"\"\nSee [subtract][1] for more details\n\n[1]: `sub/2`\n\"\"\".\n```\n\nThe above examples result in the same link being created.\n\nThe link can also other entities:\n\n- `remote functions` - Use `module:function/arity` syntax.\n\nExample:\n\n```erlang\n-doc \"See `arith:sub/2` for more details\".\n```\n\n- `modules` - Write the module with a `m` prefix. Use anchors to jump to a\n specific place in the module.\n\nExample:\n\n```erlang\n-doc \"See `m:arith` for more details\".\n-doc \"See `m:arith#anchor` for more details\".\n```\n\n- `types` - Use the same syntax as for local/remote function but add a `t`\n prefix.\n\nExample:\n\n```erlang\n-doc \"See `t:number/0` for more details\".\n-doc \"See `t:arith:number/0` for more details\".\n```\n\n- `callbacks` - Use the same syntax as for local/remote function but add a `c`\n prefix.\n\nExample:\n\n```erlang\n-doc \"See `c:increment/0` for more details\".\n-doc \"See `c:arith:increment/0` for more details\".\n```\n\n- `extra pages` - For extra pages in the current application use a normal link,\n for example \"`[release notes](notes.md)`\". For extra pages in another\n application use the `e` prefix and state which application the page belongs\n to. One can also use anchors to jump to a specific place in the page.\n\nExample:\n\n```erlang\n-doc \"See `e:stdlib:unicode_usage` for more details\".\n-doc \"See `e:stdlib:unicode_usage#notes-about-raw-filenames` for more details\".\n```","ref":"documentation.html#links-in-markdown"},{"type":"extras","title":"What is visible versus hidden? - Documentation","doc":"An Erlang `m:application` normally consists of various public and private\nmodules. That is, modules that should be used by other applications and modules\nthat should not. By default all modules in an application are visible, but by\nsetting `-moduledoc false.` specific modules can be hidden from being listed as\npart of the available API.\n\nAn Erlang [module](modules.md) consists of public and private functions and type\nattributes. By default, all exported functions, exported types and callbacks are\nconsidered visible and part of the modules public API. In addition, any\nnon-exported type that is referred to by any other visible type attribute is\nalso visible, but not considered to be part of the public API. For example:\n\n```erlang\n-export([example/0]).\n\n-type private() :: one.\n-spec example() -> private().\nexample() -> one.\n```\n\nin the above code, the function `example/0` is exported and it referenced the\nun-exported type `private/0`. Therefore both `example/0` and `private/0` will be\nmarked as visible. The `private/0` type will have the metadata field `exported`\nset to `false` to show that it is not part of the public API.\n\nIf you want to make a visible entity hidden you need to set the `-doc` attribute\nto `false`. Let us revisit our previous example:\n\n```erlang\n-export([example/0]).\n\n-type private() :: one.\n-spec example() -> private().\n-doc false.\nexample() -> one.\n```\n\nThe function `example/0` is exported but explicitly marked as hidden; therefore\nboth `example/0` and `private/0` will be hidden.\n\nAny documentation added to an automatically hidden entity (non-exported function\nor type) is ignored and will generate a warning. Such functions can be\ndocumented using comments.","ref":"documentation.html#what-is-visible-versus-hidden"},{"type":"extras","title":"Compiling and getting documentation - Documentation","doc":"The Erlang compiler will by default insert documentation into\n[EEP-48](`e:kernel:eep48_chapter.md`) documentation chunks when compiling a module.\nBy passing the [no_docs](`m:compile#no_docs`) flag to `compile:file/1`,\nor `+no_docs` to [erlc](`e:erts:erlc_cmd.md`), no documentation chunk is inserted.\n\nThe documentation can then be retrieved using `code:get_doc/1`, or viewed using\nthe shell built-in command [`h/1`](`\\\\c:h/1`). For example:\n\n```text\n1> h(arith).\n\n arith\n\n A module for basic arithmetic.\n\n2> h(arith, add).\n\n add(One, Two)\n\n Adds two numbers.\n```","ref":"documentation.html#compiling-and-getting-documentation"},{"type":"extras","title":"Using ExDoc to generate HTML/ePub documentation - Documentation","doc":"[ExDoc](https://hexdocs.pm/ex_doc/) has built-in support to generate\ndocumentation from Markdown. The simplest way is by using the\n[rebar3_ex_doc](https://hexdocs.pm/rebar3_ex_doc) plugin. To set up a\nrebar3 project to use [ExDoc](https://hexdocs.pm/ex_doc/) to generate\ndocumentation add the following to your `rebar3.config`.\n\n```erlang\n%% Enable the plugin\n{plugins, [rebar3_ex_doc]}.\n\n{ex_doc, [\n {extras, [\"README.md\"]},\n {main, \"README.md\"},\n {source_url, \"https://github.com/namespace/your_app\"}\n]}.\n```\n\nWhen configured you can run `rebar3 ex_doc` to generate the\ndocumentation to `doc/index.html`. For more details and options see\nthe [rebar3_ex_doc](https://hexdocs.pm/rebar3_ex_doc) documentation.\n\nYou can also download the\n[release escript bundle](https://github.com/elixir/ex_doc/releases/latest) from\ngithub and run it from the command line. The documentation for using the escript\nis found by running `ex_doc --help`.\n\nIf you are writing documentation that will be using\n[ExDoc](https://hexdocs.pm/ex_doc/) to generate HTML/ePub it is highly\nrecommended to read its documentation.","ref":"documentation.html#using-exdoc-to-generate-html-epub-documentation"},{"type":"extras","title":"Functions","doc":"\n# Functions\n\n[](){: #syntax }","ref":"ref_man_functions.html"},{"type":"extras","title":"Function Declaration Syntax - Functions","doc":"A _function declaration_ is a sequence of function clauses separated by\nsemicolons, and terminated by a period (`.`).\n\nA _function clause_ consists of a _clause head_ and a _clause body_, separated by\n`->`.\n\nA clause _head_ consists of the function name, an argument list, and an optional\nguard sequence beginning with the keyword `when`:\n\n```erlang\nName(Pattern11,...,Pattern1N) [when GuardSeq1] ->\n Body1;\n...;\nName(PatternK1,...,PatternKN) [when GuardSeqK] ->\n BodyK.\n```\n\nThe function name is an atom. Each argument is a pattern.\n\nThe number of arguments `N` is the _arity_ of the function. A function is\nuniquely defined by the module name, function name, and arity. That is, two\nfunctions with the same name and in the same module, but with different arities\nare two different functions.\n\nA function named `f` in module `mod` and with arity `N` is often denoted as\n`mod:f/N`.\n\nA clause _body_ consists of a sequence of expressions separated by comma (`,`):\n\n```text\nExpr1,\n...,\nExprN\n```\n\nValid Erlang expressions and guard sequences are described in\n[Expressions](expressions.md).\n\n_Example:_\n\n```erlang\nfact(N) when N > 0 -> % first clause head\n N * fact(N-1); % first clause body\n\nfact(0) -> % second clause head\n 1. % second clause body\n```\n\n[](){: #eval }","ref":"ref_man_functions.html#function-declaration-syntax"},{"type":"extras","title":"Function Evaluation - Functions","doc":"When a function `M:F/N` is called, first the code for the function is located.\nIf the function cannot be found, an `undef` runtime error occurs. Notice that\nthe function must be exported to be visible outside the module it is defined in.\n\nIf the function is found, the function clauses are scanned sequentially until a\nclause is found that fulfills both of the following two conditions:\n\n1. The patterns in the clause head can be successfully matched against the given\n arguments.\n1. The guard sequence, if any, is true.\n\nIf such a clause cannot be found, a `function_clause` runtime error occurs.\n\nIf such a clause is found, the corresponding clause body is evaluated. That is,\nthe expressions in the body are evaluated sequentially and the value of the last\nexpression is returned.\n\nConsider the function `fact`:\n\n```erlang\n-module(mod).\n-export([fact/1]).\n\nfact(N) when N > 0 ->\n N * fact(N - 1);\nfact(0) ->\n 1.\n```\n\nAssume that you want to calculate the factorial for 1:\n\n```text\n1> mod:fact(1).\n```\n\nEvaluation starts at the first clause. The pattern `N` is matched against\nargument 1. The matching succeeds and the guard (`N > 0`) is true, thus `N` is\nbound to 1, and the corresponding body is evaluated:\n\n```erlang\nN * fact(N-1) => (N is bound to 1)\n1 * fact(0)\n```\n\nNow, `fact(0)` is called, and the function clauses are scanned\nsequentially again. First, the pattern `N` is matched against 0. The\nmatching succeeds, but the guard (`N > 0`) is false. Second, the\npattern `0` is matched against the argument `0`. The matching succeeds\nand the body is evaluated:\n\n```text\n1 * fact(0) =>\n1 * 1 =>\n1\n```\n\nEvaluation has succeed and `mod:fact(1)` returns 1.\n\nIf `mod:fact/1` is called with a negative number as argument, no clause head\nmatches. A `function_clause` runtime error occurs.","ref":"ref_man_functions.html#function-evaluation"},{"type":"extras","title":"Tail recursion - Functions","doc":"If the last expression of a function body is a function call, a\n_tail-recursive call_ is done. This is to ensure that no system\nresources, for example, call stack, are consumed. This means that an\ninfinite loop using tail-recursive calls will not exhaust the call\nstack and can (in principle) run forever.\n\n_Example:_\n\n```erlang\nloop(N) ->\n io:format(\"~w~n\", [N]),\n loop(N+1).\n```\n\nThe earlier factorial example is a counter-example. It is not\ntail-recursive, since a multiplication is done on the result of the recursive\ncall to `fact(N-1)`.","ref":"ref_man_functions.html#tail-recursion"},{"type":"extras","title":"Built-In Functions (BIFs) - Functions","doc":"Built-In Functions (BIFs) are implemented in C code in the runtime\nsystem. BIFs do things that are difficult or impossible to implement\nin Erlang. Most of the BIFs belong to module `m:erlang`, but there\nare also BIFs belonging to a few other modules, for example `m:lists`\nand `m:ets`.\n\nThe most commonly used BIFs belonging to `m:erlang` are _auto-imported_. They do\nnot need to be prefixed with the module name. Which BIFs that are auto-imported\nis specified in the `m:erlang` module in ERTS. For example, standard-type\nconversion BIFs like `atom_to_list` and BIFs allowed in guards can be called\nwithout specifying the module name.\n\n_Examples:_\n\n```erlang\n1> tuple_size({a,b,c}).\n3\n2> atom_to_list('Erlang').\n\"Erlang\"\n```","ref":"ref_man_functions.html#built-in-functions-bifs"},{"type":"extras","title":"Types and Function Specifications","doc":"\n# Types and Function Specifications","ref":"typespec.html"},{"type":"extras","title":"The Erlang Type Language - Types and Function Specifications","doc":"Erlang is a dynamically typed language. Still, it comes with a notation for\ndeclaring sets of Erlang terms to form a particular type. This effectively forms\nspecific subtypes of the set of all Erlang terms.\n\nSubsequently, these types can be used to specify types of record fields and also\nthe argument and return types of functions.\n\nType information can be used for the following:\n\n- To document function interfaces\n- To provide more information for bug detection tools, such as Dialyzer\n- To be leveraged by documentation tools, such as\n [ExDoc](https://hexdocs.pm/ex_doc/) or [EDoc](`e:edoc:edoc`), for generating\n documentation\n\nIt is expected that the type language described in this section\nsupersedes and replaces the purely comment-based `@type` and `@spec`\ndeclarations used by EDoc.\n\n[](){: #syntax }","ref":"typespec.html#the-erlang-type-language"},{"type":"extras","title":"Types and their Syntax - Types and Function Specifications","doc":"Types describe sets of Erlang terms. Types consist of, and are built from, a set\nof predefined types, for example, `t:integer/0`, `t:atom/0`, and `t:pid/0`.\nPredefined types represent a typically infinite set of Erlang terms that belong\nto this type. For example, the type `t:atom/0` denotes the set of all Erlang\natoms.\n\nFor integers and atoms, it is allowed for singleton types; for example, the\nintegers `-1` and `42`, or the atoms `'foo'` and `'bar'`. All other types are\nbuilt using unions of either predefined types or singleton types. In a type\nunion between a type and one of its subtypes, the subtype is absorbed by the\nsupertype. Thus, the union is then treated as if the subtype was not a\nconstituent of the union. For example, the type union:\n\n```text\natom() | 'bar' | integer() | 42\n```\n\ndescribes the same set of terms as the type union:\n\n```text\natom() | integer()\n```\n\nBecause of subtype relations that exist between types, all types, except\n`t:dynamic/0`, form a lattice where the top-most element, `t:any/0`, denotes the\nset of all Erlang terms and the bottom-most element, `t:none/0`, denotes the\nempty set of terms.\n\n[](){: #dynamic }\n\nTo facilitate [gradual typing](https://en.wikipedia.org/wiki/Gradual_typing) of\nErlang, the type `t:dynamic/0` is provided. It is similar to\n[Any](https://docs.python.org/3/library/typing.html#the-any-type) in Python,\n[any](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#any) in\nTypeScript and [dynamic](https://docs.hhvm.com/hack/built-in-types/dynamic) in\nHack. `t:any/0` and `t:dynamic/0` interact with\n[success typing](https://learnyousomeerlang.com/dialyzer#success-typing) the\nsame way, so Dialyzer doesn't distinguish between them.\n\nThe set of predefined types and the syntax for types follows:\n{: #predefined }\n\n```text\nType :: any() %% The top type, the set of all Erlang terms\n | none() %% The bottom type, contains no terms\n | dynamic()\n | pid()\n | port()\n | reference()\n | [] %% nil\n | Atom\n | Bitstring\n | float()\n | Fun\n | Integer\n | List\n | Map\n | Tuple\n | Union\n | UserDefined %% described in Type Declarations of User-Defined Types\n\nAtom :: atom()\n | Erlang_Atom %% 'foo', 'bar', ...\n\nBitstring :: <<>>\n | <<_:M>> %% M is an Integer_Value that evaluates to a positive integer\n | <<_:_*N>> %% N is an Integer_Value that evaluates to a positive integer\n | <<_:M, _:_*N>>\n\nFun :: fun() %% any function\n | fun((...) -> Type) %% any arity, returning Type\n | fun(() -> Type)\n | fun((TList) -> Type)\n\nInteger :: integer()\n | Integer_Value\n | Integer_Value..Integer_Value %% specifies an integer range\n\nInteger_Value :: Erlang_Integer %% ..., -1, 0, 1, ... 42 ...\n | Erlang_Character %% $a, $b ...\n | Integer_Value BinaryOp Integer_Value\n | UnaryOp Integer_Value\n\nBinaryOp :: '*' | 'div' | 'rem' | 'band' | '+' | '-' | 'bor' | 'bxor' | 'bsl' | 'bsr'\n\nUnaryOp :: '+' | '-' | 'bnot'\n\nList :: list(Type) %% Proper list ([]-terminated)\n | maybe_improper_list(Type1, Type2) %% Type1=contents, Type2=termination\n | nonempty_improper_list(Type1, Type2) %% Type1 and Type2 as above\n | nonempty_list(Type) %% Proper non-empty list\n\nMap :: #{} %% denotes the empty map\n | #{AssociationList}\n\nTuple :: tuple() %% denotes a tuple of any size\n | {}\n | {TList}\n\nAssociationList :: Association\n | Association, AssociationList\n\nAssociation :: Type := Type %% denotes a mandatory association\n | Type => Type %% denotes an optional association\n\nTList :: Type\n | Type, TList\n\nUnion :: Type1 | Type2\n```\n\nInteger values are either integer or character literals or expressions\nconsisting of possibly nested unary or binary operations that evaluate to an\ninteger. Such expressions can also be used in bit strings and ranges.\n\nThe general form of bit strings is `<<_:M, _:_*N>>`, where `M` and `N` must\nevaluate to positive integers. It denotes a bit string that is `M + (k*N)` bits\nlong (that is, a bit string that starts with `M` bits and continues with `k`\nsegments of `N` bits each, where `k` is also a positive integer). The notations\n`<<_:_*N>>`, `<<_:M>>`, and `<<>>` are convenient shorthands for the cases that\n`M` or `N`, or both, are zero.\n\nBecause lists are commonly used, they have shorthand type notations. The types\n[`list(T)`](`t:list/1`) and [`nonempty_list(T)`](`t:nonempty_list/1`) have the\nshorthands `[T]` and `[T,...]`, respectively. The only difference between the\ntwo shorthands is that `[T]` can be an empty list but `[T,...]` cannot.\n\nNotice that the shorthand for `t:list/0`, that is, the list of elements of\nunknown type, is `[_]` (or `[any()]`), not `[]`. The notation `[]` specifies the\nsingleton type for the empty list.\n\nThe general form of map types is `#{AssociationList}`. The key types in\n`AssociationList` are allowed to overlap, and if they do, the leftmost\nassociation takes precedence. A map association has a key in `AssociationList`\nif it belongs to this type. `AssociationList` can contain both mandatory `(:=)`\nand optional `(=>)` association types. If an association type is mandatory, an\nassociation with that type needs to be present. In the case of an optional\nassociation type it is not required for the key type to be present.\n\nThe notation `#{}` specifies the singleton type for the empty map. Note that\nthis notation is not a shorthand for the `t:map/0` type.\n\nFor convenience, the following types are also built-in. They can be thought as\npredefined aliases for the type unions also shown in the table.\n\n[](){: #builtin_types }\n\n| _Built-in type_ | _Defined as_ |\n| ------------------------- | --------------------------------------------------------------------------- |\n| `t:term/0` | `t:any/0` |\n| `t:binary/0` | `<<_:_*8>>` |\n| `t:nonempty_binary/0` | `<<_:8, _:_*8>>` |\n| `t:bitstring/0` | `<<_:_*1>>` |\n| `t:nonempty_bitstring/0` | `<<_:1, _:_*1>>` |\n| `t:boolean/0` | `'false'` \\| `'true'` |\n| `t:byte/0` | `0..255` |\n| `t:char/0` | `0..16#10ffff` |\n| `t:nil/0` | `[]` |\n| `t:number/0` | `t:integer/0` \\| `t:float/0` |\n| `t:list/0` | `[any()]` |\n| `t:maybe_improper_list/0` | [`maybe_improper_list(any(), any())`](`t:maybe_improper_list/2`) |\n| `t:nonempty_list/0` | [`nonempty_list(any())`](`t:nonempty_list/1`) |\n| `t:string/0` | `[char()]` |\n| `t:nonempty_string/0` | `[char(),...]` |\n| `t:iodata/0` | `iolist()` \\| `binary()` |\n| `t:iolist/0` | `maybe_improper_list(byte()` \\| `binary()` \\| `iolist(), binary()` \\| `[])` |\n| `t:map/0` | `#{any() => any()}` |\n| `t:function/0` | `fun()` |\n| `t:module/0` | `t:atom/0` |\n| `t:mfa/0` | `{module(),atom(),arity()}` |\n| `t:arity/0` | `0..255` |\n| `t:identifier/0` | `pid()` \\| `port()` \\| `reference()` |\n| `node/0` | `t:atom/0` |\n| `t:timeout/0` | `'infinity'` \\| `non_neg_integer()` |\n| `t:no_return/0` | `t:none/0` |\n\n_Table: Built-in types, predefined aliases_\n\nIn addition, the following three built-in types exist and can be thought as\ndefined below, though strictly their \"type definition\" is not valid syntax\naccording to the type language defined above.\n\n| _Built-in type_ | _Can be thought defined by the syntax_ |\n| --------------------- | -------------------------------------- |\n| `t:non_neg_integer/0` | `0..` |\n| `t:pos_integer/0` | `1..` |\n| `t:neg_integer/0` | `..-1` |\n\n_Table: Additional built-in types_\n\n> #### Note {: .info }\n>\n> The following built-in list types also exist, but they are expected to be\n> rarely used. Hence, they have long names:\n\n```erlang\nnonempty_maybe_improper_list() :: nonempty_maybe_improper_list(any(), any())\nnonempty_improper_list(Type1, Type2)\nnonempty_maybe_improper_list(Type1, Type2)\n```\n\nwhere the last two types define the set of Erlang terms one would expect.\n\nAlso for convenience, record notation is allowed to be used. Records are\nshorthands for the corresponding tuples:\n\n```erlang\nRecord :: #Erlang_Atom{}\n | #Erlang_Atom{Fields}\n```\n\nRecords are extended to possibly contain type information. This is described in\n[Type Information in Record Declarations](typespec.md#typeinrecords).","ref":"typespec.html#types-and-their-syntax"},{"type":"extras","title":"Redefining built-in types - Types and Function Specifications","doc":"> #### Change {: .info }\n>\n> Starting from Erlang/OTP 26, is is permitted to define a type having the same\n> name as a built-in type.\n\nIt is recommended to avoid deliberately reusing built-in names because it can be\nconfusing. However, when an Erlang/OTP release introduces a new type, code that\nhappened to define its own type having the same name will continue to work.\n\nAs an example, imagine that the Erlang/OTP 42 release introduces a new type\n`gadget()` defined like this:\n\n```erlang\n-type gadget() :: {'gadget', reference()}.\n```\n\nFurther imagine that some code has its own (different) definition of `gadget()`,\nfor example:\n\n```erlang\n-type gadget() :: #{}.\n```\n\nSince redefinitions are allowed, the code will still compile (but with a\nwarning), and Dialyzer will not emit any additional warnings.","ref":"typespec.html#redefining-built-in-types"},{"type":"extras","title":"Type Declarations of User-Defined Types - Types and Function Specifications","doc":"As seen, the basic syntax of a type is an atom followed by closed parentheses.\nNew types are declared using `-type` and `-opaque` attributes as in the\nfollowing:\n\n```erlang\n-type my_struct_type() :: Type.\n-opaque my_opaq_type() :: Type.\n```\n\nThe type name is the atom `my_struct_type`, followed by parentheses. `Type` is a\ntype as defined in the previous section. A current restriction is that `Type`\ncan contain only predefined types, or user-defined types which are either of the\nfollowing:\n\n- Module-local type, that is, with a definition that is present in the code of\n the module\n- Remote type, that is, type defined in, and exported by, other modules; more\n about this soon.\n\nFor module-local types, the restriction that their definition exists in the\nmodule is enforced by the compiler and results in a compilation error. (A\nsimilar restriction currently exists for records.)\n\nType declarations can also be parameterized by including type variables between\nthe parentheses. The syntax of type variables is the same as Erlang variables,\nthat is, starts with an upper-case letter. These variables is to\nappear on the RHS of the definition. A concrete example follows:\n\n```erlang\n-type orddict(Key, Val) :: [{Key, Val}].\n```\n\nA module can export some types to declare that other modules are allowed to\nrefer to them as _remote types_. This declaration has the following form:\n\n```erlang\n-export_type([T1/A1, ..., Tk/Ak]).\n```\n\nHere the `Ti`s are atoms (the name of the type) and the `Ai`s are their arguments.\n\n_Example:_\n\n```erlang\n-export_type([my_struct_type/0, orddict/2]).\n```\n\nAssuming that these types are exported from module `'mod'`, you can refer to\nthem from other modules using remote type expressions like the following:\n\n```erlang\nmod:my_struct_type()\nmod:orddict(atom(), term())\n```\n\nIt is not allowed to refer to types that are not declared as exported.\n\nTypes declared as `opaque` represent sets of terms whose structure is not\nsupposed to be visible from outside of their defining module. That is, only the\nmodule defining them is allowed to depend on their term structure. Consequently,\nsuch types do not make much sense as module local - module local types are not\naccessible by other modules anyway - and is always to be exported.\n\nRead more on [Opaques](opaques.md)\n\n[](){: #typeinrecords }","ref":"typespec.html#type-declarations-of-user-defined-types"},{"type":"extras","title":"Type Information in Record Declarations - Types and Function Specifications","doc":"The types of record fields can be specified in the declaration of the record.\nThe syntax for this is as follows:\n\n```erlang\n-record(rec, {field1 :: Type1, field2, field3 :: Type3}).\n```\n\nFor fields without type annotations, their type defaults to `any()`. That is, the\nprevious example is a shorthand for the following:\n\n```erlang\n-record(rec, {field1 :: Type1, field2 :: any(), field3 :: Type3}).\n```\n\nIn the presence of initial values for fields, the type must be declared after\nthe initialization, as follows:\n\n```erlang\n-record(rec, {field1 = [] :: Type1, field2, field3 = 42 :: Type3}).\n```\n\nThe initial values for fields are to be compatible with (that is, a member of)\nthe corresponding types. This is checked by the compiler and results in a\ncompilation error if a violation is detected.\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP 19, for fields without initial values, the singleton type\n> `'undefined'` was added to all declared types. In other words, the following\n> two record declarations had identical effects:\n>\n> ```erlang\n> -record(rec, {f1 = 42 :: integer(),\n> f2 :: float(),\n> f3 :: 'a' | 'b'}).\n>\n> -record(rec, {f1 = 42 :: integer(),\n> f2 :: 'undefined' | float(),\n> f3 :: 'undefined' | 'a' | 'b'}).\n> ```\n>\n> This is no longer the case. If you require `'undefined'` in your record field\n> type, you must explicitly add it to the typespec, as in the 2nd example.\n\nAny record, containing type information or not, once defined, can be used as a\ntype using the following syntax:\n\n```text\n#rec{}\n```\n\nIn addition, the record fields can be further specified when using a record type\nby adding type information about the field as follows:\n\n```text\n#rec{some_field :: Type}\n```\n\nAny unspecified fields are assumed to have the type in the original record\ndeclaration.\n\n> #### Note {: .info }\n>\n> When records are used to create patterns for ETS and Mnesia match functions,\n> Dialyzer may need some help not to emit bad warnings. For example:\n>\n> ```erlang\n> -type height() :: pos_integer().\n> -record(person, {name :: string(), height :: height()}).\n>\n> lookup(Name, Tab) ->\n> ets:match_object(Tab, #person{name = Name, _ = '_'}).\n> ```\n>\n> Dialyzer will emit a warning since `'_'` is not in the type of record field\n> `height`.\n>\n> The recommended way of dealing with this is to declare the smallest record\n> field types to accommodate all your needs, and then create refinements as\n> needed. The modified example:\n>\n> ```erlang\n> -record(person, {name :: string(), height :: height() | '_'}).\n>\n> -type person() :: #person{height :: height()}.\n> ```\n>\n> In specifications and type declarations the type `person()` is to be preferred\n> before `#person{}`.","ref":"typespec.html#type-information-in-record-declarations"},{"type":"extras","title":"Specifications for Functions - Types and Function Specifications","doc":"A specification (or contract) for a function is given using the `-spec`\nattribute. The general format is as follows:\n\n```text\n-spec Function(ArgType1, ..., ArgTypeN) -> ReturnType.\n```\n\nAn implementation of the function with the same name `Function` must exist in\nthe current module, and the arity of the function must match the number of\narguments, otherwise the compilation fails.\n\nThe following longer format with module name is also valid as long as `Module`\nis the name of the current module. This can be useful for documentation\npurposes.\n\n```text\n-spec Module:Function(ArgType1, ..., ArgTypeN) -> ReturnType.\n```\n\nAlso, for documentation purposes, argument names can be given:\n\n```text\n-spec Function(ArgName1 :: Type1, ..., ArgNameN :: TypeN) -> RT.\n```\n\nA function specification can be overloaded. That is, it can have several types,\nseparated by a semicolon (`;`). For example:\n\n```erlang\n-spec foo(T1, T2) -> T3;\n (T4, T5) -> T6.\n```\n\nA current restriction, which currently results in a warning by Dialyzer, is that\nthe domains of the argument types cannot overlap. For example, the following\nspecification results in a warning:\n\n```erlang\n-spec foo(pos_integer()) -> pos_integer();\n (integer()) -> integer().\n```\n\nType variables can be used in specifications to specify relations for the input\nand output arguments of a function. For example, the following specification\ndefines the type of a polymorphic identity function:\n\n```text\n-spec id(X) -> X.\n```\n\nNotice that the above specification does not restrict the input and output type\nin any way. These types can be constrained by guard-like subtype constraints and\nprovide bounded quantification:\n\n```erlang\n-spec id(X) -> X when X :: tuple().\n```\n\nCurrently, the `::` constraint (read as \"is a subtype of\") is the only guard\nconstraint that can be used in the `when` part of a `-spec` attribute.\n\n> #### Note {: .info }\n>\n> The above function specification uses multiple occurrences of the same type\n> variable. That provides more type information than the following function\n> specification, where the type variables are missing:\n>\n> ```erlang\n> -spec id(tuple()) -> tuple().\n> ```\n>\n> The latter specification says that the function takes some tuple and returns\n> some tuple. The specification with the `X` type variable specifies that the\n> function takes a tuple and returns _the same_ tuple.\n>\n> However, it is up to the tools that process the specifications to choose\n> whether to take this extra information into account or not.\n\nThe scope of a `::` constraint is the `(...) -> RetType` specification after\nwhich it appears. To avoid confusion, it is suggested that different variables\nare used in different constituents of an overloaded contract, as shown in the\nfollowing example:\n\n```erlang\n-spec foo({X, integer()}) -> X when X :: atom();\n ([Y]) -> Y when Y :: number().\n```\n\nSome functions in Erlang are not meant to return; either because they define\nservers or because they are used to throw exceptions, as in the following\nfunction:\n\n```erlang\nmy_error(Err) -> throw({error, Err}).\n```\n\nFor such functions, it is recommended to use the special `t:no_return/0` type\nfor their \"return\", through a contract of the following form:\n\n```text\n-spec my_error(term()) -> no_return().\n```\n\n> #### Note {: .info }\n>\n> Erlang uses the shorthand version `_` as an anonymous type variable equivalent\n> to `t:term/0` or `t:any/0`. For example, the following function\n>\n> ```text\n> -spec Function(string(), _) -> string().\n> ```\n>\n> is equivalent to:\n>\n> ```text\n> -spec Function(string(), any()) -> string().\n> ```","ref":"typespec.html#specifications-for-functions"},{"type":"extras","title":"Opaques","doc":"\n# Opaques","ref":"opaques.html"},{"type":"extras","title":"Opaque Type Aliases - Opaques","doc":"The main use case for opacity in Erlang is to hide the implementation of a data\ntype, enabling evolving the API while minimizing the risk of breaking consumers.\nThe runtime does not check opacity. Dialyzer provides some opacity-checking, but\nthe rest is up to convention.\n\nThis document explains what Erlang opacity is (and the trade-offs involved) via\nthe example of the [`sets:set()`](`t:sets:set/0`) data type. This type _was_\ndefined in the `sets` module like this:\n\n```erlang\n-opaque set(Element) :: #set{segs :: segs(Element)}.\n```\n\nOTP 24 changed the definition to the following in\n[this commit](https://github.com/erlang/otp/commit/e66941e8d7c47b973dff94c0308ea85a6be1958e).\n\n```erlang\n-opaque set(Element) :: #set{segs :: segs(Element)} | #{Element => ?VALUE}.\n```\n\nAnd this change was safer and more backwards-compatible than if the type had\nbeen defined with `-type` instead of `-opaque`. Here is why: when a module\ndefines an `-opaque`, the contract is that only the defining module should rely\non the definition of the type: no other modules should rely on the definition.\n\nThis means that code that pattern-matched on `set` as a record/tuple technically\nbroke the contract, and opted in to being potentially broken when the definition\nof `set()` changed. Before OTP 24, this code printed `ok`. In OTP 24 it may\nerror:\n\n```erlang\ncase sets:new() of\n Set when is_tuple(Set) ->\n io:format(\"ok\")\nend.\n```\n\n**When working with an opaque defined in another module, here are some\nrecommendations:**\n\n- Don't examine the underlying type using pattern-matching, guards, or functions\n that reveal the type, such as [`tuple_size/1`](`tuple_size/1`) .\n- Instead, use functions provided by the module for working with the type. For\n example, `sets` module provides `sets:new/0`, `sets:add_element/2`,\n `sets:is_element/2`, and so on.\n- [`sets:set(a)`](`t:sets:set/1`) is a subtype of `sets:set(a | b)` and not the\n other way around. Generally, you can rely on the property that `the_opaque(T)`\n is a subtype of `the_opaque(U)` when T is a subtype of U.\n\n**When defining your own opaques, here are some recommendations:**\n\n- Since consumers are expected to not rely on the definition of the opaque type,\n you must provide functions for constructing, querying, and deconstructing\n instances of your opaque type. For example, sets can be constructed with\n `sets:new/0`, `sets:from_list/1`, `sets:add_element/2`, queried with\n `sets:is_element/2`, and deconstructed with`sets:to_list/1`.\n- Don't define an opaque with a type variable in parameter position. This breaks\n the normal and expected behavior that (for example) `my_type(a)` is a subtype\n of `my_type(a | b)`\n- Add [specs](typespec.md) to exported functions that use the opaque type\n\nNote that opaques can be harder to work with for consumers, since the consumer\nis expected not to pattern-match and must instead use functions that the author\nof the opaque type provides to use instances of the type.\n\nAlso, opacity in Erlang is skin-deep: the runtime does not enforce\nopacity-checking. So now that sets are implemented in terms of maps, an\n[`is_map/1`](`is_map/1`) check on a set _will_ pass. The opacity rules are only\nenforced by convention and by additional tooling such as Dialyzer, and this\nenforcement is not total. A determined consumer of `sets` can still reveal the\nstructure of the set, for example by printing, serializing, or using a set as a\n`t:term/0` and inspecting it via functions like [`is_map/1`](`is_map/1`) or\n`maps:get/2`. Also, Dialyzer must make some\n[approximations](https://github.com/erlang/otp/issues/5118).","ref":"opaques.html#opaque-type-aliases"},{"type":"extras","title":"Expressions","doc":"\n# Expressions\n\nIn this section, all valid Erlang expressions are listed. When writing Erlang\nprograms, it is also allowed to use macro and record expressions. However,\nthese expressions are expanded during compilation and are in that sense not true\nErlang expressions. Macro and record expressions are covered in separate\nsections:\n\n- [Preprocessor](macros.md)\n- [Records](ref_man_records.md)","ref":"expressions.html"},{"type":"extras","title":"Expression Evaluation - Expressions","doc":"All subexpressions are evaluated before an expression itself is evaluated,\nunless explicitly stated otherwise. For example, consider the expression:\n\n```\nExpr1 + Expr2\n```\n\n`Expr1` and `Expr2`, which are also expressions, are evaluated first — in any\norder — before the addition is performed.\n\nMany of the operators can only be applied to arguments of a certain type. For\nexample, arithmetic operators can only be applied to numbers. An argument of the\nwrong type causes a `badarg` runtime error.","ref":"expressions.html#expression-evaluation"},{"type":"extras","title":"Terms - Expressions","doc":"The simplest form of expression is a term, that is one of\n`t:integer/0`, `t:float/0`, `t:atom/0`, `t:string/0`, `t:list/0`,\n`t:map/0`, or `t:tuple/0`. The return value is the term itself.","ref":"expressions.html#terms"},{"type":"extras","title":"Variables - Expressions","doc":"A variable is an expression. If a variable is bound to a value, the return value\nis this value. Unbound variables are only allowed in patterns.\n\nVariables start with an uppercase letter or underscore (`_`). Variables can\ncontain alphanumeric characters, underscore, and `@`.\n\n_Examples:_\n\n```\nX\nName1\nPhoneNumber\nPhone_number\n_\n_Height\nname@node\n```\n\nVariables are bound to values using [pattern matching](patterns.md). Erlang uses\n_single assignment_, that is, a variable can only be bound once.\n\nThe _anonymous variable_ is denoted by underscore (\\_) and can be used when a\nvariable is required but its value can be ignored.\n\n_Example:_\n\n```text\n[H|_] = [1,2,3]\n```\n\nVariables starting with underscore (`_`), for example, `_Height`, are normal\nvariables, not anonymous. However, they are ignored by the compiler in the sense\nthat they do not generate warnings.\n\n_Example:_\n\nThe following code:\n\n```\nmember(_, []) ->\n [].\n```\n\ncan be rewritten to be more readable:\n\n```\nmember(Elem, []) ->\n [].\n```\n\nThis causes a warning for an unused variable, `Elem`. To avoid the warning,\nthe code can be rewritten to:\n\n```\nmember(_Elem, []) ->\n [].\n```\n\nNotice that since variables starting with an underscore are not anonymous, the\nfollowing example matches:\n\n```\n{_,_} = {1,2}\n```\n\nBut this example fails:\n\n```\n{_N,_N} = {1,2}\n```\n\nThe scope for a variable is its function clause. Variables bound in a branch of\nan `if`, `case`, or `receive` expression must be bound in all branches to have a\nvalue outside the expression. Otherwise they are regarded as unsafe outside\nthe expression.\n\nFor the `try` expression variable scoping is limited so that variables bound in\nthe expression are always unsafe outside the expression.","ref":"expressions.html#variables"},{"type":"extras","title":"Patterns - Expressions","doc":"A pattern has the same structure as a term but can contain unbound variables.\n\n_Example:_\n\n```\nName1\n[H|T]\n{error,Reason}\n```\n\nPatterns are allowed in clause heads, [case expressions](expressions.md#case),\n[receive expressions](expressions.md#receive), and\n[match expressions](expressions.md#the-match-operator).","ref":"expressions.html#patterns"},{"type":"extras","title":"The Compound Pattern Operator - Expressions","doc":"If `Pattern1` and `Pattern2` are valid patterns, the following is also a valid\npattern:\n\n```\nPattern1 = Pattern2\n```\n\nWhen matched against a term, both `Pattern1` and `Pattern2` are matched against\nthe term. The idea behind this feature is to avoid reconstruction of terms.\n\n_Example:_\n\n```\nf({connect,From,To,Number,Options}, To) ->\n Signal = {connect,From,To,Number,Options},\n ...;\nf(Signal, To) ->\n ignore.\n```\n\ncan instead be written as\n\n```\nf({connect,_,To,_,_} = Signal, To) ->\n ...;\nf(Signal, To) ->\n ignore.\n```\n\nThe compound pattern operator does not imply that its operands are matched in\nany particular order. That means that it is not legal to bind a variable in\n`Pattern1` and use it in `Pattern2`, or vice versa.","ref":"expressions.html#the-compound-pattern-operator"},{"type":"extras","title":"String Prefix in Patterns - Expressions","doc":"When matching strings, the following is a valid pattern:\n\n```\nf(\"prefix\" ++ Str) -> ...\n```\n\nThis is syntactic sugar for the equivalent, but harder to read:\n\n```\nf([$p,$r,$e,$f,$i,$x | Str]) -> ...\n```","ref":"expressions.html#string-prefix-in-patterns"},{"type":"extras","title":"Expressions in Patterns - Expressions","doc":"An arithmetic expression can be used within a pattern if it meets both of the\nfollowing two conditions:\n\n- It uses only numeric or bitwise operators.\n- Its value can be evaluated to a constant when complied.\n\n_Example:_\n\n```\ncase {Value, Result} of\n {?THRESHOLD+1, ok} -> ...\n```","ref":"expressions.html#expressions-in-patterns"},{"type":"extras","title":"The Match Operator - Expressions","doc":"The following matches `Pattern` against `Expr`:\n\n```\nPattern = Expr\n```\n\nIf the matching succeeds, any unbound variable in the pattern becomes bound and\nthe value of `Expr` is returned.\n\nIf multiple match operators are applied in sequence, they will be evaluated from\nright to left.\n\nIf the matching fails, a `badmatch` run-time error occurs.\n\n_Examples:_\n\n```\n1> {A, B} = T = {answer, 42}.\n{answer,42}\n2> A.\nanswer\n3> B.\n42\n4> T.\n{answer,42}\n5> {C, D} = [1, 2].\n** exception error: no match of right-hand side value [1,2]\n```\n\nBecause multiple match operators are evaluated from right to left, it means\nthat:\n\n```\nPattern1 = Pattern2 = . . . = PatternN = Expression\n```\n\nis equivalent to:\n\n```\nTemporary = Expression,\nPatternN = Temporary,\n .\n .\n .,\nPattern2 = Temporary,\nPattern = Temporary\n```","ref":"expressions.html#the-match-operator"},{"type":"extras","title":"The Match Operator and the Compound Pattern Operator - Expressions","doc":"> #### Note {: .info }\n>\n> This is an advanced section, which references to topics not yet introduced. It\n> can safely be skipped on a first reading.\n\nThe `=` character is used to denote two similar but distinct operators: the\nmatch operator and the compound pattern operator. Which one is meant is\ndetermined by context.\n\nThe _compound pattern operator_ is used to construct a compound pattern from two\npatterns. Compound patterns are accepted everywhere a pattern is accepted. A\ncompound pattern matches if all of its constituent patterns match. It is not\nlegal for a pattern that is part of a compound pattern to use variables (as keys\nin map patterns or sizes in binary patterns) bound in other sub patterns of the\nsame compound pattern.\n\n_Examples:_\n\n```\n1> fun(#{Key := Value} = #{key := Key}) -> Value end.\n* 1:7: variable 'Key' is unbound\n2> F = fun({A, B} = E) -> {E, A + B} end, F({1,2}).\n{{1,2},3}\n3> G = fun(< > = < >) -> {A, B, C} end, G(<<42,43>>).\n{42,43,10795}\n```\n\nThe _match operator_ is allowed everywhere an expression is allowed. It is used\nto match the value of an expression to a pattern. If multiple match operators\nare applied in sequence, they will be evaluated from right to left.\n\n_Examples:_\n\n```\n1> M = #{key => key2, key2 => value}.\n#{key => key2,key2 => value}\n2> f(Key), #{Key := Value} = #{key := Key} = M, Value.\nvalue\n3> f(Key), #{Key := Value} = (#{key := Key} = M), Value.\nvalue\n4> f(Key), (#{Key := Value} = #{key := Key}) = M, Value.\n* 1:12: variable 'Key' is unbound\n5> < > = begin Y = 8, <<42:8>> end, X.\n42\n```\n\nThe expression at prompt `2>` first matches the value of variable `M` against\npattern `#{key := Key}`, binding variable `Key`. It then matches the value of\n`M` against pattern `#{Key := Value}` using variable `Key` as the key, binding\nvariable `Value`.\n\nThe expression at prompt `3>` matches expression `(#{key := Key} = M)` against\npattern `#{Key := Value}`. The expression inside the parentheses is evaluated\nfirst. That is, `M` is matched against `#{key := Key}`, and then the value of\n`M` is matched against pattern `#{Key := Value}`. That is the same evaluation\norder as in _2_; therefore, the parentheses are redundant.\n\nIn the expression at prompt `4>` the expression `M` is matched against a pattern\ninside parentheses. Since the construct inside the parentheses is a pattern, the\n`=` that separates the two patterns is the compound pattern operator (_not_ the\nmatch operator). The match fails because the two sub patterns are matched at the\nsame time, and the variable `Key` is therefore not bound when matching against\npattern `#{Key := Value}`.\n\nIn the expression at prompt `5>` the expressions inside the\n[block expression](expressions.md#block-expressions) are evaluated first,\nbinding variable `Y` and creating a binary. The binary is then matched against\npattern `< >` using the value of `Y` as the size of the segment.","ref":"expressions.html#the-match-operator-and-the-compound-pattern-operator"},{"type":"extras","title":"Function Calls - Expressions","doc":"```\nExprF(Expr1,...,ExprN)\nExprM:ExprF(Expr1,...,ExprN)\n```\n\nIn the first form of function calls, `ExprM:ExprF(Expr1,...,ExprN)`, each of\n`ExprM` and `ExprF` must be an atom or an expression that evaluates to an atom.\nThe function is said to be called by using the _fully qualified function name_.\nThis is often referred to as a _remote_ or _external function call_.\n\n_Example:_\n\n```\nlists:keyfind(Name, 1, List)\n```\n\nIn the second form of function calls, `ExprF(Expr1,...,ExprN)`, `ExprF` must be\nan atom or evaluate to a fun.\n\nIf `ExprF` is an atom, the function is said to be called by using the\n_implicitly qualified function name_. If the function `ExprF` is locally\ndefined, it is called. Alternatively, if `ExprF` is explicitly imported from the\n`M` module, `M:ExprF(Expr1,...,ExprN)` is called. If `ExprF` is neither declared\nlocally nor explicitly imported, `ExprF` must be the name of an automatically\nimported BIF.\n\n_Examples:_\n\n```\nhandle(Msg, State)\nspawn(m, init, [])\n```\n\n_Examples_ where `ExprF` is a fun:\n\n```\n1> Fun1 = fun(X) -> X+1 end,\nFun1(3).\n4\n2> fun lists:append/2([1,2], [3,4]).\n[1,2,3,4]\n3>\n```\n\nNotice that when calling a local function, there is a difference between using\nthe implicitly or fully qualified function name. The latter always refers to the\nlatest version of the module. See\n[Compilation and Code Loading ](code_loading.md)and\n[Function Evaluation](ref_man_functions.md#eval).","ref":"expressions.html#function-calls"},{"type":"extras","title":"Local Function Names Clashing With Auto-Imported BIFs - Expressions","doc":"If a local function has the same name as an auto-imported BIF, the semantics is\nthat implicitly qualified function calls are directed to the locally defined\nfunction, not to the BIF. To avoid confusion, there is a compiler directive\navailable, `-compile({no_auto_import,[F/A]})`, that makes a BIF not being\nauto-imported. In certain situations, such a compile-directive is mandatory.\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP R14A (ERTS version 5.8), an implicitly qualified function call to a\n> function having the same name as an auto-imported BIF always resulted in the\n> BIF being called. In newer versions of the compiler, the local function is\n> called instead. This is to avoid that future additions to the set of\n> auto-imported BIFs do not silently change the behavior of old code.\n\nHowever, to avoid that old (pre R14) code changed its behavior when compiled\nwith Erlang/OTP version R14A or later, the following restriction applies: If you\noverride the name of a BIF that was auto-imported in OTP versions prior to R14A\n(ERTS version 5.8) and have an implicitly qualified call to that function in\nyour code, you either need to explicitly remove the auto-import using a compiler\ndirective, or replace the call with a fully qualified function call. Otherwise\nyou get a compilation error. See the following example:\n\n```\n-export([length/1,f/1]).\n\n-compile({no_auto_import,[length/1]}). % erlang:length/1 no longer autoimported\n\nlength([]) ->\n 0;\nlength([H|T]) ->\n 1 + length(T). %% Calls the local function length/1\n\nf(X) when erlang:length(X) > 3 -> %% Calls erlang:length/1,\n %% which is allowed in guards\n long.\n```\n\nThe same logic applies to explicitly imported functions from other modules, as\nto locally defined functions. It is not allowed to both import a function from\nanother module and have the function declared in the module at the same time:\n\n```\n-export([f/1]).\n\n-compile({no_auto_import,[length/1]}). % erlang:length/1 no longer autoimported\n\n-import(mod,[length/1]).\n\nf(X) when erlang:length(X) > 33 -> %% Calls erlang:length/1,\n %% which is allowed in guards\n\n erlang:length(X); %% Explicit call to erlang:length in body\n\nf(X) ->\n length(X). %% mod:length/1 is called\n```\n\nFor auto-imported BIFs added in Erlang/OTP R14A and thereafter, overriding the\nname with a local function or explicit import is always allowed. However, if the\n`-compile({no_auto_import,[F/A])` directive is not used, the compiler issues a\nwarning whenever the function is called in the module using the implicitly\nqualified function name.","ref":"expressions.html#local-function-names-clashing-with-auto-imported-bifs"},{"type":"extras","title":"If - Expressions","doc":"```\nif\n GuardSeq1 ->\n Body1;\n ...;\n GuardSeqN ->\n BodyN\nend\n```\n\nThe branches of an `if`\\-expression are scanned sequentially until a guard\nsequence `GuardSeq` that evaluates to true is found. Then the corresponding\n`Body` (a sequence of expressions separated by `,`) is evaluated.\n\nThe return value of `Body` is the return value of the `if` expression.\n\nIf no guard sequence is evaluated as true, an `if_clause` run-time error occurs.\nIf necessary, the guard expression `true` can be used in the last branch, as\nthat guard sequence is always true.\n\n_Example:_\n\n```\nis_greater_than(X, Y) ->\n if\n X > Y ->\n true;\n true -> % works as an 'else' branch\n false\n end\n```","ref":"expressions.html#if"},{"type":"extras","title":"Case - Expressions","doc":"```\ncase Expr of\n Pattern1 [when GuardSeq1] ->\n Body1;\n ...;\n PatternN [when GuardSeqN] ->\n BodyN\nend\n```\n\nThe expression `Expr` is evaluated and the patterns `Pattern` are sequentially\nmatched against the result. If a match succeeds and the optional guard sequence\n`GuardSeq` is true, the corresponding `Body` is evaluated.\n\nThe return value of `Body` is the return value of the `case` expression.\n\nIf there is no matching pattern with a true guard sequence, a `case_clause`\nrun-time error occurs.\n\n_Example:_\n\n```\nis_valid_signal(Signal) ->\n case Signal of\n {signal, _What, _From, _To} ->\n true;\n {signal, _What, _To} ->\n true;\n _Else ->\n false\n end.\n```","ref":"expressions.html#case"},{"type":"extras","title":"Maybe - Expressions","doc":"> #### Change {: .info }\n>\n> The `maybe` [feature](`e:system:features.md#features`) was introduced\n> in Erlang/OTP 25. Starting from Erlang/OTP 27 is is enabled by default.\n\n```\nmaybe\n Expr1,\n ...,\n ExprN\nend\n```\n\nThe expressions in a `maybe` block are evaluated sequentially. If all\nexpressions are evaluated successfully, the return value of the `maybe` block is\n`ExprN`. However, execution can be short-circuited by a conditional match\nexpression:\n\n```\nExpr1 ?= Expr2\n```\n\n`?=` is called the conditional match operator. It is only allowed to be used at\nthe top-level of a `maybe` block. It matches the pattern `Expr1` against\n`Expr2`. If the matching succeeds, any unbound variable in the pattern becomes\nbound. If the expression is the last expression in the `maybe` block, it also\nreturns the value of `Expr2`. If the matching is unsuccessful, the rest of the\nexpressions in the `maybe` block are skipped and the return value of the `maybe`\nblock is `Expr2`.\n\nNone of the variables bound in a `maybe` block must be used in the code that\nfollows the block.\n\nHere is an example:\n\n```\nmaybe\n {ok, A} ?= a(),\n true = A >= 0,\n {ok, B} ?= b(),\n A + B\nend\n```\n\nLet us first assume that `a()` returns `{ok,42}` and `b()` returns `{ok,58}`.\nWith those return values, all of the match operators will succeed, and the\nreturn value of the `maybe` block is `A + B`, which is equal to `42 + 58 = 100`.\n\nNow let us assume that `a()` returns `error`. The conditional match operator in\n`{ok, A} ?= a()` fails to match, and the return value of the `maybe` block is\nthe value of the expression that failed to match, namely `error`. Similarly, if\n`b()` returns `wrong`, the return value of the `maybe` block is `wrong`.\n\nFinally, let us assume that `a()` returns `{ok,-1}`. Because `true = A >= 0` uses\nthe match operator `=`, a `{badmatch,false}` run-time error occurs when the\nexpression fails to match the pattern.\n\nThe example can be written in a less succient way using nested case expressions:\n\n```\ncase a() of\n {ok, A} ->\n true = A >= 0,\n case b() of\n {ok, B} ->\n A + B;\n Other1 ->\n Other1\n end;\n Other2 ->\n Other2\nend\n```\n\nThe `maybe` block can be augmented with `else` clauses:\n\n```\nmaybe\n Expr1,\n ...,\n ExprN\nelse\n Pattern1 [when GuardSeq1] ->\n Body1;\n ...;\n PatternN [when GuardSeqN] ->\n BodyN\nend\n```\n\nIf a conditional match operator fails, the failed expression is matched against\nthe patterns in all clauses between the `else` and `end` keywords. If a match\nsucceeds and the optional guard sequence `GuardSeq` is true, the corresponding\n`Body` is evaluated. The value returned from the body is the return value of the\n`maybe` block.\n\nIf there is no matching pattern with a true guard sequence, an `else_clause`\nrun-time error occurs.\n\nNone of the variables bound in a `maybe` block must be used in the `else`\nclauses. None of the variables bound in the `else` clauses must be used in the\ncode that follows the `maybe` block.\n\nHere is the previous example augmented with `else` clauses:\n\n```\nmaybe\n {ok, A} ?= a(),\n true = A >= 0,\n {ok, B} ?= b(),\n A + B\nelse\n error -> error;\n wrong -> error\nend\n```\n\nThe `else` clauses translate the failing value from the conditional match\noperators to the value `error`. If the failing value is not one of the\nrecognized values, a `else_clause` run-time error occurs.","ref":"expressions.html#maybe"},{"type":"extras","title":"Send - Expressions","doc":"```\nExpr1 ! Expr2\n```\n\nSends the value of `Expr2` as a message to the process specified by `Expr1`. The\nvalue of `Expr2` is also the return value of the expression.\n\n`Expr1` must evaluate to a pid, an alias (reference), a port, a registered name\n(atom), or a tuple `{Name,Node}`. `Name` is an atom and `Node` is a node name,\nalso an atom.\n\n- If `Expr1` evaluates to a name, but this name is not registered, a `badarg`\n run-time error occurs.\n- Sending a message to a reference never fails, even if the reference is no\n longer (or never was) an alias.\n- Sending a message to a pid never fails, even if the pid identifies a\n non-existing process.\n- Distributed message sending, that is, if `Expr1` evaluates to a tuple\n `{Name,Node}` (or a pid located at another node), also never fails.","ref":"expressions.html#send"},{"type":"extras","title":"Receive - Expressions","doc":"```\nreceive\n Pattern1 [when GuardSeq1] ->\n Body1;\n ...;\n PatternN [when GuardSeqN] ->\n BodyN\nend\n```\n\nFetches a received message present in the message queue of the process. The\nfirst message in the message queue is matched sequentially against the patterns\nfrom top to bottom. If no match was found, the matching sequence is repeated for\nthe second message in the queue, and so on. Messages are queued in the\n[order they were received](ref_man_processes.md#message-queue-order). If a match\nsucceeds, that is, if the `Pattern` matches and the optional guard sequence\n`GuardSeq` is true, then the message is removed from the message queue and the\ncorresponding `Body` is evaluated. All other messages in the message queue\nremain unchanged.\n\nThe return value of `Body` is the return value of the `receive` expression.\n\n`receive` never fails. The execution is suspended, possibly indefinitely, until\na message arrives that matches one of the patterns and with a true guard\nsequence.\n\n_Example:_\n\n```\nwait_for_onhook() ->\n receive\n onhook ->\n disconnect(),\n idle();\n {connect, B} ->\n B ! {busy, self()},\n wait_for_onhook()\n end.\n```\n\nThe `receive` expression can be augmented with a timeout:\n\n```\nreceive\n Pattern1 [when GuardSeq1] ->\n Body1;\n ...;\n PatternN [when GuardSeqN] ->\n BodyN\nafter\n ExprT ->\n BodyT\nend\n```\n\n`receive...after` works exactly as `receive`, except that if no matching message\nhas arrived within `ExprT` milliseconds, then `BodyT` is evaluated instead. The\nreturn value of `BodyT` then becomes the return value of the `receive...after`\nexpression. `ExprT` is to evaluate to an integer, or the atom `infinity`. The\nallowed integer range is from 0 to 4294967295, that is, the longest possible\ntimeout is almost 50 days. With a zero value the timeout occurs immediately if\nthere is no matching message in the message queue.\n\nThe atom `infinity` will make the process wait indefinitely for a matching\nmessage. This is the same as not using a timeout. It can be useful for timeout\nvalues that are calculated at runtime.\n\n_Example:_\n\n```\nwait_for_onhook() ->\n receive\n onhook ->\n disconnect(),\n idle();\n {connect, B} ->\n B ! {busy, self()},\n wait_for_onhook()\n after\n 60000 ->\n disconnect(),\n error()\n end.\n```\n\nIt is legal to use a `receive...after` expression with no branches:\n\n```\nreceive\nafter\n ExprT ->\n BodyT\nend\n```\n\nThis construction does not consume any messages, only suspends execution in the\nprocess for `ExprT` milliseconds. This can be used to implement simple timers.\n\n_Example:_\n\n```\ntimer() ->\n spawn(m, timer, [self()]).\n\ntimer(Pid) ->\n receive\n after\n 5000 ->\n Pid ! timeout\n end.\n```","ref":"expressions.html#receive"},{"type":"extras","title":"Term Comparisons - Expressions","doc":"```\nExpr1 op Expr2\n```\n\n| _op_ | _Description_ |\n| ------ | ------------------------ |\n| `==` | Equal to |\n| `/=` | Not equal to |\n| `=<` | Less than or equal to |\n| `<` | Less than |\n| `>=` | Greater than or equal to |\n| `>` | Greater than |\n| `=:=` | Term equivalence |\n| `=/=` | Term non-equivalence |\n\n_Table: Term Comparison Operators._\n\nThe arguments can be of different data types. The following order is defined:\n\n```text\nnumber 1 == 1.0.\ntrue\n2> 1 =:= 1.0.\nfalse\n3> 0 =:= 0.0.\nfalse\n4> 0.0 =:= -0.0.\nfalse\n5> 0.0 =:= +0.0.\ntrue\n6> 1 > a.\nfalse\n7> #{c => 3} > #{a => 1, b => 2}.\nfalse\n8> #{a => 1, b => 2} == #{a => 1.0, b => 2.0}.\ntrue\n9> <<2:2>> < <<128>>.\ntrue\n10> <<3:2>> < <<128>>.\nfalse\n```\n\n> #### Note {: .info }\n>\n> Prior to OTP 27, the term equivalence operators considered `0.0`\n> and `-0.0` to be the same term.\n>\n> This was changed in OTP 27 but legacy code may have expected them to be\n> considered the same. To help users catch errors that may arise from an\n> upgrade, the compiler raises a warning when `0.0` is pattern-matched or used\n> in a term equivalence test.\n>\n> If you need to match `0.0` specifically, the warning can be silenced by\n> writing `+0.0` instead, which produces the same term but makes the compiler\n> interpret the match as being done on purpose.","ref":"expressions.html#term-comparisons"},{"type":"extras","title":"Arithmetic Expressions - Expressions","doc":"```\nop Expr\nExpr1 op Expr2\n```\n\n| _Operator_ | _Description_ | _Argument Type_ |\n| ------------ | ------------------------- | --------------- |\n| `+` | Unary + | Number |\n| `-` | Negation (unary -) | Number |\n| `+` | Addition | Number |\n| `-` | Subtraction | Number |\n| `*` | Multiplication | Number |\n| `/` | Floating point division | Number |\n| `bnot` | Unary bitwise NOT | Integer |\n| `div` | Integer division | Integer |\n| `rem` | Integer remainder of X/Y | Integer |\n| `band` | Bitwise AND | Integer |\n| `bor` | Bitwise OR | Integer |\n| `bxor` | Bitwise XOR | Integer |\n| `bsl` | Bitshift left | Integer |\n| `bsr` | Arithmetic bitshift right | Integer |\n\n_Table: Arithmetic Operators._\n\n_Examples:_\n\n```\n1> +1.\n1\n2> -1.\n-1\n3> 1+1.\n2\n4> 4/2.\n2.0\n5> 5 div 2.\n2\n6> 5 rem 2.\n1\n7> 2#10 band 2#01.\n0\n8> 2#10 bor 2#01.\n3\n9> a + 10.\n** exception error: an error occurred when evaluating an arithmetic expression\n in operator +/2\n called as a + 10\n10> 1 bsl (1 bsl 64).\n** exception error: a system limit has been reached\n in operator bsl/2\n called as 1 bsl 18446744073709551616\n```","ref":"expressions.html#arithmetic-expressions"},{"type":"extras","title":"Boolean Expressions - Expressions","doc":"```\nop Expr\nExpr1 op Expr2\n```\n\n| _Operator_ | _Description_ |\n| ---------- | ----------------- |\n| `not` | Unary logical NOT |\n| `and` | Logical AND |\n| `or` | Logical OR |\n| `xor` | Logical XOR |\n\n_Table: Logical Operators._\n\n_Examples:_\n\n```\n1> not true.\nfalse\n2> true and false.\nfalse\n3> true xor false.\ntrue\n4> true or garbage.\n** exception error: bad argument\n in operator or/2\n called as true or garbage\n```","ref":"expressions.html#boolean-expressions"},{"type":"extras","title":"Short-Circuit Expressions - Expressions","doc":"```\nExpr1 orelse Expr2\nExpr1 andalso Expr2\n```\n\n`Expr2` is evaluated only if necessary. That is, `Expr2` is evaluated only if:\n\n- `Expr1` evaluates to `false` in an `orelse` expression.\n\nor\n\n- `Expr1` evaluates to `true` in an `andalso` expression.\n\nReturns either the value of `Expr1` (that is, `true` or `false`) or the value of\n`Expr2` (if `Expr2` is evaluated).\n\n_Example 1:_\n\n```\ncase A >= -1.0 andalso math:sqrt(A+1) > B of\n```\n\nThis works even if `A` is less than `-1.0`, since in that case, `math:sqrt/1` is\nnever evaluated.\n\n_Example 2:_\n\n```\nOnlyOne = is_atom(L) orelse\n (is_list(L) andalso length(L) == 1),\n```\n\n`Expr2` is not required to evaluate to a Boolean value. Because of that,\n`andalso` and `orelse` are tail-recursive.\n\n_Example 3 (tail-recursive function):_\n\n```\nall(Pred, [Hd|Tail]) ->\n Pred(Hd) andalso all(Pred, Tail);\nall(_, []) ->\n true.\n```\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP R13A, `Expr2` was required to evaluate to a Boolean value,\n> and as consequence, `andalso` and `orelse` were **not** tail-recursive.","ref":"expressions.html#short-circuit-expressions"},{"type":"extras","title":"List Operations - Expressions","doc":"```\nExpr1 ++ Expr2\nExpr1 -- Expr2\n```\n\nThe list concatenation operator `++` appends its second argument to its first\nand returns the resulting list.\n\nThe list subtraction operator `--` produces a list that is a copy of the first\nargument. The procedure is as follows: for each element in the second argument,\nthe first occurrence of this element (if any) is removed.\n\n_Example:_\n\n```\n1> [1,2,3] ++ [4,5].\n[1,2,3,4,5]\n2> [1,2,3,2,1,2] -- [2,1,2].\n[3,1,2]\n```","ref":"expressions.html#list-operations"},{"type":"extras","title":"Map Expressions - Expressions","doc":"","ref":"expressions.html#map-expressions"},{"type":"extras","title":"Creating Maps - Expressions","doc":"Constructing a new map is done by letting an expression `K` be associated with\nanother expression `V`:\n\n```\n#{K => V}\n```\n\nNew maps can include multiple associations at construction by listing every\nassociation:\n\n```\n#{K1 => V1, ..., Kn => Vn}\n```\n\nAn empty map is constructed by not associating any terms with each other:\n\n```\n#{}\n```\n\nAll keys and values in the map are terms. Any expression is first evaluated and\nthen the resulting terms are used as _key_ and _value_ respectively.\n\nKeys and values are separated by the `=>` arrow and associations are separated\nby a comma (`,`).\n\n_Examples:_\n\n```\nM0 = #{}, % empty map\nM1 = #{a => <<\"hello\">>}, % single association with literals\nM2 = #{1 => 2, b => b}, % multiple associations with literals\nM3 = #{k => {A,B}}, % single association with variables\nM4 = #{{\"w\", 1} => f()}. % compound key associated with an evaluated expression\n```\n\nHere, `A` and `B` are any expressions and `M0` through `M4` are the resulting\nmap terms.\n\nIf two matching keys are declared, the latter key takes precedence.\n\n_Example:_\n\n```\n1> #{1 => a, 1 => b}.\n#{1 => b }\n2> #{1.0 => a, 1 => b}.\n#{1 => b, 1.0 => a}\n```\n\nThe order in which the expressions constructing the keys (and their associated\nvalues) are evaluated is not defined. The syntactic order of the key-value pairs\nin the construction is of no relevance, except in the recently mentioned case of\ntwo matching keys.","ref":"expressions.html#creating-maps"},{"type":"extras","title":"Updating Maps - Expressions","doc":"Updating a map has a similar syntax as constructing it.\n\nAn expression defining the map to be updated is put in front of the expression\ndefining the keys to be updated and their respective values:\n\n```\nM#{K => V}\n```\n\nHere `M` is a term of type map and `K` and `V` are any expression.\n\nIf key `K` does not match any existing key in the map, a new association is\ncreated from key `K` to value `V`.\n\nIf key `K` matches an existing key in map `M`, its associated value is replaced\nby the new value `V`. In both cases, the evaluated map expression returns a new\nmap.\n\nIf `M` is not of type map, an exception of type `badmap` is raised.\n\nTo only update an existing value, the following syntax is used:\n\n```\nM#{K := V}\n```\n\nHere `M` is a term of type map, `V` is an expression and `K` is an expression\nthat evaluates to an existing key in `M`.\n\nIf key `K` does not match any existing keys in map `M`, an exception of type\n`badkey` is raised at runtime. If a matching key `K` is present in map `M`,\nits associated value is replaced by the new value `V`, and the evaluated map\nexpression returns a new map.\n\nIf `M` is not of type map, an exception of type `badmap` is raised.\n\n_Examples:_\n\n```\nM0 = #{},\nM1 = M0#{a => 0},\nM2 = M1#{a => 1, b => 2},\nM3 = M2#{\"function\" => fun() -> f() end},\nM4 = M3#{a := 2, b := 3}. % 'a' and 'b' was added in `M1` and `M2`.\n```\n\nHere `M0` is any map. It follows that `M1` through `M4` are maps as well.\n\n_More examples:_\n\n```\n1> M = #{1 => a}.\n#{1 => a }\n2> M#{1.0 => b}.\n#{1 => a, 1.0 => b}.\n3> M#{1 := b}.\n#{1 => b}\n4> M#{1.0 := b}.\n** exception error: bad argument\n```\n\nAs in construction, the order in which the key and value expressions are\nevaluated is not defined. The syntactic order of the key-value pairs in the\nupdate is of no relevance, except in the case where two keys match. In that\ncase, the latter value is used.","ref":"expressions.html#updating-maps"},{"type":"extras","title":"Maps in Patterns - Expressions","doc":"Matching of key-value associations from maps is done as follows:\n\n```\n#{K := V} = M\n```\n\nHere `M` is any map. The key `K` must be a\n[guard expression](expressions.md#guard-expressions), with all variables already\nbound. `V` can be any pattern with either bound or unbound variables.\n\nIf the variable `V` is unbound, it becomes bound to the value associated with\nthe key `K`, which must exist in the map `M`. If the variable `V` is bound, it\nmust match the value associated with `K` in `M`.\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP 23, the expression defining the key `K` was restricted to be\n> either a single variable or a literal.\n\n_Example:_\n\n```\n1> M = #{\"tuple\" => {1,2}}.\n#{\"tuple\" => {1,2}}\n2> #{\"tuple\" := {1,B}} = M.\n#{\"tuple\" => {1,2}}\n3> B.\n2.\n```\n\nThis binds variable `B` to integer `2`.\n\nSimilarly, multiple values from the map can be matched:\n\n```\n#{K1 := V1, ..., Kn := Vn} = M\n```\n\nHere keys `K1` through `Kn` are any expressions with literals or bound\nvariables. If all key expressions evaluate successfully and all keys\nexist in map `M`, all variables in `V1 .. Vn` is matched to the\nassociated values of their respective keys.\n\nIf the matching conditions are not met the match fails.\n\nNote that when matching a map, only the `:=` operator (not the `=>`) is allowed\nas a delimiter for the associations.\n\nThe order in which keys are declared in matching has no relevance.\n\nDuplicate keys are allowed in matching and match each pattern associated to the\nkeys:\n\n```\n#{K := V1, K := V2} = M\n```\n\nThe empty map literal (`#{}`) matches any map when used as a pattern:\n\n```\n#{} = Expr\n```\n\nThis expression matches if the expression `Expr` is of type map, otherwise it\nfails with an exception `badmatch`.\n\nHere the key to be retrieved is constructed from an expression:\n\n```\n#{{tag,length(List)} := V} = Map\n```\n\n`List` must be an already bound variable.\n\n#### Matching Syntax\n\nMatching of literals as keys are allowed in function heads:\n\n```\n%% only start if not_started\nhandle_call(start, From, #{state := not_started} = S) ->\n...\n {reply, ok, S#{state := start}};\n\n%% only change if started\nhandle_call(change, From, #{state := start} = S) ->\n...\n {reply, ok, S#{state := changed}};\n```","ref":"expressions.html#maps-in-patterns"},{"type":"extras","title":"Maps in Guards - Expressions","doc":"Maps are allowed in guards as long as all subexpressions are valid guard\nexpressions.\n\nThe following guard BIFs handle maps:\n\n- [is_map/1](`erlang:is_map/1`) in the `erlang` module\n- [is_map_key/2](`erlang:is_map_key/2`) in the `erlang` module\n- [map_get/2](`erlang:map_get/2`) in the `erlang` module\n- [map_size/1](`erlang:map_size/1`) in the `erlang` module","ref":"expressions.html#maps-in-guards"},{"type":"extras","title":"Bit Syntax Expressions - Expressions","doc":"The bit syntax operates on _bit strings_. A bit string is a sequence of bits\nordered from the most significant bit to the least significant bit.\n\n```\n<<>> % The empty bit string, zero length\n< >\n< >\n```\n\nEach element `Ei` specifies a _segment_ of the bit string. The segments are\nordered left to right from the most significant bit to the least significant bit\nof the bit string.\n\nEach segment specification `Ei` is a value, followed by an optional _size\nexpression_ and an optional _type specifier list_.\n\n```\nEi = Value |\n Value:Size |\n Value/TypeSpecifierList |\n Value:Size/TypeSpecifierList\n```\n\nWhen used in a bit string construction, `Value` is an expression that is to\nevaluate to an integer, float, or bit string. If the expression is not a single\nliteral or variable, it is to be enclosed in parentheses.\n\nWhen used in a bit string matching, `Value` must be a variable, or an integer,\nfloat, or string.\n\nNotice that, for example, using a string literal as in `<<\"abc\">>` is syntactic\nsugar for `<<$a,$b,$c>>`.\n\nWhen used in a bit string construction, `Size` is an expression that is to\nevaluate to an integer.\n\nWhen used in a bit string matching, `Size` must be a\n[guard expression](expressions.md#guard-expressions) that evaluates to an\ninteger. All variables in the guard expression must be already bound.\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP 23, `Size` was restricted to be an integer or a variable\n> bound to an integer.\n\nThe value of `Size` specifies the size of the segment in units (see below). The\ndefault value depends on the type (see below):\n\n- For `integer` it is 8.\n- For `float` it is 64.\n- For `binary` and `bitstring` it is the whole binary or bit string.\n\nIn matching, the default value for a binary or bit string segment is only valid\nfor the last element. All other bit string or binary elements in the matching\nmust have a size specification.\n\n[](){: #binaries }\n\n**Binaries**\n\nA bit string with a length that is a multiple of 8 bits is known as a _binary_,\nwhich is the most common and useful type of bit string.\n\nA binary has a canonical representation in memory. Here follows a sequence of\nbytes where each byte's value is its sequence number:\n\n```\n<<1, 2, 3, 4, 5, 6, 7, 8, 9, 10>>\n```\n\nBit strings are a later generalization of binaries, so many texts and much\ninformation about binaries apply just as well for bit strings.\n\n**Example:**\n\n```\n1> < > = <<\"abcde\">>.\n* 1:3: a binary field without size is only allowed at the end of a binary pattern\n2> < > = <<\"abcde\">>.\n<<\"abcde\">>\n3> A.\n<<\"abc\">>\n4> B.\n<<\"de\">>\n```\n\nFor the `utf8`, `utf16`, and `utf32` types, `Size` must not be given. The size\nof the segment is implicitly determined by the type and value itself.\n\n`TypeSpecifierList` is a list of type specifiers, in any order, separated by\nhyphens (-). Default values are used for any omitted type specifiers.\n\n- **`Type`= `integer` | `float` | `binary` | `bytes` | `bitstring` | `bits` |\n `utf8` | `utf16` | `utf32`** - The default is `integer`. `bytes` is a\n shorthand for `binary` and `bits` is a shorthand for `bitstring`. See below\n for more information about the `utf` types.\n\n- **`Signedness`= `signed` | `unsigned`** - Only matters for matching and when\n the type is `integer`. The default is `unsigned`.\n\n- **`Endianness`= `big` | `little` | `native`** - Specifies byte level (octet\n level) endianness (byte order). Native-endian means that the endianness is\n resolved at load time to be either big-endian or little-endian, depending on\n what is native for the CPU that the Erlang machine is run on. Endianness only\n matters when the **Type** is either `integer`, `utf16`, `utf32`, or `float`. The\n default is `big`.\n\n ```\n <<16#1234:16/little>> = <<16#3412:16>> = <<16#34:8, 16#12:8>>\n ```\n\n- **`Unit`= `unit:IntegerLiteral`** - The allowed range is 1 through 256.\n Defaults to 1 for `integer`, `float`, and `bitstring`, and to 8 for `binary`.\n For types `bitstring`, `bits`, and `bytes`, it is not allowed to specify a\n unit value different from the default value. No unit specifier must be given\n for the types `utf8`, `utf16`, and `utf32`.","ref":"expressions.html#bit-syntax-expressions"},{"type":"extras","title":"Integer segments - Expressions","doc":"The value of `Size` multiplied with the unit gives the size of the segment in\nbits.\n\nWhen constructing bit strings, if the size `N` of an integer segment is too\nsmall to contain the given integer, the most significant bits of the integer are\nsilently discarded and only the `N` least significant bits are put into the bit\nstring. For example, `<<16#ff:4>>` will result in the bit string `<<15:4>>`.","ref":"expressions.html#integer-segments"},{"type":"extras","title":"Float segments - Expressions","doc":"The value of `Size` multiplied with the unit gives the size of the segment in\nbits. The size of a float segment in bits must be one of 16, 32, or 64.\n\nWhen constructing bit strings, if the size of a float segment is too small to\ncontain the representation of the given float value, an exception is raised.\n\nWhen matching bit strings, matching of float segments fails if the bits of the\nsegment does not contain the representation of a finite floating point value.","ref":"expressions.html#float-segments"},{"type":"extras","title":"Binary segments - Expressions","doc":"In this section, the phrase \"binary segment\" refers to any one of the segment\ntypes `binary`, `bitstring`, `bytes`, and `bits`.\n\nSee also the paragraphs about [Binaries](expressions.md#binaries).\n\nWhen constructing binaries and no size is specified for a binary segment, the\nentire binary value is interpolated into the binary being constructed. However,\nthe size in bits of the binary being interpolated must be evenly divisible by\nthe unit value for the segment; otherwise an exception is raised.\n\nFor example, the following examples all succeed:\n\n```\n1> <<(<<\"abc\">>)/bitstring>>.\n<<\"abc\">>\n2> <<(<<\"abc\">>)/binary-unit:1>>.\n<<\"abc\">>\n3> <<(<<\"abc\">>)/binary>>.\n<<\"abc\">>\n```\n\nThe first two examples have a unit value of 1 for the segment, while the third\nsegment has a unit value of 8.\n\nAttempting to interpolate a bit string of size 1 into a binary segment with unit\n8 (the default unit for `binary`) fails as shown in this example:\n\n```\n1> <<(<<1:1>>)/binary>>.\n** exception error: bad argument\n```\n\nFor the construction to succeed, the unit value of the segment must be 1:\n\n```\n2> <<(<<1:1>>)/bitstring>>.\n<<1:1>>\n3> <<(<<1:1>>)/binary-unit:1>>.\n<<1:1>>\n```\n\nSimilarly, when matching a binary segment with no size specified, the match\nsucceeds if and only if the size in bits of the rest of the binary is evenly\ndivisible by the unit value:\n\n```\n1> <<_/binary-unit:16>> = <<\"\">>.\n<<>>\n2> <<_/binary-unit:16>> = <<\"a\">>.\n** exception error: no match of right hand side value <<\"a\">>\n3> <<_/binary-unit:16>> = <<\"ab\">>.\n<<\"ab\">>\n4> <<_/binary-unit:16>> = <<\"abc\">>.\n** exception error: no match of right hand side value <<\"abc\">>\n5> <<_/binary-unit:16>> = <<\"abcd\">>.\n<<\"abcd\">>\n```\n\nWhen a size is explicitly specified for a binary segment, the segment size in\nbits is the value of `Size` multiplied by the default or explicit unit value.\n\nWhen constructing binaries, the size of the binary being interpolated into the\nconstructed binary must be at least as large as the size of the binary segment.\n\n**Examples:**\n\n```\n1> <<(<<\"abc\">>):2/binary>>.\n<<\"ab\">>\n2> <<(<<\"a\">>):2/binary>>.\n** exception error: construction of binary failed\n *** segment 1 of type 'binary': the value <<\"a\">> is shorter than the size of the segment\n```","ref":"expressions.html#binary-segments"},{"type":"extras","title":"Unicode segments - Expressions","doc":"The types `utf8`, `utf16`, and `utf32` specifies encoding/decoding of the\n*Unicode Transformation Format*s [UTF-8](https://en.wikipedia.org/wiki/UTF-8),\n[UTF-16](https://en.wikipedia.org/wiki/UTF-16), and\n[UTF-32](https://en.wikipedia.org/wiki/UTF-32), respectively.\n\nWhen constructing a segment of a `utf` type, `Value` must be an integer in the\nrange `0` through `16#D7FF` or `16#E000` through `16#10FFFF`. Construction fails with a\n`badarg` exception if `Value` is outside the allowed ranges. The sizes of the\nencoded values are as follows:\n\n- For `utf8`, `Value` is encoded in 1-4 bytes.\n- For `utf16`, `Value` is encoded in 2 or 4 bytes.\n- For `utf32`, `Value` is encoded in 4 bytes.\n\nWhen constructing, a literal string can be given followed by one of the UTF\ntypes, for example: `<<\"abc\"/utf8>>` which is syntactic sugar for\n`<<$a/utf8,$b/utf8,$c/utf8>>`.\n\nA successful match of a segment of a `utf` type, results in an integer in the\nrange `0` through `16#D7FF` or `16#E000` through `16#10FFFF`. The match fails if the\nreturned value falls outside those ranges.\n\nA segment of type `utf8` matches 1-4 bytes in the bit string, if the bit string\nat the match position contains a valid UTF-8 sequence. (See RFC-3629 or the\nUnicode standard.)\n\nA segment of type `utf16` can match 2 or 4 bytes in the bit string. The match\nfails if the bit string at the match position does not contain a legal UTF-16\nencoding of a Unicode code point. (See RFC-2781 or the Unicode standard.)\n\nA segment of type `utf32` can match 4 bytes in the bit string in the same way as\nan `integer` segment matches 32 bits. The match fails if the resulting integer\nis outside the legal ranges previously mentioned.\n\n_Examples:_\n\n```\n1> Bin1 = <<1,17,42>>.\n<<1,17,42>>\n2> Bin2 = <<\"abc\">>.\n<<97,98,99>>\n\n3> Bin3 = <<1,17,42:16>>.\n<<1,17,0,42>>\n4> < > = <<1,17,42:16>>.\n<<1,17,0,42>>\n5> C.\n42\n6> < > = <<1,17,42:16>>.\n<<1,17,0,42>>\n7> D.\n273\n8> F.\n42\n9> < > = <<1,17,42:16>>.\n<<1,17,0,42>>\n10> H.\n<<17,0,42>>\n11> < > = <<1,17,42:12>>.\n<<1,17,2,10:4>>\n12> J.\n<<17,2,10:4>>\n\n13> <<1024/utf8>>.\n<<208,128>>\n\n14> <<1:1,0:7>>.\n<<128>>\n15> <<16#123:12/little>> = <<16#231:12>> = <<2:4, 3:4, 1:4>>.\n<<35,1:4>>\n```\n\nNotice that bit string patterns cannot be nested.\n\nNotice also that \"`B=<<1>>`\" is interpreted as \"`B =< <1>>`\" which is a syntax\nerror. The correct way is to write a space after `=`: \"`B = <<1>>`.\n\nMore examples are provided in [Programming Examples](`e:system:bit_syntax.md`).","ref":"expressions.html#unicode-segments"},{"type":"extras","title":"Fun Expressions - Expressions","doc":"```\nfun\n [Name](Pattern11,...,Pattern1N) [when GuardSeq1] ->\n Body1;\n ...;\n [Name](PatternK1,...,PatternKN) [when GuardSeqK] ->\n BodyK\nend\n```\n\nA fun expression begins with the keyword `fun` and ends with the keyword `end`.\nBetween them is to be a function declaration, similar to a\n[regular function declaration](ref_man_functions.md#function-declaration-syntax),\nexcept that the function name is optional and is to be a variable, if any.\n\nVariables in a fun head shadow the function name and both shadow variables in\nthe function clause surrounding the fun expression. Variables bound in a fun\nbody are local to the fun body.\n\nThe return value of the expression is the resulting fun.\n\n_Examples:_\n\n```\n1> Fun1 = fun (X) -> X+1 end.\n#Fun \n2> Fun1(2).\n3\n3> Fun2 = fun (X) when X>=5 -> gt; (X) -> lt end.\n#Fun \n4> Fun2(7).\ngt\n5> Fun3 = fun Fact(1) -> 1; Fact(X) when X > 1 -> X * Fact(X - 1) end.\n#Fun \n6> Fun3(4).\n24\n```\n\nThe following fun expressions are also allowed:\n\n```\nfun Name/Arity\nfun Module:Name/Arity\n```\n\nIn `Name/Arity`, `Name` is an atom and `Arity` is an integer. `Name/Arity` must\nspecify an existing local function. The expression is syntactic sugar for:\n\n```\nfun (Arg1,...,ArgN) -> Name(Arg1,...,ArgN) end\n```\n\nIn `Module:Name/Arity`, `Module`, and `Name` are atoms and `Arity` is an\ninteger. `Module`, `Name`, and `Arity` can also be variables. A fun defined in\nthis way refers to the function `Name` with arity `Arity` in the _latest_\nversion of module `Module`. A fun defined in this way is not dependent on the\ncode for the module in which it is defined.\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP R15, `Module`, `Name`, and `Arity` were not allowed to be\n> variables.\n\nMore examples are provided in [Programming Examples](`e:system:funs.md`).","ref":"expressions.html#fun-expressions"},{"type":"extras","title":"Catch and Throw - Expressions","doc":"```\ncatch Expr\n```\n\nReturns the value of `Expr` unless an exception is raised during the evaluation. In\nthat case, the exception is caught. The return value depends on the class of the\nexception:\n\n- **`error`** (a run-time error or the code called [`error(Term)`](`error/1`)) -\n `{'EXIT',{Reason,Stack}}` is returned.\n\n- **`exit`** (the code called [`exit(Term)`](`exit/1`)) - `{'EXIT',Term}` is returned.\n\n- **`throw`** (the code called [`throw(Term)`](`throw/1`)): `Term` is returned.\n\n`Reason` depends on the type of error that occurred, and `Stack` is the stack of\nrecent function calls, see [Exit Reasons](errors.md#exit_reasons).\n\n_Examples:_\n\n```\n1> catch 1+2.\n3\n2> catch 1+a.\n{'EXIT',{badarith,[...]}}\n```\n\nThe BIF [`throw(Any)`](`throw/1`) can be used for non-local return from a\nfunction. It must be evaluated within a `catch`, which returns the value `Any`.\n\n_Example:_\n\n```\n3> catch throw(hello).\nhello\n```\n\nIf [`throw/1`](`throw/1`) is not evaluated within a catch, a `nocatch` run-time\nerror occurs.\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP 24, the `catch` operator had the lowest precedence, making\n> it necessary to add parentheses when combining it with the `match` operator:\n>\n> ```\n> 1> A = (catch 42).\n> 42\n> 2> A.\n> 42\n> ```\n>\n> Starting from Erlang/OTP 24, the parentheses can be omitted:\n>\n> ```\n> 1> A = catch 42.\n> 42\n> 2> A.\n> 42\n> ```","ref":"expressions.html#catch-and-throw"},{"type":"extras","title":"Try - Expressions","doc":"```\ntry Exprs\ncatch\n Class1:ExceptionPattern1[:Stacktrace] [when ExceptionGuardSeq1] ->\n ExceptionBody1;\n ClassN:ExceptionPatternN[:Stacktrace] [when ExceptionGuardSeqN] ->\n ExceptionBodyN\nend\n```\n\nThis is an enhancement of [catch](expressions.md#catch-and-throw). It gives the\npossibility to:\n\n- Distinguish between different exception classes.\n- Choose to handle only the desired ones.\n- Passing the others on to an enclosing `try` or `catch`, or to default error\n handling.\n\nNotice that although the keyword `catch` is used in the `try` expression, there\nis not a `catch` expression within the `try` expression.\n\nIt returns the value of `Exprs` (a sequence of expressions `Expr1, ..., ExprN`)\nunless an exception occurs during the evaluation. In that case the exception is\ncaught and the patterns `ExceptionPattern` with the right exception class\n`Class` are sequentially matched against the caught exception. If a match\nsucceeds and the optional guard sequence `ExceptionGuardSeq` is true, the\ncorresponding `ExceptionBody` is evaluated to become the return value.\n\n`Stacktrace`, if specified, must be the name of a variable (not a pattern). The\nstack trace is bound to the variable when the corresponding `ExceptionPattern`\nmatches.\n\nIf an exception occurs during evaluation of `Exprs` but there is no matching\n`ExceptionPattern` of the right `Class` with a true guard sequence, the\nexception is passed on as if `Exprs` had not been enclosed in a `try`\nexpression.\n\nIf an exception occurs during evaluation of `ExceptionBody`, it is not caught.\n\nIt is allowed to omit `Class` and `Stacktrace`. An omitted `Class` is shorthand\nfor `throw`:\n\n```\ntry Exprs\ncatch\n ExceptionPattern1 [when ExceptionGuardSeq1] ->\n ExceptionBody1;\n ExceptionPatternN [when ExceptionGuardSeqN] ->\n ExceptionBodyN\nend\n```\n\nThe `try` expression can have an `of` section:\n\n```\ntry Exprs of\n Pattern1 [when GuardSeq1] ->\n Body1;\n ...;\n PatternN [when GuardSeqN] ->\n BodyN\ncatch\n Class1:ExceptionPattern1[:Stacktrace] [when ExceptionGuardSeq1] ->\n ExceptionBody1;\n ...;\n ClassN:ExceptionPatternN[:Stacktrace] [when ExceptionGuardSeqN] ->\n ExceptionBodyN\nend\n```\n\nIf the evaluation of `Exprs` succeeds without an exception, the patterns\n`Pattern` are sequentially matched against the result in the same way as for a\n[case](expressions.md#case) expression, except that if the matching fails, a\n`try_clause` run-time error occurs instead of a `case_clause`.\n\nOnly exceptions occurring during the evaluation of `Exprs` can be caught by the\n`catch` section. Exceptions occurring in a `Body` or due to a failed match are\nnot caught.\n\nThe `try` expression can also be augmented with an `after` section, intended to\nbe used for cleanup with side effects:\n\n```\ntry Exprs of\n Pattern1 [when GuardSeq1] ->\n Body1;\n ...;\n PatternN [when GuardSeqN] ->\n BodyN\ncatch\n Class1:ExceptionPattern1[:Stacktrace] [when ExceptionGuardSeq1] ->\n ExceptionBody1;\n ...;\n ClassN:ExceptionPatternN[:Stacktrace] [when ExceptionGuardSeqN] ->\n ExceptionBodyN\nafter\n AfterBody\nend\n```\n\n`AfterBody` is evaluated after either `Body` or `ExceptionBody`, no matter which\none. The evaluated value of `AfterBody` is lost; the return value of the `try`\nexpression is the same with an `after` section as without.\n\nEven if an exception occurs during evaluation of `Body` or `ExceptionBody`,\n`AfterBody` is evaluated. In this case the exception is passed on after\n`AfterBody` has been evaluated, so the exception from the `try` expression is\nthe same with an `after` section as without.\n\nIf an exception occurs during evaluation of `AfterBody` itself, it is not\ncaught. So if `AfterBody` is evaluated after an exception in `Exprs`, `Body`, or\n`ExceptionBody`, that exception is lost and masked by the exception in\n`AfterBody`.\n\nThe `of`, `catch`, and `after` sections are all optional, as long as there is at\nleast a `catch` or an `after` section. So the following are valid `try`\nexpressions:\n\n```\ntry Exprs of\n Pattern when GuardSeq ->\n Body\nafter\n AfterBody\nend\n\ntry Exprs\ncatch\n ExpressionPattern ->\n ExpressionBody\nafter\n AfterBody\nend\n\ntry Exprs after AfterBody end\n```\n\nNext is an example of using `after`. This closes the file, even in the event of\nexceptions in `file:read/2` or in [`binary_to_term/1`](`binary_to_term/1`). The\nexceptions are the same as without the `try`...`after`...`end` expression:\n\n```\ntermize_file(Name) ->\n {ok,F} = file:open(Name, [read,binary]),\n try\n {ok,Bin} = file:read(F, 1024*1024),\n binary_to_term(Bin)\n after\n file:close(F)\n end.\n```\n\nNext is an example of using `try` to emulate `catch Expr`:\n\n```\ntry Expr\ncatch\n throw:Term -> Term;\n exit:Reason -> {'EXIT',Reason};\n error:Reason:Stk -> {'EXIT',{Reason,Stk}}\nend\n```\n\nVariables bound in the various parts of these expressions have different scopes.\nVariables bound just after the `try` keyword are:\n\n- bound in the `of` section\n- unsafe in both the `catch` and `after` sections, as well as after the whole\n construct\n\nVariables bound in `of` section are:\n\n- unbound in the `catch` section\n- unsafe in both the `after` section, as well as after the whole construct\n\nVariables bound in the `catch` section are unsafe in the `after` section, as\nwell as after the whole construct.\n\nVariables bound in the `after` section are unsafe after the whole construct.","ref":"expressions.html#try"},{"type":"extras","title":"Parenthesized Expressions - Expressions","doc":"```\n(Expr)\n```\n\nParenthesized expressions are useful to override\n[operator precedences](expressions.md#prec), for example, in arithmetic\nexpressions:\n\n```\n1> 1 + 2 * 3.\n7\n2> (1 + 2) * 3.\n9\n```","ref":"expressions.html#parenthesized-expressions"},{"type":"extras","title":"Block Expressions - Expressions","doc":"```\nbegin\n Expr1,\n ...,\n ExprN\nend\n```\n\nBlock expressions provide a way to group a sequence of expressions, similar to a\nclause body. The return value is the value of the last expression `ExprN`.\n\n[](){: #lcs }","ref":"expressions.html#block-expressions"},{"type":"extras","title":"Comprehensions - Expressions","doc":"Comprehensions provide a succinct notation for iterating over one or more terms\nand constructing a new term. Comprehensions come in three different flavors,\ndepending on the type of term they build.\n\nList comprehensions construct lists. They have the following syntax:\n\n```\n[Expr || Qualifier1, . . ., QualifierN]\n```\n\nHere, `Expr` is an arbitrary expression, and each `Qualifier` is either a\n**generator** or a **filter**.\n\nBit string comprehensions construct bit strings or binaries. They have the\nfollowing syntax:\n\n```\n< >\n```\n\n`BitStringExpr` is an expression that evaluates to a bit string. If\n`BitStringExpr` is a function call, it must be enclosed in parentheses. Each\n`Qualifier` is either a **generator** or a **filter**.\n\nMap comprehensions construct maps. They have the following syntax:\n\n```\n#{KeyExpr => ValueExpr || Qualifier1, . . ., QualifierN}\n```\n\nHere, `KeyExpr` and `ValueExpr` are arbitrary expressions, and each `Qualifier`\nis either a **generator** or a **filter**.\n\n> #### Change {: .info }\n>\n> Map comprehensions and map generators were introduced in Erlang/OTP 26.\n\nThere are three kinds of generators.\n\nA _list generator_ has the following syntax:\n\n```\nPattern <- ListExpr\n```\n\nwhere `ListExpr` is an expression that evaluates to a list of terms.\n\nA _bit string generator_ has the following syntax:\n\n```\nBitstringPattern <= BitStringExpr\n```\n\nwhere `BitStringExpr` is an expression that evaluates to a bit string.\n\nA _map generator_ has the following syntax:\n\n```\nKeyPattern := ValuePattern <- MapExpression\n```\n\nwhere `MapExpr` is an expression that evaluates to a map, or a map iterator\nobtained by calling `maps:iterator/1` or `maps:iterator/2`.\n\nA _filter_ is an expression that evaluates to `true` or `false`.\n\nThe variables in the generator patterns shadow previously bound variables,\nincluding variables bound in a previous generator pattern.\n\nVariables bound in a generator expression are not visible outside the\nexpression:\n\n```\n1> [{E,L} || E <- L=[1,2,3]].\n* 1:5: variable 'L' is unbound\n```\n\nA **list comprehension** returns a list, where the list elements are the result\nof evaluating `Expr` for each combination of generator elements for which all\nfilters are true.\n\nA **bit string comprehension** returns a bit string, which is created by\nconcatenating the results of evaluating `BitStringExpr` for each combination of\nbit string generator elements for which all filters are true.\n\nA **map comprehension** returns a map, where the map elements are the result of\nevaluating `KeyExpr` and `ValueExpr` for each combination of generator elements\nfor which all filters are true. If the key expressions are not unique, the last\noccurrence is stored in the map.\n\n**Examples:**\n\nMultiplying each element in a list by two:\n\n```\n1> [X*2 || X <- [1,2,3]].\n[2,4,6]\n```\n\nMultiplying each byte in a binary by two, returning a list:\n\n```\n1> [X*2 || < > <= <<1,2,3>>].\n[2,4,6]\n```\n\nMultiplying each byte in a binary by two:\n\n```\n1> << <<(X*2)>> || < > <= <<1,2,3>> >>.\n<<2,4,6>>\n```\n\nMultiplying each element in a list by two, returning a binary:\n\n```\n1> << <<(X*2)>> || X <- [1,2,3] >>.\n<<2,4,6>>\n```\n\nCreating a mapping from an integer to its square:\n\n```\n1> #{X => X*X || X <- [1,2,3]}.\n#{1 => 1,2 => 4,3 => 9}\n```\n\nMultiplying the value of each element in a map by two:\n\n```\n1> #{K => 2*V || K := V <- #{a => 1,b => 2,c => 3}}.\n#{a => 2,b => 4,c => 6}\n```\n\nFiltering a list, keeping odd numbers:\n\n```\n1> [X || X <- [1,2,3,4,5], X rem 2 =:= 1].\n[1,3,5]\n```\n\nFiltering a list, keeping only elements that match:\n\n```\n1> [X || {_,_}=X <- [{a,b}, [a], {x,y,z}, {1,2}]].\n[{a,b},{1,2}]\n```\n\nCombining elements from two list generators:\n\n```\n1> [{P,Q} || P <- [a,b,c], Q <- [1,2]].\n[{a,1},{a,2},{b,1},{b,2},{c,1},{c,2}]\n```\n\nMore examples are provided in\n[Programming Examples.](`e:system:list_comprehensions.md`)\n\nWhen there are no generators, a comprehension returns either a term constructed\nfrom a single element (the result of evaluating `Expr`) if all filters are true,\nor a term constructed from no elements (that is, `[]` for list comprehension,\n`<<>>` for a bit string comprehension, and `#{}` for a map comprehension).\n\n_Example:_\n\n```\n1> [2 || is_integer(2)].\n[2]\n2> [x || is_integer(x)].\n[]\n```\n\nWhat happens when the filter expression does not evaluate to a boolean value\ndepends on the expression:\n\n- If the expression is a [guard expression](expressions.md#guard-expressions),\n failure to evaluate or evaluating to a non-boolean value is equivalent to\n evaluating to `false`.\n- If the expression is not a guard expression and evaluates to a non-Boolean\n value `Val`, an exception `{bad_filter, Val}` is triggered at runtime. If the\n evaluation of the expression raises an exception, it is not caught by the\n comprehension.\n\n**Examples** (using a guard expression as filter):\n\n```\n1> List = [1,2,a,b,c,3,4].\n[1,2,a,b,c,3,4]\n2> [E || E <- List, E rem 2].\n[]\n3> [E || E <- List, E rem 2 =:= 0].\n[2,4]\n```\n\n**Examples** (using a non-guard expression as filter):\n\n```\n1> List = [1,2,a,b,c,3,4].\n[1,2,a,b,c,3,4]\n2> FaultyIsEven = fun(E) -> E rem 2 end.\n#Fun \n3> [E || E <- List, FaultyIsEven(E)].\n** exception error: bad filter 1\n4> IsEven = fun(E) -> E rem 2 =:= 0 end.\n#Fun \n5> [E || E <- List, IsEven(E)].\n** exception error: an error occurred when evaluating an arithmetic expression\n in operator rem/2\n called as a rem 2\n6> [E || E <- List, is_integer(E), IsEven(E)].\n[2,4]\n```\n\n[](){: #guards }","ref":"expressions.html#comprehensions"},{"type":"extras","title":"Guard Sequences - Expressions","doc":"A _guard sequence_ is a sequence of guards, separated by semicolon (`;`). The\nguard sequence is true if at least one of the guards is true. (The remaining\nguards, if any, are not evaluated.)\n\n`Guard1; ...; GuardK`\n\nA _guard_ is a sequence of guard expressions, separated by comma (`,`). The guard\nis true if all guard expressions evaluate to `true`.\n\n`GuardExpr1, ..., GuardExprN`","ref":"expressions.html#guard-sequences"},{"type":"extras","title":"Guard Expressions - Expressions","doc":"The set of valid _guard expressions_ is a subset of the set of valid Erlang\nexpressions. The reason for restricting the set of valid expressions is that\nevaluation of a guard expression must be guaranteed to be free of side effects.\nValid guard expressions are the following:\n\n- Variables\n- Constants (atoms, integer, floats, lists, tuples, records, binaries, and maps)\n- Expressions that construct atoms, integer, floats, lists, tuples, records,\n binaries, and maps\n- Expressions that update a map\n- The record expressions `Expr#Name.Field` and `#Name.Field`\n- Calls to the BIFs specified in tables _Type Test BIFs_ and _Other BIFs Allowed\n in Guard Expressions_\n- Term comparisons\n- Arithmetic expressions\n- Boolean expressions\n- Short-circuit expressions (`andalso`/`orelse`)\n\n| _BIF_ |\n| ------------------------------------ |\n| [`is_atom/1`](`is_atom/1`) |\n| [`is_binary/1`](`is_binary/1`) |\n| [`is_bitstring/1`](`is_bitstring/1`) |\n| [`is_boolean/1`](`is_boolean/1`) |\n| [`is_float/1`](`is_float/1`) |\n| [`is_function/1`](`is_function/1`) |\n| [`is_function/2`](`is_function/2`) |\n| [`is_integer/1`](`is_integer/1`) |\n| [`is_list/1`](`is_list/1`) |\n| [`is_map/1`](`is_map/1`) |\n| [`is_number/1`](`is_number/1`) |\n| [`is_pid/1`](`is_pid/1`) |\n| [`is_port/1`](`is_port/1`) |\n| [`is_record/2`](`is_record/2`) |\n| [`is_record/3`](`is_record/3`) |\n| [`is_reference/1`](`is_reference/1`) |\n| [`is_tuple/1`](`is_tuple/1`) |\n\n_Table: Type Test BIFs_\n\nNotice that most type test BIFs have older equivalents, without the\n`is_` prefix. These old BIFs are retained only for backwards\ncompatibility and are not to be used in new code. They are also only\nallowed at top level. For example, they are not allowed in Boolean\nexpressions in guards.\n\n| _BIF_ |\n| ---------------------------------------- |\n| [`abs(Number)`](`abs/1`) |\n| [`bit_size(Bitstring)`](`bit_size/1`) |\n| [`byte_size(Bitstring)`](`byte_size/1`) |\n| [`element(N, Tuple)`](`element/2`) |\n| [`float(Term)`](`float/1`) |\n| [`hd(List)`](`hd/1`) |\n| [`is_map_key(Key, Map)`](`is_map_key/2`) |\n| [`length(List)`](`length/1`) |\n| [`map_get(Key, Map)`](`map_get/2`) |\n| [`map_size(Map)`](`map_size/1`) |\n| [`max(A, B)`](`max/2`) |\n| [`min(A, B)`](`min/2`) |\n| `node/0` |\n| `node(Pid` \\| `Ref` \\| `Port)` |\n| [`round(Number)`](`round/1`) |\n| `self/0` |\n| `size(Tuple` \\| `Bitstring)` |\n| [`tl(List)`](`tl/1`) |\n| [`trunc(Number)`](`trunc/1`) |\n| [`tuple_size(Tuple)`](`tuple_size/1`) |\n\n_Table: Other BIFs Allowed in Guard Expressions_\n\n> #### Change {: .info }\n>\n> The [`min/2`](`min/2`) and [`max/2`](`max/2`) BIFs are allowed to be used in\n> guards from Erlang/OTP 26.\n\nIf an arithmetic expression, a Boolean expression, a short-circuit expression,\nor a call to a guard BIF fails (because of invalid arguments), the entire guard\nfails. If the guard was part of a guard sequence, the next guard in the sequence\n(that is, the guard following the next semicolon) is evaluated.\n\n[](){: #prec }","ref":"expressions.html#guard-expressions"},{"type":"extras","title":"Operator Precedence - Expressions","doc":"Operator precedence in descending order:\n\n| _Operator_ | _Association_ |\n| -------------------------------------------- | ----------------- |\n| `#` |   |\n| Unary `+` `-` `bnot` `not` |   |\n| `/` `*` `div` `rem` `band` `and` | Left-associative |\n| `+` `-` `bor` `bxor` `bsl` `bsr` `or` `xor` | Left-associative |\n| `++` `--` | Right-associative |\n| `==` `/=` `=<` `<` `>=` `>` `=:=` `=/=` | Non-associative |\n| `andalso` | Left-associative |\n| `orelse` | Left-associative |\n| `catch` |   |\n| `=` `!` | Right-associative |\n| `?=` | Non-associative |\n\n_Table: Operator Precedence_\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP 24, the `catch` operator had the lowest precedence.\n\n> #### Note {: .info }\n>\n> The `=` operator in the table is the\n> [match operator](expressions.md#the-match-operator). The character `=` can also\n> denote the\n> [compound pattern operator](expressions.md#the-compound-pattern-operator), which\n> can only be used in patterns.\n>\n> `?=` is restricted in that it can only be used at the top-level inside a\n> `maybe` block.\n\nWhen evaluating an expression, the operator with the highest precedence is\nevaluated first. Operators with the same precedence are evaluated according to\ntheir associativity. Non-associative operators cannot be combined with operators\nof the same precedence.\n\n_Examples:_\n\nThe left-associative arithmetic operators are evaluated left to right:\n\n```\n6 + 5 * 4 - 3 / 2 evaluates to\n6 + 20 - 1.5 evaluates to\n26 - 1.5 evaluates to\n24.5\n```\n\nThe non-associative operators cannot be combined:\n\n```\n1> 1 < X < 10.\n* 1:7: syntax error before: '<'\n```","ref":"expressions.html#operator-precedence"},{"type":"extras","title":"Preprocessor","doc":"\n# Preprocessor","ref":"macros.html"},{"type":"extras","title":"File Inclusion - Preprocessor","doc":"A file can be included as follows:\n\n```erlang\n-include(File).\n-include_lib(File).\n```\n\n`File`, a string, is to point out a file. The contents of this file are included\nas is, at the position of the directive.\n\nInclude files are typically used for record and macro definitions that are\nshared by several modules. It is recommended to use the file name extension\n`.hrl` for include files.\n\n`File` can start with a path component `$VAR`, for some string `VAR`. If that is\nthe case, the value of the environment variable `VAR` as returned by\n`os:getenv(VAR)` is substituted for `$VAR`. If `os:getenv(VAR)` returns `false`,\n`$VAR` is left as is.\n\nIf the filename `File` is absolute (possibly after variable substitution), the\ninclude file with that name is included. Otherwise, the specified file is\nsearched for in the following directories, and in this order:\n\n1. The current working directory\n1. The directory where the module is being compiled\n1. The directories given by the `include` option\n\nFor details, see [erlc](`e:erts:erlc_cmd.md`) in ERTS and\n`m:compile` in Compiler.\n\n_Examples:_\n\n```erlang\n-include(\"my_records.hrl\").\n-include(\"incdir/my_records.hrl\").\n-include(\"/home/user/proj/my_records.hrl\").\n-include(\"$PROJ_ROOT/my_records.hrl\").\n```\n\n`include_lib` is similar to `include`, but is not to point out an absolute file.\nInstead, the first path component (possibly after variable substitution) is\nassumed to be the name of an application.\n\n_Example:_\n\n```erlang\n-include_lib(\"kernel/include/file.hrl\").\n```\n\nThe code server uses `code:lib_dir(kernel)` to find the directory of the current\n(latest) version of Kernel, and then the subdirectory `include` is searched for\nthe file `file.hrl`.","ref":"macros.html#file-inclusion"},{"type":"extras","title":"Defining and Using Macros - Preprocessor","doc":"A macro is defined as follows:\n\n```erlang\n-define(Const, Replacement).\n-define(Func(Var1,...,VarN), Replacement).\n```\n\nA macro definition can be placed anywhere among the attributes and function\ndeclarations of a module, but the definition must come before any usage of the\nmacro.\n\nIf a macro is used in several modules, it is recommended that the macro\ndefinition is placed in an include file.\n\nA macro is used as follows:\n\n```text\n?Const\n?Func(Arg1,...,ArgN)\n```\n\nMacros are expanded during compilation. A simple macro `?Const` is replaced with\n`Replacement`.\n\n_Example:_\n\n```erlang\n-define(TIMEOUT, 200).\n...\ncall(Request) ->\n server:call(refserver, Request, ?TIMEOUT).\n```\n\nThis is expanded to:\n\n```erlang\ncall(Request) ->\n server:call(refserver, Request, 200).\n```\n\nA macro `?Func(Arg1,...,ArgN)` is replaced with `Replacement`, where all\noccurrences of a variable `Var` from the macro definition are replaced with the\ncorresponding argument `Arg`.\n\n_Example:_\n\n```erlang\n-define(MACRO1(X, Y), {a, X, b, Y}).\n...\nbar(X) ->\n ?MACRO1(a, b),\n ?MACRO1(X, 123)\n```\n\nThis is expanded to:\n\n```erlang\nbar(X) ->\n {a,a,b,b},\n {a,X,b,123}.\n```\n\nIt is good programming practice, but not mandatory, to ensure that a macro\ndefinition is a valid Erlang syntactic form.\n\nTo view the result of macro expansion, a module can be compiled with the `'P'`\noption. `compile:file(File, ['P'])`. This produces a listing of the parsed code\nafter preprocessing and parse transforms, in the file `File.P`.","ref":"macros.html#defining-and-using-macros"},{"type":"extras","title":"Predefined Macros - Preprocessor","doc":"The following macros are predefined:\n\n- **`?MODULE`** - The name of the current module, as an atom.\n\n- **`?MODULE_STRING`** - The name of the current module, as a string.\n\n- **`?FILE`** - The file name of the current module, as a string.\n\n- **`?LINE`** - The current line number, as an integer.\n\n- **`?MACHINE`** - The machine name, `'BEAM'`.\n\n- **`?FUNCTION_NAME`** - The name of the current function, as an atom.\n\n- **`?FUNCTION_ARITY`** - The arity (number of arguments) for the current\n function, as an integer.\n\n- **`?OTP_RELEASE`** - The OTP release for the runtime system that is\n running the compiler, as an integer. For example, when compiling using\n Erlang/OTP 27, the macro returns `27`.\n\n > #### Note {: .info }\n >\n > To find out the release at run-time, call\n > [`erlang:system_info(otp_release)`](`erlang:system_info/1`). Note\n > that it returns the release as a string. For example, when the\n > release is Erlang/OTP 27, the string `\"27\"` will be returned.\n\n > #### Change {: .info }\n >\n > The `?OTP_RELEASE` macro was introduced in Erlang/OTP 21.\n\n- **`?FEATURE_AVAILABLE(Feature)`** - Expands to `true` if the\n [feature](`e:system:features.md#features`) `Feature` is available. The feature\n might or might not be enabled.\n\n > #### Change {: .info }\n >\n > The `?FEATURE_AVAILABLE()` macro was introduced in Erlang/OTP 25.\n\n- **`?FEATURE_ENABLED(Feature)`** - Expands to `true` if the\n [feature](`e:system:features.md#features`) `Feature` is enabled.\n > #### Change {: .info }\n >\n > The `?FEATURE_ENABLED()` macro was introduced in Erlang/OTP 25.","ref":"macros.html#predefined-macros"},{"type":"extras","title":"Macros Overloading - Preprocessor","doc":"It is possible to overload macros, except for predefined macros. An overloaded\nmacro has more than one definition, each with a different number of arguments.\n\n> #### Change {: .info }\n>\n> Support for overloading of macros was added in Erlang 5.7.5/OTP R13B04.\n\nA macro `?Func(Arg1,...,ArgN)` with a (possibly empty) list of arguments results\nin an error message if there is at least one definition of `Func` with\narguments, but none with N arguments.\n\nAssuming these definitions:\n\n```erlang\n-define(F0(), c).\n-define(F1(A), A).\n-define(C, m:f).\n```\n\nthe following does not work:\n\n```erlang\nf0() ->\n ?F0. % No, an empty list of arguments expected.\n\nf1(A) ->\n ?F1(A, A). % No, exactly one argument expected.\n```\n\nOn the other hand,\n\n```text\nf() ->\n ?C().\n```\n\nis expanded to\n\n```erlang\nf() ->\n m:f().\n```","ref":"macros.html#macros-overloading"},{"type":"extras","title":"Removing a macro definition - Preprocessor","doc":"A definition of macro can be removed as follows:\n\n```erlang\n-undef(Macro).\n```","ref":"macros.html#removing-a-macro-definition"},{"type":"extras","title":"Conditional Compilation - Preprocessor","doc":"The following macro directives support conditional compilation:\n\n- **`-ifdef(Macro).`** - Evaluate the following lines only if `Macro` is\n defined.\n\n- **`-ifndef(Macro).`** - Evaluate the following lines only if `Macro` is not\n defined.\n\n- **`-else.`** - Only allowed after the `ifdef`, `ifndef`, `if`, and `elif`\n directives. The lines following `else` are evaluated if the preceding\n directive evaluated to false.\n\n- **`-if(Condition).`** - Evaluates the following lines only if `Condition`\n evaluates to true.\n\n- **`-elif(Condition).`** - Only allowed after an `if` or another `elif`\n directive. If the preceding `if` or `elif` directive does not evaluate to\n true, and the `Condition` evaluates to true, the lines following the `elif`\n are evaluated instead.\n\n- **`-endif.`** - Specifies the end of a series of control flow directives.\n\n> #### Note {: .info }\n>\n> Macro directives cannot be used inside functions.\n\nSyntactically, the `Condition` in `if` and `elif` must be a\n[guard expression](expressions.md#guard-expressions). Other constructs (such as\na `case` expression) result in a compilation error.\n\nAs opposed to the standard guard expressions, an expression in an `if` and\n`elif` also supports calling the psuedo-function `defined(Name)`, which tests\nwhether the `Name` argument is the name of a previously defined macro.\n`defined(Name)` evaluates to `true` if the macro is defined and `false`\notherwise. An attempt to call other functions results in a compilation error.\n\n_Example:_\n\n```erlang\n-module(m).\n...\n\n-ifdef(debug).\n-define(LOG(X), io:format(\"{~p,~p}: ~p~n\", [?MODULE,?LINE,X])).\n-else.\n-define(LOG(X), true).\n-endif.\n\n...\n```\n\nWhen trace output is desired, `debug` is to be defined when the module `m` is\ncompiled:\n\n```erlang\n% erlc -Ddebug m.erl\n\nor\n\n1> c(m, {d, debug}).\n{ok,m}\n```\n\n`?LOG(Arg)` is then expanded to a call to `io:format/2` and provide the user\nwith some simple trace output.\n\n_Example:_\n\n```erlang\n-module(m)\n...\n-if(?OTP_RELEASE >= 25).\n%% Code that will work in OTP 25 or higher\n-elif(?OTP_RELEASE >= 26).\n%% Code that will work in OTP 26 or higher\n-else.\n%% Code that will work in OTP 24 or lower.\n-endif.\n...\n```\n\nThis code uses the `OTP_RELEASE` macro to conditionally select code depending on\nrelease.\n\n_Example:_\n\n```erlang\n-module(m)\n...\n-if(?OTP_RELEASE >= 26 andalso defined(debug)).\n%% Debugging code that requires OTP 26 or later.\n-else.\n%% Non-debug code that works in any release.\n-endif.\n...\n```\n\nThis code uses the `OTP_RELEASE` macro and `defined(debug)` to compile debug\ncode only for OTP 26 or later.","ref":"macros.html#conditional-compilation"},{"type":"extras","title":"The -feature() directive - Preprocessor","doc":"[](){: #feature-directive }\n\nThe directive `-feature(FeatureName, enable | disable)` can be used to enable or\ndisable the [feature](`e:system:features.md#features`) `FeatureName`. This is\nthe preferred way of enabling (disabling) features, although it is possible to\ndo it with options to the compiler as well.\n\nNote that the `-feature(..)` directive may only appear before any syntax is\nused. In practice this means it should appear before any `-export(..)` or record\ndefinitions.\n\n## \\-error() and -warning() directives\n\nThe directive `-error(Term)` causes a compilation error.\n\n_Example:_\n\n```erlang\n-module(t).\n-export([version/0]).\n\n-ifdef(VERSION).\nversion() -> ?VERSION.\n-else.\n-error(\"Macro VERSION must be defined.\").\nversion() -> \"\".\n-endif.\n```\n\nThe error message will look like this:\n\n```text\n% erlc t.erl\nt.erl:7: -error(\"Macro VERSION must be defined.\").\n```\n\nThe directive `-warning(Term)` causes a compilation warning.\n\n_Example:_\n\n```erlang\n-module(t).\n-export([version/0]).\n\n-ifndef(VERSION).\n-warning(\"Macro VERSION not defined -- using default version.\").\n-define(VERSION, \"0\").\n-endif.\nversion() -> ?VERSION.\n```\n\nThe warning message will look like this:\n\n```text\n% erlc t.erl\nt.erl:5: Warning: -warning(\"Macro VERSION not defined -- using default version.\").\n```\n\n> #### Change {: .info }\n>\n> The `-error()` and `-warning()` directives were added in Erlang/OTP 19.","ref":"macros.html#the-feature-directive"},{"type":"extras","title":"Stringifying Macro Arguments - Preprocessor","doc":"The construction `??Arg`, where `Arg` is a macro argument, is expanded to a\nstring containing the tokens of the argument. This is similar to the `#arg`\nstringifying construction in C.\n\n_Example:_\n\n```erlang\n-define(TESTCALL(Call), io:format(\"Call ~s: ~w~n\", [??Call, Call])).\n\n?TESTCALL(myfunction(1,2)),\n?TESTCALL(you:function(2,1)).\n```\n\nresults in\n\n```erlang\nio:format(\"Call ~s: ~w~n\",[\"myfunction ( 1 , 2 )\",myfunction(1,2)]),\nio:format(\"Call ~s: ~w~n\",[\"you : function ( 2 , 1 )\",you:function(2,1)]).\n```\n\nThat is, a trace output, with both the function called and the resulting value.","ref":"macros.html#stringifying-macro-arguments"},{"type":"extras","title":"Records","doc":"\n# Records\n\nA record is a data structure for storing a fixed number of elements. It has\nnamed fields and is similar to a struct in C. Record expressions are translated\nto tuple expressions during compilation.\n\nMore examples are provided in\n[Programming Examples](`e:system:prog_ex_records.md`).","ref":"ref_man_records.html"},{"type":"extras","title":"Defining Records - Records","doc":"A record definition consists of the name of the record, followed by the field\nnames of the record. Record and field names must be atoms. Each field can be\ngiven an optional default value. If no default value is supplied, `undefined` is\nused.\n\n```erlang\n-record(Name, {Field1 [= Expr1],\n ...\n FieldN [= ExprN]}).\n```\n\nThe default value for a field is an arbitrary expression, except that it must\nnot use any variables.\n\nA record definition can be placed anywhere among the attributes and function\ndeclarations of a module, but the definition must come before any usage of the\nrecord.\n\nIf a record is used in several modules, it is recommended that the record\ndefinition is placed in an include file.\n\n> #### Change {: .info }\n>\n> Starting from Erlang/OTP 26, records can be defined in the Erlang shell\n> using the syntax described in this section. In earlier releases, it was\n> necessary to use the `m:shell` built-in function `rd/2`.","ref":"ref_man_records.html#defining-records"},{"type":"extras","title":"Creating Records - Records","doc":"The following expression creates a new `Name` record where the value of each\nfield `FieldI` is the value of evaluating the corresponding expression `ExprI`:\n\n```text\n#Name{Field1=Expr1, ..., FieldK=ExprK}\n```\n\nThe fields can be in any order, not necessarily the same order as in the record\ndefinition, and fields can be omitted. Omitted fields get their respective\ndefault value instead.\n\nIf several fields are to be assigned the same value, the following construction\ncan be used:\n\n```text\n#Name{Field1=Expr1, ..., FieldK=ExprK, _=ExprL}\n```\n\nOmitted fields then get the value of evaluating `ExprL` instead of their default\nvalues. This feature is primarily intended to be used to create patterns for ETS\nand Mnesia match functions.\n\n_Example:_\n\n```erlang\n-record(person, {name, phone, address}).\n\nlookup(Name, Tab) ->\n ets:match_object(Tab, #person{name=Name, _='_'}).\n```","ref":"ref_man_records.html#creating-records"},{"type":"extras","title":"Accessing Record Fields - Records","doc":"```text\nExpr#Name.Field\n```\n\nReturns the value of the specified field. `Expr` is to evaluate to a `Name`\nrecord.\n\n_Example_:\n\n```erlang\n-record(person, {name, phone, address}).\n\nget_person_name(Person) ->\n Person#person.name.\n```\n\nThe following expression returns the position of the specified field in the\ntuple representation of the record:\n\n```text\n#Name.Field\n```\n\n_Example:_\n\n```erlang\n-record(person, {name, phone, address}).\n\nlookup(Name, List) ->\n lists:keyfind(Name, #person.name, List).\n```","ref":"ref_man_records.html#accessing-record-fields"},{"type":"extras","title":"Updating Records - Records","doc":"```text\nExpr#Name{Field1=Expr1, ..., FieldK=ExprK}\n```\n\n`Expr` is to evaluate to a `Name` record. A copy of this record is returned,\nwith the value of each specified field `FieldI` changed to the value of\nevaluating the corresponding expression `ExprI`. All other fields retain their\nold values.","ref":"ref_man_records.html#updating-records"},{"type":"extras","title":"Records in Guards - Records","doc":"Since record expressions are expanded to tuple expressions, creating\nrecords and accessing record fields are allowed in guards. However,\nall subexpressions (for initializing fields), must be valid guard\nexpressions as well.\n\n_Examples:_\n\n```erlang\nhandle(Msg, State) when Msg =:= #msg{to=void, no=3} ->\n ...\n\nhandle(Msg, State) when State#state.running =:= true ->\n ...\n```\n\nThere is also a type test BIF [`is_record(Term, RecordTag)`](`is_record/2`).\n\n_Example:_\n\n```erlang\nis_person(P) when is_record(P, person) ->\n true;\nis_person(_P) ->\n false.\n```","ref":"ref_man_records.html#records-in-guards"},{"type":"extras","title":"Records in Patterns - Records","doc":"A pattern that matches a certain record is created in the same way as a record\nis created:\n\n```text\n#Name{Field1=Expr1, ..., FieldK=ExprK}\n```\n\nIn this case, one or more of `Expr1` ... `ExprK` can be unbound variables.","ref":"ref_man_records.html#records-in-patterns"},{"type":"extras","title":"Nested Records - Records","doc":"Assume the following record definitions:\n\n```erlang\n-record(nrec0, {name = \"nested0\"}).\n-record(nrec1, {name = \"nested1\", nrec0=#nrec0{}}).\n-record(nrec2, {name = \"nested2\", nrec1=#nrec1{}}).\n\nN2 = #nrec2{},\n```\n\nAccessing or updating nested records can be written without parentheses:\n\n```text\n\"nested0\" = N2#nrec2.nrec1#nrec1.nrec0#nrec0.name,\n N0n = N2#nrec2.nrec1#nrec1.nrec0#nrec0{name = \"nested0a\"},\n```\n\nwhich is equivalent to:\n\n```text\n\"nested0\" = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0.name,\nN0n = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0{name = \"nested0a\"},\n```\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP R14, parentheses were necessary when accessing or updating\n> nested records.","ref":"ref_man_records.html#nested-records"},{"type":"extras","title":"Internal Representation of Records - Records","doc":"Record expressions are translated to tuple expressions during compilation. A\nrecord defined as:\n\n```erlang\n-record(Name, {Field1, ..., FieldN}).\n```\n\nis internally represented by the tuple:\n\n```text\n{Name, Value1, ..., ValueN}\n```\n\nHere each `ValueI` is the default value for `FieldI`.\n\nTo each module using records, a pseudo function is added during compilation to\nobtain information about records:\n\n```erlang\nrecord_info(fields, Record) -> [Field]\nrecord_info(size, Record) -> Size\n```\n\n`Size` is the size of the tuple representation, that is, one more than the\nnumber of fields.","ref":"ref_man_records.html#internal-representation-of-records"},{"type":"extras","title":"Errors and Error Handling","doc":"\n# Errors and Error Handling","ref":"errors.html"},{"type":"extras","title":"Terminology - Errors and Error Handling","doc":"Errors can roughly be divided into four different types:\n\n- **Compile-time errors** - When the compiler fails to compile the program, for\n example a syntax error.\n\n- **Logical errors** - When a program does not behave as intended, but does not\n crash. An example is that nothing happens when a button in a graphical user\n interface is clicked.\n\n- **[](){: #run-time-errors } Run-time errors** - \n When a crash occurs. An example is when an operator is applied to arguments of\n the wrong type. The Erlang programming language has built-in features for\n handling of run-time errors. A run-time error can also be emulated by calling\n [`error(Reason)`](`erlang:error/1`). Run-time errors are exceptions of class\n `error`.\n\n- **[](){: #generated-errors } Generated errors**\n When the code itself calls [`exit/1`](`erlang:exit/1`) or\n [`throw/1`](`erlang:throw/1`). Generated errors are exceptions of class `exit`\n or `throw`.\n\nWhen an exception occurs in Erlang, execution of the process that evaluated the\nerroneous expression is stopped. This is referred to as a _failure_, that\nexecution or evaluation _fails_, or that the process _fails_, _terminates_, or\n_exits_. Notice that a process can terminate/exit for other reasons than a\nfailure.\n\nA process that terminates emits an _exit signal_ with an _exit reason_ that\ndescribes why the process terminated. Normally, some information about any\nerroneous termination is printed to the terminal. See\n[Process Termination](ref_man_processes.md#process-termination) in the Processes\nchapter for more details on termination.","ref":"errors.html#terminology"},{"type":"extras","title":"Exceptions - Errors and Error Handling","doc":"Exceptions are [run-time errors](errors.md#run-time-errors) or\n[generated errors](errors.md#generated-errors) and are of three different\nclasses, with different origins. The [try](expressions.md#try) expression can\ndistinguish between the different classes, whereas the\n[catch](expressions.md#catch-and-throw) expression cannot. `try` and `catch` are described\nin [Expressions](expressions.md).\n\n| _Class_ | _Origin_ |\n| ------- | ---------------------------------------------------------------------------------- |\n| `error` | Run-time error, for example, `1+a`, or the process called [`error/1`](`error/1`) |\n| `exit` | The process called [`exit/1`](`exit/1`) |\n| `throw` | The process called [`throw/1`](`throw/1`) |\n\n_Table: Exception Classes._\n\nAll of the above exceptions can also be generated by calling `erlang:raise/3`.\n\nAn exception consists of its class, an exit reason (see\n[Exit Reason](errors.md#exit_reasons)), and a stack trace (which aids in finding\nthe code location of the exception).\n\nThe stack trace can be bound to a variable from within a `try` expression for\nany exception class, or as part of the exit reason when a run-time error is\ncaught by a `catch`. Example:\n\n```erlang\n> {'EXIT',{test,Stacktrace}} = (catch error(test)), Stacktrace.\n[{shell,apply_fun,3,[]},\n {erl_eval,do_apply,6,[]},\n ...]\n> try throw(test) catch Class:Reason:Stacktrace -> Stacktrace end.\n[{shell,apply_fun,3,[]},\n {erl_eval,do_apply,6,[]},\n ...]\n```\n\n[](){: #stacktrace }","ref":"errors.html#exceptions"},{"type":"extras","title":"The call-stack back trace (stacktrace) - Errors and Error Handling","doc":"The stack back-trace ([_stacktrace_](`t:erlang:stacktrace/0`)) is a list that\ncontains `{Module, Function, Arity, ExtraInfo}` and/or `{Fun, Arity, ExtraInfo}`\ntuples. The field `Arity` in the tuple can be the argument list of that function\ncall instead of an arity integer, depending on the exception.\n\n`ExtraInfo` is a (possibly empty) list of two-element tuples in any order that\nprovides additional information about the exception. The first element is an\natom describing the type of information in the second element. The following\nitems can occur:\n\n- **`error_info`** - The second element of the tuple is a map providing\n additional information about what caused the exception. This information can\n be created by calling [`error/3`](`erlang:error/3`) and is used by\n `erl_error:format_exception/4`.\n\n- **`file`** - The second element of the tuple is a string (list of characters)\n representing the filename of the source file of the function.\n\n- **`line`** - The second element of the tuple is the line number (an\n integer > 0) in the source file where the exception occurred or the function\n was called.\n\n> #### Warning {: .warning }\n>\n> Developers should rely on stacktrace entries only for debugging purposes.\n>\n> The VM performs tail call optimization, which does not add new entries to the\n> stacktrace, and also limits stacktraces to a certain depth. Furthermore,\n> compiler options, optimizations, and future changes may add or remove\n> stacktrace entries, causing any code that expects the stacktrace to be in a\n> certain order or contain specific items to fail.\n>\n> The only exception to this rule is the class `error` with the reason `undef`\n> which is guaranteed to include the `Module`, `Function` and `Arity` of the\n> attempted function as the first stacktrace entry.","ref":"errors.html#the-call-stack-back-trace-stacktrace"},{"type":"extras","title":"Handling of Run-time Errors in Erlang - Errors and Error Handling","doc":"","ref":"errors.html#handling-of-run-time-errors-in-erlang"},{"type":"extras","title":"Error Handling Within Processes - Errors and Error Handling","doc":"It is possible to prevent run-time errors and other exceptions from\ncausing the process to terminate by using [`try`](expressions.md#try)\nor [`catch`](expressions.md#catch-and-throw).","ref":"errors.html#error-handling-within-processes"},{"type":"extras","title":"Error Handling Between Processes - Errors and Error Handling","doc":"Processes can monitor other processes and detect process terminations, see\n[Processes](ref_man_processes.md#errors).\n\n[](){: #exit_reasons }","ref":"errors.html#error-handling-between-processes"},{"type":"extras","title":"Exit Reasons - Errors and Error Handling","doc":"When a run-time error occurs, that is an exception of class `error`. The exit\nreason is a tuple `{Reason,Stack}`, where `Reason` is a term indicating the type\nof error:\n\n- **`badarg`** - Bad argument. The argument is of wrong data type, or\n is otherwise badly formed.\n\n- **`badarith`** - An argument for an arithmetic expression was not numeric,\n or the expression does not evaluate to finite number.\n\n- **`{badmatch,V}`** - Evaluation of a match expression failed. The\n value `V` did not match.\n\n- **`function_clause`** - No matching function clause is found when\n evaluating a function call.\n\n- **`{case_clause,V}`** - No matching branch is found when evaluating\n a `case` expression. The value `V` did not match.\n\n- **`if_clause`** - No true branch is found when evaluating an `if`\n expression.\n\n- **`{try_clause,V}`** - No matching branch is found when evaluating\n the of-section of a `try` expression. The value `V` did not\n match.\n\n- **`undef`** - The function cannot be found when evaluating a\n function call.\n\n- **`{badfun,F}`** - `F` was expected to a be a fun, but is not.\n\n- **`{badarity,{Fun,Args}}`** - A fun is applied to the wrong number of\n arguments.\n\n- **`timeout_value`** - The timeout value in a `receive...after`\n expression is evaluated to something else than an integer or\n `infinity`.\n\n- **`noproc`** - Trying to create [link](`link/1`) or\n [monitor](`monitor/2`) to a non-existing process or port.\n\n- **`noconnection`** - A link or monitor to a remote process was\n broken because a connection between the nodes could not be\n established or was severed.\n\n- **`{nocatch,V}`** - Trying to evaluate a `throw `outside a\n `catch`. `V` is the thrown term.\n\n- **`system_limit`** - A system limit has been reached. See\n [System Limits in the Efficiency Guide](`e:system:system_limits.md`)\n for information about system limits.\n\n`Stack` is the stack of function calls being evaluated when the error occurred,\ngiven as a list of tuples `{Module,Name,Arity,ExtraInfo}` with the most recent\nfunction call first. The most recent function call tuple can in some cases be\n`{Module,Name,[Arg],ExtraInfo}`.","ref":"errors.html#exit-reasons"},{"type":"extras","title":"Features","doc":"\n# Features\n\n[](){: #features } Introduced in OTP 25, Erlang has the concept of selectable\nfeatures. A feature can change, add or remove behaviour of the language and/or\nruntime system. Examples can include:\n\n- Adding new syntactical constructs to the language\n- Change the semantics of an existing construct\n- Change the behaviour of some runtime aspect\n\nA feature will start out with a status of experimental part of OTP, making it\npossible to try out for users and give feedback. The possibility to try out\nfeatures is enabled by options to the compiler, directives in a module and\noptions to the runtime system. Even when a feature is not experimental it will\nstill be possible to enable or disable it. This makes it possible to adapt a\ncode base at a suitable pace instead of being forced when changing to a new\nrelease.\n\nThe status of a feature will eventually end up as being either a permanent part\nof OTP or rejected, being removed and no longer selectable.","ref":"features.html"},{"type":"extras","title":"Life cycle of features - Features","doc":"A feature is in one of four possible states:\n\n- **Experimental** - The initial state, is meant for trying out and collecting\n feedback. The feature can be enabled but is disabled by default.\n\n- **Approved** - The feature has been finalised and is now part of OTP. By\n default it is enabled, but can be disabled.\n\n- **Permanent** - The feature is now a permanent part of OTP. It can no longer\n be disabled.\n\n- **Rejected** - The feature never reached the approved state and will not be\n part of OTP. It cannot be enabled.\n\nAfter leaving the experimental state, a feature can enter any of the other three\nstates, and if the next state is approved, the feature will eventually end up in\nthe permanent state. A feature can change state only in connection with a\nrelease.\n\nA feature may be in the approved state for several releases.\n\n| State | Default | Configurable | Available |\n| ------------ | -------- | ------------ | --------- |\n| Experimental | disabled | yes | yes |\n| Approved | enabled | yes | yes |\n| Permanent | enabled | no | yes |\n| Rejected | disabled | no | no |\n\n_Table: Feature States_\n\n- Being configurable means the possibility to enable or disable the feature by\n means of compiler options and directives in the file being compiled.\n- Being available can be seen using the `FEATURE_AVAILABLE` macro.","ref":"features.html#life-cycle-of-features"},{"type":"extras","title":"Enabling and Disabling Features - Features","doc":"To use a feature that is in the experimental state, it has to be enabled during\ncompilation. This can be done in a number of different ways:\n\n- **Options to `erlc`** - Options\n [`-enable-feature`](`e:erts:erlc_cmd.md#enable-feature`) and\n [`-disable-feature`](`e:erts:erlc_cmd.md#disable-feature`) can be used to\n enable or disable individal features.\n\n- **Compiler options** - The compiler option\n [`{feature, , enable|disable}`](`m:compile#feature-option`) can be\n used either as a `+ ` option to `erlc` or in the options argument to\n functions in the `compile` module.\n\n- **The feature directive** - Inside a prefix of a module, one can use a\n [`-feature( , enable|disable)`](macros.md#feature-directive)\n directive. This is the preferred method of enabling and disabling features.\n\n> #### Change {: .info }\n>\n> In Erlang/OTP 25, in order to load a module with a feature enabled, it was\n> necessary to also enable the feature in the runtime. This was done using\n> option [`-enable-feature`](`e:erts:erl_cmd.md#enable-feature`) to `erl`. This\n> requirement was removed in Erlang/OTP 26. However, if you want to use features\n> directly in shell, you still need to enable them in the runtime.","ref":"features.html#enabling-and-disabling-features"},{"type":"extras","title":"Preprocessor Additions - Features","doc":"To allow for conditional compilation during transitioning of a code base and/or\ntrying out experimental features\n[feature](`e:system:macros.md#predefined-macros`) `predefined macros`\n`?FEATURE_AVAILABLE(Feature)` and `?FEATURE_ENABLED(Feature)` are available.","ref":"features.html#preprocessor-additions"},{"type":"extras","title":"Information about Existing Features - Features","doc":"The module `erl_features` `m:erl_features` exports a number of functions that\ncan be used to obtain information about current features as well as the features\nused when compiling a module.\n\nOne can also use the `erlc` options\n[`-list-features`](`e:erts:erlc_cmd.md#list-features`) and\n[`-describe-feature `](`e:erts:erlc_cmd.md#describe-feature`) to get\ninformation about existing features.\n\nAdditionally, there is the compiler option\n[`warn_keywords`](`m:compile#warn-keywords`) that can be used to find atoms in\nthe code base that might collide with keywords in features not yet enabled.","ref":"features.html#information-about-existing-features"},{"type":"extras","title":"Existing Features - Features","doc":"The following configurable features exist:\n\n- **`maybe_expr` (experimental)** - Implementation of the\n [`maybe`](expressions.md#maybe) expression proposed in\n [EEP 49](https://www.erlang.org/eeps/eep-0049).\n It was approved in Erlang/OTP 27.","ref":"features.html#existing-features"},{"type":"extras","title":"Processes","doc":"\n# Processes","ref":"ref_man_processes.html"},{"type":"extras","title":"Processes - Processes","doc":"Erlang is designed for massive concurrency. Erlang processes are lightweight\n(grow and shrink dynamically) with small memory footprint, fast to create and\nterminate, and the scheduling overhead is low.","ref":"ref_man_processes.html#processes"},{"type":"extras","title":"Process Creation - Processes","doc":"A process is created by calling [`spawn()`](`erlang:spawn/3`):\n\n```erlang\nspawn(Module, Name, Args) -> pid()\n Module = Name = atom()\n Args = [Arg1,...,ArgN]\n ArgI = term()\n```\n\n`spawn()` creates a new process and returns the pid.\n\nThe new process starts executing in `Module:Name(Arg1,...,ArgN)` where the\narguments are the elements of the (possible empty) `Args` argument list.\n\nThere exist a number of different `spawn` BIFs:\n\n- [`spawn/1,2,3,4`](`erlang:spawn/4`)\n- [`spawn_link/1,2,3,4`](`erlang:spawn_link/4`)\n- [`spawn_monitor/1,2,3,4`](`erlang:spawn_monitor/4`)\n- [`spawn_opt/2,3,4,5`](`erlang:spawn_opt/5`)\n- [`spawn_request/1,2,3,4,5`](`erlang:spawn_request/5`)","ref":"ref_man_processes.html#process-creation"},{"type":"extras","title":"Registered Processes - Processes","doc":"Besides addressing a process by using its pid, there are also BIFs for\nregistering a process under a name. The name must be an atom and is\nautomatically unregistered if the process terminates:\n\n| _BIF_ | _Description_ |\n| ------------------------------------- | -------------------------------------------------------------------------------------- |\n| [`register(Name, Pid)`](`register/2`) | Associates the name `Name`, an atom, with the process `Pid`. |\n| `registered/0` | Returns a list of names that have been registered using [`register/2`](`register/2`). |\n| [`whereis(Name)`](`whereis/1`) | Returns the pid registered under `Name`, or `undefined `if the name is not registered. |\n\n_Table: Name Registration BIFs_","ref":"ref_man_processes.html#registered-processes"},{"type":"extras","title":"Process Aliases - Processes","doc":"When sending a message to a process, the receiving process can be identified by\na [Pid](data_types.md#pid), a\n[registered name](ref_man_processes.md#registered-processes), or a _process\nalias_ which is a term of the type [reference](data_types.md#reference). The\ntypical use case that process aliases were designed for is a request/reply\nscenario. Using a process alias when sending the reply makes it possible for the\nreceiver of the reply to prevent the reply from reaching its message queue if\nthe operation times out or if the connection between the processes is lost.\n\nA process alias can be used as identifier of the receiver when sending a message\nusing the [send operator (`!`)](expressions.md#send) or send BIFs such as\n`erlang:send/2`. As long as the process alias is active, messages will be\ndelivered the same way as if the process identifier of the process that created\nthe alias had been used. When the alias has been deactivated, messages sent\nusing the alias will be dropped before entering the message queue of the\nreceiver. Note that messages that at deactivation time already have entered the\nmessage queue will _not_ be removed.\n\nA process alias is created either by calling one of the\n[`alias/0,1`](`erlang:alias/0`) BIFs or by creating an alias and a monitor\nsimultaneously. If the alias is created together with a monitor, the same\nreference will be used both as monitor reference and alias. Creating a monitor\nand an alias at the same time is done by passing the `{alias, _}` option to the\n[`monitor/3`](`erlang:monitor/3`) BIF. The `{alias, _}` option can also be\npassed when creating a monitor via [`spawn_opt()`](`erlang:spawn_opt/5`), or\n[`spawn_request()`](`erlang:spawn_request/5`).\n\nA process alias can be deactivated by the process that created it by calling the\n[`unalias/1`](`erlang:unalias/1`) BIF. It is also possible to automatically\ndeactivate an alias on certain events. See the documentation of the\n[`alias/1`](`erlang:alias/1`) BIF, and the `{alias, _}` option of the\n[`monitor/3`](`erlang:monitor/3`) BIF for more information about automatic\ndeactivation of aliases.\n\nIt is _not_ possible to:\n\n- create an alias identifying another process than the caller.\n- deactivate an alias unless it identifies the caller.\n- look up an alias.\n- look up the process identified by an alias.\n- check if an alias is active or not.\n- check if a reference is an alias.\n\nThese are all intentional design decisions relating to performance, scalability,\nand distribution transparency.","ref":"ref_man_processes.html#process-aliases"},{"type":"extras","title":"Process Termination - Processes","doc":"When a process terminates, it always terminates with an _exit reason_. The\nreason can be any term.\n\nA process is said to terminate _normally_, if the exit reason is the atom\n`normal`. A process with no more code to execute terminates normally.\n\nA process terminates with an exit reason `{Reason,Stack}` when a run-time error\noccurs. See [Exit Reasons](errors.md#exit_reasons).\n\nA process can terminate itself by calling one of the following BIFs:\n\n- [`exit(Reason)`](`exit/1`)\n- [`error(Reason)`](`erlang:error/1`)\n- [`error(Reason, Args)`](`erlang:error/2`)\n\nThe process then terminates with reason `Reason` for [`exit/1`](`exit/1`) or\n`{Reason,Stack}` for the others.\n\nA process can also be terminated if it receives an exit signal with another exit\nreason than `normal`, see [Error Handling](ref_man_processes.md#errors).","ref":"ref_man_processes.html#process-termination"},{"type":"extras","title":"Signals - Processes","doc":"[](){: #message-sending } All communication between Erlang processes and Erlang\nports is done by sending and receiving asynchronous signals. The most common\nsignals are Erlang message signals. A message signal can be sent using the\n[send operator `!`](expressions.md#send). A received message can be fetched from\nthe message queue by the receiving process using the\n[`receive`](expressions.md#receive) expression.\n\n[](){: #sync-comm }\n\nSynchronous communication can be broken down into multiple asynchronous signals.\nAn example of such a synchronous communication is a call to the\n`erlang:process_info/2` BIF when the first argument does not equal the process\nidentifier of the calling process. The caller sends an asynchronous signal\nrequesting information, and then blocks waiting for the reply signal containing\nthe requested information. When the request signal reaches its destination, the\ndestination process replies with the requested information.","ref":"ref_man_processes.html#signals"},{"type":"extras","title":"Sending Signals - Processes","doc":"There are many signals that processes and ports use to communicate. The list\nbelow contains the most important signals. In all the cases of request/reply\nsignal pairs, the request signal is sent by the process calling the specific\nBIF, and the reply signal is sent back to it when the requested operation has\nbeen performed.\n\n- **`message`** - Sent when using the [send operator `!`](expressions.md#send),\n or when calling one of the [`erlang:send/2,3`](`erlang:send/2`) or\n [`erlang:send_nosuspend/2,3`](`erlang:send_nosuspend/2`) BIFs.\n\n- **`link`** - Sent when calling the [link/1](`erlang:link/1`) BIF.\n\n- **`unlink`** - Sent when calling the [unlink/1](`erlang:unlink/1`) BIF.\n\n- **`exit`** - Sent either when explicitly sending an `exit` signal by calling\n the [exit/2](`erlang:exit/2`) BIF, or when a\n [linked process terminates](ref_man_processes.md#sending_exit_signals). If the\n signal is sent due to a link, the signal is sent after all\n [_directly visible Erlang resources_](ref_man_processes.md#visible-resources)\n used by the process have been released.\n\n- **`monitor`** - Sent when calling one of the [monitor/2,3](`erlang:monitor/3`)\n BIFs.\n\n- **`demonitor`** - Sent when calling one of the\n [demonitor/1,2](`erlang:demonitor/1`) BIFs, or when a process monitoring\n another process terminates.\n\n- **`down`** - Sent by a\n [monitored process or port that terminates](ref_man_processes.md#monitors).\n The signal is sent after all\n [_directly visible Erlang resources_](ref_man_processes.md#visible-resources)\n used by the process or the port have been released.\n\n- **`change`** - Sent by the\n [clock service](ref_man_processes.md#runtime-service) on the local runtime\n system, when the [time offset](`erlang:time_offset/0`) changes, to processes\n which have [monitored the `time_offset`](`erlang:monitor/2`).\n\n- **`group_leader`** - Sent when calling the\n [group_leader/2](`erlang:group_leader/2`) BIF.\n\n- **`spawn_request`/`spawn_reply`, `open_port_request`/`open_port_reply`** -\n Sent due to a call to one of the [`spawn/1,2,3,4`](`erlang:spawn/4`),\n [`spawn_link/1,2,3,4`](`erlang:spawn_link/4`),\n [`spawn_monitor/1,2,3,4`](`erlang:spawn_monitor/4`),\n [`spawn_opt/2,3,4,5`](`erlang:spawn_opt/5`),\n [`spawn_request/1,2,3,4,5`](`erlang:spawn_request/5`), or `erlang:open_port/2`\n BIFs. The request signal is sent to the\n [spawn service](ref_man_processes.md#runtime-service) which responds with the\n reply signal.\n\n- **`alive_request`/`alive_reply`** - Sent due to a call to the\n [is_process_alive/1](`erlang:is_process_alive/1`) BIF.\n\n- **`garbage_collect_request`/`garbage_collect_reply`,\n `check_process_code_request`/`check_process_code_reply`,\n `process_info_request`/`process_info_reply`** - Sent due to a call to one of\n the [garbage_collect/1,2](`erlang:garbage_collect/1`),\n [erlang:check_process_code/2,3](`erlang:check_process_code/2`), or\n [process_info/1,2](`erlang:process_info/2`) BIFs. Note that if the request is\n directed towards the caller itself and it is a synchronous request, no\n signaling will be performed and the caller will instead synchronously perform\n the request before returning from the BIF.\n\n- **`port_command`, `port_connect`, `port_close`** - Sent by a process to a port\n on the local node using the [send operator (`!`)](expressions.md#send), or by\n calling one of the [`send()`](`erlang:send/2`) BIFs. The signal is sent by\n passing a term on the format `{Owner, {command, Data}}`,\n `{Owner, {connect, Pid}}`, or `{Owner, close}` as message.\n\n- **`port_command_request`/`port_command_reply`,\n `port_connect_request`/`port_connect_reply`,\n `port_close_request`/`port_close_reply`,\n `port_control_request`/`port_control_reply`,\n `port_call_request`/`port_call_reply`,\n `port_info_request`/`port_info_reply`** - Sent due to a call to one of the\n [`erlang:port_command/2,3`](`erlang:port_command/2`), `erlang:port_connect/2`,\n `erlang:port_close/1`, `erlang:port_control/3`, `erlang:port_call/3`,\n [`erlang:port_info/1,2`](`erlang:port_info/1`) BIFs. The request signal is\n sent to a port on the local node which responds with the reply signal.\n\n- **`register_name_request`/`register_name_reply`,\n `unregister_name_request`/`unregister_name_reply`,\n `whereis_name_request`/`whereis_name_reply`** - Sent due to a call to one of\n the [`register/2`](`erlang:register/2`),\n [`unregister/1`](`erlang:unregister/1`), or [`whereis/1`](`erlang:whereis/1`)\n BIFs. The request signal is sent to the\n [name service](ref_man_processes.md#runtime-service), which responds with the\n reply signal.\n\n- **`timer_start_request`/`timer_start_reply`,\n `timer_cancel_request`/`timer_cancel_reply`** - Sent due to a call to one of\n the [`erlang:send_after/3,4`](`erlang:send_after/3`),\n [`erlang:start_timer/3,4`](`erlang:start_timer/3`), or\n [`erlang:cancel_timer/1,2`](`erlang:cancel_timer/1`) BIFs. The request signal\n is sent to the [timer service](ref_man_processes.md#runtime-service) which\n responds with the reply signal.\n\n[](){: #runtime-service } The clock service, the name service, the timer\nservice, and the spawn service mentioned previously are services provided by the\nruntime system. Each of these services consists of multiple independently\nexecuting entities. Such a service can be viewed as a group of processes, and\ncould actually be implemented like that. Since each service consists of multiple\nindependently executing entities, the order between multiple signals sent from\none service to one process is _not_ preserved. Note that this does _not_ violate\nthe [signal ordering guarantee](ref_man_processes.md#signal-delivery) of the\nlanguage.\n\nThe realization of the signals described earlier may change both at runtime and\ndue to changes in implementation. You may be able to detect such changes using\n`receive` tracing or by inspecting message queues. However, these are internal\nimplementation details of the runtime system that you should _not_ rely on. As\nan example, many of the reply signals are ordinary message signals. When\nthe operation is synchronous, the reply signals do not have to be message\nsignals. The current implementation takes advantage of this and, depending on\nthe state of the system, use alternative ways of delivering the reply signals.\nThe implementation of these reply signals may also, at any time, be changed to\nnot use message signals where it previously did.","ref":"ref_man_processes.html#sending-signals"},{"type":"extras","title":"Receiving Signals - Processes","doc":"Signals are received asynchronously and automatically. There is nothing a\nprocess must do to handle the reception of signals, or can do to prevent it. In\nparticular, signal reception is _not_ tied to the execution of a\n[`receive`](expressions.md#receive) expression, but can happen anywhere in the\nexecution flow of a process.\n\nWhen a signal is received by a process, some kind of action is taken. The\nspecific action taken depends on the signal type, contents of the signal, and\nthe state of the receiving process. Actions taken for the most common signals:\n\n- **`message`** - If the message signal was sent using a\n [process alias](ref_man_processes.md#process-aliases) that is no longer\n active, the message signal will be dropped; otherwise, if the alias is still\n active or the message signal was sent by other means, the message is added to\n the end of the message queue. When the message has been added to the message\n queue, the receiving process can fetch the message from the message queue\n using the [`receive`](expressions.md#receive) expression.\n\n- **`link`, `unlink`** - Very simplified it can be viewed as updating process\n local information about the link. A detailed description of the\n [link protocol](`e:erts:erl_dist_protocol.md#link_protocol`) can be found in\n the _Distribution Protocol_ chapter of the _ERTS User's Guide_.\n\n- **`exit`** - Set the receiver in an exiting state, drop the signal, or convert\n the signal into a message and add it to the end of the message queue. If the\n receiver is set in an exiting state, no more Erlang code will be executed and\n the process is scheduled for termination. The section\n [_Receiving Exit Signals_](ref_man_processes.md#receiving_exit_signals) below\n gives more details on the action taken when an `exit` signal is received.\n\n- **`monitor`, `demonitor`** - Update process local information about the\n monitor.\n\n- **`down`, `change`** - Convert into a message if the corresponding monitor is\n still active; otherwise, drop the signal. If the signal is converted into a\n message, it is also added to the end of the message queue.\n\n- **`group_leader`** - Change the group leader of the process.\n\n- **`spawn_reply`** - Convert into a message, or drop the signal depending on\n the reply and how the `spawn_request` signal was configured. If the signal is\n converted into a message it is also added to the end of the message queue. For\n more information see the [`spawn_request()`](`erlang:spawn_request/5`) BIF.\n\n- **`alive_request`** - Schedule execution of the _is alive_ test. If the\n process is in an exiting state, the _is alive_ test will not be executed until\n after all\n [_directly visible Erlang resources_](ref_man_processes.md#visible-resources)\n used by the process have been released. The `alive_reply` will be sent after\n the _is alive_ test has executed.\n\n- **`process_info_request`, `garbage_collect_request`,\n `check_process_code_request`** - Schedule execution of the requested\n operation. The reply signal will be sent when the operation has been executed.\n\nNote that some actions taken when a signal is received involves _scheduling_\nfurther actions which will result in a reply signal when these scheduled actions\nhave completed. This implies that the reply signals may be sent in a different\norder than the order of the incoming signals that triggered these operations.\nThis does, however, _not_ violate the\n[signal ordering guarantee](ref_man_processes.md#signal-delivery) of the\nlanguage.\n\n[](){: #message-queue-order } The order of messages in the message queue of a\nprocess reflects the order in which the signals corresponding to the messages\nhas been received since\n[all signals that add messages to the message queue add them at the end of the message queue](ref_man_processes.md#receiving-signals).\nMessages corresponding to signals from the same sender are also ordered in the\nsame order as the signals were sent due to the\n[signal ordering guarantee](ref_man_processes.md#signal-delivery) of the\nlanguage.\n\n[](){: #visible-resources }","ref":"ref_man_processes.html#receiving-signals"},{"type":"extras","title":"Directly Visible Erlang Resources - Processes","doc":"As described earlier, `exit` signals due to links, `down` signals, and reply\nsignals from an exiting process due to `alive_request`s are not sent until all\n_directly visible Erlang resources_ held by the terminating process have been\nreleased. With _directly visible Erlang resources_ we here mean all resources\nmade available by the language excluding resources held by heap data, dirty\nnative code execution and the process identifier of the terminating process.\nExamples of _directly visible Erlang resources_ are\n[registered name](ref_man_processes.md#registered-processes) and [ETS](`m:ets`)\ntables.\n\n#### The Excluded Resources\n\nThe process identifier of the process cannot be released for reuse until\neverything regarding the process has been released.\n\nA process executing dirty native code in a NIF when it receives an exit signal\nwill be set into an exiting state even if it is still executing dirty native\ncode. _Directly visible Erlang resources_ will be released, but the runtime\nsystem cannot force the native code to stop executing. The runtime system tries\nto prevent the execution of the dirty native code from affecting other processes\nby, for example, disabling functionality such as\n[`enif_send()`](`e:erts:erl_nif.md#enif_send`) when used from a terminated\nprocess, but if the NIF is not well behaved it can still affect other processes.\nA well behaved dirty NIF should test if\n[the process it is executing in has exited](`e:erts:erl_nif.md#enif_is_current_process_alive`),\nand if so stop executing.\n\nIn the general case, the heap of a process cannot be removed before all signals\nthat it needs to send have been sent. Resources held by heap data are the memory\nblocks containing the heap, but also include things referred to from the heap\nsuch as off heap binaries, and resources held via NIF\n[resource objects](`e:erts:erl_nif.md#resource_objects`) on the heap.\n\n[](){: #signal-delivery }","ref":"ref_man_processes.html#directly-visible-erlang-resources"},{"type":"extras","title":"Delivery of Signals - Processes","doc":"The amount of time that passes between the time a signal is sent and the arrival\nof the signal at the destination is unspecified but positive. If the receiver\nhas terminated, the signal does not arrive, but it can trigger another signal.\nFor example, a `link` signal sent to a non-existing process triggers an `exit`\nsignal, which is sent back to where the `link` signal originated from. When\ncommunicating over the distribution, signals can be lost if the distribution\nchannel goes down.\n\nThe only signal ordering guarantee given is the following: if an entity sends\nmultiple signals to the same destination entity, the order is preserved; that\nis, if `A` sends a signal `S1` to `B`, and later sends signal `S2` to `B`, `S1`\nis guaranteed not to arrive after `S2`. Note that `S1` may, or may not have been\nlost.\n\n[](){: #signal-irregularities }","ref":"ref_man_processes.html#delivery-of-signals"},{"type":"extras","title":"Irregularities - Processes","doc":"- **Synchronous Error Checking** - Some functionality that send signals have\n synchronous error checking when sending locally on a node and fail if the\n receiver is not present at the time when the signal is sent:\n\n - The [send operator (`!`)](expressions.md#send),\n [`erlang:send/2,3`](`erlang:send/2`), BIFs and\n [`erlang:send_nosuspend/2,3`](`erlang:send_nosuspend/2`) BIFs when the\n receiver is identified by a name that is expected to be registered locally.\n - `erlang:link/1`\n - `erlang:group_leader/2`\n\n- **Unexpected Behaviours of Exit Signals** - When a process sends an exit\n signal with exit reason `normal` to itself by calling\n [`erlang:exit(self(), normal)`](`erlang:exit/2`) it will be terminated\n [when the `exit` signal is received](ref_man_processes.md#receiving_exit_signals).\n In all other cases when an exit signal with exit reason `normal` is received,\n it is dropped.\n\n When an\n [`exit` signal with exit reason `kill` is received](ref_man_processes.md#receiving_exit_signals),\n the action taken is different depending on whether the signal was sent due to\n a linked process terminating, or the signal was explicitly sent using the\n [`exit/2`](`erlang:exit/2`) BIF. When sent using the [`exit/2`](`exit/2`) BIF,\n the signal cannot be [trapped](`m:erlang#process_flag_trap_exit`), while it\n can be trapped if the signal was sent due to a link.\n\n- **Blocking Signaling Over Distribution[](){:\n #blocking-signaling-over-distribution } **\n When sending a signal over a distribution channel, the sending process may be\n suspended even though the signal is supposed to be sent asynchronously. This is\n due to the built in flow control over the channel that has been present more or\n less for ever. When the size of the output buffer for the channel reach the _distribution\n buffer busy limit_, processes sending on the channel will be suspended until the\n size of the buffer shrinks below the limit.\n\n Depending on the reason for why the buffer got full, the time it takes before\n suspended processes are resumed can vary _very much_. A consequence of this\n can, for example, be that a timeout in a call to [erpc:call()](`erpc:call/5`)\n is significantly delayed.\n\n Since this functionality has been present for so long, it is not possible to\n remove it, but it is possible to enable _fully asynchronous distributed\n signaling_ on a per process level using\n [`process_flag(async_dist, Bool)`](`m:erlang#process_flag_async_dist`) which\n can be used to solve problems occuring due to blocking signaling. However,\n note that you need to make sure that flow control for data sent using _fully\n asynchronous distributed signaling_ is implemented, or that the amount of such\n data is known to always be limited; otherwise, you may get into a situation\n with excessive memory usage.\n\n The size of the _distribution buffer busy limit_ can be inspected by calling\n [`erlang:system_info(dist_buf_busy_limit)`](`m:erlang#system_info_dist_buf_busy_limit`).\n\nThe irregularities mentioned earlier cannot be fixed as they have been part of\nErlang too long and it would break a lot of existing code.","ref":"ref_man_processes.html#irregularities"},{"type":"extras","title":"Links - Processes","doc":"Two processes can be _linked_ to each other. Also a process and a port that\nreside on the same node can be linked to each other. A link between two\nprocesses can be created if one of them calls the [`link/1`](`erlang:link/1`)\nBIF with the process identifier of the other process as argument. Links can also\nbe created using one the following spawn BIFs\n[`spawn_link()`](`erlang:spawn_link/4`), [`spawn_opt()`](`erlang:spawn_opt/5`),\nor [`spawn_request()`](`erlang:spawn_request/5`). The spawn operation and the\nlink operation will be performed atomically, in these cases.\n\nIf one of the participants of a link terminates, it will\n[send an exit signal](ref_man_processes.md#sending_exit_signals) to the other\nparticipant. The exit signal will contain the\n[exit reason](ref_man_processes.md#link_exit_signal_reason) of the terminated\nparticipant.\n\nA link can be removed by calling the [`unlink/1`](`erlang:unlink/1`) BIF.\n\nLinks are bidirectional and there can only be one link between two processes.\nRepeated calls to `link()` have no effect. Either one of the involved processes\nmay create or remove a link.\n\nLinks are used to monitor the behavior of other processes, see\n[Error Handling](ref_man_processes.md#errors).\n\n[](){: #errors }","ref":"ref_man_processes.html#links"},{"type":"extras","title":"Error Handling - Processes","doc":"Erlang has a built-in feature for error handling between processes. Terminating\nprocesses emit exit signals to all linked processes, which can terminate as well\nor handle the exit in some way. This feature can be used to build hierarchical\nprogram structures where some processes are supervising other processes, for\nexample, restarting them if they terminate abnormally.\n\nSee\n[OTP Design Principles](`e:system:design_principles.md`)\nfor more information about OTP supervision trees, which use this feature.\n\n[](){: #sending_exit_signals }","ref":"ref_man_processes.html#error-handling"},{"type":"extras","title":"Sending Exit Signals - Processes","doc":"When a process or port [terminates](ref_man_processes.md#process-termination) it\nwill send exit signals to all processes and ports that it is\n[linked](ref_man_processes.md#links) to. The exit signal will contain the\nfollowing information:\n\n- **Sender identifier** - The process or port identifier of the process or port\n that terminated.\n\n- **Receiver identifier** - The process or port identifier of the process or\n port which the exit signal is sent to.\n\n- **The `link` flag** - This flag will be set indicating that the exit signal\n was sent due to a link.\n\n- **[](){: #link_exit_signal_reason } Exit reason** \n The exit reason of the process or port that terminated or the atom:\n\n - `noproc` in case no process or port was found when setting up a link in a\n preceding call to the [`link(PidOrPort)`](`erlang:link/1`) BIF. The process\n or port identified as sender of the exit signal will equal the `PidOrPort`\n argument passed to [`link/1`](`link/1`).\n - `noconnection` in case the linked processes resides on different nodes and\n the connection between the nodes was lost or could not be established. The\n process or port identified as sender of the exit signal might in this case\n still be alive.\n\nExit signals can also be sent explicitly by calling the\n[`exit(PidOrPort, Reason)`](`erlang:exit/2`) BIF. The exit signal is sent to the\nprocess or port identified by the `PidOrPort` argument. The exit signal sent\nwill contain the following information:\n\n- **Sender identifier** - The process identifier of the process that called\n [`exit/2`](`exit/2`).\n\n- **Receiver identifier** - The process or port identifier of the process or\n port which the exit signal is sent to.\n\n- **The `link` flag** - This flag will not be set, indicating that this exit\n signal was not sent due to a link.\n\n- **Exit reason** - The term passed as `Reason` in the call to\n [`exit/2`](`exit/2`). If `Reason` is the atom `kill`, the receiver cannot\n [trap the exit](`m:erlang#process_flag_trap_exit`) signal and will\n unconditionally terminate when it receives the signal.\n\n[](){: #receiving_exit_signals }","ref":"ref_man_processes.html#sending-exit-signals"},{"type":"extras","title":"Receiving Exit Signals - Processes","doc":"What happens when a process receives an exit signal depends on:\n\n- The [trap exit](`m:erlang#process_flag_trap_exit`) state of the receiver at\n the time when the exit signal is received.\n- The exit reason of the exit signal.\n- The sender of the exit signal.\n- The state of the `link` flag of the exit signal. If the `link` flag is set,\n the exit signal was sent due to a link; otherwise, the exit signal was sent by\n a call to the [`exit/2`](`erlang:exit/2`) BIF.\n- If the `link` flag is set, what happens also depends on whether the\n [link is still active or not](`erlang:unlink/1`) when the exit signal is\n received.\n\nBased on the above states, the following will happen when an exit signal is\nreceived by a process:\n\n- The exit signal is silently dropped if:\n\n - the `link` flag of the exit signal is set and the corresponding link has\n been deactivated.\n - the exit reason of the exit signal is the atom `normal`, the receiver is not\n trapping exits, and the receiver and sender are not the same process.\n\n- The receiving process is terminated if:\n\n - the `link` flag of the exit signal is not set, and the exit reason of the\n exit signal is the atom `kill`. The receiving process will terminate with\n the atom `killed` as exit reason.\n - the receiver is not trapping exits, and the exit reason is something other\n than the atom `normal`. Also, if the `link` flag of the exit signal is set,\n the link also needs to be active otherwise the exit signal will be dropped.\n The exit reason of the receiving process will equal the exit reason of the\n exit signal. Note that if the `link` flag is set, an exit reason of `kill`\n will _not_ be converted to `killed`.\n - the exit reason of the exit signal is the atom `normal` and the sender of\n the exit signal is the same process as the receiver. The `link` flag cannot\n be set in this case. The exit reason of the receiving process will be the\n atom `normal`.\n\n- The exit signal is converted to a message signal and added to the end of the\n message queue of the receiver, if the receiver is trapping exits, the `link`\n flag of the exit signal is:\n\n - not set, and the exit reason of the signal is not the atom `kill`.\n - set, and the corresponding link is active. Note that an exit reason of\n `kill` will _not_ terminate the process in this case and it will not be\n converted to `killed`.\n\n The converted message will be on the form `{'EXIT', SenderID, Reason}` where\n `Reason` equals the exit reason of the exit signal and `SenderID` is the\n identifier of the process or port that sent the exit signal.","ref":"ref_man_processes.html#receiving-exit-signals"},{"type":"extras","title":"Monitors - Processes","doc":"An alternative to links are _monitors_. A process `Pid1` can create a\nmonitor for `Pid2` by calling the BIF [`erlang:monitor(process,\nPid2)`](`erlang:monitor/2`). The function returns a reference `Ref`.\n\nIf `Pid2` terminates with exit reason `Reason`, a 'DOWN' message is sent to\n`Pid1`:\n\n```text\n{'DOWN', Ref, process, Pid2, Reason}\n```\n\nIf `Pid2` does not exist, the 'DOWN' message is sent immediately with `Reason`\nset to `noproc`.\n\nMonitors are unidirectional. Repeated calls to `erlang:monitor(process, Pid)`\ncreates several independent monitors, and each one sends a 'DOWN' message when\n`Pid` terminates.\n\nA monitor can be removed by calling [`erlang:demonitor(Ref)`](`erlang:demonitor/1`).\n\nMonitors can be created for processes with registered names, also at other\nnodes.","ref":"ref_man_processes.html#monitors"},{"type":"extras","title":"Process Dictionary - Processes","doc":"Each process has its own process dictionary, accessed by calling the following\nBIFs:\n\n- [`put(Key, Value)`](`erlang:put/2`)\n- [`get(Key)`](`erlang:get/1`)\n- [`get()`](`erlang:get/0`)\n- [`get_keys(Value)`](`erlang:get_keys/1`)\n- [`erase(Key)`](`erlang:erase/1`)\n- [`erase()`](`erlang:erase/0`)","ref":"ref_man_processes.html#process-dictionary"},{"type":"extras","title":"Distributed Erlang","doc":"\n# Distributed Erlang","ref":"distributed.html"},{"type":"extras","title":"Distributed Erlang System - Distributed Erlang","doc":"A _distributed Erlang system_ consists of a number of Erlang runtime systems\ncommunicating with each other. Each such runtime system is called a _node_.\nMessage passing between processes at different nodes, as well as links and\nmonitors, are transparent when pids are used. Registered names, however, are\nlocal to each node. This means that the node must be specified as well when\nsending messages, and so on, using registered names.\n\nThe distribution mechanism is implemented using TCP/IP sockets. How to implement\nan alternative carrier is described in the\n[ERTS User's Guide](`e:erts:alt_dist.md`).\n\n> #### Warning {: .warning }\n>\n> Starting a distributed node without also specifying\n> [`-proto_dist inet_tls`](`e:erts:erl_cmd.md#proto_dist`) will expose the node\n> to attacks that may give the attacker complete access to the node and in\n> extension the cluster. When using un-secure distributed nodes, make sure that\n> the network is configured to keep potential attackers out. See the\n> [Using SSL for Erlang Distribution](`e:ssl:ssl_distribution.md`) User's Guide\n> for details on how to setup a secure distributed node.","ref":"distributed.html#distributed-erlang-system"},{"type":"extras","title":"Nodes - Distributed Erlang","doc":"A _node_ is an executing Erlang runtime system that has been given a name, using\nthe command-line flag [`-name`](`e:erts:erl_cmd.md#name`) (long names) or\n[`-sname`](`e:erts:erl_cmd.md#sname`) (short names).\n\nThe format of the node name is an atom `name@host`. `name` is the name given by\nthe user. `host` is the full host name if long names are used, or the first part\nof the host name if short names are used. Function [`node()`](`erlang:node/0`)\nreturns the name of the node.\n\n_Example:_\n\n```erlang\n% erl -name dilbert\n(dilbert@uab.ericsson.se)1> node().\n'dilbert@uab.ericsson.se'\n\n% erl -sname dilbert\n(dilbert@uab)1> node().\ndilbert@uab\n```\n\nThe node name can also be given in runtime by calling `net_kernel:start/1`.\n\n_Example:_\n\n```erlang\n% erl\n1> node().\nnonode@nohost\n2> net_kernel:start([dilbert,shortnames]).\n{ok,<0.102.0>}\n(dilbert@uab)3> node().\ndilbert@uab\n```\n\n> #### Note {: .info }\n>\n> A node with a long node name cannot communicate with a node with a short node\n> name.","ref":"distributed.html#nodes"},{"type":"extras","title":"Node Connections - Distributed Erlang","doc":"The nodes in a distributed Erlang system are loosely connected. The first time\nthe name of another node is used, for example, if\n[`spawn(Node, M, F, A)`](`spawn/4`) or `net_adm:ping(Node)` is called, a connection\nattempt to that node is made.\n\nConnections are by default transitive. If a node A connects to node B, and node\nB has a connection to node C, then node A also tries to connect to node C. This\nfeature can be turned off by using the command-line flag `-connect_all false`,\nsee [erl](`e:erts:erl_cmd.md`) in ERTS.\n\nIf a node goes down, all connections to that node are removed. Calling\n[`erlang:disconnect_node(Node)`](`erlang:disconnect_node/1`) forces\ndisconnection of a node.\n\nThe list of (visible) nodes currently connected to is returned by `nodes/0`.","ref":"distributed.html#node-connections"},{"type":"extras","title":"epmd - Distributed Erlang","doc":"The Erlang Port Mapper Daemon _epmd_ is automatically started at every host\nwhere an Erlang node is started. It is responsible for mapping the symbolic node\nnames to machine addresses. See the [epmd](`e:erts:epmd_cmd.md`) in ERTS.","ref":"distributed.html#epmd"},{"type":"extras","title":"Hidden Nodes - Distributed Erlang","doc":"In a distributed Erlang system, it is sometimes useful to connect to a\nnode without also connecting to all other nodes. An example is some\nkind of Operation and Maintenance functionality used to inspect the\nstatus of a system, without disturbing it. For this purpose, a _hidden\nnode_ can be used.\n\nA hidden node is a node started with the command-line flag `-hidden`.\nConnections between hidden nodes and other nodes are not transitive, they must\nbe set up explicitly. Also, hidden nodes does not show up in the list of nodes\nreturned by `nodes/0`. Instead, [`nodes(hidden)`](`nodes/1`) or\n[`nodes(connected)`](`nodes/1`) must be used. This means, for example, that the\nhidden node is not added to the set of nodes that `m:global` is keeping track of.\n\n[](){: #dyn_node_name }","ref":"distributed.html#hidden-nodes"},{"type":"extras","title":"Dynamic Node Name - Distributed Erlang","doc":"If the node name is set to _`undefined`_ the node will be started in a special\nmode to be the temporary client of another node. The node will then request a\ndynamic node name from the first node it connects to. In addition these\ndistribution settings will be set:\n\n```text\n-dist_listen false -hidden -kernel dist_auto_connect never\n```\n\nAs `-dist_auto_connect` is set to `never`, `net_kernel:connect_node/1` must be\ncalled in order to setup connections. If the first established connection is\nclosed (which gave the node its dynamic name), then any other connections will\nalso be closed and the node will lose its dynamic node name. A new call to\n`net_kernel:connect_node/1` can be made to get a new dynamic node name. The node\nname may change if the distribution is dropped and then set up again.\n\n> #### Change {: .info }\n>\n> The _dynamic node name_ feature is supported from Erlang/OTP 23. Both the\n> temporary client node and the first connected peer node (supplying the dynamic\n> node name) must be at least Erlang/OTP 23 for it to work.","ref":"distributed.html#dynamic-node-name"},{"type":"extras","title":"C Nodes - Distributed Erlang","doc":"A _C node_ is a C program written to act as a hidden node in a distributed\nErlang system. The library _Erl_Interface_ contains functions for this purpose.\nFor more information about C nodes, see the\n[Erl_Interface](`e:erl_interface:ei_users_guide.md`) application and\n[Interoperability Tutorial.](`e:system:tutorial.md`).","ref":"distributed.html#c-nodes"},{"type":"extras","title":"Security - Distributed Erlang","doc":"> #### Note {: .info }\n>\n> \"Security\" here does _not_ mean cryptographically secure, but rather security\n> against accidental misuse, such as preventing a node from connecting to a\n> cluster with which it is not intended to communicate.\n>\n> Furthermore, the communication between nodes is per default in clear text. If\n> you need strong security, please see\n> [Using TLS for Erlang Distribution ](`e:ssl:ssl_distribution.md`)in the SSL\n> application's User's Guide.\n>\n> Also, the default random cookie mentioned in the following text is not very\n> unpredictable. A better one can be generated using primitives in the `crypto`\n> module, though this still does not make the initial handshake\n> cryptographically secure. And inter-node communication is still in clear text.\n\nAuthentication determines which nodes are allowed to communicate with each\nother. In a network of different Erlang nodes, it is built into the system at\nthe lowest possible level. All nodes use a _magic cookie_, which is an Erlang\natom, when connecting another node.\n\nDuring the connection setup, after node names have been exchanged, the magic\ncookies the nodes present to each other are compared. If they do not match, the\nconnection is rejected. The cookies themselves are never transferred, instead\nthey are compared using hashed challenges, although not in a cryptographically\nsecure manner.\n\nAt start-up, a node has a random atom assigned as its default magic cookie and\nthe cookie of other nodes is assumed to be `nocookie`. The first action of the\nErlang network authentication server (`auth`) is then to search for a file named\n`.erlang.cookie` in the [user's home directory](`m:init#home`) and then in\n[`filename:basedir(user_config, \"erlang\")`](`m:filename#user_config`). If none\nof the files exist, a `.erlang.cookie` file is created in the user's home\ndirectory. The UNIX permissions mode of the file is set to octal 400 (read-only\nby user) and its content is a random string. An atom `Cookie` is created from\nthe contents of the file and the cookie of the local node is set to this using\n`erlang:set_cookie(Cookie)`. This sets the default cookie that the local node\nwill use for all other nodes.\n\nThus, groups of users with identical cookie files get Erlang nodes that can\ncommunicate freely since they use the same magic cookie. Users who want to run\nnodes where the cookie files are on different file systems must make certain\nthat their cookie files are identical.\n\nFor a node `Node1` using magic cookie `Cookie` to be able to connect to, and to\naccept a connection from, another node `Node2` that uses a different cookie\n`DiffCookie`, the function `erlang:set_cookie(Node2, DiffCookie)` must first be\ncalled at `Node1`. Distributed systems with multiple home directories (differing\ncookie files) can be handled in this way.\n\n> #### Note {: .info }\n>\n> With this setup `Node1` and `Node2` agree on which cookie to use: `Node1` uses\n> its explicitly configured `DiffCookie` for `Node2`, and `Node2` uses its\n> default cookie `DiffCookie`.\n>\n> You can also use a `DiffCookie` that neither `Node1` nor `Node2` has as its\n> default cookie, if you also call `erlang:set_cookie(Node1, DiffCookie)` in\n> `Node2` before establishing connection\n>\n> Because node names are exchanged during connection setup before cookies are\n> selected, connection setup works regardless of which node that initiates it.\n>\n> Note that to configure `Node1` to use `Node2`'s default cookie when\n> communicating with `Node2`, _and vice versa_ results in a broken configuration\n> (if the cookies are different) because then both nodes use the other node's\n> (differing) cookie.\n\nThe default when a connection is established between two nodes, is to\nimmediately connect all other visible nodes as well. This way, there is always a\nfully connected network. If there are nodes with different cookies, this method\ncan be inappropriate (since it may not be feasible to configure different\ncookies for all possible nodes) and the command-line flag `-connect_all false`\nmust be set, see the [erl](`e:erts:erl_cmd.md`) executable in ERTS.\n\nThe magic cookie of the local node can be retrieved by calling\n`erlang:get_cookie()`.","ref":"distributed.html#security"},{"type":"extras","title":"Distribution BIFs - Distributed Erlang","doc":"Here are some BIFs that are useful for distributed programming:\n\n- [`disconnect_node(Node)`](`erlang:disconnect_node/1`) - Forces the\n disconnection of a node.\n\n- `erlang:get_cookie/0` - Returns the magic cookie of the current\n node.\n\n- [`erlang:get_cookie(Node)`](`erlang:get_cookie/1`) - Returns the\n magic cookie for node `Node`.\n\n- `is_alive/0` - Returns `true` if the runtime system is a node and\n can connect to other nodes, `false` otherwise.\n\n- [`monitor_node(Node, Bool)`](`erlang:monitor_node/2`) - Monitors the\n status of `Node`. A message`{nodedown, Node}` is received if the\n connection to it is lost.\n\n- `node/0` - Returns the name of the current node. Allowed in guards.\n\n- [`node(Arg)`](`node/1`) - Returns the node where `Arg`, a pid,\n reference, or port, is located.\n\n- `nodes/0` - Returns a list of all visible nodes this node is connected to.\n\n- [`nodes(Arg)`](`nodes/1`) - Depending on `Arg`, this function can\n return a list not only of visible nodes, but also hidden nodes and\n previously known nodes, and so on.\n\n- [`erlang:set_cookie(Cookie)`](`erlang:set_cookie/1`) - Sets the\n magic cookie, `Cookie` to use when connecting all nodes that have no\n explicit cookie set with `erlang:set_cookie/2`.\n\n- [`erlang:set_cookie(Node, Cookie)`](`erlang:set_cookie/2`) - Sets\n the magic cookie used when connecting `Node`. If `Node` is the\n current node, `Cookie` is used when connecting all nodes that have\n no explicit cookie set with this function.\n\n- [`spawn_link(Node, Fun)`](`spawn_link/2`) - Creates a process at a remote node.\n\n- [`spawn_opt(Node, Fun, Opts)`](`spawn_opt/3`) - Creates a process at\n a remote node.\n\n- [`spawn_link(Node, Module, Name, Args)`](`erlang:spawn_link/4`) -\n Creates a process at a remote node.\n\n- [`spawn_opt(Node, Module, Name, Args, Opts)`](`erlang:spawn_opt/5`) - Creates\n a process at a remote node.\n\n_Table: Distribution BIFs_","ref":"distributed.html#distribution-bifs"},{"type":"extras","title":"Distribution Command-Line Flags - Distributed Erlang","doc":"Examples of command-line flags used for distributed programming (for more\ninformation, see the [erl](`e:erts:erl_cmd.md`) executable in ERTS):\n\n| _Command-Line Flag_ | _Description_ |\n| ------------------------ | ----------------------------------------------------------- |\n| `-connect_all false` | Only explicit connection setups are used. |\n| `-hidden` | Makes a node into a hidden node. |\n| `-name Name` | Makes a runtime system into a node, using long node names. |\n| `-setcookie Cookie` | Same as calling `erlang:set_cookie(Cookie)`. |\n| `-setcookie Node Cookie` | Same as calling `erlang:set_cookie(Node, Cookie)`. |\n| `-sname Name` | Makes a runtime system into a node, using short node names. |\n\n_Table: Distribution Command-Line Flags_","ref":"distributed.html#distribution-command-line-flags"},{"type":"extras","title":"Distribution Modules - Distributed Erlang","doc":"Examples of modules useful for distributed programming in the Kernel application:\n\n| _Module_ | _Description_ |\n| ---------------- | -------------------------------------------------- |\n| `m:global` | A global name registration facility. |\n| `m:global_group` | Grouping nodes to global name registration groups. |\n| `m:net_adm` | Various Erlang net administration routines. |\n| `m:net_kernel` | Erlang networking kernel. |\n\n_Table: Kernel Modules Useful For Distribution._\n\nIn the STDLIB application:\n\n| _Module_ | _Description_ |\n| -------- | --------------------------------- |\n| `m:peer` | Start and control of peer nodes. |\n\n_Table: STDLIB Modules Useful For Distribution._","ref":"distributed.html#distribution-modules"},{"type":"extras","title":"Compilation and Code Loading","doc":"\n# Compilation and Code Loading\n\nHow code is compiled and loaded is not a language issue, but is\nsystem-dependent. This section describes compilation and code loading in\nErlang/OTP with references to relevant parts of the documentation.","ref":"code_loading.html"},{"type":"extras","title":"Compilation - Compilation and Code Loading","doc":"Erlang programs must be _compiled_ to object code. The compiler can generate a\nnew file that contains the object code. The current abstract machine, which runs\nthe object code, is called BEAM, therefore the object files get the suffix\n`.beam`. The compiler can also generate a binary which can be loaded directly.\n\nThe compiler is located in the module `m:compile` in Compiler.\n\n```erlang\ncompile:file(Module)\ncompile:file(Module, Options)\n```\n\nThe Erlang shell understands the command `c(Module)`, which both compiles and\nloads `Module`.\n\nThere is also a module `make`, which provides a set of functions similar to the\nUNIX type Make functions, see module `m:make` in Tools.\n\nThe compiler can also be accessed from the OS prompt using the\n[erl](`e:erts:erl_cmd.md`) executable in ERTS.\n\n```erlang\n% erl -compile Module1...ModuleN\n% erl -make\n```\n\nThe `erlc` program provides way to compile modules from the OS\nshell, see the [erlc](`e:erts:erlc_cmd.md`) executable in ERTS. It\nunderstands a number of flags that can be used to define macros, add search\npaths for include files, and more.\n\n```text\n% erlc File1.erl...FileN.erl\n```\n\n[](){: #loading }","ref":"code_loading.html#compilation"},{"type":"extras","title":"Code Loading - Compilation and Code Loading","doc":"The object code must be _loaded_ into the Erlang runtime system. This is handled\nby the _code server_, see module `m:code` in Kernel.\n\nThe code server loads code according to a code loading strategy, which is either\n_interactive_ (default) or _embedded_. In interactive mode, code is searched for\nin a _code path_ and loaded when first referenced. In embedded mode, code is\nloaded at start-up according to a _boot script_. This is described in\n[System Principles ](`e:system:system_principles.md#code_loading`).","ref":"code_loading.html#code-loading"},{"type":"extras","title":"Code Replacement - Compilation and Code Loading","doc":"Erlang supports change of code in a running system. Code replacement is done on\nthe module level.\n\nThe code of a module can exist in two variants in a system: _current_ and _old_.\nWhen a module is loaded into the system for the first time, the code becomes\n'current'. If then a new instance of the module is loaded, the code of the\nprevious instance becomes 'old' and the new instance becomes 'current'.\n\nBoth old and current code is valid, and can be evaluated concurrently. Fully\nqualified function calls always refer to current code. Old code can still be\nevaluated because of processes lingering in the old code.\n\nIf a third instance of the module is loaded, the code server removes (purges)\nthe old code and any processes lingering in it is terminated. Then the third\ninstance becomes 'current' and the previously current code becomes 'old'.\n\nTo change from old code to current code, a process must make a fully qualified\nfunction call.\n\n_Example:_\n\n```erlang\n-module(m).\n-export([loop/0]).\n\nloop() ->\n receive\n code_switch ->\n m:loop();\n Msg ->\n ...\n loop()\n end.\n```\n\nTo make the process change code, send the message `code_switch` to it. The\nprocess then makes a fully qualified call to `m:loop()` and changes to current\ncode. Notice that `m:loop/0` must be exported.\n\nFor code replacement of funs to work, use the syntax\n`fun Module:FunctionName/Arity`.\n\n[](){: #on_load }","ref":"code_loading.html#code-replacement"},{"type":"extras","title":"Running a Function When a Module is Loaded - Compilation and Code Loading","doc":"The `-on_load()` directive names a function that is to be run automatically when\na module is loaded.\n\nIts syntax is as follows:\n\n```erlang\n-on_load(Name/0).\n```\n\nIt is not necessary to export the function. It is called in a freshly spawned\nprocess (which terminates as soon as the function returns).\n\nThe function must return `ok` if the module is to become the new current code\nfor the module and become callable.\n\nReturning any other value or generating an exception causes the new code to be\nunloaded. If the return value is not an atom, a warning error report is sent to\nthe error logger.\n\nIf there already is current code for the module, that code will remain current\nand can be called until the `on_load` function has returned. If the `on_load`\nfunction fails, the current code (if any) will remain current. If there is no\ncurrent code for a module, any process that makes an external call to the module\nbefore the `on_load` function has finished will be suspended until the `on_load`\nfunction have finished.\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP 19, if the `on_load` function failed, any previously current\n> code would become old, essentially leaving the system without any working and\n> reachable instance of the module.\n\nIn embedded mode, first all modules are loaded. Then all `on_load` functions are\ncalled. The system is terminated unless all of the `on_load` functions return\n`ok`.\n\n_Example:_\n\n```erlang\n-module(m).\n-on_load(load_my_nifs/0).\n\nload_my_nifs() ->\n NifPath = ..., %Set up the path to the NIF library.\n Info = ..., %Initialize the Info term\n erlang:load_nif(NifPath, Info).\n```\n\nIf the call to `erlang:load_nif/2` fails, the module is unloaded and a warning\nreport is sent to the error loader.","ref":"code_loading.html#running-a-function-when-a-module-is-loaded"},{"type":"extras","title":"Ports and Port Drivers","doc":"\n# Ports and Port Drivers\n\nExamples of how to use ports and port drivers are provided in\n[Interoperability Tutorial](`e:system:tutorial.md`).\nFor information about the BIFs mentioned, see module `m:erlang` in\nERTS.","ref":"ports.html"},{"type":"extras","title":"Ports - Ports and Port Drivers","doc":"_Ports_ provide the basic mechanism for communication with the external world,\nfrom Erlang's point of view. They provide a byte-oriented interface to an\nexternal program. When a port has been created, Erlang can communicate with it\nby sending and receiving lists of bytes, including binaries.\n\nThe Erlang process creating a port is said to be the _port owner_, or the\n_connected process_ of the port. All communication to and from the port must go\nthrough the port owner. If the port owner terminates, so does the port (and the\nexternal program, if it is written correctly).\n\nThe external program resides in another OS process. By default, it reads from\nstandard input (file descriptor 0) and writes to standard output (file\ndescriptor 1). The external program is to terminate when the port is closed.","ref":"ports.html#ports"},{"type":"extras","title":"Port Drivers - Ports and Port Drivers","doc":"It is possible to write a driver in C according to certain principles and\ndynamically link it to the Erlang runtime system. The linked-in driver looks\nlike a port from the Erlang programmer's point of view and is called a _port\ndriver_.\n\n> #### Warning {: .warning }\n>\n> An erroneous port driver causes the entire Erlang runtime system to leak\n> memory, hang or crash.\n\nFor information about port drivers, see:\n\n- [erl_driver](`e:erts:erl_driver.md`) in ERTS\n- [driver_entry](`e:erts:driver_entry.md`) in ERTS\n- [`erl_ddll`](`m:erl_ddll`) in Kernel","ref":"ports.html#port-drivers"},{"type":"extras","title":"Port BIFs - Ports and Port Drivers","doc":"To create a port, call [`open_port(PortName,\nPortSettings)`](`erlang:open_port/2`). It returns a port identifier `Port`\nas the result of opening the new port. Messages can be sent to\nand received from a port identifier, just like a PID. Port\nidentifiers can also be linked to using [`link/1`](`link/1`), or\nregistered under a name using [`register/2`](`register/2`).\n\n`PortName` is usually a tuple `{spawn,Command}`, where the string `Command` is\nthe name of the external program. The external program runs outside the Erlang\nworkspace, unless a port driver with the name `Command` is found. If `Command`\nis found, that driver is started.\n\n`PortSettings` is a list of settings (options) for the port. The list typically\ncontains at least a tuple `{packet,N}`, which specifies that data sent between\nthe port and the external program are preceded by an N-byte length indicator.\nValid values for N are 1, 2, or 4. If binaries are to be used instead of lists\nof bytes, the option `binary` must be included.\n\nThe port owner `Pid` can communicate with the port `Port` by sending and\nreceiving messages. (In fact, any process can send the messages to the port, but\nthe port owner must be identified in the message).\n\nMessages sent to ports are delivered asynchronously.\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP 16, messages to ports were delivered synchronously.\n\nIn the following examples, `Data` must be an I/O list. An I/O list is\na binary or a (possibly deep) list of binaries or integers in the\nrange 0 through 255.\n\nThe following messages can be sent to a port:\n\n- **`{Pid,{command,Data}}`** - Sends `Data` to the port.\n\n- **`{Pid,close}`** - Closes the port. Unless the port is already\n closed, the port replies with `{Port,closed}` when all buffers\n have been flushed and the port really closes.\n\n- **`{Pid,{connect,NewPid}}`** - Sets the port owner of `Port` to\n `NewPid`. Unless the port is already closed, the port replies\n with`{Port,connected}` to the old port owner. Note that the old\n port owner is still linked to the port, but the new port owner is\n not.\n\nHere follows the possible messages that can be received from a port. They\nare sent to the process that owns the port:\n\n- **`{Port,{data,Data}}`** - `Data` is received from the external program.\n\n- **`{Port,closed}`** - Reply to `Port ! {Pid,close}`.\n\n- **`{Port,connected}`** - Reply to `Port ! {Pid,{connect,NewPid}}`.\n\n- **`{'EXIT',Port,Reason}`** - If the port has terminated for some\n reason.\n\nInstead of sending and receiving messages, there are also a number of BIFs that\ncan be used:\n\n- [`port_command(Port, Data)`](`port_command/2`) - Sends `Data` to the\n port.\n\n- [`port_close(Port)`](`port_close/1`) - Closes the port.\n\n- [`port_connect(Port, NewPid)`](`port_connect/2`) - Sets the port\n owner of `Port`to `NewPid`. The old port owner `Pid` stays linked to\n the port and must call [`unlink(Port)`](`unlink/1`) if this is not\n desired.\n\n- [`erlang:port_info(Port, Item)`](`erlang:port_info/2`) - Returns\n information as specified by `Item`.\n\n- [`erlang:ports()`](`erlang:ports/0`) - Returns a list of all ports\n on the current node.\n\nThere also exist a few additional BIFs that apply to port drivers:\n\n- [`port_control/3`](`port_control/3`)\n- `erlang:port_call/3`.","ref":"ports.html#port-bifs"},{"type":"extras","title":"Introduction","doc":"\n# Introduction","ref":"efficiency_guide.html"},{"type":"extras","title":"Purpose - Introduction","doc":"> \"Premature optimization is the root of all evil\" (D.E. Knuth)\n\nEfficient code can be well-structured and clean, based on a sound\noverall architecture and sound algorithms. Efficient code can be\nhighly implementation-dependent code that bypasses documented\ninterfaces and takes advantage of obscure quirks.\n\nIdeally, your code only contains the first type of efficient code. If that turns\nout to be too slow, profile the application to find out where the performance\nbottlenecks are and optimize only the bottlenecks. Let other code stay as clean\nas possible.\n\nThis Efficiency Guide cannot really teach you how to write efficient code. It\ncan give you a few pointers about what to avoid and what to use, and some\nunderstanding of how certain language features are implemented. This guide does\nnot include general tips about optimization that works in any language, such as\nmoving common calculations out of loops.","ref":"efficiency_guide.html#purpose"},{"type":"extras","title":"Prerequisites - Introduction","doc":"It is assumed that you are familiar with the Erlang programming language and the\nOTP concepts.","ref":"efficiency_guide.html#prerequisites"},{"type":"extras","title":"Common Caveats","doc":"\n# Common Caveats\n\nThis section lists a few constructs to watch out for.","ref":"commoncaveats.html"},{"type":"extras","title":"Operator `++` - Common Caveats","doc":"The `++` operator copies its left-hand side operand. That is clearly\nseen if we do our own implementation in Erlang:\n\n```erlang\nmy_plus_plus([H|T], Tail) ->\n [H|my_plus_plus(T, Tail)];\nmy_plus_plus([], Tail) ->\n Tail.\n```\n\nWe must be careful how we use `++` in a loop. First is how not to use it:\n\n**DO NOT**\n\n```erlang\nnaive_reverse([H|T]) ->\n naive_reverse(T) ++ [H];\nnaive_reverse([]) ->\n [].\n```\n\nAs the `++` operator copies its left-hand side operand, the growing\nresult is copied repeatedly, leading to quadratic complexity.\n\nOn the other hand, using `++` in loop like this is perfectly fine:\n\n**OK**\n\n```erlang\nnaive_but_ok_reverse(List) ->\n naive_but_ok_reverse(List, []).\n\nnaive_but_ok_reverse([H|T], Acc) ->\n naive_but_ok_reverse(T, [H] ++ Acc);\nnaive_but_ok_reverse([], Acc) ->\n Acc.\n```\n\nEach list element is copied only once. The growing result `Acc` is the right-hand\nside operand, which it is _not_ copied.\n\nExperienced Erlang programmers would probably write as follows:\n\n**DO**\n\n```erlang\nvanilla_reverse([H|T], Acc) ->\n vanilla_reverse(T, [H|Acc]);\nvanilla_reverse([], Acc) ->\n Acc.\n```\n\nIn principle, this is slightly more efficient because the list element `[H]`\nis not built before being copied and discarded. In practice, the compiler\nrewrites `[H] ++ Acc` to `[H|Acc]`.","ref":"commoncaveats.html#operator"},{"type":"extras","title":"Timer Module - Common Caveats","doc":"Creating timers using `erlang:send_after/3` and `erlang:start_timer/3`, is more\nefficient than using the timers provided by the `m:timer` module in STDLIB.\n\nThe `timer` module uses a separate process to manage the\ntimers. Before Erlang/OTP 25, this management overhead was substantial\nand increasing with the number of timers, especially when they were\nshort-lived, so the timer server process could easily become\noverloaded and unresponsive. In Erlang/OTP 25, the timer module was\nimproved by removing most of the management overhead and the resulting\nperformance penalty. Still, the timer server remains a single process,\nand it may at some point become a bottleneck of an application.\n\nThe functions in the `timer` module that do not manage timers (such as\n`timer:tc/3` or `timer:sleep/1`), do not call the timer-server process and are\ntherefore harmless.","ref":"commoncaveats.html#timer-module"},{"type":"extras","title":"Accidental Copying and Loss of Sharing - Common Caveats","doc":"When spawning a new process using a fun, one can accidentally copy more data to\nthe process than intended. For example:\n\n**DO NOT**\n\n```erlang\naccidental1(State) ->\n spawn(fun() ->\n io:format(\"~p\\n\", [State#state.info])\n end).\n```\n\nThe code in the fun will extract one element from the record and print it. The\nrest of the `state` record is not used. However, when the [`spawn/1`](`spawn/1`)\nfunction is executed, the entire record is copied to the newly created process.\n\nThe same kind of problem can happen with a map:\n\n**DO NOT**\n\n```erlang\naccidental2(State) ->\n spawn(fun() ->\n io:format(\"~p\\n\", [map_get(info, State)])\n end).\n```\n\nIn the following example (part of a module implementing the `m:gen_server`\nbehavior) the created fun is sent to another process:\n\n**DO NOT**\n\n```erlang\nhandle_call(give_me_a_fun, _From, State) ->\n Fun = fun() -> State#state.size =:= 42 end,\n {reply, Fun, State}.\n```\n\nHow bad that unnecessary copy is depends on the contents of the record or the\nmap.\n\nFor example, if the `state` record is initialized like this:\n\n```erlang\ninit1() ->\n #state{data=lists:seq(1, 10000)}.\n```\n\na list with 10000 elements (or about 20000 heap words) will be copied to the\nnewly created process.\n\nAn unnecessary copy of 10000 element list can be bad enough, but it can get even\nworse if the `state` record contains _shared subterms_. Here is a simple example\nof a term with a shared subterm:\n\n```erlang\n{SubTerm, SubTerm}\n```\n\nWhen a term is copied to another process, sharing of subterms will be lost and\nthe copied term can be many times larger than the original term. For example:\n\n```erlang\ninit2() ->\n SharedSubTerms = lists:foldl(fun(_, A) -> [A|A] end, [0], lists:seq(1, 15)),\n #state{data=Shared}.\n```\n\nIn the process that calls `init2/0`, the size of the `data` field in the `state`\nrecord will be 32 heap words. When the record is copied to the newly created\nprocess, sharing will be lost and the size of the copied `data` field will be\n131070 heap words. More details about\n[loss off sharing](eff_guide_processes.md#loss-of-sharing) are found in a later\nsection.\n\nTo avoid the problem, outside of the fun extract only the fields of the record\nthat are actually used:\n\n**DO**\n\n```erlang\nfixed_accidental1(State) ->\n Info = State#state.info,\n spawn(fun() ->\n io:format(\"~p\\n\", [Info])\n end).\n```\n\nSimilarly, outside of the fun extract only the map elements that are actually\nused:\n\n**DO**\n\n```erlang\nfixed_accidental2(State) ->\n Info = map_get(info, State),\n spawn(fun() ->\n io:format(\"~p\\n\", [Info])\n end).\n```","ref":"commoncaveats.html#accidental-copying-and-loss-of-sharing"},{"type":"extras","title":"list_to_atom/1 - Common Caveats","doc":"Atoms are not garbage-collected. Once an atom is created, it is never removed.\nThe emulator terminates if the limit for the number of atoms (1,048,576 by\ndefault) is reached.\n\nTherefore, converting arbitrary input strings to atoms can be dangerous in a\nsystem that runs continuously. If only certain well-defined atoms are allowed as\ninput, [`list_to_existing_atom/1`](`erlang:list_to_existing_atom/1`) or\n[`binary_to_existing_atom/1`](`erlang:binary_to_existing_atom/1`) can be used\nto guard against a denial-of-service attack. (All atoms that are allowed must\nhave been created earlier, for example, by using all of them in a module\nand loading that module.)\n\nUsing [`list_to_atom/1`](`list_to_atom/1`) to construct an atom that\nis passed to [`apply/3`](`apply/3`) is quite expensive.\n\n**DO NOT**\n\n```erlang\napply(list_to_atom(\"some_prefix\"++Var), foo, Args)\n```","ref":"commoncaveats.html#list_to_atom-1"},{"type":"extras","title":"length/1 - Common Caveats","doc":"The time for calculating the length of a list is proportional to the length of\nthe list, as opposed to [`tuple_size/1`](`tuple_size/1`),\n[`byte_size/1`](`byte_size/1`), and [`bit_size/1`](`bit_size/1`), which all\nexecute in constant time.\n\nNormally, there is no need to worry about the speed of [`length/1`](`length/1`),\nbecause it is efficiently implemented in C. In time-critical code, you might\nwant to avoid it if the input list could potentially be very long.\n\nSome uses of [`length/1`](`length/1`) can be replaced by matching. For example,\nthe following code:\n\n```erlang\nfoo(L) when length(L) >= 3 ->\n ...\n```\n\ncan be rewritten to:\n\n```erlang\nfoo([_,_,_|_]=L) ->\n ...\n```\n\nOne slight difference is that [`length(L)`](`length/1`) fails if `L` is an\nimproper list, while the pattern in the second code fragment accepts an improper\nlist.","ref":"commoncaveats.html#length-1"},{"type":"extras","title":"setelement/3 - Common Caveats","doc":"[`setelement/3`](`erlang:setelement/3`) copies the tuple it modifies. Therefore,\nupdating a tuple in a loop using [`setelement/3`](`setelement/3`) creates a new\ncopy of the tuple every time.\n\nThere is one exception to the rule that the tuple is copied. If the compiler\nclearly can see that destructively updating the tuple would give the same result\nas if the tuple was copied, the call to [`setelement/3`](`setelement/3`) is\nreplaced with a special destructive `setelement` instruction. In the following\ncode sequence, the first [`setelement/3`](`setelement/3`) call copies the tuple\nand modifies the ninth element:\n\n```erlang\nmultiple_setelement(T0) when tuple_size(T0) =:= 9 ->\n T1 = setelement(9, T0, bar),\n T2 = setelement(7, T1, foobar),\n setelement(5, T2, new_value).\n```\n\nThe two following [`setelement/3`](`setelement/3`) calls modify the tuple in\nplace.\n\nFor the optimization to be applied, _all_ the following conditions must be true:\n\n- The tuple argument must be known to be a tuple of a known size.\n- The indices must be integer literals, not variables or expressions.\n- The indices must be given in descending order.\n- There must be no calls to another function in between the calls to\n [`setelement/3`](`setelement/3`).\n- The tuple returned from one [`setelement/3`](`setelement/3`) call must only be\n used in the subsequent call to [`setelement/3`](`setelement/3`).\n\nIf the code cannot be structured as in the `multiple_setelement/1` example, the\nbest way to modify multiple elements in a large tuple is to convert the tuple to\na list, modify the list, and convert it back to a tuple.","ref":"commoncaveats.html#setelement-3"},{"type":"extras","title":"size/1 - Common Caveats","doc":"[`size/1`](`size/1`) returns the size for both tuples and binaries.\n\nUsing the BIFs [`tuple_size/1`](`tuple_size/1`) and\n[`byte_size/1`](`byte_size/1`) gives the compiler and the runtime system more\nopportunities for optimization. Another advantage is that those BIFs give Dialyzer\nmore type information.","ref":"commoncaveats.html#size-1"},{"type":"extras","title":"Using NIFs - Common Caveats","doc":"Rewriting Erlang code to a NIF to make it faster should be seen as a last\nresort.\n\nDoing too much work in each NIF call will\n[degrade responsiveness of the VM](`e:erts:erl_nif.md#WARNING`). Doing too\nlittle work can mean that the gain of the faster processing in the NIF is eaten\nup by the overhead of calling the NIF and checking the arguments.\n\nBe sure to read about [Long-running NIFs](`e:erts:erl_nif.md#lengthy_work`)\nbefore writing a NIF.","ref":"commoncaveats.html#using-nifs"},{"type":"extras","title":"Constructing and Matching Binaries","doc":"\n# Constructing and Matching Binaries\n\nThis section gives a few examples on how to handle binaries in an efficient way.\nThe sections that follow take an in-depth look at how binaries are implemented\nand how to best take advantages of the optimizations done by the compiler and\nruntime system.\n\nBinaries can be efficiently _built_ in the following way:\n\n**DO**\n\n```erlang\nmy_list_to_binary(List) ->\n my_list_to_binary(List, <<>>).\n\nmy_list_to_binary([H|T], Acc) ->\n my_list_to_binary(T, < >);\nmy_list_to_binary([], Acc) ->\n Acc.\n```\n\nAppending data to a binary as in the example is efficient because it is\nspecially optimized by the runtime system to avoid copying the `Acc` binary\nevery time.\n\nPrepending data to a binary in a loop is not efficient:\n\n**DO NOT**\n\n```erlang\nrev_list_to_binary(List) ->\n rev_list_to_binary(List, <<>>).\n\nrev_list_to_binary([H|T], Acc) ->\n rev_list_to_binary(T, < >);\nrev_list_to_binary([], Acc) ->\n Acc.\n```\n\nThis is not efficient for long lists because the `Acc` binary is copied every\ntime. One way to make the function more efficient is like this:\n\n**DO NOT**\n\n```erlang\nrev_list_to_binary(List) ->\n rev_list_to_binary(lists:reverse(List), <<>>).\n\nrev_list_to_binary([H|T], Acc) ->\n rev_list_to_binary(T, < >);\nrev_list_to_binary([], Acc) ->\n Acc.\n```\n\nAnother way to avoid copying the binary each time is like this:\n\n**DO**\n\n```erlang\nrev_list_to_binary([H|T]) ->\n RevTail = rev_list_to_binary(T),\n < >;\nrev_list_to_binary([]) ->\n <<>>.\n```\n\nNote that in each of the **DO** examples, the binary to be appended to is always\ngiven as the first segment.\n\nBinaries can be efficiently _matched_ in the following way:\n\n**DO**\n\n```erlang\nmy_binary_to_list(< >) ->\n [H|my_binary_to_list(T)];\nmy_binary_to_list(<<>>) -> [].\n```","ref":"binaryhandling.html"},{"type":"extras","title":"How Binaries are Implemented - Constructing and Matching Binaries","doc":"Internally, binaries and bitstrings are implemented in the same way. In this\nsection, they are called _binaries_ because that is what they are called in the\nemulator source code.\n\nFour types of binary objects are available internally:\n\n- Two are containers for binary data and are called:\n\n - _Refc binaries_ (short for _reference-counted binaries_)\n - _Heap binaries_\n\n- Two are merely references to a part of a binary and are called:\n\n - _sub binaries_\n - _match contexts_\n\n> #### Change {: .info }\n>\n> In Erlang/OTP 27, the handling of binaries and bitstrings were\n> rewritten. To fully leverage those changes in the run-time system,\n> the compiler needs to be updated, which is planned for a future\n> release.\n>\n> Since, practically speaking, not much have changed from an efficiency\n> and optimization perspective, the following description has not yet\n> been updated to describe the implementation in Erlang/OTP 27.\n\n[](){: #refc_binary }","ref":"binaryhandling.html#how-binaries-are-implemented"},{"type":"extras","title":"Refc Binaries - Constructing and Matching Binaries","doc":"Refc binaries consist of two parts:\n\n- An object stored on the process heap, called a _ProcBin_\n- The binary object itself, stored outside all process heaps\n\nThe binary object can be referenced by any number of ProcBins from any number of\nprocesses. The object contains a reference counter to keep track of the number\nof references, so that it can be removed when the last reference disappears.\n\nAll ProcBin objects in a process are part of a linked list, so that the garbage\ncollector can keep track of them and decrement the reference counters in the\nbinary when a ProcBin disappears.\n\n[](){: #heap_binary }","ref":"binaryhandling.html#refc-binaries"},{"type":"extras","title":"Heap Binaries - Constructing and Matching Binaries","doc":"Heap binaries are small binaries, up to 64 bytes, and are stored directly on the\nprocess heap. They are copied when the process is garbage-collected and when\nthey are sent as a message. They do not require any special handling by the\ngarbage collector.","ref":"binaryhandling.html#heap-binaries"},{"type":"extras","title":"Sub Binaries - Constructing and Matching Binaries","doc":"The reference objects _sub binaries_ and _match contexts_ can reference part of\na refc binary or heap binary.\n\n[](){: #sub_binary } A _sub binary_ is created by\n[`split_binary/2`](`split_binary/2`) and when a binary is matched out in a\nbinary pattern. A sub binary is a reference into a part of another binary (refc\nor heap binary, but never into another sub binary). Therefore, matching out a\nbinary is relatively cheap because the actual binary data is never copied.\n\n[](){: #match_context }","ref":"binaryhandling.html#sub-binaries"},{"type":"extras","title":"Match Context - Constructing and Matching Binaries","doc":"A _match context_ is similar to a sub binary, but is optimized for binary\nmatching. For example, it contains a direct pointer to the binary data. For each\nfield that is matched out of a binary, the position in the match context is\nincremented.\n\nThe compiler tries to avoid generating code that creates a sub binary, only to\nshortly afterwards create a new match context and discard the sub binary.\nInstead of creating a sub binary, the match context is kept.\n\nThe compiler can only do this optimization if it knows that the match context\nwill not be shared. If it would be shared, the functional properties (also\ncalled referential transparency) of Erlang would break.","ref":"binaryhandling.html#match-context"},{"type":"extras","title":"Constructing Binaries - Constructing and Matching Binaries","doc":"Appending to a binary or bitstring in the following way is specially optimized\nto avoid copying the binary:\n\n```erlang\n< >\n%% - OR -\n< >\n```\n\nThis optimization is applied by the runtime system in a way that makes it\neffective in most circumstances (for exceptions, see\n[Circumstances That Force Copying](binaryhandling.md#forced_copying)). The\noptimization in its basic form does not need any help from the compiler.\nHowever, the compiler add hints to the runtime system when it is safe to apply\nthe optimization in a more efficient way.\n\n> #### Change {: .info }\n>\n> The compiler support for making the optimization more efficient was added in\n> Erlang/OTP 26.\n\nTo explain how the basic optimization works, let us examine the following code\nline by line:\n\n```erlang\nBin0 = <<0>>, %% 1\nBin1 = < >, %% 2\nBin2 = < >, %% 3\nBin3 = < >, %% 4\nBin4 = < >, %% 5 !!!\n{Bin4,Bin3} %% 6\n```\n\n- Line 1 (marked with the `%% 1` comment), assigns a\n [heap binary](binaryhandling.md#heap_binary) to the `Bin0` variable.\n- Line 2 is an append operation. As `Bin0` has not been involved in an append\n operation, a new [refc binary](binaryhandling.md#refc_binary) is created and\n the contents of `Bin0` is copied into it. The _ProcBin_ part of the refc\n binary has its size set to the size of the data stored in the binary, while\n the binary object has extra space allocated. The size of the binary object is\n either twice the size of `Bin1` or 256, whichever is larger. In this case it\n is 256.\n- Line 3 is more interesting. `Bin1` _has_ been used in an append operation, and\n it has 252 bytes of unused storage at the end, so the 3 new bytes are stored\n there.\n- Line 4. The same applies here. There are 249 bytes left, so there is no\n problem storing another 3 bytes.\n- Line 5. Here something _interesting_ happens. Notice that the result is not\n appended to the previous result in `Bin3`, but to `Bin1`. It is expected that\n `Bin4` will be assigned the value `<<0,1,2,3,17>>`. It is also expected that\n `Bin3` will retain its value (`<<0,1,2,3,4,5,6,7,8,9>>`). Clearly, the runtime\n system cannot write byte `17` into the binary, because that would change the\n value of `Bin3` to `<<0,1,2,3,4,17,6,7,8,9>>`.\n\n To ensure that the value of `Bin3` is retained, the runtime system _copies_\n the contents of `Bin1` to a new refc binary before storing the `17` byte.\n\n Here is not explained how the runtime system can know that it is not allowed\n to write into `Bin1`; it is left as an exercise to the curious reader to\n figure out how it is done by reading the emulator sources, primarily\n `erl_bits.c`.","ref":"binaryhandling.html#constructing-binaries"},{"type":"extras","title":"Compiler Support For Constructing Binaries - Constructing and Matching Binaries","doc":"> #### Change {: .info }\n>\n> The compiler support for making the optimization more efficient was added in\n> Erlang/OTP 26.\n\nIn the example in the previous section, it was shown that the runtime system can\nhandle an append operation to a heap binary by copying it to a refc binary (line\n2), and also handle an append operation to a previous version of the binary by\ncopying it (line 5). The support for doing that does not come for free. For\nexample, to make it possible to know when it is necessary to copy the binary,\nfor every append operation, the runtime system must create a sub binary.\n\nWhen the compiler can determine that none of those situations need to be handled\nand that the append operation cannot possibly fail, the compiler generates code\nthat causes the runtime system to apply a more efficient variant of the\noptimization.\n\n**Example:**\n\n```erlang\n-module(repack).\n-export([repack/1]).\n\nrepack(Bin) when is_binary(Bin) ->\n repack(Bin, <<>>).\n\nrepack(< >, Result) ->\n repack(T, < >);\nrepack(<<>>, Result) ->\n Result.\n```\n\nThe `repack/2` function only keeps a single version of the binary, so there is\nnever any need to copy the binary. The compiler rewrites the creation of the\nempty binary in `repack/1` to instead create a refc binary with 256 bytes\nalready reserved; thus, the append operation in `repack/2` never needs to handle\na binary not prepared for appending.\n\n[](){: #forced_copying }","ref":"binaryhandling.html#compiler-support-for-constructing-binaries"},{"type":"extras","title":"Circumstances That Force Copying - Constructing and Matching Binaries","doc":"The optimization of the binary append operation requires that there is a\n_single_ ProcBin and a _single reference_ to the ProcBin for the binary. The\nreason is that the binary object can be moved (reallocated) during an append\noperation, and when that happens, the pointer in the ProcBin must be updated. If\nthere would be more than one ProcBin pointing to the binary object, it would not\nbe possible to find and update all of them.\n\nTherefore, certain operations on a binary mark it so that any future append\noperation will be forced to copy the binary. In most cases, the binary object\nwill be shrunk at the same time to reclaim the extra space allocated for\ngrowing.\n\nWhen appending to a binary as follows, only the binary returned from the latest\nappend operation will support further cheap append operations:\n\n```erlang\nBin = < >\n```\n\nIn the code fragment in the beginning of this section, appending to `Bin` will\nbe cheap, while appending to `Bin0` will force the creation of a new binary and\ncopying of the contents of `Bin0`.\n\nIf a binary is sent as a message to a process or port, the binary will be shrunk\nand any further append operation will copy the binary data into a new binary.\nFor example, in the following code fragment `Bin1` will be copied in the third\nline:\n\n```erlang\nBin1 = < >,\nPortOrPid ! Bin1,\nBin = < > %% Bin1 will be COPIED\n```\n\nThe same happens if you insert a binary into an Ets table, send it to a port\nusing `erlang:port_command/2`, or pass it to\n[enif_inspect_binary](`e:erts:erl_nif.md#enif_inspect_binary`) in a NIF.\n\nMatching a binary will also cause it to shrink and the next append operation\nwill copy the binary data:\n\n```erlang\nBin1 = < >,\n< > = Bin1,\nBin = < > %% Bin1 will be COPIED\n```\n\nThe reason is that a [match context](binaryhandling.md#match_context) contains a\ndirect pointer to the binary data.\n\nIf a process simply keeps binaries (either in \"loop data\" or in the process\ndictionary), the garbage collector can eventually shrink the binaries. If only\none such binary is kept, it will not be shrunk. If the process later appends to\na binary that has been shrunk, the binary object will be reallocated to make\nplace for the data to be appended.","ref":"binaryhandling.html#circumstances-that-force-copying"},{"type":"extras","title":"Matching Binaries - Constructing and Matching Binaries","doc":"Let us revisit the example in the beginning of the previous section:\n\n**DO**\n\n```erlang\nmy_binary_to_list(< >) ->\n [H|my_binary_to_list(T)];\nmy_binary_to_list(<<>>) -> [].\n```\n\nThe first time `my_binary_to_list/1` is called, a\n[match context](binaryhandling.md#match_context) is created. The match context\npoints to the first byte of the binary. 1 byte is matched out and the match\ncontext is updated to point to the second byte in the binary.\n\nAt this point it would make sense to create a\n[sub binary](binaryhandling.md#sub_binary), but in this particular example the\ncompiler sees that there will soon be a call to a function (in this case, to\n`my_binary_to_list/1` itself) that immediately will create a new match context\nand discard the sub binary.\n\nTherefore `my_binary_to_list/1` calls itself with the match context instead of\nwith a sub binary. The instruction that initializes the matching operation\nbasically does nothing when it sees that it was passed a match context instead\nof a binary.\n\nWhen the end of the binary is reached and the second clause matches, the match\ncontext will simply be discarded (removed in the next garbage collection, as\nthere is no longer any reference to it).\n\nTo summarize, `my_binary_to_list/1` only needs to create _one_ match context and\nno sub binaries.\n\nNotice that the match context in `my_binary_to_list/1` was discarded when the\nentire binary had been traversed. What happens if the iteration stops before it\nhas reached the end of the binary? Will the optimization still work?\n\n```erlang\nafter_zero(<<0,T/binary>>) ->\n T;\nafter_zero(<<_,T/binary>>) ->\n after_zero(T);\nafter_zero(<<>>) ->\n <<>>.\n```\n\nYes, it will. The compiler will remove the building of the sub binary in the\nsecond clause:\n\n```erlang\n...\nafter_zero(<<_,T/binary>>) ->\n after_zero(T);\n...\n```\n\nBut it will generate code that builds a sub binary in the first clause:\n\n```erlang\nafter_zero(<<0,T/binary>>) ->\n T;\n...\n```\n\nTherefore, `after_zero/1` builds one match context and one sub binary (assuming\nit is passed a binary that contains a zero byte).\n\nCode like the following will also be optimized:\n\n```erlang\nall_but_zeroes_to_list(Buffer, Acc, 0) ->\n {lists:reverse(Acc),Buffer};\nall_but_zeroes_to_list(<<0,T/binary>>, Acc, Remaining) ->\n all_but_zeroes_to_list(T, Acc, Remaining-1);\nall_but_zeroes_to_list(< >, Acc, Remaining) ->\n all_but_zeroes_to_list(T, [Byte|Acc], Remaining-1).\n```\n\nThe compiler removes building of sub binaries in the second and third clauses,\nand it adds an instruction to the first clause that converts `Buffer` from a\nmatch context to a sub binary (or do nothing if `Buffer` is a binary already).\n\nBut in more complicated code, how can one know whether the optimization is\napplied or not?\n\n[](){: #bin_opt_info }","ref":"binaryhandling.html#matching-binaries"},{"type":"extras","title":"Option bin_opt_info - Constructing and Matching Binaries","doc":"Use the `bin_opt_info` option to have the compiler print a lot of information\nabout binary optimizations. It can be given either to the compiler or `erlc`:\n\n```erlang\nerlc +bin_opt_info Mod.erl\n```\n\nor passed through an environment variable:\n\n```erlang\nexport ERL_COMPILER_OPTIONS=bin_opt_info\n```\n\nNotice that the `bin_opt_info` is not meant to be a permanent option added to\nyour `Makefile`s, because all messages that it generates cannot be eliminated.\nTherefore, passing the option through the environment is in most cases the most\npractical approach.\n\nThe warnings look as follows:\n\n```erlang\n./efficiency_guide.erl:60: Warning: NOT OPTIMIZED: binary is returned from the function\n./efficiency_guide.erl:62: Warning: OPTIMIZED: match context reused\n```\n\nTo make it clearer exactly what code the warnings refer to, the warnings in the\nfollowing examples are inserted as comments after the clause they refer to, for\nexample:\n\n```erlang\nafter_zero(<<0,T/binary>>) ->\n %% BINARY CREATED: binary is returned from the function\n T;\nafter_zero(<<_,T/binary>>) ->\n %% OPTIMIZED: match context reused\n after_zero(T);\nafter_zero(<<>>) ->\n <<>>.\n```\n\nThe warning for the first clause says that the creation of a sub binary cannot\nbe delayed, because it will be returned. The warning for the second clause says\nthat a sub binary will not be created (yet).","ref":"binaryhandling.html#option-bin_opt_info"},{"type":"extras","title":"Unused Variables - Constructing and Matching Binaries","doc":"The compiler figures out if a variable is unused. The same code is generated for\neach of the following functions:\n\n```erlang\ncount1(<<_,T/binary>>, Count) -> count1(T, Count+1);\ncount1(<<>>, Count) -> Count.\n\ncount2(< >, Count) -> count2(T, Count+1);\ncount2(<<>>, Count) -> Count.\n\ncount3(<<_H,T/binary>>, Count) -> count3(T, Count+1);\ncount3(<<>>, Count) -> Count.\n```\n\nIn each iteration, the first 8 bits in the binary will be skipped, not matched\nout.","ref":"binaryhandling.html#unused-variables"},{"type":"extras","title":"Maps","doc":"\n# Maps\n\nThis guide to using maps efficiently starts with a brief section on the choice\nbetween records or maps, followed by three sections giving concrete (but brief)\nadvice on using maps as an alternative to records, as dictionaries, and as sets.\nThe remaining sections dig deeper, looking at how maps are implemented, the map\nsyntax, and finally the functions in the `m:maps` module.\n\n[](){: #terminology }\n\nTerminology used in this chapter:\n\n- A map with at most 32 elements will informally be called a _small map_.\n- A map with more than 32 elements will informally be called a _large map_.","ref":"maps.html"},{"type":"extras","title":"Maps or Records? - Maps","doc":"If the advice in this chapter is followed, the performance of records compared\nto using small maps instead of records is expected to be similar. Therefore, the\nchoice between records and maps should be based on the desired properties of the\ndata structure and not performance.\n\nThe advantages of records compared to maps are:\n\n- If the name of a record field is misspelled, there will be a compilation\n error. If a map key is misspelled, the compiler will give no warning and\n program will fail in some way when it is run.\n- Records will use slightly less memory than maps, and performance is expected\n to be _slightly_ better than maps in most circumstances.\n\nThe disadvantage of records compared to maps is that if a new field is added to\na record, all code that uses that record must be recompiled. Because of that, it\nis recommended to only use records within a unit of code that can easily be\nrecompiled all at once, for example within a single application or single\nmodule.","ref":"maps.html#maps-or-records"},{"type":"extras","title":"Using Maps as an Alternative to Records - Maps","doc":"- Use the map syntax instead of the functions in the `m:maps` module.\n- Avoid having more than 32 elements in the map. As soon as there are more than\n 32 elements in the map, it will require more memory and keys can no longer be\n shared with other instances of the map.\n- When creating a new map, always create it with all keys that will ever be\n used. To maximize sharing of keys (thus minimizing memory use), create a\n single function that constructs the map using the map syntax and always use\n it.\n- Always update the map using the `:=` operator (that is, requiring that an\n element with that key already exists). The `:=` operator is slightly more\n efficient, and it helps catching mispellings of keys.\n- Whenever possible, match multiple map elements at once.\n- Whenever possible, update multiple map elements at once.\n- Avoid default values and the `maps:get/3` function. If there are default\n values, sharing of keys between different instances of the map will be less\n effective, and it is not possible to match multiple elements having default\n values in one go.\n- To avoid having to deal with a map that may lack some keys, `maps:merge/2` can\n efficiently add multiple default values. For example:\n\n ```erlang\n DefaultMap = #{shoe_size => 42, editor => emacs},\n MapWithDefaultsApplied = maps:merge(DefaultMap, OtherMap)\n ```","ref":"maps.html#using-maps-as-an-alternative-to-records"},{"type":"extras","title":"Using Maps as Dictionaries - Maps","doc":"Using a map as a dictionary implies the following usage pattern:\n\n- Keys are usually variables not known at compile-time.\n- There can be any number of elements in the map.\n- Usually, no more than one element is looked up or updated at once.\n\nGiven that usage pattern, the difference in performance between using the map\nsyntax and the maps module is usually small. Therefore, which one to use is\nmostly a matter of taste.\n\nMaps are usually the most efficient dictionary data structure, with a few\nexceptions:\n\n- If it is necessary to frequently convert a dictionary to a sorted list, or\n from a sorted list to a dictionary, using `m:gb_trees` can be a better choice.\n- If all keys are non-negative integers, the `m:array` module can be a better\n choice.","ref":"maps.html#using-maps-as-dictionaries"},{"type":"extras","title":"Using Maps as Sets - Maps","doc":"Starting in OTP 24, the `m:sets` module has an option to represent sets as maps.\nExamples:\n\n```erlang\n1> sets:new([{version,2}]).\n#{}\n2> sets:from_list([x,y,z], [{version,2}]).\n#{x => [],y => [],z => []}\n```\n\n`sets` backed by maps is generally the most efficient set representation, with a\nfew possible exceptions:\n\n- `ordsets:intersection/2` can be more efficient than `sets:intersection/2`. If\n the intersection operation is frequently used and operations that operate on a\n single element in a set (such as `is_element/2`) are avoided, `m:ordsets` can\n be a better choice than `m:sets`.\n- If the intersection operation is frequently used and operations that operate\n on a single element in a set (such as `is_element/2`) must also be efficient,\n `m:gb_sets` can potentially be a better choice than `m:sets`.\n- If the elements of the set are integers in a fairly compact range, the set can\n be represented as an integer where each bit represents an element in the set.\n The union operation is performed by `bor` and the intersection operation by\n `band`.","ref":"maps.html#using-maps-as-sets"},{"type":"extras","title":"How Maps are Implemented - Maps","doc":"Internally, maps have two distinct representations depending on the number of\nelements in the map. The representation changes when a map grows beyond 32\nelements, or when it shrinks to 32 elements or less.\n\n- A map with at most 32 elements has a compact representation, making it\n suitable as an alternative to records.\n- A map with more than 32 elements is represented as a tree that can be\n efficiently searched and updated regardless of how many elements there are.","ref":"maps.html#how-maps-are-implemented"},{"type":"extras","title":"How Small Maps are Implemented - Maps","doc":"A small map looks like this inside the runtime system:\n\n| 0 | 1 | 2 | 3 | | N |\n| :---------: | --- | :----: | :------: | :-----: | :------: |\n| **FLATMAP** | _N_ | _Keys_ | _Value1_ | _..._ | _ValueN_ |\n\n_Table: The representation of a small map_\n\n- **`FLATMAP`** - The tag for a small map (called _flat map_ in the source code\n for the runtime system).\n\n- **N** - The number of elements in the map.\n\n- **Keys** - A tuple with keys of the map: `{Key1,...,KeyN}`. The keys are\n sorted.\n\n- **Value1** - The value corresponding to the first key in the key tuple.\n\n- **ValueN** - The value corresponding to the last key in the key tuple.\n\nAs an example, let us look at how the map `#{a => foo, z => bar}` is\nrepresented:\n\n| 0 | 1 | 2 | 3 | 4 |\n| :---------: | --- | :-------: | :---: | ----- |\n| **FLATMAP** | _2_ | `{a,z}` | `foo` | `bar` |\n\n_Table: \\#\\{a => foo, z => bar\\}_\n\nLet us update the map: `M#{q => baz}`. The map now looks like this:\n\n| 0 | 1 | 2 | 3 | 4 | 5 |\n| :---------: | --- | :---------: | :---: | :---: | :---: |\n| **FLATMAP** | _3_ | `{a,q,z}` | `foo` | `baz` | `bar` |\n\n_Table: \\#\\{a => foo, q => baz, z => bar\\}_\n\nFinally, change the value of one element: `M#{z := bird}`. The map now looks\nlike this:\n\n| 0 | 1 | 2 | 3 | 4 | 5 |\n| :---------: | --- | :---------: | :---: | :---: | :----: |\n| **FLATMAP** | _3_ | `{a,q,z}` | `foo` | `baz` | `bird` |\n\n_Table: \\#\\{a => foo, q => baz, z => bird\\}_\n\nWhen the value for an existing key is updated, the key tuple is not updated,\nallowing the key tuple to be shared with other instances of the map that have\nthe same keys. In fact, the key tuple can be shared between all maps with the\nsame keys with some care. To arrange that, define a function that returns a map.\nFor example:\n\n```erlang\nnew() ->\n #{a => default, b => default, c => default}.\n```\n\nDefined like this, the key tuple `{a,b,c}` will be a global literal. To ensure\nthat the key tuple is shared when creating an instance of the map, always call\n`new()` and modify the returned map:\n\n```erlang\n (SOME_MODULE:new())#{a := 42}.\n```\n\nUsing the map syntax with small maps is particularly efficient. As long as the\nkeys are known at compile-time, the map is updated in one go, making the time to\nupdate a map essentially constant regardless of the number of keys updated. The\nsame goes for matching. (When the keys are variables, one or more of the keys\ncould be identical, so the operations need to be performed sequentially from\nleft to right.)\n\nThe memory size for a small map is the size of all keys and values plus 5 words.\nSee [Memory](memory.md) for more information about memory sizes.","ref":"maps.html#how-small-maps-are-implemented"},{"type":"extras","title":"How Large Maps are Implemented - Maps","doc":"A map with more than 32 elements is implemented as a\n[Hash array mapped trie (HAMT)](https://en.wikipedia.org/wiki/Hash_array_mapped_trie).\nA large map can be efficiently searched and updated regardless of the number of\nelements in the map.\n\nThere is less performance to be gained by matching or updating multiple elements\nusing the map syntax on a large map compared to a small map. The execution time\nis roughly proportional to the number of elements matched or updated.\n\nThe storage overhead for a large map is higher than for a small map. For a large\nmap, the extra number of words besides the keys and values is roughly\nproportional to the number of elements. For a map with 33 elements the overhead\nis at least 53 heap words according to the formula in\n[Memory](memory.md) (compared to 5 extra words for a small map\nregardless of the number of elements).\n\nWhen a large map is updated, the updated map and the original map will share\ncommon parts of the HAMT, but sharing will never be as effective as the best\npossible sharing of the key tuple for small maps.\n\nTherefore, if maps are used instead of records and it is expected that many\ninstances of the map will be created, it is more efficient from a memory\nstandpoint to avoid using large maps (for example, by grouping related map\nelements into sub maps to reduce the number of elements).","ref":"maps.html#how-large-maps-are-implemented"},{"type":"extras","title":"Using the Map Syntax - Maps","doc":"Using the map syntax is usually slightly more efficient than using the\ncorresponding function in the `m:maps` module.\n\nThe gain in efficiency for the map syntax is more noticeable for the following\noperations that can only be achieved using the map syntax:\n\n- Matching multiple literal keys\n- Updating multiple literal keys\n- Adding multiple literal keys to a map\n\nFor example:\n\n**DO**\n\n```erlang\nMap = Map1#{x := X, y := Y, z := Z}\n```\n\n**DO NOT**\n\n```erlang\nMap2 = maps:update(x, X, Map1),\nMap3 = maps:update(y, Y, Map2),\nMap = maps:update(z, Z, Map3)\n```\n\nIf the map is a small map, the first example runs roughly three times as fast.\n\nNote that for variable keys, the elements are updated sequentially from left to\nright. For example, given the following update with variable keys:\n\n```erlang\nMap = Map1#{Key1 := X, Key2 := Y, Key3 := Z}\n```\n\nthe compiler rewrites it like this to ensure that the updates are applied from\nleft to right:\n\n```erlang\nMap2 = Map1#{Key1 := X},\nMap3 = Map2#{Key2 := Y},\nMap = Map3#{Key3 := Z}\n```\n\nIf a key is known to exist in a map, using the `:=` operator is slightly more\nefficient than using the `=>` operator for a small map.","ref":"maps.html#using-the-map-syntax"},{"type":"extras","title":"Using the Functions in the maps Module - Maps","doc":"Here follows some notes about most of the functions in the `maps` module. For\neach function, the implementation language (C or Erlang) is stated. The reason\nwe mention the language is that it gives an hint about how efficient the\nfunction is:\n\n- If a function is implemented in C, it is pretty much impossible to implement\n the same functionality more efficiently in Erlang.\n- However, it might be possible to beat the `maps` modules functions implemented\n in Erlang, because they are generally implemented in a way that attempts to\n make the performance reasonable for all possible inputs.\n\n For example, `maps:map/2` iterates over all elements of the map, calling the\n mapping fun, collects the updated map elements in a list, and finally converts\n the list back to a map using `maps:from_list/1`. If it is known that at most\n one percent of the values in the map will change, it can be more efficient to\n update only the changed values.\n\n> #### Note {: .info }\n>\n> The implementation details given in this section can change in the future.","ref":"maps.html#using-the-functions-in-the-maps-module"},{"type":"extras","title":"maps:filter/2 - Maps","doc":"`maps:filter/2` is implemented in Erlang. It creates a new map using\n`maps:from_list/1`. If it is known that only a minority of the values will be\nremoved, it can be more efficient to avoid `maps:filter/2` and write a function\nthat will use [maps:remove/3](`maps:remove/2`) to remove the unwanted values.","ref":"maps.html#maps-filter-2"},{"type":"extras","title":"maps:filtermap/2 - Maps","doc":"`maps:filtermap/2` is implemented in Erlang. It creates a new map using\n`maps:from_list/1`. See the notes for `maps:map/2` and `maps:filter/2` for hints\non how to implement a more efficient version.","ref":"maps.html#maps-filtermap-2"},{"type":"extras","title":"maps:find/2 - Maps","doc":"`maps:find/2` is implemented in C.\n\nUsing the map matching syntax instead of `maps:find/2` will be slightly more\nefficient since building an `{ok,Value}` tuple will be avoided.","ref":"maps.html#maps-find-2"},{"type":"extras","title":"maps:get/2 - Maps","doc":"As an optimization, the compiler will rewrite a call to `maps:get/2` to a call\nto the guard BIF [map_get/2](`erlang:map_get/2`). A call to a guard BIF is more\nefficient than calls to other BIFs, making the performance similar to using the\nmap matching syntax.\n\nIf the map is small and the keys are constants known at compile-time, using the\nmap matching syntax will be more efficient than multiple calls to `maps:get/2`.\n\n[](){: #maps_get_3 }","ref":"maps.html#maps-get-2"},{"type":"extras","title":"maps:get/3 - Maps","doc":"As an optimization, the compiler will rewrite a call to `maps:get/3` to Erlang\ncode similar to the following:\n\n```erlang\nResult = case Map of\n #{Key := Value} -> Value;\n #{} -> Default\n end\n```\n\nThis is reasonably efficient, but if a small map is used as an alternative to\nusing a record it is often better not to rely on default values as it prevents\nsharing of keys, which may in the end use more memory than what you save from\nnot storing default values in the map.\n\nIf default values are nevertheless required, instead of calling `maps:get/3`\nmultiple times, consider putting the default values in a map and merging that\nmap with the other map:\n\n```erlang\nDefaultMap = #{Key1 => Value2, Key2 => Value2, ..., KeyN => ValueN},\nMapWithDefaultsApplied = maps:merge(DefaultMap, OtherMap)\n```\n\nThis helps share keys between the default map and the one you applied defaults\nto, as long as the default map contains _all_ the keys that will ever be used\nand not just the ones with default values. Whether this is faster than calling\n`maps:get/3` multiple times depends on the size of the map and the number of\ndefault values.\n\n> #### Change {: .info }\n>\n> Before OTP 26.0 `maps:get/3` was implemented by calling the function instead\n> of rewriting it as an Erlang expression. It is now slightly faster but can no\n> longer be traced.","ref":"maps.html#maps-get-3"},{"type":"extras","title":"maps:intersect/2, maps:intersect_with/3 - Maps","doc":"`maps:intersect/2` and `maps:intersect_with/3` are implemented in Erlang. They\nboth create new maps using `maps:from_list/1`.\n\n> #### Note {: .info }\n>\n> A map is usually the most efficient way to implement a set, but an exception\n> is the intersection operation, where `ordsets:intersection/2` used on\n> `m:ordsets` can be more efficient than `maps:intersect/2` on sets implemented\n> as maps.","ref":"maps.html#maps-intersect-2-maps-intersect_with-3"},{"type":"extras","title":"maps:from_list/1 - Maps","doc":"`maps:from_list/1` is implemented in C.","ref":"maps.html#maps-from_list-1"},{"type":"extras","title":"maps:from_keys/2 - Maps","doc":"`maps:from_keys/2` is implemented in C.","ref":"maps.html#maps-from_keys-2"},{"type":"extras","title":"maps:is_key/2 - Maps","doc":"As an optimization, the compiler rewrites calls to `maps:is_key/2` to calls to\nthe guard BIF [is_map_key/2](`erlang:is_map_key/2`). A call to a guard BIF is\nmore efficient than calls to other BIFs, making the performance similar to using\nthe map matching syntax.","ref":"maps.html#maps-is_key-2"},{"type":"extras","title":"maps:iterator/1 - Maps","doc":"`maps:iterator/1` is efficiently implemented in C and Erlang.","ref":"maps.html#maps-iterator-1"},{"type":"extras","title":"maps:keys/1 - Maps","doc":"`maps:keys/1` is implemented in C. If the resulting list needs to be ordered,\nuse `lists:sort/1` to sort the result.","ref":"maps.html#maps-keys-1"},{"type":"extras","title":"maps:map/2 - Maps","doc":"`maps:map/2` is implemented in Erlang. It creates a new map using\n`maps:from_list/1`. If it is known that only a minority of the values will be\nupdated, it can be more efficient to avoid `maps:map/2` and write a function\nthat will call `maps:update/3` to update only the values that have changed.","ref":"maps.html#maps-map-2"},{"type":"extras","title":"maps:merge/2 - Maps","doc":"`maps:merge/2` is implemented in C. For [small maps](maps.md#terminology), the\nkey tuple may be shared with any of the argument maps if that argument map\ncontains all the keys. Literal key tuples are prefered if possible.\n\n> #### Change {: .info }\n>\n> The sharing of key tuples by `maps:merge/2` was introduced in OTP 26.0. Older\n> versions always contructed a new key tuple on the callers heap.","ref":"maps.html#maps-merge-2"},{"type":"extras","title":"maps:merge_with/3 - Maps","doc":"`maps:merge_with/3` is implemented in Erlang. It updates and returns the larger\nof the two maps.","ref":"maps.html#maps-merge_with-3"},{"type":"extras","title":"maps:new/0 - Maps","doc":"The compiler rewrites a call to `maps:new/0` to using the syntax `#{}` for\nconstructing an empty map.","ref":"maps.html#maps-new-0"},{"type":"extras","title":"maps:next/1 - Maps","doc":"`maps:next/1` is efficiently implemented in C and Erlang.","ref":"maps.html#maps-next-1"},{"type":"extras","title":"maps:put/3 - Maps","doc":"`maps:put/3` is implemented in C.\n\nIf the key is known to already exist in the map, `maps:update/3` is slightly\nmore efficient than `maps:put/3`.\n\nIf the compiler can determine that the third argument is always a map, it\nwill rewrite the call to `maps:put/3` to use the map syntax for updating the map.\n\nFor example, consider the following function:\n\n```erlang\nadd_to_known_map(Map0, A, B, C) when is_map(Map0) ->\n Map1 = maps:put(a, A, Map0),\n Map2 = maps:put(b, B, Map1),\n maps:put(c, C, Map2).\n```\n\nThe compiler first rewrites each call to `maps:put/3` to use the map\nsyntax, and subsequently combines the three update operations to a\nsingle update operation:\n\n```erlang\nadd_to_known_map(Map0, A, B, C) when is_map(Map0) ->\n Map0#{a => A, b => B, c => C}.\n```\n\nIf the compiler cannot determine that the third argument is always a\nmap, it retains the `maps:put/3` call. For example, given this\nfunction:\n\n```erlang\nadd_to_map(Map0, A, B, C) ->\n Map1 = maps:put(a, A, Map0),\n Map2 = maps:put(b, B, Map1),\n maps:put(c, C, Map2).\n```\n\nthe compiler keeps the first call to `maps:put/3`, but rewrites\nand combines the other two calls:\n\n```erlang\nadd_to_map(Map0, A, B, C) ->\n Map1 = maps:put(a, A, Map0),\n Map1#{b => B, c => C}.\n```\n\n> #### Change {: .info }\n>\n> The rewriting of `maps:put/3` to the map syntax was introduced in\n> Erlang/OTP 28.","ref":"maps.html#maps-put-3"},{"type":"extras","title":"maps:remove/2 - Maps","doc":"`maps:remove/2` is implemented in C.","ref":"maps.html#maps-remove-2"},{"type":"extras","title":"maps:size/1 - Maps","doc":"As an optimization, the compiler rewrites calls to `maps:size/1` to calls to the\nguard BIF [map_size/1](`erlang:map_size/1`). Calls to guard BIFs are more\nefficient than calls to other BIFs.","ref":"maps.html#maps-size-1"},{"type":"extras","title":"maps:take/2 - Maps","doc":"`maps:take/2` is implemented in C.","ref":"maps.html#maps-take-2"},{"type":"extras","title":"maps:to_list/1 - Maps","doc":"`maps:to_list/1` is efficiently implemented in C and Erlang. If the resulting\nlist needs to be ordered, use `lists:sort/1` to sort the result.\n\n> #### Note {: .info }\n>\n> Maps are usually more performant than `m:gb_trees`, but if it is necessary to\n> frequently convert to and from sorted lists, `gb_trees` can be a better\n> choice.","ref":"maps.html#maps-to_list-1"},{"type":"extras","title":"maps:update/3 - Maps","doc":"`maps:update/3` is implemented in C.\n\nIf the keys are constants known at compile-time, using the map update syntax\nwith the `:=` operator is more efficient than multiple calls to `maps:update/3`,\nespecially for [small maps](maps.md#terminology).","ref":"maps.html#maps-update-3"},{"type":"extras","title":"maps:values/1 - Maps","doc":"`maps:values/1` is implemented in C.","ref":"maps.html#maps-values-1"},{"type":"extras","title":"maps:with/2 - Maps","doc":"`maps:with/2` is implemented in Erlang. It creates a new map using\n`maps:from_list/1`.","ref":"maps.html#maps-with-2"},{"type":"extras","title":"maps:without/2 - Maps","doc":"`maps:without/2` is implemented in Erlang. It returns a modified copy of the\ninput map.","ref":"maps.html#maps-without-2"},{"type":"extras","title":"List Handling","doc":"\n# List Handling","ref":"listhandling.html"},{"type":"extras","title":"Creating a List - List Handling","doc":"Lists can only be built starting from the end and attaching list elements at the\nbeginning. If you use the `++` operator as follows, a new list is created that\nis a copy of the elements in `List1`, followed by `List2`:\n\n```erlang\nList1 ++ List2\n```\n\nLooking at how `lists:append/2` or `++` would be implemented in plain Erlang,\nclearly the first list is copied:\n\n```erlang\nappend([H|T], Tail) ->\n [H|append(T, Tail)];\nappend([], Tail) ->\n Tail.\n```\n\nWhen recursing and building a list, it is important to ensure that you attach\nthe new elements to the beginning of the list. In this way, you will build _one_\nlist, not hundreds or thousands of copies of the growing result list.\n\nLet us first see how it is not to be done:\n\n**DO NOT**\n\n```erlang\nbad_fib(N) ->\n bad_fib(N, 0, 1, []).\n\nbad_fib(0, _Current, _Next, Fibs) ->\n Fibs;\nbad_fib(N, Current, Next, Fibs) ->\n bad_fib(N - 1, Next, Current + Next, Fibs ++ [Current]).\n```\n\nHere more than one list is built. In each iteration step a new list is created\nthat is one element longer than the new previous list.\n\nTo avoid copying the result in each iteration, build the list in reverse order\nand reverse the list when you are done:\n\n**DO**\n\n```erlang\ntail_recursive_fib(N) ->\n tail_recursive_fib(N, 0, 1, []).\n\ntail_recursive_fib(0, _Current, _Next, Fibs) ->\n lists:reverse(Fibs);\ntail_recursive_fib(N, Current, Next, Fibs) ->\n tail_recursive_fib(N - 1, Next, Current + Next, [Current|Fibs]).\n```","ref":"listhandling.html#creating-a-list"},{"type":"extras","title":"List Comprehensions - List Handling","doc":"A list comprehension:\n\n```erlang\n[Expr(E) || E <- List]\n```\n\nis basically translated to a local function:\n\n```erlang\n'lc^0'([E|Tail], Expr) ->\n [Expr(E)|'lc^0'(Tail, Expr)];\n'lc^0'([], _Expr) -> [].\n```\n\nIf the result of the list comprehension will _obviously_ not be used, a list\nwill not be constructed. For example, in this code:\n\n```erlang\n[io:put_chars(E) || E <- List],\nok.\n```\n\nor in this code:\n\n```erlang\ncase Var of\n ... ->\n [io:put_chars(E) || E <- List];\n ... ->\nend,\nsome_function(...),\n```\n\nthe value is not assigned to a variable, not passed to another function, and not\nreturned. This means that there is no need to construct a list and the compiler\nwill simplify the code for the list comprehension to:\n\n```erlang\n'lc^0'([E|Tail], Expr) ->\n Expr(E),\n 'lc^0'(Tail, Expr);\n'lc^0'([], _Expr) -> [].\n```\n\nThe compiler also understands that assigning to `_` means that the value will\nnot be used. Therefore, the code in the following example will also be optimized:\n\n```erlang\n_ = [io:put_chars(E) || E <- List],\nok.\n```","ref":"listhandling.html#list-comprehensions"},{"type":"extras","title":"Deep and Flat Lists - List Handling","doc":"`lists:flatten/1` builds an entirely new list. It is therefore expensive, and\neven _more_ expensive than the `++` operator (which copies its left argument,\nbut not its right argument).\n\nIn the following situations it is unnecessary to call `lists:flatten/1`:\n\n- When sending data to a port. Ports understand deep lists so there is no reason\n to flatten the list before sending it to the port.\n- When calling BIFs that accept deep lists, such as\n [`list_to_binary/1`](`erlang:list_to_binary/1`) or\n [`iolist_to_binary/1`](`erlang:iolist_to_binary/1`).\n- When you know that your list is only one level deep. Use `lists:append/1`\n instead.\n\n_Examples:_\n\n**DO**\n\n```erlang\nport_command(Port, DeepList)\n```\n\n**DO NOT**\n\n```erlang\nport_command(Port, lists:flatten(DeepList))\n```\n\nA common way to send a zero-terminated string to a port is the following:\n\n**DO NOT**\n\n```erlang\nTerminatedStr = String ++ [0],\nport_command(Port, TerminatedStr)\n```\n\nInstead:\n\n**DO**\n\n```erlang\nTerminatedStr = [String, 0],\nport_command(Port, TerminatedStr)\n```\n\n**DO**\n\n```erlang\n1> lists:append([[1], [2], [3]]).\n[1,2,3]\n```\n\n**DO NOT**\n\n```erlang\n1> lists:flatten([[1], [2], [3]]).\n[1,2,3]\n```","ref":"listhandling.html#deep-and-flat-lists"},{"type":"extras","title":"Recursive List Functions - List Handling","doc":"There are two basic ways to write a function that traverses a list and\nproduces a new list.\n\nThe first way is writing a *body-recursive* function:\n\n```erlang\n%% Add 42 to each integer in the list.\nadd_42_body([H|T]) ->\n [H + 42 | add_42_body(T)];\nadd_42_body([]) ->\n [].\n```\n\nThe second way is writing a *tail-recursive* function:\n\n```erlang\n%% Add 42 to each integer in the list.\nadd_42_tail(List) ->\n add_42_tail(List, []).\n\nadd_42_tail([H|T], Acc) ->\n add_42_tail(T, [H + 42 | Acc]);\nadd_42_tail([], Acc) ->\n lists:reverse(Acc).\n```\n\nIn early version of Erlang the tail-recursive function would typically\nbe more efficient. In modern versions of Erlang, there is usually not\nmuch difference in performance between a body-recursive list function and\ntail-recursive function that reverses the list at the end. Therefore,\nconcentrate on writing beautiful code and forget about the performance\nof your list functions. In the time-critical parts of your code,\n_measure_ before rewriting your code.\n\nFor a thorough discussion about tail and body recursion, see\n[Erlang's Tail Recursion is Not a Silver Bullet](http://ferd.ca/erlang-s-tail-recursion-is-not-a-silver-bullet.html).\n\n> #### Note {: .info }\n>\n> This section is about list functions that _construct_ lists. A tail-recursive\n> function that does not construct a list runs in constant space, while the\n> corresponding body-recursive function uses stack space proportional to the\n> length of the list.\n\nFor example, a function that sums a list of integers, is _not_ to be written as\nfollows:\n\n**DO NOT**\n\n```erlang\nrecursive_sum([H|T]) -> H+recursive_sum(T);\nrecursive_sum([]) -> 0.\n```\n\nInstead:\n\n**DO**\n\n```erlang\nsum(L) -> sum(L, 0).\n\nsum([H|T], Sum) -> sum(T, Sum + H);\nsum([], Sum) -> Sum.\n```","ref":"listhandling.html#recursive-list-functions"},{"type":"extras","title":"Functions","doc":"\n# Functions","ref":"eff_guide_functions.html"},{"type":"extras","title":"Pattern Matching - Functions","doc":"Pattern matching in function head as well as in `case` and `receive` clauses are\noptimized by the compiler. With a few exceptions, there is nothing to gain by\nrearranging clauses.\n\nOne exception is pattern matching of binaries. The compiler does not rearrange\nclauses that match binaries. Placing the clause that matches against the empty\nbinary _last_ is usually slightly faster than placing it _first_.\n\nThe following is a rather unnatural example to show another exception where\nrearranging clauses is beneficial:\n\n**DO NOT**\n\n```erlang\natom_map1(one) -> 1;\natom_map1(two) -> 2;\natom_map1(three) -> 3;\natom_map1(Int) when is_integer(Int) -> Int;\natom_map1(four) -> 4;\natom_map1(five) -> 5;\natom_map1(six) -> 6.\n```\n\nThe problem is the clause with the variable `Int`. As a variable can match\nanything, including the atoms `four`, `five`, and `six`, which the following\nclauses also match, the compiler must generate suboptimal code that executes as\nfollows:\n\n- First, the input value is compared to `one`, `two`, and `three` (using a\n single instruction that does a binary search; thus, quite efficient even if\n there are many values) to select which one of the first three clauses to\n execute (if any).\n- If none of the first three clauses match, the fourth clause match as a\n variable always matches.\n- If the guard test [`is_integer(Int)`](`is_integer/1`) succeeds, the fourth\n clause is executed.\n- If the guard test fails, the input value is compared to `four`, `five`, and\n `six`, and the appropriate clause is selected. (There is a `function_clause`\n exception if none of the values matched.)\n\nRewriting to either:\n\n**DO**\n\n```erlang\natom_map2(one) -> 1;\natom_map2(two) -> 2;\natom_map2(three) -> 3;\natom_map2(four) -> 4;\natom_map2(five) -> 5;\natom_map2(six) -> 6;\natom_map2(Int) when is_integer(Int) -> Int.\n```\n\nor:\n\n**DO**\n\n```erlang\natom_map3(Int) when is_integer(Int) -> Int;\natom_map3(one) -> 1;\natom_map3(two) -> 2;\natom_map3(three) -> 3;\natom_map3(four) -> 4;\natom_map3(five) -> 5;\natom_map3(six) -> 6.\n```\n\ngives slightly more efficient matching code.\n\nAnother example:\n\n**DO NOT**\n\n```erlang\nmap_pairs1(_Map, [], Ys) ->\n Ys;\nmap_pairs1(_Map, Xs, []) ->\n Xs;\nmap_pairs1(Map, [X|Xs], [Y|Ys]) ->\n [Map(X, Y)|map_pairs1(Map, Xs, Ys)].\n```\n\nThe first argument is _not_ a problem. It is variable, but it is a variable in\nall clauses. The problem is the variable in the second argument, `Xs`, in the\nmiddle clause. Because the variable can match anything, the compiler is not\nallowed to rearrange the clauses, but must generate code that matches them in\nthe order written.\n\nIf the function is rewritten as follows, the compiler is free to rearrange the\nclauses:\n\n**DO**\n\n```erlang\nmap_pairs2(_Map, [], Ys) ->\n Ys;\nmap_pairs2(_Map, [_|_]=Xs, [] ) ->\n Xs;\nmap_pairs2(Map, [X|Xs], [Y|Ys]) ->\n [Map(X, Y)|map_pairs2(Map, Xs, Ys)].\n```\n\nThe compiler will generate code similar to this:\n\n**DO NOT (already done by the compiler)**\n\n```erlang\nexplicit_map_pairs(Map, Xs0, Ys0) ->\n case Xs0 of\n\t[X|Xs] ->\n\t case Ys0 of\n\t\t[Y|Ys] ->\n\t\t [Map(X, Y)|explicit_map_pairs(Map, Xs, Ys)];\n\t\t[] ->\n\t\t Xs0\n\t end;\n\t[] ->\n\t Ys0\n end.\n```\n\nThis is slightly faster for probably the most common case that the input lists\nare not empty or very short. (Another advantage is that Dialyzer can deduce a\nbetter type for the `Xs` variable.)","ref":"eff_guide_functions.html#pattern-matching"},{"type":"extras","title":"Function Calls - Functions","doc":"This is a rough hierarchy of the performance of the different types of function\ncalls:\n\n- Calls to local or external functions (`foo()`, `m:foo()`) are the fastest\n calls.\n- Calling or applying a fun (`Fun()`, [`apply(Fun, [])`](`apply/2`)) is just a\n little slower than external calls.\n- Applying an exported function (`Mod:Name()`,\n [`apply(Mod, Name, [])`](`apply/3`)) where the number of arguments is known at\n compile time is next.\n- Applying an exported function ([`apply(Mod, Name, Args)`](`apply/3`)) where\n the number of arguments is not known at compile time is the least efficient.","ref":"eff_guide_functions.html#function-calls"},{"type":"extras","title":"Notes and Implementation Details - Functions","doc":"Calling and applying a fun does not involve any hash-table lookup. A fun\ncontains an (indirect) pointer to the function that implements the fun.\n\n[`apply/3`](`apply/3`) must look up the code for the function to execute in a\nhash table. It is therefore always slower than a direct call or a fun call.\n\nCaching callback functions into funs may be more efficient in the long run than\napply calls for frequently-used callbacks.","ref":"eff_guide_functions.html#notes-and-implementation-details"},{"type":"extras","title":"Tables and Databases","doc":"\n# Tables and Databases","ref":"tablesdatabases.html"},{"type":"extras","title":"Ets, Dets, and Mnesia - Tables and Databases","doc":"Every example using Ets has a corresponding example in Mnesia. In general, all\nEts examples also apply to Dets tables.","ref":"tablesdatabases.html#ets-dets-and-mnesia"},{"type":"extras","title":"Select/Match Operations - Tables and Databases","doc":"Select/match operations on Ets and Mnesia tables can become very expensive\noperations. They usually need to scan the complete table. Try to structure the\ndata to minimize the need for select/match operations. However, if you require a\nselect/match operation, it is still more efficient than using `tab2list`.\nExamples of this and of how to avoid select/match are provided in the following\nsections. The functions `ets:select/2` and `mnesia:select/3` are to be preferred\nover `ets:match/2`, `ets:match_object/2`, and `mnesia:match_object/3`.\n\nIn some circumstances, the select/match operations do not need to scan the\ncomplete table. For example, if part of the key is bound when searching an\n`ordered_set` table, or if it is a Mnesia table and there is a secondary index\non the field that is selected/matched. If the key is fully bound, there is no\npoint in doing a select/match, unless you have a bag table and are only\ninterested in a subset of the elements with the specific key.\n\nWhen creating a record to be used in a select/match operation, you want most of\nthe fields to have the value `_`. The easiest and fastest way to do that is as\nfollows:\n\n```text\n#person{age = 42, _ = '_'}.\n```","ref":"tablesdatabases.html#select-match-operations"},{"type":"extras","title":"Deleting an Element - Tables and Databases","doc":"The `delete` operation is considered successful if the element was not present\nin the table. Hence all attempts to check that the element is present in the\nEts/Mnesia table before deletion are unnecessary. Here follows an example for\nEts tables:\n\n**DO**\n\n```text\nets:delete(Tab, Key),\n```\n\n**DO NOT**\n\n```erlang\ncase ets:lookup(Tab, Key) of\n [] ->\n ok;\n [_|_] ->\n ets:delete(Tab, Key)\nend,\n```","ref":"tablesdatabases.html#deleting-an-element"},{"type":"extras","title":"Fetching Data - Tables and Databases","doc":"Do not fetch data that you already have.\n\nConsider that you have a module that handles the abstract data type `Person`.\nYou export the interface function `print_person/1`, which uses the internal\nfunctions `print_name/1`, `print_age/1`, and `print_occupation/1`.\n\n> #### Note {: .info }\n>\n> If the function `print_name/1`, and so on, had been interface functions, the\n> situation would have been different, as you do not want the user of the\n> interface to know about the internal data representation.\n\n**DO**\n\n```erlang\n%%% Interface function\nprint_person(PersonId) ->\n %% Look up the person in the named table person,\n case ets:lookup(person, PersonId) of\n [Person] ->\n print_name(Person),\n print_age(Person),\n print_occupation(Person);\n [] ->\n io:format(\"No person with ID = ~p~n\", [PersonID])\n end.\n\n%%% Internal functions\nprint_name(Person) ->\n io:format(\"No person ~p~n\", [Person#person.name]).\n\nprint_age(Person) ->\n io:format(\"No person ~p~n\", [Person#person.age]).\n\nprint_occupation(Person) ->\n io:format(\"No person ~p~n\", [Person#person.occupation]).\n```\n\n**DO NOT**\n\n```erlang\n%%% Interface function\nprint_person(PersonId) ->\n %% Look up the person in the named table person,\n case ets:lookup(person, PersonId) of\n [Person] ->\n print_name(PersonID),\n print_age(PersonID),\n print_occupation(PersonID);\n [] ->\n io:format(\"No person with ID = ~p~n\", [PersonID])\n end.\n\n%%% Internal functions\nprint_name(PersonID) ->\n [Person] = ets:lookup(person, PersonId),\n io:format(\"No person ~p~n\", [Person#person.name]).\n\nprint_age(PersonID) ->\n [Person] = ets:lookup(person, PersonId),\n io:format(\"No person ~p~n\", [Person#person.age]).\n\nprint_occupation(PersonID) ->\n [Person] = ets:lookup(person, PersonId),\n io:format(\"No person ~p~n\", [Person#person.occupation]).\n```","ref":"tablesdatabases.html#fetching-data"},{"type":"extras","title":"Non-Persistent Database Storage - Tables and Databases","doc":"For non-persistent database storage, prefer Ets tables over Mnesia\n`local_content` tables. Even the Mnesia `dirty_write` operations carry a fixed\noverhead compared to Ets writes. Mnesia must check if the table is replicated or\nhas indices, this involves at least one Ets lookup for each `dirty_write`. Thus,\nEts writes is always faster than Mnesia writes.","ref":"tablesdatabases.html#non-persistent-database-storage"},{"type":"extras","title":"tab2list - Tables and Databases","doc":"Assuming an Ets table that uses `idno` as key and contains the following:\n\n```text\n[#person{idno = 1, name = \"Adam\", age = 31, occupation = \"mailman\"},\n #person{idno = 2, name = \"Bryan\", age = 31, occupation = \"cashier\"},\n #person{idno = 3, name = \"Bryan\", age = 35, occupation = \"banker\"},\n #person{idno = 4, name = \"Carl\", age = 25, occupation = \"mailman\"}]\n```\n\nIf you _must_ return all data stored in the Ets table, you can use\n`ets:tab2list/1`. However, usually you are only interested in a subset of the\ninformation in which case `ets:tab2list/1` is expensive. If you only want to\nextract one field from each record, for example, the age of every person, then:\n\n**DO**\n\n```erlang\nets:select(Tab, [{#person{idno='_',\n name='_',\n age='$1',\n occupation = '_'},\n [],\n ['$1']}]),\n```\n\n**DO NOT**\n\n```erlang\nTabList = ets:tab2list(Tab),\nlists:map(fun(X) -> X#person.age end, TabList),\n```\n\nIf you are only interested in the age of all persons named \"Bryan\", then:\n\n**DO**\n\n```erlang\nets:select(Tab, [{#person{idno='_',\n name=\"Bryan\",\n age='$1',\n occupation = '_'},\n [],\n ['$1']}])\n```\n\n**DO NOT**\n\n```erlang\nTabList = ets:tab2list(Tab),\nlists:foldl(fun(X, Acc) -> case X#person.name of\n \"Bryan\" ->\n [X#person.age|Acc];\n _ ->\n Acc\n end\n end, [], TabList)\n```\n\nIf you need all information stored in the Ets table about persons named \"Bryan\",\nthen:\n\n**DO**\n\n```erlang\nets:select(Tab, [{#person{idno='_',\n name=\"Bryan\",\n age='_',\n occupation = '_'}, [], ['$_']}]),\n```\n\n**DO NOT**\n\n```erlang\nTabList = ets:tab2list(Tab),\nlists:filter(fun(X) -> X#person.name == \"Bryan\" end, TabList),\n```\n\n### `ordered_set` Tables\n\nIf the data in the table is to be accessed so that the order of the keys in the\ntable is significant, the table type `ordered_set` can be used instead of the\nmore usual `set` table type. An `ordered_set` is always traversed in Erlang term\norder regarding the key field so that the return values from functions such as\n`select`, `match_object`, and `foldl` are ordered by the key values. Traversing\nan `ordered_set` with the `first` and `next` operations also returns the keys\nordered.\n\n> #### Note {: .info }\n>\n> An `ordered_set` only guarantees that objects are processed in _key_ order.\n> Results from functions such as `ets:select/2` appear in _key_ order even if\n> the key is not included in the result.","ref":"tablesdatabases.html#tab2list"},{"type":"extras","title":"ETS - Tables and Databases","doc":"","ref":"tablesdatabases.html#ets"},{"type":"extras","title":"Using Keys of Ets Table - Tables and Databases","doc":"An Ets table is a single-key table (either a hash table or a tree ordered by the\nkey) and is to be used as one. In other words, use the key to look up things\nwhenever possible. A lookup by a known key in a `set` Ets table is constant and\nfor an `ordered_set` Ets table it is _O(log N)_. A key lookup is always preferable\nto a call where the whole table has to be scanned. In the previous examples, the\nfield `idno` is the key of the table and all lookups where only the name is\nknown result in a complete scan of the (possibly large) table for a matching\nresult.\n\nA simple solution would be to use the `name` field as the key instead of the\n`idno` field, but that would cause problems if the names were not unique. A more\ngeneral solution would be to create a second table with `name` as key and `idno`\nas data, that is, to index (invert) the table regarding the `name` field.\nClearly, the second table would have to be kept consistent with the master\ntable. Mnesia can do this for you, but a home-brew index table can be very\nefficient compared to the overhead involved in using Mnesia.\n\nAn index table for the table in the previous examples would have to be a bag (as\nkeys would appear more than once) and can have the following contents:\n\n```text\n[#index_entry{name=\"Adam\", idno=1},\n #index_entry{name=\"Bryan\", idno=2},\n #index_entry{name=\"Bryan\", idno=3},\n #index_entry{name=\"Carl\", idno=4}]\n```\n\nGiven this index table, a lookup of the `age` fields for all persons named\n\"Bryan\" can be done as follows:\n\n```erlang\nMatchingIDs = ets:lookup(IndexTable,\"Bryan\"),\nlists:map(fun(#index_entry{idno = ID}) ->\n [#person{age = Age}] = ets:lookup(PersonTable, ID),\n Age\n end,\n MatchingIDs),\n```\n\nNotice that this code does not use `ets:match/2`, but instead uses the\n`ets:lookup/2` call. The `lists:map/2` call is only used to traverse the `idno`s\nmatching the name \"Bryan\" in the table; thus the number of lookups in the master\ntable is minimized.\n\nKeeping an index table introduces some overhead when inserting records in the\ntable. The number of operations gained from the table must therefore be compared\nagainst the number of operations inserting objects in the table. However, notice\nthat the gain is significant when the key can be used to lookup elements.","ref":"tablesdatabases.html#using-keys-of-ets-table"},{"type":"extras","title":"Mnesia - Tables and Databases","doc":"","ref":"tablesdatabases.html#mnesia"},{"type":"extras","title":"Secondary Index - Tables and Databases","doc":"If you frequently do lookups on a field that is not the key of the table, you\nlose performance using [mnesia:select()](`mnesia:select/3`) or\n[`mnesia:match_object()`](`mnesia:match_object/1`) as these function traverse\nthe whole table. Instead, you can create a secondary index and use\n`mnesia:index_read/3` to get faster access at the expense of using more\nmemory.\n\n_Example:_\n\n```erlang\n-record(person, {idno, name, age, occupation}).\n ...\n{atomic, ok} =\nmnesia:create_table(person, [{index,[#person.age]},\n {attributes,\n record_info(fields, person)}]),\n{atomic, ok} = mnesia:add_table_index(person, age),\n...\n\nPersonsAge42 =\n mnesia:dirty_index_read(person, 42, #person.age),\n```","ref":"tablesdatabases.html#secondary-index"},{"type":"extras","title":"Transactions - Tables and Databases","doc":"Using transactions is a way to guarantee that the distributed Mnesia database\nremains consistent, even when many different processes update it in parallel.\nHowever, if you have real-time requirements it is recommended to use dirtry\noperations instead of transactions. When using dirty operations, you lose the\nconsistency guarantee; this is usually solved by only letting one process update\nthe table. Other processes must send update requests to that process.\n\n_Example:_\n\n```erlang\n...\n%% Using transaction\n\nFun = fun() ->\n [mnesia:read({Table, Key}),\n mnesia:read({Table2, Key2})]\n end,\n\n{atomic, [Result1, Result2]} = mnesia:transaction(Fun),\n...\n\n%% Same thing using dirty operations\n...\n\nResult1 = mnesia:dirty_read({Table, Key}),\nResult2 = mnesia:dirty_read({Table2, Key2}),\n```","ref":"tablesdatabases.html#transactions"},{"type":"extras","title":"Processes","doc":"\n# Processes","ref":"eff_guide_processes.html"},{"type":"extras","title":"Creating an Erlang Process - Processes","doc":"An Erlang process is lightweight compared to threads and processes in operating\nsystems.\n\nA newly spawned Erlang process uses 327 words of memory. The size can be found\nas follows:\n\n```erlang\nErlang/OTP 27 [erts-14.2.3] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]\n\nEshell V14.2.3 (press Ctrl+G to abort, type help(). for help)\n1> Fun = fun() -> receive after infinity -> ok end end.\n#Fun \n2> {_,Bytes} = process_info(spawn(Fun), memory).\n{memory,2616}\n3> Bytes div erlang:system_info(wordsize).\n327\n```\n\nThe size includes 233 words for the heap area (which includes the stack). The\ngarbage collector increases the heap as needed.\n\nThe main (outer) loop for a process _must_ be tail-recursive. Otherwise, the\nstack grows until the process terminates.\n\n**DO NOT**\n\n```erlang\nloop() ->\n receive\n {sys, Msg} ->\n handle_sys_msg(Msg),\n loop();\n {From, Msg} ->\n Reply = handle_msg(Msg),\n From ! Reply,\n loop()\n end,\n io:format(\"Message is processed~n\", []).\n```\n\nThe call to `io:format/2` will never be executed, but a return address will\nstill be pushed to the stack each time `loop/0` is called recursively. The\ncorrect tail-recursive version of the function looks as follows:\n\n**DO**\n\n```erlang\nloop() ->\n receive\n {sys, Msg} ->\n handle_sys_msg(Msg),\n loop();\n {From, Msg} ->\n Reply = handle_msg(Msg),\n From ! Reply,\n loop()\n end.\n```","ref":"eff_guide_processes.html#creating-an-erlang-process"},{"type":"extras","title":"Initial Heap Size - Processes","doc":"The default initial heap size of 233 words is quite conservative to support\nErlang systems with hundreds of thousands or even millions of processes. The\ngarbage collector grows and shrinks the heap as needed.\n\nIn a system that use comparatively few processes, performance _might_ be\nimproved by increasing the minimum heap size using either the `+h` option for\n[erl](`e:erts:erl_cmd.md`) or on a process-per-process basis using the\n`min_heap_size` option for [spawn_opt/4](`erlang:spawn_opt/4`).\n\nThe gain is twofold:\n\n- Although the garbage collector grows the heap, it grows it step-by-step, which\n is more costly than directly establishing a larger heap when the process is\n spawned.\n- The garbage collector can also shrink the heap if it is much larger than the\n amount of data stored on it; setting the minimum heap size prevents that.\n\n> #### Warning {: .warning }\n>\n> The runtime system probably uses more memory, and because garbage collections occur\n> less frequently, huge binaries can be kept much longer.\n>\n> This optimization is not to be attempted without proper measurements.\n\nIn systems with many processes, computation tasks that run for a short time can\nbe spawned off into a new process with a higher minimum heap size. When the\nprocess is done, it sends the result of the computation to another process and\nterminates. If the minimum heap size is calculated properly, the process might\nnot have to do any garbage collections at all.","ref":"eff_guide_processes.html#initial-heap-size"},{"type":"extras","title":"Sending Messages - Processes","doc":"All data in messages sent between Erlang processes is copied, except for\n[refc binaries](binaryhandling.md#refc_binary) and\n[literals](eff_guide_processes.md#literal-pool) on the same Erlang node.\n\nWhen a message is sent to a process on another Erlang node, it is\nfirst encoded to the [Erlang External Format](`e:erts:erl_ext_dist.md`)\nbefore being sent through a TCP/IP socket. The receiving Erlang node\ndecodes the message and distributes it to the correct process.","ref":"eff_guide_processes.html#sending-messages"},{"type":"extras","title":"Receiving messages - Processes","doc":"The cost of receiving messages depends on how complicated the `receive`\nexpression is. A simple expression that matches any message is very cheap\nbecause it retrieves the first message in the message queue:\n\n**DO**\n\n```erlang\nreceive\n Message -> handle_msg(Message)\nend.\n```\n\nHowever, this is not always convenient: we can receive a message that we do not\nknow how to handle at this point, so it is common to only match the messages we\nexpect:\n\n```erlang\nreceive\n {Tag, Message} -> handle_msg(Message)\nend.\n```\n\nWhile this is convenient it means that the entire message queue must be searched\nuntil it finds a matching message. This is very expensive for processes with\nlong message queues, so there is an optimization for the common case of\nsending a request and waiting for a response shortly after:\n\n**DO**\n\n```erlang\nMRef = monitor(process, Process),\nProcess ! {self(), MRef, Request},\nreceive\n {MRef, Reply} ->\n erlang:demonitor(MRef, [flush]),\n handle_reply(Reply);\n {'DOWN', MRef, _, _, Reason} ->\n handle_error(Reason)\nend.\n```\n\nSince the compiler knows that the reference created by\n[`monitor/2`](`monitor/2`) cannot exist before the call (since it is a globally\nunique identifier), and that the `receive` only matches messages that contain\nsaid reference, it will tell the emulator to search only the messages that\narrived after the call to [`monitor/2`](`monitor/2`).\n\nThe above is a simple example where one is but guaranteed that the optimization\nwill take, but what about more complicated code?\n\n[](){: #recv_opt_info }","ref":"eff_guide_processes.html#receiving-messages"},{"type":"extras","title":"Option recv_opt_info - Processes","doc":"Use the `recv_opt_info` option to have the compiler print information about\nreceive optimizations. It can be given either to the compiler or `erlc`:\n\n```erlang\nerlc +recv_opt_info Mod.erl\n```\n\nor passed through an environment variable:\n\n```erlang\nexport ERL_COMPILER_OPTIONS=recv_opt_info\n```\n\nNotice that `recv_opt_info` is not meant to be a permanent option added to your\n`Makefile`s, because all messages that it generates cannot be eliminated.\nTherefore, passing the option through the environment is in most cases the most\npractical approach.\n\nThe warnings look as follows:\n\n```erlang\nefficiency_guide.erl:194: Warning: INFO: receive matches any message, this is always fast\nefficiency_guide.erl:200: Warning: NOT OPTIMIZED: all clauses do not match a suitable reference\nefficiency_guide.erl:206: Warning: OPTIMIZED: reference used to mark a message queue position\nefficiency_guide.erl:208: Warning: OPTIMIZED: all clauses match reference created by monitor/2 at efficiency_guide.erl:206\nefficiency_guide.erl:219: Warning: INFO: passing reference created by make_ref/0 at efficiency_guide.erl:218\nefficiency_guide.erl:222: Warning: OPTIMIZED: all clauses match reference in function parameter 1\n```\n\nTo make it clearer exactly what code the warnings refer to, the warnings in the\nfollowing examples are inserted as comments after the clause they refer to, for\nexample:\n\n```erlang\n%% DO\nsimple_receive() ->\n%% efficiency_guide.erl:194: Warning: INFO: not a selective receive, this is always fast\nreceive\n Message -> handle_msg(Message)\nend.\n\n%% DO NOT, unless Tag is known to be a suitable reference: see\n%% cross_function_receive/0 further down.\nselective_receive(Tag, Message) ->\n%% efficiency_guide.erl:200: Warning: NOT OPTIMIZED: all clauses do not match a suitable reference\nreceive\n {Tag, Message} -> handle_msg(Message)\nend.\n\n%% DO\noptimized_receive(Process, Request) ->\n%% efficiency_guide.erl:206: Warning: OPTIMIZED: reference used to mark a message queue position\n MRef = monitor(process, Process),\n Process ! {self(), MRef, Request},\n %% efficiency_guide.erl:208: Warning: OPTIMIZED: matches reference created by monitor/2 at efficiency_guide.erl:206\n receive\n {MRef, Reply} ->\n erlang:demonitor(MRef, [flush]),\n handle_reply(Reply);\n {'DOWN', MRef, _, _, Reason} ->\n handle_error(Reason)\n end.\n\n%% DO\ncross_function_receive() ->\n %% efficiency_guide.erl:218: Warning: OPTIMIZED: reference used to mark a message queue position\n Ref = make_ref(),\n %% efficiency_guide.erl:219: Warning: INFO: passing reference created by make_ref/0 at efficiency_guide.erl:218\n cross_function_receive(Ref).\n\ncross_function_receive(Ref) ->\n %% efficiency_guide.erl:222: Warning: OPTIMIZED: all clauses match reference in function parameter 1\n receive\n {Ref, Message} -> handle_msg(Message)\n end.\n```","ref":"eff_guide_processes.html#option-recv_opt_info"},{"type":"extras","title":"Literal Pool - Processes","doc":"Constant Erlang terms (hereafter called _literals_) are kept in _literal pools_;\neach loaded module has its own pool. The following function does not build the\ntuple every time it is called (only to have it discarded the next time the\ngarbage collector was run), but the tuple is located in the module's literal\npool:\n\n**DO**\n\n```erlang\ndays_in_month(M) ->\n element(M, {31,28,31,30,31,30,31,31,30,31,30,31}).\n```\n\nIf a literal, or a term that contains a literal, is inserted into an Ets table,\nit is _copied_. The reason is that the module containing the literal can be\nunloaded in the future.\n\nWhen a literal is sent to another process, it is _not_ copied. When a module\nholding a literal is unloaded, the literal will be copied to the heap of all\nprocesses that hold references to that literal.\n\nThere also exists a global literal pool that is managed by the\n`m:persistent_term` module.\n\nBy default, 1 GB of virtual address space is reserved for all literal pools (in\nBEAM code and persistent terms). The amount of virtual address space reserved\nfor literals can be changed by using the\n[`+MIscs option`](`e:erts:erts_alloc.md#MIscs`) when starting the emulator.\n\nHere is an example how the reserved virtual address space for literals can be\nraised to 2 GB (2048 MB):\n\n```text\nerl +MIscs 2048\n```","ref":"eff_guide_processes.html#literal-pool"},{"type":"extras","title":"Loss of Sharing - Processes","doc":"An Erlang term can have shared subterms. Here is a simple example:\n\n```erlang\n{SubTerm, SubTerm}\n```\n\nShared subterms are _not_ preserved in the following cases:\n\n- When a term is sent to another process\n- When a term is passed as the initial process arguments in the `spawn` call\n- When a term is stored in an Ets table\n\nThat is an optimization. Most applications do not send messages with shared\nsubterms.\n\nThe following example shows how a shared subterm can be created:\n\n```erlang\nkilo_byte() ->\n kilo_byte(10, [42]).\n\nkilo_byte(0, Acc) ->\n Acc;\nkilo_byte(N, Acc) ->\n kilo_byte(N-1, [Acc|Acc]).\n```\n\n`kilo_byte/1` creates a deep list. If [`list_to_binary/1`](`list_to_binary/1`)\nis called, the deep list can be converted to a binary of 1024 bytes:\n\n```text\n1> byte_size(list_to_binary(efficiency_guide:kilo_byte())).\n1024\n```\n\nUsing the `erts_debug:size/1` BIF, it can be seen that the deep list only\nrequires 22 words of heap space:\n\n```erlang\n2> erts_debug:size(efficiency_guide:kilo_byte()).\n22\n```\n\nUsing the `erts_debug:flat_size/1` BIF, the size of the deep list can be\ncalculated if sharing is ignored. It becomes the size of the list when it has\nbeen sent to another process or stored in an Ets table:\n\n```erlang\n3> erts_debug:flat_size(efficiency_guide:kilo_byte()).\n4094\n```\n\nIt can be verified that sharing will be lost if the data is inserted into an Ets\ntable:\n\n```erlang\n4> T = ets:new(tab, []).\n#Ref<0.1662103692.2407923716.214181>\n5> ets:insert(T, {key,efficiency_guide:kilo_byte()}).\ntrue\n6> erts_debug:size(element(2, hd(ets:lookup(T, key)))).\n4094\n7> erts_debug:flat_size(element(2, hd(ets:lookup(T, key)))).\n4094\n```\n\nWhen the data has passed through an Ets table, `erts_debug:size/1` and\n`erts_debug:flat_size/1` return the same value. Sharing has been lost.\n\nIt is possible to build an _experimental_ variant of the runtime system that\nwill preserve sharing when copying terms by giving the\n`--enable-sharing-preserving` option to the `configure` script.","ref":"eff_guide_processes.html#loss-of-sharing"},{"type":"extras","title":"SMP Run-Time System - Processes","doc":"The Erlang run-time system takes advantage of a multi-core or\nmulti-CPU computer by running several Erlang scheduler threads\n(typically, the same number of threads as the number of cores).\n\nTo gain performance from a multi-core computer, your application _must have more\nthan one runnable Erlang process_ most of the time. Otherwise, the Erlang\nemulator can still only run one Erlang process at the time.\n\nBenchmarks that appear to be concurrent are often sequential. For\nexample, the [EStone\nbenchmark](https://github.com/erlang/otp/blob/f164034e6fdab3316ae23c5d5bbaef258dd6d12c/erts/emulator/test/estone_SUITE.erl)\nis entirely sequential. So is the most common implementation of the\n\"ring benchmark\"; usually one process is active, while the others wait\nin a `receive` statement.","ref":"eff_guide_processes.html#smp-run-time-system"},{"type":"extras","title":"Drivers","doc":"\n# Drivers\n\nThis section provides a brief overview on how to write efficient drivers.\n\nIt is assumed that you have a good understanding of drivers.","ref":"drivers.html"},{"type":"extras","title":"Drivers and Concurrency - Drivers","doc":"The runtime system always takes a lock before running any code in a driver.\n\nBy default, that lock is at the driver level, that is, if several ports have\nbeen opened to the same driver, only code for one port at the same time can be\nrunning.\n\nA driver can be configured to have one lock for each port instead.\n\nIf a driver is used in a functional way (that is, holds no state, but only does\nsome heavy calculation and returns a result), several ports with registered\nnames can be opened beforehand, and the port to be used can be chosen based on\nthe scheduler ID as follows:\n\n```erlang\n-define(PORT_NAMES(),\n\t{some_driver_01, some_driver_02, some_driver_03, some_driver_04,\n\t some_driver_05, some_driver_06, some_driver_07, some_driver_08,\n\t some_driver_09, some_driver_10, some_driver_11, some_driver_12,\n\t some_driver_13, some_driver_14, some_driver_15, some_driver_16}).\n\nclient_port() ->\n element(erlang:system_info(scheduler_id) rem tuple_size(?PORT_NAMES()) + 1,\n\t ?PORT_NAMES()).\n```\n\nAs long as there are no more than 16 schedulers, there will never be any lock\ncontention on the port lock for the driver.","ref":"drivers.html#drivers-and-concurrency"},{"type":"extras","title":"Avoiding Copying Binaries When Calling a Driver - Drivers","doc":"There are basically two ways to avoid copying a binary that is sent to a driver:\n\n- If the `Data` argument for [`port_control/3`](`erlang:port_control/3`) is a\n binary, the driver will be passed a pointer to the contents of the binary and\n the binary will not be copied. If the `Data` argument is an iolist (list of\n binaries and lists), all binaries in the iolist will be copied.\n\n Therefore, if you want to send both a pre-existing binary and some extra data\n to a driver without copying the binary, you must call\n [`port_control/3`](`port_control/3`) twice; once with the binary and once with\n the extra data. However, that will only work if there is only one process\n communicating with the port (because otherwise another process can call the\n driver in-between the calls).\n\n- Implement an `outputv` callback (instead of an `output` callback) in the\n driver. If a driver has an `outputv` callback, refc binaries passed in an\n iolist in the `Data` argument for [`port_command/2`](`erlang:port_command/2`)\n will be passed as references to the driver.","ref":"drivers.html#avoiding-copying-binaries-when-calling-a-driver"},{"type":"extras","title":"Returning Small Binaries from a Driver - Drivers","doc":"The runtime system can represent binaries up to 64 bytes as heap binaries. They\nare always copied when sent in messages, but they require less memory if they\nare not sent to another process and garbage collection is cheaper.\n\nIf you know that the binaries you return are always small, you are advised to\nuse driver API calls that do not require a pre-allocated binary, for example,\n[`driver_output()`](`e:erts:erl_driver.md#driver_output`) or\n[`erl_drv_output_term()`](`e:erts:erl_driver.md#erl_drv_output_term`), using the\n`ERL_DRV_BUF2BINARY` format, to allow the runtime to construct a heap binary.","ref":"drivers.html#returning-small-binaries-from-a-driver"},{"type":"extras","title":"Returning Large Binaries without Copying from a Driver - Drivers","doc":"To avoid copying data when a large binary is sent or returned from the driver to\nan Erlang process, the driver must first allocate the binary and then send it to\nan Erlang process in some way.\n\nUse [`driver_alloc_binary()`](`e:erts:erl_driver.md#driver_alloc_binary`) to\nallocate a binary.\n\nThere are several ways to send a binary created with `driver_alloc_binary()`:\n\n- From the `control` callback, a binary can be returned if\n [`set_port_control_flags()`](`e:erts:erl_driver.md#set_port_control_flags`) has\n been called with the flag value `PORT_CONTROL_FLAG_BINARY`.\n- A single binary can be sent with\n [`driver_output_binary()`](`e:erts:erl_driver.md#driver_output_binary`).\n- Using [`erl_drv_output_term()`](`e:erts:erl_driver.md#erl_drv_output_term`) or\n [`erl_drv_send_term()`](`e:erts:erl_driver.md#erl_drv_send_term`), a binary can\n be included in an Erlang term.","ref":"drivers.html#returning-large-binaries-without-copying-from-a-driver"},{"type":"extras","title":"Memory Usage","doc":"\n# Memory Usage\n\nA good start when programming efficiently is to know how much memory different\ndata types and operations require. It is implementation-dependent how much\nmemory the Erlang data types and other items consume, but the following table\nshows some figures for the `erts-8.0` system in OTP 19.0.\n\nThe unit of measurement is memory words. There exists both a 32-bit and a 64-bit\nimplementation. A word is therefore 4 bytes or 8 bytes, respectively. The value\nfor a running system can be determined by calling\n[`erlang:system_info(wordsize)`](`m:erlang#system_info_wordsize`).\n\n\n \n \n Data Type \n Memory Size \n \n \n Small integer \n 1 word. \n On 32-bit architectures: -134217729 < i < 134217728\n (28 bits). \n On 64-bit architectures: -576460752303423489 < i <\n 576460752303423488 (60 bits). \n \n \n Large integer \n At least 3 words. \n \n \n Atom \n 1 word. \n An atom refers into an atom table, which also consumes memory.\n The atom text is stored once for each unique atom in this table.\n The atom table is not garbage-collected. \n \n \n Float \n On 32-bit architectures: 4 words. \n On 64-bit architectures: 3 words. \n \n \n Binary \n 3-6 words + data (can be shared). \n \n \n List \n 1 word + 1 word per element + the size of each element. \n \n \n String \n (is the same as a list of integers) \n 1 word + 2 words per character.\n \n \n \n Tuple \n 2 words + the size of each element. \n \n \n Small Map \n (up to 32 keys) \n 5 words + the size of all keys and values. \n \n \n Large Map \n \n (more than 32 keys) \n N x F words + the size of all keys and values. \n N is the number of keys in the Map. \n F is a sparsity factor that varies between 1.6 and 1.8\n due to the probabilistic nature of the internal HAMT data structure.\n \n \n \n Pid \n 1 word for a process identifier from the current local node. \n On 32-bit: 6 words for a process identifier from another node. \n On 64-bit: 5 words for a process identifier from another node. \n A process identifier refers into a process table and a node table,\n which also consumes memory. \n \n \n Port \n 1 word for a port identifier from the current local node. \n 5 words for a port identifier from another node. \n A port identifier refers into a port table and a node table,\n which also consumes memory. \n \n \n Reference \n On 32-bit architectures: 4-7 words for a reference from the\n current local node, and 7-9 words for a reference from another\n node. \n On 64-bit architectures: 4-6 words for a reference from the current\n local node, and 6-7 words for a reference from another node. \n A reference also refers into more or less emulator internal data\n structures which also consumes memory. At a minimum it\n refers into the node tables. \n \n \n Fun \n 9..13 words + the size of environment. \n A fun refers into a fun table, which also consumes memory. \n \n \n Ets table \n Initially 768 words + the size of each element (6 words +\n the size of Erlang data). The table grows when necessary. \n \n \n Erlang process \n 338 words when spawned, including a heap of 233 words. \n \n \n\n_Table: Memory Size of Different Data Types_","ref":"memory.html"},{"type":"extras","title":"System Limits","doc":"\n# System Limits\n\nThe Erlang language specification puts no limits on the number of processes,\nlength of atoms, and so on. However, for performance and memory saving reasons,\nthere will always be limits in a practical implementation of the Erlang language\nand execution environment.\n\n- **Processes** - The maximum number of simultaneously alive Erlang processes\nis by default 1,048,576. This limit can be configured at startup. For more information,\nsee the [`+P`](`e:erts:erl_cmd.md#max_processes`) command-line flag\nin the [`erl(1)`](`e:erts:erl_cmd.md`) manual page in ERTS.\n\n- [](){: #unique_pids } **Unique Local Process Identifiers on a\nRuntime System Instance ** - On a 64 bit system at most `2⁶⁰ - 1`\nunique process identifiers can be created, and on a 32 bit system at most `2²⁸ - 1`.\n\n- **Known nodes** - A remote node Y must be known to node X if there exists\nany pids, ports, references, or funs (Erlang data types) from Y on X, or if\nX and Y are connected. The maximum number of remote nodes simultaneously/ever known\nto a node is limited by the [maximum number of atoms](#atoms) available\nfor node names. All data concerning remote nodes, except for the node name atom,\nare garbage-collected.\n\n- **Connected nodes** - The maximum number of simultaneously connected nodes is\nlimited by either the maximum number of simultaneously known remote nodes,\n[the maximum number of (Erlang) ports](#ports) available,\nor [the maximum number of sockets](#files_sockets) available.\n\n- **Characters in an atom** - 255.\n\n- [](){: #atoms } **Atoms** - By default, the maximum number of atoms is 1,048,576.\nThis limit can be raised or lowered using the `+t` option.\n\n- **Elements in a tuple** - The maximum number of elements in a\ntuple is 16,777,215 (24-bit unsigned integer).\n\n- **Size of binary** - In the 32-bit run-time system for Erlang, 536,870,911 bytes\nis the largest binary that can be constructed or matched using the bit syntax.\nIn the 64-bit run-time system, the maximum size is 2,305,843,009,213,693,951 bytes.\nIf the limit is exceeded, bit syntax construction fails with a `system_limit`\nexception, while any attempt to match a binary that is too large\nfails. From Erlang/OTP 27, all other operations that create binaries (such as\n[`list_to_binary/1`](`list_to_binary/1`)) also enforces the same limit.\n\n- **Total amount of data allocated by an Erlang node** - The Erlang runtime system\ncan use the complete 32-bit (or 64-bit) address space, but the operating system\noften limits a single process to use less than that.\n\n- **Length of a node name** - An Erlang node name has the form `host@shortname`\nor `host@longname`. The node name is used as an atom within the system, so the\nmaximum size of 255 holds also for the node name.\n\n- [](){: #ports } **Open ports** - The maximum number of simultaneously open\nErlang ports is often by default 16,384. This limit can be configured at startup.\nFor more information, see the [`+Q`](`e:erts:erl_cmd.md#max_ports`) command-line\nflag in the [`erl(1)`](`e:erts:erl_cmd.md`) manual page in ERTS.\n\n- [](){: #unique_ports } **Unique Local Port Identifiers on a Runtime System Instance** -\nOn a 64 bit system at most `2⁶⁰ - 1` unique port identifiers can be created and\non a 32 bit system at most `2²⁸ - 1`.\n\n- [](){: #files_sockets } **Open files and sockets** - The maximum number of simultaneously\nopen files and sockets depends on [the maximum number of Erlang ports](#ports)\navailable, as well as on operating system-specific settings and limits.\n\n- **Number of arguments to a function or fun** - 255.\n\n- [](){: #unique_references } **Unique References on a Runtime System Instance** -\nEach scheduler thread has its own set of references, and all other threads have\na shared set of references. Each set of references consist of `2⁶⁴ - 1`unique\nreferences. That is, the total amount of unique references that can be produced\non a runtime system instance is `(NumSchedulers + 1) × (2⁶⁴ - 1)`. If a scheduler\nthread create a new reference each nano second, references will at earliest be\nreused after more than 584 years. That is, for the foreseeable future they are\nsufficiently unique.\n\n- [](){: #unique_integers } **Unique Integers on a Runtime System Instance** -\n There are two types of unique integers created by the\n [erlang:unique_integer/1](`erlang:unique_integer/1`) BIF:\n - Unique integers created **with** the `monotonic` modifier consist of\n a set of `2⁶⁴ - 1` unique integers.\n - Unique integers created **without** the `monotonic` modifier consist\n of a set of `2⁶⁴ - 1` unique integers per scheduler thread and a\n set of `2⁶⁴ - 1` unique integers shared by other threads. That is,\n the total amount of unique integers without the `monotonic`\n modifier is `(NumSchedulers + 1) × (2⁶⁴ - 1)`.\n\n If a unique integer is created each nano second, unique integers will be\n reused at earliest after more than 584 years. That is, for the foreseeable future\n they are sufficiently unique.","ref":"system_limits.html"},{"type":"extras","title":"Profiling","doc":"\n# Profiling","ref":"profiling.html"},{"type":"extras","title":"Never Guess About Performance Bottlenecks - Profiling","doc":"Even experienced software developers often guess wrong about where the\nperformance bottlenecks are in their programs. Therefore, profile your program\nto see where the performance bottlenecks are and concentrate on optimizing them.\n\nErlang/OTP contains several tools to help finding bottlenecks:\n\n- `m:tprof` is a tracing profiler that can measure call count, call time, or\n heap allocations per function call.\n- `m:fprof` provides the most detailed information about where the program time\n is spent, but it significantly slows down the program it profiles.\n- `m:dbg` is the generic erlang tracing frontend. By using the `timestamp` or\n `cpu_timestamp` options it can be used to time how long function calls in a\n live system take.\n- `m:lcnt` is used to find contention points in the Erlang Run-Time System's\n internal locking mechanisms. It is useful when looking for bottlenecks in\n interaction between process, port, ETS tables, and other entities that can be\n run in parallel.\n\nThe tools are further described in [Tools](profiling.md#profiling_tools).\n\nThere are also several open source tools outside of Erlang/OTP that can be used\nto help profiling. Some of them are:\n\n- [erlgrind](https://github.com/isacssouza/erlgrind) can be used to visualize\n fprof data in kcachegrind.\n- [eflame](https://github.com/proger/eflame) is an alternative to fprof that\n displays the profiling output as a flamegraph.\n- [recon](https://ferd.github.io/recon/index.html) is a collection of Erlang\n profiling and debugging tools. This tool comes with an accompanying E-book\n called [Erlang in Anger](https://www.erlang-in-anger.com/).\n- [perf](https://perf.wiki.kernel.org/index.php/Main_Page) is a sampling\n profiler for Linux that provides functionality similar to `fprof` but with\n much lower overhead. Profiling Erlang code is possible when the emulator has\n been started with the `+JPperf true` emulator flag, and is only available when\n the JIT is enabled.\n\n For more details about how to run `perf` see the\n [perf support](`e:erts:beamasm.md#linux-perf-support`) section in the BeamAsm\n internal documentation.","ref":"profiling.html#never-guess-about-performance-bottlenecks"},{"type":"extras","title":"Memory profiling - Profiling","doc":"```text\neheap_alloc: Cannot allocate 1234567890 bytes of memory (of type \"heap\").\n```\n\nThe above slogan is one of the more common reasons for Erlang to terminate. For\nunknown reasons the Erlang Run-Time System failed to allocate memory to use.\nWhen this happens a crash dump is generated that contains information about the\nstate of the system as it ran out of memory. Use\n[`crashdump_viewer`](`e:observer:cdv_cmd.md`) to get a view of the memory being\nused. Look for processes with large heaps or many messages, large ETS tables,\nand so on.\n\nWhen looking at memory usage in a running system the most basic function to get\ninformation from is [`erlang:memory()`](`erlang:memory/0`). It returns the\ncurrent memory usage of the system. `m:instrument` can be used to get a more\ndetailed breakdown of where memory is used.\n\nProcesses, ports, and ETS tables can then be inspected using their respective\ninformation functions, that is,\n[`process_info/2`](`m:erlang#process_info_memory`),\n[`erlang:port_info/2 `](`m:erlang#port_info_memory`), and `ets:info/1`.\n\nSometimes the system can enter a state where the reported memory from\n`erlang:memory(total)` is very different from the memory reported by\nthe operating system. One reason for that is internal fragmentation\nwithin the Erlang run-time system. Data about how memory is allocated\ncan be retrieved using\n[`erlang:system_info(allocator)`](`m:erlang#system_info_allocator`). The\ndata you get from that function is raw and hard to read.\n[recon_alloc](http://ferd.github.io/recon/recon_alloc.html) can\nbe used to extract useful information from system_info statistics\ncounters.","ref":"profiling.html#memory-profiling"},{"type":"extras","title":"Large Systems - Profiling","doc":"For a large system, it can be interesting to run profiling on a simulated and\nlimited scenario to start with. But bottlenecks have a tendency to appear or\ncause problems only when many things are going on at the same time, and when\nmany nodes are involved. Therefore, it is also desirable to run profiling in a\nsystem test plant on a real target system.\n\nFor a large system, you do not want to run the profiling tools on the whole\nsystem. Instead you want to concentrate on central processes and modules, which\naccount for a big part of the execution.\n\nThere are also some tools that can be used to get a view of the whole system\nwith more or less overhead.\n\n- `m:observer` is a GUI tool that can connect to remote nodes and display a\n variety of information about the running system.\n- `m:etop` is a command line tool that can connect to remote nodes and display\n information similar to what the UNIX tool top shows.\n- `m:msacc` allows the user to get a view of what the Erlang Run-Time system is\n spending its time doing. Has a very low overhead, which makes it useful to run\n in heavily loaded systems to get some idea of where to start doing more\n granular profiling.","ref":"profiling.html#large-systems"},{"type":"extras","title":"What to Look For - Profiling","doc":"When analyzing the result file from the profiling activity, look for functions\nthat are called many times and have a long \"own\" execution time (time excluding\ncalls to other functions). Functions that are called a lot of times can also be\ninteresting, as even small things can add up to quite a bit if repeated often.\nAlso ask yourself what you can do to reduce this time. The following are\nappropriate types of questions to ask yourself:\n\n- Is it possible to reduce the number of times the function is called?\n- Can any test be run less often if the order of tests is changed?\n- Can any redundant tests be removed?\n- Does any calculated expression give the same result each time?\n- Are there other ways to do this that are equivalent and more efficient?\n- Can another internal data representation be used to make things more\n efficient?\n\nThese questions are not always trivial to answer. Some benchmarks might be\nneeded to back up your theory and to avoid making things slower if your theory\nis wrong. For details, see [Benchmarking](benchmarking.md).","ref":"profiling.html#what-to-look-for"},{"type":"extras","title":"Tools - Profiling","doc":"[](){: #profiling_tools }","ref":"profiling.html#tools"},{"type":"extras","title":"fprof - Profiling","doc":"`fprof` measures the execution time for each function, both own time, that is,\nhow much time a function has used for its own execution, and accumulated time,\nthat is, including called functions. The values are displayed per process. You\nalso get to know how many times each function has been called.\n\n`fprof` is based on trace to file to minimize runtime performance impact. Using\n`fprof` is just a matter of calling a few library functions, see the `m:fprof`\nmanual page in Tools.","ref":"profiling.html#fprof"},{"type":"extras","title":"eprof - Profiling","doc":"`eprof` is based on the Erlang `trace_info` BIFs. `eprof` shows how much time\nhas been used by each process, and in which function calls this time has been\nspent. Time is shown as a percentage of total time and absolute time. For more\ninformation, see the `m:eprof` manual page in Tools.","ref":"profiling.html#eprof"},{"type":"extras","title":"cprof - Profiling","doc":"`cprof` is something in between `fprof` and `cover` regarding features. It\ncounts how many times each function is called when the program is run, on a per\nmodule basis. `cprof` has a low performance degradation effect (compared with\n`fprof`) and does not need to recompile any modules to profile (compared with\n`cover`). For more information, see the `m:cprof` manual page in Tools.","ref":"profiling.html#cprof"},{"type":"extras","title":"Tool Summary - Profiling","doc":"| _Tool_ | _Results_ | _Size of Result_ | _Effects on Program Execution Time_ | _Records Number of Calls_ | _Records Execution Time_ | _Records Called by_ | _Records Garbage Collection_ |\n| ------- | ----------------------------------- | ---------------- | ----------------------------------- | ------------------------- | ------------------------ | ------------------- | ---------------------------- |\n| `fprof` | Per process to screen/file | Large | Significant slowdown | Yes | Total and own | Yes | Yes |\n| `eprof` | Per process/function to screen/file | Medium | Small slowdown | Yes | Only total | No | No |\n| `cprof` | Per module to caller | Small | Small slowdown | Yes | No | No | No |\n\n_Table: Tool Summary_","ref":"profiling.html#tool-summary"},{"type":"extras","title":"dbg - Profiling","doc":"`dbg` is a generic Erlang trace tool. By using the `timestamp` or\n`cpu_timestamp` options it can be used as a precision instrument to profile how\nlong time a function call takes for a specific process. This can be very useful\nwhen trying to understand where time is spent in a heavily loaded system as it\nis possible to limit the scope of what is profiled to be very small. For more\ninformation, see the `m:dbg` manual page in Runtime Tools.","ref":"profiling.html#dbg"},{"type":"extras","title":"lcnt - Profiling","doc":"`lcnt` is used to profile interactions in between entities that run in parallel.\nFor example if you have a process that all other processes in the system needs\nto interact with (maybe it has some global configuration), then `lcnt` can be\nused to figure out if the interaction with that process is a problem.\n\nIn the Erlang Run-time System entities are only run in parallel when there are\nmultiple schedulers. Therefore `lcnt` will show more contention points (and thus\nbe more useful) on systems using many schedulers on many cores.\n\nFor more information, see the `m:lcnt` manual page in Tools.","ref":"profiling.html#lcnt"},{"type":"extras","title":"Benchmarking","doc":"\n# Benchmarking\n\nThe main purpose of benchmarking is to find out which implementation of a given\nalgorithm or function is the fastest. Benchmarking is far from an exact science.\nToday's operating systems generally run background tasks that are difficult to\nturn off. Caches and multiple CPU cores do not facilitate benchmarking. It would\nbe best to run UNIX computers in single-user mode when benchmarking, but that is\ninconvenient to say the least for casual testing.","ref":"benchmarking.html"},{"type":"extras","title":"Using erlperf - Benchmarking","doc":"A useful tool for benchmarking is [erlperf](https://github.com/max-au/erlperf)\n([documentation](https://hexdocs.pm/erlperf/erlperf.html)).\nIt makes it simple to find out which code is faster. For example, here is how\ntwo methods of generating random bytes can be compared:\n\n```text\n% erlperf 'rand:bytes(2).' 'crypto:strong_rand_bytes(2).'\nCode || QPS Time Rel\nrand:bytes(2). 1 7784 Ki 128 ns 100%\ncrypto:strong_rand_bytes(2). 1 2286 Ki 437 ns 29%\n```\n\nFrom the **Time** column we can read out that on average a call to\n[`rand:bytes(2)`](`rand:bytes/1`) executes in 128 nano seconds, while\na call to\n[`crypto:strong_rand_bytes(2)`](`crypto:strong_rand_bytes/1`) executes\nin 437 nano seconds.\n\nFrom the **QPS** column we can read out how many calls that can be\nmade in a second. For `rand:bytes(2)`, it is 7,784,000 calls per second.\n\nThe **Rel** column shows the relative differences, with `100%` indicating\nthe fastest code.\n\nWhen generating two random bytes at the time, `rand:bytes/1` is more\nthan three times faster than `crypto:strong_rand_bytes/1`. Assuming\nthat we really need strong random numbers and we need to get them as\nfast as possible, what can we do? One way could be to generate more\nthan two bytes at the time.\n\n```text\n% erlperf 'rand:bytes(100).' 'crypto:strong_rand_bytes(100).'\nCode || QPS Time Rel\nrand:bytes(100). 1 2124 Ki 470 ns 100%\ncrypto:strong_rand_bytes(100). 1 1915 Ki 522 ns 90%\n```\n\n`rand:bytes/1` is still faster when we generate 100 bytes at the time,\nbut the relative difference is smaller.\n\n```\n% erlperf 'rand:bytes(1000).' 'crypto:strong_rand_bytes(1000).'\nCode || QPS Time Rel\ncrypto:strong_rand_bytes(1000). 1 1518 Ki 658 ns 100%\nrand:bytes(1000). 1 284 Ki 3521 ns 19%\n```\n\nWhen we generate 1000 bytes at the time, `crypto:strong_rand_bytes/1` is\nnow the fastest.","ref":"benchmarking.html#using-erlperf"},{"type":"extras","title":"Benchmarking using Erlang/OTP functionality - Benchmarking","doc":"Benchmarks can measure wall-clock time or CPU time.\n\n- `timer:tc/3` measures wall-clock time. The advantage with wall-clock time is\n that I/O, swapping, and other activities in the operating system kernel are\n included in the measurements. The disadvantage is that the measurements often\n vary a lot. Usually it is best to run the benchmark several times and note\n the shortest time, which is the minimum time that is possible to achieve\n under the best of circumstances.\n\n- [`statistics(runtime)`](`erlang:statistics/1`) measures CPU time spent\n in the Erlang virtual machine. The advantage with CPU time is that\n the results are more consistent from run to run. The disadvantage is\n that the time spent in the operating system kernel (such as swapping\n and I/O) is not included. Therefore, measuring CPU time is\n misleading if any I/O (file or socket) is involved.\n\nIt is probably a good idea to do both wall-clock measurements and CPU time\nmeasurements.\n\nSome final advice:\n\n- The granularity of both measurement types can be high. Therefore, ensure that\n each individual measurement lasts for at least several seconds.\n- To make the test fair, each new test run is to run in its own, newly created\n Erlang process. Otherwise, if all tests run in the same process, the later\n tests start out with larger heap sizes and therefore probably do fewer garbage\n collections. Also consider restarting the Erlang emulator between each test.\n- Do not assume that the fastest implementation of a given algorithm on computer\n architecture X is also the fastest on computer architecture Y.","ref":"benchmarking.html#benchmarking-using-erlang-otp-functionality"},{"type":"extras","title":"Introduction","doc":"\n# Introduction\n\n[](){: #interoperability-tutorial }\n\nThis section informs on interoperability, that is, information exchange, between\nErlang and other programming languages. The included examples mainly treat\ninteroperability between Erlang and C.","ref":"tutorial.html"},{"type":"extras","title":"Purpose - Introduction","doc":"The purpose of this tutorial is to describe different interoperability\nmechanisms that can be used when integrating a program written in Erlang with a\nprogram written in another programming language, from the Erlang programmer's\nperspective.","ref":"tutorial.html#purpose"},{"type":"extras","title":"Prerequisites - Introduction","doc":"It is assumed that you are a skilled Erlang programmer, familiar with concepts\nsuch as Erlang data types, processes, messages, and error handling.\n\nTo illustrate the interoperability principles, C programs running in a UNIX\nenvironment have been used. It is assumed that you have enough knowledge to\napply these principles to the relevant programming languages and platforms.\n\n> #### Note {: .info }\n>\n> For readability, the example code is kept as simple as possible. For example,\n> it does not include error handling, which might be vital in a real-life\n> system.","ref":"tutorial.html#prerequisites"},{"type":"extras","title":"Overview","doc":"\n# Overview","ref":"overview.html"},{"type":"extras","title":"Built-In Mechanisms - Overview","doc":"Two interoperability mechanisms are built into the Erlang runtime system,\n_distributed Erlang_, _ports_, and _nifs_. A variation of ports is _linked-in drivers_.","ref":"overview.html#built-in-mechanisms"},{"type":"extras","title":"Distributed Erlang - Overview","doc":"An Erlang runtime system is made a distributed Erlang node by giving it a name.\nA distributed Erlang node can connect to, and monitor, other nodes. It can also\nspawn processes at other nodes. Message passing and error handling between\nprocesses at different nodes are transparent. A number of useful STDLIB modules\nare available in a distributed Erlang system. For example, `m:global`, which\nprovides global name registration. The distribution mechanism is implemented\nusing TCP/IP sockets.\n\n_When to use:_ Distributed Erlang is primarily used for Erlang-Erlang\ncommunication. It can also be used for communication between Erlang and C, if\nthe C program is implemented as a C node, see\n[C and Java Libraries](overview.md#c-nodes).\n\n_Where to read more:_ Distributed Erlang and some distributed programming\ntechniques are described in the Erlang book.\n\nFor more information, see\n[Distributed Programming](`e:system:conc_prog.md#distributed-programming`).\n\nRelevant manual pages are the following:\n\n- `m:erlang` manual page in ERTS (describes the BIFs)\n- `m:global` manual page in Kernel\n- `m:net_adm` manual page in Kernel\n- `m:pg` manual page in Kernel\n- `m:rpc` manual page in Kernel\n- `m:pool` manual page in STDLIB\n- `m:slave` manual page in STDLIB","ref":"overview.html#distributed-erlang"},{"type":"extras","title":"Ports and Linked-In Drivers - Overview","doc":"Ports provide the basic mechanism for communication with the external world,\nfrom Erlang's point of view. The ports provide a byte-oriented interface to an\nexternal program. When a port is created, Erlang can communicate with it by\nsending and receiving [lists of bytes](`t:iolist/0`) or [binaries](`t:binary/0`) (not Erlang terms).\nThis means that the programmer might have to invent a suitable encoding and decoding scheme.\n\nThe implementation of the port mechanism depends on the platform. For UNIX,\npipes are used and the external program is assumed to read from standard input\nand write to standard output. The external program can be written in any\nprogramming language as long as it can handle the interprocess communication\nmechanism with which the port is implemented.\n\nThe external program resides in another OS process than the Erlang runtime\nsystem. In some cases this is not acceptable. Consider, for example, drivers\nwith very hard time requirements. It is therefore possible to write a program in\nC according to certain principles, and dynamically link it to the Erlang runtime\nsystem. This is called a _linked-in driver_.\n\n_When to use:_ Ports can be used for all kinds of interoperability situations\nwhere the Erlang program and the other program runs on the same machine.\nProgramming is fairly straight-forward.\n\nLinked-in drivers involves writing certain call-back functions in C. This\nrequires very good skills as the code is linked to the Erlang runtime system.\nIt is recommended to use [NIFs](#native-implemented-functions-nifs)\ninstead of linked-in drivers as they provide a richer feature set and can use\n[dirty schedulers for lengthy work](`e:erts:erl_nif.md#dirty_nifs`).\n\n> #### Warning {: .warning }\n>\n> A faulty linked-in driver causes the entire Erlang runtime system to leak\n> memory, hang, or crash.\n\n_Where to read more:_ Ports are described in section \"Miscellaneous Items\" of\nthe Erlang book. Linked-in drivers are described in Appendix E.\n\nThe BIF [`open_port/2`](`open_port/2`) is documented in the `m:erlang` manual\npage in ERTS.\n\nFor linked-in drivers, the programmer needs to read the `m:erl_ddll` manual page\nin Kernel.\n\n_Examples:_ Port example in [Ports](c_port.md).","ref":"overview.html#ports-and-linked-in-drivers"},{"type":"extras","title":"Native implemented functions (Nifs) - Overview","doc":"NIFs provide an alternative to a port using linked-in drivers to link C code into\nthe Erlang runtime system. NIFs make it possible to provide C implementation of\nnormal Erlang functions when interacting with the OS or some other external library.\n\n> #### Warning {: .warning }\n>\n> A faulty NIFs causes the entire Erlang runtime system to leak\n> memory, hang, crash, or leak sensitive information.\n\n_When to use:_ Since a faulty NIF can cause many different problems related to both\nstability and security it is recommended to use an external Port if possible. If the\noverhead is not acceptable then a NIF is a good solution for interacting with any\nnative code, be it in C, C++ or Rust.\n\n_Where to read more:_ NIFs are described in [API functions for an Erlang NIF library](`e:erts:erl_nif.md`).\n\n_Examples:_ Port example in [NIFs](nif.md).","ref":"overview.html#native-implemented-functions-nifs"},{"type":"extras","title":"C and Java Libraries - Overview","doc":"","ref":"overview.html#c-and-java-libraries"},{"type":"extras","title":"Erl_Interface - Overview","doc":"The program at the other side of a port is often a C program. To help the C\nprogrammer, the Erl_Interface library has been developed\n\nThe Erlang external term format is a representation of an Erlang term as a\nsequence of bytes, that is, a binary. Conversion between the two representations\nis done using the following BIFs:\n\n```text\nBinary = term_to_binary(Term)\nTerm = binary_to_term(Binary)\n```\n\nA port can be set to use binaries instead of lists of bytes. It is then not\nnecessary to invent any encoding/decoding scheme. Erl_Interface functions are\nused for unpacking the binary and convert it into a struct similar to an Erlang\nterm. Such a struct can be manipulated in different ways, be converted to the\nErlang external format, and sent to Erlang.\n\n_When to use:_ In C code, in conjunction with Erlang binaries.\n\n_Where to read more:_ See the Erlang Interface User's Guide, Command Reference,\nand Library Reference. In Erlang/OTP R5B, and earlier versions, the information\nis part of the Kernel application.\n\n_Examples:_ Erl_Interface example in [Erl_Interface](erl_interface.md).","ref":"overview.html#erl_interface"},{"type":"extras","title":"C Nodes - Overview","doc":"A C program that uses the Erl_Interface functions for setting up a connection\nto, and communicating with, a distributed Erlang node is called a _C node_, or a\n_hidden node_. The main advantage with a C node is that the communication from\nthe Erlang programmer's perspective is extremely easy, as the C program behaves\nas a distributed Erlang node.\n\n_When to use:_ C nodes can typically be used on device processors (as opposed to\ncontrol processors) where C is a better choice than Erlang due to memory\nlimitations or application characteristics, or both.\n\n_Where to read more:_ See the `ei_connect` part of the\n[Erl_Interface](erl_interface.md) documentation. The programmer also needs to be\nfamiliar with TCP/IP sockets, see Sockets in\n[Standard Protocols](overview.md#sockets) and Distributed Erlang in\n[Built-In Mechanisms](overview.md#distributed-erlang).\n\n_Example:_ C node example in [C Nodes](cnode.md).","ref":"overview.html#c-nodes"},{"type":"extras","title":"Jinterface - Overview","doc":"In Erlang/OTP R6B, a library similar to Erl_Interface for Java was added called\n_jinterface_. It provides a tool for Java programs to communicate with Erlang\nnodes.","ref":"overview.html#jinterface"},{"type":"extras","title":"Standard Protocols - Overview","doc":"Sometimes communication between an Erlang program and another program using a\nstandard protocol is desirable. Erlang/OTP currently supports TCP/IP and UDP\n_sockets_: as follows:\n\n- SNMP\n- HTTP\n- IIOP (CORBA)\n\nUsing one of the latter three requires good knowledge about the protocol and is\nnot covered by this tutorial. See the SNMP, Inets, and Orber applications,\nrespectively.","ref":"overview.html#standard-protocols"},{"type":"extras","title":"Sockets - Overview","doc":"Simply put, connection-oriented socket communication (TCP/IP) consists of an\ninitiator socket (\"server\") started at a certain host with a certain port\nnumber. A connector socket (\"client\"), which is aware of the initiator host name\nand port number, can connect to it and data can be sent between them.\n\nConnection-less socket communication (UDP) consists of an initiator socket at a\ncertain host with a certain port number and a connector socket sending data to\nit.\n\nFor a detailed description of the socket concept, refer to a suitable book about\nnetwork programming. A suggestion is _UNIX Network Programming, Volume 1:\nNetworking APIs - Sockets and XTI_ by W. Richard Stevens, ISBN: 013490012X.\n\nIn Erlang/OTP, access to TCP/IP and UDP sockets is provided by the modules\n`gen_tcp` and `gen_udp` in Kernel. Both are easy to use and do not require\ndetailed knowledge about the socket concept.\n\n_When to use:_ For programs running on the same or on another machine than the\nErlang program.\n\n_Where to read more:_ See the `m:gen_tcp` and the `m:gen_udp` manual pages in\nKernel.","ref":"overview.html#sockets"},{"type":"extras","title":"IC and CORBA - Overview","doc":"IC (Erlang IDL Compiler) is an interface generator that, given an IDL interface\nspecification, automatically generates stub code in Erlang, C, or Java. See the\nIC User's Guide and IC Reference Manual.\n\nFor details, see the [corba repository](https://github.com/erlang/corba).","ref":"overview.html#ic-and-corba"},{"type":"extras","title":"Problem Example","doc":"\n# Problem Example","ref":"example.html"},{"type":"extras","title":"Description - Problem Example","doc":"A common interoperability situation is when you want to incorporate a piece of\ncode, solving a complex problem, in your Erlang program. Suppose for example,\nthat you have the following C functions that you would like to call from Erlang:\n\n```c\n/* complex.c */\n\nint foo(int x) {\n return x+1;\n}\n\nint bar(int y) {\n return y*2;\n}\n```\n\nThe functions are deliberately kept as simple as possible, for readability\nreasons.\n\nFrom an Erlang perspective, it is preferable to be able to call `foo` and `bar`\nwithout having to bother about that they are C functions:\n\n```erlang\n% Erlang code\n...\nRes = complex:foo(X),\n...\n```\n\nHere, the communication with C is hidden in the implementation of `complex.erl`.\nIn the following sections, it is shown how this module can be implemented using\nthe different interoperability mechanisms.","ref":"example.html#description"},{"type":"extras","title":"Ports","doc":"\n# Ports\n\nThis section outlines an example of how to solve the example problem in the\n[previous section](example.md) by using a port.\n\nThe scenario is illustrated in the following figure:\n\n```mermaid\n---\ntitle: Port Communication\n---\nflowchart LR\n subgraph Legend\n direction LR\n\n os[OS Process]\n erl([Erlang Process])\n end\n\n subgraph ERTS\n direction LR\n\n port{Port} --> erlProc\n erlProc([Connected process]) --> port\n end\n\n port --> proc[External Program]\n proc --> port\n```","ref":"c_port.html"},{"type":"extras","title":"Erlang Program - Ports","doc":"All communication between Erlang and C must be established by creating the port.\nThe Erlang process that creates a port is said to be _the connected process_ of\nthe port. All communication to and from the port must go through the connected\nprocess. If the connected process terminates, the port also terminates (and the\nexternal program, if it is written properly).\n\nThe port is created using the BIF [`open_port/2`](`open_port/2`) with\n`{spawn,ExtPrg}` as the first argument. The string `ExtPrg` is the name of the\nexternal program, including any command line arguments. The second argument is a\nlist of options, in this case only `{packet,2}`. This option says that a 2 byte\nlength indicator is to be used to simplify the communication between C and\nErlang. The Erlang port automatically adds the length indicator, but this must\nbe done explicitly in the external C program.\n\nThe process is also set to trap exits, which enables detection of failure of the\nexternal program:\n\n```erlang\n-module(complex1).\n-export([start/1, init/1]).\n\nstart(ExtPrg) ->\n spawn(?MODULE, init, [ExtPrg]).\n\ninit(ExtPrg) ->\n register(complex, self()),\n process_flag(trap_exit, true),\n Port = open_port({spawn, ExtPrg}, [{packet, 2}]),\n loop(Port).\n```\n\nNow `complex1:foo/1` and `complex1:bar/1` can be implemented. Both send a\nmessage to the `complex` process and receive the following replies:\n\n```erlang\nfoo(X) ->\n call_port({foo, X}).\nbar(Y) ->\n call_port({bar, Y}).\n\ncall_port(Msg) ->\n complex ! {call, self(), Msg},\n receive\n {complex, Result} ->\n Result\n end.\n```\n\nThe `complex` process does the following:\n\n- Encodes the message into a sequence of bytes.\n- Sends it to the port.\n- Waits for a reply.\n- Decodes the reply.\n- Sends it back to the caller:\n\n```erlang\nloop(Port) ->\n receive\n {call, Caller, Msg} ->\n Port ! {self(), {command, encode(Msg)}},\n receive\n {Port, {data, Data}} ->\n Caller ! {complex, decode(Data)}\n end,\n loop(Port)\n end.\n```\n\nAssuming that both the arguments and the results from the C functions are less\nthan 256, a simple encoding/decoding scheme is employed. In this scheme, `foo`\nis represented by byte 1, `bar` is represented by 2, and the argument/result is\nrepresented by a single byte as well:\n\n```erlang\nencode({foo, X}) -> [1, X];\nencode({bar, Y}) -> [2, Y].\n\ndecode([Int]) -> Int.\n```\n\nThe resulting Erlang program, including functionality for stopping the port and\ndetecting port failures, is as follows:\n\n```erlang\n-module(complex1).\n-export([start/1, stop/0, init/1]).\n-export([foo/1, bar/1]).\n\nstart(ExtPrg) ->\n spawn(?MODULE, init, [ExtPrg]).\nstop() ->\n complex ! stop.\n\nfoo(X) ->\n call_port({foo, X}).\nbar(Y) ->\n call_port({bar, Y}).\n\ncall_port(Msg) ->\n complex ! {call, self(), Msg},\n receive\n\t{complex, Result} ->\n\t Result\n end.\n\ninit(ExtPrg) ->\n register(complex, self()),\n process_flag(trap_exit, true),\n Port = open_port({spawn, ExtPrg}, [{packet, 2}]),\n loop(Port).\n\nloop(Port) ->\n receive\n\t{call, Caller, Msg} ->\n\t Port ! {self(), {command, encode(Msg)}},\n\t receive\n\t\t{Port, {data, Data}} ->\n\t\t Caller ! {complex, decode(Data)}\n\t end,\n\t loop(Port);\n\tstop ->\n\t Port ! {self(), close},\n\t receive\n\t\t{Port, closed} ->\n\t\t exit(normal)\n\t end;\n\t{'EXIT', Port, Reason} ->\n\t exit(port_terminated)\n end.\n\nencode({foo, X}) -> [1, X];\nencode({bar, Y}) -> [2, Y].\n\ndecode([Int]) -> Int.\n```","ref":"c_port.html#erlang-program"},{"type":"extras","title":"C Program - Ports","doc":"On the C side, it is necessary to write functions for receiving and sending data\nwith 2 byte length indicators from/to Erlang. By default, the C program is to\nread from standard input (file descriptor 0) and write to standard output (file\ndescriptor 1). Examples of such functions, `read_cmd/1` and `write_cmd/2`,\nfollows:\n\n```c\n/* erl_comm.c */\n\n#include \n#include \n\ntypedef unsigned char byte;\n\nint read_exact(byte *buf, int len)\n{\n int i, got=0;\n\n do {\n if ((i = read(0, buf+got, len-got)) <= 0){\n return(i);\n }\n got += i;\n } while (got > 8) & 0xff;\n write_exact(&li, 1);\n\n li = len & 0xff;\n write_exact(&li, 1);\n\n return write_exact(buf, len);\n}\n```\n\nNotice that `stdin` and `stdout` are for buffered input/output and must _not_ be\nused for the communication with Erlang.\n\nIn the `main` function, the C program is to listen for a message from Erlang\nand, according to the selected encoding/decoding scheme, use the first byte to\ndetermine which function to call and the second byte as argument to the\nfunction. The result of calling the function is then to be sent back to Erlang:\n\n```c\n/* port.c */\n\ntypedef unsigned char byte;\n\nint main() {\n int fn, arg, res;\n byte buf[100];\n\n while (read_cmd(buf) > 0) {\n fn = buf[0];\n arg = buf[1];\n\n if (fn == 1) {\n res = foo(arg);\n } else if (fn == 2) {\n res = bar(arg);\n }\n\n buf[0] = res;\n write_cmd(buf, 1);\n }\n}\n```\n\nNotice that the C program is in a `while`\\-loop, checking for the return value\nof `read_cmd/1`. This is because the C program must detect when the port closes\nand terminates.","ref":"c_port.html#c-program"},{"type":"extras","title":"Running the Example - Ports","doc":"_Step 1._ Compile the C code:\n\n```text\n$ gcc -o extprg complex.c erl_comm.c port.c\n```\n\n_Step 2._ Start Erlang and compile the Erlang code:\n\n```erlang\n$ erl\nErlang/OTP 26 [erts-14.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]\n\nEshell V14.2 (press Ctrl+G to abort, type help(). for help)\n1> c(complex1).\n{ok,complex1}\n```\n\n_Step 3._ Run the example:\n\n```erlang\n2> complex1:start(\"./extprg\").\n<0.34.0>\n3> complex1:foo(3).\n4\n4> complex1:bar(5).\n10\n5> complex1:stop().\nstop\n```","ref":"c_port.html#running-the-example"},{"type":"extras","title":"Erl_Interface","doc":"\n# Erl_Interface\n\nThis section outlines an example of how to solve the example problem in\n[Problem Example](example.md) by using a port and Erl_Interface. It is necessary\nto read the port example in [Ports](c_port.md) before reading this section.","ref":"erl_interface.html"},{"type":"extras","title":"Erlang Program - Erl_Interface","doc":"The following example shows an Erlang program communicating with a C program\nover a plain port with home made encoding:\n\n```erlang\n-module(complex1).\n-export([start/1, stop/0, init/1]).\n-export([foo/1, bar/1]).\n\nstart(ExtPrg) ->\n spawn(?MODULE, init, [ExtPrg]).\nstop() ->\n complex ! stop.\n\nfoo(X) ->\n call_port({foo, X}).\nbar(Y) ->\n call_port({bar, Y}).\n\ncall_port(Msg) ->\n complex ! {call, self(), Msg},\n receive\n\t{complex, Result} ->\n\t Result\n end.\n\ninit(ExtPrg) ->\n register(complex, self()),\n process_flag(trap_exit, true),\n Port = open_port({spawn, ExtPrg}, [{packet, 2}]),\n loop(Port).\n\nloop(Port) ->\n receive\n\t{call, Caller, Msg} ->\n\t Port ! {self(), {command, encode(Msg)}},\n\t receive\n\t\t{Port, {data, Data}} ->\n\t\t Caller ! {complex, decode(Data)}\n\t end,\n\t loop(Port);\n\tstop ->\n\t Port ! {self(), close},\n\t receive\n\t\t{Port, closed} ->\n\t\t exit(normal)\n\t end;\n\t{'EXIT', Port, Reason} ->\n\t exit(port_terminated)\n end.\n\nencode({foo, X}) -> [1, X];\nencode({bar, Y}) -> [2, Y].\n\ndecode([Int]) -> Int.\n```\n\nThere are two differences when using Erl_Interface on the C side compared to the\nexample in [Ports](c_port.md), using only the plain port:\n\n- As Erl_Interface operates on the Erlang external term format, the port must be\n set to use binaries.\n- Instead of inventing an encoding/decoding scheme, the\n [`term_to_binary/1`](`term_to_binary/1`) and\n [`binary_to_term/1`](`binary_to_term/1`) BIFs are to be used.\n\nThat is:\n\n```erlang\nopen_port({spawn, ExtPrg}, [{packet, 2}])\n```\n\nis replaced with:\n\n```erlang\nopen_port({spawn, ExtPrg}, [{packet, 2}, binary])\n```\n\nAnd:\n\n```erlang\nPort ! {self(), {command, encode(Msg)}},\nreceive\n {Port, {data, Data}} ->\n Caller ! {complex, decode(Data)}\nend\n```\n\nis replaced with:\n\n```erlang\nPort ! {self(), {command, term_to_binary(Msg)}},\nreceive\n {Port, {data, Data}} ->\n Caller ! {complex, binary_to_term(Data)}\nend\n```\n\nThe resulting Erlang program is as follows:\n\n```erlang\n-module(complex2).\n-export([start/1, stop/0, init/1]).\n-export([foo/1, bar/1]).\n\nstart(ExtPrg) ->\n spawn(?MODULE, init, [ExtPrg]).\nstop() ->\n complex ! stop.\n\nfoo(X) ->\n call_port({foo, X}).\nbar(Y) ->\n call_port({bar, Y}).\n\ncall_port(Msg) ->\n complex ! {call, self(), Msg},\n receive\n\t{complex, Result} ->\n\t Result\n end.\n\ninit(ExtPrg) ->\n register(complex, self()),\n process_flag(trap_exit, true),\n Port = open_port({spawn, ExtPrg}, [{packet, 2}, binary]),\n loop(Port).\n\nloop(Port) ->\n receive\n\t{call, Caller, Msg} ->\n\t Port ! {self(), {command, term_to_binary(Msg)}},\n\t receive\n\t\t{Port, {data, Data}} ->\n\t\t Caller ! {complex, binary_to_term(Data)}\n\t end,\n\t loop(Port);\n\tstop ->\n\t Port ! {self(), close},\n\t receive\n\t\t{Port, closed} ->\n\t\t exit(normal)\n\t end;\n\t{'EXIT', Port, Reason} ->\n\t exit(port_terminated)\n end.\n```\n\nNotice that calling `complex2:foo/1` and `complex2:bar/1` results in the tuple\n`{foo,X}` or `{bar,Y}` being sent to the `complex` process, which codes them as\nbinaries and sends them to the port. This means that the C program must be able\nto handle these two tuples.","ref":"erl_interface.html#erlang-program"},{"type":"extras","title":"C Program - Erl_Interface","doc":"The following example shows a C program communicating with an Erlang program\nover a plain port with the Erlang external term format encoding:\n\n```c\n/* ei.c */\n\n#include \"ei.h\"\n#include \n#include \n#include \n\ntypedef unsigned char byte;\n\nint read_cmd(byte *buf);\nint write_cmd(byte *buf, int len);\nint foo(int x);\nint bar(int y);\n\nstatic void fail(int place) {\n fprintf(stderr, \"Something went wrong %d\\n\", place);\n exit(1);\n}\n\nint main() {\n byte buf[100];\n int index = 0;\n int version = 0;\n int arity = 0;\n char atom[128];\n long in = 0;\n int res = 0;\n ei_x_buff res_buf;\n ei_init();\n while (read_cmd(buf) > 0) {\n if (ei_decode_version(buf, &index, &version) != 0)\n fail(1);\n if (ei_decode_tuple_header(buf, &index, &arity) != 0)\n fail(2);\n if (arity != 2)\n fail(3);\n if (ei_decode_atom(buf, &index, atom) != 0)\n fail(4);\n if (ei_decode_long(buf, &index, &in) != 0)\n fail(5);\n if (strncmp(atom, \"foo\", 3) == 0) {\n res = foo((int)in);\n } else if (strncmp(atom, \"bar\", 3) == 0) {\n res = bar((int)in);\n }\n if (ei_x_new_with_version(&res_buf) != 0)\n fail(6);\n if (ei_x_encode_long(&res_buf, res) != 0)\n fail(7);\n write_cmd(res_buf.buff, res_buf.index);\n\n if (ei_x_free(&res_buf) != 0)\n fail(8);\n index = 0;\n }\n}\n```\n\nThe following functions, `read_cmd()` and `write_cmd()`, from the `erl_comm.c`\nexample in [Ports](c_port.md) can still be used for reading from and writing to\nthe port:\n\n```c\n/* erl_comm.c */\n\n#include \n#include \n\ntypedef unsigned char byte;\n\nint read_exact(byte *buf, int len)\n{\n int i, got=0;\n\n do {\n if ((i = read(0, buf+got, len-got)) <= 0){\n return(i);\n }\n got += i;\n } while (got > 8) & 0xff;\n write_exact(&li, 1);\n\n li = len & 0xff;\n write_exact(&li, 1);\n\n return write_exact(buf, len);\n}\n```","ref":"erl_interface.html#c-program"},{"type":"extras","title":"Running the Example - Erl_Interface","doc":"_Step 1._ Compile the C code. This provides the paths to the include file\n`ei.h`, and also to the library `ei`:\n\n```text\n$ gcc -o extprg -I/usr/local/otp/lib/erl_interface-3.9.2/include \\\n -L/usr/local/otp/lib/erl_interface-3.9.2/lib \\\n complex.c erl_comm.c ei.c -lei -lpthread\n```\n\nIn Erlang/OTP R5B and later versions of OTP, the `include` and `lib` directories\nare situated under `$OTPROOT/lib/erl_interface-VSN`, where `$OTPROOT` is the\nroot directory of the OTP installation (`/usr/local/otp` in the recent example)\nand `VSN` is the version of the Erl_interface application (3.2.1 in the recent\nexample).\n\nIn R4B and earlier versions of OTP, `include` and `lib` are situated under\n`$OTPROOT/usr`.\n\n_Step 2._ Start Erlang and compile the Erlang code:\n\n```erlang\n$ erl\nErlang/OTP 26 [erts-14.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]\n\nEshell V14.2 (press Ctrl+G to abort, type help(). for help)\n1> c(complex2).\n{ok,complex2}\n```\n\n_Step 3._ Run the example:\n\n```erlang\n2> complex2:start(\"./extprg\").\n<0.34.0>\n3> complex2:foo(3).\n4\n4> complex2:bar(5).\n10\n5> complex2:bar(352).\n704\n6> complex2:stop().\nstop\n```","ref":"erl_interface.html#running-the-example"},{"type":"extras","title":"Port Drivers","doc":"\n# Port Drivers\n\nThis section outlines an example of how to solve the example problem in\n[Problem Example](example.md) by using a linked-in port driver.\n\nA port driver is a linked-in driver that is accessible as a port from an Erlang\nprogram. It is a shared library (SO in UNIX, DLL in Windows), with special entry\npoints. The Erlang runtime system calls these entry points when the driver is\nstarted and when data is sent to the port. The port driver can also send data to\nErlang.\n\nAs a port driver is dynamically linked into the emulator process, this is the\nfastest way of calling C-code from Erlang. Calling functions in the port driver\nrequires no context switches. But it is also the least safe way, because a crash\nin the port driver brings the emulator down too.\n\nThe scenario is illustrated in the following figure:\n\n```mermaid\n---\ntitle: Port Driver Communication\n---\nflowchart\n subgraph Legend\n direction LR\n\n os[OS Process]\n erl([Erlang Process])\n end\n\n subgraph emulator\n direction LR\n\n port{Port} --> erlProc\n erlProc([Connected process]) --> port\n\n port --> proc[Port Driver Shared Library]\n proc --> port\n end\n```","ref":"c_portdriver.html"},{"type":"extras","title":"Erlang Program - Port Drivers","doc":"Like a port program, the port communicates with an Erlang process. All\ncommunication goes through one Erlang process that is the _connected process_ of\nthe port driver. Terminating this process closes the port driver.\n\nBefore the port is created, the driver must be loaded. This is done with the\nfunction `erl_ddll:load_driver/2`, with the name of the shared library as\nargument.\n\nThe port is then created using the BIF [`open_port/2`](`open_port/2`), with the\ntuple `{spawn, DriverName}` as the first argument. The string `SharedLib` is the\nname of the port driver. The second argument is a list of options, none in this\ncase:\n\n```erlang\n-module(complex5).\n-export([start/1, init/1]).\n\nstart(SharedLib) ->\n case erl_ddll:load_driver(\".\", SharedLib) of\n ok -> ok;\n {error, already_loaded} -> ok;\n _ -> exit({error, could_not_load_driver})\n end,\n spawn(?MODULE, init, [SharedLib]).\n\ninit(SharedLib) ->\n register(complex, self()),\n Port = open_port({spawn, SharedLib}, []),\n loop(Port).\n```\n\nNow `complex5:foo/1` and `complex5:bar/1` can be implemented. Both send a\nmessage to the `complex` process and receive the following reply:\n\n```erlang\nfoo(X) ->\n call_port({foo, X}).\nbar(Y) ->\n call_port({bar, Y}).\n\ncall_port(Msg) ->\n complex ! {call, self(), Msg},\n receive\n {complex, Result} ->\n Result\n end.\n```\n\nThe `complex` process performs the following:\n\n- Encodes the message into a sequence of bytes.\n- Sends it to the port.\n- Waits for a reply.\n- Decodes the reply.\n- Sends it back to the caller:\n\n```erlang\nloop(Port) ->\n receive\n {call, Caller, Msg} ->\n Port ! {self(), {command, encode(Msg)}},\n receive\n {Port, {data, Data}} ->\n Caller ! {complex, decode(Data)}\n end,\n loop(Port)\n end.\n```\n\nAssuming that both the arguments and the results from the C functions are less\nthan 256, a simple encoding/decoding scheme is employed. In this scheme, `foo`\nis represented by byte 1, `bar` is represented by 2, and the argument/result is\nrepresented by a single byte as well:\n\n```erlang\nencode({foo, X}) -> [1, X];\nencode({bar, Y}) -> [2, Y].\n\ndecode([Int]) -> Int.\n```\n\nThe resulting Erlang program, including functions for stopping the port and\ndetecting port failures, is as follows:\n\n```erlang\n\n-module(complex5).\n-export([start/1, stop/0, init/1]).\n-export([foo/1, bar/1]).\n\nstart(SharedLib) ->\n case erl_ddll:load_driver(\".\", SharedLib) of\n\tok -> ok;\n\t{error, already_loaded} -> ok;\n\t_ -> exit({error, could_not_load_driver})\n end,\n spawn(?MODULE, init, [SharedLib]).\n\ninit(SharedLib) ->\n register(complex, self()),\n Port = open_port({spawn, SharedLib}, []),\n loop(Port).\n\nstop() ->\n complex ! stop.\n\nfoo(X) ->\n call_port({foo, X}).\nbar(Y) ->\n call_port({bar, Y}).\n\ncall_port(Msg) ->\n complex ! {call, self(), Msg},\n receive\n\t{complex, Result} ->\n\t Result\n end.\n\nloop(Port) ->\n receive\n\t{call, Caller, Msg} ->\n\t Port ! {self(), {command, encode(Msg)}},\n\t receive\n\t\t{Port, {data, Data}} ->\n\t\t Caller ! {complex, decode(Data)}\n\t end,\n\t loop(Port);\n\tstop ->\n\t Port ! {self(), close},\n\t receive\n\t\t{Port, closed} ->\n\t\t exit(normal)\n\t end;\n\t{'EXIT', Port, Reason} ->\n\t io:format(\"~p ~n\", [Reason]),\n\t exit(port_terminated)\n end.\n\nencode({foo, X}) -> [1, X];\nencode({bar, Y}) -> [2, Y].\n\ndecode([Int]) -> Int.\n```","ref":"c_portdriver.html#erlang-program"},{"type":"extras","title":"C Driver - Port Drivers","doc":"The C driver is a module that is compiled and linked into a shared library. It\nuses a driver structure and includes the header file `erl_driver.h`.\n\nThe driver structure is filled with the driver name and function pointers. It is\nreturned from the special entry point, declared with the macro\n`DRIVER_INIT( )`.\n\nThe functions for receiving and sending data are combined into a function,\npointed out by the driver structure. The data sent into the port is given as\narguments, and the replied data is sent with the C-function `driver_output`.\n\nAs the driver is a shared module, not a program, no main function is present.\nAll function pointers are not used in this example, and the corresponding fields\nin the `driver_entry` structure are set to NULL.\n\nAll functions in the driver takes a handle (returned from `start`) that is just\npassed along by the Erlang process. This must in some way refer to the port\ndriver instance.\n\nThe `example_drv_start`, is the only function that is called with a handle to\nthe port instance, so this must be saved. It is customary to use an allocated\ndriver-defined structure for this one, and to pass a pointer back as a\nreference.\n\nIt is not a good idea to use a global variable as the port driver can be spawned\nby multiple Erlang processes. This driver-structure is to be instantiated\nmultiple times:\n\n```c\n/* port_driver.c */\n\n#include \n#include \"erl_driver.h\"\n\ntypedef struct {\n ErlDrvPort port;\n} example_data;\n\nstatic ErlDrvData example_drv_start(ErlDrvPort port, char *buff)\n{\n example_data* d = (example_data*)driver_alloc(sizeof(example_data));\n d->port = port;\n return (ErlDrvData)d;\n}\n\nstatic void example_drv_stop(ErlDrvData handle)\n{\n driver_free((char*)handle);\n}\n\nstatic void example_drv_output(ErlDrvData handle, char *buff,\n\t\t\t ErlDrvSizeT bufflen)\n{\n example_data* d = (example_data*)handle;\n char fn = buff[0], arg = buff[1], res;\n if (fn == 1) {\n res = foo(arg);\n } else if (fn == 2) {\n res = bar(arg);\n }\n driver_output(d->port, &res, 1);\n}\n\nErlDrvEntry example_driver_entry = {\n NULL,\t\t\t/* F_PTR init, called when driver is loaded */\n example_drv_start,\t\t/* L_PTR start, called when port is opened */\n example_drv_stop,\t\t/* F_PTR stop, called when port is closed */\n example_drv_output,\t\t/* F_PTR output, called when erlang has sent */\n NULL,\t\t\t/* F_PTR ready_input, called when input descriptor ready */\n NULL,\t\t\t/* F_PTR ready_output, called when output descriptor ready */\n \"example_drv\",\t\t/* char *driver_name, the argument to open_port */\n NULL,\t\t\t/* F_PTR finish, called when unloaded */\n NULL, /* void *handle, Reserved by VM */\n NULL,\t\t\t/* F_PTR control, port_command callback */\n NULL,\t\t\t/* F_PTR timeout, reserved */\n NULL,\t\t\t/* F_PTR outputv, reserved */\n NULL, /* F_PTR ready_async, only for async drivers */\n NULL, /* F_PTR flush, called when port is about\n\t\t\t\t to be closed, but there is data in driver\n\t\t\t\t queue */\n NULL, /* F_PTR call, much like control, sync call\n\t\t\t\t to driver */\n NULL, /* unused */\n ERL_DRV_EXTENDED_MARKER, /* int extended marker, Should always be\n\t\t\t\t set to indicate driver versioning */\n ERL_DRV_EXTENDED_MAJOR_VERSION, /* int major_version, should always be\n\t\t\t\t set to this value */\n ERL_DRV_EXTENDED_MINOR_VERSION, /* int minor_version, should always be\n\t\t\t\t set to this value */\n 0, /* int driver_flags, see documentation */\n NULL, /* void *handle2, reserved for VM use */\n NULL, /* F_PTR process_exit, called when a\n\t\t\t\t monitored process dies */\n NULL /* F_PTR stop_select, called to close an\n\t\t\t\t event object */\n};\n\nDRIVER_INIT(example_drv) /* must match name in driver_entry */\n{\n return &example_driver_entry;\n}\n```","ref":"c_portdriver.html#c-driver"},{"type":"extras","title":"Running the Example - Port Drivers","doc":"_Step 1._ Compile the C code:\n\n```text\nunix> gcc -o example_drv.so -fpic -shared complex.c port_driver.c\nwindows> cl -LD -MD -Fe example_drv.dll complex.c port_driver.c\n```\n\n_Step 2._ Start Erlang and compile the Erlang code:\n\n```erlang\n> erl\nErlang/OTP 26 [erts-14.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]\n\nEshell V14.2 (press Ctrl+G to abort, type help(). for help)\n1> c(complex5).\n{ok,complex5}\n```\n\n_Step 3._ Run the example:\n\n```erlang\n2> complex5:start(\"example_drv\").\n<0.34.0>\n3> complex5:foo(3).\n4\n4> complex5:bar(5).\n10\n5> complex5:stop().\nstop\n```","ref":"c_portdriver.html#running-the-example"},{"type":"extras","title":"C Nodes","doc":"\n# C Nodes\n\nThe reader is referred to\n[the erl_interface users guide](`e:erl_interface:ei_users_guide.md`) for\ninformation about how to create C nodes.","ref":"cnode.html"},{"type":"extras","title":"NIFs","doc":"\n# NIFs\n\nThis section outlines an example of how to solve the example problem in\n[Problem Example](example.md) by using Native Implemented Functions (NIFs).\n\nNIFs are a simpler and more efficient way of calling C-code than using port\ndrivers. NIFs are most suitable for synchronous functions, such as `foo` and\n`bar` in the example, that do some relatively short calculations without side\neffects and return the result.\n\nA NIF is a function that is implemented in C instead of Erlang. NIFs appear as\nany other functions to the callers. They belong to a module and are called like\nany other Erlang functions. The NIFs of a module are compiled and linked into a\ndynamic loadable, shared library (SO in UNIX, DLL in Windows). The NIF library\nmust be loaded in runtime by the Erlang code of the module.\n\nAs a NIF library is dynamically linked into the emulator process, this is the\nfastest way of calling C-code from Erlang (alongside port drivers). Calling NIFs\nrequires no context switches. But it is also the least safe, because a crash in\na NIF brings the emulator down too.","ref":"nif.html"},{"type":"extras","title":"Erlang Program - NIFs","doc":"Even if all functions of a module are NIFs, an Erlang module is still needed for\ntwo reasons:\n\n- The NIF library must be explicitly loaded by Erlang code in the same module.\n- All NIFs of a module must have an Erlang implementation as well.\n\nNormally these are minimal stub implementations that throw an exception. But\nthey can also be used as fallback implementations for functions that do not have\nnative implementations on some architectures.\n\nNIF libraries are loaded by calling `erlang:load_nif/2`, with the name of the\nshared library as argument. The second argument can be any term that will be\npassed on to the library and used for initialization:\n\n```erlang\n-module(complex6).\n-export([foo/1, bar/1]).\n-nifs([foo/1, bar/1]).\n-on_load(init/0).\n\ninit() ->\n ok = erlang:load_nif(\"./complex6_nif\", 0).\n\nfoo(_X) ->\n erlang:nif_error(nif_library_not_loaded).\nbar(_Y) ->\n erlang:nif_error(nif_library_not_loaded).\n```\n\nHere, the directive `on_load` is used to get function `init` to be automatically\ncalled when the module is loaded. If `init` returns anything other than `ok`,\nsuch when the loading of the NIF library fails in this example, the module is\nunloaded and calls to functions within it, fail.\n\nLoading the NIF library overrides the stub implementations and cause calls to\n`foo` and `bar` to be dispatched to the NIF implementations instead.","ref":"nif.html#erlang-program"},{"type":"extras","title":"NIF Library Code - NIFs","doc":"The NIFs of the module are compiled and linked into a shared library. Each NIF\nis implemented as a normal C function. The macro `ERL_NIF_INIT` together with an\narray of structures defines the names, arity, and function pointers of all the\nNIFs in the module. The header file `erl_nif.h` must be included. As the library\nis a shared module, not a program, no main function is to be present.\n\nThe function arguments passed to a NIF appears in an array `argv`, with `argc`\nas the length of the array, and thus the arity of the function. The Nth argument\nof the function can be accessed as `argv[N-1]`. NIFs also take an environment\nargument that serves as an opaque handle that is needed to be passed on to most\nAPI functions. The environment contains information about the calling Erlang\nprocess:\n\n```c\n#include \n\nextern int foo(int x);\nextern int bar(int y);\n\nstatic ERL_NIF_TERM foo_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])\n{\n int x, ret;\n if (!enif_get_int(env, argv[0], &x)) {\n\treturn enif_make_badarg(env);\n }\n ret = foo(x);\n return enif_make_int(env, ret);\n}\n\nstatic ERL_NIF_TERM bar_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])\n{\n int y, ret;\n if (!enif_get_int(env, argv[0], &y)) {\n\treturn enif_make_badarg(env);\n }\n ret = bar(y);\n return enif_make_int(env, ret);\n}\n\nstatic ErlNifFunc nif_funcs[] = {\n {\"foo\", 1, foo_nif},\n {\"bar\", 1, bar_nif}\n};\n\nERL_NIF_INIT(complex6, nif_funcs, NULL, NULL, NULL, NULL)\n```\n\nHere, `ERL_NIF_INIT` has the following arguments:\n\n- The first argument must be the name of the Erlang module as a C-identifier. It\n will be stringified by the macro.\n- The second argument is the array of `ErlNifFunc` structures containing name,\n arity, and function pointer of each NIF.\n- The remaining arguments are pointers to callback functions that can be used to\n initialize the library. They are not used in this simple example, hence they\n are all set to `NULL`.\n\nFunction arguments and return values are represented as values of type\n`ERL_NIF_TERM`. Here, functions like `enif_get_int` and `enif_make_int` are used\nto convert between Erlang term and C-type. If the function argument `argv[0]` is\nnot an integer, `enif_get_int` returns false, in which case it returns by\nthrowing a `badarg`\\-exception with `enif_make_badarg`.","ref":"nif.html#nif-library-code"},{"type":"extras","title":"Running the Example - NIFs","doc":"_Step 1._ Compile the C code:\n\n```text\nunix> gcc -o complex6_nif.so -fpic -shared complex.c complex6_nif.c\nwindows> cl -LD -MD -Fe complex6_nif.dll complex.c complex6_nif.c\n```\n\n_Step 2:_ Start Erlang and compile the Erlang code:\n\n```erlang\n> erl\nErlang R13B04 (erts-5.7.5) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]\n\nEshell V5.7.5 (abort with ^G)\n1> c(complex6).\n{ok,complex6}\n```\n\n_Step 3:_ Run the example:\n\n```erlang\n3> complex6:foo(3).\n4\n4> complex6:bar(5).\n10\n5> complex6:foo(\"not an integer\").\n** exception error: bad argument\n in function complex6:foo/1\n called as comlpex6:foo(\"not an integer\")\n```","ref":"nif.html#running-the-example"},{"type":"extras","title":"Debugging NIFs and Port Drivers","doc":"\n# Debugging NIFs and Port Drivers","ref":"debugging.html"},{"type":"extras","title":"With great power comes great responsibilty - Debugging NIFs and Port Drivers","doc":"NIFs and port driver code run inside the Erlang VM OS process (the \"Beam\"). To\nmaximize performance the code is called directly by the same threads executing\nErlang beam code and has full access to all the memory of the OS process. A\nbuggy NIF/driver can thus make severe damage by corrupting memory.\n\nIn a best case scenario such memory corruption is detected immediately causing\nthe Beam to crash generating a core dump file which can be analyzed to find the\nbug. However, it is very common for memory corruption bugs to not be immediately\ndetected when the faulty write happens, but instead much later, for example when\nthe calling Erlang process is garbage collected. When that happens it can be\nvery hard to find the root cause of the memory corruption by analysing the core\ndump. All traces that could have indicated which specific buggy NIF/driver that\ncaused the corruption may be long gone.\n\nAnother kind of bugs that are hard to find are _memory leaks_. They may go\nunnoticed and not cause problem until a deployed system has been running for a\nlong time.\n\nThe following sections describe tools that make it easier to both detect and\nfind the root cause of bugs like this. These tools are actively used during\ndevelopment, testing and troubleshooting of the Erlang runtime system itself.\n\n- [Debug emulator](debugging.md#debug)\n- [Address Sanitizer](debugging.md#asan)\n- [Valgrind](debugging.md#valgrind)\n- [rr - Record and Replay](debugging.md#rr)\n\n[](){: #debug }","ref":"debugging.html#with-great-power-comes-great-responsibilty"},{"type":"extras","title":"Debug emulator - Debugging NIFs and Port Drivers","doc":"One way to make debugging easier is to run an emulator built with target\n`debug`. It will\n\n- _Increase probability of detecting bugs earlier_. It contains a lot more\n runtime checks to ensure correct use of internal interfaces and data\n structures.\n- _Generate a core dump that is easier to analyze_. Compiler optimizations are\n turned off, which stops the compiler from \"optimizing away\" variables, thus\n making it easier/possible to inspect their state.\n- _Detect lock order violations_. A runtime lock checker will verify that the\n locks in the [`erl_nif`](`e:erts:erl_nif.md`) and\n [`erl_driver`](`e:erts:erl_driver.md`) APIs are seized in a consistent order\n that cannot result in deadlock bugs.\n\nIn fact, we recommend to use the debug emulator as default during development of\nNIFs and drivers, regardless if you are troubleshooting bugs or not. Some subtle\nbugs may not be detected by the normal emulator and just happen to work anyway\nby chance. However, another version of the emulator, or even different\ncircumstances within the same emulator, may cause the bug to later provoke all\nkinds of problems.\n\nThe main disadvantage of the `debug` emulator is its reduced performance. The\nextra runtime checks and lack of compiler optimizations may result in a slowdown\nwith a factor of two or more depending on load. The memory footprint should be\nabout the same.\n\nIf the `debug` emulator is part of the Erlang/OTP installation, it can be\nstarted with the [`-emu_type`](`e:erts:erl_cmd.md#emu_type`) option.\n\n```text\n> erl -emu_type debug\nErlang/OTP 25 [erts-13.0.2] ... [type-assertions] [debug-compiled] [lock-checking]\n\nEshell V13.0.2 (abort with ^G)\n1>\n```\n\nIf the `debug` emulator is not part of the installation, you need to\n[build it from the Erlang/OTP source code](`e:system:install.md#advanced-configuration-and-build-of-erlang-otp_building_how-to-build-a-debug-enabled-erlang-runtime-system`).\nAfter building from source either make an Erlang/OTP installation or you can run\nthe debug emulator directly in the source tree with the `cerl` script:\n\n```text\n> $ERL_TOP/bin/cerl -debug\nErlang/OTP 25 [erts-13.0.2] ... [type-assertions] [debug-compiled] [lock-checking]\n\nEshell V13.0.2 (abort with ^G)\n1>\n```\n\nThe `cerl` script can also be used as a convenient way to start the debugger\n`gdb` for core dump analysis:\n\n```text\n> $ERL_TOP/bin/cerl -debug -core core.12345\nor\n> $ERL_TOP/bin/cerl -debug -rcore core.12345\n```\n\nThe first variant starts Emacs and runs `gdb` within, while the other `-rcore`\nruns `gdb` directly in the terminal. Apart from starting `gdb` with the correct\n`beam.debug.smp` executable file it will also read the file\n`$ERL_TOP/erts/etc/unix/etp-commands` which contains a lot of `gdb` command for\ninspecting a beam core dump. For example, the command `etp` that will print the\ncontent of an Erlang term (`Eterm`) in plain Erlang syntax.\n\n[](){: #asan }","ref":"debugging.html#debug-emulator"},{"type":"extras","title":"Address Sanitizer - Debugging NIFs and Port Drivers","doc":"[AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html) (asan) is\nan open source programming tool that detects memory corruption bugs such as\nbuffer overflows, use-after-free and memory leaks. AddressSanitizer is based on\ncompiler instrumentation and is supported by both gcc and clang.\n\nSimilar to the `debug` emulator, the `asan` emulator runs slower than normal,\nabout 2-3 times slower. However, it also has a larger memory footprint, about 3\ntimes more memory than normal.\n\nTo get full effect you should compile both your own NIF/driver code as well as\nthe Erlang emulator with AddressSanitizer instrumentation. Compile your own code\nby passing option `-fsanitize=address` to gcc or clang. Other recommended\noptions that will improve the fault identification are `-fno-common` and\n`-fno-omit-frame-pointer`.\n\nBuild and run the emulator with AddressSanitizer support by using the same\nprocedure as for the debug emulator, except use the `asan` build target instead\nof `debug`.\n\n- **Run in source tree** - If you run the `asan` emulator directly in the source\n tree with the `cerl` script you only need to set environment variable\n `ASAN_LOG_DIR` to the directory where the error log files will be generated.\n\n ```text\n > export ASAN_LOG_DIR=/my/asan/log/dir\n > $ERL_TOP/bin/cerl -asan\n Erlang/OTP 25 [erts-13.0.2] ... [address-sanitizer]\n\n Eshell V13.0.2 (abort with ^G)\n 1>\n ```\n\n You may however also want to set `ASAN_OPTIONS=\"halt_on_error=true\"` if you\n want the emulator to crash when an error is detected.\n\n- **Run installed Erlang/OTP** - If you run the `asan` emulator in an installed\n Erlang/OTP with `erl -emu_type asan` you need to set the path to the error log\n _file_ with\n\n ```text\n > export ASAN_OPTIONS=\"log_path=/my/asan/log/file\"\n ```\n\n To avoid false positive memory leak reports from the emulator itself set\n `LSAN_OPTIONS` (LSAN=LeakSanitizer):\n\n ```text\n > export LSAN_OPTIONS=\"suppressions=$ERL_TOP/erts/emulator/asan/suppress\"\n ```\n\n The `suppress` file is currently not installed but can be copied manually from\n the source tree to wherever you want it.\n\nMemory corruption errors are reported by AddressSanitizer when they happen, but\nmemory leaks are only checked and reported by default then the emulator\nterminates.","ref":"debugging.html#address-sanitizer"},{"type":"extras","title":"Valgrind - Debugging NIFs and Port Drivers","doc":"An even more heavy weight debugging tool is [Valgrind](https://valgrind.org). It\ncan also find memory corruption bugs and memory leaks similar to `asan`.\nValgrind is not as good at buffer overflow bugs, but it will find use of\nundefined data, which is a type of error that `asan` cannot detect.\n\nValgrind is much slower than `asan` and it is incapable at exploiting CPU\nmulticore processing. We therefore recommend `asan` as the first choice before\ntrying valgrind.\n\nValgrind runs as a virtual machine itself, emulating execution of hardware\nmachine instructions. This means you can run almost any program unchanged on\nvalgrind. However, we have found that the beam executable benefits from being\ncompiled with special adaptions for running on valgrind.\n\nBuild the emulator with `valgrind` target the same as is done for `debug` and\n`asan`. Note that `valgrind` needs to be installed on the machine before the\nbuild starts.\n\nRun the `valgrind` emulator directly in the source tree with the `cerl` script.\nSet environment variable `VALGRIND_LOG_DIR` to the directory where the error log\nfiles will be generated.\n\n```text\n> export VALGRIND_LOG_DIR=/my/valgrind/log/dir\n> $ERL_TOP/bin/cerl -valgrind\nErlang/OTP 25 [erts-13.0.2] ... [valgrind-compiled]\n\nEshell V13.0.2 (abort with ^G)\n1>\n```\n\n[](){: #rr }","ref":"debugging.html#valgrind"},{"type":"extras","title":"rr - Record and Replay - Debugging NIFs and Port Drivers","doc":"Last but not least, the fantastic interactive debugging tool\n[rr](https://rr-project.org/), developed by Mozilla as open source. `rr` stands\nfor Record and Replay. While a core dump represents only a static snapshot of\nthe OS process when it crashed, with `rr` you instead record the entire session,\nfrom start of the OS process to the end (the crash). You can then replay that\nsession from within `gdb`. Single step, set breakpoints and watchpoints, and\neven _execute backwards_.\n\nConsidering its powerful utility, `rr` is remarkably light weight. It runs on\nLinux with any reasonably modern x86 CPU. You may get a two times slowdown when\nexecuting in recording mode. The big weakness is its inability to exploite CPU\nmulticore processing. If the bug is a race condition between concurrently\nrunning threads, it may be hard to reproduce with `rr`.\n\n`rr` does not require any special instrumented compilation. However, if\npossible, run it together with the `debug` emulator, as that will result in a\nmuch nicer debugging experience. You run `rr` in the source tree using the\n`cerl` script.\n\nHere is an example of a typical session. First we catch the crash in an rr\nrecording session:\n\n```text\n> $ERL_TOP/bin/cerl -debug -rr\nrr: Saving execution to trace directory /home/foobar/.local/share/rr/beam.debug.smp-1.\nErlang/OTP 25 [erts-13.0.2]\n\nEshell V13.0.2 (abort with ^G)\n1> mymod:buggy_nif().\nSegmentation fault\n```\n\nNow we can replay that session with `rr replay`:\n\n```text\n> rr replay\nGNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2\n:\n(rr) continue\n:\nThread 2 received signal SIGSEGV, Segmentation fault.\n(rr) backtrace\n```\n\nYou get the call stack at the moment of the crash. Bad luck, it is somewhere\ndeep down in the garbage collection of the beam. But you manage to figure out\nthat variable `hp` points to a broken Erlang term.\n\nSet a watch point on that memory position and resume execution _backwards_. The\ndebugger will then stop at the exact position when that memory position `*hp`\nwas written.\n\n```text\n(rr) watch -l *hp\nHardware watchpoint 1: -location *hp\n(rr) reverse-continue\nContinuing.\n\nThread 2 received signal SIGSEGV, Segmentation fault.\n```\n\nThis is a quirk to be aware about. We started by executing forward until it\ncrashed with SIGSEGV. We are now executing backwards from that point, so we are\nhitting the same SIGSEGV again but from the other direction. Just continue\nbackwards once more to move past it.\n\n```text\n(rr) reverse-continue\nContinuing.\n\nThread 2 hit Hardware watchpoint 1: -location *hp\n\nOld value = 42\nNew value = 0\n```\n\nAnd here we are at the position when someone wrote a broken term on the process\nheap. Note that \"Old value\" and \"New value\" are reversed when we execute\nbackwards. In this case the value 42 was written on the heap. Let's see who the\nguilty one is:\n\n```text\n(rr) backtrace\n```","ref":"debugging.html#rr-record-and-replay"},{"type":"extras","title":"Introduction","doc":"\n\n# Introduction\n\nThis section describes the issues that are specific for running Erlang on an UNIX\nembedded system. It describes the differences in installing and starting Erlang\ncompared to how it is done for a non-embedded system.\n\nFor details on how to create a target system, see [Creating and Upgrading a Target System]\nin the System Principles section.\n\nWhen running on Windows, so special considerations need to be made. Starting Erlang\nshould be done via [`erlsrv`](`e:erts:erlsrv_cmd.md`).","ref":"embedded.html"},{"type":"extras","title":"Installing an Embedded System - Introduction","doc":"This section is about installing an embedded system. The following topics are\nconsidered:\n\n- Creating user and installation directory\n- Installing an embedded system\n- Configuring automatic start at boot\n- Changing permission for reboot\n- Setting TERM environment variable\n\nSeveral of the procedures in this section require expert knowledge of the\noperating system. For most of them super user privilege is needed.","ref":"embedded.html#installing-an-embedded-system"},{"type":"extras","title":"Creating User and Installation Directory - Introduction","doc":"It is recommended that the embedded environment is run by an ordinary user, that\nis, a user who does not have super user privileges.\n\nIn this section, it is assumed that the username is `otpuser` and that the home\ndirectory of that user is:\n\n```text\n/home/otpuser\n```\n\nIt is also assumed that in the home directory of `otpuser`, there is a directory\nnamed `otp`, the full path of which is:\n\n```text\n/home/otpuser/otp\n```\n\nThis directory is the _installation directory_ of the embedded environment.","ref":"embedded.html#creating-user-and-installation-directory"},{"type":"extras","title":"Installing an Embedded System - Introduction","doc":"The procedure for installing an embedded system is the same as for an ordinary\nsystem (see [Installation Guide](installation_guide/INSTALL.md) and [Creating and Upgrading a Target System]\nin the System Principles section), except for the following:\n\n- The (compressed) archive file is to be extracted in the installation\n directory defined above.\n- It is not needed to link the start script to a standard directory like\n `/usr/local/bin`.","ref":"embedded.html#installing-an-embedded-system"},{"type":"extras","title":"Configuring Automatic Start at Boot - Introduction","doc":"A true embedded system must start when the system boots. This section accounts\nfor the necessary configurations needed to achieve that using `init.d` start\nscripts.\n\nThe embedded system and all the applications start automatically if the script\nfile shown below is added to directory `/etc/rc3.d`. The file must be owned and\nreadable by `root`. Its name cannot be arbitrarily assigned; the following name\nis recommended:\n\n```text\nS75otp.system\n```\n\nFor more details on initialization (and termination) scripts, and naming\nthereof, see the `init.d` documentation on your OS.\n\n```text\n#!/bin/sh\n#\n# File name: S75otp.system\n# Purpose: Automatically starts Erlang and applications when the\n# system starts\n# Author: janne@erlang.ericsson.se\n# Resides in: /etc/rc3.d\n#\n\nif [ ! -d /usr/bin ]\nthen # /usr not mounted\n exit\nfi\n\nkillproc() { # kill the named process(es)\n pid=`/usr/bin/ps -e |\n /usr/bin/grep -w $1 |\n /usr/bin/sed -e 's/^ *//' -e 's/ .*//'`\n [ \"$pid\" != \"\" ] && kill $pid\n}\n\n# Start/stop processes required for Erlang\n\ncase \"$1\" in\n'start')\n # Start the Erlang emulator\n #\n su - otpuser -c \"/home/otpuser/otp/bin/start\" &\n ;;\n'stop')\n killproc beam\n ;;\n*)\n echo \"Usage: $0 { start | stop }\"\n ;;\nesac\n```\n\nFile `/home/otpuser/otp/bin/start` referred to in the above script is\nprecisely the `start` script described in [_Starting Erlang_](#starting-erlang).\nThe script variable `$OTPROOT` in that `start` script corresponds to the following example path used\nin this section:\n\n```text\n/home/otpuser/otp\n```\n\nThe `start` script is to be edited accordingly.\n\nUse of the `killproc` procedure in the above script can be combined with a call\nto `erl_call`, for example:\n\n```text\n$SOME_PATH/erl_call -n Node init stop\n```\n\nTo take Erlang down gracefully, see the\n[`erl_call(1)`](`e:erl_interface:erl_call_cmd.md`) manual page in\n`erl_interface` for details on the use of `erl_call`. However, that requires\nthat Erlang runs as a distributed node, which is not always the case.\n\nThe `killproc` procedure is not to be removed. The purpose is here to move from\nrun level 3 (multi-user mode with networking resources) to run level 2\n(multi-user mode without such resources), in which Erlang is not to run.","ref":"embedded.html#configuring-automatic-start-at-boot"},{"type":"extras","title":"Changing Permissions for Reboot - Introduction","doc":"If the `HEART_COMMAND` environment variable is to be set in the `start` script\nin [_Starting Erlang_](#starting-erlang), and if the value is to be set to the path of the\n`reboot` command, that is:\n\n```text\nHEART_COMMAND=/usr/sbin/reboot\n```\n\nthen the ownership and file permissions for `/usr/sbin/reboot` must be changed\nas follows:\n\n```text\nchown 0 /usr/sbin/reboot\nchmod 4755 /usr/sbin/reboot\n```\n\nSee also the `m:heart` manual page in Kernel.","ref":"embedded.html#changing-permissions-for-reboot"},{"type":"extras","title":"Setting TERM Environment Variable - Introduction","doc":"When the Erlang runtime system is automatically started from the `S75otp.system`\nscript, the `TERM` environment variable must be set. The following is a minimal\nsetting:\n\n```text\nTERM=dumb\n```\n\nThis is to be added to the `start` script.","ref":"embedded.html#setting-term-environment-variable"},{"type":"extras","title":"Starting Erlang - Introduction","doc":"This section describes how an embedded system is started. Four programs are\ninvolved and they normally reside in the directory ` /bin`. The\nonly exception is the [`start`](`e:erts:start_cmd.md`) program, which can be located anywhere, and is\nalso the only program that must be modified by the user.\n\nIn an embedded system, there is usually no interactive shell. However, an\noperator can attach to the Erlang system by command [`to_erl`](#to_erl).\nThe operator is then connected to the Erlang shell and can give ordinary Erlang commands. All\ninteraction with the system through this shell is logged in a special directory.\n\nBasically, the procedure is as follows:\n\n- The [`start`](`e:erts:start_cmd.md`)) program is called when the machine is started.\n- It calls [`run_erl`](#run_erl), which sets up things so the operator can attach to the\n system.\n- It calls [`start_erl`](`e:erts:start_erl_cmd.md`), which calls the correct version of\n `erlexec` (which is located in ` /erts-EVsn/bin`) with the correct `boot` and\n `config` files.","ref":"embedded.html#starting-erlang"},{"type":"extras","title":"Programs - Introduction","doc":"","ref":"embedded.html#programs"},{"type":"extras","title":"start - Introduction","doc":"This program is called when the machine is started. It can be modified or\nrewritten to suit a special system. By default, it must be called `start` and\nreside in ` /bin`. Another start program can be used, by using\nconfiguration parameter `start_prg` in application SASL.\n\nThe start program must call [`run_erl`](#run_erl) as shown below. It must also take an\noptional parameter, which defaults to\n` /releases/start_erl.data`.\n\nThis program is to set static parameters and environment variables such as\n`-sname Name` and `HEART_COMMAND` to reboot the machine.\n\nThe ` ` directory is where new release packets are installed, and where\nthe release handler keeps information about releases. For more information, see\nthe `m:release_handler` manual page in SASL.\n\nThe following script illustrates the default behaviour of the program:\n\n```text\n#!/bin/sh\n# Usage: start [DataFile]\n#\nROOTDIR=/usr/local/otp\n\nif [ -z \"$RELDIR\" ]\nthen\n RELDIR=$ROOTDIR/releases\nfi\n\nSTART_ERL_DATA=${1:-$RELDIR/start_erl.data}\n\n$ROOTDIR/bin/run_erl /tmp/ $ROOTDIR/log \"exec $ROOTDIR/bin/start_erl \\\n $ROOTDIR $RELDIR $START_ERL_DATA\" > /dev/null 2>&1 &\n```\n\nThe following script illustrates a modification where the node is given the name\n`cp1`, and where the environment variables `HEART_COMMAND` and `TERM` have been\nadded to the previous script:\n\n```text\n#!/bin/sh\n# Usage: start [DataFile]\n#\nHEART_COMMAND=/usr/sbin/reboot\nTERM=dumb\nexport HEART_COMMAND TERM\n\nROOTDIR=/usr/local/otp\n\nif [ -z \"$RELDIR\" ]\nthen\n RELDIR=$ROOTDIR/releases\nfi\n\nSTART_ERL_DATA=${1:-$RELDIR/start_erl.data}\n\n$ROOTDIR/bin/run_erl /tmp/ $ROOTDIR/log \"exec $ROOTDIR/bin/start_erl \\\n $ROOTDIR $RELDIR $START_ERL_DATA -heart -sname cp1\" > /dev/null 2>&1 &\n```\n\nIf a diskless and/or read-only client node is about to start, file\n`start_erl.data` is located in the client directory at the master node. Thus,\nthe `START_ERL_DATA` line is to look like:\n\n```text\nCLIENTDIR=$ROOTDIR/clients/clientname\nSTART_ERL_DATA=${1:-$CLIENTDIR/bin/start_erl.data}\n```","ref":"embedded.html#start"},{"type":"extras","title":"run_erl - Introduction","doc":"This program is used to start the emulator, but you will not be connected to the\nshell. `to_erl` is used to connect to the Erlang shell.\n\n```text\nUsage: run_erl pipe_dir/ log_dir \"exec command [parameters ...]\"\n```\n\nHere:\n\n- `pipe_dir/` is to be `/tmp/` (`to_erl` uses this name by default).\n- `log_dir` is where the log files are written.\n- `command [parameters]` is executed.\n- Everything written to `stdin` and `stdout` is logged in `log_dir`.\n\nLog files are written in `log_dir`. Each log file has a name of the form\n`erlang.log.N`, where N is a generation number, ranging from 1 to 5. Each log\nfile holds up to 100 kB text. As time goes by, the following log files are found\nin the log file directory:\n\n```text\nerlang.log.1\nerlang.log.1, erlang.log.2\nerlang.log.1, erlang.log.2, erlang.log.3\nerlang.log.1, erlang.log.2, erlang.log.3, erlang.log.4\nerlang.log.2, erlang.log.3, erlang.log.4, erlang.log.5\nerlang.log.3, erlang.log.4, erlang.log.5, erlang.log.1\n...\n```\n\nThe most recent log file is the rightmost in each row. That is, the most recent\nfile is the one with the highest number, or if there are already four files, the\none before the skip.\n\nWhen a log file is opened (for appending or created), a time stamp is written to\nthe file. If nothing has been written to the log files for 15 minutes, a record\nis inserted that says that we are still alive.\n\nFor more details see [`run_erl`](`e:erts:run_erl_cmd.md`) in the ERTS documentation.","ref":"embedded.html#run_erl"},{"type":"extras","title":"to_erl - Introduction","doc":"This program is used to attach to a running Erlang runtime system, started with\n`run_erl`.\n\n```text\nUsage: to_erl [pipe_name | pipe_dir]\n```\n\nHere `pipe_name` defaults to `/tmp/erlang.pipe.N`.\n\nTo disconnect from the shell without exiting the Erlang system, type `Ctrl-D`.","ref":"embedded.html#to_erl"},{"type":"extras","title":"start_erl - Introduction","doc":"This program starts the Erlang emulator with parameters `-boot` and `-config`\nset. It reads data about where these files are located from a file named\n`start_erl.data`, which is located in ` `. Each new release introduces a\nnew data file. This file is automatically generated by the release handler in\nErlang.\n\nThe following script illustrates the behaviour of the program:\n\n```text\n#!/bin/sh\n#\n# This program is called by run_erl. It starts\n# the Erlang emulator and sets -boot and -config parameters.\n# It should only be used at an embedded target system.\n#\n# Usage: start_erl RootDir RelDir DataFile [ErlFlags ...]\n#\nROOTDIR=$1\nshift\nRELDIR=$1\nshift\nDataFile=$1\nshift\n\nERTS_VSN=`awk '{print $1}' $DataFile`\nVSN=`awk '{print $2}' $DataFile`\n\nBINDIR=$ROOTDIR/erts-$ERTS_VSN/bin\nEMU=beam\nPROGNAME=`echo $0 | sed 's/.*\\///'`\nexport EMU\nexport ROOTDIR\nexport BINDIR\nexport PROGNAME\nexport RELDIR\n\nexec $BINDIR/erlexec -boot $RELDIR/$VSN/start -config $RELDIR/$VSN/sys $*\n```\n\nIf a diskless and/or read-only client node with the SASL configuration parameter\n`static_emulator` set to `true` is about to start, the `-boot` and `-config`\nflags must be changed.\n\nAs such a client cannot read a new `start_erl.data` file (the file cannot be\nchanged dynamically). The boot and config files are always fetched from the same\nplace (but with new contents if a new release has been installed).\n\nThe `release_handler` copies these files to the `bin` directory in the client\ndirectory at the master nodes whenever a new release is made permanent.\n\nAssuming the same `CLIENTDIR` as above, the last line is to look like:\n\n```text\nexec $BINDIR/erlexec -boot $CLIENTDIR/bin/start \\\n -config $CLIENTDIR/bin/sys $*\n```\n\n[Creating and Upgrading a Target System]: create_target.md","ref":"embedded.html#start_erl"}],"content_type":"text/plain","producer":{"name":"ex_doc","version":[48,46,51,52,46,49]}} \ No newline at end of file diff --git a/prs/8803/doc/system/dist/search_data-9BDB5A32.js b/prs/8803/doc/system/dist/search_data-9BDB5A32.js deleted file mode 100644 index a6470c6ccffab..0000000000000 --- a/prs/8803/doc/system/dist/search_data-9BDB5A32.js +++ /dev/null @@ -1 +0,0 @@ -searchData={"items":[{"type":"extras","doc":"# Erlang/OTP System Documentation\n\nThe Erlang/OTP system documentation is a collection of guides describing how\nto use Erlang/OTP and different aspects of working with Erlang/OTP. The guides are:\n\n* [Installation Guide](installation_guide/installation_guide.md) -\n Describes how to build and install Erlang/OTP on Unix and Windows.\n* [Getting Started With Erlang](getting_started/getting_started.md) -\n Describes how to get up and running with programming Erlang.\n* [System Principles](system_principles/system_principles.md) -\n Describes how to build Erlang/OTP systems.\n* [OTP Design Principles](design_principles/design_principles.md) -\n Describes how to build Erlang/OTP applications.\n* [Programming Examples](programming_examples/programming_examples.md) -\n Examples on using records, funs, list comprehensions, and the bit syntax.\n* [Erlang Reference Manual](reference_manual/reference_manual.md) -\n This section is the Erlang reference manual. It describes the Erlang programming language.\n* [Efficiency Guide](efficiency_guide/efficiency_guide.md) -\n Describes how to write efficient code in Erlang-\n* [Interoperability Tutorial](tutorial/tutorial.md) -\n This section informs on interoperability, that is, information exchange, between\n Erlang and other programming languages. The included examples mainly treat\n interoperability between Erlang and C.\n* [Embedded Systems User's Guide](embedded/embedded.md) -\n This section describes the issues that are specific for running Erlang on an embedded system.","title":"Erlang/OTP System Documentation","ref":"readme.html"},{"type":"extras","doc":"# Introduction\n\nThis section describes how to build, install and patch Erlang/OTP on UNIX and Windows.\n\n* **[Building and Installing Erlang/OTP](INSTALL.md)** - Describes how to build and install Erlang/OTP\n on any UNIX platform, that is Linux, macOS, any BSD, Solaris and so on.\n* **[Cross Compiling Erlang/OTP](INSTALL-CROSS.md)** - Describes how to use a [cross compiler] to build\n Erlang/OTP on any UNIX platform.\n* **[Building Erlang/OTP on Windows](INSTALL-WIN32.md)** - Describes how to build Erlang/OTP for on\n Windows 10 using WSL.\n\nThere are also various other guides for other OS located in the\n[Erlang/OTP HOWTO folder](https://github.com/erlang/otp/blob/master/HOWTO/).\n\n> #### Note {: .info }\n>\n> Depending on the Operating System and how familiar you are with using GNU configure/make\n> it can be difficult to build Erlang/OTP. Therefore it is recommended to first go to\n> and check if a pre-built Erlang/OTP can be used.\n\nIf the purpose of building Erlang/OTP is to contribute to its development it is recommended\nto have a look at\n[Contributing to Erlang/OTP](https://github.com/erlang/otp/blob/master/CONTRIBUTING.md)\nand [Developing Erlang/OTP](https://github.com/erlang/otp/blob/master/HOWTO/DEVELOPMENT.md).\n\n[cross compiler]: https://en.wikipedia.org/wiki/Cross_compiler","title":"Introduction","ref":"installation_guide.html"},{"type":"extras","doc":"Building and Installing Erlang/OTP\n==================================\n\nIntroduction\n------------\n\nThis document describes how to build and install Erlang/OTP-28.\nErlang/OTP should be possible to build from source on any Unix/Linux system,\nincluding macOS. You are advised to read the whole document\nbefore attempting to build and install Erlang/OTP.\n\nThe source code can be downloaded from the official site of Erlang/OTP or GitHub.\n* \n* \n\nRequired Utilities\n------------------\n\nThese are the tools you need in order to unpack and build Erlang/OTP.","title":"Building and Installing Erlang/OTP","ref":"install.html"},{"type":"extras","doc":"* GNU unzip, or a modern uncompress.\n* A TAR program that understands the GNU TAR format for long filenames.","title":"Unpacking ### - Building and Installing Erlang/OTP","ref":"install.html#unpacking"},{"type":"extras","doc":"* GNU `make`\n* Compiler -- GNU C Compiler, `gcc` or the C compiler frontend for LLVM, `clang`.\n* Perl 5\n* `ncurses`, `termcap`, or `termlib` -- The development headers and\n libraries are needed, often known as `ncurses-devel`. Use\n `--without-termcap` to build without any of these libraries. Note that\n in this case only the old shell (without any line editing) can be used.\n* `sed` -- Stream Editor for basic text transformation.\n\n#### Building in Git ####\n\nBuild the same way as when building the unpacked tar file.\n\n#### Building on macOS ####\n\n* Xcode -- Download and install via the Mac App Store.\n Read about [Building on a Mac][] before proceeding.","title":"Building ### - Building and Installing Erlang/OTP","ref":"install.html#building"},{"type":"extras","doc":"* An `install` program that can take multiple file names.\n\nOptional Utilities\n------------------\n\nSome applications are automatically skipped if the dependencies aren't met.\nHere is a list of utilities needed for those applications. You will\nalso find the utilities needed for building the documentation.","title":"Installing ### - Building and Installing Erlang/OTP","ref":"install.html#installing"},{"type":"extras","doc":"* OpenSSL -- The opensource toolkit for Secure Socket Layer\n and Transport Layer Security.\n Required for building the application `crypto`.\n Further, `ssl` and `ssh` require a working crypto application and\n will also be skipped if OpenSSL is missing. The `public_key`\n application is available without `crypto`, but the functionality\n will be very limited.\n\n The development package of OpenSSL including the header files are needed as well\n as the binary command program `openssl`. At least version 0.9.8 of OpenSSL is required.\n Read more and download from .\n* Oracle Java SE JDK -- The Java Development Kit (Standard Edition).\n Required for building the application `jinterface`.\n At least version 1.6.0 of the JDK is required.\n\n Download from .\n We have also tested with IBM's JDK 1.6.0.\n* `flex` -- Headers and libraries are needed to build the flex\n scanner for the `megaco` application on Unix/Linux.\n* wxWidgets -- Toolkit for GUI applications.\n Required for building the `wx` application. At least\n version 3.0 of wxWidgets is required.\n\n Download from \n or get it from GitHub: \n\n Further instructions on wxWidgets, read [Building with Wx][].","title":"Building ### - Building and Installing Erlang/OTP","ref":"install.html#building"},{"type":"extras","doc":"* `ex_doc` -- [ExDoc](https://hexdocs.pm/ex_doc/readme.html) is a tool to\n generate html and epub documentation for Erlang and Elixir projects.\n \n Download as an [escript from github](https://github.com/elixir-lang/ex_doc/releases/latest)\n or get it from GitHub: and build\n your self.\n \n ExDoc v0.34.1 was used to build the documentation for this release,\n but any version after that should work just as well.\n\n You can also use `./otp_build download_ex_doc` to download the correct version\n from github. One of the following dependencies are needed to check the documentation:\n \n - sha256sum, or\n - sha1sum, or\n - shasum\n\nHow to Build and Install Erlang/OTP\n-----------------------------------\n\nThe following instructions are for building [the released source tar ball][]\nor from a [git clone](https://github.com/erlang/otp).\n\nThe variable `$ERL_TOP` will be mentioned a lot of times. It refers to\nthe top directory in the source tree. More information about `$ERL_TOP`\ncan be found in the [make and $ERL_TOP][] section below.","title":"Building Documentation ### - Building and Installing Erlang/OTP","ref":"install.html#building-documentation"},{"type":"extras","doc":"Start by unpacking the Erlang/OTP distribution file with your GNU\ncompatible TAR program.\n\n $ tar -zxf otp_src_28.0-rc0.tar.gz # Assuming bash/sh\n\nor clone from github:\n\n $ git clone https://github.com/erlang/otp otp_src_28.0-rc0\n\nNow change directory into the base directory and set the `$ERL_TOP` variable.\n\n $ cd otp_src_28.0-rc0\n $ export ERL_TOP=`pwd` # Assuming bash/sh","title":"Unpacking ### - Building and Installing Erlang/OTP","ref":"install.html#unpacking"},{"type":"extras","doc":"Run the following commands to configure the build:\n\n $ ./configure [ options ]\n\nBy default, Erlang/OTP release will be installed in `/usr/local/{bin,lib/erlang}`.\nIf you for instance don't have the permission to install in the standard location,\n you can install Erlang/OTP somewhere else. For example, to install in\n`/opt/erlang/28.0-rc0/{bin,lib/erlang}`, use the `--prefix=/opt/erlang/28.0-rc0` option.\n\nOn some platforms Perl may behave strangely if certain locales are\nset. If you get errors when building, try setting the LANG variable:\n\n $ export LANG=C # Assuming bash/sh","title":"Configuring ### - Building and Installing Erlang/OTP","ref":"install.html#configuring"},{"type":"extras","doc":"Build the Erlang/OTP release.\n\n $ make","title":"Building ### - Building and Installing Erlang/OTP","ref":"install.html#building"},{"type":"extras","doc":"Before installation you should test whether your build is working properly\nby running our smoke test. The smoke test is a subset of the complete Erlang/OTP test suites.\nFirst you will need to build and release the test suites.\n\n $ make release_tests\n\nThis creates an additional folder in `$ERL_TOP/release` called `tests`.\nNow, it's time to start the smoke test.\n\n $ cd release/tests/test_server\n $ $ERL_TOP/bin/erl -s ts install -s ts smoke_test batch -s init stop\n\nTo verify that everything is ok you should open `$ERL_TOP/release/tests/test_server/index.html`\nin your web browser and make sure that there are zero failed test cases.\n\n> #### Note {: .info }\n>\n> On builds without `crypto`, `ssl` and `ssh` there is a failed test case\n> for undefined functions. Verify that the failed test case log only shows calls\n> to skipped applications.","title":"Testing ### - Building and Installing Erlang/OTP","ref":"install.html#testing"},{"type":"extras","doc":"You are now ready to install the Erlang/OTP release!\nThe following command will install the release on your system.\n\n $ make install","title":"Installing ### - Building and Installing Erlang/OTP","ref":"install.html#installing"},{"type":"extras","doc":"You should now have a working release of Erlang/OTP!\nJump to [System Principles][] for instructions on running Erlang/OTP.\n\n[](){: #How-to-Build-and-Install-Erlang-OTP_How-to-Build-the-Documentation }","title":"Running ### - Building and Installing Erlang/OTP","ref":"install.html#running"},{"type":"extras","doc":"Make sure you're in the top directory in the source tree.\n\n $ cd $ERL_TOP\n\nIf you have just built Erlang/OTP in the current source tree, you have\nalready ran `configure` and do not need to do this again; otherwise, run\n`configure`.\n\n $ ./configure [Configure Args]\n\nWhen building the documentation you need a full Erlang/OTP-28.0-rc0 system in\nthe `$PATH`.\n\n $ export PATH=$ERL_TOP/bin:$PATH # Assuming bash/sh\n\nTo build `html` and `epub` docs you need to have [ExDoc v0.34.1](https://github.com/elixir-lang/ex_doc).\nSee [Building Documentation](#building-documentation) for information on how to\ninstall ExDoc.\n\nBuild the documentation using:\n\n $ make docs\n\nIt is possible to limit which types of documentation is build by passing the `DOC_TARGETS`\nenvironment variable to `make docs`.\n\n_Example_:\n\n $ make docs DOC_TARGETS=chunks\n\nThe currently available types are: `html` and `chunks`. Where:\n\n* *chunks* - Build [EEP-48](`e:kernel:eep48_chapter.md`) documentation chunks.\n* *html* - Build html and epub documentation.","title":"How to Build the Documentation ### - Building and Installing Erlang/OTP","ref":"install.html#how-to-build-the-documentation"},{"type":"extras","doc":"The documentation can be installed either using the `install-docs` target,\nor using the `release_docs` target.\n\n* If you have installed Erlang/OTP using the `install` target, install\n the documentation using the `install-docs` target. Install locations\n determined by `configure` will be used. `$DESTDIR` can be used the\n same way as when doing `make install`.\n\n $ make install-docs\n\n* If you have installed Erlang/OTP using the `release` target, install\n the documentation using the `release_docs` target. You typically want\n to use the same `RELEASE_ROOT` as when invoking `make release`.\n\n $ make release_docs RELEASE_ROOT= \n\nIt is possible to limit which types of documentation is released using the same `DOC_TARGETS`\nenvironment variable as when building documentation.","title":"How to Install the Documentation ### - Building and Installing Erlang/OTP","ref":"install.html#how-to-install-the-documentation"},{"type":"extras","doc":"After installation you can access the documentation by\n\n* Browsing the html pages by loading the page `/usr/local/lib/erlang/doc/erlang/index.html`\n or ` /lib/erlang/doc/erlang/index.html` if the prefix option has been used.\n\n* Read the embedded documentation by using the built-in shell functions `h/1,2,3` or\n `ht/1,2,3`.","title":"Accessing the Documentation ### - Building and Installing Erlang/OTP","ref":"install.html#accessing-the-documentation"},{"type":"extras","doc":"Pre-formatted [html documentation][] can be downloaded from .\n\nExtract the html archive in the installation directory.\n\n $ cd \n $ tar -zxf otp_html_28.0-rc0.tar.gz\n\nWhere ` ` is\n\n* ` /lib/erlang` if you have installed Erlang/OTP using\n `make install`.\n* `$DESTDIR /lib/erlang` if you have installed Erlang/OTP\n using `make install DESTDIR= `.\n* `RELEASE_ROOT` if you have installed using\n `make release RELEASE_ROOT= `.\n\n\nAdvanced configuration and build of Erlang/OTP\n----------------------------------------------\n\nIf you want to tailor your Erlang/OTP build and installation, please read\non for detailed information about the individual steps.\n\n[](){: #advanced-configuration-and-build-of-erlang-otp_make-and-ERLTOP }","title":"How to Install the Pre-formatted Documentation ### - Building and Installing Erlang/OTP","ref":"install.html#how-to-install-the-pre-formatted-documentation"},{"type":"extras","doc":"All the makefiles in the entire directory tree use the environment\nvariable `ERL_TOP` to find the absolute path of the installation. The\n`configure` script will figure this out and set it in the top level\nMakefile (which, when building, it will pass on). However, when\ndeveloping it is sometimes convenient to be able to run make in a\nsubdirectory. To do this you must set the `ERL_TOP` variable\nbefore you run make.\n\nFor example, assume your GNU make program is called `make` and you\nwant to rebuild the application `STDLIB`, then you could do:\n\n $ cd lib/stdlib; env ERL_TOP= make\n\nwhere ` ` would be what you find `ERL_TOP` is set to in the top level\nMakefile.","title":"make and $ERL_TOP ### - Building and Installing Erlang/OTP","ref":"install.html#make-and-erl_top"},{"type":"extras","doc":"Building Erlang/OTP can be done either by using the `$ERL_TOP/otp_build`\nscript, or by invoking `$ERL_TOP/configure` and `make` directly. Building using\n`otp_build` is easier since it involves fewer steps, but the `otp_build` build\nprocedure is not as flexible as the `configure`/`make` build procedure. The binary\nreleases for Windows that we deliver are built using `otp_build`.\n\n[]() {: #advanced-configuration-and-build-of-erlang-otp_configuring }","title":"otp_build vs configure/make ### - Building and Installing Erlang/OTP","ref":"install.html#otp_build-vs-configure-make"},{"type":"extras","doc":"The configure script is created by the GNU autoconf utility, which\nchecks for system specific features and then creates a number of makefiles.\n\nThe configure script allows you to customize a number of parameters;\ntype `./configure --help` or `./configure --help=recursive` for details.\n`./configure --help=recursive` will give help for all `configure` scripts in\nall applications.\n\nOne of the things you can specify is where Erlang/OTP should be installed. By\ndefault Erlang/OTP will be installed in `/usr/local/{bin,lib/erlang}`.\nTo keep the same structure but install in a different place, ` ` say,\nuse the `--prefix` argument like this: `./configure --prefix= `.\n\nSome of the available `configure` options are:\n\n* `--prefix=PATH` - Specify installation prefix.\n* `--disable-parallel-configure` - Disable parallel execution of\n `configure` scripts (parallel execution is enabled by default)\n* `--{enable,disable}-jit` - Force enabling or disabling of the JIT.\n* `--{enable,disable}-kernel-poll` - Kernel poll support (enabled by\n default if possible)\n* `--enable-m64-build` - Build 64-bit binaries using the `-m64` flag to\n `(g)cc`\n* `--enable-m32-build` - Build 32-bit binaries using the `-m32` flag to\n `(g)cc`\n* `--{enable,disable}-pie` - Build position independent executable binaries.\n* `--with-assumed-cache-line-size=SIZE` - Set assumed cache-line size in\n bytes. Default is 64. Valid values are powers of two between and\n including 16 and 8192. The runtime system use this value in order to\n try to avoid false sharing. A too large value wastes memory. A to\n small value will increase the amount of false sharing.\n* `--{with,without}-termcap` - termcap (without implies that only the old\n Erlang shell can be used)\n* `--with-javac=JAVAC` - Specify Java compiler to use\n* `--{with,without}-javac` - Java compiler (without implies that the\n `jinterface` application won't be built)\n* `--{enable,disable}-builtin-zlib` - Use the built-in source for zlib.\n* `--{enable,disable}-dynamic-ssl-lib` - Enable or disable dynamic OpenSSL\n libraries when linking the crypto NIF. By default dynamic linking is\n done unless it does not work or is if it is a Windows system.\n* `--{with,without}-ssl` - OpenSSL (without implies that the `crypto`,\n `ssh`, and `ssl` won't be built)\n* `--with-ssl=PATH` - Specify base location of OpenSSL include and lib\n directories.\n* `--with-ssl-incl=PATH` - Specify base location of OpenSSL `include`\n directory (if different than base location specified by --with-ssl=PATH).\n* `--with-ssl-zlib=PATH` - Path to static zlib library to link the\n crypto NIF with. This zlib library is most often not necessary but\n might be needed in order to link the NIF in some cases.\n* `--with-ssl-lib-subdir=RELATIVE_PATH` - Specify extra OpenSSL lib\n sub-directory to search in (relative to base directory).\n* `--with-ssl-rpath=yes|no|PATHS` - Runtime library path for OpenSSL.\n Default is `yes`, which equates to a number of standard locations. If\n `no`, then no runtime library paths will be used. Anything else should be\n a comma or colon separated list of paths.\n* `--with-libatomic_ops=PATH` - Use the `libatomic_ops` library for atomic\n memory accesses. If `configure` should inform you about no native atomic\n implementation available, you typically want to try using the\n `libatomic_ops` library. It can be downloaded from\n .\n* `--disable-smp-require-native-atomics` - By default `configure` will\n fail if an SMP runtime system is about to be built, and no implementation\n for native atomic memory accesses can be found. If this happens, you are\n encouraged to find a native atomic implementation that can be used, e.g.,\n using `libatomic_ops`, but by passing `--disable-smp-require-native-atomics`\n you can build using a fallback implementation based on mutexes or spinlocks.\n Performance of the SMP runtime system will however suffer immensely without\n an implementation for native atomic memory accesses.\n* `--enable-static-{nifs,drivers}` - To allow usage of nifs and drivers on OSs\n that do not support dynamic linking of libraries it is possible to statically\n link nifs and drivers with the main Erlang VM binary. This is done by passing\n a comma separated list to the archives that you want to statically link. e.g.\n `--enable-static-nifs=/home/$USER/my_nif.a`. The paths have to be absolute.\n For drivers, the driver name has to be the same as the filename. You also\n have to define `STATIC_ERLANG_NIF_LIBNAME` (see `erl_nif` documentation) or\n `STATIC_ERLANG_DRIVER` when compiling the .o files for the nif/driver.\n If your nif/driver depends on some other dynamic library, you now have to link\n that to the Erlang VM binary. This is easily achieved by passing `LIBS=-llibname`\n to configure.\n* `--without-$app` - By default all applications in Erlang/OTP will be included\n\tin a release. If this is not wanted it is possible to specify that Erlang/OTP\n\tshould be compiled without one or more applications, i.e. `--without-wx`. There is\n\tno automatic dependency handling between applications. If you disable\n\tan application that another application depends on, you also have to disable the\n\tdependent application.\n* `--enable-gettimeofday-as-os-system-time` - Force usage of `gettimeofday()` for\n OS system time.\n* `--enable-prefer-elapsed-monotonic-time-during-suspend` - Prefer an OS monotonic\n time source with elapsed time during suspend.\n* `--disable-prefer-elapsed-monotonic-time-during-suspend` - Do not prefer an OS\n monotonic time source with elapsed time during suspend.\n* `--with-clock-resolution=high|low` - Try to find clock sources for OS system\n time, and OS monotonic time with higher or lower resolution than chosen by\n default. Note that both alternatives may have a negative impact on the performance\n and scalability compared to the default clock sources chosen.\n* `--enable-ensure-os-monotonic-time` - Enable functionality ensuring the\n monotonicity of monotonic timestamps delivered by the OS. When a\n non-monotonic timestamp is detected, it will be replaced by the last\n delivered monotonic timestamp before being used by Erlang's time\n functionality. Note that you do *not* want to enable this unless the OS\n monotonic time source on the system fails to produce monotonic timestamps.\n This since ensuring the monotonicity of OS monotonic timestamps will hurt\n scalability and performance of the system.\n* `--disable-saved-compile-time` - Disable saving of compile date and time\n in the emulator binary.\n* `--enable-ei-dynamic-lib` - Make erl_interface build a shared library in addition\n to the archive normally built.\n* `--disable-year2038` - Don't support timestamps after mid-January 2038. By\n default `configure` will try to enable support for timestamps after\n mid-January 2038. If it cannot figure out how to do that, it will fail and\n abort with an error. If you anyway want to build the system knowing that the\n system won't function properly after mid-January 2038, you can pass this\n option which will enable `configure` to continue without support for\n timestamps after mid-January 2038. This is typically only an issue on 32-bit\n platforms.\n\nIf you or your system has special requirements please read the `Makefile` for\nadditional configuration information.\n\n[](){: #advanced-configuration-and-build-of-erlang-otp_Configuring_Important-Variables-Inspected-by-configure }\n\n#### Important Variables Inspected by configure ####\n\n##### Compiler and Linker #####\n\n* `CC` - C compiler.\n* `CFLAGS` - C compiler flags. Defaults to \"-g -O2\". If you set it,\n these will be removed.\n* `STATIC_CFLAGS` - Static C compiler flags.\n* `CFLAG_RUNTIME_LIBRARY_PATH` - This flag should set runtime library\n search path for the shared libraries. Note that this actually is a\n linker flag, but it needs to be passed via the compiler.\n* `CPP` - C pre-processor.\n* `CPPFLAGS` - C pre-processor flags.\n* `CXX` - C++ compiler.\n* `CXXFLAGS` - C++ compiler flags.\n* `LD` - Linker.\n* `LDFLAGS` - Linker flags.\n* `LIBS` - Libraries.\n\n##### Dynamic Erlang Driver Linking #####\n\n> #### Note {: .info }\n>\n> Either set all or none of the `DED_LD*` variables (with the exception\n> of `DED_LDFLAGS_CONFTEST`).\n\n* `DED_LD` - Linker for Dynamically loaded Erlang Drivers.\n* `DED_LDFLAGS` - Linker flags to use with `DED_LD`.\n* `DED_LDFLAGS_CONFTEST` - Linker flags to use with `DED_LD` in configure\n link tests if `DED_LDFLAGS` cannot be used in such tests. If not set,\n `DED_LDFLAGS` will be used in configure tests.\n* `DED_LD_FLAG_RUNTIME_LIBRARY_PATH` - This flag should set runtime library\n search path for shared libraries when linking with `DED_LD`.\n\n##### Large File Support #####\n\n> #### Note {: .info }\n>\n> Either set all or none of the `LFS_*` variables.\n\n* `LFS_CFLAGS` - Large file support C compiler flags.\n* `LFS_LDFLAGS` - Large file support linker flags.\n* `LFS_LIBS` - Large file support libraries.\n\n##### Other Tools #####\n\n* `RANLIB` - `ranlib` archive index tool.\n* `AR` - `ar` archiving tool.\n* `GETCONF` - `getconf` system configuration inspection tool. `getconf` is\n currently used for finding out large file support flags to use, and\n on Linux systems for finding out if we have an NPTL thread library or\n not.\n\n#### Updating configure Scripts ####\n\nGenerated `configure` scripts are nowadays included in the git repository.\n\nIf you modify any `configure.in` files or the `erts/aclocal.m4` file, you need\nto regenerate `configure` scripts before the changes will take effect. First\nensure that you have GNU `autoconf` of version 2.69 in your path. Then execute\n`./otp_build update_configure [--no-commit]` in the `$ERL_TOP` directory. The\n`otp_build` script will verify that `autoconf` is of correct version and will\nrefuse to update the `configure` scripts if it is of any other version.\n\n[](){: #advanced-configuration-and-build-of-erlang-otp_configuring_atomic-memory-operations-and-the-vm }\n\n#### Atomic Memory Operations and the VM ####\n\nThe VM with SMP support makes quite a heavy use of atomic memory operations.\nAn implementation providing native atomic memory operations is therefore very\nimportant when building Erlang/OTP. By default the VM will refuse to build\nif native atomic memory operations are not available.\n\nErlang/OTP itself provides implementations of native atomic memory operations\nthat can be used when compiling with a `gcc` compatible compiler for 32/64-bit\nx86, 32/64-bit SPARC V9, 32-bit PowerPC, or 32-bit Tile. When compiling with\na `gcc` compatible compiler for other architectures, the VM may be able to make\nuse of native atomic operations using the `__atomic_*` builtins (may be\navailable when using a `gcc` of at least version 4.7) and/or using the\n`__sync_*` builtins (may be available when using a `gcc` of at least version\n4.1). If only the `gcc`'s `__sync_*` builtins are available, the performance\nwill suffer. Such a configuration should only be used as a last resort. When\ncompiling on Windows using a MicroSoft Visual C++ compiler native atomic\nmemory operations are provided by Windows APIs.\n\nNative atomic implementation in the order preferred:\n1. The implementation provided by Erlang/OTP.\n2. The API provided by Windows.\n3. The implementation based on the `gcc` `__atomic_*` builtins.\n4. If none of the above are available for your architecture/compiler, you\n are recommended to build and install [libatomic_ops][] before building\n Erlang/OTP. The `libatomic_ops` library provides native atomic memory\n operations for a variety of architectures and compilers. When building\n Erlang/OTP you need to inform the build system of where the\n `libatomic_ops` library is installed using the\n `--with-libatomic_ops=PATH` `configure` switch.\n5. As a last resort, the implementation solely based on the `gcc`\n `__sync_*` builtins. This will however cause lots of expensive and\n unnecessary memory barrier instructions to be issued. That is,\n performance will suffer. The `configure` script will warn at the end\n of its execution if it cannot find any other alternative than this.","title":"Configuring ### - Building and Installing Erlang/OTP","ref":"install.html#configuring"},{"type":"extras","doc":"Building Erlang/OTP on a relatively fast computer takes approximately\n5 minutes. To speed it up, you can utilize parallel make with the `-j ` option.\n\n $ export MAKEFLAGS=-j8 # Assuming bash/sh\n $ make\n\nIf you've upgraded the source with a patch you may need to clean up from previous\nbuilds before the new build.\nMake sure to read the [Pre-built Source Release][] section below before doing a `make clean`.\n\nOther useful information can be found here:\n* [Erlang/OTP GitHub wiki](https://github.com/erlang/otp/wiki)\n* [Contributing to Erlang/OTP](https://github.com/erlang/otp/blob/master/CONTRIBUTING.md)\n* [Developing Erlang/OTP](https://github.com/erlang/otp/blob/master/HOWTO/DEVELOPMENT.md)\n\n[](){: #advanced-configuration-and-build-of-erlang-otp_Building_macOS-Darwin }\n\n#### macOS (Darwin) ####\n\nMake sure that the command `hostname` returns a valid fully qualified host\nname (this is configured in `/etc/hostconfig`). Otherwise you might experience\nproblems when running distributed systems.\n\nIf you develop linked-in drivers (shared library) you need to link using\n`gcc` and the flags `-bundle -flat_namespace -undefined suppress`. You also\ninclude `-fno-common` in `CFLAGS` when compiling. Use `.so` as the library\nsuffix.\n\nIf you have Xcode 4.3, or later, you will also need to download\n\"Command Line Tools\" via the Downloads preference pane in Xcode.\n\n[](){: #advanced-configuration-and-build-of-erlang-otp_Building_Building-with-Wx }\n\n#### Building with Wx ####\n\nwxWidgets-3.2.x is recommended for building the `wx` application\n(wxWidgets-3.0.x will also work). Download it from\n or from\n . It is recommended to use the\nlatest release in the 3.2 series, which at the time of writing\nis 3.2.2.1.\n\nNote that the wxWidgets-3.3 versions are experimental, but they should\nalso work if 3.0 compatibility is enabled by adding\n`--enable-compat30` to the `configure` commands below.\n\nOn all other platforms, a shared library is built as follows:\n\n $ ./configure --prefix=/usr/local\n $ make && sudo make install\n $ export PATH=/usr/local/bin:$PATH\n\nOn Linux, a static library is built as follows:\n\n $ export CFLAGS=-fPIC\n $ export CXXFLAGS=-fPIC\n $ ./configure --prefix=/usr/local --disable-shared\n $ make && sudo make install\n $ export PATH=/usr/local/bin:$PATH\n\nOn macOs, a static library compatible with macOS 13 (Ventura) and later is built\nas follows:\n\n $ ./configure --prefix=/usr/local --with-macosx-version-min=13.0 --disable-shared\n $ make\n $ sudo make install\n $ export PATH=/usr/local/bin:$PATH\n\nVerify that the build and installation succeeded:\n\n $ which wx-config && wx-config --version-full\n\nExpected output is `/usr/local/bin/wx-config` on one line, followed by the full\nversion number. For example, if you built version 3.2.2.1, the expected output is:\n\n /usr/local/bin/wx-config\n 3.2.2.1\n\nBuild Erlang/OTP in the usual way. To verify that `wx` application is\nworking run the following command:\n\n $ erl -run wx demo\n\n\n[](){: #advanced-configuration-and-build-of-erlang-otp_Building_Prebuilt-Source-Release }\n\n#### Pre-built Source Release ####\n\nThe source release is delivered with a lot of platform independent\nbuild results already pre-built. If you want to remove these pre-built\nfiles, invoke `./otp_build remove_prebuilt_files` from the `$ERL_TOP`\ndirectory. After you have done this, you can build exactly the same way\nas before, but the build process will take a much longer time.\n\n> #### Warning {: .warning }\n>\n> Doing `make clean` in an arbitrary directory of the source\n> tree, may remove files needed for bootstrapping the build.\n>\n> Doing `./otp_build save_bootstrap` from the `$ERL_TOP` directory before\n> doing `make clean` will ensure that it will be possible to build after\n> doing `make clean`. `./otp_build save_bootstrap` will be invoked\n> automatically when `make` is invoked from `$ERL_TOP` with either the\n> `clean` target, or the default target. It is also automatically invoked\n> if `./otp_build remove_prebuilt_files` is invoked.\n>\n> If you need to verify the bootstrap beam files match the provided\n> source files, use `./otp_build update_primary` to create a new commit that\n> contains differences, if any exist.\n\n[](){: #advanced-configuration-and-build-of-erlang-otp_building_how-to-build-a-debug-enabled-erlang-runtime-system }\n\n#### How to Build a Debug Enabled Erlang RunTime System ####\n\nAfter completing all the normal building steps described above a debug\nenabled runtime system can be built. To do this you have to change\ndirectory to `$ERL_TOP/erts/emulator` and execute:\n\n $ (cd $ERL_TOP/erts/emulator && make debug)\n\nThis will produce a `beam.debug.smp` executable. The\nfile are installed along side with the normal (opt) version `beam.smp`.\n\nTo start the debug enabled runtime system execute:\n\n $ $ERL_TOP/bin/cerl -debug\n\nThe debug enabled runtime system features lock violation checking,\nassert checking and various sanity checks to help a developer ensure\ncorrectness. Some of these features can be enabled on a normal beam\nusing appropriate configure options.\n\nThere are other types of runtime systems that can be built as well\nusing the similar steps just described.\n\n $ (cd $ERL_TOP/erts/emulator && make $TYPE)\n\nwhere `$TYPE` is `opt`, `gcov`, `gprof`, `debug`, `valgrind`, `asan` or `lcnt`.\nThese different beam types are useful for debugging and profiling\npurposes.","title":"Building ### - Building and Installing Erlang/OTP","ref":"install.html#building"},{"type":"extras","doc":"* Staged install using [DESTDIR][]. You can perform the install\n phase in a temporary directory and later move the installation into\n its correct location by use of the `DESTDIR` variable:\n\n $ make DESTDIR= install\n\n The installation will be created in a location prefixed by `$DESTDIR`.\n It can, however, not be run from there. It needs to be moved into the\n correct location before it can be run. If `DESTDIR` have not been set\n but `INSTALL_PREFIX` has been set, `DESTDIR` will be set to\n `INSTALL_PREFIX`. Note that `INSTALL_PREFIX` in pre R13B04 was buggy\n and behaved as `EXTRA_PREFIX` (see below). There are lots of areas of\n use for an installation procedure using `DESTDIR`, e.g. when creating\n a package, cross compiling, etc. Here is an example where the\n installation should be located under `/opt/local`:\n\n $ ./configure --prefix=/opt/local\n $ make\n $ make DESTDIR=/tmp/erlang-build install\n $ cd /tmp/erlang-build/opt/local\n $ # gnu-tar is used in this example\n $ tar -zcf /home/me/my-erlang-build.tgz *\n $ su -\n Password: *****\n $ cd /opt/local\n $ tar -zxf /home/me/my-erlang-build.tgz\n\n* Install using the `release` target. Instead of doing `make install` you\n can create the installation in whatever directory you like using the\n `release` target and run the `Install` script yourself. `RELEASE_ROOT`\n is used for specifying the directory where the installation should be\n created. This is what by default ends up under `/usr/local/lib/erlang`\n if you do the install using `make install`. All installation paths\n provided in the `configure` phase are ignored, as well as `DESTDIR`,\n and `INSTALL_PREFIX`. If you want links from a specific `bin` directory\n to the installation you have to set those up yourself. An example where\n Erlang/OTP should be located at `/home/me/OTP`:\n\n $ ./configure\n $ make\n $ make RELEASE_ROOT=/home/me/OTP release\n $ cd /home/me/OTP\n $ ./Install -minimal /home/me/OTP\n $ mkdir -p /home/me/bin\n $ cd /home/me/bin\n $ ln -s /home/me/OTP/bin/erl erl\n $ ln -s /home/me/OTP/bin/erlc erlc\n $ ln -s /home/me/OTP/bin/escript escript\n ...\n\n The `Install` script should currently be invoked as follows in the\n directory where it resides (the top directory):\n\n $ ./Install [-cross] [-minimal|-sasl] \n\n where:\n\n * `-minimal` Creates an installation that starts up a minimal amount\n of applications, i.e., only `kernel` and `stdlib` are started. The\n minimal system is normally enough, and is what `make install` uses.\n * `-sasl` Creates an installation that also starts up the `sasl`\n application.\n * `-cross` For cross compilation. Informs the install script that it\n is run on the build machine.\n * ` ` - The absolute path to the Erlang installation to use\n at run time. This is often the same as the current working directory,\n but does not have to be. It can follow any other path through the\n file system to the same directory.\n\n If neither `-minimal`, nor `-sasl` is passed as argument you will be\n prompted.\n\n* Test install using `EXTRA_PREFIX`. The content of the `EXTRA_PREFIX`\n variable will prefix all installation paths when doing `make install`.\n Note that `EXTRA_PREFIX` is similar to `DESTDIR`, but it does *not* have\n the same effect as `DESTDIR`. The installation can and have to be run\n from the location specified by `EXTRA_PREFIX`. That is, it can be useful\n if you want to try the system out, running test suites, etc, before doing\n the real install without `EXTRA_PREFIX`.\n\n#### Symbolic Links in --bindir ####\n\nWhen doing `make install` and the default installation prefix is used,\nrelative symbolic links will be created from `/usr/local/bin` to all public\nErlang/OTP executables in `/usr/local/lib/erlang/bin`. The installation phase\nwill try to create relative symbolic links as long as `--bindir` and the\nErlang bin directory, located under `--libdir`, both have `--exec-prefix` as\nprefix. Where `--exec-prefix` defaults to `--prefix`. `--prefix`,\n`--exec-prefix`, `--bindir`, and `--libdir` are all arguments that can be\npassed to `configure`. One can force relative, or absolute links by passing\n`BINDIR_SYMLINKS=relative|absolute` as arguments to `make` during the install\nphase. Note that such a request might cause a failure if the request cannot\nbe satisfied.","title":"Installing ### - Building and Installing Erlang/OTP","ref":"install.html#installing"},{"type":"extras","doc":"Erlang/OTP are currently tested on the following hardware and operating systems.\nThis is not an exhaustive list, but we try to keep it as up to date as possible.\n\nArchitecture\n\n* x86, x86-64\n* Aarch32, Aarch64\n* powerpc, powerpc64le\n* Apple M1, M2, M2 Pro\n\nOperating system\n\n* Fedora 31\n* FreeBSD\n* macOS 13 - 14\n* MontaVista 4\n* NetBSD\n* OpenBSD\n* SLES 10, 11, 12\n* SunOS 5.11\n* Ubuntu 10.04 - 22.04\n* Windows 11, Windows 10, Windows Server 2019\n\n[DESTDIR]: http://www.gnu.org/prep/standards/html_node/DESTDIR.html\n[Building in Git]: #advanced-configuration-and-build-of-erlang-otp_Building_Within-Git\n[Advanced Configure]: #advanced-configuration-and-build-of-erlang-otp_Configuring\n[Pre-built Source Release]: #advanced-configuration-and-build-of-erlang-otp_Building_Prebuilt-Source-Release\n[make and $ERL_TOP]: #advanced-configuration-and-build-of-erlang-otp_make-and-ERLTOP\n[html documentation]: https://github.com/erlang/otp/releases/download/OTP-28.0-rc0/otp_doc_html_28.0-rc0.tar.gz\n[the released source tar ball]: https://github.com/erlang/otp/releases/download/OTP-28.0-rc0/otp_src_28.0-rc0.tar.gz\n[System Principles]: `e:system:system_principles.md`\n[native build]: #how-to-build-and-install-erlang-otp\n[cross build]: INSTALL-CROSS.md\n[Required Utilities]: #Required-Utilities\n[Optional Utilities]: #Optional-Utilities\n[Building on a Mac]: #advanced-configuration-and-build-of-erlang-otp_Building_macOS-Darwin\n[Building with Wx]: #advanced-configuration-and-build-of-erlang-otp_Building_Building-with-Wx\n[libatomic_ops]: https://github.com/ivmai/libatomic_ops/","title":"Erlang/OTP test architectures ## - Building and Installing Erlang/OTP","ref":"install.html#erlang-otp-test-architectures"},{"type":"extras","doc":"Cross Compiling Erlang/OTP\n==========================\n\nIntroduction\n------------\n\nThis document describes how to cross compile Erlang/OTP-28. \nYou are advised to read the whole document before attempting to cross\ncompile Erlang/OTP. However, before reading this document, you should read\n[Building and Installing Erlang/OTP][] which describes building\nand installing Erlang/OTP in general.\n\nIn the text below `$ERL_TOP` is the top directory in the Erlang/OTP source tree.","title":"Cross Compiling Erlang/OTP","ref":"install-cross.html"},{"type":"extras","doc":"Building Erlang/OTP can be done either by using the `$ERL_TOP/otp_build`\nscript, or by invoking `$ERL_TOP/configure` and `make` directly. Building using\n`otp_build` is easier since it involves fewer steps, but the `otp_build` build\nprocedure is not as flexible as the `configure`/`make` build procedure. Note\nthat `otp_build configure` will produce a default configuration that differs\nfrom what `configure` will produce by default. For example, currently\n`--disable-dynamic-ssl-lib` is added to the `configure` command line arguments\nunless `--enable-dynamic-ssl-lib` has been explicitly passed. The defaults used by\n`otp_build configure` may change at any time without prior notice.","title":"otp_build Versus configure/make ### - Cross Compiling Erlang/OTP","ref":"install-cross.html#otp_build-versus-configure-make"},{"type":"extras","doc":"The `$ERL_TOP/xcomp/erl-xcomp.conf.template` file contains all available cross\nconfiguration variables and can be used as a template when creating a cross\ncompilation configuration. All [cross configuration variables][] are also\nlisted at the end of this document. For examples of working cross\nconfigurations see the `$ERL_TOP/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf`\nfile and the `$ERL_TOP/xcomp/erl-xcomp-x86_64-saf-linux-gnu.conf` file. If the\ndefault behavior of a variable is satisfactory, the variable does not need to\nbe set. However, the `configure` script will issue a warning when a default\nvalue is used. When a variable has been set, no warning will be issued.\n\nA cross configuration file can be passed to `otp_build configure` using the\n`--xcomp-conf` command line argument. Note that `configure` does not accept\nthis command line argument. When using the `configure` script directly, pass\nthe configuration variables as arguments to `configure` using a\n` = ` syntax. Variables can also be passed as environment\nvariables to `configure`. However, if you pass the configuration in the\nenvironment, make sure to unset all of these environment variables before\ninvoking `make`; otherwise, the environment variables might set make variables\nin some applications, or parts of some applications, and you may end up with\nan erroneously configured build.","title":"Cross Configuration ### - Cross Compiling Erlang/OTP","ref":"install-cross.html#cross-configuration"},{"type":"extras","doc":"All Erlang/OTP applications except the `wx` application can be cross compiled.\nThe build of the `wx` driver will currently be automatically disabled when\ncross compiling.","title":"What can be Cross Compiled? ### - Cross Compiling Erlang/OTP","ref":"install-cross.html#what-can-be-cross-compiled"},{"type":"extras","doc":"The build system, including cross compilation configuration variables used,\nmay be subject to non backward compatible changes without prior notice.\nCurrent cross build system has been tested when cross compiling some Linux/GNU\nsystems, but has only been partly tested on other platforms.","title":"Compatibility ### - Cross Compiling Erlang/OTP","ref":"install-cross.html#compatibility"},{"type":"extras","doc":"Please submit any patches for cross compiling in a way consistent with this\nsystem. All input is welcome as we have a very limited set of cross compiling\nenvironments to test with. If a new configuration variable is needed, add it\nto `$ERL_TOP/xcomp/erl-xcomp.conf.template`, and use it in `configure.in`.\nOther files that might need to be updated are:\n\n- `$ERL_TOP/xcomp/erl-xcomp-vars.sh`\n- `$ERL_TOP/erl-build-tool-vars.sh`\n- `$ERL_TOP/erts/aclocal.m4`\n- `$ERL_TOP/xcomp/README.md`\n- `$ERL_TOP/xcomp/erl-xcomp-*.conf`\n\nNote that this might be an incomplete list of files that need to be updated.\n\nGeneral information on how to submit patches can be found at:\n \n\nBuild and Install Procedure\n---------------------------\n\nWe will first go through the `configure`/`make` build procedure which people\nprobably are most familiar with.","title":"Patches ### - Cross Compiling Erlang/OTP","ref":"install-cross.html#patches"},{"type":"extras","doc":"Change directory into the top directory of the Erlang/OTP source tree.\n\n $ cd $ERL_TOP\n\nIn order to compile Erlang code, a small Erlang bootstrap system has to be\nbuilt, or an Erlang/OTP system of the same release as the one being built\nhas to be provided in the `$PATH`. The Erlang/OTP for the target system will\nbe built using this Erlang system, together with the cross compilation tools\nprovided.\n\nIf you want to build using a compatible Erlang/OTP system in the `$PATH`,\njump to [Cross Building the System].\n\n#### Building a Bootstrap System ####\n\n $ ./configure --enable-bootstrap-only\n $ make\n\nThe `--enable-bootstrap-only` argument to `configure` isn't strictly necessary,\nbut will speed things up. It will only run `configure` in applications\nnecessary for the bootstrap, and will disable a lot of things not needed by\nthe bootstrap system. If you run `configure` without `--enable-boostrap-only`\nyou also have to run make as `make bootstrap`; otherwise, the whole system will\nbe built.\n\n#### Cross Building the System #### {: #cross-building-the-system }\n\n $ ./configure --host= --build= [Other Config Args]\n $ make\n\n` ` is the host/target system that you build for. It does not have to be\na full `CPU-VENDOR-OS` triplet, but can be. The full canonicalized\n`CPU-VENDOR-OS` triplet will be created by executing\n`$ERL_TOP/make/autoconf/config.sub `. If `config.sub` fails, you need\nto be more specific.\n\n` ` should equal the `CPU-VENDOR-OS` triplet of the system that you\nbuild on. If you execute `$ERL_TOP/make/autoconf/config.guess`, it will in\nmost cases print the triplet you want to use for this.\n\nThe use of ` ` and ` ` values that differ will trigger cross\ncompilation. Note that if ` ` and ` ` differ, the canonicalized\nvalues of ` ` and ` ` must also differ. If they do not, the\nconfiguration will fail.\n\nPass the cross compilation variables as command line arguments to `configure`\nusing a ` = ` syntax.\n\n> #### Note {: .info }\n>\n> You can *not* pass a configuration file using the `--xcomp-conf`\n> argument when you invoke `configure` directly. The `--xcomp-conf` argument\n> can only be passed to `otp_build configure`.\n\n`make` will verify that the Erlang/OTP system used when building is of the\nsame release as the system being built, and will fail if this is not the case.\nIt is possible, however not recommended, to force the cross compilation even\nthough the wrong Erlang/OTP system is used. This by invoking `make` like this:\n`make ERL_XCOMP_FORCE_DIFFERENT_OTP=yes`.\n\n> #### Warning {: .warning }\n>\n> Invoking `make ERL_XCOMP_FORCE_DIFFERENT_OTP=yes` might fail,\n> silently produce suboptimal code, or silently produce erroneous code.\n\n#### Installing ####\n\nYou can either install using the [Installing Using Paths Determined by configure](#installing-using-paths-determined-by-configure), or [install manually](#installing-manually).\n\n[](){: #installing-using-paths-determined-by-configure }\n\n##### Installing Using Paths Determined by configure #####\n\n $ make install DESTDIR= \n\n`make install` will install at a location specified when doing `configure`.\n`configure` arguments specifying where the installation should reside are for\nexample: `--prefix`, `--exec-prefix`, `--libdir`, `--bindir`, etc. By default\nit will install under `/usr/local`. You typically do not want to install your\ncross build under `/usr/local` on your build machine. Using [DESTDIR][]\nwill cause the installation paths to be prefixed by `$DESTDIR`. This makes it\npossible to install and package the installation on the build machine without\nhaving to place the installation in the same directory on the build machine as\nit should be executed from on the target machine.\n\nWhen `make install` has finished, change directory into `$DESTDIR`, package\nthe system, move it to the target machine, and unpack it. Note that the\ninstallation will only be working on the target machine at the location\ndetermined by `configure`.\n\n[](){: #installing-manually }\n\n##### Installing Manually #####\n\n $ make release RELEASE_ROOT= \n\n`make release` will copy what you have built for the target machine to\n` `. The `Install` script will not be run. The content of\n` ` is what by default ends up in `/usr/local/lib/erlang`.\n\nThe `Install` script used when installing Erlang/OTP requires common Unix\ntools such as `sed` to be present in your `$PATH`. If your target system\ndoes not have such tools, you need to run the `Install` script on your\nbuild machine before packaging Erlang/OTP. The `Install` script should\ncurrently be invoked as follows in the directory where it resides\n(the top directory):\n\n $ ./Install [-cross] [-minimal|-sasl] \n\nwhere:\n\n* `-minimal` Creates an installation that starts up a minimal amount\n of applications, i.e., only `kernel` and `stdlib` are started. The\n minimal system is normally enough, and is what `make install` uses.\n* `-sasl` Creates an installation that also starts up the `sasl`\n application.\n* `-cross` For cross compilation. Informs the install script that it\n is run on the build machine.\n* ` ` - The absolute path to the Erlang installation to use\n at run time. This is often the same as the current working directory,\n but does not have to be. It can follow any other path through the file\n system to the same directory.\n\nIf neither `-minimal`, nor `-sasl` is passed as argument you will be\nprompted.\n\n[](){: #install-release }\n\nYou can now either do:\n\n* Decide where the installation should be located on the target machine,\n run the `Install` script on the build machine, and package the installed\n installation. The installation just need to be unpacked at the right\n location on the target machine:\n\n $ cd \n $ ./Install -cross [-minimal|-sasl] \n\nor:\n\n* Package the installation in ` `, place it wherever you want\n on your target machine, and run the `Install` script on your target\n machine:\n\n $ cd \n $ ./Install [-minimal|-sasl]","title":"Building With configure/make Directly ### - Cross Compiling Erlang/OTP","ref":"install-cross.html#building-with-configure-make-directly"},{"type":"extras","doc":"$ cd $ERL_TOP\n\n $ ./otp_build configure --xcomp-conf= [Other Config Args]\n\nalternatively:\n\n $ ./otp_build configure --host= --build= [Other Config Args]\n\nIf you have your cross compilation configuration in a file, pass it using the\n`--xcomp-conf= ` command line argument. If not, pass `--host= `,\n`--build= `, and the configuration variables using a ` = `\nsyntax on the command line (same as in [Cross Building the System]). Note that ` ` and ` `\nhave to be passed one way or the other; either by using `erl_xcomp_host= `\nand `erl_xcomp_build= ` in the configuration file, or by using the\n`--host= `, and `--build= ` command line arguments.\n\n`otp_build configure` will configure both for the bootstrap system on the\nbuild machine and the cross host system.\n\n $ ./otp_build boot -a\n\n`otp_build boot -a` will first build a bootstrap system for the build machine\nand then do the cross build of the system.\n\n $ ./otp_build release -a \n\n`otp_build release -a` will do the same as `make release` in [Installing Manually],\nand you will after this have to do a [manual ./Install](#install-release) on either\nthe host or target.\n\nBuilding and Installing the Documentation\n-----------------------------------------\n\nAfter the system has been cross built you can build and install the\ndocumentation the same way as after a native build of the system. See the\n[How to Build the Documentation][] section in the [Building and Installing Erlang/OTP][]\ndocument for information on how to build the documentation.\n\nTesting the cross compiled system\n---------------------------------\n\nSome of the tests that come with erlang use native code to test. This means\nthat when cross compiling erlang you also have to cross compile test suites\nin order to run tests on the target host. To do this you first have to release\nthe tests as usual.\n\n $ make release_tests\n\nor\n\n $ ./otp_build tests\n\nThe tests will be released into `$ERL_TOP/release/tests`. After releasing the\ntests you have to install the tests on the build machine. You supply the same\nxcomp file as to `./otp_build` in [Building With the otp_build Script](#building-with-the-otp_build-script).\n\n $ cd $ERL_TOP/release/tests/test_server/\n $ $ERL_TOP/bootstrap/bin/erl -eval 'ts:install([{xcomp,\" \"}])' -s ts compile_testcases -s init stop\n\nYou should get a lot of printouts as the testcases are compiled. Once done you\nshould copy the entire `$ERL_TOP/release/tests` folder to the cross host system.\n\nThen go to the cross host system and setup the erlang installed\nto be in your `$PATH`. Then go to what previously was\n`$ERL_TOP/release/tests/test_server` and issue the following command.\n\n $ erl -s ts install -s ts run all_tests -s init stop\n\nThe configure should be skipped and all tests should hopefully pass. For more\ndetails about how to use ts run `erl -s ts help -s init stop`\n\nCurrently Used Configuration Variables\n--------------------------------------\n\nNote that you cannot define arbitrary variables in a cross compilation\nconfiguration file. Only the ones listed below will be guaranteed to be\nvisible throughout the whole execution of all `configure` scripts. Other\nvariables needs to be defined as arguments to `configure` or exported in\nthe environment.","title":"Building With the otp_build Script ### - Cross Compiling Erlang/OTP","ref":"install-cross.html#building-with-the-otp_build-script"},{"type":"extras","doc":"Variables in this section are only used, when configuring Erlang/OTP for\ncross compilation using `$ERL_TOP/otp_build configure`.\n\n> #### Note {: .info }\n>\n> These variables currently have *no* effect if you configure using\n> the `configure` script directly.\n\n* `erl_xcomp_build` - The build system used. This value will be passed as\n `--build=$erl_xcomp_build` argument to the `configure` script. It does\n not have to be a full `CPU-VENDOR-OS` triplet, but can be. The full\n `CPU-VENDOR-OS` triplet will be created by\n `$ERL_TOP/make/autoconf/config.sub $erl_xcomp_build`. If set to `guess`,\n the build system will be guessed using\n `$ERL_TOP/make/autoconf/config.guess`.\n\n* `erl_xcomp_host` - Cross host/target system to build for. This value will\n be passed as `--host=$erl_xcomp_host` argument to the `configure` script.\n It does not have to be a full `CPU-VENDOR-OS` triplet, but can be. The\n full `CPU-VENDOR-OS` triplet will be created by\n `$ERL_TOP/make/autoconf/config.sub $erl_xcomp_host`.\n\n* `erl_xcomp_configure_flags` - Extra configure flags to pass to the\n `configure` script.","title":"Variables for otp_build Only ### - Cross Compiling Erlang/OTP","ref":"install-cross.html#variables-for-otp_build-only"},{"type":"extras","doc":"If the cross compilation tools are prefixed by ` -` you probably do\nnot need to set these variables (where ` ` is what has been passed as\n`--host= ` argument to `configure`). Compiler and other tools can\notherwise be identified via variables passed as arguments on the command\nline to `configure`, in then xcomp file, or as environment variables. For\nmore information see the [Important Variables Inspected by configure][]\nsection in [Building and Installing Erlang/OTP][].","title":"Cross Compiler and Other Tools ### - Cross Compiling Erlang/OTP","ref":"install-cross.html#cross-compiler-and-other-tools"},{"type":"extras","doc":"* `erl_xcomp_sysroot` - The absolute path to the system root of the cross\n compilation environment. Currently, the `crypto`, `odbc`, `ssh` and\n `ssl` applications need the system root. These applications will be\n skipped if the system root has not been set. The system root might be\n needed for other things too. If this is the case and the system root\n has not been set, `configure` will fail and request you to set it.\n\n* `erl_xcomp_isysroot` - The absolute path to the system root for includes\n of the cross compilation environment. If not set, this value defaults\n to `$erl_xcomp_sysroot`, i.e., only set this value if the include system\n root path is not the same as the system root path.","title":"Cross System Root Locations ### - Cross Compiling Erlang/OTP","ref":"install-cross.html#cross-system-root-locations"},{"type":"extras","doc":"These tests cannot (always) be done automatically when cross compiling. You\nusually do not need to set these variables.\n\n> #### Warning {: .warning }\n>\n> Setting these variables wrong may cause hard to detect\n> runtime errors. If you need to change these values, *really* make sure\n> that the values are correct.\n\n> #### Note {: .info }\n>\n> Some of these values will override results of tests performed\n> by `configure`, and some will not be used until `configure` is sure that\n> it cannot figure the result out.\n\nThe `configure` script will issue a warning when a default value is used.\nWhen a variable has been set, no warning will be issued.\n\n* `erl_xcomp_after_morecore_hook` - `yes|no`. Defaults to `no`. If `yes`,\n the target system must have a working `__after_morecore_hook` that can be\n used for tracking used `malloc()` implementations core memory usage.\n This is currently only used by unsupported features.\n\n* `erl_xcomp_bigendian` - `yes|no`. No default. If `yes`, the target system\n must be big endian. If `no`, little endian. This can often be\n automatically detected, but not always. If not automatically detected,\n `configure` will fail unless this variable is set. Since no default\n value is used, `configure` will try to figure this out automatically.\n\t\n* `erl_xcomp_double_middle` - `yes|no`. Defaults to `no`. \n\tIf `yes`, the target system must have doubles in \"middle-endian\" format. If\n `no`, it has \"regular\" endianness. \t\n\n* `erl_xcomp_clock_gettime_cpu_time` - `yes|no`. Defaults to `no`. If `yes`,\n the target system must have a working `clock_gettime()` implementation\n that can be used for retrieving process CPU time.\n\n* `erl_xcomp_getaddrinfo` - `yes|no`. Defaults to `no`. If `yes`, the target\n system must have a working `getaddrinfo()` implementation that can\n handle both IPv4 and IPv6.\n\n* `erl_xcomp_gethrvtime_procfs_ioctl` - `yes|no`. Defaults to `no`. If `yes`,\n the target system must have a working `gethrvtime()` implementation and\n is used with procfs `ioctl()`.\n\n* `erl_xcomp_dlsym_brk_wrappers` - `yes|no`. Defaults to `no`. If `yes`, the\n target system must have a working `dlsym(RTLD_NEXT, )` implementation\n that can be used on `brk` and `sbrk` symbols used by the `malloc()`\n implementation in use, and by this track the `malloc()` implementations\n core memory usage. This is currently only used by unsupported features.\n\n* `erl_xcomp_kqueue` - `yes|no`. Defaults to `no`. If `yes`, the target\n system must have a working `kqueue()` implementation that returns a file\n descriptor which can be used by `poll()` and/or `select()`. If `no` and\n the target system has not got `epoll()` or `/dev/poll`, the kernel-poll\n feature will be disabled.\n\n* `erl_xcomp_linux_clock_gettime_correction` - `yes|no`. Defaults to `yes` on\n Linux; otherwise, `no`. If `yes`, `clock_gettime(CLOCK_MONOTONIC, _)` on\n the target system must work. This variable is recommended to be set to\n `no` on Linux systems with kernel versions less than 2.6.\n\n* `erl_xcomp_linux_nptl` - `yes|no`. Defaults to `yes` on Linux; otherwise,\n `no`. If `yes`, the target system must have NPTL (Native POSIX Thread\n Library). Older Linux systems have LinuxThreads instead of NPTL (Linux\n kernel versions typically less than 2.6).\n\n* `erl_xcomp_linux_usable_sigaltstack` - `yes|no`. Defaults to `yes` on Linux;\n otherwise, `no`. If `yes`, `sigaltstack()` must be usable on the target\n system. `sigaltstack()` on Linux kernel versions less than 2.4 are\n broken.\n\n* `erl_xcomp_linux_usable_sigusrx` - `yes|no`. Defaults to `yes`. If `yes`,\n the `SIGUSR1` and `SIGUSR2` signals must be usable by the ERTS. Old\n LinuxThreads thread libraries (Linux kernel versions typically less than\n 2.2) used these signals and made them unusable by the ERTS.\n\n* `erl_xcomp_poll` - `yes|no`. Defaults to `no` on Darwin/MacOSX; otherwise,\n `yes`. If `yes`, the target system must have a working `poll()`\n implementation that also can handle devices. If `no`, `select()` will be\n used instead of `poll()`.\n\n* `erl_xcomp_putenv_copy` - `yes|no`. Defaults to `no`. If `yes`, the target\n system must have a `putenv()` implementation that stores a copy of the\n key/value pair.\n\n* `erl_xcomp_reliable_fpe` - `yes|no`. Defaults to `no`. If `yes`, the target\n system must have reliable floating point exceptions.\n\n* `erl_xcomp_posix_memalign` - `yes|no`. Defaults to `yes` if `posix_memalign`\n system call exists; otherwise `no`. If `yes`, the target system must have a\n `posix_memalign` implementation that accepts larger than page size\n alignment.\n\n* `erl_xcomp_code_model_small` - `yes|no`. Default to `no`. If `yes`, the target\n system must place the beam.smp executable in the lower 2 GB of memory. That is it\n should not use position independent executable.\n\n\n[Building and Installing Erlang/OTP]: INSTALL.md\n[How to Build the Documentation]: INSTALL.md#How-to-Build-and-Install-Erlang-OTP_How-to-Build-the-Documentation\n[Important Variables Inspected by configure]: INSTALL.md#advanced-configuration-and-build-of-erlang-otp_Configuring_Important-Variables-Inspected-by-configure\n[cross configuration variables]: #currently-used-configuration-variables\n[DESTDIR]: http://www.gnu.org/prep/standards/html_node/DESTDIR.html\n[?TOC]: true\n[Cross Building the System]: #cross-building-the-system","title":"Optional Feature, and Bug Tests ### - Cross Compiling Erlang/OTP","ref":"install-cross.html#optional-feature-and-bug-tests"},{"type":"extras","doc":"Building Erlang/OTP on Windows\n==============================\n\nIntroduction\n------------\n\nThis section describes how to build the Erlang emulator and the OTP\nlibraries on Windows. Note that the Windows binary releases are still\na preferred alternative if one does not have Microsoft’s development\ntools and/or don’t want to install WSL. You can download the binary\nreleases from .\n\nThe instructions apply to Windows 10 (v.1809 and later) supporting the\nWSL.1 (Windows Subsystem for Linux v.1) and using Ubuntu 18.04 release.\n\nThe procedure described uses WSL as a build environment. You run the\nbash shell in WSL and use the gnu configure/make etc to do\nthe build. The emulator C-source code is, however, mostly compiled\nwith Microsoft Visual C++™, producing a native Windows binary. This is\nthe same procedure as we use to build the pre-built binaries. Why we\nuse VC++ and not gcc is explained further in the FAQ section.\n\nThese instructions apply for both 32-bit and 64-bit Windows. Note that\neven if you build a 64-bit version of Erlang, most of the directories\nand files involved are still named win32. Some occurrences of the name\nwin64 are however present. The installation file for a 64-bit Windows\nversion of Erlang, for example, is `otp_win64_28.exe`.\n\nIf you feel comfortable with the environment and build\nsystem, and have all the necessary tools, you have a great opportunity\nto make the Erlang/OTP distribution for Windows better. Please submit\nany suggestions or patches to our [git project] [1] to let\nthem find their way into the next version of Erlang. If making changes\nto the build system (like makefiles etc) please bear in mind that the\nsame makefiles are used on Unix, so that your changes\ndon't break other platforms. That of course goes for C-code too; system\nspecific code resides in the `$ERL_TOP/erts/emulator/sys/win32` and\n`$ERL_TOP/erts/etc/win32` directories mostly. The\n`$ERL_TOP/erts/emulator/beam` directory is for common code.\n\n\nShort Version\n-------------\n\nIn the following sections, we've described as much as we could about\nthe installation of the tools needed. Once the tools are installed,\nbuilding is quite easy. We have also tried to make these instructions\nunderstandable for people with limited Unix experience. WSL is a whole\nnew environment to some Windows users, why careful explanation of\nenvironment variables etc seemed to be in place.\n\nThis is the short story though, for the experienced and impatient:\n\n* Get and install complete WSL environment\n\n* Install Visual Studio 2019\n\n* Get and install windows JDK-8\n\n* Get and install windows NSIS 3.05 or later (3.05 tried and working)\n\n* Get, build and install OpenSSL v1.1.1d or later (up to 1.1.1d\n tried & working) with static libs.\n\n* Get, build and install wxWidgets-3.2.2.1 or later (up to that\n version tried & working) with static libs.\n\n* Get the Erlang source distribution (from\n ) and unpack with `tar`\n to the windows disk for example to: /mnt/c/src/\n\n* Install mingw-gcc, and make: `sudo apt update && sudo apt install g++-mingw-w64 gcc-mingw-w64 make`\n\n* `$ cd UNPACK_DIR`\n\n* Modify PATH and other environment variables so that all these tools\n are runnable from a bash shell. Still standing in `$ERL_TOP`, issue\n the following commands (for 32-bit Windows, remove the x64 from the\n first row and change `otp_win64_28` to `otp_win32_28` on\n the last row):\n\n $ eval `./otp_build env_win32 x64`\n $ ./otp_build configure\n $ ./otp_build boot -a\n $ ./otp_build release -a\n $ ./otp_build installer_win32\n $ release/win32/otp_win64_28 /S\n\nVoila! `Start->Programs->Erlang OTP 28->Erlang` starts the Erlang\nWindows shell.\n\n\nTools you Need and Their Environment\n------------------------------------\n\nYou need some tools to be able to build Erlang/OTP on Windows. Most\nnotably you'll need WSL (with ubuntu), Visual Studio and\nMicrosofts Windows SDK, but you might also want a Java compiler, the\nNSIS install system, OpenSSL and wxWidgets. Well, here's some information about\nthe different tools:\n\n* WSL: Install WSL and Ubuntu in Windows 10\n \n\n We have used and tested with WSL-1, WSL-2 was not available and may\n not be preferred when building Erlang/OTP since access to the windows\n disk is (currently) slower WSL-2.\n\n* Visual Studio 2019\n Download and run the installer from:\n \n Install C++ and SDK packages to the default installation directory.\n\n* Java JDK 8 or later (optional)\n If you don't care about Java, you can skip this step. The\n result will be that jinterface is not built.\n\n Our Java code (jinterface, ic) is tested on windows with JDK 8.\n Get it for Windows and install it, the JRE is not enough.\n\n URL: \n\n Add javac to your path environment, in my case this means:\n\n `PATH=\"/mnt/c/Program\\ Files/Java/jdk1.8.0_241/bin:$PATH`\n\n No `CLASSPATH` or anything is needed. Type `javac.exe` in the bash prompt\n and you should get a list of available Java options.\n\n* Nullsoft NSIS installer system (optional)\n You need this to build the self installing package.\n\n Download and run the installer from:\n URL: \n\n Add 'makensis.exe' to your path environment:\n\n `PATH=\"/mnt/c/Program\\ Files/NSIS/Bin:$PATH`\n\n Type `which makensis.exe` in the bash prompt and you should get the\n path to the program.\n\n* OpenSSL (optional)\n You need this to build crypto, ssh and ssl libs.\n\n We recommend v1.1.1d or later.\n There are prebuilt available binaries, which you can just\n download and install, available here:\n URL: \n\n Install into `C:/OpenSSL-Win64` (or `C:/OpenSSL-Win32`)\n\n* wxWidgets (optional)\n You need this to build wx to use gui's in debugger and observer.\n\n We recommend v3.2.2.1 or later.\n Unpack into `c:/opt/local64/pgm/wxWidgets-3.2.2.1`\n\n If the `wxUSE_POSTSCRIPT` isn't enabled in `c:/opt/local64/pgm/wxWidgets-3.2.2.1/include/wx/msw/setup.h`,\n enable it.\n\n We recommend to enable for wxWebView wxUSE_WEBVIEW_EDGE.\n * Download the nuget package 'Microsoft.Web.WebView2' (Version 0.9.488 or newer)\n * Extract the package (it's a zip archive) to wxWidgets/3rdparty/webview2 (you should have 3rdparty/webview2/build/native/include/WebView2.h file after unpacking it)\n * Enable wxUSE_WEBVIEW_EDGE in `c:/opt/local64/pgm/wxWidgets-3.2.2.1/include/wx/msw/setup.h`\n\n Build with:\n\n ```text\n C:\\...\\> cd c:\\opt\\local64\\pgm\\wxWidgets-3.2.2.1\\build\\msw\n C:\\...\\> nmake TARGET_CPU=amd64 BUILD=release SHARED=0 DIR_SUFFIX_CPU= -f makefile.vc\n ```\n\n Remove the `TARGET_CPU=amd64` for 32bit build.\n\n* Get the Erlang source distribution (from ).\n The same as for Unix platforms. Preferably use tar to\n unpack the source tar.gz (`tar zxf otp_src_28.tar.gz`) to somewhere\n on the windows disk, `/mnt/c/path/to/otp_src`\n\n NOTE: It is important that source on the windows disk.\n\n Set the environment `ERL_TOP` to point to the root directory of the\n source distribution. Let's say I stood in `/mnt/c/src` and unpacked\n `otp_src_28.tar.gz`, I then add the following to `.profile`:\n \n ```text\n ERL_TOP=/mnt/c/src/otp_src_28\n export ERL_TOP\n ```\n\n\nThe Shell Environment\n---------------------\n\nThe path variable should now contain the windows paths to javac.exe and makensis.exe.\n\nSetup the environment with:\n\n $ export PATH\n $ cd /mnt/c/path/to/otp_src/\n $ eval `./otp_build env_win32 x64`\n\nThis should setup the additional environment variables.\n\nThis should do the final touch to the environment and building should\nbe easy after this. You could run `./otp_build env_win32` without\n`eval` just to see what it does, and to see that the environment it\nsets seems OK. The path is cleaned of spaces if possible (using DOS\nstyle short names instead), the variables `OVERRIDE_TARGET`, `CC`, `CXX`,\n`AR` and `RANLIB` are set to their respective wrappers and the directories\n`$ERL_TOP/erts/etc/win32/wsl_tools/vc` and\n`$ERL_TOP/erts/etc/win32/wsl_tools` are added first in the PATH.\n\nNow you can check which erlc you have by writing `type erlc` in your shell.\nIt should reside in `$ERL_TOP/erts/etc/win32/wsl_tools`.\n\nAnd running `cl.exe` should print the Microsoft compiler usage message.\n\nThe needed compiler environment variables are setup inside `otp_build`\nvia `erts/etc/win32/wsl_tools/SetupWSLcross.bat`. It contains some\nhardcoded paths, if your installation path is different it can be added\nto that file.\n\n\nBuilding and Installing\n-----------------------\n\nBuilding is easiest using the `otp_build` script:\n\n $ ./otp_build configure \n $ ./otp_build boot -a\n $ ./otp_build release -a \n $ ./otp_build installer_win32 # optional\n\nNow you will have a file called `otp_win32_28.exe` or `otp_win64_28.exe`\nin the ` `, i.e. `$ERL_TOP/release/win32`.\n\nLets get into more detail:\n\n1. `$ ./otp_build configure` - This runs the newly generated configure\n scripts with options making configure behave nicely. The target machine\n type is plainly `win32`, so a lot of the configure-scripts recognize\n this awkward target name and behave accordingly. The CC variable also\n makes the compiler be `cc.sh`, which wraps MSVC++, so all configure\n tests regarding the C compiler gets to run the right compiler. A lot of\n the tests are not needed on Windows, but we thought it best to run the\n whole configure anyway.\n\n2. `$ ./otp_build boot -a` - This uses the bootstrap directory (shipped\n with the source, `$ERL_TOP/bootstrap`) to build a complete OTP\n system. When this is done you can run erl from within the source tree;\n just type `$ERL_TOP/bin/erl` and you should have the prompt.\n\n3. `$ ./otp_build release -a` - Builds a commercial release tree from the\n source tree. The default is to put it in `$ERL_TOP/release/win32`. You can\n give any directory as parameter, but it doesn't really\n matter if you're going to build a self extracting installer too.\n\n4. `$ ./otp_build installer_win32` - Creates the self extracting installer executable.\n The executable `otp_win32_28.exe` or `otp_win64_28.exe` will be placed\n in the top directory of the release created in the previous step. If\n no release directory is specified, the release is expected to have\n been built to `$ERL_TOP/release/win32`, which also will be the place\n where the installer executable will be placed. If you specified some\n other directory for the release (i.e. `./otp_build release -a\n /tmp/erl_release`), you're expected to give the same parameter here,\n (i.e. `./otp_build installer_win32 /tmp/erl_release`). You need to have\n a full NSIS installation and `makensis.exe` in your path for this to\n work. Once you have created the installer, you can run it to\n install Erlang/OTP in the regular way, just run the executable and\n follow the steps in the installation wizard. To get all default settings\n in the installation without any questions asked, you run the executable\n with the parameter `/S` (capital S) like in:\n\n $ cd $ERL_TOP\n $ release/win32/otp_win32_28 /S\n ...\n\n or\n\n $ cd $ERL_TOP\n $ release/win32/otp_win64_28 /S\n ...\n\n\n and after a while Erlang/OTP-28 will have been installed in\n `C:\\Program Files\\erl%ERTS-VSN%\\`, with shortcuts in the menu etc.\n\n\nDevelopment\n-----------\n\nOnce the system is built, you might want to change it. Having a test\nrelease in some nice directory might be useful, but you can also run\nErlang from within the source tree. The target `local_setup`, makes\nthe program `$ERL_TOP/bin/erl.exe` usable and it also uses all the OTP\nlibraries in the source tree.\n\nIf you hack the emulator, you can build the emulator executable\nby standing in `$ERL_TOP/erts/emulator` and do a simple\n\n $ make opt\n\nNote that you need to have run ``(cd $ERL_TOP && eval `./otp_build env_win32`)``\nin the particular shell before building anything on Windows. After\ndoing a make opt you can test your result by running `$ERL_TOP/bin/erl`.\nIf you want to copy the result to a release directory (say\n`/tmp/erl_release`), you do this (still in `$ERL_TOP/erts/emulator`)\n\n $ make TESTROOT=/tmp/erl_release release\n\nThat will copy the emulator executables.\n\nTo make a debug build of the emulator, you need to recompile both\n`beam.dll` (the actual runtime system) and `erlexec.dll`. Do like this\n\n $ cd $ERL_TOP\n $ rm bin/win32/erlexec.dll\n $ cd erts/emulator\n $ make debug\n $ cd ../etc\n $ make debug\n\nand sometimes\n\n $ cd $ERL_TOP\n $ make local_setup\n\nSo now when you run `$ERL_TOP/erl.exe`, you should have a debug compiled\nemulator, which you will see if you do a:\n\n 1> erlang:system_info(system_version).\n\nin the erlang shell. If the returned string contains `[debug]`, you\ngot a debug compiled emulator.\n\nTo hack the erlang libraries, you simply do a `make opt` in the\nspecific \"applications\" directory, like:\n\n $ cd $ERL_TOP/lib/stdlib\n $ make opt\n\nor even in the source directory...\n\n $ cd $ERL_TOP/lib/stdlib/src\n $ make opt\n\nNote that you're expected to have a fresh Erlang in your path when\ndoing this, preferably the plain 28 you have built in the previous\nsteps. You could also add `$ERL_TOP/bootstrap/bin` to your `PATH` before\nrebuilding specific libraries. That would give you a good enough\nErlang system to compile any OTP erlang code. Setting up the path\ncorrectly is a little bit tricky. You still need to have\n`$ERL_TOP/erts/etc/win32/wsl_tools/vc` and\n`$ERL_TOP/erts/etc/win32/wsl_tools` *before* the actual emulator\nin the path. A typical setting of the path for using the bootstrap\ncompiler would be:\n\n $ export PATH=$ERL_TOP/erts/etc/win32/wsl_tools/vc\\\n :$ERL_TOP/erts/etc/win32/wsl_tools:$ERL_TOP/bootstrap/bin:$PATH\n\nThat should make it possible to rebuild any library without hassle...\n\nIf you want to copy a library (an application) newly built, to a\nrelease area, you do like with the emulator:\n\n $ cd $ERL_TOP/lib/stdlib\n $ make TESTROOT=/tmp/erlang_release release\n\nRemember that:\n\n* Windows specific C-code goes in the `$ERL_TOP/erts/emulator/sys/win32`,\n `$ERL_TOP/erts/emulator/drivers/win32` or `$ERL_TOP/erts/etc/win32`.\n\n* Windows specific erlang code should be used conditionally and the\n host OS tested in *runtime*, the exactly same beam files should be\n distributed for every platform! So write code like:\n\n case os:type() of\n {win32,_} ->\n do_windows_specific();\n Other ->\n do_fallback_or_exit()\n end,\n\nThat's basically all you need to get going.\n\n\n\nFrequently Asked Questions\n--------------------------\n\n* Q: So, now I can build Erlang using GCC on Windows?\n\n A: No, unfortunately not. You'll need Microsoft's Visual C++\n still. A Bourne-shell script (cc.sh) wraps the Visual C++ compiler\n and runs it from within the WSL environment. All other tools\n needed to build Erlang are free-ware/open source, but not the C\n compiler.\n\n* Q: Why haven't you got rid of VC++ then, you \\*\\*\\*\\*\\*\\*?\n\n A: Well, partly because it's a good compiler - really! Actually it's\n been possible in late R11-releases to build using mingw instead of\n visual C++ (you might see the remnants of that in some scripts and\n directories). Unfortunately the development of the SMP version for\n Windows broke the mingw build and we chose to focus on the VC++ build\n as the performance has been much better in the VC++ versions. The\n mingw build will possibly be back, but as long as VC++ gives better\n performance, the commercial build will be a VC++ one.\n\n* Q: Hah, I saw you, you used GCC even though you said you didn't!\n\n A: OK, I admit, one of the files is compiled using\n MinGW's GCC and the resulting object code is then converted to MS\n VC++ compatible coff using a small C hack. It's because that\n particular file, `beam_emu.c` benefits immensely from being able\n to use the GCC labels-as-values extension, which boosts emulator\n performance by up to 50%. That does unfortunately not (yet) mean\n that all of OTP could be compiled using GCC. That particular\n source code does not do anything system specific and actually is\n adopted to the fact that GCC is used to compile it on Windows.\n\n* Q: So now there's a MS VC++ project file somewhere and I can build OTP\n using the nifty VC++ GUI?\n\n A: No, never. The hassle of keeping the project files up to date and\n do all the steps that constitute an OTP build from within the VC++ GUI\n is simply not worth it, maybe even impossible. A VC++ project\n file for Erlang/OTP will never happen.\n\n* Q: So how does it all work then?\n\n A: WSL/Ubuntu is the environment, it's almost like you had a\n virtual Unix machine inside Windows. Configure, given certain\n parameters, then creates makefiles that are used by the\n environment's gnu-make to built the system. Most of the actual\n compilers etc are not, however, WSL tools, so we've written\n a couple of wrappers (Bourne-shell scripts), which reside in\n `$ERL_TOP/etc/win32/wsl_tools`. They all do conversion of\n parameters and switches common in the Unix environment to fit the\n native Windows tools. Most notable is of course the paths, which\n in WSL are Unix-like paths with \"forward slashes\" (/) and\n no drive letters. The WSL specific command `wslpath` is used\n for most of the path conversions in a WSL environment.\n Luckily most compilers accept forward slashes instead\n of backslashes as path separators, but one still have to get the drive\n letters etc right, though. The wrapper scripts are not general in\n the sense that, for example, cc.sh would understand and translate\n every possible gcc option and pass correct options to\n cl.exe. The principle is that the scripts are powerful enough to\n allow building of Erlang/OTP, no more, no less. They might need\n extensions to cope with changes during the development of Erlang, and\n that's one of the reasons we made them into shell-scripts and not\n Perl-scripts. We believe they are easier to understand and change\n that way.\n\n In `$ERL_TOP`, there is a script called `otp_build`. That script handles\n the hassle of giving all the right parameters to `configure`/`make` and\n also helps you set up the correct environment variables to work with\n the Erlang source under WSL.\n\n* Q: Can I build something that looks exactly as the commercial release?\n\n A: Yes, we use the exact same build procedure.\n\n* Q: Which version of WSL and other tools do you use then?\n\n A: We use WSL 1 with Ubuntu 18.04.\n The GCC we used for 28 was version 7.3-win32.\n We used Visual studio 2019, Sun's JDK 1.8.0\\_241,\n NSIS 3.05, Win32 OpenSSL 1.1.1d and wxWidgets-3.1.3.\n\n\n [1]: https://github.com/erlang/otp\n\n [?TOC]: true","title":"Building Erlang/OTP on Windows","ref":"install-win32.html"},{"type":"extras","doc":"Patching OTP Applications\n=========================\n\nIntroduction\n------------\n\nThis document describes the process of patching an existing OTP\ninstallation with one or more Erlang/OTP applications of newer versions\nthan already installed. The tool `otp_patch_apply` is available for this\nspecific purpose. It resides in the top directory of the Erlang/OTP\nsource tree.\n\nThe `otp_patch_apply` tool utilizes the [runtime_dependencies][] tag in\nthe [application resource file][]. This information is used to determine\nif the patch can be installed in the given Erlang/OTP installation\ndirectory.\n\nRead more about the [version handling][] introduced in Erlang/OTP release\n17, which also describes how to determine if an installation includes one\nor more patched applications.\n\nIf you want to apply patches of multiple OTP applications that resides\nin different OTP versions, you have to apply these patches in multiple\nsteps. It is only possible to apply multiple OTP applications from the\nsame OTP version at once.\n\nPrerequisites\n-------------\n\nIt's assumed that the reader is familiar with\n[building and installing Erlang/OTP][]. To be able to patch an\napplication, the following must exist:\n\n* An Erlang/OTP installation.\n\n* An Erlang/OTP source tree containing the updated applications that\n you want to patch into the existing Erlang/OTP installation.\n\nUsing otp\\_patch\\_apply\n-----------------------\n\n> #### Warning {: .warning }\n>\n> Patching applications is a one-way process.\n> Create a backup of your OTP installation directory before\n> proceeding.\n\nFirst of all, build the OTP source tree at `$ERL_TOP` containing\nthe updated applications.\n\n> #### Note {: .info }\n>\n> Before applying a patch you need to do a *full* build\n> of OTP in the source directory.\n\nConfigure and build all applications in OTP:\n\n\t$ configure\n\t$ make\n\nor\n\n\t$ ./otp_build configure\n\t$ ./otp_build boot -a\n\nIf you have installed documentation in the OTP installation, also\nbuild the documentation:\n\n\t$ make docs\n\nAfter the successful build it's time to patch. The source tree directory,\nthe directory of the installation and the applications to patch are given\nas arguments to `otp_patch_apply`. The dependencies of each application\nare validated against the applications in the installation and the other\napplications given as arguments. If a dependency error is detected, the\nscript will be aborted.\n\nThe `otp_patch_apply` syntax:\n\n\t$ otp_patch_apply -s -i [-l ] [-c] [-f] [-h] \\\n [-n] [-v] [... ]\n\t\n\t-s -- OTP source directory that contains build results.\n\t-i -- OTP installation directory to patch.\n\t-l -- Alternative OTP source library directory path(s)\n\t containing build results of OTP applications.\n\t Multiple paths should be colon separated.\n\t-c -- Cleanup (remove) old versions of applications\n\t patched in the installation.\n\t-f -- Force patch of application(s) even though\n\t dependencies are not fulfilled (should only be\n\t considered in a test environment).\n\t-h -- Print help then exit.\n\t-n -- Do not install documentation.\n\t-v -- Print version then exit.\n\t -- Application to patch.\n\t\n\tEnvironment Variable:\n\t ERL_LIBS -- Alternative OTP source library directory path(s)\n\t containing build results of OTP applications.\n\t Multiple paths should be colon separated.\n\n> #### Note {: .info }\n>\n> The complete build environment is required while running\n> `otp_patch_apply`.\n\n> #### Note {: .info }\n>\n> All source directories identified by `-s` and `-l` should\n> contain build results of OTP applications.\n\nFor example, if the user wants to install patched versions of `mnesia`\nand `ssl` built in `/home/me/git/otp` into the OTP installation\nlocated in `/opt/erlang/my_otp` type\n\n\t$ otp_patch_apply -s /home/me/git/otp -i /opt/erlang/my_otp \\\n\t mnesia ssl\n\n> #### Note {: .info }\n>\n> If the list of applications contains core applications,\n> i.e `erts`, `kernel`, `stdlib` or `sasl`, the `Install` script in\n> the patched Erlang/OTP installation must be rerun.\n\nThe patched applications are appended to the list of installed\napplications. Take a look at\n` /releases/OTP-REL/installed_application_versions`.\n\nSanity check\n------------\n\nThe application dependencies can be checked using the Erlang shell.\nApplication dependencies are verified among installed applications by\n`otp_patch_apply`, but these are not necessarily those actually loaded.\nBy calling `system_information:sanity_check()` one can validate\ndependencies among applications actually loaded.\n\n```\n1> system_information:sanity_check().\nok\n```\n\nPlease take a look at the reference of [sanity_check()][] for more\ninformation.\n\n[application resource file]: `e:kernel:app.md`\n[runtime_dependencies]: `e:kernel:app.md#runtime_dependencies`\n[building and installing Erlang/OTP]: INSTALL.md\n[version handling]: `e:system:versions.md`\n[sanity_check()]: `system_information:sanity_check/0`","title":"Patching OTP Applications","ref":"otp-patch-apply.html"},{"type":"extras","doc":"\n# Introduction\n\nThis section is a quick start tutorial to get you started with Erlang.\nEverything in this section is true, but only part of the truth. For example,\nonly the simplest form of the syntax is shown, not all esoteric forms. Also,\nparts that are greatly simplified are indicated with _manual_. This means that a\nlot more information on the subject is to be found in the Erlang book or in\n[Erlang Reference Manual](`e:system:reference_manual.md`).","title":"Introduction","ref":"getting_started.html"},{"type":"extras","doc":"The reader of this section is assumed to be familiar with the following:\n\n- Computers in general\n- Basics on how computers are programmed","title":"Prerequisites - Introduction","ref":"getting_started.html#prerequisites"},{"type":"extras","doc":"The following topics are not treated in this section:\n\n- References.\n- Local error handling (catch/throw).\n- Single direction links (monitor).\n- Handling of binary data (binaries / bit syntax).\n- List comprehensions.\n- How to communicate with the outside world and software written in other\n languages (ports); this is described in\n [Interoperability Tutorial](`e:system:tutorial.md`).\n- Erlang libraries (for example, file handling).\n- OTP and (in consequence) the Mnesia database.\n- Hash tables for Erlang terms (ETS).\n- Changing code in running systems.","title":"Omitted Topics - Introduction","ref":"getting_started.html#omitted-topics"},{"type":"extras","doc":"\n# Sequential Programming","title":"Sequential Programming","ref":"seq_prog.html"},{"type":"extras","doc":"Most operating systems have a command interpreter or shell, UNIX and Linux have\nmany, Windows has the command prompt, powershell and more. Erlang has its own shell\nwhere bits of Erlang code can be written directly, and be evaluated to see what happens (see\nthe `m:shell` manual page in STDLIB).\n\nStart the Erlang shell (in Linux or UNIX) by starting a shell or command\ninterpreter in your operating system and typing `erl`. You will see something\nlike this.\n\n```text\n$ erl\nErlang R15B (erts-5.9.1) [source] [smp:8:8] [rq:8] [async-threads:0] [hipe] [kernel-poll:false]\n\nEshell V5.9.1 (abort with ^G)\n1>\n```\n\nType `2 + 5.` in the shell and then press Enter (carriage return). Notice that\nyou tell the shell you are done entering code by finishing with a full stop `.`\nand a carriage return.\n\n```erlang\n1> 2 + 5.\n7\n2> \n```\n\nAs shown, the Erlang shell numbers the lines that can be entered, (as 1> 2>) and\nthat it correctly says that 2 + 5 is 7. If you make writing mistakes in the\nshell, you can delete with the backspace key, as in most shells. There are many\nmore editing commands in the shell (see\n[tty - A command line interface](`e:erts:tty.md`) in ERTS User's Guide).\n\n(Notice that many line numbers given by the shell in the following examples are\nout of sequence. This is because this tutorial was written and code-tested in\nseparate sessions).\n\nHere is a bit more complex calculation:\n\n```erlang\n2> (42 + 77) * 66 / 3.\n2618.0\n```\n\nNotice the use of brackets, the multiplication operator `*`, and the division\noperator `/`, as in normal arithmetic (see\n[Expressions](`e:system:expressions.md`)).\n\nPress Control-C to shut down the Erlang system and the Erlang shell.\n\nThe following output is shown:\n\n```text\nBREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded\n (v)ersion (k)ill (D)b-tables (d)istribution\na\n$\n```\n\nType `a` to leave the Erlang system.\n\nAnother way to shut down the Erlang system is by entering `halt/0`:\n\n```erlang\n3> halt().\n$\n```","title":"The Erlang Shell - Sequential Programming","ref":"seq_prog.html#the-erlang-shell"},{"type":"extras","doc":"A programming language is not much use if you only can run code from the shell.\nSo here is a small Erlang program. Enter it into a file named `tut.erl` using a\nsuitable text editor. The file name `tut.erl` is important, and also that it is\nin the same directory as the one where you started `erl`). If you are lucky your\neditor has an Erlang mode that makes it easier for you to enter and format your\ncode nicely (see [The Erlang mode for Emacs](`e:tools:erlang_mode_chapter.md`)\nin Tools User's Guide), but you can manage perfectly well without. Here is the\ncode to enter:\n\n```erlang\n-module(tut).\n-export([double/1]).\n\ndouble(X) ->\n 2 * X.\n```\n\nIt is not hard to guess that this program doubles the value of numbers. The\nfirst two lines of the code are described later. Let us compile the program.\nThis can be done in an Erlang shell as follows, where `c` means compile:\n\n```erlang\n3> c(tut).\n{ok,tut}\n```\n\nThe `{ok,tut}` means that the compilation is OK. If it says `error` it means\nthat there is some mistake in the text that you entered. Additional error\nmessages gives an idea to what is wrong so you can modify the text and then try\nto compile the program again.\n\nNow run the program:\n\n```erlang\n4> tut:double(10).\n20\n```\n\nAs expected, double of 10 is 20.\n\nNow let us get back to the first two lines of the code. Erlang programs are\nwritten in files. Each file contains an Erlang _module_. The first line of code\nin the module is the module name (see [Modules](`e:system:modules.md`)):\n\n```erlang\n-module(tut).\n```\n\nThus, the module is called _tut_. Notice the full stop `.` at the end of the\nline. The files which are used to store the module must have the same name as\nthe module but with the extension `.erl`. In this case the file name is\n`tut.erl`. When using a function in another module, the syntax\n`module_name:function_name(arguments)` is used. So the following means call\nfunction `double` in module `tut` with argument `10`.\n\n```erlang\n4> tut:double(10).\n```\n\nThe second line says that the module `tut` contains a function called `double`,\nwhich takes one argument (`X` in our example):\n\n```erlang\n-export([double/1]).\n```\n\nThe second line also says that this function can be called from outside the\nmodule `tut`. More about this later. Again, notice the `.` at the end of the\nline.\n\nNow for a more complicated example, the factorial of a number. For example, the\nfactorial of 4 is 4 _ 3 _ 2 * 1, which equals 24.\n\nEnter the following code in a file named `tut1.erl`:\n\n```erlang\n-module(tut1).\n-export([fac/1]).\n\nfac(1) ->\n 1;\nfac(N) ->\n N * fac(N - 1).\n```\n\nSo this is a module, called `tut1` that contains a function called `fac>`, which\ntakes one argument, `N`.\n\nThe first part says that the factorial of 1 is 1.:\n\n```erlang\nfac(1) ->\n 1;\n```\n\nNotice that this part ends with a semicolon `;` that indicates that there is\nmore of the function `fac>` to come.\n\nThe second part says that the factorial of N is N multiplied by the factorial of\nN - 1:\n\n```erlang\nfac(N) ->\n N * fac(N - 1).\n```\n\nNotice that this part ends with a `.` saying that there are no more parts of\nthis function.\n\nCompile the file:\n\n```erlang\n5> c(tut1).\n{ok,tut1}\n```\n\nAnd now calculate the factorial of 4.\n\n```erlang\n6> tut1:fac(4).\n24\n```\n\nHere the function `fac>` in module `tut1` is called with argument `4`.\n\nA function can have many arguments. Let us expand the module `tut1` with the\nfunction to multiply two numbers:\n\n```erlang\n-module(tut1).\n-export([fac/1, mult/2]).\n\nfac(1) ->\n 1;\nfac(N) ->\n N * fac(N - 1).\n\nmult(X, Y) ->\n X * Y.\n```\n\nNotice that it is also required to expand the `-export` line with the\ninformation that there is another function `mult` with two arguments.\n\nCompile:\n\n```erlang\n7> c(tut1).\n{ok,tut1}\n```\n\nTry out the new function `mult`:\n\n```erlang\n8> tut1:mult(3,4).\n12\n```\n\nIn this example the numbers are integers and the arguments in the functions in\nthe code `N`, `X`, and `Y` are called variables. Variables must start with a\ncapital letter (see [Variables](`e:system:expressions.md`)). Examples of\nvariables are `Number`, `ShoeSize`, and `Age`.","title":"Modules and Functions - Sequential Programming","ref":"seq_prog.html#modules-and-functions"},{"type":"extras","doc":"Atom is another data type in Erlang. Atoms start with a small letter (see\n[Atom](`e:system:data_types.md`)), for example, `charles`, `centimeter`, and\n`inch`. Atoms are simply names, nothing else. They are not like variables, which\ncan have a value.\n\nEnter the next program in a file named `tut2.erl`). It can be useful for\nconverting from inches to centimeters and conversely:\n\n```erlang\n-module(tut2).\n-export([convert/2]).\n\nconvert(M, inch) ->\n M / 2.54;\n\nconvert(N, centimeter) ->\n N * 2.54.\n```\n\nCompile:\n\n```erlang\n9> c(tut2).\n{ok,tut2}\n```\n\nTest:\n\n```erlang\n10> tut2:convert(3, inch).\n1.1811023622047243\n11> tut2:convert(7, centimeter).\n17.78\n```\n\nNotice the introduction of decimals (floating point numbers) without any\nexplanation. Hopefully you can cope with that.\n\nLet us see what happens if something other than `centimeter` or `inch` is\nentered in the `convert` function:\n\n```erlang\n12> tut2:convert(3, miles).\n** exception error: no function clause matching tut2:convert(3,miles) (tut2.erl, line 4)\n```\n\nThe two parts of the `convert` function are called its clauses. As shown,\n`miles` is not part of either of the clauses. The Erlang system cannot _match_\neither of the clauses so an error message `function_clause` is returned. The\nshell formats the error message nicely, but the error tuple is saved in the\nshell's history list and can be output by the shell command `v/1`:\n\n```erlang\n13> v(12).\n{'EXIT',{function_clause,[{tut2,convert,\n [3,miles],\n [{file,\"tut2.erl\"},{line,4}]},\n {erl_eval,do_apply,6,\n [{file,\"erl_eval.erl\"},{line,677}]},\n {shell,exprs,7,[{file,\"shell.erl\"},{line,687}]},\n {shell,eval_exprs,7,[{file,\"shell.erl\"},{line,642}]},\n {shell,eval_loop,3,\n [{file,\"shell.erl\"},{line,627}]}]}}\n```","title":"Atoms - Sequential Programming","ref":"seq_prog.html#atoms"},{"type":"extras","doc":"Now the `tut2` program is hardly good programming style. Consider:\n\n```erlang\ntut2:convert(3, inch).\n```\n\nDoes this mean that 3 is in inches? Or does it mean that 3 is in centimeters and\nis to be converted to inches? Erlang has a way to group things together to make\nthings more understandable. These are called _tuples_ and are surrounded by\ncurly brackets, `{` and `}`.\n\nSo, `{inch,3}` denotes 3 inches and `{centimeter,5}` denotes 5 centimeters. Now\nlet us write a new program that converts centimeters to inches and conversely.\nEnter the following code in a file called `tut3.erl`):\n\n```erlang\n-module(tut3).\n-export([convert_length/1]).\n\nconvert_length({centimeter, X}) ->\n {inch, X / 2.54};\nconvert_length({inch, Y}) ->\n {centimeter, Y * 2.54}.\n```\n\nCompile and test:\n\n```erlang\n14> c(tut3).\n{ok,tut3}\n15> tut3:convert_length({inch, 5}).\n{centimeter,12.7}\n16> tut3:convert_length(tut3:convert_length({inch, 5})).\n{inch,5.0}\n```\n\nNotice on line 16 that 5 inches is converted to centimeters and back again and\nreassuringly get back to the original value. That is, the argument to a function\ncan be the result of another function. Consider how line 16 (above) works. The\nargument given to the function `{inch,5}` is first matched against the first\nhead clause of `convert_length`, that is, `convert_length({centimeter,X})`. It\ncan be seen that `{centimeter,X}` does not match `{inch,5}` (the head is the bit\nbefore the `->`). This having failed, let us try the head of the next clause\nthat is, `convert_length({inch,Y})`. This matches, and `Y` gets the value 5.\n\nTuples can have more than two parts, in fact as many parts as you want, and\ncontain any valid Erlang _term_. For example, to represent the temperature of\nvarious cities of the world:\n\n```erlang\n{moscow, {c, -10}}\n{cape_town, {f, 70}}\n{paris, {f, 28}}\n```\n\nTuples have a fixed number of items in them. Each item in a tuple is called an\n_element_. In the tuple `{moscow,{c,-10}}`, element 1 is `moscow` and element 2\nis `{c,-10}`. Here `c` represents Celsius and `f` Fahrenheit.","title":"Tuples - Sequential Programming","ref":"seq_prog.html#tuples"},{"type":"extras","doc":"Whereas tuples group things together, it is also needed to represent lists of\nthings. Lists in Erlang are surrounded by square brackets, `[` and `]`. For\nexample, a list of the temperatures of various cities in the world can be:\n\n```erlang\n[{moscow, {c, -10}}, {cape_town, {f, 70}}, {stockholm, {c, -4}},\n {paris, {f, 28}}, {london, {f, 36}}]\n```\n\nNotice that this list was so long that it did not fit on one line. This does not\nmatter, Erlang allows line breaks at all \"sensible places\" but not, for example,\nin the middle of atoms, integers, and others.\n\nA useful way of looking at parts of lists, is by using `|`. This is best\nexplained by an example using the shell:\n\n```erlang\n17> [First |TheRest] = [1,2,3,4,5].\n[1,2,3,4,5]\n18> First.\n1\n19> TheRest.\n[2,3,4,5]\n```\n\nTo separate the first elements of the list from the rest of the list, `|` is\nused. `First` has got value `1` and `TheRest` has got the value `[2,3,4,5]`.\n\nAnother example:\n\n```erlang\n20> [E1, E2 | R] = [1,2,3,4,5,6,7].\n[1,2,3,4,5,6,7]\n21> E1.\n1\n22> E2.\n2\n23> R.\n[3,4,5,6,7]\n```\n\nHere you see the use of `|` to get the first two elements from the list. If you\ntry to get more elements from the list than there are elements in the list, an\nerror is returned. Notice also the special case of the list with no elements,\n`[]`:\n\n```erlang\n24> [A, B | C] = [1, 2].\n[1,2]\n25> A.\n1\n26> B.\n2\n27> C.\n[]\n```\n\nIn the previous examples, new variable names are used, instead of reusing the\nold ones: `First`, `TheRest`, `E1`, `E2`, `R`, `A`, `B`, and `C`. The reason for\nthis is that a variable can only be given a value once in its context (scope).\nMore about this later.\n\nThe following example shows how to find the length of a list. Enter the\nfollowing code in a file named `tut4.erl`:\n\n```erlang\n-module(tut4).\n\n-export([list_length/1]).\n\nlist_length([]) ->\n 0;\nlist_length([First | Rest]) ->\n 1 + list_length(Rest).\n```\n\nCompile and test:\n\n```erlang\n28> c(tut4).\n{ok,tut4}\n29> tut4:list_length([1,2,3,4,5,6,7]).\n7\n```\n\nExplanation:\n\n```erlang\nlist_length([]) ->\n 0;\n```\n\nThe length of an empty list is obviously 0.\n\n```erlang\nlist_length([First | Rest]) ->\n 1 + list_length(Rest).\n```\n\nThe length of a list with the first element `First` and the remaining elements\n`Rest` is 1 + the length of `Rest`.\n\n(Advanced readers only: This is not tail recursive, there is a better way to\nwrite this function.)\n\nIn general, tuples are used where \"records\" or \"structs\" are used in other\nlanguages. Also, lists are used when representing things with varying sizes,\nthat is, where linked lists are used in other languages.\n\nErlang does not have a string data type. Instead, strings can be represented by\nlists of Unicode characters. This implies for example that the list `[97,98,99]`\nis equivalent to `\"abc\"`. The Erlang shell is \"clever\" and guesses what list you\nmean and outputs it in what it thinks is the most appropriate form, for example:\n\n```erlang\n30> [97,98,99].\n\"abc\"\n```","title":"Lists - Sequential Programming","ref":"seq_prog.html#lists"},{"type":"extras","doc":"Maps are a set of key to value associations. These associations are encapsulated\nwith `#{` and `}`. To create an association from `\"key\"` to value `42`:\n\n```erlang\n> #{ \"key\" => 42 }.\n#{\"key\" => 42}\n```\n\nLet us jump straight into the deep end with an example using some interesting\nfeatures.\n\nThe following example shows how to calculate alpha blending using maps to\nreference color and alpha channels. Enter the code in a file named `color.erl`):\n\n```erlang\n-module(color).\n\n-export([new/4, blend/2]).\n\n-define(is_channel(V), (is_float(V) andalso V >= 0.0 andalso V =< 1.0)).\n\nnew(R,G,B,A) when ?is_channel(R), ?is_channel(G),\n ?is_channel(B), ?is_channel(A) ->\n #{red => R, green => G, blue => B, alpha => A}.\n\nblend(Src,Dst) ->\n blend(Src,Dst,alpha(Src,Dst)).\n\nblend(Src,Dst,Alpha) when Alpha > 0.0 ->\n Dst#{\n red := red(Src,Dst) / Alpha,\n green := green(Src,Dst) / Alpha,\n blue := blue(Src,Dst) / Alpha,\n alpha := Alpha\n };\nblend(_,Dst,_) ->\n Dst#{\n red := 0.0,\n green := 0.0,\n blue := 0.0,\n alpha := 0.0\n }.\n\nalpha(#{alpha := SA}, #{alpha := DA}) ->\n SA + DA*(1.0 - SA).\n\nred(#{red := SV, alpha := SA}, #{red := DV, alpha := DA}) ->\n SV*SA + DV*DA*(1.0 - SA).\ngreen(#{green := SV, alpha := SA}, #{green := DV, alpha := DA}) ->\n SV*SA + DV*DA*(1.0 - SA).\nblue(#{blue := SV, alpha := SA}, #{blue := DV, alpha := DA}) ->\n SV*SA + DV*DA*(1.0 - SA).\n```\n\nCompile and test:\n\n```erlang\n> c(color).\n{ok,color}\n> C1 = color:new(0.3,0.4,0.5,1.0).\n#{alpha => 1.0,blue => 0.5,green => 0.4,red => 0.3}\n> C2 = color:new(1.0,0.8,0.1,0.3).\n#{alpha => 0.3,blue => 0.1,green => 0.8,red => 1.0}\n> color:blend(C1,C2).\n#{alpha => 1.0,blue => 0.5,green => 0.4,red => 0.3}\n> color:blend(C2,C1).\n#{alpha => 1.0,blue => 0.38,green => 0.52,red => 0.51}\n```\n\nThis example warrants some explanation:\n\n```erlang\n-define(is_channel(V), (is_float(V) andalso V >= 0.0 andalso V =< 1.0)).\n```\n\nFirst a macro `is_channel` is defined to help with the guard tests. This is only\nhere for convenience and to reduce syntax cluttering. For more information about\nmacros, see [The Preprocessor](`e:system:macros.md`).\n\n```erlang\nnew(R,G,B,A) when ?is_channel(R), ?is_channel(G),\n ?is_channel(B), ?is_channel(A) ->\n #{red => R, green => G, blue => B, alpha => A}.\n```\n\nThe function `new/4` creates a new map term and lets the keys `red`, `green`,\n`blue`, and `alpha` be associated with an initial value. In this case, only\nfloat values between and including 0.0 and 1.0 are allowed, as ensured by the\n`?is_channel/1` macro for each argument. Only the `=>` operator is allowed when\ncreating a new map.\n\nBy calling `blend/2` on any color term created by `new/4`, the resulting color\ncan be calculated as determined by the two map terms.\n\nThe first thing `blend/2` does is to calculate the resulting alpha channel:\n\n```erlang\nalpha(#{alpha := SA}, #{alpha := DA}) ->\n SA + DA*(1.0 - SA).\n```\n\nThe value associated with key `alpha` is fetched for both arguments using the\n`:=` operator. The other keys in the map are ignored, only the key `alpha` is\nrequired and checked for.\n\nThis is also the case for functions `red/2`, `blue/2`, and `green/2`.\n\n```erlang\nred(#{red := SV, alpha := SA}, #{red := DV, alpha := DA}) ->\n SV*SA + DV*DA*(1.0 - SA).\n```\n\nThe difference here is that a check is made for two keys in each map argument.\nThe other keys are ignored.\n\nFinally, let us return the resulting color in `blend/3`:\n\n```erlang\nblend(Src,Dst,Alpha) when Alpha > 0.0 ->\n Dst#{\n red := red(Src,Dst) / Alpha,\n green := green(Src,Dst) / Alpha,\n blue := blue(Src,Dst) / Alpha,\n alpha := Alpha\n };\n```\n\nThe `Dst` map is updated with new channel values. The syntax for updating an\nexisting key with a new value is with the `:=` operator.","title":"Maps - Sequential Programming","ref":"seq_prog.html#maps"},{"type":"extras","doc":"Erlang has many standard modules to help you do things. For example, the module\n`m:io` contains many functions that help in doing formatted input/output. To look\nup information about standard modules, the command `h(..)` can be used at the\nerlang shell. Try the erlang shell command:\n\n```text\n1> h(io).\n\n\tio\n\n Standard I/O server interface functions.\n \n This module provides an interface to standard Erlang I/O servers. The output\n functions all return `ok` if they are successful, or exit if they are not.\n ...\n```\n\nIf this does not work on your system, the documentation is included as HTML in\nthe Erlang/OTP release. You can also read the documentation as HTML or download\nit as epub from .","title":"Standard Modules and Manual Pages - Sequential Programming","ref":"seq_prog.html#standard-modules-and-manual-pages"},{"type":"extras","doc":"It is nice to be able to do formatted output in examples, so the next example\nshows a simple way to use the `io:format/2` function. Like all other exported\nfunctions, you can test the `io:format/2` function in the shell:\n\n```erlang\n31> io:format(\"hello world~n\", []).\nhello world\nok\n32> io:format(\"this outputs one Erlang term: ~w~n\", [hello]).\nthis outputs one Erlang term: hello\nok\n33> io:format(\"this outputs two Erlang terms: ~w~w~n\", [hello, world]).\nthis outputs two Erlang terms: helloworld\nok\n34> io:format(\"this outputs two Erlang terms: ~w ~w~n\", [hello, world]).\nthis outputs two Erlang terms: hello world\nok\n```\n\nThe function `io:format/2` (that is, `format` with two arguments) takes two lists.\nThe first one is nearly always a list written between `\" \"`. This list is printed\nout as it is, except that each `~w` is replaced by a term taken in order from the\nsecond list. Each ~n is replaced by a new line. The `io:format/2` function\nitself returns the atom `ok` if everything goes as planned. Like other functions\nin Erlang, it crashes if an error occurs. This is not a fault in Erlang, it is a\ndeliberate policy. Erlang has sophisticated mechanisms to handle errors which\nare shown later. As an exercise, try to make `io:format/2` crash, it should not be\ndifficult. But notice that although `io:format/2` crashes, the Erlang shell itself\ndoes not crash.","title":"Writing Output to a Terminal - Sequential Programming","ref":"seq_prog.html#writing-output-to-a-terminal"},{"type":"extras","doc":"Now for a larger example to consolidate what you have learnt so far. Assume that\nyou have a list of temperature readings from a number of cities in the world.\nSome of them are in Celsius and some in Fahrenheit (as in the previous list).\nFirst let us convert them all to Celsius, then let us print the data neatly.\n\n```erlang\n%% This module is in file tut5.erl\n\n-module(tut5).\n-export([format_temps/1]).\n\n%% Only this function is exported\nformat_temps([])-> % No output for an empty list\n ok;\nformat_temps([City | Rest]) ->\n print_temp(convert_to_celsius(City)),\n format_temps(Rest).\n\nconvert_to_celsius({Name, {c, Temp}}) -> % No conversion needed\n {Name, {c, Temp}};\nconvert_to_celsius({Name, {f, Temp}}) -> % Do the conversion\n {Name, {c, (Temp - 32) * 5 / 9}}.\n\nprint_temp({Name, {c, Temp}}) ->\n io:format(\"~-15w ~w c~n\", [Name, Temp]).\n```\n\n```erlang\n35> c(tut5).\n{ok,tut5}\n36> tut5:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},\n{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).\nmoscow -10 c\ncape_town 21.11111111111111 c\nstockholm -4 c\nparis -2.2222222222222223 c\nlondon 2.2222222222222223 c\nok\n```\n\nBefore looking at how this program works, notice that a few comments are added\nto the code. A comment starts with a %-character and goes on to the end of the\nline. Notice also that the `-export([format_temps/1]).` line only includes the\nfunction `format_temps/1`. The other functions are _local_ functions, that is,\nthey are not visible from outside the module `tut5`.\n\nNotice also that when testing the program from the shell, the input is spread\nover two lines as the line was too long.\n\nWhen `format_temps` is called the first time, `City` gets the value\n`{moscow,{c,-10}}` and `Rest` is the rest of the list. So the function\n`print_temp(convert_to_celsius({moscow,{c,-10}}))` is called.\n\nHere is a function call as `convert_to_celsius({moscow,{c,-10}})` as the\nargument to the function `print_temp`. When function calls are _nested_ like\nthis, they execute (evaluate) from the inside out. That is, first\n`convert_to_celsius({moscow,{c,-10}})` is evaluated, which gives the value\n`{moscow,{c,-10}}` as the temperature is already in Celsius. Then\n`print_temp({moscow,{c,-10}})` is evaluated. The function `convert_to_celsius`\nworks in a similar way to the `convert_length` function in the previous example.\n\n`print_temp` simply calls `io:format` in a similar way to what has been\ndescribed above. Notice that `~-15w` says to print the \"term\" with a field length\n(width) of 15 and left justify it. (see `io:fwrite/1` manual page in STDLIB).\n\nNow `format_temps(Rest)` is called with the rest of the list as an argument.\nThis way of doing things is similar to the loop constructs in other languages.\n(Yes, this is recursion, but do not let that worry you.) So the same\n`format_temps` function is called again, this time `City` gets the value\n`{cape_town,{f,70}}` and the same procedure is repeated as before. This is done\nuntil the list becomes empty, that is [], which causes the first clause\n`format_temps([])` to match. This simply returns (results in) the atom `ok`, so\nthe program ends.","title":"A Larger Example - Sequential Programming","ref":"seq_prog.html#a-larger-example"},{"type":"extras","doc":"It can be useful to find the maximum and minimum temperature in lists like this.\nBefore extending the program to do this, let us look at functions for finding\nthe maximum value of the elements in a list:\n\n```erlang\n-module(tut6).\n-export([list_max/1]).\n\nlist_max([Head|Rest]) ->\n list_max(Rest, Head).\n\nlist_max([], Res) ->\n Res;\nlist_max([Head|Rest], Result_so_far) when Head > Result_so_far ->\n list_max(Rest, Head);\nlist_max([Head|Rest], Result_so_far) ->\n list_max(Rest, Result_so_far).\n```\n\n```erlang\n37> c(tut6).\n{ok,tut6}\n38> tut6:list_max([1,2,3,4,5,7,4,3,2,1]).\n7\n```\n\nFirst notice that two functions have the same name, `list_max`. However, each of\nthese takes a different number of arguments (parameters). In Erlang these are\nregarded as completely different functions. Where you need to distinguish\nbetween these functions, you write Name/Arity, where Name is the function name\nand Arity is the number of arguments, in this case `list_max/1` and\n`list_max/2`.\n\nIn this example you walk through a list \"carrying\" a value, in this case\n`Result_so_far`. `list_max/1` simply assumes that the max value of the list is\nthe head of the list and calls `list_max/2` with the rest of the list and the\nvalue of the head of the list. In the above this would be\n`list_max([2,3,4,5,7,4,3,2,1],1)`. If you tried to use `list_max/1` with an\nempty list or tried to use it with something that is not a list at all, you\nwould cause an error. Notice that the Erlang philosophy is not to handle errors\nof this type in the function they occur, but to do so elsewhere. More about this\nlater.\n\nIn `list_max/2`, you walk down the list and use `Head` instead of\n`Result_so_far` when `Head` > `Result_so_far`. `when` is a special word used\nbefore the -> in the function to say that you only use this part of the function\nif the test that follows is true. A test of this type is called _guard_. If the\nguard is false (that is, the guard fails), the next part of the function is\ntried. In this case, if `Head` is not greater than `Result_so_far`, then it must\nbe smaller or equal to it. This means that a guard on the next part of the\nfunction is not needed.\n\nSome useful operators in guards are:\n\n- `<` less than\n- `>` greater than\n- `==` equal\n- `>=` greater or equal\n- `=<` less or equal\n- `/=` not equal\n\n(see [Guard Sequences](`e:system:expressions.md`)).\n\nTo change the above program to one that works out the minimum value of the\nelement in a list, you only need to write . (But it would be wise\nto change the name of the function to `list_min`.)\n\nEarlier it was mentioned that a variable can only be given a value once in its\nscope. In the above you see that `Result_so_far` is given several values. This\nis OK since every time you call `list_max/2` you create a new scope and one can\nregard `Result_so_far` as a different variable in each scope.\n\nAnother way of creating and giving a variable a value is by using the match\noperator = . So if you write `M = 5`, a variable called `M` is created with the\nvalue 5. If, in the same scope, you then write `M = 6`, an error is returned.\nTry this out in the shell:\n\n```erlang\n39> M = 5.\n5\n40> M = 6.\n** exception error: no match of right hand side value 6\n41> M = M + 1.\n** exception error: no match of right hand side value 6\n42> N = M + 1.\n6\n```\n\nThe use of the match operator is particularly useful for pulling apart Erlang\nterms and creating new ones.\n\n```erlang\n43> {X, Y} = {paris, {f, 28}}.\n{paris,{f,28}}\n44> X.\nparis\n45> Y.\n{f,28}\n```\n\nHere `X` gets the value `paris` and `Y` the value `{f,28}`.\n\nIf you try to do the same again with another city, an error is returned:\n\n```erlang\n46> {X, Y} = {london, {f, 36}}.\n** exception error: no match of right hand side value {london,{f,36}}\n```\n\nVariables can also be used to improve the readability of programs. For example,\nin function `list_max/2` above, you can write:\n\n```erlang\nlist_max([Head|Rest], Result_so_far) when Head > Result_so_far ->\n New_result_far = Head,\n list_max(Rest, New_result_far);\n```\n\nThis is possibly a little clearer.","title":"Matching, Guards, and Scope of Variables - Sequential Programming","ref":"seq_prog.html#matching-guards-and-scope-of-variables"},{"type":"extras","doc":"Remember that the `|` operator can be used to get the head of a list:\n\n```erlang\n47> [M1|T1] = [paris, london, rome].\n[paris,london,rome]\n48> M1.\nparis\n49> T1.\n[london,rome]\n```\n\nThe `|` operator can also be used to add a head to a list:\n\n```erlang\n50> L1 = [madrid | T1].\n[madrid,london,rome]\n51> L1.\n[madrid,london,rome]\n```\n\nNow an example of this when working with lists - reversing the order of a list:\n\n```erlang\n-module(tut8).\n\n-export([reverse/1]).\n\nreverse(List) ->\n reverse(List, []).\n\nreverse([Head | Rest], Reversed_List) ->\n reverse(Rest, [Head | Reversed_List]);\nreverse([], Reversed_List) ->\n Reversed_List.\n```\n\n```erlang\n52> c(tut8).\n{ok,tut8}\n53> tut8:reverse([1,2,3]).\n[3,2,1]\n```\n\nConsider how `Reversed_List` is built. It starts as [], then successively the\nheads are taken off of the list to be reversed and added to the the\n`Reversed_List`, as shown in the following:\n\n```erlang\nreverse([1|2,3], []) =>\n reverse([2,3], [1|[]])\n\nreverse([2|3], [1]) =>\n reverse([3], [2|[1])\n\nreverse([3|[]], [2,1]) =>\n reverse([], [3|[2,1]])\n\nreverse([], [3,2,1]) =>\n [3,2,1]\n```\n\nThe module `lists` contains many functions for manipulating lists, for example,\nfor reversing them. So before writing a list-manipulating function it is a good\nidea to check if one not already is written for you (see the `m:lists` manual\npage in STDLIB).\n\nNow let us get back to the cities and temperatures, but take a more structured\napproach this time. First let us convert the whole list to Celsius as follows:\n\n```erlang\n-module(tut7).\n-export([format_temps/1]).\n\nformat_temps(List_of_cities) ->\n convert_list_to_c(List_of_cities).\n\nconvert_list_to_c([{Name, {f, F}} | Rest]) ->\n Converted_City = {Name, {c, (F -32)* 5 / 9}},\n [Converted_City | convert_list_to_c(Rest)];\n\nconvert_list_to_c([City | Rest]) ->\n [City | convert_list_to_c(Rest)];\n\nconvert_list_to_c([]) ->\n [].\n```\n\nTest the function:\n\n```erlang\n54> c(tut7).\n{ok, tut7}.\n55> tut7:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},\n{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).\n[{moscow,{c,-10}},\n {cape_town,{c,21.11111111111111}},\n {stockholm,{c,-4}},\n {paris,{c,-2.2222222222222223}},\n {london,{c,2.2222222222222223}}]\n```\n\nExplanation:\n\n```erlang\nformat_temps(List_of_cities) ->\n convert_list_to_c(List_of_cities).\n```\n\nHere `format_temps/1` calls `convert_list_to_c/1`. `convert_list_to_c/1` takes\noff the head of the `List_of_cities`, converts it to Celsius if needed. The `|`\noperator is used to add the (maybe) converted to the converted rest of the list:\n\n```erlang\n[Converted_City | convert_list_to_c(Rest)];\n```\n\nor:\n\n```erlang\n[City | convert_list_to_c(Rest)];\n```\n\nThis is done until the end of the list is reached, that is, the list is empty:\n\n```erlang\nconvert_list_to_c([]) ->\n [].\n```\n\nNow when the list is converted, a function to print it is added:\n\n```erlang\n-module(tut7).\n-export([format_temps/1]).\n\nformat_temps(List_of_cities) ->\n Converted_List = convert_list_to_c(List_of_cities),\n print_temp(Converted_List).\n\nconvert_list_to_c([{Name, {f, F}} | Rest]) ->\n Converted_City = {Name, {c, (F -32)* 5 / 9}},\n [Converted_City | convert_list_to_c(Rest)];\n\nconvert_list_to_c([City | Rest]) ->\n [City | convert_list_to_c(Rest)];\n\nconvert_list_to_c([]) ->\n [].\n\nprint_temp([{Name, {c, Temp}} | Rest]) ->\n io:format(\"~-15w ~w c~n\", [Name, Temp]),\n print_temp(Rest);\nprint_temp([]) ->\n ok.\n```\n\n```erlang\n56> c(tut7).\n{ok,tut7}\n57> tut7:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},\n{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).\nmoscow -10 c\ncape_town 21.11111111111111 c\nstockholm -4 c\nparis -2.2222222222222223 c\nlondon 2.2222222222222223 c\nok\n```\n\nNow a function has to be added to find the cities with the maximum and minimum\ntemperatures. The following program is not the most efficient way of doing this\nas you walk through the list of cities four times. But it is better to first\nstrive for clarity and correctness and to make programs efficient only if\nneeded.\n\n```erlang\n-module(tut7).\n-export([format_temps/1]).\n\nformat_temps(List_of_cities) ->\n Converted_List = convert_list_to_c(List_of_cities),\n print_temp(Converted_List),\n {Max_city, Min_city} = find_max_and_min(Converted_List),\n print_max_and_min(Max_city, Min_city).\n\nconvert_list_to_c([{Name, {f, Temp}} | Rest]) ->\n Converted_City = {Name, {c, (Temp -32)* 5 / 9}},\n [Converted_City | convert_list_to_c(Rest)];\n\nconvert_list_to_c([City | Rest]) ->\n [City | convert_list_to_c(Rest)];\n\nconvert_list_to_c([]) ->\n [].\n\nprint_temp([{Name, {c, Temp}} | Rest]) ->\n io:format(\"~-15w ~w c~n\", [Name, Temp]),\n print_temp(Rest);\nprint_temp([]) ->\n ok.\n\nfind_max_and_min([City | Rest]) ->\n find_max_and_min(Rest, City, City).\n\nfind_max_and_min([{Name, {c, Temp}} | Rest],\n {Max_Name, {c, Max_Temp}},\n {Min_Name, {c, Min_Temp}}) ->\n if\n Temp > Max_Temp ->\n Max_City = {Name, {c, Temp}}; % Change\n true ->\n Max_City = {Max_Name, {c, Max_Temp}} % Unchanged\n end,\n if\n Temp \n Min_City = {Name, {c, Temp}}; % Change\n true ->\n Min_City = {Min_Name, {c, Min_Temp}} % Unchanged\n end,\n find_max_and_min(Rest, Max_City, Min_City);\n\nfind_max_and_min([], Max_City, Min_City) ->\n {Max_City, Min_City}.\n\nprint_max_and_min({Max_name, {c, Max_temp}}, {Min_name, {c, Min_temp}}) ->\n io:format(\"Max temperature was ~w c in ~w~n\", [Max_temp, Max_name]),\n io:format(\"Min temperature was ~w c in ~w~n\", [Min_temp, Min_name]).\n```\n\n```erlang\n58> c(tut7).\n{ok, tut7}\n59> tut7:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},\n{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).\nmoscow -10 c\ncape_town 21.11111111111111 c\nstockholm -4 c\nparis -2.2222222222222223 c\nlondon 2.2222222222222223 c\nMax temperature was 21.11111111111111 c in cape_town\nMin temperature was -10 c in moscow\nok\n```","title":"More About Lists - Sequential Programming","ref":"seq_prog.html#more-about-lists"},{"type":"extras","doc":"The function `find_max_and_min` works out the maximum and minimum temperature. A\nnew construct, `if`, is introduced here. If works as follows:\n\n```c\nif\n Condition 1 ->\n Action 1;\n Condition 2 ->\n Action 2;\n Condition 3 ->\n Action 3;\n Condition 4 ->\n Action 4\nend\n```\n\nNotice that there is no `;` before `end`. Conditions do the same as guards, that\nis, tests that succeed or fail. Erlang starts at the top and tests until it\nfinds a condition that succeeds. Then it evaluates (performs) the action\nfollowing the condition and ignores all other conditions and actions before the\n`end`. If no condition matches, a run-time failure occurs. A condition that\nalways succeeds is the atom `true`. This is often used last in an `if`, meaning,\ndo the action following the `true` if all other conditions have failed.\n\nThe following is a short program to show the workings of `if`.\n\n```erlang\n-module(tut9).\n-export([test_if/2]).\n\ntest_if(A, B) ->\n if\n A == 5 ->\n io:format(\"A == 5~n\", []),\n a_equals_5;\n B == 6 ->\n io:format(\"B == 6~n\", []),\n b_equals_6;\n A == 2, B == 3 -> %That is A equals 2 and B equals 3\n io:format(\"A == 2, B == 3~n\", []),\n a_equals_2_b_equals_3;\n A == 1 ; B == 7 -> %That is A equals 1 or B equals 7\n io:format(\"A == 1 ; B == 7~n\", []),\n a_equals_1_or_b_equals_7\n end.\n```\n\nTesting this program gives:\n\n```erlang\n60> c(tut9).\n{ok,tut9}\n61> tut9:test_if(5,33).\nA == 5\na_equals_5\n62> tut9:test_if(33,6).\nB == 6\nb_equals_6\n63> tut9:test_if(2, 3).\nA == 2, B == 3\na_equals_2_b_equals_3\n64> tut9:test_if(1, 33).\nA == 1 ; B == 7\na_equals_1_or_b_equals_7\n65> tut9:test_if(33, 7).\nA == 1 ; B == 7\na_equals_1_or_b_equals_7\n66> tut9:test_if(33, 33).\n** exception error: no true branch found when evaluating an if expression\n in function tut9:test_if/2 (tut9.erl, line 5)\n```\n\nNotice that `tut9:test_if(33,33)` does not cause any condition to succeed. This\nleads to the run time error `if_clause`, here nicely formatted by the shell. See\n[Guard Sequences](`e:system:expressions.md`) for details of the many guard tests\navailable.\n\n`case` is another construct in Erlang. Recall that the `convert_length` function\nwas written as:\n\n```erlang\nconvert_length({centimeter, X}) ->\n {inch, X / 2.54};\nconvert_length({inch, Y}) ->\n {centimeter, Y * 2.54}.\n```\n\nThe same program can also be written as:\n\n```erlang\n-module(tut10).\n-export([convert_length/1]).\n\nconvert_length(Length) ->\n case Length of\n {centimeter, X} ->\n {inch, X / 2.54};\n {inch, Y} ->\n {centimeter, Y * 2.54}\n end.\n```\n\n```erlang\n67> c(tut10).\n{ok,tut10}\n68> tut10:convert_length({inch, 6}).\n{centimeter,15.24}\n69> tut10:convert_length({centimeter, 2.5}).\n{inch,0.984251968503937}\n```\n\nBoth `case` and `if` have _return values_, that is, in the above example `case`\nreturned either `{inch,X/2.54}` or `{centimeter,Y*2.54}`. The behaviour of\n`case` can also be modified by using guards. The following example clarifies\nthis. It tells us the length of a month, given the year. The year must be known,\nsince February has 29 days in a leap year.\n\n```erlang\n-module(tut11).\n-export([month_length/2]).\n\nmonth_length(Year, Month) ->\n %% All years divisible by 400 are leap\n %% Years divisible by 100 are not leap (except the 400 rule above)\n %% Years divisible by 4 are leap (except the 100 rule above)\n Leap = if\n trunc(Year / 400) * 400 == Year ->\n leap;\n trunc(Year / 100) * 100 == Year ->\n not_leap;\n trunc(Year / 4) * 4 == Year ->\n leap;\n true ->\n not_leap\n end,\n case Month of\n sep -> 30;\n apr -> 30;\n jun -> 30;\n nov -> 30;\n feb when Leap == leap -> 29;\n feb -> 28;\n jan -> 31;\n mar -> 31;\n may -> 31;\n jul -> 31;\n aug -> 31;\n oct -> 31;\n dec -> 31\n end.\n```\n\n```erlang\n70> c(tut11).\n{ok,tut11}\n71> tut11:month_length(2004, feb).\n29\n72> tut11:month_length(2003, feb).\n28\n73> tut11:month_length(1947, aug).\n31\n```","title":"If and Case - Sequential Programming","ref":"seq_prog.html#if-and-case"},{"type":"extras","doc":"BIFs are functions that for some reason are built-in to the Erlang virtual\nmachine. BIFs often implement functionality that is impossible or is too\ninefficient to implement in Erlang. Some BIFs can be called using the function\nname only but they are by default belonging to the `erlang` module. For example,\nthe call to the BIF `trunc` below is equivalent to a call to `erlang:trunc`.\n\nAs shown, first it is checked if a year is leap. If a year is divisible by 400,\nit is a leap year. To determine this, first divide the year by 400 and use the\nBIF `trunc` (more about this later) to cut off any decimals. Then multiply by\n400 again and see if the same value is returned again. For example, year 2004:\n\n```erlang\n2004 / 400 = 5.01\ntrunc(5.01) = 5\n5 * 400 = 2000\n```\n\n2000 is not the same as 2004, so 2004 is not divisible by 400. Year 2000:\n\n```erlang\n2000 / 400 = 5.0\ntrunc(5.0) = 5\n5 * 400 = 2000\n```\n\nThat is, a leap year. The next two `trunc`\\-tests evaluate if the year is\ndivisible by 100 or 4 in the same way. The first `if` returns `leap` or\n`not_leap`, which lands up in the variable `Leap`. This variable is used in the\nguard for `feb` in the following `case` that tells us how long the month is.\n\nThis example showed the use of `trunc`. It is easier to use the Erlang operator\n`rem` that gives the remainder after division, for example:\n\n```erlang\n74> 2004 rem 400.\n4\n```\n\nSo instead of writing:\n\n```erlang\ntrunc(Year / 400) * 400 == Year ->\n leap;\n```\n\nit can be written:\n\n```erlang\nYear rem 400 == 0 ->\n leap;\n```\n\nThere are many other BIFs such as `trunc`. Only a few BIFs can be used in\nguards, and you cannot use functions you have defined yourself in guards. (see\n[Guard Sequences](`e:system:expressions.md`)) (For advanced readers: This is to\nensure that guards do not have side effects.) Let us play with a few of these\nfunctions in the shell:\n\n```erlang\n75> trunc(5.6).\n5\n76> round(5.6).\n6\n77> length([a,b,c,d]).\n4\n78> float(5).\n5.0\n79> is_atom(hello).\ntrue\n80> is_atom(\"hello\").\nfalse\n81> is_tuple({paris, {c, 30}}).\ntrue\n82> is_tuple([paris, {c, 30}]).\nfalse\n```\n\nAll of these can be used in guards. Now for some BIFs that cannot be used in\nguards:\n\n```erlang\n83> atom_to_list(hello).\n\"hello\"\n84> list_to_atom(\"goodbye\").\ngoodbye\n85> integer_to_list(22).\n\"22\"\n```\n\nThese three BIFs do conversions that would be difficult (or impossible) to do in\nErlang.","title":"Built-In Functions (BIFs) - Sequential Programming","ref":"seq_prog.html#built-in-functions-bifs"},{"type":"extras","doc":"Erlang, like most modern functional programming languages, has higher-order\nfunctions. Here is an example using the shell:\n\n```erlang\n86> Xf = fun(X) -> X * 2 end.\n#Fun \n87> Xf(5).\n10\n```\n\nHere is defined a function that doubles the value of a number and assigned this\nfunction to a variable. Thus `Xf(5)` returns value 10. Two useful functions when\nworking with lists are `foreach` and `map`, which are defined as follows:\n\n```erlang\nforeach(Fun, [First|Rest]) ->\n Fun(First),\n foreach(Fun, Rest);\nforeach(Fun, []) ->\n ok.\n\nmap(Fun, [First|Rest]) ->\n [Fun(First)|map(Fun,Rest)];\nmap(Fun, []) ->\n [].\n```\n\nThese two functions are provided in the standard module `lists`. `foreach` takes\na list and applies a fun to every element in the list. `map` creates a new list\nby applying a fun to every element in a list. Going back to the shell, `map` is\nused and a fun to add 3 to every element of a list:\n\n```erlang\n88> Add_3 = fun(X) -> X + 3 end.\n#Fun \n89> lists:map(Add_3, [1,2,3]).\n[4,5,6]\n```\n\nLet us (again) print the temperatures in a list of cities:\n\n```erlang\n90> Print_City = fun({City, {X, Temp}}) -> io:format(\"~-15w ~w ~w~n\",\n[City, X, Temp]) end.\n#Fun \n91> lists:foreach(Print_City, [{moscow, {c, -10}}, {cape_town, {f, 70}},\n{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).\nmoscow c -10\ncape_town f 70\nstockholm c -4\nparis f 28\nlondon f 36\nok\n```\n\nLet us now define a fun that can be used to go through a list of cities and\ntemperatures and transform them all to Celsius.\n\n```erlang\n-module(tut13).\n\n-export([convert_list_to_c/1]).\n\nconvert_to_c({Name, {f, Temp}}) ->\n {Name, {c, trunc((Temp - 32) * 5 / 9)}};\nconvert_to_c({Name, {c, Temp}}) ->\n {Name, {c, Temp}}.\n\nconvert_list_to_c(List) ->\n lists:map(fun convert_to_c/1, List).\n```\n\n```erlang\n92> tut13:convert_list_to_c([{moscow, {c, -10}}, {cape_town, {f, 70}},\n{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).\n[{moscow,{c,-10}},\n {cape_town,{c,21}},\n {stockholm,{c,-4}},\n {paris,{c,-2}},\n {london,{c,2}}]\n```\n\nThe `convert_to_c` function is the same as before, but here it is used as a fun:\n\n```erlang\nlists:map(fun convert_to_c/1, List)\n```\n\nWhen a function defined elsewhere is used as a fun, it can be referred to as\n`Function/Arity` (remember that `Arity` = number of arguments). So in the\n`map`\\-call `lists:map(fun convert_to_c/1, List)` is written. As shown,\n`convert_list_to_c` becomes much shorter and easier to understand.\n\nThe standard module `lists` also contains a function `sort(Fun, List)` where\n`Fun` is a fun with two arguments. This fun returns `true` if the first argument\nis less than the second argument, or else `false`. Sorting is added to the\n`convert_list_to_c`:\n\n```erlang\n-module(tut13).\n\n-export([convert_list_to_c/1]).\n\nconvert_to_c({Name, {f, Temp}}) ->\n {Name, {c, trunc((Temp - 32) * 5 / 9)}};\nconvert_to_c({Name, {c, Temp}}) ->\n {Name, {c, Temp}}.\n\nconvert_list_to_c(List) ->\n New_list = lists:map(fun convert_to_c/1, List),\n lists:sort(fun({_, {c, Temp1}}, {_, {c, Temp2}}) ->\n Temp1 c(tut13).\n{ok,tut13}\n94> tut13:convert_list_to_c([{moscow, {c, -10}}, {cape_town, {f, 70}},\n{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).\n[{moscow,{c,-10}},\n {stockholm,{c,-4}},\n {paris,{c,-2}},\n {london,{c,2}},\n {cape_town,{c,21}}]\n```\n\nIn `sort` the fun is used:\n\n```erlang\nfun({_, {c, Temp1}}, {_, {c, Temp2}}) -> Temp1 < Temp2 end,\n```\n\nHere the concept of an _anonymous variable_ `_` is introduced. This is simply\nshorthand for a variable that gets a value, but the value is ignored. This can\nbe used anywhere suitable, not just in funs. `Temp1 < Temp2` returns `true` if\n`Temp1` is less than `Temp2`.","title":"Higher-Order Functions (Funs) - Sequential Programming","ref":"seq_prog.html#higher-order-functions-funs"},{"type":"extras","doc":"\n# Concurrent Programming","title":"Concurrent Programming","ref":"conc_prog.html"},{"type":"extras","doc":"One of the main reasons for using Erlang instead of other functional languages\nis Erlang's ability to handle concurrency and distributed programming. By\nconcurrency is meant programs that can handle several threads of execution at\nthe same time. For example, modern operating systems allow you to use a word\nprocessor, a spreadsheet, a mail client, and a print job all running at the same\ntime. Each processor (CPU) in the system is probably only handling one thread\n(or job) at a time, but it swaps between the jobs at such a rate that it gives\nthe illusion of running them all at the same time. It is easy to create parallel\nthreads of execution in an Erlang program and to allow these threads to\ncommunicate with each other. In Erlang, each thread of execution is called a\n_process_.\n\n(Aside: the term \"process\" is usually used when the threads of execution share\nno data with each other and the term \"thread\" when they share data in some way.\nThreads of execution in Erlang share no data, that is why they are called\nprocesses).\n\nThe Erlang BIF `spawn` is used to create a new process:\n`spawn(Module, Exported_Function, List of Arguments)`. Consider the following\nmodule:\n\n```erlang\n-module(tut14).\n\n-export([start/0, say_something/2]).\n\nsay_something(What, 0) ->\n done;\nsay_something(What, Times) ->\n io:format(\"~p~n\", [What]),\n say_something(What, Times - 1).\n\nstart() ->\n spawn(tut14, say_something, [hello, 3]),\n spawn(tut14, say_something, [goodbye, 3]).\n```\n\n```erlang\n5> c(tut14).\n{ok,tut14}\n6> tut14:say_something(hello, 3).\nhello\nhello\nhello\ndone\n```\n\nAs shown, the function `say_something` writes its first argument the number of\ntimes specified by second argument. The function `start` starts two Erlang\nprocesses, one that writes \"hello\" three times and one that writes \"goodbye\"\nthree times. Both processes use the function `say_something`. Notice that a\nfunction used in this way by `spawn`, to start a process, must be exported from\nthe module (that is, in the `-export` at the start of the module).\n\n```erlang\n9> tut14:start().\nhello\ngoodbye\n<0.63.0>\nhello\ngoodbye\nhello\ngoodbye\n```\n\nNotice that it did not write \"hello\" three times and then \"goodbye\" three times.\nInstead, the first process wrote a \"hello\", the second a \"goodbye\", the first\nanother \"hello\" and so forth. But where did the `<0.63.0>` come from? The return\nvalue of a function is the return value of the last \"thing\" in the function. The\nlast thing in the function `start` is\n\n```erlang\nspawn(tut14, say_something, [goodbye, 3]).\n```\n\n`spawn` returns a _process identifier_, or _pid_, which uniquely identifies the\nprocess. So `<0.63.0>` is the pid of the `spawn` function call above. The next\nexample shows how to use pids.\n\nNotice also that ~p is used instead of ~w in `io:format/2`. To quote [the manual](`m:io#tilde_p`):\n\n> ~p Writes the data with standard syntax in the same way as ~w, but breaks terms\n> whose printed representation is longer than one line into many lines and indents\n> each line sensibly. It also tries to detect flat lists of printable characters and\n> to output these as strings","title":"Processes - Concurrent Programming","ref":"conc_prog.html#processes"},{"type":"extras","doc":"In the following example two processes are created and they send messages to\neach other a number of times.\n\n```erlang\n-module(tut15).\n\n-export([start/0, ping/2, pong/0]).\n\nping(0, Pong_PID) ->\n Pong_PID ! finished,\n io:format(\"ping finished~n\", []);\n\nping(N, Pong_PID) ->\n Pong_PID ! {ping, self()},\n receive\n pong ->\n io:format(\"Ping received pong~n\", [])\n end,\n ping(N - 1, Pong_PID).\n\npong() ->\n receive\n finished ->\n io:format(\"Pong finished~n\", []);\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong()\n end.\n\nstart() ->\n Pong_PID = spawn(tut15, pong, []),\n spawn(tut15, ping, [3, Pong_PID]).\n```\n\n```erlang\n1> c(tut15).\n{ok,tut15}\n2> tut15: start().\n<0.36.0>\nPong received ping\nPing received pong\nPong received ping\nPing received pong\nPong received ping\nPing received pong\nping finished\nPong finished\n```\n\nThe function `start` first creates a process, let us call it \"pong\":\n\n```erlang\nPong_PID = spawn(tut15, pong, [])\n```\n\nThis process executes `tut15:pong()`. `Pong_PID` is the process identity of the\n\"pong\" process. The function `start` now creates another process \"ping\":\n\n```erlang\nspawn(tut15, ping, [3, Pong_PID]),\n```\n\nThis process executes:\n\n```erlang\ntut15:ping(3, Pong_PID)\n```\n\n`<0.36.0>` is the return value from the `start` function.\n\nThe process \"pong\" now does:\n\n```erlang\nreceive\n finished ->\n io:format(\"Pong finished~n\", []);\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong()\nend.\n```\n\nThe `receive` construct is used to allow processes to wait for messages from\nother processes. It has the following format:\n\n```erlang\nreceive\n pattern1 ->\n actions1;\n pattern2 ->\n actions2;\n ....\n patternN\n actionsN\nend.\n```\n\nNotice there is no \";\" before the `end`.\n\nMessages between Erlang processes are simply valid Erlang terms. That is, they\ncan be lists, tuples, integers, atoms, pids, and so on.\n\nEach process has its own input queue for messages it receives. New messages\nreceived are put at the end of the queue. When a process executes a `receive`,\nthe first message in the queue is matched against the first pattern in the\n`receive`. If this matches, the message is removed from the queue and the\nactions corresponding to the pattern are executed.\n\nHowever, if the first pattern does not match, the second pattern is tested. If\nthis matches, the message is removed from the queue and the actions\ncorresponding to the second pattern are executed. If the second pattern does not\nmatch, the third is tried and so on until there are no more patterns to test. If\nthere are no more patterns to test, the first message is kept in the queue and\nthe second message is tried instead. If this matches any pattern, the\nappropriate actions are executed and the second message is removed from the\nqueue (keeping the first message and any other messages in the queue). If the\nsecond message does not match, the third message is tried, and so on, until the\nend of the queue is reached. If the end of the queue is reached, the process\nblocks (stops execution) and waits until a new message is received and this\nprocedure is repeated.\n\nThe Erlang implementation is \"clever\" and minimizes the number of times each\nmessage is tested against the patterns in each `receive`.\n\nNow back to the ping pong example.\n\n\"Pong\" is waiting for messages. If the atom `finished` is received, \"pong\"\nwrites \"Pong finished\" to the output and, as it has nothing more to do,\nterminates. If it receives a message with the format:\n\n```erlang\n{ping, Ping_PID}\n```\n\nit writes \"Pong received ping\" to the output and sends the atom `pong` to the\nprocess \"ping\":\n\n```erlang\nPing_PID ! pong\n```\n\nNotice how the operator \"\\!\" is used to send messages. The syntax of \"\\!\" is:\n\n```erlang\nPid ! Message\n```\n\nThat is, `Message` (any Erlang term) is sent to the process with identity `Pid`.\n\nAfter sending the message `pong` to the process \"ping\", \"pong\" calls the `pong`\nfunction again, which causes it to get back to the `receive` again and wait for\nanother message.\n\nNow let us look at the process \"ping\". Recall that it was started by executing:\n\n```erlang\ntut15:ping(3, Pong_PID)\n```\n\nLooking at the function `ping/2`, the second clause of `ping/2` is executed\nsince the value of the first argument is 3 (not 0) (first clause head is\n`ping(0,Pong_PID)`, second clause head is `ping(N,Pong_PID)`, so `N` becomes 3).\n\nThe second clause sends a message to \"pong\":\n\n```erlang\nPong_PID ! {ping, self()},\n```\n\n`self/0` returns the pid of the process that executes `self/0`, in this case the\npid of \"ping\". (Recall the code for \"pong\", this lands up in the variable\n`Ping_PID` in the `receive` previously explained.)\n\n\"Ping\" now waits for a reply from \"pong\":\n\n```erlang\nreceive\n pong ->\n io:format(\"Ping received pong~n\", [])\nend,\n```\n\nIt writes \"Ping received pong\" when this reply arrives, after which \"ping\" calls\nthe `ping` function again.\n\n```erlang\nping(N - 1, Pong_PID)\n```\n\n`N-1` causes the first argument to be decremented until it becomes 0. When this\noccurs, the first clause of `ping/2` is executed:\n\n```erlang\nping(0, Pong_PID) ->\n Pong_PID ! finished,\n io:format(\"ping finished~n\", []);\n```\n\nThe atom `finished` is sent to \"pong\" (causing it to terminate as described\nabove) and \"ping finished\" is written to the output. \"Ping\" then terminates as\nit has nothing left to do.","title":"Message Passing - Concurrent Programming","ref":"conc_prog.html#message-passing"},{"type":"extras","doc":"In the above example, \"pong\" was first created to be able to give the identity\nof \"pong\" when \"ping\" was started. That is, in some way \"ping\" must be able to\nknow the identity of \"pong\" to be able to send a message to it. Sometimes\nprocesses which need to know each other's identities are started independently\nof each other. Erlang thus provides a mechanism for processes to be given names\nso that these names can be used as identities instead of pids. This is done by\nusing the `register` BIF:\n\n```erlang\nregister(some_atom, Pid)\n```\n\nLet us now rewrite the ping pong example using this and give the name `pong` to\nthe \"pong\" process:\n\n```erlang\n-module(tut16).\n\n-export([start/0, ping/1, pong/0]).\n\nping(0) ->\n pong ! finished,\n io:format(\"ping finished~n\", []);\n\nping(N) ->\n pong ! {ping, self()},\n receive\n pong ->\n io:format(\"Ping received pong~n\", [])\n end,\n ping(N - 1).\n\npong() ->\n receive\n finished ->\n io:format(\"Pong finished~n\", []);\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong()\n end.\n\nstart() ->\n register(pong, spawn(tut16, pong, [])),\n spawn(tut16, ping, [3]).\n```\n\n```erlang\n2> c(tut16).\n{ok, tut16}\n3> tut16:start().\n<0.38.0>\nPong received ping\nPing received pong\nPong received ping\nPing received pong\nPong received ping\nPing received pong\nping finished\nPong finished\n```\n\nHere the `start/0` function,\n\n```erlang\nregister(pong, spawn(tut16, pong, [])),\n```\n\nboth spawns the \"pong\" process and gives it the name `pong`. In the \"ping\"\nprocess, messages can be sent to `pong` by:\n\n```erlang\npong ! {ping, self()},\n```\n\n`ping/2` now becomes `ping/1` as the argument `Pong_PID` is not needed.","title":"Registered Process Names - Concurrent Programming","ref":"conc_prog.html#registered-process-names"},{"type":"extras","doc":"Let us rewrite the ping pong program with \"ping\" and \"pong\" on different\ncomputers. First a few things are needed to set up to get this to work. The\ndistributed Erlang implementation provides a very basic authentication mechanism\nto prevent unintentional access to an Erlang system on another computer. Erlang\nsystems which talk to each other must have the same _magic cookie_. The easiest\nway to achieve this is by having a file called `.erlang.cookie` in your home\ndirectory on all machines on which you are going to run Erlang systems\ncommunicating with each other:\n\n- On Windows systems the home directory is the directory pointed out by the\n environment variable $HOME - you may need to set this.\n- On Linux or UNIX you can safely ignore this and simply create a file called\n `.erlang.cookie` in the directory you get to after executing the command `cd`\n without any argument.\n\nThe `.erlang.cookie` file is to contain a line with the same atom. For example,\non Linux or UNIX, in the OS shell:\n\n```text\n$ cd\n$ cat > .erlang.cookie\nthis_is_very_secret\n$ chmod 400 .erlang.cookie\n```\n\nThe `chmod` above makes the `.erlang.cookie` file accessible only by the owner\nof the file. This is a requirement.\n\nWhen you start an Erlang system that is going to talk to other Erlang systems,\nyou must give it a name, for example:\n\n```text\n$ erl -sname my_name\n```\n\nWe will see more details of this later. If you want to experiment with\ndistributed Erlang, but you only have one computer to work on, you can start two\nseparate Erlang systems on the same computer but give them different names. Each\nErlang system running on a computer is called an _Erlang node_.\n\n(Note: `erl -sname` assumes that all nodes are in the same IP domain and we can\nuse only the first component of the IP address, if we want to use nodes in\ndifferent domains we use `-name` instead, but then all IP address must be given\nin full.)\n\nHere is the ping pong example modified to run on two separate nodes:\n\n```erlang\n-module(tut17).\n\n-export([start_ping/1, start_pong/0, ping/2, pong/0]).\n\nping(0, Pong_Node) ->\n {pong, Pong_Node} ! finished,\n io:format(\"ping finished~n\", []);\n\nping(N, Pong_Node) ->\n {pong, Pong_Node} ! {ping, self()},\n receive\n pong ->\n io:format(\"Ping received pong~n\", [])\n end,\n ping(N - 1, Pong_Node).\n\npong() ->\n receive\n finished ->\n io:format(\"Pong finished~n\", []);\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong()\n end.\n\nstart_pong() ->\n register(pong, spawn(tut17, pong, [])).\n\nstart_ping(Pong_Node) ->\n spawn(tut17, ping, [3, Pong_Node]).\n```\n\nLet us assume there are two computers called gollum and kosken. First a node is\nstarted on kosken, called ping, and then a node on gollum, called pong.\n\nOn kosken (on a Linux/UNIX system):\n\n```text\nkosken> erl -sname ping\nErlang (BEAM) emulator version 5.2.3.7 [hipe] [threads:0]\n\nEshell V5.2.3.7 (abort with ^G)\n(ping@kosken)1>\n```\n\nOn gollum:\n\n```text\ngollum> erl -sname pong\nErlang (BEAM) emulator version 5.2.3.7 [hipe] [threads:0]\n\nEshell V5.2.3.7 (abort with ^G)\n(pong@gollum)1>\n```\n\nNow the \"pong\" process on gollum is started:\n\n```erlang\n(pong@gollum)1> tut17:start_pong().\ntrue\n```\n\nAnd the \"ping\" process on kosken is started (from the code above you can see\nthat a parameter of the `start_ping` function is the node name of the Erlang\nsystem where \"pong\" is running):\n\n```erlang\n(ping@kosken)1> tut17:start_ping(pong@gollum).\n<0.37.0>\nPing received pong\nPing received pong\nPing received pong\nping finished\n```\n\nAs shown, the ping pong program has run. On the \"pong\" side:\n\n```erlang\n(pong@gollum)2> \nPong received ping\nPong received ping\nPong received ping\nPong finished\n(pong@gollum)2> \n```\n\nLooking at the `tut17` code, you see that the `pong` function itself is\nunchanged, the following lines work in the same way irrespective of on which\nnode the \"ping\" process is executes:\n\n```erlang\n{ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n```\n\nThus, Erlang pids contain information about where the process executes. So if\nyou know the pid of a process, the `!` operator can be used to send it a\nmessage disregarding if the process is on the same node or on a different node.\n\nA difference is how messages are sent to a registered process on another node:\n\n```erlang\n{pong, Pong_Node} ! {ping, self()},\n```\n\nA tuple `{registered_name,node_name}` is used instead of just the\n`registered_name`.\n\nIn the previous example, \"ping\" and \"pong\" were started from the shells of two\nseparate Erlang nodes. `spawn` can also be used to start processes in other\nnodes.\n\nThe next example is the ping pong program, yet again, but this time \"ping\" is\nstarted in another node:\n\n```erlang\n-module(tut18).\n\n-export([start/1, ping/2, pong/0]).\n\nping(0, Pong_Node) ->\n {pong, Pong_Node} ! finished,\n io:format(\"ping finished~n\", []);\n\nping(N, Pong_Node) ->\n {pong, Pong_Node} ! {ping, self()},\n receive\n pong ->\n io:format(\"Ping received pong~n\", [])\n end,\n ping(N - 1, Pong_Node).\n\npong() ->\n receive\n finished ->\n io:format(\"Pong finished~n\", []);\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong()\n end.\n\nstart(Ping_Node) ->\n register(pong, spawn(tut18, pong, [])),\n spawn(Ping_Node, tut18, ping, [3, node()]).\n```\n\nAssuming an Erlang system called ping (but not the \"ping\" process) has already\nbeen started on kosken, then on gollum this is done:\n\n```erlang\n(pong@gollum)1> tut18:start(ping@kosken).\n<3934.39.0>\nPong received ping\nPing received pong\nPong received ping\nPing received pong\nPong received ping\nPing received pong\nPong finished\nping finished\n```\n\nNotice that all the output is received on gollum. This is because the I/O system\nfinds out where the process is spawned from and sends all output there.","title":"Distributed Programming - Concurrent Programming","ref":"conc_prog.html#distributed-programming"},{"type":"extras","doc":"Now for a larger example with a simple \"messenger\". The messenger is a program\nthat allows users to log in on different nodes and send simple messages to each\nother.\n\nBefore starting, notice the following:\n\n- This example only shows the message passing logic - no attempt has been made\n to provide a nice graphical user interface, although this can also be done in\n Erlang.\n- This sort of problem can be solved easier by use of the facilities in OTP,\n which also provide methods for updating code on the fly and so on (see\n [OTP Design Principles](`e:system:design_principles.md`)).\n- The first program contains some inadequacies regarding handling of nodes which\n disappear. These are corrected in a later version of the program.\n\nThe messenger is set up by allowing \"clients\" to connect to a central server and\nsay who and where they are. That is, a user does not need to know the name of\nthe Erlang node where another user is located to send a message.\n\nFile `messenger.erl`:\n\n[](){: #ex }\n\n```erlang\n%%% Message passing utility.\n%%% User interface:\n%%% logon(Name)\n%%% One user at a time can log in from each Erlang node in the\n%%% system messenger: and choose a suitable Name. If the Name\n%%% is already logged in at another node or if someone else is\n%%% already logged in at the same node, login will be rejected\n%%% with a suitable error message.\n%%% logoff()\n%%% Logs off anybody at that node\n%%% message(ToName, Message)\n%%% sends Message to ToName. Error messages if the user of this\n%%% function is not logged on or if ToName is not logged on at\n%%% any node.\n%%%\n%%% One node in the network of Erlang nodes runs a server which maintains\n%%% data about the logged on users. The server is registered as \"messenger\"\n%%% Each node where there is a user logged on runs a client process registered\n%%% as \"mess_client\"\n%%%\n%%% Protocol between the client processes and the server\n%%% ----------------------------------------------------\n%%%\n%%% To server: {ClientPid, logon, UserName}\n%%% Reply {messenger, stop, user_exists_at_other_node} stops the client\n%%% Reply {messenger, logged_on} logon was successful\n%%%\n%%% To server: {ClientPid, logoff}\n%%% Reply: {messenger, logged_off}\n%%%\n%%% To server: {ClientPid, logoff}\n%%% Reply: no reply\n%%%\n%%% To server: {ClientPid, message_to, ToName, Message} send a message\n%%% Reply: {messenger, stop, you_are_not_logged_on} stops the client\n%%% Reply: {messenger, receiver_not_found} no user with this name logged on\n%%% Reply: {messenger, sent} Message has been sent (but no guarantee)\n%%%\n%%% To client: {message_from, Name, Message},\n%%%\n%%% Protocol between the \"commands\" and the client\n%%% ----------------------------------------------\n%%%\n%%% Started: messenger:client(Server_Node, Name)\n%%% To client: logoff\n%%% To client: {message_to, ToName, Message}\n%%%\n%%% Configuration: change the server_node() function to return the\n%%% name of the node where the messenger server runs\n\n-module(messenger).\n-export([start_server/0, server/1, logon/1, logoff/0, message/2, client/2]).\n\n%%% Change the function below to return the name of the node where the\n%%% messenger server runs\nserver_node() ->\n messenger@super.\n\n%%% This is the server process for the \"messenger\"\n%%% the user list has the format [{ClientPid1, Name1},{ClientPid22, Name2},...]\nserver(User_List) ->\n receive\n {From, logon, Name} ->\n New_User_List = server_logon(From, Name, User_List),\n server(New_User_List);\n {From, logoff} ->\n New_User_List = server_logoff(From, User_List),\n server(New_User_List);\n {From, message_to, To, Message} ->\n server_transfer(From, To, Message, User_List),\n io:format(\"list is now: ~p~n\", [User_List]),\n server(User_List)\n end.\n\n%%% Start the server\nstart_server() ->\n register(messenger, spawn(messenger, server, [[]])).\n\n\n%%% Server adds a new user to the user list\nserver_logon(From, Name, User_List) ->\n %% check if logged on anywhere else\n case lists:keymember(Name, 2, User_List) of\n true ->\n From ! {messenger, stop, user_exists_at_other_node}, %reject logon\n User_List;\n false ->\n From ! {messenger, logged_on},\n [{From, Name} | User_List] %add user to the list\n end.\n\n%%% Server deletes a user from the user list\nserver_logoff(From, User_List) ->\n lists:keydelete(From, 1, User_List).\n\n\n%%% Server transfers a message between user\nserver_transfer(From, To, Message, User_List) ->\n %% check that the user is logged on and who he is\n case lists:keysearch(From, 1, User_List) of\n false ->\n From ! {messenger, stop, you_are_not_logged_on};\n {value, {From, Name}} ->\n server_transfer(From, Name, To, Message, User_List)\n end.\n%%% If the user exists, send the message\nserver_transfer(From, Name, To, Message, User_List) ->\n %% Find the receiver and send the message\n case lists:keysearch(To, 2, User_List) of\n false ->\n From ! {messenger, receiver_not_found};\n {value, {ToPid, To}} ->\n ToPid ! {message_from, Name, Message},\n From ! {messenger, sent}\n end.\n\n\n%%% User Commands\nlogon(Name) ->\n case whereis(mess_client) of\n undefined ->\n register(mess_client,\n spawn(messenger, client, [server_node(), Name]));\n _ -> already_logged_on\n end.\n\nlogoff() ->\n mess_client ! logoff.\n\nmessage(ToName, Message) ->\n case whereis(mess_client) of % Test if the client is running\n undefined ->\n not_logged_on;\n _ -> mess_client ! {message_to, ToName, Message},\n ok\nend.\n\n\n%%% The client process which runs on each server node\nclient(Server_Node, Name) ->\n {messenger, Server_Node} ! {self(), logon, Name},\n await_result(),\n client(Server_Node).\n\nclient(Server_Node) ->\n receive\n logoff ->\n {messenger, Server_Node} ! {self(), logoff},\n exit(normal);\n {message_to, ToName, Message} ->\n {messenger, Server_Node} ! {self(), message_to, ToName, Message},\n await_result();\n {message_from, FromName, Message} ->\n io:format(\"Message from ~p: ~p~n\", [FromName, Message])\n end,\n client(Server_Node).\n\n%%% wait for a response from the server\nawait_result() ->\n receive\n {messenger, stop, Why} -> % Stop the client\n io:format(\"~p~n\", [Why]),\n exit(normal);\n {messenger, What} -> % Normal response\n io:format(\"~p~n\", [What])\n end.\n```\n\nTo use this program, you need to:\n\n- Configure the `server_node()` function.\n- Copy the compiled code (`messenger.beam`) to the directory on each computer\n where you start Erlang.\n\nIn the following example using this program, nodes are started on four different\ncomputers. If you do not have that many machines available on your network, you\ncan start several nodes on the same machine.\n\nFour Erlang nodes are started up: messenger@super, c1@bilbo, c2@kosken,\nc3@gollum.\n\nFirst the server at messenger@super is started up:\n\n```erlang\n(messenger@super)1> messenger:start_server().\ntrue\n```\n\nNow Peter logs on at c1@bilbo:\n\n```erlang\n(c1@bilbo)1> messenger:logon(peter).\ntrue\nlogged_on\n```\n\nJames logs on at c2@kosken:\n\n```erlang\n(c2@kosken)1> messenger:logon(james).\ntrue\nlogged_on\n```\n\nAnd Fred logs on at c3@gollum:\n\n```erlang\n(c3@gollum)1> messenger:logon(fred).\ntrue\nlogged_on\n```\n\nNow Peter sends Fred a message:\n\n```erlang\n(c1@bilbo)2> messenger:message(fred, \"hello\").\nok\nsent\n```\n\nFred receives the message and sends a message to Peter and logs off:\n\n```erlang\nMessage from peter: \"hello\"\n(c3@gollum)2> messenger:message(peter, \"go away, I'm busy\").\nok\nsent\n(c3@gollum)3> messenger:logoff().\nlogoff\n```\n\nJames now tries to send a message to Fred:\n\n```erlang\n(c2@kosken)2> messenger:message(fred, \"peter doesn't like you\").\nok\nreceiver_not_found\n```\n\nBut this fails as Fred has already logged off.\n\nFirst let us look at some of the new concepts that have been introduced.\n\nThere are two versions of the `server_transfer` function: one with four\narguments (`server_transfer/4`) and one with five (`server_transfer/5`). These\nare regarded by Erlang as two separate functions.\n\nNotice how to write the `server` function so that it calls itself, through\n`server(User_List)`, and thus creates a loop. The Erlang compiler is \"clever\"\nand optimizes the code so that this really is a sort of loop and not a proper\nfunction call. But this only works if there is no code after the call.\nOtherwise, the compiler expects the call to return and make a proper function\ncall. This would result in the process getting bigger and bigger for every loop.\n\nFunctions in the `lists` module are used. This is a very useful module and a\nstudy of the manual page is recommended (`erl -man lists`).\n`lists:keymember(Key,Position,Lists)` looks through a list of tuples and looks\nat `Position` in each tuple to see if it is the same as `Key`. The first element\nis position 1. If it finds a tuple where the element at `Position` is the same\nas `Key`, it returns `true`, otherwise `false`.\n\n```erlang\n3> lists:keymember(a, 2, [{x,y,z},{b,b,b},{b,a,c},{q,r,s}]).\ntrue\n4> lists:keymember(p, 2, [{x,y,z},{b,b,b},{b,a,c},{q,r,s}]).\nfalse\n```\n\n`lists:keydelete` works in the same way but deletes the first tuple found (if\nany) and returns the remaining list:\n\n```erlang\n5> lists:keydelete(a, 2, [{x,y,z},{b,b,b},{b,a,c},{q,r,s}]).\n[{x,y,z},{b,b,b},{q,r,s}]\n```\n\n`lists:keysearch` is like `lists:keymember`, but it returns\n`{value,Tuple_Found}` or the atom `false`.\n\nThere are many very useful functions in the `lists` module.\n\nAn Erlang process (conceptually) runs until it does a `receive` and there is no\nmessage which it wants to receive in the message queue. \"conceptually\" is used\nhere because the Erlang system shares the CPU time between the active processes\nin the system.\n\nA process terminates when there is nothing more for it to do, that is, the last\nfunction it calls simply returns and does not call another function. Another way\nfor a process to terminate is for it to call [`exit/1`](`exit/1`). The argument\nto [`exit/1`](`exit/1`) has a special meaning, which is discussed later. In this\nexample, [`exit(normal)`](`exit/1`) is done, which has the same effect as a\nprocess running out of functions to call.\n\nThe BIF [`whereis(RegisteredName)`](`whereis/1`) checks if a registered process\nof name `RegisteredName` exists. If it exists, the pid of that process is\nreturned. If it does not exist, the atom `undefined` is returned.\n\nYou should by now be able to understand most of the code in the\nmessenger-module. Let us study one case in detail: a message is sent from one\nuser to another.\n\nThe first user \"sends\" the message in the example above by:\n\n```erlang\nmessenger:message(fred, \"hello\")\n```\n\nAfter testing that the client process exists:\n\n```erlang\nwhereis(mess_client)\n```\n\nAnd a message is sent to `mess_client`:\n\n```erlang\nmess_client ! {message_to, fred, \"hello\"}\n```\n\nThe client sends the message to the server by:\n\n```erlang\n{messenger, messenger@super} ! {self(), message_to, fred, \"hello\"},\n```\n\nAnd waits for a reply from the server.\n\nThe server receives this message and calls:\n\n```erlang\nserver_transfer(From, fred, \"hello\", User_List),\n```\n\nThis checks that the pid `From` is in the `User_List`:\n\n```erlang\nlists:keysearch(From, 1, User_List)\n```\n\nIf `keysearch` returns the atom `false`, some error has occurred and the server\nsends back the message:\n\n```erlang\nFrom ! {messenger, stop, you_are_not_logged_on}\n```\n\nThis is received by the client, which in turn does [`exit(normal)`](`exit/1`)\nand terminates. If `keysearch` returns `{value,{From,Name}}` it is certain that\nthe user is logged on and that his name (peter) is in variable `Name`.\n\nLet us now call:\n\n```erlang\nserver_transfer(From, peter, fred, \"hello\", User_List)\n```\n\nNotice that as this is `server_transfer/5`, it is not the same as the previous\nfunction `server_transfer/4`. Another `keysearch` is done on `User_List` to find\nthe pid of the client corresponding to fred:\n\n```erlang\nlists:keysearch(fred, 2, User_List)\n```\n\nThis time argument 2 is used, which is the second element in the tuple. If this\nreturns the atom `false`, fred is not logged on and the following message is\nsent:\n\n```erlang\nFrom ! {messenger, receiver_not_found};\n```\n\nThis is received by the client.\n\nIf `keysearch` returns:\n\n```erlang\n{value, {ToPid, fred}}\n```\n\nThe following message is sent to fred's client:\n\n```erlang\nToPid ! {message_from, peter, \"hello\"},\n```\n\nThe following message is sent to peter's client:\n\n```erlang\nFrom ! {messenger, sent}\n```\n\nFred's client receives the message and prints it:\n\n```erlang\n{message_from, peter, \"hello\"} ->\n io:format(\"Message from ~p: ~p~n\", [peter, \"hello\"])\n```\n\nPeter's client receives the message in the `await_result` function.","title":"A Larger Example - Concurrent Programming","ref":"conc_prog.html#a-larger-example"},{"type":"extras","doc":"\n# Robustness\n\nSeveral things are wrong with the messenger example in\n[A Larger Example](conc_prog.md#ex). For example, if a node where a user is\nlogged on goes down without doing a logoff, the user remains in the server's\n`User_List`, but the client disappears. This makes it impossible for the user to\nlog on again as the server thinks the user already is logged on.\n\nOr what happens if the server goes down in the middle of sending a message,\nleaving the sending client hanging forever in the `await_result` function?","title":"Robustness","ref":"robustness.html"},{"type":"extras","doc":"Before improving the messenger program, let us look at some general principles,\nusing the ping pong program as an example. Recall that when \"ping\" finishes, it\ntells \"pong\" that it has done so by sending the atom `finished` as a message to\n\"pong\" so that \"pong\" can also finish. Another way to let \"pong\" finish is to\nmake \"pong\" exit if it does not receive a message from ping within a certain\ntime. This can be done by adding a _time-out_ to `pong` as shown in the\nfollowing example:\n\n```erlang\n-module(tut19).\n\n-export([start_ping/1, start_pong/0, ping/2, pong/0]).\n\nping(0, Pong_Node) ->\n io:format(\"ping finished~n\", []);\n\nping(N, Pong_Node) ->\n {pong, Pong_Node} ! {ping, self()},\n receive\n pong ->\n io:format(\"Ping received pong~n\", [])\n end,\n ping(N - 1, Pong_Node).\n\npong() ->\n receive\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong()\n after 5000 ->\n io:format(\"Pong timed out~n\", [])\n end.\n\nstart_pong() ->\n register(pong, spawn(tut19, pong, [])).\n\nstart_ping(Pong_Node) ->\n spawn(tut19, ping, [3, Pong_Node]).\n```\n\nAfter this is compiled and the file `tut19.beam` is copied to the necessary\ndirectories, the following is seen on (pong@kosken):\n\n```text\n(pong@kosken)1> tut19:start_pong().\ntrue\nPong received ping\nPong received ping\nPong received ping\nPong timed out\n```\n\nAnd the following is seen on (ping@gollum):\n\n```text\n(ping@gollum)1> tut19:start_ping(pong@kosken).\n<0.36.0>\nPing received pong\nPing received pong\nPing received pong\nping finished\n```\n\nThe time-out is set in:\n\n```erlang\npong() ->\n receive\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong()\n after 5000 ->\n io:format(\"Pong timed out~n\", [])\n end.\n```\n\nThe time-out (`after 5000`) is started when `receive` is entered. The time-out\nis canceled if `{ping,Ping_PID}` is received. If `{ping,Ping_PID}` is not\nreceived, the actions following the time-out are done after 5000 milliseconds.\n`after` must be last in the `receive`, that is, preceded by all other message\nreception specifications in the `receive`. It is also possible to call a\nfunction that returned an integer for the time-out:\n\n```erlang\nafter pong_timeout() ->\n```\n\nIn general, there are better ways than using time-outs to supervise parts of a\ndistributed Erlang system. Time-outs are usually appropriate to supervise\nexternal events, for example, if you have expected a message from some external\nsystem within a specified time. For example, a time-out can be used to log a\nuser out of the messenger system if they have not accessed it for, say, ten\nminutes.","title":"Time-outs - Robustness","ref":"robustness.html#time-outs"},{"type":"extras","doc":"Before going into details of the supervision and error handling in an Erlang\nsystem, let us see how Erlang processes terminate, or in Erlang terminology,\n_exit_.\n\nA process which executes [`exit(normal)`](`exit/1`) or simply runs out of things\nto do has a _normal_ exit.\n\nA process which encounters a runtime error (for example, divide by zero, bad\nmatch, trying to call a function that does not exist and so on) exits with an\nerror, that is, has an _abnormal_ exit. A process which executes\n[exit(Reason)](`erlang:exit/1`) where `Reason` is any Erlang term except the\natom `normal`, also has an abnormal exit.\n\nAn Erlang process can set up links to other Erlang processes. If a process calls\n[link(Other_Pid)](`erlang:link/1`) it sets up a bidirectional link between\nitself and the process called `Other_Pid`. When a process terminates, it sends\nsomething called a _signal_ to all the processes it has links to.\n\nThe signal carries information about the pid it was sent from and the exit\nreason.\n\nThe default behaviour of a process that receives a normal exit is to ignore the\nsignal.\n\nThe default behaviour in the two other cases (that is, abnormal exit) above is\nto:\n\n- Bypass all messages to the receiving process.\n- Kill the receiving process.\n- Propagate the same error signal to the links of the killed process.\n\nIn this way you can connect all processes in a transaction together using links.\nIf one of the processes exits abnormally, all the processes in the transaction\nare killed. As it is often wanted to create a process and link to it at the same\ntime, there is a special BIF, [spawn_link](`erlang:spawn_link/1`) that does the\nsame as `spawn`, but also creates a link to the spawned process.\n\nNow an example of the ping pong example using links to terminate \"pong\":\n\n```erlang\n-module(tut20).\n\n-export([start/1, ping/2, pong/0]).\n\nping(N, Pong_Pid) ->\n link(Pong_Pid),\n ping1(N, Pong_Pid).\n\nping1(0, _) ->\n exit(ping);\n\nping1(N, Pong_Pid) ->\n Pong_Pid ! {ping, self()},\n receive\n pong ->\n io:format(\"Ping received pong~n\", [])\n end,\n ping1(N - 1, Pong_Pid).\n\npong() ->\n receive\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong()\n end.\n\nstart(Ping_Node) ->\n PongPID = spawn(tut20, pong, []),\n spawn(Ping_Node, tut20, ping, [3, PongPID]).\n```\n\n```text\n(s1@bill)3> tut20:start(s2@kosken).\nPong received ping\n<3820.41.0>\nPing received pong\nPong received ping\nPing received pong\nPong received ping\nPing received pong\n```\n\nThis is a slight modification of the ping pong program where both processes are\nspawned from the same `start/1` function, and the \"ping\" process can be spawned\non a separate node. Notice the use of the `link` BIF. \"Ping\" calls\n[`exit(ping)`](`exit/1`) when it finishes and this causes an exit signal to be\nsent to \"pong\", which also terminates.\n\nIt is possible to modify the default behaviour of a process so that it does not\nget killed when it receives abnormal exit signals. Instead, all signals are\nturned into normal messages on the format `{'EXIT',FromPID,Reason}` and added to\nthe end of the receiving process' message queue. This behaviour is set by:\n\n```erlang\nprocess_flag(trap_exit, true)\n```\n\nThere are several other process flags, see [erlang(3)](`erlang:process_flag/2`).\nChanging the default behaviour of a process in this way is usually not done in\nstandard user programs, but is left to the supervisory programs in OTP. However,\nthe ping pong program is modified to illustrate exit trapping.\n\n```erlang\n-module(tut21).\n\n-export([start/1, ping/2, pong/0]).\n\nping(N, Pong_Pid) ->\n link(Pong_Pid),\n ping1(N, Pong_Pid).\n\nping1(0, _) ->\n exit(ping);\n\nping1(N, Pong_Pid) ->\n Pong_Pid ! {ping, self()},\n receive\n pong ->\n io:format(\"Ping received pong~n\", [])\n end,\n ping1(N - 1, Pong_Pid).\n\npong() ->\n process_flag(trap_exit, true),\n pong1().\n\npong1() ->\n receive\n {ping, Ping_PID} ->\n io:format(\"Pong received ping~n\", []),\n Ping_PID ! pong,\n pong1();\n {'EXIT', From, Reason} ->\n io:format(\"pong exiting, got ~p~n\", [{'EXIT', From, Reason}])\n end.\n\nstart(Ping_Node) ->\n PongPID = spawn(tut21, pong, []),\n spawn(Ping_Node, tut21, ping, [3, PongPID]).\n```\n\n```text\n(s1@bill)1> tut21:start(s2@gollum).\n<3820.39.0>\nPong received ping\nPing received pong\nPong received ping\nPing received pong\nPong received ping\nPing received pong\npong exiting, got {'EXIT',<3820.39.0>,ping}\n```","title":"Error Handling - Robustness","ref":"robustness.html#error-handling"},{"type":"extras","doc":"Let us return to the messenger program and add changes to make it more robust:\n\n```erlang\n%%% Message passing utility.\n%%% User interface:\n%%% login(Name)\n%%% One user at a time can log in from each Erlang node in the\n%%% system messenger: and choose a suitable Name. If the Name\n%%% is already logged in at another node or if someone else is\n%%% already logged in at the same node, login will be rejected\n%%% with a suitable error message.\n%%% logoff()\n%%% Logs off anybody at that node\n%%% message(ToName, Message)\n%%% sends Message to ToName. Error messages if the user of this\n%%% function is not logged on or if ToName is not logged on at\n%%% any node.\n%%%\n%%% One node in the network of Erlang nodes runs a server which maintains\n%%% data about the logged on users. The server is registered as \"messenger\"\n%%% Each node where there is a user logged on runs a client process registered\n%%% as \"mess_client\"\n%%%\n%%% Protocol between the client processes and the server\n%%% ----------------------------------------------------\n%%%\n%%% To server: {ClientPid, logon, UserName}\n%%% Reply {messenger, stop, user_exists_at_other_node} stops the client\n%%% Reply {messenger, logged_on} logon was successful\n%%%\n%%% When the client terminates for some reason\n%%% To server: {'EXIT', ClientPid, Reason}\n%%%\n%%% To server: {ClientPid, message_to, ToName, Message} send a message\n%%% Reply: {messenger, stop, you_are_not_logged_on} stops the client\n%%% Reply: {messenger, receiver_not_found} no user with this name logged on\n%%% Reply: {messenger, sent} Message has been sent (but no guarantee)\n%%%\n%%% To client: {message_from, Name, Message},\n%%%\n%%% Protocol between the \"commands\" and the client\n%%% ----------------------------------------------\n%%%\n%%% Started: messenger:client(Server_Node, Name)\n%%% To client: logoff\n%%% To client: {message_to, ToName, Message}\n%%%\n%%% Configuration: change the server_node() function to return the\n%%% name of the node where the messenger server runs\n\n-module(messenger).\n-export([start_server/0, server/0,\n logon/1, logoff/0, message/2, client/2]).\n\n%%% Change the function below to return the name of the node where the\n%%% messenger server runs\nserver_node() ->\n messenger@super.\n\n%%% This is the server process for the \"messenger\"\n%%% the user list has the format [{ClientPid1, Name1},{ClientPid22, Name2},...]\nserver() ->\n process_flag(trap_exit, true),\n server([]).\n\nserver(User_List) ->\n receive\n {From, logon, Name} ->\n New_User_List = server_logon(From, Name, User_List),\n server(New_User_List);\n {'EXIT', From, _} ->\n New_User_List = server_logoff(From, User_List),\n server(New_User_List);\n {From, message_to, To, Message} ->\n server_transfer(From, To, Message, User_List),\n io:format(\"list is now: ~p~n\", [User_List]),\n server(User_List)\n end.\n\n%%% Start the server\nstart_server() ->\n register(messenger, spawn(messenger, server, [])).\n\n%%% Server adds a new user to the user list\nserver_logon(From, Name, User_List) ->\n %% check if logged on anywhere else\n case lists:keymember(Name, 2, User_List) of\n true ->\n From ! {messenger, stop, user_exists_at_other_node}, %reject logon\n User_List;\n false ->\n From ! {messenger, logged_on},\n link(From),\n [{From, Name} | User_List] %add user to the list\n end.\n\n%%% Server deletes a user from the user list\nserver_logoff(From, User_List) ->\n lists:keydelete(From, 1, User_List).\n\n\n%%% Server transfers a message between user\nserver_transfer(From, To, Message, User_List) ->\n %% check that the user is logged on and who he is\n case lists:keysearch(From, 1, User_List) of\n false ->\n From ! {messenger, stop, you_are_not_logged_on};\n {value, {_, Name}} ->\n server_transfer(From, Name, To, Message, User_List)\n end.\n\n%%% If the user exists, send the message\nserver_transfer(From, Name, To, Message, User_List) ->\n %% Find the receiver and send the message\n case lists:keysearch(To, 2, User_List) of\n false ->\n From ! {messenger, receiver_not_found};\n {value, {ToPid, To}} ->\n ToPid ! {message_from, Name, Message},\n From ! {messenger, sent}\n end.\n\n%%% User Commands\nlogon(Name) ->\n case whereis(mess_client) of\n undefined ->\n register(mess_client,\n spawn(messenger, client, [server_node(), Name]));\n _ -> already_logged_on\n end.\n\nlogoff() ->\n mess_client ! logoff.\n\nmessage(ToName, Message) ->\n case whereis(mess_client) of % Test if the client is running\n undefined ->\n not_logged_on;\n _ -> mess_client ! {message_to, ToName, Message},\n ok\nend.\n\n%%% The client process which runs on each user node\nclient(Server_Node, Name) ->\n {messenger, Server_Node} ! {self(), logon, Name},\n await_result(),\n client(Server_Node).\n\nclient(Server_Node) ->\n receive\n logoff ->\n exit(normal);\n {message_to, ToName, Message} ->\n {messenger, Server_Node} ! {self(), message_to, ToName, Message},\n await_result();\n {message_from, FromName, Message} ->\n io:format(\"Message from ~p: ~p~n\", [FromName, Message])\n end,\n client(Server_Node).\n\n%%% wait for a response from the server\nawait_result() ->\n receive\n {messenger, stop, Why} -> % Stop the client\n io:format(\"~p~n\", [Why]),\n exit(normal);\n {messenger, What} -> % Normal response\n io:format(\"~p~n\", [What])\n after 5000 ->\n io:format(\"No response from server~n\", []),\n exit(timeout)\n end.\n```\n\nThe following changes are added:\n\nThe messenger server traps exits. If it receives an exit signal,\n`{'EXIT',From,Reason}`, this means that a client process has terminated or is\nunreachable for one of the following reasons:\n\n- The user has logged off (the \"logoff\" message is removed).\n- The network connection to the client is broken.\n- The node on which the client process resides has gone down.\n- The client processes has done some illegal operation.\n\nIf an exit signal is received as above, the tuple `{From,Name}` is deleted from\nthe servers `User_List` using the `server_logoff` function. If the node on which\nthe server runs goes down, an exit signal (automatically generated by the\nsystem) is sent to all of the client processes:\n`{'EXIT',MessengerPID,noconnection}` causing all the client processes to\nterminate.\n\nAlso, a time-out of five seconds has been introduced in the `await_result`\nfunction. That is, if the server does not reply within five seconds (5000 ms),\nthe client terminates. This is only needed in the logon sequence before the\nclient and the server are linked.\n\nAn interesting case is if the client terminates before the server links to it.\nThis is taken care of because linking to a non-existent process causes an exit\nsignal, `{'EXIT',From,noproc}`, to be automatically generated. This is as if the\nprocess terminated immediately after the link operation.","title":"The Larger Example with Robustness Added - Robustness","ref":"robustness.html#the-larger-example-with-robustness-added"},{"type":"extras","doc":"\n# Records and Macros\n\nLarger programs are usually written as a collection of files with a well-defined\ninterface between the various parts.","title":"Records and Macros","ref":"records_macros.html"},{"type":"extras","doc":"To illustrate this, the messenger example from the previous section is divided\ninto the following five files:\n\n- `mess_config.hrl`\n\n Header file for configuration data\n\n- `mess_interface.hrl`\n\n Interface definitions between the client and the messenger\n\n- `user_interface.erl`\n\n Functions for the user interface\n\n- `mess_client.erl`\n\n Functions for the client side of the messenger\n\n- `mess_server.erl`\n\n Functions for the server side of the messenger\n\nWhile doing this, the message passing interface between the shell, the client,\nand the server is cleaned up and is defined using _records_. Also, _macros_ are\nintroduced:\n\n```erlang\n%%%----FILE mess_config.hrl----\n\n%%% Configure the location of the server node,\n-define(server_node, messenger@super).\n\n%%%----END FILE----\n```\n\n```erlang\n%%%----FILE mess_interface.hrl----\n\n%%% Message interface between client and server and client shell for\n%%% messenger program\n\n%%%Messages from Client to server received in server/1 function.\n-record(logon,{client_pid, username}).\n-record(message,{client_pid, to_name, message}).\n%%% {'EXIT', ClientPid, Reason} (client terminated or unreachable.\n\n%%% Messages from Server to Client, received in await_result/0 function\n-record(abort_client,{message}).\n%%% Messages are: user_exists_at_other_node,\n%%% you_are_not_logged_on\n-record(server_reply,{message}).\n%%% Messages are: logged_on\n%%% receiver_not_found\n%%% sent (Message has been sent (no guarantee)\n%%% Messages from Server to Client received in client/1 function\n-record(message_from,{from_name, message}).\n\n%%% Messages from shell to Client received in client/1 function\n%%% spawn(mess_client, client, [server_node(), Name])\n-record(message_to,{to_name, message}).\n%%% logoff\n\n%%%----END FILE----\n```\n\n```erlang\n%%%----FILE user_interface.erl----\n\n%%% User interface to the messenger program\n%%% login(Name)\n%%% One user at a time can log in from each Erlang node in the\n%%% system messenger: and choose a suitable Name. If the Name\n%%% is already logged in at another node or if someone else is\n%%% already logged in at the same node, login will be rejected\n%%% with a suitable error message.\n\n%%% logoff()\n%%% Logs off anybody at that node\n\n%%% message(ToName, Message)\n%%% sends Message to ToName. Error messages if the user of this\n%%% function is not logged on or if ToName is not logged on at\n%%% any node.\n\n-module(user_interface).\n-export([logon/1, logoff/0, message/2]).\n-include(\"mess_interface.hrl\").\n-include(\"mess_config.hrl\").\n\nlogon(Name) ->\n case whereis(mess_client) of\n undefined ->\n register(mess_client,\n spawn(mess_client, client, [?server_node, Name]));\n _ -> already_logged_on\n end.\n\nlogoff() ->\n mess_client ! logoff.\n\nmessage(ToName, Message) ->\n case whereis(mess_client) of % Test if the client is running\n undefined ->\n not_logged_on;\n _ -> mess_client ! #message_to{to_name=ToName, message=Message},\n ok\nend.\n\n%%%----END FILE----\n```\n\n```erlang\n%%%----FILE mess_client.erl----\n\n%%% The client process which runs on each user node\n\n-module(mess_client).\n-export([client/2]).\n-include(\"mess_interface.hrl\").\n\nclient(Server_Node, Name) ->\n {messenger, Server_Node} ! #logon{client_pid=self(), username=Name},\n await_result(),\n client(Server_Node).\n\nclient(Server_Node) ->\n receive\n logoff ->\n exit(normal);\n #message_to{to_name=ToName, message=Message} ->\n {messenger, Server_Node} !\n #message{client_pid=self(), to_name=ToName, message=Message},\n await_result();\n {message_from, FromName, Message} ->\n io:format(\"Message from ~p: ~p~n\", [FromName, Message])\n end,\n client(Server_Node).\n\n%%% wait for a response from the server\nawait_result() ->\n receive\n #abort_client{message=Why} ->\n io:format(\"~p~n\", [Why]),\n exit(normal);\n #server_reply{message=What} ->\n io:format(\"~p~n\", [What])\n after 5000 ->\n io:format(\"No response from server~n\", []),\n exit(timeout)\n end.\n\n%%%----END FILE---\n```\n\n```erlang\n%%%----FILE mess_server.erl----\n\n%%% This is the server process of the messenger service\n\n-module(mess_server).\n-export([start_server/0, server/0]).\n-include(\"mess_interface.hrl\").\n\nserver() ->\n process_flag(trap_exit, true),\n server([]).\n\n%%% the user list has the format [{ClientPid1, Name1},{ClientPid22, Name2},...]\nserver(User_List) ->\n io:format(\"User list = ~p~n\", [User_List]),\n receive\n #logon{client_pid=From, username=Name} ->\n New_User_List = server_logon(From, Name, User_List),\n server(New_User_List);\n {'EXIT', From, _} ->\n New_User_List = server_logoff(From, User_List),\n server(New_User_List);\n #message{client_pid=From, to_name=To, message=Message} ->\n server_transfer(From, To, Message, User_List),\n server(User_List)\n end.\n\n%%% Start the server\nstart_server() ->\n register(messenger, spawn(?MODULE, server, [])).\n\n%%% Server adds a new user to the user list\nserver_logon(From, Name, User_List) ->\n %% check if logged on anywhere else\n case lists:keymember(Name, 2, User_List) of\n true ->\n From ! #abort_client{message=user_exists_at_other_node},\n User_List;\n false ->\n From ! #server_reply{message=logged_on},\n link(From),\n [{From, Name} | User_List] %add user to the list\n end.\n\n%%% Server deletes a user from the user list\nserver_logoff(From, User_List) ->\n lists:keydelete(From, 1, User_List).\n\n%%% Server transfers a message between user\nserver_transfer(From, To, Message, User_List) ->\n %% check that the user is logged on and who he is\n case lists:keysearch(From, 1, User_List) of\n false ->\n From ! #abort_client{message=you_are_not_logged_on};\n {value, {_, Name}} ->\n server_transfer(From, Name, To, Message, User_List)\n end.\n%%% If the user exists, send the message\nserver_transfer(From, Name, To, Message, User_List) ->\n %% Find the receiver and send the message\n case lists:keysearch(To, 2, User_List) of\n false ->\n From ! #server_reply{message=receiver_not_found};\n {value, {ToPid, To}} ->\n ToPid ! #message_from{from_name=Name, message=Message},\n From ! #server_reply{message=sent}\n end.\n\n%%%----END FILE---\n```","title":"The Larger Example Divided into Several Files - Records and Macros","ref":"records_macros.html#the-larger-example-divided-into-several-files"},{"type":"extras","doc":"As shown above, some files have extension `.hrl`. These are header files that\nare included in the `.erl` files by:\n\n```erlang\n-include(\"File_Name\").\n```\n\nfor example:\n\n```erlang\n-include(\"mess_interface.hrl\").\n```\n\nIn the case above the file is fetched from the same directory as all the other\nfiles in the messenger example. (_manual_).\n\n.hrl files can contain any valid Erlang code but are most often used for record\nand macro definitions.","title":"Header Files - Records and Macros","ref":"records_macros.html#header-files"},{"type":"extras","doc":"A record is defined as:\n\n```erlang\n-record(name_of_record,{field_name1, field_name2, field_name3, ......}).\n```\n\nFor example:\n\n```erlang\n-record(message_to,{to_name, message}).\n```\n\nThis is equivalent to:\n\n```erlang\n{message_to, To_Name, Message}\n```\n\nCreating a record is best illustrated by an example:\n\n```erlang\n#message_to{message=\"hello\", to_name=fred)\n```\n\nThis creates:\n\n```erlang\n{message_to, fred, \"hello\"}\n```\n\nNotice that you do not have to worry about the order you assign values to the\nvarious parts of the records when you create it. The advantage of using records\nis that by placing their definitions in header files you can conveniently define\ninterfaces that are easy to change. For example, if you want to add a new field\nto the record, you only have to change the code where the new field is used and\nnot at every place the record is referred to. If you leave out a field when\ncreating a record, it gets the value of the atom `undefined`. (_manual_)\n\nPattern matching with records is very similar to creating records. For example,\ninside a `case` or `receive`:\n\n```erlang\n#message_to{to_name=ToName, message=Message} ->\n```\n\nThis is the same as:\n\n```erlang\n{message_to, ToName, Message}\n```","title":"Records - Records and Macros","ref":"records_macros.html#records"},{"type":"extras","doc":"Another thing that has been added to the messenger is a macro. The file\n`mess_config.hrl` contains the definition:\n\n```erlang\n%%% Configure the location of the server node,\n-define(server_node, messenger@super).\n```\n\nThis file is included in `mess_server.erl`:\n\n```erlang\n-include(\"mess_config.hrl\").\n```\n\nEvery occurrence of `?server_node` in `mess_server.erl` is now replaced by\n`messenger@super`.\n\nA macro is also used when spawning the server process:\n\n```erlang\nspawn(?MODULE, server, [])\n```\n\nThis is a standard macro (that is, defined by the system, not by the user).\n`?MODULE` is always replaced by the name of the current module (that is, the\n`-module` definition near the start of the file). There are more advanced ways\nof using macros with, for example, [parameters](macros.md#defining-and-using-macros).\n\nThe three Erlang (`.erl`) files in the messenger example are individually\ncompiled into object code file (`.beam`). The Erlang system loads and links\nthese files into the system when they are referred to during execution of the\ncode. In this case, they are simply put in our current working directory (that\nis, the place you have done \"cd\" to). There are ways of putting the `.beam`\nfiles in other directories.\n\nIn the messenger example, no assumptions have been made about what the message\nbeing sent is. It can be any valid Erlang term.","title":"Macros - Records and Macros","ref":"records_macros.html#macros"},{"type":"extras","doc":"\n# System Principles\n\n[](){: #system-principles }","title":"System Principles","ref":"system_principles.html"},{"type":"extras","doc":"An Erlang runtime system is started with command `erl`:\n\n```text\n% erl\nErlang/OTP 27 [erts-15.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]\n\nEshell V15.0 (press Ctrl+G to abort, type help(). for help)\n1>\n```\n\n`erl` understands a number of command-line arguments; see\n[erl](`e:erts:erl_cmd.md`) in the ERTS application. Some arguments are\nalso described in this chapter.\n\nApplication programs can access the values of the command-line arguments by\ncalling one of the following functions:\n\n* [`init:get_argument(Key)`](https://www.erlang.org/doc/man/init#get_argument-1)\n* [`init:get_arguments()`](https://www.erlang.org/doc/man/init#get_arguments-0)\n* [`init:get_plain_arguments()`](https://www.erlang.org/doc/man/init#get_plain_arguments-0)","title":"Starting the System - System Principles","ref":"system_principles.html#starting-the-system"},{"type":"extras","doc":"The runtime system is halted by calling\n[`halt/0,1,2`](https://www.erlang.org/doc/man/erlang#halt-2).\n\nModule `m:init` contains functions for restarting, rebooting, and stopping the\nruntime system:\n\n* [`init:restart()`](https://www.erlang.org/doc/man/init#restart-0)\n* [`init:reboot()`](https://www.erlang.org/doc/man/init#reboot-0)\n* [`init:stop()`](https://www.erlang.org/doc/man/init#stop-0)\n\nThe runtime system terminates if the Erlang shell is terminated.\n\n[](){: #BOOTSCRIPT }","title":"Restarting and Stopping the System - System Principles","ref":"system_principles.html#restarting-and-stopping-the-system"},{"type":"extras","doc":"The runtime system is started using a _boot script_. The boot script contains\ninstructions on which code to load and which processes and applications to\nstart.\n\nA boot script file has the extension `.script`. The runtime system uses a binary\nversion of the script. This _binary boot script_ file has the extension `.boot`.\n\nWhich boot script to use is specified by the command-line flag `-boot`. The\nextension `.boot` is to be omitted. For example, using the boot script\n`start_all.boot`:\n\n```text\n% erl -boot start_all\n```\n\nIf no boot script is specified, it defaults to `ROOT/bin/start`, where\n`ROOT` is the installation directory of Erlang/OTP. See [Default Boot\nScripts](system_principles.md#default_boot_scripts).\n\nWhen the command-line flag `-init_debug` is used, the `init` process will\noutput debug information while interpreting the boot script.\n\n```text\n% erl -init_debug\n{progress,preloaded}\n{progress,kernel_load_completed}\n{progress,modules_loaded}\n{start,heart}\n{start,logger}\n .\n .\n .\n```\n\nFor a detailed description of the syntax and contents of the boot script, see\n[`script`](https://www.erlang.org/doc/man/script) in the SASL application.\n\n[](){: #default_boot_scripts }","title":"Boot Scripts - System Principles","ref":"system_principles.html#boot-scripts"},{"type":"extras","doc":"Erlang/OTP comes with these boot scripts:\n\n- `start_clean.boot` \\- Loads the code for and starts the applications Kernel\n and STDLIB.\n- `start_sasl.boot` \\- Loads the code for and starts the applications Kernel,\n STDLIB, and SASL.\n- `no_dot_erlang.boot` \\- Loads the code for and starts the applications Kernel\n and STDLIB. Skips loading the file `.erlang`. Useful for scripts and other\n tools that are to behave the same irrespective of user preferences.\n\nWhich of `start_clean` and `start_sasl` to use as default is decided by the user\nwhen installing Erlang/OTP using `Install`. The user is asked:\n\n```text\nDo you want to use a minimal system startup instead of the SASL startup?\n```\n\nIf the answer is yes, `start_clean` is used, otherwise `start_sasl` is\nused. The chosen boot script is copied and renamed as `start.boot`,\nthen placed into directory `ROOT/bin`.","title":"Default Boot Scripts - System Principles","ref":"system_principles.html#default-boot-scripts"},{"type":"extras","doc":"It is sometimes useful or necessary to create a user-defined boot script. This\nis true especially when running Erlang in embedded mode; see\n[Code Loading Strategy](system_principles.md#code_loading).\n\nWhile it is possible to manually create a boot script, it is\npreferable to generate it from a release resource file called\n`Name.rel` using the function\n[`systools:make_script/1,2`](https://www.erlang.org/doc/man/systools#make_script-2).\nThis requires that the source code is structured as applications\naccording to the OTP design principles.\n\nFor more information about `.rel` files, see\n[OTP Design Principles](`e:system:release_handling.md`) and the\n[rel](`e:sasl:rel.md`) page in SASL.\n\nTo generate the binary boot script file `Name.boot` the boot script file\n`Name.script`, use the\n[`systools:script2boot(File)`](https://www.erlang.org/doc/man/systools#script2boot-1)\nfunction.\n\n[](){: #code_loading }","title":"User-Defined Boot Scripts - System Principles","ref":"system_principles.html#user-defined-boot-scripts"},{"type":"extras","doc":"The runtime system can be started in either _embedded_ or _interactive_ mode.\nWhich one is decided by the command-line flag `-mode`:\n\n```text\n% erl -mode embedded\n```\n\nThe default mode is `interactive`. If more than one `-mode` flag is given,\nthe first one will be used.\n\nThe mode properties are as follows:\n\n- In embedded mode, all code is loaded during system startup according\n to the boot script. (Code can be loaded later by **explicitly**\n ordering the code server to load it.)\n\n- In interactive mode, code is dynamically loaded when first required,\n which means that when an attempt is made to call a function in a\n module that is not loaded, the code server searches the code path\n and loads the module into the system.\n\nInitially, the code path consists of the current working directory and\nall object code directories under `ROOT/lib`, where `ROOT` is the\ninstallation directory of Erlang/OTP. Directories can be named\n`Name[-Vsn]`, where the `-Vsn` suffix is optional. By default, the\ncode server chooses the directory with the highest version number\namong those which have the same `Name`. If an `ebin` directory exists\nunder the `Name[-Vsn]` directory, this directory is added to the code\npath.\n\nThe code path can be extended by using the command-line flags `-pa Directories`\nand `-pz Directories`. These add `Directories` to the head or the end of the\ncode path, respectively. Example:\n\n```text\n% erl -pa /home/arne/mycode\n```\n\nThe `m:code` module contains a number of functions for modifying and\nquerying the search path.","title":"Code Loading Strategy - System Principles","ref":"system_principles.html#code-loading-strategy"},{"type":"extras","doc":"The following file types are defined in Erlang/OTP:\n\n| _File Type_ | _File Name/Extension_ | _Documented in_ |\n| ------------------------- | --------------------- | --------------------------------------------------- |\n| Module | `.erl` | [Erlang Reference Manual](`e:system:modules.md`) |\n| Include file | `.hrl` | [Erlang Reference Manual](`e:system:modules.md`) |\n| Release resource file | `.rel` | [rel](`e:sasl:rel.md`) in SASL |\n| Application resource file | `.app` | [app](`e:kernel:app.md`) in Kernel |\n| Boot script | `.script` | [script](`e:sasl:script.md`) in SASL |\n| Binary boot script | `.boot` | - |\n| Configuration file | `.config` | [config](`e:kernel:config.md`) in Kernel |\n| Application upgrade file | `.appup` | [appup](`e:sasl:appup.md`) in SASL |\n| Release upgrade file | `relup` | [relup](`e:sasl:relup.md`) in SASL |\n\n_Table: File Types_","title":"File Types - System Principles","ref":"system_principles.html#file-types"},{"type":"extras","doc":"\n# Error Logging\n\n[](){: #error-logging }","title":"Error Logging","ref":"error_logging.html"},{"type":"extras","doc":"Error information from the runtime system, that is, information about a process\nterminating because of an uncaught error exception, is by default written to\nthe terminal (TTY):\n\n```text\n=ERROR REPORT==== 9-Dec-2003::13:25:02 ===\nError in process <0.27.0> with exit value: {{badmatch,[1,2,3]},[{m,f,1},{shell,eval_loop,2}]}\n```\n\nThe error information is handled by Logger, which is part of the Kernel\napplication.\n\nThe exit reasons (such as `badarg`) used by the runtime system are described in\n[Errors and Error Handling](`e:system:errors.md#exit_reasons`).\n\nFor information about Logger and its user interface, see the `m:logger` manual\npage and the [Logging](`e:kernel:logger_chapter.md`) section in the Kernel\nUser's Guide. The system can be configured so that log events are written to\nfile or to the TTY, or both. In addition, user-defined applications can send and\nformat log events using Logger.","title":"Error Information From the Runtime System - Error Logging","ref":"error_logging.html#error-information-from-the-runtime-system"},{"type":"extras","doc":"The standard behaviours (`supervisor`, `gen_server`, and so on) send progress\nand error information to Logger. Progress reports are by default not logged, but\ncan be enabled by setting the primary log level to `info`, for example by using\nthe Kernel configuration parameter `logger_level`. Supervisor reports, crash\nreports and other error and information reports are by default logged through\nthe log handler which is set up when the Kernel application is started.\n\nPrior to Erlang/OTP 21.0, supervisor, crash, and progress reports were only\nlogged when the SASL application was running. This behaviour can, for backwards\ncompatibility, be enabled by setting the Kernel configuration parameter\n[`logger_sasl_compatible`](`e:kernel:kernel_app.md#logger_sasl_compatible`) to\n`true`. For more information, see\n[SASL Error Logging](`e:sasl:error_logging.md`) in the SASL User's Guide.\n\n```erlang\n% erl -kernel logger_level info\nErlang/OTP 21 [erts-10.0] [source-13c50db] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]\n\n=PROGRESS REPORT==== 8-Jun-2018::16:54:19.916404 ===\n application: kernel\n started_at: nonode@nohost\n=PROGRESS REPORT==== 8-Jun-2018::16:54:19.922908 ===\n application: stdlib\n started_at: nonode@nohost\n=PROGRESS REPORT==== 8-Jun-2018::16:54:19.925755 ===\n supervisor: {local,kernel_safe_sup}\n started: [{pid,<0.74.0>},\n {id,disk_log_sup},\n {mfargs,{disk_log_sup,start_link,[]}},\n {restart_type,permanent},\n {shutdown,1000},\n {child_type,supervisor}]\n=PROGRESS REPORT==== 8-Jun-2018::16:54:19.926056 ===\n supervisor: {local,kernel_safe_sup}\n started: [{pid,<0.75.0>},\n {id,disk_log_server},\n {mfargs,{disk_log_server,start_link,[]}},\n {restart_type,permanent},\n {shutdown,2000},\n {child_type,worker}]\nEshell V10.0 (abort with ^G)\n1>\n```","title":"Log events from OTP behaviours - Error Logging","ref":"error_logging.html#log-events-from-otp-behaviours"},{"type":"extras","doc":"\n# Creating and Upgrading a Target System\n\n[](){: #creating-upgrading-target-system }\n\nWhen creating a system using Erlang/OTP, the simplest way is to install\nErlang/OTP somewhere, install the application-specific code somewhere else, and\nthen start the Erlang runtime system, making sure the code path includes the\napplication-specific code.\n\nIt is often not desirable to use an Erlang/OTP system as is. A developer can\ncreate new Erlang/OTP-compliant applications for a particular purpose, and\nseveral original Erlang/OTP applications can be irrelevant for the purpose in\nquestion. Thus, there is a need to be able to create a new system based on a\ngiven Erlang/OTP system, where dispensable applications are removed and new\napplications are included. Documentation and source code is irrelevant and is\ntherefore not included in the new system.\n\nThis chapter is about creating such a system, which is called a _target system_.\n\nThe following sections deal with target systems with different requirements of\nfunctionality:\n\n- A _basic target system_ that can be started by calling the ordinary `erl`\n script.\n- A _simple target system_ that also supports code replacement in runtime.\n- An _embedded target system_ that also supports starting automatically\n at boot time, and logging output from the system files for later inspection.\n\nHere is only considered the case when Erlang/OTP is running on a UNIX system.\n\nThe `sasl` application includes the example Erlang module `target_system.erl`,\nwhich contains functions for creating and installing a target system. This\nmodule is used in the following examples. The source code of the module is\nlisted in\n[Listing of target_system.erl](create_target.md#listing-of-target-system)\n\n[](){: #create }","title":"Creating and Upgrading a Target System","ref":"create_target.html"},{"type":"extras","doc":"It is assumed that you have a working Erlang/OTP system structured according to\nthe OTP design principles.\n\n_Step 1._ Create a `.rel` file (see the [rel(4)](`e:sasl:rel.md`) manual page in\nSASL), which specifies the ERTS version and lists all applications that are to\nbe included in the new basic target system. An example is the following\n`mysystem.rel` file:\n\n```erlang\n%% mysystem.rel\n{release,\n {\"MYSYSTEM\", \"FIRST\"},\n {erts, \"5.10.4\"},\n [{kernel, \"2.16.4\"},\n {stdlib, \"1.19.4\"},\n {sasl, \"2.3.4\"},\n {pea, \"1.0\"}]}.\n```\n\nThe listed applications are not only original Erlang/OTP applications but\npossibly also new applications that you have written (here exemplified by the\napplication Pea (`pea`)).\n\n_Step 2._ Start Erlang/OTP from the directory where the `mysystem.rel` file\nresides:\n\n```text\n% erl -pa /home/user/target_system/myapps/pea-1.0/ebin\n```\n\nThe `-pa` argument prepends the path to the `ebin` directory for\nthe Pea application to the code path.\n\n_Step 3._ Create the target system:\n\n```text\n1> target_system:create(\"mysystem\").\n```\n\nThe function `target_system:create/1` performs the following:\n\n1. Reads the file `mysystem.rel` and creates a new file `plain.rel`.\n The new file is identical to the original, except that it only\n lists the Kernel and STDLIB applications.\n\n1. From the files `mysystem.rel` and `plain.rel` creates the files\n `mysystem.script`, `mysystem.boot`, `plain.script`, and `plain.boot`\n by calling `systools:make_script/2`.\n\n1. Creates the file `mysystem.tar.gz` by calling `systools:make_tar/2`. That\n file has the following contents:\n\n```text\nerts-5.10.4/bin/\nreleases/FIRST/start.boot\nreleases/FIRST/mysystem.rel\nreleases/mysystem.rel\nlib/kernel-2.16.4/\nlib/stdlib-1.19.4/\nlib/sasl-2.3.4/\nlib/pea-1.0/\n```\n\nThe file `releases/FIRST/start.boot` is a copy of our `mysystem.boot`\n\nThe release resource file `mysystem.rel` is duplicated in the tar file.\nOriginally, this file was only stored in the `releases` directory to make it\npossible for the `release_handler` to extract this file separately. After\nunpacking the tar file, `release_handler` would automatically copy the file to\n`releases/FIRST`. However, sometimes the tar file is unpacked without involving\nthe `release_handler` (for example, when unpacking the first target system).\nHence, the file is now duplicated within the tar archive, eliminating the\nneed for manual copying.\n\n1. Creates the temporary directory `tmp` and extracts the tar file\n `mysystem.tar.gz` into that directory.\n1. Deletes the files `erl` and `start` from `tmp/erts-5.10.4/bin`. These files\n are created again from source when installing the release.\n1. Creates the directory `tmp/bin`.\n1. Copies the previously created file `plain.boot` to `tmp/bin/start.boot`.\n1. Copies the files `epmd`, `run_erl`, and `to_erl` from the directory\n `tmp/erts-5.10.4/bin` to the directory `tmp/bin`.\n1. Creates the directory `tmp/log`, which is used if the system is started as\n embedded with the `bin/start` script.\n1. Creates the file `tmp/releases/start_erl.data` with the contents \"5.10.4\n FIRST\". This file is to be passed as data file to the `start_erl` script.\n1. Recreates the file `mysystem.tar.gz` from the directories in the directory\n `tmp` and removes `tmp`.","title":"Creating a Target System - Creating and Upgrading a Target System","ref":"create_target.html#creating-a-target-system"},{"type":"extras","doc":"_Step 4._ Install the created target system in a suitable directory.\n\n```text\n2> target_system:install(\"mysystem\", \"/usr/local/erl-target\").\n```\n\nThe function `target_system:install/2` performs the following:\n\n1. Extracts the tar file `mysystem.tar.gz` into the target directory\n `/usr/local/erl-target`.\n1. In the target directory reads the file `releases/start_erl.data` to find the\n Erlang runtime system version (\"5.10.4\").\n1. Substitutes `%FINAL_ROOTDIR%` and `%EMU%` for `/usr/local/erl-target` and\n `beam`, respectively, in the files `erl.src`, `start.src`, and\n `start_erl.src` of the target `erts-5.10.4/bin` directory, and puts the\n resulting files `erl`, `start`, and `run_erl` in the target `bin` directory.\n1. Finally the target `releases/RELEASES` file is created from data in the file\n `releases/mysystem.rel`.\n\n[](){: #start }","title":"Installing a Target System - Creating and Upgrading a Target System","ref":"create_target.html#installing-a-target-system"},{"type":"extras","doc":"Now we have a target system that can be started in various ways. We start it as\na _basic target system_ by invoking:\n\n```text\n% /usr/local/erl-target/bin/erl\n```\n\nHere only the Kernel and STDLIB applications are started, that is, the system is\nstarted as an ordinary development system. Only two files are needed for all\nthis to work:\n\n1. `bin/erl` (obtained from `erts-5.10.4/bin/erl.src`)\n1. `bin/start.boot` (a copy of `plain.boot`)\n\nWe can also start a distributed system (requires `bin/epmd`).\n\nTo start all applications specified in the original `mysystem.rel` file, use\nflag `-boot` as follows:\n\n```text\n% /usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FIRST/start\n```\n\nWe start a _simple target system_ as above. The only difference is that also the\nfile `releases/RELEASES` is present for code replacement in runtime to work.\n\nTo start an _embedded target system_, the shell script `bin/start` is used. The\nscript calls `bin/run_erl`, which in turn calls `bin/start_erl` (roughly,\n`start_erl` is an embedded variant of `erl`).\n\nThe shell script `start`, which is generated from `erts-5.10.4/bin/start.src`\nduring installation, is merely an example. Edit it to suite your needs. Typically\nit is executed when the UNIX system boots.\n\n`run_erl` is a wrapper that provides logging of output from the runtime system\nto file. It also provides a simple mechanism for attaching to the Erlang shell\n(`to_erl`).\n\n`start_erl` requires:\n\n1. The root directory (`\"/usr/local/erl-target\"`)\n1. The releases directory (`\"/usr/local/erl-target/releases\"`\n1. The location of the file `start_erl.data`\n\nIt performs the following:\n\n1. Reads the runtime system version (`\"5.10.4\"`) and release version (`\"FIRST\"`)\n from the file `start_erl.data`.\n1. Starts the runtime system of the version found.\n1. Provides the flag `-boot` specifying the boot file of the release version\n found (`\"releases/FIRST/start.boot\"`).\n\n`start_erl` also assumes that there is `sys.config` in the release version\ndirectory (`\"releases/FIRST/sys.config\"`). That is the topic of the next\nsection.\n\nThe `start_erl` shell script is normally not to be altered by the user.","title":"Starting a Target System - Creating and Upgrading a Target System","ref":"create_target.html#starting-a-target-system"},{"type":"extras","doc":"As was mentioned in the previous section, `start_erl` requires a `sys.config` in\nthe release version directory (`\"releases/FIRST/sys.config\"`). If there is no\nsuch file, the system start fails. Such a file must therefore also be added.\n\nIf you have system configuration data that is neither file-location-dependent\nnor site-dependent, it can be convenient to create `sys.config` early, so it\nbecomes part of the target system tar file created by `target_system:create/1`.\nIn fact, if you in the current directory create not only the file\n`mysystem.rel`, but also file `sys.config`, the latter file is tacitly put in\nthe appropriate directory.\n\nHowever, it can also be convenient to replace variables in within a `sys.config`\non the target after unpacking but before running the release. If you have a\n`sys.config.src` it will be included and is not required to be a valid Erlang\nterm file like `sys.config`. Before running the release you must have a valid\n`sys.config` in the same directory, so using `sys.config.src` requires having\nsome tool to populate what is needed and write `sys.config` to disk before\nbooting the release.","title":"System Configuration Parameters - Creating and Upgrading a Target System","ref":"create_target.html#system-configuration-parameters"},{"type":"extras","doc":"The previous `install/2` procedure differs somewhat from that of the ordinary\n`Install` shell script. In fact, `create/1` makes the release package as\ncomplete as possible, and leave to the `install/2` procedure to finish by only\nconsidering location-dependent files.","title":"Differences From the Install Script - Creating and Upgrading a Target System","ref":"create_target.html#differences-from-the-install-script"},{"type":"extras","doc":"In this example the Pea application has been changed, and so are the\napplications ERTS, Kernel, STDLIB and SASL.\n\n_Step 1._ Create the file `.rel`:\n\n```erlang\n%% mysystem2.rel\n{release,\n {\"MYSYSTEM\", \"SECOND\"},\n {erts, \"6.0\"},\n [{kernel, \"3.0\"},\n {stdlib, \"2.0\"},\n {sasl, \"2.4\"},\n {pea, \"2.0\"}]}.\n```\n\n_Step 2._ Create the application upgrade file (see\n[appup](`e:sasl:appup.md`) in SASL) for Pea, for example:\n\n```erlang\n%% pea.appup\n{\"2.0\",\n [{\"1.0\",[{load_module,pea_lib}]}],\n [{\"1.0\",[{load_module,pea_lib}]}]}.\n```\n\n_Step 3._ From the directory where the file `mysystem2.rel` resides, start the\nErlang/OTP system, giving the path to the new version of Pea:\n\n```text\n% erl -pa /home/user/target_system/myapps/pea-2.0/ebin\n```\n\n_Step 4._ Create the release upgrade file (see [relup](`e:sasl:relup.md`)\nin SASL):\n\n```text\n1> systools:make_relup(\"mysystem2\",[\"mysystem\"],[\"mysystem\"],\n [{path,[\"/home/user/target_system/myapps/pea-1.0/ebin\",\n \"/my/old/erlang/lib/*/ebin\"]}]).\n```\n\nHere `\"mysystem\"` is the base release and `\"mysystem2\"` is the release to\nupgrade to.\n\nThe `path` option is used for pointing out the old version of all applications.\n(The new versions are already in the code path - assuming of course that the\nErlang node on which this is executed is running the correct version of\nErlang/OTP.)\n\n_Step 5._ Create the new release:\n\n```text\n2> target_system:create(\"mysystem2\").\n```\n\nGiven that the file `relup` generated in Step 4 is now located in the current\ndirectory, it is automatically included in the release package.","title":"Creating the Next Version - Creating and Upgrading a Target System","ref":"create_target.html#creating-the-next-version"},{"type":"extras","doc":"This part is done on the target node, and for this example we want the node to\nbe running as an embedded system with the `-heart` option, allowing automatic\nrestart of the node. For more information, see\n[Starting a Target System](create_target.md#start).\n\nWe add `-heart` to `bin/start`:\n\n```text\n#!/bin/sh\nROOTDIR=/usr/local/erl-target/\n\nif [ -z \"$RELDIR\" ]\nthen\n RELDIR=$ROOTDIR/releases\nfi\n\nSTART_ERL_DATA=${1:-$RELDIR/start_erl.data}\n\n$ROOTDIR/bin/run_erl -daemon /tmp/ $ROOTDIR/log \"exec $ROOTDIR/bin/start_erl $ROOTDIR\\\n$RELDIR $START_ERL_DATA -heart\"\n```\n\nWe use the simplest possible `sys.config`, which we store in `releases/FIRST`:\n\n```text\n%% sys.config\n[].\n```\n\nFinally, to prepare the upgrade, we must put the new release package in the\n`releases` directory of the first target system:\n\n```text\n% cp mysystem2.tar.gz /usr/local/erl-target/releases\n```\n\nAssuming that the node has been started as follows:\n\n```text\n% /usr/local/erl-target/bin/start\n```\n\nIt can be accessed as follows:\n\n```text\n% /usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.1\n```\n\nLogs can be found in `/usr/local/erl-target/log`. This directory is specified as\nan argument to `run_erl`in the start script listed above.\n\n_Step 1._ Unpack the release:\n\n```text\n1> {ok,Vsn} = release_handler:unpack_release(\"mysystem2\").\n```\n\n_Step 2._ Install the release:\n\n```text\n2> release_handler:install_release(Vsn).\n{continue_after_restart,\"FIRST\",[]}\nheart: Tue Apr 1 12:15:10 2014: Erlang has closed.\nheart: Tue Apr 1 12:15:11 2014: Executed \"/usr/local/erl-target/bin/start /usr/local/erl-target/releases/new_start_erl.data\" -> 0. Terminating.\n[End]\n```\n\nThe above return value and output after the call to\n`release_handler:install_release/1` means that the `release_handler` has\nrestarted the node by using `heart`. This is always done when the upgrade\ninvolves a change of the applications ERTS, Kernel, STDLIB, or SASL. For more\ninformation, see [Upgrade when Erlang/OTP has Changed](upgrade.md).\n\nThe node is accessible through a new pipe:\n\n```text\n% /usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.2\n```\n\nList the available releases in the system:\n\n```erlang\n1> release_handler:which_releases().\n[{\"MYSYSTEM\",\"SECOND\",\n [\"kernel-3.0\",\"stdlib-2.0\",\"sasl-2.4\",\"pea-2.0\"],\n current},\n {\"MYSYSTEM\",\"FIRST\",\n [\"kernel-2.16.4\",\"stdlib-1.19.4\",\"sasl-2.3.4\",\"pea-1.0\"],\n permanent}]\n```\n\nOur new release, \"SECOND\", is now the current release, but we can also see that\nour \"FIRST\" release is still permanent. This means that if the node would be\nrestarted now, it would come up running the \"FIRST\" release again.\n\n_Step 3._ Make the new release permanent:\n\n```text\n2> release_handler:make_permanent(\"SECOND\").\n```\n\nCheck the releases again:\n\n```c\n3> release_handler:which_releases().\n[{\"MYSYSTEM\",\"SECOND\",\n [\"kernel-3.0\",\"stdlib-2.0\",\"sasl-2.4\",\"pea-2.0\"],\n permanent},\n {\"MYSYSTEM\",\"FIRST\",\n [\"kernel-2.16.4\",\"stdlib-1.19.4\",\"sasl-2.3.4\",\"pea-1.0\"],\n old}]\n```\n\nWe see that the new release version is `permanent`, so it would be safe to\nrestart the node.\n\n[](){: #listing-of-target-system }","title":"Upgrading the Target System - Creating and Upgrading a Target System","ref":"create_target.html#upgrading-the-target-system"},{"type":"extras","doc":"This module can also be found in the `examples` directory of the SASL\napplication.\n\n```erlang\n\n-module(target_system).\n-export([create/1, create/2, install/2]).\n\n%% Note: RelFileName below is the *stem* without trailing .rel,\n%% .script etc.\n%%\n\n%% create(RelFileName)\n%%\ncreate(RelFileName) ->\n create(RelFileName,[]).\n\ncreate(RelFileName,SystoolsOpts) ->\n RelFile = RelFileName ++ \".rel\",\n Dir = filename:dirname(RelFileName),\n PlainRelFileName = filename:join(Dir,\"plain\"),\n PlainRelFile = PlainRelFileName ++ \".rel\",\n io:fwrite(\"Reading file: ~ts ...~n\", [RelFile]),\n {ok, [RelSpec]} = file:consult(RelFile),\n io:fwrite(\"Creating file: ~ts from ~ts ...~n\",\n [PlainRelFile, RelFile]),\n {release,\n {RelName, RelVsn},\n {erts, ErtsVsn},\n AppVsns} = RelSpec,\n PlainRelSpec = {release,\n {RelName, RelVsn},\n {erts, ErtsVsn},\n lists:filter(fun({kernel, _}) ->\n true;\n ({stdlib, _}) ->\n true;\n (_) ->\n false\n end, AppVsns)\n },\n {ok, Fd} = file:open(PlainRelFile, [write]),\n io:fwrite(Fd, \"~p.~n\", [PlainRelSpec]),\n file:close(Fd),\n\n io:fwrite(\"Making \\\"~ts.script\\\" and \\\"~ts.boot\\\" files ...~n\",\n\t [PlainRelFileName,PlainRelFileName]),\n make_script(PlainRelFileName,SystoolsOpts),\n\n io:fwrite(\"Making \\\"~ts.script\\\" and \\\"~ts.boot\\\" files ...~n\",\n [RelFileName, RelFileName]),\n make_script(RelFileName,SystoolsOpts),\n\n TarFileName = RelFileName ++ \".tar.gz\",\n io:fwrite(\"Creating tar file ~ts ...~n\", [TarFileName]),\n make_tar(RelFileName,SystoolsOpts),\n\n TmpDir = filename:join(Dir,\"tmp\"),\n io:fwrite(\"Creating directory ~tp ...~n\",[TmpDir]),\n file:make_dir(TmpDir),\n\n io:fwrite(\"Extracting ~ts into directory ~ts ...~n\", [TarFileName,TmpDir]),\n extract_tar(TarFileName, TmpDir),\n\n TmpBinDir = filename:join([TmpDir, \"bin\"]),\n ErtsBinDir = filename:join([TmpDir, \"erts-\" ++ ErtsVsn, \"bin\"]),\n io:fwrite(\"Deleting \\\"erl\\\" and \\\"start\\\" in directory ~ts ...~n\",\n [ErtsBinDir]),\n file:delete(filename:join([ErtsBinDir, \"erl\"])),\n file:delete(filename:join([ErtsBinDir, \"start\"])),\n\n io:fwrite(\"Creating temporary directory ~ts ...~n\", [TmpBinDir]),\n file:make_dir(TmpBinDir),\n\n io:fwrite(\"Copying file \\\"~ts.boot\\\" to ~ts ...~n\",\n [PlainRelFileName, filename:join([TmpBinDir, \"start.boot\"])]),\n copy_file(PlainRelFileName++\".boot\",filename:join([TmpBinDir, \"start.boot\"])),\n\n io:fwrite(\"Copying files \\\"epmd\\\", \\\"run_erl\\\" and \\\"to_erl\\\" from \\n\"\n \"~ts to ~ts ...~n\",\n [ErtsBinDir, TmpBinDir]),\n copy_file(filename:join([ErtsBinDir, \"epmd\"]),\n filename:join([TmpBinDir, \"epmd\"]), [preserve]),\n copy_file(filename:join([ErtsBinDir, \"run_erl\"]),\n filename:join([TmpBinDir, \"run_erl\"]), [preserve]),\n copy_file(filename:join([ErtsBinDir, \"to_erl\"]),\n filename:join([TmpBinDir, \"to_erl\"]), [preserve]),\n\n %% This is needed if 'start' script created from 'start.src' shall\n %% be used as it points out this directory as log dir for 'run_erl'\n TmpLogDir = filename:join([TmpDir, \"log\"]),\n io:fwrite(\"Creating temporary directory ~ts ...~n\", [TmpLogDir]),\n ok = file:make_dir(TmpLogDir),\n\n StartErlDataFile = filename:join([TmpDir, \"releases\", \"start_erl.data\"]),\n io:fwrite(\"Creating ~ts ...~n\", [StartErlDataFile]),\n StartErlData = io_lib:fwrite(\"~s ~s~n\", [ErtsVsn, RelVsn]),\n write_file(StartErlDataFile, StartErlData),\n\n io:fwrite(\"Recreating tar file ~ts from contents in directory ~ts ...~n\",\n\t [TarFileName,TmpDir]),\n {ok, Tar} = erl_tar:open(TarFileName, [write, compressed]),\n %% {ok, Cwd} = file:get_cwd(),\n %% file:set_cwd(\"tmp\"),\n ErtsDir = \"erts-\"++ErtsVsn,\n erl_tar:add(Tar, filename:join(TmpDir,\"bin\"), \"bin\", []),\n erl_tar:add(Tar, filename:join(TmpDir,ErtsDir), ErtsDir, []),\n erl_tar:add(Tar, filename:join(TmpDir,\"releases\"), \"releases\", []),\n erl_tar:add(Tar, filename:join(TmpDir,\"lib\"), \"lib\", []),\n erl_tar:add(Tar, filename:join(TmpDir,\"log\"), \"log\", []),\n erl_tar:close(Tar),\n %% file:set_cwd(Cwd),\n io:fwrite(\"Removing directory ~ts ...~n\",[TmpDir]),\n remove_dir_tree(TmpDir),\n ok.\n\n\ninstall(RelFileName, RootDir) ->\n TarFile = RelFileName ++ \".tar.gz\",\n io:fwrite(\"Extracting ~ts ...~n\", [TarFile]),\n extract_tar(TarFile, RootDir),\n StartErlDataFile = filename:join([RootDir, \"releases\", \"start_erl.data\"]),\n {ok, StartErlData} = read_txt_file(StartErlDataFile),\n [ErlVsn, _RelVsn| _] = string:tokens(StartErlData, \" \\n\"),\n ErtsBinDir = filename:join([RootDir, \"erts-\" ++ ErlVsn, \"bin\"]),\n BinDir = filename:join([RootDir, \"bin\"]),\n io:fwrite(\"Substituting in erl.src, start.src and start_erl.src to \"\n \"form erl, start and start_erl ...\\n\"),\n subst_src_scripts([\"erl\", \"start\", \"start_erl\"], ErtsBinDir, BinDir,\n [{\"FINAL_ROOTDIR\", RootDir}, {\"EMU\", \"beam\"}],\n [preserve]),\n %%! Workaround for pre OTP 17.0: start.src and start_erl.src did\n %%! not have correct permissions, so the above 'preserve' option did not help\n ok = file:change_mode(filename:join(BinDir,\"start\"),8#0755),\n ok = file:change_mode(filename:join(BinDir,\"start_erl\"),8#0755),\n\n io:fwrite(\"Creating the RELEASES file ...\\n\"),\n create_RELEASES(RootDir, filename:join([RootDir, \"releases\",\n\t\t\t\t\t filename:basename(RelFileName)])).\n\n%% LOCALS\n\n%% make_script(RelFileName,Opts)\n%%\nmake_script(RelFileName,Opts) ->\n systools:make_script(RelFileName, [no_module_tests,\n\t\t\t\t {outdir,filename:dirname(RelFileName)}\n\t\t\t\t |Opts]).\n\n%% make_tar(RelFileName,Opts)\n%%\nmake_tar(RelFileName,Opts) ->\n RootDir = code:root_dir(),\n systools:make_tar(RelFileName, [{erts, RootDir},\n\t\t\t\t {outdir,filename:dirname(RelFileName)}\n\t\t\t\t |Opts]).\n\n%% extract_tar(TarFile, DestDir)\n%%\nextract_tar(TarFile, DestDir) ->\n erl_tar:extract(TarFile, [{cwd, DestDir}, compressed]).\n\ncreate_RELEASES(DestDir, RelFileName) ->\n release_handler:create_RELEASES(DestDir, RelFileName ++ \".rel\").\n\nsubst_src_scripts(Scripts, SrcDir, DestDir, Vars, Opts) ->\n lists:foreach(fun(Script) ->\n subst_src_script(Script, SrcDir, DestDir,\n Vars, Opts)\n end, Scripts).\n\nsubst_src_script(Script, SrcDir, DestDir, Vars, Opts) ->\n subst_file(filename:join([SrcDir, Script ++ \".src\"]),\n filename:join([DestDir, Script]),\n Vars, Opts).\n\nsubst_file(Src, Dest, Vars, Opts) ->\n {ok, Conts} = read_txt_file(Src),\n NConts = subst(Conts, Vars),\n write_file(Dest, NConts),\n case lists:member(preserve, Opts) of\n true ->\n {ok, FileInfo} = file:read_file_info(Src),\n file:write_file_info(Dest, FileInfo);\n false ->\n ok\n end.\n\n%% subst(Str, Vars)\n%% Vars = [{Var, Val}]\n%% Var = Val = string()\n%% Substitute all occurrences of %Var% for Val in Str, using the list\n%% of variables in Vars.\n%%\nsubst(Str, Vars) ->\n subst(Str, Vars, []).\n\nsubst([$%, C| Rest], Vars, Result) when $A = \n subst_var([C| Rest], Vars, Result, []);\nsubst([$%, C| Rest], Vars, Result) when $a = \n subst_var([C| Rest], Vars, Result, []);\nsubst([$%, C| Rest], Vars, Result) when C == $_ ->\n subst_var([C| Rest], Vars, Result, []);\nsubst([C| Rest], Vars, Result) ->\n subst(Rest, Vars, [C| Result]);\nsubst([], _Vars, Result) ->\n lists:reverse(Result).\n\nsubst_var([$%| Rest], Vars, Result, VarAcc) ->\n Key = lists:reverse(VarAcc),\n case lists:keysearch(Key, 1, Vars) of\n {value, {Key, Value}} ->\n subst(Rest, Vars, lists:reverse(Value, Result));\n false ->\n subst(Rest, Vars, [$%| VarAcc ++ [$%| Result]])\n end;\nsubst_var([C| Rest], Vars, Result, VarAcc) ->\n subst_var(Rest, Vars, Result, [C| VarAcc]);\nsubst_var([], Vars, Result, VarAcc) ->\n subst([], Vars, [VarAcc ++ [$%| Result]]).\n\ncopy_file(Src, Dest) ->\n copy_file(Src, Dest, []).\n\ncopy_file(Src, Dest, Opts) ->\n {ok,_} = file:copy(Src, Dest),\n case lists:member(preserve, Opts) of\n true ->\n {ok, FileInfo} = file:read_file_info(Src),\n file:write_file_info(Dest, FileInfo);\n false ->\n ok\n end.\n\nwrite_file(FName, Conts) ->\n Enc = file:native_name_encoding(),\n {ok, Fd} = file:open(FName, [write]),\n file:write(Fd, unicode:characters_to_binary(Conts,Enc,Enc)),\n file:close(Fd).\n\nread_txt_file(File) ->\n {ok, Bin} = file:read_file(File),\n {ok, binary_to_list(Bin)}.\n\nremove_dir_tree(Dir) ->\n remove_all_files(\".\", [Dir]).\n\nremove_all_files(Dir, Files) ->\n lists:foreach(fun(File) ->\n FilePath = filename:join([Dir, File]),\n case filelib:is_dir(FilePath) of\n true ->\n {ok, DirFiles} = file:list_dir(FilePath),\n remove_all_files(FilePath, DirFiles),\n file:del_dir(FilePath);\n _ ->\n file:delete(FilePath)\n end\n end, Files).\n```","title":"Listing of target_system.erl - Creating and Upgrading a Target System","ref":"create_target.html#listing-of-target_system-erl"},{"type":"extras","doc":"\n# Upgrade when Erlang/OTP has Changed\n\n[](){: #upgrade-section }","title":"Upgrade when Erlang/OTP has Changed","ref":"upgrade.html"},{"type":"extras","doc":"[](){: #upgrade }\n\nAs of Erlang/OTP 17, most applications deliver a valid application upgrade file\n(`appup`). Many of the applications use the `restart_application`\ninstruction. These are applications for which it is not crucial to support real\nsoft upgrade, for example, tools and library applications. The\n`restart_application` instruction ensures that all modules in the application\nare reloaded and thereby running the new code.","title":"Introduction - Upgrade when Erlang/OTP has Changed","ref":"upgrade.html#introduction"},{"type":"extras","doc":"The core applications ERTS, Kernel, STDLIB, and SASL never allow real\nsoft upgrade, but require the Erlang runtime system to be\nrestarted. This is indicated to the `release_handler` by the upgrade\ninstruction `restart_new_emulator`. This instruction is always the\nvery first instruction executed, and it restarts the runtime system\nwith the new versions of the previously mentioned core applications\nand the old versions of all other applications. When the node is back\nup, all other upgrade instructions are executed, making sure each\napplication is finally running its new version.\n\nIt might seem strange to do a two-step upgrade instead of just\nrestarting the runtime system with the new version of all\napplications. The reason for this design decision is to allow\n`code_change` functions to have side effects, for example, changing\ndata on disk. It also guarantees that the upgrade mechanism for\nnon-core applications does not differ depending on whether or not core\napplications are changed at the same time.\n\nIf, however, the more brutal variant is preferred, the release\nupgrade file can be handwritten using only the single upgrade\ninstruction `restart_emulator`. This instruction, in contrast to\n`restart_new_emulator`, causes the runtime system to restart with the\nnew versions of _all_ applications.\n\n_Note:_ If other instructions are included before `restart_emulator`\nin the handwritten `relup` file, they are executed in the old runtime\nsystem. This is a big risk since there is no guarantee that new BEAM\ncode can be loaded into the old runtime system. Adding instructions\nafter `restart_emulator` has no effect as the `release_handler` will\nnot execute them.\n\nFor information about the release upgrade file, see\n[relup](`e:sasl:relup.md`) in SASL. For more information about\nupgrade instructions, see [appup](`e:sasl:appup.md`) in SASL.","title":"Upgrade of Core Applications - Upgrade when Erlang/OTP has Changed","ref":"upgrade.html#upgrade-of-core-applications"},{"type":"extras","doc":"A few applications, such as Erl_interface, do not support upgrade. This is\nindicated by an application upgrade file containing only `{Vsn,[],[]}`. Any\nattempt at creating a release upgrade file with such input fails. The only way\nto force an upgrade involving applications like this is to handwrite the file\n`relup`, preferably as described above with only the `restart_emulator`\ninstruction.","title":"Applications that Still do Not Allow Code Upgrade - Upgrade when Erlang/OTP has Changed","ref":"upgrade.html#applications-that-still-do-not-allow-code-upgrade"},{"type":"extras","doc":"\n# Versions\n\n[](){: #versions-section }","title":"Versions","ref":"versions.html"},{"type":"extras","doc":"As of OTP release 17, the OTP release number corresponds to the major part of\nthe OTP version. The OTP version as a concept was introduced in OTP 17. The\nversion scheme used is described in detail in\n[Version Scheme](versions.md#version_scheme).\n\nOTP of a specific version is a set of applications of specific versions. The\napplication versions identified by an OTP version corresponds to application\nversions that have been tested together by the Erlang/OTP team at Ericsson AB.\nAn OTP system can, however, be put together with applications from different OTP\nversions. Such a combination of application versions has not been tested by the\nErlang/OTP team. It is therefore _always preferred to use OTP applications from\none single OTP version_.\n\nRelease candidates have an `-rc ` suffix. The suffix `-rc0` is used during\ndevelopment up to the first release candidate.","title":"OTP Version - Versions","ref":"versions.html#otp-version"},{"type":"extras","doc":"In an OTP source code tree, the OTP version can be read from the text file\n` /OTP_VERSION`. The absolute path to the file can be\nconstructed by calling\n`filename:join([`[`code:root_dir()`](`code:root_dir/0`)`, \"OTP_VERSION\"])`.\n\nIn an installed OTP development system, the OTP version can be read from the\ntext file ` /releases/ /OTP_VERSION`.\nThe absolute path to the file can by constructed by calling\n`filename:join([`[`code:root_dir()`](`code:root_dir/0`)`, \"releases\", `[`erlang:system_info(otp_release)`](`m:erlang#system_info_otp_release`)`, \"OTP_VERSION\"]).`\n\nIf the version read from the `OTP_VERSION` file in a development system has a\n`**` suffix, the system has been patched using the\n[`otp_patch_apply`](`e:system:otp-patch-apply.md`) tool. In this case, the\nsystem consists of application versions from multiple OTP versions. The version\npreceding the `**` suffix corresponds to the OTP version of the base system that\nhas been patched. Note that if a development system is updated by other means\nthan `otp_patch_apply`, the file `OTP_VERSION` can identify an incorrect OTP\nversion.\n\nNo `OTP_VERSION` file is placed in a [target system](create_target.md) created\nby OTP tools, because one can easily create a target system where it is hard\nto even determine the base OTP version. However, it is allowed to place such\na file there if one knows the OTP version.","title":"Retrieving Current OTP Version - Versions","ref":"versions.html#retrieving-current-otp-version"},{"type":"extras","doc":"The text file ` /otp_versions.table`, which is part of the\nsource code, contains information about all OTP versions from OTP 17.0 up to the\ncurrent OTP version. Each line contains information about application versions\nthat are part of a specific OTP version, and has the following format:\n\n```text\n : # :\n```\n\n` ` has the format `OTP- `, that is, the same as the git tag used\nto identify the source.\n\n` ` and ` ` are space-separated lists of\napplication versions and has the format ` - `.\n\n- ` ` corresponds to changed applications with new version\n numbers in this OTP version.\n- ` ` corresponds to unchanged application versions in this\n OTP version.\n\nBoth of them can be empty, but not at the same time. If ` `\nis empty, no changes have been made that change the build result of any\napplication. This could, for example, be a pure bug fix of the build system. The\norder of lines is undefined. All white-space characters in this file are either\nspace (character 32) or line-break (character 10).\n\nBy using ordinary UNIX tools like `sed` and `grep` one can easily find answers\nto various questions like:\n\n- Which OTP versions are `kernel-3.0` part of?\n\n `$ grep ' kernel-3\\.0 ' otp_versions.table`\n\n- In which OTP version was `kernel-3.0` introduced?\n\n `$ sed 's/#.*//;/ kernel-3\\.0 /!d' otp_versions.table`\n\nThe above commands give a bit more information than the exact answers, but\nadequate information when manually searching for answers to these questions.","title":"OTP Versions Table - Versions","ref":"versions.html#otp-versions-table"},{"type":"extras","doc":"As of OTP 17.0 application versions use the same [version\nscheme](versions.md#version_scheme) as the OTP version, except that\napplication versions never include the `-rc ` suffix. Also\nnote that a major increment in an application version does not\nnecessarily imply a major increment of the OTP version. This depends\non whether the major change in the application is considered a\nmajor change for OTP as a whole or not.\n\n[](){: #version_scheme }","title":"Application Version - Versions","ref":"versions.html#application-version"},{"type":"extras","doc":"> #### Change {: .info }\n>\n> The version scheme was changed as of OTP 17.0.\n> [A list of application versions used in OTP 17.0](versions.md#otp_17_0_app_versions)\n> is included at the end of this section.\n\nNormally, a version is constructed as ` . . `, where\n` ` is the most significant part. However, versions with more than three\ndot-separated parts are possible.\n\nThe dot-separated parts consist of non-negative integers. If all parts\nless significant than ` ` equals `0`, they are omitted. The\nthree normal parts ` . . ` are changed as follows:\n\n- ` ` - Increases when major changes, including incompatibilities, are\n made.\n- ` ` - Increases when new functionality is added.\n- ` ` - Increases when pure bug fixes are made.\n\nWhen a part in the version number increases, all less significant parts are set\nto `0`.\n\nAn application version or an OTP version identifies source code versions. That\nis, it implies nothing about how the application or OTP has been built.","title":"Version Scheme - Versions","ref":"versions.html#version-scheme"},{"type":"extras","doc":"Version numbers in general are only partially ordered. However, normal version\nnumbers (with three parts) as of OTP 17.0 have a total or linear order. This\napplies both to normal OTP versions and normal application versions.\n\nWhen comparing two version numbers with a defined order, one compares\neach part as standard integers, starting from the most significant\npart and moving towards the less significant parts. The order is\ndetermined by the first parts of the same significance that differ. A\nlarger OTP version encompasses all changes present in a smaller OTP\nversion. The same principle applies to application versions.\n\nVersions can have more than three parts, resulting in partial\nordering. Such versions are only used when branching off from another\nbranch. When an extra part (apart from the normal three parts) is added to\na version number, a new branch of versions is made. The new branch has\na linear order against the base version. However, versions on\ndifferent branches have no order, and therefore one can only conclude\nthat they all include what is included in their closest common\nancestor. When branching multiple times from the same base version,\n`0` parts are added between the base version and the least significant\n`1` part until a unique version is found. Versions that have an order\ncan be compared as described in the previous paragraph.\n\nAn example of branched versions: The version `6.0.2.1` is a branched version\nfrom the base version `6.0.2`. Versions on the form `6.0.2. ` can be compared\nwith normal versions smaller than or equal to `6.0.2`, and other versions on the\nform `6.0.2. `. The version `6.0.2.1` will include all changes in `6.0.2`.\nHowever, `6.0.3` will most likely _not_ include all changes in `6.0.2.1` (note\nthat these versions have no order). A second branched version from the base\nversion `6.0.2` will be version `6.0.2.0.1`, and a third branched version will\nbe `6.0.2.0.0.1`.\n\n[](){: #releases_and_patches }","title":"Order of Versions - Versions","ref":"versions.html#order-of-versions"},{"type":"extras","doc":"When a new OTP release is released it will have an OTP version on the form\n` .0` where the major OTP version number equals the release number. The\nmajor version number is increased one step since the last major version. All\nother OTP versions with the same major OTP version number are patches on that\nOTP release.\n\nPatches are either released as maintenance patch packages or emergency patch\npackages. The only difference is that maintenance patch packages are planned and\nusually contain more changes than emergency patch packages. Emergency patch\npackages are released to solve one or more specific issues when such are\ndiscovered.\n\nThe release of a maintenance patch package usually imply an increase\nof the OTP ` ` version, while the release of an emergency patch\npackage usually imply an increase of the OTP ` `\nversion. However, this is not always the case, as changes in OTP\nversions are determined by actual code modifications rather than\nwhether the patch was planned or not. For more information see\n[Version Scheme](versions.md#version_scheme).\n\n[](){: #otp_versions_tree }","title":"Releases and Patches - Versions","ref":"versions.html#releases-and-patches"},{"type":"extras","doc":"All released OTP versions can be found in the [OTP Versions\nTree](http://www.erlang.org/download/otp_versions_tree.html), which is\nautomatically updated whenever we release a new OTP version. Note that\neach version number explicitly determines its position in the version\ntree. All that is required to build the tree are the version numbers\nthemselves.\n\nThe root of the tree is OTP version 17.0 which is when we introduced the new\n[version scheme](versions.md#version_scheme). The green versions are normal\nversions released on the main track. Old\n[OTP releases](versions.md#releases_and_patches) will be maintained for a while\non `maint` branches that have branched off from the main track. Old `maint`\nbranches always branch off from the main track when the next OTP release is\nintroduced into the main track. Versions on these old `maint` branches are\nmarked blue.\n\nApart from the green and blue versions, there are also gray\nversions. These denote versions established on branches to resolve a\nparticular issue for a specific customer based on a specific base\nversion. Branches with gray versions will typically become dead ends\nvery quickly if not immediately.\n\n[](){: #otp_17_0_app_versions }","title":"OTP Versions Tree - Versions","ref":"versions.html#otp-versions-tree"},{"type":"extras","doc":"The following list details the application versions that were part of\nOTP 17.0.\n\nIf the normal part of an application version number is smaller than\nthe corresponding application version in the list, the version number\ndoes not adhere to the versioning scheme introduced in OTP\n17.0. Consequently, it is not regarded as having an order against\nversions used from OTP 17.0 onwards.\n\n- `asn1-3.0`\n- `common_test-1.8`\n- `compiler-5.0`\n- `cosEvent-2.1.15`\n- `cosEventDomain-1.1.14`\n- `cosFileTransfer-1.1.16`\n- `cosNotification-1.1.21`\n- `cosProperty-1.1.17`\n- `cosTime-1.1.14`\n- `cosTransactions-1.2.14`\n- `crypto-3.3`\n- `debugger-4.0`\n- `dialyzer-2.7`\n- `diameter-1.6`\n- `edoc-0.7.13`\n- `eldap-1.0.3`\n- `erl_docgen-0.3.5`\n- `erl_interface-3.7.16`\n- `erts-6.0`\n- `et-1.5`\n- `eunit-2.2.7`\n- `gs-1.5.16`\n- `hipe-3.10.3`\n- `ic-4.3.5`\n- `inets-5.10`\n- `jinterface-1.5.9`\n- `kernel-3.0`\n- `megaco-3.17.1`\n- `mnesia-4.12`\n- `observer-2.0`\n- `odbc-2.10.20`\n- `orber-3.6.27`\n- `os_mon-2.2.15`\n- `ose-1.0`\n- `otp_mibs-1.0.9`\n- `parsetools-2.0.11`\n- `percept-0.8.9`\n- `public_key-0.22`\n- `reltool-0.6.5`\n- `runtime_tools-1.8.14`\n- `sasl-2.4`\n- `snmp-4.25.1`\n- `ssh-3.0.1`\n- `ssl-5.3.4`\n- `stdlib-2.0`\n- `syntax_tools-1.6.14`\n- `test_server-3.7`\n- `tools-2.6.14`\n- `typer-0.9.6`\n- `webtool-0.8.10`\n- `wx-1.2`\n- `xmerl-1.3.7`","title":"OTP 17.0 Application Versions - Versions","ref":"versions.html#otp-17-0-application-versions"},{"type":"extras","doc":"\n# Support, Compatibility, Deprecations, and Removal","title":"Support, Compatibility, Deprecations, and Removal","ref":"misc.html"},{"type":"extras","doc":"This document describes the strategy regarding supported Releases,\ncompatibility, deprecations, and removal of functionality.\n\n> #### Change {: .info }\n>\n> This document and the strategy it describes was introduced in\n> Erlang/OTP 21.\n\n[](){: #supported_releases }","title":"Introduction - Support, Compatibility, Deprecations, and Removal","ref":"misc.html#introduction"},{"type":"extras","doc":"In general, bugs are only fixed on the latest\n[release](versions.md#releases_and_patches), and new features are introduced in\nthe upcoming release that is under development. However, when we, for\ninternal reasons, fix bugs on older releases, these will be available and\nannounced as well.\n\nPull requests are only accepted on the `maint` and the `master`\nbranches in our [git repository](https://github.com/erlang/otp). The\n`maint` branch contains changes planned for the next [maintenance\npatch package](versions.md#releases_and_patches) on the latest OTP\nrelease and the `master` branch contain changes planned for the\nupcoming OTP release.","title":"Supported Releases - Support, Compatibility, Deprecations, and Removal","ref":"misc.html#supported-releases"},{"type":"extras","doc":"We strive to remain as compatible as possible, even in cases where we\ngive no compatibility guarantees.\n\nDifferent parts of the system will be handled differently regarding\ncompatibility. The following items describe how different parts of the system\nare handled.\n\n- **Erlang Distribution** - Erlang nodes can communicate across at least two\n preceding and two subsequent releases.\n\n- **Compiled BEAM Code, NIF Libraries, and Drivers** - Compiled code\n can be loaded on at least two subsequent releases. To achive the\n highest possible performance for Erlang code, ensure it is compiled\n using the same release as the one it will be deployed on.\n\n Loading on previous releases is _not_ supported.\n\n- **APIs** - Compatible between releases.\n\n- **Compiler Warnings** - New warnings may be issued between releases.\n\n- **Command Line Arguments** - Incompatible changes may occur between releases.\n\n- **OTP Build Procedures** - Incompatible changes may occur between releases.\n\nUnder certain circumstances incompatible changes might be introduced even in\nparts of the system that should be compatible between releases. Things that\nmight trigger incompatible changes like this are:\n\n- **Security Issues** - It might be necessary to introduce incompatible changes\n in order to solve a security issue. This kind of incompatibility might occur\n in a patch.\n\n- **Bug Fixes** - We will not be bug-compatible. A bug fix might introduce\n incompatible changes. This kind of incompatibility might occur in a patch.\n\n- **Severe Previous Design Issues** - Some parts of OTP were designed\n a very long time ago and did not necessarily take today's computing\n environments into account. Consequently, the ramifications of these\n design choices can be quite significant, impacting performance,\n scalability, and more. If we determine that these consequences are\n too substantial, we may implement incompatible changes. Such changes\n are never introduced in a patch, but in the subsequent release.\n\nPeripheral, trace, and debug functionality is at greater risk of being changed\nin an incompatible way than functionality in the language itself and core\nlibraries used during operation.\n\nThere is a page in the documentation regarding incompatibilities:\n\n* [Upcoming Potential Incompatibilities](`e:general_info:upcoming_incompatibilities.md`) -\n lists all upcoming potential incompatibilities.","title":"Compatibility - Support, Compatibility, Deprecations, and Removal","ref":"misc.html#compatibility"},{"type":"extras","doc":"Deprecation of functionality occurs when newer, preferred alternatives\nare introduced. The deprecation does **not** imply future removal of the\nfunctionality unless an upcoming removal is explicitly stated in the\ndeprecation notice.\n\nDeprecated functionality will be documented as deprecated and highlighted\nin a release note as early possible. If appropriate, the compiler will\nissue warnings when the deprecated functionality is used.\n\nThere is a page in the documentation regarding deprecations:\n\n* [Deprecations](`e:general_info:deprecations.md`) - lists all\n deprecated functionality.","title":"Deprecation - Support, Compatibility, Deprecations, and Removal","ref":"misc.html#deprecation"},{"type":"extras","doc":"It can become necessary to remove legacy solutions. In such instances,\nthey will be gradually phased out over a sufficient period to allow\nusers to adjust. Before functionality is removed, it will be\ndeprecated for at least one release, with an explicit announcement\nabout the upcoming removal.\n\nPeripheral, trace, and debug functionality is at greater risk of removal than\nfunctionality in the language itself and core libraries used during operation.\n\nThere are two pages in the documentation regarding removal:\n\n* [Scheduled for Removal](`e:general_info:scheduled_for_removal.md`) - lists\n all functionality that is schedule for removal in upcoming releases.\n\n* [Removed Functionality](`e:general_info:removed.md`) - lists\n functionality that has been removed.","title":"Removal - Support, Compatibility, Deprecations, and Removal","ref":"misc.html#removal"},{"type":"extras","doc":"\n# Overview\n\n[](){: #otp-design-principles }\n\nThe _OTP Design Principles_ define how to structure Erlang code in terms of\nprocesses, modules, and directories.","title":"Overview","ref":"design_principles.html"},{"type":"extras","doc":"A basic concept in Erlang/OTP is the _supervision tree_. This is a process\nstructuring model based on the idea of _workers_ and _supervisors_:\n\n- Workers are processes that perform computations and other actual work.\n- Supervisors are processes that monitor workers. A supervisor\n can restart a worker if something goes wrong.\n- The supervision tree is a hierarchical arrangement of code into supervisors\n and workers, which makes it possible to design and program fault-tolerant\n software.\n\nIn the following figure, square boxes represents supervisors and circles\nrepresent workers:\n\n[](){: #sup6 }\n\n```mermaid\n---\ntitle: Supervision Tree\n---\nflowchart\n sup1[Type 1 Supervisor] --- sup2[Type 1 Supervisor] --- worker1((worker))\n sup1 --- sup1a[Type A Supervisor]\n\n sup1a --- sup2a[Type A Supervisor] --- worker2((worker))\n sup1a --- sup3[Type 1 Supervisor]\n\n sup3 --- worker3((worker))\n sup3 --- worker4((worker))\n```","title":"Supervision Trees - Overview","ref":"design_principles.html#supervision-trees"},{"type":"extras","doc":"In a supervision tree, many of the processes have similar structures\nand follow similar patterns. For example, the supervisors share a\nsimilar structure, with the sole distinction lying in the child\nprocesses they supervise. Many of the workers are servers in a\nserver-client relation, finite-state machines, or event handlers.\n\n_Behaviours_ are formalizations of these common patterns. The idea is to divide\nthe code for a process in a generic part (a behaviour module) and a specific\npart (a _callback module_).\n\nThe behaviour module is part of Erlang/OTP. To implement a process such as a\nsupervisor, the user only needs to implement the callback module, which is to\nexport a pre-defined set of functions, the _callback functions_.\n\nThe following example illustrate how code can be divided into a generic and a\nspecific part. Consider the following code (written in plain Erlang) for a\nsimple server, which keeps track of a number of \"channels\". Other processes can\nallocate and free the channels by calling the functions `alloc/0` and `free/1`,\nrespectively.\n\n[](){: #ch1 }\n\n```erlang\n-module(ch1).\n-export([start/0]).\n-export([alloc/0, free/1]).\n-export([init/0]).\n\nstart() ->\n spawn(ch1, init, []).\n\nalloc() ->\n ch1 ! {self(), alloc},\n receive\n {ch1, Res} ->\n Res\n end.\n\nfree(Ch) ->\n ch1 ! {free, Ch},\n ok.\n\ninit() ->\n register(ch1, self()),\n Chs = channels(),\n loop(Chs).\n\nloop(Chs) ->\n receive\n {From, alloc} ->\n {Ch, Chs2} = alloc(Chs),\n From ! {ch1, Ch},\n loop(Chs2);\n {free, Ch} ->\n Chs2 = free(Ch, Chs),\n loop(Chs2)\n end.\n```\n\nThe code for the server can be rewritten into a generic part `server.erl`:\n\n```erlang\n-module(server).\n-export([start/1]).\n-export([call/2, cast/2]).\n-export([init/1]).\n\nstart(Mod) ->\n spawn(server, init, [Mod]).\n\ncall(Name, Req) ->\n Name ! {call, self(), Req},\n receive\n {Name, Res} ->\n Res\n end.\n\ncast(Name, Req) ->\n Name ! {cast, Req},\n ok.\n\ninit(Mod) ->\n register(Mod, self()),\n State = Mod:init(),\n loop(Mod, State).\n\nloop(Mod, State) ->\n receive\n {call, From, Req} ->\n {Res, State2} = Mod:handle_call(Req, State),\n From ! {Mod, Res},\n loop(Mod, State2);\n {cast, Req} ->\n State2 = Mod:handle_cast(Req, State),\n loop(Mod, State2)\n end.\n```\n\nAnd a callback module `ch2.erl`:\n\n```erlang\n-module(ch2).\n-export([start/0]).\n-export([alloc/0, free/1]).\n-export([init/0, handle_call/2, handle_cast/2]).\n\nstart() ->\n server:start(ch2).\n\nalloc() ->\n server:call(ch2, alloc).\n\nfree(Ch) ->\n server:cast(ch2, {free, Ch}).\n\ninit() ->\n channels().\n\nhandle_call(alloc, Chs) ->\n alloc(Chs). % => {Ch,Chs2}\n\nhandle_cast({free, Ch}, Chs) ->\n free(Ch, Chs). % => Chs2\n```\n\nNotice the following:\n\n- The code in `server` can be reused to build many different servers.\n- The server name, in this example the atom `ch2`, is hidden from the users of\n the client functions. This means that the name can be changed without\n affecting them.\n- The protocol (messages sent to and received from the server) is also hidden.\n This is good programming practice and allows one to change the protocol\n without changing the code using the interface functions.\n- The functionality of `server` can be extended without having to change `ch2`\n or any other callback module.\n\nIn `ch1.erl` and `ch2.erl` above, the implementation of `channels/0`, `alloc/1`,\nand `free/2` has been intentionally left out, as it is not relevant to the\nexample. For completeness, one way to write these functions is given below. This\nis an example only, a realistic implementation must be able to handle situations\nlike running out of channels to allocate, and so on.\n\n[](){: #channels-implementation }\n\n```erlang\nchannels() ->\n {_Allocated = [], _Free = lists:seq(1, 100)}.\n\nalloc({Allocated, [H|T] = _Free}) ->\n {H, {[H|Allocated], T}}.\n\nfree(Ch, {Alloc, Free} = Channels) ->\n case lists:member(Ch, Alloc) of\n true ->\n {lists:delete(Ch, Alloc), [Ch|Free]};\n false ->\n Channels\n end.\n```\n\nCode written without using behaviours can be more efficient, but the increased\nefficiency is at the expense of generality. The ability to manage all\napplications in the system in a consistent manner is important.\n\nUsing behaviours also makes it easier to read and understand code written by\nother programmers. Improvised programming structures, while possibly more\nefficient, are always more difficult to understand.\n\nThe `server` module corresponds, greatly simplified, to the Erlang/OTP behaviour\n`gen_server`.\n\nThe standard Erlang/OTP behaviours are:\n\n- [gen_server](gen_server_concepts.md)\n\n For implementing the server of a client-server relation\n\n- [gen_statem](statem.md)\n\n For implementing state machines\n\n- [gen_event](events.md)\n\n For implementing event handling functionality\n\n- [supervisor](sup_princ.md)\n\n For implementing a supervisor in a supervision tree\n\nThe compiler understands the module attribute `-behaviour(Behaviour)` and issues\nwarnings about missing callback functions, for example:\n\n```erlang\n-module(chs3).\n-behaviour(gen_server).\n...\n\n3> c(chs3).\n./chs3.erl:10: Warning: undefined call-back function handle_call/3\n{ok,chs3}\n```","title":"Behaviours - Overview","ref":"design_principles.html#behaviours"},{"type":"extras","doc":"Erlang/OTP comes with a number of components, each implementing some specific\nfunctionality. Components are with Erlang/OTP terminology called _applications_.\nExamples of Erlang/OTP applications are Mnesia, which has everything needed for\nprogramming database services, and Debugger, which is used to debug Erlang\nprograms. The minimal system based on Erlang/OTP consists of the following two\napplications:\n\n- Kernel - Functionality necessary to run Erlang\n- STDLIB - Erlang standard libraries\n\nThe application concept applies both to program structure (processes) and\ndirectory structure (modules).\n\nThe simplest applications do not have any processes, but consist of a collection\nof functional modules. Such an application is called a _library application_. An\nexample of a library application is STDLIB.\n\nAn application with processes is easiest implemented as a supervision tree using\nthe standard behaviours.\n\nHow to program applications is described in [Applications](applications.md).","title":"Applications - Overview","ref":"design_principles.html#applications"},{"type":"extras","doc":"A _release_ is a complete system made out from a subset of Erlang/OTP\napplications and a set of user-specific applications.\n\nHow to program releases is described in [Releases](release_structure.md).\n\nHow to install a release in a target environment is described in\n[Creating and Upgrading a Target System](`e:system:create_target.md`) in System Principles.","title":"Releases - Overview","ref":"design_principles.html#releases"},{"type":"extras","doc":"_Release handling_ is upgrading and downgrading between different versions of a\nrelease, in a (possibly) running system. How to do this is described in\n[Release Handling](release_handling.md).","title":"Release Handling - Overview","ref":"design_principles.html#release-handling"},{"type":"extras","doc":"\n\n[](){: #gen_server }gen_server Behaviour\n========================================\n\nIt is recommended to read this section alongside `m:gen_server` in STDLIB.\n\nClient-Server Principles\n------------------------\n\nThe client-server model is characterized by a central server and an arbitrary\nnumber of clients. The client-server model is used for resource management\noperations, where several different clients want to share a common resource.\nThe server is responsible for managing this resource.\n\n[](){: #clientserver }\n\n```mermaid\n---\ntitle: Client Server Model\n---\n\nflowchart LR\n client1((Client))\n client2((Client))\n client3((Client))\n server((Server))\n\n client1 --> server\n server -.-> client1\n\n client2 --> server\n server -.-> client2\n\n client3 --> server\n server -.-> client3\n\n subgraph Legend\n direction LR\n\n start1[ ] -->|Query| stop1[ ]\n style start1 height:0px;\n style stop1 height:0px;\n\n start2[ ] -.->|Reply| stop2[ ]\n style start2 height:0px;\n style stop2 height:0px;\n end\n```\n\nExample\n-------\n\nAn example of a simple server written in plain Erlang is provided in\n[Overview](design_principles.md#ch1). The server can be reimplemented using\n`gen_server`, resulting in this callback module:\n\n[](){: #ex }\n\n```erlang\n-module(ch3).\n-behaviour(gen_server).\n\n-export([start_link/0]).\n-export([alloc/0, free/1]).\n-export([init/1, handle_call/3, handle_cast/2]).\n\nstart_link() ->\n gen_server:start_link({local, ch3}, ch3, [], []).\n\nalloc() ->\n gen_server:call(ch3, alloc).\n\nfree(Ch) ->\n gen_server:cast(ch3, {free, Ch}).\n\ninit(_Args) ->\n {ok, channels()}.\n\nhandle_call(alloc, _From, Chs) ->\n {Ch, Chs2} = alloc(Chs),\n {reply, Ch, Chs2}.\n\nhandle_cast({free, Ch}, Chs) ->\n Chs2 = free(Ch, Chs),\n {noreply, Chs2}.\n```\n\nThe code is explained in the next sections.\n\nStarting a Gen_Server\n---------------------\n\nIn the example in the previous section, `gen_server` is started by calling\n`ch3:start_link()`:\n\n```erlang\nstart_link() ->\n gen_server:start_link({local, ch3}, ch3, [], []) => {ok, Pid}\n```\n\n`start_link/0` calls function `gen_server:start_link/4`. This function\nspawns and links to a new process, a `gen_server`.\n\n- The first argument, `{local, ch3}`, specifies the name.\n The gen_server is then locally registered as `ch3`.\n\n If the name is omitted, the `gen_server` is not registered. Instead its pid\n must be used. The name can also be given as `{global, Name}`, in which case\n the `gen_server` is registered using `global:register_name/2`.\n\n- The second argument, `ch3`, is the name of the callback module, which is\n the module where the callback functions are located.\n\n The interface functions (`start_link/0`, `alloc/0`, and `free/1`) are located\n in the same module as the callback functions (`init/1`, `handle_call/3`, and\n `handle_cast/2`). It is usually good programming practice to have the code\n corresponding to one process contained in a single module.\n\n- The third argument, `[]`, is a term that is passed as is to the callback\n function `init`. Here, `init` does not need any indata and ignores the\n argument.\n\n- The fourth argument, `[]`, is a list of options. See `m:gen_server`\n for the available options.\n\nIf name registration succeeds, the new `gen_server` process calls the callback\nfunction `ch3:init([])`. `init` is expected to return `{ok, State}`, where\n`State` is the internal state of the `gen_server`. In this case, the state is\nthe available channels.\n\n```erlang\ninit(_Args) ->\n {ok, channels()}.\n```\n\n`gen_server:start_link/4` is synchronous. It does not return until the\n`gen_server` has been initialized and is ready to receive requests.\n\n`gen_server:start_link/4` must be used if the `gen_server` is part of\na supervision tree, meaning that it was started by a supervisor. There\nis another function, `gen_server:start/4`, to start a standalone\n`gen_server` that is not part of a supervision tree.\n\nSynchronous Requests - Call\n---------------------------\n\nThe synchronous request `alloc()` is implemented using `gen_server:call/2`:\n\n```text\nalloc() ->\n gen_server:call(ch3, alloc).\n```\n\n`ch3` is the name of the `gen_server` and must agree with the name\nused to start it. `alloc` is the actual request.\n\nThe request is made into a message and sent to the `gen_server`.\nWhen the request is received, the `gen_server` calls\n`handle_call(Request, From, State)`, which is expected to return\na tuple `{reply,Reply,State1}`. `Reply` is the reply that is to be sent back\nto the client, and `State1` is a new value for the state of the `gen_server`.\n\n```erlang\nhandle_call(alloc, _From, Chs) ->\n {Ch, Chs2} = alloc(Chs),\n {reply, Ch, Chs2}.\n```\n\nIn this case, the reply is the allocated channel `Ch` and the new state is the\nset of remaining available channels `Chs2`.\n\nThus, the call `ch3:alloc()` returns the allocated channel `Ch` and the\n`gen_server` then waits for new requests, now with an updated list of\navailable channels.\n\nAsynchronous Requests - Cast\n----------------------------\n\nThe asynchronous request `free(Ch)` is implemented using `gen_server:cast/2`:\n\n```erlang\nfree(Ch) ->\n gen_server:cast(ch3, {free, Ch}).\n```\n\n`ch3` is the name of the `gen_server`. `{free, Ch}` is the actual request.\n\nThe request is made into a message and sent to the `gen_server`.\n`cast`, and thus `free`, then returns `ok`.\n\nWhen the request is received, the `gen_server` calls\n`handle_cast(Request, State)`, which is expected to return a tuple\n`{noreply,State1}`. `State1` is a new value for the state of the `gen_server`.\n\n```erlang\nhandle_cast({free, Ch}, Chs) ->\n Chs2 = free(Ch, Chs),\n {noreply, Chs2}.\n```\n\nIn this case, the new state is the updated list of available channels `Chs2`.\nThe `gen_server` is now ready for new requests.\n\nStopping\n--------","title":"gen_server Behaviour","ref":"gen_server_concepts.html"},{"type":"extras","doc":"If the `gen_server` is part of a supervision tree, no stop function is needed.\nThe `gen_server` is automatically terminated by its supervisor. Exactly how\nthis is done is defined by a [shutdown strategy](sup_princ.md#shutdown)\nset in the supervisor.\n\nIf it is necessary to clean up before termination, the shutdown strategy\nmust be a time-out value and the `gen_server` must be set to trap exit signals\nin function `init`. When ordered to shutdown, the `gen_server` then calls\nthe callback function `terminate(shutdown, State)`:\n\n```erlang\ninit(Args) ->\n ...,\n process_flag(trap_exit, true),\n ...,\n {ok, State}.\n\n...\n\nterminate(shutdown, State) ->\n %% Code for cleaning up here\n ...\n ok.\n```","title":"In a Supervision Tree - gen_server Behaviour","ref":"gen_server_concepts.html#in-a-supervision-tree"},{"type":"extras","doc":"If the `gen_server` is not part of a supervision tree, a stop function\ncan be useful, for example:\n\n```erlang\n...\nexport([stop/0]).\n...\n\nstop() ->\n gen_server:cast(ch3, stop).\n...\n\nhandle_cast(stop, State) ->\n {stop, normal, State};\nhandle_cast({free, Ch}, State) ->\n ...\n\n...\n\nterminate(normal, State) ->\n ok.\n```\n\nThe callback function handling the `stop` request returns a tuple\n`{stop,normal,State1}`, where `normal` specifies that it is\na normal termination and `State1` is a new value for the state\nof the `gen_server`. This causes the `gen_server` to call\n`terminate(normal, State1)` and then it terminates gracefully.\n\nHandling Other Messages\n-----------------------\n\nIf the `gen_server` is to be able to receive other messages than requests,\nthe callback function `handle_info(Info, State)` must be implemented\nto handle them. Examples of other messages are exit messages,\nif the `gen_server` is linked to other processes than the supervisor\nand it is trapping exit signals.\n\n```erlang\nhandle_info({'EXIT', Pid, Reason}, State) ->\n %% Code to handle exits here.\n ...\n {noreply, State1}.\n```\n\nThe final function to implement is `code_change/3`:\n\n```erlang\ncode_change(OldVsn, State, Extra) ->\n %% Code to convert state (and more) during code change.\n ...\n {ok, NewState}.\n```","title":"Standalone Gen_Servers - gen_server Behaviour","ref":"gen_server_concepts.html#standalone-gen_servers"},{"type":"extras","doc":"\n\n`gen_statem` Behaviour\n======================\n\nIt is recommended to read this section alongside\nthe `m:gen_statem` reference manual in STDLIB.\n\nEvent-Driven State Machines\n---------------------------\n\nEstablished Automata Theory does not deal much with how a _state transition_\nis triggered, but assumes that the output is a function of the input\n(and the state) and that they are some kind of values.\n\nFor an Event-Driven State Machine, the input is an _event_ that triggers\na _state transition_ and the output is actions executed during\nthe _state transition_. Analogously to the mathematical model\nof a Finite State Machine, it can be described as a set of relations\nof the following form:\n\n```erlang\nState(S) x Event(E) -> Actions(A), State(S')\n```\n\nThese relations are interpreted as follows: if we are in state `S`,\nand event `E` occurs, we are to perform actions `A`, and make a transition\nto state `S'`. Notice that `S'` can be equal to `S`,\nand that `A` can be empty.\n\nIn `gen_statem` we define a _state change_ as a _state transition_ in which the\nnew state `S'` is different from the current state `S`, where \"different\" means\nErlang's strict inequality: `=/=` also known as \"does not match\". `gen_statem`\ndoes more things during _state changes_ than during other _state transitions_.\n\nAs `A` and `S'` depend only on `S` and `E`, the kind of state machine described\nhere is a Mealy machine (see, for example, the Wikipedia article\n[Mealy machine](https://en.wikipedia.org/wiki/Mealy_machine)).\n\nSimilar to most `gen_` behaviours, `gen_statem` keeps a server `Data`\nitem besides the state. Because of this data item, and since there is\nno restriction on the number of states (assuming sufficient virtual\nmachine memory), or on the number of distinct input events, a state\nmachine implemented with this behaviour is Turing complete. But it\nfeels mostly like an Event-Driven Mealy machine.","title":"gen_statem Behaviour","ref":"statem.html"},{"type":"extras","doc":"An example of an everyday device that can be modelled as a state machine\nis a classic ballpoint pen, the retractable type where you push the end\nto expose the tip and push the side to retract it. (A push-push pen\nwould also be an example but that type has only one event, so it is\nless interesting)\n\n![Ballpoint Pen](assets/ballpoint-pen.svg \"Ballpoint Pen\")\n\n```mermaid\n---\ntitle: Ballpoint Pen State Diagram\n---\nstateDiagram-v2\n [*] --> Retracted\n Retracted --> Retracted : push-side\n Retracted --> Exposed : push-end\\n* Expose tip\n Exposed --> Retracted : push-side\\n* Retract tip\n Exposed --> Exposed : push-end\n```\n\nThe state diagram shows the states, events, and state transitions\nwith transition actions. Note that pushing the end when the tip is exposed,\nor pushing the side when the tip is retracted, does not change the state\nnor cause any actions, which is modeled by an arrow back to the same state.\n\nWhen to use gen_statem\n----------------------\n\nYou should consider using `m:gen_statem` over `m:gen_server` if your\nprocess logic is convenient to describe as a state machine and you\nneed any of these `m:gen_statem` key features:\n\n- Co-located callback code for each state, for all\n [_event types_](#event-types-and-event-content), such as _call_,\n _cast_, and _info_\n- [_Postponing events_](#postponing-events) - a substitute for selective\n receive\n- [_Inserted events_](#inserted-events) - events from the state\n machine to itself; for purely internal events in particular\n- [_State enter calls_](#state-enter-calls) - callback on state entry\n co-located with the rest of each state's callback code\n- Easy-to-use time-outs - [_state time-outs_](#state-time-outs),\n [_event time-outs_](#event-time-outs), and\n [_generic time-outs_](#generic-time-outs) (named time-outs)\n\nFor simple state machines not needing these features, `m:gen_server`\nis perfectly suitable. It also has a smaller call overhead, but we are\ntalking about something like 2 vs 3.3 microseconds call roundtrip time\nhere, so if the server callback does just a little bit more than just\nreplying, or if calls are not extremely frequent, that difference\nwill be hard to notice.\n\nCallback Module\n---------------\n\nThe _callback module_ contains functions that implement the state\nmachine. When an event occurs, the `gen_statem` behaviour engine calls\na function in the _callback module_ with the event, current state, and\nserver data. This callback function performs the actions for the\nevent, and returns the new state and server data as well as actions to\nbe performed by the behaviour engine.\n\nThe behaviour engine holds the state machine state, server data, timer\nreferences, a queue of postponed messages, and other metadata. It receives all\nprocess messages, handles the system messages, and calls the _callback module_\nwith state machine specific events.\n\nThe _callback module_ can be changed for a running server using any of the\n[_transition actions_](#transition-actions)\n[`{change_callback_module, NewModule}`](`t:gen_statem:action/0`),\n[`{push_callback_module, NewModule}`](`t:gen_statem:action/0`), or\n[`pop_callback_module`](`t:gen_statem:action/0`).\n\n> #### Note {: .info }\n>\n> Switching the callback module is a pretty esoteric thing to do...\n>\n> The origin for this feature is a protocol that after version\n> negotiation branches off into quite different state machines depending\n> on the protocol version. There _might_ be other use cases. _Beware_\n> that the new callback module completely replaces the previous callback\n> module, so all relevant callback functions have to handle the state\n> and data from the previous callback module.\n\nCallback Modes\n--------------\n\nThe `gen_statem` behaviour supports two _callback modes_:\n\n- **[`state_functions`](`t:gen_statem:callback_mode/0`)** - Events are handled\n by one callback function per state.\n\n- **[`handle_event_function`](`t:gen_statem:callback_mode/0`)** - Events are\n handled by one single callback function.\n\nThe _callback mode_ is a property of the _callback module_ and is set at server\nstart. It may be changed due to a code upgrade/downgrade, or when changing the\n_callback module_.\n\nSee the section [_State Callback_](#state-callback) that describes the\nevent handling callback function(s).\n\nThe _callback mode_ is selected by implementing a mandatory callback function\n[`Module:callback_mode()`](`c:gen_statem:callback_mode/0`) that returns one of\nthe _callback modes_.\n\nThe [`Module:callback_mode()`](`c:gen_statem:callback_mode/0`) function\nmay also return a list containing the _callback mode_ and the atom\n`state_enter` in which case [_state enter calls_](#state-enter-calls)\nare activated for the _callback mode_.","title":"Everyday State Machine - gen_statem Behaviour","ref":"statem.html#everyday-state-machine"},{"type":"extras","doc":"The short version: choose `state_functions` - it is the one most like\n`m:gen_fsm`. But if you do not want the restriction that the state must be an\natom, or if you do not want to write one _state callback_ function per state,\nplease read on...\n\nThe two [_callback modes_](#callback-modes) give different\npossibilities and restrictions, with one common goal: to handle all possible\ncombinations of events and states.\n\nThis can be done, for example, by focusing on one state at the time and for\nevery state ensure that all events are handled. Alternatively, you can focus\non one event at the time and ensure that it is handled in every state.\nYou can also use a mix of these strategies.\n\nWith `state_functions`, you are restricted to use atom-only states, and the\n`m:gen_statem` engine branches depending on state name for you.\nThis encourages the _callback module_ to co-locate the implementation\nof all event actions particular to one state in the same place in the code,\nhence to focus on one state at the time.\n\nThis mode fits well when you have a regular state diagram, like the ones\nin this chapter, which describes all events and actions belonging to a state\nvisually around that state, and each state has its unique name.\n\nWith `handle_event_function`, you are free to mix strategies, as all events\nand states are handled in the same callback function.\n\nThis mode works equally well when you want to focus on one event\nat the time or on one state at the time, but function\n[`Module:handle_event/4`](`c:gen_statem:handle_event/4`) quickly grows\ntoo large to handle without branching to helper functions.\n\nThe mode enables the use of non-atom states, for example, complex states,\nor even hierarchical states. See section [_Complex State_](#complex-state).\nIf, for example, a state diagram is largely alike for the client side\nand the server side of a protocol, you can have a state `{StateName, server}`,\nor `{StateName, client}`, and make `StateName` determine where in the code\nto handle most events in the state. The second element of the tuple\nis then used to select whether to handle special client-side\nor server-side events.\n\nState Callback\n--------------\n\nThe _state callback_ is the callback function that handles an event in the\ncurrent state, and which function that is depends on the _callback mode_:\n\n- **`state_functions`** - The event is handled by:\n [`Module:StateName(EventType, EventContent,\n Data)`](`c:gen_statem:'StateName'/3`)\n\n This form is the one mostly used in the [_Example_](#example) section.\n\n- **`handle_event_function`** - The event is handled by:\n [`Module:handle_event(EventType, EventContent, State,\n Data)`](`c:gen_statem:handle_event/4`)\n\n See section [_One State Callback_](#one-state-callback) for an example.\n\nThe state is either the name of the state callback itself, or an argument\nto the [`handle_event()`](`c:gen_statem:handle_event/4`) callback. The\nother arguments are the `EventType` and the event dependent `EventContent`,\nboth described in section\n[_Event Types and Event Content_](#event-types-and-event-content),\nand the the last argument is the current server `Data`.\n\n[_State Enter Calls_](#state-enter-calls) (see that section)\nare also handled by the event handler and have slightly different arguments.\n\nThe _state callback_ return values are defined in the description of\n[`Module:StateName/3`](`c:gen_statem:'StateName'/3`) in `m:gen_statem`.\nHere is a maybe more readable list:\n\n- **`{next_state, NextState, NewData [, Actions]}`**\n Set next state and update the server data. If the `Actions` field is used,\n execute [_Transition Actions_](#transition-actions)\n (see that section). An empty `Actions` list is equivalent to not\n returning the field.\n\n If `NextState =/= State` it's a _state change_ and `gen_statem`\n does some extra things: the event queue is restarted from the oldest\n [postponed event](#postponing-events), any current\n [_state time-out_](#state-time-outs) is canceled, and a\n [_state enter call_](#state-enter-calls) is performed, if enabled.\n The current `State` becomes `OldState` in a _state enter call_.\n\n- **`{keep_state, NewData [, Actions]}`**\n Same as the `next_state` values with `NextState =:= State`, that is,\n no _state change_.\n\n- **`keep_state_and_data | {keep_state_and_data, Actions}`**\n Same as the `keep_state` values with `NextData =:= Data`, that is, no change\n in server data.\n\n- **`{repeat_state, NewData [, Actions]} |\n repeat_state_and_data |{repeat_state_and_data, Actions}`**\n Same as the `keep_state` or `keep_state_and_data` values, but if\n [_state enter calls_](#state-enter-calls) are enabled;\n repeat it as if this state was entered again. In this case `State`\n and `OldState` becomes equal in the repeated _state enter call_\n since the state is re-entered from itself.\n\n- **`{stop, Reason [, NewData]}`**\n Stop the server with reason `Reason`. If the `NewData` field is used,\n first update the server data.\n\n- **`{stop_and_reply, Reason, [NewData, ] ReplyActions}`**\n Same as the `stop` values, but first execute the given\n [_transition actions_](#transition-actions)\n that may only be reply actions.","title":"Choosing the Callback Mode - gen_statem Behaviour","ref":"statem.html#choosing-the-callback-mode"},{"type":"extras","doc":"To decide the first state the\n[`Module:init(Args)`](`c:gen_statem:init/1`) callback function is called\nbefore any [_state callback_](#state-callback) is called. This function\nbehaves like a _state callback_ function, but gets its only argument `Args`\nfrom the `gen_statem` [`start/3,4`](`gen_statem:start/3`) or\n[`start_link/3,4`](`gen_statem:start_link/3`) function, and returns\n`{ok, State, Data}` or `{ok, State, Data, Actions}`. If you use the\n[`postpone`](#postponing-events) action from this function, that action\nis ignored, since there is no event to postpone.\n\nTransition Actions\n------------------\n\nIn the first section\n([_Event-Driven State Machines_](#event-driven-state-machines)), actions\nwere mentioned as a part of the general state machine model. These general\nactions are implemented with the code that _callback module_ `gen_statem`\nexecutes in an event-handling callback function before returning to the\n`m:gen_statem` engine.\n\nThere are more specific _transition actions_ that a callback function can\ncommand the `gen_statem` engine to do after the callback function return.\nThese are commanded by returning a list of [_actions_](`t:gen_statem:action/0`)\nin the [return value](`t:gen_statem:state_callback_result/2`) from the\n[_callback function_](`c:gen_statem:'StateName'/3`). These are the possible\n_transition actions_:\n\n- **[`{postpone, Boolean}`](`t:gen_statem:postpone/0`)** -\n If `true` postpone the current event, see section\n [_Postponing Events_](#postponing-events).\n\n- **[`{hibernate, Boolean`](`t:gen_statem:hibernate/0`)** -\n If `true` hibernate the `gen_statem`, treated in section\n [_Hibernation_](#hibernation).\n\n- **[`{state_timeout, Time, EventContent\n [, Opts]}`](`t:gen_statem:state_timeout/0`)` |`**\\\n **[`{state_timeout, update,\n EventContent}`](`t:gen_statem:timeout_update_action/0`)` |`**\\\n **[`{state_timeout, cancel}`](`t:gen_statem:timeout_cancel_action/0`)** -\n Start, update, or cancel a _state time-out_, read more in sections\n [_Time-Outs_](#time-outs) and\n [_State Time-Outs_](#state-time-outs).\n\n- **[`{{timeout, Name}, Time, EventContent\n [, Opts]}`](`t:gen_statem:generic_timeout/0`)` |`**\\\n **[`{{timeout, Name}, update,\n EventContent}`](`t:gen_statem:timeout_update_action/0`)` |`**\\\n **[`{{timeout, Name}, cancel}`](`t:gen_statem:timeout_cancel_action/0`)** -\n Start, update, or cancel a _generic time-out_, read more in sections\n [_Time-Outs_](#time-outs) and\n [_Generic Time-Outs_](#generic-time-outs).\n\n- **[`{timeout, Time, EventContent\n [, Opts]}`](`t:gen_statem:event_timeout/0`)** -\n Start an _event time-out_, see more in sections [_Time-Outs_](#time-outs)\n and [_Event Time-Outs_](#event-time-outs).\n\n- **[`{reply, From, Reply}`](`t:gen_statem:reply_action/0`)** - Reply to a\n caller, mentioned at the end of section\n [_All State Events_](#all-state-events).\n\n- **[`{next_event, EventType, EventContent}`](`t:gen_statem:action/0`)** -\n Generate the next event to handle, see section\n [_Inserted Events_](#inserted-events).\n\n- **[`{change_callback_module, NewModule}`](`t:gen_statem:action/0`)** -\n Change the [_callback module_](#callback-module) for the running server.\n This can be done during any _state transition_, whether it is\n a _state change_ or not, but it _cannot_ be done from a\n [_state enter call_](#state-enter-calls).\n\n- **[`{push_callback_module, NewModule}`](`t:gen_statem:action/0`)** -\n Push the current _callback module_ to the top of an internal stack\n of callback modules and set the new [_callback module_](#callback-module)\n for the running server. Otherwise like\n `{change_callback_module, NewModule}` above.\n\n- **[`pop_callback_module`](`t:gen_statem:action/0`)** - Pop the top module\n from the internal stack of callback modules and set it to be the new\n [_callback module_](#callback-module) for the running server. If the\n stack is empty the server fails. Otherwise like\n `{change_callback_module, NewModule}` above.\n\nFor details, see module `m:gen_statem` for type\n[`action()`](`t:gen_statem:action/0`). You can, for example, reply to many\ncallers, generate multiple next events, and set a time-out to use absolute\ninstead of relative time (using the `Opts` field).\n\nOut of these _transition actions_, the only immediate action is\n`reply` for replying to a caller. The other actions are collected and\nhandled later during the _state transition_.\n[_Inserted events_](#inserted-events) are stored and inserted all\ntogether, and the rest set transition options where the last of a\nspecific type override the previous. See the description of a _state\ntransition_ in module `m:gen_statem` for type\n[`transition_option()`](`t:gen_statem:transition_option/0`).\n\nThe different [_Time-Outs_](#time-outs) and\n[`next_event`](#inserted-events) actions generate new events with\ncorresponding\n[_event types and event content_](#event-types-and-event-content).\n\nEvent Types and Event Content\n-----------------------------\n\nEvents are categorized in different\n[_event types_](`t:gen_statem:event_type/0`). Events of all types are for a\ngiven state handled in the same callback function, and that function gets\n`EventType` and `EventContent` as arguments. The meaning of the `EventContent`\ndepends on the `EventType`.\n\nThe following is a complete list of _event types_ and from where they come:\n\n- **[`cast`](`t:gen_statem:external_event_type/0`)** - Generated by\n [`gen_statem:cast(ServerRef, Msg)`](`gen_statem:cast/2`) where `Msg` becomes\n the `EventContent`.\n\n- **[`{call, From}`](`t:gen_statem:external_event_type/0`)** - Generated by\n [`gen_statem:call(ServerRef, Request)`](`gen_statem:call/2`),\n [`gen_statem:send_request(ServerRef,\n Request)`](`gen_statem:send_request/2`), or\n [`gen_statem:send_request(ServerRef, Request,\n _, _)`](`gen_statem:send_request/4`) where `Request` becomes\n the `EventContent`. `From` is the reply address to use when replying\n either through the _transition action_ `{reply, From, Reply}`,\n or by calling [`gen_statem:reply(From, Reply)`](`gen_statem:reply/1`)\n from the _callback module_.\n\n- **[`info`](`t:gen_statem:external_event_type/0`)** - Generated by\n any regular process message sent to the `gen_statem` process.\n The process message becomes the `EventContent`.\n\n- **[`state_timeout`](`t:gen_statem:timeout_event_type/0`)** - Generated by\n _transition action_\n [`{state_timeout, Time, EventContent}`](`t:gen_statem:timeout_action/0`)\n when the time-out expires. Read more in sections [_Time-Outs_](#time-outs)\n and [_State Time-Outs_](#state-time-outs).\n\n- **[`{timeout, Name}`](`t:gen_statem:timeout_event_type/0`)** - Generated by\n _transition action_\n [`{{timeout, Name},Time, EventContent}`](`t:gen_statem:timeout_action/0`)\n when the time-out expires. Read more in sections [_Time-Outs_](#time-outs)\n and [_Generic Time-Outs_](#generic-time-outs).\n\n- **[`timeout`](`t:gen_statem:timeout_event_type/0`)** - Generated by\n _transition action_\n [`{timeout, Time, EventContent}`](`t:gen_statem:timeout_action/0`)\n (or its short form `Time`) when the time-out expires. Read more in sections\n [_Time-Outs_](#time-outs) and [_Event Time-Outs_](#event-time-outs).\n\n- **[`internal`](`t:gen_statem:event_type/0`)** - Generated by _transition\n action_ [`{next_event, internal, EventContent}`](`t:gen_statem:action/0`).\n All _event types_ above can also be generated using the `next_event` action:\n `{next_event, EventType, EventContent}`.\n\nState Enter Calls\n-----------------\n\nThe `gen_statem` behaviour can, if this is enabled, regardless of _callback\nmode_, automatically call the [_state callback_](`t:gen_statem:state_enter/0`)\nwith special arguments whenever the state changes, so you can write\nstate enter actions near the rest of the _state transition_ rules.\nIt typically looks like this:\n\n```erlang\nStateName(enter, OldState, Data) ->\n ... code for state enter actions here ...\n {keep_state, NewData};\nStateName(EventType, EventContent, Data) ->\n ... code for actions here ...\n {next_state, NewStateName, NewData}.\n```\n\nSince the _state enter call_ is not an event there are restrictions on the\nallowed return value and state [_transition actions_](#transition-actions).\nYou must not change the state, [postpone](#postponing-events) this non-event,\n[insert any events](#inserted-events), or change the\n[_callback module_](#callback-module).\n\nThe first state that is entered after `c:gen_statem:init/1` will get\na _state enter call_ with `OldState` equal to the current state.\n\nYou may repeat the _state enter call_ using the `{repeat_state,...}` return\nvalue from the [_state callback_](#state-callback). In this case\n`OldState` will also be equal to the current state.\n\nDepending on how your state machine is specified, this can be a very useful\nfeature, but it forces you to handle the _state enter calls_ in all states.\nSee also the [_State Enter Actions_](#state-enter-actions) section.\n\nTime-Outs\n---------\n\nTime-outs in `gen_statem` are started from a\n[_transition action_](#transition-actions) during a state transition\nthat is when exiting from the [_state callback_](#state-callback).\n\nThere are 3 types of time-outs in `gen_statem`:\n\n- **[`state_timeout`](`t:gen_statem:state_timeout/0`)** - There is one\n [_state time-out_](#state-time-outs) that is automatically canceled by\n a _state change_.\n\n- **[`{timeout, Name}`](`t:gen_statem:generic_timeout/0`)** - There are any\n number of [_generic time-outs_](#generic-time-outs) differing by their\n `Name`. They have no automatic canceling.\n\n- **[`timeout`](`t:gen_statem:event_timeout/0`)** - There is one\n [_event time-out_](#event-time-outs) that is automatically canceled by\n any event. Note that [postponed](#postponing-events) and\n [inserted](#inserted-events) events cancel this time-out just as\n external events do.\n\nWhen a time-out is started, any running time-out of the same type\n(`state_timeout`, `{timeout, Name}`, or `timeout`) is canceled, that is,\nthe time-out is restarted with the new time and event content.\n\nAll time-outs have an `EventContent` that is part of the\n[_transition action_](#transition-actions) that starts the time-out.\nDifferent `EventContent`s does not create different time-outs. The\n`EventContent` is delivered to the [_state callback_](#state-callback)\nwhen the time-out expires.","title":"The First State - gen_statem Behaviour","ref":"statem.html#the-first-state"},{"type":"extras","doc":"Starting a time-out with the `infinity` time value would never time out,\nwhich is optimized by not even starting it, and any running\ntime-out with the same tag will be canceled. The `EventContent` will\nin this case be ignored, so it makes sense to set it to `undefined`.\n\nA more explicit way to cancel a time-out is to use a\n[_transition action_](#transition-actions) on the form\n[`{TimeoutType, cancel}`](`t:gen_statem:timeout_cancel_action/0`).","title":"Canceling a Time-Out - gen_statem Behaviour","ref":"statem.html#canceling-a-time-out"},{"type":"extras","doc":"While a time-out is running, its `EventContent` can be updated using a\n[_transition action_](#transition-actions) on the form\n[`{TimeoutType, update,\nNewEventContent}`](`t:gen_statem:timeout_update_action/0`).\n\nIf this feature is used while no such `TimeoutType` is running, a time-out\nevent is immediately delivered as when starting a\n[zero time-out](#zero-time-out).","title":"Updating a Time-Out - gen_statem Behaviour","ref":"statem.html#updating-a-time-out"},{"type":"extras","doc":"If a time-out is started with the time `0` it will actually not be started.\nInstead the time-out event will immediately be inserted to be processed after\nany events already enqueued, and before any not yet received external events.\n\nNote that some time-outs are automatically canceled so if you for example\ncombine [postponing](#postponing-events) an event in a _state change_\nwith starting an [_event time-out_](#event-time-outs) with time `0` there\nwill be no time-out event inserted since the _event time-out_ is canceled by\nthe postponed event that is delivered due to the state change.\n\nExample\n-------\n\nA door with a code lock can be seen as a state machine. Initially,\nthe door is locked. When someone presses a button, a `{button, Button}`\nevent is generated. In the state diagram below, \"Collect Buttons\" means\nto store buttons up to as many as in the correct code; append to\na length capped list. If correct, the door is unlocked for 10 seconds.\nIf incorrect, we wait for a new button to be pressed.\n\n```mermaid\n---\ntitle: Code Lock State Diagram\n---\nstateDiagram-v2\n state check_code < >\n\n [*] --> locked : * do_lock()\\n* Clear Buttons\n\n locked --> check_code : {button, Button}\\n* Collect Buttons\n check_code --> locked : Incorrect code\n check_code --> open : Correct code\\n* do_unlock()\\n* Clear Buttons\\n* Set state_timeout 10 s\n\n open --> open : {button, Digit}\n open --> locked : state_timeout\\n* do_lock()\n```\n\nThis code lock state machine can be implemented using `m:gen_statem` with\nthe following _callback module_:\n\n```erlang\n-module(code_lock).\n-behaviour(gen_statem).\n-define(NAME, code_lock).\n\n-export([start_link/1]).\n-export([button/1]).\n-export([init/1,callback_mode/0,terminate/3]).\n-export([locked/3,open/3]).\n\nstart_link(Code) ->\n gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).\n\nbutton(Button) ->\n gen_statem:cast(?NAME, {button,Button}).\n\ninit(Code) ->\n do_lock(),\n Data = #{code => Code, length => length(Code), buttons => []},\n {ok, locked, Data}.\n\ncallback_mode() ->\n state_functions.\n```\n\n```erlang\nlocked(\n cast, {button,Button},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n NewButtons =\n if\n length(Buttons) \n Buttons;\n true ->\n tl(Buttons)\n end ++ [Button],\n if\n NewButtons =:= Code -> % Correct\n\t do_unlock(),\n {next_state, open, Data#{buttons := []},\n [{state_timeout,10_000,lock}]}; % Time in milliseconds\n\ttrue -> % Incomplete | Incorrect\n {next_state, locked, Data#{buttons := NewButtons}}\n end.\n```\n\n```erlang\nopen(state_timeout, lock, Data) ->\n do_lock(),\n {next_state, locked, Data};\nopen(cast, {button,_}, Data) ->\n {next_state, open, Data}.\n```\n\n```erlang\ndo_lock() ->\n io:format(\"Lock~n\", []).\ndo_unlock() ->\n io:format(\"Unlock~n\", []).\n\nterminate(_Reason, State, _Data) ->\n State =/= locked andalso do_lock(),\n ok.\n```\n\nThe code is explained in the next sections.\n\nStarting gen_statem\n-------------------\n\nIn the example in the previous section, `gen_statem` is started by calling\n`code_lock:start_link(Code)`:\n\n```erlang\nstart_link(Code) ->\n gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).\n```\n\n`start_link/1` calls function `gen_statem:start_link/4`,\nwhich spawns and links to a new process, a `gen_statem`.\n\n- The first argument, `{local,?NAME}`, specifies the name. In this case, the\n `gen_statem` is locally registered as `code_lock` through the macro `?NAME`.\n\n If the name is omitted, the `gen_statem` is not registered. Instead its pid\n must be used. The name can also be specified as `{global, Name}`, then the\n `gen_statem` is registered using `global:register_name/2` in Kernel.\n\n- The second argument, `?MODULE`, is the name of the _callback module_,\n that is, the module where the callback functions are located,\n which is this module.\n\n The interface functions (`start_link/1` and `button/1`) are located in the\n same module as the callback functions (`init/1`, `locked/3`, and `open/3`).\n It is normally good programming practice to have the client-side code\n and the server-side code contained in the same module.\n\n- The third argument, `Code`, is a list of digits, which is the correct\n unlock code that is passed to callback function `init/1`.\n\n- The fourth argument, `[]`, is a list of options. For the available options,\n see `gen_statem:start_link/3`.\n\nIf name registration succeeds, the new `gen_statem` process calls callback\nfunction `code_lock:init(Code)`. This function is expected to return\n`{ok, State, Data}`, where `State` is the initial state of the `gen_statem`,\nin this case `locked`; assuming that the door is locked to begin with.\n`Data` is the internal server data of the `gen_statem`. Here the server data\nis a [`map()`](`m:maps`) with key `code` that stores the correct\nbutton sequence, key `length` store its length, and key `buttons`\nthat stores the collected buttons up to the same length.\n\n```erlang\ninit(Code) ->\n do_lock(),\n Data = #{code => Code, length => length(Code), buttons => []},\n {ok, locked, Data}.\n```\n\nFunction [`gen_statem:start_link/3,4`](`gen_statem:start_link/3`)\nis synchronous. It does not return until the `gen_statem` is initialized\nand is ready to receive events.\n\nFunction [`gen_statem:start_link/3,4`](`gen_statem:start_link/3`)\nmust be used if the `gen_statem` is part of a supervision tree, that is,\nstarted by a supervisor. Function,\n[`gen_statem:start/3,4`](`gen_statem:start/3`) can be used to start\na standalone `gen_statem`, meaning it is not part of a supervision tree.\n\nFunction [`Module:callback_mode/0`](`c:gen_statem:callback_mode/0`) selects\nthe [`CallbackMode`](#callback-modes) for the _callback module_,\nin this case [`state_functions`](`t:gen_statem:callback_mode/0`).\nThat is, each state has its own handler function:\n\n```erlang\ncallback_mode() ->\n state_functions.\n```\n\nHandling Events\n---------------\n\nThe function notifying the code lock about a button event is implemented using\n`gen_statem:cast/2`:\n\n```erlang\nbutton(Button) ->\n gen_statem:cast(?NAME, {button,Button}).\n```\n\nThe first argument is the name of the `gen_statem` and must agree with\nthe name used to start it. So, we use the same macro `?NAME` as when starting.\n`{button, Button}` is the event content.\n\nThe event is sent to the `gen_statem`. When the event is received, the\n`gen_statem` calls `StateName(cast, Event, Data)`, which is expected\nto return a tuple `{next_state, NewStateName, NewData}`, or\n`{next_state, NewStateName, NewData, Actions}`. `StateName` is the name\nof the current state and `NewStateName` is the name of the next state.\n`NewData` is a new value for the server data of the `gen_statem`,\nand `Actions` is a list of actions to be performed by the `gen_statem` engine.\n\n```erlang\nlocked(\n cast, {button,Button},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n NewButtons =\n if\n length(Buttons) \n Buttons;\n true ->\n tl(Buttons)\n end ++ [Button],\n if\n NewButtons =:= Code -> % Correct\n\t do_unlock(),\n {next_state, open, Data#{buttons := []},\n [{state_timeout,10_000,lock}]}; % Time in milliseconds\n\ttrue -> % Incomplete | Incorrect\n {next_state, locked, Data#{buttons := NewButtons}}\n end.\n```\n\nIn state `locked`, when a button is pressed, it is collected with the\npreviously pressed buttons up to the length of the correct code, then\ncompared with the correct code. Depending on the result, the door is\neither unlocked and the `gen_statem` goes to state `open`, or the door\nremains in state `locked`.\n\nWhen changing to state `open`, the collected buttons are reset, the lock\nunlocked, and a _state time-out_ for 10 seconds is started.\n\n```erlang\nopen(cast, {button,_}, Data) ->\n {next_state, open, Data}.\n```\n\nIn state `open`, a button event is ignored by staying in the same state.\nThis can also be done by returning `{keep_state, Data}`, or in this case\nsince `Data` is unchanged, by returning `keep_state_and_data`.\n\nState Time-Outs\n---------------\n\nWhen a correct code has been given, the door is unlocked and the following\ntuple is returned from `locked/2`:\n\n```erlang\n{next_state, open, Data#{buttons := []},\n [{state_timeout,10_000,lock}]}; % Time in milliseconds\n```\n\n10,000 is a time-out value in milliseconds. After this time (10 seconds),\na time-out occurs. Then, `StateName(state_timeout, lock, Data)` is called.\nThe time-out occurs when the door has been in state `open` for 10 seconds.\nAfter that the door is locked again:\n\n```erlang\nopen(state_timeout, lock, Data) ->\n do_lock(),\n {next_state, locked, Data};\n```\n\nThe timer for a _state time-out_ is automatically canceled when\nthe state machine does a _state change_.\n\nYou can restart, cancel, or update a _state time-out_. See section\n[_Time-Outs_](#time-outs) for details.\n\nAll State Events\n----------------\n\nSometimes events can arrive in any state of the `gen_statem`. It is convenient\nto handle these in a common state handler function that all state functions\ncall for events not specific to the state.\n\nConsider a `code_length/0` function that returns the length\nof the correct code. We dispatch all events that are not state-specific\nto the common function `handle_common/3`:\n\n```erlang\n...\n-export([button/1,code_length/0]).\n...\n\ncode_length() ->\n gen_statem:call(?NAME, code_length).\n\n...\nlocked(...) -> ... ;\nlocked(EventType, EventContent, Data) ->\n handle_common(EventType, EventContent, Data).\n\n...\nopen(...) -> ... ;\nopen(EventType, EventContent, Data) ->\n handle_common(EventType, EventContent, Data).\n\nhandle_common({call,From}, code_length, #{code := Code} = Data) ->\n {keep_state, Data,\n [{reply,From,length(Code)}]}.\n```\n\nAnother way to do it is through a convenience macro `?HANDLE_COMMON/0`:\n\n```erlang\n...\n-export([button/1,code_length/0]).\n...\n\ncode_length() ->\n gen_statem:call(?NAME, code_length).\n\n-define(HANDLE_COMMON,\n ?FUNCTION_NAME(T, C, D) -> handle_common(T, C, D)).\n%%\nhandle_common({call,From}, code_length, #{code := Code} = Data) ->\n {keep_state, Data,\n [{reply,From,length(Code)}]}.\n\n...\nlocked(...) -> ... ;\n?HANDLE_COMMON.\n\n...\nopen(...) -> ... ;\n?HANDLE_COMMON.\n```\n\nThis example uses `gen_statem:call/2`, which waits for a reply from the server.\nThe reply is sent with a `{reply, From, Reply}` tuple in an action list in the\n`{keep_state, ...}` tuple that retains the current state. This return form is\nconvenient when you want to stay in the current state but do not know or care\nabout what it is.\n\nIf the common _state callback_ needs to know the current state a function\n`handle_common/4` can be used instead:\n\n```erlang\n-define(HANDLE_COMMON,\n ?FUNCTION_NAME(T, C, D) -> handle_common(T, C, ?FUNCTION_NAME, D)).\n```\n\nOne State Callback\n------------------\n\nIf [_callback mode_](#callback-modes) `handle_event_function` is used,\nall events are handled in\n[`Module:handle_event/4`](`c:gen_statem:handle_event/4`) and we can\n(but do not have to) use an event-centered approach where we first branch\ndepending on event and then depending on state:\n\n```erlang\n...\n-export([handle_event/4]).\n\n...\ncallback_mode() ->\n handle_event_function.\n\nhandle_event(cast, {button,Button}, State, #{code := Code} = Data) ->\n case State of\n\tlocked ->\n #{length := Length, buttons := Buttons} = Data,\n NewButtons =\n if\n length(Buttons) \n Buttons;\n true ->\n tl(Buttons)\n end ++ [Button],\n if\n NewButtons =:= Code -> % Correct\n do_unlock(),\n {next_state, open, Data#{buttons := []},\n [{state_timeout,10_000,lock}]}; % Time in milliseconds\n true -> % Incomplete | Incorrect\n {keep_state, Data#{buttons := NewButtons}}\n end;\n\topen ->\n keep_state_and_data\n end;\nhandle_event(state_timeout, lock, open, Data) ->\n do_lock(),\n {next_state, locked, Data};\nhandle_event(\n {call,From}, code_length, _State, #{code := Code} = Data) ->\n {keep_state, Data,\n [{reply,From,length(Code)}]}.\n\n...\n```\n\nStopping\n--------","title":"Zero Time-Out - gen_statem Behaviour","ref":"statem.html#zero-time-out"},{"type":"extras","doc":"If the `gen_statem` is part of a supervision tree, no stop function is needed.\nThe `gen_statem` is automatically terminated by its supervisor. Exactly how\nthis is done is defined by a [shutdown strategy](sup_princ.md#shutdown)\nset in the supervisor.\n\nIf it is necessary to clean up before termination, the shutdown strategy\nmust be a time-out value and the `gen_statem` must in function `init/1`\nset itself to trap exit signals by calling\n[`process_flag(trap_exit, true)`](`erlang:process_flag/2`):\n\n```erlang\ninit(Args) ->\n process_flag(trap_exit, true),\n do_lock(),\n ...\n```\n\nWhen ordered to shut down, the `gen_statem` then calls callback function\n`terminate(shutdown, State, Data)`.\n\nIn this example, function `terminate/3` locks the door if it is open,\nso we do not accidentally leave the door open\nwhen the supervision tree terminates:\n\n```erlang\nterminate(_Reason, State, _Data) ->\n State =/= locked andalso do_lock(),\n ok.\n```","title":"In a Supervision Tree - gen_statem Behaviour","ref":"statem.html#in-a-supervision-tree"},{"type":"extras","doc":"If the `gen_statem` is not part of a supervision tree, it can be stopped\nusing [`gen_statem:stop/1`](`gen_statem:stop/1`), preferably through\nan API function:\n\n```erlang\n...\n-export([start_link/1,stop/0]).\n\n...\nstop() ->\n gen_statem:stop(?NAME).\n```\n\nThis makes the `gen_statem` call callback function `terminate/3` just like\nfor a supervised server and waits for the process to terminate.\n\nEvent Time-Outs\n---------------\n\nA time-out feature inherited from `gen_statem`'s predecessor `m:gen_fsm`,\nis an _event time-out_, that is, if an event arrives the timer is canceled.\nYou get either an event or a time-out, but not both.\n\nIt is ordered by the\n[_transition action_](#transition-actions) `{timeout, Time, EventContent}`,\nor just an integer `Time`, even without the enclosing actions list (the latter\nis a form inherited from `gen_fsm`).\n\nThis type of time-out is useful, for example, to act on inactivity.\nLet's restart the code sequence if no button is pressed for say 30 seconds:\n\n```erlang\n...\n\nlocked(timeout, _, Data) ->\n {next_state, locked, Data#{buttons := []}};\nlocked(\n cast, {button,Button},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n...\n\ttrue -> % Incomplete | Incorrect\n {next_state, locked, Data#{buttons := NewButtons},\n 30_000} % Time in milliseconds\n...\n```\n\nWhenever we receive a button event we start an _event time-out_ of 30 seconds,\nand if we get an _event type_ of `timeout` we reset the remaining\ncode sequence.\n\nAn _event time-out_ is canceled by any other event so you either get\nsome other event or the time-out event. Therefore, canceling,\nrestarting, or updating an _event time-out_ is neither possible nor\nnecessary. Whatever event you act on has already canceled\nthe _event time-out_, so there is never a running _event time-out_\nwhile the _state callback_ executes.\n\nNote that an _event time-out_ does not work well when you have for example a\nstatus call as in section [_All State Events_](#all-state-events), or\nhandle unknown events, since all kinds of events will cancel\nthe _event time-out_.\n\nGeneric Time-Outs\n-----------------\n\nThe previous example of _state time-outs_ only work if the state machine stays\nin the same state during the time-out time. And _event time-outs_ only work\nif no disturbing unrelated events occur.\n\nYou may want to start a timer in one state and respond to the time-out in\nanother, maybe cancel the time-out without changing states, or perhaps run\nmultiple time-outs in parallel. All this can be accomplished with\n[_generic time-outs_](`t:gen_statem:generic_timeout/0`). They may look a little\nbit like [_event time-outs_](`t:gen_statem:event_timeout/0`) but contain\na name to allow for any number of them simultaneously and they are\nnot automatically canceled.\n\nHere is how to accomplish the _state time-out_ in the previous example\nby instead using a _generic time-out_ named for example `open`:\n\n```erlang\n...\nlocked(\n cast, {button,Button},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n...\n if\n NewButtons =:= Code -> % Correct\n\t do_unlock(),\n {next_state, open, Data#{buttons := []},\n [{{timeout,open},10_000,lock}]}; % Time in milliseconds\n...\n\nopen({timeout,open}, lock, Data) ->\n do_lock(),\n {next_state,locked,Data};\nopen(cast, {button,_}, Data) ->\n {keep_state,Data};\n...\n```\n\nSpecific _generic time-outs_ can just as [_state time-outs_](#state-time-outs)\nbe restarted or canceled by setting it to a new time or `infinity`.\n\nIn this particular case we do not need to cancel the time-out since\nthe time-out event is the only possible reason to do a _state change_\nfrom `open` to `locked`.\n\nInstead of bothering with when to cancel a time-out, a late time-out event\ncan be handled by ignoring it if it arrives in a state\nwhere it is known to be late.\n\nYou can restart, cancel, or update a _generic time-out_.\nSee section [_Time-Outs_](#time-outs) for details.\n\nErlang Timers\n-------------\n\nThe most versatile way to handle time-outs is to use Erlang Timers; see\n[`erlang:start_timer/3,4`](`erlang:start_timer/4`). Most time-out tasks\ncan be performed with the time-out features in `m:gen_statem`,\nbut an example of one that cannot is if you should need the return value\nfrom [`erlang:cancel_timer(Tref)`](`erlang:cancel_timer/2`), that is,\nthe remaining time of the timer.\n\nHere is how to accomplish the _state time-out_ in the previous example\nby instead using an Erlang Timer:\n\n```erlang\n...\nlocked(\n cast, {button,Button},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n...\n if\n NewButtons =:= Code -> % Correct\n\t do_unlock(),\n\t Tref =\n erlang:start_timer(\n 10_000, self(), lock), % Time in milliseconds\n {next_state, open, Data#{buttons := [], timer => Tref}};\n...\n\nopen(info, {timeout,Tref,lock}, #{timer := Tref} = Data) ->\n do_lock(),\n {next_state,locked,maps:remove(timer, Data)};\nopen(cast, {button,_}, Data) ->\n {keep_state,Data};\n...\n```\n\nRemoving the `timer` key from the map when we do a _state change_ to `locked`\nis not strictly necessary since we can only get into state `open`\nwith an updated `timer` map value. But it can be nice to not have\noutdated values in the state `Data`.\n\nIf you need to cancel a timer because of some other event, you can use\n[`erlang:cancel_timer(Tref)`](`erlang:cancel_timer/2`). Note that no time-out\nmessage will arrive after this (because the timer has been\nexplicitly canceled), unless you have already postponed one earlier\n(see the next section), so ensure that you do not accidentally\npostpone such messages. Also note that a time-out message may arrive\nduring a _state callback_ that is canceling the timer, so you may have to\nread out such a message from the process mailbox, depending on\nthe return value from [`erlang:cancel_timer(Tref)`](`erlang:cancel_timer/2`).\n\nAnother way to handle a late time-out can be to not cancel it, but to ignore it\nif it arrives in a state where it is known to be late.\n\nPostponing Events\n-----------------\n\nIf you want to ignore a particular event in the current state and handle it\nin a future state, you can postpone the event. A postponed event\nis retried after a _state change_, that is, `OldState =/= NewState`.\n\nPostponing is ordered by the\n[_transition action_](#transition-actions) `postpone`.\n\nIn this example, instead of ignoring button events while in the `open` state,\nwe can postpone them handle them later in the `locked` state:\n\n```erlang\n...\nopen(cast, {button,_}, Data) ->\n {keep_state,Data,[postpone]};\n...\n```\n\nSince a postponed event is only retried after a _state change_, you have to\nthink about where to keep a state data item. You can keep it in the server\n`Data` or in the `State` itself, for example by having two more or less\nidentical states to keep a boolean value, or by using a complex state (see\nsection [_Complex State_](#complex-state)) with\n[_callback mode_](#callback-modes)\n[`handle_event_function`](`t:gen_statem:callback_mode/0`). If a change\nin the value changes the set of events that is handled, the value\nshould be in the State. Otherwise no postponed events will be retried\nsince only the server `Data` changes.\n\nThis is important if events are postponed. But remember that an incorrect\ndesign decision of what belongs in the state, may become a hard to find bug\nsome time later, when event postponing is introduced.","title":"Standalone gen_statem - gen_statem Behaviour","ref":"statem.html#standalone-gen_statem"},{"type":"extras","doc":"It is not uncommon that a state diagram does not specify how to handle events\nthat are not illustrated in a particular state in the diagram.\nHopefully this is described in an associated text or from the context.\n\nPossible actions: ignore as in drop the event (maybe log it) or deal with\nthe event in some other state as in postpone it.","title":"Fuzzy State Diagrams - gen_statem Behaviour","ref":"statem.html#fuzzy-state-diagrams"},{"type":"extras","doc":"Erlang's selective `receive` statement is often used to describe simple state\nmachine examples in straightforward Erlang code. The following is a possible\nimplementation of the first example:\n\n```erlang\n-module(code_lock).\n-define(NAME, code_lock_1).\n-export([start_link/1,button/1]).\n\nstart_link(Code) ->\n spawn(\n fun () ->\n\t true = register(?NAME, self()),\n\t do_lock(),\n\t locked(Code, length(Code), [])\n end).\n\nbutton(Button) ->\n ?NAME ! {button,Button}.\n```\n\n```erlang\nlocked(Code, Length, Buttons) ->\n receive\n {button,Button} ->\n NewButtons =\n if\n length(Buttons) \n Buttons;\n true ->\n tl(Buttons)\n end ++ [Button],\n if\n NewButtons =:= Code -> % Correct\n do_unlock(),\n\t\t open(Code, Length);\n true -> % Incomplete | Incorrect\n locked(Code, Length, NewButtons)\n end\n end.\n```\n\n```erlang\nopen(Code, Length) ->\n receive\n after 10_000 -> % Time in milliseconds\n\t do_lock(),\n\t locked(Code, Length, [])\n end.\n\ndo_lock() ->\n io:format(\"Locked~n\", []).\ndo_unlock() ->\n io:format(\"Open~n\", []).\n```\n\nThe selective receive in this case causes `open` to implicitly postpone any\nevents to the `locked` state.\n\nA catch-all receive should never be used from a `gen_statem` behaviour\n(or from any `gen_*` behaviour), as the receive statement is within\nthe `gen_*` engine itself. `m:sys`-compatible behaviours must respond to\nsystem messages and therefore do that in their engine receive loop,\npassing non-system messages to the _callback module_. Using a catch-all\nreceive can result in system messages being discarded, which in turn\ncan lead to unexpected behaviour. If a selective receive must be used,\ngreat care should be taken to ensure that only messages pertinent\nto the operation are received. Likewise, a callback must return\nin due time to let the engine receive loop handle system messages,\nor they might time out, also leading to unexpected behaviour.\n\nThe [_transition action_](#transition-actions) `postpone` is\ndesigned to model selective receives. A selective receive implicitly\npostpones any events not yet received, but the `postpone` _transition\naction_ explicitly postpones a single received event.\n\nBoth mechanisms have the same theoretical time and memory complexity,\nbut note that the selective receive language construct has smaller\nconstant factors.\n\nState Enter Actions\n-------------------\n\nSay you have a state machine specification that uses state enter actions.\nAlthough you can code this using inserted events (described in the next\nsection), especially if only one or a few states have state enter actions,\nthis is a perfect use case for the built in\n[_state enter calls_](#state-enter-calls).\n\nYou return a list containing `state_enter` from your\n[`callback_mode/0`](`c:gen_statem:callback_mode/0`) function and the\n`gen_statem` engine will call your _state callback_ once with an event\n`(enter, OldState, ...)` whenever it does a _state change_. Then you\njust need to handle these event-like calls in all states.\n\n```erlang\n...\ninit(Code) ->\n process_flag(trap_exit, true),\n Data = #{code => Code, length = length(Code)},\n {ok, locked, Data}.\n\ncallback_mode() ->\n [state_functions,state_enter].\n\nlocked(enter, _OldState, Data) ->\n do_lock(),\n {keep_state,Data#{buttons => []}};\nlocked(\n cast, {button,Button},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n...\n if\n NewButtons =:= Code -> % Correct\n {next_state, open, Data};\n...\n\nopen(enter, _OldState, _Data) ->\n do_unlock(),\n {keep_state_and_data,\n [{state_timeout,10_000,lock}]}; % Time in milliseconds\nopen(state_timeout, lock, Data) ->\n {next_state, locked, Data};\n...\n```\n\nYou can repeat the state enter code by returning one of\n`{repeat_state, ...}`,`{repeat_state_and_data, _}`,\nor `repeat_state_and_data` that otherwise behaves exactly like their\n`keep_state` siblings. See the type\n[`state_callback_result()`](`t:gen_statem:state_callback_result/2`)\nin the Reference Manual.\n\nInserted Events\n---------------\n\nIt can sometimes be beneficial to be able to generate events to your own\nstate machine. This can be done with the\n[_transition action_](#transition-actions)\n[`{next_event, EventType, EventContent}`](`t:gen_statem:action/0`).\n\nYou can generate events of any existing [type](`t:gen_statem:action/0`),\nbut the`internal` type can only be generated through action `next_event`.\nHence, it cannot come from an external source, so you can be certain\nthat an `internal` event is an event from your state machine to itself.\n\nOne example for this is to pre-process incoming data, for example decrypting\nchunks or collecting characters up to a line break.\n\nPurists may argue that this should be modeled with a separate state machine\nthat sends pre-processed events to the main state machine.\n\nHowever, for efficiency's sake, the small pre-processing state machine\ncan be integrated into the common event handling of the main state\nmachine. This integration involves using a few state data items\nto dispatch pre-processed events as internal events to the main state\nmachine.\n\nUsing internal events also can make it easier to synchronize the state\nmachines.\n\nA variant of this is to use a [complex state](#complex-state) with\n[one state callback](#one-state-callback), modeling the state\nwith, for example, a tuple `{MainFSMState, SubFSMState}`.\n\nTo illustrate this we make up an example where the buttons instead generate\ndown and up (press and release) events, and the lock responds\nto an up event only after the corresponding down event.\n\n```erlang\n...\n-export([down/1, up/1]).\n...\ndown(Button) ->\n gen_statem:cast(?NAME, {down,Button}).\n\nup(Button) ->\n gen_statem:cast(?NAME, {up,Button}).\n\n...\n\nlocked(enter, _OldState, Data) ->\n do_lock(),\n {keep_state,Data#{buttons => []}};\nlocked(\n internal, {button,Button},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n...\n```\n\n```erlang\nhandle_common(cast, {down,Button}, Data) ->\n {keep_state, Data#{button => Button}};\nhandle_common(cast, {up,Button}, Data) ->\n case Data of\n #{button := Button} ->\n {keep_state,maps:remove(button, Data),\n [{next_event,internal,{button,Button}}]};\n #{} ->\n keep_state_and_data\n end;\n...\n\nopen(internal, {button,_}, Data) ->\n {keep_state,Data,[postpone]};\n...\n```\n\nIf you start this program with `code_lock:start([17])` you can unlock with\n`code_lock:down(17), code_lock:up(17).`\n\nExample Revisited\n-----------------\n\nThis section includes the example after most of the mentioned modifications\nand some more using _state enter calls_, which deserves a new state diagram:\n\n```mermaid\n---\ntitle: Code Lock State Diagram Revisited\n---\nstateDiagram-v2\n state enter_locked < >\n state enter_open < >\n state check_code < >\n\n [*] --> enter_locked\n\n enter_locked --> locked : * do_lock()\\n* Clear Buttons\n locked --> check_code : {button, Button}\\n* Collect Buttons\n locked --> locked : state_timeout\\n* Clear Buttons\n check_code --> locked : Incorrect code\\n* Set state_timeout 30 s\n check_code --> enter_open : Correct code\n\n enter_open --> open : * do_unlock()\\n* Set state_timeout 10 s\n open --> enter_locked : state_timeout\n```\n\nNotice that this state diagram does not specify how to handle a button event\nin the state `open`. So, you need to read in some side notes, that is, here:\nthat unspecified events shall be postponed (handled in some later state).\nAlso, the state diagram does not show that the `code_length/0` call\nmust be handled in every state.","title":"Selective Receive - gen_statem Behaviour","ref":"statem.html#selective-receive"},{"type":"extras","doc":"Using state functions:\n\n```erlang\n-module(code_lock).\n-behaviour(gen_statem).\n-define(NAME, code_lock_2).\n\n-export([start_link/1,stop/0]).\n-export([down/1,up/1,code_length/0]).\n-export([init/1,callback_mode/0,terminate/3]).\n-export([locked/3,open/3]).\n\nstart_link(Code) ->\n gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).\nstop() ->\n gen_statem:stop(?NAME).\n\ndown(Button) ->\n gen_statem:cast(?NAME, {down,Button}).\nup(Button) ->\n gen_statem:cast(?NAME, {up,Button}).\ncode_length() ->\n gen_statem:call(?NAME, code_length).\n```\n\n```erlang\ninit(Code) ->\n process_flag(trap_exit, true),\n Data = #{code => Code, length => length(Code), buttons => []},\n {ok, locked, Data}.\n\ncallback_mode() ->\n [state_functions,state_enter].\n\n-define(HANDLE_COMMON,\n ?FUNCTION_NAME(T, C, D) -> handle_common(T, C, D)).\n%%\nhandle_common(cast, {down,Button}, Data) ->\n {keep_state, Data#{button => Button}};\nhandle_common(cast, {up,Button}, Data) ->\n case Data of\n #{button := Button} ->\n {keep_state, maps:remove(button, Data),\n [{next_event,internal,{button,Button}}]};\n #{} ->\n keep_state_and_data\n end;\nhandle_common({call,From}, code_length, #{code := Code}) ->\n {keep_state_and_data,\n [{reply,From,length(Code)}]}.\n```\n\n```erlang\nlocked(enter, _OldState, Data) ->\n do_lock(),\n {keep_state, Data#{buttons := []}};\nlocked(state_timeout, button, Data) ->\n {keep_state, Data#{buttons := []}};\nlocked(\n internal, {button,Button},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n NewButtons =\n if\n length(Buttons) \n Buttons;\n true ->\n tl(Buttons)\n end ++ [Button],\n if\n NewButtons =:= Code -> % Correct\n {next_state, open, Data};\n\ttrue -> % Incomplete | Incorrect\n {keep_state, Data#{buttons := NewButtons},\n [{state_timeout,30_000,button}]} % Time in milliseconds\n end;\n?HANDLE_COMMON.\n```\n\n```erlang\nopen(enter, _OldState, _Data) ->\n do_unlock(),\n {keep_state_and_data,\n [{state_timeout,10_000,lock}]}; % Time in milliseconds\nopen(state_timeout, lock, Data) ->\n {next_state, locked, Data};\nopen(internal, {button,_}, _) ->\n {keep_state_and_data, [postpone]};\n?HANDLE_COMMON.\n\ndo_lock() ->\n io:format(\"Locked~n\", []).\ndo_unlock() ->\n io:format(\"Open~n\", []).\n\nterminate(_Reason, State, _Data) ->\n State =/= locked andalso do_lock(),\n ok.\n```","title":"Callback Mode: state_functions - gen_statem Behaviour","ref":"statem.html#callback-mode-state_functions"},{"type":"extras","doc":"This section describes what to change in the example to use one\n`handle_event/4` function. The previously used approach to first branch\ndepending on event does not work that well here because of\nthe _state enter calls_, so this example first branches depending on state:\n\n```erlang\n-export([handle_event/4]).\n```\n\n```erlang\ncallback_mode() ->\n [handle_event_function,state_enter].\n```\n\n```erlang\n%%\n%% State: locked\nhandle_event(enter, _OldState, locked, Data) ->\n do_lock(),\n {keep_state, Data#{buttons := []}};\nhandle_event(state_timeout, button, locked, Data) ->\n {keep_state, Data#{buttons := []}};\nhandle_event(\n internal, {button,Button}, locked,\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n NewButtons =\n if\n length(Buttons) \n Buttons;\n true ->\n tl(Buttons)\n end ++ [Button],\n if\n NewButtons =:= Code -> % Correct\n {next_state, open, Data};\n\ttrue -> % Incomplete | Incorrect\n {keep_state, Data#{buttons := NewButtons},\n [{state_timeout,30_000,button}]} % Time in milliseconds\n end;\n```\n\n```erlang\n%%\n%% State: open\nhandle_event(enter, _OldState, open, _Data) ->\n do_unlock(),\n {keep_state_and_data,\n [{state_timeout,10_000,lock}]}; % Time in milliseconds\nhandle_event(state_timeout, lock, open, Data) ->\n {next_state, locked, Data};\nhandle_event(internal, {button,_}, open, _) ->\n {keep_state_and_data,[postpone]};\n```\n\n```erlang\n%% Common events\nhandle_event(cast, {down,Button}, _State, Data) ->\n {keep_state, Data#{button => Button}};\nhandle_event(cast, {up,Button}, _State, Data) ->\n case Data of\n #{button := Button} ->\n {keep_state, maps:remove(button, Data),\n [{next_event,internal,{button,Button}},\n {state_timeout,30_000,button}]}; % Time in milliseconds\n #{} ->\n keep_state_and_data\n end;\nhandle_event({call,From}, code_length, _State, #{length := Length}) ->\n {keep_state_and_data,\n [{reply,From,Length}]}.\n```\n\nNotice that postponing buttons from the `open` state to the `locked` state\nseems like a strange thing to do for a code lock, but it at least\nillustrates event postponing.\n\nFilter the State\n----------------\n\nThe example servers so far in this chapter print the full internal state\nin the error log, for example, when killed by an exit signal or because of\nan internal error. The state contains both the code lock code\nand which digits that remain to unlock.\n\nThis state data can be regarded as sensitive, and maybe not what you want\nin the error log because of some unpredictable event.\n\nAnother reason to filter the state can be that the state is too large to print,\nas it fills the error log with uninteresting details.\n\nTo avoid this, you can format the internal state that gets in the error log\nand gets returned from [`sys:get_status/1,2`](`sys:get_status/1`)\nby implementing function\n[`Module:format_status/2`](`c:gen_statem:format_status/2`),\nfor example like this:\n\n```erlang\n...\n-export([init/1,terminate/3,format_status/2]).\n...\n\nformat_status(Opt, [_PDict,State,Data]) ->\n StateData =\n\t{State,\n\t maps:filter(\n\t fun (code, _) -> false;\n\t (_, _) -> true\n\t end,\n\t Data)},\n case Opt of\n\tterminate ->\n\t StateData;\n\tnormal ->\n\t [{data,[{\"State\",StateData}]}]\n end.\n```\n\nIt is not mandatory to implement a\n[`Module:format_status/2`](`c:gen_statem:format_status/2`) function.\nIf you do not, a default implementation is used that does the same\nas this example function without filtering the `Data` term, that is,\n`StateData = {State, Data}`, in this example containing sensitive information.\n\nComplex State\n-------------\n\nThe _callback mode_ [`handle_event_function`](`t:gen_statem:callback_mode/0`)\nenables using a non-atom state as described in section\n[_Callback Modes_](#callback-modes), for example, a complex state term\nlike a tuple.\n\nOne reason to use this is when you have a state item that when changed\nshould cancel the [_state time-out_](#state-time-outs), or one that affects\nthe event handling in combination with postponing events. We will go for\nthe latter and complicate the previous example by introducing\na configurable lock button (this is the state item in question),\nwhich in the `open` state immediately locks the door, and an API function\n`set_lock_button/1` to set the lock button.\n\nSuppose now that we call `set_lock_button` while the door is open,\nand we have already postponed a button event that was the new lock button:\n\n```erlang\n1> code_lock:start_link([a,b,c], x).\n{ok,<0.666.0>}\n2> code_lock:button(a).\nok\n3> code_lock:button(b).\nok\n4> code_lock:button(c).\nok\nOpen\n5> code_lock:button(y).\nok\n6> code_lock:set_lock_button(y).\nx\n% What should happen here? Immediate lock or nothing?\n```\n\nWe could say that the button was pressed too early so it should not be\nrecognized as the lock button. Or we can make the lock button part of\nthe state so when we then change the lock button in the locked state,\nthe change becomes a _state change_ and all postponed events are retried,\ntherefore the lock is immediately locked\\!\n\nWe define the state as `{StateName, LockButton}`, where `StateName`\nis as before and `LockButton` is the current lock button:\n\n```erlang\n-module(code_lock).\n-behaviour(gen_statem).\n-define(NAME, code_lock_3).\n\n-export([start_link/2,stop/0]).\n-export([button/1,set_lock_button/1]).\n-export([init/1,callback_mode/0,terminate/3]).\n-export([handle_event/4]).\n\nstart_link(Code, LockButton) ->\n gen_statem:start_link(\n {local,?NAME}, ?MODULE, {Code,LockButton}, []).\nstop() ->\n gen_statem:stop(?NAME).\n\nbutton(Button) ->\n gen_statem:cast(?NAME, {button,Button}).\nset_lock_button(LockButton) ->\n gen_statem:call(?NAME, {set_lock_button,LockButton}).\n```\n\n```erlang\ninit({Code,LockButton}) ->\n process_flag(trap_exit, true),\n Data = #{code => Code, length => length(Code), buttons => []},\n {ok, {locked,LockButton}, Data}.\n\ncallback_mode() ->\n [handle_event_function,state_enter].\n\n%% State: locked\nhandle_event(enter, _OldState, {locked,_}, Data) ->\n do_lock(),\n {keep_state, Data#{buttons := []}};\nhandle_event(state_timeout, button, {locked,_}, Data) ->\n {keep_state, Data#{buttons := []}};\nhandle_event(\n cast, {button,Button}, {locked,LockButton},\n #{code := Code, length := Length, buttons := Buttons} = Data) ->\n NewButtons =\n if\n length(Buttons) \n Buttons;\n true ->\n tl(Buttons)\n end ++ [Button],\n if\n NewButtons =:= Code -> % Correct\n {next_state, {open,LockButton}, Data};\n\ttrue -> % Incomplete | Incorrect\n {keep_state, Data#{buttons := NewButtons},\n [{state_timeout,30_000,button}]} % Time in milliseconds\n end;\n```\n\n```erlang\n%%\n%% State: open\nhandle_event(enter, _OldState, {open,_}, _Data) ->\n do_unlock(),\n {keep_state_and_data,\n [{state_timeout,10_000,lock}]}; % Time in milliseconds\nhandle_event(state_timeout, lock, {open,LockButton}, Data) ->\n {next_state, {locked,LockButton}, Data};\nhandle_event(cast, {button,LockButton}, {open,LockButton}, Data) ->\n {next_state, {locked,LockButton}, Data};\nhandle_event(cast, {button,_}, {open,_}, _Data) ->\n {keep_state_and_data,[postpone]};\n```\n\n```erlang\n%%\n%% Common events\nhandle_event(\n {call,From}, {set_lock_button,NewLockButton},\n {StateName,OldLockButton}, Data) ->\n {next_state, {StateName,NewLockButton}, Data,\n [{reply,From,OldLockButton}]}.\n```\n\n```erlang\ndo_lock() ->\n io:format(\"Locked~n\", []).\ndo_unlock() ->\n io:format(\"Open~n\", []).\n\nterminate(_Reason, State, _Data) ->\n State =/= locked andalso do_lock(),\n ok.\n```\n\nHibernation\n-----------\n\nIf you have many servers in one node and they have some state(s) in their\nlifetime in which the servers can be expected to idle for a while, and the\namount of heap memory all these servers need is a problem, then the memory\nfootprint of a server can be minimized by hibernating it through\n`proc_lib:hibernate/3`.\n\n> #### Note {: .info }\n>\n> It is rather costly to hibernate a process; see `erlang:hibernate/3`. It is\n> not something you want to do after every event.\n\nWe can in this example hibernate in the `{open, _}` state,\nbecause what normally occurs in that state is that the _state time-out_\nafter a while triggers a transition to `{locked, _}`:\n\n```erlang\n...\n%%\n%% State: open\nhandle_event(enter, _OldState, {open,_}, _Data) ->\n do_unlock(),\n {keep_state_and_data,\n [{state_timeout,10_000,lock}, % Time in milliseconds\n hibernate]};\n...\n```\n\nThe atom [`hibernate`](`t:gen_statem:hibernate/0`) in the action list on the\nlast line when entering the `{open, _}` state is the only change. If any event\narrives in the `{open, _},` state, we do not bother to rehibernate,\nso the server stays awake after any event.\n\nTo change that we would need to insert action `hibernate` in more places.\nFor example, the state-independent `set_lock_button` operation\nwould have to use `hibernate` but only in the `{open, _}` state,\nwhich would clutter the code.\n\nAnother not uncommon scenario is to use the\n[_event time-out_](#event-time-outs) to trigger hibernation after a\ncertain time of inactivity. There is also a server start option\n[`{hibernate_after, Timeout}`](`t:gen_statem:enter_loop_opt/0`) for\n[`start/3,4`](`gen_statem:start/3`),\n[`start_link/3,4`](`gen_statem:start_link/3`), or\n[`enter_loop/4,5,6`](`gen_statem:enter_loop/4`) that may be used to\nautomatically hibernate the server.\n\nThis particular server probably does not use heap memory worth hibernating for.\nTo gain anything from hibernation, your server would have to produce\nnon-insignificant garbage during callback execution, for which this example\nserver can serve as a bad example.","title":"Callback Mode: handle_event_function - gen_statem Behaviour","ref":"statem.html#callback-mode-handle_event_function"},{"type":"extras","doc":"\n# gen_event Behaviour\n\n[](){: #gen_event }\n\nIt is recommended to read this section alongside `m:gen_event` in STDLIB.","title":"gen_event Behaviour","ref":"events.html"},{"type":"extras","doc":"In OTP, an _event manager_ is a named object to which events can be sent. An\n_event_ can be, for example, an error, an alarm, or some information that is to\nbe logged.\n\nIn the event manager, zero, one, or many _event handlers_ are installed. When\nthe event manager is notified about an event, the event is processed by all the\ninstalled event handlers. For example, an event manager for handling errors can\nby default have a handler installed that writes error messages to the\nterminal. If the error messages during a certain period are to be saved to a\nfile as well, the user adds another event handler that does this. When logging\nto the file is no longer necessary, this event handler is deleted.\n\nAn event manager is implemented as a process and each event handler is\nimplemented as a callback module.\n\nThe event manager essentially maintains a list of `{Module, State}` pairs, where\neach `Module` is an event handler, and `State` is the internal state of that\nevent handler.","title":"Event Handling Principles - gen_event Behaviour","ref":"events.html#event-handling-principles"},{"type":"extras","doc":"The callback module for the event handler writing error messages to the terminal\ncan look as follows:\n\n```erlang\n-module(terminal_logger).\n-behaviour(gen_event).\n\n-export([init/1, handle_event/2, terminate/2]).\n\ninit(_Args) ->\n {ok, []}.\n\nhandle_event(ErrorMsg, State) ->\n io:format(\"***Error*** ~p~n\", [ErrorMsg]),\n {ok, State}.\n\nterminate(_Args, _State) ->\n ok.\n```\n\nThe callback module for the event handler writing error messages to a file can\nlook as follows:\n\n```erlang\n-module(file_logger).\n-behaviour(gen_event).\n\n-export([init/1, handle_event/2, terminate/2]).\n\ninit(File) ->\n {ok, Fd} = file:open(File, read),\n {ok, Fd}.\n\nhandle_event(ErrorMsg, Fd) ->\n io:format(Fd, \"***Error*** ~p~n\", [ErrorMsg]),\n {ok, Fd}.\n\nterminate(_Args, Fd) ->\n file:close(Fd).\n```\n\nThe code is explained in the next sections.\n\n[](){: #mgr }","title":"Example - gen_event Behaviour","ref":"events.html#example"},{"type":"extras","doc":"To start an event manager for handling errors, as described in the previous\nexample, call the following function:\n\n```text\ngen_event:start_link({local, error_man})\n```\n\n`gen_event:start_link/1` spawns and links to a new event manager process.\n\nThe argument, `{local, error_man}`, specifies the name under which the\nevent manager should be locally registered. The name can also be given\nas `{global, Name}` to register the event manager globally using\n`global:register_name/2`.\n\nIf the name is omitted, the event manager is not registered. Instead its pid\nmust be used.\n\n`gen_event:start_link/1` must be used if the event manager is part of\na supervision tree, meaning that it was started by a supervisor. There\nis another function, `gen_event:start/1`, to start a standalone event\nmanager that is not part of a supervision tree.","title":"Starting an Event Manager - gen_event Behaviour","ref":"events.html#starting-an-event-manager"},{"type":"extras","doc":"The following example shows how to start an event manager and add an event\nhandler to it by using the shell:\n\n```erlang\n1> gen_event:start({local, error_man}).\n{ok,<0.31.0>}\n2> gen_event:add_handler(error_man, terminal_logger, []).\nok\n```\n\nThis function sends a message to the event manager registered as `error_man`,\ntelling it to add the event handler `terminal_logger`. The event manager calls\nthe callback function `terminal_logger:init([])`, where the argument `[]` is the\nthird argument to `add_handler`. `init/1` is expected to return `{ok, State}`,\nwhere `State` is the internal state of the event handler.\n\n```erlang\ninit(_Args) ->\n {ok, []}.\n```\n\nHere, `init/1` does not need any input data and ignores its argument. For\n`terminal_logger`, the internal state is not used. For `file_logger`, the\ninternal state is used to save the open file descriptor.\n\n```erlang\ninit(File) ->\n {ok, Fd} = file:open(File, read),\n {ok, Fd}.\n```","title":"Adding an Event Handler - gen_event Behaviour","ref":"events.html#adding-an-event-handler"},{"type":"extras","doc":"```text\n3> gen_event:notify(error_man, no_reply).\n***Error*** no_reply\nok\n```\n\n`error_man` is the name of the event manager and `no_reply` is the event.\n\nThe event is made into a message and sent to the event manager. When the event\nis received, the event manager calls `handle_event(Event, State)` for each\ninstalled event handler, in the same order as they were added. The function is\nexpected to return a tuple `{ok,State1}`, where `State1` is a new value for the\nstate of the event handler.\n\nIn `terminal_logger`:\n\n```erlang\nhandle_event(ErrorMsg, State) ->\n io:format(\"***Error*** ~p~n\", [ErrorMsg]),\n {ok, State}.\n```\n\nIn `file_logger`:\n\n```erlang\nhandle_event(ErrorMsg, Fd) ->\n io:format(Fd, \"***Error*** ~p~n\", [ErrorMsg]),\n {ok, Fd}.\n```","title":"Notifying about Events - gen_event Behaviour","ref":"events.html#notifying-about-events"},{"type":"extras","doc":"```erlang\n4> gen_event:delete_handler(error_man, terminal_logger, []).\nok\n```\n\nThis function sends a message to the event manager registered as `error_man`,\ntelling it to delete the event handler `terminal_logger`. The event manager\ncalls the callback function `terminal_logger:terminate([], State)`, where the\nargument `[]` is the third argument to `delete_handler`. `terminate/2` is to be\nthe opposite of `init/1` and do any necessary cleaning up. Its return value is\nignored.\n\nFor `terminal_logger`, no cleaning up is necessary:\n\n```erlang\nterminate(_Args, _State) ->\n ok.\n```\n\nFor `file_logger`, the file descriptor opened in `init` must be closed:\n\n```erlang\nterminate(_Args, Fd) ->\n file:close(Fd).\n```","title":"Deleting an Event Handler - gen_event Behaviour","ref":"events.html#deleting-an-event-handler"},{"type":"extras","doc":"When an event manager is stopped, it gives each of the installed event handlers\nthe chance to clean up by calling `terminate/2`, the same way as when deleting a\nhandler.","title":"Stopping - gen_event Behaviour","ref":"events.html#stopping"},{"type":"extras","doc":"If the event manager is part of a supervision tree, no stop function is needed.\nThe event manager is automatically terminated by its supervisor. Exactly how\nthis is done is defined by a [shutdown strategy](sup_princ.md#shutdown) set in\nthe supervisor.","title":"In a Supervision Tree - gen_event Behaviour","ref":"events.html#in-a-supervision-tree"},{"type":"extras","doc":"An event manager can also be stopped by calling:\n\n```erlang\n1> gen_event:stop(error_man).\nok\n```","title":"Standalone Event Managers - gen_event Behaviour","ref":"events.html#standalone-event-managers"},{"type":"extras","doc":"If the `gen_event` process is to be able to receive other messages\nthan events, the callback function `handle_info(Info, State)` must be\nimplemented to handle them. Examples of other messages are exit\nmessages if the event manager is linked to other processes than the\nsupervisor (for example via `gen_event:add_sup_handler/3`) and is\ntrapping exit signals.\n\n```erlang\nhandle_info({'EXIT', Pid, Reason}, State) ->\n %% Code to handle exits here.\n ...\n {noreply, State1}.\n```\n\nThe final function to implement is `code_change/3`:\n\n```erlang\ncode_change(OldVsn, State, Extra) ->\n %% Code to convert state (and more) during code change.\n ...\n {ok, NewState}.\n```","title":"Handling Other Messages - gen_event Behaviour","ref":"events.html#handling-other-messages"},{"type":"extras","doc":"\n# Supervisor Behaviour\n\nIt is recommended to read this section alongside `m:supervisor` in STDLIB.","title":"Supervisor Behaviour","ref":"sup_princ.html"},{"type":"extras","doc":"A supervisor is responsible for starting, stopping, and monitoring its child\nprocesses. The basic idea of a supervisor is that it is to keep its child\nprocesses alive by restarting them when necessary.\n\nWhich child processes to start and monitor is specified by a list of\n[child specifications](sup_princ.md#spec). The child processes are started in\nthe order specified by this list, and are terminated in the reverse order.","title":"Supervision Principles - Supervisor Behaviour","ref":"sup_princ.html#supervision-principles"},{"type":"extras","doc":"The callback module for a supervisor starting the server from\n[gen_server Behaviour](gen_server_concepts.md#ex) can look as follows:\n\n[](){: #ex }\n\n```erlang\n-module(ch_sup).\n-behaviour(supervisor).\n\n-export([start_link/0]).\n-export([init/1]).\n\nstart_link() ->\n supervisor:start_link(ch_sup, []).\n\ninit(_Args) ->\n SupFlags = #{strategy => one_for_one, intensity => 1, period => 5},\n ChildSpecs = [#{id => ch3,\n start => {ch3, start_link, []},\n restart => permanent,\n shutdown => brutal_kill,\n type => worker,\n modules => [ch3]}],\n {ok, {SupFlags, ChildSpecs}}.\n```\n\nThe `SupFlags` variable in the return value from `init/1` represents the\n[supervisor flags](sup_princ.md#flags).\n\nThe `ChildSpecs` variable in the return value from `init/1` is a list of\n[child specifications](sup_princ.md#spec).\n\n[](){: #flags }","title":"Example - Supervisor Behaviour","ref":"sup_princ.html#example"},{"type":"extras","doc":"This is the type definition for the supervisor flags:\n\n```erlang\nsup_flags() = #{strategy => strategy(), % optional\n intensity => non_neg_integer(), % optional\n period => pos_integer(), % optional\n auto_shutdown => auto_shutdown()} % optional\n strategy() = one_for_all\n | one_for_one\n | rest_for_one\n | simple_one_for_one\n auto_shutdown() = never\n | any_significant\n | all_significant\n```\n\n- `strategy` specifies the [restart strategy](sup_princ.md#strategy).\n- `intensity` and `period` specify the\n [maximum restart intensity](sup_princ.md#max_intensity).\n- `auto_shutdown` specifies whether and when a supervisor should\n [automatically shut itself down](sup_princ.md#automatic-shutdown).\n\n[](){: #strategy }","title":"Supervisor Flags - Supervisor Behaviour","ref":"sup_princ.html#supervisor-flags"},{"type":"extras","doc":"The restart strategy is specified by the `strategy` key in the supervisor flags\nmap returned by the callback function `init`:\n\n```text\nSupFlags = #{strategy => Strategy, ...}\n```\n\nThe `strategy` key is optional in this map. If it is not given, it defaults to\n`one_for_one`.\n\n> #### Note {: .info }\n>\n> For simplicity, the diagrams shown in this section display a setup where all\n> the depicted children are assumed to have a\n> [restart type](sup_princ.md#restart) of `permanent`.","title":"Restart Strategy - Supervisor Behaviour","ref":"sup_princ.html#restart-strategy"},{"type":"extras","doc":"If a child process terminates, only that process is restarted.\n\n```mermaid\n---\ntitle: One For One Supervision\n---\nflowchart TD\n subgraph Legend\n direction LR\n t(( )) ~~~ l1[Terminated Process]\n p(( )) ~~~ l2[Process Restarted by the Supervisor]\n end\n\n subgraph graph[\" \"]\n s[Supervisor]\n s --- p1((P1))\n s --- p2((P2))\n s --- p3((P3))\n s --- pn((Pn))\n end\n\n classDef term fill:#ff8888,color:black;\n classDef restarted stroke:#00aa00,stroke-width:3px;\n classDef legend fill-opacity:0,stroke-width:0px;\n\n class p2,t term;\n class p2,p restarted;\n class l1,l2 legend;\n```","title":"one_for_one - Supervisor Behaviour","ref":"sup_princ.html#one_for_one"},{"type":"extras","doc":"If a child process terminates, all remaining child processes are\nterminated. Subsequently, all child processes, including the\nterminated one, are restarted.\n\n```mermaid\n---\ntitle: One For All Supervision\n---\nflowchart TD\n subgraph Legend\n direction LR\n t(( )) ~~~ l1[Terminated Process]\n st(( )) ~~~ l2[Process Terminated by the Supervisor]\n p(( )) ~~~ l3[Process Restarted by the Supervisor]\n l4[\"Note:\n\n Processes are terminated right to left\n Processes are restarted left to right\"]\n\n end\n\n subgraph graph[\" \"]\n s[Supervisor]\n s --- p1((P1))\n s --- p2((P2))\n s --- p3((P3))\n s --- pn((Pn))\n end\n\n classDef term fill:#ff8888,color:black;\n classDef sterm fill:#ffaa00,color:black;\n classDef restarted stroke:#00aa00,stroke-width:3px;\n classDef legend fill-opacity:0,stroke-width:0px;\n\n class p2,t term;\n class p1,p3,pn,st sterm;\n class p1,p2,p3,pn,p restarted;\n class l1,l2,l3,l4 legend;\n```","title":"one_for_all - Supervisor Behaviour","ref":"sup_princ.html#one_for_all"},{"type":"extras","doc":"If a child process terminates, the child processes after the\nterminated process in start order are terminated. Subsequently, the\nterminated child process and the remaining child processes are\nrestarted.\n\n\n```mermaid\n---\ntitle: Rest For One Supervision\n---\nflowchart TD\n subgraph Legend\n direction LR\n t(( )) ~~~ l1[Terminated Process]\n st(( )) ~~~ l2[Process Terminated by the Supervisor]\n p(( )) ~~~ l3[Process Restarted by the Supervisor]\n l4[\"Note:\n\n Processes are terminated right to left\n Processes are restarted left to right\"]\n\n end\n\n subgraph graph[\" \"]\n s[Supervisor]\n s --- p1((P1))\n s --- p2((P2))\n s --- p3((P3))\n s --- pn((Pn))\n end\n\n classDef term fill:#ff8888,color:black;\n classDef sterm fill:#ffaa00,color:black;\n classDef restarted stroke:#00aa00,stroke-width:3px;\n classDef legend fill-opacity:0,stroke-width:0px;\n\n class p2,t term;\n class p3,pn,st sterm;\n class p2,p3,pn,p restarted;\n class l1,l2,l3,l4 legend;\n```","title":"rest_for_one - Supervisor Behaviour","ref":"sup_princ.html#rest_for_one"},{"type":"extras","doc":"See [simple-one-for-one supervisors](sup_princ.md#simple).\n\n[](){: #max_intensity }","title":"simple_one_for_one - Supervisor Behaviour","ref":"sup_princ.html#simple_one_for_one"},{"type":"extras","doc":"The supervisors have a built-in mechanism to limit the number of restarts which\ncan occur in a given time interval. This is specified by the two keys\n`intensity` and `period` in the supervisor flags map returned by the callback\nfunction `init`:\n\n```text\nSupFlags = #{intensity => MaxR, period => MaxT, ...}\n```\n\nIf more than `MaxR` number of restarts occur in the last `MaxT` seconds, the\nsupervisor terminates all the child processes and then itself. The termination\nreason for the supervisor itself in that case will be `shutdown`.\n\nWhen the supervisor terminates, then the next higher-level supervisor takes some\naction. It either restarts the terminated supervisor or terminates itself.\n\nThe intention of the restart mechanism is to prevent a situation where a process\nrepeatedly dies for the same reason, only to be restarted again.\n\nThe keys `intensity` and `period` are optional in the supervisor flags map. If\nthey are not given, they default to `1` and `5`, respectively.","title":"Maximum Restart Intensity - Supervisor Behaviour","ref":"sup_princ.html#maximum-restart-intensity"},{"type":"extras","doc":"The default values were chosen to be safe for most systems, even with\ndeep supervision hierarchies, but you will probably want to tune the\nsettings for your particular use case.\n\nFirst, the intensity decides how big bursts of restarts you want to tolerate.\nFor example, you might want to accept a burst of at most 5 or 10 attempts, even\nwithin the same second, if it results in a successful restart.\n\nSecond, you need to consider the sustained failure rate, if crashes keep\nhappening but not often enough to make the supervisor give up. If you set\nintensity to 10 and set the period as low as 1, the supervisor will allow child\nprocesses to keep restarting up to 10 times per second, forever, filling your\nlogs with crash reports until someone intervenes manually.\n\nYou should therefore set the period to be long enough that you can accept that\nthe supervisor keeps going at that rate. For example, if an intensity value\nof 5 is chosen, setting the period to 30 seconds will give you at\nmost one restart per 6 seconds for any longer period of time, which means that\nyour logs will not fill up too quickly, and you will have a chance to observe the\nfailures and apply a fix.\n\nThese choices depend a lot on your problem domain. If you do not have real time\nmonitoring and ability to fix problems quickly, for example in an embedded\nsystem, you might want to accept at most one restart per minute before the\nsupervisor should give up and escalate to the next level to try to clear the\nerror automatically. On the other hand, if it is more important that you keep\ntrying even at a high failure rate, you might want a sustained rate of as much\nas 1-2 restarts per second.\n\nAvoiding common mistakes:\n\n- Do not forget to consider the burst rate. If you set intensity to 1 and period\n to 6, it gives the same sustained error rate as 5/30 or 10/60, but will not\n allow even 2 restart attempts in quick succession. This is probably not what\n you wanted.\n- Do not set the period to a very high value if you want to tolerate bursts. If\n you set intensity to 5 and period to 3600 (one hour), the supervisor will\n allow a short burst of 5 restarts, but then gives up if it sees another single\n restart almost an hour later. You probably want to regard those crashes as\n separate incidents, so setting the period to 5 or 10 minutes will be more\n reasonable.\n- If your application has multiple levels of supervision, do not set\n the restart intensities to the same values on all levels. Keep in mind that\n the total number of restarts (before the top level supervisor gives up and\n terminates the application) will be the product of the intensity values of all\n the supervisors above the failing child process.\n\n For example, if the top level allows 10 restarts, and the next level also\n allows 10, a crashing child below that level will be restarted 100 times,\n which is probably excessive. Allowing at most 3 restarts for the top level\n supervisor might be a better choice in this case.","title":"Tuning the intensity and period - Supervisor Behaviour","ref":"sup_princ.html#tuning-the-intensity-and-period"},{"type":"extras","doc":"A supervisor can be configured to automatically shut itself down when\n[significant children](sup_princ.md#significant_child) terminate.\n\nThis is useful when a supervisor represents a work unit of cooperating children,\nas opposed to independent workers. When the work unit has finished its work,\nthat is, when any or all significant child processes have terminated, the\nsupervisor should then shut down by terminating all remaining child processes in\nreverse start order according to the respective shutdown specifications, and\nthen itself.\n\nAutomatic shutdown is specified by the `auto_shutdown` key in the supervisor\nflags map returned by the callback function `init`:\n\n```text\nSupFlags = #{auto_shutdown => AutoShutdown, ...}\n```\n\nThe `auto_shutdown` key is optional in this map. If it is not given, it defaults\nto `never`.\n\n> #### Note {: .info }\n>\n> The automatic shutdown facility only applies when significant children\n> terminate by themselves, not when their termination was caused by\n> the supervisor. Specifically, neither the termination of a child as a\n> consequence of a sibling's termination in the `one_for_all` or `rest_for_one`\n> strategies nor the manual termination of a child by\n> `supervisor:terminate_child/2` will trigger an automatic shutdown.","title":"Automatic Shutdown - Supervisor Behaviour","ref":"sup_princ.html#automatic-shutdown"},{"type":"extras","doc":"Automatic shutdown is disabled.\n\nIn this mode, specifying significant children is not accepted. If the\nchild specs returned from `init` contain significant children, the\nsupervisor will refuse to start. Attempts to start significant\nchildren dynamically will be rejected.\n\nThis is the default setting.","title":"never - Supervisor Behaviour","ref":"sup_princ.html#never"},{"type":"extras","doc":"The supervisor will automatically shut itself down when _any_ significant child\nterminates, that is, when a transient significant child terminates normally or\nwhen a temporary significant child terminates normally or abnormally.","title":"any_significant - Supervisor Behaviour","ref":"sup_princ.html#any_significant"},{"type":"extras","doc":"The supervisor will automatically shut itself down when _all_ significant\nchildren have terminated, that is, when the _last active_ significant child\nterminates. The same rules as for `any_significant` apply.\n\n> #### Warning {: .warning }\n>\n> The automatic shutdown feature was introduced in OTP 24.0, but applications\n> using this feature will also compile and run with older OTP versions.\n>\n> However, such applications, when compiled with an OTP version that predates\n> the appearance of the automatic shutdown feature, will leak processes because\n> the automatic shutdowns they rely on will not happen.\n>\n> It is up to implementors to take proper precautions if they expect that their\n> applications may be compiled with older OTP versions.\n\n> #### Warning {: .warning }\n>\n> Top supervisors of [Applications](applications.md) should not be configured\n> for automatic shutdown, because when the top supervisor exits, the application\n> terminates. If the application is `permanent`, all other applications and the\n> runtime system are terminated as well.\n\n> #### Warning {: .warning }\n>\n> Supervisors configured for automatic shutdown should not be made\n> [permanent](sup_princ.md#restart) children of their respective parent\n> supervisors, as they would be restarted immediately after having automatically\n> shut down, only to shut down automatically again after a while, and may thus\n> exhaust the [Maximum Restart Intensity](sup_princ.md#max_intensity) of the\n> parent supervisor.\n\n[](){: #spec }","title":"all_significant - Supervisor Behaviour","ref":"sup_princ.html#all_significant"},{"type":"extras","doc":"The type definition for a child specification is as follows:\n\n```erlang\nchild_spec() = #{id => child_id(), % mandatory\n start => mfargs(), % mandatory\n restart => restart(), % optional\n significant => significant(), % optional\n shutdown => shutdown(), % optional\n type => worker(), % optional\n modules => modules()} % optional\n child_id() = term()\n mfargs() = {M :: module(), F :: atom(), A :: [term()]}\n modules() = [module()] | dynamic\n restart() = permanent | transient | temporary\n significant() = boolean()\n shutdown() = brutal_kill | timeout()\n worker() = worker | supervisor\n```\n\n- `id` is used to identify the child specification internally by the supervisor.\n\n The `id` key is mandatory.\n\n Note that this identifier occasionally has been called \"name\". As far as\n possible, the terms \"identifier\" or \"id\" are now used but in order to keep\n backwards compatibility, some occurrences of \"name\" can still be found, for\n example in error messages.\n\n- `start` defines the function call used to start the child process. It is a\n module-function-arguments tuple used as [`apply(M, F, A)`](`apply/3`).\n\n It is to be (or result in) a call to any of the following:\n\n - [`supervisor:start_link/2,3`](`supervisor:start_link/3`)\n - [`gen_server:start_link/3,4`](`gen_server:start_link/4`)\n - [`gen_statem:start_link/3,4`](`gen_statem:start_link/4`)\n - [`gen_event:start_link/0,1,2`](`gen_event:start_link/2`)\n - A function compliant with these functions. For details, see\n `m:supervisor`.\n\n The `start` key is mandatory.\n\n- [](){: #restart } `restart` defines when a terminated child process is to be\n restarted.\n\n - A `permanent` child process is always restarted.\n - A `temporary` child process is never restarted (not even when the supervisor\n restart strategy is `rest_for_one` or `one_for_all` and a sibling death\n causes the temporary process to be terminated).\n - A `transient` child process is restarted only if it terminates abnormally,\n that is, with an exit reason other than `normal`, `shutdown`, or\n `{shutdown,Term}`.\n\n The `restart` key is optional. If it is not given, the default value\n `permanent` will be used.\n\n- [](){: #significant_child } `significant` defines whether a child is considered\n significant for [automatic self-shutdown](sup_princ.md#automatic-shutdown) of\n the supervisor.\n\n It is invalid to set this option to `true` for a child with\n [restart type](sup_princ.md#restart) `permanent` or in a supervisor with\n [auto_shutdown](sup_princ.md#automatic-shutdown) set to `never`.\n\n- [](){: #shutdown } `shutdown` defines how a child process is to be terminated.\n\n - `brutal_kill` means that the child process is unconditionally terminated\n using [`exit(Child, kill)`](`exit/2`).\n - An integer time-out value means that the supervisor tells the child process\n to terminate by calling [`exit(Child, shutdown)`](`exit/2`) and then waits\n for an exit signal back. If no exit signal is received within the specified\n time, the child process is unconditionally terminated using\n [`exit(Child, kill)`](`exit/2`).\n - If the child process is another supervisor, it should be set to `infinity`\n to give the subtree enough time to shut down. It is also allowed to set it\n to `infinity` if the child process is a worker.\n\n > #### Warning {: .warning }\n >\n > Setting the shutdown time to anything other than `infinity` for a child of\n > type `supervisor` can cause a race condition where the child in question\n > unlinks its own children, but fails to terminate them before it is killed.\n >\n > Be careful when setting the shutdown time to `infinity` when the child\n > process is a worker. Because, in this situation, the termination of the\n > supervision tree depends on the child process; it must be implemented in a\n > safe way and its cleanup procedure must always return.\n\n The `shutdown` key is optional. If it is not given, and the child is of type\n `worker`, the default value `5000` will be used; if the child is of type\n `supervisor`, the default value `infinity` will be used.\n\n- `type` specifies whether the child process is a supervisor or a worker.\n\n The `type` key is optional. If it is not given, the default value `worker`\n will be used.\n\n- `modules` has to be a list consisting of a single element. The value\n of that element depends on the behaviour of the process:\n\n * If the child process is a `gen_event`, the element has to be the atom\n `dynamic`.\n * Otherwise, the element should be `Module`, where `Module` is the\n name of the callback module.\n\n This information is used by the release handler during upgrades and\n downgrades; see [Release Handling](release_handling.md).\n\n The `modules` key is optional. If it is not given, it defaults to `[M]`, where\n `M` comes from the child's start `{M,F,A}`.\n\n_Example:_ The child specification to start the server `ch3` in the previous\nexample look as follows:\n\n```erlang\n#{id => ch3,\n start => {ch3, start_link, []},\n restart => permanent,\n shutdown => brutal_kill,\n type => worker,\n modules => [ch3]}\n```\n\nor simplified, relying on the default values:\n\n```text\n#{id => ch3,\n start => {ch3, start_link, []},\n shutdown => brutal_kill}\n```\n\nExample: A child specification to start the event manager from the chapter about\n[gen_event](events.md#mgr):\n\n```erlang\n#{id => error_man,\n start => {gen_event, start_link, [{local, error_man}]},\n modules => dynamic}\n```\n\nBoth server and event manager are registered processes which can be expected to\nbe always accessible. Thus they are specified to be `permanent`.\n\n`ch3` does not need to do any cleaning up before termination. Thus, no shutdown\ntime is needed, but `brutal_kill` is sufficient. `error_man` can need some time\nfor the event handlers to clean up, thus the shutdown time is set to 5000 ms\n(which is the default value).\n\nExample: A child specification to start another supervisor:\n\n```erlang\n#{id => sup,\n start => {sup, start_link, []},\n restart => transient,\n type => supervisor} % will cause default shutdown=>infinity\n```\n\n[](){: #super_tree }","title":"Child Specification - Supervisor Behaviour","ref":"sup_princ.html#child-specification"},{"type":"extras","doc":"In the previous example, the supervisor is started by calling\n`ch_sup:start_link()`:\n\n```erlang\nstart_link() ->\n supervisor:start_link(ch_sup, []).\n```\n\n`ch_sup:start_link` calls function `supervisor:start_link/2`, which spawns and\nlinks to a new process, a supervisor.\n\n- The first argument, `ch_sup`, is the name of the callback module, that is, the\n module where the `init` callback function is located.\n- The second argument, `[]`, is a term that is passed as is to the callback\n function `init`. Here, `init` does not need any data and ignores the argument.\n\nIn this case, the supervisor is not registered. Instead its pid must be used. A\nname can be specified by calling\n[`supervisor:start_link({local, Name}, Module, Args)`](`supervisor:start_link/3`)\nor\n[`supervisor:start_link({global, Name}, Module, Args)`](`supervisor:start_link/3`).\n\nThe new supervisor process calls the callback function `ch_sup:init([])`. `init`\nhas to return `{ok, {SupFlags, ChildSpecs}}`:\n\n```erlang\ninit(_Args) ->\n SupFlags = #{},\n ChildSpecs = [#{id => ch3,\n start => {ch3, start_link, []},\n shutdown => brutal_kill}],\n {ok, {SupFlags, ChildSpecs}}.\n```\n\nSubsequently, the supervisor starts its child processes according to the child\nspecifications in the start specification. In this case there is a single child\nprocess, called `ch3`.\n\n`supervisor:start_link/3` is synchronous. It does not return until all child\nprocesses have been started.","title":"Starting a Supervisor - Supervisor Behaviour","ref":"sup_princ.html#starting-a-supervisor"},{"type":"extras","doc":"In addition to the static supervision tree as defined by the child\nspecifications, dynamic child processes can be added to an existing\nsupervisor by calling [`supervisor:start_child(Sup,\nChildSpec)`](`supervisor:start_child/2`).\n\n`Sup` is the pid, or name, of the supervisor. `ChildSpec` is a\n[child specification](sup_princ.md#spec).\n\nChild processes added using `start_child/2` behave in the same way as the other\nchild processes, with one important exception: if a supervisor dies and is\nrecreated, then all child processes that were dynamically added to the\nsupervisor are lost.","title":"Adding a Child Process - Supervisor Behaviour","ref":"sup_princ.html#adding-a-child-process"},{"type":"extras","doc":"Any child process, static or dynamic, can be stopped in accordance with the\nshutdown specification by calling\n[`supervisor:terminate_child(Sup, Id)`](`supervisor:terminate_child/2`).\n\nStopping a [significant child](sup_princ.md#significant_child) of a supervisor\nconfigured for [automatic shutdown](sup_princ.md#automatic-shutdown) will not\ntrigger an automatic shutdown.\n\nThe child specification for a stopped child process is deleted by\ncalling [`supervisor:delete_child(Sup, Id)`](`supervisor:delete_child/2`).\n\n`Sup` is the pid, or name, of the supervisor. `Id` is the value associated with\nthe `id` key in the [child specification](sup_princ.md#spec).\n\nAs with dynamically added child processes, the effects of deleting a static\nchild process are lost if the supervisor itself restarts.\n\n[](){: #simple }","title":"Stopping a Child Process - Supervisor Behaviour","ref":"sup_princ.html#stopping-a-child-process"},{"type":"extras","doc":"A supervisor with restart strategy `simple_one_for_one` is a simplified\n`one_for_one` supervisor, where all child processes are dynamically added\ninstances of the same process.\n\nThe following is an example of a callback module for a `simple_one_for_one`\nsupervisor:\n\n```erlang\n-module(simple_sup).\n-behaviour(supervisor).\n\n-export([start_link/0]).\n-export([init/1]).\n\nstart_link() ->\n supervisor:start_link(simple_sup, []).\n\ninit(_Args) ->\n SupFlags = #{strategy => simple_one_for_one,\n intensity => 0,\n period => 1},\n ChildSpecs = [#{id => call,\n start => {call, start_link, []},\n shutdown => brutal_kill}],\n {ok, {SupFlags, ChildSpecs}}.\n```\n\nWhen started, the supervisor does not start any child\nprocesses. Instead, all child processes need to be added dynamically by\ncalling [`supervisor:start_child(Sup, List)`](`supervisor:start_child/2`).\n\n`Sup` is the pid, or name, of the supervisor. `List` is an arbitrary list of\nterms, which are added to the list of arguments specified in the child\nspecification. If the start function is specified as `{M, F, A}`, the child\nprocess is started by calling [`apply(M, F, A++List)`](`apply/3`).\n\nFor example, adding a child to `simple_sup` above:\n\n```text\nsupervisor:start_child(Pid, [id1])\n```\n\nThe result is that the child process is started by calling\n[`apply(call, start_link, []++[id1])`](`apply/3`), or actually:\n\n```text\ncall:start_link(id1)\n```\n\nA child under a `simple_one_for_one` supervisor can be terminated with the\nfollowing:\n\n```text\nsupervisor:terminate_child(Sup, Pid)\n```\n\n`Sup` is the pid, or name, of the supervisor and `Pid` is the pid of the child.\n\nBecause a `simple_one_for_one` supervisor can have many children, it shuts them\nall down asynchronously. This means that the children will do their cleanup in\nparallel and therefore the order in which they are stopped is not defined.\n\nStarting, restarting, and manually terminating children are synchronous operations\nwhich are executed in the context of the supervisor process. This means\nthat the supervisor process will be blocked while it is performing any of those\noperations. Child processes are responsible for keeping their start and shutdown\nphases as short as possible.","title":"Simplified one_for_one Supervisors - Supervisor Behaviour","ref":"sup_princ.html#simplified-one_for_one-supervisors"},{"type":"extras","doc":"Since the supervisor is part of a supervision tree, it is\nautomatically terminated by its supervisor. When asked to shut down, a\nsupervisor terminates all child processes in reverse start order\naccording to the respective shutdown specifications before terminating\nitself.\n\nIf the supervisor is configured for\n[automatic shutdown](sup_princ.md#automatic-shutdown) on termination of any or\nall [significant children](sup_princ.md#significant_child), it will shut down\nitself when any or the last active significant child terminates, respectively.\nThe shutdown itself follows the same procedure as described above, that is, the\nsupervisor terminates all remaining child processes in reverse start order\nbefore terminating itself.","title":"Stopping - Supervisor Behaviour","ref":"sup_princ.html#stopping"},{"type":"extras","doc":"For several reasons, a supervisor should not be stopped manually via\n`supervisor:terminate_child/2` from a child located in its own tree.\n\n1. The child process will have to know the pids or registered names not only of\n the supervisor it wants to stop, but also that of the supervisor's parent\n supervisor, in order to tell the parent supervisor to stop the supervisor it\n wants to stop. This can make restructuring a supervision tree difficult.\n1. `supervisor:terminate_child/2` is a blocking call that will only return after\n the parent supervisor has finished the shutdown of the supervisor that should\n be stopped. Unless the call is made from a spawned process, this will result\n in a deadlock, as the supervisor waits for the child to exit as part of its\n shutdown procedure, whereas the child waits for the supervisor to shut down.\n If the child is trapping exits, this deadlock will last until the\n [shutdown](sup_princ.md#shutdown) timeout for the child expires.\n1. When a supervisor is stopping a child, it will wait for the shutdown to\n complete before accepting other calls, that is, the supervisor will be\n unresponsive until then. If the termination takes some time to complete,\n especially when the considerations outlined in the previous point were not\n taken into account carefully, said supervisor might become unresponsive for a\n long time.\n\nInstead, it is generally a better approach to rely on\n[Automatic Shutdown](sup_princ.md#automatic-shutdown).\n\n1. A child process does not need to know anything about its supervisor and its\n respective parent, not even that it is part of a supervision tree in the\n first place. It is instead only the supervisor which hosts the child who must\n know which of its children are [significant](sup_princ.md#significant_child)\n ones, and when to shut itself down.\n1. A child process does not need to do anything special to shut down the work\n unit it is part of. All it needs to do is terminate normally when it has\n finished the task it was started for.\n1. A supervisor that is automatically shutting itself down will perform the\n required shutdown steps fully independent of its parent supervisor. The\n parent supervisor will only notice that its child supervisor has terminated\n in the end. As the parent supervisor is not involved in the shutdown process,\n it will not be blocked.","title":"Manual stopping versus Automatic Shutdown - Supervisor Behaviour","ref":"sup_princ.html#manual-stopping-versus-automatic-shutdown"},{"type":"extras","doc":"\n# sys and proc_lib\n\n[](){: #sys-and-proc_lib }\n\nThe `m:sys` module has functions for simple debugging of processes implemented\nusing behaviours. It also has functions that, together with functions in the\n`proc_lib` module, can be used to implement a _special process_ that complies to\nthe OTP design principles without using a standard behaviour. These functions\ncan also be used to implement user-defined (non-standard) behaviours.\n\nBoth `m:sys` and `m:proc_lib` belong to the STDLIB application.","title":"sys and proc_lib","ref":"spec_proc.html"},{"type":"extras","doc":"The `m:sys` module has functions for simple debugging of processes implemented\nusing behaviours. The `code_lock` example from\n[gen_statem Behaviour](statem.md#example) is used to illustrate this:\n\n```erlang\nErlang/OTP 27 [erts-15.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]\n\nEshell V15.0 (press Ctrl+G to abort, type help(). for help)\n1> code_lock:start_link([1,2,3,4]).\nLock\n{ok,<0.90.0>}\n2> sys:statistics(code_lock, true).\nok\n3> sys:trace(code_lock, true).\nok\n4> code_lock:button(1).\n*DBG* code_lock receive cast {button,1} in state locked\nok\n*DBG* code_lock consume cast {button,1} in state locked\n5> code_lock:button(2).\n*DBG* code_lock receive cast {button,2} in state locked\nok\n*DBG* code_lock consume cast {button,2} in state locked\n6> code_lock:button(3).\n*DBG* code_lock receive cast {button,3} in state locked\nok\n*DBG* code_lock consume cast {button,3} in state locked\n7> code_lock:button(4).\n*DBG* code_lock receive cast {button,4} in state locked\nok\nUnlock\n*DBG* code_lock consume cast {button,4} in state locked => open\n*DBG* code_lock start_timer {state_timeout,10000,lock,[]} in state open\n*DBG* code_lock receive state_timeout lock in state open\nLock\n*DBG* code_lock consume state_timeout lock in state open => locked\n8> sys:statistics(code_lock, get).\n{ok,[{start_time,{{2024,5,3},{8,11,1}}},\n {current_time,{{2024,5,3},{8,11,48}}},\n {reductions,4098},\n {messages_in,5},\n {messages_out,0}]}\n9> sys:statistics(code_lock, false).\nok\n10> sys:trace(code_lock, false).\nok\n11> sys:get_status(code_lock).\n{status,<0.90.0>,\n {module,gen_statem},\n [[{'$initial_call',{code_lock,init,1}},\n {'$ancestors',[<0.88.0>,<0.87.0>,<0.70.0>,<0.65.0>,<0.69.0>,\n <0.64.0>,kernel_sup,<0.47.0>]}],\n running,<0.88.0>,[],\n [{header,\"Status for state machine code_lock\"},\n {data,[{\"Status\",running},\n {\"Parent\",<0.88.0>},\n {\"Modules\",[code_lock]},\n {\"Time-outs\",{0,[]}},\n {\"Logged Events\",[]},\n {\"Postponed\",[]}]},\n {data,[{\"State\",\n {locked,#{code => [1,2,3,4],\n length => 4,buttons => []}}}]}]]}\n```","title":"Simple Debugging - sys and proc_lib","ref":"spec_proc.html#simple-debugging"},{"type":"extras","doc":"This section describes how to write a process that complies to the OTP design\nprinciples, without using a standard behaviour. Such a process is to:\n\n- Be started in a way that makes the process fit into a supervision tree\n- Support the `sys` [debug facilities](spec_proc.md#debug)\n- Take care of [system messages](spec_proc.md#msg).\n\nSystem messages are messages with a special meaning, used in the supervision\ntree. Typical system messages are requests for trace output, and requests to\nsuspend or resume process execution (used during release handling). Processes\nimplemented using standard behaviours automatically understand these messages.","title":"Special Processes - sys and proc_lib","ref":"spec_proc.html#special-processes"},{"type":"extras","doc":"Here follows the simple server from\n[Overview](design_principles.md#ch1),\nimplemented using `sys` and `proc_lib` to fit into a supervision tree:\n\n```erlang\n-module(ch4).\n-export([start_link/0]).\n-export([alloc/0, free/1]).\n-export([init/1]).\n-export([system_continue/3, system_terminate/4,\n write_debug/3,\n system_get_state/1, system_replace_state/2]).\n\nstart_link() ->\n proc_lib:start_link(ch4, init, [self()]).\n\nalloc() ->\n ch4 ! {self(), alloc},\n receive\n {ch4, Res} ->\n Res\n end.\n\nfree(Ch) ->\n ch4 ! {free, Ch},\n ok.\n\ninit(Parent) ->\n register(ch4, self()),\n Chs = channels(),\n Deb = sys:debug_options([]),\n proc_lib:init_ack(Parent, {ok, self()}),\n loop(Chs, Parent, Deb).\n\nloop(Chs, Parent, Deb) ->\n receive\n {From, alloc} ->\n Deb2 = sys:handle_debug(Deb, fun ch4:write_debug/3,\n ch4, {in, alloc, From}),\n {Ch, Chs2} = alloc(Chs),\n From ! {ch4, Ch},\n Deb3 = sys:handle_debug(Deb2, fun ch4:write_debug/3,\n ch4, {out, {ch4, Ch}, From}),\n loop(Chs2, Parent, Deb3);\n {free, Ch} ->\n Deb2 = sys:handle_debug(Deb, fun ch4:write_debug/3,\n ch4, {in, {free, Ch}}),\n Chs2 = free(Ch, Chs),\n loop(Chs2, Parent, Deb2);\n\n {system, From, Request} ->\n sys:handle_system_msg(Request, From, Parent,\n ch4, Deb, Chs)\n end.\n\nsystem_continue(Parent, Deb, Chs) ->\n loop(Chs, Parent, Deb).\n\nsystem_terminate(Reason, _Parent, _Deb, _Chs) ->\n exit(Reason).\n\nsystem_get_state(Chs) ->\n {ok, Chs}.\n\nsystem_replace_state(StateFun, Chs) ->\n NChs = StateFun(Chs),\n {ok, NChs, NChs}.\n\nwrite_debug(Dev, Event, Name) ->\n io:format(Dev, \"~p event = ~p~n\", [Name, Event]).\n```\n\nAs it is not relevant to the example, the channel handling functions have been\nomitted. To compile this example, the\n[implementation of channel handling](design_principles.md#channels-implementation)\nneeds to be added to the module.\n\n{: #ex }\n\nHere is an example showing how the debugging functions in the `sys`\nmodule can be used for `ch4`:\n\n```erlang\n% erl\nErlang/OTP 27 [erts-15.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]\n\nEshell V15.0 (press Ctrl+G to abort, type help(). for help)\n1> ch4:start_link().\n{ok,<0.90.0>}\n2> sys:statistics(ch4, true).\nok\n3> sys:trace(ch4, true).\nok\n4> ch4:alloc().\nch4 event = {in,alloc,<0.88.0>}\nch4 event = {out,{ch4,1},<0.88.0>}\n1\n5> ch4:free(ch1).\nch4 event = {in,{free,ch1}}\nok\n6> sys:statistics(ch4, get).\n{ok,[{start_time,{{2024,5,3},{8,26,13}}},\n {current_time,{{2024,5,3},{8,26,49}}},\n {reductions,202},\n {messages_in,2},\n {messages_out,1}]}\n7> sys:statistics(ch4, false).\nok\n8> sys:trace(ch4, false).\nok\n9> sys:get_status(ch4).\n{status,<0.90.0>,\n {module,ch4},\n [[{'$initial_call',{ch4,init,1}},\n {'$ancestors',[<0.88.0>,<0.87.0>,<0.70.0>,<0.65.0>,<0.69.0>,\n <0.64.0>,kernel_sup,<0.47.0>]}],\n running,<0.88.0>,[],\n {[1],[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19|...]}]}\n```","title":"Example - sys and proc_lib","ref":"spec_proc.html#example"},{"type":"extras","doc":"A function in the `m:proc_lib` module is to be used to start the process. Several\nfunctions are available, for example,\n[`proc_lib:spawn_link/3,4`](`proc_lib:spawn_link/4`)\nfor asynchronous start and\n[`proc_lib:start_link/3,4,5`](`proc_lib:start_link/5`) for synchronous start.\n\nInformation necessary for a process within a supervision tree, such as\ndetails on ancestors and the initial call, is stored when a process\nis started through one of these functions.\n\nIf the process terminates with a reason other than `normal` or `shutdown`, a\ncrash report is generated. For more information about the crash report, see\n[Logging](`e:kernel:logger_chapter.md`) in Kernel User's Guide.\n\nIn the example, synchronous start is used. The process starts by calling\n`ch4:start_link()`:\n\n```erlang\nstart_link() ->\n proc_lib:start_link(ch4, init, [self()]).\n```\n\n`ch4:start_link/0` calls `proc_lib:start_link/3`, which takes a module\nname, a function name, and an argument list as arguments. It then\nspawns a new process and establishes a link. The new process starts\nby executing the given function, here `ch4:init(Pid)`, where `Pid` is\nthe pid of the parent process (obtained by the call to\n[`self()`](`erlang:self/0`) in the call to `proc_lib:start_link/3`).\n\nAll initialization, including name registration, is done in `init/1`. The new\nprocess has to acknowledge that it has been started to the parent:\n\n```erlang\ninit(Parent) ->\n ...\n proc_lib:init_ack(Parent, {ok, self()}),\n loop(...).\n```\n\n`proc_lib:start_link/3` is synchronous and does not return until\n[`proc_lib:init_ack/1,2`](`proc_lib:init_ack/2`) or\n[`proc_lib:init_fail/2,3`](`proc_lib:init_fail/3`) has been called,\nor the process has exited.\n\n[](){: #debug }","title":"Starting the Process - sys and proc_lib","ref":"spec_proc.html#starting-the-process"},{"type":"extras","doc":"To support the debug facilities in `sys`, a _debug structure_ is needed. The\n`Deb` term is initialized using `sys:debug_options/1`:\n\n```erlang\ninit(Parent) ->\n ...\n Deb = sys:debug_options([]),\n ...\n loop(Chs, Parent, Deb).\n```\n\n`sys:debug_options/1` takes a list of options. Given an empty list as in this\nexample means that debugging is initially disabled. For information about the\npossible options, see `m:sys` in STDLIB.\n\nFor each _system event_ to be logged or traced, the following function\nis to be called:\n\n```erlang\nsys:handle_debug(Deb, Func, Info, Event) => Deb1\n```\n\nThe arguments have the follow meaning:\n\n- `Deb` is the debug structure as returned from `sys:debug_options/1`.\n- `Func` is a fun specifying a (user-defined) function used to format trace\n output. For each system event, the format function is called as\n `Func(Dev, Event, Info)`, where:\n - `Dev` is the I/O device to which the output is to be printed. See `m:io`\n in STDLIB.\n - `Event` and `Info` are passed as-is from the call to `sys:handle_debug/4`.\n- `Info` is used to pass more information to `Func`. It can be any term, and it\n is passed as-is.\n- `Event` is the system event. It is up to the user to define what a system\n event is and how it is to be represented. Typically, at least incoming and\n outgoing messages are considered system events and represented by the tuples\n `{in,Msg[,From]}` and `{out,Msg,To[,State]}`, respectively.\n\n`sys:handle_debug/4` returns an updated debug structure `Deb1`.\n\nIn the example, `sys:handle_debug/4` is called for each incoming and\noutgoing message. The format function `Func` is the function\n`ch4:write_debug/3`, which prints the message using `io:format/3`.\n\n```erlang\nloop(Chs, Parent, Deb) ->\n receive\n {From, alloc} ->\n Deb2 = sys:handle_debug(Deb, fun ch4:write_debug/3,\n ch4, {in, alloc, From}),\n {Ch, Chs2} = alloc(Chs),\n From ! {ch4, Ch},\n Deb3 = sys:handle_debug(Deb2, fun ch4:write_debug/3,\n ch4, {out, {ch4, Ch}, From}),\n loop(Chs2, Parent, Deb3);\n {free, Ch} ->\n Deb2 = sys:handle_debug(Deb, fun ch4:write_debug/3,\n ch4, {in, {free, Ch}}),\n Chs2 = free(Ch, Chs),\n loop(Chs2, Parent, Deb2);\n ...\n end.\n\nwrite_debug(Dev, Event, Name) ->\n io:format(Dev, \"~p event = ~p~n\", [Name, Event]).\n```\n\n[](){: #msg }","title":"Debugging - sys and proc_lib","ref":"spec_proc.html#debugging"},{"type":"extras","doc":"_System messages_ are received as:\n\n```text\n{system, From, Request}\n```\n\nThe content and meaning of these messages are not to be interpreted by the\nprocess. Instead the following function is to be called:\n\n```erlang\nsys:handle_system_msg(Request, From, Parent, Module, Deb, State)\n```\n\nThe arguments have the following meaning:\n\n- `Request` and `From` from the received system message are to be\n passed as-is to the call to `sys:handle_system_msg/6`.\n- `Parent` is the pid of the parent process.\n- `Module` is the name of the module implementing the speciall process.\n- `Deb` is the debug structure.\n- `State` is a term describing the internal state and is passed on to\n `Module:system_continue/3`, `Module:system_terminate/4`/\n `Module:system_get_state/1`, and `Module:system_replace_state/2`.\n\n`sys:handle_system_msg/6` does not return. It handles the system\nmessage and *eventually* calls either of the following functions:\n\n* `Module:system_continue(Parent, Deb, State)` - if process execution is to\n continue.\n\n* `Module:system_terminate(Reason, Parent, Deb, State)` - if the\n process is to terminate.\n\nWhile handling the system message, `sys:handle_system_msg/6` can call\none of the following functions:\n\n* `Module:system_get_state(State)` - if the process is to return its state.\n\n* `Module:system_replace_state(StateFun, State)` - if the process is\n to replace its state using the fun `StateFun` fun. See `sys:replace_state/3`\n for more information.\n\n* `system_code_change(Misc, Module, OldVsn, Extra)` - if the process is to\n perform a code change.\n\nA process in a supervision tree is expected to terminate with the same reason as\nits parent.\n\nIn the example, system messages are handed by the following code:\n\n```erlang\nloop(Chs, Parent, Deb) ->\n receive\n ...\n\n {system, From, Request} ->\n sys:handle_system_msg(Request, From, Parent,\n ch4, Deb, Chs)\n end.\n\nsystem_continue(Parent, Deb, Chs) ->\n loop(Chs, Parent, Deb).\n\nsystem_terminate(Reason, Parent, Deb, Chs) ->\n exit(Reason).\n\nsystem_get_state(Chs) ->\n {ok, Chs, Chs}.\n\nsystem_replace_state(StateFun, Chs) ->\n NChs = StateFun(Chs),\n {ok, NChs, NChs}.\n```\n\nIf a special process is configured to trap exits, it must take notice\nof 'EXIT' messages from its parent process and terminate using the\nsame exit reason once the parent process has terminated.\n\nHere is an example:\n\n```erlang\ninit(Parent) ->\n ...,\n process_flag(trap_exit, true),\n ...,\n loop(Parent).\n\nloop(Parent) ->\n receive\n ...\n {'EXIT', Parent, Reason} ->\n %% Clean up here, if needed.\n exit(Reason);\n ...\n end.\n```","title":"Handling System Messages - sys and proc_lib","ref":"spec_proc.html#handling-system-messages"},{"type":"extras","doc":"[](){: #behaviours } To implement a user-defined behaviour, write code similar\nto code for a special process, but call functions in a callback module for\nhandling specific tasks.\n\nIf the compiler is to warn for missing callback functions, as it does for the\nOTP behaviours, add `-callback` attributes in the behaviour module to describe\nthe expected callbacks:\n\n```text\n-callback Name1(Arg1_1, Arg1_2, ..., Arg1_N1) -> Res1.\n-callback Name2(Arg2_1, Arg2_2, ..., Arg2_N2) -> Res2.\n...\n-callback NameM(ArgM_1, ArgM_2, ..., ArgM_NM) -> ResM.\n```\n\n`NameX` are the names of the expected callbacks. `ArgX_Y` and `ResX` are types\nas they are described in\n[Types and Function Specifications](`e:system:typespec.md`). The whole syntax of\nthe `-spec` attribute is supported by the `-callback` attribute.\n\nCallback functions that are optional for the user of the behaviour to implement\nare specified by use of the `-optional_callbacks` attribute:\n\n```text\n-optional_callbacks([OptName1/OptArity1, ..., OptNameK/OptArityK]).\n```\n\nwhere each `OptName/OptArity` specifies the name and arity of a callback\nfunction. Note that the `-optional_callbacks` attribute is to be used together\nwith the `-callback` attribute; it cannot be combined with the\n`behaviour_info()` function described below.\n\nTools that need to know about optional callback functions can call\n`Behaviour:behaviour_info(optional_callbacks)` to get a list of all optional\ncallback functions.\n\n> #### Note {: .info }\n>\n> We recommend using the `-callback` attribute rather than the\n> `behaviour_info()` function. The reason is that the extra type information can\n> be used by tools to produce documentation or find discrepancies.\n\nAs an alternative to the `-callback` and `-optional_callbacks` attributes you\nmay directly implement and export `behaviour_info()`:\n\n```erlang\nbehaviour_info(callbacks) ->\n [{Name1, Arity1},...,{NameN, ArityN}].\n```\n\nwhere each `{Name, Arity}` specifies the name and arity of a callback function.\nThis function is otherwise automatically generated by the compiler using the\n`-callback` attributes.\n\nWhen the compiler encounters the module attribute `-behaviour(Behaviour).` in a\nmodule `Mod`, it calls `Behaviour:behaviour_info(callbacks)` and compares the\nresult with the set of functions actually exported from `Mod`, and issues a\nwarning if any callback function is missing.\n\n_Example:_\n\n```erlang\n%% User-defined behaviour module\n-module(simple_server).\n-export([start_link/2, init/3, ...]).\n\n-callback init(State :: term()) -> 'ok'.\n-callback handle_req(Req :: term(), State :: term()) -> {'ok', Reply :: term()}.\n-callback terminate() -> 'ok'.\n-callback format_state(State :: term()) -> term().\n\n-optional_callbacks([format_state/1]).\n\n%% Alternatively you may define:\n%%\n%% -export([behaviour_info/1]).\n%% behaviour_info(callbacks) ->\n%% [{init,1},\n%% {handle_req,2},\n%% {terminate,0}].\n\nstart_link(Name, Module) ->\n proc_lib:start_link(?MODULE, init, [self(), Name, Module]).\n\ninit(Parent, Name, Module) ->\n register(Name, self()),\n ...,\n Dbg = sys:debug_options([]),\n proc_lib:init_ack(Parent, {ok, self()}),\n loop(Parent, Module, Deb, ...).\n\n...\n```\n\nIn a callback module:\n\n```erlang\n-module(db).\n-behaviour(simple_server).\n\n-export([init/1, handle_req/2, terminate/0]).\n\n...\n```\n\nThe contracts specified with `-callback` attributes in behaviour modules can be\nfurther refined by adding `-spec` attributes in callback modules. This can be\nuseful as `-callback` contracts are usually generic. The same callback module\nwith contracts for the callbacks:\n\n```erlang\n-module(db).\n-behaviour(simple_server).\n\n-export([init/1, handle_req/2, terminate/0]).\n\n-record(state, {field1 :: [atom()], field2 :: integer()}).\n\n-type state() :: #state{}.\n-type request() :: {'store', term(), term()};\n {'lookup', term()}.\n\n...\n\n-spec handle_req(request(), state()) -> {'ok', term()}.\n\n...\n```\n\nEach `-spec` contract is to be a subtype of the respective `-callback` contract.","title":"User-Defined Behaviours - sys and proc_lib","ref":"spec_proc.html#user-defined-behaviours"},{"type":"extras","doc":"\n# Applications\n\n[](){: #appl }\n\nIt is recommended to read this section alongside [`app`](`e:kernel:app.md`)\nand `m:application` in Kernel.","title":"Applications","ref":"applications.html"},{"type":"extras","doc":"After creating code to implement a specific functionality, you might\nconsider transforming it into an *application* — a component that can be\nstarted and stopped as a unit, as well as reused in other systems.\n\nThe steps to create an application is as follows:\n\n* Create an [application callback\n module](applications.md#callback_module) that describes how the\n application is to be started and stopped.\n\n* Create an _application specification_ and place it in an\n [application resource file](applications.md#appl_res_file). Among\n other things, this file specifies which modules the application\n consists of and the name of the callback module.\n\nIf you use `m:systools`, the Erlang/OTP tools for packaging code (see\n[Releases](release_structure.md)), the code for each application is placed in a\nseparate directory following a pre-defined\n[directory structure](applications.md#app_dir).\n\n[](){: #callback_module }","title":"Application Concept - Applications","ref":"applications.html#application-concept"},{"type":"extras","doc":"How to start and stop the code for the application, including its supervision\ntree, is described by two callback functions:\n\n```erlang\nstart(StartType, StartArgs) -> {ok, Pid} | {ok, Pid, State}\nstop(State)\n```\n\n- `start/2` is called when starting the application and is to create the\n supervision tree by starting the top supervisor. It is expected to return the\n pid of the top supervisor and an optional term, `State`, which defaults to\n `[]`. This term is passed as is to `stop/1`.\n- `StartType` is usually the atom `normal`. It has other values only in the case\n of a takeover or failover; see\n [Distributed Applications](distributed_applications.md).\n- `StartArgs` is defined by the key `mod` in the\n [application resource file](applications.md#appl_res_file).\n- `stop/1` is called _after_ the application has been stopped and is to do any\n necessary cleaning up. The actual stopping of the application, that is,\n shutting down the supervision tree, is handled automatically as described in\n [Starting and Stopping Applications](applications.md#stopping).\n\n[](){: #ch_app }\n\nExample of an application callback module for packaging the supervision tree\nfrom [Supervisor Behaviour](sup_princ.md#ex):\n\n```erlang\n-module(ch_app).\n-behaviour(application).\n\n-export([start/2, stop/1]).\n\nstart(_Type, _Args) ->\n ch_sup:start_link().\n\nstop(_State) ->\n ok.\n```\n\nA library application that cannot be started or stopped does not need any\napplication callback module.\n\n[](){: #appl_res_file }","title":"Application Callback Module - Applications","ref":"applications.html#application-callback-module"},{"type":"extras","doc":"To define an application, an _application specification_ is created, which is\nput in an _application resource file_, or in short an `.app` file:\n\n```text\n{application, Application, [Opt1,...,OptN]}.\n```\n\n- `Application`, an atom, is the name of the application. The file must be named\n `Application.app`.\n- Each `Opt` is a tuple `{Key,Value}`, which defines a certain property of the\n application. All keys are optional. Default values are used for any omitted\n keys.\n\nThe contents of a minimal `.app` file for a library application `libapp` looks\nas follows:\n\n```text\n{application, libapp, []}.\n```\n\nThe contents of a minimal `.app` file `ch_app.app` for a supervision tree\napplication like `ch_app` looks as follows:\n\n```text\n{application, ch_app,\n [{mod, {ch_app,[]}}]}.\n```\n\nThe key `mod` defines the callback module and start argument of the application,\nin this case `ch_app` and `[]`, respectively. This means that the following is\ncalled when the application is to be started:\n\n```text\nch_app:start(normal, [])\n```\n\nThe following is called when the application is stopped:\n\n```text\nch_app:stop([])\n```\n\nWhen using `m:systools`, the Erlang/OTP tools for packaging code (see Section\n[Releases](release_structure.md)), the keys `description`, `vsn`, `modules`,\n`registered`, and `applications` are also to be specified:\n\n```erlang\n{application, ch_app,\n [{description, \"Channel allocator\"},\n {vsn, \"1\"},\n {modules, [ch_app, ch_sup, ch3]},\n {registered, [ch3]},\n {applications, [kernel, stdlib, sasl]},\n {mod, {ch_app,[]}}\n ]}.\n```\n\n- `description` - A short description, a string. Defaults to `\"\"`.\n- `vsn` - Version number, a string. Defaults to `\"\"`.\n- `modules` - All modules _introduced_ by this application. `m:systools` uses\n this list when generating boot scripts and tar files. A module must only\n be included in one application. Defaults to `[]`.\n- `registered` - All names of registered processes in the application.\n `m:systools` uses this list to detect name clashes between applications.\n Defaults to `[]`.\n- `applications` - All applications that must be started before this\n application is started. `m:systools` uses this list to generate correct boot\n scripts. Defaults to `[]`. Notice that all applications have dependencies to\n at least Kernel and STDLIB.\n\n> #### Note {: .info }\n>\n> For details about the syntax and contents of the application resource file,\n> see [app](`e:kernel:app.md`) in Kernel.\n\n[](){: #app_dir }","title":"Application Resource File - Applications","ref":"applications.html#application-resource-file"},{"type":"extras","doc":"When packaging code using `m:systools`, the code for each application is placed in\na separate directory, `lib/Application-Vsn`, where `Vsn` is the version number.\n\nThis can be useful to know, even if `m:systools` is not used, since Erlang/OTP is\npackaged according to the OTP principles and thus comes with a specific\ndirectory structure. The code server (see module `m:code` in Kernel)\nautomatically uses code from the directory with the highest version number, if\nmore than one version of an application is present.","title":"Directory Structure - Applications","ref":"applications.html#directory-structure"},{"type":"extras","doc":"Any directory structure for development will suffice as long as the released\ndirectory structure adheres to the\n[description below](applications.md#app_dir_released), but it is encouraged that\nthe same directory structure also be used in a development environment. The\nversion number should be omitted from the application directory name since this\nis an artifact of the release step.\n\nSome sub-directories are _required_. Some sub-directories are _optional_,\nmeaning that it should only be used if the application itself requires it.\nFinally, some sub-directories are _recommended_, meaning it is encouraged that\nit is used and used as described here. For example, both documentation and tests\nare encouraged to exist in an application for it to be deemed a proper OTP\napplication.\n\n```text\n ─ ${application}\n   ├── doc\n │   ├── internal\n │   ├── examples\n │   └── src\n   ├── include\n   ├── priv\n   ├── src\n │   └── ${application}.app.src\n   └── test\n```\n\n- `src` - Required. Contains the Erlang source code, the source of the `.app`\n file and internal include files used by the application itself. Additional\n sub-directories within `src` can be used as namespaces to organize source\n files. These directories should never be deeper than one level.\n- `priv` - Optional. Used for application specific files.\n- `include` - Optional. Used for public include files that must be reachable\n from other applications.\n- `doc` - Recommended. Any source documentation should be placed in\n sub-directories here.\n- `doc/internal` - Recommended. Any documentation that describes implementation\n details about this application, not intended for publication, should be placed\n here.\n- `doc/examples` - Recommended. Source code for examples on how to use this\n application should be placed here. It is encouraged that examples are sourced\n to the public documentation from this directory.\n- `doc/src` - Recommended. All source files for documentation, such as\n Markdown, AsciiDoc, or XML-files, should be placed here.\n- `test` - Recommended. All files regarding tests, such as test suites and test\n specifications, should be placed here.\n\nOther directories in the development environment may be needed. If source code\nfrom languages other than Erlang is used, for instance C-code for NIFs, that\ncode should be placed in a separate directory. By convention it is recommended\nto prefix such directories with the language name, for example `c_src` for C,\n`java_src` for Java or `go_src` for Go. Directories with `_src` suffix indicates\nthat it is a part of the application and the compilation step. The final build\nartifacts should target the `priv/lib` or `priv/bin` directories.\n\nThe `priv` directory holds assets that the application needs during runtime.\nExecutables should reside in `priv/bin` and dynamically-linked libraries should\nreside in `priv/lib`. Other assets are free to reside within the `priv`\ndirectory but it is recommended they do so in a structured manner.\n\nSource files from other languages that generate Erlang code, such as ASN.1 or\nMibs, should be placed in directories, at the top level or in `src`, with the\nsame name as the source language, for example `asn1` and `mibs`. Build artifacts\nshould be placed in their respective language directory, such as `src` for\nErlang code or `java_src` for Java code.\n\nIn a development environment, it is acceptable that the `.app` file for\nthe release resides in the `ebin` directory, but it is recommended that\nit is an artifact of the build step. By convention a `.app.src`\nlocated in the `src` directory is used. This file is nearly identical\nto the `.app` file, but certain fields, such as the application\nversion, are replaced during the build step.\n\nDirectory names should not be capitalized.\n\nIt is encouraged to omit empty directories.\n\n[](){: #app_dir_released }","title":"Directory Structure Guidelines for a Development Environment - Applications","ref":"applications.html#directory-structure-guidelines-for-a-development-environment"},{"type":"extras","doc":"A released application must follow a certain structure.\n\n```text\n ─ ${application}-${version}\n   ├── bin\n   ├── doc\n │   ├── html\n │   ├── man[1-9]\n │   ├── pdf\n │   ├── internal\n │   └── examples\n   ├── ebin\n │   └── ${application}.app\n   ├── include\n   ├── priv\n │   ├── lib\n │   └── bin\n   └── src\n```\n\n- `src` - Optional. Contains the Erlang source code and internal include files\n used by the application itself.\n- `ebin` - Required. Contains the Erlang object code, the `.beam` files. The\n `.app` file must also be placed here.\n- `priv` - Optional. Used for application specific files. `code:priv_dir/1` is\n to be used to access this directory.\n- `priv/lib` - Recommended. Any shared-object files that are used by the\n application, such as NIFs or linked-in-drivers, should be placed here.\n- `priv/bin` - Recommended. Any executable that is used by the application,\n such as port programs, should be placed here.\n- `include` - Optional. Used for public include files that must be reachable\n from other applications.\n- `bin` - Optional. Any executable that is a product of the application, such\n as escripts or shell scripts, should be placed here.\n- `doc` - Optional. Any released documentation should be placed in\n sub-directories here.\n\nThe `src` directory could be useful to release for debugging purposes,\nbut this is not required. The `include` directory should only be\nreleased if the applications has public include files.\n\nIt is encouraged to omit empty directories.\n\n[](){: #application_controller }","title":"Directory Structure for a Released System - Applications","ref":"applications.html#directory-structure-for-a-released-system"},{"type":"extras","doc":"When an Erlang runtime system is started, a number of processes are started as\npart of the Kernel application. One of these processes is the _application\ncontroller_ process, registered as `application_controller`.\n\nAll operations on applications are coordinated by the application\ncontroller. Use module `m:application` in Kernel to load, unload, start, and\nstop applications.","title":"Application Controller - Applications","ref":"applications.html#application-controller"},{"type":"extras","doc":"Before an application can be started, it must be _loaded_. The application\ncontroller reads and stores the information from the `.app` file:\n\n```erlang\n1> application:load(ch_app).\nok\n2> application:loaded_applications().\n[{kernel,\"ERTS CXC 138 10\",\"2.8.1.3\"},\n {stdlib,\"ERTS CXC 138 10\",\"1.11.4.3\"},\n {ch_app,\"Channel allocator\",\"1\"}]\n```\n\nAn application that has been stopped, or has never been started, can be\nunloaded. The information about the application is erased from the internal\ndatabase of the application controller.\n\n```erlang\n3> application:unload(ch_app).\nok\n4> application:loaded_applications().\n[{kernel,\"ERTS CXC 138 10\",\"2.8.1.3\"},\n {stdlib,\"ERTS CXC 138 10\",\"1.11.4.3\"}]\n```\n\n> #### Note {: .info }\n>\n> Loading/unloading an application does not load/unload the code used by the\n> application. Code loading is handled in the usual way by the code server.\n\n[](){: #stopping }","title":"Loading and Unloading Applications - Applications","ref":"applications.html#loading-and-unloading-applications"},{"type":"extras","doc":"An application is started by calling:\n\n```erlang\n5> application:start(ch_app).\nok\n6> application:which_applications().\n[{kernel,\"ERTS CXC 138 10\",\"2.8.1.3\"},\n {stdlib,\"ERTS CXC 138 10\",\"1.11.4.3\"},\n {ch_app,\"Channel allocator\",\"1\"}]\n```\n\nIf the application is not already loaded, the application controller first loads\nit using `application:load/1`. It checks the value of the `applications` key to\nensure that all applications that are to be started before this application are\nrunning.\n\n[](){: #application_master }\n\nFollowing that, the application controller creates an _application master_ for\nthe application.\n\nThe application master establishes itself as the [group\nleader](`erlang:group_leader/0`) of all processes in the application\nand will forward I/O to the previous group leader.\n\n> #### Note {: .info }\n>\n> The purpose of the application master being the group leader is to easily\n> keep track of which processes that belong to the application. That is needed\n> to support the `application:get_application/0` and `application:get_env/1`\n> functions, and also when stopping an application to ensure that all processes\n> belonging to the application are terminated.\n\nThe application master starts the application by calling the application\ncallback function `start/2` in the module with the start argument defined\nby the `mod` key in the `.app` file.\n\nAn application is stopped, but not unloaded, by calling:\n\n```text\n7> application:stop(ch_app).\nok\n```\n\nThe application master stops the application by telling the top supervisor to\nshut down. The top supervisor tells all its child processes to shut down, and so\non; the entire tree is terminated in reversed start order. The application\nmaster then calls the application callback function `stop/1` in the module\ndefined by the `mod` key.","title":"Starting and Stopping Applications - Applications","ref":"applications.html#starting-and-stopping-applications"},{"type":"extras","doc":"An application can be configured using _configuration parameters_. These are a\nlist of `{Par,Val}` tuples specified by a key `env` in the `.app` file:\n\n```erlang\n{application, ch_app,\n [{description, \"Channel allocator\"},\n {vsn, \"1\"},\n {modules, [ch_app, ch_sup, ch3]},\n {registered, [ch3]},\n {applications, [kernel, stdlib, sasl]},\n {mod, {ch_app,[]}},\n {env, [{file, \"/usr/local/log\"}]}\n ]}.\n```\n\n`Par` is to be an atom. `Val` is any term. The application can retrieve the\nvalue of a configuration parameter by calling `application:get_env(App, Par)` or\na number of similar functions. For more information, see module `m:application`\nin Kernel.\n\n_Example:_\n\n```erlang\n% erl\nErlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]\n\nEshell V5.2.3.6 (abort with ^G)\n1> application:start(ch_app).\nok\n2> application:get_env(ch_app, file).\n{ok,\"/usr/local/log\"}\n```\n\nThe values in the `.app` file can be overridden by values in a _system\nconfiguration file_. This is a file that contains configuration parameters for\nrelevant applications:\n\n```erlang\n[{Application1, [{Par11,Val11},...]},\n ...,\n {ApplicationN, [{ParN1,ValN1},...]}].\n```\n\nThe system configuration is to be called `Name.config` and Erlang is to be\nstarted with the command-line argument `-config Name`. For details, see\n[`config`](`e:kernel:config.md`) in Kernel.\n\n_Example:_\n\nA file `test.config` is created with the following contents:\n\n```text\n[{ch_app, [{file, \"testlog\"}]}].\n```\n\nThe value of `file` overrides the value of `file` as defined in the `.app` file:\n\n```erlang\n% erl -config test\nErlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]\n\nEshell V5.2.3.6 (abort with ^G)\n1> application:start(ch_app).\nok\n2> application:get_env(ch_app, file).\n{ok,\"testlog\"}\n```\n\nIf [release handling](release_handling.md#sys) is used, exactly one system\nconfiguration file is to be used and that file is to be called `sys.config`.\n\nThe values in the `.app` file and the values in a system configuration file can\nbe overridden directly from the command line:\n\n```text\n% erl -ApplName Par1 Val1 ... ParN ValN\n```\n\n_Example:_\n\n```erlang\n% erl -ch_app file '\"testlog\"'\nErlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]\n\nEshell V5.2.3.6 (abort with ^G)\n1> application:start(ch_app).\nok\n2> application:get_env(ch_app, file).\n{ok,\"testlog\"}\n```","title":"Configuring an Application - Applications","ref":"applications.html#configuring-an-application"},{"type":"extras","doc":"A _start type_ is defined when starting the application:\n\n```text\napplication:start(Application, Type)\n```\n\n`application:start(Application)` is the same as calling\n`application:start(Application, temporary)`. The type can also be `permanent` or\n`transient`:\n\n- If a permanent application terminates, all other applications and the runtime\n system are also terminated.\n- If a transient application terminates with reason `normal`, this is reported\n but no other applications are terminated. If a transient application\n terminates abnormally, that is with any other reason than `normal`, all other\n applications and the runtime system are also terminated.\n- If a temporary application terminates, this is reported but no other\n applications are terminated.\n\nAn application can always be stopped explicitly by calling `application:stop/1`.\nRegardless of the mode, no other applications are affected.\n\nThe transient mode is of little practical use, since when a supervision tree\nterminates, the reason is set to `shutdown`, not `normal`.","title":"Application Start Types - Applications","ref":"applications.html#application-start-types"},{"type":"extras","doc":"\n# Included Applications\n\n[](){: #included-appl }","title":"Included Applications","ref":"included_applications.html"},{"type":"extras","doc":"An application can _include_ other applications. An _included application_ has\nits own application directory and `.app` file, but it is started as part of the\nsupervisor tree of another application.\n\nAn application can only be included by one other application.\n\nAn included application can include other applications.\n\nAn application that is not included by any other application is called a\n_primary application_.\n\n[](){: #inclappls }\n\n```mermaid\n---\ntitle: Primary Application and Included Applications\n---\nflowchart TD\n prim_app((Primary Application))\n\n subgraph Included Applications\n app1((App))\n app2((App))\n app3((App))\n app4((App))\n app5((App))\n\n subgraph Included Applications\n app11((App))\n end\n subgraph Included Applications\n app31((App))\n app32((App))\n end\n end\n\n prim_app --- app1 --- app11\n prim_app --- app2\n prim_app --- app3\n prim_app --- app4\n prim_app --- app5\n\n app3 --- app31\n app3 --- app32\n```\n\nThe application controller automatically loads any included applications when\nloading a primary application, but does not start them. Instead, the top\nsupervisor of the included application must be started by a supervisor in the\nincluding application.\n\nThis means that when running, an included application is in fact part of the\nprimary application, and a process in an included application considers itself\nbelonging to the primary application.","title":"Introduction - Included Applications","ref":"included_applications.html#introduction"},{"type":"extras","doc":"Which applications to include is defined by the `included_applications` key in\nthe `.app` file:\n\n```erlang\n{application, prim_app,\n [{description, \"Tree application\"},\n {vsn, \"1\"},\n {modules, [prim_app_cb, prim_app_sup, prim_app_server]},\n {registered, [prim_app_server]},\n {included_applications, [incl_app]},\n {applications, [kernel, stdlib, sasl]},\n {mod, {prim_app_cb,[]}},\n {env, [{file, \"/usr/local/log\"}]}\n ]}.\n```","title":"Specifying Included Applications - Included Applications","ref":"included_applications.html#specifying-included-applications"},{"type":"extras","doc":"The supervisor tree of an included application is started as part of the\nsupervisor tree of the including application. If there is a need for\nsynchronization between processes in the including and included applications,\nthis can be achieved by using _start phases_.\n\nStart phases are defined by the `start_phases` key in the `.app` file as a list\nof tuples `{Phase,PhaseArgs}`, where `Phase` is an atom and `PhaseArgs` is a\nterm.\n\nThe value of the `mod` key of the including application must be set to\n`{application_starter,[Module,StartArgs]}`, where `Module` as usual is the\napplication callback module. `StartArgs` is a term provided as argument to the\ncallback function `Module:start/2`:\n\n```erlang\n{application, prim_app,\n [{description, \"Tree application\"},\n {vsn, \"1\"},\n {modules, [prim_app_cb, prim_app_sup, prim_app_server]},\n {registered, [prim_app_server]},\n {included_applications, [incl_app]},\n {start_phases, [{init,[]}, {go,[]}]},\n {applications, [kernel, stdlib, sasl]},\n {mod, {application_starter,[prim_app_cb,[]]}},\n {env, [{file, \"/usr/local/log\"}]}\n ]}.\n\n{application, incl_app,\n [{description, \"Included application\"},\n {vsn, \"1\"},\n {modules, [incl_app_cb, incl_app_sup, incl_app_server]},\n {registered, []},\n {start_phases, [{go,[]}]},\n {applications, [kernel, stdlib, sasl]},\n {mod, {incl_app_cb,[]}}\n ]}.\n```\n\nWhen starting a primary application with included applications, the primary\napplication is started the normal way, that is:\n\n- The application controller creates an application master for the application\n- The application master calls `Module:start(normal, StartArgs)` to start the\n top supervisor.\n\nThen, for the primary application and each included application in top-down,\nleft-to-right order, the application master calls\n`Module:start_phase(Phase, Type, PhaseArgs)` for each phase defined for the\nprimary application, in that order. If a phase is not defined for an included\napplication, the function is not called for this phase and application.\n\nThe following requirements apply to the `.app` file for an included application:\n\n- The `{mod, {Module,StartArgs}}` option must be included. This option is used\n to find the callback module `Module` of the application. `StartArgs` is\n ignored, as `Module:start/2` is called only for the primary application.\n- If the included application itself contains included applications, instead the\n `{mod, {application_starter, [Module,StartArgs]}}` option must be included.\n- The `{start_phases, [{Phase,PhaseArgs}]}` option must be included, and the set\n of specified phases must be a subset of the set of phases specified for the\n primary application.\n\nWhen starting `prim_app` as defined above, the application controller calls the\nfollowing callback functions before `application:start(prim_app)` returns a\nvalue:\n\n```erlang\napplication:start(prim_app)\n => prim_app_cb:start(normal, [])\n => prim_app_cb:start_phase(init, normal, [])\n => prim_app_cb:start_phase(go, normal, [])\n => incl_app_cb:start_phase(go, normal, [])\nok\n```","title":"Synchronizing Processes during Startup - Included Applications","ref":"included_applications.html#synchronizing-processes-during-startup"},{"type":"extras","doc":"\n# Distributed Applications\n\n[](){: #distributed-appl }","title":"Distributed Applications","ref":"distributed_applications.html"},{"type":"extras","doc":"In a distributed system with several Erlang nodes, it can be necessary to\ncontrol applications in a distributed manner. If the node, where a certain\napplication is running, goes down, the application is to be restarted at another\nnode.\n\nSuch an application is called a _distributed application_. Note that it is the\ncontrol of the application that is distributed. All applications can be\ndistributed in the sense that they, for example, use services on other nodes.\n\nSince a distributed application can move between nodes, some addressing\nmechanism is required to ensure that it can be addressed by other applications,\nregardless on which node it currently executes. This issue is not addressed\nhere, but the `m:global` or `m:pg` modules in Kernel can be used for this purpose.","title":"Introduction - Distributed Applications","ref":"distributed_applications.html#introduction"},{"type":"extras","doc":"Distributed applications are controlled by both the application\ncontroller and a distributed application controller process called\n`dist_ac`. Both processes are part of the Kernel application.\nDistributed applications are thus specified by\nconfiguring the Kernel application, using the following configuration\nparameter (see also [Kernel](`e:kernel:kernel_app.md`)):\n\n`distributed = [{Application, [Timeout,] NodeDesc}]`\n\n- Specifies where the application `Application = atom()` can execute.\n- `NodeDesc = [Node | {Node,...,Node}]` is a list of node names in priority\n order. The order between nodes in a tuple is undefined.\n- `Timeout = integer()` specifies how many milliseconds to wait before\n restarting the application at another node. It defaults to 0.\n\nFor distribution of application control to work properly, the nodes where a\ndistributed application can run must contact each other and negotiate where to\nstart the application. This is done using the following configuration parameters\nin Kernel:\n\n- `sync_nodes_mandatory = [Node]` - Specifies which other nodes must be started\n (within the time-out specified by `sync_nodes_timeout`).\n- `sync_nodes_optional = [Node]` - Specifies which other nodes can be started\n (within the time-out specified by `sync_nodes_timeout`).\n- `sync_nodes_timeout = integer() | infinity` - Specifies how many milliseconds\n to wait for the other nodes to start.\n\nWhen started, the node waits for all nodes specified by `sync_nodes_mandatory`\nand `sync_nodes_optional` to come up. When all nodes are up, or when all\nmandatory nodes are up and the time specified by `sync_nodes_timeout` has\nelapsed, all applications start. If not all mandatory nodes are up, the node\nterminates.\n\n_Example:_\n\nAn application `myapp` is to run at the node `cp1@cave`. If this node goes down,\n`myapp` is to be restarted at `cp2@cave` or `cp3@cave`. A system configuration\nfile `cp1.config` for `cp1@cave` can look as follows:\n\n```erlang\n[{kernel,\n [{distributed, [{myapp, 5000, [cp1@cave, {cp2@cave, cp3@cave}]}]},\n {sync_nodes_mandatory, [cp2@cave, cp3@cave]},\n {sync_nodes_timeout, 5000}\n ]\n }\n].\n```\n\nThe system configuration files for `cp2@cave` and `cp3@cave` are identical,\nexcept for the list of mandatory nodes, which is to be `[cp1@cave, cp3@cave]`\nfor `cp2@cave` and `[cp1@cave, cp2@cave]` for `cp3@cave`.\n\n> #### Note {: .info }\n>\n> All involved nodes must have the same value for `distributed` and\n> `sync_nodes_timeout`. Otherwise the system behavior is undefined.","title":"Specifying Distributed Applications - Distributed Applications","ref":"distributed_applications.html#specifying-distributed-applications"},{"type":"extras","doc":"When all involved (mandatory) nodes have been started, the distributed\napplication can be started by calling `application:start(Application)` at _all\nof these nodes._\n\nA boot script (see [Releases](release_structure.md)) can be used that\nautomatically starts the application.\n\nThe application is started at the first operational node that is listed in the\nlist of nodes in the `distributed` configuration parameter. The application is\nstarted as usual. That is, an application master is created and calls the\napplication callback function:\n\n```erlang\nModule:start(normal, StartArgs)\n```\n\nExample:\n\nContinuing the example from the previous section, the three nodes are started,\nspecifying the system configuration file:\n\n```text\n> erl -sname cp1 -config cp1\n> erl -sname cp2 -config cp2\n> erl -sname cp3 -config cp3\n```\n\nWhen all nodes are operational, `myapp` can be started. This is achieved by\ncalling `application:start(myapp)` at all three nodes. It is then started at\n`cp1`, as shown in the following figure:\n\n[](){: #dist1 }\n\n![Application myapp - Situation 1](assets/dist1.gif \"Application myapp - Situation 1\")\n\nSimilarly, the application must be stopped by calling\n`application:stop(Application)` at all involved nodes.","title":"Starting and Stopping Distributed Applications - Distributed Applications","ref":"distributed_applications.html#starting-and-stopping-distributed-applications"},{"type":"extras","doc":"If the node where the application is running goes down, the application is\nrestarted (after the specified time-out) at the first operational node that is\nlisted in the list of nodes in the `distributed` configuration parameter. This\nis called a _failover_.\n\nThe application is started the normal way at the new node, that is, by the\napplication master calling:\n\n```erlang\nModule:start(normal, StartArgs)\n```\n\nAn exception is if the application has the `start_phases` key defined (see\n[Included Applications](included_applications.md)). The application is then\ninstead started by calling:\n\n```erlang\nModule:start({failover, Node}, StartArgs)\n```\n\nHere `Node` is the terminated node.\n\n_Example:_\n\nIf `cp1` goes down, the system checks which one of the other nodes, `cp2` or\n`cp3`, has the least number of running applications, but waits for 5 seconds for\n`cp1` to restart. If `cp1` does not restart and `cp2` runs fewer applications\nthan `cp3`, `myapp` is restarted on `cp2`.\n\n[](){: #dist2 }\n\n![Application myapp - Situation 2](assets/dist2.gif \"Application myapp - Situation 2\")\n\nSuppose now that `cp2` goes also down and does not restart within 5 seconds.\n`myapp` is now restarted on `cp3`.\n\n[](){: #dist3 }\n\n![Application myapp - Situation 3](assets/dist3.gif \"Application myapp - Situation 3\")","title":"Failover - Distributed Applications","ref":"distributed_applications.html#failover"},{"type":"extras","doc":"If a node is started, which has higher priority according to `distributed` than\nthe node where a distributed application is running, the application is\nrestarted at the new node and stopped at the old node. This is called a\n_takeover_.\n\nThe application is started by the application master calling:\n\n```erlang\nModule:start({takeover, Node}, StartArgs)\n```\n\nHere `Node` is the old node.\n\n_Example:_\n\nIf `myapp` is running at `cp3`, and if `cp2` now restarts, it does not restart\n`myapp`, as the order between the `cp2` and `cp3` nodes is undefined.\n\n[](){: #dist4 }\n\n![Application myapp - Situation 4](assets/dist4.gif \"Application myapp - Situation 4\")\n\nHowever, if `cp1` also restarts, the function `application:takeover/2` moves\n`myapp` to `cp1`, as `cp1` has a higher priority than `cp3` for this\napplication. In this case, `Module:start({takeover, cp3@cave}, StartArgs)` is\nexecuted at `cp1` to start the application.\n\n[](){: #dist5 }\n\n![Application myapp - Situation 5](assets/dist5.gif \"Application myapp - Situation 5\")","title":"Takeover - Distributed Applications","ref":"distributed_applications.html#takeover"},{"type":"extras","doc":"\n# Releases\n\n[](){: #releases-section }\n\nIt is recommended to read this section alongside\n[`rel`](`e:sasl:rel.md`), `m:systools`, and\n[`script`](`e:sasl:script.md`) in SASL.","title":"Releases","ref":"release_structure.html"},{"type":"extras","doc":"When you have written one or more applications, you might want to create a\ncomplete system with these applications and a subset of the Erlang/OTP\napplications. This is called a _release_.\n\nTo do this, create a [release resource file](release_structure.md#res_file) that\ndefines which applications are included in the release.\n\nThe release resource file is used to generate\n[boot scripts](release_structure.md#boot) and\n[release packages](release_structure.md#pack). A system that is transferred to\nand installed at another site is called a _target system_. How to use a release\npackage to create a target system is described in\n[Creating and Upgrading a Target System](`e:system:create_target.md`)\nin System Principles.\n\n[](){: #res_file }","title":"Release Concept - Releases","ref":"release_structure.html#release-concept"},{"type":"extras","doc":"To define a release, create a _release resource file_, or in short a `.rel`\nfile. In the file, specify the name and version of the release, which ERTS\nversion it is based on, and which applications it consists of:\n\n```erlang\n{release, {Name,Vsn}, {erts, EVsn},\n [{Application1, AppVsn1},\n ...\n {ApplicationN, AppVsnN}]}.\n```\n\n`Name`, `Vsn`, `EVsn`, and `AppVsn` are strings.\n\nThe file must be named `Rel.rel`, where `Rel` is a unique name.\n\nEach `Application` (atom) and `AppVsn` is the name and version of an application\nincluded in the release. The minimal release based on Erlang/OTP consists of the\nKernel and STDLIB applications, so these applications must be included in the\nlist.\n\nIf the release is to be upgraded, it must also include the SASL application.\n\n[](){: #ch_rel }\n\nHere is an example showing the `.app` file for a release of `ch_app` from\nthe [Applications](applications.md#ch_app) section:\n\n```erlang\n{application, ch_app,\n [{description, \"Channel allocator\"},\n {vsn, \"1\"},\n {modules, [ch_app, ch_sup, ch3]},\n {registered, [ch3]},\n {applications, [kernel, stdlib, sasl]},\n {mod, {ch_app,[]}}\n ]}.\n```\n\nThe `.rel` file must also contain `kernel`, `stdlib`, and `sasl`, as these\napplications are required by `ch_app`. The file is called `ch_rel-1.rel`:\n\n```erlang\n{release,\n {\"ch_rel\", \"A\"},\n {erts, \"14.2.5\"},\n [{kernel, \"9.2.4\"},\n {stdlib, \"5.2.3\"},\n {sasl, \"4.2.1\"},\n {ch_app, \"1\"}]\n}.\n```\n\n[](){: #boot }","title":"Release Resource File - Releases","ref":"release_structure.html#release-resource-file"},{"type":"extras","doc":"`m:systools` in the SASL application includes tools to build and check\nreleases. The functions read the `.rel` and `.app` files and perform\nsyntax and dependency checks. The\n[`systools:make_script/1,2`](`systools:make_script/2`) function is\nused to generate a boot script:\n\n```text\n1> systools:make_script(\"ch_rel-1\", [local]).\nok\n```\n\nThis call creates both the human-readable boot script,\n`ch_rel-1.script`, and the binary boot script, `ch_rel-1.boot`, used\nby the runtime system.\n\n- `\"ch_rel-1\"` is the name of the `.rel` file, minus the extension.\n- `local` is an option that means that the directories where the applications\n are found are used in the boot script, instead of `$ROOT/lib` (`$ROOT` is the\n root directory of the installed release).\n\nThis is a useful way to test a generated boot script locally.\n\nWhen starting Erlang/OTP using the boot script, all applications from the `.rel`\nfile are automatically loaded and started:\n\n```text\n% erl -boot ch_rel-1\nErlang/OTP 26 [erts-14.2.5] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]\n\nEshell V14.2.5 (press Ctrl+G to abort, type help(). for help)\n1> application:which_applications().\n[{ch_app,\"Channel allocator\",\"1\"},\n {sasl,\"SASL CXC 138 11\",\"4.2.1\"},\n {stdlib,\"ERTS CXC 138 10\",\"5.2.3\"},\n {kernel,\"ERTS CXC 138 10\",\"9.2.4\"}]\n```\n\n[](){: #pack }","title":"Generating Boot Scripts - Releases","ref":"release_structure.html#generating-boot-scripts"},{"type":"extras","doc":"The [`systools:make_tar/1,2`](`systools:make_tar/2`) function takes a\n`.rel` file as input and creates a zipped tar file with the code for\nthe specified applications, a _release package_:\n\n```erlang\n1> systools:make_script(\"ch_rel-1\").\nok\n2> systools:make_tar(\"ch_rel-1\").\nok\n```\n\nThe release package by default contains:\n\n- The `.app` files\n- The `.rel` file\n- The object code for all applications, structured according to the\n [application directory structure](applications.md#app_dir)\n- The binary boot script renamed to `start.boot`\n\n```text\n% tar tf ch_rel-1.tar\nlib/kernel-9.2.4/ebin/kernel.app\nlib/kernel-9.2.4/ebin/application.beam\n...\nlib/stdlib-5.2.3/ebin/stdlib.app\nlib/stdlib-5.2.3/ebin/argparse.beam\n...\nlib/sasl-4.2.1/ebin/sasl.app\nlib/sasl-4.2.1/ebin/sasl.beam\n...\nlib/ch_app-1/ebin/ch_app.app\nlib/ch_app-1/ebin/ch_app.beam\nlib/ch_app-1/ebin/ch_sup.beam\nlib/ch_app-1/ebin/ch3.beam\nreleases/ch_rel-1.rel\nreleases/A/ch_rel-1.rel\nreleases/A/start.boot\n```\n\nA new boot script was generated, without the `local` option set, before the\nrelease package was made. In the release package, all application directories\nare placed under `lib`. You do not know where the release package will be\ninstalled, so no hard-coded absolute paths are allowed.\n\nThe release resource file `mysystem.rel` is duplicated in the tar file.\nOriginally, this file was only stored in the `releases` directory to make it\npossible for the `release_handler` to extract this file separately. After\nunpacking the tar file, `release_handler` would automatically copy the file to\n`releases/FIRST`. However, sometimes the tar file is unpacked without involving\nthe `release_handler` (for example, when unpacking the first target system) and\nthe file is therefore now instead duplicated in the tar file so no manual\ncopying is necessary.\n\nIf a `relup` file and/or a system configuration file called `sys.config`, or a\n`sys.config.src`, is found, these files are also included in the release\npackage. See [Release Handling](release_handling.md#req).\n\nOptions can be set to make the release package include source code and the ERTS\nbinary as well.\n\nFor information on how to install the first target system, using a release\npackage, see System Principles. For information on how to install a new release\npackage in an existing system, see [Release Handling](release_handling.md).\n\n[](){: #reldir }","title":"Creating a Release Package - Releases","ref":"release_structure.html#creating-a-release-package"},{"type":"extras","doc":"The directory structure for the code installed by the release handler from a\nrelease package is as follows:\n\n```text\n$ROOT/lib/App1-AVsn1/ebin\n /priv\n /App2-AVsn2/ebin\n /priv\n ...\n /AppN-AVsnN/ebin\n /priv\n /erts-EVsn/bin\n /releases/Vsn\n /bin\n```\n\n- `lib` \\- Application directories\n- `erts-EVsn/bin` \\- Erlang runtime system executables\n- `releases/Vsn` \\- `.rel` file and boot script `start.boot`; if present in the\n release package, `relup` and/or `sys.config` or `sys.config.src`\n- `bin` \\- Top-level Erlang runtime system executables\n\nApplications are not required to be located under directory `$ROOT/lib`. Several\ninstallation directories, which contain different parts of a system, can thus\nexist. For example, the previous example can be extended as follows:\n\n```text\n$SECOND_ROOT/.../SApp1-SAVsn1/ebin\n /priv\n /SApp2-SAVsn2/ebin\n /priv\n ...\n /SAppN-SAVsnN/ebin\n /priv\n\n$THIRD_ROOT/TApp1-TAVsn1/ebin\n /priv\n /TApp2-TAVsn2/ebin\n /priv\n ...\n /TAppN-TAVsnN/ebin\n /priv\n```\n\n`$SECOND_ROOT` and `$THIRD_ROOT` are introduced as `variables` in the call to\nthe `systools:make_script/2` function.","title":"Directory Structure - Releases","ref":"release_structure.html#directory-structure"},{"type":"extras","doc":"If a complete system consists of disk-less and/or read-only client nodes, a\n`clients` directory is to be added to the `$ROOT` directory. A read-only node is\na node with a read-only file system.\n\nThe `clients` directory is to have one subdirectory per supported client node.\nThe name of each client directory is to be the name of the corresponding client\nnode. As a minimum, each client directory is to contain the `bin` and `releases`\nsubdirectories. These directories are used to store information about installed\nreleases and to appoint the current release to the client. The `$ROOT` directory\nthus contains the following:\n\n```text\n$ROOT/...\n /clients/ClientName1/bin\n /releases/Vsn\n /ClientName2/bin\n /releases/Vsn\n ...\n /ClientNameN/bin\n /releases/Vsn\n```\n\nThis structure is to be used if all clients are running the same type of Erlang\nmachine. If there are clients running different types of Erlang machines, or on\ndifferent operating systems, the `clients` directory can be divided into one\nsubdirectory per type of Erlang machine. Alternatively, one `$ROOT` can be set\nup per type of machine. For each type, some of the directories specified for the\n`$ROOT` directory are to be included:\n\n```text\n$ROOT/...\n /clients/Type1/lib\n /erts-EVsn\n /bin\n /ClientName1/bin\n /releases/Vsn\n /ClientName2/bin\n /releases/Vsn\n ...\n /ClientNameN/bin\n /releases/Vsn\n ...\n /TypeN/lib\n /erts-EVsn\n /bin\n ...\n```\n\nWith this structure, the root directory for clients of `Type1` is\n`$ROOT/clients/Type1`.","title":"Disk-Less and/or Read-Only Clients - Releases","ref":"release_structure.html#disk-less-and-or-read-only-clients"},{"type":"extras","doc":"\n# Release Handling\n\n[](){: #release-handling }","title":"Release Handling","ref":"release_handling.html"},{"type":"extras","doc":"An important feature of the Erlang programming language is the ability to change\nmodule code at runtime, _code replacement_, as described in\n[Code Replacement](code_loading.md#code-replacement) in the Erlang Reference\nManual.\n\nBased on this feature, the OTP application SASL provides a framework for\nupgrading and downgrading between different versions of an entire release in\nruntime. This is called _release handling_.\n\nThe framework consists of:\n\n- Offline support - `systools` for generating scripts and building release\n packages\n- Online support - `release_handler` for unpacking and installing release\n packages\n\nThe minimal system based on Erlang/OTP, enabling release handling, thus consists\nof the Kernel, STDLIB, and SASL applications.","title":"Release Handling Principles - Release Handling","ref":"release_handling.html#release-handling-principles"},{"type":"extras","doc":"_Step 1_) A release is created as described in [Releases](release_structure.md).\n\n_Step 2_) The release is transferred to and installed at target environment. For\ninformation of how to install the first target system, see\n[System Principles](`e:system:create_target.md`).\n\n_Step 3_) Modifications, for example, error corrections, are made to the code in\nthe development environment.\n\n_Step 4_) At some point, it is time to make a new version of release. The\nrelevant `.app` files are updated and a new `.rel` file is written.\n\n_Step 5_) For each modified application, an\n[application upgrade file](release_handling.md#appup), `.appup`, is created. In\nthis file, it is described how to upgrade and/or downgrade between the old and\nnew version of the application.\n\n_Step 6_) Based on the `.appup` files, a\n[release upgrade file](release_handling.md#relup) called `relup`, is created.\nThis file describes how to upgrade and/or downgrade between the old and new\nversion of the entire release.\n\n_Step 7_) A new release package is made and transferred to the target system.\n\n_Step 8_) The new release package is unpacked using the release handler.\n\n_Step 9_) The new version of the release is installed, also using the release\nhandler. This is done by evaluating the instructions in `relup`. Modules can be\nadded, deleted, or reloaded, applications can be started, stopped, or restarted,\nand so on. In some cases, it is even necessary to restart the runtime system.\n\n- If the installation fails, the system can be rebooted. The old release version\n is then automatically used.\n- If the installation succeeds, the new version is made the default version,\n which is to now be used if there is a system reboot.","title":"Release Handling Workflow - Release Handling","ref":"release_handling.html#release-handling-workflow"},{"type":"extras","doc":"[Appup Cookbook](appup_cookbook.md), contains examples of `.appup` files for\ntypical cases of upgrades/downgrades that are normally easy to handle in\nruntime. However, many aspects can make release handling complicated, for\nexample:\n\n- Complicated or circular dependencies can make it difficult or even impossible\n to decide in which order things must be done without risking runtime errors\n during an upgrade or downgrade. Dependencies can be:\n\n - Between nodes\n - Between processes\n - Between modules\n\n- During release handling, non-affected processes continue normal execution.\n This can lead to time-outs or other problems. For example, new processes\n created in the time window between suspending processes using a certain\n module, and loading a new version of this module, can execute old code.\n\nIt is thus recommended that code is changed in as small steps as possible, and\nalways kept backwards compatible.\n\n[](){: #req }","title":"Release Handling Aspects - Release Handling","ref":"release_handling.html#release-handling-aspects"},{"type":"extras","doc":"For release handling to work properly, the runtime system must have knowledge\nabout which release it is running. It must also be able to change (in runtime)\nwhich boot script and system configuration file to use if the system is\nrebooted, for example, by `heart` after a failure. Thus, Erlang must be started\nas an embedded system; for information on how to do this, see Embedded System.\n\nFor system reboots to work properly, it is also required that the system is\nstarted with heartbeat monitoring; see [`erl`](`e:erts:erl_cmd.md`)\nin ERTS and module `m:heart` in Kernel.\n\nOther requirements:\n\n- The boot script included in a release package must be generated from the same\n `.rel` file as the release package itself.\n\n Information about applications is fetched from the script when an upgrade or\n downgrade is performed.\n\n- The system must be configured using only one system configuration file, called\n `sys.config`.\n\n If found, this file is automatically included when a release package is\n created.\n\n- All versions of a release, except the first one, must contain a `relup` file.\n\n If found, this file is automatically included when a release package is\n created.","title":"Requirements - Release Handling","ref":"release_handling.html#requirements"},{"type":"extras","doc":"If the system consists of several Erlang nodes, each node can use its own\nversion of the release. The release handler is a locally registered process and\nmust be called at each node where an upgrade or downgrade is required. A release\nhandling instruction, `sync_nodes`, can be used to synchronize the release\nhandler processes at a number of nodes; see [`appup`](`e:sasl:appup`) in SASL.\n\n[](){: #instr }","title":"Distributed Systems - Release Handling","ref":"release_handling.html#distributed-systems"},{"type":"extras","doc":"OTP supports a set of _release handling instructions_ that are used when\ncreating `.appup` files. The release handler understands a subset of these, the\n_low-level_ instructions. To make it easier for the user, there are also a\nnumber of _high-level_ instructions, which are translated to low-level\ninstructions by `systools:make_relup`.\n\nSome of the most frequently used instructions are described in this section. The\ncomplete list of instructions is included in [`appup`](`e:sasl:appup`) in SASL.\n\nFirst, some definitions:\n\n- _Residence module_ - The module where a process has its tail-recursive loop\n function(s). If these functions are implemented in several modules, all those\n modules are residence modules for the process.\n- _Functional module_ - A module that is not a residence module for any\n process.\n\nFor a process implemented using an OTP behaviour, the behaviour module is the\nresidence module for that process. The callback module is a functional module.","title":"Release Handling Instructions - Release Handling","ref":"release_handling.html#release-handling-instructions"},{"type":"extras","doc":"If a simple extension has been made to a functional module, it is sufficient to\nload the new version of the module into the system, and remove the old version.\nThis is called _simple code replacement_ and for this the following instruction\nis used:\n\n```text\n{load_module, Module}\n```","title":"load_module - Release Handling","ref":"release_handling.html#load_module"},{"type":"extras","doc":"If a more complex change has been made, for example, a change to the format of\nthe internal state of a `m:gen_server`, simple code replacement is not sufficient.\nInstead, it is necessary to:\n\n- Suspend the processes using the module (to avoid that they try to handle any\n requests before the code replacement is completed).\n- Ask them to transform the internal state format and switch to the new version\n of the module.\n- Remove the old version.\n- Resume the processes.\n\nThis is called _synchronized code replacement_ and for this the following\ninstructions are used:\n\n```erlang\n{update, Module, {advanced, Extra}}\n{update, Module, supervisor}\n```\n\n`update` with argument `{advanced,Extra}` is used when changing the internal\nstate of a behaviour as described above. It causes behaviour processes to call\nthe callback function `code_change/3`, passing the term `Extra` and some other\ninformation as arguments. See the manual pages for the respective behaviours and\n[Appup Cookbook](appup_cookbook.md#int_state).\n\n`update` with argument `supervisor` is used when changing the start\nspecification of a supervisor. See [Appup Cookbook](appup_cookbook.md#sup).\n\nWhen a module is to be updated, the release handler finds which processes that\nare _using_ the module by traversing the supervision tree of each running\napplication and checking all the child specifications:\n\n```erlang\n{Id, StartFunc, Restart, Shutdown, Type, Modules}\n```\n\nA process uses a module if the name is listed in `Modules` in the child\nspecification for the process.\n\nIf `Modules=dynamic`, which is the case for event managers, the event manager\nprocess informs the release handler about the list of currently installed event\nhandlers (`gen_event`), and it is checked if the module name is in this list\ninstead.\n\nThe release handler suspends, asks for code change, and resumes processes by\ncalling the functions `sys:suspend/1,2`, `sys:change_code/4,5`, and\n`sys:resume/1,2`, respectively.","title":"update - Release Handling","ref":"release_handling.html#update"},{"type":"extras","doc":"If a new module is introduced, the following instruction is used:\n\n```erlang\n{add_module, Module}\n```\n\nThis instruction loads module `Module`. When running Erlang in\nembedded mode it is necessary to use this this instruction. It is not\nstrictly required when running Erlang in interactive mode, since the\ncode server automatically searches for and loads unloaded modules.\n\nThe opposite of `add_module` is `delete_module`, which unloads a module:\n\n```erlang\n{delete_module, Module}\n```\n\nAny process, in any application, with `Module` as residence module, is\nkilled when the instruction is evaluated. Therefore, the user must\nensure that all such processes are terminated before deleting module\n`Module` to avoid a situation with failing supervisor restarts.","title":"add_module and delete_module - Release Handling","ref":"release_handling.html#add_module-and-delete_module"},{"type":"extras","doc":"The following is the instruction for adding an application:\n\n```text\n{add_application, Application}\n```\n\nAdding an application means that the modules defined by the `modules` key in the\n`.app` file are loaded using a number of `add_module` instructions, and then the\napplication is started.\n\nThe following is the instruction for removing an application:\n\n```text\n{remove_application, Application}\n```\n\nRemoving an application means that the application is stopped, the modules are\nunloaded using a number of `delete_module` instructions, and then the\napplication specification is unloaded from the application controller.\n\nThe following is the instruction for restarting an application:\n\n```text\n{restart_application, Application}\n```\n\nRestarting an application means that the application is stopped and then started\nagain similar to using the instructions `remove_application` and\n`add_application` in sequence.","title":"Application Instructions - Release Handling","ref":"release_handling.html#application-instructions"},{"type":"extras","doc":"To call an arbitrary function from the release handler, the following\ninstruction is used:\n\n```text\n{apply, {M, F, A}}\n```\n\nThe release handler evaluates [`apply(M, F, A)`](`apply/3`).\n\n[](){: #restart_new_emulator_instr }","title":"apply (Low-Level) - Release Handling","ref":"release_handling.html#apply-low-level"},{"type":"extras","doc":"This instruction is used when changing to a new version of the runtime\nsystem, or when any of the core applications Kernel, STDLIB, or SASL\nis upgraded. If a system reboot is needed for another reason, the\n`restart_emulator` instruction is to be used instead.\n\nThis instruction requires that the system is started with heartbeat monitoring;\nsee [`erl`](`e:erts:erl_cmd.md`) in ERTS and module `m:heart` in Kernel.\n\nThe `restart_new_emulator` instruction must always be the first instruction in a\nrelup. If the relup is generated by\n[`systools:make_relup/3,4`](`systools:make_relup/4`),\nthis condition is automatically met.\n\nWhen the release handler encounters this instruction, it first generates a\ntemporary boot file that starts the new versions of the runtime system and the\ncore applications, and the old version of all other applications. Then it shuts\ndown the current instance of the runtime system by calling `init:reboot/0`.\nAll processes are terminated gracefully and the system is rebooted by\nthe `heart` program, using the temporary boot file. After the reboot, the rest\nof the relup instructions are executed. This is done as a part of the temporary\nboot script.\n\n> #### Warning {: .warning }\n>\n> This mechanism causes the new versions of the runtime system and core\n> applications to run with the old version of other applications during startup.\n> Thus, take extra care to avoid incompatibility. Incompatible changes in the\n> core applications can in some situations be necessary. If possible, such changes\n> are preceded by deprecation over two major releases before the actual change.\n> To ensure the application is not crashed by an incompatible change, always\n> remove any call to deprecated functions as soon as possible.\n\nAn info report is written when the upgrade is completed. To programmatically\nfind out if the upgrade is complete, call\n[`release_handler:which_releases(current)`](`release_handler:which_releases/1`)\nand check whether it returns the expected (that is, the new) release.\n\nThe new release version must be made permanent when the new runtime system is\noperational. Otherwise, the old version will be used if there is a new system\nreboot.\n\nOn UNIX, the release handler tells the `heart` program which command to use to\nreboot the system. The environment variable `HEART_COMMAND`, normally used by\nthe `heart` program, is ignored in this case. The command instead defaults to\n`$ROOT/bin/start`. Another command can be set by using the SASL configuration\nparameter `start_prg`. For more information, see [SASL](`e:sasl:sasl_app.md`).\n\n[](){: #restart_emulator_instr }","title":"restart_new_emulator (Low-Level) - Release Handling","ref":"release_handling.html#restart_new_emulator-low-level"},{"type":"extras","doc":"This instruction is not related to upgrades of ERTS or any of the core\napplications. It can be used by any application to force a restart of the\nruntime system after all upgrade instructions are executed.\n\nA relup script can only contain one `restart_emulator` instruction, and it must\nalways be placed at the end. If the relup is generated by\n[`systools:make_relup/3,4`](`systools:make_relup/4`),\nthis condition is automatically met.\n\nWhen the release handler encounters this instruction, it shuts down\nthe runtime system by calling `init:reboot/0`. All processes are terminated\ngracefully and the system can then be rebooted by the `heart` program\nusing the new release version. No more upgrade instruction is executed\nafter the restart.\n\n[](){: #appup }","title":"restart_emulator (Low-Level) - Release Handling","ref":"release_handling.html#restart_emulator-low-level"},{"type":"extras","doc":"To define how to upgrade/downgrade between the current version and previous\nversions of an application, an _application upgrade file_, or in short\n`.appup` file is created. The file is to be called `Application.appup`, where\n`Application` is the application name:\n\n```c\n{Vsn,\n [{UpFromVsn1, InstructionsU1},\n ...,\n {UpFromVsnK, InstructionsUK}],\n [{DownToVsn1, InstructionsD1},\n ...,\n {DownToVsnK, InstructionsDK}]}.\n```\n\n- `Vsn`, a string, is the current version of the application, as defined in the\n `.app` file.\n- Each `UpFromVsn` is a previous version of the application to upgrade from.\n- Each `DownToVsn` is a previous version of the application to downgrade to.\n- Each `Instructions` is a list of release handling instructions.\n\n`UpFromVsn` and `DownToVsn` can also be specified as regular expressions. For\nmore information about the syntax and contents of the `.appup` file, see\n[`appup`](`e:sasl:appup.md`) in SASL.\n\n[Appup Cookbook](appup_cookbook.md) includes examples of `.appup` files for\ntypical upgrade/downgrade cases.\n\n_Example:_ Consider the release `ch_rel-1` from\n[Releases](release_structure.md#ch_rel). Assume you want to add a function\n`available/0` to server `ch3`, which returns the number of available channels\n(when trying out the example, make the change in a copy of the original\ndirectory, to ensure that the first version is still available):\n\n```erlang\n-module(ch3).\n-behaviour(gen_server).\n\n-export([start_link/0]).\n-export([alloc/0, free/1]).\n-export([available/0]).\n-export([init/1, handle_call/3, handle_cast/2]).\n\nstart_link() ->\n gen_server:start_link({local, ch3}, ch3, [], []).\n\nalloc() ->\n gen_server:call(ch3, alloc).\n\nfree(Ch) ->\n gen_server:cast(ch3, {free, Ch}).\n\navailable() ->\n gen_server:call(ch3, available).\n\ninit(_Args) ->\n {ok, channels()}.\n\nhandle_call(alloc, _From, Chs) ->\n {Ch, Chs2} = alloc(Chs),\n {reply, Ch, Chs2};\nhandle_call(available, _From, Chs) ->\n N = available(Chs),\n {reply, N, Chs}.\n\nhandle_cast({free, Ch}, Chs) ->\n Chs2 = free(Ch, Chs),\n {noreply, Chs2}.\n```\n\nA new version of the `ch_app.app` file must now be created, where the version is\nupdated:\n\n```erlang\n{application, ch_app,\n [{description, \"Channel allocator\"},\n {vsn, \"2\"},\n {modules, [ch_app, ch_sup, ch3]},\n {registered, [ch3]},\n {applications, [kernel, stdlib, sasl]},\n {mod, {ch_app,[]}}\n ]}.\n```\n\nTo upgrade `ch_app` from `\"1\"` to `\"2\"` (and to downgrade from `\"2\"` to `\"1\"`),\nyou only need to load the new (old) version of the `ch3` callback module. Create\nthe application upgrade file `ch_app.appup` in the `ebin` directory:\n\n```erlang\n{\"2\",\n [{\"1\", [{load_module, ch3}]}],\n [{\"1\", [{load_module, ch3}]}]\n}.\n```\n\n[](){: #relup }","title":"Application Upgrade File - Release Handling","ref":"release_handling.html#application-upgrade-file"},{"type":"extras","doc":"To define how to upgrade/downgrade between the new version and previous versions\nof a release, a _release upgrade file_, or in short `.relup` file, is to be\ncreated.\n\nThis file does not need to be created manually. It can be generated by\n[`systools:make_relup/3,4`](`systools:make_relup/4`).\nThe relevant versions of the `.rel` file, `.app`\nfiles, and `.appup` files are used as input. It is deduced which applications\nare to be added and deleted, and which applications that must be upgraded and/or\ndowngraded. The instructions for this are fetched from the `.appup` files and\ntransformed into a single list of low-level instructions in the right order.\n\nIf the `relup` file is relatively simple, it can be created manually. It is only\nto contain low-level instructions.\n\nFor details about the syntax and contents of the release upgrade file, see\n[`relup`](`e:sasl:relup.md`) in SASL.\n\n_Example, continued from the previous section:_ You have a new version \"2\" of\n`ch_app` and an `.appup` file. A new version of the `.rel` file is also needed.\nThis time the file is called `ch_rel-2.rel` and the release version string is\nchanged from \"A\" to \"B\":\n\n```erlang\n{release,\n {\"ch_rel\", \"B\"},\n {erts, \"14.2.5\"},\n [{kernel, \"9.2.4\"},\n {stdlib, \"5.2.3\"},\n {sasl, \"4.2.1\"},\n {ch_app, \"2\"}]\n}.\n```\n\nNow the `relup` file can be generated:\n\n```text\n1> systools:make_relup(\"ch_rel-2\", [\"ch_rel-1\"], [\"ch_rel-1\"]).\nok\n```\n\nThis generates a `relup` file with instructions for how to upgrade from version\n\"A\" (\"ch_rel-1\") to version \"B\" (\"ch_rel-2\") and how to downgrade from version\n\"B\" to version \"A\".\n\nBoth the old and new versions of the `.app` and `.rel` files must be in the code\npath, as well as the `.appup` and (new) `.beam` files. The code path can be\nextended by using the option `path`:\n\n```text\n1> systools:make_relup(\"ch_rel-2\", [\"ch_rel-1\"], [\"ch_rel-1\"],\n[{path,[\"../ch_rel-1\",\n\"../ch_rel-1/lib/ch_app-1/ebin\"]}]).\nok\n```\n\n[](){: #rel_handler }","title":"Release Upgrade File - Release Handling","ref":"release_handling.html#release-upgrade-file"},{"type":"extras","doc":"When you have made a new version of a release, a release package can be created\nwith this new version and transferred to the target environment.\n\nTo install the new version of the release in runtime, the _release\nhandler_ is used. This is a process belonging to the SASL application,\nwhich handles unpacking, installation, and removal of release\npackages. The `m:release_handler` module communicates with this process.\n\nAssuming there is an operational target system with installation root directory\n`$ROOT`, the release package with the new version of the release is to be copied\nto `$ROOT/releases`.\n\nFirst, _unpack_ the release package. The files are then extracted from the\npackage:\n\n```erlang\nrelease_handler:unpack_release(ReleaseName) => {ok, Vsn}\n```\n\n- `ReleaseName` is the name of the release package except the `.tar.gz`\n extension.\n- `Vsn` is the version of the unpacked release, as defined in its `.rel` file.\n\nA directory `$ROOT/lib/releases/Vsn` is created, where the `.rel` file, the boot\nscript `start.boot`, the system configuration file `sys.config`, and `relup` are\nplaced. For applications with new version numbers, the application directories\nare placed under `$ROOT/lib`. Unchanged applications are not affected.\n\nAn unpacked release can be _installed_. The release handler then evaluates the\ninstructions in `relup`, step by step:\n\n```erlang\nrelease_handler:install_release(Vsn) => {ok, FromVsn, []}\n```\n\nIf an error occurs during the installation, the system is rebooted using the old\nversion of the release. If installation succeeds, the system is afterwards using\nthe new version of the release, but if anything happens and the system is\nrebooted, it starts using the previous version again.\n\nTo be made the default version, the newly installed release must be made\n_permanent_, which means the previous version becomes _old_:\n\n```text\nrelease_handler:make_permanent(Vsn) => ok\n```\n\nThe system keeps information about which versions are old and permanent in the\nfiles `$ROOT/releases/RELEASES` and `$ROOT/releases/start_erl.data`.\n\nTo downgrade from `Vsn` to `FromVsn`, `install_release` must be called again:\n\n```erlang\nrelease_handler:install_release(FromVsn) => {ok, Vsn, []}\n```\n\nAn installed, but not permanent, release can be _removed_. Information about the\nrelease is then deleted from `$ROOT/releases/RELEASES` and the release-specific\ncode, that is, the new application directories and the `$ROOT/releases/Vsn`\ndirectory, are removed.\n\n```text\nrelease_handler:remove_release(Vsn) => ok\n```","title":"Installing a Release - Release Handling","ref":"release_handling.html#installing-a-release"},{"type":"extras","doc":"_Step 1)_ Create a target system as described in System Principles of the first\nversion `\"A\"` of `ch_rel` from [Releases](release_structure.md#ch_rel). This\ntime `sys.config` must be included in the release package. If no configuration\nis needed, the file is to contain the empty list:\n\n```text\n[].\n```\n\n_Step 2)_ Start the system as a simple target system. In reality, it is to be\nstarted as an embedded system. However, using `erl` with the correct boot script\nand config file is enough for illustration purposes:\n\n```text\n% cd $ROOT\n% bin/erl -boot $ROOT/releases/A/start -config $ROOT/releases/A/sys\n...\n```\n\n`$ROOT` is the installation directory of the target system.\n\n_Step 3)_ In another Erlang shell, generate start scripts and create a release\npackage for the new version `\"B\"`. Remember to include (a possible updated)\n`sys.config` and the `relup` file. For more information, see\n[Release Upgrade File](release_handling.md#relup).\n\n```erlang\n1> systools:make_script(\"ch_rel-2\").\nok\n2> systools:make_tar(\"ch_rel-2\").\nok\n```\n\nThe new release package now also contains version \"2\" of `ch_app` and the\n`relup` file:\n\n```text\n% tar tf ch_rel-2.tar\nlib/kernel-9.2.4/ebin/kernel.app\nlib/kernel-9.2.4/ebin/application.beam\n...\nlib/stdlib-5.2.3/ebin/stdlib.app\nlib/stdlib-5.2.3/ebin/argparse.beam\n...\nlib/sasl-4.2.1/ebin/sasl.app\nlib/sasl-4.2.1/ebin/sasl.beam\n...\nlib/ch_app-2/ebin/ch_app.app\nlib/ch_app-2/ebin/ch_app.beam\nlib/ch_app-2/ebin/ch_sup.beam\nlib/ch_app-2/ebin/ch3.beam\nreleases/B/start.boot\nreleases/B/relup\nreleases/B/sys.config\nreleases/B/ch_rel-2.rel\nreleases/ch_rel-2.rel\n```\n\n_Step 4)_ Copy the release package `ch_rel-2.tar.gz` to the `$ROOT/releases`\ndirectory.\n\n_Step 5)_ In the running target system, unpack the release package:\n\n```erlang\n1> release_handler:unpack_release(\"ch_rel-2\").\n{ok,\"B\"}\n```\n\nThe new application version `ch_app-2` is installed under `$ROOT/lib` next to\n`ch_app-1`. The `kernel`, `stdlib`, and `sasl` directories are not affected, as\nthey have not changed.\n\nUnder `$ROOT/releases`, a new directory `B` is created, containing\n`ch_rel-2.rel`, `start.boot`, `sys.config`, and `relup`.\n\n_Step 6)_ Check if the function `ch3:available/0` is available:\n\n```erlang\n2> ch3:available().\n** exception error: undefined function ch3:available/0\n```\n\n_Step 7)_ Install the new release. The instructions in `$ROOT/releases/B/relup`\nare executed one by one, resulting in the new version of `ch3` being loaded. The\nfunction `ch3:available/0` is now available:\n\n```erlang\n3> release_handler:install_release(\"B\").\n{ok,\"A\",[]}\n4> ch3:available().\n3\n5> code:which(ch3).\n\".../lib/ch_app-2/ebin/ch3.beam\"\n6> code:which(ch_sup).\n\".../lib/ch_app-1/ebin/ch_sup.beam\"\n```\n\nProcesses in `ch_app` for which code have not been updated, for example, the\nsupervisor, are still evaluating code from `ch_app-1`.\n\n_Step 8)_ If the target system is now rebooted, it uses version \"A\" again. The\n\"B\" version must be made permanent, to be used when the system is rebooted.\n\n```erlang\n7> release_handler:make_permanent(\"B\").\nok\n```\n\n[](){: #sys }","title":"Example (continued from the previous sections) - Release Handling","ref":"release_handling.html#example-continued-from-the-previous-sections"},{"type":"extras","doc":"When a new version of a release is installed, the application specifications are\nautomatically updated for all loaded applications.\n\n> #### Note {: .info }\n>\n> The information about the new application specifications is fetched from the\n> boot script included in the release package. Thus, it is important that the\n> boot script is generated from the same `.rel` file as is used to build the\n> release package itself.\n\nSpecifically, the application configuration parameters are automatically updated\naccording to (in increasing priority order):\n\n- The data in the boot script, fetched from the new application resource file\n `App.app`\n- The new `sys.config`\n- Command-line arguments `-App Par Val`\n\nThis means that parameter values set in the other system configuration files and\nvalues set using `application:set_env/3` are disregarded.\n\nWhen an installed release is made permanent, the system process `init` is set to\npoint out the new `sys.config`.\n\nAfter the installation, the application controller compares the old and new\nconfiguration parameters for all running applications and call the callback\nfunction:\n\n```erlang\nModule:config_change(Changed, New, Removed)\n```\n\n- `Module` is the application callback module as defined by the `mod` key in the\n `.app` file.\n- `Changed` and `New` are lists of `{Par,Val}` for all changed and added\n configuration parameters, respectively.\n- `Removed` is a list of all parameters `Par` that have been removed.\n\nThe function is optional and can be omitted when implementing an application\ncallback module.","title":"Updating Application Specifications - Release Handling","ref":"release_handling.html#updating-application-specifications"},{"type":"extras","doc":"\n# Appup Cookbook\n\n[](){: #appup-cookbook }\n\nThis section includes examples of `.appup` files for typical cases of\nupgrades/downgrades done in runtime.","title":"Appup Cookbook","ref":"appup_cookbook.html"},{"type":"extras","doc":"When a functional module has been changed, for example, if a new function has\nbeen added or a bug has been corrected, simple code replacement is sufficient,\nfor example:\n\n```erlang\n{\"2\",\n [{\"1\", [{load_module, m}]}],\n [{\"1\", [{load_module, m}]}]\n}.\n```","title":"Changing a Functional Module - Appup Cookbook","ref":"appup_cookbook.html#changing-a-functional-module"},{"type":"extras","doc":"In a system implemented according to the OTP design principles, all processes,\nexcept system processes and special processes, reside in one of the behaviours\n`m:supervisor`, `m:gen_server`, `m:gen_statem`, `m:gen_event`, or `m:gen_fsm`.\nThese belong to the STDLIB application and upgrading/downgrading normally\nrequires a runtime system restart.\n\nThus, OTP provides no support for changing residence modules except in the case\nof [special processes](appup_cookbook.md#spec).","title":"Changing a Residence Module - Appup Cookbook","ref":"appup_cookbook.html#changing-a-residence-module"},{"type":"extras","doc":"A callback module is a functional module, and for code extensions simple code\nreplacement is sufficient.\n\n_Example_\n\nWhen adding a function to `ch3`, as described in the example in\n[Release Handling](release_handling.md#appup), `ch_app.appup` looks as follows:\n\n```erlang\n{\"2\",\n [{\"1\", [{load_module, ch3}]}],\n [{\"1\", [{load_module, ch3}]}]\n}.\n```\n\nOTP also supports changing the internal state of behaviour processes; see\n[Changing Internal State](appup_cookbook.md#int_state).\n\n[](){: #int_state }","title":"Changing a Callback Module - Appup Cookbook","ref":"appup_cookbook.html#changing-a-callback-module"},{"type":"extras","doc":"In this case, simple code replacement is not sufficient. The process must\nexplicitly transform its state using the callback function `code_change/3` before\nswitching to the new version of the callback module. Thus, synchronized code\nreplacement is used.\n\n_Example_\n\nConsider the `ch3` module from\n[gen_server Behaviour](gen_server_concepts.md#ex). The internal state is a term\n`Chs` representing the available channels. Assume you want to add a counter `N`,\nwhich keeps track of the number of `alloc` requests so far. This means that the\nformat must be changed to `{Chs,N}`.\n\nThe `.appup` file can look as follows:\n\n```erlang\n{\"2\",\n [{\"1\", [{update, ch3, {advanced, []}}]}],\n [{\"1\", [{update, ch3, {advanced, []}}]}]\n}.\n```\n\nThe third element of the `update` instruction is a tuple `{advanced,Extra}`,\nwhich says that the affected processes are to do a state transformation before\nloading the new version of the module. This is done by the processes calling the\ncallback function `code_change/3` (see `m:gen_server` in STDLIB).\nThe term `Extra`, in this case `[]`, is passed as is to the function:\n\n[](){: #code_change }\n\n```erlang\n-module(ch3).\n...\n-export([code_change/3]).\n...\ncode_change({down, _Vsn}, {Chs, N}, _Extra) ->\n {ok, Chs};\ncode_change(_Vsn, Chs, _Extra) ->\n {ok, {Chs, 0}}.\n```\n\nThe first argument is `{down,Vsn}` if there is a downgrade, or `Vsn` if there is\na upgrade. The term `Vsn` is fetched from the 'original' version of the module,\nthat is, the version you are upgrading from, or downgrading to.\n\nThe version is defined by the module attribute `vsn`, if any. There is no such\nattribute in `ch3`, so in this case the version is the checksum (a huge integer)\nof the beam file, an uninteresting value, which is ignored.\n\nThe other callback functions of `ch3` must also be modified and perhaps a new\ninterface function must be added, but this is not shown here.","title":"Changing Internal State - Appup Cookbook","ref":"appup_cookbook.html#changing-internal-state"},{"type":"extras","doc":"Assume that a module is extended by adding an interface function, as in the\nexample in [Release Handling](release_handling.md#appup), where a function\n`available/0` is added to `ch3`.\n\nIf a call is added to this function, say in module `m1`, a runtime error could\ncan occur during release upgrade if the new version of `m1` is loaded first and\ncalls `ch3:available/0` before the new version of `ch3` is loaded.\n\nThus, `ch3` must be loaded before `m1`, in the upgrade case, and conversely in\nthe downgrade case. `m1` is said to be _dependent on_ `ch3`. In a release\nhandling instruction, this is expressed by the `DepMods` element:\n\n```erlang\n{load_module, Module, DepMods}\n{update, Module, {advanced, Extra}, DepMods}\n```\n\n`DepMods` is a list of modules, on which `Module` is dependent.\n\n_Example_\n\nThe module `m1` in application `myapp` is dependent on `ch3` when\nupgrading from \"1\" to \"2\", or downgrading from \"2\" to \"1\":\n\n```erlang\nmyapp.appup:\n\n{\"2\",\n [{\"1\", [{load_module, m1, [ch3]}]}],\n [{\"1\", [{load_module, m1, [ch3]}]}]\n}.\n\nch_app.appup:\n\n{\"2\",\n [{\"1\", [{load_module, ch3}]}],\n [{\"1\", [{load_module, ch3}]}]\n}.\n```\n\nIf instead `m1` and `ch3` belong to the same application, the `.appup` file can\nlook as follows:\n\n```erlang\n{\"2\",\n [{\"1\",\n [{load_module, ch3},\n {load_module, m1, [ch3]}]}],\n [{\"1\",\n [{load_module, ch3},\n {load_module, m1, [ch3]}]}]\n}.\n```\n\n`m1` is dependent on `ch3` also when downgrading. `systools` knows the\ndifference between up- and downgrading and generates a correct `relup`, where\n`ch3` is loaded before `m1` when upgrading, but `m1` is loaded before `ch3` when\ndowngrading.\n\n[](){: #spec }","title":"Module Dependencies - Appup Cookbook","ref":"appup_cookbook.html#module-dependencies"},{"type":"extras","doc":"In this case, simple code replacement is not sufficient. When a new version of a\nresidence module for a special process is loaded, the process must make a fully\nqualified call to its loop function to switch to the new code. Thus,\nsynchronized code replacement must be used.\n\n> #### Note {: .info }\n>\n> The name(s) of the user-defined residence module(s) must be listed in the\n> `Modules` part of the child specification for the special process. Otherwise\n> the release handler cannot find the process.\n\n_Example_\n\nConsider the example `ch4` in [sys and proc_lib](spec_proc.md#ex).\nWhen started by a supervisor, the child specification can look as follows:\n\n```erlang\n{ch4, {ch4, start_link, []},\n permanent, brutal_kill, worker, [ch4]}\n```\n\nIf `ch4` is part of the application `sp_app` and a new version of the module is\nto be loaded when upgrading from version \"1\" to \"2\" of this application,\n`sp_app.appup` can look as follows:\n\n```erlang\n{\"2\",\n [{\"1\", [{update, ch4, {advanced, []}}]}],\n [{\"1\", [{update, ch4, {advanced, []}}]}]\n}.\n```\n\nThe `update` instruction must contain the tuple `{advanced,Extra}`. The\ninstruction makes the special process call the callback function\n`system_code_change/4`, a function the user must implement. The term `Extra`, in\nthis case `[]`, is passed as is to `system_code_change/4`:\n\n```erlang\n-module(ch4).\n...\n-export([system_code_change/4]).\n...\n\nsystem_code_change(Chs, _Module, _OldVsn, _Extra) ->\n {ok, Chs}.\n```\n\n- The first argument is the internal state `State`, passed from\n function [`sys:handle_system_msg(Request, From, Parent, Module, Deb,\n State)`](`sys:handle_system_msg/6`), and called by the special\n process when a system message is received. In `ch4`, the internal\n state is the set of available channels `Chs`.\n- The second argument is the name of the module (`ch4`).\n- The third argument is `Vsn` or `{down,Vsn}`, as described for\n `c:gen_server:code_change/3` in\n [Changing Internal State](appup_cookbook.md#code_change).\n\nIn this case, all arguments but the first are ignored and the function simply\nreturns the internal state again. This is enough if the code only has been\nextended. If instead the internal state is changed (similar to the example in\n[Changing Internal State](appup_cookbook.md#int_state)), this is done in this\nfunction and `{ok,Chs2}` returned.\n\n[](){: #sup }","title":"Changing Code for a Special Process - Appup Cookbook","ref":"appup_cookbook.html#changing-code-for-a-special-process"},{"type":"extras","doc":"The supervisor behaviour supports changing the internal state, that is, changing\nthe restart strategy and maximum restart frequency properties, as well as\nchanging the existing child specifications.\n\nChild processes can be added or deleted, but this is not handled automatically.\nInstructions must be given by in the `.appup` file.","title":"Changing a Supervisor - Appup Cookbook","ref":"appup_cookbook.html#changing-a-supervisor"},{"type":"extras","doc":"Since the supervisor is to change its internal state, synchronized code\nreplacement is required. However, a special `update` instruction must be used.\n\nFirst, the new version of the callback module must be loaded, both in the case\nof upgrade and downgrade. Then the new return value of `init/1` can be checked\nand the internal state be changed accordingly.\n\nThe following `upgrade` instruction is used for supervisors:\n\n```text\n{update, Module, supervisor}\n```\n\n_Example_\n\nTo change the restart strategy of `ch_sup` (from\n[Supervisor Behaviour](sup_princ.md#ex)) from `one_for_one` to `one_for_all`,\nchange the callback function `init/1` in `ch_sup.erl`:\n\n```erlang\n-module(ch_sup).\n...\n\ninit(_Args) ->\n {ok, {#{strategy => one_for_all, ...}, ...}}.\n```\n\nThe file `ch_app.appup`:\n\n```erlang\n{\"2\",\n [{\"1\", [{update, ch_sup, supervisor}]}],\n [{\"1\", [{update, ch_sup, supervisor}]}]\n}.\n```","title":"Changing Properties - Appup Cookbook","ref":"appup_cookbook.html#changing-properties"},{"type":"extras","doc":"The instruction, and thus the `.appup` file, when changing an existing child\nspecification, is the same as when changing properties as described earlier:\n\n```erlang\n{\"2\",\n [{\"1\", [{update, ch_sup, supervisor}]}],\n [{\"1\", [{update, ch_sup, supervisor}]}]\n}.\n```\n\nThe changes do not affect existing child processes. For example, changing the\nstart function only specifies how the child process is to be restarted, if\nneeded later on.\n\nThe id of the child specification cannot be changed.\n\nChanging the `Modules` field of the child specification can affect the release\nhandling process itself, as this field is used to identify which processes are\naffected when doing a synchronized code replacement.\n\n[](){: #sup_add }","title":"Changing Child Specifications - Appup Cookbook","ref":"appup_cookbook.html#changing-child-specifications"},{"type":"extras","doc":"As stated earlier, changing child specifications does not affect existing child\nprocesses. New child specifications are automatically added, but not deleted.\nChild processes are not automatically started or terminated, this must be done\nusing `apply` instructions.\n\n_Example_\n\nAssume a new child process `m1` is to be added to `ch_sup` when\nupgrading `ch_app` from \"1\" to \"2\". This means `m1` is to be deleted when\ndowngrading from \"2\" to \"1\":\n\n```erlang\n{\"2\",\n [{\"1\",\n [{update, ch_sup, supervisor},\n {apply, {supervisor, restart_child, [ch_sup, m1]}}\n ]}],\n [{\"1\",\n [{apply, {supervisor, terminate_child, [ch_sup, m1]}},\n {apply, {supervisor, delete_child, [ch_sup, m1]}},\n {update, ch_sup, supervisor}\n ]}]\n}.\n```\n\nThe order of the instructions is important.\n\nThe supervisor must be registered as `ch_sup` for the script to work. If the\nsupervisor is not registered, it cannot be accessed directly from the script.\nInstead a help function that finds the pid of the supervisor and calls\n`supervisor:restart_child`, and so on, must be written. This function is then to\nbe called from the script using the `apply` instruction.\n\nIf the module `m1` is introduced in version \"2\" of `ch_app`, it must also be\nloaded when upgrading and deleted when downgrading:\n\n```erlang\n{\"2\",\n [{\"1\",\n [{add_module, m1},\n {update, ch_sup, supervisor},\n {apply, {supervisor, restart_child, [ch_sup, m1]}}\n ]}],\n [{\"1\",\n [{apply, {supervisor, terminate_child, [ch_sup, m1]}},\n {apply, {supervisor, delete_child, [ch_sup, m1]}},\n {update, ch_sup, supervisor},\n {delete_module, m1}\n ]}]\n}.\n```\n\nAs stated earlier, the order of the instructions is important. When upgrading,\n`m1` must be loaded, and the supervisor child specification changed, before the\nnew child process can be started. When downgrading, the child process must be\nterminated before the child specification is changed and the module is deleted.","title":"Adding and Deleting Child Processes - Appup Cookbook","ref":"appup_cookbook.html#adding-and-deleting-child-processes"},{"type":"extras","doc":"_Example\n\n_ A new functional module `m` is added to `ch_app`:\n\n```erlang\n{\"2\",\n [{\"1\", [{add_module, m}]}],\n [{\"1\", [{delete_module, m}]}]\n```","title":"Adding or Deleting a Module - Appup Cookbook","ref":"appup_cookbook.html#adding-or-deleting-a-module"},{"type":"extras","doc":"In a system structured according to the OTP design principles, any process would\nbe a child process belonging to a supervisor, see\n[Adding and Deleting Child Processes](appup_cookbook.md#sup_add) in Changing a\nSupervisor.","title":"Starting or Terminating a Process - Appup Cookbook","ref":"appup_cookbook.html#starting-or-terminating-a-process"},{"type":"extras","doc":"When adding or removing an application, no `.appup` file is needed. When\ngenerating `relup`, the `.rel` files are compared and the `add_application` and\n`remove_application` instructions are added automatically.","title":"Adding or Removing an Application - Appup Cookbook","ref":"appup_cookbook.html#adding-or-removing-an-application"},{"type":"extras","doc":"Restarting an application is useful when a change is too complicated to be made\nwithout restarting the processes, for example, if the supervisor hierarchy has\nbeen restructured.\n\n_Example_\n\nWhen adding a child `m1` to `ch_sup`, as in\n[Adding and Deleting Child Processes](appup_cookbook.md#sup_add) in Changing a\nSupervisor, an alternative to updating the supervisor is to restart the entire\napplication:\n\n```erlang\n{\"2\",\n [{\"1\", [{restart_application, ch_app}]}],\n [{\"1\", [{restart_application, ch_app}]}]\n}.\n```\n\n[](){: #app_spec }","title":"Restarting an Application - Appup Cookbook","ref":"appup_cookbook.html#restarting-an-application"},{"type":"extras","doc":"When installing a release, the application specifications are automatically\nupdated before evaluating the `relup` script. Thus, no instructions are needed\nin the `.appup` file:\n\n```erlang\n{\"2\",\n [{\"1\", []}],\n [{\"1\", []}]\n}.\n```","title":"Changing an Application Specification - Appup Cookbook","ref":"appup_cookbook.html#changing-an-application-specification"},{"type":"extras","doc":"Changing an application configuration by updating the `env` key in the `.app`\nfile is an instance of changing an application specification, see the previous\nsection.\n\nAlternatively, application configuration parameters can be added or updated in\n`sys.config`.","title":"Changing Application Configuration - Appup Cookbook","ref":"appup_cookbook.html#changing-application-configuration"},{"type":"extras","doc":"The release handling instructions for adding, removing, and restarting\napplications apply to primary applications only. There are no corresponding\ninstructions for included applications. However, since an included application\nis really a supervision tree with a topmost supervisor, started as a child\nprocess to a supervisor in the including application, a `.relup` file can be\nmanually created.\n\n_Example_\n\nAssume there is a release containing an application `prim_app`, which\nhave a supervisor `prim_sup` in its supervision tree.\n\nIn a new version of the release, the application `ch_app` is to be included in\n`prim_app`. That is, its topmost supervisor `ch_sup` is to be started as a child\nprocess to `prim_sup`.\n\nThe workflow is as follows:\n\n_Step 1)_ Edit the code for `prim_sup`:\n\n```erlang\ninit(...) ->\n {ok, {...supervisor flags...,\n [...,\n {ch_sup, {ch_sup,start_link,[]},\n permanent,infinity,supervisor,[ch_sup]},\n ...]}}.\n```\n\n_Step 2)_ Edit the `.app` file for `prim_app`:\n\n```erlang\n{application, prim_app,\n [...,\n {vsn, \"2\"},\n ...,\n {included_applications, [ch_app]},\n ...\n ]}.\n```\n\n_Step 3)_ Create a new `.rel` file, including `ch_app`:\n\n```text\n{release,\n ...,\n [...,\n {prim_app, \"2\"},\n {ch_app, \"1\"}]}.\n```\n\nThe included application can be started in two ways. This is described in the\nnext two sections.","title":"Changing Included Applications - Appup Cookbook","ref":"appup_cookbook.html#changing-included-applications"},{"type":"extras","doc":"_Step 4a)_ One way to start the included application is to restart the entire\n`prim_app` application. Normally, the `restart_application` instruction in the\n`.appup` file for `prim_app` would be used.\n\nHowever, if this is done and a `.relup` file is generated, not only would it\ncontain instructions for restarting (that is, removing and adding) `prim_app`,\nit would also contain instructions for starting `ch_app` (and stopping it, in\nthe case of downgrade). This is because `ch_app` is included in the new `.rel`\nfile, but not in the old one.\n\nInstead, a correct `relup` file can be created manually, either from scratch or\nby editing the generated version. The instructions for starting/stopping\n`ch_app` are replaced by instructions for loading/unloading the application:\n\n```c\n{\"B\",\n [{\"A\",\n [],\n [{load_object_code,{ch_app,\"1\",[ch_sup,ch3]}},\n {load_object_code,{prim_app,\"2\",[prim_app,prim_sup]}},\n point_of_no_return,\n {apply,{application,stop,[prim_app]}},\n {remove,{prim_app,brutal_purge,brutal_purge}},\n {remove,{prim_sup,brutal_purge,brutal_purge}},\n {purge,[prim_app,prim_sup]},\n {load,{prim_app,brutal_purge,brutal_purge}},\n {load,{prim_sup,brutal_purge,brutal_purge}},\n {load,{ch_sup,brutal_purge,brutal_purge}},\n {load,{ch3,brutal_purge,brutal_purge}},\n {apply,{application,load,[ch_app]}},\n {apply,{application,start,[prim_app,permanent]}}]}],\n [{\"A\",\n [],\n [{load_object_code,{prim_app,\"1\",[prim_app,prim_sup]}},\n point_of_no_return,\n {apply,{application,stop,[prim_app]}},\n {apply,{application,unload,[ch_app]}},\n {remove,{ch_sup,brutal_purge,brutal_purge}},\n {remove,{ch3,brutal_purge,brutal_purge}},\n {purge,[ch_sup,ch3]},\n {remove,{prim_app,brutal_purge,brutal_purge}},\n {remove,{prim_sup,brutal_purge,brutal_purge}},\n {purge,[prim_app,prim_sup]},\n {load,{prim_app,brutal_purge,brutal_purge}},\n {load,{prim_sup,brutal_purge,brutal_purge}},\n {apply,{application,start,[prim_app,permanent]}}]}]\n}.\n```","title":"Application Restart - Appup Cookbook","ref":"appup_cookbook.html#application-restart"},{"type":"extras","doc":"_Step 4b)_ Another way to start the included application (or stop it in the case\nof downgrade) is by combining instructions for adding and removing child\nprocesses to/from `prim_sup` with instructions for loading/unloading all\n`ch_app` code and its application specification.\n\nAgain, the `.relup` file is created manually, either from scratch or by editing a\ngenerated version. Load all code for `ch_app` first, and also load the\napplication specification, before `prim_sup` is updated. When downgrading,\n`prim_sup` is to updated first, before the code for `ch_app` and its application\nspecification are unloaded.\n\n```erlang\n{\"B\",\n [{\"A\",\n [],\n [{load_object_code,{ch_app,\"1\",[ch_sup,ch3]}},\n {load_object_code,{prim_app,\"2\",[prim_sup]}},\n point_of_no_return,\n {load,{ch_sup,brutal_purge,brutal_purge}},\n {load,{ch3,brutal_purge,brutal_purge}},\n {apply,{application,load,[ch_app]}},\n {suspend,[prim_sup]},\n {load,{prim_sup,brutal_purge,brutal_purge}},\n {code_change,up,[{prim_sup,[]}]},\n {resume,[prim_sup]},\n {apply,{supervisor,restart_child,[prim_sup,ch_sup]}}]}],\n [{\"A\",\n [],\n [{load_object_code,{prim_app,\"1\",[prim_sup]}},\n point_of_no_return,\n {apply,{supervisor,terminate_child,[prim_sup,ch_sup]}},\n {apply,{supervisor,delete_child,[prim_sup,ch_sup]}},\n {suspend,[prim_sup]},\n {load,{prim_sup,brutal_purge,brutal_purge}},\n {code_change,down,[{prim_sup,[]}]},\n {resume,[prim_sup]},\n {remove,{ch_sup,brutal_purge,brutal_purge}},\n {remove,{ch3,brutal_purge,brutal_purge}},\n {purge,[ch_sup,ch3]},\n {apply,{application,unload,[ch_app]}}]}]\n}.\n```","title":"Supervisor Change - Appup Cookbook","ref":"appup_cookbook.html#supervisor-change"},{"type":"extras","doc":"Changing code for a program written in another programming language than Erlang,\nfor example, a port program, is application-dependent and OTP provides no\nspecial support.\n\n_Example_\n\nWhen changing code for a port program, assume that the Erlang process\ncontrolling the port is a `gen_server` `portc` and that the port is opened in\nthe callback function `init/1`:\n\n```erlang\ninit(...) ->\n ...,\n PortPrg = filename:join(code:priv_dir(App), \"portc\"),\n Port = open_port({spawn,PortPrg}, [...]),\n ...,\n {ok, #state{port=Port, ...}}.\n```\n\nIf the port program is to be updated, the code for the `gen_server` can be\nextended with a `code_change/3` function, which closes the old port and opens a\nnew port. (If necessary, the `gen_server` can first request data that must be\nsaved from the port program and pass this data to the new port):\n\n```erlang\ncode_change(_OldVsn, State, port) ->\n State#state.port ! close,\n receive\n {Port,close} ->\n true\n end,\n PortPrg = filename:join(code:priv_dir(App), \"portc\"),\n Port = open_port({spawn,PortPrg}, [...]),\n {ok, #state{port=Port, ...}}.\n```\n\nUpdate the application version number in the `.app` file and write an `.appup`\nfile:\n\n```erlang\n[\"2\",\n [{\"1\", [{update, portc, {advanced,port}}]}],\n [{\"1\", [{update, portc, {advanced,port}}]}]\n].\n```\n\nEnsure that the `priv` directory, where the C program is located, is included in\nthe new release package:\n\n```erlang\n1> systools:make_tar(\"my_release\", [{dirs,[priv]}]).\n...\n```","title":"Changing Non-Erlang Code - Appup Cookbook","ref":"appup_cookbook.html#changing-non-erlang-code"},{"type":"extras","doc":"Two upgrade instructions restart the runtime system:\n\n- `restart_new_emulator`\n\n Intended when ERTS, Kernel, STDLIB, or SASL is upgraded. It is automatically\n added when the `relup` file is generated by `systools:make_relup/3,4`. It is\n executed before all other upgrade instructions. For more information about\n this instruction, see restart_new_emulator (Low-Level) in\n [Release Handling Instructions](release_handling.md#restart_new_emulator_instr).\n\n- `restart_emulator`\n\n Used when a restart of the runtime system is required after all other upgrade\n instructions are executed. For more information about this instruction, see\n restart_emulator (Low-Level) in\n [Release Handling Instructions](release_handling.md#restart_emulator_instr).\n\nIf a runtime system restart is necessary and no upgrade instructions are needed,\nthat is, if the restart itself is enough for the upgraded applications to start\nrunning the new versions, a simple `.relup` file can be created manually:\n\n```erlang\n{\"B\",\n [{\"A\",\n [],\n [restart_emulator]}],\n [{\"A\",\n [],\n [restart_emulator]}]\n}.\n```\n\nIn this case, the release handler framework with automatic packing and unpacking\nof release packages, automatic path updates, and so on, can be used without\nhaving to specify `.appup` files.","title":"Runtime System Restart and Upgrade - Appup Cookbook","ref":"appup_cookbook.html#runtime-system-restart-and-upgrade"},{"type":"extras","doc":"# Introduction\n\n[](){: #programming-examples }\n\nThis section contains examples on using records, funs, list comprehensions, and\nthe bit syntax.","title":"Introduction","ref":"programming_examples.html"},{"type":"extras","doc":"\n# Records","title":"Records","ref":"prog_ex_records.html"},{"type":"extras","doc":"The main advantage of using records rather than tuples is that fields in a\nrecord are accessed by name, whereas fields in a tuple are accessed by position.\nTo illustrate these differences, suppose that you want to represent a person\nwith the tuple `{Name, Address, Phone}`.\n\nTo write functions that manipulate this data, remember the following:\n\n- The `Name` field is the first element of the tuple.\n- The `Address` field is the second element.\n- The `Phone` field is the third element.\n\nFor example, to extract data from a variable `P` that contains such a tuple, you\ncan write the following code and then use pattern matching to extract the\nrelevant fields:\n\n```erlang\nName = element(1, P),\nAddress = element(2, P),\n...\n```\n\nSuch code is difficult to read and understand, and errors occur if the numbering\nof the elements in the tuple is wrong. If the data representation of the fields\nis changed, by re-ordering, adding, or removing fields, all references to the\nperson tuple must be checked and possibly modified.\n\nRecords allow references to the fields by name, instead of by position. In the\nfollowing example, a record instead of a tuple is used to store the data:\n\n```erlang\n-record(person, {name, phone, address}).\n```\n\nThis enables references to the fields of the record by name. For example, if `P`\nis a variable whose value is a `person` record, the following code access the\nname and address fields of the records:\n\n```erlang\nName = P#person.name,\nAddress = P#person.address,\n...\n```\n\nInternally, records are represented using tagged tuples:\n\n```erlang\n{person, Name, Phone, Address}\n```","title":"Records and Tuples - Records","ref":"prog_ex_records.html#records-and-tuples"},{"type":"extras","doc":"This following definition of a `person` is used in several examples in this\nsection. Three fields are included, `name`, `phone`, and `address`. The default\nvalues for `name` and `phone` is \"\" and [], respectively. The default value for\n`address` is the atom `undefined`, since no default value is supplied for this\nfield:\n\n```erlang\n-record(person, {name = \"\", phone = [], address}).\n```\n\nThe record must be defined in the shell to enable use of the record syntax in\nthe examples:\n\n```erlang\n> rd(person, {name = \"\", phone = [], address}).\nperson\n```\n\nThis is because record definitions are only available at compile time, not at\nruntime. For details on records in the shell, see the `m:shell` manual page in\nSTDLIB.","title":"Defining a Record - Records","ref":"prog_ex_records.html#defining-a-record"},{"type":"extras","doc":"A new `person` record is created as follows:\n\n```erlang\n> #person{phone=[0,8,2,3,4,3,1,2], name=\"Robert\"}.\n#person{name = \"Robert\",phone = [0,8,2,3,4,3,1,2],address = undefined}\n```\n\nAs the `address` field was omitted, its default value is used.\n\nFrom Erlang 5.1/OTP R8B, a value to all fields in a record can be set with the\nspecial field `_`. `_` means \"all fields not explicitly specified\".\n\n_Example:_\n\n```erlang\n> #person{name = \"Jakob\", _ = '_'}.\n#person{name = \"Jakob\",phone = '_',address = '_'}\n```\n\nIt is primarily intended to be used in `ets:match/2` and\n`mnesia:match_object/3`, to set record fields to the atom `'_'`. (This is a\nwildcard in `ets:match/2`.)","title":"Creating a Record - Records","ref":"prog_ex_records.html#creating-a-record"},{"type":"extras","doc":"The following example shows how to access a record field:\n\n```erlang\n> P = #person{name = \"Joe\", phone = [0,8,2,3,4,3,1,2]}.\n#person{name = \"Joe\",phone = [0,8,2,3,4,3,1,2],address = undefined}\n> P#person.name.\n\"Joe\"\n```","title":"Accessing a Record Field - Records","ref":"prog_ex_records.html#accessing-a-record-field"},{"type":"extras","doc":"The following example shows how to update a record:\n\n```erlang\n> P1 = #person{name=\"Joe\", phone=[1,2,3], address=\"A street\"}.\n#person{name = \"Joe\",phone = [1,2,3],address = \"A street\"}\n> P2 = P1#person{name=\"Robert\"}.\n#person{name = \"Robert\",phone = [1,2,3],address = \"A street\"}\n```","title":"Updating a Record - Records","ref":"prog_ex_records.html#updating-a-record"},{"type":"extras","doc":"The following example shows that the guard succeeds if `P` is record of type\n`person`:\n\n```erlang\nfoo(P) when is_record(P, person) -> a_person;\nfoo(_) -> not_a_person.\n```","title":"Type Testing - Records","ref":"prog_ex_records.html#type-testing"},{"type":"extras","doc":"Matching can be used in combination with records, as shown in the following\nexample:\n\n```erlang\n> P3 = #person{name=\"Joe\", phone=[0,0,7], address=\"A street\"}.\n#person{name = \"Joe\",phone = [0,0,7],address = \"A street\"}\n> #person{name = Name} = P3, Name.\n\"Joe\"\n```\n\nThe following function takes a list of `person` records and searches for the\nphone number of a person with a particular name:\n\n```erlang\nfind_phone([#person{name=Name, phone=Phone} | _], Name) ->\n {found, Phone};\nfind_phone([_| T], Name) ->\n find_phone(T, Name);\nfind_phone([], Name) ->\n not_found.\n```\n\nThe fields referred to in the pattern can be given in any order.","title":"Pattern Matching - Records","ref":"prog_ex_records.html#pattern-matching"},{"type":"extras","doc":"The value of a field in a record can be an instance of a record. Retrieval of\nnested data can be done stepwise, or in a single step, as shown in the following\nexample:\n\n```erlang\n-record(name, {first = \"Robert\", last = \"Ericsson\"}).\n-record(person, {name = #name{}, phone}).\n\ndemo() ->\n P = #person{name= #name{first=\"Robert\",last=\"Virding\"}, phone=123},\n First = (P#person.name)#name.first.\n```\n\nHere, `demo()` evaluates to `\"Robert\"`.","title":"Nested Records - Records","ref":"prog_ex_records.html#nested-records"},{"type":"extras","doc":"Comments are embedded in the following example:\n\n```erlang\n%% File: person.hrl\n\n%%-----------------------------------------------------------\n%% Data Type: person\n%% where:\n%% name: A string (default is undefined).\n%% age: An integer (default is undefined).\n%% phone: A list of integers (default is []).\n%% dict: A dictionary containing various information\n%% about the person.\n%% A {Key, Value} list (default is the empty list).\n%%------------------------------------------------------------\n-record(person, {name, age, phone = [], dict = []}).\n```\n\n```erlang\n-module(person).\n-include(\"person.hrl\").\n-compile(export_all). % For test purposes only.\n\n%% This creates an instance of a person.\n%% Note: The phone number is not supplied so the\n%% default value [] will be used.\n\nmake_hacker_without_phone(Name, Age) ->\n #person{name = Name, age = Age,\n dict = [{computer_knowledge, excellent},\n {drinks, coke}]}.\n\n%% This demonstrates matching in arguments\n\nprint(#person{name = Name, age = Age,\n phone = Phone, dict = Dict}) ->\n io:format(\"Name: ~s, Age: ~w, Phone: ~w ~n\"\n \"Dictionary: ~w.~n\", [Name, Age, Phone, Dict]).\n\n%% Demonstrates type testing, selector, updating.\n\nbirthday(P) when is_record(P, person) ->\n P#person{age = P#person.age + 1}.\n\nregister_two_hackers() ->\n Hacker1 = make_hacker_without_phone(\"Joe\", 29),\n OldHacker = birthday(Hacker1),\n % The central_register_server should have\n % an interface function for this.\n central_register_server ! {register_person, Hacker1},\n central_register_server ! {register_person,\n OldHacker#person{name = \"Robert\",\n phone = [0,8,3,2,4,5,3,1]}}.\n```","title":"A Longer Example - Records","ref":"prog_ex_records.html#a-longer-example"},{"type":"extras","doc":"\n# Funs","title":"Funs","ref":"funs.html"},{"type":"extras","doc":"The following function, `double`, doubles every element in a list:\n\n```erlang\ndouble([H|T]) -> [2*H|double(T)];\ndouble([]) -> [].\n```\n\nHence, the argument entered as input is doubled as follows:\n\n```erlang\n> double([1,2,3,4]).\n[2,4,6,8]\n```\n\nThe following function, `add_one`, adds one to every element in a list:\n\n```erlang\nadd_one([H|T]) -> [H+1|add_one(T)];\nadd_one([]) -> [].\n```\n\nThe functions `double` and `add_one` have a similar structure. This can be used\nby writing a function `map` that expresses this similarity:\n\n```erlang\nmap(F, [H|T]) -> [F(H)|map(F, T)];\nmap(F, []) -> [].\n```\n\nThe functions `double` and `add_one` can now be expressed in terms of `map` as\nfollows:\n\n```erlang\ndouble(L) -> map(fun(X) -> 2*X end, L).\nadd_one(L) -> map(fun(X) -> 1 + X end, L).\n```\n\n`map(F, List)` is a function that takes a function `F` and a list `L` as\narguments and returns a new list, obtained by applying `F` to each of the\nelements in `L`.\n\nThe process of abstracting out the common features of a number of different\nprograms is called _procedural abstraction_. Procedural abstraction can be used\nto write several different functions that have a similar structure, but differ\nin some minor detail. This is done as follows:\n\n1. _Step 1._ Write one function that represents the common features of these\n functions.\n1. _Step 2._ Parameterize the difference in terms of functions that are passed\n as arguments to the common function.","title":"map - Funs","ref":"funs.html#map"},{"type":"extras","doc":"This section illustrates procedural abstraction. Initially, the following two\nexamples are written as conventional functions.\n\nThis function prints all elements of a list onto a stream:\n\n```erlang\nprint_list(Stream, [H|T]) ->\n io:format(Stream, \"~p~n\", [H]),\n print_list(Stream, T);\nprint_list(Stream, []) ->\n true.\n```\n\nThis function broadcasts a message to a list of processes:\n\n```erlang\nbroadcast(Msg, [Pid|Pids]) ->\n Pid ! Msg,\n broadcast(Msg, Pids);\nbroadcast(_, []) ->\n true.\n```\n\nThese two functions have a similar structure. They both iterate over a list and\ndo something to each element in the list. The \"something\" is passed on as an\nextra argument to the function that does this.\n\nThe function `foreach` expresses this similarity:\n\n```erlang\nforeach(F, [H|T]) ->\n F(H),\n foreach(F, T);\nforeach(F, []) ->\n ok.\n```\n\nUsing the function `foreach`, the function `print_list` becomes:\n\n```erlang\nforeach(fun(H) -> io:format(S, \"~p~n\",[H]) end, L)\n```\n\nUsing the function `foreach`, the function `broadcast` becomes:\n\n```erlang\nforeach(fun(Pid) -> Pid ! M end, L)\n```\n\n`foreach` is evaluated for its side-effect and not its value. `foreach(Fun ,L)`\ncalls `Fun(X)` for each element `X` in `L` and the processing occurs in the\norder that the elements were defined in `L`. `map` does not define the order in\nwhich its elements are processed.","title":"foreach - Funs","ref":"funs.html#foreach"},{"type":"extras","doc":"Funs are written with the following syntax (see\n[Fun Expressions ](`e:system:expressions.md#fun-expressions`)for full description):\n\n```erlang\nF = fun (Arg1, Arg2, ... ArgN) ->\n ...\n end\n```\n\nThis creates an anonymous function of `N` arguments and binds it to the variable\n`F`.\n\nAnother function, `FunctionName`, written in the same module, can be passed as\nan argument, using the following syntax:\n\n```erlang\nF = fun FunctionName/Arity\n```\n\nWith this form of function reference, the function that is referred to does not\nneed to be exported from the module.\n\nIt is also possible to refer to a function defined in a different module, with\nthe following syntax:\n\n```erlang\nF = fun Module:FunctionName/Arity\n```\n\nIn this case, the function must be exported from the module in question.\n\nThe following program illustrates the different ways of creating funs:\n\n```erlang\n-module(fun_test).\n-export([t1/0, t2/0]).\n-import(lists, [map/2]).\n\nt1() -> map(fun(X) -> 2 * X end, [1,2,3,4,5]).\n\nt2() -> map(fun double/1, [1,2,3,4,5]).\n\ndouble(X) -> X * 2.\n```\n\nThe fun `F` can be evaluated with the following syntax:\n\n```erlang\nF(Arg1, Arg2, ..., Argn)\n```\n\nTo check whether a term is a fun, use the test\n[`is_function/1`](`is_function/1`) in a guard.\n\n_Example:_\n\n```erlang\nf(F, Args) when is_function(F) ->\n apply(F, Args);\nf(N, _) when is_integer(N) ->\n N.\n```\n\nFuns are a distinct type. The BIFs `erlang:fun_info/1,2` can be used to retrieve\ninformation about a fun, and the BIF `erlang:fun_to_list/1` returns a textual\nrepresentation of a fun. The [`check_process_code/2`](`check_process_code/2`)\nBIF returns `true` if the process contains funs that depend on the old version\nof a module.","title":"Syntax of Funs - Funs","ref":"funs.html#syntax-of-funs"},{"type":"extras","doc":"The scope rules for variables that occur in funs are as follows:\n\n- All variables that occur in the head of a fun are assumed to be \"fresh\"\n variables.\n- Variables that are defined before the fun, and that occur in function calls or\n guard tests within the fun, have the values they had outside the fun.\n- Variables cannot be exported from a fun.\n\nThe following examples illustrate these rules:\n\n```erlang\nprint_list(File, List) ->\n {ok, Stream} = file:open(File, write),\n foreach(fun(X) -> io:format(Stream,\"~p~n\",[X]) end, List),\n file:close(Stream).\n```\n\nHere, the variable `X`, defined in the head of the fun, is a new variable. The\nvariable `Stream`, which is used within the fun, gets its value from the\n`file:open` line.\n\nAs any variable that occurs in the head of a fun is considered a new variable,\nit is equally valid to write as follows:\n\n```erlang\nprint_list(File, List) ->\n {ok, Stream} = file:open(File, write),\n foreach(fun(File) ->\n io:format(Stream,\"~p~n\",[File])\n end, List),\n file:close(Stream).\n```\n\nHere, `File` is used as the new variable instead of `X`. This is not so wise\nbecause code in the fun body cannot refer to the variable `File`, which is\ndefined outside of the fun. Compiling this example gives the following\ndiagnostic:\n\n```text\n./FileName.erl:Line: Warning: variable 'File'\n shadowed in 'fun'\n```\n\nThis indicates that the variable `File`, which is defined inside the fun,\ncollides with the variable `File`, which is defined outside the fun.\n\nThe rules for importing variables into a fun has the consequence that certain\npattern matching operations must be moved into guard expressions and cannot be\nwritten in the head of the fun. For example, you might write the following code\nif you intend the first clause of `F` to be evaluated when the value of its\nargument is `Y`:\n\n```erlang\nf(...) ->\n Y = ...\n map(fun(X) when X == Y ->\n ;\n (_) ->\n ...\n end, ...)\n ...\n```\n\ninstead of writing the following code:\n\n```erlang\nf(...) ->\n Y = ...\n map(fun(Y) ->\n ;\n (_) ->\n ...\n end, ...)\n ...\n```","title":"Variable Bindings Within a Fun - Funs","ref":"funs.html#variable-bindings-within-a-fun"},{"type":"extras","doc":"The following examples show a dialogue with the Erlang shell. All the higher\norder functions discussed are exported from the module `m:lists`.","title":"Funs and Module Lists - Funs","ref":"funs.html#funs-and-module-lists"},{"type":"extras","doc":"`lists:map/2` takes a function of one argument and a list of terms:\n\n```erlang\nmap(F, [H|T]) -> [F(H)|map(F, T)];\nmap(F, []) -> [].\n```\n\nIt returns the list obtained by applying the function to every argument in the\nlist.\n\nWhen a new fun is defined in the shell, the value of the fun is printed as\n`Fun# `:\n\n```erlang\n> Double = fun(X) -> 2 * X end.\n#Fun \n> lists:map(Double, [1,2,3,4,5]).\n[2,4,6,8,10]\n```","title":"map - Funs","ref":"funs.html#map"},{"type":"extras","doc":"`lists:any/2` takes a predicate `P` of one argument and a list of terms:\n\n```erlang\nany(Pred, [H|T]) ->\n case Pred(H) of\n true -> true;\n false -> any(Pred, T)\n end;\nany(Pred, []) ->\n false.\n```\n\nA predicate is a function that returns `true` or `false`. `any` is `true` if\nthere is a term `X` in the list such that `P(X)` is `true`.\n\nA predicate `Big(X)` is defined, which is `true` if its argument is greater that\n10:\n\n```erlang\n> Big = fun(X) -> if X > 10 -> true; true -> false end end.\n#Fun \n> lists:any(Big, [1,2,3,4]).\nfalse\n> lists:any(Big, [1,2,3,12,5]).\ntrue\n```","title":"any - Funs","ref":"funs.html#any"},{"type":"extras","doc":"`lists:all/2` has the same arguments as `any`:\n\n```erlang\nall(Pred, [H|T]) ->\n case Pred(H) of\n true -> all(Pred, T);\n false -> false\n end;\nall(Pred, []) ->\n true.\n```\n\nIt is `true` if the predicate applied to all elements in the list is `true`.\n\n```erlang\n> lists:all(Big, [1,2,3,4,12,6]).\nfalse\n> lists:all(Big, [12,13,14,15]).\ntrue\n```","title":"all - Funs","ref":"funs.html#all"},{"type":"extras","doc":"`lists:foreach/2` takes a function of one argument and a list of terms:\n\n```erlang\nforeach(F, [H|T]) ->\n F(H),\n foreach(F, T);\nforeach(F, []) ->\n ok.\n```\n\nThe function is applied to each argument in the list. `foreach` returns `ok`. It\nis only used for its side-effect:\n\n```erlang\n> lists:foreach(fun(X) -> io:format(\"~w~n\",[X]) end, [1,2,3,4]).\n1\n2\n3\n4\nok\n```","title":"foreach - Funs","ref":"funs.html#foreach"},{"type":"extras","doc":"`lists:foldl/3` takes a function of two arguments, an accumulator and a list:\n\n```erlang\nfoldl(F, Accu, [Hd|Tail]) ->\n foldl(F, F(Hd, Accu), Tail);\nfoldl(F, Accu, []) -> Accu.\n```\n\nThe function is called with two arguments. The first argument is the successive\nelements in the list. The second argument is the accumulator. The function must\nreturn a new accumulator, which is used the next time the function is called.\n\nIf you have a list of lists `L = [\"I\",\"like\",\"Erlang\"]`, then you can sum the\nlengths of all the strings in `L` as follows:\n\n```erlang\n> L = [\"I\",\"like\",\"Erlang\"].\n[\"I\",\"like\",\"Erlang\"]\n10> lists:foldl(fun(X, Sum) -> length(X) + Sum end, 0, L).\n11\n```\n\n`lists:foldl/3` works like a `while` loop in an imperative language:\n\n```erlang\nL = [\"I\",\"like\",\"Erlang\"],\nSum = 0,\nwhile( L != []){\n Sum += length(head(L)),\n L = tail(L)\nend\n```","title":"foldl - Funs","ref":"funs.html#foldl"},{"type":"extras","doc":"`lists:mapfoldl/3` simultaneously maps and folds over a list:\n\n```erlang\nmapfoldl(F, Accu0, [Hd|Tail]) ->\n {R,Accu1} = F(Hd, Accu0),\n {Rs,Accu2} = mapfoldl(F, Accu1, Tail),\n {[R|Rs], Accu2};\nmapfoldl(F, Accu, []) -> {[], Accu}.\n```\n\nThe following example shows how to change all letters in `L` to upper case and\nthen count them.\n\nFirst the change to upper case:\n\n```erlang\n> Upcase = fun(X) when $a = X + $A - $a;\n(X) -> X\nend.\n#Fun \n> Upcase_word =\nfun(X) ->\nlists:map(Upcase, X)\nend.\n#Fun \n> Upcase_word(\"Erlang\").\n\"ERLANG\"\n> lists:map(Upcase_word, L).\n[\"I\",\"LIKE\",\"ERLANG\"]\n```\n\nNow, the fold and the map can be done at the same time:\n\n```erlang\n> lists:mapfoldl(fun(Word, Sum) ->\n{Upcase_word(Word), Sum + length(Word)}\nend, 0, L).\n{[\"I\",\"LIKE\",\"ERLANG\"],11}\n```","title":"mapfoldl - Funs","ref":"funs.html#mapfoldl"},{"type":"extras","doc":"`lists:filter/2` takes a predicate of one argument and a list and returns all elements\nin the list that satisfy the predicate:\n\n```erlang\nfilter(F, [H|T]) ->\n case F(H) of\n true -> [H|filter(F, T)];\n false -> filter(F, T)\n end;\nfilter(F, []) -> [].\n```\n\n```erlang\n> lists:filter(Big, [500,12,2,45,6,7]).\n[500,12,45]\n```\n\nCombining maps and filters enables writing of very succinct code. For example,\nto define a set difference function `diff(L1, L2)` to be the difference between\nthe lists `L1` and `L2`, the code can be written as follows:\n\n```erlang\ndiff(L1, L2) ->\n filter(fun(X) -> not member(X, L2) end, L1).\n```\n\nThis gives the list of all elements in L1 that are not contained in L2.\n\nThe AND intersection of the list `L1` and `L2` is also easily defined:\n\n```erlang\nintersection(L1,L2) -> filter(fun(X) -> member(X,L1) end, L2).\n```","title":"filter - Funs","ref":"funs.html#filter"},{"type":"extras","doc":"`lists:takewhile/2` takes elements `X` from a list `L` as long as the predicate\n`P(X)` is true:\n\n```erlang\ntakewhile(Pred, [H|T]) ->\n case Pred(H) of\n true -> [H|takewhile(Pred, T)];\n false -> []\n end;\ntakewhile(Pred, []) ->\n [].\n```\n\n```erlang\n> lists:takewhile(Big, [200,500,45,5,3,45,6]).\n[200,500,45]\n```","title":"takewhile - Funs","ref":"funs.html#takewhile"},{"type":"extras","doc":"`lists:dropwhile/2` is the complement of `takewhile`:\n\n```erlang\ndropwhile(Pred, [H|T]) ->\n case Pred(H) of\n true -> dropwhile(Pred, T);\n false -> [H|T]\n end;\ndropwhile(Pred, []) ->\n [].\n```\n\n```erlang\n> lists:dropwhile(Big, [200,500,45,5,3,45,6]).\n[5,3,45,6]\n```","title":"dropwhile - Funs","ref":"funs.html#dropwhile"},{"type":"extras","doc":"`lists:splitwith/2` splits the list `L` into the two sublists `{L1, L2}`, where\n`L = takewhile(P, L)` and `L2 = dropwhile(P, L)`:\n\n```erlang\nsplitwith(Pred, L) ->\n splitwith(Pred, L, []).\n\nsplitwith(Pred, [H|T], L) ->\n case Pred(H) of\n true -> splitwith(Pred, T, [H|L]);\n false -> {reverse(L), [H|T]}\n end;\nsplitwith(Pred, [], L) ->\n {reverse(L), []}.\n```\n\n```erlang\n> lists:splitwith(Big, [200,500,45,5,3,45,6]).\n{[200,500,45],[5,3,45,6]}\n```","title":"splitwith - Funs","ref":"funs.html#splitwith"},{"type":"extras","doc":"So far, only functions that take funs as arguments have been described. More\npowerful functions, that themselves return funs, can also be written. The\nfollowing examples illustrate these type of functions.","title":"Funs Returning Funs - Funs","ref":"funs.html#funs-returning-funs"},{"type":"extras","doc":"`Adder(X)` is a function that given `X`, returns a new function `G` such that\n`G(K)` returns `K + X`:\n\n```erlang\n> Adder = fun(X) -> fun(Y) -> X + Y end end.\n#Fun \n> Add6 = Adder(6).\n#Fun \n> Add6(10).\n16\n```","title":"Simple Higher Order Functions - Funs","ref":"funs.html#simple-higher-order-functions"},{"type":"extras","doc":"The idea is to write something like:\n\n```erlang\n-module(lazy).\n-export([ints_from/1]).\nints_from(N) ->\n fun() ->\n [N|ints_from(N+1)]\n end.\n```\n\nThen proceed as follows:\n\n```erlang\n> XX = lazy:ints_from(1).\n#Fun \n> XX().\n[1|#Fun ]\n> hd(XX()).\n1\n> Y = tl(XX()).\n#Fun \n> hd(Y()).\n2\n```\n\nAnd so on. This is an example of \"lazy embedding\".","title":"Infinite Lists - Funs","ref":"funs.html#infinite-lists"},{"type":"extras","doc":"The following examples show parsers of the following type:\n\n```erlang\nParser(Toks) -> {ok, Tree, Toks1} | fail\n```\n\n`Toks` is the list of tokens to be parsed. A successful parse returns\n`{ok, Tree, Toks1}`.\n\n- `Tree` is a parse tree.\n- `Toks1` is a tail of `Tree` that contains symbols encountered after the\n structure that was correctly parsed.\n\nAn unsuccessful parse returns `fail`.\n\nThe following example illustrates a simple, functional parser that parses the\ngrammar:\n\n```text\n(a | b) & (c | d)\n```\n\nThe following code defines a function `pconst(X)` in the module `funparse`,\nwhich returns a fun that parses a list of tokens:\n\n```erlang\npconst(X) ->\n fun (T) ->\n case T of\n [X|T1] -> {ok, {const, X}, T1};\n _ -> fail\n end\n end.\n```\n\nThis function can be used as follows:\n\n```erlang\n> P1 = funparse:pconst(a).\n#Fun \n> P1([a,b,c]).\n{ok,{const,a},[b,c]}\n> P1([x,y,z]).\nfail\n```\n\nNext, the two higher order functions `pand` and `por` are defined. They combine\nprimitive parsers to produce more complex parsers.\n\nFirst `pand`:\n\n```erlang\npand(P1, P2) ->\n fun (T) ->\n case P1(T) of\n {ok, R1, T1} ->\n case P2(T1) of\n {ok, R2, T2} ->\n {ok, {'and', R1, R2}};\n fail ->\n fail\n end;\n fail ->\n fail\n end\n end.\n```\n\nGiven a parser `P1` for grammar `G1`, and a parser `P2` for grammar `G2`,\n`pand(P1, P2)` returns a parser for the grammar, which consists of sequences of\ntokens that satisfy `G1`, followed by sequences of tokens that satisfy `G2`.\n\n`por(P1, P2)` returns a parser for the language described by the grammar `G1` or\n`G2`:\n\n```erlang\npor(P1, P2) ->\n fun (T) ->\n case P1(T) of\n {ok, R, T1} ->\n {ok, {'or',1,R}, T1};\n fail ->\n case P2(T) of\n {ok, R1, T1} ->\n {ok, {'or',2,R1}, T1};\n fail ->\n fail\n end\n end\n end.\n```\n\nThe original problem was to parse the grammar `(a | b) & (c | d)`. The following\ncode addresses this problem:\n\n```erlang\ngrammar() ->\n pand(\n por(pconst(a), pconst(b)),\n por(pconst(c), pconst(d))).\n```\n\nThe following code adds a parser interface to the grammar:\n\n```erlang\nparse(List) ->\n (grammar())(List).\n```\n\nThe parser can be tested as follows:\n\n```erlang\n> funparse:parse([a,c]).\n{ok,{'and',{'or',1,{const,a}},{'or',1,{const,c}}}}\n> funparse:parse([a,d]).\n{ok,{'and',{'or',1,{const,a}},{'or',2,{const,d}}}}\n> funparse:parse([b,c]).\n{ok,{'and',{'or',2,{const,b}},{'or',1,{const,c}}}}\n> funparse:parse([b,d]).\n{ok,{'and',{'or',2,{const,b}},{'or',2,{const,d}}}}\n> funparse:parse([a,b]).\nfail\n```","title":"Parsing - Funs","ref":"funs.html#parsing"},{"type":"extras","doc":"\n# List Comprehensions","title":"List Comprehensions","ref":"list_comprehensions.html"},{"type":"extras","doc":"This section starts with a simple example, showing a generator and a filter:\n\n```erlang\n> [X || X <- [1,2,a,3,4,b,5,6], X > 3].\n[a,4,b,5,6]\n```\n\nThis is read as follows: The list of X such that X is taken from the list\n`[1,2,a,...]` and X is greater than 3.\n\nThe notation `X <- [1,2,a,...]` is a generator and the expression `X > 3` is a\nfilter.\n\nAn additional filter, [`is_integer(X)`](`is_integer/1`), can be added to\nrestrict the result to integers:\n\n```erlang\n> [X || X <- [1,2,a,3,4,b,5,6], is_integer(X), X > 3].\n[4,5,6]\n```\n\nGenerators can be combined. For example, the Cartesian product of two lists can\nbe written as follows:\n\n```erlang\n> [{X, Y} || X <- [1,2,3], Y <- [a,b]].\n[{1,a},{1,b},{2,a},{2,b},{3,a},{3,b}]\n```","title":"Simple Examples - List Comprehensions","ref":"list_comprehensions.html#simple-examples"},{"type":"extras","doc":"The well-known quick sort routine can be written as follows:\n\n```erlang\nsort([]) -> [];\nsort([_] = L) -> L;\nsort([Pivot|T]) ->\n sort([ X || X <- T, X = Pivot]).\n```\n\nThe expression `[X || X <- T, X = Pivot]` is the list of all elements in `T` that are greater\nthan or equal to `Pivot`.\n\nWith the algorithm above, a list is sorted as follows:\n\n- A list with zero or one element is trivially sorted.\n- For lists with more than one element:\n 1. The first element in the list is isolated as the pivot element.\n 1. The remaining list is partitioned into two sublists, such that:\n - The first sublist contains all elements that are smaller than the pivot\n element.\n - The second sublist contains all elements that are greater than or equal to\n the pivot element.\n 1. The sublists are recursively sorted by the same algorithm and the results\n are combined, resulting in a list consisting of:\n - All elements from the first sublist, that is all elements smaller than the\n pivot element, in sorted order.\n - The pivot element.\n - All elements from the second sublist, that is all elements greater than or\n equal to the pivot element, in sorted order.\n\n> #### Note {: .info }\n>\n> While the sorting algorithm as shown above serves as a nice example to\n> illustrate list comprehensions with filters, for real world use cases the\n> `m:lists` module contains sorting functions that are implemented in a more\n> efficient way.","title":"Quick Sort - List Comprehensions","ref":"list_comprehensions.html#quick-sort"},{"type":"extras","doc":"The following example generates all permutations of the elements in a list:\n\n```erlang\nperms([]) -> [[]];\nperms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].\n```\n\nThis takes `H` from `L` in all possible ways. The result is the set of all lists\n`[H|T]`, where `T` is the set of all possible permutations of `L`, with `H`\nremoved:\n\n```erlang\n> perms([b,u,g]).\n[[b,u,g],[b,g,u],[u,b,g],[u,g,b],[g,b,u],[g,u,b]]\n```","title":"Permutations - List Comprehensions","ref":"list_comprehensions.html#permutations"},{"type":"extras","doc":"Pythagorean triplets are sets of integers `{A,B,C}` such that\n`A**2 + B**2 = C**2`.\n\nThe function `pyth(N)` generates a list of all integers `{A,B,C}` such that\n`A**2 + B**2 = C**2` and where the sum of the sides is equal to, or less than,\n`N`:\n\n```erlang\npyth(N) ->\n [ {A,B,C} ||\n A <- lists:seq(1,N),\n B <- lists:seq(1,N),\n C <- lists:seq(1,N),\n A+B+C = pyth(3).\n[].\n> pyth(11).\n[].\n> pyth(12).\n[{3,4,5},{4,3,5}]\n> pyth(50).\n[{3,4,5},\n {4,3,5},\n {5,12,13},\n {6,8,10},\n {8,6,10},\n {8,15,17},\n {9,12,15},\n {12,5,13},\n {12,9,15},\n {12,16,20},\n {15,8,17},\n {16,12,20}]\n```\n\nThe following code reduces the search space and is more efficient:\n\n```erlang\npyth1(N) ->\n [{A,B,C} ||\n A <- lists:seq(1,N-2),\n B <- lists:seq(A+1,N-1),\n C <- lists:seq(B+1,N),\n A+B+C =< N,\n A*A+B*B == C*C ].\n```","title":"Pythagorean Triplets - List Comprehensions","ref":"list_comprehensions.html#pythagorean-triplets"},{"type":"extras","doc":"As an example, list comprehensions can be used to simplify some of the functions\nin `lists.erl`:\n\n```erlang\nappend(L) -> [X || L1 <- L, X <- L1].\nmap(Fun, L) -> [Fun(X) || X <- L].\nfilter(Pred, L) -> [X || X <- L, Pred(X)].\n```","title":"Simplifications With List Comprehensions - List Comprehensions","ref":"list_comprehensions.html#simplifications-with-list-comprehensions"},{"type":"extras","doc":"The scope rules for variables that occur in list comprehensions are as follows:\n\n- All variables that occur in a generator pattern are assumed to be \"fresh\"\n variables.\n- Any variables that are defined before the list comprehension, and that are\n used in filters, have the values they had before the list comprehension.\n- Variables cannot be exported from a list comprehension.\n\nAs an example of these rules, suppose you want to write the function `select`,\nwhich selects certain elements from a list of tuples. Suppose you write\n`select(X, L) -> [Y || {X, Y} <- L].` with the intention of extracting all\ntuples from `L`, where the first item is `X`.\n\nCompiling this gives the following diagnostic:\n\n```text\n./FileName.erl:Line: Warning: variable 'X' shadowed in generate\n```\n\nThis diagnostic warns that the variable `X` in the pattern is not the same as\nthe variable `X` that occurs in the function head.\n\nEvaluating `select` gives the following result:\n\n```erlang\n> select(b,[{a,1},{b,2},{c,3},{b,7}]).\n[1,2,3,7]\n```\n\nThis is not the wanted result. To achieve the desired effect, `select` must be\nwritten as follows:\n\n```erlang\nselect(X, L) -> [Y || {X1, Y} <- L, X == X1].\n```\n\nThe generator now contains unbound variables and the test has been moved into\nthe filter.\n\nThis now works as expected:\n\n```erlang\n> select(b,[{a,1},{b,2},{c,3},{b,7}]).\n[2,7]\n```\n\nAlso note that a variable in a generator pattern will shadow a variable with the\nsame name bound in a previous generator pattern. For example:\n\n```erlang\n> [{X,Y} || X <- [1,2,3], X=Y <- [a,b,c]].\n[{a,a},{b,b},{c,c},{a,a},{b,b},{c,c},{a,a},{b,b},{c,c}]\n```\n\nA consequence of the rules for importing variables into a list comprehensions is\nthat certain pattern matching operations must be moved into the filters and\ncannot be written directly in the generators.\n\nTo illustrate this, do _not_ write as follows:\n\n```erlang\nf(...) ->\n Y = ...\n [ Expression || PatternInvolving Y <- Expr, ...]\n ...\n```\n\nInstead, write as follows:\n\n```erlang\nf(...) ->\n Y = ...\n [ Expression || PatternInvolving Y1 <- Expr, Y == Y1, ...]\n ...\n```","title":"Variable Bindings in List Comprehensions - List Comprehensions","ref":"list_comprehensions.html#variable-bindings-in-list-comprehensions"},{"type":"extras","doc":"\n# Bit Syntax","title":"Bit Syntax","ref":"bit_syntax.html"},{"type":"extras","doc":"The complete specification for the bit syntax appears in the\n[Reference Manual](`e:system:expressions.md#bit-syntax-expressions`).\n\nIn Erlang, a Bin is used for constructing binaries and matching binary patterns.\nA Bin is written with the following syntax:\n\n```erlang\n< >\n```\n\nA Bin is a low-level sequence of bits or bytes. The purpose of a Bin is to\nenable construction of binaries:\n\n```erlang\nBin = < >\n```\n\nAll elements must be bound. Or match a binary:\n\n```erlang\n< > = Bin\n```\n\nHere, `Bin` is bound and the elements are bound or unbound, as in any match.\n\nA Bin does not need to consist of a whole number of bytes.\n\nA _bitstring_ is a sequence of zero or more bits, where the number of bits does\nnot need to be divisible by 8. If the number of bits is divisible by 8, the\nbitstring is also a binary.\n\nEach element specifies a certain _segment_ of the bitstring. A segment is a set\nof contiguous bits of the binary (not necessarily on a byte boundary). The first\nelement specifies the initial segment, the second element specifies the\nfollowing segment, and so on.\n\nThe following examples illustrate how binaries are constructed, or matched, and\nhow elements and tails are specified.","title":"Introduction - Bit Syntax","ref":"bit_syntax.html#introduction"},{"type":"extras","doc":"_Example 1:_ A binary can be constructed from a set of constants or a string\nliteral:\n\n```erlang\nBin11 = <<1, 17, 42>>,\nBin12 = <<\"abc\">>\n```\n\nThis gives two binaries of size 3, with the following evaluations:\n\n- [`binary_to_list(Bin11)`](`binary_to_list/1`) evaluates to `[1, 17, 42]`.\n- [`binary_to_list(Bin12)`](`binary_to_list/1`) evaluates to `[97, 98, 99]`.\n\n*Example 2:*Similarly, a binary can be constructed from a set of bound\nvariables:\n\n```erlang\nA = 1, B = 17, C = 42,\nBin2 = < >\n```\n\nThis gives a binary of size 4. Here, a _size expression_ is used for the\nvariable `C` to specify a 16-bits segment of `Bin2`.\n\n[`binary_to_list(Bin2)`](`binary_to_list/1`) evaluates to `[1, 17, 00, 42]`.\n\n_Example 3:_ A Bin can also be used for matching. `D`, `E`, and `F` are unbound\nvariables, and `Bin2` is bound, as in Example 2:\n\n```erlang\n< > = Bin2\n```\n\nThis gives `D = 273`, `E = 00`, and F binds to a binary of size 1:\n`binary_to_list(F) = [42]`.\n\n_Example 4:_ The following is a more elaborate example of matching. Here,\n`Dgram` is bound to the consecutive bytes of an IP datagram of IP protocol\nversion 4. The ambition is to extract the header and the data of the datagram:\n\n```erlang\n-define(IP_VERSION, 4).\n-define(IP_MIN_HDR_LEN, 5).\n\nDgramSize = byte_size(Dgram),\ncase Dgram of\n <> when HLen>=5, 4*HLen= \n OptsLen = 4*(HLen - ?IP_MIN_HDR_LEN),\n < > = RestDgram,\n ...\nend.\n```\n\nHere, the segment corresponding to the `Opts` variable has a _type modifier_,\nspecifying that `Opts` is to bind to a binary. All other variables have the\ndefault type equal to unsigned integer.\n\nAn IP datagram header is of variable length. This length is measured in the\nnumber of 32-bit words and is given in the segment corresponding to `HLen`. The\nminimum value of `HLen` is 5. It is the segment corresponding to `Opts` that is\nvariable, so if `HLen` is equal to 5, `Opts` becomes an empty binary.\n\nThe tail variables `RestDgram` and `Data` bind to binaries, as all tail\nvariables do. Both can bind to empty binaries.\n\nThe match of `Dgram` fails if one of the following occurs:\n\n- The first 4-bits segment of `Dgram` is not equal to 4.\n- `HLen` is less than 5.\n- The size of `Dgram` is less than `4*HLen`.","title":"Examples - Bit Syntax","ref":"bit_syntax.html#examples"},{"type":"extras","doc":"Notice that \"`B=<<1>>`\" will be interpreted as \"`B =< <1>>`\", which is a syntax\nerror. The correct way to write the expression is: `B = <<1>>`.","title":"Lexical Note - Bit Syntax","ref":"bit_syntax.html#lexical-note"},{"type":"extras","doc":"Each segment has the following general syntax:\n\n`Value:Size/TypeSpecifierList`\n\nThe `Size` or the `TypeSpecifier`, or both, can be omitted. Thus, the following\nvariants are allowed:\n\n- `Value`\n- `Value:Size`\n- `Value/TypeSpecifierList`\n\nDefault values are used when specifications are missing. The default values are\ndescribed in [Defaults](#defaults).\n\nThe `Value` part is any expression, when used in binary construction. Used in\nbinary matching, the `Value` part must be a literal or a variable. For more\ninformation about the `Value` part, see\n[Constructing Binaries and Bitstrings](#constructing-binaries-and-bitstrings)\nand [Matching Binaries](#matching-binaries).\n\nThe `Size` part of the segment multiplied by the unit in `TypeSpecifierList`\n(described later) gives the number of bits for the segment. In construction,\n`Size` is any expression that evaluates to an integer. In matching, `Size` must\nbe a constant expression or a variable.\n\nThe `TypeSpecifierList` is a list of type specifiers separated by hyphens.\n\n- **Type** - The most commonly used types are `integer`, `float`, and `binary`.\n See\n [Bit Syntax Expressions in the Reference Manual](`e:system:expressions.md#bit-syntax-expressions`)\n for a complete description.\n\n- **Signedness** - The signedness specification can be either `signed` or\n `unsigned`. Notice that signedness only matters for matching.\n\n- **Endianness** - The endianness specification can be either `big`, `little`,\n or `native`. Native-endian means that the endian is resolved at load time, to\n be either big-endian or little-endian, depending on what is \"native\" for the\n CPU that the Erlang machine is run on.\n\n- **Unit** - The unit size is given as `unit:IntegerLiteral`. The allowed range\n is 1-256. It is multiplied by the `Size` specifier to give the effective size\n of the segment. The unit size specifies the alignment for binary segments\n without size.\n\n_Example:_\n\n```text\nX:4/little-signed-integer-unit:8\n```\n\nThis element has a total size of 4\\*8 = 32 bits, and it contains a signed\ninteger in little-endian order.","title":"Segments - Bit Syntax","ref":"bit_syntax.html#segments"},{"type":"extras","doc":"The default type for a segment is integer. The default type\ndoes not depend on the value, even if the value is a literal. For example, the\ndefault type in `<<3.14>>` is integer, not float.\n\nThe default `Size` depends on the type. For integer it is 8. For float it is 64.\nFor binary it is all of the binary. In matching, this default value is only\nvalid for the last element. All other binary elements in matching must have a\nsize specification.\n\nThe default unit depends on the type. For `integer`, `float`, and `bitstring` it\nis 1. For binary it is 8.\n\nThe default signedness is `unsigned`.\n\nThe default endianness is `big`.","title":"Defaults - Bit Syntax","ref":"bit_syntax.html#defaults"},{"type":"extras","doc":"This section describes the rules for constructing binaries using the bit syntax.\nUnlike when constructing lists or tuples, the construction of a binary can fail\nwith a `badarg` exception.\n\nThere can be zero or more segments in a binary to be constructed. The expression\n`<<>>` constructs a zero length binary.\n\nEach segment in a binary can consist of zero or more bits. There are no\nalignment rules for individual segments of type `integer` and `float`. For\nbinaries and bitstrings without size, the unit specifies the alignment. Since\nthe default alignment for the `binary` type is 8, the size of a binary segment\nmust be a multiple of 8 bits, that is, only whole bytes.\n\n_Example:_\n\n```erlang\n< >\n```\n\nThe variable `Bin` must contain a whole number of bytes, because the `binary`\ntype defaults to `unit:8`. A `badarg` exception is generated if `Bin` consist\nof, for example, 17 bits.\n\nThe `Bitstring` variable can consist of any number of bits, for example, 0, 1,\n8, 11, 17, 42, and so on. This is because the default `unit` for bitstrings\nis 1.\n\nFor clarity, it is recommended not to change the unit size for binaries.\nInstead, use `binary` when you need byte alignment and `bitstring` when you need\nbit alignment.\n\nThe following example successfully constructs a bitstring of 7 bits, provided\nthat all of X and Y are integers:\n\n```erlang\n< >\n```\n\nAs mentioned earlier, segments have the following general syntax:\n\n`Value:Size/TypeSpecifierList`\n\nWhen constructing binaries, `Value` and `Size` can be any Erlang expression.\nHowever, for syntactical reasons, both `Value` and `Size` must be enclosed in\nparenthesis if the expression consists of anything more than a single literal or\na variable. The following gives a compiler syntax error:\n\n```erlang\n< >\n```\n\nThis expression must be rewritten into the following, to be accepted by the\ncompiler:\n\n```erlang\n<<(X+1):8>>\n```","title":"Constructing Binaries and Bitstrings - Bit Syntax","ref":"bit_syntax.html#constructing-binaries-and-bitstrings"},{"type":"extras","doc":"A literal string can be written instead of an element:\n\n```erlang\n<<\"hello\">>\n```\n\nThis is syntactic sugar for the following:\n\n```erlang\n<<$h,$e,$l,$l,$o>>\n```","title":"Including Literal Strings - Bit Syntax","ref":"bit_syntax.html#including-literal-strings"},{"type":"extras","doc":"This section describes the rules for matching binaries, using the bit syntax.\n\nThere can be zero or more segments in a binary pattern. A binary pattern can\noccur wherever patterns are allowed, including inside other patterns. Binary\npatterns cannot be nested. The pattern `<<>>` matches a zero length binary.\n\nEach segment in a binary can consist of zero or more bits. A segment of type\n`binary` must have a size evenly divisible by 8 (or divisible by the unit size,\nif the unit size has been changed). A segment of type `bitstring` has no\nrestrictions on the size. A segment of type `float` must have size 64 or 32.\n\nAs mentioned earlier, segments have the following general syntax:\n\n`Value:Size/TypeSpecifierList`\n\nWhen matching `Value`, value must be either a variable or an integer, or a\nfloating point literal. Expressions are not allowed.\n\n`Size` must be a\n[guard expression](`e:system:expressions.md#guard-expressions`), which can use\nliterals and previously bound variables. The following is not allowed:\n\n```erlang\nfoo(N, < >) ->\n {X,T}.\n```\n\nThe two occurrences of `N` are not related. The compiler will complain that the\n`N` in the size field is unbound.\n\nThe correct way to write this example is as follows:\n\n```erlang\nfoo(N, Bin) ->\n < > = Bin,\n {X,T}.\n```\n\n> #### Note {: .info }\n>\n> Before OTP 23, `Size` was restricted to be an integer or a variable bound to\n> an integer.","title":"Matching Binaries - Bit Syntax","ref":"bit_syntax.html#matching-binaries"},{"type":"extras","doc":"There is one exception to the rule that a variable that is used as size must be\npreviously bound. It is possible to match and bind a variable, and use it as a\nsize within the same binary pattern. For example:\n\n```erlang\nbar(< >) ->\n {Payload,Rest}.\n```\n\nHere `Sz` is bound to the value in the first byte of the binary. `Sz` is then\nused at the number of bytes to match out as a binary.\n\nStarting in OTP 23, the size can be a guard expression:\n\n```erlang\nbar(< >) ->\n {Payload,Rest}.\n```\n\nHere `Sz` is the combined size of the header and the payload, so we will need to\nsubtract one byte to get the size of the payload.","title":"Binding and Using a Size Variable - Bit Syntax","ref":"bit_syntax.html#binding-and-using-a-size-variable"},{"type":"extras","doc":"To match out the rest of a binary, specify a binary field without size:\n\n```erlang\nfoo(< >) ->\n```\n\nThe size of the tail must be evenly divisible by 8.\n\nTo match out the rest of a bitstring, specify a field without size:\n\n```erlang\nfoo(< >) ->\n```\n\nThere are no restrictions on the number of bits in the tail.","title":"Getting the Rest of the Binary or Bitstring - Bit Syntax","ref":"bit_syntax.html#getting-the-rest-of-the-binary-or-bitstring"},{"type":"extras","doc":"Appending to a binary in an efficient way can be done as follows:\n\n```erlang\ntriples_to_bin(T) ->\n triples_to_bin(T, <<>>).\n\ntriples_to_bin([{X,Y,Z} | T], Acc) ->\n triples_to_bin(T, < >);\ntriples_to_bin([], Acc) ->\n Acc.\n```","title":"Appending to a Binary - Bit Syntax","ref":"bit_syntax.html#appending-to-a-binary"},{"type":"extras","doc":"\n# Introduction\n\n[](){: #erlang-ref-manual }\n\nThis section is the Erlang reference manual. It describes the Erlang programming\nlanguage.","title":"Introduction","ref":"reference_manual.html"},{"type":"extras","doc":"The focus of the Erlang reference manual is on the language itself, not the\nimplementation of it. The language constructs are described in text and with\nexamples rather than formally specified. This is to make the manual more\nreadable. The Erlang reference manual is not intended as a tutorial.\n\nInformation about implementation of Erlang can, for example, be found, in the\nfollowing:\n\n- [System Principles](`e:system:system_principles.md`)\n\n Starting and stopping, boot scripts, code loading,\n [logging](`e:system:error_logging.md`),\n [creating target systems](`e:system:create_target.md`)\n\n- [Efficiency Guide](`e:system:efficiency_guide.md`)\n\n [Memory consumption](`e:system:memory.md`) and\n [system limits](`e:system:system_limits.md`).\n\n- ERTS User's Guide\n\n [Crash dumps](`e:erts:crash_dump.md`), [NIFs](`e:erts:erl_nif.md`),\n [drivers](`e:erts:driver.md`)","title":"Purpose - Introduction","ref":"reference_manual.html#purpose"},{"type":"extras","doc":"It is assumed that the reader has done some programming and is familiar with\nconcepts such as data types and programming language syntax.","title":"Prerequisites - Introduction","ref":"reference_manual.html#prerequisites"},{"type":"extras","doc":"In this section, the following terminology is used:\n\n- A _sequence_ is one or more items. For example, a clause body consists of a\n sequence of expressions. This means that there must be at least one\n expression.\n- A _list_ is any number of items. For example, an argument list can consist of\n zero, one, or more arguments.\n\nIf a feature has been added in R13A or later, this is mentioned in the text.","title":"Document Conventions - Introduction","ref":"reference_manual.html#document-conventions"},{"type":"extras","doc":"For a complete list of BIFs, their arguments and return values, see module `m:erlang`\nin ERTS.","title":"Complete List of BIFs - Introduction","ref":"reference_manual.html#complete-list-of-bifs"},{"type":"extras","doc":"The following are reserved words in Erlang:\n\n`after and andalso band begin bnot bor bsl bsr bxor case catch cond div else end fun if let maybe not of or orelse receive rem try when xor`\n\n**Note**: `cond` and `let`, while reserved, are currently not used by the\nlanguage.\n\n> #### Change {: .info }\n>\n> `maybe` is a reserved word only if feature `maybe_expr` is enabled. In\n> Erlang/OTP 25 and 26, `maybe_expr` is disabled by default. Starting from\n> Erlang/OTP 27, `maybe_expr` is enabled by default.","title":"Reserved Words - Introduction","ref":"reference_manual.html#reserved-words"},{"type":"extras","doc":"\n# Character Set and Source File Encoding","title":"Character Set and Source File Encoding","ref":"character_set.html"},{"type":"extras","doc":"The syntax of Erlang tokens allow the use of the full ISO-8859-1 (Latin-1)\ncharacter set. This is noticeable in the following ways:\n\n- All the Latin-1 printable characters can be used and are shown without the\n escape backslash convention.\n- Unquoted atoms and variables can use all Latin-1 letters.\n\n| _Octal_ | _Decimal_ |   | _Class_ |\n| --------- | --------- | ----- | ---------------------- |\n| 200 - 237 | 128 - 159 |   | Control characters |\n| 240 - 277 | 160 - 191 | \\- ¿ | Punctuation characters |\n| 300 - 326 | 192 - 214 | À - Ö | Uppercase letters |\n| 327 | 215 | × | Punctuation character |\n| 330 - 336 | 216 - 222 | Ø - Þ | Uppercase letters |\n| 337 - 366 | 223 - 246 | ß - ö | Lowercase letters |\n| 367 | 247 | ÷ | Punctuation character |\n| 370 - 377 | 248 - 255 | ø - ÿ | Lowercase letters |\n\n_Table: Character Classes_\n\nThe following tokens are allowed to also use Unicode characters outside of the\nLatin-1 range:\n\n- String literals. Example: `\"√π\"`\n- Character literals. Example: `$∑`\n- Comments in code.\n- Quoted atoms. Example: `'μs'`\n- Function names. Example: `'s_to_μs'(S) -> S * 1_000_000.`\n\nAtoms used as module names, application names, and node names are restricted to\nthe Latin-1 range.\n\n> #### Change {: .info }\n>\n> Support for Unicode in string literals, character literals, and comments was\n> introduced in Erlang/OTP R16B. Support for Unicode in atom and function names\n> was introduced in Erlang/OTP 20.","title":"Character Set - Character Set and Source File Encoding","ref":"character_set.html#character-set"},{"type":"extras","doc":"[](){: #encoding }\n\nThe Erlang source file `encoding` is selected by a comment in one of the first\ntwo lines of the source file. The first string that matches the regular\nexpression `coding\\s*[:=]\\s*([-a-zA-Z0-9])+` selects the encoding. If the\nmatching string is an invalid encoding, it is ignored. The valid encodings are\n`Latin-1` and `UTF-8`, where the case of the characters can be chosen freely.\n\nThe default Erlang source file encoding if no valid `coding` comment is present\nis UTF-8.\n\nTwo examples, both selecting Latin-1 as the source file encoding:\n\n```text\n%% For this file we have chosen encoding = Latin-1\n```\n\n```erlang\n%% -*- coding: latin-1 -*-\n```\n\n> #### Change {: .info }\n>\n> The default encoding for Erlang source files was changed from Latin-1 to UTF-8\n> in Erlang/OTP 17.0.","title":"Source File Encoding - Character Set and Source File Encoding","ref":"character_set.html#source-file-encoding"},{"type":"extras","doc":"\n# Data Types\n\nErlang provides a number of data types, which are listed in this section.\n\n[](){: #no_user_types }\n\nNote that Erlang has no user defined types, only composite types (data\nstructures) made of Erlang terms. This means that any function testing for a\ncomposite type, typically named `is_type/1`, might return `true` for a term that\ncoincides with the chosen representation. The corresponding functions for built\nin types do not suffer from this.","title":"Data Types","ref":"data_types.html"},{"type":"extras","doc":"A piece of data of any data type is called a _term_.","title":"Terms - Data Types","ref":"data_types.html#terms"},{"type":"extras","doc":"There are two types of numeric literals, _integers_ and _floats_. Besides the\nconventional notation, there are two Erlang-specific notations:\n\n- `$`_`char`_ \n ASCII value or unicode code-point of the character _`char`_.\n- _`base`_`#`_`value`_ \n Integer with the base _`base`_, which must be an integer in the range 2\n through 36.\n\nLeading zeroes are ignored. Single underscore characters (`_`) can be\ninserted between digits as a visual separator.\n\n_Examples:_\n\n```text\n1> 42.\n42\n2> -1_234_567_890.\n-1234567890\n3> $A.\n65\n4> $\\n.\n10\n5> 2#101.\n5\n6> 16#1f.\n31\n7> 16#4865_316F_774F_6C64.\n5216630098191412324\n8> 2.3.\n2.3\n9> 2.3e3.\n2.3e3\n10> 2.3e-3.\n0.0023\n11> 1_234.333_333\n1234.333333\n12> 36#helloworld.\n1767707668033969\n```\n\n[](){: #numeric_comparisons }","title":"Number - Data Types","ref":"data_types.html#number"},{"type":"extras","doc":"Both integers and floats share the same linear order. That is, `1` compares less\nthan `2.4`, `3` compares greater than `2.99999`, and `5` is equal to `5.0`.\n\nWhen wanting to compare an integer with another integer or a float with another\nfloat, it may be tempting to use the term equivalence operators (`=:=`, `=/=`)\nor pattern matching. This works for integers which has a distinct representation\nfor every number, but there's a surprising edge case for floating-point as the\nlatter has two representations for zero which are considered different by the\nterm equivalence operators and pattern matching.\n\nIf you wish to compare floating-point numbers _numerically_, use the regular\ncomparison operators (such as `==`) and add guards that require both the\narguments to be floating-point.\n\n> #### Note {: .info }\n>\n> Prior to OTP 27, the term equivalence operators had a bug where they\n> considered `0.0` and `-0.0` to be the same term. Legacy code that makes\n> equality comparisons on floating-point zero should migrate to using the\n> equal-to (`==`) operator with [`is_float/1`](`is_float/1`) guards, and\n> compiler warnings have been added to that effect. These can be silenced by\n> writing `+0.0` instead, which is the same as `0.0` but makes the compiler\n> interpret the comparison as being purposely made against `0.0`.\n>\n> Note that this does _not_ break compatibility with IEEE 754 which mandates\n> that `0.0` and `-0.0` should compare equal: they are equal when interpreted as\n> numbers (`==`), and unequal when interpreted as opaque terms (`=:=`).\n\n[](){: #float_representation_problem }\n\n_Examples_:\n\n```erlang\n1> 0.0 =:= +0.0.\ntrue\n2> 0.0 =:= -0.0.\nfalse\n3> +0.0 =:= -0.0.\nfalse\n4> +0.0 == -0.0.\ntrue\n```","title":"Comparisons - Data Types","ref":"data_types.html#comparisons"},{"type":"extras","doc":"When working with floats you may not see what you expect when printing or doing\narithmetic operations. This is because floats are represented by a fixed number\nof bits in a base-2 system while printed floats are represented with a base-10\nsystem. Erlang uses 64-bit floats. Here are examples of this phenomenon:\n\n```erlang\n1> 0.1+0.2.\n0.30000000000000004\n```\n\nThe real numbers `0.1` and `0.2` cannot be represented exactly as floats.\n\n```erlang\n1> {36028797018963968.0, 36028797018963968 == 36028797018963968.0,\n 36028797018963970.0, 36028797018963970 == 36028797018963970.0}.\n{3.602879701896397e16, true,\n 3.602879701896397e16, false}.\n```\n\nThe value `36028797018963968` can be represented exactly as a float value but\nErlang's pretty printer rounds `36028797018963968.0` to `3.602879701896397e16`\n(`=36028797018963970.0`) as all values in the range\n`[36028797018963966.0, 36028797018963972.0]` are represented by\n`36028797018963968.0`.\n\nFor more information about floats and issues with them see:\n\n- [What Every Programmer Should Know About Floating-Point Arithmetic](https://floating-point-gui.de/)\n- [0\\.30000000000000004.com/](https://0.30000000000000004.com/)\n- [Floating Point Arithmetic: Issues and Limitations](https://docs.python.org/3/tutorial/floatingpoint.html)\n\nIf you need to work with exact decimal fractions, for instance to represent\nmoney, it is recommended to use a library that handles that, or work in\ncents instead of dollars or euros so that decimal fractions are not needed.\n\nAlso note that Erlang's floats do not exactly match IEEE 754 floats,\nin that neither _Inf_ nor _NaN_ are supported in Erlang. Any\noperation that would result in _NaN_, _+Inf_, or _-Inf_, will instead raise\na `badarith` exception.\n\n_Examples_:\n\n```erlang\n1> 1.0 / 0.0.\n** exception error: an error occurred when evaluating an arithmetic expression\n in operator '/'/2\n called as 1.0 / 0.0\n2> 0.0 / 0.0.\n** exception error: an error occurred when evaluating an arithmetic expression\n in operator '/'/2\n called as 0.0 / 0.0\n```","title":"Representation of Floating Point Numbers - Data Types","ref":"data_types.html#representation-of-floating-point-numbers"},{"type":"extras","doc":"An atom is a literal, a constant with name. An atom is to be enclosed in single\nquotes (`'`) if it does not begin with a lower-case letter or if it contains other\ncharacters than alphanumeric characters, underscore (`_`), or `@`.\n\n_Examples:_\n\n```text\nhello\nphone_number\nname@node\n'Monday'\n'phone number'\n```","title":"Atom - Data Types","ref":"data_types.html#atom"},{"type":"extras","doc":"A bit string is used to store an area of untyped memory.\n\nBit strings are expressed using the [bit syntax](expressions.md#bit-syntax-expressions).\n\nBit strings that consist of a number of bits that are evenly divisible\nby eight are called _binaries_.\n\n_Examples:_\n\n```text\n1> <<10,20>>.\n<<10,20>>\n2> <<\"ABC\">>.\n<<\"ABC\">>\n3> <<1:1,0:1>>.\n<<2:2>>\n```\n\nThe [`is_bitstring/1`](`erlang:is_bitstring/1`) BIF tests whether a\nterm is a bit string, and the [`is_binary/1`](`erlang:is_binary/1`)\nBIF tests whether a term is a binary.\n\n_Examples:_\n\n```erlang\n1> is_bitstring(<<1:1>>).\ntrue\n2> is_binary(<<1:1>>).\nfalse\n3> is_binary(<<42>>).\ntrue\n\n```\n\nFor more examples, see [Programming Examples](`e:system:bit_syntax.md`).","title":"Bit Strings and Binaries - Data Types","ref":"data_types.html#bit-strings-and-binaries"},{"type":"extras","doc":"A term that is [unique](`e:system:system_limits.md#unique_references`)\namong connected nodes. A reference is created by calling the\n[`make_ref/0`](`erlang:make_ref/0`) BIF. The\n[`is_reference/1`](`erlang:is_reference/1`) BIF tests whether a term\nis a reference.\n\n_Examples:_\n\n```erlang\n1> Ref = make_ref().\n#Ref<0.76482849.3801088007.198204>\n2> is_reference(Ref).\ntrue\n```","title":"Reference - Data Types","ref":"data_types.html#reference"},{"type":"extras","doc":"A fun is a functional object. Funs make it possible to create an anonymous\nfunction and pass the function itself — not its name — as argument to other\nfunctions.\n\n_Examples:_\n\n```erlang\n1> Fun1 = fun (X) -> X+1 end.\n#Fun \n2> Fun1(2).\n3\n```\n\nThe [`is_function/1`](`erlang:is_function/1`) and [`is_function/2`](`erlang:is_function/2`)\nBIFs tests whether a term is a fun.\n\n_Examples_:\n\n```erlang\n1> F = fun() -> ok end.\n#Fun \n2> is_function(F).\ntrue\n3> is_function(F, 0).\ntrue\n4> is_function(F, 1).\nfalse\n```\n\nRead more about funs in [Fun Expressions](expressions.md#fun-expressions). For more\nexamples, see [Programming Examples](`e:system:funs.md`).","title":"Fun - Data Types","ref":"data_types.html#fun"},{"type":"extras","doc":"A port identifier identifies an Erlang port.\n\n[`open_port/2`](`open_port/2`) returns a port identifier. The\n[`is_port/1`](`erlang:is_port/1`) BIF tests whether a term is a port\nidentifier.\n\nRead more about ports in [Ports and Port Drivers](ports.md).","title":"Port Identifier - Data Types","ref":"data_types.html#port-identifier"},{"type":"extras","doc":"Pid is an abbreviation for process identifier. Each process has a Pid which\nidentifies the process. Pids are unique among processes that are alive on\nconnected nodes. However, a Pid of a terminated process may be reused as a Pid\nfor a new process after a while.\n\nThe BIF [`self/0`](`erlang:self/0`) returns the Pid of the calling process. When\n[creating a new process](ref_man_processes.md#process-creation), the parent\nprocess will be able to get the Pid of the child process either via the return\nvalue, as is the case when calling the [`spawn/3`](`erlang:spawn/3`) BIF, or via\na message, which is the case when calling the\n[`spawn_request/5`](`erlang:spawn_request/5`) BIF. A Pid is typically used when\nwhen sending a process a [signal](ref_man_processes.md#signals). The\n[`is_pid/1`](`erlang:is_pid/1`) BIF tests whether a term is a Pid.\n\n_Example:_\n\n```erlang\n-module(m).\n-export([loop/0]).\n\nloop() ->\n receive\n who_are_you ->\n io:format(\"I am ~p~n\", [self()]),\n loop()\n end.\n\n1> P = spawn(m, loop, []).\n<0.58.0>\n2> P ! who_are_you.\nI am <0.58.0>\nwho_are_you\n```\n\nRead more about processes in [Processes](ref_man_processes.md).","title":"Pid - Data Types","ref":"data_types.html#pid"},{"type":"extras","doc":"A tuple is a compound data type with a fixed number of terms:\n\n```text\n{Term1,...,TermN}\n```\n\nEach term `Term` in the tuple is called an _element_. The number of elements is\nsaid to be the _size_ of the tuple.\n\nThere exists a number of BIFs to manipulate tuples.\n\n_Examples:_\n\n```erlang\n1> P = {adam,24,{july,29}}.\n{adam,24,{july,29}}\n2> element(1,P).\nadam\n3> element(3,P).\n{july,29}\n4> P2 = setelement(2,P,25).\n{adam,25,{july,29}}\n5> tuple_size(P).\n3\n6> tuple_size({}).\n0\n7> is_tuple({a,b,c}).\ntrue\n```","title":"Tuple - Data Types","ref":"data_types.html#tuple"},{"type":"extras","doc":"A map is a compound data type with a variable number of key-value associations:\n\n```text\n#{Key1 => Value1, ..., KeyN => ValueN}\n```\n\nEach key-value association in the map is called an _association pair_. The key\nand value parts of the pair are called _elements_. The number of association\npairs is said to be the _size_ of the map.\n\nThere exists a number of BIFs to manipulate maps.\n\n_Examples:_\n\n```erlang\n1> M1 = #{name => adam, age => 24, date => {july,29}}.\n#{age => 24,date => {july,29},name => adam}\n2> maps:get(name, M1).\nadam\n3> maps:get(date, M1).\n{july,29}\n4> M2 = maps:update(age, 25, M1).\n#{age => 25,date => {july,29},name => adam}\n5> map_size(M).\n3\n6> map_size(#{}).\n0\n```\n\nA collection of maps processing functions are found in module `m:maps`\nin STDLIB.\n\nRead more about maps in [Map Expressions](expressions.md#map-expressions).\n\n> #### Change {: .info }\n>\n> Maps were introduced as an experimental feature in Erlang/OTP R17. Their\n> functionality was extended and became fully supported in Erlang/OTP 18.","title":"Map - Data Types","ref":"data_types.html#map"},{"type":"extras","doc":"A list is a compound data type with a variable number of terms.\n\n```text\n[Term1,...,TermN]\n```\n\nEach term `Term` in the list is called an _element_. The number of elements is\nsaid to be the _length_ of the list.\n\nFormally, a list is either the empty list `[]` or consists of a _head_ (first\nelement) and a _tail_ (remainder of the list). The _tail_ is also a list. The\nlatter can be expressed as `[H|T]`. The notation `[Term1,...,TermN]` above is\nequivalent with the list `[Term1|[...|[TermN|[]]]]`.\n\n_Example:_\n\n`[]` is a list, thus \n`[c|[]]` is a list, thus \n`[b|[c|[]]]` is a list, thus \n`[a|[b|[c|[]]]]` is a list, or in short `[a,b,c]`\n\nA list where the tail is a list is sometimes called a _proper list_. It is\nallowed to have a list where the tail is not a list, for example, `[a|b]`.\nHowever, this type of list is of little practical use.\n\n_Examples:_\n\n```erlang\n1> L1 = [a,2,{c,4}].\n[a,2,{c,4}]\n2> [H|T] = L1.\n[a,2,{c,4}]\n3> H.\na\n4> T.\n[2,{c,4}]\n5> L2 = [d|T].\n[d,2,{c,4}]\n6> length(L1).\n3\n7> length([]).\n0\n```\n\nA collection of list processing functions are found in module\n`m:lists` in STDLIB.","title":"List - Data Types","ref":"data_types.html#list"},{"type":"extras","doc":"Strings are enclosed in double quotes (\"), but is not a data type in Erlang.\nInstead, a string `\"hello\"` is shorthand for the list `[$h,$e,$l,$l,$o]`, that\nis, `[104,101,108,108,111]`.\n\nTwo adjacent string literals are concatenated into one. This is done in the\ncompilation.\n\n_Example:_\n\n```text\n\"string\" \"42\"\n```\n\nis equivalent to\n\n```text\n\"string42\"\n```\n\n> #### Change {: .info }\n>\n> Starting with Erlang/OTP 27 two adjacent string literals have to be separated\n> by white space, or otherwise it is a syntax error. This avoids possible confusion\n> with _triple-quoted strings_.\n\n[](){: #tqstring } Strings can also be written as _triple-quoted strings_, which\ncan be _indented_ over multiple lines to follow the indentation of the\nsurrounding code. They are also _verbatim_, that is, they do not allow escape\nsequences, and thereby do not need double quote characters to be escaped.\n\n> #### Change {: .info }\n>\n> Triple-quoted strings were added in Erlang/OTP 27. Before that 3 consecutive\n> double quote characters had a different meaning. There were absolutely no good\n> reason to write such a character sequence before triple-quoted strings\n> existed, but there _are_ some gotchas; see the\n> [Warning ](data_types.md#triple-quoted-strings-warning) at the end of this\n> description of triple-quoted strings.\n\nExample, with verbatim double quote characters:\n\n```text\n\"\"\"\n Line \"1\"\n Line \"2\"\n \"\"\"\n```\n\nThat is equivalent to the normal single quoted string (which also allows\nnewlines):\n\n```text\n\"Line \\\"1\\\"\nLine \\\"2\\\"\"\n```\n\nThe opening and the closing line has got the delimiters: the `\"\"\"` characters.\nThe lines between them are the content lines. The newline on the opening line is\nnot regarded as string content, nor is the newline on the last content line.\n\nThe indentation is defined by the white space character sequence preceding the\ndelimiter on the closing line. That character sequence is stripped from all\ncontent lines. There can only be white space before the delimiter on the closing\nline, or else it is regarded as a content line.\n\nThe opening line is not allowed to have any characters other than white space\nafter the delimiter, and all content lines must start with the defined\nindentation character sequence, otherwise the string has a syntax error.\n\nHere is a larger example:\n\n```text\nX = \"\"\"\n First line starting with two spaces\n Not escaped: \"\\t \\r \\xFF\" and \"\"\"\n\n \"\"\"\n```\n\nThat corresponds to the normal string:\n\n```text\nX = \" First line starting with two spaces\nNot escaped: \\\"\\\\t \\\\r \\\\xFF\\\" and \\\"\\\"\\\"\n\"\n```\n\nIt is possible to write consecutive double quote characters on the\nbeginning of a content line by using more double quote characters as\ndelimiters. This is a string that contains exactly four double quote\ncharacters, using a delimiter with five double quote characters:\n\n```text\n\"\"\"\"\"\n\"\"\"\"\n\"\"\"\"\"\n```\n\nThese strings are all the empty string:\n\n```text\n\"\"\n```\n\n```text\n\"\"\"\n\"\"\"\n```\n\n```text\n\"\"\"\n\n \"\"\"\n```\n\n[](){: #triple-quoted-strings-warning }\n\n> #### Warning {: .warning }\n>\n> Before Erlang/OTP 27, when triple-quoted strings were added, the character\n> sequence `\"\"\"` was interpreted as `\"\" \"`, which means concatenating the empty\n> string to the string that follows. All sequences of an odd number of double\n> quote characters had this meaning.\n>\n> Any even number of double quote characters was interpreted as a sequence of\n> empty strings, that were concatenated (to the empty string).\n>\n> There was no reason to write such character sequences. But should that have\n> happened, the meaning has probably changed with the introduction of triple-quoted\n> strings.\n>\n> The compiler preprocessor was patched in Erlang/OTP 26.1 to warn about 3 or\n> more sequential double quote characters. In Erlang/OTP 26.2 this was improved\n> to warn about adjacent string literals without intervening white space, which\n> also covers the same problem at a string end.\n>\n> If the compiler should emit such a warning, please change such double quote\n> character sequences to have a whitespace after every second quote character,\n> remove redundant empty strings, or write them as one string. This makes the\n> code more readable, and means the same thing in all releases.","title":"String - Data Types","ref":"data_types.html#string"},{"type":"extras","doc":"A _sigil_ is a prefix to a string literal. It is not a data type in Erlang, but\na shorthand notation that indicates how to interpret the string literal. Sigils\noffer mainly two things: a compact way to create UTF-8 encoded binary strings,\nand a way to write verbatim strings (not having to escape `\\` characters),\nuseful for regular expressions, for example.\n\nA sigil starts with the Tilde character (`~`) followed by a name defining the\nsigil type.\n\nImmediately after follows the sigil content; a character sequence between\ncontent delimiters. The allowed delimiters are these start-end delimiter pairs:\n`() [] {} <>`, or these characters that are both start and end delimiters:\n``/ | ' \" ` #``. [Triple-quote](data_types.md#tqstring) string delimiters may\nalso be used.\n\nThe [character escaping rules ](data_types.md#escape-sequences)for the sigil\ncontent depends on the sigil type. When the sigil content is _verbatim_, there\nis no escape character. The sigil content simply ends when the end delimiter is\nfound, so it is impossible to have the end delimiter character in the string\ncontent. The set of delimiters is fairly generous, and in most cases it is\npossible to choose an end delimiter that's not in the literal string content.\n\n[Triple-quote](data_types.md#tqstring) string delimiters allow choosing a larger\nnumber of quote characters in the end delimiter, than whatever is in the string\ncontent, which thereby facilitates any content also with a sequence of `\"`\ncharacters at the start of a line even for a _verbatim_ string.\n\nThe Sigils are:\n\n- **`~`** - The Vanilla (default) Sigil. Shorthand for a UTF-8 encoded\n `t:binary/0`. This sigil does not affect the character escaping rules, so with\n triple-quoted string delimiters they are the same as for `~B`, and for other\n string delimiters they are the same as for `~b`.\n\n- **`~b`** - The Binary Sigil. Shorthand for a\n [UTF-8 encoded `binary()`](`t:unicode:unicode_binary/0`), as if calling\n [`unicode:characters_to_binary/1` ](`unicode:characters_to_binary/1`)on the\n sigil content. Character escaping rules are the same as for `~s`.\n\n- **`~B`** - The Verbatim Binary Sigil. As `~b`, but the sigil content is\n verbatim.\n\n- **`~s`** - The String Sigil. Shorthand for a\n [`string()`](`t:erlang:string/0`), that is, a `[char()]` which is a list of\n Unicode codepoints.\n [Character escaping rules ](data_types.md#escape-sequences)are the same as for\n a normal `t:string/0`. Using this sigil on a regular string does effectively\n nothing.\n\n- **`~S`** - The Verbatim String Sigil. As `~s`, but the sigil content is\n verbatim. Using this sigil on a triple-quoted string does effectively nothing.\n\nExamples\n\n```text\n<<\"\\\"\\\\µA\\\"\"/utf8>> = <<$\",$\\\\,194,181,$A,$\">> =\n ~b\"\"\"\n \"\\\\µA\"\n \"\"\" = ~b'\"\\\\µA\"' =\n ~B\"\"\"\n \"\\µA\"\n \"\"\" = ~B<\"\\µA\"> =\n ~\"\"\"\n \"\\µA\"\n \"\"\" = ~\"\\\"\\\\µA\\\"\" = ~/\"\\\\µA\"/\n```\n\n```text\n[$\",$\\\\,$µ,$A,$\"] =\n ~s\"\"\"\n \"\\\\µA\"\n \"\"\" = ~s\"\\\"\\\\µA\\\"\" = ~s[\"\\\\µA\"] =\n ~S\"\"\"\n \"\\µA\"\n \"\"\" = ~S(\"\\µA\") =\n \"\"\"\n \"\\µA\"\n \"\"\" = \"\\\"\\\\µA\\\"\"\n```\n\nAdjacent strings are concatenated in the compilation, but that is not possible\nwith sigils, since they are transformed into terms that in general may not be\nconcatenated. So, `\"a\" \"b\"` is equivalent to `\"ab\"`, but `~s\"a\" \"b\"` or\n`~s\"a\" ~s\"b\"` is a syntax error. `~s\"a\" ++ \"b\"`, however, evaluates to `\"ab\"`\nsince both operands to the `++` operator are strings.\n\n> #### Change {: .info }\n>\n> Sigils were introduced in Erlang/OTP 27","title":"Sigil - Data Types","ref":"data_types.html#sigil"},{"type":"extras","doc":"A record is a data structure for storing a fixed number of elements. It has\nnamed fields and is similar to a struct in C. However, a record is not a true\ndata type. Instead, record expressions are translated to tuple expressions\nduring compilation. Therefore, record expressions are not understood by the\nshell unless special actions are taken. For details, see module `m:shell`\nin STDLIB.\n\n_Examples:_\n\n```erlang\n-module(person).\n-export([new/2]).\n\n-record(person, {name, age}).\n\nnew(Name, Age) ->\n #person{name=Name, age=Age}.\n\n1> person:new(ernie, 44).\n{person,ernie,44}\n```\n\nRead more about records in [Records](ref_man_records.md). More examples are\nfound in [Programming Examples](`e:system:prog_ex_records.md`).","title":"Record - Data Types","ref":"data_types.html#record"},{"type":"extras","doc":"There is no Boolean data type in Erlang. Instead the atoms `true` and `false`\nare used to denote Boolean values. The [`is_boolean/1`](`erlang:is_boolean/1`)\nBIF tests whether a term is a boolean.\n\n_Examples:_\n\n```erlang\n1> 2 =< 3.\ntrue\n2> true or false.\ntrue\n3> is_boolean(true).\ntrue\n4> is_boolean(false).\ntrue\n5> is_boolean(ok).\nfalse\n```","title":"Boolean - Data Types","ref":"data_types.html#boolean"},{"type":"extras","doc":"Within strings (`\"`\\-delimited), quoted atoms, and the content of\n[`~b` and `~s` sigils](data_types.md#sigil), the following escape sequences are\nrecognized:\n\n| _Sequence_ | _Description_ |\n| --------------------------- | ------------------------------------------------------------------------------------- |\n| `\\b` | Backspace (ASCII code 8) |\n| `\\d` | Delete (ASCII code 127) |\n| `\\e` | Escape (ASCII code 27) |\n| `\\f` | Form Feed (ASCII code 12) |\n| `\\n` | Line Feed/Newline (ASCII code 10) |\n| `\\r` | Carriage Return (ASCII code 13) |\n| `\\s` | Space (ASCII code 32) |\n| `\\t` | (Horizontal) Tab (ASCII code 9) |\n| `\\v` | Vertical Tab (ASCII code 11) |\n| `\\`XYZ, `\\`YZ, `\\`Z | Character with octal representation XYZ, YZ or Z |\n| `\\xXY` | Character with hexadecimal representation XY |\n| `\\x{`X...`}` | Character with hexadecimal representation; X... is one or more hexadecimal characters |\n| `\\^a`...`\\^z` `\\^A`...`\\^Z` | Control A to control Z |\n| `\\^@` | NUL (ASCII code 0) |\n| `\\^[` | Escape (ASCII code 27) |\n| `\\^\\` | File Separator (ASCII code 28) |\n| `\\^]` | Group Separator (ASCII code 29) |\n| `\\^^` | Record Separator (ASCII code 30) |\n| `\\^_` | Unit Separator (ASCII code 31) |\n| `\\^?` | Delete (ASCII code 127) |\n| `\\'` | Single quote |\n| `\\\"` | Double quote |\n| `\\\\` | Backslash |\n\n_Table: Recognized Escape Sequences_\n\n> #### Change {: .info }\n>\n> As of Erlang/OTP 26, the value of `$\\^?` has been changed to be 127 (Delete),\n> instead of 31. Previous releases would allow any character following `$\\^`; as\n> of Erlang/OTP 26, only the documented characters are allowed.\n\nWithin [triple-quoted strings](data_types.md#tqstring), escape sequences are not\nrecognized. The only text that cannot be written in a triple-quoted string is\nthree consecutive double quote characters at the beginning of a line (preceded\nonly by whitespace). This limitation can be worked around by using more double\nquote characters for the string delimiters than in the string. Any number three\nor above is allowed for the start delimiter and the end delimiter is the same as\nthe start delimiter.\n\nWhen triple-quote string delimiters are used with the\n[`~`, `~B` or `~S` sigils ](data_types.md#sigil)the same applies, but for the\n[`~b` or `~s` sigils ](data_types.md#sigil)the escape sequences for normal\nstrings, above, are used.\n\n> #### Change {: .info }\n>\n> Triple-quoted strings and sigils were introduced in Erlang/OTP 27.","title":"Escape Sequences - Data Types","ref":"data_types.html#escape-sequences"},{"type":"extras","doc":"There are a number of BIFs for type conversions.\n\n_Examples:_\n\n```erlang\n1> atom_to_list(hello).\n\"hello\"\n2> list_to_atom(\"hello\").\nhello\n3> binary_to_list(<<\"hello\">>).\n\"hello\"\n4> binary_to_list(<<104,101,108,108,111>>).\n\"hello\"\n5> list_to_binary(\"hello\").\n<<104,101,108,108,111>>\n6> float_to_list(7.0).\n\"7.00000000000000000000e+00\"\n7> list_to_float(\"7.000e+00\").\n7.0\n8> integer_to_list(77).\n\"77\"\n9> list_to_integer(\"77\").\n77\n10> tuple_to_list({a,b,c}).\n[a,b,c]\n11> list_to_tuple([a,b,c]).\n{a,b,c}\n12> term_to_binary({a,b,c}).\n<<131,104,3,100,0,1,97,100,0,1,98,100,0,1,99>>\n13> binary_to_term(<<131,104,3,100,0,1,97,100,0,1,98,100,0,1,99>>).\n{a,b,c}\n14> binary_to_integer(<<\"77\">>).\n77\n15> integer_to_binary(77).\n<<\"77\">>\n16> float_to_binary(7.0).\n<<\"7.00000000000000000000e+00\">>\n17> binary_to_float(<<\"7.000e+00\">>).\n7.0\n```","title":"Type Conversions - Data Types","ref":"data_types.html#type-conversions"},{"type":"extras","doc":"\n# Pattern Matching","title":"Pattern Matching","ref":"patterns.html"},{"type":"extras","doc":"Variables are bound to values through the _pattern matching_ mechanism. Pattern\nmatching occurs when evaluating the `case`, `receive`, `try`, and\nthe match operator (`=`) expressions.\n\nIn pattern matching, a left-hand side [pattern](expressions.md#patterns) is\nmatched against a right-hand side [term](expressions.md#terms). If the matching\nsucceeds, any unbound variables in the pattern become bound. If the matching\nfails, an exception is raised.\n\n_Examples:_\n\n```erlang\n1> X.\n** 1:1: variable 'X' is unbound **\n2> X = 2.\n2\n3> X + 1.\n3\n4> {X, Y} = {1, 2}.\n** exception error: no match of right hand side value {1,2}\n5> {X, Y} = {2, 3}.\n{2,3}\n6> Y.\n3\n```","title":"Pattern Matching - Pattern Matching","ref":"patterns.html#pattern-matching"},{"type":"extras","doc":"\n# Modules","title":"Modules","ref":"modules.html"},{"type":"extras","doc":"Erlang code is divided into _modules_. A module consists of a sequence of\nattributes and function declarations, each terminated by a period (`.`).\n\n_Example:_\n\n```erlang\n-module(m). % module attribute\n-export([fact/1]). % module attribute\n\nfact(N) when N>0 -> % beginning of function declaration\n N * fact(N-1); % |\nfact(0) -> % |\n 1. % end of function declaration\n```\n\nFor a description of function declarations, see\n[Function Declaration Syntax](ref_man_functions.md).","title":"Module Syntax - Modules","ref":"modules.html#module-syntax"},{"type":"extras","doc":"A _module attribute_ defines a certain property of a module.\n\nA module attribute consists of a tag and a value:\n\n```text\n-Tag(Value).\n```\n\n`Tag` must be an atom, while `Value` must be a literal term. As a convenience in\nuser-defined attributes, if the literal term `Value` has the syntax `Name/Arity`\n(where `Name` is an atom and `Arity` a positive integer), the term `Name/Arity`\nis translated to `{Name,Arity}`.\n\nAny module attribute can be specified. The attributes are stored in the compiled\ncode and can be retrieved by calling `Module:module_info(attributes)`, or by\nusing the module [beam_lib](`beam_lib:chunks/2`) in STDLIB.\n\nSeveral module attributes have predefined meanings. Some of them have arity two,\nbut user-defined module attributes must have arity one.","title":"Module Attributes - Modules","ref":"modules.html#module-attributes"},{"type":"extras","doc":"Pre-defined module attributes is to be placed before any function declaration.\n\n- **`-module(Module).`** - Module declaration, defining the name of the module.\n The name `Module`, an atom, is to be same as the file name minus the extension\n `.erl`. Otherwise [code loading](code_loading.md#loading) does not work as\n intended.\n\n This attribute is to be specified first and is the only mandatory attribute.\n\n- **`-export(Functions).`** - Exported functions. Specifies which of the\n functions, defined within the module, that are visible from outside the\n module.\n\n `Functions` is a list `[Name1/Arity1, ..., NameN/ArityN]`, where each `NameI`\n is an atom and `ArityI` an integer.\n\n- **`-import(Module, Functions).`** - Imported functions. Can be called the same\n way as local functions, that is, without any module prefix.\n\n `Module`, an atom, specifies which module to import functions from.\n `Functions` is a list similar as for `export`.\n\n- **`-moduledoc(Documentation).` or `-moduledoc Documentation.`** - The user\n documentation for this module. The allowed values for `Documentation` are the\n same as for [`-doc`](modules.md#documentation-attributes).\n\n See the [Documentation](documentation.md) for more details about how\n to use `-moduledoc`.\n\n- **`-compile(Options).`** - Compiler options. `Options` is a single option or a\n list of options. This attribute is added to the option list when compiling the\n module. See module `m:compile` in Compiler.\n\n- **`-vsn(Vsn).`** - Module version. `Vsn` is any literal term and can be\n retrieved using `beam_lib:version/1`.\n\n If this attribute is not specified, the version defaults to the MD5 checksum\n of the module.\n\n- **`-on_load(Function).`** - This attribute names a function that is to be run\n automatically when a module is loaded. For more information, see\n [Running a Function When a Module is Loaded](code_loading.md#on_load).\n\n- **`-nifs(Functions).`{: #nifs_attribute }** - Specifies which of the\n functions, defined within the module, that may be loaded as NIFs with\n `erlang:load_nif/2`.\n\n `Functions` is a list `[Name1/Arity1, ..., NameN/ArityN]`, where each `NameI`\n is an atom and `ArityI` an integer.\n\n While not strictly necessary, it is recommended to use `-nifs()` attribute in\n any module that load NIFs, to allow the compiler to make better decisions\n regarding optimizations.\n\n There is no need to add `-nifs([])` in modules that do not load NIFs. The lack\n of any call to `erlang:load_nif/2`, from within the module, is enough for the\n compiler to draw the same conclusion.\n\n > #### Change {: .info }\n >\n > The special meaning for the `-nifs()` attribute was introduced in Erlang/OTP\n > 25.0. In previous releases, `-nifs()` was accepted, but had no special\n > meaning.","title":"Pre-Defined Module Attributes - Modules","ref":"modules.html#pre-defined-module-attributes"},{"type":"extras","doc":"It is possible to specify that the module is the callback module for a\n_behaviour_:\n\n```erlang\n-behaviour(Behaviour).\n```\n\nThe atom `Behaviour` gives the name of the behaviour, which can be a\nuser-defined behaviour or one of the following OTP standard behaviours:\n\n- `gen_server`\n- `gen_statem`\n- `gen_event`\n- `supervisor`\n\nThe spelling `behavior` is also accepted.\n\nThe callback functions of the module can be specified either directly by the\nexported function `behaviour_info/1`:\n\n```erlang\nbehaviour_info(callbacks) -> Callbacks.\n```\n\nor by a `-callback` attribute for each callback function:\n\n```erlang\n-callback Name(Arguments) -> Result.\n```\n\nHere, `Arguments` is a list of zero or more arguments. The `-callback` attribute\nis to be preferred since the extra type information can be used by tools to\nproduce documentation or find discrepancies.\n\nRead more about behaviours and callback modules in\n[OTP Design Principles](`e:system:spec_proc.md#behaviours`).","title":"Behaviour Module Attribute - Modules","ref":"modules.html#behaviour-module-attribute"},{"type":"extras","doc":"The same syntax as for module attributes is used for record definitions:\n\n```erlang\n-record(Record, Fields).\n```\n\nRecord definitions are allowed anywhere in a module, also among the function\ndeclarations. Read more in [Records](ref_man_records.md).","title":"Record Definitions - Modules","ref":"modules.html#record-definitions"},{"type":"extras","doc":"The same syntax as for module attributes is used by the preprocessor, which\nsupports file inclusion, macros, and conditional compilation:\n\n```erlang\n-include(\"SomeFile.hrl\").\n-define(Macro, Replacement).\n```\n\nRead more in [Preprocessor](macros.md).","title":"Preprocessor - Modules","ref":"modules.html#preprocessor"},{"type":"extras","doc":"The same syntax as for module attributes is used for changing the pre-defined\nmacros `?FILE` and `?LINE`:\n\n```erlang\n-file(File, Line).\n```\n\nThis attribute is used by tools, such as Yecc, to inform the compiler that the\nsource program is generated by another tool. It also indicates the\ncorrespondence of source files to lines of the original user-written file, from\nwhich the source program is produced.","title":"Setting File and Line - Modules","ref":"modules.html#setting-file-and-line"},{"type":"extras","doc":"A similar syntax as for module attributes is used for specifying types and\nfunction specifications:\n\n```erlang\n-type my_type() :: atom() | integer().\n-spec my_function(integer()) -> integer().\n```\n\nRead more in [Types and Function specifications](typespec.md).\n\nThe description is based on\n[EEP8 - Types and function specifications](http://www.erlang.org/eeps/eep-0008.html),\nwhich is not to be further updated.","title":"Types and function specifications - Modules","ref":"modules.html#types-and-function-specifications"},{"type":"extras","doc":"The module attribute `-doc(Documentation)` is used to provide user documentation\nfor a function/type/callback:\n\n```erlang\n-doc(\"Example documentation\").\nexample() -> ok.\n```\n\nThe attribute should be placed just before the entity it documents.The\nparenthesis are optional around `Documentation`. The allowed values for\n`Documentation` are:\n\n- **[literal string](data_types.md#string) or\n [utf-8 encoded binary string](expressions.md#unicode-segments)** - The string\n documenting the entity. Any literal string is allowed, so both\n [triple quoted strings](data_types.md#tqstring) and\n [sigils](data_types.md#sigil) that translate to literal strings can be used.\n The following examples are equivalent:\n\n ```erlang\n -doc(\"Example \\\"docs\\\"\").\n -doc(<<\"Example \\\"docs\\\"\"/utf8>>).\n -doc ~S/Example \"docs\"/.\n -doc \"\"\"\n Example \"docs\"\n \"\"\"\n -doc ~B|Example \"docs\"|.\n ```\n\n For clarity it is recommended to use either normal `\"strings\"` or triple\n quoted strings for documentation attributes.\n\n- **`{file, ` `t:file:name/0` `}`** - Read the contents of filename and use\n that as the documentation string.\n\n- **`false`** - Set the current entity as hidden, that is, it should not be\n listed as an available function and has no documentation.\n\n- **`Metadata :: `[`map()`](`t:erlang:map/0`)** - Metadata about the current\n entity. Some of the keys in the metadata have a special meaning. See\n [Moduledoc metadata](`e:system:documentation.md#moduledoc-metadata`) and\n [Doc metadata](`e:system:documentation.md#doc-metadata`) for more details.\n\nIt is possible to have multiple Metadata doc attributes per entity, but only a\nsingle documentation string entry is allowed.\n\nSee the [Documentation](documentation.md) guide in the Erlang Reference Manual\nfor more details.","title":"Documentation attributes - Modules","ref":"modules.html#documentation-attributes"},{"type":"extras","doc":"While not a module attribute, but rather a directive (since it might affect\nsyntax), there is the `-feature(..)` directive used for enabling and disabling\n[features](`e:system:features.md#features`).\n\nThe syntax is similar to that of an attribute, but has two arguments:\n\n```erlang\n-feature(FeatureName, enable | disable).\n```\n\nNote that the [feature directive](macros.md#feature-directive) can only appear\nin a prefix of the module.","title":"The feature directive - Modules","ref":"modules.html#the-feature-directive"},{"type":"extras","doc":"Comments can be placed anywhere in a module except within strings and\nquoted atoms. A comment begins with the character `%`, and continues\nup to but not including the next end of line. A comment has no effect,\nbeing essentially equivalent to white space.","title":"Comments - Modules","ref":"modules.html#comments"},{"type":"extras","doc":"The compiler automatically inserts the two special, exported functions into each\nmodule:\n\n- `Module:module_info/0`\n- `Module:module_info/1`\n\nWhen called, these functions retrieve information about the module.","title":"module_info/0 and module_info/1 functions - Modules","ref":"modules.html#module_info-0-and-module_info-1-functions"},{"type":"extras","doc":"The `module_info/0` function in each module returns a list of\n`{Key,Value}` tuples with information about the module. At the time\nwriting, the list contain tuples having the following `Key`s:\n`module`, `attributes`, `compile`, `exports`, and `md5`. The order\nand number of tuples may change without prior notice.","title":"module_info/0 - Modules","ref":"modules.html#module_info-0"},{"type":"extras","doc":"The call `module_info(Key)`, where `Key` is an atom, returns a single piece of\ninformation about the module.\n\nThe following values are allowed for `Key`:\n\n- **`module`** - Returns an atom representing the module name.\n\n- **`attributes`** - Returns a list of `{AttributeName,ValueList}` tuples, where\n `AttributeName` is the name of an attribute, and `ValueList` is a list of\n values. Notice that a given attribute can occur more than once in the list\n with different values if the attribute occurs more than once in the module.\n\n The list of attributes becomes empty if the module is stripped with\n `beam_lib:strip/1`.\n\n- **`compile`** - Returns a list of tuples with information about how the module\n was compiled. This list is empty if the module has been stripped with\n `beam_lib:strip/1`.\n\n- **`md5`** - Returns a binary representing the MD5 checksum of the module.\n\n- **`exports`** - Returns a list of `{Name,Arity}` tuples with all exported\n functions in the module.\n\n- **`functions`** - Returns a list of `{Name,Arity}` tuples with all functions\n in the module.\n\n- **`nifs`** - Returns a list of `{Name,Arity}` tuples with all NIF functions in\n the module.","title":"module_info/1 - Modules","ref":"modules.html#module_info-1"},{"type":"extras","doc":"\n# Documentation\n\nDocumentation in Erlang is done through the `-moduledoc` and `-doc`\n[attributes](modules.md#module-attributes). For example:\n\n```erlang\n-module(arith).\n-moduledoc \"\"\"\nA module for basic arithmetic.\n\"\"\".\n\n-export([add/2]).\n\n-doc \"Adds two numbers.\".\nadd(One, Two) -> One + Two.\n```\n\nThe `-moduledoc` attribute has to be located before the first `-doc` attribute\nor function declaration. It documents the overall purpose of the module.\n\nThe `-doc` attribute always precedes the [function](ref_man_functions.md) or\n[attribute](modules.md#module-attributes) it documents. The\nattributes that can be documented are\n[user-defined types](typespec.md#type-declarations-of-user-defined-types)\n(`-type` and `-opaque`) and\n[behaviour module attributes](modules.md#behaviour-module-attribute)\n(`-callback`).\n\nBy default the format used for documentation attributes is\n[Markdown](https://en.wikipedia.org/wiki/Markdown) but that can be changed by\nsetting\n[module documentation metadata](#moduledoc-metadata).\n\nA good starting point to writing Markdown is\n[Basic writing and formatting syntax](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax).\n\nFor details on what is allowed to be part of the `-moduledoc` and `-doc`\nattributes, see\n[Documentation Attributes](modules.md#documentation-attributes).\n\n`-doc` attributes have been available since Erlang/OTP 27.","title":"Documentation","ref":"documentation.html"},{"type":"extras","doc":"It is possible to add metadata to the documentation entry. You do this by adding\na `-moduledoc` or `-doc` attribute with a map as argument. For example:\n\n```erlang\n-module(arith).\n-moduledoc \"\"\"\nA module for basic arithmetic.\n\"\"\".\n-moduledoc #{since => \"1.0\"}.\n\n-export([add/2]).\n\n-doc \"Adds two numbers.\".\n-doc(#{since => \"1.0\"}).\nadd(One, Two) -> One + Two.\n```\n\nThe metadata is used by documentation tools to provide extra information to the\nuser. There can be multiple metadata documentation entries, in which case the\nmaps will be merged with the latest taking precedence if there are duplicate\nkeys. Example:\n\n```erlang\n-doc \"Adds two numbers.\".\n-doc #{since => \"1.0\", author => \"Joe\"}.\n-doc #{since => \"2.0\"}.\nadd(One, Two) -> One + Two.\n```\n\nThis will result in a metadata entry of `#{since => \"2.0\", author => \"Joe\"}`.\n\nThe keys and values in the metadata map can be any type, but it is recommended\nthat only [atoms](data_types.md#atom) are used for keys and\n[strings](data_types.md#string) for the values.","title":"Documentation metadata - Documentation","ref":"documentation.html#documentation-metadata"},{"type":"extras","doc":"The `-moduledoc` and `-doc` can also be placed in external files. To do so use\n`-doc {file, \"path/to/doc.md\"}` to point to the documentation. The path used is\nrelative to the file where the `-doc` attribute is located. For example:\n\n```markdown\n%% doc/add.md\nAdds two numbers.\n```\n\nand\n\n```erlang\n%% src/arith.erl\n-doc({file, \"../doc/add.md\"}).\nadd(One, Two) -> One + Two.\n```","title":"External documentation files - Documentation","ref":"documentation.html#external-documentation-files"},{"type":"extras","doc":"The module description should include details on how to use the API and examples\nof the different functions working together. Here is a good place to use images\nand other diagrams to better show the usage of the module. Instead of writing a\nlong text in the `moduledoc` attribute, it could be better to break it out into\nan external page.\n\nThe `moduledoc` attribute should start with a short paragraph describing the\nmodule and then go into greater details. For example:\n\n````erlang\n-module(arith).\n-moduledoc \"\"\"\n A module for basic arithmetic.\n\n This module can be used to add and subtract values. For example:\n\n ```erlang\n 1> arith:substract(arith:add(2, 3), 1).\n 4\n ```\n \"\"\".\n````","title":"Documenting a module - Documentation","ref":"documentation.html#documenting-a-module"},{"type":"extras","doc":"There are three reserved metadata keys for `-moduledoc`:\n\n- `since` - Shows in which version of the application the module was added.\n If this is added, all functions, types, and callbacks within will also receive\n the same `since` value unless specified in the metadata of the function, type\n or callback.\n- `deprecated` - Shows a text in the documentation explaining that it is\n deprecated and what to use instead.\n- `format` - The format to use for all documentation in this module. The\n default is `text/markdown`. It should be written using the\n [mime type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types)\n of the format.\n\nExample:\n\n```erlang\n-moduledoc {file, \"../doc/arith.asciidoc\"}.\n-moduledoc #{since => \"0.1\", format => \"text/asciidoc\"}.\n-moduledoc #{deprecated => \"Use the Erlang arithmetic operators instead.\"}.\n```","title":"Moduledoc metadata - Documentation","ref":"documentation.html#moduledoc-metadata"},{"type":"extras","doc":"Functions, types, and callbacks can be documented using the `-doc` attribute.\nEach entry should start with a short paragraph describing the purpose of entity,\nand then go into greater detail in needed.\n\nIt is not recommended to include images or diagrams in this documentation as it\nis used by IDEs and `\\c:h/1` to show the documentation to the user.\n\nFor example:\n\n````erlang\n-doc \"\"\"\nA number that can be used by the arith module.\n\nWe use a special number here so that we know\nthat this number comes from this module.\n\"\"\".\n-opaque number() :: {arith, erlang:number()}.\n\n-doc \"\"\"\nAdds two numbers.","title":"Documenting functions, user-defined types, and callbacks - Documentation","ref":"documentation.html#documenting-functions-user-defined-types-and-callbacks"},{"type":"extras","doc":"```\n1> arith:add(arith:number(1), arith:number(2)). {number, 3}\n```\n\"\"\".\n-spec add(number(), number()) -> number().\nadd({number, One}, {number, Two}) -> {number, One + Two}.\n````","title":"Example: - Documentation","ref":"documentation.html#example"},{"type":"extras","doc":"There are four reserved metadata keys for `-doc`:\n\n- `since => unicode:chardata()` - Shows which version of the application the\n module was added.\n- `deprecated => unicode:chardata()` - Shows a text in the documentation\n explaining that it is deprecated and what to use instead. The compiler will\n automatically insert this key if there is a `-deprecated` attribute marking a\n function as deprecated.\n- `equiv => unicode:chardata() | F/A | F(...)` - Notes that this function is equivalent to\n another function in this module. The equivalence can be described using either\n `Func/Arity`, `Func(Args)` or a [unicode string](`t:unicode:chardata/0`). For example:\n\n ```erlang\n -doc #{equiv => add/3}.\n add(One, Two) -> add(One, Two, []).\n add(One, Two, Options) -> ...\n ```\n\n or\n\n ```erlang\n -doc #{equiv => add(One, Two, [])}.\n -spec add(One :: number(), Two :: number()) -> number().\n add(One, Two) -> add(One, Two, []).\n add(One, Two, Options) -> ...\n ```\n\n The entry into the [EEP-48](`e:kernel:eep48_chapter.md`) doc chunk metadata is\n the value converted to a string.\n\n- `exported => boolean()` - A `t:boolean/0` signifying if the entry is `exported`\n or not. This value is automatically set by the compiler and should not be set\n by the user.","title":"Doc metadata - Documentation","ref":"documentation.html#doc-metadata"},{"type":"extras","doc":"The doc signature is a short text shown to describe the function and its arguments.\nBy default it is determined by looking at the names of the arguments in the\n`-spec` or function. For example:\n\n```erlang\nadd(One, Two) -> One + Two.\n\n-spec sub(One :: integer(), Two :: integer()) -> integer().\nsub(X, Y) -> X - Y.\n```\n\nwill have a signature of `add(One, Two)` and `sub(One, Two)`.\n\nFor types or callbacks, the signature is derived from the type or callback\nspecification. For example:\n\n```erlang\n-type number(Value) :: {number, Value}.\n%% signature will be `number(Value)`\n\n-opaque number() :: {number, number()}.\n%% signature will be `number()`\n\n-callback increment(In :: number()) -> Out.\n%% signature will be `increment(In)`\n\n-callback increment(In) -> Out when In :: number().\n%% signature will be `increment(In)`\n```\n\nIf it is not possible to \"easily\" figure out a nice signature from the code, the\nMFA syntax is used instead. For example: `add/2`, `number/1`, `increment/1`\n\nIt is possible to supply a custom signature by placing it as the first line of the\n`-doc` attribute. The provided signature must be in the form of a function\ndeclaration up until the `->`. For example:\n\n```erlang\n-doc \"\"\"\nadd(One, Two)\n\nAdds two numbers.\n\"\"\".\nadd(A, B) -> A + B.\n```\n\nWill create the signature `add(One, Two)`. The signature will be removed from the\ndocumentation string, so in the example above only the text `\"Adds two numbers\"`\nwill be part of the documentation. This works for functions, types, and\ncallbacks.","title":"Doc signatures - Documentation","ref":"documentation.html#doc-signatures"},{"type":"extras","doc":"When writing documentation in Markdown, links are automatically found in any\ninline code segment that looks like an MFA. For example:\n\n```erlang\n-doc \"See `sub/2` for more details\".\n```\n\nwill create a link to the `sub/2` function in the current module if it exists.\nOne can also use `` `sub/2` ``as the link target. For example:\n\n```erlang\n-doc \"See [subtract](`sub/2`) for more details\".\n-doc \"See [`sub/2`] for more details\".\n-doc \"\"\"\nSee [subtract] for more details\n\n[subtract]: `sub/2`\n\"\"\".\n-doc \"\"\"\nSee [subtract][1] for more details\n\n[1]: `sub/2`\n\"\"\".\n```\n\nThe above examples result in the same link being created.\n\nThe link can also other entities:\n\n- `remote functions` - Use `module:function/arity` syntax.\n\nExample:\n\n```erlang\n-doc \"See `arith:sub/2` for more details\".\n```\n\n- `modules` - Write the module with a `m` prefix. Use anchors to jump to a\n specific place in the module.\n\nExample:\n\n```erlang\n-doc \"See `m:arith` for more details\".\n-doc \"See `m:arith#anchor` for more details\".\n```\n\n- `types` - Use the same syntax as for local/remote function but add a `t`\n prefix.\n\nExample:\n\n```erlang\n-doc \"See `t:number/0` for more details\".\n-doc \"See `t:arith:number/0` for more details\".\n```\n\n- `callbacks` - Use the same syntax as for local/remote function but add a `c`\n prefix.\n\nExample:\n\n```erlang\n-doc \"See `c:increment/0` for more details\".\n-doc \"See `c:arith:increment/0` for more details\".\n```\n\n- `extra pages` - For extra pages in the current application use a normal link,\n for example \"`[release notes](notes.md)`\". For extra pages in another\n application use the `e` prefix and state which application the page belongs\n to. One can also use anchors to jump to a specific place in the page.\n\nExample:\n\n```erlang\n-doc \"See `e:stdlib:unicode_usage` for more details\".\n-doc \"See `e:stdlib:unicode_usage#notes-about-raw-filenames` for more details\".\n```","title":"Links in Markdown - Documentation","ref":"documentation.html#links-in-markdown"},{"type":"extras","doc":"An Erlang `m:application` normally consists of various public and private\nmodules. That is, modules that should be used by other applications and modules\nthat should not. By default all modules in an application are visible, but by\nsetting `-moduledoc false.` specific modules can be hidden from being listed as\npart of the available API.\n\nAn Erlang [module](modules.md) consists of public and private functions and type\nattributes. By default, all exported functions, exported types and callbacks are\nconsidered visible and part of the modules public API. In addition, any\nnon-exported type that is referred to by any other visible type attribute is\nalso visible, but not considered to be part of the public API. For example:\n\n```erlang\n-export([example/0]).\n\n-type private() :: one.\n-spec example() -> private().\nexample() -> one.\n```\n\nin the above code, the function `example/0` is exported and it referenced the\nun-exported type `private/0`. Therefore both `example/0` and `private/0` will be\nmarked as visible. The `private/0` type will have the metadata field `exported`\nset to `false` to show that it is not part of the public API.\n\nIf you want to make a visible entity hidden you need to set the `-doc` attribute\nto `false`. Let us revisit our previous example:\n\n```erlang\n-export([example/0]).\n\n-type private() :: one.\n-spec example() -> private().\n-doc false.\nexample() -> one.\n```\n\nThe function `example/0` is exported but explicitly marked as hidden; therefore\nboth `example/0` and `private/0` will be hidden.\n\nAny documentation added to an automatically hidden entity (non-exported function\nor type) is ignored and will generate a warning. Such functions can be\ndocumented using comments.","title":"What is visible versus hidden? - Documentation","ref":"documentation.html#what-is-visible-versus-hidden"},{"type":"extras","doc":"The Erlang compiler will by default insert documentation into\n[EEP-48](`e:kernel:eep48_chapter.md`) documentation chunks when compiling a module.\nBy passing the [no_docs](`m:compile#no_docs`) flag to `compile:file/1`,\nor `+no_docs` to [erlc](`e:erts:erlc_cmd.md`), no documentation chunk is inserted.\n\nThe documentation can then be retrieved using `code:get_doc/1`, or viewed using\nthe shell built-in command [`h/1`](`\\\\c:h/1`). For example:\n\n```text\n1> h(arith).\n\n arith\n\n A module for basic arithmetic.\n\n2> h(arith, add).\n\n add(One, Two)\n\n Adds two numbers.\n```","title":"Compiling and getting documentation - Documentation","ref":"documentation.html#compiling-and-getting-documentation"},{"type":"extras","doc":"[ExDoc](https://hexdocs.pm/ex_doc/) has built-in support to generate\ndocumentation from Markdown. The simplest way is by using the\n[rebar3_ex_doc](https://hexdocs.pm/rebar3_ex_doc) plugin. To set up a\nrebar3 project to use [ExDoc](https://hexdocs.pm/ex_doc/) to generate\ndocumentation add the following to your `rebar3.config`.\n\n```erlang\n%% Enable the plugin\n{plugins, [rebar3_ex_doc]}.\n\n{ex_doc, [\n {extras, [\"README.md\"]},\n {main, \"README.md\"},\n {source_url, \"https://github.com/namespace/your_app\"}\n]}.\n```\n\nWhen configured you can run `rebar3 ex_doc` to generate the\ndocumentation to `doc/index.html`. For more details and options see\nthe [rebar3_ex_doc](https://hexdocs.pm/rebar3_ex_doc) documentation.\n\nYou can also download the\n[release escript bundle](https://github.com/elixir/ex_doc/releases/latest) from\ngithub and run it from the command line. The documentation for using the escript\nis found by running `ex_doc --help`.\n\nIf you are writing documentation that will be using\n[ExDoc](https://hexdocs.pm/ex_doc/) to generate HTML/ePub it is highly\nrecommended to read its documentation.","title":"Using ExDoc to generate HTML/ePub documentation - Documentation","ref":"documentation.html#using-exdoc-to-generate-html-epub-documentation"},{"type":"extras","doc":"\n# Functions\n\n[](){: #syntax }","title":"Functions","ref":"ref_man_functions.html"},{"type":"extras","doc":"A _function declaration_ is a sequence of function clauses separated by\nsemicolons, and terminated by a period (`.`).\n\nA _function clause_ consists of a _clause head_ and a _clause body_, separated by\n`->`.\n\nA clause _head_ consists of the function name, an argument list, and an optional\nguard sequence beginning with the keyword `when`:\n\n```erlang\nName(Pattern11,...,Pattern1N) [when GuardSeq1] ->\n Body1;\n...;\nName(PatternK1,...,PatternKN) [when GuardSeqK] ->\n BodyK.\n```\n\nThe function name is an atom. Each argument is a pattern.\n\nThe number of arguments `N` is the _arity_ of the function. A function is\nuniquely defined by the module name, function name, and arity. That is, two\nfunctions with the same name and in the same module, but with different arities\nare two different functions.\n\nA function named `f` in module `mod` and with arity `N` is often denoted as\n`mod:f/N`.\n\nA clause _body_ consists of a sequence of expressions separated by comma (`,`):\n\n```text\nExpr1,\n...,\nExprN\n```\n\nValid Erlang expressions and guard sequences are described in\n[Expressions](expressions.md).\n\n_Example:_\n\n```erlang\nfact(N) when N > 0 -> % first clause head\n N * fact(N-1); % first clause body\n\nfact(0) -> % second clause head\n 1. % second clause body\n```\n\n[](){: #eval }","title":"Function Declaration Syntax - Functions","ref":"ref_man_functions.html#function-declaration-syntax"},{"type":"extras","doc":"When a function `M:F/N` is called, first the code for the function is located.\nIf the function cannot be found, an `undef` runtime error occurs. Notice that\nthe function must be exported to be visible outside the module it is defined in.\n\nIf the function is found, the function clauses are scanned sequentially until a\nclause is found that fulfills both of the following two conditions:\n\n1. The patterns in the clause head can be successfully matched against the given\n arguments.\n1. The guard sequence, if any, is true.\n\nIf such a clause cannot be found, a `function_clause` runtime error occurs.\n\nIf such a clause is found, the corresponding clause body is evaluated. That is,\nthe expressions in the body are evaluated sequentially and the value of the last\nexpression is returned.\n\nConsider the function `fact`:\n\n```erlang\n-module(mod).\n-export([fact/1]).\n\nfact(N) when N > 0 ->\n N * fact(N - 1);\nfact(0) ->\n 1.\n```\n\nAssume that you want to calculate the factorial for 1:\n\n```text\n1> mod:fact(1).\n```\n\nEvaluation starts at the first clause. The pattern `N` is matched against\nargument 1. The matching succeeds and the guard (`N > 0`) is true, thus `N` is\nbound to 1, and the corresponding body is evaluated:\n\n```erlang\nN * fact(N-1) => (N is bound to 1)\n1 * fact(0)\n```\n\nNow, `fact(0)` is called, and the function clauses are scanned\nsequentially again. First, the pattern `N` is matched against 0. The\nmatching succeeds, but the guard (`N > 0`) is false. Second, the\npattern `0` is matched against the argument `0`. The matching succeeds\nand the body is evaluated:\n\n```text\n1 * fact(0) =>\n1 * 1 =>\n1\n```\n\nEvaluation has succeed and `mod:fact(1)` returns 1.\n\nIf `mod:fact/1` is called with a negative number as argument, no clause head\nmatches. A `function_clause` runtime error occurs.","title":"Function Evaluation - Functions","ref":"ref_man_functions.html#function-evaluation"},{"type":"extras","doc":"If the last expression of a function body is a function call, a\n_tail-recursive call_ is done. This is to ensure that no system\nresources, for example, call stack, are consumed. This means that an\ninfinite loop using tail-recursive calls will not exhaust the call\nstack and can (in principle) run forever.\n\n_Example:_\n\n```erlang\nloop(N) ->\n io:format(\"~w~n\", [N]),\n loop(N+1).\n```\n\nThe earlier factorial example is a counter-example. It is not\ntail-recursive, since a multiplication is done on the result of the recursive\ncall to `fact(N-1)`.","title":"Tail recursion - Functions","ref":"ref_man_functions.html#tail-recursion"},{"type":"extras","doc":"Built-In Functions (BIFs) are implemented in C code in the runtime\nsystem. BIFs do things that are difficult or impossible to implement\nin Erlang. Most of the BIFs belong to module `m:erlang`, but there\nare also BIFs belonging to a few other modules, for example `m:lists`\nand `m:ets`.\n\nThe most commonly used BIFs belonging to `m:erlang` are _auto-imported_. They do\nnot need to be prefixed with the module name. Which BIFs that are auto-imported\nis specified in the `m:erlang` module in ERTS. For example, standard-type\nconversion BIFs like `atom_to_list` and BIFs allowed in guards can be called\nwithout specifying the module name.\n\n_Examples:_\n\n```erlang\n1> tuple_size({a,b,c}).\n3\n2> atom_to_list('Erlang').\n\"Erlang\"\n```","title":"Built-In Functions (BIFs) - Functions","ref":"ref_man_functions.html#built-in-functions-bifs"},{"type":"extras","doc":"\n# Types and Function Specifications","title":"Types and Function Specifications","ref":"typespec.html"},{"type":"extras","doc":"Erlang is a dynamically typed language. Still, it comes with a notation for\ndeclaring sets of Erlang terms to form a particular type. This effectively forms\nspecific subtypes of the set of all Erlang terms.\n\nSubsequently, these types can be used to specify types of record fields and also\nthe argument and return types of functions.\n\nType information can be used for the following:\n\n- To document function interfaces\n- To provide more information for bug detection tools, such as Dialyzer\n- To be leveraged by documentation tools, such as\n [ExDoc](https://hexdocs.pm/ex_doc/) or [EDoc](`e:edoc:edoc`), for generating\n documentation\n\nIt is expected that the type language described in this section\nsupersedes and replaces the purely comment-based `@type` and `@spec`\ndeclarations used by EDoc.\n\n[](){: #syntax }","title":"The Erlang Type Language - Types and Function Specifications","ref":"typespec.html#the-erlang-type-language"},{"type":"extras","doc":"Types describe sets of Erlang terms. Types consist of, and are built from, a set\nof predefined types, for example, `t:integer/0`, `t:atom/0`, and `t:pid/0`.\nPredefined types represent a typically infinite set of Erlang terms that belong\nto this type. For example, the type `t:atom/0` denotes the set of all Erlang\natoms.\n\nFor integers and atoms, it is allowed for singleton types; for example, the\nintegers `-1` and `42`, or the atoms `'foo'` and `'bar'`. All other types are\nbuilt using unions of either predefined types or singleton types. In a type\nunion between a type and one of its subtypes, the subtype is absorbed by the\nsupertype. Thus, the union is then treated as if the subtype was not a\nconstituent of the union. For example, the type union:\n\n```text\natom() | 'bar' | integer() | 42\n```\n\ndescribes the same set of terms as the type union:\n\n```text\natom() | integer()\n```\n\nBecause of subtype relations that exist between types, all types, except\n`t:dynamic/0`, form a lattice where the top-most element, `t:any/0`, denotes the\nset of all Erlang terms and the bottom-most element, `t:none/0`, denotes the\nempty set of terms.\n\n[](){: #dynamic }\n\nTo facilitate [gradual typing](https://en.wikipedia.org/wiki/Gradual_typing) of\nErlang, the type `t:dynamic/0` is provided. It is similar to\n[Any](https://docs.python.org/3/library/typing.html#the-any-type) in Python,\n[any](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#any) in\nTypeScript and [dynamic](https://docs.hhvm.com/hack/built-in-types/dynamic) in\nHack. `t:any/0` and `t:dynamic/0` interact with\n[success typing](https://learnyousomeerlang.com/dialyzer#success-typing) the\nsame way, so Dialyzer doesn't distinguish between them.\n\nThe set of predefined types and the syntax for types follows:\n{: #predefined }\n\n```text\nType :: any() %% The top type, the set of all Erlang terms\n | none() %% The bottom type, contains no terms\n | dynamic()\n | pid()\n | port()\n | reference()\n | [] %% nil\n | Atom\n | Bitstring\n | float()\n | Fun\n | Integer\n | List\n | Map\n | Tuple\n | Union\n | UserDefined %% described in Type Declarations of User-Defined Types\n\nAtom :: atom()\n | Erlang_Atom %% 'foo', 'bar', ...\n\nBitstring :: <<>>\n | <<_:M>> %% M is an Integer_Value that evaluates to a positive integer\n | <<_:_*N>> %% N is an Integer_Value that evaluates to a positive integer\n | <<_:M, _:_*N>>\n\nFun :: fun() %% any function\n | fun((...) -> Type) %% any arity, returning Type\n | fun(() -> Type)\n | fun((TList) -> Type)\n\nInteger :: integer()\n | Integer_Value\n | Integer_Value..Integer_Value %% specifies an integer range\n\nInteger_Value :: Erlang_Integer %% ..., -1, 0, 1, ... 42 ...\n | Erlang_Character %% $a, $b ...\n | Integer_Value BinaryOp Integer_Value\n | UnaryOp Integer_Value\n\nBinaryOp :: '*' | 'div' | 'rem' | 'band' | '+' | '-' | 'bor' | 'bxor' | 'bsl' | 'bsr'\n\nUnaryOp :: '+' | '-' | 'bnot'\n\nList :: list(Type) %% Proper list ([]-terminated)\n | maybe_improper_list(Type1, Type2) %% Type1=contents, Type2=termination\n | nonempty_improper_list(Type1, Type2) %% Type1 and Type2 as above\n | nonempty_list(Type) %% Proper non-empty list\n\nMap :: #{} %% denotes the empty map\n | #{AssociationList}\n\nTuple :: tuple() %% denotes a tuple of any size\n | {}\n | {TList}\n\nAssociationList :: Association\n | Association, AssociationList\n\nAssociation :: Type := Type %% denotes a mandatory association\n | Type => Type %% denotes an optional association\n\nTList :: Type\n | Type, TList\n\nUnion :: Type1 | Type2\n```\n\nInteger values are either integer or character literals or expressions\nconsisting of possibly nested unary or binary operations that evaluate to an\ninteger. Such expressions can also be used in bit strings and ranges.\n\nThe general form of bit strings is `<<_:M, _:_*N>>`, where `M` and `N` must\nevaluate to positive integers. It denotes a bit string that is `M + (k*N)` bits\nlong (that is, a bit string that starts with `M` bits and continues with `k`\nsegments of `N` bits each, where `k` is also a positive integer). The notations\n`<<_:_*N>>`, `<<_:M>>`, and `<<>>` are convenient shorthands for the cases that\n`M` or `N`, or both, are zero.\n\nBecause lists are commonly used, they have shorthand type notations. The types\n[`list(T)`](`t:list/1`) and [`nonempty_list(T)`](`t:nonempty_list/1`) have the\nshorthands `[T]` and `[T,...]`, respectively. The only difference between the\ntwo shorthands is that `[T]` can be an empty list but `[T,...]` cannot.\n\nNotice that the shorthand for `t:list/0`, that is, the list of elements of\nunknown type, is `[_]` (or `[any()]`), not `[]`. The notation `[]` specifies the\nsingleton type for the empty list.\n\nThe general form of map types is `#{AssociationList}`. The key types in\n`AssociationList` are allowed to overlap, and if they do, the leftmost\nassociation takes precedence. A map association has a key in `AssociationList`\nif it belongs to this type. `AssociationList` can contain both mandatory `(:=)`\nand optional `(=>)` association types. If an association type is mandatory, an\nassociation with that type needs to be present. In the case of an optional\nassociation type it is not required for the key type to be present.\n\nThe notation `#{}` specifies the singleton type for the empty map. Note that\nthis notation is not a shorthand for the `t:map/0` type.\n\nFor convenience, the following types are also built-in. They can be thought as\npredefined aliases for the type unions also shown in the table.\n\n[](){: #builtin_types }\n\n| _Built-in type_ | _Defined as_ |\n| ------------------------- | --------------------------------------------------------------------------- |\n| `t:term/0` | `t:any/0` |\n| `t:binary/0` | `<<_:_*8>>` |\n| `t:nonempty_binary/0` | `<<_:8, _:_*8>>` |\n| `t:bitstring/0` | `<<_:_*1>>` |\n| `t:nonempty_bitstring/0` | `<<_:1, _:_*1>>` |\n| `t:boolean/0` | `'false'` \\| `'true'` |\n| `t:byte/0` | `0..255` |\n| `t:char/0` | `0..16#10ffff` |\n| `t:nil/0` | `[]` |\n| `t:number/0` | `t:integer/0` \\| `t:float/0` |\n| `t:list/0` | `[any()]` |\n| `t:maybe_improper_list/0` | [`maybe_improper_list(any(), any())`](`t:maybe_improper_list/2`) |\n| `t:nonempty_list/0` | [`nonempty_list(any())`](`t:nonempty_list/1`) |\n| `t:string/0` | `[char()]` |\n| `t:nonempty_string/0` | `[char(),...]` |\n| `t:iodata/0` | `iolist()` \\| `binary()` |\n| `t:iolist/0` | `maybe_improper_list(byte()` \\| `binary()` \\| `iolist(), binary()` \\| `[])` |\n| `t:map/0` | `#{any() => any()}` |\n| `t:function/0` | `fun()` |\n| `t:module/0` | `t:atom/0` |\n| `t:mfa/0` | `{module(),atom(),arity()}` |\n| `t:arity/0` | `0..255` |\n| `t:identifier/0` | `pid()` \\| `port()` \\| `reference()` |\n| `node/0` | `t:atom/0` |\n| `t:timeout/0` | `'infinity'` \\| `non_neg_integer()` |\n| `t:no_return/0` | `t:none/0` |\n\n_Table: Built-in types, predefined aliases_\n\nIn addition, the following three built-in types exist and can be thought as\ndefined below, though strictly their \"type definition\" is not valid syntax\naccording to the type language defined above.\n\n| _Built-in type_ | _Can be thought defined by the syntax_ |\n| --------------------- | -------------------------------------- |\n| `t:non_neg_integer/0` | `0..` |\n| `t:pos_integer/0` | `1..` |\n| `t:neg_integer/0` | `..-1` |\n\n_Table: Additional built-in types_\n\n> #### Note {: .info }\n>\n> The following built-in list types also exist, but they are expected to be\n> rarely used. Hence, they have long names:\n\n```erlang\nnonempty_maybe_improper_list() :: nonempty_maybe_improper_list(any(), any())\nnonempty_improper_list(Type1, Type2)\nnonempty_maybe_improper_list(Type1, Type2)\n```\n\nwhere the last two types define the set of Erlang terms one would expect.\n\nAlso for convenience, record notation is allowed to be used. Records are\nshorthands for the corresponding tuples:\n\n```erlang\nRecord :: #Erlang_Atom{}\n | #Erlang_Atom{Fields}\n```\n\nRecords are extended to possibly contain type information. This is described in\n[Type Information in Record Declarations](typespec.md#typeinrecords).","title":"Types and their Syntax - Types and Function Specifications","ref":"typespec.html#types-and-their-syntax"},{"type":"extras","doc":"> #### Change {: .info }\n>\n> Starting from Erlang/OTP 26, is is permitted to define a type having the same\n> name as a built-in type.\n\nIt is recommended to avoid deliberately reusing built-in names because it can be\nconfusing. However, when an Erlang/OTP release introduces a new type, code that\nhappened to define its own type having the same name will continue to work.\n\nAs an example, imagine that the Erlang/OTP 42 release introduces a new type\n`gadget()` defined like this:\n\n```erlang\n-type gadget() :: {'gadget', reference()}.\n```\n\nFurther imagine that some code has its own (different) definition of `gadget()`,\nfor example:\n\n```erlang\n-type gadget() :: #{}.\n```\n\nSince redefinitions are allowed, the code will still compile (but with a\nwarning), and Dialyzer will not emit any additional warnings.","title":"Redefining built-in types - Types and Function Specifications","ref":"typespec.html#redefining-built-in-types"},{"type":"extras","doc":"As seen, the basic syntax of a type is an atom followed by closed parentheses.\nNew types are declared using `-type` and `-opaque` attributes as in the\nfollowing:\n\n```erlang\n-type my_struct_type() :: Type.\n-opaque my_opaq_type() :: Type.\n```\n\nThe type name is the atom `my_struct_type`, followed by parentheses. `Type` is a\ntype as defined in the previous section. A current restriction is that `Type`\ncan contain only predefined types, or user-defined types which are either of the\nfollowing:\n\n- Module-local type, that is, with a definition that is present in the code of\n the module\n- Remote type, that is, type defined in, and exported by, other modules; more\n about this soon.\n\nFor module-local types, the restriction that their definition exists in the\nmodule is enforced by the compiler and results in a compilation error. (A\nsimilar restriction currently exists for records.)\n\nType declarations can also be parameterized by including type variables between\nthe parentheses. The syntax of type variables is the same as Erlang variables,\nthat is, starts with an upper-case letter. These variables is to\nappear on the RHS of the definition. A concrete example follows:\n\n```erlang\n-type orddict(Key, Val) :: [{Key, Val}].\n```\n\nA module can export some types to declare that other modules are allowed to\nrefer to them as _remote types_. This declaration has the following form:\n\n```erlang\n-export_type([T1/A1, ..., Tk/Ak]).\n```\n\nHere the `Ti`s are atoms (the name of the type) and the `Ai`s are their arguments.\n\n_Example:_\n\n```erlang\n-export_type([my_struct_type/0, orddict/2]).\n```\n\nAssuming that these types are exported from module `'mod'`, you can refer to\nthem from other modules using remote type expressions like the following:\n\n```erlang\nmod:my_struct_type()\nmod:orddict(atom(), term())\n```\n\nIt is not allowed to refer to types that are not declared as exported.\n\nTypes declared as `opaque` represent sets of terms whose structure is not\nsupposed to be visible from outside of their defining module. That is, only the\nmodule defining them is allowed to depend on their term structure. Consequently,\nsuch types do not make much sense as module local - module local types are not\naccessible by other modules anyway - and is always to be exported.\n\nRead more on [Opaques](opaques.md)\n\n[](){: #typeinrecords }","title":"Type Declarations of User-Defined Types - Types and Function Specifications","ref":"typespec.html#type-declarations-of-user-defined-types"},{"type":"extras","doc":"The types of record fields can be specified in the declaration of the record.\nThe syntax for this is as follows:\n\n```erlang\n-record(rec, {field1 :: Type1, field2, field3 :: Type3}).\n```\n\nFor fields without type annotations, their type defaults to `any()`. That is, the\nprevious example is a shorthand for the following:\n\n```erlang\n-record(rec, {field1 :: Type1, field2 :: any(), field3 :: Type3}).\n```\n\nIn the presence of initial values for fields, the type must be declared after\nthe initialization, as follows:\n\n```erlang\n-record(rec, {field1 = [] :: Type1, field2, field3 = 42 :: Type3}).\n```\n\nThe initial values for fields are to be compatible with (that is, a member of)\nthe corresponding types. This is checked by the compiler and results in a\ncompilation error if a violation is detected.\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP 19, for fields without initial values, the singleton type\n> `'undefined'` was added to all declared types. In other words, the following\n> two record declarations had identical effects:\n>\n> ```erlang\n> -record(rec, {f1 = 42 :: integer(),\n> f2 :: float(),\n> f3 :: 'a' | 'b'}).\n>\n> -record(rec, {f1 = 42 :: integer(),\n> f2 :: 'undefined' | float(),\n> f3 :: 'undefined' | 'a' | 'b'}).\n> ```\n>\n> This is no longer the case. If you require `'undefined'` in your record field\n> type, you must explicitly add it to the typespec, as in the 2nd example.\n\nAny record, containing type information or not, once defined, can be used as a\ntype using the following syntax:\n\n```text\n#rec{}\n```\n\nIn addition, the record fields can be further specified when using a record type\nby adding type information about the field as follows:\n\n```text\n#rec{some_field :: Type}\n```\n\nAny unspecified fields are assumed to have the type in the original record\ndeclaration.\n\n> #### Note {: .info }\n>\n> When records are used to create patterns for ETS and Mnesia match functions,\n> Dialyzer may need some help not to emit bad warnings. For example:\n>\n> ```erlang\n> -type height() :: pos_integer().\n> -record(person, {name :: string(), height :: height()}).\n>\n> lookup(Name, Tab) ->\n> ets:match_object(Tab, #person{name = Name, _ = '_'}).\n> ```\n>\n> Dialyzer will emit a warning since `'_'` is not in the type of record field\n> `height`.\n>\n> The recommended way of dealing with this is to declare the smallest record\n> field types to accommodate all your needs, and then create refinements as\n> needed. The modified example:\n>\n> ```erlang\n> -record(person, {name :: string(), height :: height() | '_'}).\n>\n> -type person() :: #person{height :: height()}.\n> ```\n>\n> In specifications and type declarations the type `person()` is to be preferred\n> before `#person{}`.","title":"Type Information in Record Declarations - Types and Function Specifications","ref":"typespec.html#type-information-in-record-declarations"},{"type":"extras","doc":"A specification (or contract) for a function is given using the `-spec`\nattribute. The general format is as follows:\n\n```text\n-spec Function(ArgType1, ..., ArgTypeN) -> ReturnType.\n```\n\nAn implementation of the function with the same name `Function` must exist in\nthe current module, and the arity of the function must match the number of\narguments, otherwise the compilation fails.\n\nThe following longer format with module name is also valid as long as `Module`\nis the name of the current module. This can be useful for documentation\npurposes.\n\n```text\n-spec Module:Function(ArgType1, ..., ArgTypeN) -> ReturnType.\n```\n\nAlso, for documentation purposes, argument names can be given:\n\n```text\n-spec Function(ArgName1 :: Type1, ..., ArgNameN :: TypeN) -> RT.\n```\n\nA function specification can be overloaded. That is, it can have several types,\nseparated by a semicolon (`;`). For example:\n\n```erlang\n-spec foo(T1, T2) -> T3;\n (T4, T5) -> T6.\n```\n\nA current restriction, which currently results in a warning by Dialyzer, is that\nthe domains of the argument types cannot overlap. For example, the following\nspecification results in a warning:\n\n```erlang\n-spec foo(pos_integer()) -> pos_integer();\n (integer()) -> integer().\n```\n\nType variables can be used in specifications to specify relations for the input\nand output arguments of a function. For example, the following specification\ndefines the type of a polymorphic identity function:\n\n```text\n-spec id(X) -> X.\n```\n\nNotice that the above specification does not restrict the input and output type\nin any way. These types can be constrained by guard-like subtype constraints and\nprovide bounded quantification:\n\n```erlang\n-spec id(X) -> X when X :: tuple().\n```\n\nCurrently, the `::` constraint (read as \"is a subtype of\") is the only guard\nconstraint that can be used in the `when` part of a `-spec` attribute.\n\n> #### Note {: .info }\n>\n> The above function specification uses multiple occurrences of the same type\n> variable. That provides more type information than the following function\n> specification, where the type variables are missing:\n>\n> ```erlang\n> -spec id(tuple()) -> tuple().\n> ```\n>\n> The latter specification says that the function takes some tuple and returns\n> some tuple. The specification with the `X` type variable specifies that the\n> function takes a tuple and returns _the same_ tuple.\n>\n> However, it is up to the tools that process the specifications to choose\n> whether to take this extra information into account or not.\n\nThe scope of a `::` constraint is the `(...) -> RetType` specification after\nwhich it appears. To avoid confusion, it is suggested that different variables\nare used in different constituents of an overloaded contract, as shown in the\nfollowing example:\n\n```erlang\n-spec foo({X, integer()}) -> X when X :: atom();\n ([Y]) -> Y when Y :: number().\n```\n\nSome functions in Erlang are not meant to return; either because they define\nservers or because they are used to throw exceptions, as in the following\nfunction:\n\n```erlang\nmy_error(Err) -> throw({error, Err}).\n```\n\nFor such functions, it is recommended to use the special `t:no_return/0` type\nfor their \"return\", through a contract of the following form:\n\n```text\n-spec my_error(term()) -> no_return().\n```\n\n> #### Note {: .info }\n>\n> Erlang uses the shorthand version `_` as an anonymous type variable equivalent\n> to `t:term/0` or `t:any/0`. For example, the following function\n>\n> ```text\n> -spec Function(string(), _) -> string().\n> ```\n>\n> is equivalent to:\n>\n> ```text\n> -spec Function(string(), any()) -> string().\n> ```","title":"Specifications for Functions - Types and Function Specifications","ref":"typespec.html#specifications-for-functions"},{"type":"extras","doc":"\n# Opaques","title":"Opaques","ref":"opaques.html"},{"type":"extras","doc":"The main use case for opacity in Erlang is to hide the implementation of a data\ntype, enabling evolving the API while minimizing the risk of breaking consumers.\nThe runtime does not check opacity. Dialyzer provides some opacity-checking, but\nthe rest is up to convention.\n\nThis document explains what Erlang opacity is (and the trade-offs involved) via\nthe example of the [`sets:set()`](`t:sets:set/0`) data type. This type _was_\ndefined in the `sets` module like this:\n\n```erlang\n-opaque set(Element) :: #set{segs :: segs(Element)}.\n```\n\nOTP 24 changed the definition to the following in\n[this commit](https://github.com/erlang/otp/commit/e66941e8d7c47b973dff94c0308ea85a6be1958e).\n\n```erlang\n-opaque set(Element) :: #set{segs :: segs(Element)} | #{Element => ?VALUE}.\n```\n\nAnd this change was safer and more backwards-compatible than if the type had\nbeen defined with `-type` instead of `-opaque`. Here is why: when a module\ndefines an `-opaque`, the contract is that only the defining module should rely\non the definition of the type: no other modules should rely on the definition.\n\nThis means that code that pattern-matched on `set` as a record/tuple technically\nbroke the contract, and opted in to being potentially broken when the definition\nof `set()` changed. Before OTP 24, this code printed `ok`. In OTP 24 it may\nerror:\n\n```erlang\ncase sets:new() of\n Set when is_tuple(Set) ->\n io:format(\"ok\")\nend.\n```\n\n**When working with an opaque defined in another module, here are some\nrecommendations:**\n\n- Don't examine the underlying type using pattern-matching, guards, or functions\n that reveal the type, such as [`tuple_size/1`](`tuple_size/1`) .\n- Instead, use functions provided by the module for working with the type. For\n example, `sets` module provides `sets:new/0`, `sets:add_element/2`,\n `sets:is_element/2`, and so on.\n- [`sets:set(a)`](`t:sets:set/1`) is a subtype of `sets:set(a | b)` and not the\n other way around. Generally, you can rely on the property that `the_opaque(T)`\n is a subtype of `the_opaque(U)` when T is a subtype of U.\n\n**When defining your own opaques, here are some recommendations:**\n\n- Since consumers are expected to not rely on the definition of the opaque type,\n you must provide functions for constructing, querying, and deconstructing\n instances of your opaque type. For example, sets can be constructed with\n `sets:new/0`, `sets:from_list/1`, `sets:add_element/2`, queried with\n `sets:is_element/2`, and deconstructed with`sets:to_list/1`.\n- Don't define an opaque with a type variable in parameter position. This breaks\n the normal and expected behavior that (for example) `my_type(a)` is a subtype\n of `my_type(a | b)`\n- Add [specs](typespec.md) to exported functions that use the opaque type\n\nNote that opaques can be harder to work with for consumers, since the consumer\nis expected not to pattern-match and must instead use functions that the author\nof the opaque type provides to use instances of the type.\n\nAlso, opacity in Erlang is skin-deep: the runtime does not enforce\nopacity-checking. So now that sets are implemented in terms of maps, an\n[`is_map/1`](`is_map/1`) check on a set _will_ pass. The opacity rules are only\nenforced by convention and by additional tooling such as Dialyzer, and this\nenforcement is not total. A determined consumer of `sets` can still reveal the\nstructure of the set, for example by printing, serializing, or using a set as a\n`t:term/0` and inspecting it via functions like [`is_map/1`](`is_map/1`) or\n`maps:get/2`. Also, Dialyzer must make some\n[approximations](https://github.com/erlang/otp/issues/5118).","title":"Opaque Type Aliases - Opaques","ref":"opaques.html#opaque-type-aliases"},{"type":"extras","doc":"\n# Expressions\n\nIn this section, all valid Erlang expressions are listed. When writing Erlang\nprograms, it is also allowed to use macro and record expressions. However,\nthese expressions are expanded during compilation and are in that sense not true\nErlang expressions. Macro and record expressions are covered in separate\nsections:\n\n- [Preprocessor](macros.md)\n- [Records](ref_man_records.md)","title":"Expressions","ref":"expressions.html"},{"type":"extras","doc":"All subexpressions are evaluated before an expression itself is evaluated,\nunless explicitly stated otherwise. For example, consider the expression:\n\n```\nExpr1 + Expr2\n```\n\n`Expr1` and `Expr2`, which are also expressions, are evaluated first — in any\norder — before the addition is performed.\n\nMany of the operators can only be applied to arguments of a certain type. For\nexample, arithmetic operators can only be applied to numbers. An argument of the\nwrong type causes a `badarg` runtime error.","title":"Expression Evaluation - Expressions","ref":"expressions.html#expression-evaluation"},{"type":"extras","doc":"The simplest form of expression is a term, that is one of\n`t:integer/0`, `t:float/0`, `t:atom/0`, `t:string/0`, `t:list/0`,\n`t:map/0`, or `t:tuple/0`. The return value is the term itself.","title":"Terms - Expressions","ref":"expressions.html#terms"},{"type":"extras","doc":"A variable is an expression. If a variable is bound to a value, the return value\nis this value. Unbound variables are only allowed in patterns.\n\nVariables start with an uppercase letter or underscore (`_`). Variables can\ncontain alphanumeric characters, underscore, and `@`.\n\n_Examples:_\n\n```\nX\nName1\nPhoneNumber\nPhone_number\n_\n_Height\nname@node\n```\n\nVariables are bound to values using [pattern matching](patterns.md). Erlang uses\n_single assignment_, that is, a variable can only be bound once.\n\nThe _anonymous variable_ is denoted by underscore (\\_) and can be used when a\nvariable is required but its value can be ignored.\n\n_Example:_\n\n```text\n[H|_] = [1,2,3]\n```\n\nVariables starting with underscore (`_`), for example, `_Height`, are normal\nvariables, not anonymous. However, they are ignored by the compiler in the sense\nthat they do not generate warnings.\n\n_Example:_\n\nThe following code:\n\n```\nmember(_, []) ->\n [].\n```\n\ncan be rewritten to be more readable:\n\n```\nmember(Elem, []) ->\n [].\n```\n\nThis causes a warning for an unused variable, `Elem`. To avoid the warning,\nthe code can be rewritten to:\n\n```\nmember(_Elem, []) ->\n [].\n```\n\nNotice that since variables starting with an underscore are not anonymous, the\nfollowing example matches:\n\n```\n{_,_} = {1,2}\n```\n\nBut this example fails:\n\n```\n{_N,_N} = {1,2}\n```\n\nThe scope for a variable is its function clause. Variables bound in a branch of\nan `if`, `case`, or `receive` expression must be bound in all branches to have a\nvalue outside the expression. Otherwise they are regarded as unsafe outside\nthe expression.\n\nFor the `try` expression variable scoping is limited so that variables bound in\nthe expression are always unsafe outside the expression.","title":"Variables - Expressions","ref":"expressions.html#variables"},{"type":"extras","doc":"A pattern has the same structure as a term but can contain unbound variables.\n\n_Example:_\n\n```\nName1\n[H|T]\n{error,Reason}\n```\n\nPatterns are allowed in clause heads, [case expressions](expressions.md#case),\n[receive expressions](expressions.md#receive), and\n[match expressions](expressions.md#the-match-operator).","title":"Patterns - Expressions","ref":"expressions.html#patterns"},{"type":"extras","doc":"If `Pattern1` and `Pattern2` are valid patterns, the following is also a valid\npattern:\n\n```\nPattern1 = Pattern2\n```\n\nWhen matched against a term, both `Pattern1` and `Pattern2` are matched against\nthe term. The idea behind this feature is to avoid reconstruction of terms.\n\n_Example:_\n\n```\nf({connect,From,To,Number,Options}, To) ->\n Signal = {connect,From,To,Number,Options},\n ...;\nf(Signal, To) ->\n ignore.\n```\n\ncan instead be written as\n\n```\nf({connect,_,To,_,_} = Signal, To) ->\n ...;\nf(Signal, To) ->\n ignore.\n```\n\nThe compound pattern operator does not imply that its operands are matched in\nany particular order. That means that it is not legal to bind a variable in\n`Pattern1` and use it in `Pattern2`, or vice versa.","title":"The Compound Pattern Operator - Expressions","ref":"expressions.html#the-compound-pattern-operator"},{"type":"extras","doc":"When matching strings, the following is a valid pattern:\n\n```\nf(\"prefix\" ++ Str) -> ...\n```\n\nThis is syntactic sugar for the equivalent, but harder to read:\n\n```\nf([$p,$r,$e,$f,$i,$x | Str]) -> ...\n```","title":"String Prefix in Patterns - Expressions","ref":"expressions.html#string-prefix-in-patterns"},{"type":"extras","doc":"An arithmetic expression can be used within a pattern if it meets both of the\nfollowing two conditions:\n\n- It uses only numeric or bitwise operators.\n- Its value can be evaluated to a constant when complied.\n\n_Example:_\n\n```\ncase {Value, Result} of\n {?THRESHOLD+1, ok} -> ...\n```","title":"Expressions in Patterns - Expressions","ref":"expressions.html#expressions-in-patterns"},{"type":"extras","doc":"The following matches `Pattern` against `Expr`:\n\n```\nPattern = Expr\n```\n\nIf the matching succeeds, any unbound variable in the pattern becomes bound and\nthe value of `Expr` is returned.\n\nIf multiple match operators are applied in sequence, they will be evaluated from\nright to left.\n\nIf the matching fails, a `badmatch` run-time error occurs.\n\n_Examples:_\n\n```\n1> {A, B} = T = {answer, 42}.\n{answer,42}\n2> A.\nanswer\n3> B.\n42\n4> T.\n{answer,42}\n5> {C, D} = [1, 2].\n** exception error: no match of right-hand side value [1,2]\n```\n\nBecause multiple match operators are evaluated from right to left, it means\nthat:\n\n```\nPattern1 = Pattern2 = . . . = PatternN = Expression\n```\n\nis equivalent to:\n\n```\nTemporary = Expression,\nPatternN = Temporary,\n .\n .\n .,\nPattern2 = Temporary,\nPattern = Temporary\n```","title":"The Match Operator - Expressions","ref":"expressions.html#the-match-operator"},{"type":"extras","doc":"> #### Note {: .info }\n>\n> This is an advanced section, which references to topics not yet introduced. It\n> can safely be skipped on a first reading.\n\nThe `=` character is used to denote two similar but distinct operators: the\nmatch operator and the compound pattern operator. Which one is meant is\ndetermined by context.\n\nThe _compound pattern operator_ is used to construct a compound pattern from two\npatterns. Compound patterns are accepted everywhere a pattern is accepted. A\ncompound pattern matches if all of its constituent patterns match. It is not\nlegal for a pattern that is part of a compound pattern to use variables (as keys\nin map patterns or sizes in binary patterns) bound in other sub patterns of the\nsame compound pattern.\n\n_Examples:_\n\n```\n1> fun(#{Key := Value} = #{key := Key}) -> Value end.\n* 1:7: variable 'Key' is unbound\n2> F = fun({A, B} = E) -> {E, A + B} end, F({1,2}).\n{{1,2},3}\n3> G = fun(< > = < >) -> {A, B, C} end, G(<<42,43>>).\n{42,43,10795}\n```\n\nThe _match operator_ is allowed everywhere an expression is allowed. It is used\nto match the value of an expression to a pattern. If multiple match operators\nare applied in sequence, they will be evaluated from right to left.\n\n_Examples:_\n\n```\n1> M = #{key => key2, key2 => value}.\n#{key => key2,key2 => value}\n2> f(Key), #{Key := Value} = #{key := Key} = M, Value.\nvalue\n3> f(Key), #{Key := Value} = (#{key := Key} = M), Value.\nvalue\n4> f(Key), (#{Key := Value} = #{key := Key}) = M, Value.\n* 1:12: variable 'Key' is unbound\n5> < > = begin Y = 8, <<42:8>> end, X.\n42\n```\n\nThe expression at prompt `2>` first matches the value of variable `M` against\npattern `#{key := Key}`, binding variable `Key`. It then matches the value of\n`M` against pattern `#{Key := Value}` using variable `Key` as the key, binding\nvariable `Value`.\n\nThe expression at prompt `3>` matches expression `(#{key := Key} = M)` against\npattern `#{Key := Value}`. The expression inside the parentheses is evaluated\nfirst. That is, `M` is matched against `#{key := Key}`, and then the value of\n`M` is matched against pattern `#{Key := Value}`. That is the same evaluation\norder as in _2_; therefore, the parentheses are redundant.\n\nIn the expression at prompt `4>` the expression `M` is matched against a pattern\ninside parentheses. Since the construct inside the parentheses is a pattern, the\n`=` that separates the two patterns is the compound pattern operator (_not_ the\nmatch operator). The match fails because the two sub patterns are matched at the\nsame time, and the variable `Key` is therefore not bound when matching against\npattern `#{Key := Value}`.\n\nIn the expression at prompt `5>` the expressions inside the\n[block expression](expressions.md#block-expressions) are evaluated first,\nbinding variable `Y` and creating a binary. The binary is then matched against\npattern `< >` using the value of `Y` as the size of the segment.","title":"The Match Operator and the Compound Pattern Operator - Expressions","ref":"expressions.html#the-match-operator-and-the-compound-pattern-operator"},{"type":"extras","doc":"```\nExprF(Expr1,...,ExprN)\nExprM:ExprF(Expr1,...,ExprN)\n```\n\nIn the first form of function calls, `ExprM:ExprF(Expr1,...,ExprN)`, each of\n`ExprM` and `ExprF` must be an atom or an expression that evaluates to an atom.\nThe function is said to be called by using the _fully qualified function name_.\nThis is often referred to as a _remote_ or _external function call_.\n\n_Example:_\n\n```\nlists:keyfind(Name, 1, List)\n```\n\nIn the second form of function calls, `ExprF(Expr1,...,ExprN)`, `ExprF` must be\nan atom or evaluate to a fun.\n\nIf `ExprF` is an atom, the function is said to be called by using the\n_implicitly qualified function name_. If the function `ExprF` is locally\ndefined, it is called. Alternatively, if `ExprF` is explicitly imported from the\n`M` module, `M:ExprF(Expr1,...,ExprN)` is called. If `ExprF` is neither declared\nlocally nor explicitly imported, `ExprF` must be the name of an automatically\nimported BIF.\n\n_Examples:_\n\n```\nhandle(Msg, State)\nspawn(m, init, [])\n```\n\n_Examples_ where `ExprF` is a fun:\n\n```\n1> Fun1 = fun(X) -> X+1 end,\nFun1(3).\n4\n2> fun lists:append/2([1,2], [3,4]).\n[1,2,3,4]\n3>\n```\n\nNotice that when calling a local function, there is a difference between using\nthe implicitly or fully qualified function name. The latter always refers to the\nlatest version of the module. See\n[Compilation and Code Loading ](code_loading.md)and\n[Function Evaluation](ref_man_functions.md#eval).","title":"Function Calls - Expressions","ref":"expressions.html#function-calls"},{"type":"extras","doc":"If a local function has the same name as an auto-imported BIF, the semantics is\nthat implicitly qualified function calls are directed to the locally defined\nfunction, not to the BIF. To avoid confusion, there is a compiler directive\navailable, `-compile({no_auto_import,[F/A]})`, that makes a BIF not being\nauto-imported. In certain situations, such a compile-directive is mandatory.\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP R14A (ERTS version 5.8), an implicitly qualified function call to a\n> function having the same name as an auto-imported BIF always resulted in the\n> BIF being called. In newer versions of the compiler, the local function is\n> called instead. This is to avoid that future additions to the set of\n> auto-imported BIFs do not silently change the behavior of old code.\n\nHowever, to avoid that old (pre R14) code changed its behavior when compiled\nwith Erlang/OTP version R14A or later, the following restriction applies: If you\noverride the name of a BIF that was auto-imported in OTP versions prior to R14A\n(ERTS version 5.8) and have an implicitly qualified call to that function in\nyour code, you either need to explicitly remove the auto-import using a compiler\ndirective, or replace the call with a fully qualified function call. Otherwise\nyou get a compilation error. See the following example:\n\n```\n-export([length/1,f/1]).\n\n-compile({no_auto_import,[length/1]}). % erlang:length/1 no longer autoimported\n\nlength([]) ->\n 0;\nlength([H|T]) ->\n 1 + length(T). %% Calls the local function length/1\n\nf(X) when erlang:length(X) > 3 -> %% Calls erlang:length/1,\n %% which is allowed in guards\n long.\n```\n\nThe same logic applies to explicitly imported functions from other modules, as\nto locally defined functions. It is not allowed to both import a function from\nanother module and have the function declared in the module at the same time:\n\n```\n-export([f/1]).\n\n-compile({no_auto_import,[length/1]}). % erlang:length/1 no longer autoimported\n\n-import(mod,[length/1]).\n\nf(X) when erlang:length(X) > 33 -> %% Calls erlang:length/1,\n %% which is allowed in guards\n\n erlang:length(X); %% Explicit call to erlang:length in body\n\nf(X) ->\n length(X). %% mod:length/1 is called\n```\n\nFor auto-imported BIFs added in Erlang/OTP R14A and thereafter, overriding the\nname with a local function or explicit import is always allowed. However, if the\n`-compile({no_auto_import,[F/A])` directive is not used, the compiler issues a\nwarning whenever the function is called in the module using the implicitly\nqualified function name.","title":"Local Function Names Clashing With Auto-Imported BIFs - Expressions","ref":"expressions.html#local-function-names-clashing-with-auto-imported-bifs"},{"type":"extras","doc":"```\nif\n GuardSeq1 ->\n Body1;\n ...;\n GuardSeqN ->\n BodyN\nend\n```\n\nThe branches of an `if`\\-expression are scanned sequentially until a guard\nsequence `GuardSeq` that evaluates to true is found. Then the corresponding\n`Body` (a sequence of expressions separated by `,`) is evaluated.\n\nThe return value of `Body` is the return value of the `if` expression.\n\nIf no guard sequence is evaluated as true, an `if_clause` run-time error occurs.\nIf necessary, the guard expression `true` can be used in the last branch, as\nthat guard sequence is always true.\n\n_Example:_\n\n```\nis_greater_than(X, Y) ->\n if\n X > Y ->\n true;\n true -> % works as an 'else' branch\n false\n end\n```","title":"If - Expressions","ref":"expressions.html#if"},{"type":"extras","doc":"```\ncase Expr of\n Pattern1 [when GuardSeq1] ->\n Body1;\n ...;\n PatternN [when GuardSeqN] ->\n BodyN\nend\n```\n\nThe expression `Expr` is evaluated and the patterns `Pattern` are sequentially\nmatched against the result. If a match succeeds and the optional guard sequence\n`GuardSeq` is true, the corresponding `Body` is evaluated.\n\nThe return value of `Body` is the return value of the `case` expression.\n\nIf there is no matching pattern with a true guard sequence, a `case_clause`\nrun-time error occurs.\n\n_Example:_\n\n```\nis_valid_signal(Signal) ->\n case Signal of\n {signal, _What, _From, _To} ->\n true;\n {signal, _What, _To} ->\n true;\n _Else ->\n false\n end.\n```","title":"Case - Expressions","ref":"expressions.html#case"},{"type":"extras","doc":"> #### Change {: .info }\n>\n> The `maybe` [feature](`e:system:features.md#features`) was introduced\n> in Erlang/OTP 25. Starting from Erlang/OTP 27 is is enabled by default.\n\n```\nmaybe\n Expr1,\n ...,\n ExprN\nend\n```\n\nThe expressions in a `maybe` block are evaluated sequentially. If all\nexpressions are evaluated successfully, the return value of the `maybe` block is\n`ExprN`. However, execution can be short-circuited by a conditional match\nexpression:\n\n```\nExpr1 ?= Expr2\n```\n\n`?=` is called the conditional match operator. It is only allowed to be used at\nthe top-level of a `maybe` block. It matches the pattern `Expr1` against\n`Expr2`. If the matching succeeds, any unbound variable in the pattern becomes\nbound. If the expression is the last expression in the `maybe` block, it also\nreturns the value of `Expr2`. If the matching is unsuccessful, the rest of the\nexpressions in the `maybe` block are skipped and the return value of the `maybe`\nblock is `Expr2`.\n\nNone of the variables bound in a `maybe` block must be used in the code that\nfollows the block.\n\nHere is an example:\n\n```\nmaybe\n {ok, A} ?= a(),\n true = A >= 0,\n {ok, B} ?= b(),\n A + B\nend\n```\n\nLet us first assume that `a()` returns `{ok,42}` and `b()` returns `{ok,58}`.\nWith those return values, all of the match operators will succeed, and the\nreturn value of the `maybe` block is `A + B`, which is equal to `42 + 58 = 100`.\n\nNow let us assume that `a()` returns `error`. The conditional match operator in\n`{ok, A} ?= a()` fails to match, and the return value of the `maybe` block is\nthe value of the expression that failed to match, namely `error`. Similarly, if\n`b()` returns `wrong`, the return value of the `maybe` block is `wrong`.\n\nFinally, let us assume that `a()` returns `{ok,-1}`. Because `true = A >= 0` uses\nthe match operator `=`, a `{badmatch,false}` run-time error occurs when the\nexpression fails to match the pattern.\n\nThe example can be written in a less succient way using nested case expressions:\n\n```\ncase a() of\n {ok, A} ->\n true = A >= 0,\n case b() of\n {ok, B} ->\n A + B;\n Other1 ->\n Other1\n end;\n Other2 ->\n Other2\nend\n```\n\nThe `maybe` block can be augmented with `else` clauses:\n\n```\nmaybe\n Expr1,\n ...,\n ExprN\nelse\n Pattern1 [when GuardSeq1] ->\n Body1;\n ...;\n PatternN [when GuardSeqN] ->\n BodyN\nend\n```\n\nIf a conditional match operator fails, the failed expression is matched against\nthe patterns in all clauses between the `else` and `end` keywords. If a match\nsucceeds and the optional guard sequence `GuardSeq` is true, the corresponding\n`Body` is evaluated. The value returned from the body is the return value of the\n`maybe` block.\n\nIf there is no matching pattern with a true guard sequence, an `else_clause`\nrun-time error occurs.\n\nNone of the variables bound in a `maybe` block must be used in the `else`\nclauses. None of the variables bound in the `else` clauses must be used in the\ncode that follows the `maybe` block.\n\nHere is the previous example augmented with `else` clauses:\n\n```\nmaybe\n {ok, A} ?= a(),\n true = A >= 0,\n {ok, B} ?= b(),\n A + B\nelse\n error -> error;\n wrong -> error\nend\n```\n\nThe `else` clauses translate the failing value from the conditional match\noperators to the value `error`. If the failing value is not one of the\nrecognized values, a `else_clause` run-time error occurs.","title":"Maybe - Expressions","ref":"expressions.html#maybe"},{"type":"extras","doc":"```\nExpr1 ! Expr2\n```\n\nSends the value of `Expr2` as a message to the process specified by `Expr1`. The\nvalue of `Expr2` is also the return value of the expression.\n\n`Expr1` must evaluate to a pid, an alias (reference), a port, a registered name\n(atom), or a tuple `{Name,Node}`. `Name` is an atom and `Node` is a node name,\nalso an atom.\n\n- If `Expr1` evaluates to a name, but this name is not registered, a `badarg`\n run-time error occurs.\n- Sending a message to a reference never fails, even if the reference is no\n longer (or never was) an alias.\n- Sending a message to a pid never fails, even if the pid identifies a\n non-existing process.\n- Distributed message sending, that is, if `Expr1` evaluates to a tuple\n `{Name,Node}` (or a pid located at another node), also never fails.","title":"Send - Expressions","ref":"expressions.html#send"},{"type":"extras","doc":"```\nreceive\n Pattern1 [when GuardSeq1] ->\n Body1;\n ...;\n PatternN [when GuardSeqN] ->\n BodyN\nend\n```\n\nFetches a received message present in the message queue of the process. The\nfirst message in the message queue is matched sequentially against the patterns\nfrom top to bottom. If no match was found, the matching sequence is repeated for\nthe second message in the queue, and so on. Messages are queued in the\n[order they were received](ref_man_processes.md#message-queue-order). If a match\nsucceeds, that is, if the `Pattern` matches and the optional guard sequence\n`GuardSeq` is true, then the message is removed from the message queue and the\ncorresponding `Body` is evaluated. All other messages in the message queue\nremain unchanged.\n\nThe return value of `Body` is the return value of the `receive` expression.\n\n`receive` never fails. The execution is suspended, possibly indefinitely, until\na message arrives that matches one of the patterns and with a true guard\nsequence.\n\n_Example:_\n\n```\nwait_for_onhook() ->\n receive\n onhook ->\n disconnect(),\n idle();\n {connect, B} ->\n B ! {busy, self()},\n wait_for_onhook()\n end.\n```\n\nThe `receive` expression can be augmented with a timeout:\n\n```\nreceive\n Pattern1 [when GuardSeq1] ->\n Body1;\n ...;\n PatternN [when GuardSeqN] ->\n BodyN\nafter\n ExprT ->\n BodyT\nend\n```\n\n`receive...after` works exactly as `receive`, except that if no matching message\nhas arrived within `ExprT` milliseconds, then `BodyT` is evaluated instead. The\nreturn value of `BodyT` then becomes the return value of the `receive...after`\nexpression. `ExprT` is to evaluate to an integer, or the atom `infinity`. The\nallowed integer range is from 0 to 4294967295, that is, the longest possible\ntimeout is almost 50 days. With a zero value the timeout occurs immediately if\nthere is no matching message in the message queue.\n\nThe atom `infinity` will make the process wait indefinitely for a matching\nmessage. This is the same as not using a timeout. It can be useful for timeout\nvalues that are calculated at runtime.\n\n_Example:_\n\n```\nwait_for_onhook() ->\n receive\n onhook ->\n disconnect(),\n idle();\n {connect, B} ->\n B ! {busy, self()},\n wait_for_onhook()\n after\n 60000 ->\n disconnect(),\n error()\n end.\n```\n\nIt is legal to use a `receive...after` expression with no branches:\n\n```\nreceive\nafter\n ExprT ->\n BodyT\nend\n```\n\nThis construction does not consume any messages, only suspends execution in the\nprocess for `ExprT` milliseconds. This can be used to implement simple timers.\n\n_Example:_\n\n```\ntimer() ->\n spawn(m, timer, [self()]).\n\ntimer(Pid) ->\n receive\n after\n 5000 ->\n Pid ! timeout\n end.\n```","title":"Receive - Expressions","ref":"expressions.html#receive"},{"type":"extras","doc":"```\nExpr1 op Expr2\n```\n\n| _op_ | _Description_ |\n| ------ | ------------------------ |\n| `==` | Equal to |\n| `/=` | Not equal to |\n| `=<` | Less than or equal to |\n| `<` | Less than |\n| `>=` | Greater than or equal to |\n| `>` | Greater than |\n| `=:=` | Term equivalence |\n| `=/=` | Term non-equivalence |\n\n_Table: Term Comparison Operators._\n\nThe arguments can be of different data types. The following order is defined:\n\n```text\nnumber 1 == 1.0.\ntrue\n2> 1 =:= 1.0.\nfalse\n3> 0 =:= 0.0.\nfalse\n4> 0.0 =:= -0.0.\nfalse\n5> 0.0 =:= +0.0.\ntrue\n6> 1 > a.\nfalse\n7> #{c => 3} > #{a => 1, b => 2}.\nfalse\n8> #{a => 1, b => 2} == #{a => 1.0, b => 2.0}.\ntrue\n9> <<2:2>> < <<128>>.\ntrue\n10> <<3:2>> < <<128>>.\nfalse\n```\n\n> #### Note {: .info }\n>\n> Prior to OTP 27, the term equivalence operators considered `0.0`\n> and `-0.0` to be the same term.\n>\n> This was changed in OTP 27 but legacy code may have expected them to be\n> considered the same. To help users catch errors that may arise from an\n> upgrade, the compiler raises a warning when `0.0` is pattern-matched or used\n> in a term equivalence test.\n>\n> If you need to match `0.0` specifically, the warning can be silenced by\n> writing `+0.0` instead, which produces the same term but makes the compiler\n> interpret the match as being done on purpose.","title":"Term Comparisons - Expressions","ref":"expressions.html#term-comparisons"},{"type":"extras","doc":"```\nop Expr\nExpr1 op Expr2\n```\n\n| _Operator_ | _Description_ | _Argument Type_ |\n| ------------ | ------------------------- | --------------- |\n| `+` | Unary + | Number |\n| `-` | Negation (unary -) | Number |\n| `+` | Addition | Number |\n| `-` | Subtraction | Number |\n| `*` | Multiplication | Number |\n| `/` | Floating point division | Number |\n| `bnot` | Unary bitwise NOT | Integer |\n| `div` | Integer division | Integer |\n| `rem` | Integer remainder of X/Y | Integer |\n| `band` | Bitwise AND | Integer |\n| `bor` | Bitwise OR | Integer |\n| `bxor` | Bitwise XOR | Integer |\n| `bsl` | Bitshift left | Integer |\n| `bsr` | Arithmetic bitshift right | Integer |\n\n_Table: Arithmetic Operators._\n\n_Examples:_\n\n```\n1> +1.\n1\n2> -1.\n-1\n3> 1+1.\n2\n4> 4/2.\n2.0\n5> 5 div 2.\n2\n6> 5 rem 2.\n1\n7> 2#10 band 2#01.\n0\n8> 2#10 bor 2#01.\n3\n9> a + 10.\n** exception error: an error occurred when evaluating an arithmetic expression\n in operator +/2\n called as a + 10\n10> 1 bsl (1 bsl 64).\n** exception error: a system limit has been reached\n in operator bsl/2\n called as 1 bsl 18446744073709551616\n```","title":"Arithmetic Expressions - Expressions","ref":"expressions.html#arithmetic-expressions"},{"type":"extras","doc":"```\nop Expr\nExpr1 op Expr2\n```\n\n| _Operator_ | _Description_ |\n| ---------- | ----------------- |\n| `not` | Unary logical NOT |\n| `and` | Logical AND |\n| `or` | Logical OR |\n| `xor` | Logical XOR |\n\n_Table: Logical Operators._\n\n_Examples:_\n\n```\n1> not true.\nfalse\n2> true and false.\nfalse\n3> true xor false.\ntrue\n4> true or garbage.\n** exception error: bad argument\n in operator or/2\n called as true or garbage\n```","title":"Boolean Expressions - Expressions","ref":"expressions.html#boolean-expressions"},{"type":"extras","doc":"```\nExpr1 orelse Expr2\nExpr1 andalso Expr2\n```\n\n`Expr2` is evaluated only if necessary. That is, `Expr2` is evaluated only if:\n\n- `Expr1` evaluates to `false` in an `orelse` expression.\n\nor\n\n- `Expr1` evaluates to `true` in an `andalso` expression.\n\nReturns either the value of `Expr1` (that is, `true` or `false`) or the value of\n`Expr2` (if `Expr2` is evaluated).\n\n_Example 1:_\n\n```\ncase A >= -1.0 andalso math:sqrt(A+1) > B of\n```\n\nThis works even if `A` is less than `-1.0`, since in that case, `math:sqrt/1` is\nnever evaluated.\n\n_Example 2:_\n\n```\nOnlyOne = is_atom(L) orelse\n (is_list(L) andalso length(L) == 1),\n```\n\n`Expr2` is not required to evaluate to a Boolean value. Because of that,\n`andalso` and `orelse` are tail-recursive.\n\n_Example 3 (tail-recursive function):_\n\n```\nall(Pred, [Hd|Tail]) ->\n Pred(Hd) andalso all(Pred, Tail);\nall(_, []) ->\n true.\n```\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP R13A, `Expr2` was required to evaluate to a Boolean value,\n> and as consequence, `andalso` and `orelse` were **not** tail-recursive.","title":"Short-Circuit Expressions - Expressions","ref":"expressions.html#short-circuit-expressions"},{"type":"extras","doc":"```\nExpr1 ++ Expr2\nExpr1 -- Expr2\n```\n\nThe list concatenation operator `++` appends its second argument to its first\nand returns the resulting list.\n\nThe list subtraction operator `--` produces a list that is a copy of the first\nargument. The procedure is as follows: for each element in the second argument,\nthe first occurrence of this element (if any) is removed.\n\n_Example:_\n\n```\n1> [1,2,3] ++ [4,5].\n[1,2,3,4,5]\n2> [1,2,3,2,1,2] -- [2,1,2].\n[3,1,2]\n```","title":"List Operations - Expressions","ref":"expressions.html#list-operations"},{"type":"extras","doc":"","title":"Map Expressions - Expressions","ref":"expressions.html#map-expressions"},{"type":"extras","doc":"Constructing a new map is done by letting an expression `K` be associated with\nanother expression `V`:\n\n```\n#{K => V}\n```\n\nNew maps can include multiple associations at construction by listing every\nassociation:\n\n```\n#{K1 => V1, ..., Kn => Vn}\n```\n\nAn empty map is constructed by not associating any terms with each other:\n\n```\n#{}\n```\n\nAll keys and values in the map are terms. Any expression is first evaluated and\nthen the resulting terms are used as _key_ and _value_ respectively.\n\nKeys and values are separated by the `=>` arrow and associations are separated\nby a comma (`,`).\n\n_Examples:_\n\n```\nM0 = #{}, % empty map\nM1 = #{a => <<\"hello\">>}, % single association with literals\nM2 = #{1 => 2, b => b}, % multiple associations with literals\nM3 = #{k => {A,B}}, % single association with variables\nM4 = #{{\"w\", 1} => f()}. % compound key associated with an evaluated expression\n```\n\nHere, `A` and `B` are any expressions and `M0` through `M4` are the resulting\nmap terms.\n\nIf two matching keys are declared, the latter key takes precedence.\n\n_Example:_\n\n```\n1> #{1 => a, 1 => b}.\n#{1 => b }\n2> #{1.0 => a, 1 => b}.\n#{1 => b, 1.0 => a}\n```\n\nThe order in which the expressions constructing the keys (and their associated\nvalues) are evaluated is not defined. The syntactic order of the key-value pairs\nin the construction is of no relevance, except in the recently mentioned case of\ntwo matching keys.","title":"Creating Maps - Expressions","ref":"expressions.html#creating-maps"},{"type":"extras","doc":"Updating a map has a similar syntax as constructing it.\n\nAn expression defining the map to be updated is put in front of the expression\ndefining the keys to be updated and their respective values:\n\n```\nM#{K => V}\n```\n\nHere `M` is a term of type map and `K` and `V` are any expression.\n\nIf key `K` does not match any existing key in the map, a new association is\ncreated from key `K` to value `V`.\n\nIf key `K` matches an existing key in map `M`, its associated value is replaced\nby the new value `V`. In both cases, the evaluated map expression returns a new\nmap.\n\nIf `M` is not of type map, an exception of type `badmap` is raised.\n\nTo only update an existing value, the following syntax is used:\n\n```\nM#{K := V}\n```\n\nHere `M` is a term of type map, `V` is an expression and `K` is an expression\nthat evaluates to an existing key in `M`.\n\nIf key `K` does not match any existing keys in map `M`, an exception of type\n`badkey` is raised at runtime. If a matching key `K` is present in map `M`,\nits associated value is replaced by the new value `V`, and the evaluated map\nexpression returns a new map.\n\nIf `M` is not of type map, an exception of type `badmap` is raised.\n\n_Examples:_\n\n```\nM0 = #{},\nM1 = M0#{a => 0},\nM2 = M1#{a => 1, b => 2},\nM3 = M2#{\"function\" => fun() -> f() end},\nM4 = M3#{a := 2, b := 3}. % 'a' and 'b' was added in `M1` and `M2`.\n```\n\nHere `M0` is any map. It follows that `M1` through `M4` are maps as well.\n\n_More examples:_\n\n```\n1> M = #{1 => a}.\n#{1 => a }\n2> M#{1.0 => b}.\n#{1 => a, 1.0 => b}.\n3> M#{1 := b}.\n#{1 => b}\n4> M#{1.0 := b}.\n** exception error: bad argument\n```\n\nAs in construction, the order in which the key and value expressions are\nevaluated is not defined. The syntactic order of the key-value pairs in the\nupdate is of no relevance, except in the case where two keys match. In that\ncase, the latter value is used.","title":"Updating Maps - Expressions","ref":"expressions.html#updating-maps"},{"type":"extras","doc":"Matching of key-value associations from maps is done as follows:\n\n```\n#{K := V} = M\n```\n\nHere `M` is any map. The key `K` must be a\n[guard expression](expressions.md#guard-expressions), with all variables already\nbound. `V` can be any pattern with either bound or unbound variables.\n\nIf the variable `V` is unbound, it becomes bound to the value associated with\nthe key `K`, which must exist in the map `M`. If the variable `V` is bound, it\nmust match the value associated with `K` in `M`.\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP 23, the expression defining the key `K` was restricted to be\n> either a single variable or a literal.\n\n_Example:_\n\n```\n1> M = #{\"tuple\" => {1,2}}.\n#{\"tuple\" => {1,2}}\n2> #{\"tuple\" := {1,B}} = M.\n#{\"tuple\" => {1,2}}\n3> B.\n2.\n```\n\nThis binds variable `B` to integer `2`.\n\nSimilarly, multiple values from the map can be matched:\n\n```\n#{K1 := V1, ..., Kn := Vn} = M\n```\n\nHere keys `K1` through `Kn` are any expressions with literals or bound\nvariables. If all key expressions evaluate successfully and all keys\nexist in map `M`, all variables in `V1 .. Vn` is matched to the\nassociated values of their respective keys.\n\nIf the matching conditions are not met the match fails.\n\nNote that when matching a map, only the `:=` operator (not the `=>`) is allowed\nas a delimiter for the associations.\n\nThe order in which keys are declared in matching has no relevance.\n\nDuplicate keys are allowed in matching and match each pattern associated to the\nkeys:\n\n```\n#{K := V1, K := V2} = M\n```\n\nThe empty map literal (`#{}`) matches any map when used as a pattern:\n\n```\n#{} = Expr\n```\n\nThis expression matches if the expression `Expr` is of type map, otherwise it\nfails with an exception `badmatch`.\n\nHere the key to be retrieved is constructed from an expression:\n\n```\n#{{tag,length(List)} := V} = Map\n```\n\n`List` must be an already bound variable.\n\n#### Matching Syntax\n\nMatching of literals as keys are allowed in function heads:\n\n```\n%% only start if not_started\nhandle_call(start, From, #{state := not_started} = S) ->\n...\n {reply, ok, S#{state := start}};\n\n%% only change if started\nhandle_call(change, From, #{state := start} = S) ->\n...\n {reply, ok, S#{state := changed}};\n```","title":"Maps in Patterns - Expressions","ref":"expressions.html#maps-in-patterns"},{"type":"extras","doc":"Maps are allowed in guards as long as all subexpressions are valid guard\nexpressions.\n\nThe following guard BIFs handle maps:\n\n- [is_map/1](`erlang:is_map/1`) in the `erlang` module\n- [is_map_key/2](`erlang:is_map_key/2`) in the `erlang` module\n- [map_get/2](`erlang:map_get/2`) in the `erlang` module\n- [map_size/1](`erlang:map_size/1`) in the `erlang` module","title":"Maps in Guards - Expressions","ref":"expressions.html#maps-in-guards"},{"type":"extras","doc":"The bit syntax operates on _bit strings_. A bit string is a sequence of bits\nordered from the most significant bit to the least significant bit.\n\n```\n<<>> % The empty bit string, zero length\n< >\n< >\n```\n\nEach element `Ei` specifies a _segment_ of the bit string. The segments are\nordered left to right from the most significant bit to the least significant bit\nof the bit string.\n\nEach segment specification `Ei` is a value, followed by an optional _size\nexpression_ and an optional _type specifier list_.\n\n```\nEi = Value |\n Value:Size |\n Value/TypeSpecifierList |\n Value:Size/TypeSpecifierList\n```\n\nWhen used in a bit string construction, `Value` is an expression that is to\nevaluate to an integer, float, or bit string. If the expression is not a single\nliteral or variable, it is to be enclosed in parentheses.\n\nWhen used in a bit string matching, `Value` must be a variable, or an integer,\nfloat, or string.\n\nNotice that, for example, using a string literal as in `<<\"abc\">>` is syntactic\nsugar for `<<$a,$b,$c>>`.\n\nWhen used in a bit string construction, `Size` is an expression that is to\nevaluate to an integer.\n\nWhen used in a bit string matching, `Size` must be a\n[guard expression](expressions.md#guard-expressions) that evaluates to an\ninteger. All variables in the guard expression must be already bound.\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP 23, `Size` was restricted to be an integer or a variable\n> bound to an integer.\n\nThe value of `Size` specifies the size of the segment in units (see below). The\ndefault value depends on the type (see below):\n\n- For `integer` it is 8.\n- For `float` it is 64.\n- For `binary` and `bitstring` it is the whole binary or bit string.\n\nIn matching, the default value for a binary or bit string segment is only valid\nfor the last element. All other bit string or binary elements in the matching\nmust have a size specification.\n\n[](){: #binaries }\n\n**Binaries**\n\nA bit string with a length that is a multiple of 8 bits is known as a _binary_,\nwhich is the most common and useful type of bit string.\n\nA binary has a canonical representation in memory. Here follows a sequence of\nbytes where each byte's value is its sequence number:\n\n```\n<<1, 2, 3, 4, 5, 6, 7, 8, 9, 10>>\n```\n\nBit strings are a later generalization of binaries, so many texts and much\ninformation about binaries apply just as well for bit strings.\n\n**Example:**\n\n```\n1> < > = <<\"abcde\">>.\n* 1:3: a binary field without size is only allowed at the end of a binary pattern\n2> < > = <<\"abcde\">>.\n<<\"abcde\">>\n3> A.\n<<\"abc\">>\n4> B.\n<<\"de\">>\n```\n\nFor the `utf8`, `utf16`, and `utf32` types, `Size` must not be given. The size\nof the segment is implicitly determined by the type and value itself.\n\n`TypeSpecifierList` is a list of type specifiers, in any order, separated by\nhyphens (-). Default values are used for any omitted type specifiers.\n\n- **`Type`= `integer` | `float` | `binary` | `bytes` | `bitstring` | `bits` |\n `utf8` | `utf16` | `utf32`** - The default is `integer`. `bytes` is a\n shorthand for `binary` and `bits` is a shorthand for `bitstring`. See below\n for more information about the `utf` types.\n\n- **`Signedness`= `signed` | `unsigned`** - Only matters for matching and when\n the type is `integer`. The default is `unsigned`.\n\n- **`Endianness`= `big` | `little` | `native`** - Specifies byte level (octet\n level) endianness (byte order). Native-endian means that the endianness is\n resolved at load time to be either big-endian or little-endian, depending on\n what is native for the CPU that the Erlang machine is run on. Endianness only\n matters when the **Type** is either `integer`, `utf16`, `utf32`, or `float`. The\n default is `big`.\n\n ```\n <<16#1234:16/little>> = <<16#3412:16>> = <<16#34:8, 16#12:8>>\n ```\n\n- **`Unit`= `unit:IntegerLiteral`** - The allowed range is 1 through 256.\n Defaults to 1 for `integer`, `float`, and `bitstring`, and to 8 for `binary`.\n For types `bitstring`, `bits`, and `bytes`, it is not allowed to specify a\n unit value different from the default value. No unit specifier must be given\n for the types `utf8`, `utf16`, and `utf32`.","title":"Bit Syntax Expressions - Expressions","ref":"expressions.html#bit-syntax-expressions"},{"type":"extras","doc":"The value of `Size` multiplied with the unit gives the size of the segment in\nbits.\n\nWhen constructing bit strings, if the size `N` of an integer segment is too\nsmall to contain the given integer, the most significant bits of the integer are\nsilently discarded and only the `N` least significant bits are put into the bit\nstring. For example, `<<16#ff:4>>` will result in the bit string `<<15:4>>`.","title":"Integer segments - Expressions","ref":"expressions.html#integer-segments"},{"type":"extras","doc":"The value of `Size` multiplied with the unit gives the size of the segment in\nbits. The size of a float segment in bits must be one of 16, 32, or 64.\n\nWhen constructing bit strings, if the size of a float segment is too small to\ncontain the representation of the given float value, an exception is raised.\n\nWhen matching bit strings, matching of float segments fails if the bits of the\nsegment does not contain the representation of a finite floating point value.","title":"Float segments - Expressions","ref":"expressions.html#float-segments"},{"type":"extras","doc":"In this section, the phrase \"binary segment\" refers to any one of the segment\ntypes `binary`, `bitstring`, `bytes`, and `bits`.\n\nSee also the paragraphs about [Binaries](expressions.md#binaries).\n\nWhen constructing binaries and no size is specified for a binary segment, the\nentire binary value is interpolated into the binary being constructed. However,\nthe size in bits of the binary being interpolated must be evenly divisible by\nthe unit value for the segment; otherwise an exception is raised.\n\nFor example, the following examples all succeed:\n\n```\n1> <<(<<\"abc\">>)/bitstring>>.\n<<\"abc\">>\n2> <<(<<\"abc\">>)/binary-unit:1>>.\n<<\"abc\">>\n3> <<(<<\"abc\">>)/binary>>.\n<<\"abc\">>\n```\n\nThe first two examples have a unit value of 1 for the segment, while the third\nsegment has a unit value of 8.\n\nAttempting to interpolate a bit string of size 1 into a binary segment with unit\n8 (the default unit for `binary`) fails as shown in this example:\n\n```\n1> <<(<<1:1>>)/binary>>.\n** exception error: bad argument\n```\n\nFor the construction to succeed, the unit value of the segment must be 1:\n\n```\n2> <<(<<1:1>>)/bitstring>>.\n<<1:1>>\n3> <<(<<1:1>>)/binary-unit:1>>.\n<<1:1>>\n```\n\nSimilarly, when matching a binary segment with no size specified, the match\nsucceeds if and only if the size in bits of the rest of the binary is evenly\ndivisible by the unit value:\n\n```\n1> <<_/binary-unit:16>> = <<\"\">>.\n<<>>\n2> <<_/binary-unit:16>> = <<\"a\">>.\n** exception error: no match of right hand side value <<\"a\">>\n3> <<_/binary-unit:16>> = <<\"ab\">>.\n<<\"ab\">>\n4> <<_/binary-unit:16>> = <<\"abc\">>.\n** exception error: no match of right hand side value <<\"abc\">>\n5> <<_/binary-unit:16>> = <<\"abcd\">>.\n<<\"abcd\">>\n```\n\nWhen a size is explicitly specified for a binary segment, the segment size in\nbits is the value of `Size` multiplied by the default or explicit unit value.\n\nWhen constructing binaries, the size of the binary being interpolated into the\nconstructed binary must be at least as large as the size of the binary segment.\n\n**Examples:**\n\n```\n1> <<(<<\"abc\">>):2/binary>>.\n<<\"ab\">>\n2> <<(<<\"a\">>):2/binary>>.\n** exception error: construction of binary failed\n *** segment 1 of type 'binary': the value <<\"a\">> is shorter than the size of the segment\n```","title":"Binary segments - Expressions","ref":"expressions.html#binary-segments"},{"type":"extras","doc":"The types `utf8`, `utf16`, and `utf32` specifies encoding/decoding of the\n*Unicode Transformation Format*s [UTF-8](https://en.wikipedia.org/wiki/UTF-8),\n[UTF-16](https://en.wikipedia.org/wiki/UTF-16), and\n[UTF-32](https://en.wikipedia.org/wiki/UTF-32), respectively.\n\nWhen constructing a segment of a `utf` type, `Value` must be an integer in the\nrange `0` through `16#D7FF` or `16#E000` through `16#10FFFF`. Construction fails with a\n`badarg` exception if `Value` is outside the allowed ranges. The sizes of the\nencoded values are as follows:\n\n- For `utf8`, `Value` is encoded in 1-4 bytes.\n- For `utf16`, `Value` is encoded in 2 or 4 bytes.\n- For `utf32`, `Value` is encoded in 4 bytes.\n\nWhen constructing, a literal string can be given followed by one of the UTF\ntypes, for example: `<<\"abc\"/utf8>>` which is syntactic sugar for\n`<<$a/utf8,$b/utf8,$c/utf8>>`.\n\nA successful match of a segment of a `utf` type, results in an integer in the\nrange `0` through `16#D7FF` or `16#E000` through `16#10FFFF`. The match fails if the\nreturned value falls outside those ranges.\n\nA segment of type `utf8` matches 1-4 bytes in the bit string, if the bit string\nat the match position contains a valid UTF-8 sequence. (See RFC-3629 or the\nUnicode standard.)\n\nA segment of type `utf16` can match 2 or 4 bytes in the bit string. The match\nfails if the bit string at the match position does not contain a legal UTF-16\nencoding of a Unicode code point. (See RFC-2781 or the Unicode standard.)\n\nA segment of type `utf32` can match 4 bytes in the bit string in the same way as\nan `integer` segment matches 32 bits. The match fails if the resulting integer\nis outside the legal ranges previously mentioned.\n\n_Examples:_\n\n```\n1> Bin1 = <<1,17,42>>.\n<<1,17,42>>\n2> Bin2 = <<\"abc\">>.\n<<97,98,99>>\n\n3> Bin3 = <<1,17,42:16>>.\n<<1,17,0,42>>\n4> < > = <<1,17,42:16>>.\n<<1,17,0,42>>\n5> C.\n42\n6> < > = <<1,17,42:16>>.\n<<1,17,0,42>>\n7> D.\n273\n8> F.\n42\n9> < > = <<1,17,42:16>>.\n<<1,17,0,42>>\n10> H.\n<<17,0,42>>\n11> < > = <<1,17,42:12>>.\n<<1,17,2,10:4>>\n12> J.\n<<17,2,10:4>>\n\n13> <<1024/utf8>>.\n<<208,128>>\n\n14> <<1:1,0:7>>.\n<<128>>\n15> <<16#123:12/little>> = <<16#231:12>> = <<2:4, 3:4, 1:4>>.\n<<35,1:4>>\n```\n\nNotice that bit string patterns cannot be nested.\n\nNotice also that \"`B=<<1>>`\" is interpreted as \"`B =< <1>>`\" which is a syntax\nerror. The correct way is to write a space after `=`: \"`B = <<1>>`.\n\nMore examples are provided in [Programming Examples](`e:system:bit_syntax.md`).","title":"Unicode segments - Expressions","ref":"expressions.html#unicode-segments"},{"type":"extras","doc":"```\nfun\n [Name](Pattern11,...,Pattern1N) [when GuardSeq1] ->\n Body1;\n ...;\n [Name](PatternK1,...,PatternKN) [when GuardSeqK] ->\n BodyK\nend\n```\n\nA fun expression begins with the keyword `fun` and ends with the keyword `end`.\nBetween them is to be a function declaration, similar to a\n[regular function declaration](ref_man_functions.md#function-declaration-syntax),\nexcept that the function name is optional and is to be a variable, if any.\n\nVariables in a fun head shadow the function name and both shadow variables in\nthe function clause surrounding the fun expression. Variables bound in a fun\nbody are local to the fun body.\n\nThe return value of the expression is the resulting fun.\n\n_Examples:_\n\n```\n1> Fun1 = fun (X) -> X+1 end.\n#Fun \n2> Fun1(2).\n3\n3> Fun2 = fun (X) when X>=5 -> gt; (X) -> lt end.\n#Fun \n4> Fun2(7).\ngt\n5> Fun3 = fun Fact(1) -> 1; Fact(X) when X > 1 -> X * Fact(X - 1) end.\n#Fun \n6> Fun3(4).\n24\n```\n\nThe following fun expressions are also allowed:\n\n```\nfun Name/Arity\nfun Module:Name/Arity\n```\n\nIn `Name/Arity`, `Name` is an atom and `Arity` is an integer. `Name/Arity` must\nspecify an existing local function. The expression is syntactic sugar for:\n\n```\nfun (Arg1,...,ArgN) -> Name(Arg1,...,ArgN) end\n```\n\nIn `Module:Name/Arity`, `Module`, and `Name` are atoms and `Arity` is an\ninteger. `Module`, `Name`, and `Arity` can also be variables. A fun defined in\nthis way refers to the function `Name` with arity `Arity` in the _latest_\nversion of module `Module`. A fun defined in this way is not dependent on the\ncode for the module in which it is defined.\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP R15, `Module`, `Name`, and `Arity` were not allowed to be\n> variables.\n\nMore examples are provided in [Programming Examples](`e:system:funs.md`).","title":"Fun Expressions - Expressions","ref":"expressions.html#fun-expressions"},{"type":"extras","doc":"```\ncatch Expr\n```\n\nReturns the value of `Expr` unless an exception is raised during the evaluation. In\nthat case, the exception is caught. The return value depends on the class of the\nexception:\n\n- **`error`** (a run-time error or the code called [`error(Term)`](`error/1`)) -\n `{'EXIT',{Reason,Stack}}` is returned.\n\n- **`exit`** (the code called [`exit(Term)`](`exit/1`)) - `{'EXIT',Term}` is returned.\n\n- **`throw`** (the code called [`throw(Term)`](`throw/1`)): `Term` is returned.\n\n`Reason` depends on the type of error that occurred, and `Stack` is the stack of\nrecent function calls, see [Exit Reasons](errors.md#exit_reasons).\n\n_Examples:_\n\n```\n1> catch 1+2.\n3\n2> catch 1+a.\n{'EXIT',{badarith,[...]}}\n```\n\nThe BIF [`throw(Any)`](`throw/1`) can be used for non-local return from a\nfunction. It must be evaluated within a `catch`, which returns the value `Any`.\n\n_Example:_\n\n```\n3> catch throw(hello).\nhello\n```\n\nIf [`throw/1`](`throw/1`) is not evaluated within a catch, a `nocatch` run-time\nerror occurs.\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP 24, the `catch` operator had the lowest precedence, making\n> it necessary to add parentheses when combining it with the `match` operator:\n>\n> ```\n> 1> A = (catch 42).\n> 42\n> 2> A.\n> 42\n> ```\n>\n> Starting from Erlang/OTP 24, the parentheses can be omitted:\n>\n> ```\n> 1> A = catch 42.\n> 42\n> 2> A.\n> 42\n> ```","title":"Catch and Throw - Expressions","ref":"expressions.html#catch-and-throw"},{"type":"extras","doc":"```\ntry Exprs\ncatch\n Class1:ExceptionPattern1[:Stacktrace] [when ExceptionGuardSeq1] ->\n ExceptionBody1;\n ClassN:ExceptionPatternN[:Stacktrace] [when ExceptionGuardSeqN] ->\n ExceptionBodyN\nend\n```\n\nThis is an enhancement of [catch](expressions.md#catch-and-throw). It gives the\npossibility to:\n\n- Distinguish between different exception classes.\n- Choose to handle only the desired ones.\n- Passing the others on to an enclosing `try` or `catch`, or to default error\n handling.\n\nNotice that although the keyword `catch` is used in the `try` expression, there\nis not a `catch` expression within the `try` expression.\n\nIt returns the value of `Exprs` (a sequence of expressions `Expr1, ..., ExprN`)\nunless an exception occurs during the evaluation. In that case the exception is\ncaught and the patterns `ExceptionPattern` with the right exception class\n`Class` are sequentially matched against the caught exception. If a match\nsucceeds and the optional guard sequence `ExceptionGuardSeq` is true, the\ncorresponding `ExceptionBody` is evaluated to become the return value.\n\n`Stacktrace`, if specified, must be the name of a variable (not a pattern). The\nstack trace is bound to the variable when the corresponding `ExceptionPattern`\nmatches.\n\nIf an exception occurs during evaluation of `Exprs` but there is no matching\n`ExceptionPattern` of the right `Class` with a true guard sequence, the\nexception is passed on as if `Exprs` had not been enclosed in a `try`\nexpression.\n\nIf an exception occurs during evaluation of `ExceptionBody`, it is not caught.\n\nIt is allowed to omit `Class` and `Stacktrace`. An omitted `Class` is shorthand\nfor `throw`:\n\n```\ntry Exprs\ncatch\n ExceptionPattern1 [when ExceptionGuardSeq1] ->\n ExceptionBody1;\n ExceptionPatternN [when ExceptionGuardSeqN] ->\n ExceptionBodyN\nend\n```\n\nThe `try` expression can have an `of` section:\n\n```\ntry Exprs of\n Pattern1 [when GuardSeq1] ->\n Body1;\n ...;\n PatternN [when GuardSeqN] ->\n BodyN\ncatch\n Class1:ExceptionPattern1[:Stacktrace] [when ExceptionGuardSeq1] ->\n ExceptionBody1;\n ...;\n ClassN:ExceptionPatternN[:Stacktrace] [when ExceptionGuardSeqN] ->\n ExceptionBodyN\nend\n```\n\nIf the evaluation of `Exprs` succeeds without an exception, the patterns\n`Pattern` are sequentially matched against the result in the same way as for a\n[case](expressions.md#case) expression, except that if the matching fails, a\n`try_clause` run-time error occurs instead of a `case_clause`.\n\nOnly exceptions occurring during the evaluation of `Exprs` can be caught by the\n`catch` section. Exceptions occurring in a `Body` or due to a failed match are\nnot caught.\n\nThe `try` expression can also be augmented with an `after` section, intended to\nbe used for cleanup with side effects:\n\n```\ntry Exprs of\n Pattern1 [when GuardSeq1] ->\n Body1;\n ...;\n PatternN [when GuardSeqN] ->\n BodyN\ncatch\n Class1:ExceptionPattern1[:Stacktrace] [when ExceptionGuardSeq1] ->\n ExceptionBody1;\n ...;\n ClassN:ExceptionPatternN[:Stacktrace] [when ExceptionGuardSeqN] ->\n ExceptionBodyN\nafter\n AfterBody\nend\n```\n\n`AfterBody` is evaluated after either `Body` or `ExceptionBody`, no matter which\none. The evaluated value of `AfterBody` is lost; the return value of the `try`\nexpression is the same with an `after` section as without.\n\nEven if an exception occurs during evaluation of `Body` or `ExceptionBody`,\n`AfterBody` is evaluated. In this case the exception is passed on after\n`AfterBody` has been evaluated, so the exception from the `try` expression is\nthe same with an `after` section as without.\n\nIf an exception occurs during evaluation of `AfterBody` itself, it is not\ncaught. So if `AfterBody` is evaluated after an exception in `Exprs`, `Body`, or\n`ExceptionBody`, that exception is lost and masked by the exception in\n`AfterBody`.\n\nThe `of`, `catch`, and `after` sections are all optional, as long as there is at\nleast a `catch` or an `after` section. So the following are valid `try`\nexpressions:\n\n```\ntry Exprs of\n Pattern when GuardSeq ->\n Body\nafter\n AfterBody\nend\n\ntry Exprs\ncatch\n ExpressionPattern ->\n ExpressionBody\nafter\n AfterBody\nend\n\ntry Exprs after AfterBody end\n```\n\nNext is an example of using `after`. This closes the file, even in the event of\nexceptions in `file:read/2` or in [`binary_to_term/1`](`binary_to_term/1`). The\nexceptions are the same as without the `try`...`after`...`end` expression:\n\n```\ntermize_file(Name) ->\n {ok,F} = file:open(Name, [read,binary]),\n try\n {ok,Bin} = file:read(F, 1024*1024),\n binary_to_term(Bin)\n after\n file:close(F)\n end.\n```\n\nNext is an example of using `try` to emulate `catch Expr`:\n\n```\ntry Expr\ncatch\n throw:Term -> Term;\n exit:Reason -> {'EXIT',Reason};\n error:Reason:Stk -> {'EXIT',{Reason,Stk}}\nend\n```\n\nVariables bound in the various parts of these expressions have different scopes.\nVariables bound just after the `try` keyword are:\n\n- bound in the `of` section\n- unsafe in both the `catch` and `after` sections, as well as after the whole\n construct\n\nVariables bound in `of` section are:\n\n- unbound in the `catch` section\n- unsafe in both the `after` section, as well as after the whole construct\n\nVariables bound in the `catch` section are unsafe in the `after` section, as\nwell as after the whole construct.\n\nVariables bound in the `after` section are unsafe after the whole construct.","title":"Try - Expressions","ref":"expressions.html#try"},{"type":"extras","doc":"```\n(Expr)\n```\n\nParenthesized expressions are useful to override\n[operator precedences](expressions.md#prec), for example, in arithmetic\nexpressions:\n\n```\n1> 1 + 2 * 3.\n7\n2> (1 + 2) * 3.\n9\n```","title":"Parenthesized Expressions - Expressions","ref":"expressions.html#parenthesized-expressions"},{"type":"extras","doc":"```\nbegin\n Expr1,\n ...,\n ExprN\nend\n```\n\nBlock expressions provide a way to group a sequence of expressions, similar to a\nclause body. The return value is the value of the last expression `ExprN`.\n\n[](){: #lcs }","title":"Block Expressions - Expressions","ref":"expressions.html#block-expressions"},{"type":"extras","doc":"Comprehensions provide a succinct notation for iterating over one or more terms\nand constructing a new term. Comprehensions come in three different flavors,\ndepending on the type of term they build.\n\nList comprehensions construct lists. They have the following syntax:\n\n```\n[Expr || Qualifier1, . . ., QualifierN]\n```\n\nHere, `Expr` is an arbitrary expression, and each `Qualifier` is either a\n**generator** or a **filter**.\n\nBit string comprehensions construct bit strings or binaries. They have the\nfollowing syntax:\n\n```\n< >\n```\n\n`BitStringExpr` is an expression that evaluates to a bit string. If\n`BitStringExpr` is a function call, it must be enclosed in parentheses. Each\n`Qualifier` is either a **generator** or a **filter**.\n\nMap comprehensions construct maps. They have the following syntax:\n\n```\n#{KeyExpr => ValueExpr || Qualifier1, . . ., QualifierN}\n```\n\nHere, `KeyExpr` and `ValueExpr` are arbitrary expressions, and each `Qualifier`\nis either a **generator** or a **filter**.\n\n> #### Change {: .info }\n>\n> Map comprehensions and map generators were introduced in Erlang/OTP 26.\n\nThere are three kinds of generators.\n\nA _list generator_ has the following syntax:\n\n```\nPattern <- ListExpr\n```\n\nwhere `ListExpr` is an expression that evaluates to a list of terms.\n\nA _bit string generator_ has the following syntax:\n\n```\nBitstringPattern <= BitStringExpr\n```\n\nwhere `BitStringExpr` is an expression that evaluates to a bit string.\n\nA _map generator_ has the following syntax:\n\n```\nKeyPattern := ValuePattern <- MapExpression\n```\n\nwhere `MapExpr` is an expression that evaluates to a map, or a map iterator\nobtained by calling `maps:iterator/1` or `maps:iterator/2`.\n\nA _filter_ is an expression that evaluates to `true` or `false`.\n\nThe variables in the generator patterns shadow previously bound variables,\nincluding variables bound in a previous generator pattern.\n\nVariables bound in a generator expression are not visible outside the\nexpression:\n\n```\n1> [{E,L} || E <- L=[1,2,3]].\n* 1:5: variable 'L' is unbound\n```\n\nA **list comprehension** returns a list, where the list elements are the result\nof evaluating `Expr` for each combination of generator elements for which all\nfilters are true.\n\nA **bit string comprehension** returns a bit string, which is created by\nconcatenating the results of evaluating `BitStringExpr` for each combination of\nbit string generator elements for which all filters are true.\n\nA **map comprehension** returns a map, where the map elements are the result of\nevaluating `KeyExpr` and `ValueExpr` for each combination of generator elements\nfor which all filters are true. If the key expressions are not unique, the last\noccurrence is stored in the map.\n\n**Examples:**\n\nMultiplying each element in a list by two:\n\n```\n1> [X*2 || X <- [1,2,3]].\n[2,4,6]\n```\n\nMultiplying each byte in a binary by two, returning a list:\n\n```\n1> [X*2 || < > <= <<1,2,3>>].\n[2,4,6]\n```\n\nMultiplying each byte in a binary by two:\n\n```\n1> << <<(X*2)>> || < > <= <<1,2,3>> >>.\n<<2,4,6>>\n```\n\nMultiplying each element in a list by two, returning a binary:\n\n```\n1> << <<(X*2)>> || X <- [1,2,3] >>.\n<<2,4,6>>\n```\n\nCreating a mapping from an integer to its square:\n\n```\n1> #{X => X*X || X <- [1,2,3]}.\n#{1 => 1,2 => 4,3 => 9}\n```\n\nMultiplying the value of each element in a map by two:\n\n```\n1> #{K => 2*V || K := V <- #{a => 1,b => 2,c => 3}}.\n#{a => 2,b => 4,c => 6}\n```\n\nFiltering a list, keeping odd numbers:\n\n```\n1> [X || X <- [1,2,3,4,5], X rem 2 =:= 1].\n[1,3,5]\n```\n\nFiltering a list, keeping only elements that match:\n\n```\n1> [X || {_,_}=X <- [{a,b}, [a], {x,y,z}, {1,2}]].\n[{a,b},{1,2}]\n```\n\nCombining elements from two list generators:\n\n```\n1> [{P,Q} || P <- [a,b,c], Q <- [1,2]].\n[{a,1},{a,2},{b,1},{b,2},{c,1},{c,2}]\n```\n\nMore examples are provided in\n[Programming Examples.](`e:system:list_comprehensions.md`)\n\nWhen there are no generators, a comprehension returns either a term constructed\nfrom a single element (the result of evaluating `Expr`) if all filters are true,\nor a term constructed from no elements (that is, `[]` for list comprehension,\n`<<>>` for a bit string comprehension, and `#{}` for a map comprehension).\n\n_Example:_\n\n```\n1> [2 || is_integer(2)].\n[2]\n2> [x || is_integer(x)].\n[]\n```\n\nWhat happens when the filter expression does not evaluate to a boolean value\ndepends on the expression:\n\n- If the expression is a [guard expression](expressions.md#guard-expressions),\n failure to evaluate or evaluating to a non-boolean value is equivalent to\n evaluating to `false`.\n- If the expression is not a guard expression and evaluates to a non-Boolean\n value `Val`, an exception `{bad_filter, Val}` is triggered at runtime. If the\n evaluation of the expression raises an exception, it is not caught by the\n comprehension.\n\n**Examples** (using a guard expression as filter):\n\n```\n1> List = [1,2,a,b,c,3,4].\n[1,2,a,b,c,3,4]\n2> [E || E <- List, E rem 2].\n[]\n3> [E || E <- List, E rem 2 =:= 0].\n[2,4]\n```\n\n**Examples** (using a non-guard expression as filter):\n\n```\n1> List = [1,2,a,b,c,3,4].\n[1,2,a,b,c,3,4]\n2> FaultyIsEven = fun(E) -> E rem 2 end.\n#Fun \n3> [E || E <- List, FaultyIsEven(E)].\n** exception error: bad filter 1\n4> IsEven = fun(E) -> E rem 2 =:= 0 end.\n#Fun \n5> [E || E <- List, IsEven(E)].\n** exception error: an error occurred when evaluating an arithmetic expression\n in operator rem/2\n called as a rem 2\n6> [E || E <- List, is_integer(E), IsEven(E)].\n[2,4]\n```\n\n[](){: #guards }","title":"Comprehensions - Expressions","ref":"expressions.html#comprehensions"},{"type":"extras","doc":"A _guard sequence_ is a sequence of guards, separated by semicolon (`;`). The\nguard sequence is true if at least one of the guards is true. (The remaining\nguards, if any, are not evaluated.)\n\n`Guard1; ...; GuardK`\n\nA _guard_ is a sequence of guard expressions, separated by comma (`,`). The guard\nis true if all guard expressions evaluate to `true`.\n\n`GuardExpr1, ..., GuardExprN`","title":"Guard Sequences - Expressions","ref":"expressions.html#guard-sequences"},{"type":"extras","doc":"The set of valid _guard expressions_ is a subset of the set of valid Erlang\nexpressions. The reason for restricting the set of valid expressions is that\nevaluation of a guard expression must be guaranteed to be free of side effects.\nValid guard expressions are the following:\n\n- Variables\n- Constants (atoms, integer, floats, lists, tuples, records, binaries, and maps)\n- Expressions that construct atoms, integer, floats, lists, tuples, records,\n binaries, and maps\n- Expressions that update a map\n- The record expressions `Expr#Name.Field` and `#Name.Field`\n- Calls to the BIFs specified in tables _Type Test BIFs_ and _Other BIFs Allowed\n in Guard Expressions_\n- Term comparisons\n- Arithmetic expressions\n- Boolean expressions\n- Short-circuit expressions (`andalso`/`orelse`)\n\n| _BIF_ |\n| ------------------------------------ |\n| [`is_atom/1`](`is_atom/1`) |\n| [`is_binary/1`](`is_binary/1`) |\n| [`is_bitstring/1`](`is_bitstring/1`) |\n| [`is_boolean/1`](`is_boolean/1`) |\n| [`is_float/1`](`is_float/1`) |\n| [`is_function/1`](`is_function/1`) |\n| [`is_function/2`](`is_function/2`) |\n| [`is_integer/1`](`is_integer/1`) |\n| [`is_list/1`](`is_list/1`) |\n| [`is_map/1`](`is_map/1`) |\n| [`is_number/1`](`is_number/1`) |\n| [`is_pid/1`](`is_pid/1`) |\n| [`is_port/1`](`is_port/1`) |\n| [`is_record/2`](`is_record/2`) |\n| [`is_record/3`](`is_record/3`) |\n| [`is_reference/1`](`is_reference/1`) |\n| [`is_tuple/1`](`is_tuple/1`) |\n\n_Table: Type Test BIFs_\n\nNotice that most type test BIFs have older equivalents, without the\n`is_` prefix. These old BIFs are retained only for backwards\ncompatibility and are not to be used in new code. They are also only\nallowed at top level. For example, they are not allowed in Boolean\nexpressions in guards.\n\n| _BIF_ |\n| ---------------------------------------- |\n| [`abs(Number)`](`abs/1`) |\n| [`bit_size(Bitstring)`](`bit_size/1`) |\n| [`byte_size(Bitstring)`](`byte_size/1`) |\n| [`element(N, Tuple)`](`element/2`) |\n| [`float(Term)`](`float/1`) |\n| [`hd(List)`](`hd/1`) |\n| [`is_map_key(Key, Map)`](`is_map_key/2`) |\n| [`length(List)`](`length/1`) |\n| [`map_get(Key, Map)`](`map_get/2`) |\n| [`map_size(Map)`](`map_size/1`) |\n| [`max(A, B)`](`max/2`) |\n| [`min(A, B)`](`min/2`) |\n| `node/0` |\n| `node(Pid` \\| `Ref` \\| `Port)` |\n| [`round(Number)`](`round/1`) |\n| `self/0` |\n| `size(Tuple` \\| `Bitstring)` |\n| [`tl(List)`](`tl/1`) |\n| [`trunc(Number)`](`trunc/1`) |\n| [`tuple_size(Tuple)`](`tuple_size/1`) |\n\n_Table: Other BIFs Allowed in Guard Expressions_\n\n> #### Change {: .info }\n>\n> The [`min/2`](`min/2`) and [`max/2`](`max/2`) BIFs are allowed to be used in\n> guards from Erlang/OTP 26.\n\nIf an arithmetic expression, a Boolean expression, a short-circuit expression,\nor a call to a guard BIF fails (because of invalid arguments), the entire guard\nfails. If the guard was part of a guard sequence, the next guard in the sequence\n(that is, the guard following the next semicolon) is evaluated.\n\n[](){: #prec }","title":"Guard Expressions - Expressions","ref":"expressions.html#guard-expressions"},{"type":"extras","doc":"Operator precedence in descending order:\n\n| _Operator_ | _Association_ |\n| -------------------------------------------- | ----------------- |\n| `#` |   |\n| Unary `+` `-` `bnot` `not` |   |\n| `/` `*` `div` `rem` `band` `and` | Left-associative |\n| `+` `-` `bor` `bxor` `bsl` `bsr` `or` `xor` | Left-associative |\n| `++` `--` | Right-associative |\n| `==` `/=` `=<` `<` `>=` `>` `=:=` `=/=` | Non-associative |\n| `andalso` | Left-associative |\n| `orelse` | Left-associative |\n| `catch` |   |\n| `=` `!` | Right-associative |\n| `?=` | Non-associative |\n\n_Table: Operator Precedence_\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP 24, the `catch` operator had the lowest precedence.\n\n> #### Note {: .info }\n>\n> The `=` operator in the table is the\n> [match operator](expressions.md#the-match-operator). The character `=` can also\n> denote the\n> [compound pattern operator](expressions.md#the-compound-pattern-operator), which\n> can only be used in patterns.\n>\n> `?=` is restricted in that it can only be used at the top-level inside a\n> `maybe` block.\n\nWhen evaluating an expression, the operator with the highest precedence is\nevaluated first. Operators with the same precedence are evaluated according to\ntheir associativity. Non-associative operators cannot be combined with operators\nof the same precedence.\n\n_Examples:_\n\nThe left-associative arithmetic operators are evaluated left to right:\n\n```\n6 + 5 * 4 - 3 / 2 evaluates to\n6 + 20 - 1.5 evaluates to\n26 - 1.5 evaluates to\n24.5\n```\n\nThe non-associative operators cannot be combined:\n\n```\n1> 1 < X < 10.\n* 1:7: syntax error before: '<'\n```","title":"Operator Precedence - Expressions","ref":"expressions.html#operator-precedence"},{"type":"extras","doc":"\n# Preprocessor","title":"Preprocessor","ref":"macros.html"},{"type":"extras","doc":"A file can be included as follows:\n\n```erlang\n-include(File).\n-include_lib(File).\n```\n\n`File`, a string, is to point out a file. The contents of this file are included\nas is, at the position of the directive.\n\nInclude files are typically used for record and macro definitions that are\nshared by several modules. It is recommended to use the file name extension\n`.hrl` for include files.\n\n`File` can start with a path component `$VAR`, for some string `VAR`. If that is\nthe case, the value of the environment variable `VAR` as returned by\n`os:getenv(VAR)` is substituted for `$VAR`. If `os:getenv(VAR)` returns `false`,\n`$VAR` is left as is.\n\nIf the filename `File` is absolute (possibly after variable substitution), the\ninclude file with that name is included. Otherwise, the specified file is\nsearched for in the following directories, and in this order:\n\n1. The current working directory\n1. The directory where the module is being compiled\n1. The directories given by the `include` option\n\nFor details, see [erlc](`e:erts:erlc_cmd.md`) in ERTS and\n`m:compile` in Compiler.\n\n_Examples:_\n\n```erlang\n-include(\"my_records.hrl\").\n-include(\"incdir/my_records.hrl\").\n-include(\"/home/user/proj/my_records.hrl\").\n-include(\"$PROJ_ROOT/my_records.hrl\").\n```\n\n`include_lib` is similar to `include`, but is not to point out an absolute file.\nInstead, the first path component (possibly after variable substitution) is\nassumed to be the name of an application.\n\n_Example:_\n\n```erlang\n-include_lib(\"kernel/include/file.hrl\").\n```\n\nThe code server uses `code:lib_dir(kernel)` to find the directory of the current\n(latest) version of Kernel, and then the subdirectory `include` is searched for\nthe file `file.hrl`.","title":"File Inclusion - Preprocessor","ref":"macros.html#file-inclusion"},{"type":"extras","doc":"A macro is defined as follows:\n\n```erlang\n-define(Const, Replacement).\n-define(Func(Var1,...,VarN), Replacement).\n```\n\nA macro definition can be placed anywhere among the attributes and function\ndeclarations of a module, but the definition must come before any usage of the\nmacro.\n\nIf a macro is used in several modules, it is recommended that the macro\ndefinition is placed in an include file.\n\nA macro is used as follows:\n\n```text\n?Const\n?Func(Arg1,...,ArgN)\n```\n\nMacros are expanded during compilation. A simple macro `?Const` is replaced with\n`Replacement`.\n\n_Example:_\n\n```erlang\n-define(TIMEOUT, 200).\n...\ncall(Request) ->\n server:call(refserver, Request, ?TIMEOUT).\n```\n\nThis is expanded to:\n\n```erlang\ncall(Request) ->\n server:call(refserver, Request, 200).\n```\n\nA macro `?Func(Arg1,...,ArgN)` is replaced with `Replacement`, where all\noccurrences of a variable `Var` from the macro definition are replaced with the\ncorresponding argument `Arg`.\n\n_Example:_\n\n```erlang\n-define(MACRO1(X, Y), {a, X, b, Y}).\n...\nbar(X) ->\n ?MACRO1(a, b),\n ?MACRO1(X, 123)\n```\n\nThis is expanded to:\n\n```erlang\nbar(X) ->\n {a,a,b,b},\n {a,X,b,123}.\n```\n\nIt is good programming practice, but not mandatory, to ensure that a macro\ndefinition is a valid Erlang syntactic form.\n\nTo view the result of macro expansion, a module can be compiled with the `'P'`\noption. `compile:file(File, ['P'])`. This produces a listing of the parsed code\nafter preprocessing and parse transforms, in the file `File.P`.","title":"Defining and Using Macros - Preprocessor","ref":"macros.html#defining-and-using-macros"},{"type":"extras","doc":"The following macros are predefined:\n\n- **`?MODULE`** - The name of the current module, as an atom.\n\n- **`?MODULE_STRING`** - The name of the current module, as a string.\n\n- **`?FILE`** - The file name of the current module, as a string.\n\n- **`?LINE`** - The current line number, as an integer.\n\n- **`?MACHINE`** - The machine name, `'BEAM'`.\n\n- **`?FUNCTION_NAME`** - The name of the current function, as an atom.\n\n- **`?FUNCTION_ARITY`** - The arity (number of arguments) for the current\n function, as an integer.\n\n- **`?OTP_RELEASE`** - The OTP release for the runtime system that is\n running the compiler, as an integer. For example, when compiling using\n Erlang/OTP 27, the macro returns `27`.\n\n > #### Note {: .info }\n >\n > To find out the release at run-time, call\n > [`erlang:system_info(otp_release)`](`erlang:system_info/1`). Note\n > that it returns the release as a string. For example, when the\n > release is Erlang/OTP 27, the string `\"27\"` will be returned.\n\n > #### Change {: .info }\n >\n > The `?OTP_RELEASE` macro was introduced in Erlang/OTP 21.\n\n- **`?FEATURE_AVAILABLE(Feature)`** - Expands to `true` if the\n [feature](`e:system:features.md#features`) `Feature` is available. The feature\n might or might not be enabled.\n\n > #### Change {: .info }\n >\n > The `?FEATURE_AVAILABLE()` macro was introduced in Erlang/OTP 25.\n\n- **`?FEATURE_ENABLED(Feature)`** - Expands to `true` if the\n [feature](`e:system:features.md#features`) `Feature` is enabled.\n > #### Change {: .info }\n >\n > The `?FEATURE_ENABLED()` macro was introduced in Erlang/OTP 25.","title":"Predefined Macros - Preprocessor","ref":"macros.html#predefined-macros"},{"type":"extras","doc":"It is possible to overload macros, except for predefined macros. An overloaded\nmacro has more than one definition, each with a different number of arguments.\n\n> #### Change {: .info }\n>\n> Support for overloading of macros was added in Erlang 5.7.5/OTP R13B04.\n\nA macro `?Func(Arg1,...,ArgN)` with a (possibly empty) list of arguments results\nin an error message if there is at least one definition of `Func` with\narguments, but none with N arguments.\n\nAssuming these definitions:\n\n```erlang\n-define(F0(), c).\n-define(F1(A), A).\n-define(C, m:f).\n```\n\nthe following does not work:\n\n```erlang\nf0() ->\n ?F0. % No, an empty list of arguments expected.\n\nf1(A) ->\n ?F1(A, A). % No, exactly one argument expected.\n```\n\nOn the other hand,\n\n```text\nf() ->\n ?C().\n```\n\nis expanded to\n\n```erlang\nf() ->\n m:f().\n```","title":"Macros Overloading - Preprocessor","ref":"macros.html#macros-overloading"},{"type":"extras","doc":"A definition of macro can be removed as follows:\n\n```erlang\n-undef(Macro).\n```","title":"Removing a macro definition - Preprocessor","ref":"macros.html#removing-a-macro-definition"},{"type":"extras","doc":"The following macro directives support conditional compilation:\n\n- **`-ifdef(Macro).`** - Evaluate the following lines only if `Macro` is\n defined.\n\n- **`-ifndef(Macro).`** - Evaluate the following lines only if `Macro` is not\n defined.\n\n- **`-else.`** - Only allowed after the `ifdef`, `ifndef`, `if`, and `elif`\n directives. The lines following `else` are evaluated if the preceding\n directive evaluated to false.\n\n- **`-if(Condition).`** - Evaluates the following lines only if `Condition`\n evaluates to true.\n\n- **`-elif(Condition).`** - Only allowed after an `if` or another `elif`\n directive. If the preceding `if` or `elif` directive does not evaluate to\n true, and the `Condition` evaluates to true, the lines following the `elif`\n are evaluated instead.\n\n- **`-endif.`** - Specifies the end of a series of control flow directives.\n\n> #### Note {: .info }\n>\n> Macro directives cannot be used inside functions.\n\nSyntactically, the `Condition` in `if` and `elif` must be a\n[guard expression](expressions.md#guard-expressions). Other constructs (such as\na `case` expression) result in a compilation error.\n\nAs opposed to the standard guard expressions, an expression in an `if` and\n`elif` also supports calling the psuedo-function `defined(Name)`, which tests\nwhether the `Name` argument is the name of a previously defined macro.\n`defined(Name)` evaluates to `true` if the macro is defined and `false`\notherwise. An attempt to call other functions results in a compilation error.\n\n_Example:_\n\n```erlang\n-module(m).\n...\n\n-ifdef(debug).\n-define(LOG(X), io:format(\"{~p,~p}: ~p~n\", [?MODULE,?LINE,X])).\n-else.\n-define(LOG(X), true).\n-endif.\n\n...\n```\n\nWhen trace output is desired, `debug` is to be defined when the module `m` is\ncompiled:\n\n```erlang\n% erlc -Ddebug m.erl\n\nor\n\n1> c(m, {d, debug}).\n{ok,m}\n```\n\n`?LOG(Arg)` is then expanded to a call to `io:format/2` and provide the user\nwith some simple trace output.\n\n_Example:_\n\n```erlang\n-module(m)\n...\n-if(?OTP_RELEASE >= 25).\n%% Code that will work in OTP 25 or higher\n-elif(?OTP_RELEASE >= 26).\n%% Code that will work in OTP 26 or higher\n-else.\n%% Code that will work in OTP 24 or lower.\n-endif.\n...\n```\n\nThis code uses the `OTP_RELEASE` macro to conditionally select code depending on\nrelease.\n\n_Example:_\n\n```erlang\n-module(m)\n...\n-if(?OTP_RELEASE >= 26 andalso defined(debug)).\n%% Debugging code that requires OTP 26 or later.\n-else.\n%% Non-debug code that works in any release.\n-endif.\n...\n```\n\nThis code uses the `OTP_RELEASE` macro and `defined(debug)` to compile debug\ncode only for OTP 26 or later.","title":"Conditional Compilation - Preprocessor","ref":"macros.html#conditional-compilation"},{"type":"extras","doc":"[](){: #feature-directive }\n\nThe directive `-feature(FeatureName, enable | disable)` can be used to enable or\ndisable the [feature](`e:system:features.md#features`) `FeatureName`. This is\nthe preferred way of enabling (disabling) features, although it is possible to\ndo it with options to the compiler as well.\n\nNote that the `-feature(..)` directive may only appear before any syntax is\nused. In practice this means it should appear before any `-export(..)` or record\ndefinitions.\n\n## \\-error() and -warning() directives\n\nThe directive `-error(Term)` causes a compilation error.\n\n_Example:_\n\n```erlang\n-module(t).\n-export([version/0]).\n\n-ifdef(VERSION).\nversion() -> ?VERSION.\n-else.\n-error(\"Macro VERSION must be defined.\").\nversion() -> \"\".\n-endif.\n```\n\nThe error message will look like this:\n\n```text\n% erlc t.erl\nt.erl:7: -error(\"Macro VERSION must be defined.\").\n```\n\nThe directive `-warning(Term)` causes a compilation warning.\n\n_Example:_\n\n```erlang\n-module(t).\n-export([version/0]).\n\n-ifndef(VERSION).\n-warning(\"Macro VERSION not defined -- using default version.\").\n-define(VERSION, \"0\").\n-endif.\nversion() -> ?VERSION.\n```\n\nThe warning message will look like this:\n\n```text\n% erlc t.erl\nt.erl:5: Warning: -warning(\"Macro VERSION not defined -- using default version.\").\n```\n\n> #### Change {: .info }\n>\n> The `-error()` and `-warning()` directives were added in Erlang/OTP 19.","title":"The -feature() directive - Preprocessor","ref":"macros.html#the-feature-directive"},{"type":"extras","doc":"The construction `??Arg`, where `Arg` is a macro argument, is expanded to a\nstring containing the tokens of the argument. This is similar to the `#arg`\nstringifying construction in C.\n\n_Example:_\n\n```erlang\n-define(TESTCALL(Call), io:format(\"Call ~s: ~w~n\", [??Call, Call])).\n\n?TESTCALL(myfunction(1,2)),\n?TESTCALL(you:function(2,1)).\n```\n\nresults in\n\n```erlang\nio:format(\"Call ~s: ~w~n\",[\"myfunction ( 1 , 2 )\",myfunction(1,2)]),\nio:format(\"Call ~s: ~w~n\",[\"you : function ( 2 , 1 )\",you:function(2,1)]).\n```\n\nThat is, a trace output, with both the function called and the resulting value.","title":"Stringifying Macro Arguments - Preprocessor","ref":"macros.html#stringifying-macro-arguments"},{"type":"extras","doc":"\n# Records\n\nA record is a data structure for storing a fixed number of elements. It has\nnamed fields and is similar to a struct in C. Record expressions are translated\nto tuple expressions during compilation.\n\nMore examples are provided in\n[Programming Examples](`e:system:prog_ex_records.md`).","title":"Records","ref":"ref_man_records.html"},{"type":"extras","doc":"A record definition consists of the name of the record, followed by the field\nnames of the record. Record and field names must be atoms. Each field can be\ngiven an optional default value. If no default value is supplied, `undefined` is\nused.\n\n```erlang\n-record(Name, {Field1 [= Expr1],\n ...\n FieldN [= ExprN]}).\n```\n\nThe default value for a field is an arbitrary expression, except that it must\nnot use any variables.\n\nA record definition can be placed anywhere among the attributes and function\ndeclarations of a module, but the definition must come before any usage of the\nrecord.\n\nIf a record is used in several modules, it is recommended that the record\ndefinition is placed in an include file.\n\n> #### Change {: .info }\n>\n> Starting from Erlang/OTP 26, records can be defined in the Erlang shell\n> using the syntax described in this section. In earlier releases, it was\n> necessary to use the `m:shell` built-in function `rd/2`.","title":"Defining Records - Records","ref":"ref_man_records.html#defining-records"},{"type":"extras","doc":"The following expression creates a new `Name` record where the value of each\nfield `FieldI` is the value of evaluating the corresponding expression `ExprI`:\n\n```text\n#Name{Field1=Expr1, ..., FieldK=ExprK}\n```\n\nThe fields can be in any order, not necessarily the same order as in the record\ndefinition, and fields can be omitted. Omitted fields get their respective\ndefault value instead.\n\nIf several fields are to be assigned the same value, the following construction\ncan be used:\n\n```text\n#Name{Field1=Expr1, ..., FieldK=ExprK, _=ExprL}\n```\n\nOmitted fields then get the value of evaluating `ExprL` instead of their default\nvalues. This feature is primarily intended to be used to create patterns for ETS\nand Mnesia match functions.\n\n_Example:_\n\n```erlang\n-record(person, {name, phone, address}).\n\nlookup(Name, Tab) ->\n ets:match_object(Tab, #person{name=Name, _='_'}).\n```","title":"Creating Records - Records","ref":"ref_man_records.html#creating-records"},{"type":"extras","doc":"```text\nExpr#Name.Field\n```\n\nReturns the value of the specified field. `Expr` is to evaluate to a `Name`\nrecord.\n\n_Example_:\n\n```erlang\n-record(person, {name, phone, address}).\n\nget_person_name(Person) ->\n Person#person.name.\n```\n\nThe following expression returns the position of the specified field in the\ntuple representation of the record:\n\n```text\n#Name.Field\n```\n\n_Example:_\n\n```erlang\n-record(person, {name, phone, address}).\n\nlookup(Name, List) ->\n lists:keyfind(Name, #person.name, List).\n```","title":"Accessing Record Fields - Records","ref":"ref_man_records.html#accessing-record-fields"},{"type":"extras","doc":"```text\nExpr#Name{Field1=Expr1, ..., FieldK=ExprK}\n```\n\n`Expr` is to evaluate to a `Name` record. A copy of this record is returned,\nwith the value of each specified field `FieldI` changed to the value of\nevaluating the corresponding expression `ExprI`. All other fields retain their\nold values.","title":"Updating Records - Records","ref":"ref_man_records.html#updating-records"},{"type":"extras","doc":"Since record expressions are expanded to tuple expressions, creating\nrecords and accessing record fields are allowed in guards. However,\nall subexpressions (for initializing fields), must be valid guard\nexpressions as well.\n\n_Examples:_\n\n```erlang\nhandle(Msg, State) when Msg =:= #msg{to=void, no=3} ->\n ...\n\nhandle(Msg, State) when State#state.running =:= true ->\n ...\n```\n\nThere is also a type test BIF [`is_record(Term, RecordTag)`](`is_record/2`).\n\n_Example:_\n\n```erlang\nis_person(P) when is_record(P, person) ->\n true;\nis_person(_P) ->\n false.\n```","title":"Records in Guards - Records","ref":"ref_man_records.html#records-in-guards"},{"type":"extras","doc":"A pattern that matches a certain record is created in the same way as a record\nis created:\n\n```text\n#Name{Field1=Expr1, ..., FieldK=ExprK}\n```\n\nIn this case, one or more of `Expr1` ... `ExprK` can be unbound variables.","title":"Records in Patterns - Records","ref":"ref_man_records.html#records-in-patterns"},{"type":"extras","doc":"Assume the following record definitions:\n\n```erlang\n-record(nrec0, {name = \"nested0\"}).\n-record(nrec1, {name = \"nested1\", nrec0=#nrec0{}}).\n-record(nrec2, {name = \"nested2\", nrec1=#nrec1{}}).\n\nN2 = #nrec2{},\n```\n\nAccessing or updating nested records can be written without parentheses:\n\n```text\n\"nested0\" = N2#nrec2.nrec1#nrec1.nrec0#nrec0.name,\n N0n = N2#nrec2.nrec1#nrec1.nrec0#nrec0{name = \"nested0a\"},\n```\n\nwhich is equivalent to:\n\n```text\n\"nested0\" = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0.name,\nN0n = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0{name = \"nested0a\"},\n```\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP R14, parentheses were necessary when accessing or updating\n> nested records.","title":"Nested Records - Records","ref":"ref_man_records.html#nested-records"},{"type":"extras","doc":"Record expressions are translated to tuple expressions during compilation. A\nrecord defined as:\n\n```erlang\n-record(Name, {Field1, ..., FieldN}).\n```\n\nis internally represented by the tuple:\n\n```text\n{Name, Value1, ..., ValueN}\n```\n\nHere each `ValueI` is the default value for `FieldI`.\n\nTo each module using records, a pseudo function is added during compilation to\nobtain information about records:\n\n```erlang\nrecord_info(fields, Record) -> [Field]\nrecord_info(size, Record) -> Size\n```\n\n`Size` is the size of the tuple representation, that is, one more than the\nnumber of fields.","title":"Internal Representation of Records - Records","ref":"ref_man_records.html#internal-representation-of-records"},{"type":"extras","doc":"\n# Errors and Error Handling","title":"Errors and Error Handling","ref":"errors.html"},{"type":"extras","doc":"Errors can roughly be divided into four different types:\n\n- **Compile-time errors** - When the compiler fails to compile the program, for\n example a syntax error.\n\n- **Logical errors** - When a program does not behave as intended, but does not\n crash. An example is that nothing happens when a button in a graphical user\n interface is clicked.\n\n- **[](){: #run-time-errors } Run-time errors** - \n When a crash occurs. An example is when an operator is applied to arguments of\n the wrong type. The Erlang programming language has built-in features for\n handling of run-time errors. A run-time error can also be emulated by calling\n [`error(Reason)`](`erlang:error/1`). Run-time errors are exceptions of class\n `error`.\n\n- **[](){: #generated-errors } Generated errors**\n When the code itself calls [`exit/1`](`erlang:exit/1`) or\n [`throw/1`](`erlang:throw/1`). Generated errors are exceptions of class `exit`\n or `throw`.\n\nWhen an exception occurs in Erlang, execution of the process that evaluated the\nerroneous expression is stopped. This is referred to as a _failure_, that\nexecution or evaluation _fails_, or that the process _fails_, _terminates_, or\n_exits_. Notice that a process can terminate/exit for other reasons than a\nfailure.\n\nA process that terminates emits an _exit signal_ with an _exit reason_ that\ndescribes why the process terminated. Normally, some information about any\nerroneous termination is printed to the terminal. See\n[Process Termination](ref_man_processes.md#process-termination) in the Processes\nchapter for more details on termination.","title":"Terminology - Errors and Error Handling","ref":"errors.html#terminology"},{"type":"extras","doc":"Exceptions are [run-time errors](errors.md#run-time-errors) or\n[generated errors](errors.md#generated-errors) and are of three different\nclasses, with different origins. The [try](expressions.md#try) expression can\ndistinguish between the different classes, whereas the\n[catch](expressions.md#catch-and-throw) expression cannot. `try` and `catch` are described\nin [Expressions](expressions.md).\n\n| _Class_ | _Origin_ |\n| ------- | ---------------------------------------------------------------------------------- |\n| `error` | Run-time error, for example, `1+a`, or the process called [`error/1`](`error/1`) |\n| `exit` | The process called [`exit/1`](`exit/1`) |\n| `throw` | The process called [`throw/1`](`throw/1`) |\n\n_Table: Exception Classes._\n\nAll of the above exceptions can also be generated by calling `erlang:raise/3`.\n\nAn exception consists of its class, an exit reason (see\n[Exit Reason](errors.md#exit_reasons)), and a stack trace (which aids in finding\nthe code location of the exception).\n\nThe stack trace can be bound to a variable from within a `try` expression for\nany exception class, or as part of the exit reason when a run-time error is\ncaught by a `catch`. Example:\n\n```erlang\n> {'EXIT',{test,Stacktrace}} = (catch error(test)), Stacktrace.\n[{shell,apply_fun,3,[]},\n {erl_eval,do_apply,6,[]},\n ...]\n> try throw(test) catch Class:Reason:Stacktrace -> Stacktrace end.\n[{shell,apply_fun,3,[]},\n {erl_eval,do_apply,6,[]},\n ...]\n```\n\n[](){: #stacktrace }","title":"Exceptions - Errors and Error Handling","ref":"errors.html#exceptions"},{"type":"extras","doc":"The stack back-trace ([_stacktrace_](`t:erlang:stacktrace/0`)) is a list that\ncontains `{Module, Function, Arity, ExtraInfo}` and/or `{Fun, Arity, ExtraInfo}`\ntuples. The field `Arity` in the tuple can be the argument list of that function\ncall instead of an arity integer, depending on the exception.\n\n`ExtraInfo` is a (possibly empty) list of two-element tuples in any order that\nprovides additional information about the exception. The first element is an\natom describing the type of information in the second element. The following\nitems can occur:\n\n- **`error_info`** - The second element of the tuple is a map providing\n additional information about what caused the exception. This information can\n be created by calling [`error/3`](`erlang:error/3`) and is used by\n `erl_error:format_exception/4`.\n\n- **`file`** - The second element of the tuple is a string (list of characters)\n representing the filename of the source file of the function.\n\n- **`line`** - The second element of the tuple is the line number (an\n integer > 0) in the source file where the exception occurred or the function\n was called.\n\n> #### Warning {: .warning }\n>\n> Developers should rely on stacktrace entries only for debugging purposes.\n>\n> The VM performs tail call optimization, which does not add new entries to the\n> stacktrace, and also limits stacktraces to a certain depth. Furthermore,\n> compiler options, optimizations, and future changes may add or remove\n> stacktrace entries, causing any code that expects the stacktrace to be in a\n> certain order or contain specific items to fail.\n>\n> The only exception to this rule is the class `error` with the reason `undef`\n> which is guaranteed to include the `Module`, `Function` and `Arity` of the\n> attempted function as the first stacktrace entry.","title":"The call-stack back trace (stacktrace) - Errors and Error Handling","ref":"errors.html#the-call-stack-back-trace-stacktrace"},{"type":"extras","doc":"","title":"Handling of Run-time Errors in Erlang - Errors and Error Handling","ref":"errors.html#handling-of-run-time-errors-in-erlang"},{"type":"extras","doc":"It is possible to prevent run-time errors and other exceptions from\ncausing the process to terminate by using [`try`](expressions.md#try)\nor [`catch`](expressions.md#catch-and-throw).","title":"Error Handling Within Processes - Errors and Error Handling","ref":"errors.html#error-handling-within-processes"},{"type":"extras","doc":"Processes can monitor other processes and detect process terminations, see\n[Processes](ref_man_processes.md#errors).\n\n[](){: #exit_reasons }","title":"Error Handling Between Processes - Errors and Error Handling","ref":"errors.html#error-handling-between-processes"},{"type":"extras","doc":"When a run-time error occurs, that is an exception of class `error`. The exit\nreason is a tuple `{Reason,Stack}`, where `Reason` is a term indicating the type\nof error:\n\n- **`badarg`** - Bad argument. The argument is of wrong data type, or\n is otherwise badly formed.\n\n- **`badarith`** - An argument for an arithmetic expression was not numeric,\n or the expression does not evaluate to finite number.\n\n- **`{badmatch,V}`** - Evaluation of a match expression failed. The\n value `V` did not match.\n\n- **`function_clause`** - No matching function clause is found when\n evaluating a function call.\n\n- **`{case_clause,V}`** - No matching branch is found when evaluating\n a `case` expression. The value `V` did not match.\n\n- **`if_clause`** - No true branch is found when evaluating an `if`\n expression.\n\n- **`{try_clause,V}`** - No matching branch is found when evaluating\n the of-section of a `try` expression. The value `V` did not\n match.\n\n- **`undef`** - The function cannot be found when evaluating a\n function call.\n\n- **`{badfun,F}`** - `F` was expected to a be a fun, but is not.\n\n- **`{badarity,{Fun,Args}}`** - A fun is applied to the wrong number of\n arguments.\n\n- **`timeout_value`** - The timeout value in a `receive...after`\n expression is evaluated to something else than an integer or\n `infinity`.\n\n- **`noproc`** - Trying to create [link](`link/1`) or\n [monitor](`monitor/2`) to a non-existing process or port.\n\n- **`noconnection`** - A link or monitor to a remote process was\n broken because a connection between the nodes could not be\n established or was severed.\n\n- **`{nocatch,V}`** - Trying to evaluate a `throw `outside a\n `catch`. `V` is the thrown term.\n\n- **`system_limit`** - A system limit has been reached. See\n [System Limits in the Efficiency Guide](`e:system:system_limits.md`)\n for information about system limits.\n\n`Stack` is the stack of function calls being evaluated when the error occurred,\ngiven as a list of tuples `{Module,Name,Arity,ExtraInfo}` with the most recent\nfunction call first. The most recent function call tuple can in some cases be\n`{Module,Name,[Arg],ExtraInfo}`.","title":"Exit Reasons - Errors and Error Handling","ref":"errors.html#exit-reasons"},{"type":"extras","doc":"\n# Features\n\n[](){: #features } Introduced in OTP 25, Erlang has the concept of selectable\nfeatures. A feature can change, add or remove behaviour of the language and/or\nruntime system. Examples can include:\n\n- Adding new syntactical constructs to the language\n- Change the semantics of an existing construct\n- Change the behaviour of some runtime aspect\n\nA feature will start out with a status of experimental part of OTP, making it\npossible to try out for users and give feedback. The possibility to try out\nfeatures is enabled by options to the compiler, directives in a module and\noptions to the runtime system. Even when a feature is not experimental it will\nstill be possible to enable or disable it. This makes it possible to adapt a\ncode base at a suitable pace instead of being forced when changing to a new\nrelease.\n\nThe status of a feature will eventually end up as being either a permanent part\nof OTP or rejected, being removed and no longer selectable.","title":"Features","ref":"features.html"},{"type":"extras","doc":"A feature is in one of four possible states:\n\n- **Experimental** - The initial state, is meant for trying out and collecting\n feedback. The feature can be enabled but is disabled by default.\n\n- **Approved** - The feature has been finalised and is now part of OTP. By\n default it is enabled, but can be disabled.\n\n- **Permanent** - The feature is now a permanent part of OTP. It can no longer\n be disabled.\n\n- **Rejected** - The feature never reached the approved state and will not be\n part of OTP. It cannot be enabled.\n\nAfter leaving the experimental state, a feature can enter any of the other three\nstates, and if the next state is approved, the feature will eventually end up in\nthe permanent state. A feature can change state only in connection with a\nrelease.\n\nA feature may be in the approved state for several releases.\n\n| State | Default | Configurable | Available |\n| ------------ | -------- | ------------ | --------- |\n| Experimental | disabled | yes | yes |\n| Approved | enabled | yes | yes |\n| Permanent | enabled | no | yes |\n| Rejected | disabled | no | no |\n\n_Table: Feature States_\n\n- Being configurable means the possibility to enable or disable the feature by\n means of compiler options and directives in the file being compiled.\n- Being available can be seen using the `FEATURE_AVAILABLE` macro.","title":"Life cycle of features - Features","ref":"features.html#life-cycle-of-features"},{"type":"extras","doc":"To use a feature that is in the experimental state, it has to be enabled during\ncompilation. This can be done in a number of different ways:\n\n- **Options to `erlc`** - Options\n [`-enable-feature`](`e:erts:erlc_cmd.md#enable-feature`) and\n [`-disable-feature`](`e:erts:erlc_cmd.md#disable-feature`) can be used to\n enable or disable individal features.\n\n- **Compiler options** - The compiler option\n [`{feature, , enable|disable}`](`m:compile#feature-option`) can be\n used either as a `+ ` option to `erlc` or in the options argument to\n functions in the `compile` module.\n\n- **The feature directive** - Inside a prefix of a module, one can use a\n [`-feature( , enable|disable)`](macros.md#feature-directive)\n directive. This is the preferred method of enabling and disabling features.\n\n> #### Change {: .info }\n>\n> In Erlang/OTP 25, in order to load a module with a feature enabled, it was\n> necessary to also enable the feature in the runtime. This was done using\n> option [`-enable-feature`](`e:erts:erl_cmd.md#enable-feature`) to `erl`. This\n> requirement was removed in Erlang/OTP 26. However, if you want to use features\n> directly in shell, you still need to enable them in the runtime.","title":"Enabling and Disabling Features - Features","ref":"features.html#enabling-and-disabling-features"},{"type":"extras","doc":"To allow for conditional compilation during transitioning of a code base and/or\ntrying out experimental features\n[feature](`e:system:macros.md#predefined-macros`) `predefined macros`\n`?FEATURE_AVAILABLE(Feature)` and `?FEATURE_ENABLED(Feature)` are available.","title":"Preprocessor Additions - Features","ref":"features.html#preprocessor-additions"},{"type":"extras","doc":"The module `erl_features` `m:erl_features` exports a number of functions that\ncan be used to obtain information about current features as well as the features\nused when compiling a module.\n\nOne can also use the `erlc` options\n[`-list-features`](`e:erts:erlc_cmd.md#list-features`) and\n[`-describe-feature `](`e:erts:erlc_cmd.md#describe-feature`) to get\ninformation about existing features.\n\nAdditionally, there is the compiler option\n[`warn_keywords`](`m:compile#warn-keywords`) that can be used to find atoms in\nthe code base that might collide with keywords in features not yet enabled.","title":"Information about Existing Features - Features","ref":"features.html#information-about-existing-features"},{"type":"extras","doc":"The following configurable features exist:\n\n- **`maybe_expr` (experimental)** - Implementation of the\n [`maybe`](expressions.md#maybe) expression proposed in\n [EEP 49](https://www.erlang.org/eeps/eep-0049).\n It was approved in Erlang/OTP 27.","title":"Existing Features - Features","ref":"features.html#existing-features"},{"type":"extras","doc":"\n# Processes","title":"Processes","ref":"ref_man_processes.html"},{"type":"extras","doc":"Erlang is designed for massive concurrency. Erlang processes are lightweight\n(grow and shrink dynamically) with small memory footprint, fast to create and\nterminate, and the scheduling overhead is low.","title":"Processes - Processes","ref":"ref_man_processes.html#processes"},{"type":"extras","doc":"A process is created by calling [`spawn()`](`erlang:spawn/3`):\n\n```erlang\nspawn(Module, Name, Args) -> pid()\n Module = Name = atom()\n Args = [Arg1,...,ArgN]\n ArgI = term()\n```\n\n`spawn()` creates a new process and returns the pid.\n\nThe new process starts executing in `Module:Name(Arg1,...,ArgN)` where the\narguments are the elements of the (possible empty) `Args` argument list.\n\nThere exist a number of different `spawn` BIFs:\n\n- [`spawn/1,2,3,4`](`erlang:spawn/4`)\n- [`spawn_link/1,2,3,4`](`erlang:spawn_link/4`)\n- [`spawn_monitor/1,2,3,4`](`erlang:spawn_monitor/4`)\n- [`spawn_opt/2,3,4,5`](`erlang:spawn_opt/5`)\n- [`spawn_request/1,2,3,4,5`](`erlang:spawn_request/5`)","title":"Process Creation - Processes","ref":"ref_man_processes.html#process-creation"},{"type":"extras","doc":"Besides addressing a process by using its pid, there are also BIFs for\nregistering a process under a name. The name must be an atom and is\nautomatically unregistered if the process terminates:\n\n| _BIF_ | _Description_ |\n| ------------------------------------- | -------------------------------------------------------------------------------------- |\n| [`register(Name, Pid)`](`register/2`) | Associates the name `Name`, an atom, with the process `Pid`. |\n| `registered/0` | Returns a list of names that have been registered using [`register/2`](`register/2`). |\n| [`whereis(Name)`](`whereis/1`) | Returns the pid registered under `Name`, or `undefined `if the name is not registered. |\n\n_Table: Name Registration BIFs_","title":"Registered Processes - Processes","ref":"ref_man_processes.html#registered-processes"},{"type":"extras","doc":"When sending a message to a process, the receiving process can be identified by\na [Pid](data_types.md#pid), a\n[registered name](ref_man_processes.md#registered-processes), or a _process\nalias_ which is a term of the type [reference](data_types.md#reference). The\ntypical use case that process aliases were designed for is a request/reply\nscenario. Using a process alias when sending the reply makes it possible for the\nreceiver of the reply to prevent the reply from reaching its message queue if\nthe operation times out or if the connection between the processes is lost.\n\nA process alias can be used as identifier of the receiver when sending a message\nusing the [send operator (`!`)](expressions.md#send) or send BIFs such as\n`erlang:send/2`. As long as the process alias is active, messages will be\ndelivered the same way as if the process identifier of the process that created\nthe alias had been used. When the alias has been deactivated, messages sent\nusing the alias will be dropped before entering the message queue of the\nreceiver. Note that messages that at deactivation time already have entered the\nmessage queue will _not_ be removed.\n\nA process alias is created either by calling one of the\n[`alias/0,1`](`erlang:alias/0`) BIFs or by creating an alias and a monitor\nsimultaneously. If the alias is created together with a monitor, the same\nreference will be used both as monitor reference and alias. Creating a monitor\nand an alias at the same time is done by passing the `{alias, _}` option to the\n[`monitor/3`](`erlang:monitor/3`) BIF. The `{alias, _}` option can also be\npassed when creating a monitor via [`spawn_opt()`](`erlang:spawn_opt/5`), or\n[`spawn_request()`](`erlang:spawn_request/5`).\n\nA process alias can be deactivated by the process that created it by calling the\n[`unalias/1`](`erlang:unalias/1`) BIF. It is also possible to automatically\ndeactivate an alias on certain events. See the documentation of the\n[`alias/1`](`erlang:alias/1`) BIF, and the `{alias, _}` option of the\n[`monitor/3`](`erlang:monitor/3`) BIF for more information about automatic\ndeactivation of aliases.\n\nIt is _not_ possible to:\n\n- create an alias identifying another process than the caller.\n- deactivate an alias unless it identifies the caller.\n- look up an alias.\n- look up the process identified by an alias.\n- check if an alias is active or not.\n- check if a reference is an alias.\n\nThese are all intentional design decisions relating to performance, scalability,\nand distribution transparency.","title":"Process Aliases - Processes","ref":"ref_man_processes.html#process-aliases"},{"type":"extras","doc":"When a process terminates, it always terminates with an _exit reason_. The\nreason can be any term.\n\nA process is said to terminate _normally_, if the exit reason is the atom\n`normal`. A process with no more code to execute terminates normally.\n\nA process terminates with an exit reason `{Reason,Stack}` when a run-time error\noccurs. See [Exit Reasons](errors.md#exit_reasons).\n\nA process can terminate itself by calling one of the following BIFs:\n\n- [`exit(Reason)`](`exit/1`)\n- [`error(Reason)`](`erlang:error/1`)\n- [`error(Reason, Args)`](`erlang:error/2`)\n\nThe process then terminates with reason `Reason` for [`exit/1`](`exit/1`) or\n`{Reason,Stack}` for the others.\n\nA process can also be terminated if it receives an exit signal with another exit\nreason than `normal`, see [Error Handling](ref_man_processes.md#errors).","title":"Process Termination - Processes","ref":"ref_man_processes.html#process-termination"},{"type":"extras","doc":"[](){: #message-sending } All communication between Erlang processes and Erlang\nports is done by sending and receiving asynchronous signals. The most common\nsignals are Erlang message signals. A message signal can be sent using the\n[send operator `!`](expressions.md#send). A received message can be fetched from\nthe message queue by the receiving process using the\n[`receive`](expressions.md#receive) expression.\n\n[](){: #sync-comm }\n\nSynchronous communication can be broken down into multiple asynchronous signals.\nAn example of such a synchronous communication is a call to the\n`erlang:process_info/2` BIF when the first argument does not equal the process\nidentifier of the calling process. The caller sends an asynchronous signal\nrequesting information, and then blocks waiting for the reply signal containing\nthe requested information. When the request signal reaches its destination, the\ndestination process replies with the requested information.","title":"Signals - Processes","ref":"ref_man_processes.html#signals"},{"type":"extras","doc":"There are many signals that processes and ports use to communicate. The list\nbelow contains the most important signals. In all the cases of request/reply\nsignal pairs, the request signal is sent by the process calling the specific\nBIF, and the reply signal is sent back to it when the requested operation has\nbeen performed.\n\n- **`message`** - Sent when using the [send operator `!`](expressions.md#send),\n or when calling one of the [`erlang:send/2,3`](`erlang:send/2`) or\n [`erlang:send_nosuspend/2,3`](`erlang:send_nosuspend/2`) BIFs.\n\n- **`link`** - Sent when calling the [link/1](`erlang:link/1`) BIF.\n\n- **`unlink`** - Sent when calling the [unlink/1](`erlang:unlink/1`) BIF.\n\n- **`exit`** - Sent either when explicitly sending an `exit` signal by calling\n the [exit/2](`erlang:exit/2`) BIF, or when a\n [linked process terminates](ref_man_processes.md#sending_exit_signals). If the\n signal is sent due to a link, the signal is sent after all\n [_directly visible Erlang resources_](ref_man_processes.md#visible-resources)\n used by the process have been released.\n\n- **`monitor`** - Sent when calling one of the [monitor/2,3](`erlang:monitor/3`)\n BIFs.\n\n- **`demonitor`** - Sent when calling one of the\n [demonitor/1,2](`erlang:demonitor/1`) BIFs, or when a process monitoring\n another process terminates.\n\n- **`down`** - Sent by a\n [monitored process or port that terminates](ref_man_processes.md#monitors).\n The signal is sent after all\n [_directly visible Erlang resources_](ref_man_processes.md#visible-resources)\n used by the process or the port have been released.\n\n- **`change`** - Sent by the\n [clock service](ref_man_processes.md#runtime-service) on the local runtime\n system, when the [time offset](`erlang:time_offset/0`) changes, to processes\n which have [monitored the `time_offset`](`erlang:monitor/2`).\n\n- **`group_leader`** - Sent when calling the\n [group_leader/2](`erlang:group_leader/2`) BIF.\n\n- **`spawn_request`/`spawn_reply`, `open_port_request`/`open_port_reply`** -\n Sent due to a call to one of the [`spawn/1,2,3,4`](`erlang:spawn/4`),\n [`spawn_link/1,2,3,4`](`erlang:spawn_link/4`),\n [`spawn_monitor/1,2,3,4`](`erlang:spawn_monitor/4`),\n [`spawn_opt/2,3,4,5`](`erlang:spawn_opt/5`),\n [`spawn_request/1,2,3,4,5`](`erlang:spawn_request/5`), or `erlang:open_port/2`\n BIFs. The request signal is sent to the\n [spawn service](ref_man_processes.md#runtime-service) which responds with the\n reply signal.\n\n- **`alive_request`/`alive_reply`** - Sent due to a call to the\n [is_process_alive/1](`erlang:is_process_alive/1`) BIF.\n\n- **`garbage_collect_request`/`garbage_collect_reply`,\n `check_process_code_request`/`check_process_code_reply`,\n `process_info_request`/`process_info_reply`** - Sent due to a call to one of\n the [garbage_collect/1,2](`erlang:garbage_collect/1`),\n [erlang:check_process_code/2,3](`erlang:check_process_code/2`), or\n [process_info/1,2](`erlang:process_info/2`) BIFs. Note that if the request is\n directed towards the caller itself and it is a synchronous request, no\n signaling will be performed and the caller will instead synchronously perform\n the request before returning from the BIF.\n\n- **`port_command`, `port_connect`, `port_close`** - Sent by a process to a port\n on the local node using the [send operator (`!`)](expressions.md#send), or by\n calling one of the [`send()`](`erlang:send/2`) BIFs. The signal is sent by\n passing a term on the format `{Owner, {command, Data}}`,\n `{Owner, {connect, Pid}}`, or `{Owner, close}` as message.\n\n- **`port_command_request`/`port_command_reply`,\n `port_connect_request`/`port_connect_reply`,\n `port_close_request`/`port_close_reply`,\n `port_control_request`/`port_control_reply`,\n `port_call_request`/`port_call_reply`,\n `port_info_request`/`port_info_reply`** - Sent due to a call to one of the\n [`erlang:port_command/2,3`](`erlang:port_command/2`), `erlang:port_connect/2`,\n `erlang:port_close/1`, `erlang:port_control/3`, `erlang:port_call/3`,\n [`erlang:port_info/1,2`](`erlang:port_info/1`) BIFs. The request signal is\n sent to a port on the local node which responds with the reply signal.\n\n- **`register_name_request`/`register_name_reply`,\n `unregister_name_request`/`unregister_name_reply`,\n `whereis_name_request`/`whereis_name_reply`** - Sent due to a call to one of\n the [`register/2`](`erlang:register/2`),\n [`unregister/1`](`erlang:unregister/1`), or [`whereis/1`](`erlang:whereis/1`)\n BIFs. The request signal is sent to the\n [name service](ref_man_processes.md#runtime-service), which responds with the\n reply signal.\n\n- **`timer_start_request`/`timer_start_reply`,\n `timer_cancel_request`/`timer_cancel_reply`** - Sent due to a call to one of\n the [`erlang:send_after/3,4`](`erlang:send_after/3`),\n [`erlang:start_timer/3,4`](`erlang:start_timer/3`), or\n [`erlang:cancel_timer/1,2`](`erlang:cancel_timer/1`) BIFs. The request signal\n is sent to the [timer service](ref_man_processes.md#runtime-service) which\n responds with the reply signal.\n\n[](){: #runtime-service } The clock service, the name service, the timer\nservice, and the spawn service mentioned previously are services provided by the\nruntime system. Each of these services consists of multiple independently\nexecuting entities. Such a service can be viewed as a group of processes, and\ncould actually be implemented like that. Since each service consists of multiple\nindependently executing entities, the order between multiple signals sent from\none service to one process is _not_ preserved. Note that this does _not_ violate\nthe [signal ordering guarantee](ref_man_processes.md#signal-delivery) of the\nlanguage.\n\nThe realization of the signals described earlier may change both at runtime and\ndue to changes in implementation. You may be able to detect such changes using\n`receive` tracing or by inspecting message queues. However, these are internal\nimplementation details of the runtime system that you should _not_ rely on. As\nan example, many of the reply signals are ordinary message signals. When\nthe operation is synchronous, the reply signals do not have to be message\nsignals. The current implementation takes advantage of this and, depending on\nthe state of the system, use alternative ways of delivering the reply signals.\nThe implementation of these reply signals may also, at any time, be changed to\nnot use message signals where it previously did.","title":"Sending Signals - Processes","ref":"ref_man_processes.html#sending-signals"},{"type":"extras","doc":"Signals are received asynchronously and automatically. There is nothing a\nprocess must do to handle the reception of signals, or can do to prevent it. In\nparticular, signal reception is _not_ tied to the execution of a\n[`receive`](expressions.md#receive) expression, but can happen anywhere in the\nexecution flow of a process.\n\nWhen a signal is received by a process, some kind of action is taken. The\nspecific action taken depends on the signal type, contents of the signal, and\nthe state of the receiving process. Actions taken for the most common signals:\n\n- **`message`** - If the message signal was sent using a\n [process alias](ref_man_processes.md#process-aliases) that is no longer\n active, the message signal will be dropped; otherwise, if the alias is still\n active or the message signal was sent by other means, the message is added to\n the end of the message queue. When the message has been added to the message\n queue, the receiving process can fetch the message from the message queue\n using the [`receive`](expressions.md#receive) expression.\n\n- **`link`, `unlink`** - Very simplified it can be viewed as updating process\n local information about the link. A detailed description of the\n [link protocol](`e:erts:erl_dist_protocol.md#link_protocol`) can be found in\n the _Distribution Protocol_ chapter of the _ERTS User's Guide_.\n\n- **`exit`** - Set the receiver in an exiting state, drop the signal, or convert\n the signal into a message and add it to the end of the message queue. If the\n receiver is set in an exiting state, no more Erlang code will be executed and\n the process is scheduled for termination. The section\n [_Receiving Exit Signals_](ref_man_processes.md#receiving_exit_signals) below\n gives more details on the action taken when an `exit` signal is received.\n\n- **`monitor`, `demonitor`** - Update process local information about the\n monitor.\n\n- **`down`, `change`** - Convert into a message if the corresponding monitor is\n still active; otherwise, drop the signal. If the signal is converted into a\n message, it is also added to the end of the message queue.\n\n- **`group_leader`** - Change the group leader of the process.\n\n- **`spawn_reply`** - Convert into a message, or drop the signal depending on\n the reply and how the `spawn_request` signal was configured. If the signal is\n converted into a message it is also added to the end of the message queue. For\n more information see the [`spawn_request()`](`erlang:spawn_request/5`) BIF.\n\n- **`alive_request`** - Schedule execution of the _is alive_ test. If the\n process is in an exiting state, the _is alive_ test will not be executed until\n after all\n [_directly visible Erlang resources_](ref_man_processes.md#visible-resources)\n used by the process have been released. The `alive_reply` will be sent after\n the _is alive_ test has executed.\n\n- **`process_info_request`, `garbage_collect_request`,\n `check_process_code_request`** - Schedule execution of the requested\n operation. The reply signal will be sent when the operation has been executed.\n\nNote that some actions taken when a signal is received involves _scheduling_\nfurther actions which will result in a reply signal when these scheduled actions\nhave completed. This implies that the reply signals may be sent in a different\norder than the order of the incoming signals that triggered these operations.\nThis does, however, _not_ violate the\n[signal ordering guarantee](ref_man_processes.md#signal-delivery) of the\nlanguage.\n\n[](){: #message-queue-order } The order of messages in the message queue of a\nprocess reflects the order in which the signals corresponding to the messages\nhas been received since\n[all signals that add messages to the message queue add them at the end of the message queue](ref_man_processes.md#receiving-signals).\nMessages corresponding to signals from the same sender are also ordered in the\nsame order as the signals were sent due to the\n[signal ordering guarantee](ref_man_processes.md#signal-delivery) of the\nlanguage.\n\n[](){: #visible-resources }","title":"Receiving Signals - Processes","ref":"ref_man_processes.html#receiving-signals"},{"type":"extras","doc":"As described earlier, `exit` signals due to links, `down` signals, and reply\nsignals from an exiting process due to `alive_request`s are not sent until all\n_directly visible Erlang resources_ held by the terminating process have been\nreleased. With _directly visible Erlang resources_ we here mean all resources\nmade available by the language excluding resources held by heap data, dirty\nnative code execution and the process identifier of the terminating process.\nExamples of _directly visible Erlang resources_ are\n[registered name](ref_man_processes.md#registered-processes) and [ETS](`m:ets`)\ntables.\n\n#### The Excluded Resources\n\nThe process identifier of the process cannot be released for reuse until\neverything regarding the process has been released.\n\nA process executing dirty native code in a NIF when it receives an exit signal\nwill be set into an exiting state even if it is still executing dirty native\ncode. _Directly visible Erlang resources_ will be released, but the runtime\nsystem cannot force the native code to stop executing. The runtime system tries\nto prevent the execution of the dirty native code from affecting other processes\nby, for example, disabling functionality such as\n[`enif_send()`](`e:erts:erl_nif.md#enif_send`) when used from a terminated\nprocess, but if the NIF is not well behaved it can still affect other processes.\nA well behaved dirty NIF should test if\n[the process it is executing in has exited](`e:erts:erl_nif.md#enif_is_current_process_alive`),\nand if so stop executing.\n\nIn the general case, the heap of a process cannot be removed before all signals\nthat it needs to send have been sent. Resources held by heap data are the memory\nblocks containing the heap, but also include things referred to from the heap\nsuch as off heap binaries, and resources held via NIF\n[resource objects](`e:erts:erl_nif.md#resource_objects`) on the heap.\n\n[](){: #signal-delivery }","title":"Directly Visible Erlang Resources - Processes","ref":"ref_man_processes.html#directly-visible-erlang-resources"},{"type":"extras","doc":"The amount of time that passes between the time a signal is sent and the arrival\nof the signal at the destination is unspecified but positive. If the receiver\nhas terminated, the signal does not arrive, but it can trigger another signal.\nFor example, a `link` signal sent to a non-existing process triggers an `exit`\nsignal, which is sent back to where the `link` signal originated from. When\ncommunicating over the distribution, signals can be lost if the distribution\nchannel goes down.\n\nThe only signal ordering guarantee given is the following: if an entity sends\nmultiple signals to the same destination entity, the order is preserved; that\nis, if `A` sends a signal `S1` to `B`, and later sends signal `S2` to `B`, `S1`\nis guaranteed not to arrive after `S2`. Note that `S1` may, or may not have been\nlost.\n\n[](){: #signal-irregularities }","title":"Delivery of Signals - Processes","ref":"ref_man_processes.html#delivery-of-signals"},{"type":"extras","doc":"- **Synchronous Error Checking** - Some functionality that send signals have\n synchronous error checking when sending locally on a node and fail if the\n receiver is not present at the time when the signal is sent:\n\n - The [send operator (`!`)](expressions.md#send),\n [`erlang:send/2,3`](`erlang:send/2`), BIFs and\n [`erlang:send_nosuspend/2,3`](`erlang:send_nosuspend/2`) BIFs when the\n receiver is identified by a name that is expected to be registered locally.\n - `erlang:link/1`\n - `erlang:group_leader/2`\n\n- **Unexpected Behaviours of Exit Signals** - When a process sends an exit\n signal with exit reason `normal` to itself by calling\n [`erlang:exit(self(), normal)`](`erlang:exit/2`) it will be terminated\n [when the `exit` signal is received](ref_man_processes.md#receiving_exit_signals).\n In all other cases when an exit signal with exit reason `normal` is received,\n it is dropped.\n\n When an\n [`exit` signal with exit reason `kill` is received](ref_man_processes.md#receiving_exit_signals),\n the action taken is different depending on whether the signal was sent due to\n a linked process terminating, or the signal was explicitly sent using the\n [`exit/2`](`erlang:exit/2`) BIF. When sent using the [`exit/2`](`exit/2`) BIF,\n the signal cannot be [trapped](`m:erlang#process_flag_trap_exit`), while it\n can be trapped if the signal was sent due to a link.\n\n- **Blocking Signaling Over Distribution[](){:\n #blocking-signaling-over-distribution } **\n When sending a signal over a distribution channel, the sending process may be\n suspended even though the signal is supposed to be sent asynchronously. This is\n due to the built in flow control over the channel that has been present more or\n less for ever. When the size of the output buffer for the channel reach the _distribution\n buffer busy limit_, processes sending on the channel will be suspended until the\n size of the buffer shrinks below the limit.\n\n Depending on the reason for why the buffer got full, the time it takes before\n suspended processes are resumed can vary _very much_. A consequence of this\n can, for example, be that a timeout in a call to [erpc:call()](`erpc:call/5`)\n is significantly delayed.\n\n Since this functionality has been present for so long, it is not possible to\n remove it, but it is possible to enable _fully asynchronous distributed\n signaling_ on a per process level using\n [`process_flag(async_dist, Bool)`](`m:erlang#process_flag_async_dist`) which\n can be used to solve problems occuring due to blocking signaling. However,\n note that you need to make sure that flow control for data sent using _fully\n asynchronous distributed signaling_ is implemented, or that the amount of such\n data is known to always be limited; otherwise, you may get into a situation\n with excessive memory usage.\n\n The size of the _distribution buffer busy limit_ can be inspected by calling\n [`erlang:system_info(dist_buf_busy_limit)`](`m:erlang#system_info_dist_buf_busy_limit`).\n\nThe irregularities mentioned earlier cannot be fixed as they have been part of\nErlang too long and it would break a lot of existing code.","title":"Irregularities - Processes","ref":"ref_man_processes.html#irregularities"},{"type":"extras","doc":"Two processes can be _linked_ to each other. Also a process and a port that\nreside on the same node can be linked to each other. A link between two\nprocesses can be created if one of them calls the [`link/1`](`erlang:link/1`)\nBIF with the process identifier of the other process as argument. Links can also\nbe created using one the following spawn BIFs\n[`spawn_link()`](`erlang:spawn_link/4`), [`spawn_opt()`](`erlang:spawn_opt/5`),\nor [`spawn_request()`](`erlang:spawn_request/5`). The spawn operation and the\nlink operation will be performed atomically, in these cases.\n\nIf one of the participants of a link terminates, it will\n[send an exit signal](ref_man_processes.md#sending_exit_signals) to the other\nparticipant. The exit signal will contain the\n[exit reason](ref_man_processes.md#link_exit_signal_reason) of the terminated\nparticipant.\n\nA link can be removed by calling the [`unlink/1`](`erlang:unlink/1`) BIF.\n\nLinks are bidirectional and there can only be one link between two processes.\nRepeated calls to `link()` have no effect. Either one of the involved processes\nmay create or remove a link.\n\nLinks are used to monitor the behavior of other processes, see\n[Error Handling](ref_man_processes.md#errors).\n\n[](){: #errors }","title":"Links - Processes","ref":"ref_man_processes.html#links"},{"type":"extras","doc":"Erlang has a built-in feature for error handling between processes. Terminating\nprocesses emit exit signals to all linked processes, which can terminate as well\nor handle the exit in some way. This feature can be used to build hierarchical\nprogram structures where some processes are supervising other processes, for\nexample, restarting them if they terminate abnormally.\n\nSee\n[OTP Design Principles](`e:system:design_principles.md`)\nfor more information about OTP supervision trees, which use this feature.\n\n[](){: #sending_exit_signals }","title":"Error Handling - Processes","ref":"ref_man_processes.html#error-handling"},{"type":"extras","doc":"When a process or port [terminates](ref_man_processes.md#process-termination) it\nwill send exit signals to all processes and ports that it is\n[linked](ref_man_processes.md#links) to. The exit signal will contain the\nfollowing information:\n\n- **Sender identifier** - The process or port identifier of the process or port\n that terminated.\n\n- **Receiver identifier** - The process or port identifier of the process or\n port which the exit signal is sent to.\n\n- **The `link` flag** - This flag will be set indicating that the exit signal\n was sent due to a link.\n\n- **[](){: #link_exit_signal_reason } Exit reason** \n The exit reason of the process or port that terminated or the atom:\n\n - `noproc` in case no process or port was found when setting up a link in a\n preceding call to the [`link(PidOrPort)`](`erlang:link/1`) BIF. The process\n or port identified as sender of the exit signal will equal the `PidOrPort`\n argument passed to [`link/1`](`link/1`).\n - `noconnection` in case the linked processes resides on different nodes and\n the connection between the nodes was lost or could not be established. The\n process or port identified as sender of the exit signal might in this case\n still be alive.\n\nExit signals can also be sent explicitly by calling the\n[`exit(PidOrPort, Reason)`](`erlang:exit/2`) BIF. The exit signal is sent to the\nprocess or port identified by the `PidOrPort` argument. The exit signal sent\nwill contain the following information:\n\n- **Sender identifier** - The process identifier of the process that called\n [`exit/2`](`exit/2`).\n\n- **Receiver identifier** - The process or port identifier of the process or\n port which the exit signal is sent to.\n\n- **The `link` flag** - This flag will not be set, indicating that this exit\n signal was not sent due to a link.\n\n- **Exit reason** - The term passed as `Reason` in the call to\n [`exit/2`](`exit/2`). If `Reason` is the atom `kill`, the receiver cannot\n [trap the exit](`m:erlang#process_flag_trap_exit`) signal and will\n unconditionally terminate when it receives the signal.\n\n[](){: #receiving_exit_signals }","title":"Sending Exit Signals - Processes","ref":"ref_man_processes.html#sending-exit-signals"},{"type":"extras","doc":"What happens when a process receives an exit signal depends on:\n\n- The [trap exit](`m:erlang#process_flag_trap_exit`) state of the receiver at\n the time when the exit signal is received.\n- The exit reason of the exit signal.\n- The sender of the exit signal.\n- The state of the `link` flag of the exit signal. If the `link` flag is set,\n the exit signal was sent due to a link; otherwise, the exit signal was sent by\n a call to the [`exit/2`](`erlang:exit/2`) BIF.\n- If the `link` flag is set, what happens also depends on whether the\n [link is still active or not](`erlang:unlink/1`) when the exit signal is\n received.\n\nBased on the above states, the following will happen when an exit signal is\nreceived by a process:\n\n- The exit signal is silently dropped if:\n\n - the `link` flag of the exit signal is set and the corresponding link has\n been deactivated.\n - the exit reason of the exit signal is the atom `normal`, the receiver is not\n trapping exits, and the receiver and sender are not the same process.\n\n- The receiving process is terminated if:\n\n - the `link` flag of the exit signal is not set, and the exit reason of the\n exit signal is the atom `kill`. The receiving process will terminate with\n the atom `killed` as exit reason.\n - the receiver is not trapping exits, and the exit reason is something other\n than the atom `normal`. Also, if the `link` flag of the exit signal is set,\n the link also needs to be active otherwise the exit signal will be dropped.\n The exit reason of the receiving process will equal the exit reason of the\n exit signal. Note that if the `link` flag is set, an exit reason of `kill`\n will _not_ be converted to `killed`.\n - the exit reason of the exit signal is the atom `normal` and the sender of\n the exit signal is the same process as the receiver. The `link` flag cannot\n be set in this case. The exit reason of the receiving process will be the\n atom `normal`.\n\n- The exit signal is converted to a message signal and added to the end of the\n message queue of the receiver, if the receiver is trapping exits, the `link`\n flag of the exit signal is:\n\n - not set, and the exit reason of the signal is not the atom `kill`.\n - set, and the corresponding link is active. Note that an exit reason of\n `kill` will _not_ terminate the process in this case and it will not be\n converted to `killed`.\n\n The converted message will be on the form `{'EXIT', SenderID, Reason}` where\n `Reason` equals the exit reason of the exit signal and `SenderID` is the\n identifier of the process or port that sent the exit signal.","title":"Receiving Exit Signals - Processes","ref":"ref_man_processes.html#receiving-exit-signals"},{"type":"extras","doc":"An alternative to links are _monitors_. A process `Pid1` can create a\nmonitor for `Pid2` by calling the BIF [`erlang:monitor(process,\nPid2)`](`erlang:monitor/2`). The function returns a reference `Ref`.\n\nIf `Pid2` terminates with exit reason `Reason`, a 'DOWN' message is sent to\n`Pid1`:\n\n```text\n{'DOWN', Ref, process, Pid2, Reason}\n```\n\nIf `Pid2` does not exist, the 'DOWN' message is sent immediately with `Reason`\nset to `noproc`.\n\nMonitors are unidirectional. Repeated calls to `erlang:monitor(process, Pid)`\ncreates several independent monitors, and each one sends a 'DOWN' message when\n`Pid` terminates.\n\nA monitor can be removed by calling [`erlang:demonitor(Ref)`](`erlang:demonitor/1`).\n\nMonitors can be created for processes with registered names, also at other\nnodes.","title":"Monitors - Processes","ref":"ref_man_processes.html#monitors"},{"type":"extras","doc":"Each process has its own process dictionary, accessed by calling the following\nBIFs:\n\n- [`put(Key, Value)`](`erlang:put/2`)\n- [`get(Key)`](`erlang:get/1`)\n- [`get()`](`erlang:get/0`)\n- [`get_keys(Value)`](`erlang:get_keys/1`)\n- [`erase(Key)`](`erlang:erase/1`)\n- [`erase()`](`erlang:erase/0`)","title":"Process Dictionary - Processes","ref":"ref_man_processes.html#process-dictionary"},{"type":"extras","doc":"\n# Distributed Erlang","title":"Distributed Erlang","ref":"distributed.html"},{"type":"extras","doc":"A _distributed Erlang system_ consists of a number of Erlang runtime systems\ncommunicating with each other. Each such runtime system is called a _node_.\nMessage passing between processes at different nodes, as well as links and\nmonitors, are transparent when pids are used. Registered names, however, are\nlocal to each node. This means that the node must be specified as well when\nsending messages, and so on, using registered names.\n\nThe distribution mechanism is implemented using TCP/IP sockets. How to implement\nan alternative carrier is described in the\n[ERTS User's Guide](`e:erts:alt_dist.md`).\n\n> #### Warning {: .warning }\n>\n> Starting a distributed node without also specifying\n> [`-proto_dist inet_tls`](`e:erts:erl_cmd.md#proto_dist`) will expose the node\n> to attacks that may give the attacker complete access to the node and in\n> extension the cluster. When using un-secure distributed nodes, make sure that\n> the network is configured to keep potential attackers out. See the\n> [Using SSL for Erlang Distribution](`e:ssl:ssl_distribution.md`) User's Guide\n> for details on how to setup a secure distributed node.","title":"Distributed Erlang System - Distributed Erlang","ref":"distributed.html#distributed-erlang-system"},{"type":"extras","doc":"A _node_ is an executing Erlang runtime system that has been given a name, using\nthe command-line flag [`-name`](`e:erts:erl_cmd.md#name`) (long names) or\n[`-sname`](`e:erts:erl_cmd.md#sname`) (short names).\n\nThe format of the node name is an atom `name@host`. `name` is the name given by\nthe user. `host` is the full host name if long names are used, or the first part\nof the host name if short names are used. Function [`node()`](`erlang:node/0`)\nreturns the name of the node.\n\n_Example:_\n\n```erlang\n% erl -name dilbert\n(dilbert@uab.ericsson.se)1> node().\n'dilbert@uab.ericsson.se'\n\n% erl -sname dilbert\n(dilbert@uab)1> node().\ndilbert@uab\n```\n\nThe node name can also be given in runtime by calling `net_kernel:start/1`.\n\n_Example:_\n\n```erlang\n% erl\n1> node().\nnonode@nohost\n2> net_kernel:start([dilbert,shortnames]).\n{ok,<0.102.0>}\n(dilbert@uab)3> node().\ndilbert@uab\n```\n\n> #### Note {: .info }\n>\n> A node with a long node name cannot communicate with a node with a short node\n> name.","title":"Nodes - Distributed Erlang","ref":"distributed.html#nodes"},{"type":"extras","doc":"The nodes in a distributed Erlang system are loosely connected. The first time\nthe name of another node is used, for example, if\n[`spawn(Node, M, F, A)`](`spawn/4`) or `net_adm:ping(Node)` is called, a connection\nattempt to that node is made.\n\nConnections are by default transitive. If a node A connects to node B, and node\nB has a connection to node C, then node A also tries to connect to node C. This\nfeature can be turned off by using the command-line flag `-connect_all false`,\nsee [erl](`e:erts:erl_cmd.md`) in ERTS.\n\nIf a node goes down, all connections to that node are removed. Calling\n[`erlang:disconnect_node(Node)`](`erlang:disconnect_node/1`) forces\ndisconnection of a node.\n\nThe list of (visible) nodes currently connected to is returned by `nodes/0`.","title":"Node Connections - Distributed Erlang","ref":"distributed.html#node-connections"},{"type":"extras","doc":"The Erlang Port Mapper Daemon _epmd_ is automatically started at every host\nwhere an Erlang node is started. It is responsible for mapping the symbolic node\nnames to machine addresses. See the [epmd](`e:erts:epmd_cmd.md`) in ERTS.","title":"epmd - Distributed Erlang","ref":"distributed.html#epmd"},{"type":"extras","doc":"In a distributed Erlang system, it is sometimes useful to connect to a\nnode without also connecting to all other nodes. An example is some\nkind of Operation and Maintenance functionality used to inspect the\nstatus of a system, without disturbing it. For this purpose, a _hidden\nnode_ can be used.\n\nA hidden node is a node started with the command-line flag `-hidden`.\nConnections between hidden nodes and other nodes are not transitive, they must\nbe set up explicitly. Also, hidden nodes does not show up in the list of nodes\nreturned by `nodes/0`. Instead, [`nodes(hidden)`](`nodes/1`) or\n[`nodes(connected)`](`nodes/1`) must be used. This means, for example, that the\nhidden node is not added to the set of nodes that `m:global` is keeping track of.\n\n[](){: #dyn_node_name }","title":"Hidden Nodes - Distributed Erlang","ref":"distributed.html#hidden-nodes"},{"type":"extras","doc":"If the node name is set to _`undefined`_ the node will be started in a special\nmode to be the temporary client of another node. The node will then request a\ndynamic node name from the first node it connects to. In addition these\ndistribution settings will be set:\n\n```text\n-dist_listen false -hidden -kernel dist_auto_connect never\n```\n\nAs `-dist_auto_connect` is set to `never`, `net_kernel:connect_node/1` must be\ncalled in order to setup connections. If the first established connection is\nclosed (which gave the node its dynamic name), then any other connections will\nalso be closed and the node will lose its dynamic node name. A new call to\n`net_kernel:connect_node/1` can be made to get a new dynamic node name. The node\nname may change if the distribution is dropped and then set up again.\n\n> #### Change {: .info }\n>\n> The _dynamic node name_ feature is supported from Erlang/OTP 23. Both the\n> temporary client node and the first connected peer node (supplying the dynamic\n> node name) must be at least Erlang/OTP 23 for it to work.","title":"Dynamic Node Name - Distributed Erlang","ref":"distributed.html#dynamic-node-name"},{"type":"extras","doc":"A _C node_ is a C program written to act as a hidden node in a distributed\nErlang system. The library _Erl_Interface_ contains functions for this purpose.\nFor more information about C nodes, see the\n[Erl_Interface](`e:erl_interface:ei_users_guide.md`) application and\n[Interoperability Tutorial.](`e:system:tutorial.md`).","title":"C Nodes - Distributed Erlang","ref":"distributed.html#c-nodes"},{"type":"extras","doc":"> #### Note {: .info }\n>\n> \"Security\" here does _not_ mean cryptographically secure, but rather security\n> against accidental misuse, such as preventing a node from connecting to a\n> cluster with which it is not intended to communicate.\n>\n> Furthermore, the communication between nodes is per default in clear text. If\n> you need strong security, please see\n> [Using TLS for Erlang Distribution ](`e:ssl:ssl_distribution.md`)in the SSL\n> application's User's Guide.\n>\n> Also, the default random cookie mentioned in the following text is not very\n> unpredictable. A better one can be generated using primitives in the `crypto`\n> module, though this still does not make the initial handshake\n> cryptographically secure. And inter-node communication is still in clear text.\n\nAuthentication determines which nodes are allowed to communicate with each\nother. In a network of different Erlang nodes, it is built into the system at\nthe lowest possible level. All nodes use a _magic cookie_, which is an Erlang\natom, when connecting another node.\n\nDuring the connection setup, after node names have been exchanged, the magic\ncookies the nodes present to each other are compared. If they do not match, the\nconnection is rejected. The cookies themselves are never transferred, instead\nthey are compared using hashed challenges, although not in a cryptographically\nsecure manner.\n\nAt start-up, a node has a random atom assigned as its default magic cookie and\nthe cookie of other nodes is assumed to be `nocookie`. The first action of the\nErlang network authentication server (`auth`) is then to search for a file named\n`.erlang.cookie` in the [user's home directory](`m:init#home`) and then in\n[`filename:basedir(user_config, \"erlang\")`](`m:filename#user_config`). If none\nof the files exist, a `.erlang.cookie` file is created in the user's home\ndirectory. The UNIX permissions mode of the file is set to octal 400 (read-only\nby user) and its content is a random string. An atom `Cookie` is created from\nthe contents of the file and the cookie of the local node is set to this using\n`erlang:set_cookie(Cookie)`. This sets the default cookie that the local node\nwill use for all other nodes.\n\nThus, groups of users with identical cookie files get Erlang nodes that can\ncommunicate freely since they use the same magic cookie. Users who want to run\nnodes where the cookie files are on different file systems must make certain\nthat their cookie files are identical.\n\nFor a node `Node1` using magic cookie `Cookie` to be able to connect to, and to\naccept a connection from, another node `Node2` that uses a different cookie\n`DiffCookie`, the function `erlang:set_cookie(Node2, DiffCookie)` must first be\ncalled at `Node1`. Distributed systems with multiple home directories (differing\ncookie files) can be handled in this way.\n\n> #### Note {: .info }\n>\n> With this setup `Node1` and `Node2` agree on which cookie to use: `Node1` uses\n> its explicitly configured `DiffCookie` for `Node2`, and `Node2` uses its\n> default cookie `DiffCookie`.\n>\n> You can also use a `DiffCookie` that neither `Node1` nor `Node2` has as its\n> default cookie, if you also call `erlang:set_cookie(Node1, DiffCookie)` in\n> `Node2` before establishing connection\n>\n> Because node names are exchanged during connection setup before cookies are\n> selected, connection setup works regardless of which node that initiates it.\n>\n> Note that to configure `Node1` to use `Node2`'s default cookie when\n> communicating with `Node2`, _and vice versa_ results in a broken configuration\n> (if the cookies are different) because then both nodes use the other node's\n> (differing) cookie.\n\nThe default when a connection is established between two nodes, is to\nimmediately connect all other visible nodes as well. This way, there is always a\nfully connected network. If there are nodes with different cookies, this method\ncan be inappropriate (since it may not be feasible to configure different\ncookies for all possible nodes) and the command-line flag `-connect_all false`\nmust be set, see the [erl](`e:erts:erl_cmd.md`) executable in ERTS.\n\nThe magic cookie of the local node can be retrieved by calling\n`erlang:get_cookie()`.","title":"Security - Distributed Erlang","ref":"distributed.html#security"},{"type":"extras","doc":"Here are some BIFs that are useful for distributed programming:\n\n- [`disconnect_node(Node)`](`erlang:disconnect_node/1`) - Forces the\n disconnection of a node.\n\n- `erlang:get_cookie/0` - Returns the magic cookie of the current\n node.\n\n- [`erlang:get_cookie(Node)`](`erlang:get_cookie/1`) - Returns the\n magic cookie for node `Node`.\n\n- `is_alive/0` - Returns `true` if the runtime system is a node and\n can connect to other nodes, `false` otherwise.\n\n- [`monitor_node(Node, Bool)`](`erlang:monitor_node/2`) - Monitors the\n status of `Node`. A message`{nodedown, Node}` is received if the\n connection to it is lost.\n\n- `node/0` - Returns the name of the current node. Allowed in guards.\n\n- [`node(Arg)`](`node/1`) - Returns the node where `Arg`, a pid,\n reference, or port, is located.\n\n- `nodes/0` - Returns a list of all visible nodes this node is connected to.\n\n- [`nodes(Arg)`](`nodes/1`) - Depending on `Arg`, this function can\n return a list not only of visible nodes, but also hidden nodes and\n previously known nodes, and so on.\n\n- [`erlang:set_cookie(Cookie)`](`erlang:set_cookie/1`) - Sets the\n magic cookie, `Cookie` to use when connecting all nodes that have no\n explicit cookie set with `erlang:set_cookie/2`.\n\n- [`erlang:set_cookie(Node, Cookie)`](`erlang:set_cookie/2`) - Sets\n the magic cookie used when connecting `Node`. If `Node` is the\n current node, `Cookie` is used when connecting all nodes that have\n no explicit cookie set with this function.\n\n- [`spawn_link(Node, Fun)`](`spawn_link/2`) - Creates a process at a remote node.\n\n- [`spawn_opt(Node, Fun, Opts)`](`spawn_opt/3`) - Creates a process at\n a remote node.\n\n- [`spawn_link(Node, Module, Name, Args)`](`erlang:spawn_link/4`) -\n Creates a process at a remote node.\n\n- [`spawn_opt(Node, Module, Name, Args, Opts)`](`erlang:spawn_opt/5`) - Creates\n a process at a remote node.\n\n_Table: Distribution BIFs_","title":"Distribution BIFs - Distributed Erlang","ref":"distributed.html#distribution-bifs"},{"type":"extras","doc":"Examples of command-line flags used for distributed programming (for more\ninformation, see the [erl](`e:erts:erl_cmd.md`) executable in ERTS):\n\n| _Command-Line Flag_ | _Description_ |\n| ------------------------ | ----------------------------------------------------------- |\n| `-connect_all false` | Only explicit connection setups are used. |\n| `-hidden` | Makes a node into a hidden node. |\n| `-name Name` | Makes a runtime system into a node, using long node names. |\n| `-setcookie Cookie` | Same as calling `erlang:set_cookie(Cookie)`. |\n| `-setcookie Node Cookie` | Same as calling `erlang:set_cookie(Node, Cookie)`. |\n| `-sname Name` | Makes a runtime system into a node, using short node names. |\n\n_Table: Distribution Command-Line Flags_","title":"Distribution Command-Line Flags - Distributed Erlang","ref":"distributed.html#distribution-command-line-flags"},{"type":"extras","doc":"Examples of modules useful for distributed programming in the Kernel application:\n\n| _Module_ | _Description_ |\n| ---------------- | -------------------------------------------------- |\n| `m:global` | A global name registration facility. |\n| `m:global_group` | Grouping nodes to global name registration groups. |\n| `m:net_adm` | Various Erlang net administration routines. |\n| `m:net_kernel` | Erlang networking kernel. |\n\n_Table: Kernel Modules Useful For Distribution._\n\nIn the STDLIB application:\n\n| _Module_ | _Description_ |\n| -------- | --------------------------------- |\n| `m:peer` | Start and control of peer nodes. |\n\n_Table: STDLIB Modules Useful For Distribution._","title":"Distribution Modules - Distributed Erlang","ref":"distributed.html#distribution-modules"},{"type":"extras","doc":"\n# Compilation and Code Loading\n\nHow code is compiled and loaded is not a language issue, but is\nsystem-dependent. This section describes compilation and code loading in\nErlang/OTP with references to relevant parts of the documentation.","title":"Compilation and Code Loading","ref":"code_loading.html"},{"type":"extras","doc":"Erlang programs must be _compiled_ to object code. The compiler can generate a\nnew file that contains the object code. The current abstract machine, which runs\nthe object code, is called BEAM, therefore the object files get the suffix\n`.beam`. The compiler can also generate a binary which can be loaded directly.\n\nThe compiler is located in the module `m:compile` in Compiler.\n\n```erlang\ncompile:file(Module)\ncompile:file(Module, Options)\n```\n\nThe Erlang shell understands the command `c(Module)`, which both compiles and\nloads `Module`.\n\nThere is also a module `make`, which provides a set of functions similar to the\nUNIX type Make functions, see module `m:make` in Tools.\n\nThe compiler can also be accessed from the OS prompt using the\n[erl](`e:erts:erl_cmd.md`) executable in ERTS.\n\n```erlang\n% erl -compile Module1...ModuleN\n% erl -make\n```\n\nThe `erlc` program provides way to compile modules from the OS\nshell, see the [erlc](`e:erts:erlc_cmd.md`) executable in ERTS. It\nunderstands a number of flags that can be used to define macros, add search\npaths for include files, and more.\n\n```text\n% erlc File1.erl...FileN.erl\n```\n\n[](){: #loading }","title":"Compilation - Compilation and Code Loading","ref":"code_loading.html#compilation"},{"type":"extras","doc":"The object code must be _loaded_ into the Erlang runtime system. This is handled\nby the _code server_, see module `m:code` in Kernel.\n\nThe code server loads code according to a code loading strategy, which is either\n_interactive_ (default) or _embedded_. In interactive mode, code is searched for\nin a _code path_ and loaded when first referenced. In embedded mode, code is\nloaded at start-up according to a _boot script_. This is described in\n[System Principles ](`e:system:system_principles.md#code_loading`).","title":"Code Loading - Compilation and Code Loading","ref":"code_loading.html#code-loading"},{"type":"extras","doc":"Erlang supports change of code in a running system. Code replacement is done on\nthe module level.\n\nThe code of a module can exist in two variants in a system: _current_ and _old_.\nWhen a module is loaded into the system for the first time, the code becomes\n'current'. If then a new instance of the module is loaded, the code of the\nprevious instance becomes 'old' and the new instance becomes 'current'.\n\nBoth old and current code is valid, and can be evaluated concurrently. Fully\nqualified function calls always refer to current code. Old code can still be\nevaluated because of processes lingering in the old code.\n\nIf a third instance of the module is loaded, the code server removes (purges)\nthe old code and any processes lingering in it is terminated. Then the third\ninstance becomes 'current' and the previously current code becomes 'old'.\n\nTo change from old code to current code, a process must make a fully qualified\nfunction call.\n\n_Example:_\n\n```erlang\n-module(m).\n-export([loop/0]).\n\nloop() ->\n receive\n code_switch ->\n m:loop();\n Msg ->\n ...\n loop()\n end.\n```\n\nTo make the process change code, send the message `code_switch` to it. The\nprocess then makes a fully qualified call to `m:loop()` and changes to current\ncode. Notice that `m:loop/0` must be exported.\n\nFor code replacement of funs to work, use the syntax\n`fun Module:FunctionName/Arity`.\n\n[](){: #on_load }","title":"Code Replacement - Compilation and Code Loading","ref":"code_loading.html#code-replacement"},{"type":"extras","doc":"The `-on_load()` directive names a function that is to be run automatically when\na module is loaded.\n\nIts syntax is as follows:\n\n```erlang\n-on_load(Name/0).\n```\n\nIt is not necessary to export the function. It is called in a freshly spawned\nprocess (which terminates as soon as the function returns).\n\nThe function must return `ok` if the module is to become the new current code\nfor the module and become callable.\n\nReturning any other value or generating an exception causes the new code to be\nunloaded. If the return value is not an atom, a warning error report is sent to\nthe error logger.\n\nIf there already is current code for the module, that code will remain current\nand can be called until the `on_load` function has returned. If the `on_load`\nfunction fails, the current code (if any) will remain current. If there is no\ncurrent code for a module, any process that makes an external call to the module\nbefore the `on_load` function has finished will be suspended until the `on_load`\nfunction have finished.\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP 19, if the `on_load` function failed, any previously current\n> code would become old, essentially leaving the system without any working and\n> reachable instance of the module.\n\nIn embedded mode, first all modules are loaded. Then all `on_load` functions are\ncalled. The system is terminated unless all of the `on_load` functions return\n`ok`.\n\n_Example:_\n\n```erlang\n-module(m).\n-on_load(load_my_nifs/0).\n\nload_my_nifs() ->\n NifPath = ..., %Set up the path to the NIF library.\n Info = ..., %Initialize the Info term\n erlang:load_nif(NifPath, Info).\n```\n\nIf the call to `erlang:load_nif/2` fails, the module is unloaded and a warning\nreport is sent to the error loader.","title":"Running a Function When a Module is Loaded - Compilation and Code Loading","ref":"code_loading.html#running-a-function-when-a-module-is-loaded"},{"type":"extras","doc":"\n# Ports and Port Drivers\n\nExamples of how to use ports and port drivers are provided in\n[Interoperability Tutorial](`e:system:tutorial.md`).\nFor information about the BIFs mentioned, see module `m:erlang` in\nERTS.","title":"Ports and Port Drivers","ref":"ports.html"},{"type":"extras","doc":"_Ports_ provide the basic mechanism for communication with the external world,\nfrom Erlang's point of view. They provide a byte-oriented interface to an\nexternal program. When a port has been created, Erlang can communicate with it\nby sending and receiving lists of bytes, including binaries.\n\nThe Erlang process creating a port is said to be the _port owner_, or the\n_connected process_ of the port. All communication to and from the port must go\nthrough the port owner. If the port owner terminates, so does the port (and the\nexternal program, if it is written correctly).\n\nThe external program resides in another OS process. By default, it reads from\nstandard input (file descriptor 0) and writes to standard output (file\ndescriptor 1). The external program is to terminate when the port is closed.","title":"Ports - Ports and Port Drivers","ref":"ports.html#ports"},{"type":"extras","doc":"It is possible to write a driver in C according to certain principles and\ndynamically link it to the Erlang runtime system. The linked-in driver looks\nlike a port from the Erlang programmer's point of view and is called a _port\ndriver_.\n\n> #### Warning {: .warning }\n>\n> An erroneous port driver causes the entire Erlang runtime system to leak\n> memory, hang or crash.\n\nFor information about port drivers, see:\n\n- [erl_driver](`e:erts:erl_driver.md`) in ERTS\n- [driver_entry](`e:erts:driver_entry.md`) in ERTS\n- [`erl_ddll`](`m:erl_ddll`) in Kernel","title":"Port Drivers - Ports and Port Drivers","ref":"ports.html#port-drivers"},{"type":"extras","doc":"To create a port, call [`open_port(PortName,\nPortSettings)`](`erlang:open_port/2`). It returns a port identifier `Port`\nas the result of opening the new port. Messages can be sent to\nand received from a port identifier, just like a PID. Port\nidentifiers can also be linked to using [`link/1`](`link/1`), or\nregistered under a name using [`register/2`](`register/2`).\n\n`PortName` is usually a tuple `{spawn,Command}`, where the string `Command` is\nthe name of the external program. The external program runs outside the Erlang\nworkspace, unless a port driver with the name `Command` is found. If `Command`\nis found, that driver is started.\n\n`PortSettings` is a list of settings (options) for the port. The list typically\ncontains at least a tuple `{packet,N}`, which specifies that data sent between\nthe port and the external program are preceded by an N-byte length indicator.\nValid values for N are 1, 2, or 4. If binaries are to be used instead of lists\nof bytes, the option `binary` must be included.\n\nThe port owner `Pid` can communicate with the port `Port` by sending and\nreceiving messages. (In fact, any process can send the messages to the port, but\nthe port owner must be identified in the message).\n\nMessages sent to ports are delivered asynchronously.\n\n> #### Change {: .info }\n>\n> Before Erlang/OTP 16, messages to ports were delivered synchronously.\n\nIn the following examples, `Data` must be an I/O list. An I/O list is\na binary or a (possibly deep) list of binaries or integers in the\nrange 0 through 255.\n\nThe following messages can be sent to a port:\n\n- **`{Pid,{command,Data}}`** - Sends `Data` to the port.\n\n- **`{Pid,close}`** - Closes the port. Unless the port is already\n closed, the port replies with `{Port,closed}` when all buffers\n have been flushed and the port really closes.\n\n- **`{Pid,{connect,NewPid}}`** - Sets the port owner of `Port` to\n `NewPid`. Unless the port is already closed, the port replies\n with`{Port,connected}` to the old port owner. Note that the old\n port owner is still linked to the port, but the new port owner is\n not.\n\nHere follows the possible messages that can be received from a port. They\nare sent to the process that owns the port:\n\n- **`{Port,{data,Data}}`** - `Data` is received from the external program.\n\n- **`{Port,closed}`** - Reply to `Port ! {Pid,close}`.\n\n- **`{Port,connected}`** - Reply to `Port ! {Pid,{connect,NewPid}}`.\n\n- **`{'EXIT',Port,Reason}`** - If the port has terminated for some\n reason.\n\nInstead of sending and receiving messages, there are also a number of BIFs that\ncan be used:\n\n- [`port_command(Port, Data)`](`port_command/2`) - Sends `Data` to the\n port.\n\n- [`port_close(Port)`](`port_close/1`) - Closes the port.\n\n- [`port_connect(Port, NewPid)`](`port_connect/2`) - Sets the port\n owner of `Port`to `NewPid`. The old port owner `Pid` stays linked to\n the port and must call [`unlink(Port)`](`unlink/1`) if this is not\n desired.\n\n- [`erlang:port_info(Port, Item)`](`erlang:port_info/2`) - Returns\n information as specified by `Item`.\n\n- [`erlang:ports()`](`erlang:ports/0`) - Returns a list of all ports\n on the current node.\n\nThere also exist a few additional BIFs that apply to port drivers:\n\n- [`port_control/3`](`port_control/3`)\n- `erlang:port_call/3`.","title":"Port BIFs - Ports and Port Drivers","ref":"ports.html#port-bifs"},{"type":"extras","doc":"\n# Introduction","title":"Introduction","ref":"efficiency_guide.html"},{"type":"extras","doc":"> \"Premature optimization is the root of all evil\" (D.E. Knuth)\n\nEfficient code can be well-structured and clean, based on a sound\noverall architecture and sound algorithms. Efficient code can be\nhighly implementation-dependent code that bypasses documented\ninterfaces and takes advantage of obscure quirks.\n\nIdeally, your code only contains the first type of efficient code. If that turns\nout to be too slow, profile the application to find out where the performance\nbottlenecks are and optimize only the bottlenecks. Let other code stay as clean\nas possible.\n\nThis Efficiency Guide cannot really teach you how to write efficient code. It\ncan give you a few pointers about what to avoid and what to use, and some\nunderstanding of how certain language features are implemented. This guide does\nnot include general tips about optimization that works in any language, such as\nmoving common calculations out of loops.","title":"Purpose - Introduction","ref":"efficiency_guide.html#purpose"},{"type":"extras","doc":"It is assumed that you are familiar with the Erlang programming language and the\nOTP concepts.","title":"Prerequisites - Introduction","ref":"efficiency_guide.html#prerequisites"},{"type":"extras","doc":"\n# Common Caveats\n\nThis section lists a few constructs to watch out for.","title":"Common Caveats","ref":"commoncaveats.html"},{"type":"extras","doc":"The `++` operator copies its left-hand side operand. That is clearly\nseen if we do our own implementation in Erlang:\n\n```erlang\nmy_plus_plus([H|T], Tail) ->\n [H|my_plus_plus(T, Tail)];\nmy_plus_plus([], Tail) ->\n Tail.\n```\n\nWe must be careful how we use `++` in a loop. First is how not to use it:\n\n**DO NOT**\n\n```erlang\nnaive_reverse([H|T]) ->\n naive_reverse(T) ++ [H];\nnaive_reverse([]) ->\n [].\n```\n\nAs the `++` operator copies its left-hand side operand, the growing\nresult is copied repeatedly, leading to quadratic complexity.\n\nOn the other hand, using `++` in loop like this is perfectly fine:\n\n**OK**\n\n```erlang\nnaive_but_ok_reverse(List) ->\n naive_but_ok_reverse(List, []).\n\nnaive_but_ok_reverse([H|T], Acc) ->\n naive_but_ok_reverse(T, [H] ++ Acc);\nnaive_but_ok_reverse([], Acc) ->\n Acc.\n```\n\nEach list element is copied only once. The growing result `Acc` is the right-hand\nside operand, which it is _not_ copied.\n\nExperienced Erlang programmers would probably write as follows:\n\n**DO**\n\n```erlang\nvanilla_reverse([H|T], Acc) ->\n vanilla_reverse(T, [H|Acc]);\nvanilla_reverse([], Acc) ->\n Acc.\n```\n\nIn principle, this is slightly more efficient because the list element `[H]`\nis not built before being copied and discarded. In practice, the compiler\nrewrites `[H] ++ Acc` to `[H|Acc]`.","title":"Operator `++` - Common Caveats","ref":"commoncaveats.html#operator"},{"type":"extras","doc":"Creating timers using `erlang:send_after/3` and `erlang:start_timer/3`, is more\nefficient than using the timers provided by the `m:timer` module in STDLIB.\n\nThe `timer` module uses a separate process to manage the\ntimers. Before Erlang/OTP 25, this management overhead was substantial\nand increasing with the number of timers, especially when they were\nshort-lived, so the timer server process could easily become\noverloaded and unresponsive. In Erlang/OTP 25, the timer module was\nimproved by removing most of the management overhead and the resulting\nperformance penalty. Still, the timer server remains a single process,\nand it may at some point become a bottleneck of an application.\n\nThe functions in the `timer` module that do not manage timers (such as\n`timer:tc/3` or `timer:sleep/1`), do not call the timer-server process and are\ntherefore harmless.","title":"Timer Module - Common Caveats","ref":"commoncaveats.html#timer-module"},{"type":"extras","doc":"When spawning a new process using a fun, one can accidentally copy more data to\nthe process than intended. For example:\n\n**DO NOT**\n\n```erlang\naccidental1(State) ->\n spawn(fun() ->\n io:format(\"~p\\n\", [State#state.info])\n end).\n```\n\nThe code in the fun will extract one element from the record and print it. The\nrest of the `state` record is not used. However, when the [`spawn/1`](`spawn/1`)\nfunction is executed, the entire record is copied to the newly created process.\n\nThe same kind of problem can happen with a map:\n\n**DO NOT**\n\n```erlang\naccidental2(State) ->\n spawn(fun() ->\n io:format(\"~p\\n\", [map_get(info, State)])\n end).\n```\n\nIn the following example (part of a module implementing the `m:gen_server`\nbehavior) the created fun is sent to another process:\n\n**DO NOT**\n\n```erlang\nhandle_call(give_me_a_fun, _From, State) ->\n Fun = fun() -> State#state.size =:= 42 end,\n {reply, Fun, State}.\n```\n\nHow bad that unnecessary copy is depends on the contents of the record or the\nmap.\n\nFor example, if the `state` record is initialized like this:\n\n```erlang\ninit1() ->\n #state{data=lists:seq(1, 10000)}.\n```\n\na list with 10000 elements (or about 20000 heap words) will be copied to the\nnewly created process.\n\nAn unnecessary copy of 10000 element list can be bad enough, but it can get even\nworse if the `state` record contains _shared subterms_. Here is a simple example\nof a term with a shared subterm:\n\n```erlang\n{SubTerm, SubTerm}\n```\n\nWhen a term is copied to another process, sharing of subterms will be lost and\nthe copied term can be many times larger than the original term. For example:\n\n```erlang\ninit2() ->\n SharedSubTerms = lists:foldl(fun(_, A) -> [A|A] end, [0], lists:seq(1, 15)),\n #state{data=Shared}.\n```\n\nIn the process that calls `init2/0`, the size of the `data` field in the `state`\nrecord will be 32 heap words. When the record is copied to the newly created\nprocess, sharing will be lost and the size of the copied `data` field will be\n131070 heap words. More details about\n[loss off sharing](eff_guide_processes.md#loss-of-sharing) are found in a later\nsection.\n\nTo avoid the problem, outside of the fun extract only the fields of the record\nthat are actually used:\n\n**DO**\n\n```erlang\nfixed_accidental1(State) ->\n Info = State#state.info,\n spawn(fun() ->\n io:format(\"~p\\n\", [Info])\n end).\n```\n\nSimilarly, outside of the fun extract only the map elements that are actually\nused:\n\n**DO**\n\n```erlang\nfixed_accidental2(State) ->\n Info = map_get(info, State),\n spawn(fun() ->\n io:format(\"~p\\n\", [Info])\n end).\n```","title":"Accidental Copying and Loss of Sharing - Common Caveats","ref":"commoncaveats.html#accidental-copying-and-loss-of-sharing"},{"type":"extras","doc":"Atoms are not garbage-collected. Once an atom is created, it is never removed.\nThe emulator terminates if the limit for the number of atoms (1,048,576 by\ndefault) is reached.\n\nTherefore, converting arbitrary input strings to atoms can be dangerous in a\nsystem that runs continuously. If only certain well-defined atoms are allowed as\ninput, [`list_to_existing_atom/1`](`erlang:list_to_existing_atom/1`) or\n[`binary_to_existing_atom/1`](`erlang:binary_to_existing_atom/1`) can be used\nto guard against a denial-of-service attack. (All atoms that are allowed must\nhave been created earlier, for example, by using all of them in a module\nand loading that module.)\n\nUsing [`list_to_atom/1`](`list_to_atom/1`) to construct an atom that\nis passed to [`apply/3`](`apply/3`) is quite expensive.\n\n**DO NOT**\n\n```erlang\napply(list_to_atom(\"some_prefix\"++Var), foo, Args)\n```","title":"list_to_atom/1 - Common Caveats","ref":"commoncaveats.html#list_to_atom-1"},{"type":"extras","doc":"The time for calculating the length of a list is proportional to the length of\nthe list, as opposed to [`tuple_size/1`](`tuple_size/1`),\n[`byte_size/1`](`byte_size/1`), and [`bit_size/1`](`bit_size/1`), which all\nexecute in constant time.\n\nNormally, there is no need to worry about the speed of [`length/1`](`length/1`),\nbecause it is efficiently implemented in C. In time-critical code, you might\nwant to avoid it if the input list could potentially be very long.\n\nSome uses of [`length/1`](`length/1`) can be replaced by matching. For example,\nthe following code:\n\n```erlang\nfoo(L) when length(L) >= 3 ->\n ...\n```\n\ncan be rewritten to:\n\n```erlang\nfoo([_,_,_|_]=L) ->\n ...\n```\n\nOne slight difference is that [`length(L)`](`length/1`) fails if `L` is an\nimproper list, while the pattern in the second code fragment accepts an improper\nlist.","title":"length/1 - Common Caveats","ref":"commoncaveats.html#length-1"},{"type":"extras","doc":"[`setelement/3`](`erlang:setelement/3`) copies the tuple it modifies. Therefore,\nupdating a tuple in a loop using [`setelement/3`](`setelement/3`) creates a new\ncopy of the tuple every time.\n\nThere is one exception to the rule that the tuple is copied. If the compiler\nclearly can see that destructively updating the tuple would give the same result\nas if the tuple was copied, the call to [`setelement/3`](`setelement/3`) is\nreplaced with a special destructive `setelement` instruction. In the following\ncode sequence, the first [`setelement/3`](`setelement/3`) call copies the tuple\nand modifies the ninth element:\n\n```erlang\nmultiple_setelement(T0) when tuple_size(T0) =:= 9 ->\n T1 = setelement(9, T0, bar),\n T2 = setelement(7, T1, foobar),\n setelement(5, T2, new_value).\n```\n\nThe two following [`setelement/3`](`setelement/3`) calls modify the tuple in\nplace.\n\nFor the optimization to be applied, _all_ the following conditions must be true:\n\n- The tuple argument must be known to be a tuple of a known size.\n- The indices must be integer literals, not variables or expressions.\n- The indices must be given in descending order.\n- There must be no calls to another function in between the calls to\n [`setelement/3`](`setelement/3`).\n- The tuple returned from one [`setelement/3`](`setelement/3`) call must only be\n used in the subsequent call to [`setelement/3`](`setelement/3`).\n\nIf the code cannot be structured as in the `multiple_setelement/1` example, the\nbest way to modify multiple elements in a large tuple is to convert the tuple to\na list, modify the list, and convert it back to a tuple.","title":"setelement/3 - Common Caveats","ref":"commoncaveats.html#setelement-3"},{"type":"extras","doc":"[`size/1`](`size/1`) returns the size for both tuples and binaries.\n\nUsing the BIFs [`tuple_size/1`](`tuple_size/1`) and\n[`byte_size/1`](`byte_size/1`) gives the compiler and the runtime system more\nopportunities for optimization. Another advantage is that those BIFs give Dialyzer\nmore type information.","title":"size/1 - Common Caveats","ref":"commoncaveats.html#size-1"},{"type":"extras","doc":"Rewriting Erlang code to a NIF to make it faster should be seen as a last\nresort.\n\nDoing too much work in each NIF call will\n[degrade responsiveness of the VM](`e:erts:erl_nif.md#WARNING`). Doing too\nlittle work can mean that the gain of the faster processing in the NIF is eaten\nup by the overhead of calling the NIF and checking the arguments.\n\nBe sure to read about [Long-running NIFs](`e:erts:erl_nif.md#lengthy_work`)\nbefore writing a NIF.","title":"Using NIFs - Common Caveats","ref":"commoncaveats.html#using-nifs"},{"type":"extras","doc":"\n# Constructing and Matching Binaries\n\nThis section gives a few examples on how to handle binaries in an efficient way.\nThe sections that follow take an in-depth look at how binaries are implemented\nand how to best take advantages of the optimizations done by the compiler and\nruntime system.\n\nBinaries can be efficiently _built_ in the following way:\n\n**DO**\n\n```erlang\nmy_list_to_binary(List) ->\n my_list_to_binary(List, <<>>).\n\nmy_list_to_binary([H|T], Acc) ->\n my_list_to_binary(T, < >);\nmy_list_to_binary([], Acc) ->\n Acc.\n```\n\nAppending data to a binary as in the example is efficient because it is\nspecially optimized by the runtime system to avoid copying the `Acc` binary\nevery time.\n\nPrepending data to a binary in a loop is not efficient:\n\n**DO NOT**\n\n```erlang\nrev_list_to_binary(List) ->\n rev_list_to_binary(List, <<>>).\n\nrev_list_to_binary([H|T], Acc) ->\n rev_list_to_binary(T, < >);\nrev_list_to_binary([], Acc) ->\n Acc.\n```\n\nThis is not efficient for long lists because the `Acc` binary is copied every\ntime. One way to make the function more efficient is like this:\n\n**DO NOT**\n\n```erlang\nrev_list_to_binary(List) ->\n rev_list_to_binary(lists:reverse(List), <<>>).\n\nrev_list_to_binary([H|T], Acc) ->\n rev_list_to_binary(T, < >);\nrev_list_to_binary([], Acc) ->\n Acc.\n```\n\nAnother way to avoid copying the binary each time is like this:\n\n**DO**\n\n```erlang\nrev_list_to_binary([H|T]) ->\n RevTail = rev_list_to_binary(T),\n < >;\nrev_list_to_binary([]) ->\n <<>>.\n```\n\nNote that in each of the **DO** examples, the binary to be appended to is always\ngiven as the first segment.\n\nBinaries can be efficiently _matched_ in the following way:\n\n**DO**\n\n```erlang\nmy_binary_to_list(< >) ->\n [H|my_binary_to_list(T)];\nmy_binary_to_list(<<>>) -> [].\n```","title":"Constructing and Matching Binaries","ref":"binaryhandling.html"},{"type":"extras","doc":"Internally, binaries and bitstrings are implemented in the same way. In this\nsection, they are called _binaries_ because that is what they are called in the\nemulator source code.\n\nFour types of binary objects are available internally:\n\n- Two are containers for binary data and are called:\n\n - _Refc binaries_ (short for _reference-counted binaries_)\n - _Heap binaries_\n\n- Two are merely references to a part of a binary and are called:\n\n - _sub binaries_\n - _match contexts_\n\n> #### Change {: .info }\n>\n> In Erlang/OTP 27, the handling of binaries and bitstrings were\n> rewritten. To fully leverage those changes in the run-time system,\n> the compiler needs to be updated, which is planned for a future\n> release.\n>\n> Since, practically speaking, not much have changed from an efficiency\n> and optimization perspective, the following description has not yet\n> been updated to describe the implementation in Erlang/OTP 27.\n\n[](){: #refc_binary }","title":"How Binaries are Implemented - Constructing and Matching Binaries","ref":"binaryhandling.html#how-binaries-are-implemented"},{"type":"extras","doc":"Refc binaries consist of two parts:\n\n- An object stored on the process heap, called a _ProcBin_\n- The binary object itself, stored outside all process heaps\n\nThe binary object can be referenced by any number of ProcBins from any number of\nprocesses. The object contains a reference counter to keep track of the number\nof references, so that it can be removed when the last reference disappears.\n\nAll ProcBin objects in a process are part of a linked list, so that the garbage\ncollector can keep track of them and decrement the reference counters in the\nbinary when a ProcBin disappears.\n\n[](){: #heap_binary }","title":"Refc Binaries - Constructing and Matching Binaries","ref":"binaryhandling.html#refc-binaries"},{"type":"extras","doc":"Heap binaries are small binaries, up to 64 bytes, and are stored directly on the\nprocess heap. They are copied when the process is garbage-collected and when\nthey are sent as a message. They do not require any special handling by the\ngarbage collector.","title":"Heap Binaries - Constructing and Matching Binaries","ref":"binaryhandling.html#heap-binaries"},{"type":"extras","doc":"The reference objects _sub binaries_ and _match contexts_ can reference part of\na refc binary or heap binary.\n\n[](){: #sub_binary } A _sub binary_ is created by\n[`split_binary/2`](`split_binary/2`) and when a binary is matched out in a\nbinary pattern. A sub binary is a reference into a part of another binary (refc\nor heap binary, but never into another sub binary). Therefore, matching out a\nbinary is relatively cheap because the actual binary data is never copied.\n\n[](){: #match_context }","title":"Sub Binaries - Constructing and Matching Binaries","ref":"binaryhandling.html#sub-binaries"},{"type":"extras","doc":"A _match context_ is similar to a sub binary, but is optimized for binary\nmatching. For example, it contains a direct pointer to the binary data. For each\nfield that is matched out of a binary, the position in the match context is\nincremented.\n\nThe compiler tries to avoid generating code that creates a sub binary, only to\nshortly afterwards create a new match context and discard the sub binary.\nInstead of creating a sub binary, the match context is kept.\n\nThe compiler can only do this optimization if it knows that the match context\nwill not be shared. If it would be shared, the functional properties (also\ncalled referential transparency) of Erlang would break.","title":"Match Context - Constructing and Matching Binaries","ref":"binaryhandling.html#match-context"},{"type":"extras","doc":"Appending to a binary or bitstring in the following way is specially optimized\nto avoid copying the binary:\n\n```erlang\n< >\n%% - OR -\n< >\n```\n\nThis optimization is applied by the runtime system in a way that makes it\neffective in most circumstances (for exceptions, see\n[Circumstances That Force Copying](binaryhandling.md#forced_copying)). The\noptimization in its basic form does not need any help from the compiler.\nHowever, the compiler add hints to the runtime system when it is safe to apply\nthe optimization in a more efficient way.\n\n> #### Change {: .info }\n>\n> The compiler support for making the optimization more efficient was added in\n> Erlang/OTP 26.\n\nTo explain how the basic optimization works, let us examine the following code\nline by line:\n\n```erlang\nBin0 = <<0>>, %% 1\nBin1 = < >, %% 2\nBin2 = < >, %% 3\nBin3 = < >, %% 4\nBin4 = < >, %% 5 !!!\n{Bin4,Bin3} %% 6\n```\n\n- Line 1 (marked with the `%% 1` comment), assigns a\n [heap binary](binaryhandling.md#heap_binary) to the `Bin0` variable.\n- Line 2 is an append operation. As `Bin0` has not been involved in an append\n operation, a new [refc binary](binaryhandling.md#refc_binary) is created and\n the contents of `Bin0` is copied into it. The _ProcBin_ part of the refc\n binary has its size set to the size of the data stored in the binary, while\n the binary object has extra space allocated. The size of the binary object is\n either twice the size of `Bin1` or 256, whichever is larger. In this case it\n is 256.\n- Line 3 is more interesting. `Bin1` _has_ been used in an append operation, and\n it has 252 bytes of unused storage at the end, so the 3 new bytes are stored\n there.\n- Line 4. The same applies here. There are 249 bytes left, so there is no\n problem storing another 3 bytes.\n- Line 5. Here something _interesting_ happens. Notice that the result is not\n appended to the previous result in `Bin3`, but to `Bin1`. It is expected that\n `Bin4` will be assigned the value `<<0,1,2,3,17>>`. It is also expected that\n `Bin3` will retain its value (`<<0,1,2,3,4,5,6,7,8,9>>`). Clearly, the runtime\n system cannot write byte `17` into the binary, because that would change the\n value of `Bin3` to `<<0,1,2,3,4,17,6,7,8,9>>`.\n\n To ensure that the value of `Bin3` is retained, the runtime system _copies_\n the contents of `Bin1` to a new refc binary before storing the `17` byte.\n\n Here is not explained how the runtime system can know that it is not allowed\n to write into `Bin1`; it is left as an exercise to the curious reader to\n figure out how it is done by reading the emulator sources, primarily\n `erl_bits.c`.","title":"Constructing Binaries - Constructing and Matching Binaries","ref":"binaryhandling.html#constructing-binaries"},{"type":"extras","doc":"> #### Change {: .info }\n>\n> The compiler support for making the optimization more efficient was added in\n> Erlang/OTP 26.\n\nIn the example in the previous section, it was shown that the runtime system can\nhandle an append operation to a heap binary by copying it to a refc binary (line\n2), and also handle an append operation to a previous version of the binary by\ncopying it (line 5). The support for doing that does not come for free. For\nexample, to make it possible to know when it is necessary to copy the binary,\nfor every append operation, the runtime system must create a sub binary.\n\nWhen the compiler can determine that none of those situations need to be handled\nand that the append operation cannot possibly fail, the compiler generates code\nthat causes the runtime system to apply a more efficient variant of the\noptimization.\n\n**Example:**\n\n```erlang\n-module(repack).\n-export([repack/1]).\n\nrepack(Bin) when is_binary(Bin) ->\n repack(Bin, <<>>).\n\nrepack(< >, Result) ->\n repack(T, < >);\nrepack(<<>>, Result) ->\n Result.\n```\n\nThe `repack/2` function only keeps a single version of the binary, so there is\nnever any need to copy the binary. The compiler rewrites the creation of the\nempty binary in `repack/1` to instead create a refc binary with 256 bytes\nalready reserved; thus, the append operation in `repack/2` never needs to handle\na binary not prepared for appending.\n\n[](){: #forced_copying }","title":"Compiler Support For Constructing Binaries - Constructing and Matching Binaries","ref":"binaryhandling.html#compiler-support-for-constructing-binaries"},{"type":"extras","doc":"The optimization of the binary append operation requires that there is a\n_single_ ProcBin and a _single reference_ to the ProcBin for the binary. The\nreason is that the binary object can be moved (reallocated) during an append\noperation, and when that happens, the pointer in the ProcBin must be updated. If\nthere would be more than one ProcBin pointing to the binary object, it would not\nbe possible to find and update all of them.\n\nTherefore, certain operations on a binary mark it so that any future append\noperation will be forced to copy the binary. In most cases, the binary object\nwill be shrunk at the same time to reclaim the extra space allocated for\ngrowing.\n\nWhen appending to a binary as follows, only the binary returned from the latest\nappend operation will support further cheap append operations:\n\n```erlang\nBin = < >\n```\n\nIn the code fragment in the beginning of this section, appending to `Bin` will\nbe cheap, while appending to `Bin0` will force the creation of a new binary and\ncopying of the contents of `Bin0`.\n\nIf a binary is sent as a message to a process or port, the binary will be shrunk\nand any further append operation will copy the binary data into a new binary.\nFor example, in the following code fragment `Bin1` will be copied in the third\nline:\n\n```erlang\nBin1 = < >,\nPortOrPid ! Bin1,\nBin = < > %% Bin1 will be COPIED\n```\n\nThe same happens if you insert a binary into an Ets table, send it to a port\nusing `erlang:port_command/2`, or pass it to\n[enif_inspect_binary](`e:erts:erl_nif.md#enif_inspect_binary`) in a NIF.\n\nMatching a binary will also cause it to shrink and the next append operation\nwill copy the binary data:\n\n```erlang\nBin1 = < >,\n< > = Bin1,\nBin = < > %% Bin1 will be COPIED\n```\n\nThe reason is that a [match context](binaryhandling.md#match_context) contains a\ndirect pointer to the binary data.\n\nIf a process simply keeps binaries (either in \"loop data\" or in the process\ndictionary), the garbage collector can eventually shrink the binaries. If only\none such binary is kept, it will not be shrunk. If the process later appends to\na binary that has been shrunk, the binary object will be reallocated to make\nplace for the data to be appended.","title":"Circumstances That Force Copying - Constructing and Matching Binaries","ref":"binaryhandling.html#circumstances-that-force-copying"},{"type":"extras","doc":"Let us revisit the example in the beginning of the previous section:\n\n**DO**\n\n```erlang\nmy_binary_to_list(< >) ->\n [H|my_binary_to_list(T)];\nmy_binary_to_list(<<>>) -> [].\n```\n\nThe first time `my_binary_to_list/1` is called, a\n[match context](binaryhandling.md#match_context) is created. The match context\npoints to the first byte of the binary. 1 byte is matched out and the match\ncontext is updated to point to the second byte in the binary.\n\nAt this point it would make sense to create a\n[sub binary](binaryhandling.md#sub_binary), but in this particular example the\ncompiler sees that there will soon be a call to a function (in this case, to\n`my_binary_to_list/1` itself) that immediately will create a new match context\nand discard the sub binary.\n\nTherefore `my_binary_to_list/1` calls itself with the match context instead of\nwith a sub binary. The instruction that initializes the matching operation\nbasically does nothing when it sees that it was passed a match context instead\nof a binary.\n\nWhen the end of the binary is reached and the second clause matches, the match\ncontext will simply be discarded (removed in the next garbage collection, as\nthere is no longer any reference to it).\n\nTo summarize, `my_binary_to_list/1` only needs to create _one_ match context and\nno sub binaries.\n\nNotice that the match context in `my_binary_to_list/1` was discarded when the\nentire binary had been traversed. What happens if the iteration stops before it\nhas reached the end of the binary? Will the optimization still work?\n\n```erlang\nafter_zero(<<0,T/binary>>) ->\n T;\nafter_zero(<<_,T/binary>>) ->\n after_zero(T);\nafter_zero(<<>>) ->\n <<>>.\n```\n\nYes, it will. The compiler will remove the building of the sub binary in the\nsecond clause:\n\n```erlang\n...\nafter_zero(<<_,T/binary>>) ->\n after_zero(T);\n...\n```\n\nBut it will generate code that builds a sub binary in the first clause:\n\n```erlang\nafter_zero(<<0,T/binary>>) ->\n T;\n...\n```\n\nTherefore, `after_zero/1` builds one match context and one sub binary (assuming\nit is passed a binary that contains a zero byte).\n\nCode like the following will also be optimized:\n\n```erlang\nall_but_zeroes_to_list(Buffer, Acc, 0) ->\n {lists:reverse(Acc),Buffer};\nall_but_zeroes_to_list(<<0,T/binary>>, Acc, Remaining) ->\n all_but_zeroes_to_list(T, Acc, Remaining-1);\nall_but_zeroes_to_list(< >, Acc, Remaining) ->\n all_but_zeroes_to_list(T, [Byte|Acc], Remaining-1).\n```\n\nThe compiler removes building of sub binaries in the second and third clauses,\nand it adds an instruction to the first clause that converts `Buffer` from a\nmatch context to a sub binary (or do nothing if `Buffer` is a binary already).\n\nBut in more complicated code, how can one know whether the optimization is\napplied or not?\n\n[](){: #bin_opt_info }","title":"Matching Binaries - Constructing and Matching Binaries","ref":"binaryhandling.html#matching-binaries"},{"type":"extras","doc":"Use the `bin_opt_info` option to have the compiler print a lot of information\nabout binary optimizations. It can be given either to the compiler or `erlc`:\n\n```erlang\nerlc +bin_opt_info Mod.erl\n```\n\nor passed through an environment variable:\n\n```erlang\nexport ERL_COMPILER_OPTIONS=bin_opt_info\n```\n\nNotice that the `bin_opt_info` is not meant to be a permanent option added to\nyour `Makefile`s, because all messages that it generates cannot be eliminated.\nTherefore, passing the option through the environment is in most cases the most\npractical approach.\n\nThe warnings look as follows:\n\n```erlang\n./efficiency_guide.erl:60: Warning: NOT OPTIMIZED: binary is returned from the function\n./efficiency_guide.erl:62: Warning: OPTIMIZED: match context reused\n```\n\nTo make it clearer exactly what code the warnings refer to, the warnings in the\nfollowing examples are inserted as comments after the clause they refer to, for\nexample:\n\n```erlang\nafter_zero(<<0,T/binary>>) ->\n %% BINARY CREATED: binary is returned from the function\n T;\nafter_zero(<<_,T/binary>>) ->\n %% OPTIMIZED: match context reused\n after_zero(T);\nafter_zero(<<>>) ->\n <<>>.\n```\n\nThe warning for the first clause says that the creation of a sub binary cannot\nbe delayed, because it will be returned. The warning for the second clause says\nthat a sub binary will not be created (yet).","title":"Option bin_opt_info - Constructing and Matching Binaries","ref":"binaryhandling.html#option-bin_opt_info"},{"type":"extras","doc":"The compiler figures out if a variable is unused. The same code is generated for\neach of the following functions:\n\n```erlang\ncount1(<<_,T/binary>>, Count) -> count1(T, Count+1);\ncount1(<<>>, Count) -> Count.\n\ncount2(< >, Count) -> count2(T, Count+1);\ncount2(<<>>, Count) -> Count.\n\ncount3(<<_H,T/binary>>, Count) -> count3(T, Count+1);\ncount3(<<>>, Count) -> Count.\n```\n\nIn each iteration, the first 8 bits in the binary will be skipped, not matched\nout.","title":"Unused Variables - Constructing and Matching Binaries","ref":"binaryhandling.html#unused-variables"},{"type":"extras","doc":"\n# Maps\n\nThis guide to using maps efficiently starts with a brief section on the choice\nbetween records or maps, followed by three sections giving concrete (but brief)\nadvice on using maps as an alternative to records, as dictionaries, and as sets.\nThe remaining sections dig deeper, looking at how maps are implemented, the map\nsyntax, and finally the functions in the `m:maps` module.\n\n[](){: #terminology }\n\nTerminology used in this chapter:\n\n- A map with at most 32 elements will informally be called a _small map_.\n- A map with more than 32 elements will informally be called a _large map_.","title":"Maps","ref":"maps.html"},{"type":"extras","doc":"If the advice in this chapter is followed, the performance of records compared\nto using small maps instead of records is expected to be similar. Therefore, the\nchoice between records and maps should be based on the desired properties of the\ndata structure and not performance.\n\nThe advantages of records compared to maps are:\n\n- If the name of a record field is misspelled, there will be a compilation\n error. If a map key is misspelled, the compiler will give no warning and\n program will fail in some way when it is run.\n- Records will use slightly less memory than maps, and performance is expected\n to be _slightly_ better than maps in most circumstances.\n\nThe disadvantage of records compared to maps is that if a new field is added to\na record, all code that uses that record must be recompiled. Because of that, it\nis recommended to only use records within a unit of code that can easily be\nrecompiled all at once, for example within a single application or single\nmodule.","title":"Maps or Records? - Maps","ref":"maps.html#maps-or-records"},{"type":"extras","doc":"- Use the map syntax instead of the functions in the `m:maps` module.\n- Avoid having more than 32 elements in the map. As soon as there are more than\n 32 elements in the map, it will require more memory and keys can no longer be\n shared with other instances of the map.\n- When creating a new map, always create it with all keys that will ever be\n used. To maximize sharing of keys (thus minimizing memory use), create a\n single function that constructs the map using the map syntax and always use\n it.\n- Always update the map using the `:=` operator (that is, requiring that an\n element with that key already exists). The `:=` operator is slightly more\n efficient, and it helps catching mispellings of keys.\n- Whenever possible, match multiple map elements at once.\n- Whenever possible, update multiple map elements at once.\n- Avoid default values and the `maps:get/3` function. If there are default\n values, sharing of keys between different instances of the map will be less\n effective, and it is not possible to match multiple elements having default\n values in one go.\n- To avoid having to deal with a map that may lack some keys, `maps:merge/2` can\n efficiently add multiple default values. For example:\n\n ```erlang\n DefaultMap = #{shoe_size => 42, editor => emacs},\n MapWithDefaultsApplied = maps:merge(DefaultMap, OtherMap)\n ```","title":"Using Maps as an Alternative to Records - Maps","ref":"maps.html#using-maps-as-an-alternative-to-records"},{"type":"extras","doc":"Using a map as a dictionary implies the following usage pattern:\n\n- Keys are usually variables not known at compile-time.\n- There can be any number of elements in the map.\n- Usually, no more than one element is looked up or updated at once.\n\nGiven that usage pattern, the difference in performance between using the map\nsyntax and the maps module is usually small. Therefore, which one to use is\nmostly a matter of taste.\n\nMaps are usually the most efficient dictionary data structure, with a few\nexceptions:\n\n- If it is necessary to frequently convert a dictionary to a sorted list, or\n from a sorted list to a dictionary, using `m:gb_trees` can be a better choice.\n- If all keys are non-negative integers, the `m:array` module can be a better\n choice.","title":"Using Maps as Dictionaries - Maps","ref":"maps.html#using-maps-as-dictionaries"},{"type":"extras","doc":"Starting in OTP 24, the `m:sets` module has an option to represent sets as maps.\nExamples:\n\n```erlang\n1> sets:new([{version,2}]).\n#{}\n2> sets:from_list([x,y,z], [{version,2}]).\n#{x => [],y => [],z => []}\n```\n\n`sets` backed by maps is generally the most efficient set representation, with a\nfew possible exceptions:\n\n- `ordsets:intersection/2` can be more efficient than `sets:intersection/2`. If\n the intersection operation is frequently used and operations that operate on a\n single element in a set (such as `is_element/2`) are avoided, `m:ordsets` can\n be a better choice than `m:sets`.\n- If the intersection operation is frequently used and operations that operate\n on a single element in a set (such as `is_element/2`) must also be efficient,\n `m:gb_sets` can potentially be a better choice than `m:sets`.\n- If the elements of the set are integers in a fairly compact range, the set can\n be represented as an integer where each bit represents an element in the set.\n The union operation is performed by `bor` and the intersection operation by\n `band`.","title":"Using Maps as Sets - Maps","ref":"maps.html#using-maps-as-sets"},{"type":"extras","doc":"Internally, maps have two distinct representations depending on the number of\nelements in the map. The representation changes when a map grows beyond 32\nelements, or when it shrinks to 32 elements or less.\n\n- A map with at most 32 elements has a compact representation, making it\n suitable as an alternative to records.\n- A map with more than 32 elements is represented as a tree that can be\n efficiently searched and updated regardless of how many elements there are.","title":"How Maps are Implemented - Maps","ref":"maps.html#how-maps-are-implemented"},{"type":"extras","doc":"A small map looks like this inside the runtime system:\n\n| 0 | 1 | 2 | 3 | | N |\n| :---------: | --- | :----: | :------: | :-----: | :------: |\n| **FLATMAP** | _N_ | _Keys_ | _Value1_ | _..._ | _ValueN_ |\n\n_Table: The representation of a small map_\n\n- **`FLATMAP`** - The tag for a small map (called _flat map_ in the source code\n for the runtime system).\n\n- **N** - The number of elements in the map.\n\n- **Keys** - A tuple with keys of the map: `{Key1,...,KeyN}`. The keys are\n sorted.\n\n- **Value1** - The value corresponding to the first key in the key tuple.\n\n- **ValueN** - The value corresponding to the last key in the key tuple.\n\nAs an example, let us look at how the map `#{a => foo, z => bar}` is\nrepresented:\n\n| 0 | 1 | 2 | 3 | 4 |\n| :---------: | --- | :-------: | :---: | ----- |\n| **FLATMAP** | _2_ | `{a,z}` | `foo` | `bar` |\n\n_Table: \\#\\{a => foo, z => bar\\}_\n\nLet us update the map: `M#{q => baz}`. The map now looks like this:\n\n| 0 | 1 | 2 | 3 | 4 | 5 |\n| :---------: | --- | :---------: | :---: | :---: | :---: |\n| **FLATMAP** | _3_ | `{a,q,z}` | `foo` | `baz` | `bar` |\n\n_Table: \\#\\{a => foo, q => baz, z => bar\\}_\n\nFinally, change the value of one element: `M#{z := bird}`. The map now looks\nlike this:\n\n| 0 | 1 | 2 | 3 | 4 | 5 |\n| :---------: | --- | :---------: | :---: | :---: | :----: |\n| **FLATMAP** | _3_ | `{a,q,z}` | `foo` | `baz` | `bird` |\n\n_Table: \\#\\{a => foo, q => baz, z => bird\\}_\n\nWhen the value for an existing key is updated, the key tuple is not updated,\nallowing the key tuple to be shared with other instances of the map that have\nthe same keys. In fact, the key tuple can be shared between all maps with the\nsame keys with some care. To arrange that, define a function that returns a map.\nFor example:\n\n```erlang\nnew() ->\n #{a => default, b => default, c => default}.\n```\n\nDefined like this, the key tuple `{a,b,c}` will be a global literal. To ensure\nthat the key tuple is shared when creating an instance of the map, always call\n`new()` and modify the returned map:\n\n```erlang\n (SOME_MODULE:new())#{a := 42}.\n```\n\nUsing the map syntax with small maps is particularly efficient. As long as the\nkeys are known at compile-time, the map is updated in one go, making the time to\nupdate a map essentially constant regardless of the number of keys updated. The\nsame goes for matching. (When the keys are variables, one or more of the keys\ncould be identical, so the operations need to be performed sequentially from\nleft to right.)\n\nThe memory size for a small map is the size of all keys and values plus 5 words.\nSee [Memory](memory.md) for more information about memory sizes.","title":"How Small Maps are Implemented - Maps","ref":"maps.html#how-small-maps-are-implemented"},{"type":"extras","doc":"A map with more than 32 elements is implemented as a\n[Hash array mapped trie (HAMT)](https://en.wikipedia.org/wiki/Hash_array_mapped_trie).\nA large map can be efficiently searched and updated regardless of the number of\nelements in the map.\n\nThere is less performance to be gained by matching or updating multiple elements\nusing the map syntax on a large map compared to a small map. The execution time\nis roughly proportional to the number of elements matched or updated.\n\nThe storage overhead for a large map is higher than for a small map. For a large\nmap, the extra number of words besides the keys and values is roughly\nproportional to the number of elements. For a map with 33 elements the overhead\nis at least 53 heap words according to the formula in\n[Memory](memory.md) (compared to 5 extra words for a small map\nregardless of the number of elements).\n\nWhen a large map is updated, the updated map and the original map will share\ncommon parts of the HAMT, but sharing will never be as effective as the best\npossible sharing of the key tuple for small maps.\n\nTherefore, if maps are used instead of records and it is expected that many\ninstances of the map will be created, it is more efficient from a memory\nstandpoint to avoid using large maps (for example, by grouping related map\nelements into sub maps to reduce the number of elements).","title":"How Large Maps are Implemented - Maps","ref":"maps.html#how-large-maps-are-implemented"},{"type":"extras","doc":"Using the map syntax is usually slightly more efficient than using the\ncorresponding function in the `m:maps` module.\n\nThe gain in efficiency for the map syntax is more noticeable for the following\noperations that can only be achieved using the map syntax:\n\n- Matching multiple literal keys\n- Updating multiple literal keys\n- Adding multiple literal keys to a map\n\nFor example:\n\n**DO**\n\n```erlang\nMap = Map1#{x := X, y := Y, z := Z}\n```\n\n**DO NOT**\n\n```erlang\nMap2 = maps:update(x, X, Map1),\nMap3 = maps:update(y, Y, Map2),\nMap = maps:update(z, Z, Map3)\n```\n\nIf the map is a small map, the first example runs roughly three times as fast.\n\nNote that for variable keys, the elements are updated sequentially from left to\nright. For example, given the following update with variable keys:\n\n```erlang\nMap = Map1#{Key1 := X, Key2 := Y, Key3 := Z}\n```\n\nthe compiler rewrites it like this to ensure that the updates are applied from\nleft to right:\n\n```erlang\nMap2 = Map1#{Key1 := X},\nMap3 = Map2#{Key2 := Y},\nMap = Map3#{Key3 := Z}\n```\n\nIf a key is known to exist in a map, using the `:=` operator is slightly more\nefficient than using the `=>` operator for a small map.","title":"Using the Map Syntax - Maps","ref":"maps.html#using-the-map-syntax"},{"type":"extras","doc":"Here follows some notes about most of the functions in the `maps` module. For\neach function, the implementation language (C or Erlang) is stated. The reason\nwe mention the language is that it gives an hint about how efficient the\nfunction is:\n\n- If a function is implemented in C, it is pretty much impossible to implement\n the same functionality more efficiently in Erlang.\n- However, it might be possible to beat the `maps` modules functions implemented\n in Erlang, because they are generally implemented in a way that attempts to\n make the performance reasonable for all possible inputs.\n\n For example, `maps:map/2` iterates over all elements of the map, calling the\n mapping fun, collects the updated map elements in a list, and finally converts\n the list back to a map using `maps:from_list/1`. If it is known that at most\n one percent of the values in the map will change, it can be more efficient to\n update only the changed values.\n\n> #### Note {: .info }\n>\n> The implementation details given in this section can change in the future.","title":"Using the Functions in the maps Module - Maps","ref":"maps.html#using-the-functions-in-the-maps-module"},{"type":"extras","doc":"`maps:filter/2` is implemented in Erlang. It creates a new map using\n`maps:from_list/1`. If it is known that only a minority of the values will be\nremoved, it can be more efficient to avoid `maps:filter/2` and write a function\nthat will use [maps:remove/3](`maps:remove/2`) to remove the unwanted values.","title":"maps:filter/2 - Maps","ref":"maps.html#maps-filter-2"},{"type":"extras","doc":"`maps:filtermap/2` is implemented in Erlang. It creates a new map using\n`maps:from_list/1`. See the notes for `maps:map/2` and `maps:filter/2` for hints\non how to implement a more efficient version.","title":"maps:filtermap/2 - Maps","ref":"maps.html#maps-filtermap-2"},{"type":"extras","doc":"`maps:find/2` is implemented in C.\n\nUsing the map matching syntax instead of `maps:find/2` will be slightly more\nefficient since building an `{ok,Value}` tuple will be avoided.","title":"maps:find/2 - Maps","ref":"maps.html#maps-find-2"},{"type":"extras","doc":"As an optimization, the compiler will rewrite a call to `maps:get/2` to a call\nto the guard BIF [map_get/2](`erlang:map_get/2`). A call to a guard BIF is more\nefficient than calls to other BIFs, making the performance similar to using the\nmap matching syntax.\n\nIf the map is small and the keys are constants known at compile-time, using the\nmap matching syntax will be more efficient than multiple calls to `maps:get/2`.\n\n[](){: #maps_get_3 }","title":"maps:get/2 - Maps","ref":"maps.html#maps-get-2"},{"type":"extras","doc":"As an optimization, the compiler will rewrite a call to `maps:get/3` to Erlang\ncode similar to the following:\n\n```erlang\nResult = case Map of\n #{Key := Value} -> Value;\n #{} -> Default\n end\n```\n\nThis is reasonably efficient, but if a small map is used as an alternative to\nusing a record it is often better not to rely on default values as it prevents\nsharing of keys, which may in the end use more memory than what you save from\nnot storing default values in the map.\n\nIf default values are nevertheless required, instead of calling `maps:get/3`\nmultiple times, consider putting the default values in a map and merging that\nmap with the other map:\n\n```erlang\nDefaultMap = #{Key1 => Value2, Key2 => Value2, ..., KeyN => ValueN},\nMapWithDefaultsApplied = maps:merge(DefaultMap, OtherMap)\n```\n\nThis helps share keys between the default map and the one you applied defaults\nto, as long as the default map contains _all_ the keys that will ever be used\nand not just the ones with default values. Whether this is faster than calling\n`maps:get/3` multiple times depends on the size of the map and the number of\ndefault values.\n\n> #### Change {: .info }\n>\n> Before OTP 26.0 `maps:get/3` was implemented by calling the function instead\n> of rewriting it as an Erlang expression. It is now slightly faster but can no\n> longer be traced.","title":"maps:get/3 - Maps","ref":"maps.html#maps-get-3"},{"type":"extras","doc":"`maps:intersect/2` and `maps:intersect_with/3` are implemented in Erlang. They\nboth create new maps using `maps:from_list/1`.\n\n> #### Note {: .info }\n>\n> A map is usually the most efficient way to implement a set, but an exception\n> is the intersection operation, where `ordsets:intersection/2` used on\n> `m:ordsets` can be more efficient than `maps:intersect/2` on sets implemented\n> as maps.","title":"maps:intersect/2, maps:intersect_with/3 - Maps","ref":"maps.html#maps-intersect-2-maps-intersect_with-3"},{"type":"extras","doc":"`maps:from_list/1` is implemented in C.","title":"maps:from_list/1 - Maps","ref":"maps.html#maps-from_list-1"},{"type":"extras","doc":"`maps:from_keys/2` is implemented in C.","title":"maps:from_keys/2 - Maps","ref":"maps.html#maps-from_keys-2"},{"type":"extras","doc":"As an optimization, the compiler rewrites calls to `maps:is_key/2` to calls to\nthe guard BIF [is_map_key/2](`erlang:is_map_key/2`). A call to a guard BIF is\nmore efficient than calls to other BIFs, making the performance similar to using\nthe map matching syntax.","title":"maps:is_key/2 - Maps","ref":"maps.html#maps-is_key-2"},{"type":"extras","doc":"`maps:iterator/1` is efficiently implemented in C and Erlang.","title":"maps:iterator/1 - Maps","ref":"maps.html#maps-iterator-1"},{"type":"extras","doc":"`maps:keys/1` is implemented in C. If the resulting list needs to be ordered,\nuse `lists:sort/1` to sort the result.","title":"maps:keys/1 - Maps","ref":"maps.html#maps-keys-1"},{"type":"extras","doc":"`maps:map/2` is implemented in Erlang. It creates a new map using\n`maps:from_list/1`. If it is known that only a minority of the values will be\nupdated, it can be more efficient to avoid `maps:map/2` and write a function\nthat will call `maps:update/3` to update only the values that have changed.","title":"maps:map/2 - Maps","ref":"maps.html#maps-map-2"},{"type":"extras","doc":"`maps:merge/2` is implemented in C. For [small maps](maps.md#terminology), the\nkey tuple may be shared with any of the argument maps if that argument map\ncontains all the keys. Literal key tuples are prefered if possible.\n\n> #### Change {: .info }\n>\n> The sharing of key tuples by `maps:merge/2` was introduced in OTP 26.0. Older\n> versions always contructed a new key tuple on the callers heap.","title":"maps:merge/2 - Maps","ref":"maps.html#maps-merge-2"},{"type":"extras","doc":"`maps:merge_with/3` is implemented in Erlang. It updates and returns the larger\nof the two maps.","title":"maps:merge_with/3 - Maps","ref":"maps.html#maps-merge_with-3"},{"type":"extras","doc":"The compiler rewrites a call to `maps:new/0` to using the syntax `#{}` for\nconstructing an empty map.","title":"maps:new/0 - Maps","ref":"maps.html#maps-new-0"},{"type":"extras","doc":"`maps:next/1` is efficiently implemented in C and Erlang.","title":"maps:next/1 - Maps","ref":"maps.html#maps-next-1"},{"type":"extras","doc":"`maps:put/3` is implemented in C.\n\nIf the key is known to already exist in the map, `maps:update/3` is slightly\nmore efficient than `maps:put/3`.\n\nIf the compiler can determine that the third argument is always a map, it\nwill rewrite the call to `maps:put/3` to use the map syntax for updating the map.\n\nFor example, consider the following function:\n\n```erlang\nadd_to_known_map(Map0, A, B, C) when is_map(Map0) ->\n Map1 = maps:put(a, A, Map0),\n Map2 = maps:put(b, B, Map1),\n maps:put(c, C, Map2).\n```\n\nThe compiler first rewrites each call to `maps:put/3` to use the map\nsyntax, and subsequently combines the three update operations to a\nsingle update operation:\n\n```erlang\nadd_to_known_map(Map0, A, B, C) when is_map(Map0) ->\n Map0#{a => A, b => B, c => C}.\n```\n\nIf the compiler cannot determine that the third argument is always a\nmap, it retains the `maps:put/3` call. For example, given this\nfunction:\n\n```erlang\nadd_to_map(Map0, A, B, C) ->\n Map1 = maps:put(a, A, Map0),\n Map2 = maps:put(b, B, Map1),\n maps:put(c, C, Map2).\n```\n\nthe compiler keeps the first call to `maps:put/3`, but rewrites\nand combines the other two calls:\n\n```erlang\nadd_to_map(Map0, A, B, C) ->\n Map1 = maps:put(a, A, Map0),\n Map1#{b => B, c => C}.\n```\n\n> #### Change {: .info }\n>\n> The rewriting of `maps:put/3` to the map syntax was introduced in\n> Erlang/OTP 28.","title":"maps:put/3 - Maps","ref":"maps.html#maps-put-3"},{"type":"extras","doc":"`maps:remove/2` is implemented in C.","title":"maps:remove/2 - Maps","ref":"maps.html#maps-remove-2"},{"type":"extras","doc":"As an optimization, the compiler rewrites calls to `maps:size/1` to calls to the\nguard BIF [map_size/1](`erlang:map_size/1`). Calls to guard BIFs are more\nefficient than calls to other BIFs.","title":"maps:size/1 - Maps","ref":"maps.html#maps-size-1"},{"type":"extras","doc":"`maps:take/2` is implemented in C.","title":"maps:take/2 - Maps","ref":"maps.html#maps-take-2"},{"type":"extras","doc":"`maps:to_list/1` is efficiently implemented in C and Erlang. If the resulting\nlist needs to be ordered, use `lists:sort/1` to sort the result.\n\n> #### Note {: .info }\n>\n> Maps are usually more performant than `m:gb_trees`, but if it is necessary to\n> frequently convert to and from sorted lists, `gb_trees` can be a better\n> choice.","title":"maps:to_list/1 - Maps","ref":"maps.html#maps-to_list-1"},{"type":"extras","doc":"`maps:update/3` is implemented in C.\n\nIf the keys are constants known at compile-time, using the map update syntax\nwith the `:=` operator is more efficient than multiple calls to `maps:update/3`,\nespecially for [small maps](maps.md#terminology).","title":"maps:update/3 - Maps","ref":"maps.html#maps-update-3"},{"type":"extras","doc":"`maps:values/1` is implemented in C.","title":"maps:values/1 - Maps","ref":"maps.html#maps-values-1"},{"type":"extras","doc":"`maps:with/2` is implemented in Erlang. It creates a new map using\n`maps:from_list/1`.","title":"maps:with/2 - Maps","ref":"maps.html#maps-with-2"},{"type":"extras","doc":"`maps:without/2` is implemented in Erlang. It returns a modified copy of the\ninput map.","title":"maps:without/2 - Maps","ref":"maps.html#maps-without-2"},{"type":"extras","doc":"\n# List Handling","title":"List Handling","ref":"listhandling.html"},{"type":"extras","doc":"Lists can only be built starting from the end and attaching list elements at the\nbeginning. If you use the `++` operator as follows, a new list is created that\nis a copy of the elements in `List1`, followed by `List2`:\n\n```erlang\nList1 ++ List2\n```\n\nLooking at how `lists:append/2` or `++` would be implemented in plain Erlang,\nclearly the first list is copied:\n\n```erlang\nappend([H|T], Tail) ->\n [H|append(T, Tail)];\nappend([], Tail) ->\n Tail.\n```\n\nWhen recursing and building a list, it is important to ensure that you attach\nthe new elements to the beginning of the list. In this way, you will build _one_\nlist, not hundreds or thousands of copies of the growing result list.\n\nLet us first see how it is not to be done:\n\n**DO NOT**\n\n```erlang\nbad_fib(N) ->\n bad_fib(N, 0, 1, []).\n\nbad_fib(0, _Current, _Next, Fibs) ->\n Fibs;\nbad_fib(N, Current, Next, Fibs) ->\n bad_fib(N - 1, Next, Current + Next, Fibs ++ [Current]).\n```\n\nHere more than one list is built. In each iteration step a new list is created\nthat is one element longer than the new previous list.\n\nTo avoid copying the result in each iteration, build the list in reverse order\nand reverse the list when you are done:\n\n**DO**\n\n```erlang\ntail_recursive_fib(N) ->\n tail_recursive_fib(N, 0, 1, []).\n\ntail_recursive_fib(0, _Current, _Next, Fibs) ->\n lists:reverse(Fibs);\ntail_recursive_fib(N, Current, Next, Fibs) ->\n tail_recursive_fib(N - 1, Next, Current + Next, [Current|Fibs]).\n```","title":"Creating a List - List Handling","ref":"listhandling.html#creating-a-list"},{"type":"extras","doc":"A list comprehension:\n\n```erlang\n[Expr(E) || E <- List]\n```\n\nis basically translated to a local function:\n\n```erlang\n'lc^0'([E|Tail], Expr) ->\n [Expr(E)|'lc^0'(Tail, Expr)];\n'lc^0'([], _Expr) -> [].\n```\n\nIf the result of the list comprehension will _obviously_ not be used, a list\nwill not be constructed. For example, in this code:\n\n```erlang\n[io:put_chars(E) || E <- List],\nok.\n```\n\nor in this code:\n\n```erlang\ncase Var of\n ... ->\n [io:put_chars(E) || E <- List];\n ... ->\nend,\nsome_function(...),\n```\n\nthe value is not assigned to a variable, not passed to another function, and not\nreturned. This means that there is no need to construct a list and the compiler\nwill simplify the code for the list comprehension to:\n\n```erlang\n'lc^0'([E|Tail], Expr) ->\n Expr(E),\n 'lc^0'(Tail, Expr);\n'lc^0'([], _Expr) -> [].\n```\n\nThe compiler also understands that assigning to `_` means that the value will\nnot be used. Therefore, the code in the following example will also be optimized:\n\n```erlang\n_ = [io:put_chars(E) || E <- List],\nok.\n```","title":"List Comprehensions - List Handling","ref":"listhandling.html#list-comprehensions"},{"type":"extras","doc":"`lists:flatten/1` builds an entirely new list. It is therefore expensive, and\neven _more_ expensive than the `++` operator (which copies its left argument,\nbut not its right argument).\n\nIn the following situations it is unnecessary to call `lists:flatten/1`:\n\n- When sending data to a port. Ports understand deep lists so there is no reason\n to flatten the list before sending it to the port.\n- When calling BIFs that accept deep lists, such as\n [`list_to_binary/1`](`erlang:list_to_binary/1`) or\n [`iolist_to_binary/1`](`erlang:iolist_to_binary/1`).\n- When you know that your list is only one level deep. Use `lists:append/1`\n instead.\n\n_Examples:_\n\n**DO**\n\n```erlang\nport_command(Port, DeepList)\n```\n\n**DO NOT**\n\n```erlang\nport_command(Port, lists:flatten(DeepList))\n```\n\nA common way to send a zero-terminated string to a port is the following:\n\n**DO NOT**\n\n```erlang\nTerminatedStr = String ++ [0],\nport_command(Port, TerminatedStr)\n```\n\nInstead:\n\n**DO**\n\n```erlang\nTerminatedStr = [String, 0],\nport_command(Port, TerminatedStr)\n```\n\n**DO**\n\n```erlang\n1> lists:append([[1], [2], [3]]).\n[1,2,3]\n```\n\n**DO NOT**\n\n```erlang\n1> lists:flatten([[1], [2], [3]]).\n[1,2,3]\n```","title":"Deep and Flat Lists - List Handling","ref":"listhandling.html#deep-and-flat-lists"},{"type":"extras","doc":"There are two basic ways to write a function that traverses a list and\nproduces a new list.\n\nThe first way is writing a *body-recursive* function:\n\n```erlang\n%% Add 42 to each integer in the list.\nadd_42_body([H|T]) ->\n [H + 42 | add_42_body(T)];\nadd_42_body([]) ->\n [].\n```\n\nThe second way is writing a *tail-recursive* function:\n\n```erlang\n%% Add 42 to each integer in the list.\nadd_42_tail(List) ->\n add_42_tail(List, []).\n\nadd_42_tail([H|T], Acc) ->\n add_42_tail(T, [H + 42 | Acc]);\nadd_42_tail([], Acc) ->\n lists:reverse(Acc).\n```\n\nIn early version of Erlang the tail-recursive function would typically\nbe more efficient. In modern versions of Erlang, there is usually not\nmuch difference in performance between a body-recursive list function and\ntail-recursive function that reverses the list at the end. Therefore,\nconcentrate on writing beautiful code and forget about the performance\nof your list functions. In the time-critical parts of your code,\n_measure_ before rewriting your code.\n\nFor a thorough discussion about tail and body recursion, see\n[Erlang's Tail Recursion is Not a Silver Bullet](http://ferd.ca/erlang-s-tail-recursion-is-not-a-silver-bullet.html).\n\n> #### Note {: .info }\n>\n> This section is about list functions that _construct_ lists. A tail-recursive\n> function that does not construct a list runs in constant space, while the\n> corresponding body-recursive function uses stack space proportional to the\n> length of the list.\n\nFor example, a function that sums a list of integers, is _not_ to be written as\nfollows:\n\n**DO NOT**\n\n```erlang\nrecursive_sum([H|T]) -> H+recursive_sum(T);\nrecursive_sum([]) -> 0.\n```\n\nInstead:\n\n**DO**\n\n```erlang\nsum(L) -> sum(L, 0).\n\nsum([H|T], Sum) -> sum(T, Sum + H);\nsum([], Sum) -> Sum.\n```","title":"Recursive List Functions - List Handling","ref":"listhandling.html#recursive-list-functions"},{"type":"extras","doc":"\n# Functions","title":"Functions","ref":"eff_guide_functions.html"},{"type":"extras","doc":"Pattern matching in function head as well as in `case` and `receive` clauses are\noptimized by the compiler. With a few exceptions, there is nothing to gain by\nrearranging clauses.\n\nOne exception is pattern matching of binaries. The compiler does not rearrange\nclauses that match binaries. Placing the clause that matches against the empty\nbinary _last_ is usually slightly faster than placing it _first_.\n\nThe following is a rather unnatural example to show another exception where\nrearranging clauses is beneficial:\n\n**DO NOT**\n\n```erlang\natom_map1(one) -> 1;\natom_map1(two) -> 2;\natom_map1(three) -> 3;\natom_map1(Int) when is_integer(Int) -> Int;\natom_map1(four) -> 4;\natom_map1(five) -> 5;\natom_map1(six) -> 6.\n```\n\nThe problem is the clause with the variable `Int`. As a variable can match\nanything, including the atoms `four`, `five`, and `six`, which the following\nclauses also match, the compiler must generate suboptimal code that executes as\nfollows:\n\n- First, the input value is compared to `one`, `two`, and `three` (using a\n single instruction that does a binary search; thus, quite efficient even if\n there are many values) to select which one of the first three clauses to\n execute (if any).\n- If none of the first three clauses match, the fourth clause match as a\n variable always matches.\n- If the guard test [`is_integer(Int)`](`is_integer/1`) succeeds, the fourth\n clause is executed.\n- If the guard test fails, the input value is compared to `four`, `five`, and\n `six`, and the appropriate clause is selected. (There is a `function_clause`\n exception if none of the values matched.)\n\nRewriting to either:\n\n**DO**\n\n```erlang\natom_map2(one) -> 1;\natom_map2(two) -> 2;\natom_map2(three) -> 3;\natom_map2(four) -> 4;\natom_map2(five) -> 5;\natom_map2(six) -> 6;\natom_map2(Int) when is_integer(Int) -> Int.\n```\n\nor:\n\n**DO**\n\n```erlang\natom_map3(Int) when is_integer(Int) -> Int;\natom_map3(one) -> 1;\natom_map3(two) -> 2;\natom_map3(three) -> 3;\natom_map3(four) -> 4;\natom_map3(five) -> 5;\natom_map3(six) -> 6.\n```\n\ngives slightly more efficient matching code.\n\nAnother example:\n\n**DO NOT**\n\n```erlang\nmap_pairs1(_Map, [], Ys) ->\n Ys;\nmap_pairs1(_Map, Xs, []) ->\n Xs;\nmap_pairs1(Map, [X|Xs], [Y|Ys]) ->\n [Map(X, Y)|map_pairs1(Map, Xs, Ys)].\n```\n\nThe first argument is _not_ a problem. It is variable, but it is a variable in\nall clauses. The problem is the variable in the second argument, `Xs`, in the\nmiddle clause. Because the variable can match anything, the compiler is not\nallowed to rearrange the clauses, but must generate code that matches them in\nthe order written.\n\nIf the function is rewritten as follows, the compiler is free to rearrange the\nclauses:\n\n**DO**\n\n```erlang\nmap_pairs2(_Map, [], Ys) ->\n Ys;\nmap_pairs2(_Map, [_|_]=Xs, [] ) ->\n Xs;\nmap_pairs2(Map, [X|Xs], [Y|Ys]) ->\n [Map(X, Y)|map_pairs2(Map, Xs, Ys)].\n```\n\nThe compiler will generate code similar to this:\n\n**DO NOT (already done by the compiler)**\n\n```erlang\nexplicit_map_pairs(Map, Xs0, Ys0) ->\n case Xs0 of\n\t[X|Xs] ->\n\t case Ys0 of\n\t\t[Y|Ys] ->\n\t\t [Map(X, Y)|explicit_map_pairs(Map, Xs, Ys)];\n\t\t[] ->\n\t\t Xs0\n\t end;\n\t[] ->\n\t Ys0\n end.\n```\n\nThis is slightly faster for probably the most common case that the input lists\nare not empty or very short. (Another advantage is that Dialyzer can deduce a\nbetter type for the `Xs` variable.)","title":"Pattern Matching - Functions","ref":"eff_guide_functions.html#pattern-matching"},{"type":"extras","doc":"This is a rough hierarchy of the performance of the different types of function\ncalls:\n\n- Calls to local or external functions (`foo()`, `m:foo()`) are the fastest\n calls.\n- Calling or applying a fun (`Fun()`, [`apply(Fun, [])`](`apply/2`)) is just a\n little slower than external calls.\n- Applying an exported function (`Mod:Name()`,\n [`apply(Mod, Name, [])`](`apply/3`)) where the number of arguments is known at\n compile time is next.\n- Applying an exported function ([`apply(Mod, Name, Args)`](`apply/3`)) where\n the number of arguments is not known at compile time is the least efficient.","title":"Function Calls - Functions","ref":"eff_guide_functions.html#function-calls"},{"type":"extras","doc":"Calling and applying a fun does not involve any hash-table lookup. A fun\ncontains an (indirect) pointer to the function that implements the fun.\n\n[`apply/3`](`apply/3`) must look up the code for the function to execute in a\nhash table. It is therefore always slower than a direct call or a fun call.\n\nCaching callback functions into funs may be more efficient in the long run than\napply calls for frequently-used callbacks.","title":"Notes and Implementation Details - Functions","ref":"eff_guide_functions.html#notes-and-implementation-details"},{"type":"extras","doc":"\n# Tables and Databases","title":"Tables and Databases","ref":"tablesdatabases.html"},{"type":"extras","doc":"Every example using Ets has a corresponding example in Mnesia. In general, all\nEts examples also apply to Dets tables.","title":"Ets, Dets, and Mnesia - Tables and Databases","ref":"tablesdatabases.html#ets-dets-and-mnesia"},{"type":"extras","doc":"Select/match operations on Ets and Mnesia tables can become very expensive\noperations. They usually need to scan the complete table. Try to structure the\ndata to minimize the need for select/match operations. However, if you require a\nselect/match operation, it is still more efficient than using `tab2list`.\nExamples of this and of how to avoid select/match are provided in the following\nsections. The functions `ets:select/2` and `mnesia:select/3` are to be preferred\nover `ets:match/2`, `ets:match_object/2`, and `mnesia:match_object/3`.\n\nIn some circumstances, the select/match operations do not need to scan the\ncomplete table. For example, if part of the key is bound when searching an\n`ordered_set` table, or if it is a Mnesia table and there is a secondary index\non the field that is selected/matched. If the key is fully bound, there is no\npoint in doing a select/match, unless you have a bag table and are only\ninterested in a subset of the elements with the specific key.\n\nWhen creating a record to be used in a select/match operation, you want most of\nthe fields to have the value `_`. The easiest and fastest way to do that is as\nfollows:\n\n```text\n#person{age = 42, _ = '_'}.\n```","title":"Select/Match Operations - Tables and Databases","ref":"tablesdatabases.html#select-match-operations"},{"type":"extras","doc":"The `delete` operation is considered successful if the element was not present\nin the table. Hence all attempts to check that the element is present in the\nEts/Mnesia table before deletion are unnecessary. Here follows an example for\nEts tables:\n\n**DO**\n\n```text\nets:delete(Tab, Key),\n```\n\n**DO NOT**\n\n```erlang\ncase ets:lookup(Tab, Key) of\n [] ->\n ok;\n [_|_] ->\n ets:delete(Tab, Key)\nend,\n```","title":"Deleting an Element - Tables and Databases","ref":"tablesdatabases.html#deleting-an-element"},{"type":"extras","doc":"Do not fetch data that you already have.\n\nConsider that you have a module that handles the abstract data type `Person`.\nYou export the interface function `print_person/1`, which uses the internal\nfunctions `print_name/1`, `print_age/1`, and `print_occupation/1`.\n\n> #### Note {: .info }\n>\n> If the function `print_name/1`, and so on, had been interface functions, the\n> situation would have been different, as you do not want the user of the\n> interface to know about the internal data representation.\n\n**DO**\n\n```erlang\n%%% Interface function\nprint_person(PersonId) ->\n %% Look up the person in the named table person,\n case ets:lookup(person, PersonId) of\n [Person] ->\n print_name(Person),\n print_age(Person),\n print_occupation(Person);\n [] ->\n io:format(\"No person with ID = ~p~n\", [PersonID])\n end.\n\n%%% Internal functions\nprint_name(Person) ->\n io:format(\"No person ~p~n\", [Person#person.name]).\n\nprint_age(Person) ->\n io:format(\"No person ~p~n\", [Person#person.age]).\n\nprint_occupation(Person) ->\n io:format(\"No person ~p~n\", [Person#person.occupation]).\n```\n\n**DO NOT**\n\n```erlang\n%%% Interface function\nprint_person(PersonId) ->\n %% Look up the person in the named table person,\n case ets:lookup(person, PersonId) of\n [Person] ->\n print_name(PersonID),\n print_age(PersonID),\n print_occupation(PersonID);\n [] ->\n io:format(\"No person with ID = ~p~n\", [PersonID])\n end.\n\n%%% Internal functions\nprint_name(PersonID) ->\n [Person] = ets:lookup(person, PersonId),\n io:format(\"No person ~p~n\", [Person#person.name]).\n\nprint_age(PersonID) ->\n [Person] = ets:lookup(person, PersonId),\n io:format(\"No person ~p~n\", [Person#person.age]).\n\nprint_occupation(PersonID) ->\n [Person] = ets:lookup(person, PersonId),\n io:format(\"No person ~p~n\", [Person#person.occupation]).\n```","title":"Fetching Data - Tables and Databases","ref":"tablesdatabases.html#fetching-data"},{"type":"extras","doc":"For non-persistent database storage, prefer Ets tables over Mnesia\n`local_content` tables. Even the Mnesia `dirty_write` operations carry a fixed\noverhead compared to Ets writes. Mnesia must check if the table is replicated or\nhas indices, this involves at least one Ets lookup for each `dirty_write`. Thus,\nEts writes is always faster than Mnesia writes.","title":"Non-Persistent Database Storage - Tables and Databases","ref":"tablesdatabases.html#non-persistent-database-storage"},{"type":"extras","doc":"Assuming an Ets table that uses `idno` as key and contains the following:\n\n```text\n[#person{idno = 1, name = \"Adam\", age = 31, occupation = \"mailman\"},\n #person{idno = 2, name = \"Bryan\", age = 31, occupation = \"cashier\"},\n #person{idno = 3, name = \"Bryan\", age = 35, occupation = \"banker\"},\n #person{idno = 4, name = \"Carl\", age = 25, occupation = \"mailman\"}]\n```\n\nIf you _must_ return all data stored in the Ets table, you can use\n`ets:tab2list/1`. However, usually you are only interested in a subset of the\ninformation in which case `ets:tab2list/1` is expensive. If you only want to\nextract one field from each record, for example, the age of every person, then:\n\n**DO**\n\n```erlang\nets:select(Tab, [{#person{idno='_',\n name='_',\n age='$1',\n occupation = '_'},\n [],\n ['$1']}]),\n```\n\n**DO NOT**\n\n```erlang\nTabList = ets:tab2list(Tab),\nlists:map(fun(X) -> X#person.age end, TabList),\n```\n\nIf you are only interested in the age of all persons named \"Bryan\", then:\n\n**DO**\n\n```erlang\nets:select(Tab, [{#person{idno='_',\n name=\"Bryan\",\n age='$1',\n occupation = '_'},\n [],\n ['$1']}])\n```\n\n**DO NOT**\n\n```erlang\nTabList = ets:tab2list(Tab),\nlists:foldl(fun(X, Acc) -> case X#person.name of\n \"Bryan\" ->\n [X#person.age|Acc];\n _ ->\n Acc\n end\n end, [], TabList)\n```\n\nIf you need all information stored in the Ets table about persons named \"Bryan\",\nthen:\n\n**DO**\n\n```erlang\nets:select(Tab, [{#person{idno='_',\n name=\"Bryan\",\n age='_',\n occupation = '_'}, [], ['$_']}]),\n```\n\n**DO NOT**\n\n```erlang\nTabList = ets:tab2list(Tab),\nlists:filter(fun(X) -> X#person.name == \"Bryan\" end, TabList),\n```\n\n### `ordered_set` Tables\n\nIf the data in the table is to be accessed so that the order of the keys in the\ntable is significant, the table type `ordered_set` can be used instead of the\nmore usual `set` table type. An `ordered_set` is always traversed in Erlang term\norder regarding the key field so that the return values from functions such as\n`select`, `match_object`, and `foldl` are ordered by the key values. Traversing\nan `ordered_set` with the `first` and `next` operations also returns the keys\nordered.\n\n> #### Note {: .info }\n>\n> An `ordered_set` only guarantees that objects are processed in _key_ order.\n> Results from functions such as `ets:select/2` appear in _key_ order even if\n> the key is not included in the result.","title":"tab2list - Tables and Databases","ref":"tablesdatabases.html#tab2list"},{"type":"extras","doc":"","title":"ETS - Tables and Databases","ref":"tablesdatabases.html#ets"},{"type":"extras","doc":"An Ets table is a single-key table (either a hash table or a tree ordered by the\nkey) and is to be used as one. In other words, use the key to look up things\nwhenever possible. A lookup by a known key in a `set` Ets table is constant and\nfor an `ordered_set` Ets table it is _O(log N)_. A key lookup is always preferable\nto a call where the whole table has to be scanned. In the previous examples, the\nfield `idno` is the key of the table and all lookups where only the name is\nknown result in a complete scan of the (possibly large) table for a matching\nresult.\n\nA simple solution would be to use the `name` field as the key instead of the\n`idno` field, but that would cause problems if the names were not unique. A more\ngeneral solution would be to create a second table with `name` as key and `idno`\nas data, that is, to index (invert) the table regarding the `name` field.\nClearly, the second table would have to be kept consistent with the master\ntable. Mnesia can do this for you, but a home-brew index table can be very\nefficient compared to the overhead involved in using Mnesia.\n\nAn index table for the table in the previous examples would have to be a bag (as\nkeys would appear more than once) and can have the following contents:\n\n```text\n[#index_entry{name=\"Adam\", idno=1},\n #index_entry{name=\"Bryan\", idno=2},\n #index_entry{name=\"Bryan\", idno=3},\n #index_entry{name=\"Carl\", idno=4}]\n```\n\nGiven this index table, a lookup of the `age` fields for all persons named\n\"Bryan\" can be done as follows:\n\n```erlang\nMatchingIDs = ets:lookup(IndexTable,\"Bryan\"),\nlists:map(fun(#index_entry{idno = ID}) ->\n [#person{age = Age}] = ets:lookup(PersonTable, ID),\n Age\n end,\n MatchingIDs),\n```\n\nNotice that this code does not use `ets:match/2`, but instead uses the\n`ets:lookup/2` call. The `lists:map/2` call is only used to traverse the `idno`s\nmatching the name \"Bryan\" in the table; thus the number of lookups in the master\ntable is minimized.\n\nKeeping an index table introduces some overhead when inserting records in the\ntable. The number of operations gained from the table must therefore be compared\nagainst the number of operations inserting objects in the table. However, notice\nthat the gain is significant when the key can be used to lookup elements.","title":"Using Keys of Ets Table - Tables and Databases","ref":"tablesdatabases.html#using-keys-of-ets-table"},{"type":"extras","doc":"","title":"Mnesia - Tables and Databases","ref":"tablesdatabases.html#mnesia"},{"type":"extras","doc":"If you frequently do lookups on a field that is not the key of the table, you\nlose performance using [mnesia:select()](`mnesia:select/3`) or\n[`mnesia:match_object()`](`mnesia:match_object/1`) as these function traverse\nthe whole table. Instead, you can create a secondary index and use\n`mnesia:index_read/3` to get faster access at the expense of using more\nmemory.\n\n_Example:_\n\n```erlang\n-record(person, {idno, name, age, occupation}).\n ...\n{atomic, ok} =\nmnesia:create_table(person, [{index,[#person.age]},\n {attributes,\n record_info(fields, person)}]),\n{atomic, ok} = mnesia:add_table_index(person, age),\n...\n\nPersonsAge42 =\n mnesia:dirty_index_read(person, 42, #person.age),\n```","title":"Secondary Index - Tables and Databases","ref":"tablesdatabases.html#secondary-index"},{"type":"extras","doc":"Using transactions is a way to guarantee that the distributed Mnesia database\nremains consistent, even when many different processes update it in parallel.\nHowever, if you have real-time requirements it is recommended to use dirtry\noperations instead of transactions. When using dirty operations, you lose the\nconsistency guarantee; this is usually solved by only letting one process update\nthe table. Other processes must send update requests to that process.\n\n_Example:_\n\n```erlang\n...\n%% Using transaction\n\nFun = fun() ->\n [mnesia:read({Table, Key}),\n mnesia:read({Table2, Key2})]\n end,\n\n{atomic, [Result1, Result2]} = mnesia:transaction(Fun),\n...\n\n%% Same thing using dirty operations\n...\n\nResult1 = mnesia:dirty_read({Table, Key}),\nResult2 = mnesia:dirty_read({Table2, Key2}),\n```","title":"Transactions - Tables and Databases","ref":"tablesdatabases.html#transactions"},{"type":"extras","doc":"\n# Processes","title":"Processes","ref":"eff_guide_processes.html"},{"type":"extras","doc":"An Erlang process is lightweight compared to threads and processes in operating\nsystems.\n\nA newly spawned Erlang process uses 327 words of memory. The size can be found\nas follows:\n\n```erlang\nErlang/OTP 27 [erts-14.2.3] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]\n\nEshell V14.2.3 (press Ctrl+G to abort, type help(). for help)\n1> Fun = fun() -> receive after infinity -> ok end end.\n#Fun \n2> {_,Bytes} = process_info(spawn(Fun), memory).\n{memory,2616}\n3> Bytes div erlang:system_info(wordsize).\n327\n```\n\nThe size includes 233 words for the heap area (which includes the stack). The\ngarbage collector increases the heap as needed.\n\nThe main (outer) loop for a process _must_ be tail-recursive. Otherwise, the\nstack grows until the process terminates.\n\n**DO NOT**\n\n```erlang\nloop() ->\n receive\n {sys, Msg} ->\n handle_sys_msg(Msg),\n loop();\n {From, Msg} ->\n Reply = handle_msg(Msg),\n From ! Reply,\n loop()\n end,\n io:format(\"Message is processed~n\", []).\n```\n\nThe call to `io:format/2` will never be executed, but a return address will\nstill be pushed to the stack each time `loop/0` is called recursively. The\ncorrect tail-recursive version of the function looks as follows:\n\n**DO**\n\n```erlang\nloop() ->\n receive\n {sys, Msg} ->\n handle_sys_msg(Msg),\n loop();\n {From, Msg} ->\n Reply = handle_msg(Msg),\n From ! Reply,\n loop()\n end.\n```","title":"Creating an Erlang Process - Processes","ref":"eff_guide_processes.html#creating-an-erlang-process"},{"type":"extras","doc":"The default initial heap size of 233 words is quite conservative to support\nErlang systems with hundreds of thousands or even millions of processes. The\ngarbage collector grows and shrinks the heap as needed.\n\nIn a system that use comparatively few processes, performance _might_ be\nimproved by increasing the minimum heap size using either the `+h` option for\n[erl](`e:erts:erl_cmd.md`) or on a process-per-process basis using the\n`min_heap_size` option for [spawn_opt/4](`erlang:spawn_opt/4`).\n\nThe gain is twofold:\n\n- Although the garbage collector grows the heap, it grows it step-by-step, which\n is more costly than directly establishing a larger heap when the process is\n spawned.\n- The garbage collector can also shrink the heap if it is much larger than the\n amount of data stored on it; setting the minimum heap size prevents that.\n\n> #### Warning {: .warning }\n>\n> The runtime system probably uses more memory, and because garbage collections occur\n> less frequently, huge binaries can be kept much longer.\n>\n> This optimization is not to be attempted without proper measurements.\n\nIn systems with many processes, computation tasks that run for a short time can\nbe spawned off into a new process with a higher minimum heap size. When the\nprocess is done, it sends the result of the computation to another process and\nterminates. If the minimum heap size is calculated properly, the process might\nnot have to do any garbage collections at all.","title":"Initial Heap Size - Processes","ref":"eff_guide_processes.html#initial-heap-size"},{"type":"extras","doc":"All data in messages sent between Erlang processes is copied, except for\n[refc binaries](binaryhandling.md#refc_binary) and\n[literals](eff_guide_processes.md#literal-pool) on the same Erlang node.\n\nWhen a message is sent to a process on another Erlang node, it is\nfirst encoded to the [Erlang External Format](`e:erts:erl_ext_dist.md`)\nbefore being sent through a TCP/IP socket. The receiving Erlang node\ndecodes the message and distributes it to the correct process.","title":"Sending Messages - Processes","ref":"eff_guide_processes.html#sending-messages"},{"type":"extras","doc":"The cost of receiving messages depends on how complicated the `receive`\nexpression is. A simple expression that matches any message is very cheap\nbecause it retrieves the first message in the message queue:\n\n**DO**\n\n```erlang\nreceive\n Message -> handle_msg(Message)\nend.\n```\n\nHowever, this is not always convenient: we can receive a message that we do not\nknow how to handle at this point, so it is common to only match the messages we\nexpect:\n\n```erlang\nreceive\n {Tag, Message} -> handle_msg(Message)\nend.\n```\n\nWhile this is convenient it means that the entire message queue must be searched\nuntil it finds a matching message. This is very expensive for processes with\nlong message queues, so there is an optimization for the common case of\nsending a request and waiting for a response shortly after:\n\n**DO**\n\n```erlang\nMRef = monitor(process, Process),\nProcess ! {self(), MRef, Request},\nreceive\n {MRef, Reply} ->\n erlang:demonitor(MRef, [flush]),\n handle_reply(Reply);\n {'DOWN', MRef, _, _, Reason} ->\n handle_error(Reason)\nend.\n```\n\nSince the compiler knows that the reference created by\n[`monitor/2`](`monitor/2`) cannot exist before the call (since it is a globally\nunique identifier), and that the `receive` only matches messages that contain\nsaid reference, it will tell the emulator to search only the messages that\narrived after the call to [`monitor/2`](`monitor/2`).\n\nThe above is a simple example where one is but guaranteed that the optimization\nwill take, but what about more complicated code?\n\n[](){: #recv_opt_info }","title":"Receiving messages - Processes","ref":"eff_guide_processes.html#receiving-messages"},{"type":"extras","doc":"Use the `recv_opt_info` option to have the compiler print information about\nreceive optimizations. It can be given either to the compiler or `erlc`:\n\n```erlang\nerlc +recv_opt_info Mod.erl\n```\n\nor passed through an environment variable:\n\n```erlang\nexport ERL_COMPILER_OPTIONS=recv_opt_info\n```\n\nNotice that `recv_opt_info` is not meant to be a permanent option added to your\n`Makefile`s, because all messages that it generates cannot be eliminated.\nTherefore, passing the option through the environment is in most cases the most\npractical approach.\n\nThe warnings look as follows:\n\n```erlang\nefficiency_guide.erl:194: Warning: INFO: receive matches any message, this is always fast\nefficiency_guide.erl:200: Warning: NOT OPTIMIZED: all clauses do not match a suitable reference\nefficiency_guide.erl:206: Warning: OPTIMIZED: reference used to mark a message queue position\nefficiency_guide.erl:208: Warning: OPTIMIZED: all clauses match reference created by monitor/2 at efficiency_guide.erl:206\nefficiency_guide.erl:219: Warning: INFO: passing reference created by make_ref/0 at efficiency_guide.erl:218\nefficiency_guide.erl:222: Warning: OPTIMIZED: all clauses match reference in function parameter 1\n```\n\nTo make it clearer exactly what code the warnings refer to, the warnings in the\nfollowing examples are inserted as comments after the clause they refer to, for\nexample:\n\n```erlang\n%% DO\nsimple_receive() ->\n%% efficiency_guide.erl:194: Warning: INFO: not a selective receive, this is always fast\nreceive\n Message -> handle_msg(Message)\nend.\n\n%% DO NOT, unless Tag is known to be a suitable reference: see\n%% cross_function_receive/0 further down.\nselective_receive(Tag, Message) ->\n%% efficiency_guide.erl:200: Warning: NOT OPTIMIZED: all clauses do not match a suitable reference\nreceive\n {Tag, Message} -> handle_msg(Message)\nend.\n\n%% DO\noptimized_receive(Process, Request) ->\n%% efficiency_guide.erl:206: Warning: OPTIMIZED: reference used to mark a message queue position\n MRef = monitor(process, Process),\n Process ! {self(), MRef, Request},\n %% efficiency_guide.erl:208: Warning: OPTIMIZED: matches reference created by monitor/2 at efficiency_guide.erl:206\n receive\n {MRef, Reply} ->\n erlang:demonitor(MRef, [flush]),\n handle_reply(Reply);\n {'DOWN', MRef, _, _, Reason} ->\n handle_error(Reason)\n end.\n\n%% DO\ncross_function_receive() ->\n %% efficiency_guide.erl:218: Warning: OPTIMIZED: reference used to mark a message queue position\n Ref = make_ref(),\n %% efficiency_guide.erl:219: Warning: INFO: passing reference created by make_ref/0 at efficiency_guide.erl:218\n cross_function_receive(Ref).\n\ncross_function_receive(Ref) ->\n %% efficiency_guide.erl:222: Warning: OPTIMIZED: all clauses match reference in function parameter 1\n receive\n {Ref, Message} -> handle_msg(Message)\n end.\n```","title":"Option recv_opt_info - Processes","ref":"eff_guide_processes.html#option-recv_opt_info"},{"type":"extras","doc":"Constant Erlang terms (hereafter called _literals_) are kept in _literal pools_;\neach loaded module has its own pool. The following function does not build the\ntuple every time it is called (only to have it discarded the next time the\ngarbage collector was run), but the tuple is located in the module's literal\npool:\n\n**DO**\n\n```erlang\ndays_in_month(M) ->\n element(M, {31,28,31,30,31,30,31,31,30,31,30,31}).\n```\n\nIf a literal, or a term that contains a literal, is inserted into an Ets table,\nit is _copied_. The reason is that the module containing the literal can be\nunloaded in the future.\n\nWhen a literal is sent to another process, it is _not_ copied. When a module\nholding a literal is unloaded, the literal will be copied to the heap of all\nprocesses that hold references to that literal.\n\nThere also exists a global literal pool that is managed by the\n`m:persistent_term` module.\n\nBy default, 1 GB of virtual address space is reserved for all literal pools (in\nBEAM code and persistent terms). The amount of virtual address space reserved\nfor literals can be changed by using the\n[`+MIscs option`](`e:erts:erts_alloc.md#MIscs`) when starting the emulator.\n\nHere is an example how the reserved virtual address space for literals can be\nraised to 2 GB (2048 MB):\n\n```text\nerl +MIscs 2048\n```","title":"Literal Pool - Processes","ref":"eff_guide_processes.html#literal-pool"},{"type":"extras","doc":"An Erlang term can have shared subterms. Here is a simple example:\n\n```erlang\n{SubTerm, SubTerm}\n```\n\nShared subterms are _not_ preserved in the following cases:\n\n- When a term is sent to another process\n- When a term is passed as the initial process arguments in the `spawn` call\n- When a term is stored in an Ets table\n\nThat is an optimization. Most applications do not send messages with shared\nsubterms.\n\nThe following example shows how a shared subterm can be created:\n\n```erlang\nkilo_byte() ->\n kilo_byte(10, [42]).\n\nkilo_byte(0, Acc) ->\n Acc;\nkilo_byte(N, Acc) ->\n kilo_byte(N-1, [Acc|Acc]).\n```\n\n`kilo_byte/1` creates a deep list. If [`list_to_binary/1`](`list_to_binary/1`)\nis called, the deep list can be converted to a binary of 1024 bytes:\n\n```text\n1> byte_size(list_to_binary(efficiency_guide:kilo_byte())).\n1024\n```\n\nUsing the `erts_debug:size/1` BIF, it can be seen that the deep list only\nrequires 22 words of heap space:\n\n```erlang\n2> erts_debug:size(efficiency_guide:kilo_byte()).\n22\n```\n\nUsing the `erts_debug:flat_size/1` BIF, the size of the deep list can be\ncalculated if sharing is ignored. It becomes the size of the list when it has\nbeen sent to another process or stored in an Ets table:\n\n```erlang\n3> erts_debug:flat_size(efficiency_guide:kilo_byte()).\n4094\n```\n\nIt can be verified that sharing will be lost if the data is inserted into an Ets\ntable:\n\n```erlang\n4> T = ets:new(tab, []).\n#Ref<0.1662103692.2407923716.214181>\n5> ets:insert(T, {key,efficiency_guide:kilo_byte()}).\ntrue\n6> erts_debug:size(element(2, hd(ets:lookup(T, key)))).\n4094\n7> erts_debug:flat_size(element(2, hd(ets:lookup(T, key)))).\n4094\n```\n\nWhen the data has passed through an Ets table, `erts_debug:size/1` and\n`erts_debug:flat_size/1` return the same value. Sharing has been lost.\n\nIt is possible to build an _experimental_ variant of the runtime system that\nwill preserve sharing when copying terms by giving the\n`--enable-sharing-preserving` option to the `configure` script.","title":"Loss of Sharing - Processes","ref":"eff_guide_processes.html#loss-of-sharing"},{"type":"extras","doc":"The Erlang run-time system takes advantage of a multi-core or\nmulti-CPU computer by running several Erlang scheduler threads\n(typically, the same number of threads as the number of cores).\n\nTo gain performance from a multi-core computer, your application _must have more\nthan one runnable Erlang process_ most of the time. Otherwise, the Erlang\nemulator can still only run one Erlang process at the time.\n\nBenchmarks that appear to be concurrent are often sequential. For\nexample, the [EStone\nbenchmark](https://github.com/erlang/otp/blob/f164034e6fdab3316ae23c5d5bbaef258dd6d12c/erts/emulator/test/estone_SUITE.erl)\nis entirely sequential. So is the most common implementation of the\n\"ring benchmark\"; usually one process is active, while the others wait\nin a `receive` statement.","title":"SMP Run-Time System - Processes","ref":"eff_guide_processes.html#smp-run-time-system"},{"type":"extras","doc":"\n# Drivers\n\nThis section provides a brief overview on how to write efficient drivers.\n\nIt is assumed that you have a good understanding of drivers.","title":"Drivers","ref":"drivers.html"},{"type":"extras","doc":"The runtime system always takes a lock before running any code in a driver.\n\nBy default, that lock is at the driver level, that is, if several ports have\nbeen opened to the same driver, only code for one port at the same time can be\nrunning.\n\nA driver can be configured to have one lock for each port instead.\n\nIf a driver is used in a functional way (that is, holds no state, but only does\nsome heavy calculation and returns a result), several ports with registered\nnames can be opened beforehand, and the port to be used can be chosen based on\nthe scheduler ID as follows:\n\n```erlang\n-define(PORT_NAMES(),\n\t{some_driver_01, some_driver_02, some_driver_03, some_driver_04,\n\t some_driver_05, some_driver_06, some_driver_07, some_driver_08,\n\t some_driver_09, some_driver_10, some_driver_11, some_driver_12,\n\t some_driver_13, some_driver_14, some_driver_15, some_driver_16}).\n\nclient_port() ->\n element(erlang:system_info(scheduler_id) rem tuple_size(?PORT_NAMES()) + 1,\n\t ?PORT_NAMES()).\n```\n\nAs long as there are no more than 16 schedulers, there will never be any lock\ncontention on the port lock for the driver.","title":"Drivers and Concurrency - Drivers","ref":"drivers.html#drivers-and-concurrency"},{"type":"extras","doc":"There are basically two ways to avoid copying a binary that is sent to a driver:\n\n- If the `Data` argument for [`port_control/3`](`erlang:port_control/3`) is a\n binary, the driver will be passed a pointer to the contents of the binary and\n the binary will not be copied. If the `Data` argument is an iolist (list of\n binaries and lists), all binaries in the iolist will be copied.\n\n Therefore, if you want to send both a pre-existing binary and some extra data\n to a driver without copying the binary, you must call\n [`port_control/3`](`port_control/3`) twice; once with the binary and once with\n the extra data. However, that will only work if there is only one process\n communicating with the port (because otherwise another process can call the\n driver in-between the calls).\n\n- Implement an `outputv` callback (instead of an `output` callback) in the\n driver. If a driver has an `outputv` callback, refc binaries passed in an\n iolist in the `Data` argument for [`port_command/2`](`erlang:port_command/2`)\n will be passed as references to the driver.","title":"Avoiding Copying Binaries When Calling a Driver - Drivers","ref":"drivers.html#avoiding-copying-binaries-when-calling-a-driver"},{"type":"extras","doc":"The runtime system can represent binaries up to 64 bytes as heap binaries. They\nare always copied when sent in messages, but they require less memory if they\nare not sent to another process and garbage collection is cheaper.\n\nIf you know that the binaries you return are always small, you are advised to\nuse driver API calls that do not require a pre-allocated binary, for example,\n[`driver_output()`](`e:erts:erl_driver.md#driver_output`) or\n[`erl_drv_output_term()`](`e:erts:erl_driver.md#erl_drv_output_term`), using the\n`ERL_DRV_BUF2BINARY` format, to allow the runtime to construct a heap binary.","title":"Returning Small Binaries from a Driver - Drivers","ref":"drivers.html#returning-small-binaries-from-a-driver"},{"type":"extras","doc":"To avoid copying data when a large binary is sent or returned from the driver to\nan Erlang process, the driver must first allocate the binary and then send it to\nan Erlang process in some way.\n\nUse [`driver_alloc_binary()`](`e:erts:erl_driver.md#driver_alloc_binary`) to\nallocate a binary.\n\nThere are several ways to send a binary created with `driver_alloc_binary()`:\n\n- From the `control` callback, a binary can be returned if\n [`set_port_control_flags()`](`e:erts:erl_driver.md#set_port_control_flags`) has\n been called with the flag value `PORT_CONTROL_FLAG_BINARY`.\n- A single binary can be sent with\n [`driver_output_binary()`](`e:erts:erl_driver.md#driver_output_binary`).\n- Using [`erl_drv_output_term()`](`e:erts:erl_driver.md#erl_drv_output_term`) or\n [`erl_drv_send_term()`](`e:erts:erl_driver.md#erl_drv_send_term`), a binary can\n be included in an Erlang term.","title":"Returning Large Binaries without Copying from a Driver - Drivers","ref":"drivers.html#returning-large-binaries-without-copying-from-a-driver"},{"type":"extras","doc":"\n# Memory Usage\n\nA good start when programming efficiently is to know how much memory different\ndata types and operations require. It is implementation-dependent how much\nmemory the Erlang data types and other items consume, but the following table\nshows some figures for the `erts-8.0` system in OTP 19.0.\n\nThe unit of measurement is memory words. There exists both a 32-bit and a 64-bit\nimplementation. A word is therefore 4 bytes or 8 bytes, respectively. The value\nfor a running system can be determined by calling\n[`erlang:system_info(wordsize)`](`m:erlang#system_info_wordsize`).\n\n\n \n \n Data Type \n Memory Size \n \n \n Small integer \n 1 word. \n On 32-bit architectures: -134217729 < i < 134217728\n (28 bits). \n On 64-bit architectures: -576460752303423489 < i <\n 576460752303423488 (60 bits). \n \n \n Large integer \n At least 3 words. \n \n \n Atom \n 1 word. \n An atom refers into an atom table, which also consumes memory.\n The atom text is stored once for each unique atom in this table.\n The atom table is not garbage-collected. \n \n \n Float \n On 32-bit architectures: 4 words. \n On 64-bit architectures: 3 words. \n \n \n Binary \n 3-6 words + data (can be shared). \n \n \n List \n 1 word + 1 word per element + the size of each element. \n \n \n String \n (is the same as a list of integers) \n 1 word + 2 words per character.\n \n \n \n Tuple \n 2 words + the size of each element. \n \n \n Small Map \n (up to 32 keys) \n 5 words + the size of all keys and values. \n \n \n Large Map \n \n (more than 32 keys) \n N x F words + the size of all keys and values. \n N is the number of keys in the Map. \n F is a sparsity factor that varies between 1.6 and 1.8\n due to the probabilistic nature of the internal HAMT data structure.\n \n \n \n Pid \n 1 word for a process identifier from the current local node. \n On 32-bit: 6 words for a process identifier from another node. \n On 64-bit: 5 words for a process identifier from another node. \n A process identifier refers into a process table and a node table,\n which also consumes memory. \n \n \n Port \n 1 word for a port identifier from the current local node. \n 5 words for a port identifier from another node. \n A port identifier refers into a port table and a node table,\n which also consumes memory. \n \n \n Reference \n On 32-bit architectures: 4-7 words for a reference from the\n current local node, and 7-9 words for a reference from another\n node. \n On 64-bit architectures: 4-6 words for a reference from the current\n local node, and 6-7 words for a reference from another node. \n A reference also refers into more or less emulator internal data\n structures which also consumes memory. At a minimum it\n refers into the node tables. \n \n \n Fun \n 9..13 words + the size of environment. \n A fun refers into a fun table, which also consumes memory. \n \n \n Ets table \n Initially 768 words + the size of each element (6 words +\n the size of Erlang data). The table grows when necessary. \n \n \n Erlang process \n 338 words when spawned, including a heap of 233 words. \n \n \n\n_Table: Memory Size of Different Data Types_","title":"Memory Usage","ref":"memory.html"},{"type":"extras","doc":"\n# System Limits\n\nThe Erlang language specification puts no limits on the number of processes,\nlength of atoms, and so on. However, for performance and memory saving reasons,\nthere will always be limits in a practical implementation of the Erlang language\nand execution environment.\n\n- **Processes** - The maximum number of simultaneously alive Erlang processes\nis by default 1,048,576. This limit can be configured at startup. For more information,\nsee the [`+P`](`e:erts:erl_cmd.md#max_processes`) command-line flag\nin the [`erl(1)`](`e:erts:erl_cmd.md`) manual page in ERTS.\n\n- [](){: #unique_pids } **Unique Local Process Identifiers on a\nRuntime System Instance ** - On a 64 bit system at most `2⁶⁰ - 1`\nunique process identifiers can be created, and on a 32 bit system at most `2²⁸ - 1`.\n\n- **Known nodes** - A remote node Y must be known to node X if there exists\nany pids, ports, references, or funs (Erlang data types) from Y on X, or if\nX and Y are connected. The maximum number of remote nodes simultaneously/ever known\nto a node is limited by the [maximum number of atoms](#atoms) available\nfor node names. All data concerning remote nodes, except for the node name atom,\nare garbage-collected.\n\n- **Connected nodes** - The maximum number of simultaneously connected nodes is\nlimited by either the maximum number of simultaneously known remote nodes,\n[the maximum number of (Erlang) ports](#ports) available,\nor [the maximum number of sockets](#files_sockets) available.\n\n- **Characters in an atom** - 255.\n\n- [](){: #atoms } **Atoms** - By default, the maximum number of atoms is 1,048,576.\nThis limit can be raised or lowered using the `+t` option.\n\n- **Elements in a tuple** - The maximum number of elements in a\ntuple is 16,777,215 (24-bit unsigned integer).\n\n- **Size of binary** - In the 32-bit run-time system for Erlang, 536,870,911 bytes\nis the largest binary that can be constructed or matched using the bit syntax.\nIn the 64-bit run-time system, the maximum size is 2,305,843,009,213,693,951 bytes.\nIf the limit is exceeded, bit syntax construction fails with a `system_limit`\nexception, while any attempt to match a binary that is too large\nfails. From Erlang/OTP 27, all other operations that create binaries (such as\n[`list_to_binary/1`](`list_to_binary/1`)) also enforces the same limit.\n\n- **Total amount of data allocated by an Erlang node** - The Erlang runtime system\ncan use the complete 32-bit (or 64-bit) address space, but the operating system\noften limits a single process to use less than that.\n\n- **Length of a node name** - An Erlang node name has the form `host@shortname`\nor `host@longname`. The node name is used as an atom within the system, so the\nmaximum size of 255 holds also for the node name.\n\n- [](){: #ports } **Open ports** - The maximum number of simultaneously open\nErlang ports is often by default 16,384. This limit can be configured at startup.\nFor more information, see the [`+Q`](`e:erts:erl_cmd.md#max_ports`) command-line\nflag in the [`erl(1)`](`e:erts:erl_cmd.md`) manual page in ERTS.\n\n- [](){: #unique_ports } **Unique Local Port Identifiers on a Runtime System Instance** -\nOn a 64 bit system at most `2⁶⁰ - 1` unique port identifiers can be created and\non a 32 bit system at most `2²⁸ - 1`.\n\n- [](){: #files_sockets } **Open files and sockets** - The maximum number of simultaneously\nopen files and sockets depends on [the maximum number of Erlang ports](#ports)\navailable, as well as on operating system-specific settings and limits.\n\n- **Number of arguments to a function or fun** - 255.\n\n- [](){: #unique_references } **Unique References on a Runtime System Instance** -\nEach scheduler thread has its own set of references, and all other threads have\na shared set of references. Each set of references consist of `2⁶⁴ - 1`unique\nreferences. That is, the total amount of unique references that can be produced\non a runtime system instance is `(NumSchedulers + 1) × (2⁶⁴ - 1)`. If a scheduler\nthread create a new reference each nano second, references will at earliest be\nreused after more than 584 years. That is, for the foreseeable future they are\nsufficiently unique.\n\n- [](){: #unique_integers } **Unique Integers on a Runtime System Instance** -\n There are two types of unique integers created by the\n [erlang:unique_integer/1](`erlang:unique_integer/1`) BIF:\n - Unique integers created **with** the `monotonic` modifier consist of\n a set of `2⁶⁴ - 1` unique integers.\n - Unique integers created **without** the `monotonic` modifier consist\n of a set of `2⁶⁴ - 1` unique integers per scheduler thread and a\n set of `2⁶⁴ - 1` unique integers shared by other threads. That is,\n the total amount of unique integers without the `monotonic`\n modifier is `(NumSchedulers + 1) × (2⁶⁴ - 1)`.\n\n If a unique integer is created each nano second, unique integers will be\n reused at earliest after more than 584 years. That is, for the foreseeable future\n they are sufficiently unique.","title":"System Limits","ref":"system_limits.html"},{"type":"extras","doc":"\n# Profiling","title":"Profiling","ref":"profiling.html"},{"type":"extras","doc":"Even experienced software developers often guess wrong about where the\nperformance bottlenecks are in their programs. Therefore, profile your program\nto see where the performance bottlenecks are and concentrate on optimizing them.\n\nErlang/OTP contains several tools to help finding bottlenecks:\n\n- `m:tprof` is a tracing profiler that can measure call count, call time, or\n heap allocations per function call.\n- `m:fprof` provides the most detailed information about where the program time\n is spent, but it significantly slows down the program it profiles.\n- `m:dbg` is the generic erlang tracing frontend. By using the `timestamp` or\n `cpu_timestamp` options it can be used to time how long function calls in a\n live system take.\n- `m:lcnt` is used to find contention points in the Erlang Run-Time System's\n internal locking mechanisms. It is useful when looking for bottlenecks in\n interaction between process, port, ETS tables, and other entities that can be\n run in parallel.\n\nThe tools are further described in [Tools](profiling.md#profiling_tools).\n\nThere are also several open source tools outside of Erlang/OTP that can be used\nto help profiling. Some of them are:\n\n- [erlgrind](https://github.com/isacssouza/erlgrind) can be used to visualize\n fprof data in kcachegrind.\n- [eflame](https://github.com/proger/eflame) is an alternative to fprof that\n displays the profiling output as a flamegraph.\n- [recon](https://ferd.github.io/recon/index.html) is a collection of Erlang\n profiling and debugging tools. This tool comes with an accompanying E-book\n called [Erlang in Anger](https://www.erlang-in-anger.com/).\n- [perf](https://perf.wiki.kernel.org/index.php/Main_Page) is a sampling\n profiler for Linux that provides functionality similar to `fprof` but with\n much lower overhead. Profiling Erlang code is possible when the emulator has\n been started with the `+JPperf true` emulator flag, and is only available when\n the JIT is enabled.\n\n For more details about how to run `perf` see the\n [perf support](`e:erts:beamasm.md#linux-perf-support`) section in the BeamAsm\n internal documentation.","title":"Never Guess About Performance Bottlenecks - Profiling","ref":"profiling.html#never-guess-about-performance-bottlenecks"},{"type":"extras","doc":"```text\neheap_alloc: Cannot allocate 1234567890 bytes of memory (of type \"heap\").\n```\n\nThe above slogan is one of the more common reasons for Erlang to terminate. For\nunknown reasons the Erlang Run-Time System failed to allocate memory to use.\nWhen this happens a crash dump is generated that contains information about the\nstate of the system as it ran out of memory. Use\n[`crashdump_viewer`](`e:observer:cdv_cmd.md`) to get a view of the memory being\nused. Look for processes with large heaps or many messages, large ETS tables,\nand so on.\n\nWhen looking at memory usage in a running system the most basic function to get\ninformation from is [`erlang:memory()`](`erlang:memory/0`). It returns the\ncurrent memory usage of the system. `m:instrument` can be used to get a more\ndetailed breakdown of where memory is used.\n\nProcesses, ports, and ETS tables can then be inspected using their respective\ninformation functions, that is,\n[`process_info/2`](`m:erlang#process_info_memory`),\n[`erlang:port_info/2 `](`m:erlang#port_info_memory`), and `ets:info/1`.\n\nSometimes the system can enter a state where the reported memory from\n`erlang:memory(total)` is very different from the memory reported by\nthe operating system. One reason for that is internal fragmentation\nwithin the Erlang run-time system. Data about how memory is allocated\ncan be retrieved using\n[`erlang:system_info(allocator)`](`m:erlang#system_info_allocator`). The\ndata you get from that function is raw and hard to read.\n[recon_alloc](http://ferd.github.io/recon/recon_alloc.html) can\nbe used to extract useful information from system_info statistics\ncounters.","title":"Memory profiling - Profiling","ref":"profiling.html#memory-profiling"},{"type":"extras","doc":"For a large system, it can be interesting to run profiling on a simulated and\nlimited scenario to start with. But bottlenecks have a tendency to appear or\ncause problems only when many things are going on at the same time, and when\nmany nodes are involved. Therefore, it is also desirable to run profiling in a\nsystem test plant on a real target system.\n\nFor a large system, you do not want to run the profiling tools on the whole\nsystem. Instead you want to concentrate on central processes and modules, which\naccount for a big part of the execution.\n\nThere are also some tools that can be used to get a view of the whole system\nwith more or less overhead.\n\n- `m:observer` is a GUI tool that can connect to remote nodes and display a\n variety of information about the running system.\n- `m:etop` is a command line tool that can connect to remote nodes and display\n information similar to what the UNIX tool top shows.\n- `m:msacc` allows the user to get a view of what the Erlang Run-Time system is\n spending its time doing. Has a very low overhead, which makes it useful to run\n in heavily loaded systems to get some idea of where to start doing more\n granular profiling.","title":"Large Systems - Profiling","ref":"profiling.html#large-systems"},{"type":"extras","doc":"When analyzing the result file from the profiling activity, look for functions\nthat are called many times and have a long \"own\" execution time (time excluding\ncalls to other functions). Functions that are called a lot of times can also be\ninteresting, as even small things can add up to quite a bit if repeated often.\nAlso ask yourself what you can do to reduce this time. The following are\nappropriate types of questions to ask yourself:\n\n- Is it possible to reduce the number of times the function is called?\n- Can any test be run less often if the order of tests is changed?\n- Can any redundant tests be removed?\n- Does any calculated expression give the same result each time?\n- Are there other ways to do this that are equivalent and more efficient?\n- Can another internal data representation be used to make things more\n efficient?\n\nThese questions are not always trivial to answer. Some benchmarks might be\nneeded to back up your theory and to avoid making things slower if your theory\nis wrong. For details, see [Benchmarking](benchmarking.md).","title":"What to Look For - Profiling","ref":"profiling.html#what-to-look-for"},{"type":"extras","doc":"[](){: #profiling_tools }","title":"Tools - Profiling","ref":"profiling.html#tools"},{"type":"extras","doc":"`fprof` measures the execution time for each function, both own time, that is,\nhow much time a function has used for its own execution, and accumulated time,\nthat is, including called functions. The values are displayed per process. You\nalso get to know how many times each function has been called.\n\n`fprof` is based on trace to file to minimize runtime performance impact. Using\n`fprof` is just a matter of calling a few library functions, see the `m:fprof`\nmanual page in Tools.","title":"fprof - Profiling","ref":"profiling.html#fprof"},{"type":"extras","doc":"`eprof` is based on the Erlang `trace_info` BIFs. `eprof` shows how much time\nhas been used by each process, and in which function calls this time has been\nspent. Time is shown as a percentage of total time and absolute time. For more\ninformation, see the `m:eprof` manual page in Tools.","title":"eprof - Profiling","ref":"profiling.html#eprof"},{"type":"extras","doc":"`cprof` is something in between `fprof` and `cover` regarding features. It\ncounts how many times each function is called when the program is run, on a per\nmodule basis. `cprof` has a low performance degradation effect (compared with\n`fprof`) and does not need to recompile any modules to profile (compared with\n`cover`). For more information, see the `m:cprof` manual page in Tools.","title":"cprof - Profiling","ref":"profiling.html#cprof"},{"type":"extras","doc":"| _Tool_ | _Results_ | _Size of Result_ | _Effects on Program Execution Time_ | _Records Number of Calls_ | _Records Execution Time_ | _Records Called by_ | _Records Garbage Collection_ |\n| ------- | ----------------------------------- | ---------------- | ----------------------------------- | ------------------------- | ------------------------ | ------------------- | ---------------------------- |\n| `fprof` | Per process to screen/file | Large | Significant slowdown | Yes | Total and own | Yes | Yes |\n| `eprof` | Per process/function to screen/file | Medium | Small slowdown | Yes | Only total | No | No |\n| `cprof` | Per module to caller | Small | Small slowdown | Yes | No | No | No |\n\n_Table: Tool Summary_","title":"Tool Summary - Profiling","ref":"profiling.html#tool-summary"},{"type":"extras","doc":"`dbg` is a generic Erlang trace tool. By using the `timestamp` or\n`cpu_timestamp` options it can be used as a precision instrument to profile how\nlong time a function call takes for a specific process. This can be very useful\nwhen trying to understand where time is spent in a heavily loaded system as it\nis possible to limit the scope of what is profiled to be very small. For more\ninformation, see the `m:dbg` manual page in Runtime Tools.","title":"dbg - Profiling","ref":"profiling.html#dbg"},{"type":"extras","doc":"`lcnt` is used to profile interactions in between entities that run in parallel.\nFor example if you have a process that all other processes in the system needs\nto interact with (maybe it has some global configuration), then `lcnt` can be\nused to figure out if the interaction with that process is a problem.\n\nIn the Erlang Run-time System entities are only run in parallel when there are\nmultiple schedulers. Therefore `lcnt` will show more contention points (and thus\nbe more useful) on systems using many schedulers on many cores.\n\nFor more information, see the `m:lcnt` manual page in Tools.","title":"lcnt - Profiling","ref":"profiling.html#lcnt"},{"type":"extras","doc":"\n# Benchmarking\n\nThe main purpose of benchmarking is to find out which implementation of a given\nalgorithm or function is the fastest. Benchmarking is far from an exact science.\nToday's operating systems generally run background tasks that are difficult to\nturn off. Caches and multiple CPU cores do not facilitate benchmarking. It would\nbe best to run UNIX computers in single-user mode when benchmarking, but that is\ninconvenient to say the least for casual testing.","title":"Benchmarking","ref":"benchmarking.html"},{"type":"extras","doc":"A useful tool for benchmarking is [erlperf](https://github.com/max-au/erlperf)\n([documentation](https://hexdocs.pm/erlperf/erlperf.html)).\nIt makes it simple to find out which code is faster. For example, here is how\ntwo methods of generating random bytes can be compared:\n\n```text\n% erlperf 'rand:bytes(2).' 'crypto:strong_rand_bytes(2).'\nCode || QPS Time Rel\nrand:bytes(2). 1 7784 Ki 128 ns 100%\ncrypto:strong_rand_bytes(2). 1 2286 Ki 437 ns 29%\n```\n\nFrom the **Time** column we can read out that on average a call to\n[`rand:bytes(2)`](`rand:bytes/1`) executes in 128 nano seconds, while\na call to\n[`crypto:strong_rand_bytes(2)`](`crypto:strong_rand_bytes/1`) executes\nin 437 nano seconds.\n\nFrom the **QPS** column we can read out how many calls that can be\nmade in a second. For `rand:bytes(2)`, it is 7,784,000 calls per second.\n\nThe **Rel** column shows the relative differences, with `100%` indicating\nthe fastest code.\n\nWhen generating two random bytes at the time, `rand:bytes/1` is more\nthan three times faster than `crypto:strong_rand_bytes/1`. Assuming\nthat we really need strong random numbers and we need to get them as\nfast as possible, what can we do? One way could be to generate more\nthan two bytes at the time.\n\n```text\n% erlperf 'rand:bytes(100).' 'crypto:strong_rand_bytes(100).'\nCode || QPS Time Rel\nrand:bytes(100). 1 2124 Ki 470 ns 100%\ncrypto:strong_rand_bytes(100). 1 1915 Ki 522 ns 90%\n```\n\n`rand:bytes/1` is still faster when we generate 100 bytes at the time,\nbut the relative difference is smaller.\n\n```\n% erlperf 'rand:bytes(1000).' 'crypto:strong_rand_bytes(1000).'\nCode || QPS Time Rel\ncrypto:strong_rand_bytes(1000). 1 1518 Ki 658 ns 100%\nrand:bytes(1000). 1 284 Ki 3521 ns 19%\n```\n\nWhen we generate 1000 bytes at the time, `crypto:strong_rand_bytes/1` is\nnow the fastest.","title":"Using erlperf - Benchmarking","ref":"benchmarking.html#using-erlperf"},{"type":"extras","doc":"Benchmarks can measure wall-clock time or CPU time.\n\n- `timer:tc/3` measures wall-clock time. The advantage with wall-clock time is\n that I/O, swapping, and other activities in the operating system kernel are\n included in the measurements. The disadvantage is that the measurements often\n vary a lot. Usually it is best to run the benchmark several times and note\n the shortest time, which is the minimum time that is possible to achieve\n under the best of circumstances.\n\n- [`statistics(runtime)`](`erlang:statistics/1`) measures CPU time spent\n in the Erlang virtual machine. The advantage with CPU time is that\n the results are more consistent from run to run. The disadvantage is\n that the time spent in the operating system kernel (such as swapping\n and I/O) is not included. Therefore, measuring CPU time is\n misleading if any I/O (file or socket) is involved.\n\nIt is probably a good idea to do both wall-clock measurements and CPU time\nmeasurements.\n\nSome final advice:\n\n- The granularity of both measurement types can be high. Therefore, ensure that\n each individual measurement lasts for at least several seconds.\n- To make the test fair, each new test run is to run in its own, newly created\n Erlang process. Otherwise, if all tests run in the same process, the later\n tests start out with larger heap sizes and therefore probably do fewer garbage\n collections. Also consider restarting the Erlang emulator between each test.\n- Do not assume that the fastest implementation of a given algorithm on computer\n architecture X is also the fastest on computer architecture Y.","title":"Benchmarking using Erlang/OTP functionality - Benchmarking","ref":"benchmarking.html#benchmarking-using-erlang-otp-functionality"},{"type":"extras","doc":"\n# Introduction\n\n[](){: #interoperability-tutorial }\n\nThis section informs on interoperability, that is, information exchange, between\nErlang and other programming languages. The included examples mainly treat\ninteroperability between Erlang and C.","title":"Introduction","ref":"tutorial.html"},{"type":"extras","doc":"The purpose of this tutorial is to describe different interoperability\nmechanisms that can be used when integrating a program written in Erlang with a\nprogram written in another programming language, from the Erlang programmer's\nperspective.","title":"Purpose - Introduction","ref":"tutorial.html#purpose"},{"type":"extras","doc":"It is assumed that you are a skilled Erlang programmer, familiar with concepts\nsuch as Erlang data types, processes, messages, and error handling.\n\nTo illustrate the interoperability principles, C programs running in a UNIX\nenvironment have been used. It is assumed that you have enough knowledge to\napply these principles to the relevant programming languages and platforms.\n\n> #### Note {: .info }\n>\n> For readability, the example code is kept as simple as possible. For example,\n> it does not include error handling, which might be vital in a real-life\n> system.","title":"Prerequisites - Introduction","ref":"tutorial.html#prerequisites"},{"type":"extras","doc":"\n# Overview","title":"Overview","ref":"overview.html"},{"type":"extras","doc":"Two interoperability mechanisms are built into the Erlang runtime system,\n_distributed Erlang_, _ports_, and _nifs_. A variation of ports is _linked-in drivers_.","title":"Built-In Mechanisms - Overview","ref":"overview.html#built-in-mechanisms"},{"type":"extras","doc":"An Erlang runtime system is made a distributed Erlang node by giving it a name.\nA distributed Erlang node can connect to, and monitor, other nodes. It can also\nspawn processes at other nodes. Message passing and error handling between\nprocesses at different nodes are transparent. A number of useful STDLIB modules\nare available in a distributed Erlang system. For example, `m:global`, which\nprovides global name registration. The distribution mechanism is implemented\nusing TCP/IP sockets.\n\n_When to use:_ Distributed Erlang is primarily used for Erlang-Erlang\ncommunication. It can also be used for communication between Erlang and C, if\nthe C program is implemented as a C node, see\n[C and Java Libraries](overview.md#c-nodes).\n\n_Where to read more:_ Distributed Erlang and some distributed programming\ntechniques are described in the Erlang book.\n\nFor more information, see\n[Distributed Programming](`e:system:conc_prog.md#distributed-programming`).\n\nRelevant manual pages are the following:\n\n- `m:erlang` manual page in ERTS (describes the BIFs)\n- `m:global` manual page in Kernel\n- `m:net_adm` manual page in Kernel\n- `m:pg` manual page in Kernel\n- `m:rpc` manual page in Kernel\n- `m:pool` manual page in STDLIB\n- `m:slave` manual page in STDLIB","title":"Distributed Erlang - Overview","ref":"overview.html#distributed-erlang"},{"type":"extras","doc":"Ports provide the basic mechanism for communication with the external world,\nfrom Erlang's point of view. The ports provide a byte-oriented interface to an\nexternal program. When a port is created, Erlang can communicate with it by\nsending and receiving [lists of bytes](`t:iolist/0`) or [binaries](`t:binary/0`) (not Erlang terms).\nThis means that the programmer might have to invent a suitable encoding and decoding scheme.\n\nThe implementation of the port mechanism depends on the platform. For UNIX,\npipes are used and the external program is assumed to read from standard input\nand write to standard output. The external program can be written in any\nprogramming language as long as it can handle the interprocess communication\nmechanism with which the port is implemented.\n\nThe external program resides in another OS process than the Erlang runtime\nsystem. In some cases this is not acceptable. Consider, for example, drivers\nwith very hard time requirements. It is therefore possible to write a program in\nC according to certain principles, and dynamically link it to the Erlang runtime\nsystem. This is called a _linked-in driver_.\n\n_When to use:_ Ports can be used for all kinds of interoperability situations\nwhere the Erlang program and the other program runs on the same machine.\nProgramming is fairly straight-forward.\n\nLinked-in drivers involves writing certain call-back functions in C. This\nrequires very good skills as the code is linked to the Erlang runtime system.\nIt is recommended to use [NIFs](#native-implemented-functions-nifs)\ninstead of linked-in drivers as they provide a richer feature set and can use\n[dirty schedulers for lengthy work](`e:erts:erl_nif.md#dirty_nifs`).\n\n> #### Warning {: .warning }\n>\n> A faulty linked-in driver causes the entire Erlang runtime system to leak\n> memory, hang, or crash.\n\n_Where to read more:_ Ports are described in section \"Miscellaneous Items\" of\nthe Erlang book. Linked-in drivers are described in Appendix E.\n\nThe BIF [`open_port/2`](`open_port/2`) is documented in the `m:erlang` manual\npage in ERTS.\n\nFor linked-in drivers, the programmer needs to read the `m:erl_ddll` manual page\nin Kernel.\n\n_Examples:_ Port example in [Ports](c_port.md).","title":"Ports and Linked-In Drivers - Overview","ref":"overview.html#ports-and-linked-in-drivers"},{"type":"extras","doc":"NIFs provide an alternative to a port using linked-in drivers to link C code into\nthe Erlang runtime system. NIFs make it possible to provide C implementation of\nnormal Erlang functions when interacting with the OS or some other external library.\n\n> #### Warning {: .warning }\n>\n> A faulty NIFs causes the entire Erlang runtime system to leak\n> memory, hang, crash, or leak sensitive information.\n\n_When to use:_ Since a faulty NIF can cause many different problems related to both\nstability and security it is recommended to use an external Port if possible. If the\noverhead is not acceptable then a NIF is a good solution for interacting with any\nnative code, be it in C, C++ or Rust.\n\n_Where to read more:_ NIFs are described in [API functions for an Erlang NIF library](`e:erts:erl_nif.md`).\n\n_Examples:_ Port example in [NIFs](nif.md).","title":"Native implemented functions (Nifs) - Overview","ref":"overview.html#native-implemented-functions-nifs"},{"type":"extras","doc":"","title":"C and Java Libraries - Overview","ref":"overview.html#c-and-java-libraries"},{"type":"extras","doc":"The program at the other side of a port is often a C program. To help the C\nprogrammer, the Erl_Interface library has been developed\n\nThe Erlang external term format is a representation of an Erlang term as a\nsequence of bytes, that is, a binary. Conversion between the two representations\nis done using the following BIFs:\n\n```text\nBinary = term_to_binary(Term)\nTerm = binary_to_term(Binary)\n```\n\nA port can be set to use binaries instead of lists of bytes. It is then not\nnecessary to invent any encoding/decoding scheme. Erl_Interface functions are\nused for unpacking the binary and convert it into a struct similar to an Erlang\nterm. Such a struct can be manipulated in different ways, be converted to the\nErlang external format, and sent to Erlang.\n\n_When to use:_ In C code, in conjunction with Erlang binaries.\n\n_Where to read more:_ See the Erlang Interface User's Guide, Command Reference,\nand Library Reference. In Erlang/OTP R5B, and earlier versions, the information\nis part of the Kernel application.\n\n_Examples:_ Erl_Interface example in [Erl_Interface](erl_interface.md).","title":"Erl_Interface - Overview","ref":"overview.html#erl_interface"},{"type":"extras","doc":"A C program that uses the Erl_Interface functions for setting up a connection\nto, and communicating with, a distributed Erlang node is called a _C node_, or a\n_hidden node_. The main advantage with a C node is that the communication from\nthe Erlang programmer's perspective is extremely easy, as the C program behaves\nas a distributed Erlang node.\n\n_When to use:_ C nodes can typically be used on device processors (as opposed to\ncontrol processors) where C is a better choice than Erlang due to memory\nlimitations or application characteristics, or both.\n\n_Where to read more:_ See the `ei_connect` part of the\n[Erl_Interface](erl_interface.md) documentation. The programmer also needs to be\nfamiliar with TCP/IP sockets, see Sockets in\n[Standard Protocols](overview.md#sockets) and Distributed Erlang in\n[Built-In Mechanisms](overview.md#distributed-erlang).\n\n_Example:_ C node example in [C Nodes](cnode.md).","title":"C Nodes - Overview","ref":"overview.html#c-nodes"},{"type":"extras","doc":"In Erlang/OTP R6B, a library similar to Erl_Interface for Java was added called\n_jinterface_. It provides a tool for Java programs to communicate with Erlang\nnodes.","title":"Jinterface - Overview","ref":"overview.html#jinterface"},{"type":"extras","doc":"Sometimes communication between an Erlang program and another program using a\nstandard protocol is desirable. Erlang/OTP currently supports TCP/IP and UDP\n_sockets_: as follows:\n\n- SNMP\n- HTTP\n- IIOP (CORBA)\n\nUsing one of the latter three requires good knowledge about the protocol and is\nnot covered by this tutorial. See the SNMP, Inets, and Orber applications,\nrespectively.","title":"Standard Protocols - Overview","ref":"overview.html#standard-protocols"},{"type":"extras","doc":"Simply put, connection-oriented socket communication (TCP/IP) consists of an\ninitiator socket (\"server\") started at a certain host with a certain port\nnumber. A connector socket (\"client\"), which is aware of the initiator host name\nand port number, can connect to it and data can be sent between them.\n\nConnection-less socket communication (UDP) consists of an initiator socket at a\ncertain host with a certain port number and a connector socket sending data to\nit.\n\nFor a detailed description of the socket concept, refer to a suitable book about\nnetwork programming. A suggestion is _UNIX Network Programming, Volume 1:\nNetworking APIs - Sockets and XTI_ by W. Richard Stevens, ISBN: 013490012X.\n\nIn Erlang/OTP, access to TCP/IP and UDP sockets is provided by the modules\n`gen_tcp` and `gen_udp` in Kernel. Both are easy to use and do not require\ndetailed knowledge about the socket concept.\n\n_When to use:_ For programs running on the same or on another machine than the\nErlang program.\n\n_Where to read more:_ See the `m:gen_tcp` and the `m:gen_udp` manual pages in\nKernel.","title":"Sockets - Overview","ref":"overview.html#sockets"},{"type":"extras","doc":"IC (Erlang IDL Compiler) is an interface generator that, given an IDL interface\nspecification, automatically generates stub code in Erlang, C, or Java. See the\nIC User's Guide and IC Reference Manual.\n\nFor details, see the [corba repository](https://github.com/erlang/corba).","title":"IC and CORBA - Overview","ref":"overview.html#ic-and-corba"},{"type":"extras","doc":"\n# Problem Example","title":"Problem Example","ref":"example.html"},{"type":"extras","doc":"A common interoperability situation is when you want to incorporate a piece of\ncode, solving a complex problem, in your Erlang program. Suppose for example,\nthat you have the following C functions that you would like to call from Erlang:\n\n```c\n/* complex.c */\n\nint foo(int x) {\n return x+1;\n}\n\nint bar(int y) {\n return y*2;\n}\n```\n\nThe functions are deliberately kept as simple as possible, for readability\nreasons.\n\nFrom an Erlang perspective, it is preferable to be able to call `foo` and `bar`\nwithout having to bother about that they are C functions:\n\n```erlang\n% Erlang code\n...\nRes = complex:foo(X),\n...\n```\n\nHere, the communication with C is hidden in the implementation of `complex.erl`.\nIn the following sections, it is shown how this module can be implemented using\nthe different interoperability mechanisms.","title":"Description - Problem Example","ref":"example.html#description"},{"type":"extras","doc":"\n# Ports\n\nThis section outlines an example of how to solve the example problem in the\n[previous section](example.md) by using a port.\n\nThe scenario is illustrated in the following figure:\n\n```mermaid\n---\ntitle: Port Communication\n---\nflowchart LR\n subgraph Legend\n direction LR\n\n os[OS Process]\n erl([Erlang Process])\n end\n\n subgraph ERTS\n direction LR\n\n port{Port} --> erlProc\n erlProc([Connected process]) --> port\n end\n\n port --> proc[External Program]\n proc --> port\n```","title":"Ports","ref":"c_port.html"},{"type":"extras","doc":"All communication between Erlang and C must be established by creating the port.\nThe Erlang process that creates a port is said to be _the connected process_ of\nthe port. All communication to and from the port must go through the connected\nprocess. If the connected process terminates, the port also terminates (and the\nexternal program, if it is written properly).\n\nThe port is created using the BIF [`open_port/2`](`open_port/2`) with\n`{spawn,ExtPrg}` as the first argument. The string `ExtPrg` is the name of the\nexternal program, including any command line arguments. The second argument is a\nlist of options, in this case only `{packet,2}`. This option says that a 2 byte\nlength indicator is to be used to simplify the communication between C and\nErlang. The Erlang port automatically adds the length indicator, but this must\nbe done explicitly in the external C program.\n\nThe process is also set to trap exits, which enables detection of failure of the\nexternal program:\n\n```erlang\n-module(complex1).\n-export([start/1, init/1]).\n\nstart(ExtPrg) ->\n spawn(?MODULE, init, [ExtPrg]).\n\ninit(ExtPrg) ->\n register(complex, self()),\n process_flag(trap_exit, true),\n Port = open_port({spawn, ExtPrg}, [{packet, 2}]),\n loop(Port).\n```\n\nNow `complex1:foo/1` and `complex1:bar/1` can be implemented. Both send a\nmessage to the `complex` process and receive the following replies:\n\n```erlang\nfoo(X) ->\n call_port({foo, X}).\nbar(Y) ->\n call_port({bar, Y}).\n\ncall_port(Msg) ->\n complex ! {call, self(), Msg},\n receive\n {complex, Result} ->\n Result\n end.\n```\n\nThe `complex` process does the following:\n\n- Encodes the message into a sequence of bytes.\n- Sends it to the port.\n- Waits for a reply.\n- Decodes the reply.\n- Sends it back to the caller:\n\n```erlang\nloop(Port) ->\n receive\n {call, Caller, Msg} ->\n Port ! {self(), {command, encode(Msg)}},\n receive\n {Port, {data, Data}} ->\n Caller ! {complex, decode(Data)}\n end,\n loop(Port)\n end.\n```\n\nAssuming that both the arguments and the results from the C functions are less\nthan 256, a simple encoding/decoding scheme is employed. In this scheme, `foo`\nis represented by byte 1, `bar` is represented by 2, and the argument/result is\nrepresented by a single byte as well:\n\n```erlang\nencode({foo, X}) -> [1, X];\nencode({bar, Y}) -> [2, Y].\n\ndecode([Int]) -> Int.\n```\n\nThe resulting Erlang program, including functionality for stopping the port and\ndetecting port failures, is as follows:\n\n```erlang\n-module(complex1).\n-export([start/1, stop/0, init/1]).\n-export([foo/1, bar/1]).\n\nstart(ExtPrg) ->\n spawn(?MODULE, init, [ExtPrg]).\nstop() ->\n complex ! stop.\n\nfoo(X) ->\n call_port({foo, X}).\nbar(Y) ->\n call_port({bar, Y}).\n\ncall_port(Msg) ->\n complex ! {call, self(), Msg},\n receive\n\t{complex, Result} ->\n\t Result\n end.\n\ninit(ExtPrg) ->\n register(complex, self()),\n process_flag(trap_exit, true),\n Port = open_port({spawn, ExtPrg}, [{packet, 2}]),\n loop(Port).\n\nloop(Port) ->\n receive\n\t{call, Caller, Msg} ->\n\t Port ! {self(), {command, encode(Msg)}},\n\t receive\n\t\t{Port, {data, Data}} ->\n\t\t Caller ! {complex, decode(Data)}\n\t end,\n\t loop(Port);\n\tstop ->\n\t Port ! {self(), close},\n\t receive\n\t\t{Port, closed} ->\n\t\t exit(normal)\n\t end;\n\t{'EXIT', Port, Reason} ->\n\t exit(port_terminated)\n end.\n\nencode({foo, X}) -> [1, X];\nencode({bar, Y}) -> [2, Y].\n\ndecode([Int]) -> Int.\n```","title":"Erlang Program - Ports","ref":"c_port.html#erlang-program"},{"type":"extras","doc":"On the C side, it is necessary to write functions for receiving and sending data\nwith 2 byte length indicators from/to Erlang. By default, the C program is to\nread from standard input (file descriptor 0) and write to standard output (file\ndescriptor 1). Examples of such functions, `read_cmd/1` and `write_cmd/2`,\nfollows:\n\n```c\n/* erl_comm.c */\n\n#include \n#include \n\ntypedef unsigned char byte;\n\nint read_exact(byte *buf, int len)\n{\n int i, got=0;\n\n do {\n if ((i = read(0, buf+got, len-got)) <= 0){\n return(i);\n }\n got += i;\n } while (got > 8) & 0xff;\n write_exact(&li, 1);\n\n li = len & 0xff;\n write_exact(&li, 1);\n\n return write_exact(buf, len);\n}\n```\n\nNotice that `stdin` and `stdout` are for buffered input/output and must _not_ be\nused for the communication with Erlang.\n\nIn the `main` function, the C program is to listen for a message from Erlang\nand, according to the selected encoding/decoding scheme, use the first byte to\ndetermine which function to call and the second byte as argument to the\nfunction. The result of calling the function is then to be sent back to Erlang:\n\n```c\n/* port.c */\n\ntypedef unsigned char byte;\n\nint main() {\n int fn, arg, res;\n byte buf[100];\n\n while (read_cmd(buf) > 0) {\n fn = buf[0];\n arg = buf[1];\n\n if (fn == 1) {\n res = foo(arg);\n } else if (fn == 2) {\n res = bar(arg);\n }\n\n buf[0] = res;\n write_cmd(buf, 1);\n }\n}\n```\n\nNotice that the C program is in a `while`\\-loop, checking for the return value\nof `read_cmd/1`. This is because the C program must detect when the port closes\nand terminates.","title":"C Program - Ports","ref":"c_port.html#c-program"},{"type":"extras","doc":"_Step 1._ Compile the C code:\n\n```text\n$ gcc -o extprg complex.c erl_comm.c port.c\n```\n\n_Step 2._ Start Erlang and compile the Erlang code:\n\n```erlang\n$ erl\nErlang/OTP 26 [erts-14.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]\n\nEshell V14.2 (press Ctrl+G to abort, type help(). for help)\n1> c(complex1).\n{ok,complex1}\n```\n\n_Step 3._ Run the example:\n\n```erlang\n2> complex1:start(\"./extprg\").\n<0.34.0>\n3> complex1:foo(3).\n4\n4> complex1:bar(5).\n10\n5> complex1:stop().\nstop\n```","title":"Running the Example - Ports","ref":"c_port.html#running-the-example"},{"type":"extras","doc":"\n# Erl_Interface\n\nThis section outlines an example of how to solve the example problem in\n[Problem Example](example.md) by using a port and Erl_Interface. It is necessary\nto read the port example in [Ports](c_port.md) before reading this section.","title":"Erl_Interface","ref":"erl_interface.html"},{"type":"extras","doc":"The following example shows an Erlang program communicating with a C program\nover a plain port with home made encoding:\n\n```erlang\n-module(complex1).\n-export([start/1, stop/0, init/1]).\n-export([foo/1, bar/1]).\n\nstart(ExtPrg) ->\n spawn(?MODULE, init, [ExtPrg]).\nstop() ->\n complex ! stop.\n\nfoo(X) ->\n call_port({foo, X}).\nbar(Y) ->\n call_port({bar, Y}).\n\ncall_port(Msg) ->\n complex ! {call, self(), Msg},\n receive\n\t{complex, Result} ->\n\t Result\n end.\n\ninit(ExtPrg) ->\n register(complex, self()),\n process_flag(trap_exit, true),\n Port = open_port({spawn, ExtPrg}, [{packet, 2}]),\n loop(Port).\n\nloop(Port) ->\n receive\n\t{call, Caller, Msg} ->\n\t Port ! {self(), {command, encode(Msg)}},\n\t receive\n\t\t{Port, {data, Data}} ->\n\t\t Caller ! {complex, decode(Data)}\n\t end,\n\t loop(Port);\n\tstop ->\n\t Port ! {self(), close},\n\t receive\n\t\t{Port, closed} ->\n\t\t exit(normal)\n\t end;\n\t{'EXIT', Port, Reason} ->\n\t exit(port_terminated)\n end.\n\nencode({foo, X}) -> [1, X];\nencode({bar, Y}) -> [2, Y].\n\ndecode([Int]) -> Int.\n```\n\nThere are two differences when using Erl_Interface on the C side compared to the\nexample in [Ports](c_port.md), using only the plain port:\n\n- As Erl_Interface operates on the Erlang external term format, the port must be\n set to use binaries.\n- Instead of inventing an encoding/decoding scheme, the\n [`term_to_binary/1`](`term_to_binary/1`) and\n [`binary_to_term/1`](`binary_to_term/1`) BIFs are to be used.\n\nThat is:\n\n```erlang\nopen_port({spawn, ExtPrg}, [{packet, 2}])\n```\n\nis replaced with:\n\n```erlang\nopen_port({spawn, ExtPrg}, [{packet, 2}, binary])\n```\n\nAnd:\n\n```erlang\nPort ! {self(), {command, encode(Msg)}},\nreceive\n {Port, {data, Data}} ->\n Caller ! {complex, decode(Data)}\nend\n```\n\nis replaced with:\n\n```erlang\nPort ! {self(), {command, term_to_binary(Msg)}},\nreceive\n {Port, {data, Data}} ->\n Caller ! {complex, binary_to_term(Data)}\nend\n```\n\nThe resulting Erlang program is as follows:\n\n```erlang\n-module(complex2).\n-export([start/1, stop/0, init/1]).\n-export([foo/1, bar/1]).\n\nstart(ExtPrg) ->\n spawn(?MODULE, init, [ExtPrg]).\nstop() ->\n complex ! stop.\n\nfoo(X) ->\n call_port({foo, X}).\nbar(Y) ->\n call_port({bar, Y}).\n\ncall_port(Msg) ->\n complex ! {call, self(), Msg},\n receive\n\t{complex, Result} ->\n\t Result\n end.\n\ninit(ExtPrg) ->\n register(complex, self()),\n process_flag(trap_exit, true),\n Port = open_port({spawn, ExtPrg}, [{packet, 2}, binary]),\n loop(Port).\n\nloop(Port) ->\n receive\n\t{call, Caller, Msg} ->\n\t Port ! {self(), {command, term_to_binary(Msg)}},\n\t receive\n\t\t{Port, {data, Data}} ->\n\t\t Caller ! {complex, binary_to_term(Data)}\n\t end,\n\t loop(Port);\n\tstop ->\n\t Port ! {self(), close},\n\t receive\n\t\t{Port, closed} ->\n\t\t exit(normal)\n\t end;\n\t{'EXIT', Port, Reason} ->\n\t exit(port_terminated)\n end.\n```\n\nNotice that calling `complex2:foo/1` and `complex2:bar/1` results in the tuple\n`{foo,X}` or `{bar,Y}` being sent to the `complex` process, which codes them as\nbinaries and sends them to the port. This means that the C program must be able\nto handle these two tuples.","title":"Erlang Program - Erl_Interface","ref":"erl_interface.html#erlang-program"},{"type":"extras","doc":"The following example shows a C program communicating with an Erlang program\nover a plain port with the Erlang external term format encoding:\n\n```c\n/* ei.c */\n\n#include \"ei.h\"\n#include \n#include \n#include \n\ntypedef unsigned char byte;\n\nint read_cmd(byte *buf);\nint write_cmd(byte *buf, int len);\nint foo(int x);\nint bar(int y);\n\nstatic void fail(int place) {\n fprintf(stderr, \"Something went wrong %d\\n\", place);\n exit(1);\n}\n\nint main() {\n byte buf[100];\n int index = 0;\n int version = 0;\n int arity = 0;\n char atom[128];\n long in = 0;\n int res = 0;\n ei_x_buff res_buf;\n ei_init();\n while (read_cmd(buf) > 0) {\n if (ei_decode_version(buf, &index, &version) != 0)\n fail(1);\n if (ei_decode_tuple_header(buf, &index, &arity) != 0)\n fail(2);\n if (arity != 2)\n fail(3);\n if (ei_decode_atom(buf, &index, atom) != 0)\n fail(4);\n if (ei_decode_long(buf, &index, &in) != 0)\n fail(5);\n if (strncmp(atom, \"foo\", 3) == 0) {\n res = foo((int)in);\n } else if (strncmp(atom, \"bar\", 3) == 0) {\n res = bar((int)in);\n }\n if (ei_x_new_with_version(&res_buf) != 0)\n fail(6);\n if (ei_x_encode_long(&res_buf, res) != 0)\n fail(7);\n write_cmd(res_buf.buff, res_buf.index);\n\n if (ei_x_free(&res_buf) != 0)\n fail(8);\n index = 0;\n }\n}\n```\n\nThe following functions, `read_cmd()` and `write_cmd()`, from the `erl_comm.c`\nexample in [Ports](c_port.md) can still be used for reading from and writing to\nthe port:\n\n```c\n/* erl_comm.c */\n\n#include \n#include \n\ntypedef unsigned char byte;\n\nint read_exact(byte *buf, int len)\n{\n int i, got=0;\n\n do {\n if ((i = read(0, buf+got, len-got)) <= 0){\n return(i);\n }\n got += i;\n } while (got > 8) & 0xff;\n write_exact(&li, 1);\n\n li = len & 0xff;\n write_exact(&li, 1);\n\n return write_exact(buf, len);\n}\n```","title":"C Program - Erl_Interface","ref":"erl_interface.html#c-program"},{"type":"extras","doc":"_Step 1._ Compile the C code. This provides the paths to the include file\n`ei.h`, and also to the library `ei`:\n\n```text\n$ gcc -o extprg -I/usr/local/otp/lib/erl_interface-3.9.2/include \\\n -L/usr/local/otp/lib/erl_interface-3.9.2/lib \\\n complex.c erl_comm.c ei.c -lei -lpthread\n```\n\nIn Erlang/OTP R5B and later versions of OTP, the `include` and `lib` directories\nare situated under `$OTPROOT/lib/erl_interface-VSN`, where `$OTPROOT` is the\nroot directory of the OTP installation (`/usr/local/otp` in the recent example)\nand `VSN` is the version of the Erl_interface application (3.2.1 in the recent\nexample).\n\nIn R4B and earlier versions of OTP, `include` and `lib` are situated under\n`$OTPROOT/usr`.\n\n_Step 2._ Start Erlang and compile the Erlang code:\n\n```erlang\n$ erl\nErlang/OTP 26 [erts-14.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]\n\nEshell V14.2 (press Ctrl+G to abort, type help(). for help)\n1> c(complex2).\n{ok,complex2}\n```\n\n_Step 3._ Run the example:\n\n```erlang\n2> complex2:start(\"./extprg\").\n<0.34.0>\n3> complex2:foo(3).\n4\n4> complex2:bar(5).\n10\n5> complex2:bar(352).\n704\n6> complex2:stop().\nstop\n```","title":"Running the Example - Erl_Interface","ref":"erl_interface.html#running-the-example"},{"type":"extras","doc":"\n# Port Drivers\n\nThis section outlines an example of how to solve the example problem in\n[Problem Example](example.md) by using a linked-in port driver.\n\nA port driver is a linked-in driver that is accessible as a port from an Erlang\nprogram. It is a shared library (SO in UNIX, DLL in Windows), with special entry\npoints. The Erlang runtime system calls these entry points when the driver is\nstarted and when data is sent to the port. The port driver can also send data to\nErlang.\n\nAs a port driver is dynamically linked into the emulator process, this is the\nfastest way of calling C-code from Erlang. Calling functions in the port driver\nrequires no context switches. But it is also the least safe way, because a crash\nin the port driver brings the emulator down too.\n\nThe scenario is illustrated in the following figure:\n\n```mermaid\n---\ntitle: Port Driver Communication\n---\nflowchart\n subgraph Legend\n direction LR\n\n os[OS Process]\n erl([Erlang Process])\n end\n\n subgraph emulator\n direction LR\n\n port{Port} --> erlProc\n erlProc([Connected process]) --> port\n\n port --> proc[Port Driver Shared Library]\n proc --> port\n end\n```","title":"Port Drivers","ref":"c_portdriver.html"},{"type":"extras","doc":"Like a port program, the port communicates with an Erlang process. All\ncommunication goes through one Erlang process that is the _connected process_ of\nthe port driver. Terminating this process closes the port driver.\n\nBefore the port is created, the driver must be loaded. This is done with the\nfunction `erl_ddll:load_driver/2`, with the name of the shared library as\nargument.\n\nThe port is then created using the BIF [`open_port/2`](`open_port/2`), with the\ntuple `{spawn, DriverName}` as the first argument. The string `SharedLib` is the\nname of the port driver. The second argument is a list of options, none in this\ncase:\n\n```erlang\n-module(complex5).\n-export([start/1, init/1]).\n\nstart(SharedLib) ->\n case erl_ddll:load_driver(\".\", SharedLib) of\n ok -> ok;\n {error, already_loaded} -> ok;\n _ -> exit({error, could_not_load_driver})\n end,\n spawn(?MODULE, init, [SharedLib]).\n\ninit(SharedLib) ->\n register(complex, self()),\n Port = open_port({spawn, SharedLib}, []),\n loop(Port).\n```\n\nNow `complex5:foo/1` and `complex5:bar/1` can be implemented. Both send a\nmessage to the `complex` process and receive the following reply:\n\n```erlang\nfoo(X) ->\n call_port({foo, X}).\nbar(Y) ->\n call_port({bar, Y}).\n\ncall_port(Msg) ->\n complex ! {call, self(), Msg},\n receive\n {complex, Result} ->\n Result\n end.\n```\n\nThe `complex` process performs the following:\n\n- Encodes the message into a sequence of bytes.\n- Sends it to the port.\n- Waits for a reply.\n- Decodes the reply.\n- Sends it back to the caller:\n\n```erlang\nloop(Port) ->\n receive\n {call, Caller, Msg} ->\n Port ! {self(), {command, encode(Msg)}},\n receive\n {Port, {data, Data}} ->\n Caller ! {complex, decode(Data)}\n end,\n loop(Port)\n end.\n```\n\nAssuming that both the arguments and the results from the C functions are less\nthan 256, a simple encoding/decoding scheme is employed. In this scheme, `foo`\nis represented by byte 1, `bar` is represented by 2, and the argument/result is\nrepresented by a single byte as well:\n\n```erlang\nencode({foo, X}) -> [1, X];\nencode({bar, Y}) -> [2, Y].\n\ndecode([Int]) -> Int.\n```\n\nThe resulting Erlang program, including functions for stopping the port and\ndetecting port failures, is as follows:\n\n```erlang\n\n-module(complex5).\n-export([start/1, stop/0, init/1]).\n-export([foo/1, bar/1]).\n\nstart(SharedLib) ->\n case erl_ddll:load_driver(\".\", SharedLib) of\n\tok -> ok;\n\t{error, already_loaded} -> ok;\n\t_ -> exit({error, could_not_load_driver})\n end,\n spawn(?MODULE, init, [SharedLib]).\n\ninit(SharedLib) ->\n register(complex, self()),\n Port = open_port({spawn, SharedLib}, []),\n loop(Port).\n\nstop() ->\n complex ! stop.\n\nfoo(X) ->\n call_port({foo, X}).\nbar(Y) ->\n call_port({bar, Y}).\n\ncall_port(Msg) ->\n complex ! {call, self(), Msg},\n receive\n\t{complex, Result} ->\n\t Result\n end.\n\nloop(Port) ->\n receive\n\t{call, Caller, Msg} ->\n\t Port ! {self(), {command, encode(Msg)}},\n\t receive\n\t\t{Port, {data, Data}} ->\n\t\t Caller ! {complex, decode(Data)}\n\t end,\n\t loop(Port);\n\tstop ->\n\t Port ! {self(), close},\n\t receive\n\t\t{Port, closed} ->\n\t\t exit(normal)\n\t end;\n\t{'EXIT', Port, Reason} ->\n\t io:format(\"~p ~n\", [Reason]),\n\t exit(port_terminated)\n end.\n\nencode({foo, X}) -> [1, X];\nencode({bar, Y}) -> [2, Y].\n\ndecode([Int]) -> Int.\n```","title":"Erlang Program - Port Drivers","ref":"c_portdriver.html#erlang-program"},{"type":"extras","doc":"The C driver is a module that is compiled and linked into a shared library. It\nuses a driver structure and includes the header file `erl_driver.h`.\n\nThe driver structure is filled with the driver name and function pointers. It is\nreturned from the special entry point, declared with the macro\n`DRIVER_INIT( )`.\n\nThe functions for receiving and sending data are combined into a function,\npointed out by the driver structure. The data sent into the port is given as\narguments, and the replied data is sent with the C-function `driver_output`.\n\nAs the driver is a shared module, not a program, no main function is present.\nAll function pointers are not used in this example, and the corresponding fields\nin the `driver_entry` structure are set to NULL.\n\nAll functions in the driver takes a handle (returned from `start`) that is just\npassed along by the Erlang process. This must in some way refer to the port\ndriver instance.\n\nThe `example_drv_start`, is the only function that is called with a handle to\nthe port instance, so this must be saved. It is customary to use an allocated\ndriver-defined structure for this one, and to pass a pointer back as a\nreference.\n\nIt is not a good idea to use a global variable as the port driver can be spawned\nby multiple Erlang processes. This driver-structure is to be instantiated\nmultiple times:\n\n```c\n/* port_driver.c */\n\n#include \n#include \"erl_driver.h\"\n\ntypedef struct {\n ErlDrvPort port;\n} example_data;\n\nstatic ErlDrvData example_drv_start(ErlDrvPort port, char *buff)\n{\n example_data* d = (example_data*)driver_alloc(sizeof(example_data));\n d->port = port;\n return (ErlDrvData)d;\n}\n\nstatic void example_drv_stop(ErlDrvData handle)\n{\n driver_free((char*)handle);\n}\n\nstatic void example_drv_output(ErlDrvData handle, char *buff,\n\t\t\t ErlDrvSizeT bufflen)\n{\n example_data* d = (example_data*)handle;\n char fn = buff[0], arg = buff[1], res;\n if (fn == 1) {\n res = foo(arg);\n } else if (fn == 2) {\n res = bar(arg);\n }\n driver_output(d->port, &res, 1);\n}\n\nErlDrvEntry example_driver_entry = {\n NULL,\t\t\t/* F_PTR init, called when driver is loaded */\n example_drv_start,\t\t/* L_PTR start, called when port is opened */\n example_drv_stop,\t\t/* F_PTR stop, called when port is closed */\n example_drv_output,\t\t/* F_PTR output, called when erlang has sent */\n NULL,\t\t\t/* F_PTR ready_input, called when input descriptor ready */\n NULL,\t\t\t/* F_PTR ready_output, called when output descriptor ready */\n \"example_drv\",\t\t/* char *driver_name, the argument to open_port */\n NULL,\t\t\t/* F_PTR finish, called when unloaded */\n NULL, /* void *handle, Reserved by VM */\n NULL,\t\t\t/* F_PTR control, port_command callback */\n NULL,\t\t\t/* F_PTR timeout, reserved */\n NULL,\t\t\t/* F_PTR outputv, reserved */\n NULL, /* F_PTR ready_async, only for async drivers */\n NULL, /* F_PTR flush, called when port is about\n\t\t\t\t to be closed, but there is data in driver\n\t\t\t\t queue */\n NULL, /* F_PTR call, much like control, sync call\n\t\t\t\t to driver */\n NULL, /* unused */\n ERL_DRV_EXTENDED_MARKER, /* int extended marker, Should always be\n\t\t\t\t set to indicate driver versioning */\n ERL_DRV_EXTENDED_MAJOR_VERSION, /* int major_version, should always be\n\t\t\t\t set to this value */\n ERL_DRV_EXTENDED_MINOR_VERSION, /* int minor_version, should always be\n\t\t\t\t set to this value */\n 0, /* int driver_flags, see documentation */\n NULL, /* void *handle2, reserved for VM use */\n NULL, /* F_PTR process_exit, called when a\n\t\t\t\t monitored process dies */\n NULL /* F_PTR stop_select, called to close an\n\t\t\t\t event object */\n};\n\nDRIVER_INIT(example_drv) /* must match name in driver_entry */\n{\n return &example_driver_entry;\n}\n```","title":"C Driver - Port Drivers","ref":"c_portdriver.html#c-driver"},{"type":"extras","doc":"_Step 1._ Compile the C code:\n\n```text\nunix> gcc -o example_drv.so -fpic -shared complex.c port_driver.c\nwindows> cl -LD -MD -Fe example_drv.dll complex.c port_driver.c\n```\n\n_Step 2._ Start Erlang and compile the Erlang code:\n\n```erlang\n> erl\nErlang/OTP 26 [erts-14.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]\n\nEshell V14.2 (press Ctrl+G to abort, type help(). for help)\n1> c(complex5).\n{ok,complex5}\n```\n\n_Step 3._ Run the example:\n\n```erlang\n2> complex5:start(\"example_drv\").\n<0.34.0>\n3> complex5:foo(3).\n4\n4> complex5:bar(5).\n10\n5> complex5:stop().\nstop\n```","title":"Running the Example - Port Drivers","ref":"c_portdriver.html#running-the-example"},{"type":"extras","doc":"\n# C Nodes\n\nThe reader is referred to\n[the erl_interface users guide](`e:erl_interface:ei_users_guide.md`) for\ninformation about how to create C nodes.","title":"C Nodes","ref":"cnode.html"},{"type":"extras","doc":"\n# NIFs\n\nThis section outlines an example of how to solve the example problem in\n[Problem Example](example.md) by using Native Implemented Functions (NIFs).\n\nNIFs are a simpler and more efficient way of calling C-code than using port\ndrivers. NIFs are most suitable for synchronous functions, such as `foo` and\n`bar` in the example, that do some relatively short calculations without side\neffects and return the result.\n\nA NIF is a function that is implemented in C instead of Erlang. NIFs appear as\nany other functions to the callers. They belong to a module and are called like\nany other Erlang functions. The NIFs of a module are compiled and linked into a\ndynamic loadable, shared library (SO in UNIX, DLL in Windows). The NIF library\nmust be loaded in runtime by the Erlang code of the module.\n\nAs a NIF library is dynamically linked into the emulator process, this is the\nfastest way of calling C-code from Erlang (alongside port drivers). Calling NIFs\nrequires no context switches. But it is also the least safe, because a crash in\na NIF brings the emulator down too.","title":"NIFs","ref":"nif.html"},{"type":"extras","doc":"Even if all functions of a module are NIFs, an Erlang module is still needed for\ntwo reasons:\n\n- The NIF library must be explicitly loaded by Erlang code in the same module.\n- All NIFs of a module must have an Erlang implementation as well.\n\nNormally these are minimal stub implementations that throw an exception. But\nthey can also be used as fallback implementations for functions that do not have\nnative implementations on some architectures.\n\nNIF libraries are loaded by calling `erlang:load_nif/2`, with the name of the\nshared library as argument. The second argument can be any term that will be\npassed on to the library and used for initialization:\n\n```erlang\n-module(complex6).\n-export([foo/1, bar/1]).\n-nifs([foo/1, bar/1]).\n-on_load(init/0).\n\ninit() ->\n ok = erlang:load_nif(\"./complex6_nif\", 0).\n\nfoo(_X) ->\n erlang:nif_error(nif_library_not_loaded).\nbar(_Y) ->\n erlang:nif_error(nif_library_not_loaded).\n```\n\nHere, the directive `on_load` is used to get function `init` to be automatically\ncalled when the module is loaded. If `init` returns anything other than `ok`,\nsuch when the loading of the NIF library fails in this example, the module is\nunloaded and calls to functions within it, fail.\n\nLoading the NIF library overrides the stub implementations and cause calls to\n`foo` and `bar` to be dispatched to the NIF implementations instead.","title":"Erlang Program - NIFs","ref":"nif.html#erlang-program"},{"type":"extras","doc":"The NIFs of the module are compiled and linked into a shared library. Each NIF\nis implemented as a normal C function. The macro `ERL_NIF_INIT` together with an\narray of structures defines the names, arity, and function pointers of all the\nNIFs in the module. The header file `erl_nif.h` must be included. As the library\nis a shared module, not a program, no main function is to be present.\n\nThe function arguments passed to a NIF appears in an array `argv`, with `argc`\nas the length of the array, and thus the arity of the function. The Nth argument\nof the function can be accessed as `argv[N-1]`. NIFs also take an environment\nargument that serves as an opaque handle that is needed to be passed on to most\nAPI functions. The environment contains information about the calling Erlang\nprocess:\n\n```c\n#include \n\nextern int foo(int x);\nextern int bar(int y);\n\nstatic ERL_NIF_TERM foo_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])\n{\n int x, ret;\n if (!enif_get_int(env, argv[0], &x)) {\n\treturn enif_make_badarg(env);\n }\n ret = foo(x);\n return enif_make_int(env, ret);\n}\n\nstatic ERL_NIF_TERM bar_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])\n{\n int y, ret;\n if (!enif_get_int(env, argv[0], &y)) {\n\treturn enif_make_badarg(env);\n }\n ret = bar(y);\n return enif_make_int(env, ret);\n}\n\nstatic ErlNifFunc nif_funcs[] = {\n {\"foo\", 1, foo_nif},\n {\"bar\", 1, bar_nif}\n};\n\nERL_NIF_INIT(complex6, nif_funcs, NULL, NULL, NULL, NULL)\n```\n\nHere, `ERL_NIF_INIT` has the following arguments:\n\n- The first argument must be the name of the Erlang module as a C-identifier. It\n will be stringified by the macro.\n- The second argument is the array of `ErlNifFunc` structures containing name,\n arity, and function pointer of each NIF.\n- The remaining arguments are pointers to callback functions that can be used to\n initialize the library. They are not used in this simple example, hence they\n are all set to `NULL`.\n\nFunction arguments and return values are represented as values of type\n`ERL_NIF_TERM`. Here, functions like `enif_get_int` and `enif_make_int` are used\nto convert between Erlang term and C-type. If the function argument `argv[0]` is\nnot an integer, `enif_get_int` returns false, in which case it returns by\nthrowing a `badarg`\\-exception with `enif_make_badarg`.","title":"NIF Library Code - NIFs","ref":"nif.html#nif-library-code"},{"type":"extras","doc":"_Step 1._ Compile the C code:\n\n```text\nunix> gcc -o complex6_nif.so -fpic -shared complex.c complex6_nif.c\nwindows> cl -LD -MD -Fe complex6_nif.dll complex.c complex6_nif.c\n```\n\n_Step 2:_ Start Erlang and compile the Erlang code:\n\n```erlang\n> erl\nErlang R13B04 (erts-5.7.5) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]\n\nEshell V5.7.5 (abort with ^G)\n1> c(complex6).\n{ok,complex6}\n```\n\n_Step 3:_ Run the example:\n\n```erlang\n3> complex6:foo(3).\n4\n4> complex6:bar(5).\n10\n5> complex6:foo(\"not an integer\").\n** exception error: bad argument\n in function complex6:foo/1\n called as comlpex6:foo(\"not an integer\")\n```","title":"Running the Example - NIFs","ref":"nif.html#running-the-example"},{"type":"extras","doc":"\n# Debugging NIFs and Port Drivers","title":"Debugging NIFs and Port Drivers","ref":"debugging.html"},{"type":"extras","doc":"NIFs and port driver code run inside the Erlang VM OS process (the \"Beam\"). To\nmaximize performance the code is called directly by the same threads executing\nErlang beam code and has full access to all the memory of the OS process. A\nbuggy NIF/driver can thus make severe damage by corrupting memory.\n\nIn a best case scenario such memory corruption is detected immediately causing\nthe Beam to crash generating a core dump file which can be analyzed to find the\nbug. However, it is very common for memory corruption bugs to not be immediately\ndetected when the faulty write happens, but instead much later, for example when\nthe calling Erlang process is garbage collected. When that happens it can be\nvery hard to find the root cause of the memory corruption by analysing the core\ndump. All traces that could have indicated which specific buggy NIF/driver that\ncaused the corruption may be long gone.\n\nAnother kind of bugs that are hard to find are _memory leaks_. They may go\nunnoticed and not cause problem until a deployed system has been running for a\nlong time.\n\nThe following sections describe tools that make it easier to both detect and\nfind the root cause of bugs like this. These tools are actively used during\ndevelopment, testing and troubleshooting of the Erlang runtime system itself.\n\n- [Debug emulator](debugging.md#debug)\n- [Address Sanitizer](debugging.md#asan)\n- [Valgrind](debugging.md#valgrind)\n- [rr - Record and Replay](debugging.md#rr)\n\n[](){: #debug }","title":"With great power comes great responsibilty - Debugging NIFs and Port Drivers","ref":"debugging.html#with-great-power-comes-great-responsibilty"},{"type":"extras","doc":"One way to make debugging easier is to run an emulator built with target\n`debug`. It will\n\n- _Increase probability of detecting bugs earlier_. It contains a lot more\n runtime checks to ensure correct use of internal interfaces and data\n structures.\n- _Generate a core dump that is easier to analyze_. Compiler optimizations are\n turned off, which stops the compiler from \"optimizing away\" variables, thus\n making it easier/possible to inspect their state.\n- _Detect lock order violations_. A runtime lock checker will verify that the\n locks in the [`erl_nif`](`e:erts:erl_nif.md`) and\n [`erl_driver`](`e:erts:erl_driver.md`) APIs are seized in a consistent order\n that cannot result in deadlock bugs.\n\nIn fact, we recommend to use the debug emulator as default during development of\nNIFs and drivers, regardless if you are troubleshooting bugs or not. Some subtle\nbugs may not be detected by the normal emulator and just happen to work anyway\nby chance. However, another version of the emulator, or even different\ncircumstances within the same emulator, may cause the bug to later provoke all\nkinds of problems.\n\nThe main disadvantage of the `debug` emulator is its reduced performance. The\nextra runtime checks and lack of compiler optimizations may result in a slowdown\nwith a factor of two or more depending on load. The memory footprint should be\nabout the same.\n\nIf the `debug` emulator is part of the Erlang/OTP installation, it can be\nstarted with the [`-emu_type`](`e:erts:erl_cmd.md#emu_type`) option.\n\n```text\n> erl -emu_type debug\nErlang/OTP 25 [erts-13.0.2] ... [type-assertions] [debug-compiled] [lock-checking]\n\nEshell V13.0.2 (abort with ^G)\n1>\n```\n\nIf the `debug` emulator is not part of the installation, you need to\n[build it from the Erlang/OTP source code](`e:system:install.md#advanced-configuration-and-build-of-erlang-otp_building_how-to-build-a-debug-enabled-erlang-runtime-system`).\nAfter building from source either make an Erlang/OTP installation or you can run\nthe debug emulator directly in the source tree with the `cerl` script:\n\n```text\n> $ERL_TOP/bin/cerl -debug\nErlang/OTP 25 [erts-13.0.2] ... [type-assertions] [debug-compiled] [lock-checking]\n\nEshell V13.0.2 (abort with ^G)\n1>\n```\n\nThe `cerl` script can also be used as a convenient way to start the debugger\n`gdb` for core dump analysis:\n\n```text\n> $ERL_TOP/bin/cerl -debug -core core.12345\nor\n> $ERL_TOP/bin/cerl -debug -rcore core.12345\n```\n\nThe first variant starts Emacs and runs `gdb` within, while the other `-rcore`\nruns `gdb` directly in the terminal. Apart from starting `gdb` with the correct\n`beam.debug.smp` executable file it will also read the file\n`$ERL_TOP/erts/etc/unix/etp-commands` which contains a lot of `gdb` command for\ninspecting a beam core dump. For example, the command `etp` that will print the\ncontent of an Erlang term (`Eterm`) in plain Erlang syntax.\n\n[](){: #asan }","title":"Debug emulator - Debugging NIFs and Port Drivers","ref":"debugging.html#debug-emulator"},{"type":"extras","doc":"[AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html) (asan) is\nan open source programming tool that detects memory corruption bugs such as\nbuffer overflows, use-after-free and memory leaks. AddressSanitizer is based on\ncompiler instrumentation and is supported by both gcc and clang.\n\nSimilar to the `debug` emulator, the `asan` emulator runs slower than normal,\nabout 2-3 times slower. However, it also has a larger memory footprint, about 3\ntimes more memory than normal.\n\nTo get full effect you should compile both your own NIF/driver code as well as\nthe Erlang emulator with AddressSanitizer instrumentation. Compile your own code\nby passing option `-fsanitize=address` to gcc or clang. Other recommended\noptions that will improve the fault identification are `-fno-common` and\n`-fno-omit-frame-pointer`.\n\nBuild and run the emulator with AddressSanitizer support by using the same\nprocedure as for the debug emulator, except use the `asan` build target instead\nof `debug`.\n\n- **Run in source tree** - If you run the `asan` emulator directly in the source\n tree with the `cerl` script you only need to set environment variable\n `ASAN_LOG_DIR` to the directory where the error log files will be generated.\n\n ```text\n > export ASAN_LOG_DIR=/my/asan/log/dir\n > $ERL_TOP/bin/cerl -asan\n Erlang/OTP 25 [erts-13.0.2] ... [address-sanitizer]\n\n Eshell V13.0.2 (abort with ^G)\n 1>\n ```\n\n You may however also want to set `ASAN_OPTIONS=\"halt_on_error=true\"` if you\n want the emulator to crash when an error is detected.\n\n- **Run installed Erlang/OTP** - If you run the `asan` emulator in an installed\n Erlang/OTP with `erl -emu_type asan` you need to set the path to the error log\n _file_ with\n\n ```text\n > export ASAN_OPTIONS=\"log_path=/my/asan/log/file\"\n ```\n\n To avoid false positive memory leak reports from the emulator itself set\n `LSAN_OPTIONS` (LSAN=LeakSanitizer):\n\n ```text\n > export LSAN_OPTIONS=\"suppressions=$ERL_TOP/erts/emulator/asan/suppress\"\n ```\n\n The `suppress` file is currently not installed but can be copied manually from\n the source tree to wherever you want it.\n\nMemory corruption errors are reported by AddressSanitizer when they happen, but\nmemory leaks are only checked and reported by default then the emulator\nterminates.","title":"Address Sanitizer - Debugging NIFs and Port Drivers","ref":"debugging.html#address-sanitizer"},{"type":"extras","doc":"An even more heavy weight debugging tool is [Valgrind](https://valgrind.org). It\ncan also find memory corruption bugs and memory leaks similar to `asan`.\nValgrind is not as good at buffer overflow bugs, but it will find use of\nundefined data, which is a type of error that `asan` cannot detect.\n\nValgrind is much slower than `asan` and it is incapable at exploiting CPU\nmulticore processing. We therefore recommend `asan` as the first choice before\ntrying valgrind.\n\nValgrind runs as a virtual machine itself, emulating execution of hardware\nmachine instructions. This means you can run almost any program unchanged on\nvalgrind. However, we have found that the beam executable benefits from being\ncompiled with special adaptions for running on valgrind.\n\nBuild the emulator with `valgrind` target the same as is done for `debug` and\n`asan`. Note that `valgrind` needs to be installed on the machine before the\nbuild starts.\n\nRun the `valgrind` emulator directly in the source tree with the `cerl` script.\nSet environment variable `VALGRIND_LOG_DIR` to the directory where the error log\nfiles will be generated.\n\n```text\n> export VALGRIND_LOG_DIR=/my/valgrind/log/dir\n> $ERL_TOP/bin/cerl -valgrind\nErlang/OTP 25 [erts-13.0.2] ... [valgrind-compiled]\n\nEshell V13.0.2 (abort with ^G)\n1>\n```\n\n[](){: #rr }","title":"Valgrind - Debugging NIFs and Port Drivers","ref":"debugging.html#valgrind"},{"type":"extras","doc":"Last but not least, the fantastic interactive debugging tool\n[rr](https://rr-project.org/), developed by Mozilla as open source. `rr` stands\nfor Record and Replay. While a core dump represents only a static snapshot of\nthe OS process when it crashed, with `rr` you instead record the entire session,\nfrom start of the OS process to the end (the crash). You can then replay that\nsession from within `gdb`. Single step, set breakpoints and watchpoints, and\neven _execute backwards_.\n\nConsidering its powerful utility, `rr` is remarkably light weight. It runs on\nLinux with any reasonably modern x86 CPU. You may get a two times slowdown when\nexecuting in recording mode. The big weakness is its inability to exploite CPU\nmulticore processing. If the bug is a race condition between concurrently\nrunning threads, it may be hard to reproduce with `rr`.\n\n`rr` does not require any special instrumented compilation. However, if\npossible, run it together with the `debug` emulator, as that will result in a\nmuch nicer debugging experience. You run `rr` in the source tree using the\n`cerl` script.\n\nHere is an example of a typical session. First we catch the crash in an rr\nrecording session:\n\n```text\n> $ERL_TOP/bin/cerl -debug -rr\nrr: Saving execution to trace directory /home/foobar/.local/share/rr/beam.debug.smp-1.\nErlang/OTP 25 [erts-13.0.2]\n\nEshell V13.0.2 (abort with ^G)\n1> mymod:buggy_nif().\nSegmentation fault\n```\n\nNow we can replay that session with `rr replay`:\n\n```text\n> rr replay\nGNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2\n:\n(rr) continue\n:\nThread 2 received signal SIGSEGV, Segmentation fault.\n(rr) backtrace\n```\n\nYou get the call stack at the moment of the crash. Bad luck, it is somewhere\ndeep down in the garbage collection of the beam. But you manage to figure out\nthat variable `hp` points to a broken Erlang term.\n\nSet a watch point on that memory position and resume execution _backwards_. The\ndebugger will then stop at the exact position when that memory position `*hp`\nwas written.\n\n```text\n(rr) watch -l *hp\nHardware watchpoint 1: -location *hp\n(rr) reverse-continue\nContinuing.\n\nThread 2 received signal SIGSEGV, Segmentation fault.\n```\n\nThis is a quirk to be aware about. We started by executing forward until it\ncrashed with SIGSEGV. We are now executing backwards from that point, so we are\nhitting the same SIGSEGV again but from the other direction. Just continue\nbackwards once more to move past it.\n\n```text\n(rr) reverse-continue\nContinuing.\n\nThread 2 hit Hardware watchpoint 1: -location *hp\n\nOld value = 42\nNew value = 0\n```\n\nAnd here we are at the position when someone wrote a broken term on the process\nheap. Note that \"Old value\" and \"New value\" are reversed when we execute\nbackwards. In this case the value 42 was written on the heap. Let's see who the\nguilty one is:\n\n```text\n(rr) backtrace\n```","title":"rr - Record and Replay - Debugging NIFs and Port Drivers","ref":"debugging.html#rr-record-and-replay"},{"type":"extras","doc":"\n\n# Introduction\n\nThis section describes the issues that are specific for running Erlang on an UNIX\nembedded system. It describes the differences in installing and starting Erlang\ncompared to how it is done for a non-embedded system.\n\nFor details on how to create a target system, see [Creating and Upgrading a Target System]\nin the System Principles section.\n\nWhen running on Windows, so special considerations need to be made. Starting Erlang\nshould be done via [`erlsrv`](`e:erts:erlsrv_cmd.md`).","title":"Introduction","ref":"embedded.html"},{"type":"extras","doc":"This section is about installing an embedded system. The following topics are\nconsidered:\n\n- Creating user and installation directory\n- Installing an embedded system\n- Configuring automatic start at boot\n- Changing permission for reboot\n- Setting TERM environment variable\n\nSeveral of the procedures in this section require expert knowledge of the\noperating system. For most of them super user privilege is needed.","title":"Installing an Embedded System - Introduction","ref":"embedded.html#installing-an-embedded-system"},{"type":"extras","doc":"It is recommended that the embedded environment is run by an ordinary user, that\nis, a user who does not have super user privileges.\n\nIn this section, it is assumed that the username is `otpuser` and that the home\ndirectory of that user is:\n\n```text\n/home/otpuser\n```\n\nIt is also assumed that in the home directory of `otpuser`, there is a directory\nnamed `otp`, the full path of which is:\n\n```text\n/home/otpuser/otp\n```\n\nThis directory is the _installation directory_ of the embedded environment.","title":"Creating User and Installation Directory - Introduction","ref":"embedded.html#creating-user-and-installation-directory"},{"type":"extras","doc":"The procedure for installing an embedded system is the same as for an ordinary\nsystem (see [Installation Guide](installation_guide/INSTALL.md) and [Creating and Upgrading a Target System]\nin the System Principles section), except for the following:\n\n- The (compressed) archive file is to be extracted in the installation\n directory defined above.\n- It is not needed to link the start script to a standard directory like\n `/usr/local/bin`.","title":"Installing an Embedded System - Introduction","ref":"embedded.html#installing-an-embedded-system"},{"type":"extras","doc":"A true embedded system must start when the system boots. This section accounts\nfor the necessary configurations needed to achieve that using `init.d` start\nscripts.\n\nThe embedded system and all the applications start automatically if the script\nfile shown below is added to directory `/etc/rc3.d`. The file must be owned and\nreadable by `root`. Its name cannot be arbitrarily assigned; the following name\nis recommended:\n\n```text\nS75otp.system\n```\n\nFor more details on initialization (and termination) scripts, and naming\nthereof, see the `init.d` documentation on your OS.\n\n```text\n#!/bin/sh\n#\n# File name: S75otp.system\n# Purpose: Automatically starts Erlang and applications when the\n# system starts\n# Author: janne@erlang.ericsson.se\n# Resides in: /etc/rc3.d\n#\n\nif [ ! -d /usr/bin ]\nthen # /usr not mounted\n exit\nfi\n\nkillproc() { # kill the named process(es)\n pid=`/usr/bin/ps -e |\n /usr/bin/grep -w $1 |\n /usr/bin/sed -e 's/^ *//' -e 's/ .*//'`\n [ \"$pid\" != \"\" ] && kill $pid\n}\n\n# Start/stop processes required for Erlang\n\ncase \"$1\" in\n'start')\n # Start the Erlang emulator\n #\n su - otpuser -c \"/home/otpuser/otp/bin/start\" &\n ;;\n'stop')\n killproc beam\n ;;\n*)\n echo \"Usage: $0 { start | stop }\"\n ;;\nesac\n```\n\nFile `/home/otpuser/otp/bin/start` referred to in the above script is\nprecisely the `start` script described in [_Starting Erlang_](#starting-erlang).\nThe script variable `$OTPROOT` in that `start` script corresponds to the following example path used\nin this section:\n\n```text\n/home/otpuser/otp\n```\n\nThe `start` script is to be edited accordingly.\n\nUse of the `killproc` procedure in the above script can be combined with a call\nto `erl_call`, for example:\n\n```text\n$SOME_PATH/erl_call -n Node init stop\n```\n\nTo take Erlang down gracefully, see the\n[`erl_call(1)`](`e:erl_interface:erl_call_cmd.md`) manual page in\n`erl_interface` for details on the use of `erl_call`. However, that requires\nthat Erlang runs as a distributed node, which is not always the case.\n\nThe `killproc` procedure is not to be removed. The purpose is here to move from\nrun level 3 (multi-user mode with networking resources) to run level 2\n(multi-user mode without such resources), in which Erlang is not to run.","title":"Configuring Automatic Start at Boot - Introduction","ref":"embedded.html#configuring-automatic-start-at-boot"},{"type":"extras","doc":"If the `HEART_COMMAND` environment variable is to be set in the `start` script\nin [_Starting Erlang_](#starting-erlang), and if the value is to be set to the path of the\n`reboot` command, that is:\n\n```text\nHEART_COMMAND=/usr/sbin/reboot\n```\n\nthen the ownership and file permissions for `/usr/sbin/reboot` must be changed\nas follows:\n\n```text\nchown 0 /usr/sbin/reboot\nchmod 4755 /usr/sbin/reboot\n```\n\nSee also the `m:heart` manual page in Kernel.","title":"Changing Permissions for Reboot - Introduction","ref":"embedded.html#changing-permissions-for-reboot"},{"type":"extras","doc":"When the Erlang runtime system is automatically started from the `S75otp.system`\nscript, the `TERM` environment variable must be set. The following is a minimal\nsetting:\n\n```text\nTERM=dumb\n```\n\nThis is to be added to the `start` script.","title":"Setting TERM Environment Variable - Introduction","ref":"embedded.html#setting-term-environment-variable"},{"type":"extras","doc":"This section describes how an embedded system is started. Four programs are\ninvolved and they normally reside in the directory ` /bin`. The\nonly exception is the [`start`](`e:erts:start_cmd.md`) program, which can be located anywhere, and is\nalso the only program that must be modified by the user.\n\nIn an embedded system, there is usually no interactive shell. However, an\noperator can attach to the Erlang system by command [`to_erl`](#to_erl).\nThe operator is then connected to the Erlang shell and can give ordinary Erlang commands. All\ninteraction with the system through this shell is logged in a special directory.\n\nBasically, the procedure is as follows:\n\n- The [`start`](`e:erts:start_cmd.md`)) program is called when the machine is started.\n- It calls [`run_erl`](#run_erl), which sets up things so the operator can attach to the\n system.\n- It calls [`start_erl`](`e:erts:start_erl_cmd.md`), which calls the correct version of\n `erlexec` (which is located in ` /erts-EVsn/bin`) with the correct `boot` and\n `config` files.","title":"Starting Erlang - Introduction","ref":"embedded.html#starting-erlang"},{"type":"extras","doc":"","title":"Programs - Introduction","ref":"embedded.html#programs"},{"type":"extras","doc":"This program is called when the machine is started. It can be modified or\nrewritten to suit a special system. By default, it must be called `start` and\nreside in ` /bin`. Another start program can be used, by using\nconfiguration parameter `start_prg` in application SASL.\n\nThe start program must call [`run_erl`](#run_erl) as shown below. It must also take an\noptional parameter, which defaults to\n` /releases/start_erl.data`.\n\nThis program is to set static parameters and environment variables such as\n`-sname Name` and `HEART_COMMAND` to reboot the machine.\n\nThe ` ` directory is where new release packets are installed, and where\nthe release handler keeps information about releases. For more information, see\nthe `m:release_handler` manual page in SASL.\n\nThe following script illustrates the default behaviour of the program:\n\n```text\n#!/bin/sh\n# Usage: start [DataFile]\n#\nROOTDIR=/usr/local/otp\n\nif [ -z \"$RELDIR\" ]\nthen\n RELDIR=$ROOTDIR/releases\nfi\n\nSTART_ERL_DATA=${1:-$RELDIR/start_erl.data}\n\n$ROOTDIR/bin/run_erl /tmp/ $ROOTDIR/log \"exec $ROOTDIR/bin/start_erl \\\n $ROOTDIR $RELDIR $START_ERL_DATA\" > /dev/null 2>&1 &\n```\n\nThe following script illustrates a modification where the node is given the name\n`cp1`, and where the environment variables `HEART_COMMAND` and `TERM` have been\nadded to the previous script:\n\n```text\n#!/bin/sh\n# Usage: start [DataFile]\n#\nHEART_COMMAND=/usr/sbin/reboot\nTERM=dumb\nexport HEART_COMMAND TERM\n\nROOTDIR=/usr/local/otp\n\nif [ -z \"$RELDIR\" ]\nthen\n RELDIR=$ROOTDIR/releases\nfi\n\nSTART_ERL_DATA=${1:-$RELDIR/start_erl.data}\n\n$ROOTDIR/bin/run_erl /tmp/ $ROOTDIR/log \"exec $ROOTDIR/bin/start_erl \\\n $ROOTDIR $RELDIR $START_ERL_DATA -heart -sname cp1\" > /dev/null 2>&1 &\n```\n\nIf a diskless and/or read-only client node is about to start, file\n`start_erl.data` is located in the client directory at the master node. Thus,\nthe `START_ERL_DATA` line is to look like:\n\n```text\nCLIENTDIR=$ROOTDIR/clients/clientname\nSTART_ERL_DATA=${1:-$CLIENTDIR/bin/start_erl.data}\n```","title":"start - Introduction","ref":"embedded.html#start"},{"type":"extras","doc":"This program is used to start the emulator, but you will not be connected to the\nshell. `to_erl` is used to connect to the Erlang shell.\n\n```text\nUsage: run_erl pipe_dir/ log_dir \"exec command [parameters ...]\"\n```\n\nHere:\n\n- `pipe_dir/` is to be `/tmp/` (`to_erl` uses this name by default).\n- `log_dir` is where the log files are written.\n- `command [parameters]` is executed.\n- Everything written to `stdin` and `stdout` is logged in `log_dir`.\n\nLog files are written in `log_dir`. Each log file has a name of the form\n`erlang.log.N`, where N is a generation number, ranging from 1 to 5. Each log\nfile holds up to 100 kB text. As time goes by, the following log files are found\nin the log file directory:\n\n```text\nerlang.log.1\nerlang.log.1, erlang.log.2\nerlang.log.1, erlang.log.2, erlang.log.3\nerlang.log.1, erlang.log.2, erlang.log.3, erlang.log.4\nerlang.log.2, erlang.log.3, erlang.log.4, erlang.log.5\nerlang.log.3, erlang.log.4, erlang.log.5, erlang.log.1\n...\n```\n\nThe most recent log file is the rightmost in each row. That is, the most recent\nfile is the one with the highest number, or if there are already four files, the\none before the skip.\n\nWhen a log file is opened (for appending or created), a time stamp is written to\nthe file. If nothing has been written to the log files for 15 minutes, a record\nis inserted that says that we are still alive.\n\nFor more details see [`run_erl`](`e:erts:run_erl_cmd.md`) in the ERTS documentation.","title":"run_erl - Introduction","ref":"embedded.html#run_erl"},{"type":"extras","doc":"This program is used to attach to a running Erlang runtime system, started with\n`run_erl`.\n\n```text\nUsage: to_erl [pipe_name | pipe_dir]\n```\n\nHere `pipe_name` defaults to `/tmp/erlang.pipe.N`.\n\nTo disconnect from the shell without exiting the Erlang system, type `Ctrl-D`.","title":"to_erl - Introduction","ref":"embedded.html#to_erl"},{"type":"extras","doc":"This program starts the Erlang emulator with parameters `-boot` and `-config`\nset. It reads data about where these files are located from a file named\n`start_erl.data`, which is located in ` `. Each new release introduces a\nnew data file. This file is automatically generated by the release handler in\nErlang.\n\nThe following script illustrates the behaviour of the program:\n\n```text\n#!/bin/sh\n#\n# This program is called by run_erl. It starts\n# the Erlang emulator and sets -boot and -config parameters.\n# It should only be used at an embedded target system.\n#\n# Usage: start_erl RootDir RelDir DataFile [ErlFlags ...]\n#\nROOTDIR=$1\nshift\nRELDIR=$1\nshift\nDataFile=$1\nshift\n\nERTS_VSN=`awk '{print $1}' $DataFile`\nVSN=`awk '{print $2}' $DataFile`\n\nBINDIR=$ROOTDIR/erts-$ERTS_VSN/bin\nEMU=beam\nPROGNAME=`echo $0 | sed 's/.*\\///'`\nexport EMU\nexport ROOTDIR\nexport BINDIR\nexport PROGNAME\nexport RELDIR\n\nexec $BINDIR/erlexec -boot $RELDIR/$VSN/start -config $RELDIR/$VSN/sys $*\n```\n\nIf a diskless and/or read-only client node with the SASL configuration parameter\n`static_emulator` set to `true` is about to start, the `-boot` and `-config`\nflags must be changed.\n\nAs such a client cannot read a new `start_erl.data` file (the file cannot be\nchanged dynamically). The boot and config files are always fetched from the same\nplace (but with new contents if a new release has been installed).\n\nThe `release_handler` copies these files to the `bin` directory in the client\ndirectory at the master nodes whenever a new release is made permanent.\n\nAssuming the same `CLIENTDIR` as above, the last line is to look like:\n\n```text\nexec $BINDIR/erlexec -boot $CLIENTDIR/bin/start \\\n -config $CLIENTDIR/bin/sys $*\n```\n\n[Creating and Upgrading a Target System]: create_target.md","title":"start_erl - Introduction","ref":"embedded.html#start_erl"}],"content_type":"text/plain","producer":{"name":"ex_doc","version":[48,46,51,52,46,49]}} \ No newline at end of file diff --git a/prs/8803/doc/system/distributed.html b/prs/8803/doc/system/distributed.html index bbdeb8196063e..b1ca7dcf0af82 100644 --- a/prs/8803/doc/system/distributed.html +++ b/prs/8803/doc/system/distributed.html @@ -146,17 +146,17 @@

      the user. host is the full host name if long names are used, or the first part of the host name if short names are used. Function node() returns the name of the node.

      Example:

      % erl -name dilbert
      -(dilbert@uab.ericsson.se)1> node().
      +(dilbert@uab.ericsson.se)1> node().
       'dilbert@uab.ericsson.se'
       
       % erl -sname dilbert
      -(dilbert@uab)1> node().
      +(dilbert@uab)1> node().
       dilbert@uab

      The node name can also be given in runtime by calling net_kernel:start/1.

      Example:

      % erl
      -1> node().
      +1> node().
       nonode@nohost
      -2> net_kernel:start([dilbert,shortnames]).
      -{ok,<0.102.0>}
      -(dilbert@uab)3> node().
      +2> net_kernel:start([dilbert,shortnames]).
      +{ok,<0.102.0>}
      +(dilbert@uab)3> node().
       dilbert@uab

      Note

      A node with a long node name cannot communicate with a node with a short node name.

      diff --git a/prs/8803/doc/system/distributed_applications.html b/prs/8803/doc/system/distributed_applications.html index ec2557ffdd7ae..5d70cb72657a0 100644 --- a/prs/8803/doc/system/distributed_applications.html +++ b/prs/8803/doc/system/distributed_applications.html @@ -154,13 +154,13 @@

      elapsed, all applications start. If not all mandatory nodes are up, the node terminates.

      Example:

      An application myapp is to run at the node cp1@cave. If this node goes down, myapp is to be restarted at cp2@cave or cp3@cave. A system configuration -file cp1.config for cp1@cave can look as follows:

      [{kernel,
      -  [{distributed, [{myapp, 5000, [cp1@cave, {cp2@cave, cp3@cave}]}]},
      -   {sync_nodes_mandatory, [cp2@cave, cp3@cave]},
      -   {sync_nodes_timeout, 5000}
      -  ]
      - }
      -].

      The system configuration files for cp2@cave and cp3@cave are identical, +file cp1.config for cp1@cave can look as follows:

      [{kernel,
      +  [{distributed, [{myapp, 5000, [cp1@cave, {cp2@cave, cp3@cave}]}]},
      +   {sync_nodes_mandatory, [cp2@cave, cp3@cave]},
      +   {sync_nodes_timeout, 5000}
      +  ]
      + }
      +].

      The system configuration files for cp2@cave and cp3@cave are identical, except for the list of mandatory nodes, which is to be [cp1@cave, cp3@cave] for cp2@cave and [cp1@cave, cp2@cave] for cp3@cave.

      Note

      All involved nodes must have the same value for distributed and sync_nodes_timeout. Otherwise the system behavior is undefined.

      @@ -175,7 +175,7 @@

      automatically starts the application.

      The application is started at the first operational node that is listed in the list of nodes in the distributed configuration parameter. The application is started as usual. That is, an application master is created and calls the -application callback function:

      Module:start(normal, StartArgs)

      Example:

      Continuing the example from the previous section, the three nodes are started, +application callback function:

      Module:start(normal, StartArgs)

      Example:

      Continuing the example from the previous section, the three nodes are started, specifying the system configuration file:

      > erl -sname cp1 -config cp1
       > erl -sname cp2 -config cp2
       > erl -sname cp3 -config cp3

      When all nodes are operational, myapp can be started. This is achieved by @@ -191,9 +191,9 @@

      restarted (after the specified time-out) at the first operational node that is listed in the list of nodes in the distributed configuration parameter. This is called a failover.

      The application is started the normal way at the new node, that is, by the -application master calling:

      Module:start(normal, StartArgs)

      An exception is if the application has the start_phases key defined (see +application master calling:

      Module:start(normal, StartArgs)

      An exception is if the application has the start_phases key defined (see Included Applications). The application is then -instead started by calling:

      Module:start({failover, Node}, StartArgs)

      Here Node is the terminated node.

      Example:

      If cp1 goes down, the system checks which one of the other nodes, cp2 or +instead started by calling:

      Module:start({failover, Node}, StartArgs)

      Here Node is the terminated node.

      Example:

      If cp1 goes down, the system checks which one of the other nodes, cp2 or cp3, has the least number of running applications, but waits for 5 seconds for cp1 to restart. If cp1 does not restart and cp2 runs fewer applications than cp3, myapp is restarted on cp2.

      Application myapp - Situation 2

      Suppose now that cp2 goes also down and does not restart within 5 seconds. @@ -206,7 +206,7 @@

      If a node is started, which has higher priority according to distributed than the node where a distributed application is running, the application is restarted at the new node and stopped at the old node. This is called a -takeover.

      The application is started by the application master calling:

      Module:start({takeover, Node}, StartArgs)

      Here Node is the old node.

      Example:

      If myapp is running at cp3, and if cp2 now restarts, it does not restart +takeover.

      The application is started by the application master calling:

      Module:start({takeover, Node}, StartArgs)

      Here Node is the old node.

      Example:

      If myapp is running at cp3, and if cp2 now restarts, it does not restart myapp, as the order between the cp2 and cp3 nodes is undefined.

      Application myapp - Situation 4

      However, if cp1 also restarts, the function application:takeover/2 moves myapp to cp1, as cp1 has a higher priority than cp3 for this application. In this case, Module:start({takeover, cp3@cave}, StartArgs) is diff --git a/prs/8803/doc/system/documentation.html b/prs/8803/doc/system/documentation.html index dd995b889910d..70f06b61d9a42 100644 --- a/prs/8803/doc/system/documentation.html +++ b/prs/8803/doc/system/documentation.html @@ -116,15 +116,15 @@

      Documentation in Erlang is done through the -moduledoc and -doc -attributes. For example:

      -module(arith).
      +attributes. For example:

      -module(arith).
       -moduledoc """
       A module for basic arithmetic.
       """.
       
      --export([add/2]).
      +-export([add/2]).
       
       -doc "Adds two numbers.".
      -add(One, Two) -> One + Two.

      The -moduledoc attribute has to be located before the first -doc attribute +add(One, Two) -> One + Two.

      The -moduledoc attribute has to be located before the first -doc attribute or function declaration. It documents the overall purpose of the module.

      The -doc attribute always precedes the function or attribute it documents. The attributes that can be documented are @@ -144,23 +144,23 @@

      Documentation metadata

      It is possible to add metadata to the documentation entry. You do this by adding -a -moduledoc or -doc attribute with a map as argument. For example:

      -module(arith).
      +a -moduledoc or -doc attribute with a map as argument. For example:

      -module(arith).
       -moduledoc """
       A module for basic arithmetic.
       """.
      --moduledoc #{since => "1.0"}.
      +-moduledoc #{since => "1.0"}.
       
      --export([add/2]).
      +-export([add/2]).
       
       -doc "Adds two numbers.".
      --doc(#{since => "1.0"}).
      -add(One, Two) -> One + Two.

      The metadata is used by documentation tools to provide extra information to the +-doc(#{since => "1.0"}). +add(One, Two) -> One + Two.

      The metadata is used by documentation tools to provide extra information to the user. There can be multiple metadata documentation entries, in which case the maps will be merged with the latest taking precedence if there are duplicate keys. Example:

      -doc "Adds two numbers.".
      --doc #{since => "1.0", author => "Joe"}.
      --doc #{since => "2.0"}.
      -add(One, Two) -> One + Two.

      This will result in a metadata entry of #{since => "2.0", author => "Joe"}.

      The keys and values in the metadata map can be any type, but it is recommended +-doc #{since => "1.0", author => "Joe"}. +-doc #{since => "2.0"}. +add(One, Two) -> One + Two.

      This will result in a metadata entry of #{since => "2.0", author => "Joe"}.

      The keys and values in the metadata map can be any type, but it is recommended that only atoms are used for keys and strings for the values.

      @@ -172,8 +172,8 @@

      -doc {file, "path/to/doc.md"} to point to the documentation. The path used is relative to the file where the -doc attribute is located. For example:

      %% doc/add.md
       Adds two numbers.

      and

      %% src/arith.erl
      --doc({file, "../doc/add.md"}).
      -add(One, Two) -> One + Two.

      +-doc({file, "../doc/add.md"}). +add(One, Two) -> One + Two.

    @@ -184,7 +184,7 @@

    and other diagrams to better show the usage of the module. Instead of writing a long text in the moduledoc attribute, it could be better to break it out into an external page.

    The moduledoc attribute should start with a short paragraph describing the -module and then go into greater details. For example:

    -module(arith).
    +module and then go into greater details. For example:

    -module(arith).
     -moduledoc """
        A module for basic arithmetic.
     
    @@ -207,9 +207,9 @@ 

    deprecated and what to use instead.
  • format - The format to use for all documentation in this module. The default is text/markdown. It should be written using the mime type -of the format.

Example:

-moduledoc {file, "../doc/arith.asciidoc"}.
--moduledoc #{since => "0.1", format => "text/asciidoc"}.
--moduledoc #{deprecated => "Use the Erlang arithmetic operators instead."}.

+of the format.

Example:

-moduledoc {file, "../doc/arith.asciidoc"}.
+-moduledoc #{since => "0.1", format => "text/asciidoc"}.
+-moduledoc #{deprecated => "Use the Erlang arithmetic operators instead."}.

@@ -224,7 +224,7 @@

We use a special number here so that we know that this number comes from this module. """. --opaque number() :: {arith, erlang:number()}. +-opaque number() :: {arith, erlang:number()}. -doc """ Adds two numbers. @@ -235,8 +235,8 @@

1> arith:add(arith:number(1), arith:number(2)). {number, 3} ``` """. --spec add(number(), number()) -> number(). -add({number, One}, {number, Two}) -> {number, One + Two}.

+-spec add(number(), number()) -> number(). +add({number, One}, {number, Two}) -> {number, One + Two}.

@@ -248,12 +248,12 @@

automatically insert this key if there is a -deprecated attribute marking a function as deprecated.

  • equiv => unicode:chardata() | F/A | F(...) - Notes that this function is equivalent to another function in this module. The equivalence can be described using either -Func/Arity, Func(Args) or a unicode string. For example:

    -doc #{equiv => add/3}.
    -add(One, Two) -> add(One, Two, []).
    -add(One, Two, Options) -> ...

    or

    -doc #{equiv => add(One, Two, [])}.
    --spec add(One :: number(), Two :: number()) -> number().
    -add(One, Two) -> add(One, Two, []).
    -add(One, Two, Options) -> ...

    The entry into the EEP-48 doc chunk metadata is +Func/Arity, Func(Args) or a unicode string. For example:

    -doc #{equiv => add/3}.
    +add(One, Two) -> add(One, Two, []).
    +add(One, Two, Options) -> ...

    or

    -doc #{equiv => add(One, Two, [])}.
    +-spec add(One :: number(), Two :: number()) -> number().
    +add(One, Two) -> add(One, Two, []).
    +add(One, Two, Options) -> ...

    The entry into the EEP-48 doc chunk metadata is the value converted to a string.

  • exported => boolean() - A boolean/0 signifying if the entry is exported or not. This value is automatically set by the compiler and should not be set by the user.

  • @@ -264,20 +264,20 @@

    The doc signature is a short text shown to describe the function and its arguments. By default it is determined by looking at the names of the arguments in the --spec or function. For example:

    add(One, Two) -> One + Two.
    +-spec or function. For example:

    add(One, Two) -> One + Two.
     
    --spec sub(One :: integer(), Two :: integer()) -> integer().
    -sub(X, Y) -> X - Y.

    will have a signature of add(One, Two) and sub(One, Two).

    For types or callbacks, the signature is derived from the type or callback -specification. For example:

    -type number(Value) :: {number, Value}.
    +-spec sub(One :: integer(), Two :: integer()) -> integer().
    +sub(X, Y) -> X - Y.

    will have a signature of add(One, Two) and sub(One, Two).

    For types or callbacks, the signature is derived from the type or callback +specification. For example:

    -type number(Value) :: {number, Value}.
     %% signature will be `number(Value)`
     
    --opaque number() :: {number, number()}.
    +-opaque number() :: {number, number()}.
     %% signature will be `number()`
     
    --callback increment(In :: number()) -> Out.
    +-callback increment(In :: number()) -> Out.
     %% signature will be `increment(In)`
     
    --callback increment(In) -> Out when In :: number().
    +-callback increment(In) -> Out when In :: number().
     %% signature will be `increment(In)`

    If it is not possible to "easily" figure out a nice signature from the code, the MFA syntax is used instead. For example: add/2, number/1, increment/1

    It is possible to supply a custom signature by placing it as the first line of the -doc attribute. The provided signature must be in the form of a function @@ -286,7 +286,7 @@

    Adds two numbers. """. -add(A, B) -> A + B.

    Will create the signature add(One, Two). The signature will be removed from the +add(A, B) -> A + B.

    Will create the signature add(One, Two). The signature will be removed from the documentation string, so in the example above only the text "Adds two numbers" will be part of the documentation. This works for functions, types, and callbacks.

    When configured you can run rebar3 ex_doc to generate the documentation to doc/index.html. For more details and options see the rebar3_ex_doc documentation.

    You can also download the release escript bundle from diff --git a/prs/8803/doc/system/drivers.html b/prs/8803/doc/system/drivers.html index 3c960d016d92d..38a648b23a63a 100644 --- a/prs/8803/doc/system/drivers.html +++ b/prs/8803/doc/system/drivers.html @@ -126,15 +126,15 @@

    running.

    A driver can be configured to have one lock for each port instead.

    If a driver is used in a functional way (that is, holds no state, but only does some heavy calculation and returns a result), several ports with registered names can be opened beforehand, and the port to be used can be chosen based on -the scheduler ID as follows:

    -define(PORT_NAMES(),
    -	{some_driver_01, some_driver_02, some_driver_03, some_driver_04,
    +the scheduler ID as follows:

    -define(PORT_NAMES(),
    +	{some_driver_01, some_driver_02, some_driver_03, some_driver_04,
     	 some_driver_05, some_driver_06, some_driver_07, some_driver_08,
     	 some_driver_09, some_driver_10, some_driver_11, some_driver_12,
    -	 some_driver_13, some_driver_14, some_driver_15, some_driver_16}).
    +	 some_driver_13, some_driver_14, some_driver_15, some_driver_16}).
     
    -client_port() ->
    -    element(erlang:system_info(scheduler_id) rem tuple_size(?PORT_NAMES()) + 1,
    -	    ?PORT_NAMES()).

    As long as there are no more than 16 schedulers, there will never be any lock +client_port() -> + element(erlang:system_info(scheduler_id) rem tuple_size(?PORT_NAMES()) + 1, + ?PORT_NAMES()).

    As long as there are no more than 16 schedulers, there will never be any lock contention on the port lock for the driver.

    diff --git a/prs/8803/doc/system/eff_guide_functions.html b/prs/8803/doc/system/eff_guide_functions.html index bf7066199cc1f..89f3f4361a449 100644 --- a/prs/8803/doc/system/eff_guide_functions.html +++ b/prs/8803/doc/system/eff_guide_functions.html @@ -126,13 +126,13 @@

    rearranging clauses.

    One exception is pattern matching of binaries. The compiler does not rearrange clauses that match binaries. Placing the clause that matches against the empty binary last is usually slightly faster than placing it first.

    The following is a rather unnatural example to show another exception where -rearranging clauses is beneficial:

    DO NOT

    atom_map1(one) -> 1;
    -atom_map1(two) -> 2;
    -atom_map1(three) -> 3;
    -atom_map1(Int) when is_integer(Int) -> Int;
    -atom_map1(four) -> 4;
    -atom_map1(five) -> 5;
    -atom_map1(six) -> 6.

    The problem is the clause with the variable Int. As a variable can match +rearranging clauses is beneficial:

    DO NOT

    atom_map1(one) -> 1;
    +atom_map1(two) -> 2;
    +atom_map1(three) -> 3;
    +atom_map1(Int) when is_integer(Int) -> Int;
    +atom_map1(four) -> 4;
    +atom_map1(five) -> 5;
    +atom_map1(six) -> 6.

    The problem is the clause with the variable Int. As a variable can match anything, including the atoms four, five, and six, which the following clauses also match, the compiler must generate suboptimal code that executes as follows:

    Rewriting to either:

    DO

    atom_map2(one) -> 1;
    -atom_map2(two) -> 2;
    -atom_map2(three) -> 3;
    -atom_map2(four) -> 4;
    -atom_map2(five) -> 5;
    -atom_map2(six) -> 6;
    -atom_map2(Int) when is_integer(Int) -> Int.

    or:

    DO

    atom_map3(Int) when is_integer(Int) -> Int;
    -atom_map3(one) -> 1;
    -atom_map3(two) -> 2;
    -atom_map3(three) -> 3;
    -atom_map3(four) -> 4;
    -atom_map3(five) -> 5;
    -atom_map3(six) -> 6.

    gives slightly more efficient matching code.

    Another example:

    DO NOT

    map_pairs1(_Map, [], Ys) ->
    +exception if none of the values matched.)

    Rewriting to either:

    DO

    atom_map2(one) -> 1;
    +atom_map2(two) -> 2;
    +atom_map2(three) -> 3;
    +atom_map2(four) -> 4;
    +atom_map2(five) -> 5;
    +atom_map2(six) -> 6;
    +atom_map2(Int) when is_integer(Int) -> Int.

    or:

    DO

    atom_map3(Int) when is_integer(Int) -> Int;
    +atom_map3(one) -> 1;
    +atom_map3(two) -> 2;
    +atom_map3(three) -> 3;
    +atom_map3(four) -> 4;
    +atom_map3(five) -> 5;
    +atom_map3(six) -> 6.

    gives slightly more efficient matching code.

    Another example:

    DO NOT

    map_pairs1(_Map, [], Ys) ->
         Ys;
    -map_pairs1(_Map, Xs, []) ->
    +map_pairs1(_Map, Xs, []) ->
         Xs;
    -map_pairs1(Map, [X|Xs], [Y|Ys]) ->
    -    [Map(X, Y)|map_pairs1(Map, Xs, Ys)].

    The first argument is not a problem. It is variable, but it is a variable in +map_pairs1(Map, [X|Xs], [Y|Ys]) -> + [Map(X, Y)|map_pairs1(Map, Xs, Ys)].

    The first argument is not a problem. It is variable, but it is a variable in all clauses. The problem is the variable in the second argument, Xs, in the middle clause. Because the variable can match anything, the compiler is not allowed to rearrange the clauses, but must generate code that matches them in the order written.

    If the function is rewritten as follows, the compiler is free to rearrange the -clauses:

    DO

    map_pairs2(_Map, [], Ys) ->
    +clauses:

    DO

    map_pairs2(_Map, [], Ys) ->
         Ys;
    -map_pairs2(_Map, [_|_]=Xs, [] ) ->
    +map_pairs2(_Map, [_|_]=Xs, [] ) ->
         Xs;
    -map_pairs2(Map, [X|Xs], [Y|Ys]) ->
    -    [Map(X, Y)|map_pairs2(Map, Xs, Ys)].

    The compiler will generate code similar to this:

    DO NOT (already done by the compiler)

    explicit_map_pairs(Map, Xs0, Ys0) ->
    +map_pairs2(Map, [X|Xs], [Y|Ys]) ->
    +    [Map(X, Y)|map_pairs2(Map, Xs, Ys)].

    The compiler will generate code similar to this:

    DO NOT (already done by the compiler)

    explicit_map_pairs(Map, Xs0, Ys0) ->
         case Xs0 of
    -	[X|Xs] ->
    +	[X|Xs] ->
     	    case Ys0 of
    -		[Y|Ys] ->
    -		    [Map(X, Y)|explicit_map_pairs(Map, Xs, Ys)];
    -		[] ->
    +		[Y|Ys] ->
    +		    [Map(X, Y)|explicit_map_pairs(Map, Xs, Ys)];
    +		[] ->
     		    Xs0
     	    end;
    -	[] ->
    +	[] ->
     	    Ys0
         end.

    This is slightly faster for probably the most common case that the input lists are not empty or very short. (Another advantage is that Dialyzer can deduce a diff --git a/prs/8803/doc/system/eff_guide_processes.html b/prs/8803/doc/system/eff_guide_processes.html index f7de077122dca..f3a5ded4ddde3 100644 --- a/prs/8803/doc/system/eff_guide_processes.html +++ b/prs/8803/doc/system/eff_guide_processes.html @@ -123,37 +123,37 @@

    An Erlang process is lightweight compared to threads and processes in operating systems.

    A newly spawned Erlang process uses 327 words of memory. The size can be found -as follows:

    Erlang/OTP 27 [erts-14.2.3] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]
    +as follows:

    Erlang/OTP 27 [erts-14.2.3] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]
     
    -Eshell V14.2.3 (press Ctrl+G to abort, type help(). for help)
    -1> Fun = fun() -> receive after infinity -> ok end end.
    +Eshell V14.2.3 (press Ctrl+G to abort, type help(). for help)
    +1> Fun = fun() -> receive after infinity -> ok end end.
     #Fun<erl_eval.43.39164016>
    -2> {_,Bytes} = process_info(spawn(Fun), memory).
    -{memory,2616}
    -3> Bytes div erlang:system_info(wordsize).
    +2> {_,Bytes} = process_info(spawn(Fun), memory).
    +{memory,2616}
    +3> Bytes div erlang:system_info(wordsize).
     327

    The size includes 233 words for the heap area (which includes the stack). The garbage collector increases the heap as needed.

    The main (outer) loop for a process must be tail-recursive. Otherwise, the -stack grows until the process terminates.

    DO NOT

    loop() ->
    +stack grows until the process terminates.

    DO NOT

    loop() ->
       receive
    -     {sys, Msg} ->
    -         handle_sys_msg(Msg),
    -         loop();
    -     {From, Msg} ->
    -          Reply = handle_msg(Msg),
    +     {sys, Msg} ->
    +         handle_sys_msg(Msg),
    +         loop();
    +     {From, Msg} ->
    +          Reply = handle_msg(Msg),
               From ! Reply,
    -          loop()
    +          loop()
       end,
    -  io:format("Message is processed~n", []).

    The call to io:format/2 will never be executed, but a return address will + io:format("Message is processed~n", []).

    The call to io:format/2 will never be executed, but a return address will still be pushed to the stack each time loop/0 is called recursively. The -correct tail-recursive version of the function looks as follows:

    DO

    loop() ->
    +correct tail-recursive version of the function looks as follows:

    DO

    loop() ->
        receive
    -      {sys, Msg} ->
    -         handle_sys_msg(Msg),
    -         loop();
    -      {From, Msg} ->
    -         Reply = handle_msg(Msg),
    +      {sys, Msg} ->
    +         handle_sys_msg(Msg),
    +         loop();
    +      {From, Msg} ->
    +         Reply = handle_msg(Msg),
              From ! Reply,
    -         loop()
    +         loop()
      end.

    @@ -193,22 +193,22 @@

    The cost of receiving messages depends on how complicated the receive expression is. A simple expression that matches any message is very cheap because it retrieves the first message in the message queue:

    DO

    receive
    -    Message -> handle_msg(Message)
    +    Message -> handle_msg(Message)
     end.

    However, this is not always convenient: we can receive a message that we do not know how to handle at this point, so it is common to only match the messages we expect:

    receive
    -    {Tag, Message} -> handle_msg(Message)
    +    {Tag, Message} -> handle_msg(Message)
     end.

    While this is convenient it means that the entire message queue must be searched until it finds a matching message. This is very expensive for processes with long message queues, so there is an optimization for the common case of -sending a request and waiting for a response shortly after:

    DO

    MRef = monitor(process, Process),
    -Process ! {self(), MRef, Request},
    +sending a request and waiting for a response shortly after:

    DO

    MRef = monitor(process, Process),
    +Process ! {self(), MRef, Request},
     receive
    -    {MRef, Reply} ->
    -        erlang:demonitor(MRef, [flush]),
    -        handle_reply(Reply);
    -    {'DOWN', MRef, _, _, Reason} ->
    -        handle_error(Reason)
    +    {MRef, Reply} ->
    +        erlang:demonitor(MRef, [flush]),
    +        handle_reply(Reply);
    +    {'DOWN', MRef, _, _, Reason} ->
    +        handle_error(Reason)
     end.

    Since the compiler knows that the reference created by monitor/2 cannot exist before the call (since it is a globally unique identifier), and that the receive only matches messages that contain @@ -232,45 +232,45 @@

    efficiency_guide.erl:222: Warning: OPTIMIZED: all clauses match reference in function parameter 1

    To make it clearer exactly what code the warnings refer to, the warnings in the following examples are inserted as comments after the clause they refer to, for example:

    %% DO
    -simple_receive() ->
    +simple_receive() ->
     %% efficiency_guide.erl:194: Warning: INFO: not a selective receive, this is always fast
     receive
    -    Message -> handle_msg(Message)
    +    Message -> handle_msg(Message)
     end.
     
     %% DO NOT, unless Tag is known to be a suitable reference: see
     %% cross_function_receive/0 further down.
    -selective_receive(Tag, Message) ->
    +selective_receive(Tag, Message) ->
     %% efficiency_guide.erl:200: Warning: NOT OPTIMIZED: all clauses do not match a suitable reference
     receive
    -    {Tag, Message} -> handle_msg(Message)
    +    {Tag, Message} -> handle_msg(Message)
     end.
     
     %% DO
    -optimized_receive(Process, Request) ->
    +optimized_receive(Process, Request) ->
     %% efficiency_guide.erl:206: Warning: OPTIMIZED: reference used to mark a message queue position
    -    MRef = monitor(process, Process),
    -    Process ! {self(), MRef, Request},
    +    MRef = monitor(process, Process),
    +    Process ! {self(), MRef, Request},
         %% efficiency_guide.erl:208: Warning: OPTIMIZED: matches reference created by monitor/2 at efficiency_guide.erl:206
         receive
    -        {MRef, Reply} ->
    -        erlang:demonitor(MRef, [flush]),
    -        handle_reply(Reply);
    -    {'DOWN', MRef, _, _, Reason} ->
    -    handle_error(Reason)
    +        {MRef, Reply} ->
    +        erlang:demonitor(MRef, [flush]),
    +        handle_reply(Reply);
    +    {'DOWN', MRef, _, _, Reason} ->
    +    handle_error(Reason)
         end.
     
     %% DO
    -cross_function_receive() ->
    +cross_function_receive() ->
         %% efficiency_guide.erl:218: Warning: OPTIMIZED: reference used to mark a message queue position
    -    Ref = make_ref(),
    +    Ref = make_ref(),
         %% efficiency_guide.erl:219: Warning: INFO: passing reference created by make_ref/0 at efficiency_guide.erl:218
    -    cross_function_receive(Ref).
    +    cross_function_receive(Ref).
     
    -cross_function_receive(Ref) ->
    +cross_function_receive(Ref) ->
         %% efficiency_guide.erl:222: Warning: OPTIMIZED: all clauses match reference in function parameter 1
         receive
    -        {Ref, Message} -> handle_msg(Message)
    +        {Ref, Message} -> handle_msg(Message)
         end.

    @@ -281,8 +281,8 @@

    each loaded module has its own pool. The following function does not build the tuple every time it is called (only to have it discarded the next time the garbage collector was run), but the tuple is located in the module's literal -pool:

    DO

    days_in_month(M) ->
    -    element(M, {31,28,31,30,31,30,31,31,30,31,30,31}).

    If a literal, or a term that contains a literal, is inserted into an Ets table, +pool:

    DO

    days_in_month(M) ->
    +    element(M, {31,28,31,30,31,30,31,31,30,31,30,31}).

    If a literal, or a term that contains a literal, is inserted into an Ets table, it is copied. The reason is that the module containing the literal can be unloaded in the future.

    When a literal is sent to another process, it is not copied. When a module holding a literal is unloaded, the literal will be copied to the heap of all @@ -297,28 +297,28 @@

    Loss of Sharing

    -

    An Erlang term can have shared subterms. Here is a simple example:

    {SubTerm, SubTerm}

    Shared subterms are not preserved in the following cases:

    • When a term is sent to another process
    • When a term is passed as the initial process arguments in the spawn call
    • When a term is stored in an Ets table

    That is an optimization. Most applications do not send messages with shared -subterms.

    The following example shows how a shared subterm can be created:

    kilo_byte() ->
    -    kilo_byte(10, [42]).
    +

    An Erlang term can have shared subterms. Here is a simple example:

    {SubTerm, SubTerm}

    Shared subterms are not preserved in the following cases:

    • When a term is sent to another process
    • When a term is passed as the initial process arguments in the spawn call
    • When a term is stored in an Ets table

    That is an optimization. Most applications do not send messages with shared +subterms.

    The following example shows how a shared subterm can be created:

    kilo_byte() ->
    +    kilo_byte(10, [42]).
     
    -kilo_byte(0, Acc) ->
    +kilo_byte(0, Acc) ->
         Acc;
    -kilo_byte(N, Acc) ->
    -    kilo_byte(N-1, [Acc|Acc]).

    kilo_byte/1 creates a deep list. If list_to_binary/1 +kilo_byte(N, Acc) -> + kilo_byte(N-1, [Acc|Acc]).

    kilo_byte/1 creates a deep list. If list_to_binary/1 is called, the deep list can be converted to a binary of 1024 bytes:

    1> byte_size(list_to_binary(efficiency_guide:kilo_byte())).
     1024

    Using the erts_debug:size/1 BIF, it can be seen that the deep list only -requires 22 words of heap space:

    2> erts_debug:size(efficiency_guide:kilo_byte()).
    +requires 22 words of heap space:

    2> erts_debug:size(efficiency_guide:kilo_byte()).
     22

    Using the erts_debug:flat_size/1 BIF, the size of the deep list can be calculated if sharing is ignored. It becomes the size of the list when it has -been sent to another process or stored in an Ets table:

    3> erts_debug:flat_size(efficiency_guide:kilo_byte()).
    +been sent to another process or stored in an Ets table:

    3> erts_debug:flat_size(efficiency_guide:kilo_byte()).
     4094

    It can be verified that sharing will be lost if the data is inserted into an Ets -table:

    4> T = ets:new(tab, []).
    +table:

    4> T = ets:new(tab, []).
     #Ref<0.1662103692.2407923716.214181>
    -5> ets:insert(T, {key,efficiency_guide:kilo_byte()}).
    +5> ets:insert(T, {key,efficiency_guide:kilo_byte()}).
     true
    -6> erts_debug:size(element(2, hd(ets:lookup(T, key)))).
    +6> erts_debug:size(element(2, hd(ets:lookup(T, key)))).
     4094
    -7> erts_debug:flat_size(element(2, hd(ets:lookup(T, key)))).
    +7> erts_debug:flat_size(element(2, hd(ets:lookup(T, key)))).
     4094

    When the data has passed through an Ets table, erts_debug:size/1 and erts_debug:flat_size/1 return the same value. Sharing has been lost.

    It is possible to build an experimental variant of the runtime system that will preserve sharing when copying terms by giving the diff --git a/prs/8803/doc/system/erl_interface.html b/prs/8803/doc/system/erl_interface.html index 9630fb1bdb5c1..263efc1db5117 100644 --- a/prs/8803/doc/system/erl_interface.html +++ b/prs/8803/doc/system/erl_interface.html @@ -124,111 +124,111 @@

    Erlang Program

    The following example shows an Erlang program communicating with a C program -over a plain port with home made encoding:

    -module(complex1).
    --export([start/1, stop/0, init/1]).
    --export([foo/1, bar/1]).
    +over a plain port with home made encoding:

    -module(complex1).
    +-export([start/1, stop/0, init/1]).
    +-export([foo/1, bar/1]).
     
    -start(ExtPrg) ->
    -    spawn(?MODULE, init, [ExtPrg]).
    -stop() ->
    +start(ExtPrg) ->
    +    spawn(?MODULE, init, [ExtPrg]).
    +stop() ->
         complex ! stop.
     
    -foo(X) ->
    -    call_port({foo, X}).
    -bar(Y) ->
    -    call_port({bar, Y}).
    +foo(X) ->
    +    call_port({foo, X}).
    +bar(Y) ->
    +    call_port({bar, Y}).
     
    -call_port(Msg) ->
    -    complex ! {call, self(), Msg},
    +call_port(Msg) ->
    +    complex ! {call, self(), Msg},
         receive
    -	{complex, Result} ->
    +	{complex, Result} ->
     	    Result
         end.
     
    -init(ExtPrg) ->
    -    register(complex, self()),
    -    process_flag(trap_exit, true),
    -    Port = open_port({spawn, ExtPrg}, [{packet, 2}]),
    -    loop(Port).
    +init(ExtPrg) ->
    +    register(complex, self()),
    +    process_flag(trap_exit, true),
    +    Port = open_port({spawn, ExtPrg}, [{packet, 2}]),
    +    loop(Port).
     
    -loop(Port) ->
    +loop(Port) ->
         receive
    -	{call, Caller, Msg} ->
    -	    Port ! {self(), {command, encode(Msg)}},
    +	{call, Caller, Msg} ->
    +	    Port ! {self(), {command, encode(Msg)}},
     	    receive
    -		{Port, {data, Data}} ->
    -		    Caller ! {complex, decode(Data)}
    +		{Port, {data, Data}} ->
    +		    Caller ! {complex, decode(Data)}
     	    end,
    -	    loop(Port);
    +	    loop(Port);
     	stop ->
    -	    Port ! {self(), close},
    +	    Port ! {self(), close},
     	    receive
    -		{Port, closed} ->
    -		    exit(normal)
    +		{Port, closed} ->
    +		    exit(normal)
     	    end;
    -	{'EXIT', Port, Reason} ->
    -	    exit(port_terminated)
    +	{'EXIT', Port, Reason} ->
    +	    exit(port_terminated)
         end.
     
    -encode({foo, X}) -> [1, X];
    -encode({bar, Y}) -> [2, Y].
    +encode({foo, X}) -> [1, X];
    +encode({bar, Y}) -> [2, Y].
     
    -decode([Int]) -> Int.

    There are two differences when using Erl_Interface on the C side compared to the +decode([Int]) -> Int.

    There are two differences when using Erl_Interface on the C side compared to the example in Ports, using only the plain port:

    • As Erl_Interface operates on the Erlang external term format, the port must be set to use binaries.
    • Instead of inventing an encoding/decoding scheme, the term_to_binary/1 and -binary_to_term/1 BIFs are to be used.

    That is:

    open_port({spawn, ExtPrg}, [{packet, 2}])

    is replaced with:

    open_port({spawn, ExtPrg}, [{packet, 2}, binary])

    And:

    Port ! {self(), {command, encode(Msg)}},
    +binary_to_term/1 BIFs are to be used.

    That is:

    open_port({spawn, ExtPrg}, [{packet, 2}])

    is replaced with:

    open_port({spawn, ExtPrg}, [{packet, 2}, binary])

    And:

    Port ! {self(), {command, encode(Msg)}},
     receive
    -  {Port, {data, Data}} ->
    -    Caller ! {complex, decode(Data)}
    -end

    is replaced with:

    Port ! {self(), {command, term_to_binary(Msg)}},
    +  {Port, {data, Data}} ->
    +    Caller ! {complex, decode(Data)}
    +end

    is replaced with:

    Port ! {self(), {command, term_to_binary(Msg)}},
     receive
    -  {Port, {data, Data}} ->
    -    Caller ! {complex, binary_to_term(Data)}
    -end

    The resulting Erlang program is as follows:

    -module(complex2).
    --export([start/1, stop/0, init/1]).
    --export([foo/1, bar/1]).
    -
    -start(ExtPrg) ->
    -    spawn(?MODULE, init, [ExtPrg]).
    -stop() ->
    +  {Port, {data, Data}} ->
    +    Caller ! {complex, binary_to_term(Data)}
    +end

    The resulting Erlang program is as follows:

    -module(complex2).
    +-export([start/1, stop/0, init/1]).
    +-export([foo/1, bar/1]).
    +
    +start(ExtPrg) ->
    +    spawn(?MODULE, init, [ExtPrg]).
    +stop() ->
         complex ! stop.
     
    -foo(X) ->
    -    call_port({foo, X}).
    -bar(Y) ->
    -    call_port({bar, Y}).
    +foo(X) ->
    +    call_port({foo, X}).
    +bar(Y) ->
    +    call_port({bar, Y}).
     
    -call_port(Msg) ->
    -    complex ! {call, self(), Msg},
    +call_port(Msg) ->
    +    complex ! {call, self(), Msg},
         receive
    -	{complex, Result} ->
    +	{complex, Result} ->
     	    Result
         end.
     
    -init(ExtPrg) ->
    -    register(complex, self()),
    -    process_flag(trap_exit, true),
    -    Port = open_port({spawn, ExtPrg}, [{packet, 2}, binary]),
    -    loop(Port).
    +init(ExtPrg) ->
    +    register(complex, self()),
    +    process_flag(trap_exit, true),
    +    Port = open_port({spawn, ExtPrg}, [{packet, 2}, binary]),
    +    loop(Port).
     
    -loop(Port) ->
    +loop(Port) ->
         receive
    -	{call, Caller, Msg} ->
    -	    Port ! {self(), {command, term_to_binary(Msg)}},
    +	{call, Caller, Msg} ->
    +	    Port ! {self(), {command, term_to_binary(Msg)}},
     	    receive
    -		{Port, {data, Data}} ->
    -		    Caller ! {complex, binary_to_term(Data)}
    +		{Port, {data, Data}} ->
    +		    Caller ! {complex, binary_to_term(Data)}
     	    end,
    -	    loop(Port);
    +	    loop(Port);
     	stop ->
    -	    Port ! {self(), close},
    +	    Port ! {self(), close},
     	    receive
    -		{Port, closed} ->
    -		    exit(normal)
    +		{Port, closed} ->
    +		    exit(normal)
     	    end;
    -	{'EXIT', Port, Reason} ->
    -	    exit(port_terminated)
    +	{'EXIT', Port, Reason} ->
    +	    exit(port_terminated)
         end.

    Notice that calling complex2:foo/1 and complex2:bar/1 results in the tuple {foo,X} or {bar,Y} being sent to the complex process, which codes them as binaries and sends them to the port. This means that the C program must be able @@ -248,53 +248,53 @@

    typedef unsigned char byte; -int read_cmd(byte *buf); -int write_cmd(byte *buf, int len); -int foo(int x); -int bar(int y); +int read_cmd(byte *buf); +int write_cmd(byte *buf, int len); +int foo(int x); +int bar(int y); -static void fail(int place) { - fprintf(stderr, "Something went wrong %d\n", place); - exit(1); -} +static void fail(int place) { + fprintf(stderr, "Something went wrong %d\n", place); + exit(1); +} -int main() { - byte buf[100]; +int main() { + byte buf[100]; int index = 0; int version = 0; int arity = 0; - char atom[128]; + char atom[128]; long in = 0; int res = 0; ei_x_buff res_buf; - ei_init(); - while (read_cmd(buf) > 0) { - if (ei_decode_version(buf, &index, &version) != 0) - fail(1); - if (ei_decode_tuple_header(buf, &index, &arity) != 0) - fail(2); - if (arity != 2) - fail(3); - if (ei_decode_atom(buf, &index, atom) != 0) - fail(4); - if (ei_decode_long(buf, &index, &in) != 0) - fail(5); - if (strncmp(atom, "foo", 3) == 0) { - res = foo((int)in); - } else if (strncmp(atom, "bar", 3) == 0) { - res = bar((int)in); - } - if (ei_x_new_with_version(&res_buf) != 0) - fail(6); - if (ei_x_encode_long(&res_buf, res) != 0) - fail(7); - write_cmd(res_buf.buff, res_buf.index); - - if (ei_x_free(&res_buf) != 0) - fail(8); + ei_init(); + while (read_cmd(buf) > 0) { + if (ei_decode_version(buf, &index, &version) != 0) + fail(1); + if (ei_decode_tuple_header(buf, &index, &arity) != 0) + fail(2); + if (arity != 2) + fail(3); + if (ei_decode_atom(buf, &index, atom) != 0) + fail(4); + if (ei_decode_long(buf, &index, &in) != 0) + fail(5); + if (strncmp(atom, "foo", 3) == 0) { + res = foo((int)in); + } else if (strncmp(atom, "bar", 3) == 0) { + res = bar((int)in); + } + if (ei_x_new_with_version(&res_buf) != 0) + fail(6); + if (ei_x_encode_long(&res_buf, res) != 0) + fail(7); + write_cmd(res_buf.buff, res_buf.index); + + if (ei_x_free(&res_buf) != 0) + fail(8); index = 0; - } -}

    The following functions, read_cmd() and write_cmd(), from the erl_comm.c + } +}

    The following functions, read_cmd() and write_cmd(), from the erl_comm.c example in Ports can still be used for reading from and writing to the port:

    /* erl_comm.c */
     
    @@ -303,55 +303,55 @@ 

    typedef unsigned char byte; -int read_exact(byte *buf, int len) -{ +int read_exact(byte *buf, int len) +{ int i, got=0; - do { - if ((i = read(0, buf+got, len-got)) <= 0){ - return(i); - } + do { + if ((i = read(0, buf+got, len-got)) <= 0){ + return(i); + } got += i; - } while (got<len); + } while (got<len); - return(len); -} + return(len); +} -int write_exact(byte *buf, int len) -{ +int write_exact(byte *buf, int len) +{ int i, wrote = 0; - do { - if ((i = write(1, buf+wrote, len-wrote)) <= 0) - return (i); + do { + if ((i = write(1, buf+wrote, len-wrote)) <= 0) + return (i); wrote += i; - } while (wrote<len); + } while (wrote<len); - return (len); -} + return (len); +} -int read_cmd(byte *buf) -{ +int read_cmd(byte *buf) +{ int len; - if (read_exact(buf, 2) != 2) - return(-1); - len = (buf[0] << 8) | buf[1]; - return read_exact(buf, len); -} + if (read_exact(buf, 2) != 2) + return(-1); + len = (buf[0] << 8) | buf[1]; + return read_exact(buf, len); +} -int write_cmd(byte *buf, int len) -{ +int write_cmd(byte *buf, int len) +{ byte li; - li = (len >> 8) & 0xff; - write_exact(&li, 1); + li = (len >> 8) & 0xff; + write_exact(&li, 1); li = len & 0xff; - write_exact(&li, 1); + write_exact(&li, 1); - return write_exact(buf, len); -}

    + return write_exact(buf, len); +}

    @@ -366,19 +366,19 @@

    and VSN is the version of the Erl_interface application (3.2.1 in the recent example).

    In R4B and earlier versions of OTP, include and lib are situated under $OTPROOT/usr.

    Step 2. Start Erlang and compile the Erlang code:

    $ erl
    -Erlang/OTP 26 [erts-14.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]
    +Erlang/OTP 26 [erts-14.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]
     
    -Eshell V14.2 (press Ctrl+G to abort, type help(). for help)
    -1> c(complex2).
    -{ok,complex2}

    Step 3. Run the example:

    2> complex2:start("./extprg").
    +Eshell V14.2 (press Ctrl+G to abort, type help(). for help)
    +1> c(complex2).
    +{ok,complex2}

    Step 3. Run the example:

    2> complex2:start("./extprg").
     <0.34.0>
    -3> complex2:foo(3).
    +3> complex2:foo(3).
     4
    -4> complex2:bar(5).
    +4> complex2:bar(5).
     10
    -5> complex2:bar(352).
    +5> complex2:bar(352).
     704
    -6> complex2:stop().
    +6> complex2:stop().
     stop

    diff --git a/prs/8803/doc/system/error_logging.html b/prs/8803/doc/system/error_logging.html index fb2712a62d78b..37a67ef54e32e 100644 --- a/prs/8803/doc/system/error_logging.html +++ b/prs/8803/doc/system/error_logging.html @@ -147,7 +147,7 @@

    logger_sasl_compatible to true. For more information, see SASL Error Logging in the SASL User's Guide.

    % erl -kernel logger_level info
    -Erlang/OTP 21 [erts-10.0] [source-13c50db] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]
    +Erlang/OTP 21 [erts-10.0] [source-13c50db] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]
     
     =PROGRESS REPORT==== 8-Jun-2018::16:54:19.916404 ===
         application: kernel
    @@ -156,22 +156,22 @@ 

    application: stdlib started_at: nonode@nohost =PROGRESS REPORT==== 8-Jun-2018::16:54:19.925755 === - supervisor: {local,kernel_safe_sup} - started: [{pid,<0.74.0>}, - {id,disk_log_sup}, - {mfargs,{disk_log_sup,start_link,[]}}, - {restart_type,permanent}, - {shutdown,1000}, - {child_type,supervisor}] + supervisor: {local,kernel_safe_sup} + started: [{pid,<0.74.0>}, + {id,disk_log_sup}, + {mfargs,{disk_log_sup,start_link,[]}}, + {restart_type,permanent}, + {shutdown,1000}, + {child_type,supervisor}] =PROGRESS REPORT==== 8-Jun-2018::16:54:19.926056 === - supervisor: {local,kernel_safe_sup} - started: [{pid,<0.75.0>}, - {id,disk_log_server}, - {mfargs,{disk_log_server,start_link,[]}}, - {restart_type,permanent}, - {shutdown,2000}, - {child_type,worker}] -Eshell V10.0 (abort with ^G) + supervisor: {local,kernel_safe_sup} + started: [{pid,<0.75.0>}, + {id,disk_log_server}, + {mfargs,{disk_log_server,start_link,[]}}, + {restart_type,permanent}, + {shutdown,2000}, + {child_type,worker}] +Eshell V10.0 (abort with ^G) 1>

    diff --git a/prs/8803/doc/system/errors.html b/prs/8803/doc/system/errors.html index e774610dfc089..dd2a7709174e3 100644 --- a/prs/8803/doc/system/errors.html +++ b/prs/8803/doc/system/errors.html @@ -155,14 +155,14 @@

    Exit Reason), and a stack trace (which aids in finding the code location of the exception).

    The stack trace can be bound to a variable from within a try expression for any exception class, or as part of the exit reason when a run-time error is -caught by a catch. Example:

    > {'EXIT',{test,Stacktrace}} = (catch error(test)), Stacktrace.
    -[{shell,apply_fun,3,[]},
    - {erl_eval,do_apply,6,[]},
    - ...]
    -> try throw(test) catch Class:Reason:Stacktrace -> Stacktrace end.
    -[{shell,apply_fun,3,[]},
    - {erl_eval,do_apply,6,[]},
    - ...]

    +caught by a catch. Example:

    > {'EXIT',{test,Stacktrace}} = (catch error(test)), Stacktrace.
    +[{shell,apply_fun,3,[]},
    + {erl_eval,do_apply,6,[]},
    + ...]
    +> try throw(test) catch Class:Reason:Stacktrace -> Stacktrace end.
    +[{shell,apply_fun,3,[]},
    + {erl_eval,do_apply,6,[]},
    + ...]

    diff --git a/prs/8803/doc/system/events.html b/prs/8803/doc/system/events.html index 6ca88a64a42b7..0ef6a45775bce 100644 --- a/prs/8803/doc/system/events.html +++ b/prs/8803/doc/system/events.html @@ -139,35 +139,35 @@

    Example

    The callback module for the event handler writing error messages to the terminal -can look as follows:

    -module(terminal_logger).
    --behaviour(gen_event).
    +can look as follows:

    -module(terminal_logger).
    +-behaviour(gen_event).
     
    --export([init/1, handle_event/2, terminate/2]).
    +-export([init/1, handle_event/2, terminate/2]).
     
    -init(_Args) ->
    -    {ok, []}.
    +init(_Args) ->
    +    {ok, []}.
     
    -handle_event(ErrorMsg, State) ->
    -    io:format("***Error*** ~p~n", [ErrorMsg]),
    -    {ok, State}.
    +handle_event(ErrorMsg, State) ->
    +    io:format("***Error*** ~p~n", [ErrorMsg]),
    +    {ok, State}.
     
    -terminate(_Args, _State) ->
    +terminate(_Args, _State) ->
         ok.

    The callback module for the event handler writing error messages to a file can -look as follows:

    -module(file_logger).
    --behaviour(gen_event).
    +look as follows:

    -module(file_logger).
    +-behaviour(gen_event).
     
    --export([init/1, handle_event/2, terminate/2]).
    +-export([init/1, handle_event/2, terminate/2]).
     
    -init(File) ->
    -    {ok, Fd} = file:open(File, read),
    -    {ok, Fd}.
    +init(File) ->
    +    {ok, Fd} = file:open(File, read),
    +    {ok, Fd}.
     
    -handle_event(ErrorMsg, Fd) ->
    -    io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),
    -    {ok, Fd}.
    +handle_event(ErrorMsg, Fd) ->
    +    io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),
    +    {ok, Fd}.
     
    -terminate(_Args, Fd) ->
    -    file:close(Fd).

    The code is explained in the next sections.

    +terminate(_Args, Fd) -> + file:close(Fd).

    The code is explained in the next sections.

    @@ -188,19 +188,19 @@

    Adding an Event Handler

    The following example shows how to start an event manager and add an event -handler to it by using the shell:

    1> gen_event:start({local, error_man}).
    -{ok,<0.31.0>}
    -2> gen_event:add_handler(error_man, terminal_logger, []).
    +handler to it by using the shell:

    1> gen_event:start({local, error_man}).
    +{ok,<0.31.0>}
    +2> gen_event:add_handler(error_man, terminal_logger, []).
     ok

    This function sends a message to the event manager registered as error_man, telling it to add the event handler terminal_logger. The event manager calls the callback function terminal_logger:init([]), where the argument [] is the third argument to add_handler. init/1 is expected to return {ok, State}, -where State is the internal state of the event handler.

    init(_Args) ->
    -    {ok, []}.

    Here, init/1 does not need any input data and ignores its argument. For +where State is the internal state of the event handler.

    init(_Args) ->
    +    {ok, []}.

    Here, init/1 does not need any input data and ignores its argument. For terminal_logger, the internal state is not used. For file_logger, the -internal state is used to save the open file descriptor.

    init(File) ->
    -    {ok, Fd} = file:open(File, read),
    -    {ok, Fd}.

    +internal state is used to save the open file descriptor.

    init(File) ->
    +    {ok, Fd} = file:open(File, read),
    +    {ok, Fd}.

    @@ -212,25 +212,25 @@

    is received, the event manager calls handle_event(Event, State) for each installed event handler, in the same order as they were added. The function is expected to return a tuple {ok,State1}, where State1 is a new value for the -state of the event handler.

    In terminal_logger:

    handle_event(ErrorMsg, State) ->
    -    io:format("***Error*** ~p~n", [ErrorMsg]),
    -    {ok, State}.

    In file_logger:

    handle_event(ErrorMsg, Fd) ->
    -    io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),
    -    {ok, Fd}.

    +state of the event handler.

    In terminal_logger:

    handle_event(ErrorMsg, State) ->
    +    io:format("***Error*** ~p~n", [ErrorMsg]),
    +    {ok, State}.

    In file_logger:

    handle_event(ErrorMsg, Fd) ->
    +    io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),
    +    {ok, Fd}.

    Deleting an Event Handler

    -
    4> gen_event:delete_handler(error_man, terminal_logger, []).
    +
    4> gen_event:delete_handler(error_man, terminal_logger, []).
     ok

    This function sends a message to the event manager registered as error_man, telling it to delete the event handler terminal_logger. The event manager calls the callback function terminal_logger:terminate([], State), where the argument [] is the third argument to delete_handler. terminate/2 is to be the opposite of init/1 and do any necessary cleaning up. Its return value is -ignored.

    For terminal_logger, no cleaning up is necessary:

    terminate(_Args, _State) ->
    -    ok.

    For file_logger, the file descriptor opened in init must be closed:

    terminate(_Args, Fd) ->
    -    file:close(Fd).

    +ignored.

    For terminal_logger, no cleaning up is necessary:

    terminate(_Args, _State) ->
    +    ok.

    For file_logger, the file descriptor opened in init must be closed:

    terminate(_Args, Fd) ->
    +    file:close(Fd).

    @@ -253,7 +253,7 @@

    Standalone Event Managers

    -

    An event manager can also be stopped by calling:

    1> gen_event:stop(error_man).
    +

    An event manager can also be stopped by calling:

    1> gen_event:stop(error_man).
     ok

    @@ -265,13 +265,13 @@

    implemented to handle them. Examples of other messages are exit messages if the event manager is linked to other processes than the supervisor (for example via gen_event:add_sup_handler/3) and is -trapping exit signals.

    handle_info({'EXIT', Pid, Reason}, State) ->
    +trapping exit signals.

    handle_info({'EXIT', Pid, Reason}, State) ->
         %% Code to handle exits here.
         ...
    -    {noreply, State1}.

    The final function to implement is code_change/3:

    code_change(OldVsn, State, Extra) ->
    +    {noreply, State1}.

    The final function to implement is code_change/3:

    code_change(OldVsn, State, Extra) ->
         %% Code to convert state (and more) during code change.
         ...
    -    {ok, NewState}.
    +
    {ok, NewState}.

    diff --git a/prs/8803/doc/system/example.html b/prs/8803/doc/system/example.html index 0d338aa4bba0a..bff90d1c70095 100644 --- a/prs/8803/doc/system/example.html +++ b/prs/8803/doc/system/example.html @@ -125,17 +125,17 @@

    code, solving a complex problem, in your Erlang program. Suppose for example, that you have the following C functions that you would like to call from Erlang:

    /* complex.c */
     
    -int foo(int x) {
    +int foo(int x) {
       return x+1;
    -}
    +}
     
    -int bar(int y) {
    +int bar(int y) {
       return y*2;
    -}

    The functions are deliberately kept as simple as possible, for readability +}

    The functions are deliberately kept as simple as possible, for readability reasons.

    From an Erlang perspective, it is preferable to be able to call foo and bar without having to bother about that they are C functions:

    % Erlang code
     ...
    -Res = complex:foo(X),
    +Res = complex:foo(X),
     ...

    Here, the communication with C is hidden in the implementation of complex.erl. In the following sections, it is shown how this module can be implemented using the different interoperability mechanisms.

    diff --git a/prs/8803/doc/system/expressions.html b/prs/8803/doc/system/expressions.html index f6da19ae84b68..c44aaf569e512 100644 --- a/prs/8803/doc/system/expressions.html +++ b/prs/8803/doc/system/expressions.html @@ -155,12 +155,12 @@

    single assignment, that is, a variable can only be bound once.

    The anonymous variable is denoted by underscore (_) and can be used when a variable is required but its value can be ignored.

    Example:

    [H|_] = [1,2,3]

    Variables starting with underscore (_), for example, _Height, are normal variables, not anonymous. However, they are ignored by the compiler in the sense -that they do not generate warnings.

    Example:

    The following code:

    member(_, []) ->
    -    [].

    can be rewritten to be more readable:

    member(Elem, []) ->
    -    [].

    This causes a warning for an unused variable, Elem. To avoid the warning, -the code can be rewritten to:

    member(_Elem, []) ->
    -    [].

    Notice that since variables starting with an underscore are not anonymous, the -following example matches:

    {_,_} = {1,2}

    But this example fails:

    {_N,_N} = {1,2}

    The scope for a variable is its function clause. Variables bound in a branch of +that they do not generate warnings.

    Example:

    The following code:

    member(_, []) ->
    +    [].

    can be rewritten to be more readable:

    member(Elem, []) ->
    +    [].

    This causes a warning for an unused variable, Elem. To avoid the warning, +the code can be rewritten to:

    member(_Elem, []) ->
    +    [].

    Notice that since variables starting with an underscore are not anonymous, the +following example matches:

    {_,_} = {1,2}

    But this example fails:

    {_N,_N} = {1,2}

    The scope for a variable is its function clause. Variables bound in a branch of an if, case, or receive expression must be bound in all branches to have a value outside the expression. Otherwise they are regarded as unsafe outside the expression.

    For the try expression variable scoping is limited so that variables bound in @@ -171,8 +171,8 @@

    Patterns

    A pattern has the same structure as a term but can contain unbound variables.

    Example:

    Name1
    -[H|T]
    -{error,Reason}

    Patterns are allowed in clause heads, case expressions, +[H|T] +{error,Reason}

    Patterns are allowed in clause heads, case expressions, receive expressions, and match expressions.

    @@ -182,13 +182,13 @@

    If Pattern1 and Pattern2 are valid patterns, the following is also a valid pattern:

    Pattern1 = Pattern2

    When matched against a term, both Pattern1 and Pattern2 are matched against -the term. The idea behind this feature is to avoid reconstruction of terms.

    Example:

    f({connect,From,To,Number,Options}, To) ->
    -    Signal = {connect,From,To,Number,Options},
    +the term. The idea behind this feature is to avoid reconstruction of terms.

    Example:

    f({connect,From,To,Number,Options}, To) ->
    +    Signal = {connect,From,To,Number,Options},
         ...;
    -f(Signal, To) ->
    -    ignore.

    can instead be written as

    f({connect,_,To,_,_} = Signal, To) ->
    +f(Signal, To) ->
    +    ignore.

    can instead be written as

    f({connect,_,To,_,_} = Signal, To) ->
         ...;
    -f(Signal, To) ->
    +f(Signal, To) ->
         ignore.

    The compound pattern operator does not imply that its operands are matched in any particular order. That means that it is not legal to bind a variable in Pattern1 and use it in Pattern2, or vice versa.

    @@ -197,15 +197,15 @@

    String Prefix in Patterns

    -

    When matching strings, the following is a valid pattern:

    f("prefix" ++ Str) -> ...

    This is syntactic sugar for the equivalent, but harder to read:

    f([$p,$r,$e,$f,$i,$x | Str]) -> ...

    +

    When matching strings, the following is a valid pattern:

    f("prefix" ++ Str) -> ...

    This is syntactic sugar for the equivalent, but harder to read:

    f([$p,$r,$e,$f,$i,$x | Str]) -> ...

    Expressions in Patterns

    An arithmetic expression can be used within a pattern if it meets both of the -following two conditions:

    • It uses only numeric or bitwise operators.
    • Its value can be evaluated to a constant when complied.

    Example:

    case {Value, Result} of
    -    {?THRESHOLD+1, ok} -> ...

    +following two conditions:

    • It uses only numeric or bitwise operators.
    • Its value can be evaluated to a constant when complied.

    Example:

    case {Value, Result} of
    +    {?THRESHOLD+1, ok} -> ...

    @@ -213,15 +213,15 @@

    The following matches Pattern against Expr:

    Pattern = Expr

    If the matching succeeds, any unbound variable in the pattern becomes bound and the value of Expr is returned.

    If multiple match operators are applied in sequence, they will be evaluated from -right to left.

    If the matching fails, a badmatch run-time error occurs.

    Examples:

    1> {A, B} = T = {answer, 42}.
    -{answer,42}
    +right to left.

    If the matching fails, a badmatch run-time error occurs.

    Examples:

    1> {A, B} = T = {answer, 42}.
    +{answer,42}
     2> A.
     answer
     3> B.
     42
     4> T.
    -{answer,42}
    -5> {C, D} = [1, 2].
    +{answer,42}
    +5> {C, D} = [1, 2].
     ** exception error: no match of right-hand side value [1,2]

    Because multiple match operators are evaluated from right to left, it means that:

    Pattern1 = Pattern2 = . . . = PatternN = Expression

    is equivalent to:

    Temporary = Expression,
     PatternN = Temporary,
    @@ -243,20 +243,20 @@ 

    compound pattern matches if all of its constituent patterns match. It is not legal for a pattern that is part of a compound pattern to use variables (as keys in map patterns or sizes in binary patterns) bound in other sub patterns of the -same compound pattern.

    Examples:

    1> fun(#{Key := Value} = #{key := Key}) -> Value end.
    +same compound pattern.

    Examples:

    1> fun(#{Key := Value} = #{key := Key}) -> Value end.
     * 1:7: variable 'Key' is unbound
    -2> F = fun({A, B} = E) -> {E, A + B} end, F({1,2}).
    -{{1,2},3}
    -3> G = fun(<<A:8,B:8>> = <<C:16>>) -> {A, B, C} end, G(<<42,43>>).
    -{42,43,10795}

    The match operator is allowed everywhere an expression is allowed. It is used +2> F = fun({A, B} = E) -> {E, A + B} end, F({1,2}). +{{1,2},3} +3> G = fun(<<A:8,B:8>> = <<C:16>>) -> {A, B, C} end, G(<<42,43>>). +{42,43,10795}

    The match operator is allowed everywhere an expression is allowed. It is used to match the value of an expression to a pattern. If multiple match operators -are applied in sequence, they will be evaluated from right to left.

    Examples:

    1> M = #{key => key2, key2 => value}.
    -#{key => key2,key2 => value}
    -2> f(Key), #{Key := Value} = #{key := Key} = M, Value.
    +are applied in sequence, they will be evaluated from right to left.

    Examples:

    1> M = #{key => key2, key2 => value}.
    +#{key => key2,key2 => value}
    +2> f(Key), #{Key := Value} = #{key := Key} = M, Value.
     value
    -3> f(Key), #{Key := Value} = (#{key := Key} = M), Value.
    +3> f(Key), #{Key := Value} = (#{key := Key} = M), Value.
     value
    -4> f(Key), (#{Key := Value} = #{key := Key}) = M, Value.
    +4> f(Key), (#{Key := Value} = #{key := Key}) = M, Value.
     * 1:12: variable 'Key' is unbound
     5> <<X:Y>> = begin Y = 8, <<42:8>> end, X.
     42

    The expression at prompt 2> first matches the value of variable M against @@ -280,22 +280,22 @@

    Function Calls

    -
    ExprF(Expr1,...,ExprN)
    -ExprM:ExprF(Expr1,...,ExprN)

    In the first form of function calls, ExprM:ExprF(Expr1,...,ExprN), each of +

    ExprF(Expr1,...,ExprN)
    +ExprM:ExprF(Expr1,...,ExprN)

    In the first form of function calls, ExprM:ExprF(Expr1,...,ExprN), each of ExprM and ExprF must be an atom or an expression that evaluates to an atom. The function is said to be called by using the fully qualified function name. -This is often referred to as a remote or external function call.

    Example:

    lists:keyfind(Name, 1, List)

    In the second form of function calls, ExprF(Expr1,...,ExprN), ExprF must be +This is often referred to as a remote or external function call.

    Example:

    lists:keyfind(Name, 1, List)

    In the second form of function calls, ExprF(Expr1,...,ExprN), ExprF must be an atom or evaluate to a fun.

    If ExprF is an atom, the function is said to be called by using the implicitly qualified function name. If the function ExprF is locally defined, it is called. Alternatively, if ExprF is explicitly imported from the M module, M:ExprF(Expr1,...,ExprN) is called. If ExprF is neither declared locally nor explicitly imported, ExprF must be the name of an automatically -imported BIF.

    Examples:

    handle(Msg, State)
    -spawn(m, init, [])

    Examples where ExprF is a fun:

    1> Fun1 = fun(X) -> X+1 end,
    -Fun1(3).
    +imported BIF.

    Examples:

    handle(Msg, State)
    +spawn(m, init, [])

    Examples where ExprF is a fun:

    1> Fun1 = fun(X) -> X+1 end,
    +Fun1(3).
     4
    -2> fun lists:append/2([1,2], [3,4]).
    -[1,2,3,4]
    +2> fun lists:append/2([1,2], [3,4]).
    +[1,2,3,4]
     3>

    Notice that when calling a local function, there is a difference between using the implicitly or fully qualified function name. The latter always refers to the latest version of the module. See @@ -320,32 +320,32 @@

    (ERTS version 5.8) and have an implicitly qualified call to that function in your code, you either need to explicitly remove the auto-import using a compiler directive, or replace the call with a fully qualified function call. Otherwise -you get a compilation error. See the following example:

    -export([length/1,f/1]).
    +you get a compilation error. See the following example:

    -export([length/1,f/1]).
     
    --compile({no_auto_import,[length/1]}). % erlang:length/1 no longer autoimported
    +-compile({no_auto_import,[length/1]}). % erlang:length/1 no longer autoimported
     
    -length([]) ->
    +length([]) ->
         0;
    -length([H|T]) ->
    -    1 + length(T). %% Calls the local function length/1
    +length([H|T]) ->
    +    1 + length(T). %% Calls the local function length/1
     
    -f(X) when erlang:length(X) > 3 -> %% Calls erlang:length/1,
    +f(X) when erlang:length(X) > 3 -> %% Calls erlang:length/1,
                                       %% which is allowed in guards
         long.

    The same logic applies to explicitly imported functions from other modules, as to locally defined functions. It is not allowed to both import a function from -another module and have the function declared in the module at the same time:

    -export([f/1]).
    +another module and have the function declared in the module at the same time:

    -export([f/1]).
     
    --compile({no_auto_import,[length/1]}). % erlang:length/1 no longer autoimported
    +-compile({no_auto_import,[length/1]}). % erlang:length/1 no longer autoimported
     
    --import(mod,[length/1]).
    +-import(mod,[length/1]).
     
    -f(X) when erlang:length(X) > 33 -> %% Calls erlang:length/1,
    +f(X) when erlang:length(X) > 33 -> %% Calls erlang:length/1,
                                        %% which is allowed in guards
     
    -    erlang:length(X);              %% Explicit call to erlang:length in body
    +    erlang:length(X);              %% Explicit call to erlang:length in body
     
    -f(X) ->
    -    length(X).                     %% mod:length/1 is called

    For auto-imported BIFs added in Erlang/OTP R14A and thereafter, overriding the +f(X) -> + length(X). %% mod:length/1 is called

    For auto-imported BIFs added in Erlang/OTP R14A and thereafter, overriding the name with a local function or explicit import is always allowed. However, if the -compile({no_auto_import,[F/A]) directive is not used, the compiler issues a warning whenever the function is called in the module using the implicitly @@ -365,7 +365,7 @@

    sequence GuardSeq that evaluates to true is found. Then the corresponding Body (a sequence of expressions separated by ,) is evaluated.

    The return value of Body is the return value of the if expression.

    If no guard sequence is evaluated as true, an if_clause run-time error occurs. If necessary, the guard expression true can be used in the last branch, as -that guard sequence is always true.

    Example:

    is_greater_than(X, Y) ->
    +that guard sequence is always true.

    Example:

    is_greater_than(X, Y) ->
         if
             X > Y ->
                 true;
    @@ -378,19 +378,19 @@ 

    Case

    case Expr of
    -    Pattern1 [when GuardSeq1] ->
    +    Pattern1 [when GuardSeq1] ->
             Body1;
         ...;
    -    PatternN [when GuardSeqN] ->
    +    PatternN [when GuardSeqN] ->
             BodyN
     end

    The expression Expr is evaluated and the patterns Pattern are sequentially matched against the result. If a match succeeds and the optional guard sequence GuardSeq is true, the corresponding Body is evaluated.

    The return value of Body is the return value of the case expression.

    If there is no matching pattern with a true guard sequence, a case_clause -run-time error occurs.

    Example:

    is_valid_signal(Signal) ->
    +run-time error occurs.

    Example:

    is_valid_signal(Signal) ->
         case Signal of
    -        {signal, _What, _From, _To} ->
    +        {signal, _What, _From, _To} ->
                 true;
    -        {signal, _What, _To} ->
    +        {signal, _What, _To} ->
                 true;
             _Else ->
                 false
    @@ -416,9 +416,9 @@ 

    expressions in the maybe block are skipped and the return value of the maybe block is Expr2.

    None of the variables bound in a maybe block must be used in the code that follows the block.

    Here is an example:

    maybe
    -    {ok, A} ?= a(),
    +    {ok, A} ?= a(),
         true = A >= 0,
    -    {ok, B} ?= b(),
    +    {ok, B} ?= b(),
         A + B
     end

    Let us first assume that a() returns {ok,42} and b() returns {ok,58}. With those return values, all of the match operators will succeed, and the @@ -427,11 +427,11 @@

    the value of the expression that failed to match, namely error. Similarly, if b() returns wrong, the return value of the maybe block is wrong.

    Finally, let us assume that a() returns {ok,-1}. Because true = A >= 0 uses the match operator =, a {badmatch,false} run-time error occurs when the -expression fails to match the pattern.

    The example can be written in a less succient way using nested case expressions:

    case a() of
    -    {ok, A} ->
    +expression fails to match the pattern.

    The example can be written in a less succient way using nested case expressions:

    case a() of
    +    {ok, A} ->
             true = A >= 0,
    -        case b() of
    -            {ok, B} ->
    +        case b() of
    +            {ok, B} ->
                     A + B;
                 Other1 ->
                     Other1
    @@ -443,10 +443,10 @@ 

    ..., ExprN else - Pattern1 [when GuardSeq1] -> + Pattern1 [when GuardSeq1] -> Body1; ...; - PatternN [when GuardSeqN] -> + PatternN [when GuardSeqN] -> BodyN end

    If a conditional match operator fails, the failed expression is matched against the patterns in all clauses between the else and end keywords. If a match @@ -456,9 +456,9 @@

    run-time error occurs.

    None of the variables bound in a maybe block must be used in the else clauses. None of the variables bound in the else clauses must be used in the code that follows the maybe block.

    Here is the previous example augmented with else clauses:

    maybe
    -    {ok, A} ?= a(),
    +    {ok, A} ?= a(),
         true = A >= 0,
    -    {ok, B} ?= b(),
    +    {ok, B} ?= b(),
         A + B
     else
         error -> error;
    @@ -485,10 +485,10 @@ 

    Receive

    receive
    -    Pattern1 [when GuardSeq1] ->
    +    Pattern1 [when GuardSeq1] ->
             Body1;
         ...;
    -    PatternN [when GuardSeqN] ->
    +    PatternN [when GuardSeqN] ->
             BodyN
     end

    Fetches a received message present in the message queue of the process. The first message in the message queue is matched sequentially against the patterns @@ -500,19 +500,19 @@

    corresponding Body is evaluated. All other messages in the message queue remain unchanged.

    The return value of Body is the return value of the receive expression.

    receive never fails. The execution is suspended, possibly indefinitely, until a message arrives that matches one of the patterns and with a true guard -sequence.

    Example:

    wait_for_onhook() ->
    +sequence.

    Example:

    wait_for_onhook() ->
         receive
             onhook ->
    -            disconnect(),
    -            idle();
    -        {connect, B} ->
    -            B ! {busy, self()},
    -            wait_for_onhook()
    +            disconnect(),
    +            idle();
    +        {connect, B} ->
    +            B ! {busy, self()},
    +            wait_for_onhook()
         end.

    The receive expression can be augmented with a timeout:

    receive
    -    Pattern1 [when GuardSeq1] ->
    +    Pattern1 [when GuardSeq1] ->
             Body1;
         ...;
    -    PatternN [when GuardSeqN] ->
    +    PatternN [when GuardSeqN] ->
             BodyN
     after
         ExprT ->
    @@ -525,27 +525,27 @@ 

    timeout is almost 50 days. With a zero value the timeout occurs immediately if there is no matching message in the message queue.

    The atom infinity will make the process wait indefinitely for a matching message. This is the same as not using a timeout. It can be useful for timeout -values that are calculated at runtime.

    Example:

    wait_for_onhook() ->
    +values that are calculated at runtime.

    Example:

    wait_for_onhook() ->
         receive
             onhook ->
    -            disconnect(),
    -            idle();
    -        {connect, B} ->
    -            B ! {busy, self()},
    -            wait_for_onhook()
    +            disconnect(),
    +            idle();
    +        {connect, B} ->
    +            B ! {busy, self()},
    +            wait_for_onhook()
         after
             60000 ->
    -            disconnect(),
    -            error()
    +            disconnect(),
    +            error()
         end.

    It is legal to use a receive...after expression with no branches:

    receive
     after
         ExprT ->
             BodyT
     end

    This construction does not consume any messages, only suspends execution in the -process for ExprT milliseconds. This can be used to implement simple timers.

    Example:

    timer() ->
    -    spawn(m, timer, [self()]).
    +process for ExprT milliseconds. This can be used to implement simple timers.

    Example:

    timer() ->
    +    spawn(m, timer, [self()]).
     
    -timer(Pid) ->
    +timer(Pid) ->
         receive
         after
             5000 ->
    @@ -592,9 +592,9 @@ 

    true 6> 1 > a. false -7> #{c => 3} > #{a => 1, b => 2}. +7> #{c => 3} > #{a => 1, b => 2}. false -8> #{a => 1, b => 2} == #{a => 1.0, b => 2.0}. +8> #{a => 1, b => 2} == #{a => 1.0, b => 2.0}. true 9> <<2:2>> < <<128>>. true @@ -632,7 +632,7 @@

    ** exception error: an error occurred when evaluating an arithmetic expression in operator +/2 called as a + 10 -10> 1 bsl (1 bsl 64). +10> 1 bsl (1 bsl 64). ** exception error: a system limit has been reached in operator bsl/2 called as 1 bsl 18446744073709551616

    @@ -659,12 +659,12 @@

    Expr1 orelse Expr2
     Expr1 andalso Expr2

    Expr2 is evaluated only if necessary. That is, Expr2 is evaluated only if:

    • Expr1 evaluates to false in an orelse expression.

    or

    • Expr1 evaluates to true in an andalso expression.

    Returns either the value of Expr1 (that is, true or false) or the value of -Expr2 (if Expr2 is evaluated).

    Example 1:

    case A >= -1.0 andalso math:sqrt(A+1) > B of

    This works even if A is less than -1.0, since in that case, math:sqrt/1 is -never evaluated.

    Example 2:

    OnlyOne = is_atom(L) orelse
    -         (is_list(L) andalso length(L) == 1),

    Expr2 is not required to evaluate to a Boolean value. Because of that, -andalso and orelse are tail-recursive.

    Example 3 (tail-recursive function):

    all(Pred, [Hd|Tail]) ->
    -    Pred(Hd) andalso all(Pred, Tail);
    -all(_, []) ->
    +Expr2 (if Expr2 is evaluated).

    Example 1:

    case A >= -1.0 andalso math:sqrt(A+1) > B of

    This works even if A is less than -1.0, since in that case, math:sqrt/1 is +never evaluated.

    Example 2:

    OnlyOne = is_atom(L) orelse
    +         (is_list(L) andalso length(L) == 1),

    Expr2 is not required to evaluate to a Boolean value. Because of that, +andalso and orelse are tail-recursive.

    Example 3 (tail-recursive function):

    all(Pred, [Hd|Tail]) ->
    +    Pred(Hd) andalso all(Pred, Tail);
    +all(_, []) ->
         true.

    Change

    Before Erlang/OTP R13A, Expr2 was required to evaluate to a Boolean value, and as consequence, andalso and orelse were not tail-recursive.

    @@ -676,10 +676,10 @@

    Expr1 -- Expr2

    The list concatenation operator ++ appends its second argument to its first and returns the resulting list.

    The list subtraction operator -- produces a list that is a copy of the first argument. The procedure is as follows: for each element in the second argument, -the first occurrence of this element (if any) is removed.

    Example:

    1> [1,2,3] ++ [4,5].
    -[1,2,3,4,5]
    -2> [1,2,3,2,1,2] -- [2,1,2].
    -[3,1,2]

    +the first occurrence of this element (if any) is removed.

    Example:

    1> [1,2,3] ++ [4,5].
    +[1,2,3,4,5]
    +2> [1,2,3,2,1,2] -- [2,1,2].
    +[3,1,2]

    @@ -692,18 +692,18 @@

    Creating Maps

    Constructing a new map is done by letting an expression K be associated with -another expression V:

    #{K => V}

    New maps can include multiple associations at construction by listing every -association:

    #{K1 => V1, ..., Kn => Vn}

    An empty map is constructed by not associating any terms with each other:

    #{}

    All keys and values in the map are terms. Any expression is first evaluated and +another expression V:

    #{K => V}

    New maps can include multiple associations at construction by listing every +association:

    #{K1 => V1, ..., Kn => Vn}

    An empty map is constructed by not associating any terms with each other:

    #{}

    All keys and values in the map are terms. Any expression is first evaluated and then the resulting terms are used as key and value respectively.

    Keys and values are separated by the => arrow and associations are separated -by a comma (,).

    Examples:

    M0 = #{},                 % empty map
    -M1 = #{a => <<"hello">>}, % single association with literals
    -M2 = #{1 => 2, b => b},   % multiple associations with literals
    -M3 = #{k => {A,B}},       % single association with variables
    -M4 = #{{"w", 1} => f()}.  % compound key associated with an evaluated expression

    Here, A and B are any expressions and M0 through M4 are the resulting -map terms.

    If two matching keys are declared, the latter key takes precedence.

    Example:

    1> #{1 => a, 1 => b}.
    -#{1 => b }
    -2> #{1.0 => a, 1 => b}.
    -#{1 => b, 1.0 => a}

    The order in which the expressions constructing the keys (and their associated +by a comma (,).

    Examples:

    M0 = #{},                 % empty map
    +M1 = #{a => <<"hello">>}, % single association with literals
    +M2 = #{1 => 2, b => b},   % multiple associations with literals
    +M3 = #{k => {A,B}},       % single association with variables
    +M4 = #{{"w", 1} => f()}.  % compound key associated with an evaluated expression

    Here, A and B are any expressions and M0 through M4 are the resulting +map terms.

    If two matching keys are declared, the latter key takes precedence.

    Example:

    1> #{1 => a, 1 => b}.
    +#{1 => b }
    +2> #{1.0 => a, 1 => b}.
    +#{1 => b, 1.0 => a}

    The order in which the expressions constructing the keys (and their associated values) are evaluated is not defined. The syntactic order of the key-value pairs in the construction is of no relevance, except in the recently mentioned case of two matching keys.

    @@ -713,24 +713,24 @@

    Updating Maps

    Updating a map has a similar syntax as constructing it.

    An expression defining the map to be updated is put in front of the expression -defining the keys to be updated and their respective values:

    M#{K => V}

    Here M is a term of type map and K and V are any expression.

    If key K does not match any existing key in the map, a new association is +defining the keys to be updated and their respective values:

    M#{K => V}

    Here M is a term of type map and K and V are any expression.

    If key K does not match any existing key in the map, a new association is created from key K to value V.

    If key K matches an existing key in map M, its associated value is replaced by the new value V. In both cases, the evaluated map expression returns a new -map.

    If M is not of type map, an exception of type badmap is raised.

    To only update an existing value, the following syntax is used:

    M#{K := V}

    Here M is a term of type map, V is an expression and K is an expression +map.

    If M is not of type map, an exception of type badmap is raised.

    To only update an existing value, the following syntax is used:

    M#{K := V}

    Here M is a term of type map, V is an expression and K is an expression that evaluates to an existing key in M.

    If key K does not match any existing keys in map M, an exception of type badkey is raised at runtime. If a matching key K is present in map M, its associated value is replaced by the new value V, and the evaluated map -expression returns a new map.

    If M is not of type map, an exception of type badmap is raised.

    Examples:

    M0 = #{},
    -M1 = M0#{a => 0},
    -M2 = M1#{a => 1, b => 2},
    -M3 = M2#{"function" => fun() -> f() end},
    -M4 = M3#{a := 2, b := 3}.  % 'a' and 'b' was added in `M1` and `M2`.

    Here M0 is any map. It follows that M1 through M4 are maps as well.

    More examples:

    1> M = #{1 => a}.
    -#{1 => a }
    -2> M#{1.0 => b}.
    -#{1 => a, 1.0 => b}.
    -3> M#{1 := b}.
    -#{1 => b}
    -4> M#{1.0 := b}.
    +expression returns a new map.

    If M is not of type map, an exception of type badmap is raised.

    Examples:

    M0 = #{},
    +M1 = M0#{a => 0},
    +M2 = M1#{a => 1, b => 2},
    +M3 = M2#{"function" => fun() -> f() end},
    +M4 = M3#{a := 2, b := 3}.  % 'a' and 'b' was added in `M1` and `M2`.

    Here M0 is any map. It follows that M1 through M4 are maps as well.

    More examples:

    1> M = #{1 => a}.
    +#{1 => a }
    +2> M#{1.0 => b}.
    +#{1 => a, 1.0 => b}.
    +3> M#{1 := b}.
    +#{1 => b}
    +4> M#{1.0 := b}.
     ** exception error: bad argument

    As in construction, the order in which the key and value expressions are evaluated is not defined. The syntactic order of the key-value pairs in the update is of no relevance, except in the case where two keys match. In that @@ -740,31 +740,31 @@

    Maps in Patterns

    -

    Matching of key-value associations from maps is done as follows:

    #{K := V} = M

    Here M is any map. The key K must be a +

    Matching of key-value associations from maps is done as follows:

    #{K := V} = M

    Here M is any map. The key K must be a guard expression, with all variables already bound. V can be any pattern with either bound or unbound variables.

    If the variable V is unbound, it becomes bound to the value associated with the key K, which must exist in the map M. If the variable V is bound, it must match the value associated with K in M.

    Change

    Before Erlang/OTP 23, the expression defining the key K was restricted to be -either a single variable or a literal.

    Example:

    1> M = #{"tuple" => {1,2}}.
    -#{"tuple" => {1,2}}
    -2> #{"tuple" := {1,B}} = M.
    -#{"tuple" => {1,2}}
    +either a single variable or a literal.

    Example:

    1> M = #{"tuple" => {1,2}}.
    +#{"tuple" => {1,2}}
    +2> #{"tuple" := {1,B}} = M.
    +#{"tuple" => {1,2}}
     3> B.
    -2.

    This binds variable B to integer 2.

    Similarly, multiple values from the map can be matched:

    #{K1 := V1, ..., Kn := Vn} = M

    Here keys K1 through Kn are any expressions with literals or bound +2.

    This binds variable B to integer 2.

    Similarly, multiple values from the map can be matched:

    #{K1 := V1, ..., Kn := Vn} = M

    Here keys K1 through Kn are any expressions with literals or bound variables. If all key expressions evaluate successfully and all keys exist in map M, all variables in V1 .. Vn is matched to the associated values of their respective keys.

    If the matching conditions are not met the match fails.

    Note that when matching a map, only the := operator (not the =>) is allowed as a delimiter for the associations.

    The order in which keys are declared in matching has no relevance.

    Duplicate keys are allowed in matching and match each pattern associated to the -keys:

    #{K := V1, K := V2} = M

    The empty map literal (#{}) matches any map when used as a pattern:

    #{} = Expr

    This expression matches if the expression Expr is of type map, otherwise it -fails with an exception badmatch.

    Here the key to be retrieved is constructed from an expression:

    #{{tag,length(List)} := V} = Map

    List must be an already bound variable.

    Matching Syntax

    Matching of literals as keys are allowed in function heads:

    %% only start if not_started
    -handle_call(start, From, #{state := not_started} = S) ->
    +keys:

    #{K := V1, K := V2} = M

    The empty map literal (#{}) matches any map when used as a pattern:

    #{} = Expr

    This expression matches if the expression Expr is of type map, otherwise it +fails with an exception badmatch.

    Here the key to be retrieved is constructed from an expression:

    #{{tag,length(List)} := V} = Map

    List must be an already bound variable.

    Matching Syntax

    Matching of literals as keys are allowed in function heads:

    %% only start if not_started
    +handle_call(start, From, #{state := not_started} = S) ->
     ...
    -    {reply, ok, S#{state := start}};
    +    {reply, ok, S#{state := start}};
     
     %% only change if started
    -handle_call(change, From, #{state := start} = S) ->
    +handle_call(change, From, #{state := start} = S) ->
     ...
    -    {reply, ok, S#{state := changed}};

    + {reply, ok, S#{state := changed}};

    @@ -851,17 +851,17 @@

    types binary, bitstring, bytes, and bits.

    See also the paragraphs about Binaries.

    When constructing binaries and no size is specified for a binary segment, the entire binary value is interpolated into the binary being constructed. However, the size in bits of the binary being interpolated must be evenly divisible by -the unit value for the segment; otherwise an exception is raised.

    For example, the following examples all succeed:

    1> <<(<<"abc">>)/bitstring>>.
    +the unit value for the segment; otherwise an exception is raised.

    For example, the following examples all succeed:

    1> <<(<<"abc">>)/bitstring>>.
     <<"abc">>
    -2> <<(<<"abc">>)/binary-unit:1>>.
    +2> <<(<<"abc">>)/binary-unit:1>>.
     <<"abc">>
    -3> <<(<<"abc">>)/binary>>.
    +3> <<(<<"abc">>)/binary>>.
     <<"abc">>

    The first two examples have a unit value of 1 for the segment, while the third segment has a unit value of 8.

    Attempting to interpolate a bit string of size 1 into a binary segment with unit -8 (the default unit for binary) fails as shown in this example:

    1> <<(<<1:1>>)/binary>>.
    -** exception error: bad argument

    For the construction to succeed, the unit value of the segment must be 1:

    2> <<(<<1:1>>)/bitstring>>.
    +8 (the default unit for binary) fails as shown in this example:

    1> <<(<<1:1>>)/binary>>.
    +** exception error: bad argument

    For the construction to succeed, the unit value of the segment must be 1:

    2> <<(<<1:1>>)/bitstring>>.
     <<1:1>>
    -3> <<(<<1:1>>)/binary-unit:1>>.
    +3> <<(<<1:1>>)/binary-unit:1>>.
     <<1:1>>

    Similarly, when matching a binary segment with no size specified, the match succeeds if and only if the size in bits of the rest of the binary is evenly divisible by the unit value:

    1> <<_/binary-unit:16>> = <<"">>.
    @@ -875,9 +875,9 @@ 

    5> <<_/binary-unit:16>> = <<"abcd">>. <<"abcd">>

    When a size is explicitly specified for a binary segment, the segment size in bits is the value of Size multiplied by the default or explicit unit value.

    When constructing binaries, the size of the binary being interpolated into the -constructed binary must be at least as large as the size of the binary segment.

    Examples:

    1> <<(<<"abc">>):2/binary>>.
    +constructed binary must be at least as large as the size of the binary segment.

    Examples:

    1> <<(<<"abc">>):2/binary>>.
     <<"ab">>
    -2> <<(<<"a">>):2/binary>>.
    +2> <<(<<"a">>):2/binary>>.
     ** exception error: construction of binary failed
             *** segment 1 of type 'binary': the value <<"a">> is shorter than the size of the segment

    @@ -941,30 +941,30 @@

    Fun Expressions

    fun
    -    [Name](Pattern11,...,Pattern1N) [when GuardSeq1] ->
    +    [Name](Pattern11,...,Pattern1N) [when GuardSeq1] ->
                   Body1;
         ...;
    -    [Name](PatternK1,...,PatternKN) [when GuardSeqK] ->
    +    [Name](PatternK1,...,PatternKN) [when GuardSeqK] ->
                   BodyK
     end

    A fun expression begins with the keyword fun and ends with the keyword end. Between them is to be a function declaration, similar to a regular function declaration, except that the function name is optional and is to be a variable, if any.

    Variables in a fun head shadow the function name and both shadow variables in the function clause surrounding the fun expression. Variables bound in a fun -body are local to the fun body.

    The return value of the expression is the resulting fun.

    Examples:

    1> Fun1 = fun (X) -> X+1 end.
    +body are local to the fun body.

    The return value of the expression is the resulting fun.

    Examples:

    1> Fun1 = fun (X) -> X+1 end.
     #Fun<erl_eval.6.39074546>
    -2> Fun1(2).
    +2> Fun1(2).
     3
    -3> Fun2 = fun (X) when X>=5 -> gt; (X) -> lt end.
    +3> Fun2 = fun (X) when X>=5 -> gt; (X) -> lt end.
     #Fun<erl_eval.6.39074546>
    -4> Fun2(7).
    +4> Fun2(7).
     gt
    -5> Fun3 = fun Fact(1) -> 1; Fact(X) when X > 1 -> X * Fact(X - 1) end.
    +5> Fun3 = fun Fact(1) -> 1; Fact(X) when X > 1 -> X * Fact(X - 1) end.
     #Fun<erl_eval.6.39074546>
    -6> Fun3(4).
    +6> Fun3(4).
     24

    The following fun expressions are also allowed:

    fun Name/Arity
     fun Module:Name/Arity

    In Name/Arity, Name is an atom and Arity is an integer. Name/Arity must -specify an existing local function. The expression is syntactic sugar for:

    fun (Arg1,...,ArgN) -> Name(Arg1,...,ArgN) end

    In Module:Name/Arity, Module, and Name are atoms and Arity is an +specify an existing local function. The expression is syntactic sugar for:

    fun (Arg1,...,ArgN) -> Name(Arg1,...,ArgN) end

    In Module:Name/Arity, Module, and Name are atoms and Arity is an integer. Module, Name, and Arity can also be variables. A fun defined in this way refers to the function Name with arity Arity in the latest version of module Module. A fun defined in this way is not dependent on the @@ -982,11 +982,11 @@

    recent function calls, see Exit Reasons.

    Examples:

    1> catch 1+2.
     3
     2> catch 1+a.
    -{'EXIT',{badarith,[...]}}

    The BIF throw(Any) can be used for non-local return from a -function. It must be evaluated within a catch, which returns the value Any.

    Example:

    3> catch throw(hello).
    +{'EXIT',{badarith,[...]}}

    The BIF throw(Any) can be used for non-local return from a +function. It must be evaluated within a catch, which returns the value Any.

    Example:

    3> catch throw(hello).
     hello

    If throw/1 is not evaluated within a catch, a nocatch run-time error occurs.

    Change

    Before Erlang/OTP 24, the catch operator had the lowest precedence, making -it necessary to add parentheses when combining it with the match operator:

    1> A = (catch 42).
    +it necessary to add parentheses when combining it with the match operator:

    1> A = (catch 42).
     42
     2> A.
     42

    Starting from Erlang/OTP 24, the parentheses can be omitted:

    1> A = catch 42.
    @@ -1000,9 +1000,9 @@ 

    try Exprs
     catch
    -    Class1:ExceptionPattern1[:Stacktrace] [when ExceptionGuardSeq1] ->
    +    Class1:ExceptionPattern1[:Stacktrace] [when ExceptionGuardSeq1] ->
             ExceptionBody1;
    -    ClassN:ExceptionPatternN[:Stacktrace] [when ExceptionGuardSeqN] ->
    +    ClassN:ExceptionPatternN[:Stacktrace] [when ExceptionGuardSeqN] ->
             ExceptionBodyN
     end

    This is an enhancement of catch. It gives the possibility to:

    Examples (using a guard expression as filter):

    1> List = [1,2,a,b,c,3,4].
    +[1,2,a,b,c,3,4]
    +2> [E || E <- List, E rem 2].
    +[]
    +3> [E || E <- List, E rem 2 =:= 0].
    +[2,4]

    Examples (using a non-guard expression as filter):

    1> List = [1,2,a,b,c,3,4].
    +[1,2,a,b,c,3,4]
    +2> FaultyIsEven = fun(E) -> E rem 2 end.
     #Fun<erl_eval.42.17316486>
    -3> [E || E <- List, FaultyIsEven(E)].
    +3> [E || E <- List, FaultyIsEven(E)].
     ** exception error: bad filter 1
    -4> IsEven = fun(E) -> E rem 2 =:= 0 end.
    +4> IsEven = fun(E) -> E rem 2 =:= 0 end.
     #Fun<erl_eval.42.17316486>
    -5> [E || E <- List, IsEven(E)].
    +5> [E || E <- List, IsEven(E)].
     ** exception error: an error occurred when evaluating an arithmetic expression
          in operator  rem/2
             called as a rem 2
    -6> [E || E <- List, is_integer(E), IsEven(E)].
    -[2,4]

    +6> [E || E <- List, is_integer(E), IsEven(E)]. +[2,4]

    diff --git a/prs/8803/doc/system/funs.html b/prs/8803/doc/system/funs.html index 4fea69357a75d..fc0eb83935aa1 100644 --- a/prs/8803/doc/system/funs.html +++ b/prs/8803/doc/system/funs.html @@ -121,14 +121,14 @@

    map

    -

    The following function, double, doubles every element in a list:

    double([H|T]) -> [2*H|double(T)];
    -double([])    -> [].

    Hence, the argument entered as input is doubled as follows:

    > double([1,2,3,4]).
    -[2,4,6,8]

    The following function, add_one, adds one to every element in a list:

    add_one([H|T]) -> [H+1|add_one(T)];
    -add_one([])    -> [].

    The functions double and add_one have a similar structure. This can be used -by writing a function map that expresses this similarity:

    map(F, [H|T]) -> [F(H)|map(F, T)];
    -map(F, [])    -> [].

    The functions double and add_one can now be expressed in terms of map as -follows:

    double(L)  -> map(fun(X) -> 2*X end, L).
    -add_one(L) -> map(fun(X) -> 1 + X end, L).

    map(F, List) is a function that takes a function F and a list L as +

    The following function, double, doubles every element in a list:

    double([H|T]) -> [2*H|double(T)];
    +double([])    -> [].

    Hence, the argument entered as input is doubled as follows:

    > double([1,2,3,4]).
    +[2,4,6,8]

    The following function, add_one, adds one to every element in a list:

    add_one([H|T]) -> [H+1|add_one(T)];
    +add_one([])    -> [].

    The functions double and add_one have a similar structure. This can be used +by writing a function map that expresses this similarity:

    map(F, [H|T]) -> [F(H)|map(F, T)];
    +map(F, [])    -> [].

    The functions double and add_one can now be expressed in terms of map as +follows:

    double(L)  -> map(fun(X) -> 2*X end, L).
    +add_one(L) -> map(fun(X) -> 1 + X end, L).

    map(F, List) is a function that takes a function F and a list L as arguments and returns a new list, obtained by applying F to each of the elements in L.

    The process of abstracting out the common features of a number of different programs is called procedural abstraction. Procedural abstraction can be used @@ -142,21 +142,21 @@

    foreach

    This section illustrates procedural abstraction. Initially, the following two -examples are written as conventional functions.

    This function prints all elements of a list onto a stream:

    print_list(Stream, [H|T]) ->
    -    io:format(Stream, "~p~n", [H]),
    -    print_list(Stream, T);
    -print_list(Stream, []) ->
    -    true.

    This function broadcasts a message to a list of processes:

    broadcast(Msg, [Pid|Pids]) ->
    +examples are written as conventional functions.

    This function prints all elements of a list onto a stream:

    print_list(Stream, [H|T]) ->
    +    io:format(Stream, "~p~n", [H]),
    +    print_list(Stream, T);
    +print_list(Stream, []) ->
    +    true.

    This function broadcasts a message to a list of processes:

    broadcast(Msg, [Pid|Pids]) ->
         Pid ! Msg,
    -    broadcast(Msg, Pids);
    -broadcast(_, []) ->
    +    broadcast(Msg, Pids);
    +broadcast(_, []) ->
         true.

    These two functions have a similar structure. They both iterate over a list and do something to each element in the list. The "something" is passed on as an -extra argument to the function that does this.

    The function foreach expresses this similarity:

    foreach(F, [H|T]) ->
    -    F(H),
    -    foreach(F, T);
    -foreach(F, []) ->
    -    ok.

    Using the function foreach, the function print_list becomes:

    foreach(fun(H) -> io:format(S, "~p~n",[H]) end, L)

    Using the function foreach, the function broadcast becomes:

    foreach(fun(Pid) -> Pid ! M end, L)

    foreach is evaluated for its side-effect and not its value. foreach(Fun ,L) +extra argument to the function that does this.

    The function foreach expresses this similarity:

    foreach(F, [H|T]) ->
    +    F(H),
    +    foreach(F, T);
    +foreach(F, []) ->
    +    ok.

    Using the function foreach, the function print_list becomes:

    foreach(fun(H) -> io:format(S, "~p~n",[H]) end, L)

    Using the function foreach, the function broadcast becomes:

    foreach(fun(Pid) -> Pid ! M end, L)

    foreach is evaluated for its side-effect and not its value. foreach(Fun ,L) calls Fun(X) for each element X in L and the processing occurs in the order that the elements were defined in L. map does not define the order in which its elements are processed.

    @@ -166,24 +166,24 @@

    Syntax of Funs

    Funs are written with the following syntax (see -Fun Expressions for full description):

    F = fun (Arg1, Arg2, ... ArgN) ->
    +Fun Expressions for full description):

    F = fun (Arg1, Arg2, ... ArgN) ->
             ...
         end

    This creates an anonymous function of N arguments and binds it to the variable F.

    Another function, FunctionName, written in the same module, can be passed as an argument, using the following syntax:

    F = fun FunctionName/Arity

    With this form of function reference, the function that is referred to does not need to be exported from the module.

    It is also possible to refer to a function defined in a different module, with -the following syntax:

    F = fun Module:FunctionName/Arity

    In this case, the function must be exported from the module in question.

    The following program illustrates the different ways of creating funs:

    -module(fun_test).
    --export([t1/0, t2/0]).
    --import(lists, [map/2]).
    +the following syntax:

    F = fun Module:FunctionName/Arity

    In this case, the function must be exported from the module in question.

    The following program illustrates the different ways of creating funs:

    -module(fun_test).
    +-export([t1/0, t2/0]).
    +-import(lists, [map/2]).
     
    -t1() -> map(fun(X) -> 2 * X end, [1,2,3,4,5]).
    +t1() -> map(fun(X) -> 2 * X end, [1,2,3,4,5]).
     
    -t2() -> map(fun double/1, [1,2,3,4,5]).
    +t2() -> map(fun double/1, [1,2,3,4,5]).
     
    -double(X) -> X * 2.

    The fun F can be evaluated with the following syntax:

    F(Arg1, Arg2, ..., Argn)

    To check whether a term is a fun, use the test -is_function/1 in a guard.

    Example:

    f(F, Args) when is_function(F) ->
    -   apply(F, Args);
    -f(N, _) when is_integer(N) ->
    +double(X) -> X * 2.

    The fun F can be evaluated with the following syntax:

    F(Arg1, Arg2, ..., Argn)

    To check whether a term is a fun, use the test +is_function/1 in a guard.

    Example:

    f(F, Args) when is_function(F) ->
    +   apply(F, Args);
    +f(N, _) when is_integer(N) ->
        N.

    Funs are a distinct type. The BIFs erlang:fun_info/1,2 can be used to retrieve information about a fun, and the BIF erlang:fun_to_list/1 returns a textual representation of a fun. The check_process_code/2 @@ -196,18 +196,18 @@

    The scope rules for variables that occur in funs are as follows:

    • All variables that occur in the head of a fun are assumed to be "fresh" variables.
    • Variables that are defined before the fun, and that occur in function calls or -guard tests within the fun, have the values they had outside the fun.
    • Variables cannot be exported from a fun.

    The following examples illustrate these rules:

    print_list(File, List) ->
    -    {ok, Stream} = file:open(File, write),
    -    foreach(fun(X) -> io:format(Stream,"~p~n",[X]) end, List),
    -    file:close(Stream).

    Here, the variable X, defined in the head of the fun, is a new variable. The +guard tests within the fun, have the values they had outside the fun.

  • Variables cannot be exported from a fun.
  • The following examples illustrate these rules:

    print_list(File, List) ->
    +    {ok, Stream} = file:open(File, write),
    +    foreach(fun(X) -> io:format(Stream,"~p~n",[X]) end, List),
    +    file:close(Stream).

    Here, the variable X, defined in the head of the fun, is a new variable. The variable Stream, which is used within the fun, gets its value from the file:open line.

    As any variable that occurs in the head of a fun is considered a new variable, -it is equally valid to write as follows:

    print_list(File, List) ->
    -    {ok, Stream} = file:open(File, write),
    -    foreach(fun(File) ->
    -                io:format(Stream,"~p~n",[File])
    -            end, List),
    -    file:close(Stream).

    Here, File is used as the new variable instead of X. This is not so wise +it is equally valid to write as follows:

    print_list(File, List) ->
    +    {ok, Stream} = file:open(File, write),
    +    foreach(fun(File) ->
    +                io:format(Stream,"~p~n",[File])
    +            end, List),
    +    file:close(Stream).

    Here, File is used as the new variable instead of X. This is not so wise because code in the fun body cannot refer to the variable File, which is defined outside of the fun. Compiling this example gives the following diagnostic:

    ./FileName.erl:Line: Warning: variable 'File'
    @@ -216,20 +216,20 @@ 

    pattern matching operations must be moved into guard expressions and cannot be written in the head of the fun. For example, you might write the following code if you intend the first clause of F to be evaluated when the value of its -argument is Y:

    f(...) ->
    +argument is Y:

    f(...) ->
         Y = ...
    -    map(fun(X) when X == Y ->
    +    map(fun(X) when X == Y ->
                  ;
    -           (_) ->
    +           (_) ->
                  ...
    -        end, ...)
    -    ...

    instead of writing the following code:

    f(...) ->
    +        end, ...)
    +    ...

    instead of writing the following code:

    f(...) ->
         Y = ...
    -    map(fun(Y) ->
    +    map(fun(Y) ->
                  ;
    -           (_) ->
    +           (_) ->
                  ...
    -        end, ...)
    +        end, ...)
         ...

    @@ -243,58 +243,58 @@

    map

    -

    lists:map/2 takes a function of one argument and a list of terms:

    map(F, [H|T]) -> [F(H)|map(F, T)];
    -map(F, [])    -> [].

    It returns the list obtained by applying the function to every argument in the +

    lists:map/2 takes a function of one argument and a list of terms:

    map(F, [H|T]) -> [F(H)|map(F, T)];
    +map(F, [])    -> [].

    It returns the list obtained by applying the function to every argument in the list.

    When a new fun is defined in the shell, the value of the fun is printed as -Fun#<erl_eval>:

    > Double = fun(X) -> 2 * X end.
    +Fun#<erl_eval>:

    > Double = fun(X) -> 2 * X end.
     #Fun<erl_eval.6.72228031>
    -> lists:map(Double, [1,2,3,4,5]).
    -[2,4,6,8,10]

    +> lists:map(Double, [1,2,3,4,5]). +[2,4,6,8,10]

    any

    -

    lists:any/2 takes a predicate P of one argument and a list of terms:

    any(Pred, [H|T]) ->
    -    case Pred(H) of
    +

    lists:any/2 takes a predicate P of one argument and a list of terms:

    any(Pred, [H|T]) ->
    +    case Pred(H) of
             true  ->  true;
    -        false ->  any(Pred, T)
    +        false ->  any(Pred, T)
         end;
    -any(Pred, []) ->
    +any(Pred, []) ->
         false.

    A predicate is a function that returns true or false. any is true if there is a term X in the list such that P(X) is true.

    A predicate Big(X) is defined, which is true if its argument is greater that -10:

    > Big =  fun(X) -> if X > 10 -> true; true -> false end end.
    +10:

    > Big =  fun(X) -> if X > 10 -> true; true -> false end end.
     #Fun<erl_eval.6.72228031>
    -> lists:any(Big, [1,2,3,4]).
    +> lists:any(Big, [1,2,3,4]).
     false
    -> lists:any(Big, [1,2,3,12,5]).
    +> lists:any(Big, [1,2,3,12,5]).
     true

    all

    -

    lists:all/2 has the same arguments as any:

    all(Pred, [H|T]) ->
    -    case Pred(H) of
    -        true  ->  all(Pred, T);
    +

    lists:all/2 has the same arguments as any:

    all(Pred, [H|T]) ->
    +    case Pred(H) of
    +        true  ->  all(Pred, T);
             false ->  false
         end;
    -all(Pred, []) ->
    -    true.

    It is true if the predicate applied to all elements in the list is true.

    > lists:all(Big, [1,2,3,4,12,6]).
    +all(Pred, []) ->
    +    true.

    It is true if the predicate applied to all elements in the list is true.

    > lists:all(Big, [1,2,3,4,12,6]).
     false
    -> lists:all(Big, [12,13,14,15]).
    +> lists:all(Big, [12,13,14,15]).
     true

    foreach

    -

    lists:foreach/2 takes a function of one argument and a list of terms:

    foreach(F, [H|T]) ->
    -    F(H),
    -    foreach(F, T);
    -foreach(F, []) ->
    +

    lists:foreach/2 takes a function of one argument and a list of terms:

    foreach(F, [H|T]) ->
    +    F(H),
    +    foreach(F, T);
    +foreach(F, []) ->
         ok.

    The function is applied to each argument in the list. foreach returns ok. It -is only used for its side-effect:

    > lists:foreach(fun(X) -> io:format("~w~n",[X]) end, [1,2,3,4]).
    +is only used for its side-effect:

    > lists:foreach(fun(X) -> io:format("~w~n",[X]) end, [1,2,3,4]).
     1
     2
     3
    @@ -305,106 +305,106 @@ 

    foldl

    -

    lists:foldl/3 takes a function of two arguments, an accumulator and a list:

    foldl(F, Accu, [Hd|Tail]) ->
    -    foldl(F, F(Hd, Accu), Tail);
    -foldl(F, Accu, []) -> Accu.

    The function is called with two arguments. The first argument is the successive +

    lists:foldl/3 takes a function of two arguments, an accumulator and a list:

    foldl(F, Accu, [Hd|Tail]) ->
    +    foldl(F, F(Hd, Accu), Tail);
    +foldl(F, Accu, []) -> Accu.

    The function is called with two arguments. The first argument is the successive elements in the list. The second argument is the accumulator. The function must return a new accumulator, which is used the next time the function is called.

    If you have a list of lists L = ["I","like","Erlang"], then you can sum the -lengths of all the strings in L as follows:

    > L = ["I","like","Erlang"].
    -["I","like","Erlang"]
    -10> lists:foldl(fun(X, Sum) -> length(X) + Sum end, 0, L).
    -11

    lists:foldl/3 works like a while loop in an imperative language:

    L =  ["I","like","Erlang"],
    +lengths of all the strings in L as follows:

    > L = ["I","like","Erlang"].
    +["I","like","Erlang"]
    +10> lists:foldl(fun(X, Sum) -> length(X) + Sum end, 0, L).
    +11

    lists:foldl/3 works like a while loop in an imperative language:

    L =  ["I","like","Erlang"],
     Sum = 0,
    -while( L != []){
    -    Sum += length(head(L)),
    -    L = tail(L)
    +while( L != []){
    +    Sum += length(head(L)),
    +    L = tail(L)
     end

    mapfoldl

    -

    lists:mapfoldl/3 simultaneously maps and folds over a list:

    mapfoldl(F, Accu0, [Hd|Tail]) ->
    -    {R,Accu1} = F(Hd, Accu0),
    -    {Rs,Accu2} = mapfoldl(F, Accu1, Tail),
    -    {[R|Rs], Accu2};
    -mapfoldl(F, Accu, []) -> {[], Accu}.

    The following example shows how to change all letters in L to upper case and -then count them.

    First the change to upper case:

    > Upcase =  fun(X) when $a =< X,  X =< $z -> X + $A - $a;
    -(X) -> X
    +

    lists:mapfoldl/3 simultaneously maps and folds over a list:

    mapfoldl(F, Accu0, [Hd|Tail]) ->
    +    {R,Accu1} = F(Hd, Accu0),
    +    {Rs,Accu2} = mapfoldl(F, Accu1, Tail),
    +    {[R|Rs], Accu2};
    +mapfoldl(F, Accu, []) -> {[], Accu}.

    The following example shows how to change all letters in L to upper case and +then count them.

    First the change to upper case:

    > Upcase =  fun(X) when $a =< X,  X =< $z -> X + $A - $a;
    +(X) -> X
     end.
     #Fun<erl_eval.6.72228031>
     > Upcase_word =
    -fun(X) ->
    -lists:map(Upcase, X)
    +fun(X) ->
    +lists:map(Upcase, X)
     end.
     #Fun<erl_eval.6.72228031>
    -> Upcase_word("Erlang").
    +> Upcase_word("Erlang").
     "ERLANG"
    -> lists:map(Upcase_word, L).
    -["I","LIKE","ERLANG"]

    Now, the fold and the map can be done at the same time:

    > lists:mapfoldl(fun(Word, Sum) ->
    -{Upcase_word(Word), Sum + length(Word)}
    -end, 0, L).
    -{["I","LIKE","ERLANG"],11}

    +> lists:map(Upcase_word, L). +["I","LIKE","ERLANG"]

    Now, the fold and the map can be done at the same time:

    > lists:mapfoldl(fun(Word, Sum) ->
    +{Upcase_word(Word), Sum + length(Word)}
    +end, 0, L).
    +{["I","LIKE","ERLANG"],11}

    filter

    lists:filter/2 takes a predicate of one argument and a list and returns all elements -in the list that satisfy the predicate:

    filter(F, [H|T]) ->
    -    case F(H) of
    -        true  -> [H|filter(F, T)];
    -        false -> filter(F, T)
    +in the list that satisfy the predicate:

    filter(F, [H|T]) ->
    +    case F(H) of
    +        true  -> [H|filter(F, T)];
    +        false -> filter(F, T)
         end;
    -filter(F, []) -> [].
    > lists:filter(Big, [500,12,2,45,6,7]).
    -[500,12,45]

    Combining maps and filters enables writing of very succinct code. For example, +filter(F, []) -> [].

    > lists:filter(Big, [500,12,2,45,6,7]).
    +[500,12,45]

    Combining maps and filters enables writing of very succinct code. For example, to define a set difference function diff(L1, L2) to be the difference between -the lists L1 and L2, the code can be written as follows:

    diff(L1, L2) ->
    -    filter(fun(X) -> not member(X, L2) end, L1).

    This gives the list of all elements in L1 that are not contained in L2.

    The AND intersection of the list L1 and L2 is also easily defined:

    intersection(L1,L2) -> filter(fun(X) -> member(X,L1) end, L2).

    +the lists L1 and L2, the code can be written as follows:

    diff(L1, L2) ->
    +    filter(fun(X) -> not member(X, L2) end, L1).

    This gives the list of all elements in L1 that are not contained in L2.

    The AND intersection of the list L1 and L2 is also easily defined:

    intersection(L1,L2) -> filter(fun(X) -> member(X,L1) end, L2).

    takewhile

    lists:takewhile/2 takes elements X from a list L as long as the predicate -P(X) is true:

    takewhile(Pred, [H|T]) ->
    -    case Pred(H) of
    -        true  -> [H|takewhile(Pred, T)];
    -        false -> []
    +P(X) is true:

    takewhile(Pred, [H|T]) ->
    +    case Pred(H) of
    +        true  -> [H|takewhile(Pred, T)];
    +        false -> []
         end;
    -takewhile(Pred, []) ->
    -    [].
    > lists:takewhile(Big, [200,500,45,5,3,45,6]).
    -[200,500,45]

    +takewhile(Pred, []) -> + [].

    > lists:takewhile(Big, [200,500,45,5,3,45,6]).
    +[200,500,45]

    dropwhile

    -

    lists:dropwhile/2 is the complement of takewhile:

    dropwhile(Pred, [H|T]) ->
    -    case Pred(H) of
    -        true  -> dropwhile(Pred, T);
    -        false -> [H|T]
    +

    lists:dropwhile/2 is the complement of takewhile:

    dropwhile(Pred, [H|T]) ->
    +    case Pred(H) of
    +        true  -> dropwhile(Pred, T);
    +        false -> [H|T]
         end;
    -dropwhile(Pred, []) ->
    -    [].
    > lists:dropwhile(Big, [200,500,45,5,3,45,6]).
    -[5,3,45,6]

    +dropwhile(Pred, []) -> + [].

    > lists:dropwhile(Big, [200,500,45,5,3,45,6]).
    +[5,3,45,6]

    splitwith

    lists:splitwith/2 splits the list L into the two sublists {L1, L2}, where -L = takewhile(P, L) and L2 = dropwhile(P, L):

    splitwith(Pred, L) ->
    -    splitwith(Pred, L, []).
    +L = takewhile(P, L) and L2 = dropwhile(P, L):

    splitwith(Pred, L) ->
    +    splitwith(Pred, L, []).
     
    -splitwith(Pred, [H|T], L) ->
    -    case Pred(H) of
    -        true  -> splitwith(Pred, T, [H|L]);
    -        false -> {reverse(L), [H|T]}
    +splitwith(Pred, [H|T], L) ->
    +    case Pred(H) of
    +        true  -> splitwith(Pred, T, [H|L]);
    +        false -> {reverse(L), [H|T]}
         end;
    -splitwith(Pred, [], L) ->
    -    {reverse(L), []}.
    > lists:splitwith(Big, [200,500,45,5,3,45,6]).
    -{[200,500,45],[5,3,45,6]}

    +splitwith(Pred, [], L) -> + {reverse(L), []}.

    > lists:splitwith(Big, [200,500,45,5,3,45,6]).
    +{[200,500,45],[5,3,45,6]}

    @@ -419,60 +419,60 @@

    Simple Higher Order Functions

    Adder(X) is a function that given X, returns a new function G such that -G(K) returns K + X:

    > Adder = fun(X) -> fun(Y) -> X + Y end end.
    +G(K) returns K + X:

    > Adder = fun(X) -> fun(Y) -> X + Y end end.
     #Fun<erl_eval.6.72228031>
    -> Add6 = Adder(6).
    +> Add6 = Adder(6).
     #Fun<erl_eval.6.72228031>
    -> Add6(10).
    +> Add6(10).
     16

    Infinite Lists

    -

    The idea is to write something like:

    -module(lazy).
    --export([ints_from/1]).
    -ints_from(N) ->
    -    fun() ->
    -            [N|ints_from(N+1)]
    -    end.

    Then proceed as follows:

    > XX = lazy:ints_from(1).
    +

    The idea is to write something like:

    -module(lazy).
    +-export([ints_from/1]).
    +ints_from(N) ->
    +    fun() ->
    +            [N|ints_from(N+1)]
    +    end.

    Then proceed as follows:

    > XX = lazy:ints_from(1).
     #Fun<lazy.0.29874839>
    -> XX().
    -[1|#Fun<lazy.0.29874839>]
    -> hd(XX()).
    +> XX().
    +[1|#Fun<lazy.0.29874839>]
    +> hd(XX()).
     1
    -> Y = tl(XX()).
    +> Y = tl(XX()).
     #Fun<lazy.0.29874839>
    -> hd(Y()).
    +> hd(Y()).
     2

    And so on. This is an example of "lazy embedding".

    Parsing

    -

    The following examples show parsers of the following type:

    Parser(Toks) -> {ok, Tree, Toks1} | fail

    Toks is the list of tokens to be parsed. A successful parse returns +

    The following examples show parsers of the following type:

    Parser(Toks) -> {ok, Tree, Toks1} | fail

    Toks is the list of tokens to be parsed. A successful parse returns {ok, Tree, Toks1}.

    • Tree is a parse tree.
    • Toks1 is a tail of Tree that contains symbols encountered after the structure that was correctly parsed.

    An unsuccessful parse returns fail.

    The following example illustrates a simple, functional parser that parses the grammar:

    (a | b) & (c | d)

    The following code defines a function pconst(X) in the module funparse, -which returns a fun that parses a list of tokens:

    pconst(X) ->
    -    fun (T) ->
    +which returns a fun that parses a list of tokens:

    pconst(X) ->
    +    fun (T) ->
            case T of
    -           [X|T1] -> {ok, {const, X}, T1};
    +           [X|T1] -> {ok, {const, X}, T1};
                _      -> fail
            end
    -    end.

    This function can be used as follows:

    > P1 = funparse:pconst(a).
    +    end.

    This function can be used as follows:

    > P1 = funparse:pconst(a).
     #Fun<funparse.0.22674075>
    -> P1([a,b,c]).
    -{ok,{const,a},[b,c]}
    -> P1([x,y,z]).
    +> P1([a,b,c]).
    +{ok,{const,a},[b,c]}
    +> P1([x,y,z]).
     fail

    Next, the two higher order functions pand and por are defined. They combine -primitive parsers to produce more complex parsers.

    First pand:

    pand(P1, P2) ->
    -    fun (T) ->
    -        case P1(T) of
    -            {ok, R1, T1} ->
    -                case P2(T1) of
    -                    {ok, R2, T2} ->
    -                        {ok, {'and', R1, R2}};
    +primitive parsers to produce more complex parsers.

    First pand:

    pand(P1, P2) ->
    +    fun (T) ->
    +        case P1(T) of
    +            {ok, R1, T1} ->
    +                case P2(T1) of
    +                    {ok, R2, T2} ->
    +                        {ok, {'and', R1, R2}};
                         fail ->
                             fail
                     end;
    @@ -482,33 +482,33 @@ 

    end.

    Given a parser P1 for grammar G1, and a parser P2 for grammar G2, pand(P1, P2) returns a parser for the grammar, which consists of sequences of tokens that satisfy G1, followed by sequences of tokens that satisfy G2.

    por(P1, P2) returns a parser for the language described by the grammar G1 or -G2:

    por(P1, P2) ->
    -    fun (T) ->
    -        case P1(T) of
    -            {ok, R, T1} ->
    -                {ok, {'or',1,R}, T1};
    +G2:

    por(P1, P2) ->
    +    fun (T) ->
    +        case P1(T) of
    +            {ok, R, T1} ->
    +                {ok, {'or',1,R}, T1};
                 fail ->
    -                case P2(T) of
    -                    {ok, R1, T1} ->
    -                        {ok, {'or',2,R1}, T1};
    +                case P2(T) of
    +                    {ok, R1, T1} ->
    +                        {ok, {'or',2,R1}, T1};
                         fail ->
                             fail
                     end
             end
         end.

    The original problem was to parse the grammar (a | b) & (c | d). The following -code addresses this problem:

    grammar() ->
    -    pand(
    -         por(pconst(a), pconst(b)),
    -         por(pconst(c), pconst(d))).

    The following code adds a parser interface to the grammar:

    parse(List) ->
    -    (grammar())(List).

    The parser can be tested as follows:

    > funparse:parse([a,c]).
    -{ok,{'and',{'or',1,{const,a}},{'or',1,{const,c}}}}
    -> funparse:parse([a,d]).
    -{ok,{'and',{'or',1,{const,a}},{'or',2,{const,d}}}}
    -> funparse:parse([b,c]).
    -{ok,{'and',{'or',2,{const,b}},{'or',1,{const,c}}}}
    -> funparse:parse([b,d]).
    -{ok,{'and',{'or',2,{const,b}},{'or',2,{const,d}}}}
    -> funparse:parse([a,b]).
    +code addresses this problem:

    grammar() ->
    +    pand(
    +         por(pconst(a), pconst(b)),
    +         por(pconst(c), pconst(d))).

    The following code adds a parser interface to the grammar:

    parse(List) ->
    +    (grammar())(List).

    The parser can be tested as follows:

    > funparse:parse([a,c]).
    +{ok,{'and',{'or',1,{const,a}},{'or',1,{const,c}}}}
    +> funparse:parse([a,d]).
    +{ok,{'and',{'or',1,{const,a}},{'or',2,{const,d}}}}
    +> funparse:parse([b,c]).
    +{ok,{'and',{'or',2,{const,b}},{'or',1,{const,c}}}}
    +> funparse:parse([b,d]).
    +{ok,{'and',{'or',2,{const,b}},{'or',2,{const,d}}}}
    +> funparse:parse([a,b]).
     fail

    diff --git a/prs/8803/doc/system/gen_server_concepts.html b/prs/8803/doc/system/gen_server_concepts.html index 0b69a255548a5..963f782ef746d 100644 --- a/prs/8803/doc/system/gen_server_concepts.html +++ b/prs/8803/doc/system/gen_server_concepts.html @@ -161,40 +161,40 @@

    An example of a simple server written in plain Erlang is provided in Overview. The server can be reimplemented using -gen_server, resulting in this callback module:

    -module(ch3).
    --behaviour(gen_server).
    +gen_server, resulting in this callback module:

    -module(ch3).
    +-behaviour(gen_server).
     
    --export([start_link/0]).
    --export([alloc/0, free/1]).
    --export([init/1, handle_call/3, handle_cast/2]).
    +-export([start_link/0]).
    +-export([alloc/0, free/1]).
    +-export([init/1, handle_call/3, handle_cast/2]).
     
    -start_link() ->
    -    gen_server:start_link({local, ch3}, ch3, [], []).
    +start_link() ->
    +    gen_server:start_link({local, ch3}, ch3, [], []).
     
    -alloc() ->
    -    gen_server:call(ch3, alloc).
    +alloc() ->
    +    gen_server:call(ch3, alloc).
     
    -free(Ch) ->
    -    gen_server:cast(ch3, {free, Ch}).
    +free(Ch) ->
    +    gen_server:cast(ch3, {free, Ch}).
     
    -init(_Args) ->
    -    {ok, channels()}.
    +init(_Args) ->
    +    {ok, channels()}.
     
    -handle_call(alloc, _From, Chs) ->
    -    {Ch, Chs2} = alloc(Chs),
    -    {reply, Ch, Chs2}.
    +handle_call(alloc, _From, Chs) ->
    +    {Ch, Chs2} = alloc(Chs),
    +    {reply, Ch, Chs2}.
     
    -handle_cast({free, Ch}, Chs) ->
    -    Chs2 = free(Ch, Chs),
    -    {noreply, Chs2}.

    The code is explained in the next sections.

    +handle_cast({free, Ch}, Chs) -> + Chs2 = free(Ch, Chs), + {noreply, Chs2}.

    The code is explained in the next sections.

    Starting a Gen_Server

    In the example in the previous section, gen_server is started by calling -ch3:start_link():

    start_link() ->
    -    gen_server:start_link({local, ch3}, ch3, [], []) => {ok, Pid}

    start_link/0 calls function gen_server:start_link/4. This function +ch3:start_link():

    start_link() ->
    +    gen_server:start_link({local, ch3}, ch3, [], []) => {ok, Pid}

    start_link/0 calls function gen_server:start_link/4. This function spawns and links to a new process, a gen_server.

    • The first argument, {local, ch3}, specifies the name. The gen_server is then locally registered as ch3.

      If the name is omitted, the gen_server is not registered. Instead its pid must be used. The name can also be given as {global, Name}, in which case @@ -208,8 +208,8 @@

      for the available options.

    If name registration succeeds, the new gen_server process calls the callback function ch3:init([]). init is expected to return {ok, State}, where State is the internal state of the gen_server. In this case, the state is -the available channels.

    init(_Args) ->
    -    {ok, channels()}.

    gen_server:start_link/4 is synchronous. It does not return until the +the available channels.

    init(_Args) ->
    +    {ok, channels()}.

    gen_server:start_link/4 is synchronous. It does not return until the gen_server has been initialized and is ready to receive requests.

    gen_server:start_link/4 must be used if the gen_server is part of a supervision tree, meaning that it was started by a supervisor. There is another function, gen_server:start/4, to start a standalone @@ -225,9 +225,9 @@

    When the request is received, the gen_server calls handle_call(Request, From, State), which is expected to return a tuple {reply,Reply,State1}. Reply is the reply that is to be sent back -to the client, and State1 is a new value for the state of the gen_server.

    handle_call(alloc, _From, Chs) ->
    -    {Ch, Chs2} = alloc(Chs),
    -    {reply, Ch, Chs2}.

    In this case, the reply is the allocated channel Ch and the new state is the +to the client, and State1 is a new value for the state of the gen_server.

    handle_call(alloc, _From, Chs) ->
    +    {Ch, Chs2} = alloc(Chs),
    +    {reply, Ch, Chs2}.

    In this case, the reply is the allocated channel Ch and the new state is the set of remaining available channels Chs2.

    Thus, the call ch3:alloc() returns the allocated channel Ch and the gen_server then waits for new requests, now with an updated list of available channels.

    @@ -236,13 +236,13 @@

    Asynchronous Requests - Cast

    -

    The asynchronous request free(Ch) is implemented using gen_server:cast/2:

    free(Ch) ->
    -    gen_server:cast(ch3, {free, Ch}).

    ch3 is the name of the gen_server. {free, Ch} is the actual request.

    The request is made into a message and sent to the gen_server. +

    The asynchronous request free(Ch) is implemented using gen_server:cast/2:

    free(Ch) ->
    +    gen_server:cast(ch3, {free, Ch}).

    ch3 is the name of the gen_server. {free, Ch} is the actual request.

    The request is made into a message and sent to the gen_server. cast, and thus free, then returns ok.

    When the request is received, the gen_server calls handle_cast(Request, State), which is expected to return a tuple -{noreply,State1}. State1 is a new value for the state of the gen_server.

    handle_cast({free, Ch}, Chs) ->
    -    Chs2 = free(Ch, Chs),
    -    {noreply, Chs2}.

    In this case, the new state is the updated list of available channels Chs2. +{noreply,State1}. State1 is a new value for the state of the gen_server.

    handle_cast({free, Ch}, Chs) ->
    +    Chs2 = free(Ch, Chs),
    +    {noreply, Chs2}.

    In this case, the new state is the updated list of available channels Chs2. The gen_server is now ready for new requests.

    @@ -261,15 +261,15 @@

    set in the supervisor.

    If it is necessary to clean up before termination, the shutdown strategy must be a time-out value and the gen_server must be set to trap exit signals in function init. When ordered to shutdown, the gen_server then calls -the callback function terminate(shutdown, State):

    init(Args) ->
    +the callback function terminate(shutdown, State):

    init(Args) ->
         ...,
    -    process_flag(trap_exit, true),
    +    process_flag(trap_exit, true),
         ...,
    -    {ok, State}.
    +    {ok, State}.
     
     ...
     
    -terminate(shutdown, State) ->
    +terminate(shutdown, State) ->
         %% Code for cleaning up here
         ...
         ok.

    @@ -280,21 +280,21 @@

    If the gen_server is not part of a supervision tree, a stop function can be useful, for example:

    ...
    -export([stop/0]).
    +export([stop/0]).
     ...
     
    -stop() ->
    -    gen_server:cast(ch3, stop).
    +stop() ->
    +    gen_server:cast(ch3, stop).
     ...
     
    -handle_cast(stop, State) ->
    -    {stop, normal, State};
    -handle_cast({free, Ch}, State) ->
    +handle_cast(stop, State) ->
    +    {stop, normal, State};
    +handle_cast({free, Ch}, State) ->
         ...
     
     ...
     
    -terminate(normal, State) ->
    +terminate(normal, State) ->
         ok.

    The callback function handling the stop request returns a tuple {stop,normal,State1}, where normal specifies that it is a normal termination and State1 is a new value for the state @@ -309,13 +309,13 @@

    the callback function handle_info(Info, State) must be implemented to handle them. Examples of other messages are exit messages, if the gen_server is linked to other processes than the supervisor -and it is trapping exit signals.

    handle_info({'EXIT', Pid, Reason}, State) ->
    +and it is trapping exit signals.

    handle_info({'EXIT', Pid, Reason}, State) ->
         %% Code to handle exits here.
         ...
    -    {noreply, State1}.

    The final function to implement is code_change/3:

    code_change(OldVsn, State, Extra) ->
    +    {noreply, State1}.

    The final function to implement is code_change/3:

    code_change(OldVsn, State, Extra) ->
         %% Code to convert state (and more) during code change.
         ...
    -    {ok, NewState}.
    +
    {ok, NewState}.

    diff --git a/prs/8803/doc/system/included_applications.html b/prs/8803/doc/system/included_applications.html index daef8aa7aa637..b66e2998936a2 100644 --- a/prs/8803/doc/system/included_applications.html +++ b/prs/8803/doc/system/included_applications.html @@ -165,16 +165,16 @@

    Specifying Included Applications

    Which applications to include is defined by the included_applications key in -the .app file:

    {application, prim_app,
    - [{description, "Tree application"},
    -  {vsn, "1"},
    -  {modules, [prim_app_cb, prim_app_sup, prim_app_server]},
    -  {registered, [prim_app_server]},
    -  {included_applications, [incl_app]},
    -  {applications, [kernel, stdlib, sasl]},
    -  {mod, {prim_app_cb,[]}},
    -  {env, [{file, "/usr/local/log"}]}
    - ]}.

    +the .app file:

    {application, prim_app,
    + [{description, "Tree application"},
    +  {vsn, "1"},
    +  {modules, [prim_app_cb, prim_app_sup, prim_app_server]},
    +  {registered, [prim_app_server]},
    +  {included_applications, [incl_app]},
    +  {applications, [kernel, stdlib, sasl]},
    +  {mod, {prim_app_cb,[]}},
    +  {env, [{file, "/usr/local/log"}]}
    + ]}.

    @@ -188,27 +188,27 @@

    term.

    The value of the mod key of the including application must be set to {application_starter,[Module,StartArgs]}, where Module as usual is the application callback module. StartArgs is a term provided as argument to the -callback function Module:start/2:

    {application, prim_app,
    - [{description, "Tree application"},
    -  {vsn, "1"},
    -  {modules, [prim_app_cb, prim_app_sup, prim_app_server]},
    -  {registered, [prim_app_server]},
    -  {included_applications, [incl_app]},
    -  {start_phases, [{init,[]}, {go,[]}]},
    -  {applications, [kernel, stdlib, sasl]},
    -  {mod, {application_starter,[prim_app_cb,[]]}},
    -  {env, [{file, "/usr/local/log"}]}
    - ]}.
    -
    -{application, incl_app,
    - [{description, "Included application"},
    -  {vsn, "1"},
    -  {modules, [incl_app_cb, incl_app_sup, incl_app_server]},
    -  {registered, []},
    -  {start_phases, [{go,[]}]},
    -  {applications, [kernel, stdlib, sasl]},
    -  {mod, {incl_app_cb,[]}}
    - ]}.

    When starting a primary application with included applications, the primary +callback function Module:start/2:

    {application, prim_app,
    + [{description, "Tree application"},
    +  {vsn, "1"},
    +  {modules, [prim_app_cb, prim_app_sup, prim_app_server]},
    +  {registered, [prim_app_server]},
    +  {included_applications, [incl_app]},
    +  {start_phases, [{init,[]}, {go,[]}]},
    +  {applications, [kernel, stdlib, sasl]},
    +  {mod, {application_starter,[prim_app_cb,[]]}},
    +  {env, [{file, "/usr/local/log"}]}
    + ]}.
    +
    +{application, incl_app,
    + [{description, "Included application"},
    +  {vsn, "1"},
    +  {modules, [incl_app_cb, incl_app_sup, incl_app_server]},
    +  {registered, []},
    +  {start_phases, [{go,[]}]},
    +  {applications, [kernel, stdlib, sasl]},
    +  {mod, {incl_app_cb,[]}}
    + ]}.

    When starting a primary application with included applications, the primary application is started the normal way, that is:

    • The application controller creates an application master for the application
    • The application master calls Module:start(normal, StartArgs) to start the top supervisor.

    Then, for the primary application and each included application in top-down, left-to-right order, the application master calls @@ -221,11 +221,11 @@

    of specified phases must be a subset of the set of phases specified for the primary application.

    When starting prim_app as defined above, the application controller calls the following callback functions before application:start(prim_app) returns a -value:

    application:start(prim_app)
    - => prim_app_cb:start(normal, [])
    - => prim_app_cb:start_phase(init, normal, [])
    - => prim_app_cb:start_phase(go, normal, [])
    - => incl_app_cb:start_phase(go, normal, [])
    +value:

    application:start(prim_app)
    + => prim_app_cb:start(normal, [])
    + => prim_app_cb:start_phase(init, normal, [])
    + => prim_app_cb:start_phase(go, normal, [])
    + => incl_app_cb:start_phase(go, normal, [])
     ok

    diff --git a/prs/8803/doc/system/install-win32.html b/prs/8803/doc/system/install-win32.html index 145e095f0262e..c87d21c14215f 100644 --- a/prs/8803/doc/system/install-win32.html +++ b/prs/8803/doc/system/install-win32.html @@ -299,7 +299,7 @@

    and sometimes

    $ cd $ERL_TOP
     $ make local_setup
     

    So now when you run $ERL_TOP/erl.exe, you should have a debug compiled -emulator, which you will see if you do a:

    1> erlang:system_info(system_version).

    in the erlang shell. If the returned string contains [debug], you +emulator, which you will see if you do a:

    1> erlang:system_info(system_version).

    in the erlang shell. If the returned string contains [debug], you got a debug compiled emulator.

    To hack the erlang libraries, you simply do a make opt in the specific "applications" directory, like:

    $ cd $ERL_TOP/lib/stdlib
     $ make opt
    @@ -322,11 +322,11 @@ 

    Remember that:

    • Windows specific C-code goes in the $ERL_TOP/erts/emulator/sys/win32, $ERL_TOP/erts/emulator/drivers/win32 or $ERL_TOP/erts/etc/win32.

    • Windows specific erlang code should be used conditionally and the host OS tested in runtime, the exactly same beam files should be -distributed for every platform! So write code like:

      case os:type() of
      -    {win32,_} ->
      -        do_windows_specific();
      +distributed for every platform! So write code like:

      case os:type() of
      +    {win32,_} ->
      +        do_windows_specific();
           Other ->
      -        do_fallback_or_exit()
      +        do_fallback_or_exit()
       end,

    That's basically all you need to get going.

    diff --git a/prs/8803/doc/system/list_comprehensions.html b/prs/8803/doc/system/list_comprehensions.html index 54e84b573554c..a46cafc2ba15b 100644 --- a/prs/8803/doc/system/list_comprehensions.html +++ b/prs/8803/doc/system/list_comprehensions.html @@ -121,25 +121,25 @@

    Simple Examples

    -

    This section starts with a simple example, showing a generator and a filter:

    > [X || X <- [1,2,a,3,4,b,5,6], X > 3].
    -[a,4,b,5,6]

    This is read as follows: The list of X such that X is taken from the list +

    This section starts with a simple example, showing a generator and a filter:

    > [X || X <- [1,2,a,3,4,b,5,6], X > 3].
    +[a,4,b,5,6]

    This is read as follows: The list of X such that X is taken from the list [1,2,a,...] and X is greater than 3.

    The notation X <- [1,2,a,...] is a generator and the expression X > 3 is a filter.

    An additional filter, is_integer(X), can be added to -restrict the result to integers:

    > [X || X <- [1,2,a,3,4,b,5,6], is_integer(X), X > 3].
    -[4,5,6]

    Generators can be combined. For example, the Cartesian product of two lists can -be written as follows:

    > [{X, Y} || X <- [1,2,3], Y <- [a,b]].
    -[{1,a},{1,b},{2,a},{2,b},{3,a},{3,b}]

    +restrict the result to integers:

    > [X || X <- [1,2,a,3,4,b,5,6], is_integer(X), X > 3].
    +[4,5,6]

    Generators can be combined. For example, the Cartesian product of two lists can +be written as follows:

    > [{X, Y} || X <- [1,2,3], Y <- [a,b]].
    +[{1,a},{1,b},{2,a},{2,b},{3,a},{3,b}]

    Quick Sort

    -

    The well-known quick sort routine can be written as follows:

    sort([]) -> [];
    -sort([_] = L) -> L;
    -sort([Pivot|T]) ->
    -    sort([ X || X <- T, X < Pivot]) ++
    -    [Pivot] ++
    -    sort([ X || X <- T, X >= Pivot]).

    The expression [X || X <- T, X < Pivot] is the list of all elements in T +

    The well-known quick sort routine can be written as follows:

    sort([]) -> [];
    +sort([_] = L) -> L;
    +sort([Pivot|T]) ->
    +    sort([ X || X <- T, X < Pivot]) ++
    +    [Pivot] ++
    +    sort([ X || X <- T, X >= Pivot]).

    The expression [X || X <- T, X < Pivot] is the list of all elements in T that are less than Pivot.

    [X || X <- T, X >= Pivot] is the list of all elements in T that are greater than or equal to Pivot.

    With the algorithm above, a list is sorted as follows:

    • A list with zero or one element is trivially sorted.
    • For lists with more than one element:
      1. The first element in the list is isolated as the pivot element.
      2. The remaining list is partitioned into two sublists, such that:
      • The first sublist contains all elements that are smaller than the pivot element.
      • The second sublist contains all elements that are greater than or equal to @@ -155,11 +155,11 @@

        Permutations

        -

        The following example generates all permutations of the elements in a list:

        perms([]) -> [[]];
        -perms(L)  -> [[H|T] || H <- L, T <- perms(L--[H])].

        This takes H from L in all possible ways. The result is the set of all lists +

        The following example generates all permutations of the elements in a list:

        perms([]) -> [[]];
        +perms(L)  -> [[H|T] || H <- L, T <- perms(L--[H])].

        This takes H from L in all possible ways. The result is the set of all lists [H|T], where T is the set of all possible permutations of L, with H -removed:

        > perms([b,u,g]).
        -[[b,u,g],[b,g,u],[u,b,g],[u,g,b],[g,b,u],[g,u,b]]

        +removed:

        > perms([b,u,g]).
        +[[b,u,g],[b,g,u],[u,b,g],[u,g,b],[g,b,u],[g,u,b]]

        @@ -168,47 +168,47 @@

        Pythagorean triplets are sets of integers {A,B,C} such that A**2 + B**2 = C**2.

        The function pyth(N) generates a list of all integers {A,B,C} such that A**2 + B**2 = C**2 and where the sum of the sides is equal to, or less than, -N:

        pyth(N) ->
        -    [ {A,B,C} ||
        -        A <- lists:seq(1,N),
        -        B <- lists:seq(1,N),
        -        C <- lists:seq(1,N),
        +N:

        pyth(N) ->
        +    [ {A,B,C} ||
        +        A <- lists:seq(1,N),
        +        B <- lists:seq(1,N),
        +        C <- lists:seq(1,N),
                 A+B+C =< N,
                 A*A+B*B == C*C
        -    ].
        > pyth(3).
        -[].
        -> pyth(11).
        -[].
        -> pyth(12).
        -[{3,4,5},{4,3,5}]
        -> pyth(50).
        -[{3,4,5},
        - {4,3,5},
        - {5,12,13},
        - {6,8,10},
        - {8,6,10},
        - {8,15,17},
        - {9,12,15},
        - {12,5,13},
        - {12,9,15},
        - {12,16,20},
        - {15,8,17},
        - {16,12,20}]

        The following code reduces the search space and is more efficient:

        pyth1(N) ->
        -   [{A,B,C} ||
        -       A <- lists:seq(1,N-2),
        -       B <- lists:seq(A+1,N-1),
        -       C <- lists:seq(B+1,N),
        +    ].
        > pyth(3).
        +[].
        +> pyth(11).
        +[].
        +> pyth(12).
        +[{3,4,5},{4,3,5}]
        +> pyth(50).
        +[{3,4,5},
        + {4,3,5},
        + {5,12,13},
        + {6,8,10},
        + {8,6,10},
        + {8,15,17},
        + {9,12,15},
        + {12,5,13},
        + {12,9,15},
        + {12,16,20},
        + {15,8,17},
        + {16,12,20}]

        The following code reduces the search space and is more efficient:

        pyth1(N) ->
        +   [{A,B,C} ||
        +       A <- lists:seq(1,N-2),
        +       B <- lists:seq(A+1,N-1),
        +       C <- lists:seq(B+1,N),
                A+B+C =< N,
        -       A*A+B*B == C*C ].

        + A*A+B*B == C*C ].

        Simplifications With List Comprehensions

        As an example, list comprehensions can be used to simplify some of the functions -in lists.erl:

        append(L)   ->  [X || L1 <- L, X <- L1].
        -map(Fun, L) -> [Fun(X) || X <- L].
        -filter(Pred, L) -> [X || X <- L, Pred(X)].

        +in lists.erl:

        append(L)   ->  [X || L1 <- L, X <- L1].
        +map(Fun, L) -> [Fun(X) || X <- L].
        +filter(Pred, L) -> [X || X <- L, Pred(X)].

        @@ -220,20 +220,20 @@

        which selects certain elements from a list of tuples. Suppose you write select(X, L) -> [Y || {X, Y} <- L]. with the intention of extracting all tuples from L, where the first item is X.

        Compiling this gives the following diagnostic:

        ./FileName.erl:Line: Warning: variable 'X' shadowed in generate

        This diagnostic warns that the variable X in the pattern is not the same as -the variable X that occurs in the function head.

        Evaluating select gives the following result:

        > select(b,[{a,1},{b,2},{c,3},{b,7}]).
        -[1,2,3,7]

        This is not the wanted result. To achieve the desired effect, select must be -written as follows:

        select(X, L) ->  [Y || {X1, Y} <- L, X == X1].

        The generator now contains unbound variables and the test has been moved into -the filter.

        This now works as expected:

        > select(b,[{a,1},{b,2},{c,3},{b,7}]).
        -[2,7]

        Also note that a variable in a generator pattern will shadow a variable with the -same name bound in a previous generator pattern. For example:

        > [{X,Y} || X <- [1,2,3], X=Y <- [a,b,c]].
        -[{a,a},{b,b},{c,c},{a,a},{b,b},{c,c},{a,a},{b,b},{c,c}]

        A consequence of the rules for importing variables into a list comprehensions is +the variable X that occurs in the function head.

        Evaluating select gives the following result:

        > select(b,[{a,1},{b,2},{c,3},{b,7}]).
        +[1,2,3,7]

        This is not the wanted result. To achieve the desired effect, select must be +written as follows:

        select(X, L) ->  [Y || {X1, Y} <- L, X == X1].

        The generator now contains unbound variables and the test has been moved into +the filter.

        This now works as expected:

        > select(b,[{a,1},{b,2},{c,3},{b,7}]).
        +[2,7]

        Also note that a variable in a generator pattern will shadow a variable with the +same name bound in a previous generator pattern. For example:

        > [{X,Y} || X <- [1,2,3], X=Y <- [a,b,c]].
        +[{a,a},{b,b},{c,c},{a,a},{b,b},{c,c},{a,a},{b,b},{c,c}]

        A consequence of the rules for importing variables into a list comprehensions is that certain pattern matching operations must be moved into the filters and -cannot be written directly in the generators.

        To illustrate this, do not write as follows:

        f(...) ->
        +cannot be written directly in the generators.

        To illustrate this, do not write as follows:

        f(...) ->
             Y = ...
        -    [ Expression || PatternInvolving Y  <- Expr, ...]
        -    ...

        Instead, write as follows:

        f(...) ->
        +    [ Expression || PatternInvolving Y  <- Expr, ...]
        +    ...

        Instead, write as follows:

        f(...) ->
             Y = ...
        -    [ Expression || PatternInvolving Y1  <- Expr, Y == Y1, ...]
        +    [ Expression || PatternInvolving Y1  <- Expr, Y == Y1, ...]
             ...

    diff --git a/prs/8803/doc/system/listhandling.html b/prs/8803/doc/system/listhandling.html index 0c1b3c0abae0c..1938e4e8c5692 100644 --- a/prs/8803/doc/system/listhandling.html +++ b/prs/8803/doc/system/listhandling.html @@ -124,47 +124,47 @@

    Lists can only be built starting from the end and attaching list elements at the beginning. If you use the ++ operator as follows, a new list is created that is a copy of the elements in List1, followed by List2:

    List1 ++ List2

    Looking at how lists:append/2 or ++ would be implemented in plain Erlang, -clearly the first list is copied:

    append([H|T], Tail) ->
    -    [H|append(T, Tail)];
    -append([], Tail) ->
    +clearly the first list is copied:

    append([H|T], Tail) ->
    +    [H|append(T, Tail)];
    +append([], Tail) ->
         Tail.

    When recursing and building a list, it is important to ensure that you attach the new elements to the beginning of the list. In this way, you will build one -list, not hundreds or thousands of copies of the growing result list.

    Let us first see how it is not to be done:

    DO NOT

    bad_fib(N) ->
    -    bad_fib(N, 0, 1, []).
    +list, not hundreds or thousands of copies of the growing result list.

    Let us first see how it is not to be done:

    DO NOT

    bad_fib(N) ->
    +    bad_fib(N, 0, 1, []).
     
    -bad_fib(0, _Current, _Next, Fibs) ->
    +bad_fib(0, _Current, _Next, Fibs) ->
         Fibs;
    -bad_fib(N, Current, Next, Fibs) ->
    -    bad_fib(N - 1, Next, Current + Next, Fibs ++ [Current]).

    Here more than one list is built. In each iteration step a new list is created +bad_fib(N, Current, Next, Fibs) -> + bad_fib(N - 1, Next, Current + Next, Fibs ++ [Current]).

    Here more than one list is built. In each iteration step a new list is created that is one element longer than the new previous list.

    To avoid copying the result in each iteration, build the list in reverse order -and reverse the list when you are done:

    DO

    tail_recursive_fib(N) ->
    -    tail_recursive_fib(N, 0, 1, []).
    +and reverse the list when you are done:

    DO

    tail_recursive_fib(N) ->
    +    tail_recursive_fib(N, 0, 1, []).
     
    -tail_recursive_fib(0, _Current, _Next, Fibs) ->
    -    lists:reverse(Fibs);
    -tail_recursive_fib(N, Current, Next, Fibs) ->
    -    tail_recursive_fib(N - 1, Next, Current + Next, [Current|Fibs]).

    +tail_recursive_fib(0, _Current, _Next, Fibs) -> + lists:reverse(Fibs); +tail_recursive_fib(N, Current, Next, Fibs) -> + tail_recursive_fib(N - 1, Next, Current + Next, [Current|Fibs]).

    List Comprehensions

    -

    A list comprehension:

    [Expr(E) || E <- List]

    is basically translated to a local function:

    'lc^0'([E|Tail], Expr) ->
    -    [Expr(E)|'lc^0'(Tail, Expr)];
    -'lc^0'([], _Expr) -> [].

    If the result of the list comprehension will obviously not be used, a list -will not be constructed. For example, in this code:

    [io:put_chars(E) || E <- List],
    +

    A list comprehension:

    [Expr(E) || E <- List]

    is basically translated to a local function:

    'lc^0'([E|Tail], Expr) ->
    +    [Expr(E)|'lc^0'(Tail, Expr)];
    +'lc^0'([], _Expr) -> [].

    If the result of the list comprehension will obviously not be used, a list +will not be constructed. For example, in this code:

    [io:put_chars(E) || E <- List],
     ok.

    or in this code:

    case Var of
         ... ->
    -        [io:put_chars(E) || E <- List];
    +        [io:put_chars(E) || E <- List];
         ... ->
     end,
    -some_function(...),

    the value is not assigned to a variable, not passed to another function, and not +some_function(...),

    the value is not assigned to a variable, not passed to another function, and not returned. This means that there is no need to construct a list and the compiler -will simplify the code for the list comprehension to:

    'lc^0'([E|Tail], Expr) ->
    -    Expr(E),
    -    'lc^0'(Tail, Expr);
    -'lc^0'([], _Expr) -> [].

    The compiler also understands that assigning to _ means that the value will -not be used. Therefore, the code in the following example will also be optimized:

    _ = [io:put_chars(E) || E <- List],
    +will simplify the code for the list comprehension to:

    'lc^0'([E|Tail], Expr) ->
    +    Expr(E),
    +    'lc^0'(Tail, Expr);
    +'lc^0'([], _Expr) -> [].

    The compiler also understands that assigning to _ means that the value will +not be used. Therefore, the code in the following example will also be optimized:

    _ = [io:put_chars(E) || E <- List],
     ok.

    @@ -177,11 +177,11 @@

    to flatten the list before sending it to the port.
  • When calling BIFs that accept deep lists, such as list_to_binary/1 or iolist_to_binary/1.
  • When you know that your list is only one level deep. Use lists:append/1 -instead.
  • Examples:

    DO

    port_command(Port, DeepList)

    DO NOT

    port_command(Port, lists:flatten(DeepList))

    A common way to send a zero-terminated string to a port is the following:

    DO NOT

    TerminatedStr = String ++ [0],
    -port_command(Port, TerminatedStr)

    Instead:

    DO

    TerminatedStr = [String, 0],
    -port_command(Port, TerminatedStr)

    DO

    1> lists:append([[1], [2], [3]]).
    -[1,2,3]

    DO NOT

    1> lists:flatten([[1], [2], [3]]).
    -[1,2,3]

    +instead.

    Examples:

    DO

    port_command(Port, DeepList)

    DO NOT

    port_command(Port, lists:flatten(DeepList))

    A common way to send a zero-terminated string to a port is the following:

    DO NOT

    TerminatedStr = String ++ [0],
    +port_command(Port, TerminatedStr)

    Instead:

    DO

    TerminatedStr = [String, 0],
    +port_command(Port, TerminatedStr)

    DO

    1> lists:append([[1], [2], [3]]).
    +[1,2,3]

    DO NOT

    1> lists:flatten([[1], [2], [3]]).
    +[1,2,3]

    @@ -189,17 +189,17 @@

    There are two basic ways to write a function that traverses a list and produces a new list.

    The first way is writing a body-recursive function:

    %% Add 42 to each integer in the list.
    -add_42_body([H|T]) ->
    -    [H + 42 | add_42_body(T)];
    -add_42_body([]) ->
    -    [].

    The second way is writing a tail-recursive function:

    %% Add 42 to each integer in the list.
    -add_42_tail(List) ->
    -    add_42_tail(List, []).
    -
    -add_42_tail([H|T], Acc) ->
    -    add_42_tail(T, [H + 42 | Acc]);
    -add_42_tail([], Acc) ->
    -    lists:reverse(Acc).

    In early version of Erlang the tail-recursive function would typically +add_42_body([H|T]) -> + [H + 42 | add_42_body(T)]; +add_42_body([]) -> + [].

    The second way is writing a tail-recursive function:

    %% Add 42 to each integer in the list.
    +add_42_tail(List) ->
    +    add_42_tail(List, []).
    +
    +add_42_tail([H|T], Acc) ->
    +    add_42_tail(T, [H + 42 | Acc]);
    +add_42_tail([], Acc) ->
    +    lists:reverse(Acc).

    In early version of Erlang the tail-recursive function would typically be more efficient. In modern versions of Erlang, there is usually not much difference in performance between a body-recursive list function and tail-recursive function that reverses the list at the end. Therefore, @@ -210,11 +210,11 @@

    function that does not construct a list runs in constant space, while the corresponding body-recursive function uses stack space proportional to the length of the list.

    For example, a function that sums a list of integers, is not to be written as -follows:

    DO NOT

    recursive_sum([H|T]) -> H+recursive_sum(T);
    -recursive_sum([])    -> 0.

    Instead:

    DO

    sum(L) -> sum(L, 0).
    +follows:

    DO NOT

    recursive_sum([H|T]) -> H+recursive_sum(T);
    +recursive_sum([])    -> 0.

    Instead:

    DO

    sum(L) -> sum(L, 0).
     
    -sum([H|T], Sum) -> sum(T, Sum + H);
    -sum([], Sum)    -> Sum.
    +
    sum([H|T], Sum) -> sum(T, Sum + H); +sum([], Sum) -> Sum.

    diff --git a/prs/8803/doc/system/macros.html b/prs/8803/doc/system/macros.html index 01ed45af1d80a..2a1d6f39f5fc5 100644 --- a/prs/8803/doc/system/macros.html +++ b/prs/8803/doc/system/macros.html @@ -121,8 +121,8 @@

    File Inclusion

    -

    A file can be included as follows:

    -include(File).
    --include_lib(File).

    File, a string, is to point out a file. The contents of this file are included +

    A file can be included as follows:

    -include(File).
    +-include_lib(File).

    File, a string, is to point out a file. The contents of this file are included as is, at the position of the directive.

    Include files are typically used for record and macro definitions that are shared by several modules. It is recommended to use the file name extension .hrl for include files.

    File can start with a path component $VAR, for some string VAR. If that is @@ -131,12 +131,12 @@

    $VAR is left as is.

    If the filename File is absolute (possibly after variable substitution), the include file with that name is included. Otherwise, the specified file is searched for in the following directories, and in this order:

    1. The current working directory
    2. The directory where the module is being compiled
    3. The directories given by the include option

    For details, see erlc in ERTS and -compile in Compiler.

    Examples:

    -include("my_records.hrl").
    --include("incdir/my_records.hrl").
    --include("/home/user/proj/my_records.hrl").
    --include("$PROJ_ROOT/my_records.hrl").

    include_lib is similar to include, but is not to point out an absolute file. +compile in Compiler.

    Examples:

    -include("my_records.hrl").
    +-include("incdir/my_records.hrl").
    +-include("/home/user/proj/my_records.hrl").
    +-include("$PROJ_ROOT/my_records.hrl").

    include_lib is similar to include, but is not to point out an absolute file. Instead, the first path component (possibly after variable substitution) is -assumed to be the name of an application.

    Example:

    -include_lib("kernel/include/file.hrl").

    The code server uses code:lib_dir(kernel) to find the directory of the current +assumed to be the name of an application.

    Example:

    -include_lib("kernel/include/file.hrl").

    The code server uses code:lib_dir(kernel) to find the directory of the current (latest) version of Kernel, and then the subdirectory include is searched for the file file.hrl.

    @@ -144,25 +144,25 @@

    Defining and Using Macros

    -

    A macro is defined as follows:

    -define(Const, Replacement).
    --define(Func(Var1,...,VarN), Replacement).

    A macro definition can be placed anywhere among the attributes and function +

    A macro is defined as follows:

    -define(Const, Replacement).
    +-define(Func(Var1,...,VarN), Replacement).

    A macro definition can be placed anywhere among the attributes and function declarations of a module, but the definition must come before any usage of the macro.

    If a macro is used in several modules, it is recommended that the macro definition is placed in an include file.

    A macro is used as follows:

    ?Const
     ?Func(Arg1,...,ArgN)

    Macros are expanded during compilation. A simple macro ?Const is replaced with -Replacement.

    Example:

    -define(TIMEOUT, 200).
    +Replacement.

    Example:

    -define(TIMEOUT, 200).
     ...
    -call(Request) ->
    -    server:call(refserver, Request, ?TIMEOUT).

    This is expanded to:

    call(Request) ->
    -    server:call(refserver, Request, 200).

    A macro ?Func(Arg1,...,ArgN) is replaced with Replacement, where all +call(Request) -> + server:call(refserver, Request, ?TIMEOUT).

    This is expanded to:

    call(Request) ->
    +    server:call(refserver, Request, 200).

    A macro ?Func(Arg1,...,ArgN) is replaced with Replacement, where all occurrences of a variable Var from the macro definition are replaced with the -corresponding argument Arg.

    Example:

    -define(MACRO1(X, Y), {a, X, b, Y}).
    +corresponding argument Arg.

    Example:

    -define(MACRO1(X, Y), {a, X, b, Y}).
     ...
    -bar(X) ->
    -    ?MACRO1(a, b),
    -    ?MACRO1(X, 123)

    This is expanded to:

    bar(X) ->
    -    {a,a,b,b},
    -    {a,X,b,123}.

    It is good programming practice, but not mandatory, to ensure that a macro +bar(X) -> + ?MACRO1(a, b), + ?MACRO1(X, 123)

    This is expanded to:

    bar(X) ->
    +    {a,a,b,b},
    +    {a,X,b,123}.

    It is good programming practice, but not mandatory, to ensure that a macro definition is a valid Erlang syntactic form.

    To view the result of macro expansion, a module can be compiled with the 'P' option. compile:file(File, ['P']). This produces a listing of the parsed code after preprocessing and parse transforms, in the file File.P.

    @@ -189,21 +189,21 @@

    It is possible to overload macros, except for predefined macros. An overloaded macro has more than one definition, each with a different number of arguments.

    Change

    Support for overloading of macros was added in Erlang 5.7.5/OTP R13B04.

    A macro ?Func(Arg1,...,ArgN) with a (possibly empty) list of arguments results in an error message if there is at least one definition of Func with -arguments, but none with N arguments.

    Assuming these definitions:

    -define(F0(), c).
    --define(F1(A), A).
    --define(C, m:f).

    the following does not work:

    f0() ->
    +arguments, but none with N arguments.

    Assuming these definitions:

    -define(F0(), c).
    +-define(F1(A), A).
    +-define(C, m:f).

    the following does not work:

    f0() ->
         ?F0. % No, an empty list of arguments expected.
     
    -f1(A) ->
    -    ?F1(A, A). % No, exactly one argument expected.

    On the other hand,

    f() ->
    -    ?C().

    is expanded to

    f() ->
    -    m:f().

    +f1(A) -> + ?F1(A, A). % No, exactly one argument expected.

    On the other hand,

    f() ->
    +    ?C().

    is expanded to

    f() ->
    +    m:f().

    Removing a macro definition

    -

    A definition of macro can be removed as follows:

    -undef(Macro).

    +

    A definition of macro can be removed as follows:

    -undef(Macro).

    @@ -223,13 +223,13 @@

    elif also supports calling the psuedo-function defined(Name), which tests whether the Name argument is the name of a previously defined macro. defined(Name) evaluates to true if the macro is defined and false -otherwise. An attempt to call other functions results in a compilation error.

    Example:

    -module(m).
    +otherwise. An attempt to call other functions results in a compilation error.

    Example:

    -module(m).
     ...
     
    --ifdef(debug).
    --define(LOG(X), io:format("{~p,~p}: ~p~n", [?MODULE,?LINE,X])).
    +-ifdef(debug).
    +-define(LOG(X), io:format("{~p,~p}: ~p~n", [?MODULE,?LINE,X])).
     -else.
    --define(LOG(X), true).
    +-define(LOG(X), true).
     -endif.
     
     ...

    When trace output is desired, debug is to be defined when the module m is @@ -237,21 +237,21 @@

    or -1> c(m, {d, debug}). -{ok,m}

    ?LOG(Arg) is then expanded to a call to io:format/2 and provide the user -with some simple trace output.

    Example:

    -module(m)
    +1> c(m, {d, debug}).
    +{ok,m}

    ?LOG(Arg) is then expanded to a call to io:format/2 and provide the user +with some simple trace output.

    Example:

    -module(m)
     ...
    --if(?OTP_RELEASE >= 25).
    +-if(?OTP_RELEASE >= 25).
     %% Code that will work in OTP 25 or higher
    --elif(?OTP_RELEASE >= 26).
    +-elif(?OTP_RELEASE >= 26).
     %% Code that will work in OTP 26 or higher
     -else.
     %% Code that will work in OTP 24 or lower.
     -endif.
     ...

    This code uses the OTP_RELEASE macro to conditionally select code depending on -release.

    Example:

    -module(m)
    +release.

    Example:

    -module(m)
     ...
    --if(?OTP_RELEASE >= 26 andalso defined(debug)).
    +-if(?OTP_RELEASE >= 26 andalso defined(debug)).
     %% Debugging code that requires OTP 26 or later.
     -else.
     %% Non-debug code that works in any release.
    @@ -274,23 +274,23 @@ 

    -error() and -warning() directives

    -

    The directive -error(Term) causes a compilation error.

    Example:

    -module(t).
    --export([version/0]).
    +

    The directive -error(Term) causes a compilation error.

    Example:

    -module(t).
    +-export([version/0]).
     
    --ifdef(VERSION).
    -version() -> ?VERSION.
    +-ifdef(VERSION).
    +version() -> ?VERSION.
     -else.
    --error("Macro VERSION must be defined.").
    -version() -> "".
    +-error("Macro VERSION must be defined.").
    +version() -> "".
     -endif.

    The error message will look like this:

    % erlc t.erl
    -t.erl:7: -error("Macro VERSION must be defined.").

    The directive -warning(Term) causes a compilation warning.

    Example:

    -module(t).
    --export([version/0]).
    +t.erl:7: -error("Macro VERSION must be defined.").

    The directive -warning(Term) causes a compilation warning.

    Example:

    -module(t).
    +-export([version/0]).
     
    --ifndef(VERSION).
    --warning("Macro VERSION not defined -- using default version.").
    --define(VERSION, "0").
    +-ifndef(VERSION).
    +-warning("Macro VERSION not defined -- using default version.").
    +-define(VERSION, "0").
     -endif.
    -version() -> ?VERSION.

    The warning message will look like this:

    % erlc t.erl
    +version() -> ?VERSION.

    The warning message will look like this:

    % erlc t.erl
     t.erl:5: Warning: -warning("Macro VERSION not defined -- using default version.").

    Change

    The -error() and -warning() directives were added in Erlang/OTP 19.

    @@ -299,11 +299,11 @@

    The construction ??Arg, where Arg is a macro argument, is expanded to a string containing the tokens of the argument. This is similar to the #arg -stringifying construction in C.

    Example:

    -define(TESTCALL(Call), io:format("Call ~s: ~w~n", [??Call, Call])).
    +stringifying construction in C.

    Example:

    -define(TESTCALL(Call), io:format("Call ~s: ~w~n", [??Call, Call])).
     
    -?TESTCALL(myfunction(1,2)),
    -?TESTCALL(you:function(2,1)).

    results in

    io:format("Call ~s: ~w~n",["myfunction ( 1 , 2 )",myfunction(1,2)]),
    -io:format("Call ~s: ~w~n",["you : function ( 2 , 1 )",you:function(2,1)]).

    That is, a trace output, with both the function called and the resulting value.

    +
    ?TESTCALL(myfunction(1,2)), +?TESTCALL(you:function(2,1)).

    results in

    io:format("Call ~s: ~w~n",["myfunction ( 1 , 2 )",myfunction(1,2)]),
    +io:format("Call ~s: ~w~n",["you : function ( 2 , 1 )",you:function(2,1)]).

    That is, a trace output, with both the function called and the resulting value.

    diff --git a/prs/8803/doc/system/maps.html b/prs/8803/doc/system/maps.html index e7aab8e5629eb..625a301852410 100644 --- a/prs/8803/doc/system/maps.html +++ b/prs/8803/doc/system/maps.html @@ -152,8 +152,8 @@

    values, sharing of keys between different instances of the map will be less effective, and it is not possible to match multiple elements having default values in one go.

  • To avoid having to deal with a map that may lack some keys, maps:merge/2 can -efficiently add multiple default values. For example:

    DefaultMap = #{shoe_size => 42, editor => emacs},
    -MapWithDefaultsApplied = maps:merge(DefaultMap, OtherMap)
  • +efficiently add multiple default values. For example:

    DefaultMap = #{shoe_size => 42, editor => emacs},
    +MapWithDefaultsApplied = maps:merge(DefaultMap, OtherMap)

    @@ -171,10 +171,10 @@

    Using Maps as Sets

    Starting in OTP 24, the sets module has an option to represent sets as maps. -Examples:

    1> sets:new([{version,2}]).
    -#{}
    -2> sets:from_list([x,y,z], [{version,2}]).
    -#{x => [],y => [],z => []}

    sets backed by maps is generally the most efficient set representation, with a +Examples:

    1> sets:new([{version,2}]).
    +#{}
    +2> sets:from_list([x,y,z], [{version,2}]).
    +#{x => [],y => [],z => []}

    sets backed by maps is generally the most efficient set representation, with a few possible exceptions:

    • ordsets:intersection/2 can be more efficient than sets:intersection/2. If the intersection operation is frequently used and operations that operate on a single element in a set (such as is_element/2) are avoided, ordsets can @@ -207,10 +207,10 @@

      allowing the key tuple to be shared with other instances of the map that have the same keys. In fact, the key tuple can be shared between all maps with the same keys with some care. To arrange that, define a function that returns a map. -For example:

      new() ->
      -    #{a => default, b => default, c => default}.

      Defined like this, the key tuple {a,b,c} will be a global literal. To ensure +For example:

      new() ->
      +    #{a => default, b => default, c => default}.

      Defined like this, the key tuple {a,b,c} will be a global literal. To ensure that the key tuple is shared when creating an instance of the map, always call -new() and modify the returned map:

          (SOME_MODULE:new())#{a := 42}.

      Using the map syntax with small maps is particularly efficient. As long as the +new() and modify the returned map:

          (SOME_MODULE:new())#{a := 42}.

      Using the map syntax with small maps is particularly efficient. As long as the keys are known at compile-time, the map is updated in one go, making the time to update a map essentially constant regardless of the number of keys updated. The same goes for matching. (When the keys are variables, one or more of the keys @@ -245,13 +245,13 @@

      Using the map syntax is usually slightly more efficient than using the corresponding function in the maps module.

      The gain in efficiency for the map syntax is more noticeable for the following -operations that can only be achieved using the map syntax:

      • Matching multiple literal keys
      • Updating multiple literal keys
      • Adding multiple literal keys to a map

      For example:

      DO

      Map = Map1#{x := X, y := Y, z := Z}

      DO NOT

      Map2 = maps:update(x, X, Map1),
      -Map3 = maps:update(y, Y, Map2),
      -Map = maps:update(z, Z, Map3)

      If the map is a small map, the first example runs roughly three times as fast.

      Note that for variable keys, the elements are updated sequentially from left to -right. For example, given the following update with variable keys:

      Map = Map1#{Key1 := X, Key2 := Y, Key3 := Z}

      the compiler rewrites it like this to ensure that the updates are applied from -left to right:

      Map2 = Map1#{Key1 := X},
      -Map3 = Map2#{Key2 := Y},
      -Map = Map3#{Key3 := Z}

      If a key is known to exist in a map, using the := operator is slightly more +operations that can only be achieved using the map syntax:

      • Matching multiple literal keys
      • Updating multiple literal keys
      • Adding multiple literal keys to a map

      For example:

      DO

      Map = Map1#{x := X, y := Y, z := Z}

      DO NOT

      Map2 = maps:update(x, X, Map1),
      +Map3 = maps:update(y, Y, Map2),
      +Map = maps:update(z, Z, Map3)

      If the map is a small map, the first example runs roughly three times as fast.

      Note that for variable keys, the elements are updated sequentially from left to +right. For example, given the following update with variable keys:

      Map = Map1#{Key1 := X, Key2 := Y, Key3 := Z}

      the compiler rewrites it like this to ensure that the updates are applied from +left to right:

      Map2 = Map1#{Key1 := X},
      +Map3 = Map2#{Key2 := Y},
      +Map = Map3#{Key3 := Z}

      If a key is known to exist in a map, using the := operator is slightly more efficient than using the => operator for a small map.

      @@ -310,15 +310,15 @@

      As an optimization, the compiler will rewrite a call to maps:get/3 to Erlang code similar to the following:

      Result = case Map of
      -             #{Key := Value} -> Value;
      -             #{} -> Default
      +             #{Key := Value} -> Value;
      +             #{} -> Default
                end

      This is reasonably efficient, but if a small map is used as an alternative to using a record it is often better not to rely on default values as it prevents sharing of keys, which may in the end use more memory than what you save from not storing default values in the map.

      If default values are nevertheless required, instead of calling maps:get/3 multiple times, consider putting the default values in a map and merging that -map with the other map:

      DefaultMap = #{Key1 => Value2, Key2 => Value2, ..., KeyN => ValueN},
      -MapWithDefaultsApplied = maps:merge(DefaultMap, OtherMap)

      This helps share keys between the default map and the one you applied defaults +map with the other map:

      DefaultMap = #{Key1 => Value2, Key2 => Value2, ..., KeyN => ValueN},
      +MapWithDefaultsApplied = maps:merge(DefaultMap, OtherMap)

      This helps share keys between the default map and the one you applied defaults to, as long as the default map contains all the keys that will ever be used and not just the ones with default values. Whether this is faster than calling maps:get/3 multiple times depends on the size of the map and the number of @@ -414,21 +414,21 @@

      maps:put/3 is implemented in C.

      If the key is known to already exist in the map, maps:update/3 is slightly more efficient than maps:put/3.

      If the compiler can determine that the third argument is always a map, it -will rewrite the call to maps:put/3 to use the map syntax for updating the map.

      For example, consider the following function:

      add_to_known_map(Map0, A, B, C) when is_map(Map0) ->
      -    Map1 = maps:put(a, A, Map0),
      -    Map2 = maps:put(b, B, Map1),
      -    maps:put(c, C, Map2).

      The compiler first rewrites each call to maps:put/3 to use the map +will rewrite the call to maps:put/3 to use the map syntax for updating the map.

      For example, consider the following function:

      add_to_known_map(Map0, A, B, C) when is_map(Map0) ->
      +    Map1 = maps:put(a, A, Map0),
      +    Map2 = maps:put(b, B, Map1),
      +    maps:put(c, C, Map2).

      The compiler first rewrites each call to maps:put/3 to use the map syntax, and subsequently combines the three update operations to a -single update operation:

      add_to_known_map(Map0, A, B, C) when is_map(Map0) ->
      -    Map0#{a => A, b => B, c => C}.

      If the compiler cannot determine that the third argument is always a +single update operation:

      add_to_known_map(Map0, A, B, C) when is_map(Map0) ->
      +    Map0#{a => A, b => B, c => C}.

      If the compiler cannot determine that the third argument is always a map, it retains the maps:put/3 call. For example, given this -function:

      add_to_map(Map0, A, B, C) ->
      -    Map1 = maps:put(a, A, Map0),
      -    Map2 = maps:put(b, B, Map1),
      -    maps:put(c, C, Map2).

      the compiler keeps the first call to maps:put/3, but rewrites -and combines the other two calls:

      add_to_map(Map0, A, B, C) ->
      -    Map1 = maps:put(a, A, Map0),
      -    Map1#{b => B, c => C}.

      Change

      The rewriting of maps:put/3 to the map syntax was introduced in +function:

      add_to_map(Map0, A, B, C) ->
      +    Map1 = maps:put(a, A, Map0),
      +    Map2 = maps:put(b, B, Map1),
      +    maps:put(c, C, Map2).

      the compiler keeps the first call to maps:put/3, but rewrites +and combines the other two calls:

      add_to_map(Map0, A, B, C) ->
      +    Map1 = maps:put(a, A, Map0),
      +    Map1#{b => B, c => C}.

      Change

      The rewriting of maps:put/3 to the map syntax was introduced in Erlang/OTP 28.

      diff --git a/prs/8803/doc/system/modules.html b/prs/8803/doc/system/modules.html index a3cefbf17bd05..22e61a6c50f43 100644 --- a/prs/8803/doc/system/modules.html +++ b/prs/8803/doc/system/modules.html @@ -122,12 +122,12 @@

      Module Syntax

      Erlang code is divided into modules. A module consists of a sequence of -attributes and function declarations, each terminated by a period (.).

      Example:

      -module(m).          % module attribute
      --export([fact/1]).   % module attribute
      +attributes and function declarations, each terminated by a period (.).

      Example:

      -module(m).          % module attribute
      +-export([fact/1]).   % module attribute
       
      -fact(N) when N>0 ->  % beginning of function declaration
      -    N * fact(N-1);   %  |
      -fact(0) ->           %  |
      +fact(N) when N>0 ->  % beginning of function declaration
      +    N * fact(N-1);   %  |
      +fact(0) ->           %  |
           1.               % end of function declaration

      For a description of function declarations, see Function Declaration Syntax.

      @@ -180,9 +180,9 @@

      Behaviour Module Attribute

      It is possible to specify that the module is the callback module for a -behaviour:

      -behaviour(Behaviour).

      The atom Behaviour gives the name of the behaviour, which can be a +behaviour:

      -behaviour(Behaviour).

      The atom Behaviour gives the name of the behaviour, which can be a user-defined behaviour or one of the following OTP standard behaviours:

      • gen_server
      • gen_statem
      • gen_event
      • supervisor

      The spelling behavior is also accepted.

      The callback functions of the module can be specified either directly by the -exported function behaviour_info/1:

      behaviour_info(callbacks) -> Callbacks.

      or by a -callback attribute for each callback function:

      -callback Name(Arguments) -> Result.

      Here, Arguments is a list of zero or more arguments. The -callback attribute +exported function behaviour_info/1:

      behaviour_info(callbacks) -> Callbacks.

      or by a -callback attribute for each callback function:

      -callback Name(Arguments) -> Result.

      Here, Arguments is a list of zero or more arguments. The -callback attribute is to be preferred since the extra type information can be used by tools to produce documentation or find discrepancies.

      Read more about behaviours and callback modules in OTP Design Principles.

      @@ -191,7 +191,7 @@

      Record Definitions

      -

      The same syntax as for module attributes is used for record definitions:

      -record(Record, Fields).

      Record definitions are allowed anywhere in a module, also among the function +

      The same syntax as for module attributes is used for record definitions:

      -record(Record, Fields).

      Record definitions are allowed anywhere in a module, also among the function declarations. Read more in Records.

      @@ -199,15 +199,15 @@

      Preprocessor

      The same syntax as for module attributes is used by the preprocessor, which -supports file inclusion, macros, and conditional compilation:

      -include("SomeFile.hrl").
      --define(Macro, Replacement).

      Read more in Preprocessor.

      +supports file inclusion, macros, and conditional compilation:

      -include("SomeFile.hrl").
      +-define(Macro, Replacement).

      Read more in Preprocessor.

      Setting File and Line

      The same syntax as for module attributes is used for changing the pre-defined -macros ?FILE and ?LINE:

      -file(File, Line).

      This attribute is used by tools, such as Yecc, to inform the compiler that the +macros ?FILE and ?LINE:

      -file(File, Line).

      This attribute is used by tools, such as Yecc, to inform the compiler that the source program is generated by another tool. It also indicates the correspondence of source files to lines of the original user-written file, from which the source program is produced.

      @@ -217,8 +217,8 @@

      Types and function specifications

      A similar syntax as for module attributes is used for specifying types and -function specifications:

      -type my_type() :: atom() | integer().
      --spec my_function(integer()) -> integer().

      Read more in Types and Function specifications.

      The description is based on +function specifications:

      -type my_type() :: atom() | integer().
      +-spec my_function(integer()) -> integer().

      Read more in Types and Function specifications.

      The description is based on EEP8 - Types and function specifications, which is not to be further updated.

      @@ -227,16 +227,16 @@

      Documentation attributes

      The module attribute -doc(Documentation) is used to provide user documentation -for a function/type/callback:

      -doc("Example documentation").
      -example() -> ok.

      The attribute should be placed just before the entity it documents.The +for a function/type/callback:

      -doc("Example documentation").
      +example() -> ok.

      The attribute should be placed just before the entity it documents.The parenthesis are optional around Documentation. The allowed values for Documentation are:

      • literal string or utf-8 encoded binary string - The string documenting the entity. Any literal string is allowed, so both triple quoted strings and sigils that translate to literal strings can be used. -The following examples are equivalent:

        -doc("Example \"docs\"").
        --doc(<<"Example \"docs\""/utf8>>).
        +The following examples are equivalent:

        -doc("Example \"docs\"").
        +-doc(<<"Example \"docs\""/utf8>>).
         -doc ~S/Example "docs"/.
         -doc """
            Example "docs"
        @@ -257,7 +257,7 @@ 

        While not a module attribute, but rather a directive (since it might affect syntax), there is the -feature(..) directive used for enabling and disabling -features.

        The syntax is similar to that of an attribute, but has two arguments:

        -feature(FeatureName, enable | disable).

        Note that the feature directive can only appear +features.

        The syntax is similar to that of an attribute, but has two arguments:

        -feature(FeatureName, enable | disable).

        Note that the feature directive can only appear in a prefix of the module.

        diff --git a/prs/8803/doc/system/nif.html b/prs/8803/doc/system/nif.html index 383235a7e5e87..125c1482a2f7a 100644 --- a/prs/8803/doc/system/nif.html +++ b/prs/8803/doc/system/nif.html @@ -137,18 +137,18 @@

        they can also be used as fallback implementations for functions that do not have native implementations on some architectures.

        NIF libraries are loaded by calling erlang:load_nif/2, with the name of the shared library as argument. The second argument can be any term that will be -passed on to the library and used for initialization:

        -module(complex6).
        --export([foo/1, bar/1]).
        --nifs([foo/1, bar/1]).
        --on_load(init/0).
        -
        -init() ->
        -    ok = erlang:load_nif("./complex6_nif", 0).
        -
        -foo(_X) ->
        -    erlang:nif_error(nif_library_not_loaded).
        -bar(_Y) ->
        -    erlang:nif_error(nif_library_not_loaded).

        Here, the directive on_load is used to get function init to be automatically +passed on to the library and used for initialization:

        -module(complex6).
        +-export([foo/1, bar/1]).
        +-nifs([foo/1, bar/1]).
        +-on_load(init/0).
        +
        +init() ->
        +    ok = erlang:load_nif("./complex6_nif", 0).
        +
        +foo(_X) ->
        +    erlang:nif_error(nif_library_not_loaded).
        +bar(_Y) ->
        +    erlang:nif_error(nif_library_not_loaded).

        Here, the directive on_load is used to get function init to be automatically called when the module is loaded. If init returns anything other than ok, such when the loading of the NIF library fails in this example, the module is unloaded and calls to functions within it, fail.

        Loading the NIF library overrides the stub implementations and cause calls to @@ -169,35 +169,35 @@

        API functions. The environment contains information about the calling Erlang process:

        #include <erl_nif.h>
         
        -extern int foo(int x);
        -extern int bar(int y);
        +extern int foo(int x);
        +extern int bar(int y);
         
        -static ERL_NIF_TERM foo_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
        -{
        +static ERL_NIF_TERM foo_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
        +{
             int x, ret;
        -    if (!enif_get_int(env, argv[0], &x)) {
        -	return enif_make_badarg(env);
        -    }
        -    ret = foo(x);
        -    return enif_make_int(env, ret);
        -}
        -
        -static ERL_NIF_TERM bar_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
        -{
        +    if (!enif_get_int(env, argv[0], &x)) {
        +	return enif_make_badarg(env);
        +    }
        +    ret = foo(x);
        +    return enif_make_int(env, ret);
        +}
        +
        +static ERL_NIF_TERM bar_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
        +{
             int y, ret;
        -    if (!enif_get_int(env, argv[0], &y)) {
        -	return enif_make_badarg(env);
        -    }
        -    ret = bar(y);
        -    return enif_make_int(env, ret);
        -}
        -
        -static ErlNifFunc nif_funcs[] = {
        -    {"foo", 1, foo_nif},
        -    {"bar", 1, bar_nif}
        -};
        -
        -ERL_NIF_INIT(complex6, nif_funcs, NULL, NULL, NULL, NULL)

        Here, ERL_NIF_INIT has the following arguments:

        • The first argument must be the name of the Erlang module as a C-identifier. It + if (!enif_get_int(env, argv[0], &y)) { + return enif_make_badarg(env); + } + ret = bar(y); + return enif_make_int(env, ret); +} + +static ErlNifFunc nif_funcs[] = { + {"foo", 1, foo_nif}, + {"bar", 1, bar_nif} +}; + +ERL_NIF_INIT(complex6, nif_funcs, NULL, NULL, NULL, NULL)

        Here, ERL_NIF_INIT has the following arguments:

        • The first argument must be the name of the Erlang module as a C-identifier. It will be stringified by the macro.
        • The second argument is the array of ErlNifFunc structures containing name, arity, and function pointer of each NIF.
        • The remaining arguments are pointers to callback functions that can be used to initialize the library. They are not used in this simple example, hence they @@ -213,15 +213,15 @@

          Step 1. Compile the C code:

          unix> gcc -o complex6_nif.so -fpic -shared complex.c complex6_nif.c
           windows> cl -LD -MD -Fe complex6_nif.dll complex.c complex6_nif.c

          Step 2: Start Erlang and compile the Erlang code:

          > erl
          -Erlang R13B04 (erts-5.7.5) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
          +Erlang R13B04 (erts-5.7.5) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
           
          -Eshell V5.7.5  (abort with ^G)
          -1> c(complex6).
          -{ok,complex6}

          Step 3: Run the example:

          3> complex6:foo(3).
          +Eshell V5.7.5  (abort with ^G)
          +1> c(complex6).
          +{ok,complex6}

          Step 3: Run the example:

          3> complex6:foo(3).
           4
          -4> complex6:bar(5).
          +4> complex6:bar(5).
           10
          -5> complex6:foo("not an integer").
          +5> complex6:foo("not an integer").
           ** exception error: bad argument
                in function  complex6:foo/1
                   called as comlpex6:foo("not an integer")
          diff --git a/prs/8803/doc/system/opaques.html b/prs/8803/doc/system/opaques.html index ca514418fbf03..62282db7e3e79 100644 --- a/prs/8803/doc/system/opaques.html +++ b/prs/8803/doc/system/opaques.html @@ -126,16 +126,16 @@

          The runtime does not check opacity. Dialyzer provides some opacity-checking, but the rest is up to convention.

          This document explains what Erlang opacity is (and the trade-offs involved) via the example of the sets:set() data type. This type was -defined in the sets module like this:

          -opaque set(Element) :: #set{segs :: segs(Element)}.

          OTP 24 changed the definition to the following in -this commit.

          -opaque set(Element) :: #set{segs :: segs(Element)} | #{Element => ?VALUE}.

          And this change was safer and more backwards-compatible than if the type had +defined in the sets module like this:

          -opaque set(Element) :: #set{segs :: segs(Element)}.

          OTP 24 changed the definition to the following in +this commit.

          -opaque set(Element) :: #set{segs :: segs(Element)} | #{Element => ?VALUE}.

          And this change was safer and more backwards-compatible than if the type had been defined with -type instead of -opaque. Here is why: when a module defines an -opaque, the contract is that only the defining module should rely on the definition of the type: no other modules should rely on the definition.

          This means that code that pattern-matched on set as a record/tuple technically broke the contract, and opted in to being potentially broken when the definition of set() changed. Before OTP 24, this code printed ok. In OTP 24 it may -error:

          case sets:new() of
          -    Set when is_tuple(Set) ->
          -        io:format("ok")
          +error:

          case sets:new() of
          +    Set when is_tuple(Set) ->
          +        io:format("ok")
           end.

          When working with an opaque defined in another module, here are some recommendations:

          • Don't examine the underlying type using pattern-matching, guards, or functions that reveal the type, such as tuple_size/1 .
          • Instead, use functions provided by the module for working with the type. For diff --git a/prs/8803/doc/system/otp-patch-apply.html b/prs/8803/doc/system/otp-patch-apply.html index 4eb2c47a5efec..d2754922a2577 100644 --- a/prs/8803/doc/system/otp-patch-apply.html +++ b/prs/8803/doc/system/otp-patch-apply.html @@ -205,7 +205,7 @@

            Application dependencies are verified among installed applications by otp_patch_apply, but these are not necessarily those actually loaded. By calling system_information:sanity_check() one can validate -dependencies among applications actually loaded.

            1> system_information:sanity_check().
            +dependencies among applications actually loaded.

            1> system_information:sanity_check().
             ok

            Please take a look at the reference of sanity_check() for more information.

    diff --git a/prs/8803/doc/system/patterns.html b/prs/8803/doc/system/patterns.html index cde2f71cd135c..4d2f58cdfbeb6 100644 --- a/prs/8803/doc/system/patterns.html +++ b/prs/8803/doc/system/patterns.html @@ -132,10 +132,10 @@

    2 3> X + 1. 3 -4> {X, Y} = {1, 2}. +4> {X, Y} = {1, 2}. ** exception error: no match of right hand side value {1,2} -5> {X, Y} = {2, 3}. -{2,3} +5> {X, Y} = {2, 3}. +{2,3} 6> Y. 3

    diff --git a/prs/8803/doc/system/prog_ex_records.html b/prs/8803/doc/system/prog_ex_records.html index 2daaff3a3ec39..7828e206e2b9d 100644 --- a/prs/8803/doc/system/prog_ex_records.html +++ b/prs/8803/doc/system/prog_ex_records.html @@ -126,17 +126,17 @@

    To illustrate these differences, suppose that you want to represent a person with the tuple {Name, Address, Phone}.

    To write functions that manipulate this data, remember the following:

    • The Name field is the first element of the tuple.
    • The Address field is the second element.
    • The Phone field is the third element.

    For example, to extract data from a variable P that contains such a tuple, you can write the following code and then use pattern matching to extract the -relevant fields:

    Name = element(1, P),
    -Address = element(2, P),
    +relevant fields:

    Name = element(1, P),
    +Address = element(2, P),
     ...

    Such code is difficult to read and understand, and errors occur if the numbering of the elements in the tuple is wrong. If the data representation of the fields is changed, by re-ordering, adding, or removing fields, all references to the person tuple must be checked and possibly modified.

    Records allow references to the fields by name, instead of by position. In the -following example, a record instead of a tuple is used to store the data:

    -record(person, {name, phone, address}).

    This enables references to the fields of the record by name. For example, if P +following example, a record instead of a tuple is used to store the data:

    -record(person, {name, phone, address}).

    This enables references to the fields of the record by name. For example, if P is a variable whose value is a person record, the following code access the name and address fields of the records:

    Name = P#person.name,
     Address = P#person.address,
    -...

    Internally, records are represented using tagged tuples:

    {person, Name, Phone, Address}

    +...

    Internally, records are represented using tagged tuples:

    {person, Name, Phone, Address}

    @@ -146,8 +146,8 @@

    section. Three fields are included, name, phone, and address. The default values for name and phone is "" and [], respectively. The default value for address is the atom undefined, since no default value is supplied for this -field:

    -record(person, {name = "", phone = [], address}).

    The record must be defined in the shell to enable use of the record syntax in -the examples:

    > rd(person, {name = "", phone = [], address}).
    +field:

    -record(person, {name = "", phone = [], address}).

    The record must be defined in the shell to enable use of the record syntax in +the examples:

    > rd(person, {name = "", phone = [], address}).
     person

    This is because record definitions are only available at compile time, not at runtime. For details on records in the shell, see the shell manual page in STDLIB.

    @@ -156,10 +156,10 @@

    Creating a Record

    -

    A new person record is created as follows:

    > #person{phone=[0,8,2,3,4,3,1,2], name="Robert"}.
    -#person{name = "Robert",phone = [0,8,2,3,4,3,1,2],address = undefined}

    As the address field was omitted, its default value is used.

    From Erlang 5.1/OTP R8B, a value to all fields in a record can be set with the -special field _. _ means "all fields not explicitly specified".

    Example:

    > #person{name = "Jakob", _ = '_'}.
    -#person{name = "Jakob",phone = '_',address = '_'}

    It is primarily intended to be used in ets:match/2 and +

    A new person record is created as follows:

    > #person{phone=[0,8,2,3,4,3,1,2], name="Robert"}.
    +#person{name = "Robert",phone = [0,8,2,3,4,3,1,2],address = undefined}

    As the address field was omitted, its default value is used.

    From Erlang 5.1/OTP R8B, a value to all fields in a record can be set with the +special field _. _ means "all fields not explicitly specified".

    Example:

    > #person{name = "Jakob", _ = '_'}.
    +#person{name = "Jakob",phone = '_',address = '_'}

    It is primarily intended to be used in ets:match/2 and mnesia:match_object/3, to set record fields to the atom '_'. (This is a wildcard in ets:match/2.)

    @@ -167,8 +167,8 @@

    Accessing a Record Field

    -

    The following example shows how to access a record field:

    > P = #person{name = "Joe", phone = [0,8,2,3,4,3,1,2]}.
    -#person{name = "Joe",phone = [0,8,2,3,4,3,1,2],address = undefined}
    +

    The following example shows how to access a record field:

    > P = #person{name = "Joe", phone = [0,8,2,3,4,3,1,2]}.
    +#person{name = "Joe",phone = [0,8,2,3,4,3,1,2],address = undefined}
     > P#person.name.
     "Joe"

    @@ -176,33 +176,33 @@

    Updating a Record

    -

    The following example shows how to update a record:

    > P1 = #person{name="Joe", phone=[1,2,3], address="A street"}.
    -#person{name = "Joe",phone = [1,2,3],address = "A street"}
    -> P2 = P1#person{name="Robert"}.
    -#person{name = "Robert",phone = [1,2,3],address = "A street"}

    +

    The following example shows how to update a record:

    > P1 = #person{name="Joe", phone=[1,2,3], address="A street"}.
    +#person{name = "Joe",phone = [1,2,3],address = "A street"}
    +> P2 = P1#person{name="Robert"}.
    +#person{name = "Robert",phone = [1,2,3],address = "A street"}

    Type Testing

    The following example shows that the guard succeeds if P is record of type -person:

    foo(P) when is_record(P, person) -> a_person;
    -foo(_) -> not_a_person.

    +person:

    foo(P) when is_record(P, person) -> a_person;
    +foo(_) -> not_a_person.

    Pattern Matching

    Matching can be used in combination with records, as shown in the following -example:

    > P3 = #person{name="Joe", phone=[0,0,7], address="A street"}.
    -#person{name = "Joe",phone = [0,0,7],address = "A street"}
    -> #person{name = Name} = P3, Name.
    +example:

    > P3 = #person{name="Joe", phone=[0,0,7], address="A street"}.
    +#person{name = "Joe",phone = [0,0,7],address = "A street"}
    +> #person{name = Name} = P3, Name.
     "Joe"

    The following function takes a list of person records and searches for the -phone number of a person with a particular name:

    find_phone([#person{name=Name, phone=Phone} | _], Name) ->
    -    {found,  Phone};
    -find_phone([_| T], Name) ->
    -    find_phone(T, Name);
    -find_phone([], Name) ->
    +phone number of a person with a particular name:

    find_phone([#person{name=Name, phone=Phone} | _], Name) ->
    +    {found,  Phone};
    +find_phone([_| T], Name) ->
    +    find_phone(T, Name);
    +find_phone([], Name) ->
         not_found.

    The fields referred to in the pattern can be given in any order.

    @@ -211,12 +211,12 @@

    The value of a field in a record can be an instance of a record. Retrieval of nested data can be done stepwise, or in a single step, as shown in the following -example:

    -record(name, {first = "Robert", last = "Ericsson"}).
    --record(person, {name = #name{}, phone}).
    +example:

    -record(name, {first = "Robert", last = "Ericsson"}).
    +-record(person, {name = #name{}, phone}).
     
    -demo() ->
    -  P = #person{name= #name{first="Robert",last="Virding"}, phone=123},
    -  First = (P#person.name)#name.first.

    Here, demo() evaluates to "Robert".

    +demo() -> + P = #person{name= #name{first="Robert",last="Virding"}, phone=123}, + First = (P#person.name)#name.first.

    Here, demo() evaluates to "Robert".

    @@ -234,40 +234,40 @@

    %% about the person. %% A {Key, Value} list (default is the empty list). %%------------------------------------------------------------ --record(person, {name, age, phone = [], dict = []}).

    -module(person).
    --include("person.hrl").
    --compile(export_all). % For test purposes only.
    +-record(person, {name, age, phone = [], dict = []}).
    -module(person).
    +-include("person.hrl").
    +-compile(export_all). % For test purposes only.
     
     %% This creates an instance of a person.
     %%   Note: The phone number is not supplied so the
     %%         default value [] will be used.
     
    -make_hacker_without_phone(Name, Age) ->
    -   #person{name = Name, age = Age,
    -           dict = [{computer_knowledge, excellent},
    -                   {drinks, coke}]}.
    +make_hacker_without_phone(Name, Age) ->
    +   #person{name = Name, age = Age,
    +           dict = [{computer_knowledge, excellent},
    +                   {drinks, coke}]}.
     
     %% This demonstrates matching in arguments
     
    -print(#person{name = Name, age = Age,
    -              phone = Phone, dict = Dict}) ->
    -  io:format("Name: ~s, Age: ~w, Phone: ~w ~n"
    -            "Dictionary: ~w.~n", [Name, Age, Phone, Dict]).
    +print(#person{name = Name, age = Age,
    +              phone = Phone, dict = Dict}) ->
    +  io:format("Name: ~s, Age: ~w, Phone: ~w ~n"
    +            "Dictionary: ~w.~n", [Name, Age, Phone, Dict]).
     
     %% Demonstrates type testing, selector, updating.
     
    -birthday(P) when is_record(P, person) ->
    -   P#person{age = P#person.age + 1}.
    +birthday(P) when is_record(P, person) ->
    +   P#person{age = P#person.age + 1}.
     
    -register_two_hackers() ->
    -   Hacker1 = make_hacker_without_phone("Joe", 29),
    -   OldHacker = birthday(Hacker1),
    +register_two_hackers() ->
    +   Hacker1 = make_hacker_without_phone("Joe", 29),
    +   OldHacker = birthday(Hacker1),
        % The central_register_server should have
        % an interface function for this.
    -   central_register_server ! {register_person, Hacker1},
    -   central_register_server ! {register_person,
    -             OldHacker#person{name = "Robert",
    -                              phone = [0,8,3,2,4,5,3,1]}}.
    +
    central_register_server ! {register_person, Hacker1}, + central_register_server ! {register_person, + OldHacker#person{name = "Robert", + phone = [0,8,3,2,4,5,3,1]}}.

    diff --git a/prs/8803/doc/system/records_macros.html b/prs/8803/doc/system/records_macros.html index 4b63d8897fda5..f7029bafb9e6b 100644 --- a/prs/8803/doc/system/records_macros.html +++ b/prs/8803/doc/system/records_macros.html @@ -128,7 +128,7 @@

    introduced:

    %%%----FILE mess_config.hrl----
     
     %%% Configure the location of the server node,
    --define(server_node, messenger@super).
    +-define(server_node, messenger@super).
     
     %%%----END FILE----
    %%%----FILE mess_interface.hrl----
     
    @@ -136,24 +136,24 @@ 

    %%% messenger program %%%Messages from Client to server received in server/1 function. --record(logon,{client_pid, username}). --record(message,{client_pid, to_name, message}). +-record(logon,{client_pid, username}). +-record(message,{client_pid, to_name, message}). %%% {'EXIT', ClientPid, Reason} (client terminated or unreachable. %%% Messages from Server to Client, received in await_result/0 function --record(abort_client,{message}). +-record(abort_client,{message}). %%% Messages are: user_exists_at_other_node, %%% you_are_not_logged_on --record(server_reply,{message}). +-record(server_reply,{message}). %%% Messages are: logged_on %%% receiver_not_found %%% sent (Message has been sent (no guarantee) %%% Messages from Server to Client received in client/1 function --record(message_from,{from_name, message}). +-record(message_from,{from_name, message}). %%% Messages from shell to Client received in client/1 function %%% spawn(mess_client, client, [server_node(), Name]) --record(message_to,{to_name, message}). +-record(message_to,{to_name, message}). %%% logoff %%%----END FILE----

    %%%----FILE user_interface.erl----
    @@ -174,27 +174,27 @@ 

    %%% function is not logged on or if ToName is not logged on at %%% any node. --module(user_interface). --export([logon/1, logoff/0, message/2]). --include("mess_interface.hrl"). --include("mess_config.hrl"). +-module(user_interface). +-export([logon/1, logoff/0, message/2]). +-include("mess_interface.hrl"). +-include("mess_config.hrl"). -logon(Name) -> - case whereis(mess_client) of +logon(Name) -> + case whereis(mess_client) of undefined -> - register(mess_client, - spawn(mess_client, client, [?server_node, Name])); + register(mess_client, + spawn(mess_client, client, [?server_node, Name])); _ -> already_logged_on end. -logoff() -> +logoff() -> mess_client ! logoff. -message(ToName, Message) -> - case whereis(mess_client) of % Test if the client is running +message(ToName, Message) -> + case whereis(mess_client) of % Test if the client is running undefined -> not_logged_on; - _ -> mess_client ! #message_to{to_name=ToName, message=Message}, + _ -> mess_client ! #message_to{to_name=ToName, message=Message}, ok end. @@ -202,107 +202,107 @@

    %%% The client process which runs on each user node --module(mess_client). --export([client/2]). --include("mess_interface.hrl"). +-module(mess_client). +-export([client/2]). +-include("mess_interface.hrl"). -client(Server_Node, Name) -> - {messenger, Server_Node} ! #logon{client_pid=self(), username=Name}, - await_result(), - client(Server_Node). +client(Server_Node, Name) -> + {messenger, Server_Node} ! #logon{client_pid=self(), username=Name}, + await_result(), + client(Server_Node). -client(Server_Node) -> +client(Server_Node) -> receive logoff -> - exit(normal); - #message_to{to_name=ToName, message=Message} -> - {messenger, Server_Node} ! - #message{client_pid=self(), to_name=ToName, message=Message}, - await_result(); - {message_from, FromName, Message} -> - io:format("Message from ~p: ~p~n", [FromName, Message]) + exit(normal); + #message_to{to_name=ToName, message=Message} -> + {messenger, Server_Node} ! + #message{client_pid=self(), to_name=ToName, message=Message}, + await_result(); + {message_from, FromName, Message} -> + io:format("Message from ~p: ~p~n", [FromName, Message]) end, - client(Server_Node). + client(Server_Node). %%% wait for a response from the server -await_result() -> +await_result() -> receive - #abort_client{message=Why} -> - io:format("~p~n", [Why]), - exit(normal); - #server_reply{message=What} -> - io:format("~p~n", [What]) + #abort_client{message=Why} -> + io:format("~p~n", [Why]), + exit(normal); + #server_reply{message=What} -> + io:format("~p~n", [What]) after 5000 -> - io:format("No response from server~n", []), - exit(timeout) + io:format("No response from server~n", []), + exit(timeout) end. %%%----END FILE---

    %%%----FILE mess_server.erl----
     
     %%% This is the server process of the messenger service
     
    --module(mess_server).
    --export([start_server/0, server/0]).
    --include("mess_interface.hrl").
    +-module(mess_server).
    +-export([start_server/0, server/0]).
    +-include("mess_interface.hrl").
     
    -server() ->
    -    process_flag(trap_exit, true),
    -    server([]).
    +server() ->
    +    process_flag(trap_exit, true),
    +    server([]).
     
     %%% the user list has the format [{ClientPid1, Name1},{ClientPid22, Name2},...]
    -server(User_List) ->
    -    io:format("User list = ~p~n", [User_List]),
    +server(User_List) ->
    +    io:format("User list = ~p~n", [User_List]),
         receive
    -        #logon{client_pid=From, username=Name} ->
    -            New_User_List = server_logon(From, Name, User_List),
    -            server(New_User_List);
    -        {'EXIT', From, _} ->
    -            New_User_List = server_logoff(From, User_List),
    -            server(New_User_List);
    -        #message{client_pid=From, to_name=To, message=Message} ->
    -            server_transfer(From, To, Message, User_List),
    -            server(User_List)
    +        #logon{client_pid=From, username=Name} ->
    +            New_User_List = server_logon(From, Name, User_List),
    +            server(New_User_List);
    +        {'EXIT', From, _} ->
    +            New_User_List = server_logoff(From, User_List),
    +            server(New_User_List);
    +        #message{client_pid=From, to_name=To, message=Message} ->
    +            server_transfer(From, To, Message, User_List),
    +            server(User_List)
         end.
     
     %%% Start the server
    -start_server() ->
    -    register(messenger, spawn(?MODULE, server, [])).
    +start_server() ->
    +    register(messenger, spawn(?MODULE, server, [])).
     
     %%% Server adds a new user to the user list
    -server_logon(From, Name, User_List) ->
    +server_logon(From, Name, User_List) ->
         %% check if logged on anywhere else
    -    case lists:keymember(Name, 2, User_List) of
    +    case lists:keymember(Name, 2, User_List) of
             true ->
    -            From ! #abort_client{message=user_exists_at_other_node},
    +            From ! #abort_client{message=user_exists_at_other_node},
                 User_List;
             false ->
    -            From ! #server_reply{message=logged_on},
    -            link(From),
    -            [{From, Name} | User_List]        %add user to the list
    +            From ! #server_reply{message=logged_on},
    +            link(From),
    +            [{From, Name} | User_List]        %add user to the list
         end.
     
     %%% Server deletes a user from the user list
    -server_logoff(From, User_List) ->
    -    lists:keydelete(From, 1, User_List).
    +server_logoff(From, User_List) ->
    +    lists:keydelete(From, 1, User_List).
     
     %%% Server transfers a message between user
    -server_transfer(From, To, Message, User_List) ->
    +server_transfer(From, To, Message, User_List) ->
         %% check that the user is logged on and who he is
    -    case lists:keysearch(From, 1, User_List) of
    +    case lists:keysearch(From, 1, User_List) of
             false ->
    -            From ! #abort_client{message=you_are_not_logged_on};
    -        {value, {_, Name}} ->
    -            server_transfer(From, Name, To, Message, User_List)
    +            From ! #abort_client{message=you_are_not_logged_on};
    +        {value, {_, Name}} ->
    +            server_transfer(From, Name, To, Message, User_List)
         end.
     %%% If the user exists, send the message
    -server_transfer(From, Name, To, Message, User_List) ->
    +server_transfer(From, Name, To, Message, User_List) ->
         %% Find the receiver and send the message
    -    case lists:keysearch(To, 2, User_List) of
    +    case lists:keysearch(To, 2, User_List) of
             false ->
    -            From ! #server_reply{message=receiver_not_found};
    -        {value, {ToPid, To}} ->
    -            ToPid ! #message_from{from_name=Name, message=Message},
    -            From !  #server_reply{message=sent}
    +            From ! #server_reply{message=receiver_not_found};
    +        {value, {ToPid, To}} ->
    +            ToPid ! #message_from{from_name=Name, message=Message},
    +            From !  #server_reply{message=sent}
         end.
     
     %%%----END FILE---

    @@ -312,7 +312,7 @@

    Header Files

    As shown above, some files have extension .hrl. These are header files that -are included in the .erl files by:

    -include("File_Name").

    for example:

    -include("mess_interface.hrl").

    In the case above the file is fetched from the same directory as all the other +are included in the .erl files by:

    -include("File_Name").

    for example:

    -include("mess_interface.hrl").

    In the case above the file is fetched from the same directory as all the other files in the messenger example. (manual).

    .hrl files can contain any valid Erlang code but are most often used for record and macro definitions.

    @@ -320,14 +320,14 @@

    Records

    -

    A record is defined as:

    -record(name_of_record,{field_name1, field_name2, field_name3, ......}).

    For example:

    -record(message_to,{to_name, message}).

    This is equivalent to:

    {message_to, To_Name, Message}

    Creating a record is best illustrated by an example:

    #message_to{message="hello", to_name=fred)

    This creates:

    {message_to, fred, "hello"}

    Notice that you do not have to worry about the order you assign values to the +

    A record is defined as:

    -record(name_of_record,{field_name1, field_name2, field_name3, ......}).

    For example:

    -record(message_to,{to_name, message}).

    This is equivalent to:

    {message_to, To_Name, Message}

    Creating a record is best illustrated by an example:

    #message_to{message="hello", to_name=fred)

    This creates:

    {message_to, fred, "hello"}

    Notice that you do not have to worry about the order you assign values to the various parts of the records when you create it. The advantage of using records is that by placing their definitions in header files you can conveniently define interfaces that are easy to change. For example, if you want to add a new field to the record, you only have to change the code where the new field is used and not at every place the record is referred to. If you leave out a field when creating a record, it gets the value of the atom undefined. (manual)

    Pattern matching with records is very similar to creating records. For example, -inside a case or receive:

    #message_to{to_name=ToName, message=Message} ->

    This is the same as:

    {message_to, ToName, Message}

    +inside a case or receive:

    #message_to{to_name=ToName, message=Message} ->

    This is the same as:

    {message_to, ToName, Message}

    @@ -335,8 +335,8 @@

    Another thing that has been added to the messenger is a macro. The file mess_config.hrl contains the definition:

    %%% Configure the location of the server node,
    --define(server_node, messenger@super).

    This file is included in mess_server.erl:

    -include("mess_config.hrl").

    Every occurrence of ?server_node in mess_server.erl is now replaced by -messenger@super.

    A macro is also used when spawning the server process:

    spawn(?MODULE, server, [])

    This is a standard macro (that is, defined by the system, not by the user). +-define(server_node, messenger@super).

    This file is included in mess_server.erl:

    -include("mess_config.hrl").

    Every occurrence of ?server_node in mess_server.erl is now replaced by +messenger@super.

    A macro is also used when spawning the server process:

    spawn(?MODULE, server, [])

    This is a standard macro (that is, defined by the system, not by the user). ?MODULE is always replaced by the name of the current module (that is, the -module definition near the start of the file). There are more advanced ways of using macros with, for example, parameters.

    The three Erlang (.erl) files in the messenger example are individually diff --git a/prs/8803/doc/system/ref_man_functions.html b/prs/8803/doc/system/ref_man_functions.html index 23432641f4c51..92184dd2c0a2d 100644 --- a/prs/8803/doc/system/ref_man_functions.html +++ b/prs/8803/doc/system/ref_man_functions.html @@ -124,10 +124,10 @@

    A function declaration is a sequence of function clauses separated by semicolons, and terminated by a period (.).

    A function clause consists of a clause head and a clause body, separated by ->.

    A clause head consists of the function name, an argument list, and an optional -guard sequence beginning with the keyword when:

    Name(Pattern11,...,Pattern1N) [when GuardSeq1] ->
    +guard sequence beginning with the keyword when:

    Name(Pattern11,...,Pattern1N) [when GuardSeq1] ->
         Body1;
     ...;
    -Name(PatternK1,...,PatternKN) [when GuardSeqK] ->
    +Name(PatternK1,...,PatternKN) [when GuardSeqK] ->
         BodyK.

    The function name is an atom. Each argument is a pattern.

    The number of arguments N is the arity of the function. A function is uniquely defined by the module name, function name, and arity. That is, two functions with the same name and in the same module, but with different arities @@ -135,10 +135,10 @@

    mod:f/N.

    A clause body consists of a sequence of expressions separated by comma (,):

    Expr1,
     ...,
     ExprN

    Valid Erlang expressions and guard sequences are described in -Expressions.

    Example:

    fact(N) when N > 0 ->  % first clause head
    -    N * fact(N-1);     % first clause body
    +Expressions.

    Example:

    fact(N) when N > 0 ->  % first clause head
    +    N * fact(N-1);     % first clause body
     
    -fact(0) ->             % second clause head
    +fact(0) ->             % second clause head
         1.                 % second clause body

    @@ -151,16 +151,16 @@

    clause is found that fulfills both of the following two conditions:

    1. The patterns in the clause head can be successfully matched against the given arguments.
    2. The guard sequence, if any, is true.

    If such a clause cannot be found, a function_clause runtime error occurs.

    If such a clause is found, the corresponding clause body is evaluated. That is, the expressions in the body are evaluated sequentially and the value of the last -expression is returned.

    Consider the function fact:

    -module(mod).
    --export([fact/1]).
    +expression is returned.

    Consider the function fact:

    -module(mod).
    +-export([fact/1]).
     
    -fact(N) when N > 0 ->
    -    N * fact(N - 1);
    -fact(0) ->
    +fact(N) when N > 0 ->
    +    N * fact(N - 1);
    +fact(0) ->
         1.

    Assume that you want to calculate the factorial for 1:

    1> mod:fact(1).

    Evaluation starts at the first clause. The pattern N is matched against argument 1. The matching succeeds and the guard (N > 0) is true, thus N is -bound to 1, and the corresponding body is evaluated:

    N * fact(N-1) => (N is bound to 1)
    -1 * fact(0)

    Now, fact(0) is called, and the function clauses are scanned +bound to 1, and the corresponding body is evaluated:

    N * fact(N-1) => (N is bound to 1)
    +1 * fact(0)

    Now, fact(0) is called, and the function clauses are scanned sequentially again. First, the pattern N is matched against 0. The matching succeeds, but the guard (N > 0) is false. Second, the pattern 0 is matched against the argument 0. The matching succeeds @@ -177,9 +177,9 @@

    tail-recursive call is done. This is to ensure that no system resources, for example, call stack, are consumed. This means that an infinite loop using tail-recursive calls will not exhaust the call -stack and can (in principle) run forever.

    Example:

    loop(N) ->
    -    io:format("~w~n", [N]),
    -    loop(N+1).

    The earlier factorial example is a counter-example. It is not +stack and can (in principle) run forever.

    Example:

    loop(N) ->
    +    io:format("~w~n", [N]),
    +    loop(N+1).

    The earlier factorial example is a counter-example. It is not tail-recursive, since a multiplication is done on the result of the recursive call to fact(N-1).

    @@ -195,9 +195,9 @@

    not need to be prefixed with the module name. Which BIFs that are auto-imported is specified in the erlang module in ERTS. For example, standard-type conversion BIFs like atom_to_list and BIFs allowed in guards can be called -without specifying the module name.

    Examples:

    1> tuple_size({a,b,c}).
    +without specifying the module name.

    Examples:

    1> tuple_size({a,b,c}).
     3
    -2> atom_to_list('Erlang').
    +2> atom_to_list('Erlang').
     "Erlang"

    diff --git a/prs/8803/doc/system/ref_man_processes.html b/prs/8803/doc/system/ref_man_processes.html index 42a1d1b293148..36d3ff5492078 100644 --- a/prs/8803/doc/system/ref_man_processes.html +++ b/prs/8803/doc/system/ref_man_processes.html @@ -129,10 +129,10 @@

    Process Creation

    -

    A process is created by calling spawn():

    spawn(Module, Name, Args) -> pid()
    -  Module = Name = atom()
    -  Args = [Arg1,...,ArgN]
    -    ArgI = term()

    spawn() creates a new process and returns the pid.

    The new process starts executing in Module:Name(Arg1,...,ArgN) where the +

    A process is created by calling spawn():

    spawn(Module, Name, Args) -> pid()
    +  Module = Name = atom()
    +  Args = [Arg1,...,ArgN]
    +    ArgI = term()

    spawn() creates a new process and returns the pid.

    The new process starts executing in Module:Name(Arg1,...,ArgN) where the arguments are the elements of the (possible empty) Args argument list.

    There exist a number of different spawn BIFs:

    diff --git a/prs/8803/doc/system/ref_man_records.html b/prs/8803/doc/system/ref_man_records.html index 55563e6c7f161..7b177fe9dc5e2 100644 --- a/prs/8803/doc/system/ref_man_records.html +++ b/prs/8803/doc/system/ref_man_records.html @@ -127,9 +127,9 @@

    A record definition consists of the name of the record, followed by the field names of the record. Record and field names must be atoms. Each field can be given an optional default value. If no default value is supplied, undefined is -used.

    -record(Name, {Field1 [= Expr1],
    +used.

    -record(Name, {Field1 [= Expr1],
                    ...
    -               FieldN [= ExprN]}).

    The default value for a field is an arbitrary expression, except that it must + FieldN [= ExprN]}).

    The default value for a field is an arbitrary expression, except that it must not use any variables.

    A record definition can be placed anywhere among the attributes and function declarations of a module, but the definition must come before any usage of the record.

    If a record is used in several modules, it is recommended that the record @@ -147,24 +147,24 @@

    default value instead.

    If several fields are to be assigned the same value, the following construction can be used:

    #Name{Field1=Expr1, ..., FieldK=ExprK, _=ExprL}

    Omitted fields then get the value of evaluating ExprL instead of their default values. This feature is primarily intended to be used to create patterns for ETS -and Mnesia match functions.

    Example:

    -record(person, {name, phone, address}).
    +and Mnesia match functions.

    Example:

    -record(person, {name, phone, address}).
     
    -lookup(Name, Tab) ->
    -    ets:match_object(Tab, #person{name=Name, _='_'}).

    +lookup(Name, Tab) -> + ets:match_object(Tab, #person{name=Name, _='_'}).

    Accessing Record Fields

    Expr#Name.Field

    Returns the value of the specified field. Expr is to evaluate to a Name -record.

    Example:

    -record(person, {name, phone, address}).
    +record.

    Example:

    -record(person, {name, phone, address}).
     
    -get_person_name(Person) ->
    +get_person_name(Person) ->
         Person#person.name.

    The following expression returns the position of the specified field in the -tuple representation of the record:

    #Name.Field

    Example:

    -record(person, {name, phone, address}).
    +tuple representation of the record:

    #Name.Field

    Example:

    -record(person, {name, phone, address}).
     
    -lookup(Name, List) ->
    -    lists:keyfind(Name, #person.name, List).

    +lookup(Name, List) -> + lists:keyfind(Name, #person.name, List).

    @@ -182,13 +182,13 @@

    Since record expressions are expanded to tuple expressions, creating records and accessing record fields are allowed in guards. However, all subexpressions (for initializing fields), must be valid guard -expressions as well.

    Examples:

    handle(Msg, State) when Msg =:= #msg{to=void, no=3} ->
    +expressions as well.

    Examples:

    handle(Msg, State) when Msg =:= #msg{to=void, no=3} ->
         ...
     
    -handle(Msg, State) when State#state.running =:= true ->
    -    ...

    There is also a type test BIF is_record(Term, RecordTag).

    Example:

    is_person(P) when is_record(P, person) ->
    +handle(Msg, State) when State#state.running =:= true ->
    +    ...

    There is also a type test BIF is_record(Term, RecordTag).

    Example:

    is_person(P) when is_record(P, person) ->
         true;
    -is_person(_P) ->
    +is_person(_P) ->
         false.

    @@ -202,11 +202,11 @@

    Nested Records

    -

    Assume the following record definitions:

    -record(nrec0, {name = "nested0"}).
    --record(nrec1, {name = "nested1", nrec0=#nrec0{}}).
    --record(nrec2, {name = "nested2", nrec1=#nrec1{}}).
    +

    Assume the following record definitions:

    -record(nrec0, {name = "nested0"}).
    +-record(nrec1, {name = "nested1", nrec0=#nrec0{}}).
    +-record(nrec2, {name = "nested2", nrec1=#nrec1{}}).
     
    -N2 = #nrec2{},

    Accessing or updating nested records can be written without parentheses:

    "nested0" = N2#nrec2.nrec1#nrec1.nrec0#nrec0.name,
    +N2 = #nrec2{},

    Accessing or updating nested records can be written without parentheses:

    "nested0" = N2#nrec2.nrec1#nrec1.nrec0#nrec0.name,
         N0n = N2#nrec2.nrec1#nrec1.nrec0#nrec0{name = "nested0a"},

    which is equivalent to:

    "nested0" = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0.name,
     N0n = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0{name = "nested0a"},

    Change

    Before Erlang/OTP R14, parentheses were necessary when accessing or updating nested records.

    @@ -216,9 +216,9 @@

    Internal Representation of Records

    Record expressions are translated to tuple expressions during compilation. A -record defined as:

    -record(Name, {Field1, ..., FieldN}).

    is internally represented by the tuple:

    {Name, Value1, ..., ValueN}

    Here each ValueI is the default value for FieldI.

    To each module using records, a pseudo function is added during compilation to -obtain information about records:

    record_info(fields, Record) -> [Field]
    -record_info(size, Record) -> Size

    Size is the size of the tuple representation, that is, one more than the +record defined as:

    -record(Name, {Field1, ..., FieldN}).

    is internally represented by the tuple:

    {Name, Value1, ..., ValueN}

    Here each ValueI is the default value for FieldI.

    To each module using records, a pseudo function is added during compilation to +obtain information about records:

    record_info(fields, Record) -> [Field]
    +record_info(size, Record) -> Size

    Size is the size of the tuple representation, that is, one more than the number of fields.

    diff --git a/prs/8803/doc/system/release_handling.html b/prs/8803/doc/system/release_handling.html index 1ebbce6714efd..a94601283b8a6 100644 --- a/prs/8803/doc/system/release_handling.html +++ b/prs/8803/doc/system/release_handling.html @@ -227,15 +227,15 @@

    Instead, it is necessary to:

    • Suspend the processes using the module (to avoid that they try to handle any requests before the code replacement is completed).
    • Ask them to transform the internal state format and switch to the new version of the module.
    • Remove the old version.
    • Resume the processes.

    This is called synchronized code replacement and for this the following -instructions are used:

    {update, Module, {advanced, Extra}}
    -{update, Module, supervisor}

    update with argument {advanced,Extra} is used when changing the internal +instructions are used:

    {update, Module, {advanced, Extra}}
    +{update, Module, supervisor}

    update with argument {advanced,Extra} is used when changing the internal state of a behaviour as described above. It causes behaviour processes to call the callback function code_change/3, passing the term Extra and some other information as arguments. See the manual pages for the respective behaviours and Appup Cookbook.

    update with argument supervisor is used when changing the start specification of a supervisor. See Appup Cookbook.

    When a module is to be updated, the release handler finds which processes that are using the module by traversing the supervision tree of each running -application and checking all the child specifications:

    {Id, StartFunc, Restart, Shutdown, Type, Modules}

    A process uses a module if the name is listed in Modules in the child +application and checking all the child specifications:

    {Id, StartFunc, Restart, Shutdown, Type, Modules}

    A process uses a module if the name is listed in Modules in the child specification for the process.

    If Modules=dynamic, which is the case for event managers, the event manager process informs the release handler about the list of currently installed event handlers (gen_event), and it is checked if the module name is in this list @@ -247,10 +247,10 @@

    add_module and delete_module

    -

    If a new module is introduced, the following instruction is used:

    {add_module, Module}

    This instruction loads module Module. When running Erlang in +

    If a new module is introduced, the following instruction is used:

    {add_module, Module}

    This instruction loads module Module. When running Erlang in embedded mode it is necessary to use this this instruction. It is not strictly required when running Erlang in interactive mode, since the -code server automatically searches for and loads unloaded modules.

    The opposite of add_module is delete_module, which unloads a module:

    {delete_module, Module}

    Any process, in any application, with Module as residence module, is +code server automatically searches for and loads unloaded modules.

    The opposite of add_module is delete_module, which unloads a module:

    {delete_module, Module}

    Any process, in any application, with Module as residence module, is killed when the instruction is evaluated. Therefore, the user must ensure that all such processes are terminated before deleting module Module to avoid a situation with failing supervisor restarts.

    @@ -331,13 +331,13 @@

    To define how to upgrade/downgrade between the current version and previous versions of an application, an application upgrade file, or in short .appup file is created. The file is to be called Application.appup, where -Application is the application name:

    {Vsn,
    - [{UpFromVsn1, InstructionsU1},
    +Application is the application name:

    {Vsn,
    + [{UpFromVsn1, InstructionsU1},
       ...,
    -  {UpFromVsnK, InstructionsUK}],
    - [{DownToVsn1, InstructionsD1},
    +  {UpFromVsnK, InstructionsUK}],
    + [{DownToVsn1, InstructionsD1},
       ...,
    -  {DownToVsnK, InstructionsDK}]}.
    • Vsn, a string, is the current version of the application, as defined in the + {DownToVsnK, InstructionsDK}]}.
    • Vsn, a string, is the current version of the application, as defined in the .app file.
    • Each UpFromVsn is a previous version of the application to upgrade from.
    • Each DownToVsn is a previous version of the application to downgrade to.
    • Each Instructions is a list of release handling instructions.

    UpFromVsn and DownToVsn can also be specified as regular expressions. For more information about the syntax and contents of the .appup file, see appup in SASL.

    Appup Cookbook includes examples of .appup files for @@ -345,52 +345,52 @@

    Releases. Assume you want to add a function available/0 to server ch3, which returns the number of available channels (when trying out the example, make the change in a copy of the original -directory, to ensure that the first version is still available):

    -module(ch3).
    --behaviour(gen_server).
    +directory, to ensure that the first version is still available):

    -module(ch3).
    +-behaviour(gen_server).
     
    --export([start_link/0]).
    --export([alloc/0, free/1]).
    --export([available/0]).
    --export([init/1, handle_call/3, handle_cast/2]).
    -
    -start_link() ->
    -    gen_server:start_link({local, ch3}, ch3, [], []).
    -
    -alloc() ->
    -    gen_server:call(ch3, alloc).
    -
    -free(Ch) ->
    -    gen_server:cast(ch3, {free, Ch}).
    -
    -available() ->
    -    gen_server:call(ch3, available).
    -
    -init(_Args) ->
    -    {ok, channels()}.
    -
    -handle_call(alloc, _From, Chs) ->
    -    {Ch, Chs2} = alloc(Chs),
    -    {reply, Ch, Chs2};
    -handle_call(available, _From, Chs) ->
    -    N = available(Chs),
    -    {reply, N, Chs}.
    -
    -handle_cast({free, Ch}, Chs) ->
    -    Chs2 = free(Ch, Chs),
    -    {noreply, Chs2}.

    A new version of the ch_app.app file must now be created, where the version is -updated:

    {application, ch_app,
    - [{description, "Channel allocator"},
    -  {vsn, "2"},
    -  {modules, [ch_app, ch_sup, ch3]},
    -  {registered, [ch3]},
    -  {applications, [kernel, stdlib, sasl]},
    -  {mod, {ch_app,[]}}
    - ]}.

    To upgrade ch_app from "1" to "2" (and to downgrade from "2" to "1"), +-export([start_link/0]). +-export([alloc/0, free/1]). +-export([available/0]). +-export([init/1, handle_call/3, handle_cast/2]). + +start_link() -> + gen_server:start_link({local, ch3}, ch3, [], []). + +alloc() -> + gen_server:call(ch3, alloc). + +free(Ch) -> + gen_server:cast(ch3, {free, Ch}). + +available() -> + gen_server:call(ch3, available). + +init(_Args) -> + {ok, channels()}. + +handle_call(alloc, _From, Chs) -> + {Ch, Chs2} = alloc(Chs), + {reply, Ch, Chs2}; +handle_call(available, _From, Chs) -> + N = available(Chs), + {reply, N, Chs}. + +handle_cast({free, Ch}, Chs) -> + Chs2 = free(Ch, Chs), + {noreply, Chs2}.

    A new version of the ch_app.app file must now be created, where the version is +updated:

    {application, ch_app,
    + [{description, "Channel allocator"},
    +  {vsn, "2"},
    +  {modules, [ch_app, ch_sup, ch3]},
    +  {registered, [ch3]},
    +  {applications, [kernel, stdlib, sasl]},
    +  {mod, {ch_app,[]}}
    + ]}.

    To upgrade ch_app from "1" to "2" (and to downgrade from "2" to "1"), you only need to load the new (old) version of the ch3 callback module. Create -the application upgrade file ch_app.appup in the ebin directory:

    {"2",
    - [{"1", [{load_module, ch3}]}],
    - [{"1", [{load_module, ch3}]}]
    -}.

    +the application upgrade file ch_app.appup in the ebin directory:

    {"2",
    + [{"1", [{load_module, ch3}]}],
    + [{"1", [{load_module, ch3}]}]
    +}.

    @@ -409,14 +409,14 @@

    relup in SASL.

    Example, continued from the previous section: You have a new version "2" of ch_app and an .appup file. A new version of the .rel file is also needed. This time the file is called ch_rel-2.rel and the release version string is -changed from "A" to "B":

    {release,
    - {"ch_rel", "B"},
    - {erts, "14.2.5"},
    - [{kernel, "9.2.4"},
    -  {stdlib, "5.2.3"},
    -  {sasl, "4.2.1"},
    -  {ch_app, "2"}]
    -}.

    Now the relup file can be generated:

    1> systools:make_relup("ch_rel-2", ["ch_rel-1"], ["ch_rel-1"]).
    +changed from "A" to "B":

    {release,
    + {"ch_rel", "B"},
    + {erts, "14.2.5"},
    + [{kernel, "9.2.4"},
    +  {stdlib, "5.2.3"},
    +  {sasl, "4.2.1"},
    +  {ch_app, "2"}]
    +}.

    Now the relup file can be generated:

    1> systools:make_relup("ch_rel-2", ["ch_rel-1"], ["ch_rel-1"]).
     ok

    This generates a relup file with instructions for how to upgrade from version "A" ("ch_rel-1") to version "B" ("ch_rel-2") and how to downgrade from version "B" to version "A".

    Both the old and new versions of the .app and .rel files must be in the code @@ -437,17 +437,17 @@

    packages. The release_handler module communicates with this process.

    Assuming there is an operational target system with installation root directory $ROOT, the release package with the new version of the release is to be copied to $ROOT/releases.

    First, unpack the release package. The files are then extracted from the -package:

    release_handler:unpack_release(ReleaseName) => {ok, Vsn}
    • ReleaseName is the name of the release package except the .tar.gz +package:

      release_handler:unpack_release(ReleaseName) => {ok, Vsn}
      • ReleaseName is the name of the release package except the .tar.gz extension.
      • Vsn is the version of the unpacked release, as defined in its .rel file.

      A directory $ROOT/lib/releases/Vsn is created, where the .rel file, the boot script start.boot, the system configuration file sys.config, and relup are placed. For applications with new version numbers, the application directories are placed under $ROOT/lib. Unchanged applications are not affected.

      An unpacked release can be installed. The release handler then evaluates the -instructions in relup, step by step:

      release_handler:install_release(Vsn) => {ok, FromVsn, []}

      If an error occurs during the installation, the system is rebooted using the old +instructions in relup, step by step:

      release_handler:install_release(Vsn) => {ok, FromVsn, []}

      If an error occurs during the installation, the system is rebooted using the old version of the release. If installation succeeds, the system is afterwards using the new version of the release, but if anything happens and the system is rebooted, it starts using the previous version again.

      To be made the default version, the newly installed release must be made permanent, which means the previous version becomes old:

      release_handler:make_permanent(Vsn) => ok

      The system keeps information about which versions are old and permanent in the -files $ROOT/releases/RELEASES and $ROOT/releases/start_erl.data.

      To downgrade from Vsn to FromVsn, install_release must be called again:

      release_handler:install_release(FromVsn) => {ok, Vsn, []}

      An installed, but not permanent, release can be removed. Information about the +files $ROOT/releases/RELEASES and $ROOT/releases/start_erl.data.

      To downgrade from Vsn to FromVsn, install_release must be called again:

      release_handler:install_release(FromVsn) => {ok, Vsn, []}

      An installed, but not permanent, release can be removed. Information about the release is then deleted from $ROOT/releases/RELEASES and the release-specific code, that is, the new application directories and the $ROOT/releases/Vsn directory, are removed.

      release_handler:remove_release(Vsn) => ok

      @@ -466,9 +466,9 @@

      ...

    $ROOT is the installation directory of the target system.

    Step 3) In another Erlang shell, generate start scripts and create a release package for the new version "B". Remember to include (a possible updated) sys.config and the relup file. For more information, see -Release Upgrade File.

    1> systools:make_script("ch_rel-2").
    +Release Upgrade File.

    1> systools:make_script("ch_rel-2").
     ok
    -2> systools:make_tar("ch_rel-2").
    +2> systools:make_tar("ch_rel-2").
     ok

    The new release package now also contains version "2" of ch_app and the relup file:

    % tar tf ch_rel-2.tar
     lib/kernel-9.2.4/ebin/kernel.app
    @@ -489,23 +489,23 @@ 

    releases/B/sys.config releases/B/ch_rel-2.rel releases/ch_rel-2.rel

    Step 4) Copy the release package ch_rel-2.tar.gz to the $ROOT/releases -directory.

    Step 5) In the running target system, unpack the release package:

    1> release_handler:unpack_release("ch_rel-2").
    -{ok,"B"}

    The new application version ch_app-2 is installed under $ROOT/lib next to +directory.

    Step 5) In the running target system, unpack the release package:

    1> release_handler:unpack_release("ch_rel-2").
    +{ok,"B"}

    The new application version ch_app-2 is installed under $ROOT/lib next to ch_app-1. The kernel, stdlib, and sasl directories are not affected, as they have not changed.

    Under $ROOT/releases, a new directory B is created, containing -ch_rel-2.rel, start.boot, sys.config, and relup.

    Step 6) Check if the function ch3:available/0 is available:

    2> ch3:available().
    +ch_rel-2.rel, start.boot, sys.config, and relup.

    Step 6) Check if the function ch3:available/0 is available:

    2> ch3:available().
     ** exception error: undefined function ch3:available/0

    Step 7) Install the new release. The instructions in $ROOT/releases/B/relup are executed one by one, resulting in the new version of ch3 being loaded. The -function ch3:available/0 is now available:

    3> release_handler:install_release("B").
    -{ok,"A",[]}
    -4> ch3:available().
    +function ch3:available/0 is now available:

    3> release_handler:install_release("B").
    +{ok,"A",[]}
    +4> ch3:available().
     3
    -5> code:which(ch3).
    +5> code:which(ch3).
     ".../lib/ch_app-2/ebin/ch3.beam"
    -6> code:which(ch_sup).
    +6> code:which(ch_sup).
     ".../lib/ch_app-1/ebin/ch_sup.beam"

    Processes in ch_app for which code have not been updated, for example, the supervisor, are still evaluating code from ch_app-1.

    Step 8) If the target system is now rebooted, it uses version "A" again. The -"B" version must be made permanent, to be used when the system is rebooted.

    7> release_handler:make_permanent("B").
    +"B" version must be made permanent, to be used when the system is rebooted.

    7> release_handler:make_permanent("B").
     ok

    @@ -522,7 +522,7 @@

    values set using application:set_env/3 are disregarded.

    When an installed release is made permanent, the system process init is set to point out the new sys.config.

    After the installation, the application controller compares the old and new configuration parameters for all running applications and call the callback -function:

    Module:config_change(Changed, New, Removed)
    • Module is the application callback module as defined by the mod key in the +function:

      Module:config_change(Changed, New, Removed)
      • Module is the application callback module as defined by the mod key in the .app file.
      • Changed and New are lists of {Par,Val} for all changed and added configuration parameters, respectively.
      • Removed is a list of all parameters Par that have been removed.

      The function is optional and can be omitted when implementing an application callback module.

      diff --git a/prs/8803/doc/system/release_structure.html b/prs/8803/doc/system/release_structure.html index 6ec88785c05b2..2363384ec6b01 100644 --- a/prs/8803/doc/system/release_structure.html +++ b/prs/8803/doc/system/release_structure.html @@ -140,29 +140,29 @@

      To define a release, create a release resource file, or in short a .rel file. In the file, specify the name and version of the release, which ERTS -version it is based on, and which applications it consists of:

      {release, {Name,Vsn}, {erts, EVsn},
      - [{Application1, AppVsn1},
      +version it is based on, and which applications it consists of:

      {release, {Name,Vsn}, {erts, EVsn},
      + [{Application1, AppVsn1},
          ...
      -  {ApplicationN, AppVsnN}]}.

      Name, Vsn, EVsn, and AppVsn are strings.

      The file must be named Rel.rel, where Rel is a unique name.

      Each Application (atom) and AppVsn is the name and version of an application + {ApplicationN, AppVsnN}]}.

      Name, Vsn, EVsn, and AppVsn are strings.

      The file must be named Rel.rel, where Rel is a unique name.

      Each Application (atom) and AppVsn is the name and version of an application included in the release. The minimal release based on Erlang/OTP consists of the Kernel and STDLIB applications, so these applications must be included in the list.

      If the release is to be upgraded, it must also include the SASL application.

      Here is an example showing the .app file for a release of ch_app from -the Applications section:

      {application, ch_app,
      - [{description, "Channel allocator"},
      -  {vsn, "1"},
      -  {modules, [ch_app, ch_sup, ch3]},
      -  {registered, [ch3]},
      -  {applications, [kernel, stdlib, sasl]},
      -  {mod, {ch_app,[]}}
      - ]}.

      The .rel file must also contain kernel, stdlib, and sasl, as these -applications are required by ch_app. The file is called ch_rel-1.rel:

      {release,
      - {"ch_rel", "A"},
      - {erts, "14.2.5"},
      - [{kernel, "9.2.4"},
      -  {stdlib, "5.2.3"},
      -  {sasl, "4.2.1"},
      -  {ch_app, "1"}]
      -}.

      +the Applications section:

      {application, ch_app,
      + [{description, "Channel allocator"},
      +  {vsn, "1"},
      +  {modules, [ch_app, ch_sup, ch3]},
      +  {registered, [ch3]},
      +  {applications, [kernel, stdlib, sasl]},
      +  {mod, {ch_app,[]}}
      + ]}.

      The .rel file must also contain kernel, stdlib, and sasl, as these +applications are required by ch_app. The file is called ch_rel-1.rel:

      {release,
      + {"ch_rel", "A"},
      + {erts, "14.2.5"},
      + [{kernel, "9.2.4"},
      +  {stdlib, "5.2.3"},
      +  {sasl, "4.2.1"},
      +  {ch_app, "1"}]
      +}.

      @@ -194,9 +194,9 @@

      The systools:make_tar/1,2 function takes a .rel file as input and creates a zipped tar file with the code for -the specified applications, a release package:

      1> systools:make_script("ch_rel-1").
      +the specified applications, a release package:

      1> systools:make_script("ch_rel-1").
       ok
      -2> systools:make_tar("ch_rel-1").
      +2> systools:make_tar("ch_rel-1").
       ok

      The release package by default contains:

      • The .app files
      • The .rel file
      • The object code for all applications, structured according to the application directory structure
      • The binary boot script renamed to start.boot
      % tar tf ch_rel-1.tar
       lib/kernel-9.2.4/ebin/kernel.app
      diff --git a/prs/8803/doc/system/robustness.html b/prs/8803/doc/system/robustness.html
      index a1f0b564669ab..81b482de558cc 100644
      --- a/prs/8803/doc/system/robustness.html
      +++ b/prs/8803/doc/system/robustness.html
      @@ -132,36 +132,36 @@ 

      "pong" so that "pong" can also finish. Another way to let "pong" finish is to make "pong" exit if it does not receive a message from ping within a certain time. This can be done by adding a time-out to pong as shown in the -following example:

      -module(tut19).
      +following example:

      -module(tut19).
       
      --export([start_ping/1, start_pong/0,  ping/2, pong/0]).
      +-export([start_ping/1, start_pong/0,  ping/2, pong/0]).
       
      -ping(0, Pong_Node) ->
      -    io:format("ping finished~n", []);
      +ping(0, Pong_Node) ->
      +    io:format("ping finished~n", []);
       
      -ping(N, Pong_Node) ->
      -    {pong, Pong_Node} ! {ping, self()},
      +ping(N, Pong_Node) ->
      +    {pong, Pong_Node} ! {ping, self()},
           receive
               pong ->
      -            io:format("Ping received pong~n", [])
      +            io:format("Ping received pong~n", [])
           end,
      -    ping(N - 1, Pong_Node).
      +    ping(N - 1, Pong_Node).
       
      -pong() ->
      +pong() ->
           receive
      -        {ping, Ping_PID} ->
      -            io:format("Pong received ping~n", []),
      +        {ping, Ping_PID} ->
      +            io:format("Pong received ping~n", []),
                   Ping_PID ! pong,
      -            pong()
      +            pong()
           after 5000 ->
      -            io:format("Pong timed out~n", [])
      +            io:format("Pong timed out~n", [])
           end.
       
      -start_pong() ->
      -    register(pong, spawn(tut19, pong, [])).
      +start_pong() ->
      +    register(pong, spawn(tut19, pong, [])).
       
      -start_ping(Pong_Node) ->
      -    spawn(tut19, ping, [3, Pong_Node]).

      After this is compiled and the file tut19.beam is copied to the necessary +start_ping(Pong_Node) -> + spawn(tut19, ping, [3, Pong_Node]).

      After this is compiled and the file tut19.beam is copied to the necessary directories, the following is seen on (pong@kosken):

      (pong@kosken)1> tut19:start_pong().
       true
       Pong received ping
      @@ -172,20 +172,20 @@ 

      Ping received pong Ping received pong Ping received pong -ping finished

      The time-out is set in:

      pong() ->
      +ping finished

      The time-out is set in:

      pong() ->
           receive
      -        {ping, Ping_PID} ->
      -            io:format("Pong received ping~n", []),
      +        {ping, Ping_PID} ->
      +            io:format("Pong received ping~n", []),
                   Ping_PID ! pong,
      -            pong()
      +            pong()
           after 5000 ->
      -            io:format("Pong timed out~n", [])
      +            io:format("Pong timed out~n", [])
           end.

      The time-out (after 5000) is started when receive is entered. The time-out is canceled if {ping,Ping_PID} is received. If {ping,Ping_PID} is not received, the actions following the time-out are done after 5000 milliseconds. after must be last in the receive, that is, preceded by all other message reception specifications in the receive. It is also possible to call a -function that returned an integer for the time-out:

      after pong_timeout() ->

      In general, there are better ways than using time-outs to supervise parts of a +function that returned an integer for the time-out:

      after pong_timeout() ->

      In general, there are better ways than using time-outs to supervise parts of a distributed Erlang system. Time-outs are usually appropriate to supervise external events, for example, if you have expected a message from some external system within a specified time. For example, a time-out can be used to log a @@ -213,36 +213,36 @@

      If one of the processes exits abnormally, all the processes in the transaction are killed. As it is often wanted to create a process and link to it at the same time, there is a special BIF, spawn_link that does the -same as spawn, but also creates a link to the spawned process.

      Now an example of the ping pong example using links to terminate "pong":

      -module(tut20).
      +same as spawn, but also creates a link to the spawned process.

      Now an example of the ping pong example using links to terminate "pong":

      -module(tut20).
       
      --export([start/1,  ping/2, pong/0]).
      +-export([start/1,  ping/2, pong/0]).
       
      -ping(N, Pong_Pid) ->
      -    link(Pong_Pid),
      -    ping1(N, Pong_Pid).
      +ping(N, Pong_Pid) ->
      +    link(Pong_Pid),
      +    ping1(N, Pong_Pid).
       
      -ping1(0, _) ->
      -    exit(ping);
      +ping1(0, _) ->
      +    exit(ping);
       
      -ping1(N, Pong_Pid) ->
      -    Pong_Pid ! {ping, self()},
      +ping1(N, Pong_Pid) ->
      +    Pong_Pid ! {ping, self()},
           receive
               pong ->
      -            io:format("Ping received pong~n", [])
      +            io:format("Ping received pong~n", [])
           end,
      -    ping1(N - 1, Pong_Pid).
      +    ping1(N - 1, Pong_Pid).
       
      -pong() ->
      +pong() ->
           receive
      -        {ping, Ping_PID} ->
      -            io:format("Pong received ping~n", []),
      +        {ping, Ping_PID} ->
      +            io:format("Pong received ping~n", []),
                   Ping_PID ! pong,
      -            pong()
      +            pong()
           end.
       
      -start(Ping_Node) ->
      -    PongPID = spawn(tut20, pong, []),
      -    spawn(Ping_Node, tut20, ping, [3, PongPID]).
      (s1@bill)3> tut20:start(s2@kosken).
      +start(Ping_Node) ->
      +    PongPID = spawn(tut20, pong, []),
      +    spawn(Ping_Node, tut20, ping, [3, PongPID]).
      (s1@bill)3> tut20:start(s2@kosken).
       Pong received ping
       <3820.41.0>
       Ping received pong
      @@ -256,45 +256,45 @@ 

      sent to "pong", which also terminates.

      It is possible to modify the default behaviour of a process so that it does not get killed when it receives abnormal exit signals. Instead, all signals are turned into normal messages on the format {'EXIT',FromPID,Reason} and added to -the end of the receiving process' message queue. This behaviour is set by:

      process_flag(trap_exit, true)

      There are several other process flags, see erlang(3). +the end of the receiving process' message queue. This behaviour is set by:

      process_flag(trap_exit, true)

      There are several other process flags, see erlang(3). Changing the default behaviour of a process in this way is usually not done in standard user programs, but is left to the supervisory programs in OTP. However, -the ping pong program is modified to illustrate exit trapping.

      -module(tut21).
      +the ping pong program is modified to illustrate exit trapping.

      -module(tut21).
       
      --export([start/1,  ping/2, pong/0]).
      +-export([start/1,  ping/2, pong/0]).
       
      -ping(N, Pong_Pid) ->
      -    link(Pong_Pid),
      -    ping1(N, Pong_Pid).
      +ping(N, Pong_Pid) ->
      +    link(Pong_Pid),
      +    ping1(N, Pong_Pid).
       
      -ping1(0, _) ->
      -    exit(ping);
      +ping1(0, _) ->
      +    exit(ping);
       
      -ping1(N, Pong_Pid) ->
      -    Pong_Pid ! {ping, self()},
      +ping1(N, Pong_Pid) ->
      +    Pong_Pid ! {ping, self()},
           receive
               pong ->
      -            io:format("Ping received pong~n", [])
      +            io:format("Ping received pong~n", [])
           end,
      -    ping1(N - 1, Pong_Pid).
      +    ping1(N - 1, Pong_Pid).
       
      -pong() ->
      -    process_flag(trap_exit, true),
      -    pong1().
      +pong() ->
      +    process_flag(trap_exit, true),
      +    pong1().
       
      -pong1() ->
      +pong1() ->
           receive
      -        {ping, Ping_PID} ->
      -            io:format("Pong received ping~n", []),
      +        {ping, Ping_PID} ->
      +            io:format("Pong received ping~n", []),
                   Ping_PID ! pong,
      -            pong1();
      -        {'EXIT', From, Reason} ->
      -            io:format("pong exiting, got ~p~n", [{'EXIT', From, Reason}])
      +            pong1();
      +        {'EXIT', From, Reason} ->
      +            io:format("pong exiting, got ~p~n", [{'EXIT', From, Reason}])
           end.
       
      -start(Ping_Node) ->
      -    PongPID = spawn(tut21, pong, []),
      -    spawn(Ping_Node, tut21, ping, [3, PongPID]).
      (s1@bill)1> tut21:start(s2@gollum).
      +start(Ping_Node) ->
      +    PongPID = spawn(tut21, pong, []),
      +    spawn(Ping_Node, tut21, ping, [3, PongPID]).
      (s1@bill)1> tut21:start(s2@gollum).
       <3820.39.0>
       Pong received ping
       Ping received pong
      @@ -355,127 +355,127 @@ 

      %%% Configuration: change the server_node() function to return the %%% name of the node where the messenger server runs --module(messenger). --export([start_server/0, server/0, - logon/1, logoff/0, message/2, client/2]). +-module(messenger). +-export([start_server/0, server/0, + logon/1, logoff/0, message/2, client/2]). %%% Change the function below to return the name of the node where the %%% messenger server runs -server_node() -> +server_node() -> messenger@super. %%% This is the server process for the "messenger" %%% the user list has the format [{ClientPid1, Name1},{ClientPid22, Name2},...] -server() -> - process_flag(trap_exit, true), - server([]). +server() -> + process_flag(trap_exit, true), + server([]). -server(User_List) -> +server(User_List) -> receive - {From, logon, Name} -> - New_User_List = server_logon(From, Name, User_List), - server(New_User_List); - {'EXIT', From, _} -> - New_User_List = server_logoff(From, User_List), - server(New_User_List); - {From, message_to, To, Message} -> - server_transfer(From, To, Message, User_List), - io:format("list is now: ~p~n", [User_List]), - server(User_List) + {From, logon, Name} -> + New_User_List = server_logon(From, Name, User_List), + server(New_User_List); + {'EXIT', From, _} -> + New_User_List = server_logoff(From, User_List), + server(New_User_List); + {From, message_to, To, Message} -> + server_transfer(From, To, Message, User_List), + io:format("list is now: ~p~n", [User_List]), + server(User_List) end. %%% Start the server -start_server() -> - register(messenger, spawn(messenger, server, [])). +start_server() -> + register(messenger, spawn(messenger, server, [])). %%% Server adds a new user to the user list -server_logon(From, Name, User_List) -> +server_logon(From, Name, User_List) -> %% check if logged on anywhere else - case lists:keymember(Name, 2, User_List) of + case lists:keymember(Name, 2, User_List) of true -> - From ! {messenger, stop, user_exists_at_other_node}, %reject logon + From ! {messenger, stop, user_exists_at_other_node}, %reject logon User_List; false -> - From ! {messenger, logged_on}, - link(From), - [{From, Name} | User_List] %add user to the list + From ! {messenger, logged_on}, + link(From), + [{From, Name} | User_List] %add user to the list end. %%% Server deletes a user from the user list -server_logoff(From, User_List) -> - lists:keydelete(From, 1, User_List). +server_logoff(From, User_List) -> + lists:keydelete(From, 1, User_List). %%% Server transfers a message between user -server_transfer(From, To, Message, User_List) -> +server_transfer(From, To, Message, User_List) -> %% check that the user is logged on and who he is - case lists:keysearch(From, 1, User_List) of + case lists:keysearch(From, 1, User_List) of false -> - From ! {messenger, stop, you_are_not_logged_on}; - {value, {_, Name}} -> - server_transfer(From, Name, To, Message, User_List) + From ! {messenger, stop, you_are_not_logged_on}; + {value, {_, Name}} -> + server_transfer(From, Name, To, Message, User_List) end. %%% If the user exists, send the message -server_transfer(From, Name, To, Message, User_List) -> +server_transfer(From, Name, To, Message, User_List) -> %% Find the receiver and send the message - case lists:keysearch(To, 2, User_List) of + case lists:keysearch(To, 2, User_List) of false -> - From ! {messenger, receiver_not_found}; - {value, {ToPid, To}} -> - ToPid ! {message_from, Name, Message}, - From ! {messenger, sent} + From ! {messenger, receiver_not_found}; + {value, {ToPid, To}} -> + ToPid ! {message_from, Name, Message}, + From ! {messenger, sent} end. %%% User Commands -logon(Name) -> - case whereis(mess_client) of +logon(Name) -> + case whereis(mess_client) of undefined -> - register(mess_client, - spawn(messenger, client, [server_node(), Name])); + register(mess_client, + spawn(messenger, client, [server_node(), Name])); _ -> already_logged_on end. -logoff() -> +logoff() -> mess_client ! logoff. -message(ToName, Message) -> - case whereis(mess_client) of % Test if the client is running +message(ToName, Message) -> + case whereis(mess_client) of % Test if the client is running undefined -> not_logged_on; - _ -> mess_client ! {message_to, ToName, Message}, + _ -> mess_client ! {message_to, ToName, Message}, ok end. %%% The client process which runs on each user node -client(Server_Node, Name) -> - {messenger, Server_Node} ! {self(), logon, Name}, - await_result(), - client(Server_Node). +client(Server_Node, Name) -> + {messenger, Server_Node} ! {self(), logon, Name}, + await_result(), + client(Server_Node). -client(Server_Node) -> +client(Server_Node) -> receive logoff -> - exit(normal); - {message_to, ToName, Message} -> - {messenger, Server_Node} ! {self(), message_to, ToName, Message}, - await_result(); - {message_from, FromName, Message} -> - io:format("Message from ~p: ~p~n", [FromName, Message]) + exit(normal); + {message_to, ToName, Message} -> + {messenger, Server_Node} ! {self(), message_to, ToName, Message}, + await_result(); + {message_from, FromName, Message} -> + io:format("Message from ~p: ~p~n", [FromName, Message]) end, - client(Server_Node). + client(Server_Node). %%% wait for a response from the server -await_result() -> +await_result() -> receive - {messenger, stop, Why} -> % Stop the client - io:format("~p~n", [Why]), - exit(normal); - {messenger, What} -> % Normal response - io:format("~p~n", [What]) + {messenger, stop, Why} -> % Stop the client + io:format("~p~n", [Why]), + exit(normal); + {messenger, What} -> % Normal response + io:format("~p~n", [What]) after 5000 -> - io:format("No response from server~n", []), - exit(timeout) + io:format("No response from server~n", []), + exit(timeout) end.

      The following changes are added:

      The messenger server traps exits. If it receives an exit signal, {'EXIT',From,Reason}, this means that a client process has terminated or is unreachable for one of the following reasons:

      • The user has logged off (the "logoff" message is removed).
      • The network connection to the client is broken.
      • The node on which the client process resides has gone down.
      • The client processes has done some illegal operation.

      If an exit signal is received as above, the tuple {From,Name} is deleted from diff --git a/prs/8803/doc/system/search.html b/prs/8803/doc/system/search.html index b28cfa319469e..c08442d0c429e 100644 --- a/prs/8803/doc/system/search.html +++ b/prs/8803/doc/system/search.html @@ -112,7 +112,7 @@

    - +
    diff --git a/prs/8803/doc/system/statem.html b/prs/8803/doc/system/statem.html index 032aa731d1a23..cdca1b9ede95b 100644 --- a/prs/8803/doc/system/statem.html +++ b/prs/8803/doc/system/statem.html @@ -128,7 +128,7 @@

    a state transition and the output is actions executed during the state transition. Analogously to the mathematical model of a Finite State Machine, it can be described as a set of relations -of the following form:

    State(S) x Event(E) -> Actions(A), State(S')

    These relations are interpreted as follows: if we are in state S, +of the following form:

    State(S) x Event(E) -> Actions(A), State(S')

    These relations are interpreted as follows: if we are in state S, and event E occurs, we are to perform actions A, and make a transition to state S'. Notice that S' can be equal to S, and that A can be empty.

    In gen_statem we define a state change as a state transition in which the @@ -409,12 +409,12 @@

    mode, automatically call the state callback with special arguments whenever the state changes, so you can write state enter actions near the rest of the state transition rules. -It typically looks like this:

    StateName(enter, OldState, Data) ->
    +It typically looks like this:

    StateName(enter, OldState, Data) ->
         ... code for state enter actions here ...
    -    {keep_state, NewData};
    -StateName(EventType, EventContent, Data) ->
    +    {keep_state, NewData};
    +StateName(EventType, EventContent, Data) ->
         ... code for actions here ...
    -    {next_state, NewStateName, NewData}.

    Since the state enter call is not an event there are restrictions on the + {next_state, NewStateName, NewData}.

    Since the state enter call is not an event there are restrictions on the allowed return value and state transition actions. You must not change the state, postpone this non-event, insert any events, or change the @@ -503,55 +503,55 @@

    open --> open : {button, Digit} open --> locked : state_timeout\n* do_lock()

    This code lock state machine can be implemented using gen_statem with -the following callback module:

    -module(code_lock).
    --behaviour(gen_statem).
    --define(NAME, code_lock).
    +the following callback module:

    -module(code_lock).
    +-behaviour(gen_statem).
    +-define(NAME, code_lock).
     
    --export([start_link/1]).
    --export([button/1]).
    --export([init/1,callback_mode/0,terminate/3]).
    --export([locked/3,open/3]).
    -
    -start_link(Code) ->
    -    gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).
    -
    -button(Button) ->
    -    gen_statem:cast(?NAME, {button,Button}).
    -
    -init(Code) ->
    -    do_lock(),
    -    Data = #{code => Code, length => length(Code), buttons => []},
    -    {ok, locked, Data}.
    -
    -callback_mode() ->
    -    state_functions.
    locked(
    -  cast, {button,Button},
    -  #{code := Code, length := Length, buttons := Buttons} = Data) ->
    +-export([start_link/1]).
    +-export([button/1]).
    +-export([init/1,callback_mode/0,terminate/3]).
    +-export([locked/3,open/3]).
    +
    +start_link(Code) ->
    +    gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).
    +
    +button(Button) ->
    +    gen_statem:cast(?NAME, {button,Button}).
    +
    +init(Code) ->
    +    do_lock(),
    +    Data = #{code => Code, length => length(Code), buttons => []},
    +    {ok, locked, Data}.
    +
    +callback_mode() ->
    +    state_functions.
    locked(
    +  cast, {button,Button},
    +  #{code := Code, length := Length, buttons := Buttons} = Data) ->
         NewButtons =
             if
    -            length(Buttons) < Length ->
    +            length(Buttons) < Length ->
                     Buttons;
                 true ->
    -                tl(Buttons)
    -        end ++ [Button],
    +                tl(Buttons)
    +        end ++ [Button],
         if
             NewButtons =:= Code -> % Correct
    -	    do_unlock(),
    -            {next_state, open, Data#{buttons := []},
    -             [{state_timeout,10_000,lock}]}; % Time in milliseconds
    +	    do_unlock(),
    +            {next_state, open, Data#{buttons := []},
    +             [{state_timeout,10_000,lock}]}; % Time in milliseconds
     	true -> % Incomplete | Incorrect
    -            {next_state, locked, Data#{buttons := NewButtons}}
    -    end.
    open(state_timeout, lock,  Data) ->
    -    do_lock(),
    -    {next_state, locked, Data};
    -open(cast, {button,_}, Data) ->
    -    {next_state, open, Data}.
    do_lock() ->
    -    io:format("Lock~n", []).
    -do_unlock() ->
    -    io:format("Unlock~n", []).
    -
    -terminate(_Reason, State, _Data) ->
    -    State =/= locked andalso do_lock(),
    +            {next_state, locked, Data#{buttons := NewButtons}}
    +    end.
    open(state_timeout, lock,  Data) ->
    +    do_lock(),
    +    {next_state, locked, Data};
    +open(cast, {button,_}, Data) ->
    +    {next_state, open, Data}.
    do_lock() ->
    +    io:format("Lock~n", []).
    +do_unlock() ->
    +    io:format("Unlock~n", []).
    +
    +terminate(_Reason, State, _Data) ->
    +    State =/= locked andalso do_lock(),
         ok.

    The code is explained in the next sections.

    @@ -559,8 +559,8 @@

    Starting gen_statem

    In the example in the previous section, gen_statem is started by calling -code_lock:start_link(Code):

    start_link(Code) ->
    -    gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).

    start_link/1 calls function gen_statem:start_link/4, +code_lock:start_link(Code):

    start_link(Code) ->
    +    gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).

    start_link/1 calls function gen_statem:start_link/4, which spawns and links to a new process, a gen_statem.

    diff --git a/prs/8803/doc/system/typespec.html b/prs/8803/doc/system/typespec.html index e05a37645d267..97165d930bf5f 100644 --- a/prs/8803/doc/system/typespec.html +++ b/prs/8803/doc/system/typespec.html @@ -241,11 +241,11 @@

    predefined aliases for the type unions also shown in the table.

    Built-in typeDefined as
    term/0any/0
    binary/0<<_:_*8>>
    nonempty_binary/0<<_:8, _:_*8>>
    bitstring/0<<_:_*1>>
    nonempty_bitstring/0<<_:1, _:_*1>>
    boolean/0'false' | 'true'
    byte/00..255
    char/00..16#10ffff
    nil/0[]
    number/0integer/0 | float/0
    list/0[any()]
    maybe_improper_list/0maybe_improper_list(any(), any())
    nonempty_list/0nonempty_list(any())
    string/0[char()]
    nonempty_string/0[char(),...]
    iodata/0iolist() | binary()
    iolist/0maybe_improper_list(byte() | binary() | iolist(), binary() | [])
    map/0#{any() => any()}
    function/0fun()
    module/0atom/0
    mfa/0{module(),atom(),arity()}
    arity/00..255
    identifier/0pid() | port() | reference()
    node/0atom/0
    timeout/0'infinity' | non_neg_integer()
    no_return/0none/0

    Table: Built-in types, predefined aliases

    In addition, the following three built-in types exist and can be thought as defined below, though strictly their "type definition" is not valid syntax according to the type language defined above.

    Built-in typeCan be thought defined by the syntax
    non_neg_integer/00..
    pos_integer/01..
    neg_integer/0..-1

    Table: Additional built-in types

    Note

    The following built-in list types also exist, but they are expected to be -rarely used. Hence, they have long names:

    nonempty_maybe_improper_list() :: nonempty_maybe_improper_list(any(), any())
    -nonempty_improper_list(Type1, Type2)
    -nonempty_maybe_improper_list(Type1, Type2)

    where the last two types define the set of Erlang terms one would expect.

    Also for convenience, record notation is allowed to be used. Records are -shorthands for the corresponding tuples:

    Record :: #Erlang_Atom{}
    -        | #Erlang_Atom{Fields}

    Records are extended to possibly contain type information. This is described in +rarely used. Hence, they have long names:

    nonempty_maybe_improper_list() :: nonempty_maybe_improper_list(any(), any())
    +nonempty_improper_list(Type1, Type2)
    +nonempty_maybe_improper_list(Type1, Type2)

    where the last two types define the set of Erlang terms one would expect.

    Also for convenience, record notation is allowed to be used. Records are +shorthands for the corresponding tuples:

    Record :: #Erlang_Atom{}
    +        | #Erlang_Atom{Fields}

    Records are extended to possibly contain type information. This is described in Type Information in Record Declarations.

    @@ -256,8 +256,8 @@

    name as a built-in type.

    It is recommended to avoid deliberately reusing built-in names because it can be confusing. However, when an Erlang/OTP release introduces a new type, code that happened to define its own type having the same name will continue to work.

    As an example, imagine that the Erlang/OTP 42 release introduces a new type -gadget() defined like this:

    -type gadget() :: {'gadget', reference()}.

    Further imagine that some code has its own (different) definition of gadget(), -for example:

    -type gadget() :: #{}.

    Since redefinitions are allowed, the code will still compile (but with a +gadget() defined like this:

    -type gadget() :: {'gadget', reference()}.

    Further imagine that some code has its own (different) definition of gadget(), +for example:

    -type gadget() :: #{}.

    Since redefinitions are allowed, the code will still compile (but with a warning), and Dialyzer will not emit any additional warnings.

    @@ -266,8 +266,8 @@

    As seen, the basic syntax of a type is an atom followed by closed parentheses. New types are declared using -type and -opaque attributes as in the -following:

    -type my_struct_type() :: Type.
    --opaque my_opaq_type() :: Type.

    The type name is the atom my_struct_type, followed by parentheses. Type is a +following:

    -type my_struct_type() :: Type.
    +-opaque my_opaq_type() :: Type.

    The type name is the atom my_struct_type, followed by parentheses. Type is a type as defined in the previous section. A current restriction is that Type can contain only predefined types, or user-defined types which are either of the following:

    diff --git a/prs/8803/doc/upcoming_incompatibilities.html b/prs/8803/doc/upcoming_incompatibilities.html index bac06e39fb14c..9536d8843d8fc 100644 --- a/prs/8803/doc/upcoming_incompatibilities.html +++ b/prs/8803/doc/upcoming_incompatibilities.html @@ -170,10 +170,10 @@

    Singleton type variables will become a compile-time error

    -

    Before Erlang/OTP 26, the compiler would silenty accept the following spec:

    -spec f(Opts) -> term() when
    -    Opts :: {ok, Unknown} | {error, Unknown}.
    -f(_) -> error.

    In OTP 26, the compiler emits a warning pointing out that the type variable -Unknown is unbound:

    t.erl:6:18: Warning: type variable 'Unknown' is only used once (is unbound)
    +

    Before Erlang/OTP 26, the compiler would silenty accept the following spec:

    -spec f(Opts) -> term() when
    +    Opts :: {ok, Unknown} | {error, Unknown}.
    +f(_) -> error.

    In OTP 26, the compiler emits a warning pointing out that the type variable +Unknown is unbound:

    t.erl:6:18: Warning: type variable 'Unknown' is only used once (is unbound)
     %    6|     Opts :: {ok, Unknown} | {error, Unknown}.
     %     |                  ^

    In OTP 27, that warning will become an error.

    @@ -183,7 +183,7 @@

    compiler application must be available.

    The old behavior of interpreting escripts can be restored by adding the -following line to the script file:

    -mode(interpret).

    In OTP 28, support for interpreting an escript will be removed.

    +following line to the script file:

    -mode(interpret).

    In OTP 28, support for interpreting an escript will be removed.

    @@ -235,10 +235,10 @@

    """" -++ foo() ++ +++ foo() ++ """" %% Became -"" ++ foo() ++ "" +"" ++ foo() ++ "" %% %% In OTP 27 it is instead interpreted as a %% Triple-Quoted String (triple-or-more) equivalent to diff --git a/prs/8803/erts-15.0.1/doc/html/alt_dist.html b/prs/8803/erts-15.0.1/doc/html/alt_dist.html index 6ea300addeafd..abbfbc8e09c60 100644 --- a/prs/8803/erts-15.0.1/doc/html/alt_dist.html +++ b/prs/8803/erts-15.0.1/doc/html/alt_dist.html @@ -241,10 +241,10 @@

    Exported Callback Functions

    -

    The following functions are mandatory:

    • listen(Name) ->
      -  {ok, {Listen, Address, Creation}} | {error, Error}
      -listen(Name,Host) ->
      -  {ok, {Listen, Address, Creation}} | {error, Error}

      listen/2 is called once in order to listen for incoming connection requests. +

      The following functions are mandatory:

      • listen(Name) ->
        +  {ok, {Listen, Address, Creation}} | {error, Error}
        +listen(Name,Host) ->
        +  {ok, {Listen, Address, Creation}} | {error, Error}

        listen/2 is called once in order to listen for incoming connection requests. The call is made when the distribution is brought up. The argument Name is the part of the node name before the @ sign in the full node name. It can be either an atom or a string. The argument Host is the part of the node name @@ -254,12 +254,12 @@

        #net_address{} record is defined in kernel/include/net_address.hrl), and Creation which (currently) is an integer 1, 2, or 3.

        If epmd is to be used for node discovery, you typically want to use the erl_epmd module (part of the kernel application) in order to -register the listen port with epmd and retrieve Creation to use.

      • address() ->
        +register the listen port with epmd and retrieve Creation to use.

      • address() ->
           Address

        address/0 is called in order to get the Address part of the listen/2 function without creating a listen socket. -All fields except address have to be set in the returned record

        Example:

        address() ->
        -    {ok, Host} = inet:gethostname(),
        -    #net_address{ host = Host, protocol = tcp, family = inet6 }.
      • accept(Listen) ->
        +All fields except address have to be set in the returned record

        Example:

        address() ->
        +    {ok, Host} = inet:gethostname(),
        +    #net_address{ host = Host, protocol = tcp, family = inet6 }.
      • accept(Listen) ->
           AcceptorPid

        accept/1 should spawn a process that accepts connections. This process should preferably execute on max priority. The process identifier of this process should be returned.

        The Listen argument will be the same as the Listen handle part of the @@ -268,7 +268,7 @@

        may not be the process registered as net_kernel) and is in this document identified as Kernel. When a connection has been accepted by the acceptor process, it needs to inform Kernel about the accepted connection. This is -done by passing a message on the form:

        Kernel ! {accept, AcceptorPid, DistController, Family, Proto}

        DistController is either the process or port identifier of the distribution +done by passing a message on the form:

        Kernel ! {accept, AcceptorPid, DistController, Family, Proto}

        DistController is either the process or port identifier of the distribution controller for the connection. The distribution controller should be created by the acceptor processes when a new connection is accepted. Its job is to dispatch traffic on the connection.

        Kernel responds with one of the following messages:

        • {Kernel, controller, SupervisorPid} - The request was accepted and @@ -276,7 +276,7 @@

          process (which is created in the accept_connection/5 callback).

        • {Kernel, unsupported_protocol} - The request was rejected. This is a fatal error. The acceptor process should terminate.

        When an accept sequence has been completed the acceptor process is expected to -continue accepting further requests.

      • accept_connection(AcceptorPid, DistCtrl, MyNode, Allowed, SetupTime) ->
        +continue accepting further requests.

      • accept_connection(AcceptorPid, DistCtrl, MyNode, Allowed, SetupTime) ->
           ConnectionSupervisorPid

        accept_connection/5 should spawn a process that will perform the Erlang distribution handshake for the connection. If the handshake successfully completes it should continue to function as a connection supervisor. This @@ -298,7 +298,7 @@

        the handshake in a #hs_data{} record and call dist_util:handshake_other_started(HsData) with this record.

        dist_util:handshake_other_started(HsData) will perform the handshake and if the handshake successfully completes this process will then continue in a -connection supervisor loop as long as the connection is up.

      • setup(Node, Type, MyNode, LongOrShortNames, SetupTime) ->
        +connection supervisor loop as long as the connection is up.

      • setup(Node, Type, MyNode, LongOrShortNames, SetupTime) ->
           ConnectionSupervisorPid

        setup/5 should spawn a process that connects to Node. When connection has been established it should perform the Erlang distribution handshake for the connection. If the handshake successfully completes it should continue to @@ -324,15 +324,15 @@

        the handshake in a #hs_data{} record and call dist_util:handshake_we_started(HsData) with this record.

        dist_util:handshake_we_started(HsData) will perform the handshake and the handshake successfully completes this process will then continue in a -connection supervisor loop as long as the connection is up.

      • close(Listen) ->
        -  void()

        Called in order to close the Listen handle that originally was passed from -the listen/1 callback.

      • select(NodeName) ->
        -  boolean()

        Return true if the host name part of the NodeName is valid for use with -this protocol; otherwise, false.

      There are also two optional functions that may be exported:

      • setopts(Listen, Opts) ->
        -  ok | {error, Error}

        The argument Listen is the handle originally passed from the +connection supervisor loop as long as the connection is up.

      • close(Listen) ->
        +  void()

        Called in order to close the Listen handle that originally was passed from +the listen/1 callback.

      • select(NodeName) ->
        +  boolean()

        Return true if the host name part of the NodeName is valid for use with +this protocol; otherwise, false.

      There are also two optional functions that may be exported:

      • setopts(Listen, Opts) ->
        +  ok | {error, Error}

        The argument Listen is the handle originally passed from the listen/1 callback. The argument Opts is a list of -options to set on future connections.

      • getopts(Listen, Opts) ->
        -  {ok, OptionValues} | {error, Error}

        The argument Listen is the handle originally passed from the +options to set on future connections.

      • getopts(Listen, Opts) ->
        +  {ok, OptionValues} | {error, Error}

        The argument Listen is the handle originally passed from the listen/1 callback. The argument Opts is a list of options to read for future connections.

      @@ -354,36 +354,36 @@

      dist_util:start_timer/1.

    • allowed - Information passed as Allowed to accept_connection/5. This field is only mandatory when the remote node initiated the connection. That is, when the connection is set up via -accept_connection/5.

    • f_send - A fun with the following signature:

      fun (DistCtrlr, Data) -> ok | {error, Error}

      where DistCtrlr is the identifier of the distribution controller and Data -is io data to pass to the other side.

      Only used during handshake phase.

    • f_recv - A fun with the following signature:

      fun (DistCtrlr, Length) -> {ok, Packet} | {error, Reason}

      where DistCtrlr is the identifier of the distribution controller. If +accept_connection/5.

    • f_send - A fun with the following signature:

      fun (DistCtrlr, Data) -> ok | {error, Error}

      where DistCtrlr is the identifier of the distribution controller and Data +is io data to pass to the other side.

      Only used during handshake phase.

    • f_recv - A fun with the following signature:

      fun (DistCtrlr, Length) -> {ok, Packet} | {error, Reason}

      where DistCtrlr is the identifier of the distribution controller. If Length is 0, all available bytes should be returned. If Length > 0, exactly Length bytes should be returned, or an error; possibly discarding less than Length bytes of data when the connection is closed from the other side. It is used for passive receive of data from the other end.

      Only used during handshake phase.

    • f_setopts_pre_nodeup - A fun with the -following signature:

      fun (DistCtrlr) -> ok | {error, Error}

      where DistCtrlr is the identifier of the distribution controller. Called +following signature:

      fun (DistCtrlr) -> ok | {error, Error}

      where DistCtrlr is the identifier of the distribution controller. Called just before the distribution channel is taken up for normal traffic.

      Only used during handshake phase.

    • f_setopts_post_nodeup - A fun with -the following signature:

      fun (DistCtrlr) -> ok | {error, Error}

      where DistCtrlr is the identifier of the distribution controller. Called -just after distribution channel has been taken up for normal traffic.

      Only used during handshake phase.

    • f_getll - A fun with the following signature:

      fun (DistCtrlr) -> ID

      where DistCtrlr is the identifier of the distribution controller and ID is +the following signature:

      fun (DistCtrlr) -> ok | {error, Error}

      where DistCtrlr is the identifier of the distribution controller. Called +just after distribution channel has been taken up for normal traffic.

      Only used during handshake phase.

    • f_getll - A fun with the following signature:

      fun (DistCtrlr) -> ID

      where DistCtrlr is the identifier of the distribution controller and ID is the identifier of the low level entity that handles the connection (often -DistCtrlr itself).

      Only used during handshake phase.

    • f_address - A fun with the following signature:

      fun (DistCtrlr, Node) -> NetAddress

      where DistCtrlr is the identifier of the distribution controller, Node is +DistCtrlr itself).

      Only used during handshake phase.

    • f_address - A fun with the following signature:

      fun (DistCtrlr, Node) -> NetAddress

      where DistCtrlr is the identifier of the distribution controller, Node is the node name of the node on the other end, and NetAddress is a #net_address{} record with information about the address for the Node on the other end of the connection. The #net_address{} record is defined in -kernel/include/net_address.hrl.

      Only used during handshake phase.

    • mf_tick - A fun with the following signature:

      fun (DistCtrlr) -> void()

      where DistCtrlr is the identifier of the distribution controller. This +kernel/include/net_address.hrl.

      Only used during handshake phase.

    • mf_tick - A fun with the following signature:

      fun (DistCtrlr) -> void()

      where DistCtrlr is the identifier of the distribution controller. This function should send information over the connection that is not interpreted by the other end while increasing the statistics of received packets on the other end. This is usually implemented by sending an empty packet.

      Note

      It is of vital importance that this operation does not block the caller for -a long time. This since it is called from the connection supervisor.

      Used when connection is up.

    • mf_getstat - A fun with the following signature:

      fun (DistCtrlr) -> {ok, Received, Sent, PendSend}

      where DistCtrlr is the identifier of the distribution controller, Received +a long time. This since it is called from the connection supervisor.

      Used when connection is up.

    • mf_getstat - A fun with the following signature:

      fun (DistCtrlr) -> {ok, Received, Sent, PendSend}

      where DistCtrlr is the identifier of the distribution controller, Received is received packets, Sent is sent packets, and PendSend is amount of data in queue to be sent (typically in bytes, but dist_util only checks whether the value is non-zero to know there is data in queue) or a boolean/0 indicating whether there are packets in queue to be sent.

      Note

      It is of vital importance that this operation does not block the caller for a long time. This since it is called from the connection supervisor.

      Used when connection is up.

    • request_type - The request Type as passed to setup/5. This is only mandatory when the connection has -been initiated by this node. That is, the connection is set up via setup/5.

    • mf_setopts - A fun with the following signature:

      fun (DistCtrl, Opts) -> ok | {error, Error}

      where DistCtrlr is the identifier of the distribution controller and Opts -is a list of options to set on the connection.

      This function is optional. Used when connection is up.

    • mf_getopts - A fun with the following signature:

      fun (DistCtrl, Opts) -> {ok, OptionValues} | {error, Error}

      where DistCtrlr is the identifier of the distribution controller and Opts +been initiated by this node. That is, the connection is set up via setup/5.

    • mf_setopts - A fun with the following signature:

      fun (DistCtrl, Opts) -> ok | {error, Error}

      where DistCtrlr is the identifier of the distribution controller and Opts +is a list of options to set on the connection.

      This function is optional. Used when connection is up.

    • mf_getopts - A fun with the following signature:

      fun (DistCtrl, Opts) -> {ok, OptionValues} | {error, Error}

      where DistCtrlr is the identifier of the distribution controller and Opts is a list of options to read for the connection.

      This function is optional. Used when connection is up.

    • f_handshake_complete - A fun with the -following signature:

      fun (DistCtrlr, Node, DHandle) -> void()

      where DistCtrlr is the identifier of the distribution controller, Node is +following signature:

      fun (DistCtrlr, Node, DHandle) -> void()

      where DistCtrlr is the identifier of the distribution controller, Node is the node name of the node connected at the other end, and DHandle is a distribution handle needed by a distribution controller process when calling the following BIFs:

      This function is called when the handshake has completed and the distribution @@ -519,62 +519,62 @@

      because in most situation you need to do it. Unix domain sockets are reliable and order maintaining, so we do not need to implement resends and such in the driver.

      We start writing the example Unix domain sockets driver by declaring prototypes -and filling in a static ErlDrvEntry structure:

      ( 1) #include <stdio.h>
      -( 2) #include <stdlib.h>
      -( 3) #include <string.h>
      -( 4) #include <unistd.h>
      -( 5) #include <errno.h>
      -( 6) #include <sys/types.h>
      -( 7) #include <sys/stat.h>
      -( 8) #include <sys/socket.h>
      -( 9) #include <sys/un.h>
      -(10) #include <fcntl.h>
      +and filling in a static ErlDrvEntry structure:

      ( 1) #include <stdio.h>
      +( 2) #include <stdlib.h>
      +( 3) #include <string.h>
      +( 4) #include <unistd.h>
      +( 5) #include <errno.h>
      +( 6) #include <sys/types.h>
      +( 7) #include <sys/stat.h>
      +( 8) #include <sys/socket.h>
      +( 9) #include <sys/un.h>
      +(10) #include <fcntl.h>
       
      -(11) #define HAVE_UIO_H
      -(12) #include "erl_driver.h"
      +(11) #define HAVE_UIO_H
      +(12) #include "erl_driver.h"
       
      -(13) /*
      +(13) /*
       (14) ** Interface routines
       (15) */
      -(16) static ErlDrvData uds_start(ErlDrvPort port, char *buff);
      -(17) static void uds_stop(ErlDrvData handle);
      -(18) static void uds_command(ErlDrvData handle, char *buff, int bufflen);
      -(19) static void uds_input(ErlDrvData handle, ErlDrvEvent event);
      -(20) static void uds_output(ErlDrvData handle, ErlDrvEvent event);
      -(21) static void uds_finish(void);
      -(22) static int uds_control(ErlDrvData handle, unsigned int command,
      -(23)                        char* buf, int count, char** res, int res_size);
      +(16) static ErlDrvData uds_start(ErlDrvPort port, char *buff);
      +(17) static void uds_stop(ErlDrvData handle);
      +(18) static void uds_command(ErlDrvData handle, char *buff, int bufflen);
      +(19) static void uds_input(ErlDrvData handle, ErlDrvEvent event);
      +(20) static void uds_output(ErlDrvData handle, ErlDrvEvent event);
      +(21) static void uds_finish(void);
      +(22) static int uds_control(ErlDrvData handle, unsigned int command,
      +(23)                        char* buf, int count, char** res, int res_size);
       
      -(24) /* The driver entry */
      -(25) static ErlDrvEntry uds_driver_entry = {
      -(26)     NULL,                            /* init, N/A */
      -(27)     uds_start,                       /* start, called when port is opened */
      -(28)     uds_stop,                        /* stop, called when port is closed */
      -(29)     uds_command,                     /* output, called when erlang has sent */
      -(30)     uds_input,                       /* ready_input, called when input
      +(24) /* The driver entry */
      +(25) static ErlDrvEntry uds_driver_entry = {
      +(26)     NULL,                            /* init, N/A */
      +(27)     uds_start,                       /* start, called when port is opened */
      +(28)     uds_stop,                        /* stop, called when port is closed */
      +(29)     uds_command,                     /* output, called when erlang has sent */
      +(30)     uds_input,                       /* ready_input, called when input
       (31)                                         descriptor ready */
      -(32)     uds_output,                      /* ready_output, called when output
      +(32)     uds_output,                      /* ready_output, called when output
       (33)                                         descriptor ready */
      -(34)     "uds_drv",                       /* char *driver_name, the argument
      +(34)     "uds_drv",                       /* char *driver_name, the argument
       (35)                                         to open_port */
      -(36)     uds_finish,                      /* finish, called when unloaded */
      -(37)     NULL,                            /* void * that is not used (BC) */
      -(38)     uds_control,                     /* control, port_control callback */
      -(39)     NULL,                            /* timeout, called on timeouts */
      -(40)     NULL,                            /* outputv, vector output interface */
      -(41)     NULL,                            /* ready_async callback */
      -(42)     NULL,                            /* flush callback */
      -(43)     NULL,                            /* call callback */
      -(44)     NULL,                            /* event callback */
      -(45)     ERL_DRV_EXTENDED_MARKER,         /* Extended driver interface marker */
      -(46)     ERL_DRV_EXTENDED_MAJOR_VERSION,  /* Major version number */
      -(47)     ERL_DRV_EXTENDED_MINOR_VERSION,  /* Minor version number */
      -(48)     ERL_DRV_FLAG_SOFT_BUSY,          /* Driver flags. Soft busy flag is
      +(36)     uds_finish,                      /* finish, called when unloaded */
      +(37)     NULL,                            /* void * that is not used (BC) */
      +(38)     uds_control,                     /* control, port_control callback */
      +(39)     NULL,                            /* timeout, called on timeouts */
      +(40)     NULL,                            /* outputv, vector output interface */
      +(41)     NULL,                            /* ready_async callback */
      +(42)     NULL,                            /* flush callback */
      +(43)     NULL,                            /* call callback */
      +(44)     NULL,                            /* event callback */
      +(45)     ERL_DRV_EXTENDED_MARKER,         /* Extended driver interface marker */
      +(46)     ERL_DRV_EXTENDED_MAJOR_VERSION,  /* Major version number */
      +(47)     ERL_DRV_EXTENDED_MINOR_VERSION,  /* Minor version number */
      +(48)     ERL_DRV_FLAG_SOFT_BUSY,          /* Driver flags. Soft busy flag is
       (49)                                         required for distribution drivers */
      -(50)     NULL,                            /* Reserved for internal use */
      -(51)     NULL,                            /* process_exit callback */
      -(52)     NULL                             /* stop_select callback */
      -(53) };

      On line 1-10 the OS headers needed for the driver are included. As this driver +(50) NULL, /* Reserved for internal use */ +(51) NULL, /* process_exit callback */ +(52) NULL /* stop_select callback */ +(53) };

      On line 1-10 the OS headers needed for the driver are included. As this driver is written for Solaris, we know that the header uio.h exists. So the preprocessor variable HAVE_UIO_H can be defined before erl_driver.h is included on line 12. The definition of HAVE_UIO_H will make the I/O vectors @@ -625,17 +625,17 @@

      up, the port is to accept data to send. However, the port should not receive any data, to avoid that data arrives from another node before every kernel subsystem is prepared to handle it. A third mode, named intermediate, is used for this -intermediate stage.

      An enum is defined for the different types of ports:

      ( 1) typedef enum {
      -( 2)     portTypeUnknown,      /* An uninitialized port */
      -( 3)     portTypeListener,     /* A listening port/socket */
      -( 4)     portTypeAcceptor,     /* An intermediate stage when accepting
      +intermediate stage.

      An enum is defined for the different types of ports:

      ( 1) typedef enum {
      +( 2)     portTypeUnknown,      /* An uninitialized port */
      +( 3)     portTypeListener,     /* A listening port/socket */
      +( 4)     portTypeAcceptor,     /* An intermediate stage when accepting
       ( 5)                              on a listen port */
      -( 6)     portTypeConnector,    /* An intermediate stage when connecting */
      -( 7)     portTypeCommand,      /* A connected open port in command mode */
      -( 8)     portTypeIntermediate, /* A connected open port in special
      +( 6)     portTypeConnector,    /* An intermediate stage when connecting */
      +( 7)     portTypeCommand,      /* A connected open port in command mode */
      +( 8)     portTypeIntermediate, /* A connected open port in special
       ( 9)                              half active mode */
      -(10)     portTypeData          /* A connected open port in data mode */
      -(11) } PortType;

      The different types are as follows:

      • portTypeUnknown - The type a port has when it is opened, but not bound +(10) portTypeData /* A connected open port in data mode */ +(11) } PortType;

      The different types are as follows:

      • portTypeUnknown - The type a port has when it is opened, but not bound to any file descriptor.

      • portTypeListener - A port that is connected to a listen socket. This port does not do much, no data pumping is done on this socket, but read data is available when one is trying to do an accept on the port.

      • portTypeAcceptor - This port is to represent the result of an accept @@ -651,29 +651,29 @@

        the socket, much like in the active mode of a gen_tcp socket.

      We study the state that is needed for the ports. Notice that not all fields are used for all types of ports. Some space could be saved by using unions, but that would clutter the code with multiple indirections, so here is used one struct -for all types of ports, for readability:

      ( 1) typedef unsigned char Byte;
      -( 2) typedef unsigned int Word;
      +for all types of ports, for readability:

      ( 1) typedef unsigned char Byte;
      +( 2) typedef unsigned int Word;
       
      -( 3) typedef struct uds_data {
      -( 4)     int fd;                   /* File descriptor */
      -( 5)     ErlDrvPort port;          /* The port identifier */
      -( 6)     int lockfd;               /* The file descriptor for a lock file in
      +( 3) typedef struct uds_data {
      +( 4)     int fd;                   /* File descriptor */
      +( 5)     ErlDrvPort port;          /* The port identifier */
      +( 6)     int lockfd;               /* The file descriptor for a lock file in
       ( 7)                                  case of listen sockets */
      -( 8)     Byte creation;            /* The creation serial derived from the
      +( 8)     Byte creation;            /* The creation serial derived from the
       ( 9)                                  lock file */
      -(10)     PortType type;            /* Type of port */
      -(11)     char *name;               /* Short name of socket for unlink */
      -(12)     Word sent;                /* Bytes sent */
      -(13)     Word received;            /* Bytes received */
      -(14)     struct uds_data *partner; /* The partner in an accept/listen pair */
      -(15)     struct uds_data *next;    /* Next structure in list */
      -(16)     /* The input buffer and its data */
      -(17)     int buffer_size;          /* The allocated size of the input buffer */
      -(18)     int buffer_pos;           /* Current position in input buffer */
      -(19)     int header_pos;           /* Where the current header is in the
      +(10)     PortType type;            /* Type of port */
      +(11)     char *name;               /* Short name of socket for unlink */
      +(12)     Word sent;                /* Bytes sent */
      +(13)     Word received;            /* Bytes received */
      +(14)     struct uds_data *partner; /* The partner in an accept/listen pair */
      +(15)     struct uds_data *next;    /* Next structure in list */
      +(16)     /* The input buffer and its data */
      +(17)     int buffer_size;          /* The allocated size of the input buffer */
      +(18)     int buffer_pos;           /* Current position in input buffer */
      +(19)     int header_pos;           /* Where the current header is in the
       (20)                                  input buffer */
      -(21)     Byte *buffer;             /* The actual input buffer */
      -(22) } UdsData;

      This structure is used for all types of ports although some fields are useless +(21) Byte *buffer; /* The actual input buffer */ +(22) } UdsData;

      This structure is used for all types of ports although some fields are useless for some types. The least memory consuming solution would be to arrange this structure as a union of structures. However, the multiple indirections in the code to access a field in such a structure would clutter the code too much for @@ -722,97 +722,97 @@

      driver easier to port between different operating systems (and flavors of systems). This is the only routine that must have a well-defined name. All other callbacks are reached through the driver structure. The macro to use is named -DRIVER_INIT and takes the driver name as parameter:

      (1) /* Beginning of linked list of ports */
      -(2) static UdsData *first_data;
      +DRIVER_INIT and takes the driver name as parameter:

      (1) /* Beginning of linked list of ports */
      +(2) static UdsData *first_data;
       
      -(3) DRIVER_INIT(uds_drv)
      -(4) {
      -(5)     first_data = NULL;
      -(6)     return &uds_driver_entry;
      -(7) }

      The routine initializes the single global data structure and returns a pointer +(3) DRIVER_INIT(uds_drv) +(4) { +(5) first_data = NULL; +(6) return &uds_driver_entry; +(7) }

      The routine initializes the single global data structure and returns a pointer to the driver entry. The routine is called when erl_ddll:load_driver is called from Erlang.

      The uds_start routine is called when a port is opened from Erlang. In this case, we only allocate a structure and initialize it. Creating the actual socket -is left to the uds_command routine.

      ( 1) static ErlDrvData uds_start(ErlDrvPort port, char *buff)
      -( 2) {
      -( 3)     UdsData *ud;
      -( 4)
      -( 5)     ud = ALLOC(sizeof(UdsData));
      -( 6)     ud->fd = -1;
      -( 7)     ud->lockfd = -1;
      -( 8)     ud->creation = 0;
      -( 9)     ud->port = port;
      -(10)     ud->type = portTypeUnknown;
      -(11)     ud->name = NULL;
      -(12)     ud->buffer_size = 0;
      -(13)     ud->buffer_pos = 0;
      -(14)     ud->header_pos = 0;
      -(15)     ud->buffer = NULL;
      -(16)     ud->sent = 0;
      -(17)     ud->received = 0;
      -(18)     ud->partner = NULL;
      -(19)     ud->next = first_data;
      -(20)     first_data = ud;
      -(21)
      -(22)     return((ErlDrvData) ud);
      -(23) }

      Every data item is initialized, so that no problems arise when a newly created +is left to the uds_command routine.

      ( 1) static ErlDrvData uds_start(ErlDrvPort port, char *buff)
      +( 2) {
      +( 3)     UdsData *ud;
      +( 4)
      +( 5)     ud = ALLOC(sizeof(UdsData));
      +( 6)     ud->fd = -1;
      +( 7)     ud->lockfd = -1;
      +( 8)     ud->creation = 0;
      +( 9)     ud->port = port;
      +(10)     ud->type = portTypeUnknown;
      +(11)     ud->name = NULL;
      +(12)     ud->buffer_size = 0;
      +(13)     ud->buffer_pos = 0;
      +(14)     ud->header_pos = 0;
      +(15)     ud->buffer = NULL;
      +(16)     ud->sent = 0;
      +(17)     ud->received = 0;
      +(18)     ud->partner = NULL;
      +(19)     ud->next = first_data;
      +(20)     first_data = ud;
      +(21)
      +(22)     return((ErlDrvData) ud);
      +(23) }

      Every data item is initialized, so that no problems arise when a newly created port is closed (without there being any corresponding socket). This routine is called when open_port({spawn, "uds_drv"},[]) is called from Erlang.

      The uds_command routine is the routine called when an Erlang process sends data to the port. This routine handles all asynchronous commands when the port is in command mode and the sending of all data when the port is in data -mode:

      ( 1) static void uds_command(ErlDrvData handle, char *buff, int bufflen)
      -( 2) {
      -( 3)     UdsData *ud = (UdsData *) handle;
      +mode:

      ( 1) static void uds_command(ErlDrvData handle, char *buff, int bufflen)
      +( 2) {
      +( 3)     UdsData *ud = (UdsData *) handle;
       
      -( 4)     if (ud->type == portTypeData || ud->type == portTypeIntermediate) {
      -( 5)         DEBUGF(("Passive do_send %d",bufflen));
      -( 6)         do_send(ud, buff + 1, bufflen - 1); /* XXX */
      -( 7)         return;
      -( 8)     }
      -( 9)     if (bufflen == 0) {
      -(10)         return;
      -(11)     }
      -(12)     switch (*buff) {
      -(13)     case 'L':
      -(14)         if (ud->type != portTypeUnknown) {
      -(15)             driver_failure_posix(ud->port, ENOTSUP);
      -(16)             return;
      -(17)         }
      -(18)         uds_command_listen(ud,buff,bufflen);
      -(19)         return;
      -(20)     case 'A':
      -(21)         if (ud->type != portTypeUnknown) {
      -(22)             driver_failure_posix(ud->port, ENOTSUP);
      -(23)             return;
      -(24)         }
      -(25)         uds_command_accept(ud,buff,bufflen);
      -(26)         return;
      -(27)     case 'C':
      -(28)         if (ud->type != portTypeUnknown) {
      -(29)             driver_failure_posix(ud->port, ENOTSUP);
      -(30)             return;
      -(31)         }
      -(32)         uds_command_connect(ud,buff,bufflen);
      -(33)         return;
      -(34)     case 'S':
      -(35)         if (ud->type != portTypeCommand) {
      -(36)             driver_failure_posix(ud->port, ENOTSUP);
      -(37)             return;
      -(38)         }
      -(39)         do_send(ud, buff + 1, bufflen - 1);
      -(40)         return;
      -(41)     case 'R':
      -(42)         if (ud->type != portTypeCommand) {
      -(43)             driver_failure_posix(ud->port, ENOTSUP);
      -(44)             return;
      -(45)         }
      -(46)         do_recv(ud);
      -(47)         return;
      -(48)     default:
      -(49)         return;
      -(50)     }
      -(51) }

      The command routine takes three parameters; the handle returned for the port by +( 4) if (ud->type == portTypeData || ud->type == portTypeIntermediate) { +( 5) DEBUGF(("Passive do_send %d",bufflen)); +( 6) do_send(ud, buff + 1, bufflen - 1); /* XXX */ +( 7) return; +( 8) } +( 9) if (bufflen == 0) { +(10) return; +(11) } +(12) switch (*buff) { +(13) case 'L': +(14) if (ud->type != portTypeUnknown) { +(15) driver_failure_posix(ud->port, ENOTSUP); +(16) return; +(17) } +(18) uds_command_listen(ud,buff,bufflen); +(19) return; +(20) case 'A': +(21) if (ud->type != portTypeUnknown) { +(22) driver_failure_posix(ud->port, ENOTSUP); +(23) return; +(24) } +(25) uds_command_accept(ud,buff,bufflen); +(26) return; +(27) case 'C': +(28) if (ud->type != portTypeUnknown) { +(29) driver_failure_posix(ud->port, ENOTSUP); +(30) return; +(31) } +(32) uds_command_connect(ud,buff,bufflen); +(33) return; +(34) case 'S': +(35) if (ud->type != portTypeCommand) { +(36) driver_failure_posix(ud->port, ENOTSUP); +(37) return; +(38) } +(39) do_send(ud, buff + 1, bufflen - 1); +(40) return; +(41) case 'R': +(42) if (ud->type != portTypeCommand) { +(43) driver_failure_posix(ud->port, ENOTSUP); +(44) return; +(45) } +(46) do_recv(ud); +(47) return; +(48) default: +(49) return; +(50) } +(51) }

      The command routine takes three parameters; the handle returned for the port by uds_start, which is a pointer to the internal port structure, the data buffer, and the length of the data buffer. The buffer is the data sent from Erlang (a list of bytes) converted to an C array (of bytes).

      If Erlang sends, for example, the list [$a,$b,$c] to the port, the bufflen @@ -841,34 +841,34 @@

      signals to all linked processes.

      The uds_input routine is called when data is available on a file descriptor previously passed to the driver_select routine. This occurs typically when a read command is issued and no data is available. The do_recv routine is as -follows:

      ( 1) static void do_recv(UdsData *ud)
      -( 2) {
      -( 3)     int res;
      -( 4)     char *ibuf;
      -( 5)     for(;;) {
      -( 6)         if ((res = buffered_read_package(ud,&ibuf)) < 0) {
      -( 7)             if (res == NORMAL_READ_FAILURE) {
      -( 8)                 driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ, 1);
      -( 9)             } else {
      -(10)                 driver_failure_eof(ud->port);
      -(11)             }
      -(12)             return;
      -(13)         }
      -(14)         /* Got a package */
      -(15)         if (ud->type == portTypeCommand) {
      -(16)             ibuf[-1] = 'R'; /* There is always room for a single byte
      +follows:

      ( 1) static void do_recv(UdsData *ud)
      +( 2) {
      +( 3)     int res;
      +( 4)     char *ibuf;
      +( 5)     for(;;) {
      +( 6)         if ((res = buffered_read_package(ud,&ibuf)) < 0) {
      +( 7)             if (res == NORMAL_READ_FAILURE) {
      +( 8)                 driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ, 1);
      +( 9)             } else {
      +(10)                 driver_failure_eof(ud->port);
      +(11)             }
      +(12)             return;
      +(13)         }
      +(14)         /* Got a package */
      +(15)         if (ud->type == portTypeCommand) {
      +(16)             ibuf[-1] = 'R'; /* There is always room for a single byte
       (17)                                opcode before the actual buffer
       (18)                                (where the packet header was) */
      -(19)             driver_output(ud->port,ibuf - 1, res + 1);
      -(20)             driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ,0);
      -(21)             return;
      -(22)         } else {
      -(23)             ibuf[-1] = DIST_MAGIC_RECV_TAG; /* XXX */
      -(24)             driver_output(ud->port,ibuf - 1, res + 1);
      -(25)             driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ,1);
      -(26)         }
      -(27)     }
      -(28) }

      The routine tries to read data until a packet is read or the +(19) driver_output(ud->port,ibuf - 1, res + 1); +(20) driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ,0); +(21) return; +(22) } else { +(23) ibuf[-1] = DIST_MAGIC_RECV_TAG; /* XXX */ +(24) driver_output(ud->port,ibuf - 1, res + 1); +(25) driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ,1); +(26) } +(27) } +(28) }

      The routine tries to read data until a packet is read or the buffered_read_package routine returns a NORMAL_READ_FAILURE (an internally defined constant for the module, which means that the read operation resulted in an EWOULDBLOCK). If the port is in command mode, the reading stops when one @@ -883,77 +883,77 @@

      emulator version, received data is to be tagged with a single byte of 100. That is what the macro DIST_MAGIC_RECV_TAG is defined to. The tagging of data in the distribution can be changed in the future.

      The uds_input routine handles other input events (like non-blocking accept), -but most importantly handle data arriving at the socket by calling do_recv:

      ( 1) static void uds_input(ErlDrvData handle, ErlDrvEvent event)
      -( 2) {
      -( 3)     UdsData *ud = (UdsData *) handle;
      +but most importantly handle data arriving at the socket by calling do_recv:

      ( 1) static void uds_input(ErlDrvData handle, ErlDrvEvent event)
      +( 2) {
      +( 3)     UdsData *ud = (UdsData *) handle;
       
      -( 4)     if (ud->type == portTypeListener) {
      -( 5)         UdsData *ad = ud->partner;
      -( 6)         struct sockaddr_un peer;
      -( 7)         int pl = sizeof(struct sockaddr_un);
      -( 8)         int fd;
      +( 4)     if (ud->type == portTypeListener) {
      +( 5)         UdsData *ad = ud->partner;
      +( 6)         struct sockaddr_un peer;
      +( 7)         int pl = sizeof(struct sockaddr_un);
      +( 8)         int fd;
       
      -( 9)         if ((fd = accept(ud->fd, (struct sockaddr *) &peer, &pl)) < 0) {
      -(10)             if (errno != EWOULDBLOCK) {
      -(11)                 driver_failure_posix(ud->port, errno);
      -(12)                 return;
      -(13)             }
      -(14)             return;
      -(15)         }
      -(16)         SET_NONBLOCKING(fd);
      -(17)         ad->fd = fd;
      -(18)         ad->partner = NULL;
      -(19)         ad->type = portTypeCommand;
      -(20)         ud->partner = NULL;
      -(21)         driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ, 0);
      -(22)         driver_output(ad->port, "Aok",3);
      -(23)         return;
      -(24)     }
      -(25)     do_recv(ud);
      -(26) }

      The important line is the last line in the function: the do_read routine is +( 9) if ((fd = accept(ud->fd, (struct sockaddr *) &peer, &pl)) < 0) { +(10) if (errno != EWOULDBLOCK) { +(11) driver_failure_posix(ud->port, errno); +(12) return; +(13) } +(14) return; +(15) } +(16) SET_NONBLOCKING(fd); +(17) ad->fd = fd; +(18) ad->partner = NULL; +(19) ad->type = portTypeCommand; +(20) ud->partner = NULL; +(21) driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ, 0); +(22) driver_output(ad->port, "Aok",3); +(23) return; +(24) } +(25) do_recv(ud); +(26) }

      The important line is the last line in the function: the do_read routine is called to handle new input. The remaining function handles input on a listen socket, which means that it is to be possible to do an accept on the socket, which is also recognized as a read event.

      The output mechanisms are similar to the input. The do_send routine is as -follows:

      ( 1) static void do_send(UdsData *ud, char *buff, int bufflen)
      -( 2) {
      -( 3)     char header[4];
      -( 4)     int written;
      -( 5)     SysIOVec iov[2];
      -( 6)     ErlIOVec eio;
      -( 7)     ErlDrvBinary *binv[] = {NULL,NULL};
      +follows:

      ( 1) static void do_send(UdsData *ud, char *buff, int bufflen)
      +( 2) {
      +( 3)     char header[4];
      +( 4)     int written;
      +( 5)     SysIOVec iov[2];
      +( 6)     ErlIOVec eio;
      +( 7)     ErlDrvBinary *binv[] = {NULL,NULL};
       
      -( 8)     put_packet_length(header, bufflen);
      -( 9)     iov[0].iov_base = (char *) header;
      -(10)     iov[0].iov_len = 4;
      -(11)     iov[1].iov_base = buff;
      -(12)     iov[1].iov_len = bufflen;
      -(13)     eio.iov = iov;
      -(14)     eio.binv = binv;
      -(15)     eio.vsize = 2;
      -(16)     eio.size = bufflen + 4;
      -(17)     written = 0;
      -(18)     if (driver_sizeq(ud->port) == 0) {
      -(19)         if ((written = writev(ud->fd, iov, 2)) == eio.size) {
      -(20)             ud->sent += written;
      -(21)             if (ud->type == portTypeCommand) {
      -(22)                 driver_output(ud->port, "Sok", 3);
      -(23)             }
      -(24)             return;
      -(25)         } else if (written < 0) {
      -(26)             if (errno != EWOULDBLOCK) {
      -(27)                 driver_failure_eof(ud->port);
      -(28)                 return;
      -(29)             } else {
      -(30)                 written = 0;
      -(31)             }
      -(32)         } else {
      -(33)             ud->sent += written;
      -(34)         }
      -(35)         /* Enqueue remaining */
      -(36)     }
      -(37)     driver_enqv(ud->port, &eio, written);
      -(38)     send_out_queue(ud);
      -(39) }

      This driver uses the writev system call to send data onto the socket. A +( 8) put_packet_length(header, bufflen); +( 9) iov[0].iov_base = (char *) header; +(10) iov[0].iov_len = 4; +(11) iov[1].iov_base = buff; +(12) iov[1].iov_len = bufflen; +(13) eio.iov = iov; +(14) eio.binv = binv; +(15) eio.vsize = 2; +(16) eio.size = bufflen + 4; +(17) written = 0; +(18) if (driver_sizeq(ud->port) == 0) { +(19) if ((written = writev(ud->fd, iov, 2)) == eio.size) { +(20) ud->sent += written; +(21) if (ud->type == portTypeCommand) { +(22) driver_output(ud->port, "Sok", 3); +(23) } +(24) return; +(25) } else if (written < 0) { +(26) if (errno != EWOULDBLOCK) { +(27) driver_failure_eof(ud->port); +(28) return; +(29) } else { +(30) written = 0; +(31) } +(32) } else { +(33) ud->sent += written; +(34) } +(35) /* Enqueue remaining */ +(36) } +(37) driver_enqv(ud->port, &eio, written); +(38) send_out_queue(ud); +(39) }

      This driver uses the writev system call to send data onto the socket. A combination of writev and the driver output queues is very convenient. An ErlIOVec structure contains a SysIOVec (which is equivalent to the struct iovec structure defined in uio.h. The ErlIOVec also contains an @@ -969,52 +969,52 @@

      completely (line 22). The send_out_queue sends acknowledgements if the sending is completed there. If the port is in command mode, the Erlang code serializes the send operations so that only one packet can be waiting for delivery at a -time. Therefore the acknowledgement can be sent whenever the queue is empty.

      The send_out_queue routine is as follows:

      ( 1) static int send_out_queue(UdsData *ud)
      -( 2) {
      -( 3)     for(;;) {
      -( 4)         int vlen;
      -( 5)         SysIOVec *tmp = driver_peekq(ud->port, &vlen);
      -( 6)         int wrote;
      -( 7)         if (tmp == NULL) {
      -( 8)             driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_WRITE, 0);
      -( 9)             if (ud->type == portTypeCommand) {
      -(10)                 driver_output(ud->port, "Sok", 3);
      -(11)             }
      -(12)             return 0;
      -(13)         }
      -(14)         if (vlen > IO_VECTOR_MAX) {
      -(15)             vlen = IO_VECTOR_MAX;
      -(16)         }
      -(17)         if ((wrote = writev(ud->fd, tmp, vlen)) < 0) {
      -(18)             if (errno == EWOULDBLOCK) {
      -(19)                 driver_select(ud->port, (ErlDrvEvent) ud->fd,
      -(20)                               DO_WRITE, 1);
      -(21)                 return 0;
      -(22)             } else {
      -(23)                 driver_failure_eof(ud->port);
      -(24)                 return -1;
      -(25)             }
      -(26)         }
      -(27)         driver_deq(ud->port, wrote);
      -(28)         ud->sent += wrote;
      -(29)     }
      -(30) }

      We simply pick out an I/O vector from the queue (which is the whole queue as a +time. Therefore the acknowledgement can be sent whenever the queue is empty.

      The send_out_queue routine is as follows:

      ( 1) static int send_out_queue(UdsData *ud)
      +( 2) {
      +( 3)     for(;;) {
      +( 4)         int vlen;
      +( 5)         SysIOVec *tmp = driver_peekq(ud->port, &vlen);
      +( 6)         int wrote;
      +( 7)         if (tmp == NULL) {
      +( 8)             driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_WRITE, 0);
      +( 9)             if (ud->type == portTypeCommand) {
      +(10)                 driver_output(ud->port, "Sok", 3);
      +(11)             }
      +(12)             return 0;
      +(13)         }
      +(14)         if (vlen > IO_VECTOR_MAX) {
      +(15)             vlen = IO_VECTOR_MAX;
      +(16)         }
      +(17)         if ((wrote = writev(ud->fd, tmp, vlen)) < 0) {
      +(18)             if (errno == EWOULDBLOCK) {
      +(19)                 driver_select(ud->port, (ErlDrvEvent) ud->fd,
      +(20)                               DO_WRITE, 1);
      +(21)                 return 0;
      +(22)             } else {
      +(23)                 driver_failure_eof(ud->port);
      +(24)                 return -1;
      +(25)             }
      +(26)         }
      +(27)         driver_deq(ud->port, wrote);
      +(28)         ud->sent += wrote;
      +(29)     }
      +(30) }

      We simply pick out an I/O vector from the queue (which is the whole queue as a SysIOVec). If the I/O vector is too long (IO_VECTOR_MAX is defined to 16), the vector length is decreased (line 15), otherwise the writev call (line 17) fails. Writing is tried and anything written is dequeued (line 27). If the write fails with EWOULDBLOCK (notice that all sockets are in non-blocking mode), driver_select is called to make the uds_output routine be called when there -is space to write again.

      We continue trying to write until the queue is empty or the writing blocks.

      The routine above is called from the uds_output routine:

      ( 1) static void uds_output(ErlDrvData handle, ErlDrvEvent event)
      -( 2) {
      -( 3)    UdsData *ud = (UdsData *) handle;
      -( 4)    if (ud->type == portTypeConnector) {
      -( 5)        ud->type = portTypeCommand;
      -( 6)        driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_WRITE, 0);
      -( 7)        driver_output(ud->port, "Cok",3);
      -( 8)        return;
      -( 9)    }
      -(10)    send_out_queue(ud);
      -(11) }

      The routine is simple: it first handles the fact that the output select will +is space to write again.

      We continue trying to write until the queue is empty or the writing blocks.

      The routine above is called from the uds_output routine:

      ( 1) static void uds_output(ErlDrvData handle, ErlDrvEvent event)
      +( 2) {
      +( 3)    UdsData *ud = (UdsData *) handle;
      +( 4)    if (ud->type == portTypeConnector) {
      +( 5)        ud->type = portTypeCommand;
      +( 6)        driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_WRITE, 0);
      +( 7)        driver_output(ud->port, "Cok",3);
      +( 8)        return;
      +( 9)    }
      +(10)    send_out_queue(ud);
      +(11) }

      The routine is simple: it first handles the fact that the output select will concern a socket in the business of connecting (and the connecting blocked). If the socket is in a connected state, it simply sends the output queue. This routine is called when it is possible to write to a socket where we have an @@ -1038,85 +1038,85 @@

      the number stored in the lock file to differentiate between invocations of Erlang nodes with the same name.

    The control interface gets a buffer to return its value in, but is free to allocate its own buffer if the provided one is too small. The uds_control code -is as follows:

    ( 1) static int uds_control(ErlDrvData handle, unsigned int command,
    -( 2)                        char* buf, int count, char** res, int res_size)
    -( 3) {
    -( 4) /* Local macro to ensure large enough buffer. */
    -( 5) #define ENSURE(N)                               \
    -( 6)    do {                                         \
    -( 7)        if (res_size < N) {                      \
    -( 8)            *res = ALLOC(N);                     \
    -( 9)        }                                        \
    -(10)    } while(0)
    +is as follows:

    ( 1) static int uds_control(ErlDrvData handle, unsigned int command,
    +( 2)                        char* buf, int count, char** res, int res_size)
    +( 3) {
    +( 4) /* Local macro to ensure large enough buffer. */
    +( 5) #define ENSURE(N)                               \
    +( 6)    do {                                         \
    +( 7)        if (res_size < N) {                      \
    +( 8)            *res = ALLOC(N);                     \
    +( 9)        }                                        \
    +(10)    } while(0)
     
    -(11)    UdsData *ud = (UdsData *) handle;
    +(11)    UdsData *ud = (UdsData *) handle;
     
    -(12)    switch (command) {
    -(13)    case 'S':
    -(14)        {
    -(15)            ENSURE(13);
    -(16)            **res = 0;
    -(17)            put_packet_length((*res) + 1, ud->received);
    -(18)            put_packet_length((*res) + 5, ud->sent);
    -(19)            put_packet_length((*res) + 9, driver_sizeq(ud->port));
    -(20)            return 13;
    -(21)        }
    -(22)    case 'C':
    -(23)        if (ud->type < portTypeCommand) {
    -(24)            return report_control_error(res, res_size, "einval");
    -(25)        }
    -(26)        ud->type = portTypeCommand;
    -(27)        driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ, 0);
    -(28)        ENSURE(1);
    -(29)        **res = 0;
    -(30)        return 1;
    -(31)    case 'I':
    -(32)        if (ud->type < portTypeCommand) {
    -(33)            return report_control_error(res, res_size, "einval");
    -(34)        }
    -(35)        ud->type = portTypeIntermediate;
    -(36)        driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ, 0);
    -(37)        ENSURE(1);
    -(38)        **res = 0;
    -(39)        return 1;
    -(40)    case 'D':
    -(41)        if (ud->type < portTypeCommand) {
    -(42)            return report_control_error(res, res_size, "einval");
    -(43)        }
    -(44)        ud->type = portTypeData;
    -(45)        do_recv(ud);
    -(46)        ENSURE(1);
    -(47)        **res = 0;
    -(48)        return 1;
    -(49)    case 'N':
    -(50)        if (ud->type != portTypeListener) {
    -(51)            return report_control_error(res, res_size, "einval");
    -(52)        }
    -(53)        ENSURE(5);
    -(54)        (*res)[0] = 0;
    -(55)        put_packet_length((*res) + 1, ud->fd);
    -(56)        return 5;
    -(57)    case 'T': /* tick */
    -(58)        if (ud->type != portTypeData) {
    -(59)            return report_control_error(res, res_size, "einval");
    -(60)        }
    -(61)        do_send(ud,"",0);
    -(62)        ENSURE(1);
    -(63)        **res = 0;
    -(64)        return 1;
    -(65)    case 'R':
    -(66)        if (ud->type != portTypeListener) {
    -(67)            return report_control_error(res, res_size, "einval");
    -(68)        }
    -(69)        ENSURE(2);
    -(70)        (*res)[0] = 0;
    -(71)        (*res)[1] = ud->creation;
    -(72)        return 2;
    -(73)    default:
    -(74)        return report_control_error(res, res_size, "einval");
    -(75)    }
    -(76) #undef ENSURE
    -(77) }

    The macro ENSURE (line 5-10) is used to ensure that the buffer is large enough +(12) switch (command) { +(13) case 'S': +(14) { +(15) ENSURE(13); +(16) **res = 0; +(17) put_packet_length((*res) + 1, ud->received); +(18) put_packet_length((*res) + 5, ud->sent); +(19) put_packet_length((*res) + 9, driver_sizeq(ud->port)); +(20) return 13; +(21) } +(22) case 'C': +(23) if (ud->type < portTypeCommand) { +(24) return report_control_error(res, res_size, "einval"); +(25) } +(26) ud->type = portTypeCommand; +(27) driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ, 0); +(28) ENSURE(1); +(29) **res = 0; +(30) return 1; +(31) case 'I': +(32) if (ud->type < portTypeCommand) { +(33) return report_control_error(res, res_size, "einval"); +(34) } +(35) ud->type = portTypeIntermediate; +(36) driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ, 0); +(37) ENSURE(1); +(38) **res = 0; +(39) return 1; +(40) case 'D': +(41) if (ud->type < portTypeCommand) { +(42) return report_control_error(res, res_size, "einval"); +(43) } +(44) ud->type = portTypeData; +(45) do_recv(ud); +(46) ENSURE(1); +(47) **res = 0; +(48) return 1; +(49) case 'N': +(50) if (ud->type != portTypeListener) { +(51) return report_control_error(res, res_size, "einval"); +(52) } +(53) ENSURE(5); +(54) (*res)[0] = 0; +(55) put_packet_length((*res) + 1, ud->fd); +(56) return 5; +(57) case 'T': /* tick */ +(58) if (ud->type != portTypeData) { +(59) return report_control_error(res, res_size, "einval"); +(60) } +(61) do_send(ud,"",0); +(62) ENSURE(1); +(63) **res = 0; +(64) return 1; +(65) case 'R': +(66) if (ud->type != portTypeListener) { +(67) return report_control_error(res, res_size, "einval"); +(68) } +(69) ENSURE(2); +(70) (*res)[0] = 0; +(71) (*res)[1] = ud->creation; +(72) return 2; +(73) default: +(74) return report_control_error(res, res_size, "einval"); +(75) } +(76) #undef ENSURE +(77) }

    The macro ENSURE (line 5-10) is used to ensure that the buffer is large enough for the answer. We switch on the command and take actions. We always have read select active on a port in data mode (achieved by calling do_recv on line 45), but we turn off read selection in intermediate and command modes (line diff --git a/prs/8803/erts-15.0.1/doc/html/automaticyieldingofccode.html b/prs/8803/erts-15.0.1/doc/html/automaticyieldingofccode.html index 546e4507fe64c..d84c9a37d60f8 100644 --- a/prs/8803/erts-15.0.1/doc/html/automaticyieldingofccode.html +++ b/prs/8803/erts-15.0.1/doc/html/automaticyieldingofccode.html @@ -213,9 +213,9 @@

    function is used, the convention is to "comment out" the source for the function by surrounding it with the following #ifdef (this way, one will not get warnings about unused functions):

    #ifdef INCLUDE_YCF_TRANSFORMED_ONLY_FUNCTIONS
    -void my_fun() {
    +void my_fun() {
         ...
    -}
    +}
     #endif /* INCLUDE_YCF_TRANSFORMED_ONLY_FUNCTIONS */

    While editing the function one can define INCLUDE_YCF_TRANSFORMED_ONLY_FUNCTIONS so that one can see errors and warnings in the non-transformed source.

    diff --git a/prs/8803/erts-15.0.1/doc/html/beam_makeops.html b/prs/8803/erts-15.0.1/doc/html/beam_makeops.html index 2d659a6dfc157..3067a9f8791cd 100644 --- a/prs/8803/erts-15.0.1/doc/html/beam_makeops.html +++ b/prs/8803/erts-15.0.1/doc/html/beam_makeops.html @@ -155,9 +155,9 @@

    BEAM interpreter. For the BeamAsm JIT introduced in OTP 24, the implementation of instructions are defined in emitter functions written in C++.

    Generic instructions have typed operands. Here are a few examples of -operands for move/2:

    {move,{atom,id},{x,5}}.
    -{move,{x,3},{x,0}}.
    -{move,{x,2},{y,1}}.

    When those instructions are loaded, the loader rewrites them +operands for move/2:

    {move,{atom,id},{x,5}}.
    +{move,{x,3},{x,0}}.
    +{move,{x,2},{y,1}}.

    When those instructions are loaded, the loader rewrites them to specific instructions:

    move_cx id 5
     move_xx 3 0
     move_xy 2 1

    Corresponding to each generic instruction, there is a family of @@ -189,9 +189,9 @@

    an integer, an atom, or a literal).

    Now let's look at the implementation of the move instruction. There are multiple files containing implementations of instructions in the erts/emulator/beam/emu directory. The move instruction is defined -in instrs.tab. It looks like this:

    move(Src, Dst) {
    +in instrs.tab.  It looks like this:

    move(Src, Dst) {
         $Dst = $Src;
    -}

    The implementation for an instruction largely follows the C syntax, +}

    The implementation for an instruction largely follows the C syntax, except that the variables in the function head don't have any types. The $ before an identifier denotes a macro expansion. Thus, $Src will expand to the code to pick up the source operand for @@ -208,14 +208,14 @@

    is stored in the lower 32 bits of the word. In the upper 32 bits is the byte offset to the X register; the register number 5 has been multiplied by the word size size 8.

    In the next word the tagged atom id is stored.

    With that background, we can look at the generated code for move_cx -in beam_hot.h:

    OpCase(move_cx):
    -{
    -  BeamInstr next_pf = BeamCodeAddr(I[2]);
    -  xb(BeamExtraData(I[0])) = I[1];
    +in beam_hot.h:

    OpCase(move_cx):
    +{
    +  BeamInstr next_pf = BeamCodeAddr(I[2]);
    +  xb(BeamExtraData(I[0])) = I[1];
       I += 2;
    -  ASSERT(VALID_INSTR(next_pf));
    -  GotoPF(next_pf);
    -}

    We will go through each line in turn.

    • OpCase(move_cx): defines a label for the instruction. The + ASSERT(VALID_INSTR(next_pf)); + GotoPF(next_pf); +}

    We will go through each line in turn.

    • OpCase(move_cx): defines a label for the instruction. The OpCase() macro is defined in beam_emu.c. It will expand this line to lb_move_cx:.

    • BeamInstr next_pf = BeamCodeAddr(I[2]); fetches the pointer to code for the next instruction to be executed. The BeamCodeAddr() @@ -229,15 +229,15 @@

      this case).

    • I += 2 advances the instruction pointer to the next instruction.

    • In a debug-compiled emulator, ASSERT(VALID_INSTR(next_pf)); makes sure that next_pf is a valid instruction (that is, that it points -within the process_main() function in beam_emu.c).

    • GotoPF(next_pf); transfers control to the next instruction.

    Now let's look at the implementation of move_xx:

    OpCase(move_xx):
    -{
    -  Eterm tmp_packed1 = BeamExtraData(I[0]);
    -  BeamInstr next_pf = BeamCodeAddr(I[1]);
    -  xb((tmp_packed1>>BEAM_TIGHT_SHIFT)) = xb(tmp_packed1&BEAM_TIGHT_MASK);
    +within the process_main() function in beam_emu.c).

  • GotoPF(next_pf); transfers control to the next instruction.

  • Now let's look at the implementation of move_xx:

    OpCase(move_xx):
    +{
    +  Eterm tmp_packed1 = BeamExtraData(I[0]);
    +  BeamInstr next_pf = BeamCodeAddr(I[1]);
    +  xb((tmp_packed1>>BEAM_TIGHT_SHIFT)) = xb(tmp_packed1&BEAM_TIGHT_MASK);
       I += 1;
    -  ASSERT(VALID_INSTR(next_pf));
    -  GotoPF(next_pf);
    -}

    We will go through the lines that are new or have changed compared to + ASSERT(VALID_INSTR(next_pf)); + GotoPF(next_pf); +}

    We will go through the lines that are new or have changed compared to move_cx.

    • Eterm tmp_packed1 = BeamExtraData(I[0]); picks up both X register numbers packed into the upper 32 bits of the instruction word.

    • BeamInstr next_pf = BeamCodeAddr(I[1]); pre-fetches the address of the next instruction. Note that because both X registers operands fits @@ -246,15 +246,15 @@

      copies the source to the destination. (For a 64-bit architecture, BEAM_TIGHT_SHIFT is 16 and BEAM_TIGHT_MASK is 0xFFFF.)

    • I += 1; advances the instruction pointer to the next instruction.

    move_xy is almost identical to move_xx. The only difference is the use of the yb() macro instead of xb() to reference the -destination register:

    OpCase(move_xy):
    -{
    -  Eterm tmp_packed1 = BeamExtraData(I[0]);
    -  BeamInstr next_pf = BeamCodeAddr(I[1]);
    -  yb((tmp_packed1>>BEAM_TIGHT_SHIFT)) = xb(tmp_packed1&BEAM_TIGHT_MASK);
    +destination register:

    OpCase(move_xy):
    +{
    +  Eterm tmp_packed1 = BeamExtraData(I[0]);
    +  BeamInstr next_pf = BeamCodeAddr(I[1]);
    +  yb((tmp_packed1>>BEAM_TIGHT_SHIFT)) = xb(tmp_packed1&BEAM_TIGHT_MASK);
       I += 1;
    -  ASSERT(VALID_INSTR(next_pf));
    -  GotoPF(next_pf);
    -}

    + ASSERT(VALID_INSTR(next_pf)); + GotoPF(next_pf); +}

    @@ -275,13 +275,13 @@

    move2 x y x y // In instrs.tab -move2(S1, D1, S2, D2) { +move2(S1, D1, S2, D2) { Eterm V1, V2; V1 = $S1; V2 = $S2; $D1 = V1; $D2 = V2; -}

    When the loader has found a match and replaced the matched instructions, +}

    When the loader has found a match and replaced the matched instructions, it will match the new instructions against the transformation rules. Because of that, we can define the rule for a move3/6 instruction as follows:

    move2 X1=x Y1=y X2=x Y2=y | move X3=x Y3=y =>
    @@ -437,21 +437,21 @@ 

    i_fcheckerror fclearerror %endif

    It is also possible to add an %else clause:

    %if ARCH_64
    -BS_SAFE_MUL(A, B, Fail, Dst) {
    -    Uint64 res = ($A) * ($B);
    -    if (res / $B != $A) {
    +BS_SAFE_MUL(A, B, Fail, Dst) {
    +    Uint64 res = ($A) * ($B);
    +    if (res / $B != $A) {
             $Fail;
    -    }
    +    }
         $Dst = res;
    -}
    +}
     %else
    -BS_SAFE_MUL(A, B, Fail, Dst) {
    -    Uint64 res = (Uint64)($A) * (Uint64)($B);
    -    if ((res >> (8*sizeof(Uint))) != 0) {
    +BS_SAFE_MUL(A, B, Fail, Dst) {
    +    Uint64 res = (Uint64)($A) * (Uint64)($B);
    +    if ((res >> (8*sizeof(Uint))) != 0) {
             $Fail;
    -    }
    +    }
         $Dst = res;
    -}
    +}
     %endif

    Symbols that are defined in directives

    The following symbols are always defined.

    • ARCH_64 - is 1 for a 64-bit machine, and 0 otherwise.
    • ARCH_32 - is 1 for 32-bit machine, and 0 otherwise.

    The Makefile for building the emulator currently defines the following symbols by using the -D option on the command line for beam_makeops.

    • USE_VM_PROBES - 1 if the runtime system is compiled to use VM @@ -680,7 +680,7 @@

      a non-zero value, the matching of the rule will continue, otherwise the match will fail. Such guard functions are hereafter called predicates.

      The most commonly used guard constraints is equal(). It can be used -to remove a redundant move instructio like this:

      move R1 R2 | equal(R1, R2) => _

      or remove a redundant is_eq_exact instruction like this:

      is_eq_exact Lbl Src1 Src2 | equal(Src1, Src2) => _

      At the time of writing, all predicates are defined in files named +to remove a redundant move instructio like this:

      move R1 R2 | equal(R1, R2) => _

      or remove a redundant is_eq_exact instruction like this:

      is_eq_exact Lbl Src1 Src2 | equal(Src1, Src2) => _

      At the time of writing, all predicates are defined in files named predicates.tab in several directories. In predicates.tab directly in $ERL_TOP/erts/emulator/beam, predicates that are used by both the traditinal emulator and the JIT implementations are contained. @@ -696,33 +696,33 @@

      internal loader data structures, but here is quick look at the implementation of a simple predicate called literal_is_map().

      Here is first an example how it is used:

      ismap Fail Lit=q | literal_is_map(Lit) =>

      If the Lit operand is a literal, then the literal_is_map() predicate is called to determine whether it is a map literal. -If it is, the instruction is not needed and can be removed.

      literal_is_map() is implemented like this (in emu/predicates.tab):

      pred.literal_is_map(Lit) {
      +If it is, the instruction is not needed and can be removed.

      literal_is_map() is implemented like this (in emu/predicates.tab):

      pred.literal_is_map(Lit) {
           Eterm term;
       
      -    ASSERT(Lit.type == TAG_q);
      -    term = beamfile_get_literal(&S->beam, Lit.val);
      -    return is_map(term);
      -}

      The pred. prefix tells beam_makeops that this function is a + ASSERT(Lit.type == TAG_q); + term = beamfile_get_literal(&S->beam, Lit.val); + return is_map(term); +}

      The pred. prefix tells beam_makeops that this function is a predicate. Without the prefix, it would have been interpreted as the implementation of an instruction (described in Defining the implementation).

      Predicate functions have a magic variabled called S, which is a pointer to a state struct. In the example, beamfile_get_literal(&S->beam, Lit.val); is used to retrieve the actual term for the literal.

      At the time of writing, the expanded C code generated by -beam_makeops looks like this:

      static int literal_is_map(LoaderState* S, BeamOpArg Lit) {
      +beam_makeops looks like this:

      static int literal_is_map(LoaderState* S, BeamOpArg Lit) {
         Eterm term;
       
      -  ASSERT(Lit.type == TAG_q);
      -  term = S->literals[Lit.val].term;
      -  return is_map(term);;
      -}

      Handling instructions with variable number of operands

      Some instructions, such as select_val/3, essentially has a variable + ASSERT(Lit.type == TAG_q); + term = S->literals[Lit.val].term; + return is_map(term);; +}

      Handling instructions with variable number of operands

      Some instructions, such as select_val/3, essentially has a variable number of operands. Such instructions have a {list,[...]} operand -as their last operand in the BEAM assembly code. For example:

      {select_val,{x,0},
      -            {f,1},
      -            {list,[{atom,b},{f,4},{atom,a},{f,5}]}}.

      The loader will convert a {list,[...]} operand to an u operand whose +as their last operand in the BEAM assembly code. For example:

      {select_val,{x,0},
      +            {f,1},
      +            {list,[{atom,b},{f,4},{atom,a},{f,5}]}}.

      The loader will convert a {list,[...]} operand to an u operand whose value is the number of elements in the list, followed by each element in the list. The instruction above would be translated to the following -generic instruction:

      {select_val,{x,0},{f,1},{u,4},{atom,b},{f,4},{atom,a},{f,5}}

      To match a variable number of arguments we need to use the special +generic instruction:

      {select_val,{x,0},{f,1},{u,4},{atom,b},{f,4},{atom,a},{f,5}}

      To match a variable number of arguments we need to use the special operand type * like this:

      select_val Src=aiq Fail=f Size=u List=* =>
           i_const_select_val Src Fail Size List

      This transformation renames a select_val/3 instruction with a constant source operand to i_const_select_val/3.

      Constructing new instructions on the right-hand side

      The most common operand on the right-hand side is a variable that was @@ -750,7 +750,7 @@

      side of the transformation will perform the match and bind operands to variables. The variables can then be passed to a generator function on the right-hand side. For example:

      bif2 Fail=j u$bif:erlang:element/2 Index=s Tuple=xy Dst=d =>
      -    element(Jump, Index, Tuple, Dst)

      This transformation rule matches a call to the BIF element/2. + element(Jump, Index, Tuple, Dst)

    This transformation rule matches a call to the BIF element/2. The operands will be captured and the generator function element() will be called.

    The element() generator will produce one of two instructions depending on Index. If Index is an integer in the range from 1 up @@ -765,30 +765,30 @@

    named generators.tab in several directories (in the same directories as the predicates.tab files).

    It is outside the scope of this document to describe in detail how generator functions are written, but here is the implementation of -element():

    gen.element(Fail, Index, Tuple, Dst) {
    +element():

    gen.element(Fail, Index, Tuple, Dst) {
         BeamOp* op;
     
    -    $NewBeamOp(S, op);
    +    $NewBeamOp(S, op);
     
    -    if (Index.type == TAG_i && Index.val > 0 &&
    +    if (Index.type == TAG_i && Index.val > 0 &&
             Index.val <= ERTS_MAX_TUPLE_SIZE &&
    -        (Tuple.type == TAG_x || Tuple.type == TAG_y)) {
    -        $BeamOpNameArity(op, i_fast_element, 4);
    -        op->a[0] = Tuple;
    -        op->a[1] = Fail;
    -        op->a[2].type = TAG_u;
    -        op->a[2].val = Index.val;
    -        op->a[3] = Dst;
    -    } else {
    -        $BeamOpNameArity(op, i_element, 4);
    -        op->a[0] = Tuple;
    -        op->a[1] = Fail;
    -        op->a[2] = Index;
    -        op->a[3] = Dst;
    -    }
    +        (Tuple.type == TAG_x || Tuple.type == TAG_y)) {
    +        $BeamOpNameArity(op, i_fast_element, 4);
    +        op->a[0] = Tuple;
    +        op->a[1] = Fail;
    +        op->a[2].type = TAG_u;
    +        op->a[2].val = Index.val;
    +        op->a[3] = Dst;
    +    } else {
    +        $BeamOpNameArity(op, i_element, 4);
    +        op->a[0] = Tuple;
    +        op->a[1] = Fail;
    +        op->a[2] = Index;
    +        op->a[3] = Dst;
    +    }
     
         return op;
    -}

    The gen. prefix tells beam_makeops that this function is a +}

    The gen. prefix tells beam_makeops that this function is a generator. Without the prefix, it would have been interpreted as the implementation of an instruction (described in Defining the implementation).

    Generator functions have a magic variabled called S, which is a @@ -818,9 +818,9 @@

    following line:

    // -*- c -*-

    To avoid messing up the indentation, all comments are written as C++ style comments (//) instead of #. Note that a comment must start at the beginning of a line.

    The meat of an instruction definition file are macro definitions. -We have seen this macro definition before:

    move(Src, Dst) {
    +We have seen this macro definition before:

    move(Src, Dst) {
         $Dst = $Src;
    -}

    A macro definitions must start at the beginning of the line (no spaces +}

    A macro definitions must start at the beginning of the line (no spaces allowed), the opening curly bracket must be on the same line, and the finishing curly bracket must be at the beginning of a line. It is recommended that the macro body is properly indented.

    As a convention, the macro arguments in the head all start with an @@ -829,103 +829,103 @@

    specific instructions is assumed to be the implementation of that instruction.

    A macro can also be invoked from within another macro. For example, move_deallocate_return/2 avoids repeating code by invoking -$deallocate_return() as a macro:

    move_deallocate_return(Src, Deallocate) {
    -    x(0) = $Src;
    -    $deallocate_return($Deallocate);
    -}

    Here is the definition of deallocate_return/1:

    deallocate_return(Deallocate) {
    +$deallocate_return() as a macro:

    move_deallocate_return(Src, Deallocate) {
    +    x(0) = $Src;
    +    $deallocate_return($Deallocate);
    +}

    Here is the definition of deallocate_return/1:

    deallocate_return(Deallocate) {
         //| -no_next
         int words_to_pop = $Deallocate;
    -    SET_I((BeamInstr *) cp_val(*E));
    -    E = ADD_BYTE_OFFSET(E, words_to_pop);
    -    CHECK_TERM(x(0));
    +    SET_I((BeamInstr *) cp_val(*E));
    +    E = ADD_BYTE_OFFSET(E, words_to_pop);
    +    CHECK_TERM(x(0));
         DispatchReturn;
    -}

    The expanded code for move_deallocate_return will look this:

    OpCase(move_deallocate_return_cQ):
    -{
    -  x(0) = I[1];
    -  do {
    -    int words_to_pop = Qb(BeamExtraData(I[0]));
    -    SET_I((BeamInstr *) cp_val(*E));
    -    E = ADD_BYTE_OFFSET(E, words_to_pop);
    -    CHECK_TERM(x(0));
    +}

    The expanded code for move_deallocate_return will look this:

    OpCase(move_deallocate_return_cQ):
    +{
    +  x(0) = I[1];
    +  do {
    +    int words_to_pop = Qb(BeamExtraData(I[0]));
    +    SET_I((BeamInstr *) cp_val(*E));
    +    E = ADD_BYTE_OFFSET(E, words_to_pop);
    +    CHECK_TERM(x(0));
         DispatchReturn;
    -  } while (0);
    -}

    When expanding macros, beam_makeops wraps the expansion in a + } while (0); +}

    When expanding macros, beam_makeops wraps the expansion in a do/while wrapper unless beam_makeops can clearly see that no wrapper is needed. In this case, the wrapper is needed.

    Note that arguments for macros cannot be complex expressions, because the arguments are split on ,. For example, the following would not work because beam_makeops would split the expression into -two arguments:

    $deallocate_return(get_deallocation(y, $Deallocate));

    Code generation directives

    Within macro definitions, // comments are in general not treated +two arguments:

    $deallocate_return(get_deallocation(y, $Deallocate));

    Code generation directives

    Within macro definitions, // comments are in general not treated specially. They will be copied to the file with the generated code along with the rest of code in the body.

    However, there is an exception. Within a macro definition, a line that starts with whitespace followed by //| is treated specially. The rest of the line is assumed to contain directives to control code generation.

    Currently, two code generation directives are recognized:

    • -no_prefetch
    • -no_next
    The -no_prefetch directive

    To see what -no_prefetch does, let's first look at the default code -generation. Here is the code generated for move_cx:

    OpCase(move_cx):
    -{
    -  BeamInstr next_pf = BeamCodeAddr(I[2]);
    -  xb(BeamExtraData(I[0])) = I[1];
    +generation.  Here is the code generated for move_cx:

    OpCase(move_cx):
    +{
    +  BeamInstr next_pf = BeamCodeAddr(I[2]);
    +  xb(BeamExtraData(I[0])) = I[1];
       I += 2;
    -  ASSERT(VALID_INSTR(next_pf));
    -  GotoPF(next_pf);
    -}

    Note that the very first thing done is to fetch the address to the + ASSERT(VALID_INSTR(next_pf)); + GotoPF(next_pf); +}

    Note that the very first thing done is to fetch the address to the next instruction. The reason is that it usually improves performance.

    Just as a demonstration, we can add a -no_prefetch directive to -the move/2 instruction:

    move(Src, Dst) {
    +the move/2 instruction:

    move(Src, Dst) {
         //| -no_prefetch
         $Dst = $Src;
    -}

    We can see that the prefetch is no longer done:

    OpCase(move_cx):
    -{
    -  xb(BeamExtraData(I[0])) = I[1];
    +}

    We can see that the prefetch is no longer done:

    OpCase(move_cx):
    +{
    +  xb(BeamExtraData(I[0])) = I[1];
       I += 2;
    -  ASSERT(VALID_INSTR(*I));
    -  Goto(*I);
    -}

    When would we want to turn off the prefetch in practice?

    In instructions that will not always execute the next instruction. -For example:

    is_atom(Fail, Src) {
    -    if (is_not_atom($Src)) {
    -        $FAIL($Fail);
    -    }
    -}
    +  ASSERT(VALID_INSTR(*I));
    +  Goto(*I);
    +}

    When would we want to turn off the prefetch in practice?

    In instructions that will not always execute the next instruction. +For example:

    is_atom(Fail, Src) {
    +    if (is_not_atom($Src)) {
    +        $FAIL($Fail);
    +    }
    +}
     
     // From macros.tab
    -FAIL(Fail) {
    +FAIL(Fail) {
         //| -no_prefetch
    -    $SET_I_REL($Fail);
    -    Goto(*I);
    -}

    is_atom/2 may either execute the next instruction (if the second -operand is an atom) or branch to the failure label.

    The generated code looks like this:

    OpCase(is_atom_fx):
    -{
    -  if (is_not_atom(xb(I[1]))) {
    -    ASSERT(VALID_INSTR(*(I + (fb(BeamExtraData(I[0]))) + 0)));
    -    I += fb(BeamExtraData(I[0])) + 0;;
    -    Goto(*I);;
    -  }
    +    $SET_I_REL($Fail);
    +    Goto(*I);
    +}

    is_atom/2 may either execute the next instruction (if the second +operand is an atom) or branch to the failure label.

    The generated code looks like this:

    OpCase(is_atom_fx):
    +{
    +  if (is_not_atom(xb(I[1]))) {
    +    ASSERT(VALID_INSTR(*(I + (fb(BeamExtraData(I[0]))) + 0)));
    +    I += fb(BeamExtraData(I[0])) + 0;;
    +    Goto(*I);;
    +  }
       I += 2;
    -  ASSERT(VALID_INSTR(*I));
    -  Goto(*I);
    -}
    The -no_next directive

    Next we will look at when the -no_next directive can be used. Here -is the jump/1 instruction:

    jump(Fail) {
    -    $JUMP($Fail);
    -}
    +  ASSERT(VALID_INSTR(*I));
    +  Goto(*I);
    +}
    The -no_next directive

    Next we will look at when the -no_next directive can be used. Here +is the jump/1 instruction:

    jump(Fail) {
    +    $JUMP($Fail);
    +}
     
     // From macros.tab
    -JUMP(Fail) {
    +JUMP(Fail) {
         //| -no_next
    -    $SET_I_REL($Fail);
    -    Goto(*I);
    -}

    The generated code looks like this:

    OpCase(jump_f):
    -{
    -  ASSERT(VALID_INSTR(*(I + (fb(BeamExtraData(I[0]))) + 0)));
    -  I += fb(BeamExtraData(I[0])) + 0;;
    -  Goto(*I);;
    -}

    If we remove the -no_next directive, the code would look like this:

    OpCase(jump_f):
    -{
    -  BeamInstr next_pf = BeamCodeAddr(I[1]);
    -  ASSERT(VALID_INSTR(*(I + (fb(BeamExtraData(I[0]))) + 0)));
    -  I += fb(BeamExtraData(I[0])) + 0;;
    -  Goto(*I);;
    +    $SET_I_REL($Fail);
    +    Goto(*I);
    +}

    The generated code looks like this:

    OpCase(jump_f):
    +{
    +  ASSERT(VALID_INSTR(*(I + (fb(BeamExtraData(I[0]))) + 0)));
    +  I += fb(BeamExtraData(I[0])) + 0;;
    +  Goto(*I);;
    +}

    If we remove the -no_next directive, the code would look like this:

    OpCase(jump_f):
    +{
    +  BeamInstr next_pf = BeamCodeAddr(I[1]);
    +  ASSERT(VALID_INSTR(*(I + (fb(BeamExtraData(I[0]))) + 0)));
    +  I += fb(BeamExtraData(I[0])) + 0;;
    +  Goto(*I);;
       I += 1;
    -  ASSERT(VALID_INSTR(next_pf));
    -  GotoPF(next_pf);
    -}

    In the end, the C compiler will probably optimize this code to the + ASSERT(VALID_INSTR(next_pf)); + GotoPF(next_pf); +}

    In the end, the C compiler will probably optimize this code to the same native code as the first version, but the first version is certainly much easier to read for human readers.

    Macros in the macros.tab file

    The file macros.tab contains many useful macros. When implementing new instructions it is good practice to look through macros.tab to @@ -936,61 +936,61 @@

    $REFRESH_GEN_DEST() macro.

    If you need to define a new function that does garbage collection, you should give it the prefix erts_gc_. If that is not possible you should update the regular expression so that it will match your -new function.

    FAIL(Fail)

    Branch to $Fail. Will suppress prefetch (-no_prefetch). Typical use:

    is_nonempty_list(Fail, Src) {
    -    if (is_not_list($Src)) {
    -        $FAIL($Fail);
    -    }
    -}
    JUMP(Fail)

    Branch to $Fail. Suppresses generation of dispatch of the next -instruction (-no_next). Typical use:

    jump(Fail) {
    -    $JUMP($Fail);
    -}
    GC_TEST(NeedStack, NeedHeap, Live)

    $GC_TEST(NeedStack, NeedHeap, Live) tests that given amount of +new function.

    FAIL(Fail)

    Branch to $Fail. Will suppress prefetch (-no_prefetch). Typical use:

    is_nonempty_list(Fail, Src) {
    +    if (is_not_list($Src)) {
    +        $FAIL($Fail);
    +    }
    +}
    JUMP(Fail)

    Branch to $Fail. Suppresses generation of dispatch of the next +instruction (-no_next). Typical use:

    jump(Fail) {
    +    $JUMP($Fail);
    +}
    GC_TEST(NeedStack, NeedHeap, Live)

    $GC_TEST(NeedStack, NeedHeap, Live) tests that given amount of stack space and heap space is available. If not it will do a -garbage collection. Typical use:

    test_heap(Nh, Live) {
    -    $GC_TEST(0, $Nh, $Live);
    -}
    AH(NeedStack, NeedHeap, Live)

    AH(NeedStack, NeedHeap, Live) allocates a stack frame and +garbage collection. Typical use:

    test_heap(Nh, Live) {
    +    $GC_TEST(0, $Nh, $Live);
    +}
    AH(NeedStack, NeedHeap, Live)

    AH(NeedStack, NeedHeap, Live) allocates a stack frame and optionally additional heap space.

    Pre-defined macros and variables

    beam_makeops defines several built-in macros and pre-bound variables.

    The NEXT_INSTRUCTION pre-bound variable

    The NEXT_INSTRUCTION is a pre-bound variable that is available in -all instructions. It expands to the address of the next instruction.

    Here is an example:

    i_call(CallDest) {
    +all instructions.  It expands to the address of the next instruction.

    Here is an example:

    i_call(CallDest) {
         //| -no_next
    -    $SAVE_CONTINUATION_POINTER($NEXT_INSTRUCTION);
    -    $DISPATCH_REL($CallDest);
    -}

    When calling a function, the return address is first stored in E[0] + $SAVE_CONTINUATION_POINTER($NEXT_INSTRUCTION); + $DISPATCH_REL($CallDest); +}

    When calling a function, the return address is first stored in E[0] (using the $SAVE_CONTINUATION_POINTER() macro), and then control is -transferred to the callee. Here is the generated code:

    OpCase(i_call_f):
    -{
    -    ASSERT(VALID_INSTR(*(I+2)));
    -    *E = (BeamInstr) (I+2);;
    +transferred to the callee.  Here is the generated code:

    OpCase(i_call_f):
    +{
    +    ASSERT(VALID_INSTR(*(I+2)));
    +    *E = (BeamInstr) (I+2);;
     
         /* ... dispatch code intentionally left out ... */
    -}

    We can see that that $NEXT_INSTRUCTION has been expanded to I+2. +}

    We can see that that $NEXT_INSTRUCTION has been expanded to I+2. That makes sense since the size of the i_call_f/1 instruction is two words.

    The IP_ADJUSTMENT pre-bound variable

    $IP_ADJUSTMENT is usually 0. In a few combined instructions (described below) it can be non-zero. It is used like this -in macros.tab:

    SET_I_REL(Offset) {
    -    ASSERT(VALID_INSTR(*(I + ($Offset) + $IP_ADJUSTMENT)));
    +in macros.tab:

    SET_I_REL(Offset) {
    +    ASSERT(VALID_INSTR(*(I + ($Offset) + $IP_ADJUSTMENT)));
         I += $Offset + $IP_ADJUSTMENT;
    -}

    Avoid using IP_ADJUSTMENT directly. Use SET_I_REL() or +}

    Avoid using IP_ADJUSTMENT directly. Use SET_I_REL() or one of the macros that invoke such as FAIL() or JUMP() defined in macros.tab.

    Pre-defined macro functions

    The IF() macro

    $IF(Expr, IfTrue, IfFalse) evaluates Expr, which must be a valid Perl expression (which for simple numeric expressions have the same syntax as C). If Expr evaluates to 0, the entire IF() expression will be replaced with IfFalse, otherwise it will be replaced with IfTrue.

    See the description of OPERAND_POSITION() for an example.

    The OPERAND_POSITION() macro

    $OPERAND_POSITION(Expr) returns the position for Expr, if Expr is an operand that is not packed. The first operand is -at position 1.

    Returns 0 otherwise.

    This macro could be used like this in order to share code:

    FAIL(Fail) {
    +at position 1.

    Returns 0 otherwise.

    This macro could be used like this in order to share code:

    FAIL(Fail) {
         //| -no_prefetch
    -    $IF($OPERAND_POSITION($Fail) == 1 && $IP_ADJUSTMENT == 0,
    +    $IF($OPERAND_POSITION($Fail) == 1 && $IP_ADJUSTMENT == 0,
             goto common_jump,
    -        $DO_JUMP($Fail));
    -}
    +        $DO_JUMP($Fail));
    +}
     
    -DO_JUMP(Fail) {
    -    $SET_I_REL($Fail);
    -    Goto(*I));
    -}
    +DO_JUMP(Fail) {
    +    $SET_I_REL($Fail);
    +    Goto(*I));
    +}
     
     // In beam_emu.c:
     common_jump:
    -   I += I[1];
    -   Goto(*I));

    The $REFRESH_GEN_DEST() macro

    When a specific instruction has a d operand, early during execution + I += I[1]; + Goto(*I));

    The $REFRESH_GEN_DEST() macro

    When a specific instruction has a d operand, early during execution of the instruction, a pointer will be initialized to point to the X or Y register in question.

    If there is a garbage collection before the result is stored, the stack will move and if the d operand referred to a Y @@ -999,29 +999,29 @@

    to set up the pointer again. beam_makeops will notice if there is a call to a function that does a garbage collection and $REFRESH_GEN_DEST() is not called.

    Here is a complete example. The new_map instruction is defined -like this:

    new_map d t I

    It is implemented like this:

    new_map(Dst, Live, N) {
    +like this:

    new_map d t I

    It is implemented like this:

    new_map(Dst, Live, N) {
         Eterm res;
     
         HEAVY_SWAPOUT;
    -    res = erts_gc_new_map(c_p, reg, $Live, $N, $NEXT_INSTRUCTION);
    +    res = erts_gc_new_map(c_p, reg, $Live, $N, $NEXT_INSTRUCTION);
         HEAVY_SWAPIN;
    -    $REFRESH_GEN_DEST();
    +    $REFRESH_GEN_DEST();
         $Dst = res;
    -    $NEXT($NEXT_INSTRUCTION+$N);
    -}

    If we have forgotten the $REFRESH_GEN_DEST() there would be a message -similar to this:

    pointer to destination register is invalid after GC -- use $REFRESH_GEN_DEST()
    -... from the body of new_map at beam/map_instrs.tab(30)

    Variable number of operands

    Here follows an example of how to handle an instruction with a variable number + $NEXT($NEXT_INSTRUCTION+$N); +}

    If we have forgotten the $REFRESH_GEN_DEST() there would be a message +similar to this:

    pointer to destination register is invalid after GC -- use $REFRESH_GEN_DEST()
    +... from the body of new_map at beam/map_instrs.tab(30)

    Variable number of operands

    Here follows an example of how to handle an instruction with a variable number of operands for the interpreter. Here is the instruction definition in emu/ops.tab:

    put_tuple2 xy I *

    For the interpreter, the * is optional, because it does not effect code generation in any way. However, it is recommended to include it to make it clear for human readers that there is a variable number of operands.

    Use the $NEXT_INSTRUCTION macro to obtain a pointer to the first of the variable -operands.

    Here is the implementation:

    put_tuple2(Dst, Arity) {
    +operands.

    Here is the implementation:

    put_tuple2(Dst, Arity) {
     Eterm* hp = HTOP;
     Eterm arity = $Arity;
    -Eterm* dst_ptr = &($Dst);
    +Eterm* dst_ptr = &($Dst);
     
     //| -no_next
    -ASSERT(arity != 0);
    -*hp++ = make_arityval(arity);
    +ASSERT(arity != 0);
    +*hp++ = make_arityval(arity);
     
     /*
      * The $NEXT_INSTRUCTION macro points just beyond the fixed
    @@ -1029,58 +1029,58 @@ 

    * the first element to be put into the tuple. */ I = $NEXT_INSTRUCTION; -do { +do { Eterm term = *I++; - switch (loader_tag(term)) { + switch (loader_tag(term)) { case LOADER_X_REG: - *hp++ = x(loader_x_reg_index(term)); + *hp++ = x(loader_x_reg_index(term)); break; case LOADER_Y_REG: - *hp++ = y(loader_y_reg_index(term)); + *hp++ = y(loader_y_reg_index(term)); break; default: *hp++ = term; break; - } -} while (--arity != 0); -*dst_ptr = make_tuple(HTOP); + } +} while (--arity != 0); +*dst_ptr = make_tuple(HTOP); HTOP = hp; -ASSERT(VALID_INSTR(* (Eterm *)I)); -Goto(*I); -}

    Combined instructions

    Problem: For frequently executed instructions we want to use +ASSERT(VALID_INSTR(* (Eterm *)I)); +Goto(*I); +}

    Combined instructions

    Problem: For frequently executed instructions we want to use "fast" operands types such as x and y, as opposed to s or S. To avoid an explosion in code size, we want to share most of the implementation between the instructions. Here are the specific instructions for i_increment/5:

    i_increment r W t d
     i_increment x W t d
    -i_increment y W t d

    The i_increment instruction is implemented like this:

    i_increment(Source, IncrementVal, Live, Dst) {
    +i_increment y W t d

    The i_increment instruction is implemented like this:

    i_increment(Source, IncrementVal, Live, Dst) {
         Eterm increment_reg_source = $Source;
         Eterm increment_val = $IncrementVal;
         Uint live;
         Eterm result;
     
    -    if (ERTS_LIKELY(is_small(increment_reg_val))) {
    -        Sint i = signed_val(increment_reg_val) + increment_val;
    -        if (ERTS_LIKELY(IS_SSMALL(i))) {
    -            $Dst = make_small(i);
    -            $NEXT0();
    -        }
    -    }
    +    if (ERTS_LIKELY(is_small(increment_reg_val))) {
    +        Sint i = signed_val(increment_reg_val) + increment_val;
    +        if (ERTS_LIKELY(IS_SSMALL(i))) {
    +            $Dst = make_small(i);
    +            $NEXT0();
    +        }
    +    }
         live = $Live;
         HEAVY_SWAPOUT;
    -    reg[live] = increment_reg_val;
    -    reg[live+1] = make_small(increment_val);
    -    result = erts_gc_mixed_plus(c_p, reg, live);
    +    reg[live] = increment_reg_val;
    +    reg[live+1] = make_small(increment_val);
    +    result = erts_gc_mixed_plus(c_p, reg, live);
         HEAVY_SWAPIN;
    -    ERTS_HOLE_CHECK(c_p);
    -    if (ERTS_LIKELY(is_value(result))) {
    -        $REFRESH_GEN_DEST();
    +    ERTS_HOLE_CHECK(c_p);
    +    if (ERTS_LIKELY(is_value(result))) {
    +        $REFRESH_GEN_DEST();
             $Dst = result;
    -        $NEXT0();
    -    }
    -    ASSERT(c_p->freason != BADMATCH || is_value(c_p->fvalue));
    +        $NEXT0();
    +    }
    +    ASSERT(c_p->freason != BADMATCH || is_value(c_p->fvalue));
         goto find_func_info;
    -}

    There will be three almost identical copies of the code. Given the +}

    There will be three almost identical copies of the code. Given the size of the code, that could be too high cost to pay.

    To avoid the three copies of the code, we could use only one specific instruction:

    i_increment S W t d

    (The same implementation as above will work.)

    That reduces the code size, but is slower because S means that there will be extra code to test whether the operand refers to an X @@ -1089,44 +1089,44 @@

    bulk of the code can be shared.

    Here we will show how i_increment can be implemented as a combined instruction. We will show each individual fragment first, and then show how to connect them together. First we will need a variable that -we can store the value fetched from the register in:

    increment.head() {
    +we can store the value fetched from the register in:

    increment.head() {
         Eterm increment_reg_val;
    -}

    The name increment is the name of the group that the fragment +}

    The name increment is the name of the group that the fragment belongs to. Note that it does not need to have the same name as the instruction. The group name is followed by . and the name of the fragment. The name head is pre-defined. The code in it will be placed at the beginning of a block, so that all fragments in the group can access it.

    Next we define the fragment that will pick up the value from the -register from the first operand:

    increment.fetch(Src) {
    +register from the first operand:

    increment.fetch(Src) {
         increment_reg_val = $Src;
    -}

    We call this fragment fetch. This fragment will be duplicated three -times, one for each value of the first operand (r, x, and y).

    Next we define the main part of the code that do the actual incrementing.

    increment.execute(IncrementVal, Live, Dst) {
    +}

    We call this fragment fetch. This fragment will be duplicated three +times, one for each value of the first operand (r, x, and y).

    Next we define the main part of the code that do the actual incrementing.

    increment.execute(IncrementVal, Live, Dst) {
         Eterm increment_val = $IncrementVal;
         Uint live;
         Eterm result;
     
    -    if (ERTS_LIKELY(is_small(increment_reg_val))) {
    -        Sint i = signed_val(increment_reg_val) + increment_val;
    -        if (ERTS_LIKELY(IS_SSMALL(i))) {
    -            $Dst = make_small(i);
    -            $NEXT0();
    -        }
    -    }
    +    if (ERTS_LIKELY(is_small(increment_reg_val))) {
    +        Sint i = signed_val(increment_reg_val) + increment_val;
    +        if (ERTS_LIKELY(IS_SSMALL(i))) {
    +            $Dst = make_small(i);
    +            $NEXT0();
    +        }
    +    }
         live = $Live;
         HEAVY_SWAPOUT;
    -    reg[live] = increment_reg_val;
    -    reg[live+1] = make_small(increment_val);
    -    result = erts_gc_mixed_plus(c_p, reg, live);
    +    reg[live] = increment_reg_val;
    +    reg[live+1] = make_small(increment_val);
    +    result = erts_gc_mixed_plus(c_p, reg, live);
         HEAVY_SWAPIN;
    -    ERTS_HOLE_CHECK(c_p);
    -    if (ERTS_LIKELY(is_value(result))) {
    -        $REFRESH_GEN_DEST();
    +    ERTS_HOLE_CHECK(c_p);
    +    if (ERTS_LIKELY(is_value(result))) {
    +        $REFRESH_GEN_DEST();
             $Dst = result;
    -        $NEXT0();
    -    }
    -    ASSERT(c_p->freason != BADMATCH || is_value(c_p->fvalue));
    +        $NEXT0();
    +    }
    +    ASSERT(c_p->freason != BADMATCH || is_value(c_p->fvalue));
         goto find_func_info;
    -}

    We call this fragment execute. It will handle the three remaining +}

    We call this fragment execute. It will handle the three remaining operands (W t d). There will only be one copy of this fragment.

    Now that we have defined the fragments, we need to inform beam_makeops how they should be connected:

    i_increment := increment.fetch.execute;

    To the left of the := is the name of the specific instruction that should be implemented by the fragments, in this case i_increment. @@ -1134,33 +1134,33 @@

    followed by a .. Then the name of the fragments in the group are listed in the order they should be executed. Note that the head fragment is not listed.

    The line ends in ; (to avoid messing up the indentation in Emacs).

    (Note that in practice the := line is usually placed before the -fragments.)

    The generated code looks like this:

    {
    +fragments.)

    The generated code looks like this:

    {
       Eterm increment_reg_val;
    -  OpCase(i_increment_rWtd):
    -  {
    -    increment_reg_val = r(0);
    -  }
    +  OpCase(i_increment_rWtd):
    +  {
    +    increment_reg_val = r(0);
    +  }
       goto increment__execute;
     
    -  OpCase(i_increment_xWtd):
    -  {
    -    increment_reg_val = xb(BeamExtraData(I[0]));
    -  }
    +  OpCase(i_increment_xWtd):
    +  {
    +    increment_reg_val = xb(BeamExtraData(I[0]));
    +  }
       goto increment__execute;
     
    -  OpCase(i_increment_yWtd):
    -  {
    -    increment_reg_val = yb(BeamExtraData(I[0]));
    -  }
    +  OpCase(i_increment_yWtd):
    +  {
    +    increment_reg_val = yb(BeamExtraData(I[0]));
    +  }
       goto increment__execute;
     
       increment__execute:
    -  {
    -    // Here follows the code from increment.execute()
    +  {
    +    // Here follows the code from increment.execute()
         .
         .
         .
    -}
    Some notes about combined instructions

    The operands that are different must be at +}

    Some notes about combined instructions

    The operands that are different must be at the beginning of the instruction. All operands in the last fragment must have the same operands in all variants of the specific instruction.

    As an example, the following specific instructions cannot be @@ -1171,21 +1171,21 @@

    i_times x y j? t d i_times s s j? t d

    We can then define:

    i_times := times.fetch.execute;
     
    -times.head {
    +times.head {
         Eterm op1, op2;
    -}
    +}
     
    -times.fetch(Src1, Src2) {
    +times.fetch(Src1, Src2) {
         op1 = $Src1;
         op2 = $Src2;
    -}
    +}
     
    -times.execute(Fail, Live, Dst) {
    +times.execute(Fail, Live, Dst) {
         // Multiply op1 and op2.
         .
         .
         .
    -}

    Several instructions can share a group. As an example, the following +}

    Several instructions can share a group. As an example, the following instructions have different names, but in the end they all create a binary. The last two operands are common for all of them:

    i_bs_init_fail       xy j? t? x
     i_bs_init_fail_heap s I j? t? x
    @@ -1195,46 +1195,46 @@ 

    i_bs_init_fail := bs_init . fail . verify . execute; i_bs_init := bs_init . . plain . execute; i_bs_init_heap := bs_init . heap . execute;

    Note that the first two instruction have three fragments, while the -other two only have two fragments. Here are the fragments:

    bs_init_bits.head() {
    +other two only have two fragments.  Here are the fragments:

    bs_init_bits.head() {
         Eterm num_bits_term;
         Uint num_bits;
         Uint alloc;
    -}
    +}
     
    -bs_init_bits.plain(NumBits) {
    +bs_init_bits.plain(NumBits) {
         num_bits = $NumBits;
         alloc = 0;
    -}
    +}
     
    -bs_init_bits.heap(NumBits, Alloc) {
    +bs_init_bits.heap(NumBits, Alloc) {
         num_bits = $NumBits;
         alloc = $Alloc;
    -}
    +}
     
    -bs_init_bits.fail(NumBitsTerm) {
    +bs_init_bits.fail(NumBitsTerm) {
         num_bits_term = $NumBitsTerm;
         alloc = 0;
    -}
    +}
     
    -bs_init_bits.fail_heap(NumBitsTerm, Alloc) {
    +bs_init_bits.fail_heap(NumBitsTerm, Alloc) {
         num_bits_term = $NumBitsTerm;
         alloc = $Alloc;
    -}
    +}
     
    -bs_init_bits.verify(Fail) {
    +bs_init_bits.verify(Fail) {
         // Verify the num_bits_term, fail using $FAIL
         // if there is a problem.
     .
     .
     .
    -}
    +}
     
    -bs_init_bits.execute(Live, Dst) {
    +bs_init_bits.execute(Live, Dst) {
        // Long complicated code to a create a binary.
        .
        .
        .
    -}

    The full definitions of those instructions can be found in bs_instrs.tab. +}

    The full definitions of those instructions can be found in bs_instrs.tab. The generated code can be found in beam_warm.h.

    @@ -1244,39 +1244,39 @@

    For the BeamAsm runtime system, the implementation of each instruction is defined by emitter functions written in C++ that emit the assembly code for each instruction. There is one emitter function for each family of specific instructions.

    Take for example the move instruction. In beam/asm/ops.tab there is a -single specific instruction for move defined like this:

    move s d

    The implementation is found in beam/asm/instr_common.cpp:

    void BeamModuleAssembler::emit_move(const ArgVal &Src, const ArgVal &Dst) {
    -    mov_arg(Dst, Src);
    -}

    The mov_arg() helper function will handle all combinations of source and destination -operands. For example, the instruction {move,{x,1},{y,1}} will be translated like this:

    mov rdi, qword [rbx+8]
    -mov qword [rsp+8], rdi

    while {move,{integer,42},{x,0}} will be translated like this:

    mov qword [rbx], 687

    It is possible to define more than one specific instruction, but there will still be +single specific instruction for move defined like this:

    move s d

    The implementation is found in beam/asm/instr_common.cpp:

    void BeamModuleAssembler::emit_move(const ArgVal &Src, const ArgVal &Dst) {
    +    mov_arg(Dst, Src);
    +}

    The mov_arg() helper function will handle all combinations of source and destination +operands. For example, the instruction {move,{x,1},{y,1}} will be translated like this:

    mov rdi, qword [rbx+8]
    +mov qword [rsp+8], rdi

    while {move,{integer,42},{x,0}} will be translated like this:

    mov qword [rbx], 687

    It is possible to define more than one specific instruction, but there will still be only one emitter function. For example:

    fload S l
     fload q l

    By defining fload like this, the source operand must be a X register, Y register, or a literal. If not, the loading will be aborted. If the instruction instead had been defined like this:

    fload s l

    attempting to load an invalid instruction such as {fload,{atom,clearly_bad},{fr,0}} would cause a crash (either at load time or when the instruction was executed).

    Regardless on how many specific instructions there are in the family, -only a single emit_fload() function is allowed:

    void BeamModuleAssembler::emit_fload(const ArgVal &Src, const ArgVal &Dst) {
    +only a single emit_fload() function is allowed:

    void BeamModuleAssembler::emit_fload(const ArgVal &Src, const ArgVal &Dst) {
         .
         .
         .
    -}

    Handling a variable number of operands

    Here follows an example of how an instruction with a variable number +}

    Handling a variable number of operands

    Here follows an example of how an instruction with a variable number of operands could be handled. One such instructions is -select_val/3. Here is an example how it can look like in BEAM code:

    {select_val,{x,0},
    -            {f,1},
    -            {list,[{atom,b},{f,4},{atom,a},{f,5}]}}.

    The loader will convert a {list,[...]} operand to an u operand whose +select_val/3. Here is an example how it can look like in BEAM code:

    {select_val,{x,0},
    +            {f,1},
    +            {list,[{atom,b},{f,4},{atom,a},{f,5}]}}.

    The loader will convert a {list,[...]} operand to an u operand whose value is the number of elements in the list, followed by each element in the list. The instruction above would be translated to the following -instruction:

    {select_val,{x,0},{f,1},{u,4},{atom,b},{f,4},{atom,a},{f,5}}

    A definition of a specific instruction for that instruction would look +instruction:

    {select_val,{x,0},{f,1},{u,4},{atom,b},{f,4},{atom,a},{f,5}}

    A definition of a specific instruction for that instruction would look like this:

    select_val s f I *

    The * as the last operand will make sure that the variable operands are passed in as a Span of ArgVal (will be std::span in C++20 onwards). -Here is the emitter function:

    void BeamModuleAssembler::emit_select_val(const ArgVal &Src,
    +Here is the emitter function:

    void BeamModuleAssembler::emit_select_val(const ArgVal &Src,
                                               const ArgVal &Fail,
                                               const ArgVal &Size,
    -                                          const Span<ArgVal> &args) {
    -    ASSERT(Size.getValue() == args.size());
    +                                          const Span<ArgVal> &args) {
    +    ASSERT(Size.getValue() == args.size());
            .
            .
            .
    -}
    +
    }

    diff --git a/prs/8803/erts-15.0.1/doc/html/beamasm.html b/prs/8803/erts-15.0.1/doc/html/beamasm.html index 55e11aac60c9d..74ed784a01bb4 100644 --- a/prs/8803/erts-15.0.1/doc/html/beamasm.html +++ b/prs/8803/erts-15.0.1/doc/html/beamasm.html @@ -149,10 +149,10 @@

    used in BeamAsm are much simpler than the interpreter's, as most of the transformations for the interpreter are done only to eliminate the instruction dispatch overhead.

    Then each instruction is encoded using the C++ functions in the -jit/$ARCH/instr_*.cpp files. For example:

    void BeamModuleAssembler::emit_is_nonempty_list(const ArgVal &Fail, const ArgVal &Src) {
    -  a.test(getArgRef(Src), imm(_TAG_PRIMARY_MASK - TAG_PRIMARY_LIST));
    -  a.jne(labels[Fail.getLabel()]);
    -}

    asmjit provides a fairly straightforward +jit/$ARCH/instr_*.cpp files. For example:

    void BeamModuleAssembler::emit_is_nonempty_list(const ArgVal &Fail, const ArgVal &Src) {
    +  a.test(getArgRef(Src), imm(_TAG_PRIMARY_MASK - TAG_PRIMARY_LIST));
    +  a.jne(labels[Fail.getLabel()]);
    +}

    asmjit provides a fairly straightforward mapping from a C++ function call to the x86 assembly instruction. The above instruction tests if the value in the Src register is a non-empty list and if it is not then it jumps to the fail label.

    For comparison, the interpreter has 8 combinations and specializations of @@ -160,7 +160,7 @@

    common patterns.

    The original register allocation done by the Erlang compiler is used to manage the liveness of values and the physical registers are statically allocated to keep the necessary process state. At the moment this is the static register -allocation on x86-64:

    rbx: ErtsSchedulerRegisters struct (contains x/float registers and some metadata)
    +allocation on x86-64:

    rbx: ErtsSchedulerRegisters struct (contains x/float registers and some metadata)
     rbp: Current frame pointer when `perf` support is enabled, otherwise this
          is an optional save slot for the Erlang stack pointer when executing C
          code.
    @@ -187,13 +187,13 @@ 

    used about double the amount of memory for code as the interpreter, while current versions use about 10% more. How was this achieved?

    In BeamAsm we heavily use shared code fragments to try to emit as much code as possible as global shared fragments instead of duplicating the code unnecessarily. -For instance, the return instruction looks something like this:

    Label yield = a.newLabel();
    +For instance, the return instruction looks something like this:

    Label yield = a.newLabel();
     
     /* Decrement reduction counter */
    -a.dec(FCALLS);
    +a.dec(FCALLS);
     /* If FCALLS < 0, jump to the yield-on-return fragment */
    -a.jl(resolve_fragment(ga->get_dispatch_return()));
    -a.ret();

    The code above is not exactly what is emitted, but close enough. The thing to note +a.jl(resolve_fragment(ga->get_dispatch_return())); +a.ret();

    The code above is not exactly what is emitted, but close enough. The thing to note is that the code for doing the context switch is never emitted. Instead, we jump to a global fragment that all return instructions share. This greatly reduces the amount of code that has to be emitted for each module.

    @@ -243,24 +243,24 @@

    As Erlang stacks can be very small, we have to switch over to a different stack when we need to execute C code (which may expect a much larger stack). This is -done through emit_enter_runtime and emit_leave_runtime, for example:

    mov_arg(ARG4, NumFree);
    +done through emit_enter_runtime and emit_leave_runtime, for example:

    mov_arg(ARG4, NumFree);
     
     /* Move to the C stack and swap out our current reductions, stack-, and
      * heap pointer to the process structure. */
    -emit_enter_runtime<Update::eReductions | Update::eStack | Update::eHeap>();
    +emit_enter_runtime<Update::eReductions | Update::eStack | Update::eHeap>();
     
    -a.mov(ARG1, c_p);
    -load_x_reg_array(ARG2);
    -make_move_patch(ARG3, lambdas[Fun.getValue()].patches);
    +a.mov(ARG1, c_p);
    +load_x_reg_array(ARG2);
    +make_move_patch(ARG3, lambdas[Fun.getValue()].patches);
     
     /* Call `new_fun`, asserting that we're on the C stack. */
    -runtime_call<4>(new_fun);
    +runtime_call<4>(new_fun);
     
     /* Move back to the C stack, and read the updated values from the process
      * structure */
    -emit_leave_runtime<Update::eReductions | Update::eStack | Update::eHeap>();
    +emit_leave_runtime<Update::eReductions | Update::eStack | Update::eHeap>();
     
    -a.mov(getXRef(0), RET);

    All combinations of the Update constants are legal, but the ones given to +a.mov(getXRef(0), RET);

    All combinations of the Update constants are legal, but the ones given to emit_leave_runtime must be the same as those given to emit_enter_runtime.

    @@ -271,7 +271,7 @@

    any function call. In the interpreter, this is done by rewriting the loaded BEAM code, but this is more complicated in BeamAsm as we want to have a fast and compact way to do this. This is solved by emitting the code below at the -start of each function (x86 variant below):

      0x0: short jmp 6 (address 0x8)
    +start of each function (x86 variant below):

      0x0: short jmp 6 (address 0x8)
       0x2: nop
       0x3: relative near call to shared breakpoint fragment
       0x8: actual code for function

    When code starts to execute it will simply see the short jmp 6 instruction @@ -293,23 +293,23 @@

    executable page and once with a writable page. Since they're backed by the same memory, writes to the writable page appear magically in the executable one.

    The erts_writable_code_ptr function can be used to get writable pointers -given a module instance, provided that it has been unsealed first:

    for (i = 0; i < n; i++) {
    +given a module instance, provided that it has been unsealed first:

    for (i = 0; i < n; i++) {
         const ErtsCodeInfo* ci_exec;
         ErtsCodeInfo* ci_rw;
         void *w_ptr;
     
    -    erts_unseal_module(&modp->curr);
    +    erts_unseal_module(&modp->curr);
     
    -    ci_exec = code_hdr->functions[i];
    -    w_ptr = erts_writable_code_ptr(&modp->curr, ci_exec);
    -    ci_rw = (ErtsCodeInfo*)w_ptr;
    +    ci_exec = code_hdr->functions[i];
    +    w_ptr = erts_writable_code_ptr(&modp->curr, ci_exec);
    +    ci_rw = (ErtsCodeInfo*)w_ptr;
     
    -    uninstall_breakpoint(ci_rw, ci_exec);
    -    consolidate_bp_data(modp, ci_rw, 1);
    -    ASSERT(ci_rw->gen_bp == NULL);
    +    uninstall_breakpoint(ci_rw, ci_exec);
    +    consolidate_bp_data(modp, ci_rw, 1);
    +    ASSERT(ci_rw->gen_bp == NULL);
     
    -    erts_seal_module(&modp->curr);
    -}

    Without the module instance there's no reliable way to figure out the writable + erts_seal_module(&modp->curr); +}

    Without the module instance there's no reliable way to figure out the writable address of a code page, and we rely on address space layout randomization (ASLR) to make it difficult to guess. On some platforms, security is further enhanced by protecting the writable area from writes until the module has been @@ -397,7 +397,7 @@

    flamegraph.pl out.folded > out.svg

    We get a graph that would look something like this:

    Linux Perf FlameGraph: dialyzer PLT build

    You can view a larger version here. It contains the same information, but it is easier to share with others as it does not need the symbols in the executable.

    Using the same data we can also produce a graph where the scheduler profile data -has been merged by using sed:

    ## Strip [0-9]+_ and/or _[0-9]+ from all scheduler names
    +has been merged by using sed:

    ## Strip [0-9]+_ and/or _[0-9]+ from all scheduler names
     ## scheduler names changed in OTP26, hence two expressions
     sed -e 's/^[0-9]\+_//' -e 's/^erts_\([^_]\+\)_[0-9]\+/erts_\1/' out.folded > out.folded_sched
     ## Create the svg
    diff --git a/prs/8803/erts-15.0.1/doc/html/codeloading.html b/prs/8803/erts-15.0.1/doc/html/codeloading.html
    index 2c476b9d8eaa5..1f6a0d994f31d 100644
    --- a/prs/8803/erts-15.0.1/doc/html/codeloading.html
    +++ b/prs/8803/erts-15.0.1/doc/html/codeloading.html
    @@ -167,8 +167,8 @@ 

    erts_try_seize_code_load_permission and erts_release_code_load_permission).

    The ability to prepare several modules in parallel is not currently used as almost all code loading is serialized by the code_server -process. The BIF interface is however prepared for this.

      erlang:prepare_loading(Module, Code) -> LoaderState
    -  erlang:finish_loading([LoaderState])

    The idea is that prepare_loading could be called in parallel for +process. The BIF interface is however prepared for this.

      erlang:prepare_loading(Module, Code) -> LoaderState
    +  erlang:finish_loading([LoaderState])

    The idea is that prepare_loading could be called in parallel for different modules and returns a "magic binary" containing the internal state of each prepared module. Function finish_loading could take a list of such states and do the finishing of all of them in one go.

    Currently we use the legacy BIF erlang:load_module which is now diff --git a/prs/8803/erts-15.0.1/doc/html/crash_dump.html b/prs/8803/erts-15.0.1/doc/html/crash_dump.html index 17bdffa9ed9dd..2e6e645d78875 100644 --- a/prs/8803/erts-15.0.1/doc/html/crash_dump.html +++ b/prs/8803/erts-15.0.1/doc/html/crash_dump.html @@ -405,13 +405,13 @@

    interesting. One has to "guess" what is what, but as the information is symbolic, thorough reading of this information can be useful. As an example, we can find the state variable of the Erlang primitive loader online (5) and -(6) in the following example:

    (1)  3cac44   Return addr 0x13BF58 (<terminate process normally>)
    -(2)  y(0)     ["/view/siri_r10_dev/clearcase/otp/erts/lib/kernel/ebin",
    -(3)            "/view/siri_r10_dev/clearcase/otp/erts/lib/stdlib/ebin"]
    -(4)  y(1)     <0.1.0>
    -(5)  y(2)     {state,[],none,#Fun<erl_prim_loader.6.7085890>,undefined,#Fun<erl_prim_loader.7.9000327>,
    -(6)            #Fun<erl_prim_loader.8.116480692>,#Port<0.2>,infinity,#Fun<erl_prim_loader.9.10708760>}
    -(7)  y(3)     infinity

    When interpreting the data for a process, it is helpful to know that anonymous +(6) in the following example:

    (1)  3cac44   Return addr 0x13BF58 (<terminate process normally>)
    +(2)  y(0)     ["/view/siri_r10_dev/clearcase/otp/erts/lib/kernel/ebin",
    +(3)            "/view/siri_r10_dev/clearcase/otp/erts/lib/stdlib/ebin"]
    +(4)  y(1)     <0.1.0>
    +(5)  y(2)     {state,[],none,#Fun<erl_prim_loader.6.7085890>,undefined,#Fun<erl_prim_loader.7.9000327>,
    +(6)            #Fun<erl_prim_loader.8.116480692>,#Port<0.2>,infinity,#Fun<erl_prim_loader.9.10708760>}
    +(7)  y(3)     infinity

    When interpreting the data for a process, it is helpful to know that anonymous function objects (funs) are given the following:

    • A name constructed from the name of the function in which they are created
    • A number (starting with 0) indicating the number of that fun within that function

    diff --git a/prs/8803/erts-15.0.1/doc/html/driver.html b/prs/8803/erts-15.0.1/doc/html/driver.html index 4b6a49e36c5a5..ae4d9bcd6fabe 100644 --- a/prs/8803/erts-15.0.1/doc/html/driver.html +++ b/prs/8803/erts-15.0.1/doc/html/driver.html @@ -180,12 +180,12 @@

    terms, so binary_to_term is called in Erlang to convert the result to term form.

    The code is available in pg_sync.c in the sample directory of erts.

    The driver entry contains the functions that will be called by the emulator. In this example, only start, stop, and control are provided:

    /* Driver interface declarations */
    -static ErlDrvData start(ErlDrvPort port, char *command);
    -static void stop(ErlDrvData drv_data);
    -static int control(ErlDrvData drv_data, unsigned int command, char *buf,
    -                   int len, char **rbuf, int rlen);
    +static ErlDrvData start(ErlDrvPort port, char *command);
    +static void stop(ErlDrvData drv_data);
    +static int control(ErlDrvData drv_data, unsigned int command, char *buf,
    +                   int len, char **rbuf, int rlen);
     
    -static ErlDrvEntry pq_driver_entry = {
    +static ErlDrvEntry pq_driver_entry = {
         NULL,                        /* init */
         start,
         stop,
    @@ -202,10 +202,10 @@ 

    NULL, /* flush */ NULL, /* call */ NULL /* event */ -};

    We have a structure to store state needed by the driver, in this case we only -need to keep the database connection:

    typedef struct our_data_s {
    +};

    We have a structure to store state needed by the driver, in this case we only +need to keep the database connection:

    typedef struct our_data_s {
         PGconn* conn;
    -} our_data_t;

    The control codes that we have defined are as follows:

    /* Keep the following definitions in alignment with the
    +} our_data_t;

    The control codes that we have defined are as follows:

    /* Keep the following definitions in alignment with the
      * defines in erl_pq_sync.erl
      */
     
    @@ -221,130 +221,130 @@ 

    * the driver entry. */ -DRIVER_INIT(pq_drv) -{ +DRIVER_INIT(pq_drv) +{ return &pq_driver_entry; -}

    Here some initialization is done, start is called from open_port/2. The data +}

    Here some initialization is done, start is called from open_port/2. The data will be passed to control and stop.

    /* DRIVER INTERFACE */
    -static ErlDrvData start(ErlDrvPort port, char *command)
    -{
    +static ErlDrvData start(ErlDrvPort port, char *command)
    +{
         our_data_t* data;
     
    -    data = (our_data_t*)driver_alloc(sizeof(our_data_t));
    +    data = (our_data_t*)driver_alloc(sizeof(our_data_t));
         data->conn = NULL;
    -    set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
    -    return (ErlDrvData)data;
    -}

    We call disconnect to log out from the database. (This should have been done -from Erlang, but just in case.)

    static int do_disconnect(our_data_t* data, ei_x_buff* x);
    -
    -static void stop(ErlDrvData drv_data)
    -{
    -    our_data_t* data = (our_data_t*)drv_data;
    -
    -    do_disconnect(data, NULL);
    -    driver_free(data);
    -}

    We use the binary format only to return data to the emulator; input data is a + set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); + return (ErlDrvData)data; +}

    We call disconnect to log out from the database. (This should have been done +from Erlang, but just in case.)

    static int do_disconnect(our_data_t* data, ei_x_buff* x);
    +
    +static void stop(ErlDrvData drv_data)
    +{
    +    our_data_t* data = (our_data_t*)drv_data;
    +
    +    do_disconnect(data, NULL);
    +    driver_free(data);
    +}

    We use the binary format only to return data to the emulator; input data is a string parameter for connect and select. The returned data consists of Erlang terms.

    The functions get_s and ei_x_to_new_binary are utilities that are used to make the code shorter. get_s duplicates the string and zero-terminates it, as the postgres client library wants that. ei_x_to_new_binary takes an ei_x_buff buffer, allocates a binary, and copies the data there. This binary is returned in *rbuf. (Notice that this binary is freed by the emulator, not -by us.)

    static char* get_s(const char* buf, int len);
    -static int do_connect(const char *s, our_data_t* data, ei_x_buff* x);
    -static int do_select(const char* s, our_data_t* data, ei_x_buff* x);
    +by us.)

    static char* get_s(const char* buf, int len);
    +static int do_connect(const char *s, our_data_t* data, ei_x_buff* x);
    +static int do_select(const char* s, our_data_t* data, ei_x_buff* x);
     
     /* As we are operating in binary mode, the return value from control
      * is irrelevant, as long as it is not negative.
      */
    -static int control(ErlDrvData drv_data, unsigned int command, char *buf,
    -                   int len, char **rbuf, int rlen)
    -{
    +static int control(ErlDrvData drv_data, unsigned int command, char *buf,
    +                   int len, char **rbuf, int rlen)
    +{
         int r;
         ei_x_buff x;
    -    our_data_t* data = (our_data_t*)drv_data;
    -    char* s = get_s(buf, len);
    -    ei_x_new_with_version(&x);
    -    switch (command) {
    -        case DRV_CONNECT:    r = do_connect(s, data, &x);  break;
    -        case DRV_DISCONNECT: r = do_disconnect(data, &x);  break;
    -        case DRV_SELECT:     r = do_select(s, data, &x);   break;
    +    our_data_t* data = (our_data_t*)drv_data;
    +    char* s = get_s(buf, len);
    +    ei_x_new_with_version(&x);
    +    switch (command) {
    +        case DRV_CONNECT:    r = do_connect(s, data, &x);  break;
    +        case DRV_DISCONNECT: r = do_disconnect(data, &x);  break;
    +        case DRV_SELECT:     r = do_select(s, data, &x);   break;
             default:             r = -1;        break;
    -    }
    -    *rbuf = (char*)ei_x_to_new_binary(&x);
    -    ei_x_free(&x);
    -    driver_free(s);
    +    }
    +    *rbuf = (char*)ei_x_to_new_binary(&x);
    +    ei_x_free(&x);
    +    driver_free(s);
         return r;
    -}

    do_connect is where we log in to the database. If the connection was +}

    do_connect is where we log in to the database. If the connection was successful, we store the connection handle in the driver data, and return 'ok'. Otherwise, we return the error message from postgres and store NULL in -the driver data.

    static int do_connect(const char *s, our_data_t* data, ei_x_buff* x)
    -{
    -    PGconn* conn = PQconnectdb(s);
    -    if (PQstatus(conn) != CONNECTION_OK) {
    -        encode_error(x, conn);
    -        PQfinish(conn);
    +the driver data.

    static int do_connect(const char *s, our_data_t* data, ei_x_buff* x)
    +{
    +    PGconn* conn = PQconnectdb(s);
    +    if (PQstatus(conn) != CONNECTION_OK) {
    +        encode_error(x, conn);
    +        PQfinish(conn);
             conn = NULL;
    -    } else {
    -        encode_ok(x);
    -    }
    +    } else {
    +        encode_ok(x);
    +    }
         data->conn = conn;
         return 0;
    -}

    If we are connected (and if the connection handle is not NULL), we log out +}

    If we are connected (and if the connection handle is not NULL), we log out from the database. We need to check if we should encode an 'ok', as we can get -here from function stop, which does not return data to the emulator:

    static int do_disconnect(our_data_t* data, ei_x_buff* x)
    -{
    -    if (data->conn == NULL)
    +here from function stop, which does not return data to the emulator:

    static int do_disconnect(our_data_t* data, ei_x_buff* x)
    +{
    +    if (data->conn == NULL)
             return 0;
    -    PQfinish(data->conn);
    +    PQfinish(data->conn);
         data->conn = NULL;
    -    if (x != NULL)
    -        encode_ok(x);
    +    if (x != NULL)
    +        encode_ok(x);
         return 0;
    -}

    We execute a query and encode the result. Encoding is done in another C module, -pg_encode.c, which is also provided as sample code.

    static int do_select(const char* s, our_data_t* data, ei_x_buff* x)
    -{
    -   PGresult* res = PQexec(data->conn, s);
    -    encode_result(x, res, data->conn);
    -    PQclear(res);
    +}

    We execute a query and encode the result. Encoding is done in another C module, +pg_encode.c, which is also provided as sample code.

    static int do_select(const char* s, our_data_t* data, ei_x_buff* x)
    +{
    +   PGresult* res = PQexec(data->conn, s);
    +    encode_result(x, res, data->conn);
    +    PQclear(res);
         return 0;
    -}

    Here we check the result from postgres. If it is data, we encode it as lists of +}

    Here we check the result from postgres. If it is data, we encode it as lists of lists with column data. Everything from postgres is C strings, so we use ei_x_encode_string to send the result as strings to Erlang. (The head of the -list contains the column names.)

    void encode_result(ei_x_buff* x, PGresult* res, PGconn* conn)
    -{
    +list contains the column names.)

    void encode_result(ei_x_buff* x, PGresult* res, PGconn* conn)
    +{
         int row, n_rows, col, n_cols;
    -    switch (PQresultStatus(res)) {
    +    switch (PQresultStatus(res)) {
         case PGRES_TUPLES_OK:
    -        n_rows = PQntuples(res);
    -        n_cols = PQnfields(res);
    -        ei_x_encode_tuple_header(x, 2);
    -        encode_ok(x);
    -        ei_x_encode_list_header(x, n_rows+1);
    -        ei_x_encode_list_header(x, n_cols);
    -        for (col = 0; col < n_cols; ++col) {
    -            ei_x_encode_string(x, PQfname(res, col));
    -        }
    -        ei_x_encode_empty_list(x);
    -        for (row = 0; row < n_rows; ++row) {
    -            ei_x_encode_list_header(x, n_cols);
    -            for (col = 0; col < n_cols; ++col) {
    -                ei_x_encode_string(x, PQgetvalue(res, row, col));
    -            }
    -            ei_x_encode_empty_list(x);
    -        }
    -        ei_x_encode_empty_list(x);
    +        n_rows = PQntuples(res);
    +        n_cols = PQnfields(res);
    +        ei_x_encode_tuple_header(x, 2);
    +        encode_ok(x);
    +        ei_x_encode_list_header(x, n_rows+1);
    +        ei_x_encode_list_header(x, n_cols);
    +        for (col = 0; col < n_cols; ++col) {
    +            ei_x_encode_string(x, PQfname(res, col));
    +        }
    +        ei_x_encode_empty_list(x);
    +        for (row = 0; row < n_rows; ++row) {
    +            ei_x_encode_list_header(x, n_cols);
    +            for (col = 0; col < n_cols; ++col) {
    +                ei_x_encode_string(x, PQgetvalue(res, row, col));
    +            }
    +            ei_x_encode_empty_list(x);
    +        }
    +        ei_x_encode_empty_list(x);
             break;
         case PGRES_COMMAND_OK:
    -        ei_x_encode_tuple_header(x, 2);
    -        encode_ok(x);
    -        ei_x_encode_string(x, PQcmdTuples(res));
    +        ei_x_encode_tuple_header(x, 2);
    +        encode_ok(x);
    +        ei_x_encode_string(x, PQcmdTuples(res));
             break;
         default:
    -        encode_error(x, conn);
    +        encode_error(x, conn);
             break;
    -    }
    -}

    + } +}

    @@ -368,33 +368,33 @@

    the shared library and the name in the driver entry structure.

    When the port has been opened, the driver can be called. In the pg_sync example, we do not have any data from the port, only the return value from the port_control/3.

    The following code is the Erlang part of the synchronous postgres driver, -pg_sync.erl:

    -module(pg_sync).
    +pg_sync.erl:

    -module(pg_sync).
     
    --define(DRV_CONNECT, 1).
    --define(DRV_DISCONNECT, 2).
    --define(DRV_SELECT, 3).
    +-define(DRV_CONNECT, 1).
    +-define(DRV_DISCONNECT, 2).
    +-define(DRV_SELECT, 3).
     
    --export([connect/1, disconnect/1, select/2]).
    +-export([connect/1, disconnect/1, select/2]).
     
    -connect(ConnectStr) ->
    -    case erl_ddll:load_driver(".", "pg_sync") of
    +connect(ConnectStr) ->
    +    case erl_ddll:load_driver(".", "pg_sync") of
             ok -> ok;
    -        {error, already_loaded} -> ok;
    -        E -> exit({error, E})
    +        {error, already_loaded} -> ok;
    +        E -> exit({error, E})
         end,
    -    Port = open_port({spawn, ?MODULE}, []),
    -    case binary_to_term(port_control(Port, ?DRV_CONNECT, ConnectStr)) of
    -        ok -> {ok, Port};
    +    Port = open_port({spawn, ?MODULE}, []),
    +    case binary_to_term(port_control(Port, ?DRV_CONNECT, ConnectStr)) of
    +        ok -> {ok, Port};
             Error -> Error
         end.
     
    -disconnect(Port) ->
    -    R = binary_to_term(port_control(Port, ?DRV_DISCONNECT, "")),
    -    port_close(Port),
    +disconnect(Port) ->
    +    R = binary_to_term(port_control(Port, ?DRV_DISCONNECT, "")),
    +    port_close(Port),
         R.
     
    -select(Port, Query) ->
    -    binary_to_term(port_control(Port, ?DRV_SELECT, Query)).

    The API is simple:

    • connect/1 loads the driver, opens it, and logs on to the database, returning +select(Port, Query) -> + binary_to_term(port_control(Port, ?DRV_SELECT, Query)).

    The API is simple:

    • connect/1 loads the driver, opens it, and logs on to the database, returning the Erlang port if successful.
    • select/2 sends a query to the driver and returns the result.
    • disconnect/1 closes the database connection and the driver. (However, it does not unload it.)

    The connection string is to be a connection string for postgres.

    The driver is loaded with erl_ddll:load_driver/2. If this is successful, or if it is already loaded, it is opened. This will call the start function in the @@ -414,13 +414,13 @@

    on our postgres driver, we re-implement it using the asynchronous calls in LibPQ.

    The asynchronous version of the driver is in the sample files pg_async.c and pg_asyng.erl.

    /* Driver interface declarations */
    -static ErlDrvData start(ErlDrvPort port, char *command);
    -static void stop(ErlDrvData drv_data);
    -static int control(ErlDrvData drv_data, unsigned int command, char *buf,
    -                   int len, char **rbuf, int rlen);
    -static void ready_io(ErlDrvData drv_data, ErlDrvEvent event);
    +static ErlDrvData start(ErlDrvPort port, char *command);
    +static void stop(ErlDrvData drv_data);
    +static int control(ErlDrvData drv_data, unsigned int command, char *buf,
    +                   int len, char **rbuf, int rlen);
    +static void ready_io(ErlDrvData drv_data, ErlDrvEvent event);
     
    -static ErlDrvEntry pq_driver_entry = {
    +static ErlDrvEntry pq_driver_entry = {
         NULL,                     /* init */
         start,
         stop,
    @@ -437,14 +437,14 @@ 

    NULL, /* flush */ NULL, /* call */ NULL /* event */ -}; +}; -typedef struct our_data_t { +typedef struct our_data_t { PGconn* conn; ErlDrvPort port; int socket; int connecting; -} our_data_t;

    Some things have changed from pg_sync.c: we use the entry ready_io for +} our_data_t;

    Some things have changed from pg_sync.c: we use the entry ready_io for ready_input and ready_output, which is called from the emulator only when there is input to be read from the socket. (Actually, the socket is used in a select function inside the emulator, and when the socket is signaled, @@ -454,83 +454,83 @@

    data to the port with driver_output. We have a flag connecting to tell whether the driver is waiting for a connection or waiting for the result of a query. (This is needed, as the entry ready_io is called both when connecting -and when there is a query result.)

    static int do_connect(const char *s, our_data_t* data)
    -{
    -    PGconn* conn = PQconnectStart(s);
    -    if (PQstatus(conn) == CONNECTION_BAD) {
    +and when there is a query result.)

    static int do_connect(const char *s, our_data_t* data)
    +{
    +    PGconn* conn = PQconnectStart(s);
    +    if (PQstatus(conn) == CONNECTION_BAD) {
             ei_x_buff x;
    -        ei_x_new_with_version(&x);
    -        encode_error(&x, conn);
    -        PQfinish(conn);
    +        ei_x_new_with_version(&x);
    +        encode_error(&x, conn);
    +        PQfinish(conn);
             conn = NULL;
    -        driver_output(data->port, x.buff, x.index);
    -        ei_x_free(&x);
    -    }
    -    PQconnectPoll(conn);
    -    int socket = PQsocket(conn);
    +        driver_output(data->port, x.buff, x.index);
    +        ei_x_free(&x);
    +    }
    +    PQconnectPoll(conn);
    +    int socket = PQsocket(conn);
         data->socket = socket;
    -    driver_select(data->port, (ErlDrvEvent)socket, DO_READ, 1);
    -    driver_select(data->port, (ErlDrvEvent)socket, DO_WRITE, 1);
    +    driver_select(data->port, (ErlDrvEvent)socket, DO_READ, 1);
    +    driver_select(data->port, (ErlDrvEvent)socket, DO_WRITE, 1);
         data->conn = conn;
         data->connecting = 1;
         return 0;
    -}

    The connect function looks a bit different too. We connect using the +}

    The connect function looks a bit different too. We connect using the asynchronous PQconnectStart function. After the connection is started, we retrieve the socket for the connection with PQsocket. This socket is used with the driver_select function to wait for connection. When the socket is ready for input or for output, the ready_io function is called.

    Notice that we only return data (with driver_output) if there is an error here, otherwise we wait for the connection to be completed, in which case our -ready_io function is called.

    static int do_select(const char* s, our_data_t* data)
    -{
    +ready_io function is called.

    static int do_select(const char* s, our_data_t* data)
    +{
         data->connecting = 0;
         PGconn* conn = data->conn;
         /* if there's an error return it now */
    -    if (PQsendQuery(conn, s) == 0) {
    +    if (PQsendQuery(conn, s) == 0) {
             ei_x_buff x;
    -        ei_x_new_with_version(&x);
    -        encode_error(&x, conn);
    -        driver_output(data->port, x.buff, x.index);
    -        ei_x_free(&x);
    -    }
    +        ei_x_new_with_version(&x);
    +        encode_error(&x, conn);
    +        driver_output(data->port, x.buff, x.index);
    +        ei_x_free(&x);
    +    }
         /* else wait for ready_output to get results */
         return 0;
    -}

    The do_select function initiates a select, and returns if there is no -immediate error. The result is returned when ready_io is called.

    static void ready_io(ErlDrvData drv_data, ErlDrvEvent event)
    -{
    +}

    The do_select function initiates a select, and returns if there is no +immediate error. The result is returned when ready_io is called.

    static void ready_io(ErlDrvData drv_data, ErlDrvEvent event)
    +{
         PGresult* res = NULL;
    -    our_data_t* data = (our_data_t*)drv_data;
    +    our_data_t* data = (our_data_t*)drv_data;
         PGconn* conn = data->conn;
         ei_x_buff x;
    -    ei_x_new_with_version(&x);
    -    if (data->connecting) {
    +    ei_x_new_with_version(&x);
    +    if (data->connecting) {
             ConnStatusType status;
    -        PQconnectPoll(conn);
    -        status = PQstatus(conn);
    -        if (status == CONNECTION_OK)
    -            encode_ok(&x);
    -        else if (status == CONNECTION_BAD)
    -            encode_error(&x, conn);
    -    } else {
    -        PQconsumeInput(conn);
    -        if (PQisBusy(conn))
    +        PQconnectPoll(conn);
    +        status = PQstatus(conn);
    +        if (status == CONNECTION_OK)
    +            encode_ok(&x);
    +        else if (status == CONNECTION_BAD)
    +            encode_error(&x, conn);
    +    } else {
    +        PQconsumeInput(conn);
    +        if (PQisBusy(conn))
                 return;
    -        res = PQgetResult(conn);
    -        encode_result(&x, res, conn);
    -        PQclear(res);
    -        for (;;) {
    -            res = PQgetResult(conn);
    -            if (res == NULL)
    +        res = PQgetResult(conn);
    +        encode_result(&x, res, conn);
    +        PQclear(res);
    +        for (;;) {
    +            res = PQgetResult(conn);
    +            if (res == NULL)
                     break;
    -            PQclear(res);
    -        }
    -    }
    -    if (x.index > 1) {
    -        driver_output(data->port, x.buff, x.index);
    -        if (data->connecting)
    -            driver_select(data->port, (ErlDrvEvent)data->socket, DO_WRITE, 0);
    -    }
    -    ei_x_free(&x);
    -}

    The ready_io function is called when the socket we got from postgres is ready + PQclear(res); + } + } + if (x.index > 1) { + driver_output(data->port, x.buff, x.index); + if (data->connecting) + driver_select(data->port, (ErlDrvEvent)data->socket, DO_WRITE, 0); + } + ei_x_free(&x); +}

    The ready_io function is called when the socket we got from postgres is ready for input or output. Here we first check if we are connecting to the database. In that case, we check connection status and return OK if the connection is successful, or error if it is not. If the connection is not yet established, we @@ -540,43 +540,43 @@

    the result and return it. The encoding is done with the same functions as in the earlier example.

    Error handling is to be added here, for example, checking that the socket is still open, but this is only a simple example.

    The Erlang part of the asynchronous driver consists of the sample file -pg_async.erl.

    -module(pg_async).
    +pg_async.erl.

    -module(pg_async).
     
    --define(DRV_CONNECT, $C).
    --define(DRV_DISCONNECT, $D).
    --define(DRV_SELECT, $S).
    +-define(DRV_CONNECT, $C).
    +-define(DRV_DISCONNECT, $D).
    +-define(DRV_SELECT, $S).
     
    --export([connect/1, disconnect/1, select/2]).
    +-export([connect/1, disconnect/1, select/2]).
     
    -connect(ConnectStr) ->
    -    case erl_ddll:load_driver(".", "pg_async") of
    +connect(ConnectStr) ->
    +    case erl_ddll:load_driver(".", "pg_async") of
             ok -> ok;
    -        {error, already_loaded} -> ok;
    -        _ -> exit({error, could_not_load_driver})
    +        {error, already_loaded} -> ok;
    +        _ -> exit({error, could_not_load_driver})
         end,
    -    Port = open_port({spawn, ?MODULE}, [binary]),
    -    port_control(Port, ?DRV_CONNECT, ConnectStr),
    -    case return_port_data(Port) of
    +    Port = open_port({spawn, ?MODULE}, [binary]),
    +    port_control(Port, ?DRV_CONNECT, ConnectStr),
    +    case return_port_data(Port) of
             ok ->
    -            {ok, Port};
    +            {ok, Port};
             Error ->
                 Error
         end.
     
    -disconnect(Port) ->
    -    port_control(Port, ?DRV_DISCONNECT, ""),
    -    R = return_port_data(Port),
    -    port_close(Port),
    +disconnect(Port) ->
    +    port_control(Port, ?DRV_DISCONNECT, ""),
    +    R = return_port_data(Port),
    +    port_close(Port),
         R.
     
    -select(Port, Query) ->
    -    port_control(Port, ?DRV_SELECT, Query),
    -    return_port_data(Port).
    +select(Port, Query) ->
    +    port_control(Port, ?DRV_SELECT, Query),
    +    return_port_data(Port).
     
    -return_port_data(Port) ->
    +return_port_data(Port) ->
         receive
    -        {Port, {data, Data}} ->
    -            binary_to_term(Data)
    +        {Port, {data, Data}} ->
    +            binary_to_term(Data)
         end.

    The Erlang code is slightly different, as we do not return the result synchronously from port_control/3, instead we get it from driver_output as data in the message queue. The function return_port_data above receives data @@ -606,7 +606,7 @@

    callback ready_async is called from the main emulator thread, this is where we return the result to Erlang. (We cannot return the result from within the asynchronous function, as we cannot call the driver functions.)

    The following code is from the sample file next_perm.cc. The driver entry -looks like before, but also contains the callback ready_async.

    static ErlDrvEntry next_perm_driver_entry = {
    +looks like before, but also contains the callback ready_async.

    static ErlDrvEntry next_perm_driver_entry = {
         NULL,                        /* init */
         start,
         NULL,                        /* stop */
    @@ -623,109 +623,109 @@ 

    NULL, /* flush */ NULL, /* call */ NULL /* event */ -};

    The output function allocates the work area of the asynchronous function. As +};

    The output function allocates the work area of the asynchronous function. As we use C++, we use a struct, and stuff the data in it. We must copy the original data, it is not valid after we have returned from the output function, and the do_perm function is called later, and from another thread. We return no data here, instead it is sent later from the ready_async callback.

    The async_data is passed to the do_perm function. We do not use a async_free function (the last argument to driver_async), it is only used if -the task is cancelled programmatically.

    struct our_async_data {
    +the task is cancelled programmatically.

    struct our_async_data {
         bool prev;
         vector<int> data;
    -    our_async_data(ErlDrvPort p, int command, const char* buf, int len);
    -};
    -
    -our_async_data::our_async_data(ErlDrvPort p, int command,
    -                               const char* buf, int len)
    -    : prev(command == 2),
    -      data((int*)buf, (int*)buf + len / sizeof(int))
    -{
    -}
    -
    -static void do_perm(void* async_data);
    -
    -static void output(ErlDrvData drv_data, char *buf, int len)
    -{
    -    if (*buf < 1 || *buf > 2) return;
    -    ErlDrvPort port = reinterpret_cast<ErlDrvPort>(drv_data);
    -    void* async_data = new our_async_data(port, *buf, buf+1, len);
    -    driver_async(port, NULL, do_perm, async_data, do_free);
    -}

    In the do_perm we do the work, operating on the structure that was allocated -in output.

    static void do_perm(void* async_data)
    -{
    -    our_async_data* d = reinterpret_cast<our_async_data*>(async_data);
    -    if (d->prev)
    -        prev_permutation(d->data.begin(), d->data.end());
    +    our_async_data(ErlDrvPort p, int command, const char* buf, int len);
    +};
    +
    +our_async_data::our_async_data(ErlDrvPort p, int command,
    +                               const char* buf, int len)
    +    : prev(command == 2),
    +      data((int*)buf, (int*)buf + len / sizeof(int))
    +{
    +}
    +
    +static void do_perm(void* async_data);
    +
    +static void output(ErlDrvData drv_data, char *buf, int len)
    +{
    +    if (*buf < 1 || *buf > 2) return;
    +    ErlDrvPort port = reinterpret_cast<ErlDrvPort>(drv_data);
    +    void* async_data = new our_async_data(port, *buf, buf+1, len);
    +    driver_async(port, NULL, do_perm, async_data, do_free);
    +}

    In the do_perm we do the work, operating on the structure that was allocated +in output.

    static void do_perm(void* async_data)
    +{
    +    our_async_data* d = reinterpret_cast<our_async_data*>(async_data);
    +    if (d->prev)
    +        prev_permutation(d->data.begin(), d->data.end());
         else
    -        next_permutation(d->data.begin(), d->data.end());
    -}

    In the ready_async function the output is sent back to the emulator. We use + next_permutation(d->data.begin(), d->data.end()); +}

    In the ready_async function the output is sent back to the emulator. We use the driver term format instead of ei. This is the only way to send Erlang terms directly to a driver, without having the Erlang code to call binary_to_term/1. In the simple example this works well, -and we do not need to use ei to handle the binary term format.

    When the data is returned, we deallocate our data.

    static void ready_async(ErlDrvData drv_data, ErlDrvThreadData async_data)
    -{
    -    ErlDrvPort port = reinterpret_cast<ErlDrvPort>(drv_data);
    -    our_async_data* d = reinterpret_cast<our_async_data*>(async_data);
    -    int n = d->data.size(), result_n = n*2 + 3;
    -    ErlDrvTermData *result = new ErlDrvTermData[result_n], *rp = result;
    -    for (vector<int>::iterator i = d->data.begin();
    -         i != d->data.end(); ++i) {
    +and we do not need to use ei to handle the binary term format.

    When the data is returned, we deallocate our data.

    static void ready_async(ErlDrvData drv_data, ErlDrvThreadData async_data)
    +{
    +    ErlDrvPort port = reinterpret_cast<ErlDrvPort>(drv_data);
    +    our_async_data* d = reinterpret_cast<our_async_data*>(async_data);
    +    int n = d->data.size(), result_n = n*2 + 3;
    +    ErlDrvTermData *result = new ErlDrvTermData[result_n], *rp = result;
    +    for (vector<int>::iterator i = d->data.begin();
    +         i != d->data.end(); ++i) {
             *rp++ = ERL_DRV_INT;
             *rp++ = *i;
    -    }
    +    }
         *rp++ = ERL_DRV_NIL;
         *rp++ = ERL_DRV_LIST;
         *rp++ = n+1;
    -    driver_output_term(port, result, result_n);
    -    delete[] result;
    +    driver_output_term(port, result, result_n);
    +    delete[] result;
         delete d;
    -}

    This driver is called like the others from Erlang. However, as we use +}

    This driver is called like the others from Erlang. However, as we use driver_output_term, there is no need to call binary_to_term/1. The Erlang code -is in the sample file next_perm.erl.

    The input is changed into a list of integers and sent to the driver.

    -module(next_perm).
    +is in the sample file next_perm.erl.

    The input is changed into a list of integers and sent to the driver.

    -module(next_perm).
     
    --export([next_perm/1, prev_perm/1, load/0, all_perm/1]).
    +-export([next_perm/1, prev_perm/1, load/0, all_perm/1]).
     
    -load() ->
    -    case whereis(next_perm) of
    +load() ->
    +    case whereis(next_perm) of
             undefined ->
    -            case erl_ddll:load_driver(".", "next_perm") of
    +            case erl_ddll:load_driver(".", "next_perm") of
                     ok -> ok;
    -                {error, already_loaded} -> ok;
    -                E -> exit(E)
    +                {error, already_loaded} -> ok;
    +                E -> exit(E)
                 end,
    -            Port = open_port({spawn, "next_perm"}, []),
    -            register(next_perm, Port);
    +            Port = open_port({spawn, "next_perm"}, []),
    +            register(next_perm, Port);
             _ ->
                 ok
         end.
     
    -list_to_integer_binaries(L) ->
    -    [<<I:32/integer-native>> || I <- L].
    +list_to_integer_binaries(L) ->
    +    [<<I:32/integer-native>> || I <- L].
     
    -next_perm(L) ->
    -    next_perm(L, 1).
    +next_perm(L) ->
    +    next_perm(L, 1).
     
    -prev_perm(L) ->
    -    next_perm(L, 2).
    +prev_perm(L) ->
    +    next_perm(L, 2).
     
    -next_perm(L, Nxt) ->
    -    load(),
    -    B = list_to_integer_binaries(L),
    -    port_control(next_perm, Nxt, B),
    +next_perm(L, Nxt) ->
    +    load(),
    +    B = list_to_integer_binaries(L),
    +    port_control(next_perm, Nxt, B),
         receive
             Result ->
                 Result
         end.
     
    -all_perm(L) ->
    -    New = prev_perm(L),
    -    all_perm(New, L, [New]).
    +all_perm(L) ->
    +    New = prev_perm(L),
    +    all_perm(New, L, [New]).
     
    -all_perm(L, L, Acc) ->
    +all_perm(L, L, Acc) ->
         Acc;
    -all_perm(L, Orig, Acc) ->
    -    New = prev_perm(L),
    -    all_perm(New, Orig, [New | Acc]).
    +
    all_perm(L, Orig, Acc) -> + New = prev_perm(L), + all_perm(New, Orig, [New | Acc]).

    diff --git a/prs/8803/erts-15.0.1/doc/html/driver_entry.html b/prs/8803/erts-15.0.1/doc/html/driver_entry.html index 9f40040e1a59b..cff915cbc6f03 100644 --- a/prs/8803/erts-15.0.1/doc/html/driver_entry.html +++ b/prs/8803/erts-15.0.1/doc/html/driver_entry.html @@ -176,54 +176,54 @@

    Data Types

    -

    ErlDrvEntry

    typedef struct erl_drv_entry {
    -    int (*init)(void);          /* Called at system startup for statically
    +

    ErlDrvEntry

    typedef struct erl_drv_entry {
    +    int (*init)(void);          /* Called at system startup for statically
                                        linked drivers, and after loading for
                                        dynamically loaded drivers */
     #ifndef ERL_SYS_DRV
    -    ErlDrvData (*start)(ErlDrvPort port, char *command);
    +    ErlDrvData (*start)(ErlDrvPort port, char *command);
                                     /* Called when open_port/2 is invoked,
                                        return value -1 means failure */
     #else
    -    ErlDrvData (*start)(ErlDrvPort port, char *command, SysDriverOpts* opts);
    +    ErlDrvData (*start)(ErlDrvPort port, char *command, SysDriverOpts* opts);
                                     /* Special options, only for system driver */
     #endif
    -    void (*stop)(ErlDrvData drv_data);
    +    void (*stop)(ErlDrvData drv_data);
                                     /* Called when port is closed, and when the
                                        emulator is halted */
    -    void (*output)(ErlDrvData drv_data, char *buf, ErlDrvSizeT len);
    +    void (*output)(ErlDrvData drv_data, char *buf, ErlDrvSizeT len);
                                     /* Called when we have output from Erlang to
                                        the port */
    -    void (*ready_input)(ErlDrvData drv_data, ErlDrvEvent event);
    +    void (*ready_input)(ErlDrvData drv_data, ErlDrvEvent event);
                                     /* Called when we have input from one of
                                        the driver's handles */
    -    void (*ready_output)(ErlDrvData drv_data, ErlDrvEvent event);
    +    void (*ready_output)(ErlDrvData drv_data, ErlDrvEvent event);
                                     /* Called when output is possible to one of
                                        the driver's handles */
         char *driver_name;          /* Name supplied as command in
                                        erlang:open_port/2 */
    -    void (*finish)(void);       /* Called before unloading the driver -
    +    void (*finish)(void);       /* Called before unloading the driver -
                                        dynamic drivers only */
         void *handle;               /* Reserved, used by emulator internally */
    -    ErlDrvSSizeT (*control)(ErlDrvData drv_data, unsigned int command,
    +    ErlDrvSSizeT (*control)(ErlDrvData drv_data, unsigned int command,
                                 char *buf, ErlDrvSizeT len,
    -			    char **rbuf, ErlDrvSizeT rlen);
    +			    char **rbuf, ErlDrvSizeT rlen);
                                     /* "ioctl" for drivers - invoked by
                                        port_control/3 */
    -    void (*timeout)(ErlDrvData drv_data);
    +    void (*timeout)(ErlDrvData drv_data);
                                     /* Handling of time-out in driver */
    -    void (*outputv)(ErlDrvData drv_data, ErlIOVec *ev);
    +    void (*outputv)(ErlDrvData drv_data, ErlIOVec *ev);
                                     /* Called when we have output from Erlang
                                        to the port */
    -    void (*ready_async)(ErlDrvData drv_data, ErlDrvThreadData thread_data);
    -    void (*flush)(ErlDrvData drv_data);
    +    void (*ready_async)(ErlDrvData drv_data, ErlDrvThreadData thread_data);
    +    void (*flush)(ErlDrvData drv_data);
                                     /* Called when the port is about to be
                                        closed, and there is data in the
                                        driver queue that must be flushed
                                        before 'stop' can be called */
    -    ErlDrvSSizeT (*call)(ErlDrvData drv_data, unsigned int command,
    +    ErlDrvSSizeT (*call)(ErlDrvData drv_data, unsigned int command,
                              char *buf, ErlDrvSizeT len,
    -			 char **rbuf, ErlDrvSizeT rlen, unsigned int *flags);
    +			 char **rbuf, ErlDrvSizeT rlen, unsigned int *flags);
                                     /* Works mostly like 'control', a synchronous
                                        call into the driver */
         void* unused_event_callback;
    @@ -232,11 +232,11 @@ 

    int minor_version; /* ERL_DRV_EXTENDED_MINOR_VERSION */ int driver_flags; /* ERL_DRV_FLAGs */ void *handle2; /* Reserved, used by emulator internally */ - void (*process_exit)(ErlDrvData drv_data, ErlDrvMonitor *monitor); + void (*process_exit)(ErlDrvData drv_data, ErlDrvMonitor *monitor); /* Called when a process monitor fires */ - void (*stop_select)(ErlDrvEvent event, void* reserved); + void (*stop_select)(ErlDrvEvent event, void* reserved); /* Called to close an event object */ - } ErlDrvEntry;

    • int (*init)(void) - Called directly after the driver has been + } ErlDrvEntry;

    • int (*init)(void) - Called directly after the driver has been loaded by erl_ddll:load_driver/2 (actually when the driver is added to the driver list). The driver is to return 0, or, if the driver cannot initialize, -1.

    • ErlDrvData (*start)(ErlDrvPort port, char* command) - Called diff --git a/prs/8803/erts-15.0.1/doc/html/erl_cmd.html b/prs/8803/erts-15.0.1/doc/html/erl_cmd.html index dc45cf3dc3922..c38bfcedf5e90 100644 --- a/prs/8803/erts-15.0.1/doc/html/erl_cmd.html +++ b/prs/8803/erts-15.0.1/doc/html/erl_cmd.html @@ -154,18 +154,18 @@

      init process and can be retrieved by calling init:get_plain_arguments/0. Plain arguments can occur before the first flag, or after a -- flag. Also, the -extra flag causes everything that follows to become plain arguments.

    Examples:

    % erl +W w -sname arnie +R 9 -s my_init -extra +bertie
    -(arnie@host)1> init:get_argument(sname).
    -{ok,[["arnie"]]}
    -(arnie@host)2> init:get_plain_arguments().
    -["+bertie"]

    Here +W w and +R 9 are emulator flags. -s my_init is an init flag, +(arnie@host)1> init:get_argument(sname). +{ok,[["arnie"]]} +(arnie@host)2> init:get_plain_arguments(). +["+bertie"]

    Here +W w and +R 9 are emulator flags. -s my_init is an init flag, interpreted by init. -sname arnie is a user flag, stored by init. It is read by Kernel and causes the Erlang runtime system to become distributed. Finally, everything after -extra (that is, +bertie) is considered as plain arguments.

    % erl -myflag 1
    -1> init:get_argument(myflag).
    -{ok,[["1"]]}
    -2> init:get_plain_arguments().
    -[]

    Here the user flag -myflag 1 is passed to and stored by the init process. It +1> init:get_argument(myflag). +{ok,[["1"]]} +2> init:get_plain_arguments(). +[]

    Here the user flag -myflag 1 is passed to and stored by the init process. It is a user-defined flag, presumably used by some user-defined application.

    @@ -704,7 +704,7 @@

    also balances scheduler utilization between schedulers.

  • +sct CpuTopology - Sets a user-defined CPU topology. The user-defined CPU topology overrides any automatically detected CPU topology. The CPU topology is used when -binding schedulers to logical processors.

    <Id> = integer(); when 0 =< <Id> =< 65535
    +binding schedulers to logical processors.

    <Id> = integer(); when 0 =< <Id> =< 65535
     <IdRange> = <Id>-<Id>
     <IdOrIdRange> = <Id> | <IdRange>
     <IdList> = <IdOrIdRange>,<IdOrIdRange> | <IdOrIdRange>
    @@ -737,22 +737,22 @@ 

    NUMA node. If <ProcessorIds> is omitted, its default position is before <NodeIds>. That is, the default is processor external NUMA nodes.

    If a list of identifiers is used in an <IdDefs>:

    • <LogicalIds> must be a list of identifiers.
    • At least one other identifier type besides <LogicalIds> must also have a list of identifiers.
    • All lists of identifiers must produce the same number of identifiers.

    A simple example. A single quad core processor can be described as follows:

    % erl +sct L0-3c0-3
    -1> erlang:system_info(cpu_topology).
    -[{processor,[{core,{logical,0}},
    -             {core,{logical,1}},
    -             {core,{logical,2}},
    -             {core,{logical,3}}]}]

    A more complicated example with two quad core processors, each processor in +1> erlang:system_info(cpu_topology). +[{processor,[{core,{logical,0}}, + {core,{logical,1}}, + {core,{logical,2}}, + {core,{logical,3}}]}]

    A more complicated example with two quad core processors, each processor in its own NUMA node. The ordering of logical processors is a bit weird. This to give a better example of identifier lists:

    % erl +sct L0-1,3-2c0-3p0N0:L7,4,6-5c0-3p1N1
    -1> erlang:system_info(cpu_topology).
    -[{node,[{processor,[{core,{logical,0}},
    -                    {core,{logical,1}},
    -                    {core,{logical,3}},
    -                    {core,{logical,2}}]}]},
    - {node,[{processor,[{core,{logical,7}},
    -                    {core,{logical,4}},
    -                    {core,{logical,6}},
    -                    {core,{logical,5}}]}]}]

    As long as real identifiers are correct, it is OK to pass a CPU topology +1> erlang:system_info(cpu_topology). +[{node,[{processor,[{core,{logical,0}}, + {core,{logical,1}}, + {core,{logical,3}}, + {core,{logical,2}}]}]}, + {node,[{processor,[{core,{logical,7}}, + {core,{logical,4}}, + {core,{logical,6}}, + {core,{logical,5}}]}]}]

    As long as real identifiers are correct, it is OK to pass a CPU topology that is not a correct description of the CPU topology. When used with care this can be very useful. This to trick the emulator to bind its schedulers as you want. For example, if you want to run multiple Erlang runtime systems @@ -927,10 +927,10 @@

    user's home directory and then filename:basedir(user_config, "erlang").

    If an .erlang file is found, it is assumed to contain valid Erlang expressions. These expressions are evaluated as if they were input to the -shell.

    A typical .erlang file contains a set of search paths, for example:

    io:format("executing user profile in $HOME/.erlang\n",[]).
    -code:add_path("/home/calvin/test/ebin").
    -code:add_path("/home/hobbes/bigappl-1.2/ebin").
    -io:format(".erlang rc finished\n",[]).

  • user_default and shell_default - Functions in the shell that are not +shell.

    A typical .erlang file contains a set of search paths, for example:

    io:format("executing user profile in $HOME/.erlang\n",[]).
    +code:add_path("/home/calvin/test/ebin").
    +code:add_path("/home/hobbes/bigappl-1.2/ebin").
    +io:format(".erlang rc finished\n",[]).
  • user_default and shell_default - Functions in the shell that are not prefixed by a module name are assumed to be functional objects (funs), built-in functions (BIFs), or belong to the module user_default or shell_default.

    To include private shell commands, define them in a module user_default and diff --git a/prs/8803/erts-15.0.1/doc/html/erl_dist_protocol.html b/prs/8803/erts-15.0.1/doc/html/erl_dist_protocol.html index 7e1e6e842a26a..2f57403d140d3 100644 --- a/prs/8803/erts-15.0.1/doc/html/erl_dist_protocol.html +++ b/prs/8803/erts-15.0.1/doc/html/erl_dist_protocol.html @@ -256,7 +256,7 @@

    client ->> EPMD: NAMES_REQ EPMD -->> client: NAMES_RESP

  • 1
    110

    Table: NAMES_REQ (110)

    The response for a NAMES_REQ is as follows:

    4
    EPMDPortNoNodeInfo*

    Table: NAMES_RESP

    NodeInfo is a string written for each active node. When all NodeInfo has -been written the connection is closed by the EPMD.

    NodeInfo is, as expressed in Erlang:

    io:format("name ~ts at port ~p~n", [NodeName, Port]).

    +been written the connection is closed by the EPMD.

    NodeInfo is, as expressed in Erlang:

    io:format("name ~ts at port ~p~n", [NodeName, Port]).

    @@ -271,9 +271,9 @@

    client ->> EPMD: DUMP_REQ EPMD -->> client: DUMP_RESP

    1
    100

    Table: DUMP_REQ

    The response for a DUMP_REQ is as follows:

    4
    EPMDPortNoNodeInfo*

    Table: DUMP_RESP

    NodeInfo is a string written for each node kept in the EPMD. When all -NodeInfo has been written the connection is closed by the EPMD.

    NodeInfo is, as expressed in Erlang:

    io:format("active name     ~ts at port ~p, fd = ~p~n",
    -          [NodeName, Port, Fd]).

    or

    io:format("old/unused name ~ts at port ~p, fd = ~p ~n",
    -          [NodeName, Port, Fd]).

    +NodeInfo has been written the connection is closed by the EPMD.

    NodeInfo is, as expressed in Erlang:

    io:format("active name     ~ts at port ~p, fd = ~p~n",
    +          [NodeName, Port, Fd]).

    or

    io:format("old/unused name ~ts at port ~p, fd = ~p ~n",
    +          [NodeName, Port, Fd]).

    @@ -411,7 +411,7 @@

    Semigraphic View

    -
    A (initiator)                                      B (acceptor)
    +
    A (initiator)                                      B (acceptor)
     
     TCP connect ------------------------------------>
                                                        TCP accept
    @@ -421,36 +421,36 @@ 

    <---------------------------------------------- send_status recv_status -(if status was 'alive' +(if status was 'alive' send_status - - - - - - - - - - - - - - - - - -> - recv_status) + recv_status) - (ChB) ChB = gen_challenge() + (ChB) ChB = gen_challenge() <---------------------------------------------- send_challenge recv_challenge -(if old send_name +(if old send_name send_complement - - - - - - - - - - - - - - - -> - recv_complement) + recv_complement) -ChA = gen_challenge(), -OCA = out_cookie(B), -DiA = gen_digest(ChB, OCA) - (ChA, DiA) +ChA = gen_challenge(), +OCA = out_cookie(B), +DiA = gen_digest(ChB, OCA) + (ChA, DiA) send_challenge_reply ---------------------------> recv_challenge_reply - ICB = in_cookie(A), + ICB = in_cookie(A), check: - DiA == gen_digest (ChB, ICB)? + DiA == gen_digest (ChB, ICB)? - if OK: - OCB = out_cookie(A), - DiB = gen_digest (ChA, OCB) - (DiB) + OCB = out_cookie(A), + DiB = gen_digest (ChA, OCB) + (DiB) <----------------------------------------------- send_challenge_ack recv_challenge_ack DONE -ICA = in_cookie(B), - else: +ICA = in_cookie(B), - else: check: CLOSE -DiB == gen_digest(ChA, ICA)? +DiB == gen_digest(ChA, ICA)? - if OK: DONE - else: diff --git a/prs/8803/erts-15.0.1/doc/html/erl_driver.html b/prs/8803/erts-15.0.1/doc/html/erl_driver.html index 2fa467f492a42..e51c4634cf0d3 100644 --- a/prs/8803/erts-15.0.1/doc/html/erl_driver.html +++ b/prs/8803/erts-15.0.1/doc/html/erl_driver.html @@ -333,7 +333,7 @@

    • ErlDrvSizeT - An unsigned integer type to be used as size_t.

    • ErlDrvSSizeT - A signed integer type, the size of -ErlDrvSizeT.

    • ErlDrvSysInfo

      typedef struct ErlDrvSysInfo {
      +ErlDrvSizeT.

    • ErlDrvSysInfo

      typedef struct ErlDrvSysInfo {
          int driver_major_version;
          int driver_minor_version;
          char *erts_version;
      @@ -345,7 +345,7 @@ 

      int nif_major_version; int nif_minor_version; int dirty_scheduler_support; -} ErlDrvSysInfo;

      The ErlDrvSysInfo structure is used for storage of information about the +} ErlDrvSysInfo;

    The ErlDrvSysInfo structure is used for storage of information about the Erlang runtime system. driver_system_info writes the system information when passed a reference to a ErlDrvSysInfo structure. The fields @@ -401,12 +401,12 @@

    aligned for storage of an array of doubles (usually 8-byte aligned).

  • ErlDrvData - A handle to driver-specific data, passed to the driver callbacks. It is a pointer, and is most often type cast to a specific pointer in the driver.

  • SysIOVec - A system I/O vector, as used by writev on Unix and -WSASend on Win32. It is used in ErlIOVec.

  • ErlIOVec

    typedef struct ErlIOVec {
    +WSASend on Win32. It is used in ErlIOVec.

  • ErlIOVec

    typedef struct ErlIOVec {
       int vsize;
       ErlDrvSizeT size;
       SysIOVec* iov;
       ErlDrvBinary** binv;
    -} ErlIOVec;

    The I/O vector used by the emulator and drivers is a list of binaries, with a +} ErlIOVec;

  • The I/O vector used by the emulator and drivers is a list of binaries, with a SysIOVec pointing to the buffers of the binaries. It is used in driver_outputv and the outputv driver callback. Also, the driver queue is an ErlIOVec.

  • ErlDrvMonitor - When a driver creates a monitor for a process, a @@ -485,8 +485,8 @@

    add_driver_entry()

    -
    void add_driver_entry(ErlDrvEntry
    -        *de);

    Adds a driver entry to the list of drivers known by Erlang. The +

    void add_driver_entry(ErlDrvEntry
    +        *de);

    Adds a driver entry to the list of drivers known by Erlang. The init function of parameter de is called.

    Note

    To use this function for adding drivers residing in dynamically loaded code is dangerous. If the driver code for the added driver resides in the same dynamically loaded module (that is, .so file) as a normal dynamically loaded @@ -498,7 +498,7 @@

    driver_alloc()

    -
    void * driver_alloc(ErlDrvSizeT size);

    Allocates a memory block of the size specified in size, and returns it. This +

    void * driver_alloc(ErlDrvSizeT size);

    Allocates a memory block of the size specified in size, and returns it. This fails only on out of memory, in which case NULL is returned. (This is most often a wrapper for malloc).

    Memory allocated must be explicitly freed with a corresponding call to driver_free (unless otherwise stated).

    This function is thread-safe.

    @@ -507,7 +507,7 @@

    driver_alloc_binary()

    -
    ErlDrvBinary * driver_alloc_binary(ErlDrvSizeT size);

    Allocates a driver binary with a memory block of at least size bytes, and +

    ErlDrvBinary * driver_alloc_binary(ErlDrvSizeT size);

    Allocates a driver binary with a memory block of at least size bytes, and returns a pointer to it, or NULL on failure (out of memory). When a driver binary has been sent to the emulator, it must not be changed. Every allocated binary is to be freed by a corresponding call to @@ -521,9 +521,9 @@

    driver_async()

    -
    long driver_async(ErlDrvPort port, unsigned
    -        int* key, void (*async_invoke)(void*), void* async_data, void
    -        (*async_free)(void*));

    Performs an asynchronous call. The function async_invoke is invoked in a +

    long driver_async(ErlDrvPort port, unsigned
    +        int* key, void (*async_invoke)(void*), void* async_data, void
    +        (*async_free)(void*));

    Performs an asynchronous call. The function async_invoke is invoked in a thread separate from the emulator thread. This enables the driver to perform time-consuming, blocking operations without blocking the emulator.

    The async thread pool size can be set with command-line argument +A in erl(1). If an async @@ -555,7 +555,7 @@

    driver_async_port_key()

    -
    unsigned int driver_async_port_key(ErlDrvPort port);

    Calculates a key for later use in driver_async. +

    unsigned int driver_async_port_key(ErlDrvPort port);

    Calculates a key for later use in driver_async. The keys are evenly distributed so that a fair mapping between port IDs and async thread IDs is achieved.

    Note

    Before Erlang/OTP R16, the port ID could be used as a key with proper casting, but after the rewrite of the port subsystem, this is no longer the case. With @@ -566,7 +566,7 @@

    driver_binary_dec_refc()

    -
    long driver_binary_dec_refc(ErlDrvBinary *bin);

    Decrements the reference count on bin and returns the reference count reached +

    long driver_binary_dec_refc(ErlDrvBinary *bin);

    Decrements the reference count on bin and returns the reference count reached after the decrement.

    This function is thread-safe.

    Note

    The reference count of driver binary is normally to be decremented by calling driver_free_binary.

    driver_binary_dec_refc does not free the binary if the reference count reaches zero. Only use driver_binary_dec_refc when you are sure not to @@ -576,21 +576,21 @@

    driver_binary_get_refc()

    -
    long driver_binary_get_refc(ErlDrvBinary *bin);

    Returns the current reference count on bin.

    This function is thread-safe.

    +
    long driver_binary_get_refc(ErlDrvBinary *bin);

    Returns the current reference count on bin.

    This function is thread-safe.

    driver_binary_inc_refc()

    -
    long driver_binary_inc_refc(ErlDrvBinary *bin);

    Increments the reference count on bin and returns the reference count reached +

    long driver_binary_inc_refc(ErlDrvBinary *bin);

    Increments the reference count on bin and returns the reference count reached after the increment.

    This function is thread-safe.

    driver_caller()

    -
    ErlDrvTermData driver_caller(ErlDrvPort
    -        port);

    Returns the process ID of the process that made the current call to the driver. +

    ErlDrvTermData driver_caller(ErlDrvPort
    +        port);

    Returns the process ID of the process that made the current call to the driver. The process ID can be used with driver_send_term to send back data to the caller. driver_caller only returns valid data when currently executing in one @@ -603,14 +603,14 @@

    driver_cancel_timer()

    -
    int driver_cancel_timer(ErlDrvPort port);

    Cancels a timer set with driver_set_timer.

    The return value is 0.

    +
    int driver_cancel_timer(ErlDrvPort port);

    Cancels a timer set with driver_set_timer.

    The return value is 0.

    driver_compare_monitors()

    -
    int driver_compare_monitors(const ErlDrvMonitor
    -        *monitor1, const ErlDrvMonitor *monitor2);

    Compares two ErlDrvMonitors. Can also be used to imply some artificial order +

    int driver_compare_monitors(const ErlDrvMonitor
    +        *monitor1, const ErlDrvMonitor *monitor2);

    Compares two ErlDrvMonitors. Can also be used to imply some artificial order on monitors, for whatever reason.

    Returns 0 if monitor1 and monitor2 are equal, < 0 if monitor1 < monitor2, and > 0 if monitor1 > monitor2.

    @@ -618,16 +618,16 @@

    driver_connected()

    -
    ErlDrvTermData driver_connected(ErlDrvPort
    -        port);

    Returns the port owner process.

    Notice that this function is not thread-safe.

    +
    ErlDrvTermData driver_connected(ErlDrvPort
    +        port);

    Returns the port owner process.

    Notice that this function is not thread-safe.

    driver_create_port()

    -
    ErlDrvPort driver_create_port(ErlDrvPort port,
    +
    ErlDrvPort driver_create_port(ErlDrvPort port,
             ErlDrvTermData owner_pid, char* name,
    -        ErlDrvData drv_data);

    Creates a new port executing the same driver code as the port creating the new + ErlDrvData drv_data);

    Creates a new port executing the same driver code as the port creating the new port.

    • port - The port handle of the port (driver instance) creating the new port.

    • owner_pid - The process ID of the Erlang process to become owner of the new port. This process will be linked to the new port. You usually want to use @@ -648,15 +648,15 @@

      driver_demonitor_process()

      -
      int driver_demonitor_process(ErlDrvPort port,
      -        const ErlDrvMonitor *monitor);

      Cancels a monitor created earlier.

      Returns 0 if a monitor was removed and > 0 if the monitor no longer exists.

      +
      int driver_demonitor_process(ErlDrvPort port,
      +        const ErlDrvMonitor *monitor);

      Cancels a monitor created earlier.

      Returns 0 if a monitor was removed and > 0 if the monitor no longer exists.

      driver_deq()

      -
      ErlDrvSizeT driver_deq(ErlDrvPort port,
      -        ErlDrvSizeT size);

      Dequeues data by moving the head pointer forward in the driver queue by size +

      ErlDrvSizeT driver_deq(ErlDrvPort port,
      +        ErlDrvSizeT size);

      Dequeues data by moving the head pointer forward in the driver queue by size bytes. The data in the queue is deallocated.

      Returns the number of bytes remaining in the queue on success, otherwise -1.

      This function can be called from any thread if a port data lock associated with the port is locked by the calling thread during the call.

      @@ -665,8 +665,8 @@

      driver_enq()

      -
      int driver_enq(ErlDrvPort port, char* buf,
      -        ErlDrvSizeT len);

      Enqueues data in the driver queue. The data in buf is copied (len bytes) and +

      int driver_enq(ErlDrvPort port, char* buf,
      +        ErlDrvSizeT len);

      Enqueues data in the driver queue. The data in buf is copied (len bytes) and placed at the end of the driver queue. The driver queue is normally used in a FIFO way.

      The driver queue is available to queue output from the emulator to the driver (data from the driver to the emulator is queued by the emulator in normal Erlang @@ -681,8 +681,8 @@

      driver_enq_bin()

      -
      int driver_enq_bin(ErlDrvPort port,
      -        ErlDrvBinary *bin, ErlDrvSizeT offset, ErlDrvSizeT len);

      Enqueues a driver binary in the driver queue. The data in bin at offset with +

      int driver_enq_bin(ErlDrvPort port,
      +        ErlDrvBinary *bin, ErlDrvSizeT offset, ErlDrvSizeT len);

      Enqueues a driver binary in the driver queue. The data in bin at offset with length len is placed at the end of the queue. This function is most often faster than driver_enq, because no data must be copied.

      This function can be called from any thread if a @@ -693,8 +693,8 @@

      driver_enqv()

      -
      int driver_enqv(ErlDrvPort port, ErlIOVec *ev,
      -        ErlDrvSizeT skip);

      Enqueues the data in ev, skipping the first skip bytes of it, at the end of +

      int driver_enqv(ErlDrvPort port, ErlIOVec *ev,
      +        ErlDrvSizeT skip);

      Enqueues the data in ev, skipping the first skip bytes of it, at the end of the driver queue. It is faster than driver_enq, because no data must be copied.

      The return value is 0.

      This function can be called from any thread if a port data lock associated with the port is locked @@ -716,10 +716,10 @@

      driver_failure_posix()

      -
      int driver_failure(ErlDrvPort port, int
      -        error);
      int driver_failure_atom(ErlDrvPort port, char
      -        *string);
      int driver_failure_posix(ErlDrvPort port, int
      -        error);

      Signals to Erlang that the driver has encountered an error and is to be closed. +

      int driver_failure(ErlDrvPort port, int
      +        error);
      int driver_failure_atom(ErlDrvPort port, char
      +        *string);
      int driver_failure_posix(ErlDrvPort port, int
      +        error);

      Signals to Erlang that the driver has encountered an error and is to be closed. The port is closed and the tuple {'EXIT', error, Err} is sent to the port owner process, where error is an error atom (driver_failure_atom and driver_failure_posix) or an integer (driver_failure).

      The driver is to fail only when in severe error situations, when the driver @@ -731,8 +731,8 @@

      driver_failure_eof()

      -
      int driver_failure_eof(ErlDrvPort
      -        port);

      Signals to Erlang that the driver has encountered an EOF and is to be closed, +

      int driver_failure_eof(ErlDrvPort
      +        port);

      Signals to Erlang that the driver has encountered an EOF and is to be closed, unless the port was opened with option eof, in which case eof is sent to the port. Otherwise the port is closed and an 'EXIT' message is sent to the port owner process.

      The return value is 0.

      @@ -741,7 +741,7 @@

      driver_free()

      -
      void driver_free(void *ptr);

      Frees the memory pointed to by ptr. The memory is to have been allocated with +

      void driver_free(void *ptr);

      Frees the memory pointed to by ptr. The memory is to have been allocated with driver_alloc. All allocated memory is to be deallocated, only once. There is no garbage collection in drivers.

      This function is thread-safe.

      @@ -749,7 +749,7 @@

      driver_free_binary()

      -
      void driver_free_binary(ErlDrvBinary *bin);

      Frees a driver binary bin, allocated previously with +

      void driver_free_binary(ErlDrvBinary *bin);

      Frees a driver binary bin, allocated previously with driver_alloc_binary. As binaries in Erlang are reference counted, the binary can still be around.

      This function is thread-safe.

      @@ -757,8 +757,8 @@

      driver_get_monitored_process()

      -
      ErlDrvTermData driver_get_monitored_process(ErlDrvPort port, const
      -        ErlDrvMonitor *monitor);

      Returns the process ID associated with a living monitor. It can be used in the +

      ErlDrvTermData driver_get_monitored_process(ErlDrvPort port, const
      +        ErlDrvMonitor *monitor);

      Returns the process ID associated with a living monitor. It can be used in the process_exit callback to get the process identification for the exiting process.

      Returns driver_term_nil if the monitor no longer exists.

      @@ -766,7 +766,7 @@

      driver_get_now()

      -
      int driver_get_now(ErlDrvNowData *now);

      Warning

      This function is deprecated. Do not use it. Use +

      int driver_get_now(ErlDrvNowData *now);

      Warning

      This function is deprecated. Do not use it. Use erl_drv_monotonic_time (perhaps in combination with erl_drv_time_offset) instead.

      Reads a time stamp into the memory pointed to by parameter now. For @@ -778,8 +778,8 @@

      driver_lock_driver()

      -
      int driver_lock_driver(ErlDrvPort
      -        port);

      Locks the driver used by the port port in memory for the rest of the emulator +

      int driver_lock_driver(ErlDrvPort
      +        port);

      Locks the driver used by the port port in memory for the rest of the emulator process' lifetime. After this call, the driver behaves as one of Erlang's statically linked-in drivers.

      @@ -787,8 +787,8 @@

      driver_mk_atom()

      -
      ErlDrvTermData driver_mk_atom(char*
      -        string);

      Returns an atom given a name string. The atom is created and does not change, +

      ErlDrvTermData driver_mk_atom(char*
      +        string);

      Returns an atom given a name string. The atom is created and does not change, so the return value can be saved and reused, which is faster than looking up the atom several times.

      Notice that this function is not thread-safe.

      @@ -796,8 +796,8 @@

      driver_mk_port()

      -
      ErlDrvTermData driver_mk_port(ErlDrvPort
      -        port);

      Converts a port handle to the Erlang term format, usable in +

      ErlDrvTermData driver_mk_port(ErlDrvPort
      +        port);

      Converts a port handle to the Erlang term format, usable in erl_drv_output_term and erl_drv_send_term.

      Notice that this function is not thread-safe.

      @@ -805,8 +805,8 @@

      driver_monitor_process()

      -
      int driver_monitor_process(ErlDrvPort port,
      -        ErlDrvTermData process, ErlDrvMonitor *monitor);

      Starts monitoring a process from a driver. When a process is monitored, a +

      int driver_monitor_process(ErlDrvPort port,
      +        ErlDrvTermData process, ErlDrvMonitor *monitor);

      Starts monitoring a process from a driver. When a process is monitored, a process exit results in a call to the provided process_exit callback in the ErlDrvEntry structure. The ErlDrvMonitor structure is @@ -819,8 +819,8 @@

      driver_output()

      -
      int driver_output(ErlDrvPort port, char *buf,
      -        ErlDrvSizeT len);

      Sends data from the driver up to the emulator. The data is received as terms or +

      int driver_output(ErlDrvPort port, char *buf,
      +        ErlDrvSizeT len);

      Sends data from the driver up to the emulator. The data is received as terms or binary data, depending on how the driver port was opened.

      The data is queued in the port owner process' message queue. Notice that this does not yield to the emulator (as the driver and the emulator run in the same thread).

      Parameter buf points to the data to send, and len is the number of bytes.

      The return value for all output functions is 0 for normal use. If the driver @@ -830,9 +830,9 @@

      driver_output_binary()

      -
      int driver_output_binary(ErlDrvPort port, char
      +
      int driver_output_binary(ErlDrvPort port, char
               *hbuf, ErlDrvSizeT hlen, ErlDrvBinary* bin, ErlDrvSizeT offset,
      -        ErlDrvSizeT len);

      Sends data to a port owner process from a driver binary. It has a header buffer + ErlDrvSizeT len);

      Sends data to a port owner process from a driver binary. It has a header buffer (hbuf and hlen) just like driver_output2. Parameter hbuf can be NULL.

      Parameter offset is an offset into the binary and len is the number of bytes to send.

      Driver binaries are created with @@ -846,8 +846,8 @@

      driver_output_term()

      -
      int driver_output_term(ErlDrvPort port,
      -        ErlDrvTermData* term, int n);

      Warning

      This function is deprecated. Use +

      int driver_output_term(ErlDrvPort port,
      +        ErlDrvTermData* term, int n);

      Warning

      This function is deprecated. Use erl_drv_output_terminstead.

      Parameters term and n work as in erl_drv_output_term.

      Notice that this function is not thread-safe.

      @@ -855,8 +855,8 @@

      driver_output2()

      -
      int driver_output2(ErlDrvPort port, char *hbuf,
      -        ErlDrvSizeT hlen, char *buf, ErlDrvSizeT len);

      First sends hbuf (length in hlen) data as a list, regardless of port +

      int driver_output2(ErlDrvPort port, char *hbuf,
      +        ErlDrvSizeT hlen, char *buf, ErlDrvSizeT len);

      First sends hbuf (length in hlen) data as a list, regardless of port settings. Then sends buf as a binary or list. For example, if hlen is 3, the port owner process receives [H1, H2, H3 | T].

      The point of sending data as a list header, is to facilitate matching on the data received.

      The return value is 0 for normal use.

      @@ -865,8 +865,8 @@

      driver_outputv()

      -
      int driver_outputv(ErlDrvPort port, char* hbuf,
      -        ErlDrvSizeT hlen, ErlIOVec *ev, ErlDrvSizeT skip);

      Sends data from an I/O vector, ev, to the port owner process. It has a header +

      int driver_outputv(ErlDrvPort port, char* hbuf,
      +        ErlDrvSizeT hlen, ErlIOVec *ev, ErlDrvSizeT skip);

      Sends data from an I/O vector, ev, to the port owner process. It has a header buffer (hbuf and hlen), just like driver_output2.

      Parameter skip is a number of bytes to skip of the ev vector from the head.

      You get vectors of ErlIOVec type from the driver queue (see below), and the outputv driver entry function. You can also make @@ -878,7 +878,7 @@

      driver_pdl_create()

      -
      ErlDrvPDL driver_pdl_create(ErlDrvPort port);

      Creates a port data lock associated with the port.

      Note

      Once a port data lock has been created, it must be locked during all +

      ErlDrvPDL driver_pdl_create(ErlDrvPort port);

      Creates a port data lock associated with the port.

      Note

      Once a port data lock has been created, it must be locked during all operations on the driver queue of the port.

      Returns a newly created port data lock on success, otherwise NULL. The function fails if port is invalid or if a port data lock already has been associated with the port.

      @@ -887,40 +887,40 @@

      driver_pdl_dec_refc()

      -
      long driver_pdl_dec_refc(ErlDrvPDL
      -        pdl);

      Decrements the reference count of the port data lock passed as argument (pdl).

      The current reference count after the decrement has been performed is returned.

      This function is thread-safe.

      +
      long driver_pdl_dec_refc(ErlDrvPDL
      +        pdl);

      Decrements the reference count of the port data lock passed as argument (pdl).

      The current reference count after the decrement has been performed is returned.

      This function is thread-safe.

      driver_pdl_get_refc()

      -
      long driver_pdl_get_refc(ErlDrvPDL pdl);

      Returns the current reference count of the port data lock passed as argument +

      long driver_pdl_get_refc(ErlDrvPDL pdl);

      Returns the current reference count of the port data lock passed as argument (pdl).

      This function is thread-safe.

      driver_pdl_inc_refc()

      -
      long driver_pdl_inc_refc(ErlDrvPDL pdl);

      Increments the reference count of the port data lock passed as argument (pdl).

      The current reference count after the increment has been performed is returned.

      This function is thread-safe.

      +
      long driver_pdl_inc_refc(ErlDrvPDL pdl);

      Increments the reference count of the port data lock passed as argument (pdl).

      The current reference count after the increment has been performed is returned.

      This function is thread-safe.

      driver_pdl_lock()

      -
      void driver_pdl_lock(ErlDrvPDL pdl);

      Locks the port data lock passed as argument (pdl).

      This function is thread-safe.

      +
      void driver_pdl_lock(ErlDrvPDL pdl);

      Locks the port data lock passed as argument (pdl).

      This function is thread-safe.

      driver_pdl_unlock()

      -
      void driver_pdl_unlock(ErlDrvPDL pdl);

      Unlocks the port data lock passed as argument (pdl).

      This function is thread-safe.

      +
      void driver_pdl_unlock(ErlDrvPDL pdl);

      Unlocks the port data lock passed as argument (pdl).

      This function is thread-safe.

      driver_peekq()

      -
      SysIOVec * driver_peekq(ErlDrvPort port, int
      -        *vlen);

      Retrieves the driver queue as a pointer to an array of SysIOVecs. It also +

      SysIOVec * driver_peekq(ErlDrvPort port, int
      +        *vlen);

      Retrieves the driver queue as a pointer to an array of SysIOVecs. It also returns the number of elements in vlen. This is one of two ways to get data out of the queue.

      Nothing is removed from the queue by this function, that must be done with driver_deq.

      The returned array is suitable to use with the Unix system call writev.

      This function can be called from any thread if a @@ -931,8 +931,8 @@

      driver_peekqv()

      -
      ErlDrvSizeT driver_peekqv(ErlDrvPort port,
      -        ErlIOVec *ev);

      Retrieves the driver queue into a supplied ErlIOVec ev. It also returns the +

      ErlDrvSizeT driver_peekqv(ErlDrvPort port,
      +        ErlIOVec *ev);

      Retrieves the driver queue into a supplied ErlIOVec ev. It also returns the queue size. This is one of two ways to get data out of the queue.

      If ev is NULL, all ones that is -1 type cast to ErlDrvSizeT are returned.

      Nothing is removed from the queue by this function, that must be done with driver_deq.

      This function can be called from any thread if a @@ -943,8 +943,8 @@

      driver_pushq()

      -
      int driver_pushq(ErlDrvPort port, char* buf,
      -        ErlDrvSizeT len);

      Puts data at the head of the driver queue. The data in buf is copied (len +

      int driver_pushq(ErlDrvPort port, char* buf,
      +        ErlDrvSizeT len);

      Puts data at the head of the driver queue. The data in buf is copied (len bytes) and placed at the beginning of the queue.

      The return value is 0.

      This function can be called from any thread if a port data lock associated with the port is locked by the calling thread during the call.

      @@ -953,8 +953,8 @@

      driver_pushq_bin()

      -
      int driver_pushq_bin(ErlDrvPort port,
      -        ErlDrvBinary *bin, ErlDrvSizeT offset, ErlDrvSizeT len);

      Puts data in the binary bin, at offset with length len at the head of the +

      int driver_pushq_bin(ErlDrvPort port,
      +        ErlDrvBinary *bin, ErlDrvSizeT offset, ErlDrvSizeT len);

      Puts data in the binary bin, at offset with length len at the head of the driver queue. It is most often faster than driver_pushq, because no data must be copied.

      This function can be called from any thread if a port data lock associated with the port is locked @@ -964,8 +964,8 @@

      driver_pushqv()

      -
      int driver_pushqv(ErlDrvPort port, ErlIOVec
      -        *ev, ErlDrvSizeT skip);

      Puts the data in ev, skipping the first skip bytes of it, at the head of the +

      int driver_pushqv(ErlDrvPort port, ErlIOVec
      +        *ev, ErlDrvSizeT skip);

      Puts the data in ev, skipping the first skip bytes of it, at the head of the driver queue. It is faster than driver_pushq, because no data must be copied.

      The return value is 0.

      This function can be called from any thread if a port data lock associated with the port is locked @@ -975,15 +975,15 @@

      driver_read_timer()

      -
      int driver_read_timer(ErlDrvPort port, unsigned
      -        long *time_left);

      Reads the current time of a timer, and places the result in time_left. This is +

      int driver_read_timer(ErlDrvPort port, unsigned
      +        long *time_left);

      Reads the current time of a timer, and places the result in time_left. This is the time in milliseconds, before the time-out occurs.

      The return value is 0.

      driver_realloc()

      -
      void * driver_realloc(void *ptr, ErlDrvSizeT size);

      Resizes a memory block, either in place, or by allocating a new block, copying +

      void * driver_realloc(void *ptr, ErlDrvSizeT size);

      Resizes a memory block, either in place, or by allocating a new block, copying the data, and freeing the old block. A pointer is returned to the reallocated memory. On failure (out of memory), NULL is returned. (This is most often a wrapper for realloc.)

      This function is thread-safe.

      @@ -992,15 +992,15 @@

      driver_realloc_binary()

      -
      ErlDrvBinary * driver_realloc_binary(ErlDrvBinary *bin, ErlDrvSizeT size);

      Resizes a driver binary, while keeping the data.

      Returns the resized driver binary on success. Returns NULL on failure (out of +

      ErlDrvBinary * driver_realloc_binary(ErlDrvBinary *bin, ErlDrvSizeT size);

      Resizes a driver binary, while keeping the data.

      Returns the resized driver binary on success. Returns NULL on failure (out of memory).

      This function is thread-safe.

      driver_select()

      -
      int driver_select(ErlDrvPort port, ErlDrvEvent
      -        event, int mode, int on);

      This function is used by drivers to provide the emulator with events to check +

      int driver_select(ErlDrvPort port, ErlDrvEvent
      +        event, int mode, int on);

      This function is used by drivers to provide the emulator with events to check for. This enables the emulator to call the driver when something has occurred asynchronously.

      Parameter event identifies an OS-specific event object. On Unix systems, the functions select/poll are used. The event object must be a socket or pipe @@ -1030,8 +1030,8 @@

      driver_send_term()

      -
      int driver_send_term(ErlDrvPort port,
      -        ErlDrvTermData receiver, ErlDrvTermData* term, int n);

      Warning

      This function is deprecated. Use +

      int driver_send_term(ErlDrvPort port,
      +        ErlDrvTermData receiver, ErlDrvTermData* term, int n);

      Warning

      This function is deprecated. Use erl_drv_send_term instead.

      Note

      The parameters of this function cannot be properly checked by the runtime system when executed by arbitrary threads. This can cause the function not to fail when it should.

      Parameters term and n work as in @@ -1041,8 +1041,8 @@

      driver_set_timer()

      -
      int driver_set_timer(ErlDrvPort port, unsigned
      -        long time);

      Sets a timer on the driver, which will count down and call the driver when it is +

      int driver_set_timer(ErlDrvPort port, unsigned
      +        long time);

      Sets a timer on the driver, which will count down and call the driver when it is timed out. Parameter time is the time in milliseconds before the timer expires.

      When the timer reaches 0 and expires, the driver entry function timeout is called.

      Notice that only one timer exists on each driver instance; setting a new timer @@ -1053,7 +1053,7 @@

      driver_sizeq()

      -
      ErlDrvSizeT driver_sizeq(ErlDrvPort port);

      Returns the number of bytes currently in the driver queue.

      This function can be called from any thread if a +

      ErlDrvSizeT driver_sizeq(ErlDrvPort port);

      Returns the number of bytes currently in the driver queue.

      This function can be called from any thread if a port data lock associated with the port is locked by the calling thread during the call.

      @@ -1061,8 +1061,8 @@

      driver_system_info()

      -
      void driver_system_info(ErlDrvSysInfo
      -        *sys_info_ptr, size_t size);

      Writes information about the Erlang runtime system into the +

      void driver_system_info(ErlDrvSysInfo
      +        *sys_info_ptr, size_t size);

      Writes information about the Erlang runtime system into the ErlDrvSysInfo structure referred to by the first argument. The second argument is to be the size of the ErlDrvSysInfo structure, that is, @@ -1073,8 +1073,8 @@

      driver_vec_to_buf()

      -
      ErlDrvSizeT driver_vec_to_buf(ErlIOVec *ev,
      -        char *buf, ErlDrvSizeT len);

      Collects several segments of data, referenced by ev, by copying them in order +

      ErlDrvSizeT driver_vec_to_buf(ErlIOVec *ev,
      +        char *buf, ErlDrvSizeT len);

      Collects several segments of data, referenced by ev, by copying them in order to the buffer buf, of the size len.

      If the data is to be sent from the driver to the port owner process, it is faster to use driver_outputv.

      The return value is the space left in the buffer, that is, if ev contains less than len bytes it is the difference, and if ev contains len bytes or more, @@ -1085,8 +1085,8 @@

      erl_drv_busy_msgq_limits()

      -
      void erl_drv_busy_msgq_limits(ErlDrvPort port,
      -        ErlDrvSizeT *low, ErlDrvSizeT *high);

      Sets and gets limits that will be used for controlling the busy state of the +

      void erl_drv_busy_msgq_limits(ErlDrvPort port,
      +        ErlDrvSizeT *low, ErlDrvSizeT *high);

      Sets and gets limits that will be used for controlling the busy state of the port message queue.

      The port message queue is set into a busy state when the amount of command data queued on the message queue reaches the high limit. The port message queue is set into a not busy state when the amount of command data queued on the message @@ -1118,16 +1118,16 @@

      erl_drv_cond_broadcast()

      -
      void erl_drv_cond_broadcast(ErlDrvCond
      -        *cnd);

      Broadcasts on a condition variable. That is, if other threads are waiting on the +

      void erl_drv_cond_broadcast(ErlDrvCond
      +        *cnd);

      Broadcasts on a condition variable. That is, if other threads are waiting on the condition variable being broadcast on, all of them are woken.

      cnd is a pointer to a condition variable to broadcast on.

      This function is thread-safe.

      erl_drv_cond_create()

      -
      ErlDrvCond * erl_drv_cond_create(char
      -        *name);

      Creates a condition variable and returns a pointer to it.

      name is a string identifying the created condition variable. It is used to +

      ErlDrvCond * erl_drv_cond_create(char
      +        *name);

      Creates a condition variable and returns a pointer to it.

      name is a string identifying the created condition variable. It is used to identify the condition variable in planned future debug functionality.

      Returns NULL on failure. The driver creating the condition variable is responsible for destroying it before the driver is unloaded.

      This function is thread-safe.

      @@ -1135,31 +1135,31 @@

      erl_drv_cond_destroy()

      -
      void erl_drv_cond_destroy(ErlDrvCond
      -        *cnd);

      Destroys a condition variable previously created by +

      void erl_drv_cond_destroy(ErlDrvCond
      +        *cnd);

      Destroys a condition variable previously created by erl_drv_cond_create.

      cnd is a pointer to a condition variable to destroy.

      This function is thread-safe.

      erl_drv_cond_name()

      -
      char * erl_drv_cond_name(ErlDrvCond
      -        *cnd);

      Returns a pointer to the name of the condition.

      cnd is a pointer to an initialized condition.

      Note

      This function is intended for debugging purposes only.

      Available since OTP R16B02

      +
      char * erl_drv_cond_name(ErlDrvCond
      +        *cnd);

      Returns a pointer to the name of the condition.

      cnd is a pointer to an initialized condition.

      Note

      This function is intended for debugging purposes only.

      Available since OTP R16B02

      erl_drv_cond_signal()

      -
      void erl_drv_cond_signal(ErlDrvCond
      -        *cnd);

      Signals on a condition variable. That is, if other threads are waiting on the +

      void erl_drv_cond_signal(ErlDrvCond
      +        *cnd);

      Signals on a condition variable. That is, if other threads are waiting on the condition variable being signaled, one of them is woken.

      cnd is a pointer to a condition variable to signal on.

      This function is thread-safe.

      erl_drv_cond_wait()

      -
      void erl_drv_cond_wait(ErlDrvCond *cnd,
      -        ErlDrvMutex *mtx);

      Waits on a condition variable. The calling thread is blocked until another +

      void erl_drv_cond_wait(ErlDrvCond *cnd,
      +        ErlDrvMutex *mtx);

      Waits on a condition variable. The calling thread is blocked until another thread wakes it by signaling or broadcasting on the condition variable. Before the calling thread is blocked, it unlocks the mutex passed as argument. When the calling thread is woken, it locks the same mutex before returning. That is, the @@ -1175,8 +1175,8 @@

      erl_drv_consume_timeslice()

      -
      int erl_drv_consume_timeslice(ErlDrvPort port,
      -        int percent);

      Gives the runtime system a hint about how much CPU time the current driver +

      int erl_drv_consume_timeslice(ErlDrvPort port,
      +        int percent);

      Gives the runtime system a hint about how much CPU time the current driver callback call has consumed since the last hint, or since the the start of the callback if no previous hint has been given.

      • port - Port handle of the executing port.

      • percent - Approximate consumed fraction of a full time-slice in percent.

      The time is specified as a fraction, in percent, of a full time-slice that a port is allowed to execute before it is to surrender the CPU to other runnable @@ -1199,8 +1199,8 @@

      erl_drv_convert_time_unit()

      -
      ErlDrvTime erl_drv_convert_time_unit(ErlDrvTime
      -        val, ErlDrvTimeUnit from, ErlDrvTimeUnit to);

      Converts the val value of time unit from to the corresponding value of time +

      ErlDrvTime erl_drv_convert_time_unit(ErlDrvTime
      +        val, ErlDrvTimeUnit from, ErlDrvTimeUnit to);

      Converts the val value of time unit from to the corresponding value of time unit to. The result is rounded using the floor function.

      • val - Value to convert time unit for.

      • from - Time unit of val.

      • to - Time unit of returned value.

      Returns ERL_DRV_TIME_ERROR if called with an invalid time unit argument.

      See also ErlDrvTime and ErlDrvTimeUnit.

      Available since OTP 18.3

      @@ -1208,8 +1208,8 @@

      erl_drv_equal_tids()

      -
      int erl_drv_equal_tids(ErlDrvTid tid1,
      -        ErlDrvTid tid2);

      Compares two thread identifiers, tid1 and tid2, for equality.

      Returns 0 it they are not equal, and a value not equal to 0 if they are +

      int erl_drv_equal_tids(ErlDrvTid tid1,
      +        ErlDrvTid tid2);

      Compares two thread identifiers, tid1 and tid2, for equality.

      Returns 0 it they are not equal, and a value not equal to 0 if they are equal.

      Note

      A thread identifier can be reused very quickly after a thread has terminated. Therefore, if a thread corresponding to one of the involved thread identifiers has terminated since the thread identifier was saved, the result of @@ -1219,8 +1219,8 @@

      erl_drv_getenv()

      -
      int erl_drv_getenv(const char *key, char
      -        *value, size_t *value_size);

      Retrieves the value of an environment variable.

      • key - A NULL-terminated string containing the name of the environment +

        int erl_drv_getenv(const char *key, char
        +        *value, size_t *value_size);

        Retrieves the value of an environment variable.

        • key - A NULL-terminated string containing the name of the environment variable.

        • value - A pointer to an output buffer.

        • value_size - A pointer to an integer. The integer is used both for passing input and output sizes (see below).

        When this function is called, *value_size is to contain the size of the value buffer.

        On success, 0 is returned, the value of the environment variable has been @@ -1238,8 +1238,8 @@

        erl_drv_init_ack()

        -
        void erl_drv_init_ack(ErlDrvPort port,
        -        ErlDrvData res);

        Acknowledges the start of the port.

        • port - The port handle of the port (driver instance) doing the +

          void erl_drv_init_ack(ErlDrvPort port,
          +        ErlDrvData res);

          Acknowledges the start of the port.

          • port - The port handle of the port (driver instance) doing the acknowledgment.

          • res - The result of the port initialization. Can be the same values as the return value of start, that is, any of the error codes or the ErlDrvData that is to be used for this port.

          When this function is called the initiating erlang:open_port call is returned @@ -1252,7 +1252,7 @@

          erl_drv_monotonic_time()

          -
          ErlDrvTime erl_drv_monotonic_time(ErlDrvTimeUnit time_unit);

          Returns Erlang monotonic time. +

          ErlDrvTime erl_drv_monotonic_time(ErlDrvTimeUnit time_unit);

          Returns Erlang monotonic time. Notice that negative values are not uncommon.

          time_unit is time unit of returned value.

          Returns ERL_DRV_TIME_ERROR if called with an invalid time unit argument, or if called from a thread that is not a scheduler thread.

          See also ErlDrvTime and ErlDrvTimeUnit.

          Available since OTP 18.3

          @@ -1261,8 +1261,8 @@

          erl_drv_mutex_create()

          -
          ErlDrvMutex * erl_drv_mutex_create(char
          -        *name);

          Creates a mutex and returns a pointer to it.

          name is a string identifying the created mutex. It is used to identify the +

          ErlDrvMutex * erl_drv_mutex_create(char
          +        *name);

          Creates a mutex and returns a pointer to it.

          name is a string identifying the created mutex. It is used to identify the mutex in debug functionality (see note).

          Returns NULL on failure. The driver creating the mutex is responsible for destroying it before the driver is unloaded.

          This function is thread-safe.

          Note

          One such debug functionality is the lock checker, which can detect locking order violations and thereby potential deadlock bugs. For the lock checker to @@ -1279,8 +1279,8 @@

          erl_drv_mutex_destroy()

          -
          void erl_drv_mutex_destroy(ErlDrvMutex
          -        *mtx);

          Destroys a mutex previously created by +

          void erl_drv_mutex_destroy(ErlDrvMutex
          +        *mtx);

          Destroys a mutex previously created by erl_drv_mutex_create. The mutex must be in an unlocked state before it is destroyed.

          mtx is a pointer to a mutex to destroy.

          This function is thread-safe.

          @@ -1288,8 +1288,8 @@

          erl_drv_mutex_lock()

          -
          void erl_drv_mutex_lock(ErlDrvMutex
          -        *mtx);

          Locks a mutex. The calling thread is blocked until the mutex has been locked. A +

          void erl_drv_mutex_lock(ErlDrvMutex
          +        *mtx);

          Locks a mutex. The calling thread is blocked until the mutex has been locked. A thread that has currently locked the mutex cannot lock the same mutex again.

          mtx is a pointer to a mutex to lock.

          Warning

          If you leave a mutex locked in an emulator thread when you let the thread out of your control, you will very likely deadlock the whole emulator.

          This function is thread-safe.

          @@ -1297,15 +1297,15 @@

          erl_drv_mutex_name()

          -
          char * erl_drv_mutex_name(ErlDrvMutex
          -        *mtx);

          Returns a pointer to the mutex name.

          mtx is a pointer to an initialized mutex.

          Note

          This function is intended for debugging purposes only.

          Available since OTP R16B02

          +
          char * erl_drv_mutex_name(ErlDrvMutex
          +        *mtx);

          Returns a pointer to the mutex name.

          mtx is a pointer to an initialized mutex.

          Note

          This function is intended for debugging purposes only.

          Available since OTP R16B02

          erl_drv_mutex_trylock()

          -
          int erl_drv_mutex_trylock(ErlDrvMutex
          -        *mtx);

          Tries to lock a mutex. A thread that has currently locked the mutex cannot try +

          int erl_drv_mutex_trylock(ErlDrvMutex
          +        *mtx);

          Tries to lock a mutex. A thread that has currently locked the mutex cannot try to lock the same mutex again.

          mtx is a pointer to a mutex to try to lock.

          Returns 0 on success, otherwise EBUSY.

          Warning

          If you leave a mutex locked in an emulator thread when you let the thread out of your control, you will very likely deadlock the whole emulator.

          This function is thread-safe.

          @@ -1313,15 +1313,15 @@

          erl_drv_mutex_unlock()

          -
          void erl_drv_mutex_unlock(ErlDrvMutex
          -        *mtx);

          Unlocks a mutex. The mutex currently must be locked by the calling thread.

          mtx is a pointer to a mutex to unlock.

          This function is thread-safe.

          +
          void erl_drv_mutex_unlock(ErlDrvMutex
          +        *mtx);

          Unlocks a mutex. The mutex currently must be locked by the calling thread.

          mtx is a pointer to a mutex to unlock.

          This function is thread-safe.

          erl_drv_output_term()

          -
          int erl_drv_output_term(ErlDrvTermData port,
          -        ErlDrvTermData* term, int n);

          Sends data in the special driver term format to the port owner process. This is +

          int erl_drv_output_term(ErlDrvTermData port,
          +        ErlDrvTermData* term, int n);

          Sends data in the special driver term format to the port owner process. This is a fast way to deliver term data from a driver. It needs no binary conversion, so the port owner process receives data as normal Erlang terms. The erl_drv_send_term functions can be used for @@ -1379,20 +1379,20 @@

          concatenating the strings added to a list. The tail must be specified before ERL_DRV_STRING_CONS.

          ERL_DRV_STRING constructs a string, and ends it. (So it is the same as ERL_DRV_NIL followed by ERL_DRV_STRING_CONS.)

          /* to send [x, "abc", y] to the port: */
          -ErlDrvTermData spec[] = {
          -    ERL_DRV_ATOM, driver_mk_atom("x"),
          -    ERL_DRV_STRING, (ErlDrvTermData)"abc", 3,
          -    ERL_DRV_ATOM, driver_mk_atom("y"),
          +ErlDrvTermData spec[] = {
          +    ERL_DRV_ATOM, driver_mk_atom("x"),
          +    ERL_DRV_STRING, (ErlDrvTermData)"abc", 3,
          +    ERL_DRV_ATOM, driver_mk_atom("y"),
               ERL_DRV_NIL,
               ERL_DRV_LIST, 4
          -};
          -erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0]));
          /* to send "abc123" to the port: */
          -ErlDrvTermData spec[] = {
          +};
          +erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0]));
          /* to send "abc123" to the port: */
          +ErlDrvTermData spec[] = {
               ERL_DRV_NIL,        /* with STRING_CONS, the tail comes first */
          -    ERL_DRV_STRING_CONS, (ErlDrvTermData)"123", 3,
          -    ERL_DRV_STRING_CONS, (ErlDrvTermData)"abc", 3,
          -};
          -erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0]));

          The ERL_DRV_EXT2TERM term type is used for passing + ERL_DRV_STRING_CONS, (ErlDrvTermData)"123", 3, + ERL_DRV_STRING_CONS, (ErlDrvTermData)"abc", 3, +}; +erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0]));

  • The ERL_DRV_EXT2TERM term type is used for passing a term encoded with the external format, that is, a term that has been encoded by erlang:term_to_binary(), erl_interface:ei(3), and so on. For example, if @@ -1429,8 +1429,8 @@

    erl_drv_putenv()

    -
    int erl_drv_putenv(const char *key, char
    -        *value);

    Sets the value of an environment variable.

    key is a NULL-terminated string containing the name of the environment +

    int erl_drv_putenv(const char *key, char
    +        *value);

    Sets the value of an environment variable.

    key is a NULL-terminated string containing the name of the environment variable.

    value is a NULL-terminated string containing the new value of the environment variable.

    Returns 0 on success, otherwise a value != 0.

    Note

    The result of passing the empty string ("") as a value is platform-dependent. On some platforms the variable value is set to the empty @@ -1444,8 +1444,8 @@

    erl_drv_rwlock_create()

    -
    ErlDrvRWLock * erl_drv_rwlock_create(char
    -        *name);

    Creates an rwlock and returns a pointer to it.

    name is a string identifying the created rwlock. It is used to identify the +

    ErlDrvRWLock * erl_drv_rwlock_create(char
    +        *name);

    Creates an rwlock and returns a pointer to it.

    name is a string identifying the created rwlock. It is used to identify the rwlock in debug functionality (see note about the lock checker).

    Returns NULL on failure. The driver creating the rwlock is responsible for destroying it before the driver is unloaded.

    This function is thread-safe.

    @@ -1454,8 +1454,8 @@

    erl_drv_rwlock_destroy()

    -
    void erl_drv_rwlock_destroy(ErlDrvRWLock
    -        *rwlck);

    Destroys an rwlock previously created by +

    void erl_drv_rwlock_destroy(ErlDrvRWLock
    +        *rwlck);

    Destroys an rwlock previously created by erl_drv_rwlock_create. The rwlock must be in an unlocked state before it is destroyed.

    rwlck is a pointer to an rwlock to destroy.

    This function is thread-safe.

    @@ -1463,15 +1463,15 @@

    erl_drv_rwlock_name()

    -
    char * erl_drv_rwlock_name(ErlDrvRWLock
    -        *rwlck);

    Returns a pointer to the name of the rwlock.

    rwlck is a pointer to an initialized rwlock.

    Note

    This function is intended for debugging purposes only.

    Available since OTP R16B02

    +
    char * erl_drv_rwlock_name(ErlDrvRWLock
    +        *rwlck);

    Returns a pointer to the name of the rwlock.

    rwlck is a pointer to an initialized rwlock.

    Note

    This function is intended for debugging purposes only.

    Available since OTP R16B02

    erl_drv_rwlock_rlock()

    -
    void erl_drv_rwlock_rlock(ErlDrvRWLock
    -        *rwlck);

    Read locks an rwlock. The calling thread is blocked until the rwlock has been +

    void erl_drv_rwlock_rlock(ErlDrvRWLock
    +        *rwlck);

    Read locks an rwlock. The calling thread is blocked until the rwlock has been read locked. A thread that currently has read or read/write locked the rwlock cannot lock the same rwlock again.

    rwlck is a pointer to the rwlock to read lock.

    Warning

    If you leave an rwlock locked in an emulator thread when you let the thread out of your control, you will very likely deadlock the whole emulator.

    This function is thread-safe.

    @@ -1480,16 +1480,16 @@

    erl_drv_rwlock_runlock()

    -
    void erl_drv_rwlock_runlock(ErlDrvRWLock
    -        *rwlck);

    Read unlocks an rwlock. The rwlock currently must be read locked by the calling +

    void erl_drv_rwlock_runlock(ErlDrvRWLock
    +        *rwlck);

    Read unlocks an rwlock. The rwlock currently must be read locked by the calling thread.

    rwlck is a pointer to an rwlock to read unlock.

    This function is thread-safe.

    erl_drv_rwlock_rwlock()

    -
    void erl_drv_rwlock_rwlock(ErlDrvRWLock
    -        *rwlck);

    Read/write locks an rwlock. The calling thread is blocked until the rwlock has +

    void erl_drv_rwlock_rwlock(ErlDrvRWLock
    +        *rwlck);

    Read/write locks an rwlock. The calling thread is blocked until the rwlock has been read/write locked. A thread that currently has read or read/write locked the rwlock cannot lock the same rwlock again.

    rwlck is a pointer to an rwlock to read/write lock.

    Warning

    If you leave an rwlock locked in an emulator thread when you let the thread out of your control, you will very likely deadlock the whole emulator.

    This function is thread-safe.

    @@ -1498,16 +1498,16 @@

    erl_drv_rwlock_rwunlock()

    -
    void erl_drv_rwlock_rwunlock(ErlDrvRWLock
    -        *rwlck);

    Read/write unlocks an rwlock. The rwlock currently must be read/write locked by +

    void erl_drv_rwlock_rwunlock(ErlDrvRWLock
    +        *rwlck);

    Read/write unlocks an rwlock. The rwlock currently must be read/write locked by the calling thread.

    rwlck is a pointer to an rwlock to read/write unlock.

    This function is thread-safe.

    erl_drv_rwlock_tryrlock()

    -
    int erl_drv_rwlock_tryrlock(ErlDrvRWLock
    -        *rwlck);

    Tries to read lock an rwlock.

    rwlck is a pointer to an rwlock to try to read lock.

    Returns 0 on success, otherwise EBUSY. A thread that currently has read or +

    int erl_drv_rwlock_tryrlock(ErlDrvRWLock
    +        *rwlck);

    Tries to read lock an rwlock.

    rwlck is a pointer to an rwlock to try to read lock.

    Returns 0 on success, otherwise EBUSY. A thread that currently has read or read/write locked the rwlock cannot try to lock the same rwlock again.

    Warning

    If you leave an rwlock locked in an emulator thread when you let the thread out of your control, you will very likely deadlock the whole emulator.

    This function is thread-safe.

    @@ -1515,8 +1515,8 @@

    erl_drv_rwlock_tryrwlock()

    -
    int erl_drv_rwlock_tryrwlock(ErlDrvRWLock
    -        *rwlck);

    Tries to read/write lock an rwlock. A thread that currently has read or +

    int erl_drv_rwlock_tryrwlock(ErlDrvRWLock
    +        *rwlck);

    Tries to read/write lock an rwlock. A thread that currently has read or read/write locked the rwlock cannot try to lock the same rwlock again.

    rwlckis pointer to an rwlock to try to read/write lock.

    Returns 0 on success, otherwise EBUSY.

    Warning

    If you leave an rwlock locked in an emulator thread when you let the thread out of your control, you will very likely deadlock the whole emulator.

    This function is thread-safe.

    @@ -1524,8 +1524,8 @@

    erl_drv_send_term()

    -
    int erl_drv_send_term(ErlDrvTermData port,
    -        ErlDrvTermData receiver, ErlDrvTermData* term, int n);

    This function is the only way for a driver to send data to other processes +

    int erl_drv_send_term(ErlDrvTermData port,
    +        ErlDrvTermData receiver, ErlDrvTermData* term, int n);

    This function is the only way for a driver to send data to other processes than the port owner process. Parameter receiver specifies the process to receive the data.

    Note

    Parameter port is not an ordinary port handle, but a port handle converted using driver_mk_port.

    Parameters port, term, and n work as in @@ -1535,17 +1535,17 @@

    erl_drv_set_os_pid()

    -
    void erl_drv_set_os_pid(ErlDrvPort port,
    -        ErlDrvSInt pid);

    Sets the os_pid seen when doing erlang:port_info/2 on this port.

    port is the port handle of the port (driver instance) to set the pid on. +

    void erl_drv_set_os_pid(ErlDrvPort port,
    +        ErlDrvSInt pid);

    Sets the os_pid seen when doing erlang:port_info/2 on this port.

    port is the port handle of the port (driver instance) to set the pid on. pidis the pid to set.

    Available since OTP 19.0

    erl_drv_thread_create()

    -
    int erl_drv_thread_create(char *name, ErlDrvTid
    -        *tid, void * (*func)(void *), void *arg, ErlDrvThreadOpts
    -        *opts);

    Creates a new thread.

    • name - A string identifying the created thread. It is used to identify +

      int erl_drv_thread_create(char *name, ErlDrvTid
      +        *tid, void * (*func)(void *), void *arg, ErlDrvThreadOpts
      +        *opts);

      Creates a new thread.

      • name - A string identifying the created thread. It is used to identify the thread in planned future debug functionality.

      • tid - A pointer to a thread identifier variable.

      • func - A pointer to a function to execute in the created thread.

      • arg - A pointer to argument to the func function.

      • opts - A pointer to thread options to use or NULL.

      Returns 0 on success, otherwise an errno value is returned to indicate the error. The newly created thread begins executing in the function pointed to by func, and func is passed arg as argument. When erl_drv_thread_create @@ -1570,8 +1570,8 @@

      erl_drv_thread_exit()

      -
      void erl_drv_thread_exit(void
      -        *exit_value);

      Terminates the calling thread with the exit value passed as argument. +

      void erl_drv_thread_exit(void
      +        *exit_value);

      Terminates the calling thread with the exit value passed as argument. exit_value is a pointer to an exit value or NULL.

      You are only allowed to terminate threads created with erl_drv_thread_create.

      The exit value can later be retrieved by another thread through erl_drv_thread_join.

      This function is thread-safe.

      @@ -1580,8 +1580,8 @@

      erl_drv_thread_join()

      -
      int erl_drv_thread_join(ErlDrvTid tid, void
      -        **exit_value);

      Joins the calling thread with another thread, that is, the calling thread is +

      int erl_drv_thread_join(ErlDrvTid tid, void
      +        **exit_value);

      Joins the calling thread with another thread, that is, the calling thread is blocked until the thread identified by tid has terminated.

      tid is the thread identifier of the thread to join. exit_value is a pointer to a pointer to an exit value, or NULL.

      Returns 0 on success, otherwise an errno value is returned to indicate the error.

      A thread can only be joined once. The behavior of joining more than once is @@ -1593,14 +1593,14 @@

      erl_drv_thread_name()

      -
      char * erl_drv_thread_name(ErlDrvTid
      -        tid);

      Returns a pointer to the name of the thread.

      tid is a thread identifier.

      Note

      This function is intended for debugging purposes only.

      Available since OTP R16B02

      +
      char * erl_drv_thread_name(ErlDrvTid
      +        tid);

      Returns a pointer to the name of the thread.

      tid is a thread identifier.

      Note

      This function is intended for debugging purposes only.

      Available since OTP R16B02

      erl_drv_thread_opts_create()

      -
      ErlDrvThreadOpts * erl_drv_thread_opts_create(char *name);

      Allocates and initializes a thread option structure.

      name is a string identifying the created thread options. It is used to +

      ErlDrvThreadOpts * erl_drv_thread_opts_create(char *name);

      Allocates and initializes a thread option structure.

      name is a string identifying the created thread options. It is used to identify the thread options in planned future debug functionality.

      Returns NULL on failure. A thread option structure is used for passing options to erl_drv_thread_create. If the structure is not modified before it is passed to @@ -1613,21 +1613,21 @@

      erl_drv_thread_opts_destroy()

      -
      void erl_drv_thread_opts_destroy(ErlDrvThreadOpts *opts);

      Destroys thread options previously created by +

      void erl_drv_thread_opts_destroy(ErlDrvThreadOpts *opts);

      Destroys thread options previously created by erl_drv_thread_opts_create.

      opts is a pointer to thread options to destroy.

      This function is thread-safe.

      erl_drv_thread_self()

      -
      ErlDrvTid erl_drv_thread_self(void);

      Returns the thread identifier of the calling thread.

      This function is thread-safe.

      +
      ErlDrvTid erl_drv_thread_self(void);

      Returns the thread identifier of the calling thread.

      This function is thread-safe.

      erl_drv_time_offset()

      -
      ErlDrvTime erl_drv_time_offset(ErlDrvTimeUnit
      -        time_unit);

      Returns the current time offset between +

      ErlDrvTime erl_drv_time_offset(ErlDrvTimeUnit
      +        time_unit);

      Returns the current time offset between Erlang monotonic time and Erlang system time converted into the time_unit passed as argument.

      time_unit is time unit of returned value.

      Returns ERL_DRV_TIME_ERROR if called with an invalid time unit argument, or if @@ -1638,15 +1638,15 @@

      erl_drv_tsd_get()

      -
      void * erl_drv_tsd_get(ErlDrvTSDKey
      -        key);

      Returns the thread-specific data associated with key for the calling thread.

      key is a thread-specific data key.

      Returns NULL if no data has been associated with key for the calling thread.

      This function is thread-safe.

      +
      void * erl_drv_tsd_get(ErlDrvTSDKey
      +        key);

      Returns the thread-specific data associated with key for the calling thread.

      key is a thread-specific data key.

      Returns NULL if no data has been associated with key for the calling thread.

      This function is thread-safe.

      erl_drv_tsd_key_create()

      -
      int erl_drv_tsd_key_create(char *name,
      -        ErlDrvTSDKey *key);

      Creates a thread-specific data key.

      name is a string identifying the created key. It is used to identify the key +

      int erl_drv_tsd_key_create(char *name,
      +        ErlDrvTSDKey *key);

      Creates a thread-specific data key.

      name is a string identifying the created key. It is used to identify the key in planned future debug functionality.

      key is a pointer to a thread-specific data key variable.

      Returns 0 on success, otherwise an errno value is returned to indicate the error. The driver creating the key is responsible for destroying it before the driver is unloaded.

      This function is thread-safe.

      @@ -1655,8 +1655,8 @@

      erl_drv_tsd_key_destroy()

      -
      void erl_drv_tsd_key_destroy(ErlDrvTSDKey
      -        key);

      Destroys a thread-specific data key previously created by +

      void erl_drv_tsd_key_destroy(ErlDrvTSDKey
      +        key);

      Destroys a thread-specific data key previously created by erl_drv_tsd_key_create. All thread-specific data using this key in all threads must be cleared (see erl_drv_tsd_set) before the call to @@ -1669,8 +1669,8 @@

      erl_drv_tsd_set()

      -
      void erl_drv_tsd_set(ErlDrvTSDKey key, void
      -        *data);

      Sets thread-specific data associated with key for the calling thread. You are +

      void erl_drv_tsd_set(ErlDrvTSDKey key, void
      +        *data);

      Sets thread-specific data associated with key for the calling thread. You are only allowed to set thread-specific data for threads while they are fully under your control. For example, if you set thread-specific data in a thread calling a driver callback function, it must be cleared, that is, set to NULL, before @@ -1682,7 +1682,7 @@

      erl_errno_id()

      -
      char * erl_errno_id(int error);

      Returns the atom name of the Erlang error, given the error number in error. +

      char * erl_errno_id(int error);

      Returns the atom name of the Erlang error, given the error number in error. The error atoms are einval, enoent, and so on. It can be used to make error terms from the driver.

      @@ -1690,8 +1690,8 @@

      remove_driver_entry()

      -
      int remove_driver_entry(ErlDrvEntry
      -        *de);

      Removes a driver entry de previously added with +

      int remove_driver_entry(ErlDrvEntry
      +        *de);

      Removes a driver entry de previously added with add_driver_entry.

      Driver entries added by the erl_ddll Erlang interface cannot be removed by using this interface.

      @@ -1699,8 +1699,8 @@

      set_busy_port()

      -
      void set_busy_port(ErlDrvPort port, int
      -        on);

      Sets and unsets the busy state of the port. If on is non-zero, the port is set +

      void set_busy_port(ErlDrvPort port, int
      +        on);

      Sets and unsets the busy state of the port. If on is non-zero, the port is set to busy. If it is zero, the port is set to not busy. You typically want to combine this feature with the busy port message queue functionality.

      Processes sending command data to the port are suspended if either the port or @@ -1717,8 +1717,8 @@

      set_port_control_flags()

      -
      void set_port_control_flags(ErlDrvPort port,
      -        int flags);

      Sets flags for how the control driver entry +

      void set_port_control_flags(ErlDrvPort port,
      +        int flags);

      Sets flags for how the control driver entry function will return data to the port owner process. (The control function is called from erlang:port_control/3.)

      Currently there are only two meaningful values for flags: 0 means that data is returned in a list, and PORT_CONTROL_FLAG_BINARY means data is returned as diff --git a/prs/8803/erts-15.0.1/doc/html/erl_ext_dist.html b/prs/8803/erts-15.0.1/doc/html/erl_ext_dist.html index 7c77ba5549596..33d49c5cb6220 100644 --- a/prs/8803/erts-15.0.1/doc/html/erl_ext_dist.html +++ b/prs/8803/erts-15.0.1/doc/html/erl_ext_dist.html @@ -440,7 +440,7 @@

      positive and 1 if it is negative. The digits are stored with the least significant byte stored first. To calculate the integer, the following formula can be used:

      B = 256
      -(d0*B^0 + d1*B^1 + d2*B^2 + ... d(N-1)*B^(n-1))

      +(d0*B^0 + d1*B^1 + d2*B^2 + ... d(N-1)*B^(n-1))

    diff --git a/prs/8803/erts-15.0.1/doc/html/erl_nif.html b/prs/8803/erts-15.0.1/doc/html/erl_nif.html index 644f18def1629..67d8e5efae244 100644 --- a/prs/8803/erts-15.0.1/doc/html/erl_nif.html +++ b/prs/8803/erts-15.0.1/doc/html/erl_nif.html @@ -155,29 +155,29 @@

    A minimal example of a NIF library can look as follows:

    /* niftest.c */
     #include <erl_nif.h>
     
    -static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
    -{
    -    return enif_make_string(env, "Hello world!", ERL_NIF_LATIN1);
    -}
    +static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
    +{
    +    return enif_make_string(env, "Hello world!", ERL_NIF_LATIN1);
    +}
     
    -static ErlNifFunc nif_funcs[] =
    -{
    -    {"hello", 0, hello}
    -};
    +static ErlNifFunc nif_funcs[] =
    +{
    +    {"hello", 0, hello}
    +};
     
    -ERL_NIF_INIT(niftest,nif_funcs,NULL,NULL,NULL,NULL)

    The Erlang module can look as follows:

    -module(niftest).
    +ERL_NIF_INIT(niftest,nif_funcs,NULL,NULL,NULL,NULL)

    The Erlang module can look as follows:

    -module(niftest).
     
    --export([init/0, hello/0]).
    +-export([init/0, hello/0]).
     
    --nifs([hello/0]).
    +-nifs([hello/0]).
     
    --on_load(init/0).
    +-on_load(init/0).
     
    -init() ->
    -      erlang:load_nif("./niftest", 0).
    +init() ->
    +      erlang:load_nif("./niftest", 0).
     
    -hello() ->
    -      erlang:nif_error("NIF library not loaded").

    Compile and test can look as follows (on Linux):

    $> gcc -fPIC -shared -o niftest.so niftest.c -I $ERL_ROOT/usr/include/
    +hello() ->
    +      erlang:nif_error("NIF library not loaded").

    Compile and test can look as follows (on Linux):

    $> gcc -fPIC -shared -o niftest.so niftest.c -I $ERL_ROOT/usr/include/
     $> erl
     
     1> c(niftest).
    @@ -223,21 +223,21 @@ 

    ERL_NIF_TERM world_atom; -static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) -{ - world_atom = enif_make_atom(env, "world"); +static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) +{ + world_atom = enif_make_atom(env, "world"); return 0; -} +} -static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{ - ERL_NIF_TERM hello_string = enif_make_string(env, "Hello", ERL_NIF_LATIN1); - return enif_make_tuple2(env, hello_string, world_atom); -} +static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + ERL_NIF_TERM hello_string = enif_make_string(env, "Hello", ERL_NIF_LATIN1); + return enif_make_tuple2(env, hello_string, world_atom); +} -static ErlNifFunc nif_funcs[] = { { "hello", 0, hello } }; +static ErlNifFunc nif_funcs[] = { { "hello", 0, hello } }; -ERL_NIF_INIT(niftest, nif_funcs, load, NULL, NULL, NULL)

  • Binaries - Terms of type binary are accessed with the help of struct type +ERL_NIF_INIT(niftest, nif_funcs, load, NULL, NULL, NULL)

  • Binaries - Terms of type binary are accessed with the help of struct type ErlNifBinary, which contains a pointer (data) to the raw binary data and the length (size) of the data in bytes. Both data and size are read-only and are only to be written using calls to API @@ -275,19 +275,19 @@

    garbage collector or enif_release_resource). Resource types are uniquely identified by a supplied name string and the name of the implementing module.

    The following is a template example of how to create and return a resource object.

    ERL_NIF_TERM term;
    -MyStruct* obj = enif_alloc_resource(my_resource_type, sizeof(MyStruct));
    +MyStruct* obj = enif_alloc_resource(my_resource_type, sizeof(MyStruct));
     
     /* initialize struct ... */
     
    -term = enif_make_resource(env, obj);
    +term = enif_make_resource(env, obj);
     
    -if (keep_a_reference_of_our_own) {
    +if (keep_a_reference_of_our_own) {
         /* store 'obj' in static variable, private data or other resource object */
    -}
    -else {
    -    enif_release_resource(obj);
    +}
    +else {
    +    enif_release_resource(obj);
         /* resource now only owned by "Erlang" */
    -}
    +}
     return term;

    Notice that once enif_make_resource creates the term to return to Erlang, the code can choose to either keep its own native pointer to the allocated struct and release it later, or release it immediately and rely only on the @@ -339,50 +339,50 @@

    libraries can however fail if deprecated features are used.

  • Time Measurement - Support for time measurement in NIF libraries:

  • I/O Queues
    The Erlang nif library contains function for easily working with I/O vectors as used by the unix system call writev. The I/O Queue is not thread safe, so -some other synchronization mechanism has to be used.

    Typical usage when writing to a file descriptor looks like this:

    int writeiovec(ErlNifEnv *env, ERL_NIF_TERM term, ERL_NIF_TERM *tail,
    -               ErlNifIOQueue *q, int fd) {
    +some other synchronization mechanism has to be used.

    Typical usage when writing to a file descriptor looks like this:

    int writeiovec(ErlNifEnv *env, ERL_NIF_TERM term, ERL_NIF_TERM *tail,
    +               ErlNifIOQueue *q, int fd) {
     
         ErlNifIOVec vec, *iovec = &vec;
         SysIOVec *sysiovec;
         int saved_errno;
         int iovcnt, n;
     
    -    if (!enif_inspect_iovec(env, 64, term, tail, &iovec))
    +    if (!enif_inspect_iovec(env, 64, term, tail, &iovec))
             return -2;
     
    -    if (enif_ioq_size(q) > 0) {
    +    if (enif_ioq_size(q) > 0) {
             /* If the I/O queue contains data we enqueue the iovec and
                then peek the data to write out of the queue. */
    -        if (!enif_ioq_enqv(q, iovec, 0))
    +        if (!enif_ioq_enqv(q, iovec, 0))
                 return -3;
     
    -        sysiovec = enif_ioq_peek(q, &iovcnt);
    -    } else {
    +        sysiovec = enif_ioq_peek(q, &iovcnt);
    +    } else {
             /* If the I/O queue is empty we skip the trip through it. */
             iovcnt = iovec->iovcnt;
             sysiovec = iovec->iov;
    -    }
    +    }
     
         /* Attempt to write the data */
    -    n = writev(fd, sysiovec, iovcnt);
    +    n = writev(fd, sysiovec, iovcnt);
         saved_errno = errno;
     
    -    if (enif_ioq_size(q) == 0) {
    +    if (enif_ioq_size(q) == 0) {
             /* If the I/O queue was initially empty we enqueue any
                remaining data into the queue for writing later. */
    -        if (n >= 0 && !enif_ioq_enqv(q, iovec, n))
    +        if (n >= 0 && !enif_ioq_enqv(q, iovec, n))
                 return -3;
    -    } else {
    +    } else {
             /* Dequeue any data that was written from the queue. */
    -        if (n > 0 && !enif_ioq_deq(q, n, NULL))
    +        if (n > 0 && !enif_ioq_deq(q, n, NULL))
                 return -4;
    -    }
    +    }
     
         /* return n, which is either number of bytes written or -1 if
            some error happened */
         errno = saved_errno;
         return n;
    -}
  • Long-running NIFs
    As mentioned in the warning text at the beginning of +}

  • Long-running NIFs
    As mentioned in the warning text at the beginning of this manual page, it is of vital importance that a native function returns relatively fast. It is difficult to give an exact maximum amount of time that a native function is allowed to work, but usually a well-behaving native @@ -512,12 +512,12 @@

    with all its terms is valid until you explicitly invalidate it with enif_free_env or enif_send.

  • All contained terms of a list/tuple/map must belong to the same environment as the list/tuple/map itself. Terms can be copied between environments with -enif_make_copy.

  • ErlNifFunc

    typedef struct {
    +enif_make_copy.

  • ErlNifFunc

    typedef struct {
         const char* name;
         unsigned arity;
    -    ERL_NIF_TERM (*fptr)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
    +    ERL_NIF_TERM (*fptr)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
         unsigned flags;
    -} ErlNifFunc;

    Describes a NIF by its name, arity, and implementation.

    • fptr - A pointer to the function that implements the NIF.

    • argv - Contains the function arguments passed to the NIF.

    • argc - The array length, that is, the function arity. argv[N-1] thus +} ErlNifFunc;

  • Describes a NIF by its name, arity, and implementation.

    • fptr - A pointer to the function that implements the NIF.

    • argv - Contains the function arguments passed to the NIF.

    • argc - The array length, that is, the function arity. argv[N-1] thus denotes the Nth argument to the NIF. Notice that the argument argc allows for the same C function to implement several Erlang functions with different arity (but probably with the same name).

    • flags - Is 0 for a regular NIF (and so its value can be omitted for @@ -561,25 +561,25 @@

      type. It can be copied, moved in memory, forgotten, and so on.

    • ErlNifResourceType - Each instance of ErlNifResourceType represents a class of memory-managed resource objects that can be garbage collected. Each resource type has a unique name and a -destructor function that is called when objects of its type are released.

    • ErlNifResourceTypeInit

      typedef struct {
      +destructor function that is called when objects of its type are released.

    • ErlNifResourceTypeInit

      typedef struct {
           ErlNifResourceDtor* dtor;       // #1 Destructor
           ErlNifResourceStop* stop;       // #2 Select stop
           ErlNifResourceDown* down;       // #3 Monitor down
           int members;
           ErlNifResourceDynCall* dyncall; // #4 Dynamic call
      -} ErlNifResourceTypeInit;

      Initialization structure read by +} ErlNifResourceTypeInit;

    Initialization structure read by enif_open_resource_type_x enif_init_resource_type.

  • ErlNifResourceDtor

    typedef void ErlNifResourceDtor(ErlNifEnv* caller_env, void* obj);

    The function prototype of a resource destructor function.

    The obj argument is a pointer to the resource. The only allowed use for the resource in the destructor is to access its user data one final time. The destructor is guaranteed to be the last callback before the resource is -deallocated.

  • ErlNifResourceDown

    typedef void ErlNifResourceDown(ErlNifEnv* caller_env, void* obj, ErlNifPid* pid, ErlNifMonitor* mon);

    The function prototype of a resource down function, called on the behalf of +deallocated.

  • ErlNifResourceDown

    typedef void ErlNifResourceDown(ErlNifEnv* caller_env, void* obj, ErlNifPid* pid, ErlNifMonitor* mon);

    The function prototype of a resource down function, called on the behalf of enif_monitor_process. obj is the resource, pid is the identity of the monitored process that is exiting, and mon is the identity of the monitor.

  • ErlNifResourceStop

    typedef void ErlNifResourceStop(ErlNifEnv* caller_env, void* obj, ErlNifEvent event, int is_direct_call);

    The function prototype of a resource stop function, called on the behalf of enif_select. obj is the resource, event is OS event, is_direct_call is true if the call is made directly from enif_select or false if it is a scheduled call (potentially from another -thread).

  • ErlNifResourceDynCall

    typedef void ErlNifResourceDynCall(ErlNifEnv* caller_env, void* obj, void* call_data);

    The function prototype of a dynamic resource call function, called by +thread).

  • ErlNifResourceDynCall

    typedef void ErlNifResourceDynCall(ErlNifEnv* caller_env, void* obj, void* call_data);

    The function prototype of a dynamic resource call function, called by enif_dynamic_resource_call. Argument obj is the resource object and call_data is the last argument to enif_dynamic_resource_call passed through.

  • ErlNifCharEncoding

    typedef enum {
    @@ -602,11 +602,11 @@ 

    guarantees the same hash for the same term within one Erlang VM instance.

    It takes 32-bit salt values and generates hashes within 0..2^32-1.

  • ERL_NIF_PHASH2 - Portable hash function that gives the same hash for the same Erlang term regardless of machine architecture and ERTS version.

    It ignores salt values and generates hashes within 0..2^27-1.

    Slower than ERL_NIF_INTERNAL_HASH. It corresponds to erlang:phash2/1.

  • SysIOVec - A system I/O vector, as used by writev on Unix and WSASend on Win32. It is used in ErlNifIOVec and by -enif_ioq_peek.

  • ErlNifIOVec

    typedef struct {
    +enif_ioq_peek.

  • ErlNifIOVec

    typedef struct {
       int iovcnt;
       size_t size;
       SysIOVec* iov;
    -} ErlNifIOVec;

    An I/O vector containing iovcnt SysIOVecs pointing to the data. It is used +} ErlNifIOVec;

  • An I/O vector containing iovcnt SysIOVecs pointing to the data. It is used by enif_inspect_iovec and enif_ioq_enqv.

  • ErlNifIOQueueOpts - Options to configure a ErlNifIOQueue.

    • ERL_NIF_IOQ_NORMAL - Create a normal I/O Queue
  • @@ -615,14 +615,14 @@

    enif_alloc()

    -
    void * enif_alloc(size_t size);

    Allocates memory of size bytes.

    Returns NULL if the allocation fails.

    The returned pointer is suitably aligned for any built-in type that fit in the +

    void * enif_alloc(size_t size);

    Allocates memory of size bytes.

    Returns NULL if the allocation fails.

    The returned pointer is suitably aligned for any built-in type that fit in the allocated memory.

    enif_alloc_binary()

    -
    int enif_alloc_binary(size_t size, ErlNifBinary* bin);

    Allocates a new binary of size size bytes. Initializes the structure pointed +

    int enif_alloc_binary(size_t size, ErlNifBinary* bin);

    Allocates a new binary of size size bytes. Initializes the structure pointed to by bin to refer to the allocated binary. The binary must either be released by enif_release_binary or ownership transferred to an Erlang term with @@ -635,7 +635,7 @@

    enif_alloc_env()

    -
    ErlNifEnv * enif_alloc_env();

    Allocates a new process independent environment. +

    ErlNifEnv * enif_alloc_env();

    Allocates a new process independent environment. The environment can be used to hold terms that are not bound to any process. Such terms can later be copied to a process environment with enif_make_copy or be sent to a process as a @@ -645,18 +645,18 @@

    enif_alloc_resource()

    -
    void * enif_alloc_resource(ErlNifResourceType* type,
    -                           unsigned size);

    Allocates a memory-managed resource object of type type and size size bytes.

    Available since OTP R13B04

    +
    void * enif_alloc_resource(ErlNifResourceType* type,
    +                           unsigned size);

    Allocates a memory-managed resource object of type type and size size bytes.

    Available since OTP R13B04

    enif_binary_to_term()

    -
    size_t enif_binary_to_term(ErlNifEnv *env,
    +
    size_t enif_binary_to_term(ErlNifEnv *env,
                                const unsigned char* data,
     			   size_t size,
     			   ERL_NIF_TERM *term,
    -                           unsigned int opts);

    Creates a term that is the result of decoding the binary data at data, which + unsigned int opts);

    Creates a term that is the result of decoding the binary data at data, which must be encoded according to the Erlang external term format. No more than size bytes are read from data. Argument opts corresponds to the second argument to erlang:binary_to_term/2 and must be either 0 or @@ -669,14 +669,14 @@

    enif_clear_env()

    -
    void enif_clear_env(ErlNifEnv* env);

    Frees all terms in an environment and clears it for reuse. The environment must +

    void enif_clear_env(ErlNifEnv* env);

    Frees all terms in an environment and clears it for reuse. The environment must have been allocated with enif_alloc_env.

    Available since OTP R14B

    enif_compare()

    -
    int enif_compare(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs);

    Returns an integer < 0 if lhs < rhs, 0 if lhs = rhs, and > 0 if +

    int enif_compare(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs);

    Returns an integer < 0 if lhs < rhs, 0 if lhs = rhs, and > 0 if lhs > rhs. Corresponds to the Erlang operators ==, /=, =<, <, >=, and > (but not =:= or =/=).

    Available since OTP R13B04

    @@ -684,8 +684,8 @@

    enif_compare_monitors()

    -
    int enif_compare_monitors(const ErlNifMonitor
    -        *monitor1, const ErlNifMonitor *monitor2);

    Compares two ErlNifMonitors. Can also be used to +

    int enif_compare_monitors(const ErlNifMonitor
    +        *monitor1, const ErlNifMonitor *monitor2);

    Compares two ErlNifMonitors. Can also be used to imply some artificial order on monitors, for whatever reason.

    Returns 0 if monitor1 and monitor2 are equal, < 0 if monitor1 < monitor2, and > 0 if monitor1 > monitor2.

    Available since OTP 20.0

    @@ -693,50 +693,50 @@

    enif_compare_pids()

    -
    int enif_compare_pids(const ErlNifPid *pid1, const ErlNifPid *pid2);

    Compares two ErlNifPid s according to term order.

    Returns 0 if pid1 and pid2 are equal, < 0 if pid1 < pid2, and > 0 +

    int enif_compare_pids(const ErlNifPid *pid1, const ErlNifPid *pid2);

    Compares two ErlNifPid s according to term order.

    Returns 0 if pid1 and pid2 are equal, < 0 if pid1 < pid2, and > 0 if pid1 > pid2.

    Available since OTP 22.0

    enif_cond_broadcast()

    -
    void enif_cond_broadcast(ErlNifCond *cnd);

    Same as erl_drv_cond_broadcast.

    Available since OTP R13B04

    +
    void enif_cond_broadcast(ErlNifCond *cnd);

    Same as erl_drv_cond_broadcast.

    Available since OTP R13B04

    enif_cond_create()

    -
    ErlNifCond * enif_cond_create(char *name);

    Same as erl_drv_cond_create.

    Available since OTP R13B04

    +
    ErlNifCond * enif_cond_create(char *name);

    Same as erl_drv_cond_create.

    Available since OTP R13B04

    enif_cond_destroy()

    -
    void enif_cond_destroy(ErlNifCond *cnd);

    Same as erl_drv_cond_destroy.

    Available since OTP R13B04

    +
    void enif_cond_destroy(ErlNifCond *cnd);

    Same as erl_drv_cond_destroy.

    Available since OTP R13B04

    enif_cond_name()

    -
    char* enif_cond_name(ErlNifCond* cnd);

    Same as erl_drv_cond_name.

    Available since OTP 21.0

    +
    char* enif_cond_name(ErlNifCond* cnd);

    Same as erl_drv_cond_name.

    Available since OTP 21.0

    enif_cond_signal()

    -
    void enif_cond_signal(ErlNifCond *cnd);

    Same as erl_drv_cond_signal.

    Available since OTP R13B04

    +
    void enif_cond_signal(ErlNifCond *cnd);

    Same as erl_drv_cond_signal.

    Available since OTP R13B04

    enif_cond_wait()

    -
    void enif_cond_wait(ErlNifCond *cnd, ErlNifMutex *mtx);

    Same as erl_drv_cond_wait.

    Available since OTP R13B04

    +
    void enif_cond_wait(ErlNifCond *cnd, ErlNifMutex *mtx);

    Same as erl_drv_cond_wait.

    Available since OTP R13B04

    enif_consume_timeslice()

    -
    int enif_consume_timeslice(ErlNifEnv *env, int percent);

    Gives the runtime system a hint about how much CPU time the current NIF call has +

    int enif_consume_timeslice(ErlNifEnv *env, int percent);

    Gives the runtime system a hint about how much CPU time the current NIF call has consumed since the last hint, or since the start of the NIF if no previous hint has been specified. The time is specified as a percent of the timeslice that a process is allowed to execute Erlang code until it can be suspended to give time @@ -758,8 +758,8 @@

    enif_convert_time_unit()

    -
    ErlNifTime enif_convert_time_unit(ErlNifTime
    -        val, ErlNifTimeUnit from, ErlNifTimeUnit to);

    Converts the val value of time unit from to the corresponding value of time +

    ErlNifTime enif_convert_time_unit(ErlNifTime
    +        val, ErlNifTimeUnit from, ErlNifTimeUnit to);

    Converts the val value of time unit from to the corresponding value of time unit to. The result is rounded using the floor function.

    • val - Value to convert time unit for.

    • from - Time unit of val.

    • to - Time unit of returned value.

    Returns ERL_NIF_TIME_ERROR if called with an invalid time unit argument.

    See also ErlNifTime and ErlNifTimeUnit.

    Available since OTP 18.3

    @@ -767,7 +767,7 @@

    enif_cpu_time()

    -
    ERL_NIF_TERM enif_cpu_time(ErlNifEnv *);

    Returns the CPU time in the same format as +

    ERL_NIF_TERM enif_cpu_time(ErlNifEnv *);

    Returns the CPU time in the same format as erlang:timestamp(). The CPU time is the time the current logical CPU has spent executing since some arbitrary point in the past. If the OS does not support fetching this value, enif_cpu_time invokes @@ -777,8 +777,8 @@

    enif_demonitor_process()

    -
    int enif_demonitor_process(ErlNifEnv* caller_env,
    -      void* obj, const ErlNifMonitor* mon);

    Cancels a monitor created earlier with +

    int enif_demonitor_process(ErlNifEnv* caller_env,
    +      void* obj, const ErlNifMonitor* mon);

    Cancels a monitor created earlier with enif_monitor_process. Argument obj is a pointer to the resource holding the monitor and *mon identifies the monitor.

    Argument caller_env is the environment of the calling thread (process bound or @@ -790,9 +790,9 @@

    enif_dynamic_resource_call()

    -
    int enif_dynamic_resource_call(ErlNifEnv* caller_env,
    +
    int enif_dynamic_resource_call(ErlNifEnv* caller_env,
     	ERL_NIF_TERM rt_module, ERL_NIF_TERM rt_name, ERL_NIF_TERM resource,
    -	void* call_data);

    Call code of a resource type implemented by another NIF module. The atoms + void* call_data);

    Call code of a resource type implemented by another NIF module. The atoms rt_module and rt_name identifies the resource type to be called. Argument resource identifies a resource object of that type.

    The callback dyncall of the identified resource type will be called with a pointer to the resource objects obj and @@ -807,13 +807,13 @@

    enif_equal_tids()

    -
    int enif_equal_tids(ErlNifTid tid1, ErlNifTid tid2);

    Same as erl_drv_equal_tids.

    Available since OTP R13B04

    +
    int enif_equal_tids(ErlNifTid tid1, ErlNifTid tid2);

    Same as erl_drv_equal_tids.

    Available since OTP R13B04

    enif_fprintf()

    -
    int enif_fprintf(FILE *stream, const char *format, ...);

    Similar to fprintf but this format string also accepts "%T", which formats +

    int enif_fprintf(FILE *stream, const char *format, ...);

    Similar to fprintf but this format string also accepts "%T", which formats Erlang terms of type ERL_NIF_TERM.

    This function is primarily intended for debugging purpose. It is not recommended to print very large terms with %T. The function may change errno, even if successful.

    Available since OTP 21.0

    @@ -822,13 +822,13 @@

    enif_free()

    -
    void enif_free(void* ptr);

    Frees memory allocated by enif_alloc.

    +
    void enif_free(void* ptr);

    Frees memory allocated by enif_alloc.

    enif_free_env()

    -
    void enif_free_env(ErlNifEnv* env);

    Frees an environment allocated with +

    void enif_free_env(ErlNifEnv* env);

    Frees an environment allocated with enif_alloc_env. All terms created in the environment are freed as well.

    Available since OTP R14B

    @@ -836,26 +836,26 @@

    enif_free_iovec()

    -
    void enif_free_iovec(ErlNifIOVec* iov);

    Frees an io vector returned from +

    void enif_free_iovec(ErlNifIOVec* iov);

    Frees an io vector returned from enif_inspect_iovec. This is needed only if a NULL environment is passed to enif_inspect_iovec.

    ErlNifIOVec *iovec = NULL;
     size_t max_elements = 128;
     ERL_NIF_TERM tail;
    -if (!enif_inspect_iovec(NULL, max_elements, term, &tail, &iovec))
    +if (!enif_inspect_iovec(NULL, max_elements, term, &tail, &iovec))
       return 0;
     
     // Do things with the iovec
     
     /* Free the iovector, possibly in another thread or nif function call */
    -enif_free_iovec(iovec);

    Available since OTP 20.1

    +enif_free_iovec(iovec);

    Available since OTP 20.1

    enif_get_atom()

    -
    int enif_get_atom(ErlNifEnv *env, ERL_NIF_TERM
    -        term, char *buf, unsigned size, ErlNifCharEncoding encoding);

    Writes a NULL-terminated string in the buffer pointed to by buf of size +

    int enif_get_atom(ErlNifEnv *env, ERL_NIF_TERM
    +        term, char *buf, unsigned size, ErlNifCharEncoding encoding);

    Writes a NULL-terminated string in the buffer pointed to by buf of size size bytes, consisting of the string representation of the atom term with encoding.

    Returns the number of bytes written (including terminating NULL character) or 0 if term is not an atom with maximum length of size-1 bytes in @@ -865,8 +865,8 @@

    enif_get_atom_length()

    -
    int enif_get_atom_length(ErlNifEnv *env,
    -        ERL_NIF_TERM term, unsigned *len, ErlNifCharEncoding encoding);

    Sets *len to the length (number of bytes excluding terminating NULL +

    int enif_get_atom_length(ErlNifEnv *env,
    +        ERL_NIF_TERM term, unsigned *len, ErlNifCharEncoding encoding);

    Sets *len to the length (number of bytes excluding terminating NULL character) of the atom term with encoding.

    Returns true on success, or false if term is not an atom or if the atom cannot be encoded using encoding.

    Available since OTP R14B

    @@ -874,31 +874,31 @@

    enif_get_double()

    -
    int enif_get_double(ErlNifEnv* env,
    -        ERL_NIF_TERM term, double* dp);

    Sets *dp to the floating-point value of term.

    Returns true on success, or false if term is not a float.

    Available since OTP R13B04

    +
    int enif_get_double(ErlNifEnv* env,
    +        ERL_NIF_TERM term, double* dp);

    Sets *dp to the floating-point value of term.

    Returns true on success, or false if term is not a float.

    Available since OTP R13B04

    enif_get_int()

    -
    int enif_get_int(ErlNifEnv* env, ERL_NIF_TERM
    -        term, int* ip);

    Sets *ip to the integer value of term.

    Returns true on success, or false if term is not an integer or is outside +

    int enif_get_int(ErlNifEnv* env, ERL_NIF_TERM
    +        term, int* ip);

    Sets *ip to the integer value of term.

    Returns true on success, or false if term is not an integer or is outside the bounds of type int.

    enif_get_int64()

    -
    int enif_get_int64(ErlNifEnv* env, ERL_NIF_TERM
    -        term, ErlNifSInt64* ip);

    Sets *ip to the integer value of term.

    Returns true on success, or false if term is not an integer or is outside +

    int enif_get_int64(ErlNifEnv* env, ERL_NIF_TERM
    +        term, ErlNifSInt64* ip);

    Sets *ip to the integer value of term.

    Returns true on success, or false if term is not an integer or is outside the bounds of a signed 64-bit integer.

    Available since OTP R14B

    enif_get_local_pid()

    -
    int enif_get_local_pid(ErlNifEnv* env,
    -        ERL_NIF_TERM term, ErlNifPid* pid);

    If term is the pid of a node local process, this function initializes the pid +

    int enif_get_local_pid(ErlNifEnv* env,
    +        ERL_NIF_TERM term, ErlNifPid* pid);

    If term is the pid of a node local process, this function initializes the pid variable *pid from it and returns true. Otherwise returns false. No check is done to see if the process is alive.

    Note

    enif_get_local_pid will return false if argument term is the atom undefined.

    Available since OTP R14B

    @@ -907,8 +907,8 @@

    enif_get_local_port()

    -
    int enif_get_local_port(ErlNifEnv* env,
    -        ERL_NIF_TERM term, ErlNifPort* port_id);

    If term identifies a node local port, this function initializes the port +

    int enif_get_local_port(ErlNifEnv* env,
    +        ERL_NIF_TERM term, ErlNifPort* port_id);

    If term identifies a node local port, this function initializes the port variable *port_id from it and returns true. Otherwise returns false. No check is done to see if the port is alive.

    Available since OTP 19.0

    @@ -916,45 +916,45 @@

    enif_get_list_cell()

    -
    int enif_get_list_cell(ErlNifEnv* env,
    -        ERL_NIF_TERM list, ERL_NIF_TERM* head, ERL_NIF_TERM* tail);

    Sets *head and *tail from list list.

    Returns true on success, or false if it is not a list or the list is empty.

    +
    int enif_get_list_cell(ErlNifEnv* env,
    +        ERL_NIF_TERM list, ERL_NIF_TERM* head, ERL_NIF_TERM* tail);

    Sets *head and *tail from list list.

    Returns true on success, or false if it is not a list or the list is empty.

    enif_get_list_length()

    -
    int enif_get_list_length(ErlNifEnv* env,
    -        ERL_NIF_TERM term, unsigned* len);

    Sets *len to the length of list term.

    Returns true on success, or false if term is not a proper list.

    Available since OTP R14B

    +
    int enif_get_list_length(ErlNifEnv* env,
    +        ERL_NIF_TERM term, unsigned* len);

    Sets *len to the length of list term.

    Returns true on success, or false if term is not a proper list.

    Available since OTP R14B

    enif_get_long()

    -
    int enif_get_long(ErlNifEnv* env, ERL_NIF_TERM
    -        term, long int* ip);

    Sets *ip to the long integer value of term.

    Returns true on success, or false if term is not an integer or is outside +

    int enif_get_long(ErlNifEnv* env, ERL_NIF_TERM
    +        term, long int* ip);

    Sets *ip to the long integer value of term.

    Returns true on success, or false if term is not an integer or is outside the bounds of type long int.

    Available since OTP R13B04

    enif_get_map_size()

    -
    int enif_get_map_size(ErlNifEnv* env,
    -        ERL_NIF_TERM term, size_t *size);

    Sets *size to the number of key-value pairs in the map term.

    Returns true on success, or false if term is not a map.

    Available since OTP 18.0

    +
    int enif_get_map_size(ErlNifEnv* env,
    +        ERL_NIF_TERM term, size_t *size);

    Sets *size to the number of key-value pairs in the map term.

    Returns true on success, or false if term is not a map.

    Available since OTP 18.0

    enif_get_map_value()

    -
    int enif_get_map_value(ErlNifEnv* env,
    -        ERL_NIF_TERM map, ERL_NIF_TERM key, ERL_NIF_TERM* value);

    Sets *value to the value associated with key in the map map.

    Returns true on success, or false if map is not a map or if map does not +

    int enif_get_map_value(ErlNifEnv* env,
    +        ERL_NIF_TERM map, ERL_NIF_TERM key, ERL_NIF_TERM* value);

    Sets *value to the value associated with key in the map map.

    Returns true on success, or false if map is not a map or if map does not contain key.

    Available since OTP 18.0

    enif_get_resource()

    -
    int enif_get_resource(ErlNifEnv* env,
    -        ERL_NIF_TERM term, ErlNifResourceType* type, void** objp);

    Sets *objp to point to the resource object referred to by term.

    Returns true on success, or false if term is not a handle to a resource +

    int enif_get_resource(ErlNifEnv* env,
    +        ERL_NIF_TERM term, ErlNifResourceType* type, void** objp);

    Sets *objp to point to the resource object referred to by term.

    Returns true on success, or false if term is not a handle to a resource object of type type.

    enif_get_resource does not add a reference to the resource object. However, the pointer received in *objp is guaranteed to be valid at least as long as the resource handle term is valid.

    Available since OTP R13B04

    @@ -963,9 +963,9 @@

    enif_get_string()

    -
    int enif_get_string(ErlNifEnv* env,
    +
    int enif_get_string(ErlNifEnv* env,
             ERL_NIF_TERM list, char* buf, unsigned size,
    -        ErlNifCharEncoding encoding);

    Writes a NULL-terminated string in the buffer pointed to by buf with size + ErlNifCharEncoding encoding);

    Writes a NULL-terminated string in the buffer pointed to by buf with size size, consisting of the characters in the string list. The characters are written using encoding.

    Returns one of the following:

    • The number of bytes written (including terminating NULL character)
    • -size if the string was truncated because of buffer space
    • 0 if list is not a string that can be encoded with encoding or if size was < 1.

    The written string is always NULL-terminated, unless buffer size is < 1.

    Available since OTP R13B04

    @@ -974,8 +974,8 @@

    enif_get_string_length()

    -
    int enif_get_string_length(ErlNifEnv *env,
    -        ERL_NIF_TERM list, unsigned *len, ErlNifCharEncoding encoding);

    Sets *len to the length (number of bytes excluding terminating NULL +

    int enif_get_string_length(ErlNifEnv *env,
    +        ERL_NIF_TERM list, unsigned *len, ErlNifCharEncoding encoding);

    Sets *len to the length (number of bytes excluding terminating NULL character) of the string list with encoding.

    Returns true on success, or false if list is not a string that can be encoded with encoding.

    Available since OTP 26.0

    @@ -983,8 +983,8 @@

    enif_get_tuple()

    -
    int enif_get_tuple(ErlNifEnv* env, ERL_NIF_TERM
    -        term, int* arity, const ERL_NIF_TERM** array);

    If term is a tuple, this function sets *array to point to an array +

    int enif_get_tuple(ErlNifEnv* env, ERL_NIF_TERM
    +        term, int* arity, const ERL_NIF_TERM** array);

    If term is a tuple, this function sets *array to point to an array containing the elements of the tuple, and sets *arity to the number of elements. Notice that the array is read-only and (*array)[N-1] is the Nth element of the tuple. *array is undefined if the arity of the tuple is zero.

    Returns true on success, or false if term is not a tuple.

    Available since OTP R13B04

    @@ -993,39 +993,39 @@

    enif_get_uint()

    -
    int enif_get_uint(ErlNifEnv* env, ERL_NIF_TERM
    -        term, unsigned int* ip);

    Sets *ip to the unsigned integer value of term.

    Returns true on success, or false if term is not an unsigned integer or is +

    int enif_get_uint(ErlNifEnv* env, ERL_NIF_TERM
    +        term, unsigned int* ip);

    Sets *ip to the unsigned integer value of term.

    Returns true on success, or false if term is not an unsigned integer or is outside the bounds of type unsigned int.

    Available since OTP R13B04

    enif_get_uint64()

    -
    int enif_get_uint64(ErlNifEnv* env,
    -        ERL_NIF_TERM term, ErlNifUInt64* ip);

    Sets *ip to the unsigned integer value of term.

    Returns true on success, or false if term is not an unsigned integer or is +

    int enif_get_uint64(ErlNifEnv* env,
    +        ERL_NIF_TERM term, ErlNifUInt64* ip);

    Sets *ip to the unsigned integer value of term.

    Returns true on success, or false if term is not an unsigned integer or is outside the bounds of an unsigned 64-bit integer.

    Available since OTP R14B

    enif_get_ulong()

    -
    int enif_get_ulong(ErlNifEnv* env, ERL_NIF_TERM
    -        term, unsigned long* ip);

    Sets *ip to the unsigned long integer value of term.

    Returns true on success, or false if term is not an unsigned integer or is +

    int enif_get_ulong(ErlNifEnv* env, ERL_NIF_TERM
    +        term, unsigned long* ip);

    Sets *ip to the unsigned long integer value of term.

    Returns true on success, or false if term is not an unsigned integer or is outside the bounds of type unsigned long.

    enif_getenv()

    -
    int enif_getenv(const char* key, char* value,
    -        size_t *value_size);

    Same as erl_drv_getenv.

    Available since OTP 18.2

    +
    int enif_getenv(const char* key, char* value,
    +        size_t *value_size);

    Same as erl_drv_getenv.

    Available since OTP 18.2

    enif_has_pending_exception()

    -
    int enif_has_pending_exception(ErlNifEnv* env,
    -        ERL_NIF_TERM* reason);

    Returns true if a pending exception is associated with the environment env. +

    int enif_has_pending_exception(ErlNifEnv* env,
    +        ERL_NIF_TERM* reason);

    Returns true if a pending exception is associated with the environment env. If reason is a NULL pointer, ignore it. Otherwise, if a pending exception associated with env exists, set *reason to the value of the exception term. For example, if enif_make_badarg is called to @@ -1038,23 +1038,23 @@

    enif_hash()

    -
    ErlNifUInt64 enif_hash(ErlNifHash type, ERL_NIF_TERM term, ErlNifUInt64 salt);

    Hashes term according to the specified ErlNifHash +

    ErlNifUInt64 enif_hash(ErlNifHash type, ERL_NIF_TERM term, ErlNifUInt64 salt);

    Hashes term according to the specified ErlNifHash type.

    Ranges of taken salt (if any) and returned value depend on the hash type.

    Available since OTP 20.0

    enif_inspect_binary()

    -
    int enif_inspect_binary(ErlNifEnv* env,
    -        ERL_NIF_TERM bin_term, ErlNifBinary* bin);

    Initializes the structure pointed to by bin with information about binary term +

    int enif_inspect_binary(ErlNifEnv* env,
    +        ERL_NIF_TERM bin_term, ErlNifBinary* bin);

    Initializes the structure pointed to by bin with information about binary term bin_term.

    Returns true on success, or false if bin_term is not a binary.

    enif_inspect_iolist_as_binary()

    -
    int enif_inspect_iolist_as_binary(ErlNifEnv*
    -        env, ERL_NIF_TERM term, ErlNifBinary* bin);

    Initializes the structure pointed to by bin with a continuous buffer with the +

    int enif_inspect_iolist_as_binary(ErlNifEnv*
    +        env, ERL_NIF_TERM term, ErlNifBinary* bin);

    Initializes the structure pointed to by bin with a continuous buffer with the same byte content as iolist. As with inspect_binary, the data pointed to by bin is transient and does not need to be released.

    Returns true on success, or false if iolist is not an iolist.

    Available since OTP R13B04

    @@ -1062,20 +1062,20 @@

    enif_inspect_iovec()

    -
    int enif_inspect_iovec(ErlNifEnv*
    +
    int enif_inspect_iovec(ErlNifEnv*
             env, size_t max_elements, ERL_NIF_TERM iovec_term, ERL_NIF_TERM* tail,
    -        ErlNifIOVec** iovec);

    Fills iovec with the list of binaries provided in iovec_term. The number of + ErlNifIOVec** iovec);

    Fills iovec with the list of binaries provided in iovec_term. The number of elements handled in the call is limited to max_elements, and tail is set to the remainder of the list. Note that the output may be longer than max_elements on some platforms.

    To create a list of binaries from an arbitrary iolist, use erlang:iolist_to_iovec/1.

    When calling this function, iovec should contain a pointer to NULL or a ErlNifIOVec structure that should be used if possible. e.g.

    /* Don't use a pre-allocated structure */
     ErlNifIOVec *iovec = NULL;
    -enif_inspect_iovec(env, max_elements, term, &tail, &iovec);
    +enif_inspect_iovec(env, max_elements, term, &tail, &iovec);
     
     /* Use a stack-allocated vector as an optimization for vectors with few elements */
     ErlNifIOVec vec, *iovec = &vec;
    -enif_inspect_iovec(env, max_elements, term, &tail, &iovec);

    The contents of the iovec is valid until the called nif function returns. If +enif_inspect_iovec(env, max_elements, term, &tail, &iovec);

    The contents of the iovec is valid until the called nif function returns. If the iovec should be valid after the nif call returns, it is possible to call this function with a NULL environment. If no environment is given the iovec owns the data in the vector and it has to be explicitly freed using @@ -1085,20 +1085,20 @@

    enif_ioq_create()

    -
    ErlNifIOQueue * enif_ioq_create(ErlNifIOQueueOpts opts);

    Create a new I/O Queue that can be used to store data. opts has to be set to +

    ErlNifIOQueue * enif_ioq_create(ErlNifIOQueueOpts opts);

    Create a new I/O Queue that can be used to store data. opts has to be set to ERL_NIF_IOQ_NORMAL.

    Available since OTP 20.1

    enif_ioq_destroy()

    -
    void enif_ioq_destroy(ErlNifIOQueue *q);

    Destroy the I/O queue and free all of it's contents

    Available since OTP 20.1

    +
    void enif_ioq_destroy(ErlNifIOQueue *q);

    Destroy the I/O queue and free all of it's contents

    Available since OTP 20.1

    enif_ioq_deq()

    -
    int enif_ioq_deq(ErlNifIOQueue *q, size_t count, size_t *size);

    Dequeue count bytes from the I/O queue. If size is not NULL, the new size +

    int enif_ioq_deq(ErlNifIOQueue *q, size_t count, size_t *size);

    Dequeue count bytes from the I/O queue. If size is not NULL, the new size of the queue is placed there.

    Returns true on success, or false if the I/O does not contain count bytes. On failure the queue is left un-altered.

    Available since OTP 20.1

    @@ -1106,7 +1106,7 @@

    enif_ioq_enq_binary()

    -
    int enif_ioq_enq_binary(ErlNifIOQueue *q, ErlNifBinary *bin, size_t skip);

    Enqueue the bin into q skipping the first skip bytes.

    Returns true on success, or false if skip is greater than the size of +

    int enif_ioq_enq_binary(ErlNifIOQueue *q, ErlNifBinary *bin, size_t skip);

    Enqueue the bin into q skipping the first skip bytes.

    Returns true on success, or false if skip is greater than the size of bin. Any ownership of the binary data is transferred to the queue and bin is to be considered read-only for the rest of the NIF call and then as released.

    Available since OTP 20.1

    @@ -1114,14 +1114,14 @@

    enif_ioq_enqv()

    -
    int enif_ioq_enqv(ErlNifIOQueue *q, ErlNifIOVec *iovec, size_t skip);

    Enqueue the iovec into q skipping the first skip bytes.

    Returns true on success, or false if skip is greater than the size of +

    int enif_ioq_enqv(ErlNifIOQueue *q, ErlNifIOVec *iovec, size_t skip);

    Enqueue the iovec into q skipping the first skip bytes.

    Returns true on success, or false if skip is greater than the size of iovec.

    Available since OTP 20.1

    enif_ioq_peek()

    -
    SysIOVec * enif_ioq_peek(ErlNifIOQueue *q, int *iovlen);

    Get the I/O queue as a pointer to an array of SysIOVecs. It also returns the +

    SysIOVec * enif_ioq_peek(ErlNifIOQueue *q, int *iovlen);

    Get the I/O queue as a pointer to an array of SysIOVecs. It also returns the number of elements in iovlen.

    Nothing is removed from the queue by this function, that must be done with enif_ioq_deq.

    The returned array is suitable to use with the Unix system call writev.

    Available since OTP 20.1

    @@ -1129,32 +1129,32 @@

    enif_ioq_peek_head()

    -
    int enif_ioq_peek_head(ErlNifEnv *env, ErlNifIOQueue *q, size_t *size, ERL_NIF_TERM *bin_term);

    Get the head of the IO Queue as a binary term.

    If size is not NULL, the size of the head is placed there.

    Nothing is removed from the queue by this function, that must be done with +

    int enif_ioq_peek_head(ErlNifEnv *env, ErlNifIOQueue *q, size_t *size, ERL_NIF_TERM *bin_term);

    Get the head of the IO Queue as a binary term.

    If size is not NULL, the size of the head is placed there.

    Nothing is removed from the queue by this function, that must be done with enif_ioq_deq.

    Returns true on success, or false if the queue is empty.

    Available since OTP 21.0

    enif_ioq_size()

    -
    size_t enif_ioq_size(ErlNifIOQueue *q);

    Get the size of q.

    Available since OTP 20.1

    +
    size_t enif_ioq_size(ErlNifIOQueue *q);

    Get the size of q.

    Available since OTP 20.1

    enif_is_atom()

    -
    int enif_is_atom(ErlNifEnv* env, ERL_NIF_TERM term);

    Returns true if term is an atom.

    Available since OTP R13B04

    +
    int enif_is_atom(ErlNifEnv* env, ERL_NIF_TERM term);

    Returns true if term is an atom.

    Available since OTP R13B04

    enif_is_binary()

    -
    int enif_is_binary(ErlNifEnv* env, ERL_NIF_TERM term);

    Returns true if term is a binary.

    +
    int enif_is_binary(ErlNifEnv* env, ERL_NIF_TERM term);

    Returns true if term is a binary.

    enif_is_current_process_alive()

    -
    int enif_is_current_process_alive(ErlNifEnv* env);

    Returns true if the currently executing process is currently alive, otherwise +

    int enif_is_current_process_alive(ErlNifEnv* env);

    Returns true if the currently executing process is currently alive, otherwise false.

    This function can only be used from a NIF-calling thread, and with an environment corresponding to currently executing processes.

    Available since OTP 19.0

    @@ -1162,101 +1162,101 @@

    enif_is_empty_list()

    -
    int enif_is_empty_list(ErlNifEnv* env,
    -        ERL_NIF_TERM term);

    Returns true if term is an empty list.

    Available since OTP R13B04

    +
    int enif_is_empty_list(ErlNifEnv* env,
    +        ERL_NIF_TERM term);

    Returns true if term is an empty list.

    Available since OTP R13B04

    enif_is_exception()

    -
    int enif_is_exception(ErlNifEnv* env,
    -        ERL_NIF_TERM term);

    Return true if term is an exception.

    Available since OTP R14B03

    +
    int enif_is_exception(ErlNifEnv* env,
    +        ERL_NIF_TERM term);

    Return true if term is an exception.

    Available since OTP R14B03

    enif_is_fun()

    -
    int enif_is_fun(ErlNifEnv* env, ERL_NIF_TERM
    -        term);

    Returns true if term is a fun.

    Available since OTP R13B04

    +
    int enif_is_fun(ErlNifEnv* env, ERL_NIF_TERM
    +        term);

    Returns true if term is a fun.

    Available since OTP R13B04

    enif_is_identical()

    -
    int enif_is_identical(ERL_NIF_TERM lhs,
    -        ERL_NIF_TERM rhs);

    Returns true if the two terms are identical. Corresponds to the Erlang +

    int enif_is_identical(ERL_NIF_TERM lhs,
    +        ERL_NIF_TERM rhs);

    Returns true if the two terms are identical. Corresponds to the Erlang operators =:= and =/=.

    Available since OTP R13B04

    enif_is_list()

    -
    int enif_is_list(ErlNifEnv* env, ERL_NIF_TERM term);

    Returns true if term is a list.

    Available since OTP R14B

    +
    int enif_is_list(ErlNifEnv* env, ERL_NIF_TERM term);

    Returns true if term is a list.

    Available since OTP R14B

    enif_is_map()

    -
    int enif_is_map(ErlNifEnv* env, ERL_NIF_TERM
    -        term);

    Returns true if term is a map, otherwise false.

    Available since OTP 18.0

    +
    int enif_is_map(ErlNifEnv* env, ERL_NIF_TERM
    +        term);

    Returns true if term is a map, otherwise false.

    Available since OTP 18.0

    enif_is_number()

    -
    int enif_is_number(ErlNifEnv* env, ERL_NIF_TERM
    -        term);

    Returns true if term is a number.

    Available since OTP R15B

    +
    int enif_is_number(ErlNifEnv* env, ERL_NIF_TERM
    +        term);

    Returns true if term is a number.

    Available since OTP R15B

    enif_is_pid()

    -
    int enif_is_pid(ErlNifEnv* env, ERL_NIF_TERM term);

    Returns true if term is a pid.

    Available since OTP R13B04

    +
    int enif_is_pid(ErlNifEnv* env, ERL_NIF_TERM term);

    Returns true if term is a pid.

    Available since OTP R13B04

    enif_is_pid_undefined()

    -
    int enif_is_pid_undefined(const ErlNifPid* pid);

    Returns true if pid has been set as undefined by +

    int enif_is_pid_undefined(const ErlNifPid* pid);

    Returns true if pid has been set as undefined by enif_set_pid_undefined .

    Available since OTP 22.0

    enif_is_port()

    -
    int enif_is_port(ErlNifEnv* env, ERL_NIF_TERM term);

    Returns true if term is a port.

    Available since OTP R13B04

    +
    int enif_is_port(ErlNifEnv* env, ERL_NIF_TERM term);

    Returns true if term is a port.

    Available since OTP R13B04

    enif_is_port_alive()

    -
    int enif_is_port_alive(ErlNifEnv* env,
    -        ErlNifPort *port_id);

    Returns true if port_id is alive.

    This function is thread-safe.

    Available since OTP 19.0

    +
    int enif_is_port_alive(ErlNifEnv* env,
    +        ErlNifPort *port_id);

    Returns true if port_id is alive.

    This function is thread-safe.

    Available since OTP 19.0

    enif_is_process_alive()

    -
    int enif_is_process_alive(ErlNifEnv* env,
    -        ErlNifPid *pid);

    Returns true if pid is alive.

    This function is thread-safe.

    Available since OTP 19.0

    +
    int enif_is_process_alive(ErlNifEnv* env,
    +        ErlNifPid *pid);

    Returns true if pid is alive.

    This function is thread-safe.

    Available since OTP 19.0

    enif_is_ref()

    -
    int enif_is_ref(ErlNifEnv* env, ERL_NIF_TERM term);

    Returns true if term is a reference.

    Available since OTP R13B04

    +
    int enif_is_ref(ErlNifEnv* env, ERL_NIF_TERM term);

    Returns true if term is a reference.

    Available since OTP R13B04

    enif_is_tuple()

    -
    int enif_is_tuple(ErlNifEnv* env, ERL_NIF_TERM term);

    Returns true if term is a tuple.

    Available since OTP R14B

    +
    int enif_is_tuple(ErlNifEnv* env, ERL_NIF_TERM term);

    Returns true if term is a tuple.

    Available since OTP R14B

    enif_keep_resource()

    -
    int enif_keep_resource(void* obj);

    Adds a reference to resource object obj obtained from +

    int enif_keep_resource(void* obj);

    Adds a reference to resource object obj obtained from enif_alloc_resource. Each call to enif_keep_resource for an object must be balanced by a call to enif_release_resource before the object is @@ -1266,7 +1266,7 @@

    enif_make_atom()

    -
    ERL_NIF_TERM enif_make_atom(ErlNifEnv *env, const char *name);

    Creates an atom term from the NULL-terminated C-string name with ISO +

    ERL_NIF_TERM enif_make_atom(ErlNifEnv *env, const char *name);

    Creates an atom term from the NULL-terminated C-string name with ISO Latin-1 encoding. If the length of name exceeds the maximum length allowed for an atom (255 characters), enif_make_atom invokes enif_make_badarg.

    @@ -1275,8 +1275,8 @@

    enif_make_atom_len()

    -
    ERL_NIF_TERM enif_make_atom_len(ErlNifEnv *env,
    -        const char *name, size_t len);

    Create an atom term from the string name with length len and ISO Latin-1 +

    ERL_NIF_TERM enif_make_atom_len(ErlNifEnv *env,
    +        const char *name, size_t len);

    Create an atom term from the string name with length len and ISO Latin-1 encoding. NULL characters are treated as any other characters. If len exceeds the maximum length allowed for an atom (255 characters), enif_make_atom invokes enif_make_badarg .

    Available since OTP R14B

    @@ -1285,7 +1285,7 @@

    enif_make_badarg()

    -
    ERL_NIF_TERM enif_make_badarg(ErlNifEnv* env);

    Makes a badarg exception to be returned from a NIF, and associates it with +

    ERL_NIF_TERM enif_make_badarg(ErlNifEnv* env);

    Makes a badarg exception to be returned from a NIF, and associates it with environment env. Once a NIF or any function it calls invokes enif_make_badarg, the runtime ensures that a badarg exception is raised when the NIF returns, even if the NIF attempts to return a non-exception term @@ -1301,7 +1301,7 @@

    enif_make_binary()

    -
    ERL_NIF_TERM enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin);

    Makes a binary term from bin. Any ownership of the binary data is transferred +

    ERL_NIF_TERM enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin);

    Makes a binary term from bin. Any ownership of the binary data is transferred to the created term and bin is to be considered read-only for the rest of the NIF call and then as released.

    @@ -1309,15 +1309,15 @@

    enif_make_copy()

    -
    ERL_NIF_TERM enif_make_copy(ErlNifEnv* dst_env,
    -        ERL_NIF_TERM src_term);

    Makes a copy of term src_term. The copy is created in environment dst_env. +

    ERL_NIF_TERM enif_make_copy(ErlNifEnv* dst_env,
    +        ERL_NIF_TERM src_term);

    Makes a copy of term src_term. The copy is created in environment dst_env. The source term can be located in any environment.

    Available since OTP R14B

    enif_make_double()

    -
    ERL_NIF_TERM enif_make_double(ErlNifEnv* env, double d);

    Creates a floating-point term from a double. If argument double is not +

    ERL_NIF_TERM enif_make_double(ErlNifEnv* env, double d);

    Creates a floating-point term from a double. If argument double is not finite or is NaN, enif_make_double invokes enif_make_badarg.

    Available since OTP R13B04

    @@ -1325,9 +1325,9 @@

    enif_make_existing_atom()

    -
    int enif_make_existing_atom(ErlNifEnv *env,
    +
    int enif_make_existing_atom(ErlNifEnv *env,
             const char *name, ERL_NIF_TERM *atom, ErlNifCharEncoding
    -        encoding);

    Tries to create the term of an already existing atom from the NULL-terminated + encoding);

    Tries to create the term of an already existing atom from the NULL-terminated C-string name with encoding.

    If the atom already exists, this function stores the term in *atom and returns true, otherwise returns false. It also returns false if the string name exceeds the maximum length allowed for an atom (255 characters) or if name is @@ -1337,9 +1337,9 @@

    enif_make_existing_atom_len()

    -
    int enif_make_existing_atom_len(ErlNifEnv *env,
    +
    int enif_make_existing_atom_len(ErlNifEnv *env,
             const char *name, size_t len, ERL_NIF_TERM *atom, ErlNifCharEncoding
    -        encoding);

    Tries to create the term of an already existing atom from the string name with + encoding);

    Tries to create the term of an already existing atom from the string name with length len bytes and encoding. NULL characters are treated as any other characters.

    If the atom already exists, this function stores the term in *atom and returns true, otherwise returns false. It also returns false if the string name @@ -1350,19 +1350,19 @@

    enif_make_int()

    -
    ERL_NIF_TERM enif_make_int(ErlNifEnv* env, int i);

    Creates an integer term.

    +
    ERL_NIF_TERM enif_make_int(ErlNifEnv* env, int i);

    Creates an integer term.

    enif_make_int64()

    -
    ERL_NIF_TERM enif_make_int64(ErlNifEnv* env, ErlNifSInt64 i);

    Creates an integer term from a signed 64-bit integer.

    Available since OTP R14B

    +
    ERL_NIF_TERM enif_make_int64(ErlNifEnv* env, ErlNifSInt64 i);

    Creates an integer term from a signed 64-bit integer.

    Available since OTP R14B

    enif_make_list()

    -
    ERL_NIF_TERM enif_make_list(ErlNifEnv* env, unsigned cnt, ...);

    Creates an ordinary list term of length cnt. Expects cnt number of arguments +

    ERL_NIF_TERM enif_make_list(ErlNifEnv* env, unsigned cnt, ...);

    Creates an ordinary list term of length cnt. Expects cnt number of arguments (after cnt) of type ERL_NIF_TERM as the elements of the list.

    Returns an empty list if cnt is 0.

    @@ -1417,15 +1417,15 @@

    enif_make_list9()

    -
    ERL_NIF_TERM enif_make_list1(ErlNifEnv* env, ERL_NIF_TERM e1);
    ERL_NIF_TERM enif_make_list2(ErlNifEnv* env,
    -        ERL_NIF_TERM e1, ERL_NIF_TERM e2);
    ERL_NIF_TERM enif_make_list3(ErlNifEnv* env,
    -        ERL_NIF_TERM e1, ERL_NIF_TERM e2, ERL_NIF_TERM e3);
    ERL_NIF_TERM enif_make_list4(ErlNifEnv* env,
    -        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e4);
    ERL_NIF_TERM enif_make_list5(ErlNifEnv* env,
    -        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e5);
    ERL_NIF_TERM enif_make_list6(ErlNifEnv* env,
    -        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e6);
    ERL_NIF_TERM enif_make_list7(ErlNifEnv* env,
    -        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e7);
    ERL_NIF_TERM enif_make_list8(ErlNifEnv* env,
    -        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e8);
    ERL_NIF_TERM enif_make_list9(ErlNifEnv* env,
    -        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e9);

    Creates an ordinary list term with length indicated by the function name. Prefer +

    ERL_NIF_TERM enif_make_list1(ErlNifEnv* env, ERL_NIF_TERM e1);
    ERL_NIF_TERM enif_make_list2(ErlNifEnv* env,
    +        ERL_NIF_TERM e1, ERL_NIF_TERM e2);
    ERL_NIF_TERM enif_make_list3(ErlNifEnv* env,
    +        ERL_NIF_TERM e1, ERL_NIF_TERM e2, ERL_NIF_TERM e3);
    ERL_NIF_TERM enif_make_list4(ErlNifEnv* env,
    +        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e4);
    ERL_NIF_TERM enif_make_list5(ErlNifEnv* env,
    +        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e5);
    ERL_NIF_TERM enif_make_list6(ErlNifEnv* env,
    +        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e6);
    ERL_NIF_TERM enif_make_list7(ErlNifEnv* env,
    +        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e7);
    ERL_NIF_TERM enif_make_list8(ErlNifEnv* env,
    +        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e8);
    ERL_NIF_TERM enif_make_list9(ErlNifEnv* env,
    +        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e9);

    Creates an ordinary list term with length indicated by the function name. Prefer these functions (macros) over the variadic enif_make_list to get a compile-time error if the number of arguments does not match.

    Available since OTP R13B04

    @@ -1433,29 +1433,29 @@

    enif_make_list_cell()

    -
    ERL_NIF_TERM enif_make_list_cell(ErlNifEnv*
    -        env, ERL_NIF_TERM head, ERL_NIF_TERM tail);

    Creates a list cell [head | tail].

    +
    ERL_NIF_TERM enif_make_list_cell(ErlNifEnv*
    +        env, ERL_NIF_TERM head, ERL_NIF_TERM tail);

    Creates a list cell [head | tail].

    enif_make_list_from_array()

    -
    ERL_NIF_TERM enif_make_list_from_array(ErlNifEnv* env, const ERL_NIF_TERM
    -          arr[], unsigned cnt);

    Creates an ordinary list containing the elements of array arr of length cnt.

    Returns an empty list if cnt is 0.

    Available since OTP R13B04

    +
    ERL_NIF_TERM enif_make_list_from_array(ErlNifEnv* env, const ERL_NIF_TERM
    +          arr[], unsigned cnt);

    Creates an ordinary list containing the elements of array arr of length cnt.

    Returns an empty list if cnt is 0.

    Available since OTP R13B04

    enif_make_long()

    -
    ERL_NIF_TERM enif_make_long(ErlNifEnv* env, long int i);

    Creates an integer term from a long int.

    Available since OTP R13B04

    +
    ERL_NIF_TERM enif_make_long(ErlNifEnv* env, long int i);

    Creates an integer term from a long int.

    Available since OTP R13B04

    enif_make_map_put()

    -
    int enif_make_map_put(ErlNifEnv* env,
    +
    int enif_make_map_put(ErlNifEnv* env,
             ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM value,
    -        ERL_NIF_TERM* map_out);

    Makes a copy of map map_in and inserts key with value. If key already + ERL_NIF_TERM* map_out);

    Makes a copy of map map_in and inserts key with value. If key already exists in map_in, the old associated value is replaced by value.

    If successful, this function sets *map_out to the new map and returns true. Returns false if map_in is not a map.

    The map_in term must belong to environment env.

    Available since OTP 18.0

    @@ -1463,8 +1463,8 @@

    enif_make_map_remove()

    -
    int enif_make_map_remove(ErlNifEnv* env,
    -        ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM* map_out);

    If map map_in contains key, this function makes a copy of map_in in +

    int enif_make_map_remove(ErlNifEnv* env,
    +        ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM* map_out);

    If map map_in contains key, this function makes a copy of map_in in *map_out, and removes key and the associated value. If map map_in does not contain key, *map_out is set to map_in.

    Returns true on success, or false if map_in is not a map.

    The map_in term must belong to environment env.

    Available since OTP 18.0

    @@ -1472,9 +1472,9 @@

    enif_make_map_update()

    -
    int enif_make_map_update(ErlNifEnv* env,
    +
    int enif_make_map_update(ErlNifEnv* env,
             ERL_NIF_TERM map_in, ERL_NIF_TERM key, ERL_NIF_TERM new_value,
    -        ERL_NIF_TERM* map_out);

    Makes a copy of map map_in and replace the old associated value for key with + ERL_NIF_TERM* map_out);

    Makes a copy of map map_in and replace the old associated value for key with new_value.

    If successful, this function sets *map_out to the new map and returns true. Returns false if map_in is not a map or if it does not contain key.

    The map_in term must belong to environment env.

    Available since OTP 18.0

    @@ -1482,24 +1482,24 @@

    enif_make_map_from_arrays()

    -
    int enif_make_map_from_arrays(ErlNifEnv* env, ERL_NIF_TERM keys[],
    -        ERL_NIF_TERM values[], size_t cnt, ERL_NIF_TERM *map_out);

    Makes a map term from the given keys and values.

    If successful, this function sets *map_out to the new map and returns true. +

    int enif_make_map_from_arrays(ErlNifEnv* env, ERL_NIF_TERM keys[],
    +        ERL_NIF_TERM values[], size_t cnt, ERL_NIF_TERM *map_out);

    Makes a map term from the given keys and values.

    If successful, this function sets *map_out to the new map and returns true. Returns false there are any duplicate keys.

    All keys and values must belong to env.

    Available since OTP 21.0

    enif_make_monitor_term()

    -
    ERL_NIF_TERM enif_make_monitor_term(ErlNifEnv* env, const ErlNifMonitor* mon);

    Creates a term identifying the given monitor received from +

    ERL_NIF_TERM enif_make_monitor_term(ErlNifEnv* env, const ErlNifMonitor* mon);

    Creates a term identifying the given monitor received from enif_monitor_process .

    This function is primarily intended for debugging purpose.

    Available since OTP 22.0

    enif_make_new_atom()

    -
    int enif_make_new_atom(ErlNifEnv *env,
    +
    int enif_make_new_atom(ErlNifEnv *env,
             const char *name, ERL_NIF_TERM *atom, ErlNifCharEncoding
    -        encoding);

    Creates an atom term from the NULL-terminated C-string name with + encoding);

    Creates an atom term from the NULL-terminated C-string name with encoding.

    If successful, true is returned and the atom term is stored in *atom.

    Otherwise, false is returned if the length of name exceeds the maximum length allowed for an atom (255 characters) or if name is not correctly encoded.

    Available since OTP 26.0

    @@ -1508,9 +1508,9 @@

    enif_make_new_atom_len()

    -
    int enif_make_new_atom_len(ErlNifEnv *env,
    +
    int enif_make_new_atom_len(ErlNifEnv *env,
             const char *name, size_t len, ERL_NIF_TERM *atom, ErlNifCharEncoding
    -        encoding);

    Create an atom term from string name with length len bytes and + encoding);

    Create an atom term from string name with length len bytes and encoding.

    If successful, true is returned and atom term is stored in *atom.

    Otherwise, false is returned if the string exceeds the maximum length allowed for an atom (255 characters) or if the string is not correctly encoded.

    Available since OTP 26.0

    @@ -1518,8 +1518,8 @@

    enif_make_new_binary()

    -
    unsigned char * enif_make_new_binary(ErlNifEnv*
    -        env, size_t size, ERL_NIF_TERM* termp);

    Allocates a binary of size size bytes and creates an owning term. The binary +

    unsigned char * enif_make_new_binary(ErlNifEnv*
    +        env, size_t size, ERL_NIF_TERM* termp);

    Allocates a binary of size size bytes and creates an owning term. The binary data is mutable until the calling NIF returns. This is a quick way to create a new binary without having to use ErlNifBinary. The drawbacks are that the binary cannot be kept between NIF calls and it cannot be @@ -1529,26 +1529,26 @@

    enif_make_new_map()

    -
    ERL_NIF_TERM enif_make_new_map(ErlNifEnv* env);

    Makes an empty map term.

    Available since OTP 18.0

    +
    ERL_NIF_TERM enif_make_new_map(ErlNifEnv* env);

    Makes an empty map term.

    Available since OTP 18.0

    enif_make_pid()

    -
    ERL_NIF_TERM enif_make_pid(ErlNifEnv* env, const ErlNifPid* pid);

    Makes a pid term or the atom undefined +

    ERL_NIF_TERM enif_make_pid(ErlNifEnv* env, const ErlNifPid* pid);

    Makes a pid term or the atom undefined from *pid.

    Available since OTP R14B

    enif_make_ref()

    -
    ERL_NIF_TERM enif_make_ref(ErlNifEnv* env);

    Creates a reference like erlang:make_ref/0.

    Available since OTP R13B04

    +
    ERL_NIF_TERM enif_make_ref(ErlNifEnv* env);

    Creates a reference like erlang:make_ref/0.

    Available since OTP R13B04

    enif_make_resource()

    -
    ERL_NIF_TERM enif_make_resource(ErlNifEnv* env, void* obj);

    Creates an opaque handle to a memory-managed resource object obtained by +

    ERL_NIF_TERM enif_make_resource(ErlNifEnv* env, void* obj);

    Creates an opaque handle to a memory-managed resource object obtained by enif_alloc_resource. No ownership transfer is done, as the resource object still needs to be released by enif_release_resource. However, notice @@ -1575,8 +1575,8 @@

    enif_make_resource_binary()

    -
    ERL_NIF_TERM enif_make_resource_binary(ErlNifEnv* env, void* obj, const
    -        void* data, size_t size);

    Creates a binary term that is memory-managed by a resource object obj obtained +

    ERL_NIF_TERM enif_make_resource_binary(ErlNifEnv* env, void* obj, const
    +        void* data, size_t size);

    Creates a binary term that is memory-managed by a resource object obj obtained by enif_alloc_resource. The returned binary term consists of size bytes pointed to by data. This raw binary data must be kept readable and unchanged until the destructor of the resource is called. The @@ -1591,8 +1591,8 @@

    enif_make_reverse_list()

    -
    int enif_make_reverse_list(ErlNifEnv* env, ERL_NIF_TERM list_in,
    -        ERL_NIF_TERM *list_out);

    Sets *list_out to the reverse list of the list list_in and returns true, +

    int enif_make_reverse_list(ErlNifEnv* env, ERL_NIF_TERM list_in,
    +        ERL_NIF_TERM *list_out);

    Sets *list_out to the reverse list of the list list_in and returns true, or returns false if list_in is not a list.

    This function is only to be used on short lists, as a copy is created of the list, which is not released until after the NIF returns.

    The list_in term must belong to environment env.

    Available since OTP R15B

    @@ -1600,17 +1600,17 @@

    enif_make_string()

    -
    ERL_NIF_TERM enif_make_string(ErlNifEnv *env,
    -        const char *string, ErlNifCharEncoding encoding);

    Creates a list containing the characters of the NULL-terminated string +

    ERL_NIF_TERM enif_make_string(ErlNifEnv *env,
    +        const char *string, ErlNifCharEncoding encoding);

    Creates a list containing the characters of the NULL-terminated string string with encoding.

    enif_make_string_len()

    -
    ERL_NIF_TERM enif_make_string_len(ErlNifEnv
    +
    ERL_NIF_TERM enif_make_string_len(ErlNifEnv
             *env, const char *string, size_t len, ErlNifCharEncoding
    -        encoding);

    Creates a list containing the characters of the string string with length + encoding);

    Creates a list containing the characters of the string string with length len and encoding. NULL characters are treated as any other characters.

    Available since OTP R14B

    @@ -1618,8 +1618,8 @@

    enif_make_sub_binary()

    -
    ERL_NIF_TERM enif_make_sub_binary(ErlNifEnv*
    -        env, ERL_NIF_TERM bin_term, size_t pos, size_t size);

    Makes a subbinary of binary bin_term, starting at zero-based position pos +

    ERL_NIF_TERM enif_make_sub_binary(ErlNifEnv*
    +        env, ERL_NIF_TERM bin_term, size_t pos, size_t size);

    Makes a subbinary of binary bin_term, starting at zero-based position pos with a length of size bytes. bin_term must be a binary or bitstring. pos+size must be less or equal to the number of whole bytes in bin_term.

    Available since OTP R13B04

    @@ -1627,8 +1627,8 @@

    enif_make_tuple()

    -
    ERL_NIF_TERM enif_make_tuple(ErlNifEnv* env,
    -        unsigned cnt, ...);

    Creates a tuple term of arity cnt. Expects cnt number of arguments (after +

    ERL_NIF_TERM enif_make_tuple(ErlNifEnv* env,
    +        unsigned cnt, ...);

    Creates a tuple term of arity cnt. Expects cnt number of arguments (after cnt) of type ERL_NIF_TERM as the elements of the tuple.

    @@ -1683,16 +1683,16 @@

    enif_make_tuple9()

    -
    ERL_NIF_TERM enif_make_tuple1(ErlNifEnv* env,
    -        ERL_NIF_TERM e1);
    ERL_NIF_TERM enif_make_tuple2(ErlNifEnv* env,
    -        ERL_NIF_TERM e1, ERL_NIF_TERM e2);
    ERL_NIF_TERM enif_make_tuple3(ErlNifEnv* env,
    -        ERL_NIF_TERM e1, ERL_NIF_TERM e2, ERL_NIF_TERM e3);
    ERL_NIF_TERM enif_make_tuple4(ErlNifEnv* env,
    -        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e4);
    ERL_NIF_TERM enif_make_tuple5(ErlNifEnv* env,
    -        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e5);
    ERL_NIF_TERM enif_make_tuple6(ErlNifEnv* env,
    -        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e6);
    ERL_NIF_TERM enif_make_tuple7(ErlNifEnv* env,
    -        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e7);
    ERL_NIF_TERM enif_make_tuple8(ErlNifEnv* env,
    -        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e8);
    ERL_NIF_TERM enif_make_tuple9(ErlNifEnv* env,
    -        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e9);

    Creates a tuple term with length indicated by the function name. Prefer these +

    ERL_NIF_TERM enif_make_tuple1(ErlNifEnv* env,
    +        ERL_NIF_TERM e1);
    ERL_NIF_TERM enif_make_tuple2(ErlNifEnv* env,
    +        ERL_NIF_TERM e1, ERL_NIF_TERM e2);
    ERL_NIF_TERM enif_make_tuple3(ErlNifEnv* env,
    +        ERL_NIF_TERM e1, ERL_NIF_TERM e2, ERL_NIF_TERM e3);
    ERL_NIF_TERM enif_make_tuple4(ErlNifEnv* env,
    +        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e4);
    ERL_NIF_TERM enif_make_tuple5(ErlNifEnv* env,
    +        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e5);
    ERL_NIF_TERM enif_make_tuple6(ErlNifEnv* env,
    +        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e6);
    ERL_NIF_TERM enif_make_tuple7(ErlNifEnv* env,
    +        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e7);
    ERL_NIF_TERM enif_make_tuple8(ErlNifEnv* env,
    +        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e8);
    ERL_NIF_TERM enif_make_tuple9(ErlNifEnv* env,
    +        ERL_NIF_TERM e1, ..., ERL_NIF_TERM e9);

    Creates a tuple term with length indicated by the function name. Prefer these functions (macros) over the variadic enif_make_tuple to get a compile-time error if the number of arguments does not match.

    Available since OTP R13B04

    @@ -1700,33 +1700,33 @@

    enif_make_tuple_from_array()

    -
    ERL_NIF_TERM enif_make_tuple_from_array(ErlNifEnv* env, const ERL_NIF_TERM
    -        arr[], unsigned cnt);

    Creates a tuple containing the elements of array arr of length cnt.

    Available since OTP R13B04

    +
    ERL_NIF_TERM enif_make_tuple_from_array(ErlNifEnv* env, const ERL_NIF_TERM
    +        arr[], unsigned cnt);

    Creates a tuple containing the elements of array arr of length cnt.

    Available since OTP R13B04

    enif_make_uint()

    -
    ERL_NIF_TERM enif_make_uint(ErlNifEnv* env, unsigned int i);

    Creates an integer term from an unsigned int.

    Available since OTP R13B04

    +
    ERL_NIF_TERM enif_make_uint(ErlNifEnv* env, unsigned int i);

    Creates an integer term from an unsigned int.

    Available since OTP R13B04

    enif_make_uint64()

    -
    ERL_NIF_TERM enif_make_uint64(ErlNifEnv* env, ErlNifUInt64 i);

    Creates an integer term from an unsigned 64-bit integer.

    Available since OTP R14B

    +
    ERL_NIF_TERM enif_make_uint64(ErlNifEnv* env, ErlNifUInt64 i);

    Creates an integer term from an unsigned 64-bit integer.

    Available since OTP R14B

    enif_make_ulong()

    -
    ERL_NIF_TERM enif_make_ulong(ErlNifEnv* env, unsigned long i);

    Creates an integer term from an unsigned long int.

    +
    ERL_NIF_TERM enif_make_ulong(ErlNifEnv* env, unsigned long i);

    Creates an integer term from an unsigned long int.

    enif_make_unique_integer()

    -
    ERL_NIF_TERM enif_make_unique_integer(ErlNifEnv
    -        *env, ErlNifUniqueInteger properties);

    Returns a unique integer with the same properties as specified by +

    ERL_NIF_TERM enif_make_unique_integer(ErlNifEnv
    +        *env, ErlNifUniqueInteger properties);

    Returns a unique integer with the same properties as specified by erlang:unique_integer/1.

    env is the environment to create the integer in.

    ERL_NIF_UNIQUE_POSITIVE and ERL_NIF_UNIQUE_MONOTONIC can be passed as the second argument to change the properties of the integer returned. They can be combined by OR:ing the two values together.

    See also ErlNifUniqueInteger.

    Available since OTP 19.0

    @@ -1735,21 +1735,21 @@

    enif_map_iterator_create()

    -
    int enif_map_iterator_create(ErlNifEnv *env,
    +
    int enif_map_iterator_create(ErlNifEnv *env,
             ERL_NIF_TERM map, ErlNifMapIterator *iter, ErlNifMapIteratorEntry
    -        entry);

    Creates an iterator for the map map by initializing the structure pointed to + entry);

    Creates an iterator for the map map by initializing the structure pointed to by iter. Argument entry determines the start position of the iterator: ERL_NIF_MAP_ITERATOR_FIRST or ERL_NIF_MAP_ITERATOR_LAST.

    Returns true on success, or false if map is not a map.

    A map iterator is only useful during the lifetime of environment env that the map belongs to. The iterator must be destroyed by calling enif_map_iterator_destroy:

    ERL_NIF_TERM key, value;
     ErlNifMapIterator iter;
    -enif_map_iterator_create(env, my_map, &iter, ERL_NIF_MAP_ITERATOR_FIRST);
    +enif_map_iterator_create(env, my_map, &iter, ERL_NIF_MAP_ITERATOR_FIRST);
     
    -while (enif_map_iterator_get_pair(env, &iter, &key, &value)) {
    -    do_something(key,value);
    -    enif_map_iterator_next(env, &iter);
    -}
    -enif_map_iterator_destroy(env, &iter);

    Note

    The key-value pairs of a map have no defined iteration order. The only +while (enif_map_iterator_get_pair(env, &iter, &key, &value)) { + do_something(key,value); + enif_map_iterator_next(env, &iter); +} +enif_map_iterator_destroy(env, &iter);

    Note

    The key-value pairs of a map have no defined iteration order. The only guarantee is that the iteration order of a single map instance is preserved during the lifetime of the environment that the map belongs to.

    Available since OTP 18.0

    @@ -1757,55 +1757,55 @@

    enif_map_iterator_destroy()

    -
    void enif_map_iterator_destroy(ErlNifEnv *env,
    -        ErlNifMapIterator *iter);

    Destroys a map iterator created by +

    void enif_map_iterator_destroy(ErlNifEnv *env,
    +        ErlNifMapIterator *iter);

    Destroys a map iterator created by enif_map_iterator_create.

    Available since OTP 18.0

    enif_map_iterator_get_pair()

    -
    int enif_map_iterator_get_pair(ErlNifEnv *env,
    +
    int enif_map_iterator_get_pair(ErlNifEnv *env,
             ErlNifMapIterator *iter, ERL_NIF_TERM *key, ERL_NIF_TERM
    -        *value);

    Gets key and value terms at the current map iterator position.

    On success, sets *key and *value and returns true. Returns false if the + *value);

    Gets key and value terms at the current map iterator position.

    On success, sets *key and *value and returns true. Returns false if the iterator is positioned at head (before first entry) or tail (beyond last entry).

    Available since OTP 18.0

    enif_map_iterator_is_head()

    -
    int enif_map_iterator_is_head(ErlNifEnv *env,
    -        ErlNifMapIterator *iter);

    Returns true if map iterator iter is positioned before the first entry.

    Available since OTP 18.0

    +
    int enif_map_iterator_is_head(ErlNifEnv *env,
    +        ErlNifMapIterator *iter);

    Returns true if map iterator iter is positioned before the first entry.

    Available since OTP 18.0

    enif_map_iterator_is_tail()

    -
    int enif_map_iterator_is_tail(ErlNifEnv *env,
    -        ErlNifMapIterator *iter);

    Returns true if map iterator iter is positioned after the last entry.

    Available since OTP 18.0

    +
    int enif_map_iterator_is_tail(ErlNifEnv *env,
    +        ErlNifMapIterator *iter);

    Returns true if map iterator iter is positioned after the last entry.

    Available since OTP 18.0

    enif_map_iterator_next()

    -
    int enif_map_iterator_next(ErlNifEnv *env,
    -        ErlNifMapIterator *iter);

    Increments map iterator to point to the next key-value entry.

    Returns true if the iterator is now positioned at a valid key-value entry, or +

    int enif_map_iterator_next(ErlNifEnv *env,
    +        ErlNifMapIterator *iter);

    Increments map iterator to point to the next key-value entry.

    Returns true if the iterator is now positioned at a valid key-value entry, or false if the iterator is positioned at the tail (beyond the last entry).

    Available since OTP 18.0

    enif_map_iterator_prev()

    -
    int enif_map_iterator_prev(ErlNifEnv *env,
    -        ErlNifMapIterator *iter);

    Decrements map iterator to point to the previous key-value entry.

    Returns true if the iterator is now positioned at a valid key-value entry, or +

    int enif_map_iterator_prev(ErlNifEnv *env,
    +        ErlNifMapIterator *iter);

    Decrements map iterator to point to the previous key-value entry.

    Returns true if the iterator is now positioned at a valid key-value entry, or false if the iterator is positioned at the head (before the first entry).

    Available since OTP 18.0

    enif_monitor_process()

    -
    int enif_monitor_process(ErlNifEnv* caller_env,
    -      void* obj, const ErlNifPid* target_pid, ErlNifMonitor* mon);

    Starts monitoring a process from a resource. When a process is monitored, a +

    int enif_monitor_process(ErlNifEnv* caller_env,
    +      void* obj, const ErlNifPid* target_pid, ErlNifMonitor* mon);

    Starts monitoring a process from a resource. When a process is monitored, a process exit results in a call to the provided down callback associated with the resource type.

    Argument obj is pointer to the resource to hold the monitor and *target_pid @@ -1825,7 +1825,7 @@

    enif_monotonic_time()

    -
    ErlNifTime enif_monotonic_time(ErlNifTimeUnit time_unit);

    Returns the current +

    ErlNifTime enif_monotonic_time(ErlNifTimeUnit time_unit);

    Returns the current Erlang monotonic time. Notice that it is not uncommon with negative values.

    time_unit is the time unit of the returned value.

    Returns ERL_NIF_TIME_ERROR if called with an invalid time unit argument, or if called from a thread that is not a scheduler thread.

    See also ErlNifTime and @@ -1835,51 +1835,51 @@

    enif_mutex_create()

    -
    ErlNifMutex * enif_mutex_create(char *name);

    Same as erl_drv_mutex_create.

    Available since OTP R13B04

    +
    ErlNifMutex * enif_mutex_create(char *name);

    Same as erl_drv_mutex_create.

    Available since OTP R13B04

    enif_mutex_destroy()

    -
    void enif_mutex_destroy(ErlNifMutex *mtx);

    Same as erl_drv_mutex_destroy.

    Available since OTP R13B04

    +
    void enif_mutex_destroy(ErlNifMutex *mtx);

    Same as erl_drv_mutex_destroy.

    Available since OTP R13B04

    enif_mutex_lock()

    -
    void enif_mutex_lock(ErlNifMutex *mtx);

    Same as erl_drv_mutex_lock.

    Available since OTP R13B04

    +
    void enif_mutex_lock(ErlNifMutex *mtx);

    Same as erl_drv_mutex_lock.

    Available since OTP R13B04

    enif_mutex_name()

    -
    char* enif_mutex_name(ErlNifMutex* mtx);

    Same as erl_drv_mutex_name.

    Available since OTP 21.0

    +
    char* enif_mutex_name(ErlNifMutex* mtx);

    Same as erl_drv_mutex_name.

    Available since OTP 21.0

    enif_mutex_trylock()

    -
    int enif_mutex_trylock(ErlNifMutex *mtx);

    Same as erl_drv_mutex_trylock.

    Available since OTP R13B04

    +
    int enif_mutex_trylock(ErlNifMutex *mtx);

    Same as erl_drv_mutex_trylock.

    Available since OTP R13B04

    enif_mutex_unlock()

    -
    void enif_mutex_unlock(ErlNifMutex *mtx);

    Same as erl_drv_mutex_unlock.

    Available since OTP R13B04

    +
    void enif_mutex_unlock(ErlNifMutex *mtx);

    Same as erl_drv_mutex_unlock.

    Available since OTP R13B04

    enif_now_time()

    -
    ERL_NIF_TERM enif_now_time(ErlNifEnv *env);

    Returns an erlang:now() time stamp.

    This function is deprecated.

    Available since OTP 19.0

    +
    ERL_NIF_TERM enif_now_time(ErlNifEnv *env);

    Returns an erlang:now() time stamp.

    This function is deprecated.

    Available since OTP 19.0

    enif_open_resource_type()

    -
    ErlNifResourceType * enif_open_resource_type(ErlNifEnv* env, const char*
    +
    ErlNifResourceType * enif_open_resource_type(ErlNifEnv* env, const char*
             module_str, const char* name, ErlNifResourceDtor* dtor,
    -        ErlNifResourceFlags flags, ErlNifResourceFlags* tried);

    Creates or takes over a resource type identified by the string name and gives + ErlNifResourceFlags flags, ErlNifResourceFlags* tried);

    Creates or takes over a resource type identified by the string name and gives it the destructor function pointed to by dtor. Argument flags can have the following values:

    • ERL_NIF_RT_CREATE - Creates a new resource type that does not already @@ -1900,9 +1900,9 @@

      enif_open_resource_type_x()

      -
      ErlNifResourceType * enif_open_resource_type_x(ErlNifEnv* env, const char* name,
      +
      ErlNifResourceType * enif_open_resource_type_x(ErlNifEnv* env, const char* name,
       	const ErlNifResourceTypeInit* init,
      -        ErlNifResourceFlags flags, ErlNifResourceFlags* tried);

      Same as enif_open_resource_type except + ErlNifResourceFlags flags, ErlNifResourceFlags* tried);

      Same as enif_open_resource_type except it accepts additional callback functions for resource types that are used together with enif_select and enif_monitor_process.

      Argument init is a pointer to an @@ -1917,9 +1917,9 @@

      enif_init_resource_type()

      -
      ErlNifResourceType * enif_init_resource_type(ErlNifEnv* env, const char* name,
      +
      ErlNifResourceType * enif_init_resource_type(ErlNifEnv* env, const char* name,
       	const ErlNifResourceTypeInit* init,
      -        ErlNifResourceFlags flags, ErlNifResourceFlags* tried);

      Same as enif_open_resource_type_x + ErlNifResourceFlags flags, ErlNifResourceFlags* tried);

      Same as enif_open_resource_type_x except it accepts an additional callback function for resource types that are used together with enif_dynamic_resource_call.

      Argument init is a pointer to an @@ -1934,8 +1934,8 @@

      enif_port_command()

      -
      int enif_port_command(ErlNifEnv* env, const
      -       ErlNifPort* to_port, ErlNifEnv *msg_env, ERL_NIF_TERM msg);

      Works as erlang:port_command/2, except that it is always completely +

      int enif_port_command(ErlNifEnv* env, const
      +       ErlNifPort* to_port, ErlNifEnv *msg_env, ERL_NIF_TERM msg);

      Works as erlang:port_command/2, except that it is always completely asynchronous.

      • env - The environment of the calling process. Must not be NULL.

      • *to_port - The port ID of the receiving port. The port ID is to refer to a port on the local node.

      • msg_env - The environment of the message term. Can be a process independent environment allocated with @@ -1950,15 +1950,15 @@

        enif_priv_data()

        -
        void * enif_priv_data(ErlNifEnv* env);

        Returns the pointer to the private data that was set by +

        void * enif_priv_data(ErlNifEnv* env);

        Returns the pointer to the private data that was set by load or upgrade.

        Available since OTP R13B04

        enif_raise_exception()

        -
        ERL_NIF_TERM enif_raise_exception(ErlNifEnv*
        -        env, ERL_NIF_TERM reason);

        Creates an error exception with the term reason to be returned from a NIF, and +

        ERL_NIF_TERM enif_raise_exception(ErlNifEnv*
        +        env, ERL_NIF_TERM reason);

        Creates an error exception with the term reason to be returned from a NIF, and associates it with environment env. Once a NIF or any function it calls invokes enif_raise_exception, the runtime ensures that the exception it creates is raised when the NIF returns, even if the NIF attempts to return a @@ -1972,7 +1972,7 @@

        enif_realloc()

        -
        void * enif_realloc(void* ptr, size_t size);

        Reallocates memory allocated by enif_alloc to size +

        void * enif_realloc(void* ptr, size_t size);

        Reallocates memory allocated by enif_alloc to size bytes.

        Returns NULL if the reallocation fails.

        The returned pointer is suitably aligned for any built-in type that fit in the allocated memory.

        Available since OTP 20.2

        @@ -1980,7 +1980,7 @@

        enif_realloc_binary()

        -
        int enif_realloc_binary(ErlNifBinary* bin, size_t size);

        Changes the size of a binary bin. The source binary can be read-only, in which +

        int enif_realloc_binary(ErlNifBinary* bin, size_t size);

        Changes the size of a binary bin. The source binary can be read-only, in which case it is left untouched and a mutable copy is allocated and assigned to *bin.

        Returns true on success, or false if memory allocation failed.

        Available since OTP R13B04

        @@ -1988,14 +1988,14 @@

        enif_release_binary()

        -
        void enif_release_binary(ErlNifBinary* bin);

        Releases a binary obtained from +

        void enif_release_binary(ErlNifBinary* bin);

        Releases a binary obtained from enif_alloc_binary.

        enif_release_resource()

        -
        void enif_release_resource(void* obj);

        Removes a reference to resource object obj obtained from +

        void enif_release_resource(void* obj);

        Removes a reference to resource object obj obtained from enif_alloc_resource. The resource object is destructed when the last reference is removed. Each call to enif_release_resource must correspond to a previous call to @@ -2009,64 +2009,64 @@

        enif_rwlock_create()

        -
        ErlNifRWLock * enif_rwlock_create(char *name);

        Same as erl_drv_rwlock_create.

        Available since OTP R13B04

        +
        ErlNifRWLock * enif_rwlock_create(char *name);

        Same as erl_drv_rwlock_create.

        Available since OTP R13B04

        enif_rwlock_destroy()

        -
        void enif_rwlock_destroy(ErlNifRWLock *rwlck);

        Same as erl_drv_rwlock_destroy.

        Available since OTP R13B04

        +
        void enif_rwlock_destroy(ErlNifRWLock *rwlck);

        Same as erl_drv_rwlock_destroy.

        Available since OTP R13B04

        enif_rwlock_name()

        -
        char* enif_rwlock_name(ErlNifRWLock* rwlck);

        Same as erl_drv_rwlock_name.

        Available since OTP 21.0

        +
        char* enif_rwlock_name(ErlNifRWLock* rwlck);

        Same as erl_drv_rwlock_name.

        Available since OTP 21.0

        enif_rwlock_rlock()

        -
        void enif_rwlock_rlock(ErlNifRWLock *rwlck);

        Same as erl_drv_rwlock_rlock.

        Available since OTP R13B04

        +
        void enif_rwlock_rlock(ErlNifRWLock *rwlck);

        Same as erl_drv_rwlock_rlock.

        Available since OTP R13B04

        enif_rwlock_runlock()

        -
        void enif_rwlock_runlock(ErlNifRWLock *rwlck);

        Same as erl_drv_rwlock_runlock.

        Available since OTP R13B04

        +
        void enif_rwlock_runlock(ErlNifRWLock *rwlck);

        Same as erl_drv_rwlock_runlock.

        Available since OTP R13B04

        enif_rwlock_rwlock()

        -
        void enif_rwlock_rwlock(ErlNifRWLock *rwlck);

        Same as erl_drv_rwlock_rwlock.

        Available since OTP R13B04

        +
        void enif_rwlock_rwlock(ErlNifRWLock *rwlck);

        Same as erl_drv_rwlock_rwlock.

        Available since OTP R13B04

        enif_rwlock_rwunlock()

        -
        void enif_rwlock_rwunlock(ErlNifRWLock *rwlck);

        Same as erl_drv_rwlock_rwunlock.

        Available since OTP R13B04

        +
        void enif_rwlock_rwunlock(ErlNifRWLock *rwlck);

        Same as erl_drv_rwlock_rwunlock.

        Available since OTP R13B04

        enif_rwlock_tryrlock()

        -
        int enif_rwlock_tryrlock(ErlNifRWLock *rwlck);

        Same as erl_drv_rwlock_tryrlock.

        Available since OTP R13B04

        +
        int enif_rwlock_tryrlock(ErlNifRWLock *rwlck);

        Same as erl_drv_rwlock_tryrlock.

        Available since OTP R13B04

        enif_rwlock_tryrwlock()

        -
        int enif_rwlock_tryrwlock(ErlNifRWLock *rwlck);

        Same as erl_drv_rwlock_tryrwlock.

        Available since OTP R13B04

        +
        int enif_rwlock_tryrwlock(ErlNifRWLock *rwlck);

        Same as erl_drv_rwlock_tryrwlock.

        Available since OTP R13B04

        enif_schedule_nif()

        -
        ERL_NIF_TERM enif_schedule_nif(
        +
        ERL_NIF_TERM enif_schedule_nif(
                 ErlNifEnv* caller_env, const char* fun_name, int flags,
        -	ERL_NIF_TERM (*fp)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]),
        -	int argc, const ERL_NIF_TERM argv[]);

        Schedules NIF fp to execute. This function allows an application to break up + ERL_NIF_TERM (*fp)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]), + int argc, const ERL_NIF_TERM argv[]);

        Schedules NIF fp to execute. This function allows an application to break up long-running work into multiple regular NIF calls or to schedule a dirty NIF to execute on a dirty scheduler thread.

        • caller_env - Must be process bound environment of the calling NIF.

        • fun_name - Provides a name for the NIF that is scheduled for execution. @@ -2087,8 +2087,8 @@

          enif_select()

          -
          int enif_select(ErlNifEnv* env, ErlNifEvent event, enum ErlNifSelectFlags mode,
          -	void* obj, const ErlNifPid* pid, ERL_NIF_TERM ref);

          This function can be used to receive asynchronous notifications when OS-specific +

          int enif_select(ErlNifEnv* env, ErlNifEvent event, enum ErlNifSelectFlags mode,
          +	void* obj, const ErlNifPid* pid, ERL_NIF_TERM ref);

          This function can be used to receive asynchronous notifications when OS-specific event objects become ready for either read or write operations.

          Argument event identifies the event object. On Unix systems, the functions select/poll are used. The event object must be a socket, pipe or other file descriptor object that select/poll can use.

          Argument mode describes the type of events to wait for. It can be @@ -2143,14 +2143,14 @@

          to the poll set.

        Note

        Use bitwise AND to test for specific bits in the return value. New significant bits may be added in future releases to give more detailed information for both failed and successful calls. Do NOT use equality tests like ==, as that -may cause your application to stop working.

        Example:

        retval = enif_select(env, fd, ERL_NIF_SELECT_STOP, resource, ref);
        -if (retval < 0) {
        +may cause your application to stop working.

        Example:

        retval = enif_select(env, fd, ERL_NIF_SELECT_STOP, resource, ref);
        +if (retval < 0) {
             /* handle error */
        -}
        +}
         /* Success! */
        -if (retval & ERL_NIF_SELECT_STOP_CALLED) {
        +if (retval & ERL_NIF_SELECT_STOP_CALLED) {
             /* ... */
        -}

        Note

        The mode flag ERL_NIF_SELECT_CANCEL and the return flags +}

        Note

        The mode flag ERL_NIF_SELECT_CANCEL and the return flags ERL_NIF_SELECT_READ_CANCELLED and ERL_NIF_SELECT_WRITE_CANCELLED were introduced in erts-11.0 (OTP-22.0).

        Available since OTP 20.0

        @@ -2164,9 +2164,9 @@

        enif_select_write()

        -
        int enif_select_read(ErlNifEnv* env, ErlNifEvent event, void* obj,
        -      const ErlNifPid* pid, ERL_NIF_TERM msg, ErlNifEnv* msg_env);
        int enif_select_write(ErlNifEnv* env, ErlNifEvent event, void* obj,
        -      const ErlNifPid* pid, ERL_NIF_TERM msg, ErlNifEnv* msg_env);

        These are variants of enif_select where you can supply +

        int enif_select_read(ErlNifEnv* env, ErlNifEvent event, void* obj,
        +      const ErlNifPid* pid, ERL_NIF_TERM msg, ErlNifEnv* msg_env);
        int enif_select_write(ErlNifEnv* env, ErlNifEvent event, void* obj,
        +      const ErlNifPid* pid, ERL_NIF_TERM msg, ErlNifEnv* msg_env);

        These are variants of enif_select where you can supply your own message term msg that will be sent to the process instead of the predefined tuple {select,_,_,_}.

        Argument msg_env must either be NULL or the environment of msg allocated with enif_alloc_env. If argument msg_env is @@ -2184,7 +2184,7 @@

        enif_self()

        -
        ErlNifPid * enif_self(ErlNifEnv* caller_env, ErlNifPid* pid);

        Initializes the ErlNifPid variable at *pid to +

        ErlNifPid * enif_self(ErlNifEnv* caller_env, ErlNifPid* pid);

        Initializes the ErlNifPid variable at *pid to represent the calling process.

        Returns pid if successful, or NULL if caller_env is not a process bound environment.

        Available since OTP R14B

        @@ -2192,8 +2192,8 @@

        enif_send()

        -
        int enif_send(ErlNifEnv* caller_env,
        -      ErlNifPid* to_pid, ErlNifEnv* msg_env, ERL_NIF_TERM msg);

        Sends a message to a process.

        • caller_env - The environment of the calling thread +

          int enif_send(ErlNifEnv* caller_env,
          +      ErlNifPid* to_pid, ErlNifEnv* msg_env, ERL_NIF_TERM msg);

          Sends a message to a process.

          • caller_env - The environment of the calling thread (process bound or callback environment) or NULL if calling from a custom thread not spawned by ERTS.

          • *to_pid - The pid of the receiving process. The pid is to refer to a @@ -2212,8 +2212,8 @@

            enif_set_option()

            -
            int enif_set_option(ErlNifEnv *env, ErlNifOption opt, ...);

            Set an option. On success, zero will be returned. On failure, a non zero value -will be returned. Currently the following options can be set:

            • ERL_NIF_OPT_DELAY_HALT

              enif_set_option(env, ERL_NIF_OPT_DELAY_HALT)

              Enable delay of +

              int enif_set_option(ErlNifEnv *env, ErlNifOption opt, ...);

              Set an option. On success, zero will be returned. On failure, a non zero value +will be returned. Currently the following options can be set:

              • ERL_NIF_OPT_DELAY_HALT

                enif_set_option(env, ERL_NIF_OPT_DELAY_HALT)

                Enable delay of runtime system halt with flushing enabled until all calls to NIFs in the NIF library have returned. If the delay halt feature has not been enabled, a halt with flushing enabled may complete even though processes are still @@ -2243,7 +2243,7 @@

                case typically used to notify processes blocked in NIFs in the library that it is time to return in order to let the runtime system complete the halting. Such NIFs should be dirty NIFs, since ordinary NIFs should never block for a -long time.

              • ERL_NIF_OPT_ON_HALT

                enif_set_option(env, ERL_NIF_OPT_ON_HALT, on_halt)

                Install a callback that will be called when the runtime system halts with +long time.

              • ERL_NIF_OPT_ON_HALT

                enif_set_option(env, ERL_NIF_OPT_ON_HALT, on_halt)

                Install a callback that will be called when the runtime system halts with flushing enabled.

                The runtime system halts when one of the erlang:halt() BIFs are called. By default flushing is enabled, but can be disabled using the erlang:halt/2 BIF. When flushing has been disabled, the runtime system will @@ -2270,7 +2270,7 @@

                returned. The on halt callback is in this case typically used to notify processes blocked in NIFs in the library that it is time to return in order to let the runtime system complete the halting. Such NIFs should be dirty NIFs, -since ordinary NIFs should never block for a long time.

              • ERL_NIF_OPT_ON_UNLOAD_THREAD

                enif_set_option(env, ERL_NIF_OPT_ON_UNLOAD_THREAD, on_unload_thread)

                Install a callback that will be called by each scheduler thread when the +since ordinary NIFs should never block for a long time.

              • ERL_NIF_OPT_ON_UNLOAD_THREAD

                enif_set_option(env, ERL_NIF_OPT_ON_UNLOAD_THREAD, on_unload_thread)

                Install a callback that will be called by each scheduler thread when the module instance that the NIF library belongs to is purged as old. A typical use is to release thread specific data.

                The ERL_NIF_OPT_ON_UNLOAD_THREAD option can only be set during loading of a NIF library inside a call to load() or @@ -2295,22 +2295,22 @@

                enif_set_pid_undefined()

                -
                void enif_set_pid_undefined(ErlNifPid* pid);

                Sets an ErlNifPid variable as undefined. See +

                void enif_set_pid_undefined(ErlNifPid* pid);

                Sets an ErlNifPid variable as undefined. See enif_is_pid_undefined.

                Available since OTP 22.0

                enif_sizeof_resource()

                -
                unsigned enif_sizeof_resource(void* obj);

                Gets the byte size of resource object obj obtained by +

                unsigned enif_sizeof_resource(void* obj);

                Gets the byte size of resource object obj obtained by enif_alloc_resource.

                Available since OTP R13B04

                enif_snprintf()

                -
                int enif_snprintf(char *str, size_t size, const
                -        char *format, ...);

                Similar to snprintf but this format string also accepts "%T", which formats +

                int enif_snprintf(char *str, size_t size, const
                +        char *format, ...);

                Similar to snprintf but this format string also accepts "%T", which formats Erlang terms of type ERL_NIF_TERM.

                This function is primarily intended for debugging purpose. It is not recommended to print very large terms with %T. The function may change errno, even if successful.

                Available since OTP 19.0

                @@ -2319,15 +2319,15 @@

                enif_system_info()

                -
                void enif_system_info(ErlNifSysInfo
                -        *sys_info_ptr, size_t size);

                Same as driver_system_info.

                Available since OTP R13B04

                +
                void enif_system_info(ErlNifSysInfo
                +        *sys_info_ptr, size_t size);

                Same as driver_system_info.

                Available since OTP R13B04

                enif_term_to_binary()

                -
                int enif_term_to_binary(ErlNifEnv *env,
                -        ERL_NIF_TERM term, ErlNifBinary *bin);

                Allocates a new binary with enif_alloc_binary +

                int enif_term_to_binary(ErlNifEnv *env,
                +        ERL_NIF_TERM term, ErlNifBinary *bin);

                Allocates a new binary with enif_alloc_binary and stores the result of encoding term according to the Erlang external term format.

                Returns true on success, or false if the allocation fails.

                See also erlang:term_to_binary/1 and enif_binary_to_term.

                Available since OTP 19.0

                @@ -2336,7 +2336,7 @@

                enif_term_type()

                -
                ErlNifTermType enif_term_type(ErlNifEnv *env, ERL_NIF_TERM term);

                Determines the type of the given term. The term must be an ordinary Erlang term +

                ErlNifTermType enif_term_type(ErlNifEnv *env, ERL_NIF_TERM term);

                Determines the type of the given term. The term must be an ordinary Erlang term and not one of the special terms returned by enif_raise_exception, enif_schedule_nif, or similar.

                The following types are defined at the moment:

                • ERL_NIF_TERM_TYPE_ATOM

                • ERL_NIF_TERM_TYPE_BITSTRING - A bitstring or binary

                • ERL_NIF_TERM_TYPE_FLOAT

                • ERL_NIF_TERM_TYPE_FUN

                • ERL_NIF_TERM_TYPE_INTEGER

                • ERL_NIF_TERM_TYPE_LIST - A list, empty or not

                • ERL_NIF_TERM_TYPE_MAP

                • ERL_NIF_TERM_TYPE_PID

                • ERL_NIF_TERM_TYPE_PORT

                • ERL_NIF_TERM_TYPE_REFERENCE

                • ERL_NIF_TERM_TYPE_TUPLE

                Note that new types may be added in the future, so the caller must be prepared @@ -2346,53 +2346,53 @@

                enif_thread_create()

                -
                int enif_thread_create(char *name,ErlNifTid
                -        *tid,void * (*func)(void *),void *args,ErlNifThreadOpts
                -        *opts);

                Same as erl_drv_thread_create.

                Available since OTP R13B04

                +
                int enif_thread_create(char *name,ErlNifTid
                +        *tid,void * (*func)(void *),void *args,ErlNifThreadOpts
                +        *opts);

                Same as erl_drv_thread_create.

                Available since OTP R13B04

                enif_thread_exit()

                -
                void enif_thread_exit(void *resp);

                Same as erl_drv_thread_exit.

                Available since OTP R13B04

                +
                void enif_thread_exit(void *resp);

                Same as erl_drv_thread_exit.

                Available since OTP R13B04

                enif_thread_join()

                -
                int enif_thread_join(ErlNifTid, void **respp);

                Same as erl_drv_thread_join.

                Available since OTP R13B04

                +
                int enif_thread_join(ErlNifTid, void **respp);

                Same as erl_drv_thread_join.

                Available since OTP R13B04

                enif_thread_name()

                -
                char* enif_thread_name(ErlNifTid tid);

                Same as erl_drv_thread_name.

                Available since OTP 21.0

                +
                char* enif_thread_name(ErlNifTid tid);

                Same as erl_drv_thread_name.

                Available since OTP 21.0

                enif_thread_opts_create()

                -
                ErlNifThreadOpts * enif_thread_opts_create(char *name);

                Same as +

                ErlNifThreadOpts * enif_thread_opts_create(char *name);

                Same as erl_drv_thread_opts_create.

                Available since OTP R13B04

                enif_thread_opts_destroy()

                -
                void enif_thread_opts_destroy(ErlNifThreadOpts *opts);

                Same as +

                void enif_thread_opts_destroy(ErlNifThreadOpts *opts);

                Same as erl_drv_thread_opts_destroy.

                Available since OTP R13B04

                enif_thread_self()

                -
                ErlNifTid enif_thread_self(void);

                Same as erl_drv_thread_self.

                Available since OTP R13B04

                +
                ErlNifTid enif_thread_self(void);

                Same as erl_drv_thread_self.

                Available since OTP R13B04

                enif_thread_type()

                -
                int enif_thread_type(void);

                Determine the type of currently executing thread. A positive value indicates a +

                int enif_thread_type(void);

                Determine the type of currently executing thread. A positive value indicates a scheduler thread while a negative value or zero indicates another type of thread. Currently the following specific types exist (which may be extended in the future):

                • ERL_NIF_THR_UNDEFINED - Undefined thread that is not a scheduler thread.

                • ERL_NIF_THR_NORMAL_SCHEDULER - A normal scheduler thread.

                • ERL_NIF_THR_DIRTY_CPU_SCHEDULER - A dirty CPU scheduler thread.

                • ERL_NIF_THR_DIRTY_IO_SCHEDULER - A dirty I/O scheduler thread.

                Available since OTP 19.0

                @@ -2401,7 +2401,7 @@

                enif_time_offset()

                -
                ErlNifTime enif_time_offset(ErlNifTimeUnit time_unit);

                Returns the current time offset between +

                ErlNifTime enif_time_offset(ErlNifTimeUnit time_unit);

                Returns the current time offset between Erlang monotonic time and Erlang system time converted into the time_unit passed as argument.

                time_unit is the time unit of the returned value.

                Returns ERL_NIF_TIME_ERROR if called with an invalid time unit argument or if @@ -2412,46 +2412,46 @@

                enif_tsd_get()

                -
                void * enif_tsd_get(ErlNifTSDKey key);

                Same as erl_drv_tsd_get.

                Available since OTP R13B04

                +
                void * enif_tsd_get(ErlNifTSDKey key);

                Same as erl_drv_tsd_get.

                Available since OTP R13B04

                enif_tsd_key_create()

                -
                int enif_tsd_key_create(char *name, ErlNifTSDKey *key);

                Same as erl_drv_tsd_key_create.

                Available since OTP R13B04

                +
                int enif_tsd_key_create(char *name, ErlNifTSDKey *key);

                Same as erl_drv_tsd_key_create.

                Available since OTP R13B04

                enif_tsd_key_destroy()

                -
                void enif_tsd_key_destroy(ErlNifTSDKey key);

                Same as erl_drv_tsd_key_destroy.

                Available since OTP R13B04

                +
                void enif_tsd_key_destroy(ErlNifTSDKey key);

                Same as erl_drv_tsd_key_destroy.

                Available since OTP R13B04

                enif_tsd_set()

                -
                void enif_tsd_set(ErlNifTSDKey key, void *data);

                Same as erl_drv_tsd_set.

                Available since OTP R13B04

                +
                void enif_tsd_set(ErlNifTSDKey key, void *data);

                Same as erl_drv_tsd_set.

                Available since OTP R13B04

                enif_vfprintf()

                -
                int enif_vfprintf(FILE *stream, const char *format, va_list ap);

                Equivalent to enif_fprintf except that its called +

                int enif_vfprintf(FILE *stream, const char *format, va_list ap);

                Equivalent to enif_fprintf except that its called with a va_list instead of a variable number of arguments.

                Available since OTP 21.0

                enif_vsnprintf()

                -
                int enif_vsnprintf(char *str, size_t size, const char *format, va_list ap);

                Equivalent to enif_snprintf except that its called +

                int enif_vsnprintf(char *str, size_t size, const char *format, va_list ap);

                Equivalent to enif_snprintf except that its called with a va_list instead of a variable number of arguments.

                Available since OTP 21.0

                enif_whereis_pid()

                -
                int enif_whereis_pid(ErlNifEnv *caller_env,
                -          ERL_NIF_TERM name, ErlNifPid *pid);

                Looks up a process by its registered name.

                • caller_env - The environment of the calling thread +

                  int enif_whereis_pid(ErlNifEnv *caller_env,
                  +          ERL_NIF_TERM name, ErlNifPid *pid);

                  Looks up a process by its registered name.

                  • caller_env - The environment of the calling thread (process bound or callback environment) or NULL if calling from a custom thread not spawned by ERTS.

                  • name - The name of a registered process, as an atom.

                  • *pid - The ErlNifPid in which the resolved @@ -2464,8 +2464,8 @@

                    enif_whereis_port()

                    -
                    int enif_whereis_port(ErlNifEnv *caller_env,
                    -          ERL_NIF_TERM name, ErlNifPort *port);

                    Looks up a port by its registered name.

                    • caller_env - The environment of the calling thread +

                      int enif_whereis_port(ErlNifEnv *caller_env,
                      +          ERL_NIF_TERM name, ErlNifPort *port);

                      Looks up a port by its registered name.

                      • caller_env - The environment of the calling thread (process bound or callback environment) or NULL if calling from a custom thread not spawned by ERTS.

                      • name - The name of a registered port, as an atom.

                      • *port - The ErlNifPort in which the resolved diff --git a/prs/8803/erts-15.0.1/doc/html/erl_prim_loader.html b/prs/8803/erts-15.0.1/doc/html/erl_prim_loader.html index c5d4be6a323ac..4cbdef0c8e210 100644 --- a/prs/8803/erts-15.0.1/doc/html/erl_prim_loader.html +++ b/prs/8803/erts-15.0.1/doc/html/erl_prim_loader.html @@ -412,7 +412,7 @@

                        read_file_info(Filename)

                        Retrieves information about a file.

                        Returns {ok, FileInfo} if successful, otherwise error. FileInfo is a record file_info, defined in the Kernel include file file.hrl. Include the following directive in the module from which the -function is called:

                        -include_lib("kernel/include/file.hrl").

                        For more information about the record see file:read_file_info/2.

                        Filename can also be a file in an archive, for example, +function is called:

                        -include_lib("kernel/include/file.hrl").

                        For more information about the record see file:read_file_info/2.

                        Filename can also be a file in an archive, for example, $OTPROOT/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin/mnesia. For information about archive files, see code.

                        diff --git a/prs/8803/erts-15.0.1/doc/html/erl_tracer.html b/prs/8803/erts-15.0.1/doc/html/erl_tracer.html index 1217f7d755414..f2d5b571e6ffb 100644 --- a/prs/8803/erts-15.0.1/doc/html/erl_tracer.html +++ b/prs/8803/erts-15.0.1/doc/html/erl_tracer.html @@ -149,107 +149,107 @@

                        module, a much more lightweight message tracer is used, which only records who sent messages to who.

                        The following is an example session using it on Linux:

                        $ gcc -I erts-8.0/include/ -fPIC -shared -o erl_msg_tracer.so erl_msg_tracer.c
                         $ erl
                        -Erlang/OTP 19 [DEVELOPMENT] [erts-8.0] [source-ed2b56b] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]
                        +Erlang/OTP 19 [DEVELOPMENT] [erts-8.0] [source-ed2b56b] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]
                         
                        -Eshell V8.0  (abort with ^G)
                        -1> c(erl_msg_tracer), erl_msg_tracer:load().
                        +Eshell V8.0  (abort with ^G)
                        +1> c(erl_msg_tracer), erl_msg_tracer:load().
                         ok
                        -2> Tracer = spawn(fun F() -> receive M -> io:format("~p~n",[M]), F() end end).
                        +2> Tracer = spawn(fun F() -> receive M -> io:format("~p~n",[M]), F() end end).
                         <0.37.0>
                        -3> erlang:trace(new, true, [send,{tracer, erl_msg_tracer, Tracer}]).
                        +3> erlang:trace(new, true, [send,{tracer, erl_msg_tracer, Tracer}]).
                         0
                        -{trace,<0.39.0>,<0.27.0>}
                        -4> {ok, D} = file:open("/tmp/tmp.data",[write]).
                        -{trace,#Port<0.486>,<0.40.0>}
                        -{trace,<0.40.0>,<0.21.0>}
                        -{trace,#Port<0.487>,<0.4.0>}
                        -{trace,#Port<0.488>,<0.4.0>}
                        -{trace,#Port<0.489>,<0.4.0>}
                        -{trace,#Port<0.490>,<0.4.0>}
                        -{ok,<0.40.0>}
                        -{trace,<0.41.0>,<0.27.0>}
                        -5>

                        erl_msg_tracer.erl:

                        -module(erl_msg_tracer).
                        +{trace,<0.39.0>,<0.27.0>}
                        +4> {ok, D} = file:open("/tmp/tmp.data",[write]).
                        +{trace,#Port<0.486>,<0.40.0>}
                        +{trace,<0.40.0>,<0.21.0>}
                        +{trace,#Port<0.487>,<0.4.0>}
                        +{trace,#Port<0.488>,<0.4.0>}
                        +{trace,#Port<0.489>,<0.4.0>}
                        +{trace,#Port<0.490>,<0.4.0>}
                        +{ok,<0.40.0>}
                        +{trace,<0.41.0>,<0.27.0>}
                        +5>

                        erl_msg_tracer.erl:

                        -module(erl_msg_tracer).
                         
                        --export([enabled/3, trace/5, load/0]).
                        +-export([enabled/3, trace/5, load/0]).
                         
                        -load() ->
                        -    erlang:load_nif("erl_msg_tracer", []).
                        +load() ->
                        +    erlang:load_nif("erl_msg_tracer", []).
                         
                        -enabled(_, _, _) ->
                        +enabled(_, _, _) ->
                             error.
                         
                        -trace(_, _, _, _, _) ->
                        +trace(_, _, _, _, _) ->
                             error.

                        erl_msg_tracer.c:

                        #include <erl_nif.h>
                         
                         /* NIF interface declarations */
                        -static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info);
                        -static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info);
                        -static void unload(ErlNifEnv* env, void* priv_data);
                        +static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info);
                        +static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info);
                        +static void unload(ErlNifEnv* env, void* priv_data);
                         
                         /* The NIFs: */
                        -static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
                        -static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
                        +static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
                        +static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
                         
                        -static ErlNifFunc nif_funcs[] = {
                        -    {"enabled", 3, enabled},
                        -    {"trace", 5, trace}
                        -};
                        +static ErlNifFunc nif_funcs[] = {
                        +    {"enabled", 3, enabled},
                        +    {"trace", 5, trace}
                        +};
                         
                        -ERL_NIF_INIT(erl_msg_tracer, nif_funcs, load, NULL, upgrade, unload)
                        +ERL_NIF_INIT(erl_msg_tracer, nif_funcs, load, NULL, upgrade, unload)
                         
                        -static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
                        -{
                        +static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
                        +{
                             *priv_data = NULL;
                             return 0;
                        -}
                        +}
                         
                        -static void unload(ErlNifEnv* env, void* priv_data)
                        -{
                        +static void unload(ErlNifEnv* env, void* priv_data)
                        +{
                         
                        -}
                        +}
                         
                        -static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data,
                        -		   ERL_NIF_TERM load_info)
                        -{
                        -    if (*old_priv_data != NULL || *priv_data != NULL) {
                        +static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data,
                        +		   ERL_NIF_TERM load_info)
                        +{
                        +    if (*old_priv_data != NULL || *priv_data != NULL) {
                         	return -1; /* Don't know how to do that */
                        -    }
                        -    if (load(env, priv_data, load_info)) {
                        +    }
                        +    if (load(env, priv_data, load_info)) {
                         	return -1;
                        -    }
                        +    }
                             return 0;
                        -}
                        +}
                         
                         /*
                          * argv[0]: TraceTag
                          * argv[1]: TracerState
                          * argv[2]: Tracee
                          */
                        -static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
                        -{
                        +static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
                        +{
                             ErlNifPid to_pid;
                        -    if (enif_get_local_pid(env, argv[1], &to_pid))
                        -        if (!enif_is_process_alive(env, &to_pid))
                        -            if (enif_is_identical(enif_make_atom(env, "trace_status"), argv[0]))
                        +    if (enif_get_local_pid(env, argv[1], &to_pid))
                        +        if (!enif_is_process_alive(env, &to_pid))
                        +            if (enif_is_identical(enif_make_atom(env, "trace_status"), argv[0]))
                                         /* tracer is dead so we should remove this tracepoint */
                        -                return enif_make_atom(env, "remove");
                        +                return enif_make_atom(env, "remove");
                                     else
                        -                return enif_make_atom(env, "discard");
                        +                return enif_make_atom(env, "discard");
                         
                             /* Only generate trace for when tracer != tracee */
                        -    if (enif_is_identical(argv[1], argv[2]))
                        -        return enif_make_atom(env, "discard");
                        +    if (enif_is_identical(argv[1], argv[2]))
                        +        return enif_make_atom(env, "discard");
                         
                             /* Only trigger trace messages on 'send' */
                        -    if (enif_is_identical(enif_make_atom(env, "send"), argv[0]))
                        -        return enif_make_atom(env, "trace");
                        +    if (enif_is_identical(enif_make_atom(env, "send"), argv[0]))
                        +        return enif_make_atom(env, "trace");
                         
                             /* Have to answer trace_status */
                        -    if (enif_is_identical(enif_make_atom(env, "trace_status"), argv[0]))
                        -        return enif_make_atom(env, "trace");
                        +    if (enif_is_identical(enif_make_atom(env, "trace_status"), argv[0]))
                        +        return enif_make_atom(env, "trace");
                         
                        -    return enif_make_atom(env, "discard");
                        -}
                        +    return enif_make_atom(env, "discard");
                        +}
                         
                         /*
                          * argv[0]: TraceTag, should only be 'send'
                        @@ -258,20 +258,20 @@ 

                        * argv[3]: Message * argv[4]: Options, map containing Recipient */ -static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{ +static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ ErlNifPid to_pid; ERL_NIF_TERM recipient, msg; - if (enif_get_local_pid(env, argv[1], &to_pid)) { - if (enif_get_map_value(env, argv[4], enif_make_atom(env, "extra"), &recipient)) { - msg = enif_make_tuple3(env, enif_make_atom(env, "trace"), argv[2], recipient); - enif_send(env, &to_pid, NULL, msg); - } - } + if (enif_get_local_pid(env, argv[1], &to_pid)) { + if (enif_get_map_value(env, argv[4], enif_make_atom(env, "extra"), &recipient)) { + msg = enif_make_tuple3(env, enif_make_atom(env, "trace"), argv[2], recipient); + enif_send(env, &to_pid, NULL, msg); + } + } - return enif_make_atom(env, "ok"); -}

                        + return enif_make_atom(env, "ok"); +}

    diff --git a/prs/8803/erts-15.0.1/doc/html/erlang.html b/prs/8803/erts-15.0.1/doc/html/erlang.html index 3e26ee71f7f79..36ce87d1d2dd1 100644 --- a/prs/8803/erts-15.0.1/doc/html/erlang.html +++ b/prs/8803/erts-15.0.1/doc/html/erlang.html @@ -7035,8 +7035,8 @@

    adler32(OldAdler, Data)

    Continues computing the adler32 checksum by combining the previous checksum, -OldAdler, with the checksum of Data.

    The following code:

    X = erlang:adler32(Data1),
    -Y = erlang:adler32(X,Data2).

    assigns the same value to Y as this:

    Y = erlang:adler32([Data1,Data2]).
    +OldAdler, with the checksum of Data.

    The following code:

    X = erlang:adler32(Data1),
    +Y = erlang:adler32(X,Data2).

    assigns the same value to Y as this:

    Y = erlang:adler32([Data1,Data2]).
    @@ -7069,10 +7069,10 @@

    adler32_combine(FirstAdler, SecondAdler, Se

    Combines two previously computed adler32 checksums.

    This computation requires the size of the data object for the second checksum -to be known.

    The following code:

    Y = erlang:adler32(Data1),
    -Z = erlang:adler32(Y,Data2).

    assigns the same value to Z as this:

    X = erlang:adler32(Data1),
    -Y = erlang:adler32(Data2),
    -Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).
    +to be known.

    The following code:

    Y = erlang:adler32(Data1),
    +Z = erlang:adler32(Y,Data2).

    assigns the same value to Z as this:

    X = erlang:adler32(Data1),
    +Y = erlang:adler32(Data2),
    +Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).

    @@ -7129,8 +7129,8 @@

    crc32(OldCrc, Data)

    Continues computing the crc32 checksum by combining the previous checksum, -OldCrc, with the checksum of Data.

    The following code:

    X = erlang:crc32(Data1),
    -Y = erlang:crc32(X,Data2).

    assigns the same value to Y as this:

    Y = erlang:crc32([Data1,Data2]).
    +OldCrc, with the checksum of Data.

    The following code:

    X = erlang:crc32(Data1),
    +Y = erlang:crc32(X,Data2).

    assigns the same value to Y as this:

    Y = erlang:crc32([Data1,Data2]).
    @@ -7163,10 +7163,10 @@

    crc32_combine(FirstCrc, SecondCrc, SecondSi

    Combines two previously computed crc32 checksums.

    This computation requires the size of the data object for the second checksum -to be known.

    The following code:

    Y = erlang:crc32(Data1),
    -Z = erlang:crc32(Y,Data2).

    assigns the same value to Z as this:

    X = erlang:crc32(Data1),
    -Y = erlang:crc32(Data2),
    -Z = erlang:crc32_combine(X,Y,iolist_size(Data2)).
    +to be known.

    The following code:

    Y = erlang:crc32(Data1),
    +Z = erlang:crc32(Y,Data2).

    assigns the same value to Z as this:

    X = erlang:crc32(Data1),
    +Y = erlang:crc32(Data2),
    +Z = erlang:crc32_combine(X,Y,iolist_size(Data2)).

    @@ -8390,11 +8390,11 @@

    nodes(Arg, InfoOpts)

    in the result returned by nodes/0.

  • hidden - The node is connected to the node of the calling process through a hidden connection. That is, the node name would not appear in the result returned by nodes/0.

  • this - This is the node of the calling process.

  • known - The node is not connected but known to the node of the calling -process.

  • Example:

    (a@localhost)1> nodes([this, connected], #{connection_id=>true, node_type=>true}).
    -[{c@localhost,#{connection_id => 13892108,node_type => hidden}},
    - {b@localhost,#{connection_id => 3067553,node_type => visible}},
    - {a@localhost,#{connection_id => undefined,node_type => this}}]
    -(a@localhost)2>
    +process.

    Example:

    (a@localhost)1> nodes([this, connected], #{connection_id=>true, node_type=>true}).
    +[{c@localhost,#{connection_id => 13892108,node_type => hidden}},
    + {b@localhost,#{connection_id => 3067553,node_type => visible}},
    + {a@localhost,#{connection_id => undefined,node_type => this}}]
    +(a@localhost)2>
    @@ -8504,9 +8504,9 @@

    abs(Number)

    Returns an integer or float that is the arithmetical absolute value of Float -or Int.

    For example:

    > abs(-3.33).
    +or Int.

    For example:

    > abs(-3.33).
     3.33
    -> abs(-3).
    +> abs(-3).
     3
    @@ -8538,8 +8538,8 @@

    append_element(Tuple1, Term)

    Returns a new tuple that has one element more than Tuple1, and contains the elements in Tuple1 followed by Term as the last element.

    Semantically equivalent to list_to_tuple(tuple_to_list(Tuple1) ++ [Term]), but much -faster.

    For example:

    > erlang:append_element({one, two}, three).
    -{one,two,three}
    +faster.

    For example:

    > erlang:append_element({one, two}, three).
    +{one,two,three}
    @@ -8606,7 +8606,7 @@

    atom_to_binary(Atom, Encoding)

    representation. If Encoding is utf8 or unicode, the characters are encoded using UTF-8 where characters may require multiple bytes.

    Change

    As from Erlang/OTP 20, atoms can contain any Unicode character and atom_to_binary(Atom, latin1) may fail if the text -representation for Atom contains a Unicode character > 255.

    Example:

    > atom_to_binary('Erlang', latin1).
    +representation for Atom contains a Unicode character > 255.

    Example:

    > atom_to_binary('Erlang', latin1).
     <<"Erlang">>
    @@ -8638,9 +8638,9 @@

    atom_to_list(Atom)

    Returns a list of unicode code points corresponding to the text representation -of Atom.

    For example:

    > atom_to_list('Erlang').
    -"Erlang"
    > atom_to_list('你好').
    -[20320,22909]

    See unicode for how to convert the resulting list to different formats.

    +of Atom.

    For example:

    > atom_to_list('Erlang').
    +"Erlang"
    > atom_to_list('你好').
    +[20320,22909]

    See unicode for how to convert the resulting list to different formats.

    @@ -8678,9 +8678,9 @@

    binary_part(Subject, PosLen)

    Extracts the part of the binary described by PosLen.

    Negative length can be used to extract bytes at the end of a binary.

    For example:

    1> Bin = <<1,2,3,4,5,6,7,8,9,10>>.
    -2> binary_part(Bin,{byte_size(Bin), -5}).
    +2> binary_part(Bin,{byte_size(Bin), -5}).
     <<6,7,8,9,10>>

    Failure: badarg if PosLen in any way references outside the binary.

    Start is zero-based, that is:

    1> Bin = <<1,2,3>>
    -2> binary_part(Bin,{0,2}).
    +2> binary_part(Bin,{0,2}).
     <<1,2>>

    For details about the PosLen semantics, see binary.

    @@ -8788,8 +8788,8 @@

    binary_to_atom(Binary, Encoding)

    garbage collected. Therefore, it is recommended to consider whether binary_to_existing_atom/2 is a better option than binary_to_atom/2. The default limits can be found -in Efficiency Guide (section System Limits).

    Examples:

    > binary_to_atom(<<"Erlang">>, latin1).
    -'Erlang'
    > binary_to_atom(<<1024/utf8>>, utf8).
    +in Efficiency Guide (section System Limits).

    Examples:

    > binary_to_atom(<<"Erlang">>, latin1).
    +'Erlang'
    > binary_to_atom(<<1024/utf8>>, utf8).
     'Ѐ'
    @@ -8902,7 +8902,7 @@

    binary_to_float(Binary)

    -

    Returns the float whose text representation is Binary.

    For example:

    > binary_to_float(<<"2.2017764e+0">>).
    +

    Returns the float whose text representation is Binary.

    For example:

    > binary_to_float(<<"2.2017764e+0">>).
     2.2017764

    The float string format is the same as the format for Erlang float literals except for that underscores are not permitted.

    Failure: badarg if Binary contains a bad representation of a float.

    @@ -8937,7 +8937,7 @@

    binary_to_integer(Binary)

    -

    Returns an integer whose text representation is Binary.

    For example:

    > binary_to_integer(<<"123">>).
    +

    Returns an integer whose text representation is Binary.

    For example:

    > binary_to_integer(<<"123">>).
     123

    binary_to_integer/1 accepts the same string formats as list_to_integer/1.

    Failure: badarg if Binary contains a bad representation of an integer.

    @@ -8971,7 +8971,7 @@

    binary_to_integer(Binary, Base)

    -

    Returns an integer whose text representation in base Base is Binary.

    For example:

    > binary_to_integer(<<"3FF">>, 16).
    +

    Returns an integer whose text representation in base Base is Binary.

    For example:

    > binary_to_integer(<<"3FF">>, 16).
     1023

    binary_to_integer/2 accepts the same string formats as list_to_integer/2.

    Failure: badarg if Binary contains a bad representation of an integer.

    @@ -9070,9 +9070,9 @@

    binary_to_term(Binary)

    Returns an Erlang term that is the result of decoding binary object Binary, which must be encoded according to the -Erlang external term format.

    > Bin = term_to_binary(hello).
    +Erlang external term format.

    > Bin = term_to_binary(hello).
     <<131,100,0,5,104,101,108,108,111>>
    -> hello = binary_to_term(Bin).
    +> hello = binary_to_term(Bin).
     hello

    Warning

    When decoding binaries from untrusted sources, the untrusted source may submit data in a way to create resources, such as atoms and remote references, that cannot be garbage collected and lead to Denial of Service attack. In such @@ -9121,11 +9121,11 @@

    binary_to_term(Binary, Opts)

    (as they are embedded in certain structures, such as process identifiers, refs, and funs), and creation of new external function references. None of those resources are garbage collected, so unchecked creation of them can -exhaust available memory.

    > binary_to_term(<<131,100,0,5,"hello">>, [safe]).
    +exhaust available memory.

    > binary_to_term(<<131,100,0,5,"hello">>, [safe]).
     ** exception error: bad argument
     > hello.
     hello
    -> binary_to_term(<<131,100,0,5,"hello">>, [safe]).
    +> binary_to_term(<<131,100,0,5,"hello">>, [safe]).
     hello

    Warning

    The safe option ensures the data is safely processed by the Erlang runtime but it does not guarantee the data is safe to your application. You must always validate data from untrusted sources. If the binary is stored or @@ -9133,10 +9133,10 @@

    binary_to_term(Binary, Opts)

    cryptographically signing it.

  • used - Changes the return value to {Term, Used} where Used is the number of bytes actually read from Binary.

    > Input = <<131,100,0,5,"hello","world">>.
     <<131,100,0,5,104,101,108,108,111,119,111,114,108,100>>
    -> {Term, Used} = binary_to_term(Input, [used]).
    -{hello, 9}
    -> split_binary(Input, Used).
    -{<<131,100,0,5,104,101,108,108,111>>, <<"world">>}
  • Failure: badarg if safe is specified and unsafe data is decoded.

    See also term_to_binary/1, binary_to_term/1, and list_to_existing_atom/1.

    +>
    {Term, Used} = binary_to_term(Input, [used]). +{hello, 9} +> split_binary(Input, Used). +{<<131,100,0,5,104,101,108,108,111>>, <<"world">>}

    Failure: badarg if safe is specified and unsafe data is decoded.

    See also term_to_binary/1, binary_to_term/1, and list_to_existing_atom/1.

    @@ -9168,9 +9168,9 @@

    bit_size(Bitstring)

    -

    Returns an integer that is the size in bits of Bitstring.

    For example:

    > bit_size(<<433:16,3:3>>).
    +

    Returns an integer that is the size in bits of Bitstring.

    For example:

    > bit_size(<<433:16,3:3>>).
     19
    -> bit_size(<<1,2,3>>).
    +> bit_size(<<1,2,3>>).
     24
    @@ -9202,9 +9202,9 @@

    bitstring_to_list(Bitstring)

    Returns a list of integers corresponding to the bytes of Bitstring.

    If the number of bits in the binary is not divisible by 8, the last element of -the list is a bitstring containing the remaining 1-7 bits.

    For example:

    > bitstring_to_list(<<433:16>>).
    -[1,177]
    > bitstring_to_list(<<433:16,3:3>>).
    -[1,177,<<3:3>>]
    +the list is a bitstring containing the remaining 1-7 bits.

    For example:

    > bitstring_to_list(<<433:16>>).
    +[1,177]
    > bitstring_to_list(<<433:16,3:3>>).
    +[1,177,<<3:3>>]
    @@ -9238,9 +9238,9 @@

    byte_size(Bitstring)

    Returns an integer that is the number of bytes needed to contain Bitstring. That is, if the number of bits in Bitstring is not divisible by 8, the -resulting number of bytes is rounded up.

    For example:

    > byte_size(<<433:16,3:3>>).
    +resulting number of bytes is rounded up.

    For example:

    > byte_size(<<433:16,3:3>>).
     3
    -> byte_size(<<1,2,3>>).
    +> byte_size(<<1,2,3>>).
     3
    @@ -9275,7 +9275,7 @@

    ceil(Number)

    -

    Returns the smallest integer not less than Number.

    For example:

    > ceil(5.5).
    +

    Returns the smallest integer not less than Number.

    For example:

    > ceil(5.5).
     6
    @@ -9385,10 +9385,10 @@

    decode_packet(Type, Bin, Options)

    than the indicated length are truncated.

    Option line_length also applies to http* packet types as an alias for option packet_size if packet_size itself is not set. This use is only intended for backward compatibility.

  • {line_delimiter, 0 =< byte() =< 255} - For packet type line, sets the -delimiting byte. Default is the latin-1 character $\n.

  • Examples:

    > erlang:decode_packet(1,<<3,"abcd">>,[]).
    -{ok,<<"abc">>,<<"d">>}
    -> erlang:decode_packet(1,<<5,"abcd">>,[]).
    -{more,6}
    +delimiting byte. Default is the latin-1 character $\n.

    Examples:

    > erlang:decode_packet(1,<<3,"abcd">>,[]).
    +{ok,<<"abc">>,<<"d">>}
    +> erlang:decode_packet(1,<<5,"abcd">>,[]).
    +{more,6}
    @@ -9419,8 +9419,8 @@

    delete_element(Index, Tuple1)

    -

    Returns a new tuple with element at Index removed from tuple Tuple1.

    For example:

    > erlang:delete_element(2, {one, two, three}).
    -{one,three}
    +

    Returns a new tuple with element at Index removed from tuple Tuple1.

    For example:

    > erlang:delete_element(2, {one, two, three}).
    +{one,three}
    @@ -9482,7 +9482,7 @@

    element(N, Tuple)

    -

    Returns the Nth element (numbering from 1) of Tuple.

    For example:

    > element(2, {a, b, c}).
    +

    Returns the Nth element (numbering from 1) of Tuple.

    For example:

    > element(2, {a, b, c}).
     b
    @@ -9514,10 +9514,10 @@

    external_size(Term)

    Calculates, without doing the encoding, the maximum byte size for a term encoded -in the Erlang external term format.

    The following condition applies always:

    > Size1 = byte_size(term_to_binary(Term)),
    -> Size2 = erlang:external_size(Term),
    +in the Erlang external term format.

    The following condition applies always:

    > Size1 = byte_size(term_to_binary(Term)),
    +> Size2 = erlang:external_size(Term),
     > true = Size1 =< Size2.
    -true

    This is equivalent to a call to:

    erlang:external_size(Term, [])
    +
    true

    This is equivalent to a call to:

    erlang:external_size(Term, [])
    @@ -9556,8 +9556,8 @@

    external_size(Term, Options)

    Calculates, without doing the encoding, the maximum byte size for a term encoded -in the Erlang external term format.

    The following condition applies always:

    > Size1 = byte_size(term_to_binary(Term, Options)),
    -> Size2 = erlang:external_size(Term, Options),
    +in the Erlang external term format.

    The following condition applies always:

    > Size1 = byte_size(term_to_binary(Term, Options)),
    +> Size2 = erlang:external_size(Term, Options),
     > true = Size1 =< Size2.
     true

    Option {minor_version, Version} specifies how floats are encoded. For a detailed description, see term_to_binary/2.

    @@ -9592,7 +9592,7 @@

    float(Number)

    -

    Returns a float by converting Number to a float.

    For example:

    > float(55).
    +

    Returns a float by converting Number to a float.

    For example:

    > float(55).
     55.0

    Note

    If used on the top level in a guard, it tests whether the argument is a floating point number; for clarity, use is_float/1 instead.

    When float/1 is used in an expression in a guard, such as 'float(A) == 4.0', it converts a number as described earlier.

    @@ -9667,17 +9667,17 @@

    float_to_binary(Float, Options)

    Returns a binary corresponding to the text representation of Float using fixed -decimal point formatting.

    Options behaves in the same way as float_to_list/2.

    For example:

    > float_to_binary(7.12, [{decimals, 4}]).
    +decimal point formatting.

    Options behaves in the same way as float_to_list/2.

    For example:

    > float_to_binary(7.12, [{decimals, 4}]).
     <<"7.1200">>
    -> float_to_binary(7.12, [{decimals, 4}, compact]).
    +> float_to_binary(7.12, [{decimals, 4}, compact]).
     <<"7.12">>
    -> float_to_binary(7.12, [{scientific, 3}]).
    +> float_to_binary(7.12, [{scientific, 3}]).
     <<"7.120e+00">>
    -> float_to_binary(7.12, [short]).
    +> float_to_binary(7.12, [short]).
     <<"7.12">>
    -> float_to_binary(0.1+0.2, [short]).
    +> float_to_binary(0.1+0.2, [short]).
     <<"0.30000000000000004">>
    -> float_to_binary(0.1+0.2)
    +> float_to_binary(0.1+0.2)
     <<"3.00000000000000044409e-01">>
    @@ -9758,17 +9758,17 @@

    float_to_list(Float, Options)

    range (-2⁵³, 2⁵³), the notation that yields the smallest number of characters is used (scientific notation or normal decimal notation). Floats outside the range (-2⁵³, 2⁵³) are always formatted using scientific notation to avoid -confusing results when doing arithmetic operations.
  • If Options is [], the function behaves as float_to_list/1.
  • Examples:

    > float_to_list(7.12, [{decimals, 4}]).
    +confusing results when doing arithmetic operations.
  • If Options is [], the function behaves as float_to_list/1.
  • Examples:

    > float_to_list(7.12, [{decimals, 4}]).
     "7.1200"
    -> float_to_list(7.12, [{decimals, 4}, compact]).
    +> float_to_list(7.12, [{decimals, 4}, compact]).
     "7.12"
    -> float_to_list(7.12, [{scientific, 3}]).
    +> float_to_list(7.12, [{scientific, 3}]).
     "7.120e+00"
    -> float_to_list(7.12, [short]).
    +> float_to_list(7.12, [short]).
     "7.12"
    -> float_to_list(0.1+0.2, [short]).
    +> float_to_list(0.1+0.2, [short]).
     "0.30000000000000004"
    -> float_to_list(0.1+0.2)
    +> float_to_list(0.1+0.2)
     "3.00000000000000044409e-01"

    In the last example, float_to_list(0.1+0.2) evaluates to "3.00000000000000044409e-01". The reason for this is explained in Representation of Floating Point Numbers.

    @@ -9805,7 +9805,7 @@

    floor(Number)

    -

    Returns the largest integer not greater than Number.

    For example:

    > floor(-10.5).
    +

    Returns the largest integer not greater than Number.

    For example:

    > floor(-10.5).
     -11
    @@ -9939,17 +9939,17 @@

    fun_to_list(Fun)

    funs are equal as fun_to_list/1 does not take the fun's environment into account. See erlang:fun_info/1 for how to get the environment of a fun.

    Change

    The output of fun_to_list/1 can differ between Erlang -implementations and may change in future versions.

    Examples:

    -module(test).
    --export([add/1, add2/0, fun_tuple/0]).
    -add(A) -> fun(B) -> A + B end.
    -add2() -> fun add/1.
    -fun_tuple() -> {fun() -> 1 end, fun() -> 1 end}.
    > {fun test:add/1, test:add2()}.
    -{fun test:add/1,#Fun<test.1.107738983>}

    Explanation: fun test:add/1 is upgradable but test:add2() is not upgradable.

    > {test:add(1), test:add(42)}.
    -{#Fun<test.0.107738983>,#Fun<test.0.107738983>}

    Explanation: test:add(1) and test:add(42) has the same string representation -as the environment is not taken into account.

    >test:fun_tuple().
    -{#Fun<test.2.107738983>,#Fun<test.3.107738983>}

    Explanation: The string representations differ because the funs come from -different fun expressions.

    > {fun() -> 1 end, fun() -> 1 end}. >
    -{#Fun<erl_eval.45.97283095>,#Fun<erl_eval.45.97283095>}

    Explanation: All funs created from fun expressions of this form in uncompiled +implementations and may change in future versions.

    Examples:

    -module(test).
    +-export([add/1, add2/0, fun_tuple/0]).
    +add(A) -> fun(B) -> A + B end.
    +add2() -> fun add/1.
    +fun_tuple() -> {fun() -> 1 end, fun() -> 1 end}.
    > {fun test:add/1, test:add2()}.
    +{fun test:add/1,#Fun<test.1.107738983>}

    Explanation: fun test:add/1 is upgradable but test:add2() is not upgradable.

    > {test:add(1), test:add(42)}.
    +{#Fun<test.0.107738983>,#Fun<test.0.107738983>}

    Explanation: test:add(1) and test:add(42) has the same string representation +as the environment is not taken into account.

    >test:fun_tuple().
    +{#Fun<test.2.107738983>,#Fun<test.3.107738983>}

    Explanation: The string representations differ because the funs come from +different fun expressions.

    > {fun() -> 1 end, fun() -> 1 end}. >
    +{#Fun<erl_eval.45.97283095>,#Fun<erl_eval.45.97283095>}

    Explanation: All funs created from fun expressions of this form in uncompiled code with the same arity are mapped to the same list by fun_to_list/1.

    @@ -9983,8 +9983,8 @@

    hd(List)

    -

    Returns the head of List, that is, the first element.

    It works with improper lists.

    Examples:

    > hd([1,2,3,4,5]).
    -1
    > hd([first, second, third, so_on | improper_end]).
    +

    Returns the head of List, that is, the first element.

    It works with improper lists.

    Examples:

    > hd([1,2,3,4,5]).
    +1
    > hd([first, second, third, so_on | improper_end]).
     first

    Failure: badarg if List is an empty list [].

    @@ -10019,8 +10019,8 @@

    insert_element(Index, Tuple1, Term)

    Returns a new tuple with element Term inserted at position Index in tuple Tuple1. All elements from position Index and upwards are pushed one step -higher in the new tuple Tuple2.

    For example:

    > erlang:insert_element(2, {one, two, three}, new).
    -{one,new,two,three}
    +higher in the new tuple Tuple2.

    For example:

    > erlang:insert_element(2, {one, two, three}, new).
    +{one,new,two,three}
    @@ -10052,7 +10052,7 @@

    integer_to_binary(Integer)

    -

    Returns a binary corresponding to the text representation of Integer.

    For example:

    > integer_to_binary(77).
    +

    Returns a binary corresponding to the text representation of Integer.

    For example:

    > integer_to_binary(77).
     <<"77">>
    @@ -10086,7 +10086,7 @@

    integer_to_binary(Integer, Base)

    Returns a binary corresponding to the text representation of Integer in base -Base.

    For example:

    > integer_to_binary(1023, 16).
    +Base.

    For example:

    > integer_to_binary(1023, 16).
     <<"3FF">>
    @@ -10117,7 +10117,7 @@

    integer_to_list(Integer)

    -

    Returns a string corresponding to the text representation of Integer.

    For example:

    > integer_to_list(77).
    +

    Returns a string corresponding to the text representation of Integer.

    For example:

    > integer_to_list(77).
     "77"
    @@ -10149,7 +10149,7 @@

    integer_to_list(Integer, Base)

    Returns a string corresponding to the text representation of Integer in base -Base.

    For example:

    > integer_to_list(1023, 16).
    +Base.

    For example:

    > integer_to_list(1023, 16).
     "3FF"
    @@ -10181,7 +10181,7 @@

    iolist_size(Item)

    Returns an integer, that is the size in bytes, of the binary that would be the -result of iolist_to_binary(Item).

    For example:

    > iolist_size([1,2|<<3,4>>]).
    +result of iolist_to_binary(Item).

    For example:

    > iolist_size([1,2|<<3,4>>]).
     4
    @@ -10219,7 +10219,7 @@

    iolist_to_binary(IoListOrBinary)

    <<4,5>> > Bin3 = <<6>>. <<6>> -> iolist_to_binary([Bin1,1,[2,3,Bin2],4|Bin3]). +> iolist_to_binary([Bin1,1,[2,3,Bin2],4|Bin3]). <<1,2,3,1,2,3,4,5,4,6>>
    @@ -10263,16 +10263,16 @@

    iolist_to_iovec(IoListOrBinary)

    >
    Bin3 = <<6>>. <<6>> %% If you pass small binaries and integers it works as iolist_to_binary -> erlang:iolist_to_iovec([Bin1,1,[2,3,Bin2],4|Bin3]). -[<<1,2,3,1,2,3,4,5,4,6>>] +> erlang:iolist_to_iovec([Bin1,1,[2,3,Bin2],4|Bin3]). +[<<1,2,3,1,2,3,4,5,4,6>>] %% If you pass larger binaries, they are split and returned in a form %% optimized for calling the C function writev. -> erlang:iolist_to_iovec([<<1>>,<<2:8096>>,<<3:8096>>]). -[<<1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +> erlang:iolist_to_iovec([<<1>>,<<2:8096>>,<<3:8096>>]). +[<<1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,...>>, <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, ...>>, - <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...>>]
    +
    <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...>>]
    @@ -10632,11 +10632,11 @@

    is_map_key(Key, Map)

    Returns true if map Map contains Key and returns false if it does not -contain the Key.

    The call fails with a {badmap,Map} exception if Map is not a map.

    Example:

    > Map = #{"42" => value}.
    -#{"42" => value}
    -> is_map_key("42",Map).
    +contain the Key.

    The call fails with a {badmap,Map} exception if Map is not a map.

    Example:

    > Map = #{"42" => value}.
    +#{"42" => value}
    +> is_map_key("42",Map).
     true
    -> is_map_key(value,Map).
    +> is_map_key(value,Map).
     false
    @@ -10903,7 +10903,7 @@

    length(List)

    -

    Returns the length of List.

    For example:

    > length([1,2,3,4,5,6,7,8,9]).
    +

    Returns the length of List.

    For example:

    > length([1,2,3,4,5,6,7,8,9]).
     9
    @@ -10943,7 +10943,7 @@

    list_to_atom(String)

    garbage collected. Therefore, it is recommended to consider if list_to_existing_atom/1 is a better option than list_to_atom/1. The default limits can be found in the -Efficiency Guide (section System Limits).

    Example:

    > list_to_atom("Erlang").
    +Efficiency Guide (section System Limits).

    Example:

    > list_to_atom("Erlang").
     'Erlang'
    @@ -10980,7 +10980,7 @@

    list_to_binary(IoList)

    <<4,5>> > Bin3 = <<6>>. <<6>> -> list_to_binary([Bin1,1,[2,3,Bin2],4|Bin3]). +> list_to_binary([Bin1,1,[2,3,Bin2],4|Bin3]). <<1,2,3,1,2,3,4,5,4,6>>
    @@ -11019,7 +11019,7 @@

    list_to_bitstring(BitstringList)

    <<4,5>> > Bin3 = <<6,7:4>>. <<6,7:4>> -> list_to_bitstring([Bin1,1,[2,3,Bin2],4|Bin3]). +> list_to_bitstring([Bin1,1,[2,3,Bin2],4|Bin3]). <<1,2,3,1,2,3,4,5,4,6,7:4>>
    @@ -11088,7 +11088,7 @@

    list_to_float(String)

    -

    Returns the float whose text representation is String.

    For example:

    > list_to_float("2.2017764e+0").
    +

    Returns the float whose text representation is String.

    For example:

    > list_to_float("2.2017764e+0").
     2.2017764

    The float string format is the same as the format for Erlang float literals except for that underscores are not permitted.

    Failure: badarg if String contains a bad representation of a float.

    @@ -11121,9 +11121,9 @@

    list_to_integer(String)

    -

    Returns an integer whose text representation is String.

    For example:

    > list_to_integer("123").
    -123
    > list_to_integer("-123").
    --123
    > list_to_integer("+123234982304982309482093833234234").
    +

    Returns an integer whose text representation is String.

    For example:

    > list_to_integer("123").
    +123
    > list_to_integer("-123").
    +-123
    > list_to_integer("+123234982304982309482093833234234").
     123234982304982309482093833234234

    String must contain at least one digit character and can have an optional prefix consisting of a single "+" or "-" character (that is, String must match the regular expression "^[+-]?[0-9]+$").

    Failure: badarg if String contains a bad representation of an integer.

    @@ -11156,11 +11156,11 @@

    list_to_integer(String, Base)

    -

    Returns an integer whose text representation in base Base is String.

    For example:

    > list_to_integer("3FF", 16).
    -1023
    > list_to_integer("+3FF", 16).
    -1023
    > list_to_integer("3ff", 16).
    -1023
    > list_to_integer("3fF", 16).
    -1023
    > list_to_integer("-3FF", 16).
    +

    Returns an integer whose text representation in base Base is String.

    For example:

    > list_to_integer("3FF", 16).
    +1023
    > list_to_integer("+3FF", 16).
    +1023
    > list_to_integer("3ff", 16).
    +1023
    > list_to_integer("3fF", 16).
    +1023
    > list_to_integer("-3FF", 16).
     -1023

    For example, when Base is 16, String must match the regular expression "^[+-]?([0-9]|[A-F]|[a-f])+$".

    Failure: badarg if String contains a bad representation of an integer.

    @@ -11192,7 +11192,7 @@

    list_to_pid(String)

    -

    Returns a process identifier whose text representation is a String.

    For example:

    > list_to_pid("<0.4.1>").
    +

    Returns a process identifier whose text representation is a String.

    For example:

    > list_to_pid("<0.4.1>").
     <0.4.1>

    Failure: badarg if String contains a bad representation of a process identifier.

    Warning

    This BIF is intended for debugging and is not to be used in application programs.

    @@ -11227,7 +11227,7 @@

    list_to_port(String)

    -

    Returns a port identifier whose text representation is a String.

    For example:

    > list_to_port("#Port<0.4>").
    +

    Returns a port identifier whose text representation is a String.

    For example:

    > list_to_port("#Port<0.4>").
     #Port<0.4>

    Failure: badarg if String contains a bad representation of a port identifier.

    Warning

    This BIF is intended for debugging and is not to be used in application programs.

    @@ -11262,7 +11262,7 @@

    list_to_ref(String)

    -

    Returns a reference whose text representation is a String.

    For example:

    > list_to_ref("#Ref<0.4192537678.4073193475.71181>").
    +

    Returns a reference whose text representation is a String.

    For example:

    > list_to_ref("#Ref<0.4192537678.4073193475.71181>").
     #Ref<0.4192537678.4073193475.71181>

    Failure: badarg if String contains a bad representation of a reference.

    Warning

    This BIF is intended for debugging and is not to be used in application programs.

    @@ -11294,8 +11294,8 @@

    list_to_tuple(List)

    -

    Returns a tuple corresponding to List, for example

    > list_to_tuple([share, ['Ericsson_B', 163]]).
    -{share, ['Ericsson_B', 163]}

    List can contain any Erlang terms.

    +

    Returns a tuple corresponding to List, for example

    > list_to_tuple([share, ['Ericsson_B', 163]]).
    +{share, ['Ericsson_B', 163]}

    List can contain any Erlang terms.

    @@ -11357,8 +11357,8 @@

    make_tuple(Arity, InitialValue)

    Creates a new tuple of the specified Arity, where all elements are -InitialValue.

    For example:

    > erlang:make_tuple(4, []).
    -{[],[],[],[]}
    +InitialValue.

    For example:

    > erlang:make_tuple(4, []).
    +{[],[],[],[]}
    @@ -11394,8 +11394,8 @@

    make_tuple(Arity, DefaultValue, InitList)InitList.

    Each list element in InitList must be a two-tuple, where the first element is a position in the newly created tuple and the second element is any term. If a position occurs more than once in the list, the term corresponding to the last -occurrence is used.

    For example:

    > erlang:make_tuple(5, [], [{2,ignored},{5,zz},{2,aa}]).
    -{[],aa,[],[],zz}
    +occurrence is used.

    For example:

    > erlang:make_tuple(5, [], [{2,ignored},{5,zz},{2,aa}]).
    +{[],aa,[],[],zz}

    @@ -11431,8 +11431,8 @@

    map_get(Key, Map)

    Returns value Value associated with Key if Map contains Key.

    The call fails with a {badmap,Map} exception if Map is not a map, or with a {badkey,Key} exception if no value is associated with Key.

    Example:

    > Key = 1337,
    -  Map = #{42 => value_two,1337 => "value one","a" => 1},
    -  map_get(Key,Map).
    +  Map = #{42 => value_two,1337 => "value one","a" => 1},
    +  map_get(Key,Map).
     "value one"
    @@ -11467,7 +11467,7 @@

    map_size(Map)

    -

    Returns an integer, which is the number of key-value pairs in Map.

    For example:

    > map_size(#{a=>1, b=>2, c=>3}).
    +

    Returns an integer, which is the number of key-value pairs in Map.

    For example:

    > map_size(#{a=>1, b=>2, c=>3}).
     3
    @@ -11550,10 +11550,10 @@

    max(Term1, Term2)

    Returns the largest of Term1 and Term2. If the terms compare equal with the == operator, Term1 is returned.

    The Expressions section contains -descriptions of the == operator and how terms are ordered.

    Examples:

    > max(1, 2).
    -2
    > max(1.0, 1).
    -1.0
    > max(1, 1.0).
    -1
    > max("abc", "b").
    +descriptions of the == operator and how terms are ordered.

    Examples:

    > max(1, 2).
    +2
    > max(1.0, 1).
    +1.0
    > max(1, 1.0).
    +1
    > max("abc", "b").
     "b"

    Change

    Allowed in guards tests from Erlang/OTP 26.

    @@ -11588,10 +11588,10 @@

    min(Term1, Term2)

    Returns the smallest of Term1 and Term2. If the terms compare equal with the == operator, Term1 is returned.

    The Expressions section contains -descriptions of the == operator and how terms are ordered.

    Examples:

    > min(1, 2).
    -1
    > min(1.0, 1).
    -1.0
    > min(1, 1.0).
    -1
    > min("abc", "b").
    +descriptions of the == operator and how terms are ordered.

    Examples:

    > min(1, 2).
    +1
    > min(1.0, 1).
    +1.0
    > min(1, 1.0).
    +1
    > min("abc", "b").
     "abc"

    Change

    Allowed in guards tests from Erlang/OTP 26.

    @@ -11717,7 +11717,7 @@

    pid_to_list(Pid)

    -

    Returns a string corresponding to the text representation of Pid.

    For example:

    > erlang:pid_to_list(self()).
    +

    Returns a string corresponding to the text representation of Pid.

    For example:

    > erlang:pid_to_list(self()).
     "<0.85.0>"

    Note

    The creation for the node is not included in the list representation of Pid. This means that processes in different incarnations of a node with a specific name can get the same list representation.

    @@ -11814,10 +11814,10 @@

    round(Number)

    -

    Returns an integer by rounding Number.

    For example:

    round(42.1).
    -42
    round(5.5).
    -6
    round(-5.5).
    --6
    round(36028797018963969.0).
    +

    Returns an integer by rounding Number.

    For example:

    round(42.1).
    +42
    round(5.5).
    +6
    round(-5.5).
    +-6
    round(36028797018963969.0).
     36028797018963968

    In the last example, round(36028797018963969.0) evaluates to 36028797018963968. The reason for this is that the number 36028797018963969.0 cannot be represented exactly as a float value. Instead, @@ -11857,8 +11857,8 @@

    setelement(Index, Tuple1, Value)

    Returns a tuple that is a copy of argument Tuple1 with the element specified by integer argument Index (the first element is the element with index 1) -replaced by argument Value.

    For example:

    > setelement(2, {10, green, bottles}, red).
    -{10,red,bottles}
    +replaced by argument Value.

    For example:

    > setelement(2, {10, green, bottles}, red).
    +{10,red,bottles}
    @@ -11891,9 +11891,9 @@

    size(Item)

    Returns the number of elements in a tuple or the number of bytes in a binary or -bitstring.

    For example:

    > size({morni, mulle, bwange}).
    +bitstring.

    For example:

    > size({morni, mulle, bwange}).
     3
    -> size(<<11, 22, 33>>).
    +> size(<<11, 22, 33>>).
     3

    For bitstrings, the number of whole bytes is returned. That is, if the number of bits in the bitstring is not divisible by 8, the resulting number of bytes is rounded down.

    See also tuple_size/1, byte_size/1, and bit_size/1.

    @@ -11927,15 +11927,15 @@

    split_binary(Bin, Pos)

    Returns a tuple containing the binaries that are the result of splitting Bin -into two parts at position Pos.

    This is not a destructive operation. After the operation, there are three binaries altogether.

    For example:

    > B = list_to_binary("0123456789").
    +into two parts at position Pos.

    This is not a destructive operation. After the operation, there are three binaries altogether.

    For example:

    > B = list_to_binary("0123456789").
     <<"0123456789">>
    -> byte_size(B).
    +> byte_size(B).
     10
    -> {B1, B2} = split_binary(B,3).
    -{<<"012">>,<<"3456789">>}
    -> byte_size(B1).
    +> {B1, B2} = split_binary(B,3).
    +{<<"012">>,<<"3456789">>}
    +> byte_size(B1).
     3
    -> byte_size(B2).
    +> byte_size(B2).
     7
    @@ -11969,9 +11969,9 @@

    term_to_binary(Term)

    Returns a binary data object that is the result of encoding Term according to the Erlang external term format.

    This can be used for various purposes, for example, writing a term to a file in an efficient way, or sending an Erlang term to some type of communications -channel not supported by distributed Erlang.

    > Bin = term_to_binary(hello).
    +channel not supported by distributed Erlang.

    > Bin = term_to_binary(hello).
     <<131,100,0,5,104,101,108,108,111>>
    -> hello = binary_to_term(Bin).
    +> hello = binary_to_term(Bin).
     hello

    See also binary_to_term/1.

    Note

    There is no guarantee that this function will return the same encoded representation for the same term.

    @@ -12204,10 +12204,10 @@

    tl(List)

    -

    Returns the tail of List, that is, the list minus the first element

    It works with improper lists.

    Examples:

    > tl([geesties, guilies, beasties]).
    -[guilies, beasties]
    > tl([geesties]).
    -[]
    > tl([geesties, guilies, beasties | improper_end]).
    -[guilies, beasties | improper_end]
    > tl([geesties | improper_end]).
    +

    Returns the tail of List, that is, the list minus the first element

    It works with improper lists.

    Examples:

    > tl([geesties, guilies, beasties]).
    +[guilies, beasties]
    > tl([geesties]).
    +[]
    > tl([geesties, guilies, beasties | improper_end]).
    +[guilies, beasties | improper_end]
    > tl([geesties | improper_end]).
     improper_end

    Failure: badarg if List is an empty list [].

    @@ -12240,10 +12240,10 @@

    trunc(Number)

    -

    Truncates the decimals of Number.

    For example:

    > trunc(5.7).
    -5
    > trunc(-5.7).
    --5
    > trunc(5).
    -5
    > trunc(36028797018963969.0).
    +

    Truncates the decimals of Number.

    For example:

    > trunc(5.7).
    +5
    > trunc(-5.7).
    +-5
    > trunc(5).
    +5
    > trunc(36028797018963969.0).
     36028797018963968

    In the last example, trunc(36028797018963969.0) evaluates to 36028797018963968. The reason for this is that the number 36028797018963969.0 cannot be represented exactly as a float value. Instead, @@ -12282,7 +12282,7 @@

    tuple_size(Tuple)

    -

    Returns an integer that is the number of elements in Tuple.

    For example:

    > tuple_size({morni, mulle, bwange}).
    +

    Returns an integer that is the number of elements in Tuple.

    For example:

    > tuple_size({morni, mulle, bwange}).
     3
    @@ -12314,8 +12314,8 @@

    tuple_to_list(Tuple)

    Returns a list corresponding to Tuple. Tuple can contain any Erlang terms. -Example:

    > tuple_to_list({share, {'Ericsson_B', 163}}).
    -[share,{'Ericsson_B',163}]
    +Example:

    > tuple_to_list({share, {'Ericsson_B', 163}}).
    +[share,{'Ericsson_B',163}]
    @@ -12486,27 +12486,27 @@

    alias(Opts)

    unalias/1. This is also the default behaviour if no options are passed or if alias/0 is called.

  • reply - The alias will be automatically deactivated when a reply message sent via the alias is received. The alias can also still be deactivated via a -call to unalias/1.

  • Example:

    server() ->
    +call to unalias/1.

    Example:

    server() ->
         receive
    -        {request, AliasReqId, Request} ->
    -            Result = perform_request(Request),
    -            AliasReqId ! {reply, AliasReqId, Result}
    +        {request, AliasReqId, Request} ->
    +            Result = perform_request(Request),
    +            AliasReqId ! {reply, AliasReqId, Result}
         end,
    -    server().
    +    server().
     
    -client(ServerPid, Request) ->
    -    AliasReqId = alias([reply]),
    -    ServerPid ! {request, AliasReqId, Request},
    +client(ServerPid, Request) ->
    +    AliasReqId = alias([reply]),
    +    ServerPid ! {request, AliasReqId, Request},
         %% Alias will be automatically deactivated if we receive a reply
         %% since we used the 'reply' option...
         receive
    -        {reply, AliasReqId, Result} -> Result
    +        {reply, AliasReqId, Result} -> Result
         after 5000 ->
    -            unalias(AliasReqId),
    +            unalias(AliasReqId),
                 %% Flush message queue in case the reply arrived
                 %% just before the alias was deactivated...
    -            receive {reply, AliasReqId, Result} -> Result
    -            after 0 -> exit(timeout)
    +            receive {reply, AliasReqId, Result} -> Result
    +            after 0 -> exit(timeout)
                 end
         end.

    Note that both the server and the client in this example must be executing on at least OTP 24 systems in order for this to work.

    For more information on process aliases see the @@ -12577,9 +12577,9 @@

    apply(Module, Function, Args)

    Returns the result of applying Function in Module to Args. The applied function must be exported from Module. The arity of the function is the length -of Args.

    For example:

    > apply(lists, reverse, [[a, b, c]]).
    -[c,b,a]
    -> apply(erlang, atom_to_list, ['Erlang']).
    +of Args.

    For example:

    > apply(lists, reverse, [[a, b, c]]).
    +[c,b,a]
    +> apply(erlang, atom_to_list, ['Erlang']).
     "Erlang"

    If the number of arguments are known at compile time, the call is better written as Module:Function(Arg1, Arg2, ..., ArgN).

    Failure: error_handler:undefined_function/3 is called if the applied function is not exported. The error handler can be redefined (see process_flag/2). If @@ -12700,9 +12700,9 @@

    demonitor(MonitorRef, OptionList)

    The returned value is true unless info is part of OptionList.

    demonitor(MonitorRef, []) is equivalent to demonitor(MonitorRef).

    Options:

    • flush - Removes (one) {_, MonitorRef, _, _, _} message, if there is one, from the caller message queue after monitoring has been stopped.

      Calling demonitor(MonitorRef, [flush]) is equivalent to the -following, but more efficient:

      demonitor(MonitorRef),
      +following, but more efficient:

      demonitor(MonitorRef),
       receive
      -    {_, MonitorRef, _, _, _} ->
      +    {_, MonitorRef, _, _, _} ->
               true
       after 0 ->
               true
      @@ -12741,10 +12741,10 @@ 

      erase()

      -

      Returns the process dictionary and deletes it.

      For example:

      > put(key1, {1, 2, 3}),
      -put(key2, [a, b, c]),
      -erase().
      -[{key1,{1,2,3}},{key2,[a,b,c]}]
      +

      Returns the process dictionary and deletes it.

      For example:

      > put(key1, {1, 2, 3}),
      +put(key2, [a, b, c]),
      +erase().
      +[{key1,{1,2,3}},{key2,[a,b,c]}]
    @@ -12777,10 +12777,10 @@

    erase(Key)

    Returns the value Val associated with Key and deletes it from the process dictionary. Returns undefined if no value is associated with Key.

    The average time complexity for the current implementation of this function is O(1) and the worst case time complexity is O(N), where N is the number of -items in the process dictionary.

    For example:

    > put(key1, {merry, lambs, are, playing}),
    -X = erase(key1),
    -{X, erase(key1)}.
    -{{merry,lambs,are,playing},undefined}
    +items in the process dictionary.

    For example:

    > put(key1, {merry, lambs, are, playing}),
    +X = erase(key1),
    +{X, erase(key1)}.
    +{{merry,lambs,are,playing},undefined}
    @@ -12814,14 +12814,14 @@

    error(Reason)

    has happened (for example, a function is called with a parameter that has an incorrect type). See the guide about errors and error handling for additional information. -Example:

    > catch error(foobar).
    -{'EXIT',{foobar,[{shell,apply_fun,3,
    -                        [{file,"shell.erl"},{line,906}]},
    -                 {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,677}]},
    -                 {erl_eval,expr,5,[{file,"erl_eval.erl"},{line,430}]},
    -                 {shell,exprs,7,[{file,"shell.erl"},{line,687}]},
    -                 {shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
    -                 {shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}}
    +Example:

    > catch error(foobar).
    +{'EXIT',{foobar,[{shell,apply_fun,3,
    +                        [{file,"shell.erl"},{line,906}]},
    +                 {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,677}]},
    +                 {erl_eval,expr,5,[{file,"erl_eval.erl"},{line,430}]},
    +                 {shell,exprs,7,[{file,"shell.erl"},{line,687}]},
    +                 {shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
    +                 {shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}}
    @@ -12860,13 +12860,13 @@

    error(Reason, Args)

    has happened (for example, a function is called with a parameter that has an incorrect type). See the guide about errors and error handling for additional information. -Example:

    test.erl:

    -module(test).
    --export([example_fun/2]).
    +Example:

    test.erl:

    -module(test).
    +-export([example_fun/2]).
     
    -example_fun(A1, A2) ->
    -    erlang:error(my_error, [A1, A2]).

    Erlang shell:

    6> c(test).
    -{ok,test}
    -7> test:example_fun(arg1,"this is the second argument").
    +example_fun(A1, A2) ->
    +    erlang:error(my_error, [A1, A2]).

    Erlang shell:

    6> c(test).
    +{ok,test}
    +7> test:example_fun(arg1,"this is the second argument").
     ** exception error: my_error
          in function  test:example_fun/2
              called as test:example_fun(arg1,"this is the second argument")
    @@ -12955,10 +12955,10 @@

    exit(Reason)

    stopped (for example when a message telling a process to stop is received).

    This function differ from error/1,2,3 by causing an exception of a different class and by having a reason that does not include the list of functions from the call stack.

    See the guide about errors and error handling for -additional information.

    Example:

    > exit(foobar).
    +additional information.

    Example:

    > exit(foobar).
     ** exception exit: foobar
    -> catch exit(foobar).
    -{'EXIT',foobar}

    Note

    If a process calls exit(kill) and does not catch the exception, +> catch exit(foobar). +{'EXIT',foobar}

    Note

    If a process calls exit(kill) and does not catch the exception, it will terminate with exit reason kill and also emit exit signals with exit reason kill (not killed) to all linked processes. Such exit signals with exit reason kill can be trapped by the linked processes. Note that this @@ -13169,11 +13169,11 @@

    get()

    Returns the process dictionary as a list of {Key, Val} tuples. The items in -the returned list can be in any order.

    For example:

    > put(key1, merry),
    -put(key2, lambs),
    -put(key3, {are, playing}),
    -get().
    -[{key1,merry},{key2,lambs},{key3,{are,playing}}]
    +the returned list can be in any order.

    For example:

    > put(key1, merry),
    +put(key2, lambs),
    +put(key3, {are, playing}),
    +get().
    +[{key1,merry},{key2,lambs},{key3,{are,playing}}]
    @@ -13206,11 +13206,11 @@

    get(Key)

    Returns the value Val associated with Key in the process dictionary, or undefined if Key does not exist.

    The expected time complexity for the current implementation of this function is O(1) and the worst case time complexity is O(N), where N is the number of -items in the process dictionary.

    For example:

    > put(key1, merry),
    -put(key2, lambs),
    -put({any, [valid, term]}, {are, playing}),
    -get({any, [valid, term]}).
    -{are,playing}
    +items in the process dictionary.

    For example:

    > put(key1, merry),
    +put(key2, lambs),
    +put({any, [valid, term]}, {are, playing}),
    +get({any, [valid, term]}).
    +{are,playing}
    @@ -13243,11 +13243,11 @@

    get_keys()

    Returns a list of all keys present in the process dictionary. The items in the -returned list can be in any order.

    For example:

    > put(dog, {animal,1}),
    -put(cow, {animal,2}),
    -put(lamb, {animal,3}),
    -get_keys().
    -[dog,cow,lamb]
    +returned list can be in any order.

    For example:

    > put(dog, {animal,1}),
    +put(cow, {animal,2}),
    +put(lamb, {animal,3}),
    +get_keys().
    +[dog,cow,lamb]
    @@ -13278,14 +13278,14 @@

    get_keys(Val)

    Returns a list of keys that are associated with the value Val in the process -dictionary. The items in the returned list can be in any order.

    For example:

    > put(mary, {1, 2}),
    -put(had, {1, 2}),
    -put(a, {1, 2}),
    -put(little, {1, 2}),
    -put(dog, {1, 3}),
    -put(lamb, {1, 2}),
    -get_keys({1, 2}).
    -[mary,had,a,little,lamb]
    +dictionary. The items in the returned list can be in any order.

    For example:

    > put(mary, {1, 2}),
    +put(had, {1, 2}),
    +put(a, {1, 2}),
    +put(little, {1, 2}),
    +put(dog, {1, 3}),
    +put(lamb, {1, 2}),
    +get_keys({1, 2}).
    +[mary,had,a,little,lamb]
    @@ -13448,9 +13448,9 @@

    is_process_alive(Pid)

    aliveness of P2 is checked. This guarantee means that one can use is_process_alive/1 to let a process P1 wait until a process P2, which has got an exit signal with reason kill from P1, is -killed.

    For example:

    exit(P2Pid, kill),
    +killed.

    For example:

    exit(P2Pid, kill),
     % P2 might not be killed
    -is_process_alive(P2Pid),
    +is_process_alive(P2Pid),
     % P2 is not alive (the call above always return false)

    See the documentation about signals and erlang:exit/2 for more information about signals and exit signals.

    @@ -13543,7 +13543,7 @@

    monitor(Type, Item)

    Sends a monitor request of type Type to the entity identified by Item.

    If the monitored entity does not exist or it changes monitored state, the caller -of monitor/2 is notified by a message on the following format:

    {Tag, MonitorRef, Type, Object, Info}

    Note

    The monitor request is an asynchronous signal. That is, it takes time before +of monitor/2 is notified by a message on the following format:

    {Tag, MonitorRef, Type, Object, Info}

    Note

    The monitor request is an asynchronous signal. That is, it takes time before the signal reaches its destination.

    Type can be one of the following atoms: process, port or time_offset.

    A process or port monitor is triggered only once, after that it is removed from both monitoring process and the monitored entity. Monitors are fired when the monitored process or port terminates, does not exist at the moment of @@ -13552,7 +13552,7 @@

    monitor(Type, Item)

    demonitor/1 is called.

    A process or port monitor by name resolves the RegisteredName to pid/0 or port/0 only once at the moment of monitor instantiation, later changes to the name registration will not affect the existing monitor.

    When a process or port monitor is triggered, a 'DOWN' message is sent that -has the following pattern:

    {'DOWN', MonitorRef, Type, Object, Info}

    In the monitor message MonitorRef and Type are the same as described +has the following pattern:

    {'DOWN', MonitorRef, Type, Object, Info}

    In the monitor message MonitorRef and Type are the same as described earlier, and:

    • Object - The monitored entity, which triggered the event. When monitoring a process or a local port, Object will be equal to the pid/0 or port/0 that was being monitored. When monitoring process or port by @@ -13596,7 +13596,7 @@

      monitor(Type, Item)

      under normal operation this is to be detected within a minute, but during heavy load it can take longer time.

      The monitor is not automatically removed after it has been triggered. That is, repeated changes of the time offset trigger the monitor repeatedly.

      When the monitor is triggered a 'CHANGE' message is sent to the monitoring -process. A 'CHANGE' message has the following pattern:

      {'CHANGE', MonitorRef, Type, Item, NewTimeOffset}

      where MonitorRef, Type, and Item are the same as described above, and +process. A 'CHANGE' message has the following pattern:

      {'CHANGE', MonitorRef, Type, Item, NewTimeOffset}

      where MonitorRef, Type, and Item are the same as described above, and NewTimeOffset is the new time offset.

      When the 'CHANGE' message has been received you are guaranteed not to retrieve the old time offset when calling erlang:time_offset/0. Notice that you can observe the @@ -13662,25 +13662,25 @@

      monitor(Type, Item, Opts)

      monitor will be automatically removed regardless of whether the response is a reply or a 'DOWN' message. The alias can also still be deactivated via a call to unalias/1. Note that if the alias is removed using -the unalias/1 BIF, the monitor will still be left active.

    Example:

    server() ->
    +the unalias/1 BIF, the monitor will still be left active.

    Example:

    server() ->
         receive
    -        {request, AliasReqId, Request} ->
    -            Result = perform_request(Request),
    -            AliasReqId ! {reply, AliasReqId, Result}
    +        {request, AliasReqId, Request} ->
    +            Result = perform_request(Request),
    +            AliasReqId ! {reply, AliasReqId, Result}
         end,
    -    server().
    +    server().
     
    -client(ServerPid, Request) ->
    -    AliasMonReqId = monitor(process, ServerPid, [{alias, reply_demonitor}]),
    -    ServerPid ! {request, AliasMonReqId, Request},
    +client(ServerPid, Request) ->
    +    AliasMonReqId = monitor(process, ServerPid, [{alias, reply_demonitor}]),
    +    ServerPid ! {request, AliasMonReqId, Request},
         %% Alias as well as monitor will be automatically deactivated if we
         %% receive a reply or a 'DOWN' message since we used 'reply_demonitor'
         %% as unalias option...
         receive
    -        {reply, AliasMonReqId, Result} ->
    +        {reply, AliasMonReqId, Result} ->
                 Result;
    -        {'DOWN', AliasMonReqId, process, ServerPid, ExitReason} ->
    -            error(ExitReason)
    +        {'DOWN', AliasMonReqId, process, ServerPid, ExitReason} ->
    +            error(ExitReason)
         end.

    Note that both the server and the client in this example must be executing on at least OTP 24 systems in order for this to work.

    For more information on process aliases see the Process Aliases section @@ -13690,42 +13690,42 @@

    monitor(Type, Item, Opts)

    in the down message will be replaced by UserDefinedTag.

    An example of how the {tag, UserDefinedTag} option can be used in order to enable the new selective receive optimization, -introduced in OTP 24, when making multiple requests to different servers:

    server() ->
    +introduced in OTP 24, when making multiple requests to different servers:

    server() ->
         receive
    -        {request, From, ReqId, Request} ->
    -            Result = perform_request(Request),
    -            From ! {reply, self(), ReqId, Result}
    +        {request, From, ReqId, Request} ->
    +            Result = perform_request(Request),
    +            From ! {reply, self(), ReqId, Result}
         end,
    -    server().
    -
    -client(ServerPids, Request) when is_list(ServerPids) ->
    -    ReqId = make_ref(),
    -    lists:foreach(fun (ServerPid) ->
    -                          _ = monitor(process, ServerPid,
    -                                      [{tag, {'DOWN', ReqId}}]),
    -                          ServerPid ! {request, self(), ReqId, Request}
    +    server().
    +
    +client(ServerPids, Request) when is_list(ServerPids) ->
    +    ReqId = make_ref(),
    +    lists:foreach(fun (ServerPid) ->
    +                          _ = monitor(process, ServerPid,
    +                                      [{tag, {'DOWN', ReqId}}]),
    +                          ServerPid ! {request, self(), ReqId, Request}
                       end,
    -                  ServerPids),
    -    receive_replies(ReqId, length(ServerPids), []).
    +                  ServerPids),
    +    receive_replies(ReqId, length(ServerPids), []).
     
    -receive_replies(_ReqId, 0, Acc) ->
    +receive_replies(_ReqId, 0, Acc) ->
         Acc;
    -receive_replies(ReqId, N, Acc) ->
    +receive_replies(ReqId, N, Acc) ->
         %% The compiler will detect that we match on the 'ReqId'
         %% reference in all clauses, and will enable the selective
         %% receive optimization which makes the receive able to
         %% skip past all messages present in the message queue at
         %% the time when the 'ReqId' reference was created...
         Res = receive
    -              {reply, ServerPid, ReqId, Result} ->
    +              {reply, ServerPid, ReqId, Result} ->
                       %% Here we typically would have deactivated the
                       %% monitor by a call to demonitor(Mon, [flush]) but
                       %% we ignore this in this example for simplicity...
    -                  {ok, ServerPid, Result};
    -              {{'DOWN', ReqId}, _Mon, process, ServerPid, ExitReason} ->
    -                  {error, ServerPid, ExitReason}
    +                  {ok, ServerPid, Result};
    +              {{'DOWN', ReqId}, _Mon, process, ServerPid, ExitReason} ->
    +                  {error, ServerPid, ExitReason}
               end,
    -    receive_replies(ReqId, N-1, [Res | Acc]).

    In order for this example to work as intended, the client must be executing on + receive_replies(ReqId, N-1, [Res | Acc]).

    In order for this example to work as intended, the client must be executing on at least an OTP 24 system, but the servers may execute on older systems.

    @@ -14467,7 +14467,7 @@

    process_flag(Flag, Value)

    Sets the process flag indicated to the specified value. Returns the previous value -of the flag.

    Flag is one of the following:

    • process_flag(async_dist, boolean())

      Enable or disable fully asynchronous distributed signaling for the calling +of the flag.

      Flag is one of the following:

      • process_flag(async_dist, boolean())

        Enable or disable fully asynchronous distributed signaling for the calling process. When disabled, which is the default, the process sending a distributed signal will block in the send operation if the buffer for the distribution channel reach the distribution buffer busy limit. The @@ -14492,14 +14492,14 @@

        process_flag(Flag, Value)

        command line argument +pad <boolean> when starting the runtime system. If the +pad <boolean> command line argument is not passed, the default value of the async_dist flag will be false.

        You can inspect the state of the async_dist process flag of a process by -calling process_info(Pid, async_dist).

      • process_flag(trap_exit, boolean())

        When trap_exit is set to true, exit signals arriving to a process are +calling process_info(Pid, async_dist).

      • process_flag(trap_exit, boolean())

        When trap_exit is set to true, exit signals arriving to a process are converted to {'EXIT', From, Reason} messages, which can be received as ordinary messages. If trap_exit is set to false, the process exits if it receives an exit signal other than normal and the exit signal is propagated to -its linked processes. Application processes are normally not to trap exits.

        See also exit/2.

      • process_flag(error_handler, module())

        Used by a process to redefine the error_handler for undefined function calls and +its linked processes. Application processes are normally not to trap exits.

        See also exit/2.

      • process_flag(error_handler, module())

        Used by a process to redefine the error_handler for undefined function calls and undefined registered processes. Use this flag with substantial caution, as code -auto-loading depends on the correct operation of the error handling module.

      • process_flag(fullsweep_after,  non_neg_integer())

        Changes the maximum number of generational collections before forcing a -fullsweep for the calling process.

      • process_flag(min_heap_size, non_neg_integer())

        Changes the minimum heap size for the calling process.

      • process_flag(min_bin_vheap_size, non_neg_integer())

        Changes the minimum binary virtual heap size for the calling process.

      • process_flag(max_heap_size, max_heap_size())

        This flag sets the maximum heap size for the calling process. If MaxHeapSize +auto-loading depends on the correct operation of the error handling module.

      • process_flag(fullsweep_after,  non_neg_integer())

        Changes the maximum number of generational collections before forcing a +fullsweep for the calling process.

      • process_flag(min_heap_size, non_neg_integer())

        Changes the minimum heap size for the calling process.

      • process_flag(min_bin_vheap_size, non_neg_integer())

        Changes the minimum binary virtual heap size for the calling process.

      • process_flag(max_heap_size, max_heap_size())

        This flag sets the maximum heap size for the calling process. If MaxHeapSize is an integer, the system default values for kill and error_logger are used.

        For details on how the heap grows, see Sizing the heap in the ERTS internal documentation.

        • size - The maximum size in words of the process. If set to zero, the @@ -14535,7 +14535,7 @@

          process_flag(Flag, Value)

          memory that is used during the garbage collection. When contemplating using this option, it is recommended to first run it in production with kill set to false and inspect the log events to see what the normal peak sizes of the -processes in the system is and then tune the value accordingly.

        • process_flag(message_queue_data, message_queue_data())

          Determines how messages in the message queue are stored, as follows:

          • off_heap - All messages in the message queue will be stored outside +processes in the system is and then tune the value accordingly.

          • process_flag(message_queue_data, message_queue_data())

            Determines how messages in the message queue are stored, as follows:

            • off_heap - All messages in the message queue will be stored outside the process heap. This implies that no messages in the message queue will be part of a garbage collection of the process.

            • on_heap - All messages in the message queue will eventually be placed on the process heap. They can, however, be temporarily stored off the heap. This @@ -14547,7 +14547,7 @@

              process_flag(Flag, Value)

              consume large amounts of memory. The performance of the actual message passing is, however, generally better when the flag value is on_heap.

              Changing the flag value causes any existing messages to be moved. The move operation is initiated, but not necessarily completed, by the time the function -returns.

            • process_flag(priority, priority_level())

              Sets the process priority. Level is an atom. Four priority levels exist: +returns.

            • process_flag(priority, priority_level())

              Sets the process priority. Level is an atom. Four priority levels exist: low, normal, high, and max. Default is normal.

              Note

              Priority level max is reserved for internal use in the Erlang runtime system, and is not to be used by others.

              Internally in each priority level, processes are scheduled in a round robin fashion.

              Execution of processes on priority normal and low are interleaved. Processes @@ -14576,7 +14576,7 @@

              process_flag(Flag, Value)

              are used, use them with care, especially priority high. A process on priority high is only to perform work for short periods. Busy looping for long periods in a high priority process causes most likely problems, as important -OTP servers run on priority normal.

            • process_flag(save_calls, 0..10000)

              N must be an integer in the interval 0..10000. If N > 0, call saving is made +OTP servers run on priority normal.

            • process_flag(save_calls, 0..10000)

              N must be an integer in the interval 0..10000. If N > 0, call saving is made active for the process. This means that information about the N most recent global function calls, BIF calls, sends, and receives made by the process are saved in a list, which can be retrieved with @@ -14585,7 +14585,7 @@

              process_flag(Flag, Value)

              amount of information is saved, as follows:

              • A tuple {Module, Function, Arity} for function calls
              • The atoms send, 'receive', and timeout for sends and receives ('receive' when a message is received and timeout when a receive times out)

              If N = 0, call saving is disabled for the process, which is the default. -Whenever the size of the call saving list is set, its contents are reset.

            • process_flag(sensitive, boolean())

              Sets or clears flag sensitive for the current process. When a process has been +Whenever the size of the call saving list is set, its contents are reset.

            • process_flag(sensitive, boolean())

              Sets or clears flag sensitive for the current process. When a process has been marked as sensitive by calling process_flag(sensitive, true), features in the runtime system that can be used for examining the data or inner working of the process @@ -14844,8 +14844,8 @@

              processes()

              currently existing on the local node.

              Notice that an exiting process exists, but is not alive. That is, is_process_alive/1 returns false for an exiting process, but its process identifier is part of the result returned from -processes/0.

              Example:

              > processes().
              -[<0.0.0>,<0.2.0>,<0.4.0>,<0.5.0>,<0.7.0>,<0.8.0>]
              +processes/0.

              Example:

              > processes().
              +[<0.0.0>,<0.2.0>,<0.4.0>,<0.5.0>,<0.7.0>,<0.8.0>]
              @@ -14879,10 +14879,10 @@

              put(Key, Val)

              returns undefined. If Key exists, the old value is deleted and replaced by Val, and the function returns the old value.

              The average time complexity for the current implementation of this function is O(1) and the worst case time complexity is O(N), where N is the number of -items in the process dictionary.

              For example:

              > X = put(name, walrus), Y = put(name, carpenter),
              -Z = get(name),
              -{X, Y, Z}.
              -{undefined,walrus,carpenter}

              Note

              The values stored when put is evaluated within the scope of a catch are +items in the process dictionary.

              For example:

              > X = put(name, walrus), Y = put(name, carpenter),
              +Z = get(name),
              +{X, Y, Z}.
              +{undefined,walrus,carpenter}

              Note

              The values stored when put is evaluated within the scope of a catch are not retracted if a throw is evaluated, or if an error occurs.

              @@ -14965,7 +14965,7 @@

              register(RegName, PidOrPort)

              name registry. RegName, which must be an atom, can be used instead of the pid or port identifier in send operator (RegName ! Message) and most other BIFs that take -a pid or port identifies as an argument.

              For example:

              > register(db, Pid).
              +a pid or port identifies as an argument.

              For example:

              > register(db, Pid).
               true

              The registered name is considered a Directly Visible Erlang Resource and is automatically unregistered when the process terminates.

              Failures:

              • badarg - If PidOrPort is not an existing local process or port.

              • badarg - If RegName is already in use.

              • badarg - If the process or port is already registered (already has a @@ -14999,8 +14999,8 @@

                registered()

                -

                Returns a list of names that have been registered using register/2.

                For example:

                > registered().
                -[code_server, file_server, init, user, my_db]
                +

                Returns a list of names that have been registered using register/2.

                For example:

                > registered().
                +[code_server, file_server, init, user, my_db]
                @@ -15067,7 +15067,7 @@

                self()

                -

                Returns the process identifier of the calling process.

                For example:

                > self().
                +

                Returns the process identifier of the calling process.

                For example:

                > self().
                 <0.26.0>
                @@ -15331,7 +15331,7 @@

                spawn(Module, Function, Args)

                (see process_flag/2). If error_handler is undefined, or the user has redefined the default error_handler and its replacement is undefined, a failure with reason undef -occurs.

                Example:

                > spawn(speed, regulator, [high_speed, thin_cut]).
                +occurs.

                Example:

                > spawn(speed, regulator, [high_speed, thin_cut]).
                 <0.13.1>
                @@ -16323,14 +16323,14 @@

                throw(Any)

                Raises an exception of class throw. Intended to be used to do non-local returns from functions.

                If evaluated within a catch expression, the -catch expression returns value Any.

                For example:

                > catch throw({hello, there}).
                -        {hello,there}

                If evaluated within a try-block of a +catch expression returns value Any.

                For example:

                > catch throw({hello, there}).
                +        {hello,there}

                If evaluated within a try-block of a try expression, the value Any can be caught within the catch block.

                For example:

                try
                -    throw({my_exception, "Something happened"})
                +    throw({my_exception, "Something happened"})
                 catch
                -    throw:{my_exception, Desc} ->
                -        io:format(standard_error, "Error: ~s~n", [Desc])
                +    throw:{my_exception, Desc} ->
                +        io:format(standard_error, "Error: ~s~n", [Desc])
                 end

                Failure: nocatch if not caught by an exception handler.

                See the guide about errors and error handling for additional information.

                @@ -16412,9 +16412,9 @@

                unlink(Id)

                result of the link, but may also be the result of the unlikee sending the caller an exit signal by calling the exit/2 BIF. Therefore, it may or may not be appropriate to clean up the message queue after a call to -unlink(Id) as follows, when trapping exits:

                unlink(Id),
                +unlink(Id) as follows, when trapping exits:

                unlink(Id),
                 receive
                -    {'EXIT', Id, _} ->
                +    {'EXIT', Id, _} ->
                         true
                 after 0 ->
                         true
                @@ -16455,7 +16455,7 @@ 

                unregister(RegName)

                Removes the registered name RegName associated with a process identifier or a port identifier from the -name registry.

                For example:

                > unregister(db).
                +name registry.

                For example:

                > unregister(db).
                 true

                Keep in mind that you can still receive signals associated with the registered name after it has been unregistered as the sender may have looked up the name before sending to it.

                Users are advised not to unregister system processes.

                Failure: badarg if RegName is not a registered name.

                @@ -16491,7 +16491,7 @@

                whereis(RegName)

                Returns the process identifier or port identifier with the registered name RegName from the name registry. Returns -undefined if the name is not registered.

                For example:

                > whereis(db).
                +undefined if the name is not registered.

                For example:

                > whereis(db).
                 <0.43.0>
                @@ -16570,7 +16570,7 @@

                halt()

                -

                Equivalent to calling halt(0, []).

                For example:

                > halt().
                +

                Equivalent to calling halt(0, []).

                For example:

                > halt().
                 os_prompt%
                @@ -16603,7 +16603,7 @@

                halt(HaltType)

                -

                Equivalent to calling halt(HaltType, []).

                For example:

                > halt(17).
                +

                Equivalent to calling halt(HaltType, []).

                For example:

                > halt(17).
                 os_prompt% echo $?
                 17
                 os_prompt%
                @@ -16640,7 +16640,7 @@

                halt/2

                -

                Halt the runtime system.

                • halt(Status :: non_neg_integer(), Options :: halt_options())

                  Halt the runtime system with status code Status.

                  Note

                  On many platforms, the OS supports only status codes 0-255. A too large +

                  Halt the runtime system.

                  • halt(Status :: non_neg_integer(), Options :: halt_options())

                    Halt the runtime system with status code Status.

                    Note

                    On many platforms, the OS supports only status codes 0-255. A too large status code is truncated by clearing the high bits.

                    Currently the following options are valid:

                    • {flush, EnableFlushing} - If EnableFlushing equals true, which also is the default behavior, the runtime system will perform the following operations before terminating:

                      • Flush all outstanding output.
                      • Send all Erlang ports exit signals and wait for them to exit.
                      • Wait for all async threads to complete all outstanding async jobs.
                      • Call all installed NIF on halt callbacks.
                      • Wait for all ongoing @@ -16657,10 +16657,10 @@

                        halt/2

                        with the exit code 255. If flushing is not enabled, the timeout will have no effect on the system.

                        See also the erl +zhft <Timeout> command line flag. Note that the shortest timeout set by the command line flag and the -flush_timeout option will be the actual timeout value in effect.

                        Since: OTP 27.0

                    • halt(Abort :: abort, Options :: halt_options())

                      Halt the Erlang runtime system by aborting and produce a core dump if core +flush_timeout option will be the actual timeout value in effect.

                      Since: OTP 27.0

                  • halt(Abort :: abort, Options :: halt_options())

                    Halt the Erlang runtime system by aborting and produce a core dump if core dumping has been enabled in the environment that the runtime system is executing in.

                    Note

                    The {flush, boolean()} option will be ignored, and -flushing will be disabled.

                  • halt(CrashDumpSlogan :: string(), Options :: halt_options())

                    Halt the Erlang runtime system and generate an +flushing will be disabled.

                • halt(CrashDumpSlogan :: string(), Options :: halt_options())

                  Halt the Erlang runtime system and generate an Erlang crash dump. The string CrashDumpSlogan will be used as slogan in the Erlang crash dump created. The slogan will be trunkated if CrashDumpSlogan is longer than 1023 characters.

                  Note

                  The {flush, boolean()} option will be ignored, and @@ -16851,11 +16851,11 @@

                  statistics(Item)

                  -

                  Returns statistics about the current system.

                  The possible flags are:

                  • statistics(active_tasks) -> [non_neg_integer()]

                    Returns the same as +

                    Returns statistics about the current system.

                    The possible flags are:

                    • statistics(active_tasks) -> [non_neg_integer()]

                      Returns the same as statistics(active_tasks_all) with the exception that no information about the dirty IO run queue and its associated schedulers is part of the result. That is, only tasks that are -expected to be CPU bound are part of the result.

                      Available since OTP 18.3

                    • statistics(active_tasks_all) -> [non_neg_integer()]

                      Returns a list where each element represents the amount of active processes and +expected to be CPU bound are part of the result.

                      Available since OTP 18.3

                    • statistics(active_tasks_all) -> [non_neg_integer()]

                      Returns a list where each element represents the amount of active processes and ports on each run queue and its associated schedulers. That is, the number of processes and ports that are ready to run, or are currently running. Values for normal run queues and their associated schedulers are located first in the @@ -16877,11 +16877,11 @@

                      statistics(Item)

                      statistics(run_queue_lengths_all), statistics(total_run_queue_lengths), and -statistics(total_run_queue_lengths_all).

                      Available since OTP 20.0

                    • statistics(context_switches) -> {non_neg_integer(), 0}

                      Returns the total number of context switches since the system started.

                    • statistics(exact_reductions) -> {Total :: non_neg_integer(), SinceLastCall :: non_neg_integer()}

                      Returns the number of exact reductions.

                      Note

                      statistics(exact_reductions) is a more expensive operation -than statistics(reductions).

                    • statistics(garbage_collection) ->
                      -  { NumerOfGCs :: non_neg_integer(), WordsReclaimed :: non_neg_integer(), 0}

                      Returns information about garbage collection, for example:

                      > statistics(garbage_collection).
                      -{85,23961,0}

                      This information can be invalid for some implementations.

                    • statistics(io) -> {{input, non_neg_integer()}, {output, non_neg_integer()}}

                      Returns Input, which is the total number of bytes received through ports, and -Output, which is the total number of bytes output to ports.

                    • statistics(microstate_accounting) -> [MSAcc_Thread]

                      Microstate accounting can be used to measure how much time the Erlang runtime +statistics(total_run_queue_lengths_all).

                      Available since OTP 20.0

                    • statistics(context_switches) -> {non_neg_integer(), 0}

                      Returns the total number of context switches since the system started.

                    • statistics(exact_reductions) -> {Total :: non_neg_integer(), SinceLastCall :: non_neg_integer()}

                      Returns the number of exact reductions.

                      Note

                      statistics(exact_reductions) is a more expensive operation +than statistics(reductions).

                    • statistics(garbage_collection) ->
                      +  { NumerOfGCs :: non_neg_integer(), WordsReclaimed :: non_neg_integer(), 0}

                      Returns information about garbage collection, for example:

                      > statistics(garbage_collection).
                      +{85,23961,0}

                      This information can be invalid for some implementations.

                    • statistics(io) -> {{input, non_neg_integer()}, {output, non_neg_integer()}}

                      Returns Input, which is the total number of bytes received through ports, and +Output, which is the total number of bytes output to ports.

                    • statistics(microstate_accounting) -> [MSAcc_Thread]

                      Microstate accounting can be used to measure how much time the Erlang runtime system spends doing various tasks. It is designed to be as lightweight as possible, but some overhead exists when this is enabled. Microstate accounting is meant to be a profiling tool to help finding performance bottlenecks. To @@ -16890,23 +16890,23 @@

                      statistics(Item)

                      representing some of the OS threads within ERTS. Each map contains type and id fields that can be used to identify what thread it is, and also a counters field that contains data about how much time has been spent in the various -states.

                      Example:

                      > erlang:statistics(microstate_accounting).
                      -[#{counters => #{aux => 1899182914,
                      +states.

                      Example:

                      > erlang:statistics(microstate_accounting).
                      +[#{counters => #{aux => 1899182914,
                                        check_io => 2605863602,
                                        emulator => 45731880463,
                                        gc => 1512206910,
                                        other => 5421338456,
                                        port => 221631,
                      -                 sleep => 5150294100},
                      +                 sleep => 5150294100},
                          id => 1,
                      -   type => scheduler}|...]

                      The time unit is the same as returned by os:perf_counter/0. So, to convert it -to milliseconds, you can do something like this:

                      lists:map(
                      -  fun(#{ counters := Cnt } = M) ->
                      -         MsCnt = maps:map(fun(_K, PerfCount) ->
                      -                                    erlang:convert_time_unit(PerfCount, perf_counter, 1000)
                      -                           end, Cnt),
                      -         M#{ counters := MsCnt }
                      -  end, erlang:statistics(microstate_accounting)).

                      Notice that these values are not guaranteed to be the exact time spent in each + type => scheduler}|...]

                      The time unit is the same as returned by os:perf_counter/0. So, to convert it +to milliseconds, you can do something like this:

                      lists:map(
                      +  fun(#{ counters := Cnt } = M) ->
                      +         MsCnt = maps:map(fun(_K, PerfCount) ->
                      +                                    erlang:convert_time_unit(PerfCount, perf_counter, 1000)
                      +                           end, Cnt),
                      +         M#{ counters := MsCnt }
                      +  end, erlang:statistics(microstate_accounting)).

                      Notice that these values are not guaranteed to be the exact time spent in each state. This is because of various optimisation done to keep the overhead as small as possible.

                      MSAcc_Thread_Types:

                      • scheduler - The main execution threads that do most of the work. See erl +S for more details.

                      • dirty_cpu_scheduler - The threads for long running cpu intensive work. @@ -16938,20 +16938,20 @@

                        statistics(Item)

                        statistics.

                        Returns undefined if system flag microstate_accounting is turned off.

                        The list of thread information is unsorted and can appear in different order -between calls.

                        Note

                        The threads and states are subject to change without any prior notice.

                        Available since OTP 19.0

                      • statistics(reductions) -> {Reductions :: non_neg_integer(), SinceLastCall :: non_neg_integer()}

                        Returns information about reductions, for example:

                        > statistics(reductions).
                        -{2046,11}

                        Change

                        As from ERTS 5.5 (Erlang/OTP R11B), this value does not include reductions +between calls.

                        Note

                        The threads and states are subject to change without any prior notice.

                        Available since OTP 19.0

                      • statistics(reductions) -> {Reductions :: non_neg_integer(), SinceLastCall :: non_neg_integer()}

                        Returns information about reductions, for example:

                        > statistics(reductions).
                        +{2046,11}

                        Change

                        As from ERTS 5.5 (Erlang/OTP R11B), this value does not include reductions performed in current time slices of currently scheduled processes. If an exact value is wanted, use -statistics(exact_reductions).

                      • statistics(run_queue) -> non_neg_integer()

                        Returns the total length of all normal and dirty CPU run queues. That is, queued +statistics(exact_reductions).

                • statistics(run_queue) -> non_neg_integer()

                  Returns the total length of all normal and dirty CPU run queues. That is, queued work that is expected to be CPU bound. The information is gathered atomically. That is, the result is a consistent snapshot of the state, but this operation is much more expensive compared to statistics(total_run_queue_lengths), -especially when a large amount of schedulers is used.

                • statistics(run_queue_lengths) -> [non_neg_integer()]

                  Returns the same as +especially when a large amount of schedulers is used.

                • statistics(run_queue_lengths) -> [non_neg_integer()]

                  Returns the same as statistics(run_queue_lengths_all) with the exception that no information about the dirty IO run queue is part of the result. That is, only run queues with work that is expected to be CPU bound -is part of the result.

                  Available since OTP 18.3

                • statistics(run_queue_lengths_all) -> [non_neg_integer()]

                  Returns a list where each element represents the amount of processes and ports +is part of the result.

                  Available since OTP 18.3

                • statistics(run_queue_lengths_all) -> [non_neg_integer()]

                  Returns a list where each element represents the amount of processes and ports ready to run for each run queue. Values for normal run queues are located first in the resulting list. The first element corresponds to the normal run queue of scheduler number 1 and so on. If support for dirty schedulers exist, values for @@ -16971,13 +16971,13 @@

                  statistics(Item)

                  statistics(active_tasks), statistics(active_tasks_all), and statistics(total_active_tasks), -statistics(total_active_tasks_all).

                  Available since OTP 20.0

                • statistics(runtime) -> {Total :: non_neg_integer(), SinceLastCall :: non_neg_integer()}

                  Returns information about runtime, in milliseconds.

                  This is the sum of the runtime for all threads in the Erlang runtime system and +statistics(total_active_tasks_all).

                  Available since OTP 20.0

                • statistics(runtime) -> {Total :: non_neg_integer(), SinceLastCall :: non_neg_integer()}

                  Returns information about runtime, in milliseconds.

                  This is the sum of the runtime for all threads in the Erlang runtime system and can therefore be greater than the wall clock time.

                  Warning

                  This value might wrap due to limitations in the underlying functionality -provided by the operating system that is used.

                  Example:

                  > statistics(runtime).
                  -{1690,1620}
                • statistics(scheduler_wall_time) ->
                  -  [{Id :: pos_integer,
                  -    ActiveTime :: non_neg_integer(),
                  -    TotalTime :: non_neg_integer()}] |
                  +provided by the operating system that is used.

                  Example:

                  > statistics(runtime).
                  +{1690,1620}
                • statistics(scheduler_wall_time) ->
                  +  [{Id :: pos_integer,
                  +    ActiveTime :: non_neg_integer(),
                  +    TotalTime :: non_neg_integer()}] |
                     undefined

                  Returns information describing how much time normal and dirty CPU schedulers in the @@ -17017,52 +17017,52 @@

                  statistics(Item)

                  This fact has to be taken under consideration when evaluating the result returned.

                  You can use scheduler_wall_time to calculate scheduler utilization. First you take a sample of the values returned by -erlang:statistics(scheduler_wall_time).

                  > erlang:system_flag(scheduler_wall_time, true).
                  +erlang:statistics(scheduler_wall_time).

                  > erlang:system_flag(scheduler_wall_time, true).
                   false
                  -> Ts0 = lists:sort(erlang:statistics(scheduler_wall_time)), ok.
                  +> Ts0 = lists:sort(erlang:statistics(scheduler_wall_time)), ok.
                   ok

                  Some time later the user takes another snapshot and calculates scheduler -utilization per scheduler, for example:

                  > Ts1 = lists:sort(erlang:statistics(scheduler_wall_time)), ok.
                  +utilization per scheduler, for example:

                  > Ts1 = lists:sort(erlang:statistics(scheduler_wall_time)), ok.
                   ok
                  -> lists:map(fun({{I, A0, T0}, {I, A1, T1}}) ->
                  -        {I, (A1 - A0)/(T1 - T0)} end, lists:zip(Ts0,Ts1)).
                  -[{1,0.9743474730177548},
                  - {2,0.9744843782751444},
                  - {3,0.9995902361669045},
                  - {4,0.9738012596572161},
                  - {5,0.9717956667018103},
                  - {6,0.9739235846420741},
                  - {7,0.973237033077876},
                  - {8,0.9741297293248656}]

                  Using the same snapshots to calculate a total scheduler utilization:

                  > {A, T} = lists:foldl(fun({{_, A0, T0}, {_, A1, T1}}, {Ai,Ti}) ->
                  -        {Ai + (A1 - A0), Ti + (T1 - T0)} end, {0, 0}, lists:zip(Ts0,Ts1)),
                  +> lists:map(fun({{I, A0, T0}, {I, A1, T1}}) ->
                  +        {I, (A1 - A0)/(T1 - T0)} end, lists:zip(Ts0,Ts1)).
                  +[{1,0.9743474730177548},
                  + {2,0.9744843782751444},
                  + {3,0.9995902361669045},
                  + {4,0.9738012596572161},
                  + {5,0.9717956667018103},
                  + {6,0.9739235846420741},
                  + {7,0.973237033077876},
                  + {8,0.9741297293248656}]

                  Using the same snapshots to calculate a total scheduler utilization:

                  > {A, T} = lists:foldl(fun({{_, A0, T0}, {_, A1, T1}}, {Ai,Ti}) ->
                  +        {Ai + (A1 - A0), Ti + (T1 - T0)} end, {0, 0}, lists:zip(Ts0,Ts1)),
                     TotalSchedulerUtilization = A/T.
                   0.9769136803764825

                  Total scheduler utilization will equal 1.0 when all schedulers have been active all the time between the two measurements.

                  Another (probably more) useful value is to calculate total scheduler utilization -weighted against maximum amount of available CPU time:

                  > WeightedSchedulerUtilization = (TotalSchedulerUtilization
                  -                                  * (erlang:system_info(schedulers)
                  -                                     + erlang:system_info(dirty_cpu_schedulers)))
                  -                                 / erlang:system_info(logical_processors_available).
                  +weighted against maximum amount of available CPU time:

                  > WeightedSchedulerUtilization = (TotalSchedulerUtilization
                  +                                  * (erlang:system_info(schedulers)
                  +                                     + erlang:system_info(dirty_cpu_schedulers)))
                  +                                 / erlang:system_info(logical_processors_available).
                   0.9769136803764825

                  This weighted scheduler utilization will reach 1.0 when schedulers are active the same amount of time as maximum available CPU time. If more schedulers exist than available logical processors, this value may be greater than 1.0.

                  As of ERTS version 9.0, the Erlang runtime system will as default have more schedulers than logical processors. This due to the dirty schedulers.

                  Note

                  scheduler_wall_time is by default disabled. To enable it, use -erlang:system_flag(scheduler_wall_time, true).

                  Available since OTP R15B01

                • statistics(scheduler_wall_time_all) ->
                  -  [{Id :: pos_integer,
                  -    ActiveTime :: non_neg_integer(),
                  -    TotalTime :: non_neg_integer()}] |
                  +erlang:system_flag(scheduler_wall_time, true).

                  Available since OTP R15B01

                • statistics(scheduler_wall_time_all) ->
                  +  [{Id :: pos_integer,
                  +    ActiveTime :: non_neg_integer(),
                  +    TotalTime :: non_neg_integer()}] |
                     undefined

                  Equivalent to statistics(scheduler_wall_time), except that it also include information about all dirty I/O schedulers.

                  Dirty IO schedulers will have scheduler identifiers in the range erlang:system_info(schedulers)+erlang:system_info(dirty_cpu_schedulers)< SchedulerId =< erlang:system_info(schedulers) + erlang:system_info(dirty_cpu_schedulers) +erlang:system_info(dirty_io_schedulers).

                  Note

                  Note that work executing on dirty I/O schedulers are expected to mainly wait for I/O. That is, when you get high scheduler utilization on dirty I/O -schedulers, CPU utilization is not expected to be high due to this work.

                  Available since OTP 20.0

                • statistics(total_active_tasks) -> non_neg_integer()

                  Equivalent to calling +schedulers, CPU utilization is not expected to be high due to this work.

                  Available since OTP 20.0

                • statistics(total_active_tasks) -> non_neg_integer()

                  Equivalent to calling lists:sum(statistics(active_tasks)), -but more efficient.

                  Available since OTP 18.3

                • statistics(total_active_tasks_all) -> non_neg_integer()

                  Equivalent to calling +but more efficient.

                  Available since OTP 18.3

                • statistics(total_active_tasks_all) -> non_neg_integer()

                  Equivalent to calling lists:sum(statistics(active_tasks_all)), -but more efficient.

                  Available since OTP 20.0

                • statistics(total_run_queue_lengths) -> non_neg_integer()

                  Equivalent to calling +but more efficient.

                  Available since OTP 20.0

                • statistics(total_run_queue_lengths) -> non_neg_integer()

                  Equivalent to calling lists:sum(statistics(run_queue_lengths)), -but more efficient.

                  Available since OTP 18.3

                • statistics(total_run_queue_lengths_all) -> non_neg_integer()

                  Equivalent to calling +but more efficient.

                  Available since OTP 18.3

                • statistics(total_run_queue_lengths_all) -> non_neg_integer()

                  Equivalent to calling lists:sum(statistics(run_queue_lengths_all)), -but more efficient.

                  Available since OTP 20.0

                • statistics(wall_clock) -> {Total :: non_neg_integer(), SinceLastCall :: non_neg_integer()}

                  Returns information about wall clock. wall_clock can be used in the same +but more efficient.

                  Available since OTP 20.0

                • statistics(wall_clock) -> {Total :: non_neg_integer(), SinceLastCall :: non_neg_integer()}

                  Returns information about wall clock. wall_clock can be used in the same manner as runtime, except that real time is measured as opposed to runtime or CPU time.

                @@ -17136,9 +17136,9 @@

                system_flag(Flag, Value)

                -

                Sets a system flag to the given value.

                The possible flags to set are:

                • system_flag(backtrace_depths, non_neg_integer()) -> non_neg_integer()

                  Sets the maximum depth of call stack back-traces in the exit reason element of +

                  Sets a system flag to the given value.

                  The possible flags to set are:

                  • system_flag(backtrace_depths, non_neg_integer()) -> non_neg_integer()

                    Sets the maximum depth of call stack back-traces in the exit reason element of 'EXIT' tuples. The flag also limits the stacktrace depth returned by -process_info/2 item current_stacktrace.

                    Returns the old value of the flag.

                  • system_flag(cpu_topology, cpu_topology()) -> cpu_topology()

                    Warning

                    This argument is deprecated. Instead of using this argument, use +process_info/2 item current_stacktrace.

                    Returns the old value of the flag.

                  • system_flag(cpu_topology, cpu_topology()) -> cpu_topology()

                    Warning

                    This argument is deprecated. Instead of using this argument, use command-line argument +sct in erl.

                    When this argument is removed, a final CPU topology to use is determined at emulator boot time.

                    Sets the user-defined CpuTopology. The user-defined CPU topology overrides any automatically detected CPU topology. By passing undefined as CpuTopology, @@ -17150,7 +17150,7 @@

                    system_flag(Flag, Value)

                    +sct to erl.

                    For information on type CpuTopology and more, see erlang:system_info(cpu_topology) as well as command-line flags +sct and -+sbt in erl.

                  • system_flag(dirty_cpu_schedulers_online, pos_integer()) -> pos_integer()

                    Sets the number of dirty CPU schedulers online. Range is ++sbt in erl.

                  • system_flag(dirty_cpu_schedulers_online, pos_integer()) -> pos_integer()

                    Sets the number of dirty CPU schedulers online. Range is 1 <= DirtyCPUSchedulersOnline <= N, where N is the smallest of the return values of erlang:system_info(dirty_cpu_schedulers) and erlang:system_info(schedulers_online).

                    Returns the old value of the flag.

                    The number of dirty CPU schedulers online can change if the number of schedulers @@ -17162,31 +17162,31 @@

                    system_flag(Flag, Value)

                    of schedulers online.

                    For more information, see erlang:system_info(dirty_cpu_schedulers) and -erlang:system_info(dirty_cpu_schedulers_online).

                    Available since OTP 17.0

                  • system_flag(erts_alloc, {Alloc :: atom(), F :: atom(), V :: integer()}) ->
                    +erlang:system_info(dirty_cpu_schedulers_online).

                    Available since OTP 17.0

                  • system_flag(erts_alloc, {Alloc :: atom(), F :: atom(), V :: integer()}) ->
                       ok | notsup

                    Sets system flags for erts_alloc(3). Alloc is the allocator to affect, for example binary_alloc. F is the flag to change and V is the new value.

                    Only a subset of all erts_alloc flags can be changed at run time. This subset -is currently only the flag sbct.

                    Returns ok if the flag was set or notsup if not supported by erts_alloc.

                    Available since OTP 20.2.3

                  • system_flag(fullsweep_after, non_neg_integer()) -> non_neg_integer()

                    Sets system flag fullsweep_after. Number is a non-negative integer +is currently only the flag sbct.

                    Returns ok if the flag was set or notsup if not supported by erts_alloc.

                    Available since OTP 20.2.3

                  • system_flag(fullsweep_after, non_neg_integer()) -> non_neg_integer()

                    Sets system flag fullsweep_after. Number is a non-negative integer indicating how many times generational garbage collections can be done without forcing a fullsweep collection. The value applies to new processes, while processes already running are not affected.

                    Returns the old value of the flag.

                    In low-memory systems (especially without virtual memory), setting the value to 0 can help to conserve memory.

                    This value can also be set through (OS) environment variable -ERL_FULLSWEEP_AFTER.

                  • system_flag(microstate_accounting, true | false | reset) -> boolean()

                    Turns on/off microstate accounting measurements. When passing reset, all +ERL_FULLSWEEP_AFTER.

                  • system_flag(microstate_accounting, true | false | reset) -> boolean()

                    Turns on/off microstate accounting measurements. When passing reset, all counters are reset to 0.

                    For more information see -statistics(microstate_accounting).

                    Available since OTP 19.0

                  • system_flag(min_heap_size, non_neg_integer()) -> non_neg_integer()

                    Sets the default minimum heap size for processes. The size is specified in +statistics(microstate_accounting).

                    Available since OTP 19.0

                  • system_flag(min_heap_size, non_neg_integer()) -> non_neg_integer()

                    Sets the default minimum heap size for processes. The size is specified in words. The new min_heap_size effects only processes spawned after the change of min_heap_size has been made. min_heap_size can be set for individual -processes by using spawn_opt/4 or process_flag/2.

                    Returns the old value of the flag.

                  • system_flag(min_bin_vheap_size, non_neg_integer()) -> non_neg_integer()

                    Sets the default minimum binary virtual heap size for processes. The size is +processes by using spawn_opt/4 or process_flag/2.

                    Returns the old value of the flag.

                  • system_flag(min_bin_vheap_size, non_neg_integer()) -> non_neg_integer()

                    Sets the default minimum binary virtual heap size for processes. The size is specified in words. The new min_bin_vhheap_size effects only processes spawned after the change of min_bin_vheap_size has been made. min_bin_vheap_size can be set for individual processes by using spawn_opt/2,3,4 or -process_flag/2.

                    Returns the old value of the flag.

                    Available since OTP R13B04

                  • system_flag(max_heap_size, max_heap_size()) -> max_heap_size()

                    Sets the default maximum heap size settings for processes. The size is specified +process_flag/2.

                    Returns the old value of the flag.

                    Available since OTP R13B04

                  • system_flag(max_heap_size, max_heap_size()) -> max_heap_size()

                    Sets the default maximum heap size settings for processes. The size is specified in words. The new max_heap_size effects only processes spawned after the change has been made. max_heap_size can be set for individual processes using spawn_opt/2,3,4 or process_flag/2.

                    Returns the old value of the flag.

                    For details on how the heap grows, see Sizing the heap in the ERTS internal -documentation.

                    Available since OTP 19.0

                  • system_flag(multi_scheduling, BlockState) -> OldBlockState when
                    +documentation.

                    Available since OTP 19.0

                  • system_flag(multi_scheduling, BlockState) -> OldBlockState when
                       BlockState :: block | unblock | block_normal | unblock_normal,
                       OldBlockState :: blocked | disabled | enabled

                    If multi-scheduling is enabled, more than one scheduler thread is used by the emulator. Multi-scheduling can be blocked in two different ways. Either all @@ -17215,7 +17215,7 @@

                    system_flag(Flag, Value)

                    erlang:system_info(multi_scheduling), erlang:system_info(normal_multi_scheduling_blockers), erlang:system_info(multi_scheduling_blockers), -and erlang:system_info(schedulers).

                  • system_flag(outstanding_system_requests_limit, 1..134217727) -> 1..134217727

                    Sets a limit on the amount of outstanding requests made by a system process +and erlang:system_info(schedulers).

                  • system_flag(outstanding_system_requests_limit, 1..134217727) -> 1..134217727

                    Sets a limit on the amount of outstanding requests made by a system process orchestrating system wide changes. Currently there are two such processes:

                    • The Code Purger - The code purger orchestrates checking of references to old code before old code is removed from the system.

                    • The Literal Area Collector - The literal area collector orchestrates copying of references from old literal areas before removal of such areas from @@ -17226,8 +17226,8 @@

                      system_flag(Flag, Value)

                      quickly as possible at the same time as other work will be interleaved with this work. Currently used limit can be checked by calling erlang:system_info(outstanding_system_requests_limit).

                      This limit can also be set by passing the command line argument -+zosrl <Limit> to erl.

                      Available since OTP 24.2

                    • system_flag(scheduler_bind_type, scheduler_bind_type() | default_bind) ->
                      -  scheduler_bind_type()

                      Warning

                      This argument is deprecated. Instead of using this argument, use ++zosrl <Limit> to erl.

                      Available since OTP 24.2

                    • system_flag(scheduler_bind_type, scheduler_bind_type() | default_bind) ->
                      +  scheduler_bind_type()

                      Warning

                      This argument is deprecated. Instead of using this argument, use command-line argument +sbt in erl. When this argument is removed, a final scheduler bind type to use is determined at emulator boot time.

                      Controls if and how schedulers are bound to logical processors.

                      When erlang:system_flag(scheduler_bind_type, How) is called, an asynchronous @@ -17261,7 +17261,7 @@

                      system_flag(Flag, Value)

                      erlang:system_info(scheduler_bind_type), erlang:system_info(scheduler_bindings), as well as command-line flags +sbt and -+sct in erl.

                    • system_flag(scheduler_wall_time, boolean()) -> boolean()

                      Try enable or disable scheduler wall time measurements by passing Boolean as ++sct in erl.

                    • system_flag(scheduler_wall_time, boolean()) -> boolean()

                      Try enable or disable scheduler wall time measurements by passing Boolean as either true or false.

                      For more information about how to use scheduler wall time measurements, see statistics(scheduler_wall_time).

                      Scheduler wall time measurements has a node global state. It is either enabled for all processes on the node or disabled for all processes. Each process has a @@ -17273,7 +17273,7 @@

                      system_flag(Flag, Value)

                      counter will also disappear. To ensure scheduler_wall_time is kept enabled, the process that enabled it must therefore be kept alive.

                      Returns the old value of the node global state, true if scheduler wall time measurements were enabled, false if it were disabled.

                      Scheduler wall time measurements do consume some cpu overhead and should not be -left turned on unless used.

                      Available since OTP R15B01

                    • system_flag(schedulers_online, pos_integer()) -> pos_integer()

                      Sets the number of schedulers online. Range is +left turned on unless used.

                      Available since OTP R15B01

                    • system_flag(schedulers_online, pos_integer()) -> pos_integer()

                      Sets the number of schedulers online. Range is 1 <= SchedulersOnline <= erlang:system_info(schedulers).

                      Returns the old value of the flag.

                      If the emulator was built with support for dirty schedulers, changing the number of schedulers online can also change the number of dirty CPU @@ -17284,23 +17284,23 @@

                      system_flag(Flag, Value)

                      dirty CPU schedulers online increases proportionally to increases in the number of schedulers online.

                      For more information, see erlang:system_info(schedulers) and -erlang:system_info(schedulers_online).

                    • system_flag(system_logger, logger | undefined | pid()) -> logger | undefined | pid()

                      Sets the process that will receive the logging messages generated by ERTS. If +erlang:system_info(schedulers_online).

                    • system_flag(system_logger, logger | undefined | pid()) -> logger | undefined | pid()

                      Sets the process that will receive the logging messages generated by ERTS. If set to undefined, all logging messages generated by ERTS will be dropped. The -messages will be in the format:

                      {log,Level,Format,ArgList,Metadata} where
                      -
                      -Level = atom(),
                      -Format = string(),
                      -ArgList = list(term()),
                      -Metadata = #{ pid => pid(),
                      -   group_leader => pid(),
                      -   time := logger:timestamp(),
                      -   error_logger := #{ emulator := true, tag := atom() }

                      If the system_logger process dies, this flag will be reset to logger.

                      The default is the process named logger.

                      Returns the old value of the flag.

                      Note

                      This function is designed to be used by the KERNEL logger. Be careful if +messages will be in the format:

                      {log,Level,Format,ArgList,Metadata} where
                      +
                      +Level = atom(),
                      +Format = string(),
                      +ArgList = list(term()),
                      +Metadata = #{ pid => pid(),
                      +   group_leader => pid(),
                      +   time := logger:timestamp(),
                      +   error_logger := #{ emulator := true, tag := atom() }

                      If the system_logger process dies, this flag will be reset to logger.

                      The default is the process named logger.

                      Returns the old value of the flag.

                      Note

                      This function is designed to be used by the KERNEL logger. Be careful if you change it to something else as log messages may be lost. If you want to intercept emulator log messages, do it by adding a specialized handler to the -KERNEL logger.

                      Available since OTP 21.2

                    • system_flag(trace_control_word, non_neg_integer()) -> non_neg_integer()

                      Sets the value of the node trace control word to TCW, which is to be an +KERNEL logger.

                      Available since OTP 21.2

                    • system_flag(trace_control_word, non_neg_integer()) -> non_neg_integer()

                      Sets the value of the node trace control word to TCW, which is to be an unsigned integer. For more information, see function set_tcw in section "Match Specifications in Erlang" -in the User's Guide.

                      Returns the old value of the flag.

                    • system_flag(time_offset, finalize) -> preliminary | final | volatile

                      Finalizes the time offset when +in the User's Guide.

                      Returns the old value of the flag.

                    • system_flag(time_offset, finalize) -> preliminary | final | volatile

                      Finalizes the time offset when single time warp mode is used. If another time warp mode is used, the time offset state is left unchanged.

                      Returns the old state identifier, that is:

                      • If preliminary is returned, finalization was performed and the time offset is now final.
                      • If final is returned, the time offset was already in the final state. This @@ -17512,14 +17512,14 @@

                        system_info(Item)

                        allocated by the emulator. Some values are part of other values, and some memory areas are not part of the result. For information about the total amount of memory allocated by the emulator, see -erlang:memory/0,1.

                      • allocator - Returns

                        {Allocator :: undefined | glibc,
                        - Version :: [non_neg_integer()],
                        - Features :: [atom()],
                        - Settings :: [{Subsystem :: atom(),
                        -               [{Parameter :: atom(),
                        -                 Value :: term()}]
                        -               }]
                        -}

                        where

                        • allocator - Returns

                          {Allocator :: undefined | glibc,
                          + Version :: [non_neg_integer()],
                          + Features :: [atom()],
                          + Settings :: [{Subsystem :: atom(),
                          +               [{Parameter :: atom(),
                          +                 Value :: term()}]
                          +               }]
                          +}

                          where

                          • Allocator corresponds to the malloc() implementation used. If Allocator equals undefined, the malloc() implementation used cannot be identified. glibc can be identified.
                          • Version is a list of integers (but not a string) representing the version of the malloc() implementation used.
                          • Features is a list of atoms representing the allocation features used.
                          • Settings is a list of subsystems, their configurable parameters, and used @@ -18415,8 +18415,8 @@

                            date()

                            Returns the current date as {Year, Month, Day}.

                            The time zone and Daylight Saving Time correction depend on the underlying OS. The return value is based on the -OS System Time.

                            For example:

                            > date().
                            -{1995,2,19}
                            +OS System Time.

                            For example:

                            > date().
                            +{1995,2,19}
                            @@ -18445,8 +18445,8 @@

                            localtime()

                            Returns the current local date and time, -{{Year, Month, Day}, {Hour, Minute, Second}}.

                            For example:

                            > erlang:localtime().
                            -{{1996,11,6},{14,45,17}}

                            The time zone and Daylight Saving Time correction depend on the underlying OS. +{{Year, Month, Day}, {Hour, Minute, Second}}.

                            For example:

                            > erlang:localtime().
                            +{{1996,11,6},{14,45,17}}

                            The time zone and Daylight Saving Time correction depend on the underlying OS. The return value is based on the OS System Time.

                            @@ -18481,8 +18481,8 @@

                            localtime_to_universaltime(Localtime)

                            Converts local date and time to Universal Time Coordinated (UTC), if supported by the underlying OS. Otherwise no conversion is done and Localtime is -returned.

                            For example:

                            > erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}).
                            -{{1996,11,6},{13,45,17}}

                            Failure: badarg if Localtime denotes an invalid date and time.

                            +returned.

                            For example:

                            > erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}).
                            +{{1996,11,6},{13,45,17}}

                            Failure: badarg if Localtime denotes an invalid date and time.

                            @@ -18519,12 +18519,12 @@

                            localtime_to_universaltime(Localtime, IsDst Time is active.

                            If IsDst == true, Localtime is during Daylight Saving Time, if IsDst == false it is not. If IsDst == undefined, the underlying OS can guess, which is the same as calling -erlang:localtime_to_universaltime(Localtime).

                            Examples:

                            > erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}, true).
                            -{{1996,11,6},{12,45,17}}
                            -> erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}, false).
                            -{{1996,11,6},{13,45,17}}
                            -> erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}, undefined).
                            -{{1996,11,6},{13,45,17}}

                            Failure: badarg if Localtime denotes an invalid date and time.

                            +erlang:localtime_to_universaltime(Localtime).

                            Examples:

                            > erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}, true).
                            +{{1996,11,6},{12,45,17}}
                            +> erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}, false).
                            +{{1996,11,6},{13,45,17}}
                            +> erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}, undefined).
                            +{{1996,11,6},{13,45,17}}

                            Failure: badarg if Localtime denotes an invalid date and time.

                            @@ -18952,8 +18952,8 @@

                            time()

                            Returns the current time as {Hour, Minute, Second}.

                            The time zone and Daylight Saving Time correction depend on the underlying OS. The return value is based on the -OS System Time.

                            For example:

                            > time().
                            -{9,42,44}
                            +OS System Time.

                            For example:

                            > time().
                            +{9,42,44}
                            @@ -19066,12 +19066,12 @@

                            timestamp()

                            The reason for the existence of erlang:timestamp() is purely to simplify use for existing code that assumes this time stamp format. Current Erlang system time can more efficiently be retrieved in the time unit of your choice using -erlang:system_time/1.

                            The erlang:timestamp() BIF is equivalent to:

                            timestamp() ->
                            -    ErlangSystemTime = erlang:system_time(microsecond),
                            +erlang:system_time/1.

                            The erlang:timestamp() BIF is equivalent to:

                            timestamp() ->
                            +    ErlangSystemTime = erlang:system_time(microsecond),
                                 MegaSecs = ErlangSystemTime div 1000_000_000_000,
                                 Secs = ErlangSystemTime div 1000_000 - MegaSecs*1000_000,
                                 MicroSecs = ErlangSystemTime rem 1000_000,
                            -    {MegaSecs, Secs, MicroSecs}.

                            It, however, uses a native implementation that does not build garbage on the + {MegaSecs, Secs, MicroSecs}.

                            It, however, uses a native implementation that does not build garbage on the heap and with slightly better performance.

                            Note

                            This time is not a monotonically increasing time in the general case. For more information, see the documentation of time warp modes in the User's Guide.

                            @@ -19106,8 +19106,8 @@

                            universaltime()

                            in the form {{Year, Month, Day}, {Hour, Minute, Second}} if supported by the underlying OS. Otherwise erlang:universaltime() is equivalent to erlang:localtime(). The return value is based on the -OS System Time.

                            For example:

                            > erlang:universaltime().
                            -{{1996,11,6},{14,18,43}}
                            +OS System Time.

                            For example:

                            > erlang:universaltime().
                            +{{1996,11,6},{14,18,43}}
                            @@ -19140,8 +19140,8 @@

                            universaltime_to_localtime(Universaltime)Converts Universal Time Coordinated (UTC) date and time to local date and time in the form {{Year, Month, Day}, {Hour, Minute, Second}} if supported by the -underlying OS. Otherwise no conversion is done, and Universaltime is returned.

                            For example:

                            > erlang:universaltime_to_localtime({{1996,11,6},{14,18,43}}).
                            -{{1996,11,7},{15,18,43}}

                            Failure: badarg if Universaltime denotes an invalid date and time.

                            +underlying OS. Otherwise no conversion is done, and Universaltime is returned.

                            For example:

                            > erlang:universaltime_to_localtime({{1996,11,6},{14,18,43}}).
                            +{{1996,11,7},{15,18,43}}

                            Failure: badarg if Universaltime denotes an invalid date and time.

                            diff --git a/prs/8803/erts-15.0.1/doc/html/erlsrv_cmd.html b/prs/8803/erts-15.0.1/doc/html/erlsrv_cmd.html index 59fd4444ef286..b30c71ae73d57 100644 --- a/prs/8803/erts-15.0.1/doc/html/erlsrv_cmd.html +++ b/prs/8803/erts-15.0.1/doc/html/erlsrv_cmd.html @@ -315,28 +315,28 @@

                            ** A Console control handler that ignores the log off events, ** and lets the default handler take care of other events. */ -BOOL WINAPI service_aware_handler(DWORD ctrl){ - if(ctrl == CTRL_LOGOFF_EVENT) +BOOL WINAPI service_aware_handler(DWORD ctrl){ + if(ctrl == CTRL_LOGOFF_EVENT) return TRUE; - if(ctrl == CTRL_SHUTDOWN_EVENT) + if(ctrl == CTRL_SHUTDOWN_EVENT) return TRUE; return FALSE; -} +} -void initialize_handler(void){ - char buffer[2]; +void initialize_handler(void){ + char buffer[2]; /* * We assume we are running as a service if this * environment variable is defined. */ - if(GetEnvironmentVariable("ERLSRV_SERVICE_NAME",buffer, - (DWORD) 2)){ + if(GetEnvironmentVariable("ERLSRV_SERVICE_NAME",buffer, + (DWORD) 2)){ /* ** Actually set the control handler */ - SetConsoleCtrlHandler(&service_aware_handler, TRUE); - } -}

                + SetConsoleCtrlHandler(&service_aware_handler, TRUE); + } +}

                diff --git a/prs/8803/erts-15.0.1/doc/html/escript_cmd.html b/prs/8803/erts-15.0.1/doc/html/escript_cmd.html index 92b2fc82ba31f..26399d497e2e5 100644 --- a/prs/8803/erts-15.0.1/doc/html/escript_cmd.html +++ b/prs/8803/erts-15.0.1/doc/html/escript_cmd.html @@ -131,7 +131,7 @@

                Synopsis

                -
                script-name [arg1 arg2...]

                +
                script-name [arg1 arg2...]

                @@ -143,24 +143,24 @@

                $ cat factorial

                #!/usr/bin/env escript
                 %% -*- erlang -*-
                 %%! -sname factorial -mnesia debug verbose
                -main([String]) ->
                +main([String]) ->
                     try
                -        N = list_to_integer(String),
                -        F = fac(N),
                -        io:format("factorial ~w = ~w\n", [N,F])
                +        N = list_to_integer(String),
                +        F = fac(N),
                +        io:format("factorial ~w = ~w\n", [N,F])
                     catch
                         _:_ ->
                -            usage()
                +            usage()
                     end;
                -main(_) ->
                -    usage().
                +main(_) ->
                +    usage().
                 
                -usage() ->
                -    io:format("usage: factorial integer\n"),
                -    halt(1).
                +usage() ->
                +    io:format("usage: factorial integer\n"),
                +    halt(1).
                 
                -fac(0) -> 1;
                -fac(N) -> N * fac(N-1).
                $ ./factorial 5
                +fac(0) -> 1;
                +fac(N) -> N * fac(N-1).
                $ ./factorial 5
                 factorial 5 = 120
                 $ ./factorial
                 usage: factorial integer
                @@ -173,7 +173,7 @@ 

                If the directive is present, it must be located on the second line.

                If a comment selecting the encoding exists, it can be located on the second line.

                Note

                The encoding specified by the above mentioned comment applies to the script itself. The encoding of the I/O-server, however, must be set explicitly as -follows:

                io:setopts([{encoding, latin1}])

                The default encoding of the I/O-server for +follows:

                io:setopts([{encoding, latin1}])

                The default encoding of the I/O-server for standard_io is unicode if its supported. (see section Summary of Options) in @@ -192,7 +192,7 @@

                script (the pathname is usually, but not always, absolute).

                If the file contains source code (as in the example above), it is processed by the epp preprocessor. This means that you, for example, can use predefined macros (such as ?MODULE) and include directives like the -include_lib -directive. For example, use

                -include_lib("kernel/include/file.hrl").

                to include the record definitions for the records used by function +directive. For example, use

                -include_lib("kernel/include/file.hrl").

                to include the record definitions for the records used by function file:read_link_info/1. You can also select encoding by including an encoding comment here, but if a valid encoding comment exists on the second line, it takes precedence.

                The script is checked for syntactic and semantic correctness before it is run. @@ -200,7 +200,7 @@

                script will still be run. If there are errors, they are printed and the script will not be run and its exit status is 127.

                Both the module declaration and the export declaration of the main/1 function are optional.

                By default, the script will be compiled by the Erlang compiler.

                It is possible to force it to be interpreted by including the following line -somewhere in the script file:

                -mode(interpret).

                Execution of interpreted code is slower than compiled code, and some language +somewhere in the script file:

                -mode(interpret).

                Execution of interpreted code is slower than compiled code, and some language constructs will not work, but there is no requirement for the Erlang compiler application to be available.

                Change

                Before Erlang/OTP 27 the script would be interpreted by default.

                diff --git a/prs/8803/erts-15.0.1/doc/html/garbagecollection.html b/prs/8803/erts-15.0.1/doc/html/garbagecollection.html index db44445b99a28..7f8b39b4c7492 100644 --- a/prs/8803/erts-15.0.1/doc/html/garbagecollection.html +++ b/prs/8803/erts-15.0.1/doc/html/garbagecollection.html @@ -137,25 +137,25 @@

                Creating Data

                -

                Terms are created on the heap by evaluating expressions. There are two major types of terms: immediate terms which require no heap space (small integers, atoms, pids, port ids etc) and cons or boxed terms (tuple, big num, binaries etc) that do require heap space. Immediate terms do not need any heap space because they are embedded into the containing structure.

                Let's look at an example that returns a tuple with the newly created data.

                data(Foo) ->
                -   Cons = [42|Foo],
                -   Literal = {text, "hello world!"},
                -   {tag, Cons, Literal}.

                In this example we first create a new cons cell with an integer and a tuple with some text. Then a tuple of size three wrapping the other values with an atom tag is created and returned.

                On the heap tuples require a word size for each of its elements as well as for the header. Cons cells always require two words. Adding these things together, we get seven words for the tuples and 26 words for the cons cells. The string "hello world!" is a list of cons cells and thus requires 24 words. The atom tag and the integer 42 do not require any additional heap memory since it is an immediate. Adding all the terms together, the heap space required in this example should be 33 words.

                Compiling this code to beam assembly (erlc -S) shows exactly what is happening.

                ...
                -{test_heap,6,1}.
                -{put_list,{integer,42},{x,0},{x,1}}.
                -{put_tuple,3,{x,0}}.
                -{put,{atom,tag}}.
                -{put,{x,1}}.
                -{put,{literal,{text,"hello world!"}}}.
                +

                Terms are created on the heap by evaluating expressions. There are two major types of terms: immediate terms which require no heap space (small integers, atoms, pids, port ids etc) and cons or boxed terms (tuple, big num, binaries etc) that do require heap space. Immediate terms do not need any heap space because they are embedded into the containing structure.

                Let's look at an example that returns a tuple with the newly created data.

                data(Foo) ->
                +   Cons = [42|Foo],
                +   Literal = {text, "hello world!"},
                +   {tag, Cons, Literal}.

                In this example we first create a new cons cell with an integer and a tuple with some text. Then a tuple of size three wrapping the other values with an atom tag is created and returned.

                On the heap tuples require a word size for each of its elements as well as for the header. Cons cells always require two words. Adding these things together, we get seven words for the tuples and 26 words for the cons cells. The string "hello world!" is a list of cons cells and thus requires 24 words. The atom tag and the integer 42 do not require any additional heap memory since it is an immediate. Adding all the terms together, the heap space required in this example should be 33 words.

                Compiling this code to beam assembly (erlc -S) shows exactly what is happening.

                ...
                +{test_heap,6,1}.
                +{put_list,{integer,42},{x,0},{x,1}}.
                +{put_tuple,3,{x,0}}.
                +{put,{atom,tag}}.
                +{put,{x,1}}.
                +{put,{literal,{text,"hello world!"}}}.
                 return.

                Looking at the assembler code we can see three things: The heap requirement in this function turns out to be only six words, as seen by the {test_heap,6,1} instruction. All the allocations are combined to a single instruction. The bulk of the data {text, "hello world!"} is a literal. Literals, sometimes referred to as constants, are not allocated in the function since they are a part of the module and allocated at load time.

                If there is not enough space available on the heap to satisfy the test_heap instructions request for memory, then a garbage collection is initiated. It may happen immediately in the test_heap instruction, or it can be delayed until a later time depending on what state the process is in. If the garbage collection is delayed, any memory needed will be allocated in heap fragments. Heap fragments are extra memory blocks that are a part of the young heap, but are not allocated in the contiguous area where terms normally reside. See The young heap for more details.

                The collector

                -

                Erlang has a copying semi-space garbage collector. This means that when doing a garbage collection, the terms are copied from one distinct area, called the from space, to a new clean area, called the to space. The collector starts by scanning the root-set (stack, registers, etc).

                Garbage collection: initial values

                It follows all the pointers from the root-set to the heap and copies each term word by word to the to space.

                After the header word has been copied a move marker is destructively placed in it pointing to the term in the to space. Any other term that points to the already moved term will see this move marker and copy the referring pointer instead. For example, if the have the following Erlang code:

                foo(Arg) ->
                -    T = {test, Arg},
                -    {wrapper, T, T, T}.

                Only one copy of T exists on the heap and during the garbage collection only the first time T is encountered will it be copied.

                Garbage collection: root set scan

                After all terms referenced by the root-set have been copied, the collector scans the to space and copies all terms that these terms reference. When scanning, the collector steps through each term on the to space and any term still referencing the from space is copied over to the to space. Some terms contain non-term data (the payload of a on heap binary for instance). When encountered by the collector, these values are simply skipped.

                Garbage collection: heap scan

                Every term object we can reach is copied to the to space and stored on top off the scan stop line, and then the scan stop is moved to the end of the last object.

                Garbage collection: heap scan

                When scan stop marker catches up to the scan start marker, the garbage collection is done. At this point we can deallocate the entire from space and therefore reclaim the entire young heap.

                +

                Erlang has a copying semi-space garbage collector. This means that when doing a garbage collection, the terms are copied from one distinct area, called the from space, to a new clean area, called the to space. The collector starts by scanning the root-set (stack, registers, etc).

                Garbage collection: initial values

                It follows all the pointers from the root-set to the heap and copies each term word by word to the to space.

                After the header word has been copied a move marker is destructively placed in it pointing to the term in the to space. Any other term that points to the already moved term will see this move marker and copy the referring pointer instead. For example, if the have the following Erlang code:

                foo(Arg) ->
                +    T = {test, Arg},
                +    {wrapper, T, T, T}.

                Only one copy of T exists on the heap and during the garbage collection only the first time T is encountered will it be copied.

                Garbage collection: root set scan

                After all terms referenced by the root-set have been copied, the collector scans the to space and copies all terms that these terms reference. When scanning, the collector steps through each term on the to space and any term still referencing the from space is copied over to the to space. Some terms contain non-term data (the payload of a on heap binary for instance). When encountered by the collector, these values are simply skipped.

                Garbage collection: heap scan

                Every term object we can reach is copied to the to space and stored on top off the scan stop line, and then the scan stop is moved to the end of the last object.

                Garbage collection: heap scan

                When scan stop marker catches up to the scan start marker, the garbage collection is done. At this point we can deallocate the entire from space and therefore reclaim the entire young heap.

                @@ -179,11 +179,11 @@

                Literals

                -

                When garbage collecting a heap (young or old) all literals are left in place and not copied. To figure out if a term should be copied or not when doing a garbage collection the following pseudo code is used:

                if (erts_is_literal(ptr) || (on_old_heap(ptr) && !fullsweep)) {
                +

                When garbage collecting a heap (young or old) all literals are left in place and not copied. To figure out if a term should be copied or not when doing a garbage collection the following pseudo code is used:

                if (erts_is_literal(ptr) || (on_old_heap(ptr) && !fullsweep)) {
                   /* literal or non fullsweep - do not copy */
                -} else {
                -  copy(ptr);
                -}

                The erts_is_literal check works differently on different architectures and operating systems.

                On 64 bit systems that allow mapping of unreserved virtual memory areas (most operating systems except Windows), an area of size 1 GB (by default) is mapped and then all literals are placed within that area. Then all that has to be done to determine if something is a literal or not is two quick pointer checks. This system relies on the fact that a memory page that has not been touched yet does not take any actual space. So even if 1 GB of virtual memory is mapped, only the memory which is actually needed for literals is allocated in ram. The size of the literal area is configurable through the +MIscs erts_alloc option.

                On 32 bit systems, there is not enough virtual memory space to allocate 1 GB for just literals, so instead small 256 KB sized literal regions are created on demand and a card mark bit-array of the entire 32 bit memory space is then used to determine if a term is a literal or not. Since the total memory space is only 32 bits, the card mark bit-array is only 256 words large. On a 64 bit system the same bit-array would have to be 1 tera words large, so this technique is only viable on 32 bit systems. Doing lookups in the array is a little more expensive then just doing the pointer checks that can be done in 64 bit systems, but not extremely so.

                On 64 bit windows, on which erts_alloc cannot do unreserved virtual memory mappings, a special tag within the Erlang term object is used to determine if something is a literal or not. This is very cheap, however, the tag is only available on 64 bit machines, and it is possible to do a great deal of other nice optimizations with this tag in the future (like for instance a more compact list implementation) so it is not used on operating systems where it is not needed.

                This behaviour is different from how it worked prior to Erlang/OTP 19.0. Before 19.0 the literal check was done by checking if the pointer pointed to the young or old heap block. If it did not, then it was considered a literal. This lead to considerable overhead and strange memory usage scenarios, so it was removed in 19.0.

                +} else { + copy(ptr); +}

                The erts_is_literal check works differently on different architectures and operating systems.

                On 64 bit systems that allow mapping of unreserved virtual memory areas (most operating systems except Windows), an area of size 1 GB (by default) is mapped and then all literals are placed within that area. Then all that has to be done to determine if something is a literal or not is two quick pointer checks. This system relies on the fact that a memory page that has not been touched yet does not take any actual space. So even if 1 GB of virtual memory is mapped, only the memory which is actually needed for literals is allocated in ram. The size of the literal area is configurable through the +MIscs erts_alloc option.

                On 32 bit systems, there is not enough virtual memory space to allocate 1 GB for just literals, so instead small 256 KB sized literal regions are created on demand and a card mark bit-array of the entire 32 bit memory space is then used to determine if a term is a literal or not. Since the total memory space is only 32 bits, the card mark bit-array is only 256 words large. On a 64 bit system the same bit-array would have to be 1 tera words large, so this technique is only viable on 32 bit systems. Doing lookups in the array is a little more expensive then just doing the pointer checks that can be done in 64 bit systems, but not extremely so.

                On 64 bit windows, on which erts_alloc cannot do unreserved virtual memory mappings, a special tag within the Erlang term object is used to determine if something is a literal or not. This is very cheap, however, the tag is only available on 64 bit machines, and it is possible to do a great deal of other nice optimizations with this tag in the future (like for instance a more compact list implementation) so it is not used on operating systems where it is not needed.

                This behaviour is different from how it worked prior to Erlang/OTP 19.0. Before 19.0 the literal check was done by checking if the pointer pointed to the young or old heap block. If it did not, then it was considered a literal. This lead to considerable overhead and strange memory usage scenarios, so it was removed in 19.0.

                diff --git a/prs/8803/erts-15.0.1/doc/html/inet_cfg.html b/prs/8803/erts-15.0.1/doc/html/inet_cfg.html index 4bc1d8fab5617..39254df1af49d 100644 --- a/prs/8803/erts-15.0.1/doc/html/inet_cfg.html +++ b/prs/8803/erts-15.0.1/doc/html/inet_cfg.html @@ -165,11 +165,11 @@

                The user configuration file is always examined last in the configuration process, making it possible for the user to override any default values or previously made settings. Call inet:get_rc() to view the state of the inet -configuration database.

                The valid configuration parameters are as follows:

                • {file, Format, File}.
                  -  Format = atom()
                  -  File = string()

                  Specify a system file that Erlang is to read configuration data from. Format -tells the parser how the file is to be interpreted:

                  • resolv (Unix resolv.conf)
                  • host_conf_freebsd (FreeBSD host.conf)
                  • host_conf_bsdos (BSDOS host.conf)
                  • host_conf_linux (Linux host.conf)
                  • nsswitch_conf (Unix nsswitch.conf)
                  • hosts (Unix hosts)

                  File is to specify the filename with full path.

                • {resolv_conf, File}.
                  -  File = string()

                  Specify a system file that Erlang is to read resolver configuration from for +configuration database.

                  The valid configuration parameters are as follows:

                  • {file, Format, File}.
                    +  Format = atom()
                    +  File = string()

                    Specify a system file that Erlang is to read configuration data from. Format +tells the parser how the file is to be interpreted:

                    • resolv (Unix resolv.conf)
                    • host_conf_freebsd (FreeBSD host.conf)
                    • host_conf_bsdos (BSDOS host.conf)
                    • host_conf_linux (Linux host.conf)
                    • nsswitch_conf (Unix nsswitch.conf)
                    • hosts (Unix hosts)

                    File is to specify the filename with full path.

                  • {resolv_conf, File}.
                    +  File = string()

                    Specify a system file that Erlang is to read resolver configuration from for the internal DNS client inet_res, and monitor for changes, even if it does not exist. The path must be absolute.

                    This can override the configuration parameters nameserver and search depending on the contents of the specified file. They can also change any time @@ -177,61 +177,61 @@

                    in the future. This emulates the old behavior of not configuring the DNS client when the node is started in short name distributed mode.

                    If this parameter is not specified, it defaults to /etc/resolv.conf unless environment variable ERL_INET_ETC_DIR is set, which defines the directory -for this file to some maybe other than /etc.

                  • {hosts_file, File}.
                    -  File = string()

                    Specify a system file that Erlang is to read resolver configuration from for +for this file to some maybe other than /etc.

                  • {hosts_file, File}.
                    +  File = string()

                    Specify a system file that Erlang is to read resolver configuration from for the internal hosts file resolver, and monitor for changes, even if it does not exist. The path must be absolute.

                    These host entries are searched after all added with {file, hosts, File} above or {host, IP, Aliases} below when lookup option file is used.

                    If the file is specified as an empty string "", no file is read or monitored in the future. This emulates the old behavior of not configuring the DNS client when the node is started in short name distributed mode.

                    If this parameter is not specified, it defaults to /etc/hosts unless environment variable ERL_INET_ETC_DIR is set, which defines the directory -for this file to some maybe other than /etc.

                  • {registry, Type}.
                    -  Type = atom()

                    Specify a system registry that Erlang is to read configuration data from. -win32 is the only valid option.

                  • {host, IP, Aliases}.
                    -  IP = tuple()

                    Aliases = [string()]

                    Add host entry to the hosts table.

                  • {domain, Domain}.
                    -  Domain = string()

                    Set domain name.

                  • {nameserver, IP [,Port]}.
                    -  IP = tuple()
                    -  Port = integer()

                    Add address (and port, if other than default) of the primary nameserver to use -for inet_res.

                  • {alt_nameserver, IP [,Port]}.
                    -  IP = tuple()
                    -  Port = integer()

                    Add address (and port, if other than default) of the secondary nameserver for -inet_res.

                  • {search, Domains}.
                    -  Domains = [string()]

                    Add search domains for inet_res.

                  • {lookup, Methods}.
                    -  Methods = [atom()]

                    Specify lookup methods and in which order to try them. The valid methods are +for this file to some maybe other than /etc.

                  • {registry, Type}.
                    +  Type = atom()

                    Specify a system registry that Erlang is to read configuration data from. +win32 is the only valid option.

                  • {host, IP, Aliases}.
                    +  IP = tuple()

                    Aliases = [string()]

                    Add host entry to the hosts table.

                  • {domain, Domain}.
                    +  Domain = string()

                    Set domain name.

                  • {nameserver, IP [,Port]}.
                    +  IP = tuple()
                    +  Port = integer()

                    Add address (and port, if other than default) of the primary nameserver to use +for inet_res.

                  • {alt_nameserver, IP [,Port]}.
                    +  IP = tuple()
                    +  Port = integer()

                    Add address (and port, if other than default) of the secondary nameserver for +inet_res.

                  • {search, Domains}.
                    +  Domains = [string()]

                    Add search domains for inet_res.

                  • {lookup, Methods}.
                    +  Methods = [atom()]

                    Specify lookup methods and in which order to try them. The valid methods are as follows:

                    • native (use system calls)
                    • file (use host data retrieved from system configuration files and/or the user configuration file)
                    • dns (use the Erlang DNS client inet_res for nameserver queries)

                    The lookup method string tries to parse the hostname as an IPv4 or IPv6 string and return the resulting IP address. It is automatically tried first when native is not in the Methods list. To skip it in this case, the pseudo lookup method nostring can be inserted anywhere in the Methods -list.

                  • {cache_size, Size}.
                    -  Size = integer()

                    Set the resolver cache size for dns lookups. native lookups are not -cached. Defaults to 100 DNS records.

                  • {cache_refresh, Time}.
                    -  Time = integer()

                    Set how often (in milliseconds) the resolver cache for inet_res is -refreshed (that is, expired DNS records are deleted). Defaults to 1 hour.

                  • {timeout, Time}.
                    -  Time = integer()

                    Set the time to wait until retry (in milliseconds) for DNS queries made by -inet_res. Defaults to 2 seconds.

                  • {retry, N}.
                    -  N = integer()

                    Set the number of DNS queries inet_res will try before giving up. Defaults -to 3.

                  • {servfail_retry_timeout, Time}.
                    -  Time = non_neg_integer()

                    After all name servers have been tried, there is a timeout before the name +list.

                  • {cache_size, Size}.
                    +  Size = integer()

                    Set the resolver cache size for dns lookups. native lookups are not +cached. Defaults to 100 DNS records.

                  • {cache_refresh, Time}.
                    +  Time = integer()

                    Set how often (in milliseconds) the resolver cache for inet_res is +refreshed (that is, expired DNS records are deleted). Defaults to 1 hour.

                  • {timeout, Time}.
                    +  Time = integer()

                    Set the time to wait until retry (in milliseconds) for DNS queries made by +inet_res. Defaults to 2 seconds.

                  • {retry, N}.
                    +  N = integer()

                    Set the number of DNS queries inet_res will try before giving up. Defaults +to 3.

                  • {servfail_retry_timeout, Time}.
                    +  Time = non_neg_integer()

                    After all name servers have been tried, there is a timeout before the name servers are tried again. This is to prevent the server from answering the query with what's in the servfail cache, inet_res. Defaults to 1500 milli -seconds .

                  • {inet6, Bool}.
                    +seconds .

                  • {inet6, Bool}.
                       Bool = true | false

                    Tells the DNS client inet_res to look up IPv6 addresses. Defaults to -false.

                  • {usevc, Bool}.
                    +false.

                  • {usevc, Bool}.
                       Bool = true | false

                    Tells the DNS client inet_res to use TCP (Virtual Circuit) instead of UDP. -Defaults to false.

                  • {edns, Version}.
                    +Defaults to false.

                  • {edns, Version}.
                       Version = false | 0

                    Sets the EDNS version that inet_res will use. The only allowed version is -zero. Defaults to false, which means not to use EDNS.

                  • {udp_payload_size, Size}.
                    -  N = integer()

                    Sets the allowed UDP payload size inet_res will advertise in EDNS queries. +zero. Defaults to false, which means not to use EDNS.

                  • {udp_payload_size, Size}.
                    +  N = integer()

                    Sets the allowed UDP payload size inet_res will advertise in EDNS queries. Also sets the limit when the DNS query will be deemed too large for UDP forcing a TCP query instead; this is not entirely correct, as the advertised UDP payload size of the individual nameserver is what is to be used, but this simple strategy will do until a more intelligent (probing, caching) algorithm needs to be implemented. Default to 1280, which stems from the standard -Ethernet MTU size.

                  • {udp, Module}.
                    -  Module = atom()

                    Tell Erlang to use another primitive UDP module than inet_udp.

                  • {tcp, Module}.
                    -  Module = atom()

                    Tell Erlang to use another primitive TCP module than inet_tcp.

                  • clear_hosts.

                    Clear the hosts table.

                  • clear_ns.

                    Clear the list of recorded nameservers (primary and secondary).

                  • clear_search.

                    Clear the list of search domains.

                  +Ethernet MTU size.

                • {udp, Module}.
                  +  Module = atom()

                  Tell Erlang to use another primitive UDP module than inet_udp.

                • {tcp, Module}.
                  +  Module = atom()

                  Tell Erlang to use another primitive TCP module than inet_tcp.

                • clear_hosts.

                  Clear the hosts table.

                • clear_ns.

                  Clear the list of recorded nameservers (primary and secondary).

                • clear_search.

                  Clear the list of search domains.

                @@ -246,19 +246,19 @@

                (in this example named erl_inetrc, stored in directory ./cfg_files) can then look as follows (Unix):

                %% -- ERLANG INET CONFIGURATION FILE --
                 %% read the hosts file
                -{file, hosts, "/etc/hosts"}.
                +{file, hosts, "/etc/hosts"}.
                 %% add a particular host
                -{host, {134,138,177,105}, ["finwe"]}.
                +{host, {134,138,177,105}, ["finwe"]}.
                 %% do not monitor the hosts file
                -{hosts_file, ""}.
                +{hosts_file, ""}.
                 %% read and monitor nameserver config from here
                -{resolv_conf, "/usr/local/etc/resolv.conf"}.
                +{resolv_conf, "/usr/local/etc/resolv.conf"}.
                 %% enable EDNS
                -{edns,0}.
                +{edns,0}.
                 %% disable caching
                -{cache_size, 0}.
                +{cache_size, 0}.
                 %% specify lookup method
                -{lookup, [file, dns]}.

                And Erlang can, for example, be started as follows:

                % erl -sname my_node -kernel inetrc '"./cfg_files/erl_inetrc"'
                +{lookup, [file, dns]}.

                And Erlang can, for example, be started as follows:

                % erl -sname my_node -kernel inetrc '"./cfg_files/erl_inetrc"'
                diff --git a/prs/8803/erts-15.0.1/doc/html/init.html b/prs/8803/erts-15.0.1/doc/html/init.html index f3690f9ba2e25..554baf201f4ef 100644 --- a/prs/8803/erts-15.0.1/doc/html/init.html +++ b/prs/8803/erts-15.0.1/doc/html/init.html @@ -161,8 +161,8 @@

                initialization process.

              • -extra - Everything following -extra is considered plain arguments and can be retrieved using get_plain_arguments/0.

                Example:

                % erl -extra +A 1 --
                 ...
                -1> init:get_plain_arguments().
                -["+A","1","--"]

                The -extra flag can be passed on the command line, through ERL_*FLAGS or +1> init:get_plain_arguments(). +["+A","1","--"]

              The -extra flag can be passed on the command line, through ERL_*FLAGS or -args_file. It only effects the remaining command-line flags in the entity in which it is passed. If multiple -extra flags are passed they are concatenated using the same order rules as ERL_*FLAGS or -args_file in @@ -216,13 +216,13 @@

              % erl -- a b -children thomas claire -ages 7 3 -- x y
               ...
               
              -1> init:get_plain_arguments().
              -["a","b","x","y"]
              -2> init:get_argument(children).
              -{ok,[["thomas","claire"]]}
              -3> init:get_argument(ages).
              -{ok, [["7","3"]]}
              -4> init:get_argument(silly).
              +1> init:get_plain_arguments().
              +["a","b","x","y"]
              +2> init:get_argument(children).
              +{ok,[["thomas","claire"]]}
              +3> init:get_argument(ages).
              +{ok, [["7","3"]]}
              +4> init:get_argument(silly).
               error

              @@ -524,12 +524,12 @@

              get_argument(Flag)

              Returns all values associated with the command-line user flag Flag.

              If Flag is provided several times, each Values is returned in preserved order. Example:

              % erl -a b c -a d
               ...
              -1> init:get_argument(a).
              -{ok,[["b","c"],["d"]]}

              The following flags are defined automatically and can be retrieved using this +1> init:get_argument(a). +{ok,[["b","c"],["d"]]}

    The following flags are defined automatically and can be retrieved using this function:

    Returns error if no value is associated with Flag.

    +{ok,[["/usr/local/otp/releases/otp_beam_solaris8_r10b_patched"]]}
  • progname - The name of the program which started Erlang:

    3> init:get_argument(progname).
    +{ok,[["erl"]]}
  • home - The home directory (on Unix, the value of $HOME):

    4> init:get_argument(home).
    +{ok,[["/home/harry"]]}
  • Returns error if no value is associated with Flag.

    diff --git a/prs/8803/erts-15.0.1/doc/html/match_spec.html b/prs/8803/erts-15.0.1/doc/html/match_spec.html index 5e09511160da7..6c58d779c2f7e 100644 --- a/prs/8803/erts-15.0.1/doc/html/match_spec.html +++ b/prs/8803/erts-15.0.1/doc/html/match_spec.html @@ -371,70 +371,70 @@

    Tracing Examples

    -

    Match an argument list of three, where the first and third arguments are equal:

    [{['$1', '_', '$1'],
    -  [],
    -  []}]

    Match an argument list of three, where the second argument is a number > 3:

    [{['_', '$1', '_'],
    -  [{ '>', '$1', 3}],
    -  []}]

    Match an argument list of three, where the third argument is either a tuple +

    Match an argument list of three, where the first and third arguments are equal:

    [{['$1', '_', '$1'],
    +  [],
    +  []}]

    Match an argument list of three, where the second argument is a number > 3:

    [{['_', '$1', '_'],
    +  [{ '>', '$1', 3}],
    +  []}]

    Match an argument list of three, where the third argument is either a tuple containing argument one and two, or a list beginning with argument one and two -(that is, [a,b,[a,b,c]] or [a,b,{a,b}]):

    [{['$1', '$2', '$3'],
    -  [{'orelse',
    -      {'=:=', '$3', {{'$1','$2'}}},
    -      {'and',
    -        {'=:=', '$1', {hd, '$3'}},
    -        {'=:=', '$2', {hd, {tl, '$3'}}}}}],
    -  []}]

    The above problem can also be solved as follows:

    [{['$1', '$2', {'$1', '$2}], [], []},
    - {['$1', '$2', ['$1', '$2' | '_']], [], []}]

    Match two arguments, where the first is a tuple beginning with a list that in +(that is, [a,b,[a,b,c]] or [a,b,{a,b}]):

    [{['$1', '$2', '$3'],
    +  [{'orelse',
    +      {'=:=', '$3', {{'$1','$2'}}},
    +      {'and',
    +        {'=:=', '$1', {hd, '$3'}},
    +        {'=:=', '$2', {hd, {tl, '$3'}}}}}],
    +  []}]

    The above problem can also be solved as follows:

    [{['$1', '$2', {'$1', '$2}], [], []},
    + {['$1', '$2', ['$1', '$2' | '_']], [], []}]

    Match two arguments, where the first is a tuple beginning with a list that in turn begins with the second argument times two (that is, [{[4,x],y},2] or -[{[8], y, z},4]):

    [{['$1', '$2'],[{'=:=', {'*', 2, '$2'}, {hd, {element, 1, '$1'}}}],
    -  []}]

    Match three arguments. When all three are equal and are numbers, append the +[{[8], y, z},4]):

    [{['$1', '$2'],[{'=:=', {'*', 2, '$2'}, {hd, {element, 1, '$1'}}}],
    +  []}]

    Match three arguments. When all three are equal and are numbers, append the process dump to the trace message, otherwise let the trace message be "as is", -but set the sequential trace token label to 4711:

    [{['$1', '$1', '$1'],
    -  [{is_number, '$1'}],
    -  [{message, {process_dump}}]},
    - {'_', [], [{set_seq_token, label, 4711}]}]

    As can be noted above, the parameter list can be matched against a single +but set the sequential trace token label to 4711:

    [{['$1', '$1', '$1'],
    +  [{is_number, '$1'}],
    +  [{message, {process_dump}}]},
    + {'_', [], [{set_seq_token, label, 4711}]}]

    As can be noted above, the parameter list can be matched against a single MatchVariable or an '_'. To replace the whole parameter list with a single variable is a special case. In all other cases the MatchHead must be a -proper list.

    Generate a trace message only if the trace control word is set to 1:

    [{'_',
    -  [{'==',{get_tcw},{const, 1}}],
    -  []}]

    Generate a trace message only if there is a seq_trace token:

    [{'_',
    -  [{'==',{is_seq_trace},{const, 1}}],
    -  []}]

    Remove the 'silent' trace flag when the first argument is 'verbose', and add -it when it is 'silent':

    [{'$1',
    -  [{'==',{hd, '$1'},verbose}],
    -  [{trace, [silent],[]}]},
    - {'$1',
    -  [{'==',{hd, '$1'},silent}],
    -  [{trace, [],[silent]}]}]

    Add a return_trace message if the function is of arity 3:

    [{'$1',
    -  [{'==',{length, '$1'},3}],
    -  [{return_trace}]},
    - {'_',[],[]}]

    Generate a trace message only if the function is of arity 3 and the first -argument is 'trace':

    [{['trace','$2','$3'],
    -  [],
    -  []},
    - {'_',[],[]}]

    +proper list.

    Generate a trace message only if the trace control word is set to 1:

    [{'_',
    +  [{'==',{get_tcw},{const, 1}}],
    +  []}]

    Generate a trace message only if there is a seq_trace token:

    [{'_',
    +  [{'==',{is_seq_trace},{const, 1}}],
    +  []}]

    Remove the 'silent' trace flag when the first argument is 'verbose', and add +it when it is 'silent':

    [{'$1',
    +  [{'==',{hd, '$1'},verbose}],
    +  [{trace, [silent],[]}]},
    + {'$1',
    +  [{'==',{hd, '$1'},silent}],
    +  [{trace, [],[silent]}]}]

    Add a return_trace message if the function is of arity 3:

    [{'$1',
    +  [{'==',{length, '$1'},3}],
    +  [{return_trace}]},
    + {'_',[],[]}]

    Generate a trace message only if the function is of arity 3 and the first +argument is 'trace':

    [{['trace','$2','$3'],
    +  [],
    +  []},
    + {'_',[],[]}]

    ETS Examples

    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:

    [{{strider,'_','_'},
    -  [],
    -  ['$_']}]

    Match all objects in an ETS table with arity > 1 and the first element is -'gandalf', and return element 2:

    [{'$1',
    -  [{'==', gandalf, {element, 1, '$1'}},{'>=',{size, '$1'},2}],
    -  [{element,2,'$1'}]}]

    In this example, if the first element had been the key, it is much more +'strider' and the tuple arity is 3, and return the whole object:

    [{{strider,'_','_'},
    +  [],
    +  ['$_']}]

    Match all objects in an ETS table with arity > 1 and the first element is +'gandalf', and return element 2:

    [{'$1',
    +  [{'==', gandalf, {element, 1, '$1'}},{'>=',{size, '$1'},2}],
    +  [{element,2,'$1'}]}]

    In this example, if the first element had been the key, it is much more efficient to match that key in the MatchHead part than in the MatchConditions part. The search space of the tables is restricted with regards to the MatchHead so that only objects with the matching key are searched.

    Match tuples of three elements, where the second element is either 'merry' or -'pippin', and return the whole objects:

    [{{'_',merry,'_'},
    -  [],
    -  ['$_']},
    - {{'_',pippin,'_'},
    -  [],
    -  ['$_']}]

    Function ets:test_ms/2 can be useful for testing complicated ETS matches.

    +'pippin', and return the whole objects:

    [{{'_',merry,'_'},
    +  [],
    +  ['$_']},
    + {{'_',pippin,'_'},
    +  [],
    +  ['$_']}]

    Function ets:test_ms/2 can be useful for testing complicated ETS matches.

    diff --git a/prs/8803/erts-15.0.1/doc/html/notes.html b/prs/8803/erts-15.0.1/doc/html/notes.html index 0a5487e3fb655..d3b252d6e6392 100644 --- a/prs/8803/erts-15.0.1/doc/html/notes.html +++ b/prs/8803/erts-15.0.1/doc/html/notes.html @@ -155,17 +155,17 @@

    Improvements and New Features

    -
    • Refactored how the JIT handles POSIX signals and how they affect thread stacks, allowing us to use the native stack register for Erlang stacks on more platforms.

      Notably, containers built on 64-bit x86 Alpine Linux images will now perform much better in sequential code. As an example, running dialyzer over the OTP code base finishes about 15% quicker.

      Own Id: OTP-18568 Aux Id: PR-7174

    • The instrument module can now track allocations on a per-process or per-port basis.

      Own Id: OTP-18577 Aux Id: PR-7236

    • The pid field returned from erlang:fun_info/1,2 is now always the pid for the init process of the local node, not the pid for the actual process that created the fun.

      POTENTIAL INCOMPATIBILITY

      Own Id: OTP-18594 Aux Id: PR-7274

    • By default, escripts will now be compiled instead of interpreted. That means that the compiler application must be installed.

      POTENTIAL INCOMPATIBILITY

      Own Id: OTP-18639 Aux Id: PR-7348

    • A binary returned from the socket receive functions is no longer created as a sub binary of an often large receive buffer binary (socket option {otp,rcvbuf}). This avoids space waste, trusting the allocators to implement reallocation efficiently.

      Own Id: OTP-18642 Aux Id: GH-6152, PR-7465

    • The default process limit has been raised to 1048576 processes.

      Own Id: OTP-18699 Aux Id: PR-7388

    • The erlang:system_monitor/2 functionality is now able to monitor long message queues in the system.

      Own Id: OTP-18709 Aux Id: PR-7651

    • The erl command now supports the -S flag, which is similar to the -run flag, except that it will pass all arguments up to end of the command line to the called function. (The -run flag will not pass arguments beginning with a hyphen.) Another difference is that -S will always call a function with one argument, passing an empty list if no arguments were given.

      Own Id: OTP-18744 Aux Id: PR-7470

    • When implementing an alternative carrier for the Erlang distribution, a separate input handler process may now be registered, using erlang:dist_ctrl_input_handler/2, also in the case when the distribution controller is a port.

      Own Id: OTP-18774 Aux Id: PR-7110

    • The call stack trace has now been added to the error reported by erlang:process_flag/2 when max_heap_size limit has been exceeded.

      Own Id: OTP-18779 Aux Id: PR-7592

    • -callback attributes have been added to erl_tracer.

      Own Id: OTP-18794 Aux Id: PR-7703

    • For inet_backend = socket, setting the active socket option alone, to once, true or N has been optimized, as well as the corresponding data delivery.

      Own Id: OTP-18835

    • New functions socket:sendv/* for sending I/O vectors have been added.

      Own Id: OTP-18845

    • Socket options that take string now also accept binaries.

      Own Id: OTP-18849 Aux Id: PR-6510

    • Native coverage support has been implemented in the JIT. It will automatically be used by the cover tool to reduce the execution overhead when running cover-compiled code.

      There are also new APIs to support native coverage without using the cover tool.

      To instrument code for native coverage it must be compiled with the line_coverage option.

      To enable native coverage in the runtime system, start it like so:

      $ erl +JPcover true

      There are also the following new functions for supporting native coverage:

      Own Id: OTP-18856 Aux Id: PR-7856

    • Changed the default value of the command line flag -code_path_choice to strict.

      Note that for application systems using archives, it is necessary to add the code_path_choice relaxed to the command line that invokes erl.

      Own Id: OTP-18894 Aux Id: PR-7243

    • Added module loading to erl -init_debug printouts.

      Own Id: OTP-18929 Aux Id: PR-8004

    • When the runtime system halts, it performs various flush operations before terminating. By default there is no limit on how much time the flush operations are allowed to take. A new halt flush timeout functionality has been introduced which can be used for limiting the amount of time that the flushing operations are allowed to take. For more information see the documentation of the flush_timeout option of the erlang:halt/2 BIF and the documentation of the erl +zhft <Timeout> command line flag.

      Own Id: OTP-18938 Aux Id: PR-8035, GH-7438

    • Optimized code loading by moving certain operations from the code server to the caller.

      Own Id: OTP-18941 Aux Id: PR-7981

    • Updated asmjit to version a465fe71ab3d0e224b2b4bd0fac69ae68ab9239d

      Own Id: OTP-18942

    • The deprecated functions in zlib have been removed. That includes inflateChunk/{1,2}, getBufSize/1, setBufSize/2, the CRC32 functions, and the Adler checksum functions.

      Own Id: OTP-18950

    • The documentation has been migrated to use Markdown and ExDoc.

      Own Id: OTP-18955 Aux Id: PR-8026

    • Safe destructive update of tuples has been implemented in the compiler and runtime system. This allows the VM to update tuples in-place when it is safe to do so, thus improving performance by doing less copying but also by producing less garbage.

      Example:

      -record(rec, {a,b,c}).
      +
      • Refactored how the JIT handles POSIX signals and how they affect thread stacks, allowing us to use the native stack register for Erlang stacks on more platforms.

        Notably, containers built on 64-bit x86 Alpine Linux images will now perform much better in sequential code. As an example, running dialyzer over the OTP code base finishes about 15% quicker.

        Own Id: OTP-18568 Aux Id: PR-7174

      • The instrument module can now track allocations on a per-process or per-port basis.

        Own Id: OTP-18577 Aux Id: PR-7236

      • The pid field returned from erlang:fun_info/1,2 is now always the pid for the init process of the local node, not the pid for the actual process that created the fun.

        POTENTIAL INCOMPATIBILITY

        Own Id: OTP-18594 Aux Id: PR-7274

      • By default, escripts will now be compiled instead of interpreted. That means that the compiler application must be installed.

        POTENTIAL INCOMPATIBILITY

        Own Id: OTP-18639 Aux Id: PR-7348

      • A binary returned from the socket receive functions is no longer created as a sub binary of an often large receive buffer binary (socket option {otp,rcvbuf}). This avoids space waste, trusting the allocators to implement reallocation efficiently.

        Own Id: OTP-18642 Aux Id: GH-6152, PR-7465

      • The default process limit has been raised to 1048576 processes.

        Own Id: OTP-18699 Aux Id: PR-7388

      • The erlang:system_monitor/2 functionality is now able to monitor long message queues in the system.

        Own Id: OTP-18709 Aux Id: PR-7651

      • The erl command now supports the -S flag, which is similar to the -run flag, except that it will pass all arguments up to end of the command line to the called function. (The -run flag will not pass arguments beginning with a hyphen.) Another difference is that -S will always call a function with one argument, passing an empty list if no arguments were given.

        Own Id: OTP-18744 Aux Id: PR-7470

      • When implementing an alternative carrier for the Erlang distribution, a separate input handler process may now be registered, using erlang:dist_ctrl_input_handler/2, also in the case when the distribution controller is a port.

        Own Id: OTP-18774 Aux Id: PR-7110

      • The call stack trace has now been added to the error reported by erlang:process_flag/2 when max_heap_size limit has been exceeded.

        Own Id: OTP-18779 Aux Id: PR-7592

      • -callback attributes have been added to erl_tracer.

        Own Id: OTP-18794 Aux Id: PR-7703

      • For inet_backend = socket, setting the active socket option alone, to once, true or N has been optimized, as well as the corresponding data delivery.

        Own Id: OTP-18835

      • New functions socket:sendv/* for sending I/O vectors have been added.

        Own Id: OTP-18845

      • Socket options that take string now also accept binaries.

        Own Id: OTP-18849 Aux Id: PR-6510

      • Native coverage support has been implemented in the JIT. It will automatically be used by the cover tool to reduce the execution overhead when running cover-compiled code.

        There are also new APIs to support native coverage without using the cover tool.

        To instrument code for native coverage it must be compiled with the line_coverage option.

        To enable native coverage in the runtime system, start it like so:

        $ erl +JPcover true

        There are also the following new functions for supporting native coverage:

        Own Id: OTP-18856 Aux Id: PR-7856

      • Changed the default value of the command line flag -code_path_choice to strict.

        Note that for application systems using archives, it is necessary to add the code_path_choice relaxed to the command line that invokes erl.

        Own Id: OTP-18894 Aux Id: PR-7243

      • Added module loading to erl -init_debug printouts.

        Own Id: OTP-18929 Aux Id: PR-8004

      • When the runtime system halts, it performs various flush operations before terminating. By default there is no limit on how much time the flush operations are allowed to take. A new halt flush timeout functionality has been introduced which can be used for limiting the amount of time that the flushing operations are allowed to take. For more information see the documentation of the flush_timeout option of the erlang:halt/2 BIF and the documentation of the erl +zhft <Timeout> command line flag.

        Own Id: OTP-18938 Aux Id: PR-8035, GH-7438

      • Optimized code loading by moving certain operations from the code server to the caller.

        Own Id: OTP-18941 Aux Id: PR-7981

      • Updated asmjit to version a465fe71ab3d0e224b2b4bd0fac69ae68ab9239d

        Own Id: OTP-18942

      • The deprecated functions in zlib have been removed. That includes inflateChunk/{1,2}, getBufSize/1, setBufSize/2, the CRC32 functions, and the Adler checksum functions.

        Own Id: OTP-18950

      • The documentation has been migrated to use Markdown and ExDoc.

        Own Id: OTP-18955 Aux Id: PR-8026

      • Safe destructive update of tuples has been implemented in the compiler and runtime system. This allows the VM to update tuples in-place when it is safe to do so, thus improving performance by doing less copying but also by producing less garbage.

        Example:

        -record(rec, {a,b,c}).
         
        -update(#rec{a=needs_update,b=N}=R0) ->
        -    R = R0#rec{a=up_to_date},
        +update(#rec{a=needs_update,b=N}=R0) ->
        +    R = R0#rec{a=up_to_date},
             if
                 N < 0 ->
        -            R#rec{c=negative};
        +            R#rec{c=negative};
                 N == 0 ->
        -            R#rec{c=zero};
        +            R#rec{c=zero};
                 N > 0 ->
        -            R#rec{c=positive}
        +            R#rec{c=positive}
             end.

        The record updates in each of the three clauses of the if can safely be done in-place, because variable R is not used again.

        Own Id: OTP-18972 Aux Id: PR-8090

      • The obsolete and undocumented support for opening a port to an external resource by passing an atom (or a string) as first argument to open_port(), implemented by the vanilla driver, @@ -3003,9 +3003,9 @@

        has now been removed.

        * POTENTIAL INCOMPATIBILITY *

        Own Id: OTP-16329 Aux Id: OTP-15621

      • The return value when using the httph and httph_bin option to erlang:decode_packet/3 and inet:setopts/2 has been changed to also include the original header unmodified. See erlang:decode_packet/3. Example:

         >
        -      erlang:decode_packet(httph_bin,<<"HELLO:
        -      hi\r\n\r\n">>,[]).
        -      {ok,{http_header,0,<<"Hello">>,<<"HELLO">>,<<"hi">>},<<"\r\n">>}

        Own Id: OTP-16347 Aux Id: PR-2466

      • Ensure net_kernel:monitor_nodes/1 sends nodedown messages of a failed + erlang:decode_packet(httph_bin,<<"HELLO: + hi\r\n\r\n">>,[]). + {ok,{http_header,0,<<"Hello">>,<<"HELLO">>,<<"hi">>},<<"\r\n">>}

      Own Id: OTP-16347 Aux Id: PR-2466

    • Ensure net_kernel:monitor_nodes/1 sends nodedown messages of a failed connection before nodeup messages of a reestablished connection toward the same node.

      Own Id: OTP-16362

    • Update of sequential tracing to also support other information transfers than message passing.

      Own Id: OTP-16370 Aux Id: OTP-15251, OTP-15232

    • socket: It is now possible to create a socket from an already existing file @@ -10720,12 +10720,12 @@

      viewed as two operations performed atomically. Asynchronously send an unlink signal or a demonitor signal, and ignore any future results of the link or monitor.

      NOTE: This change can cause some obscure code to fail which previously did -not. For example, the following code might hang:

                  Mon = erlang:monitor(process, Pid),
      +not. For example, the following code might hang:

                  Mon = erlang:monitor(process, Pid),
                   %% ...
      -            exit(Pid, bang),
      -            erlang:demonitor(Mon),
      +            exit(Pid, bang),
      +            erlang:demonitor(Mon),
                   receive
      -                {'DOWN', Mon , process, Pid, _} -> ok
      +                {'DOWN', Mon , process, Pid, _} -> ok
                   %% We were previously guaranteed to get a down message
                   %% (since we exited the process ourself), so we could
                   %% in this case leave out:
      diff --git a/prs/8803/erts-15.0.1/doc/html/persistent_term.html b/prs/8803/erts-15.0.1/doc/html/persistent_term.html
      index 8b7278f6dc0ab..5a6ae36e2a531 100644
      --- a/prs/8803/erts-15.0.1/doc/html/persistent_term.html
      +++ b/prs/8803/erts-15.0.1/doc/html/persistent_term.html
      @@ -200,9 +200,9 @@ 

      The following example shows how lock contention for ETS tables can be minimized by having one ETS table for each scheduler. The table identifiers for the ETS tables are stored as a single persistent term:

          %% There is one ETS table for each scheduler.
      -    Sid = erlang:system_info(scheduler_id),
      -    Tid = element(Sid, persistent_term:get(?MODULE)),
      -    ets:update_counter(Tid, Key, 1).
      + Sid = erlang:system_info(scheduler_id), + Tid = element(Sid, persistent_term:get(?MODULE)), + ets:update_counter(Tid, Key, 1).

    diff --git a/prs/8803/erts-15.0.1/doc/html/supercarrier.html b/prs/8803/erts-15.0.1/doc/html/supercarrier.html index 6802e18a09108..b1edcbeb6d83d 100644 --- a/prs/8803/erts-15.0.1/doc/html/supercarrier.html +++ b/prs/8803/erts-15.0.1/doc/html/supercarrier.html @@ -229,12 +229,12 @@

    and free entire pages and we don't want to waste an entire page just to hold the block header of the following pages.

    Instead we store the meta information about all the free segments in a dedicated area apart from the sa and sua areas. Every free segment is -represented by a descriptor struct (ErtsFreeSegDesc).

    typedef struct {
    +represented by a descriptor struct (ErtsFreeSegDesc).

    typedef struct {
         RBTNode snode;      /* node in 'stree' */
         RBTNode anode;      /* node in 'atree' */
         char* start;
         char* end;
    -}ErtsFreeSegDesc;

    To find the smallest free segment that will satisfy a carrier allocation +}ErtsFreeSegDesc;

    To find the smallest free segment that will satisfy a carrier allocation (best fit), the free segments are organized in a tree sorted by size (stree). We search in this tree at allocation. If no free segment of sufficient size was found, the area (sa or sua) is instead expanded. diff --git a/prs/8803/erts-15.0.1/doc/html/time_correction.html b/prs/8803/erts-15.0.1/doc/html/time_correction.html index ec2b6bb3f8e39..9bc05aac32478 100644 --- a/prs/8803/erts-15.0.1/doc/html/time_correction.html +++ b/prs/8803/erts-15.0.1/doc/html/time_correction.html @@ -547,9 +547,9 @@

    the event occurs.

    Do

    Determine the order of events by saving a tuple containing monotonic time and a strictly monotonically increasing integer as -follows:

    Time = erlang:monotonic_time(),
    -UMI = erlang:unique_integer([monotonic]),
    -EventTag = {Time, UMI}

    These tuples are strictly monotonically ordered on the current runtime system +follows:

    Time = erlang:monotonic_time(),
    +UMI = erlang:unique_integer([monotonic]),
    +EventTag = {Time, UMI}

    These tuples are strictly monotonically ordered on the current runtime system instance according to creation time. It is important that the monotonic time is in the first element (the most significant element when comparing two-tuples). Using the monotonic time in the tuples, you can calculate time diff --git a/prs/8803/erts-15.0.1/doc/html/tracing.html b/prs/8803/erts-15.0.1/doc/html/tracing.html index 80b18f86a3916..81227bf868191 100644 --- a/prs/8803/erts-15.0.1/doc/html/tracing.html +++ b/prs/8803/erts-15.0.1/doc/html/tracing.html @@ -149,23 +149,23 @@

    to inspecting the stack we can only say where we're going to return to, which is not quite the same thing.

    As an illustration, when the caller option is enabled all trace messages from bar/1 will say that they were called from foo/0, even though it -went through a bunch of other functions on the way:

    foo() ->
    -    lots(),
    +went through a bunch of other functions on the way:

    foo() ->
    +    lots(),
         ok.
     
    -lots() ->
    -    'of'().
    +lots() ->
    +    'of'().
     
    -'of'() ->
    -    indirections().
    +'of'() ->
    +    indirections().
     
    -indirections() ->
    -    bar(10).
    +indirections() ->
    +    bar(10).
     
    -bar(0) ->
    +bar(0) ->
         done;
    -bar(N) ->
    -    bar(N - 1).

    +bar(N) -> + bar(N - 1).

    diff --git a/prs/8803/erts-15.0.1/doc/html/zlib.html b/prs/8803/erts-15.0.1/doc/html/zlib.html index 973399fc23583..4b1f09f19c421 100644 --- a/prs/8803/erts-15.0.1/doc/html/zlib.html +++ b/prs/8803/erts-15.0.1/doc/html/zlib.html @@ -133,18 +133,18 @@

    data. The data format is described by RFC 1950, RFC 1951, and -RFC 1952.

    A typical (compress) usage is as follows:

    Z = zlib:open(),
    -ok = zlib:deflateInit(Z,default),
    +RFC 1952.

    A typical (compress) usage is as follows:

    Z = zlib:open(),
    +ok = zlib:deflateInit(Z,default),
     
    -Compress = fun(end_of_data, _Cont) -> [];
    -              (Data, Cont) ->
    -                 [zlib:deflate(Z, Data)|Cont(Read(),Cont)]
    +Compress = fun(end_of_data, _Cont) -> [];
    +              (Data, Cont) ->
    +                 [zlib:deflate(Z, Data)|Cont(Read(),Cont)]
                end,
    -Compressed = Compress(Read(),Compress),
    -Last = zlib:deflate(Z, [], finish),
    -ok = zlib:deflateEnd(Z),
    -zlib:close(Z),
    -list_to_binary([Compressed|Last])

    In all functions errors, {'EXIT',{Reason,Backtrace}}, can be thrown, where +Compressed = Compress(Read(),Compress), +Last = zlib:deflate(Z, [], finish), +ok = zlib:deflateEnd(Z), +zlib:close(Z), +list_to_binary([Compressed|Last])

    In all functions errors, {'EXIT',{Reason,Backtrace}}, can be thrown, where Reason describes the error.

    Typical Reasons:

    • badarg - Bad argument.

    • not_initialized - The stream hasn't been initialized, eg. if inflateInit/1 wasn't called prior to a call to inflate/2.

    • not_on_controlling_process - The stream was used by a process that doesn't control it. Use set_controlling_process/2 if you need to transfer a @@ -853,11 +853,11 @@

      deflate(Z, Data, Flush)

      full too often can seriously degrade the compression.

      If Flush is set to finish, pending input is processed, pending output is flushed, and deflate/3 returns. Afterwards the only possible operations on the stream are deflateReset/1 or deflateEnd/1.

      Flush can be set to finish immediately after -deflateInit if all compression is to be done in one step.

      Example:

      zlib:deflateInit(Z),
      -B1 = zlib:deflate(Z,Data),
      -B2 = zlib:deflate(Z,<< >>,finish),
      -zlib:deflateEnd(Z),
      -list_to_binary([B1,B2])
      +deflateInit if all compression is to be done in one step.

      Example:

      zlib:deflateInit(Z),
      +B1 = zlib:deflate(Z,Data),
      +B2 = zlib:deflate(Z,<< >>,finish),
      +zlib:deflateEnd(Z),
      +list_to_binary([B1,B2])
      @@ -1409,20 +1409,20 @@

      inflateSetDictionary(Z, Dictionary)

      {'EXIT',{{need_dictionary,Adler},_StackTrace}} exception.

      The dictionary chosen by the compressor can be determined from the Adler value returned or thrown by the call to the inflate function. The compressor and decompressor must use the same dictionary (See deflateSetDictionary/2).

      After setting the dictionary the inflate operation should be retried without new -input.

      Example:

      deprecated_unpack(Z, Compressed, Dict) ->
      -     case catch zlib:inflate(Z, Compressed) of
      -          {'EXIT',{{need_dictionary,_DictID},_}} ->
      -                 ok = zlib:inflateSetDictionary(Z, Dict),
      -                 Uncompressed = zlib:inflate(Z, []);
      +input.

      Example:

      deprecated_unpack(Z, Compressed, Dict) ->
      +     case catch zlib:inflate(Z, Compressed) of
      +          {'EXIT',{{need_dictionary,_DictID},_}} ->
      +                 ok = zlib:inflateSetDictionary(Z, Dict),
      +                 Uncompressed = zlib:inflate(Z, []);
                 Uncompressed ->
                        Uncompressed
            end.
       
      -new_unpack(Z, Compressed, Dict) ->
      -    case zlib:inflate(Z, Compressed, [{exception_on_need_dict, false}]) of
      -        {need_dictionary, _DictId, Output} ->
      -            ok = zlib:inflateSetDictionary(Z, Dict),
      -            [Output | zlib:inflate(Z, [])];
      +new_unpack(Z, Compressed, Dict) ->
      +    case zlib:inflate(Z, Compressed, [{exception_on_need_dict, false}]) of
      +        {need_dictionary, _DictId, Output} ->
      +            ok = zlib:inflateSetDictionary(Z, Dict),
      +            [Output | zlib:inflate(Z, [])];
               Uncompressed ->
                   Uncompressed
           end.
      @@ -1498,18 +1498,18 @@

      safeInflate(Z, Data)

      desired, and the function will return {finished, Output} once all queued data has been decompressed.

      This function can introduce some output latency (reading input without producing any output).

      If a preset dictionary is required for further decompression, this function -returns a need_dictionary tuple. See inflateSetDictionary/2) for details.

      Example:

      walk(Compressed, Handler) ->
      -    Z = zlib:open(),
      -    zlib:inflateInit(Z),
      -    loop(Z, Handler, zlib:safeInflate(Z, Compressed)),
      -    zlib:inflateEnd(Z),
      -    zlib:close(Z).
      -
      -loop(Z, Handler, {continue, Output}) ->
      -    Handler(Output),
      -    loop(Z, Handler, zlib:safeInflate(Z, []));
      -loop(Z, Handler, {finished, Output}) ->
      -    Handler(Output).
      +returns a need_dictionary tuple. See inflateSetDictionary/2) for details.

      Example:

      walk(Compressed, Handler) ->
      +    Z = zlib:open(),
      +    zlib:inflateInit(Z),
      +    loop(Z, Handler, zlib:safeInflate(Z, Compressed)),
      +    zlib:inflateEnd(Z),
      +    zlib:close(Z).
      +
      +loop(Z, Handler, {continue, Output}) ->
      +    Handler(Output),
      +    loop(Z, Handler, zlib:safeInflate(Z, []));
      +loop(Z, Handler, {finished, Output}) ->
      +    Handler(Output).
      diff --git a/prs/8803/lib/asn1-5.3/doc/html/.build b/prs/8803/lib/asn1-5.3/doc/html/.build index 8d82cf86eab44..cca7f51935adf 100644 --- a/prs/8803/lib/asn1-5.3/doc/html/.build +++ b/prs/8803/lib/asn1-5.3/doc/html/.build @@ -27,7 +27,7 @@ dist/lato-latin-ext-300-normal-VPGGJKJL.woff2 dist/lato-latin-ext-400-normal-N27NCBWW.woff2 dist/lato-latin-ext-700-normal-Q2L5DVMW.woff2 dist/remixicon-NKANDIL5.woff2 -dist/search_data-06A31C18.js +dist/search_data-965B670D.js dist/sidebar_items-C28B0719.js index.html notes.html diff --git a/prs/8803/lib/asn1-5.3/doc/html/asn1.epub b/prs/8803/lib/asn1-5.3/doc/html/asn1.epub index 1d65f20ff4dc0..93c9414f8a560 100644 Binary files a/prs/8803/lib/asn1-5.3/doc/html/asn1.epub and b/prs/8803/lib/asn1-5.3/doc/html/asn1.epub differ diff --git a/prs/8803/lib/asn1-5.3/doc/html/asn1_getting_started.html b/prs/8803/lib/asn1-5.3/doc/html/asn1_getting_started.html index b55ba26538157..afe8937395ad7 100644 --- a/prs/8803/lib/asn1-5.3/doc/html/asn1_getting_started.html +++ b/prs/8803/lib/asn1-5.3/doc/html/asn1_getting_started.html @@ -143,37 +143,37 @@

      the syntax is correct and that the text represents proper ASN.1 code before generating an abstract syntax tree. The code generator then uses the abstract syntax tree to generate code.

      The generated Erlang files are placed in the current directory or in the -directory specified with option {outdir,Dir}.

      The compiler can be called from the Erlang shell like this:

      1> asn1ct:compile("People", [ber]).
      -ok

      Option verbose can be added to get information about the generated files:

      2> asn1ct:compile("People", [ber,verbose]).
      +directory specified with option {outdir,Dir}.

      The compiler can be called from the Erlang shell like this:

      1> asn1ct:compile("People", [ber]).
      +ok

      Option verbose can be added to get information about the generated files:

      2> asn1ct:compile("People", [ber,verbose]).
       Erlang ASN.1 compiling "People.asn"
      ---{generated,"People.asn1db"}--
      ---{generated,"People.hrl"}--
      ---{generated,"People.erl"}--
      +--{generated,"People.asn1db"}--
      +--{generated,"People.hrl"}--
      +--{generated,"People.erl"}--
       ok

      ASN.1 module People is now accepted and the abstract syntax tree is saved in file People.asn1db. The generated Erlang code is compiled using the Erlang compiler and loaded into the Erlang runtime system. There is now an API for -encode/2 and decode/2 in module People, which is called like this:

      'People':encode(<Type name>, <Value>)

      or:

      'People':decode(<Type name>, <Value>)

      Assume that there is a network application that receives instances of the ASN.1 +encode/2 and decode/2 in module People, which is called like this:

      'People':encode(<Type name>, <Value>)

      or:

      'People':decode(<Type name>, <Value>)

      Assume that there is a network application that receives instances of the ASN.1 defined type Person, modifies, and sends them back again:

      receive
      -   {Port,{data,Bytes}} ->
      -       case 'People':decode('Person',Bytes) of
      -           {ok,P} ->
      -               {ok,Answer} = 'People':encode('Person',mk_answer(P)),
      -               Port ! {self(),{command,Answer}};
      -           {error,Reason} ->
      -               exit({error,Reason})
      +   {Port,{data,Bytes}} ->
      +       case 'People':decode('Person',Bytes) of
      +           {ok,P} ->
      +               {ok,Answer} = 'People':encode('Person',mk_answer(P)),
      +               Port ! {self(),{command,Answer}};
      +           {error,Reason} ->
      +               exit({error,Reason})
              end
           end,

      In this example, a series of bytes is received from an external source and the bytes are then decoded into a valid Erlang term. This was achieved with the call 'People':decode('Person',Bytes), which returned an Erlang value of the ASN.1 type Person. Then an answer was constructed and encoded using 'People':encode('Person',Answer), which takes an instance of a defined ASN.1 -type and transforms it to a binary according to the BER or PER encoding rules.

      The encoder and decoder can also be run from the shell:

      2> Rockstar = {'Person',"Some Name",roving,50}.
      -{'Person',"Some Name",roving,50}
      -3> {ok,Bin} = 'People':encode('Person',Rockstar).
      -{ok,<<243,17,19,9,83,111,109,101,32,78,97,109,101,2,1,2,
      -      2,1,50>>}
      -4> {ok,Person} = 'People':decode('Person',Bin).
      -{ok,{'Person',"Some Name",roving,50}}

      +type and transforms it to a binary according to the BER or PER encoding rules.

      The encoder and decoder can also be run from the shell:

      2> Rockstar = {'Person',"Some Name",roving,50}.
      +{'Person',"Some Name",roving,50}
      +3> {ok,Bin} = 'People':encode('Person',Rockstar).
      +{ok,<<243,17,19,9,83,111,109,101,32,78,97,109,101,2,1,2,
      +      2,1,50>>}
      +4> {ok,Person} = 'People':decode('Person',Bin).
      +{ok,{'Person',"Some Name",roving,50}}

      @@ -271,16 +271,16 @@

      to manually add tags to certain constructs in order for the ASN.1 specification to be valid. Example of an old-style specification:

      Tags DEFINITIONS ::=
       BEGIN
      -  Afters ::= CHOICE { cheese [0] IA5String,
      -                      dessert [1] IA5String }
      +  Afters ::= CHOICE { cheese [0] IA5String,
      +                      dessert [1] IA5String }
       END

      Without the tags (the numbers in square brackets) the ASN.1 compiler refused to compile the file.

      In 1994 the global tagging mode AUTOMATIC TAGS was introduced. By putting AUTOMATIC TAGS in the module header, the ASN.1 compiler automatically adds tags when needed. The following is the same specification in AUTOMATIC TAGS mode:

      Tags DEFINITIONS AUTOMATIC TAGS ::=
       BEGIN
      -  Afters ::= CHOICE { cheese IA5String,
      -                      dessert IA5String }
      +  Afters ::= CHOICE { cheese IA5String,
      +                      dessert IA5String }
       END

      @@ -291,7 +291,7 @@

      and how values are assigned in Erlang.

      ASN.1 has both primitive and constructed types:

      Primitive TypesConstructed Types
      BOOLEANSEQUENCE
      INTEGERSET
      REALCHOICE
      NULLSET OF and SEQUENCE OF
      ENUMERATEDANY
      BIT STRINGANY DEFINED BY
      OCTET STRINGEXTERNAL
      Character StringsEMBEDDED PDV
      OBJECT IDENTIFIERCHARACTER STRING
      Object Descriptor
      TIME Types

      Table: Supported ASN.1 Types

      Note

      The values of each ASN.1 type have their own representation in Erlang, as described in the following sections. Users must provide these values for encoding according to the representation, as shown in the following example:

      Operational ::= BOOLEAN --ASN.1 definition

      In Erlang code it can look as follows:

      Val = true,
      -{ok,Bytes} = MyModule:encode('Operational', Val),

      +{ok,Bytes} = MyModule:encode('Operational', Val),

      @@ -308,11 +308,11 @@

      An ASN.1 INTEGER is represented by an integer in Erlang.

      The concept of subtyping can be applied to integers and to other ASN.1 types. The details of subtyping are not explained here; for more information, see X.680. Various syntaxes are allowed when defining a type as an integer:

      T1 ::= INTEGER
      -T2 ::= INTEGER (-2..7)
      -T3 ::= INTEGER (0..MAX)
      -T4 ::= INTEGER (0<..MAX)
      -T5 ::= INTEGER (MIN<..-99)
      -T6 ::= INTEGER {red(0),blue(1),white(2)}

      The Erlang representation of an ASN.1 INTEGER is an integer or an atom if a +T2 ::= INTEGER (-2..7) +T3 ::= INTEGER (0..MAX) +T4 ::= INTEGER (0<..MAX) +T5 ::= INTEGER (MIN<..-99) +T6 ::= INTEGER {red(0),blue(1),white(2)}

    The Erlang representation of an ASN.1 INTEGER is an integer or an atom if a Named Number List (see T6 in the previous list) is specified.

    The following is an example of Erlang code that assigns values for the types in the previous list:

    T1value = 0,
     T2value = 6,
    @@ -359,7 +359,7 @@ 

    The type BIT STRING can be used to model information that is made up of arbitrary length series of bits. It is intended to be used for selection of flags, not for binary files.

    In ASN.1, BIT STRING definitions can look as follows:

    Bits1 ::= BIT STRING
    -Bits2 ::= BIT STRING {foo(0),bar(1),gnu(2),gnome(3),punk(14)}

    The following two notations are available for representation of BIT STRING +Bits2 ::= BIT STRING {foo(0),bar(1),gnu(2),gnome(3),punk(14)}

    The following two notations are available for representation of BIT STRING values in Erlang and as input to the encode functions:

    1. A bitstring. By default, a BIT STRING with no symbolic names is decoded to an Erlang bitstring.
    2. A list of atoms corresponding to atoms in the NamedBitList in the BIT STRING definition. A BIT STRING with symbolic names is always decoded @@ -387,7 +387,7 @@

      OCTET STRING is the simplest of all ASN.1 types. OCTET STRING only moves or transfers, for example, binary files or other unstructured information complying with two rules: the bytes consist of octets and encoding is not required.

      It is possible to have the following ASN.1 type definitions:

      O1 ::= OCTET STRING
      -O2 ::= OCTET STRING (SIZE(28))

      With the following example assignments in Erlang:

      O1Val = <<17,13,19,20,0,0,255,254>>,
      +O2 ::= OCTET STRING (SIZE(28))

      With the following example assignments in Erlang:

      O1Val = <<17,13,19,20,0,0,255,254>>,
       O2Val = <<"must be exactly 28 chars....">>,

      By default, an OCTET STRING is always represented as an Erlang binary. If the specification has been compiled with option legacy_erlang_types, the encode functions accept both lists and binaries, and the decode functions decode an @@ -408,11 +408,11 @@

      of view, octets are very similar to character strings and are compiled in the same way.

      When PER is used, there is a significant difference in the encoding scheme for OCTET STRINGs and other strings. The constraints specified for a type -are especially important for PER, because they affect the encoding.

      Examples:

      Digs ::= NumericString (SIZE(1..3))
      -TextFile ::= IA5String (SIZE(0..64000))

      The corresponding Erlang assignments:

      DigsVal1 = "456",
      +are especially important for PER, because they affect the encoding.

      Examples:

      Digs ::= NumericString (SIZE(1..3))
      +TextFile ::= IA5String (SIZE(0..64000))

      The corresponding Erlang assignments:

      DigsVal1 = "456",
       DigsVal2 = "123",
       TextFileVal1 = "abc...xyz...",
      -TextFileVal2 = [88,76,55,44,99,121 .......... a lot of characters here ....]

      The Erlang representation for BMPString and UniversalString is either a list +TextFileVal2 = [88,76,55,44,99,121 .......... a lot of characters here ....]

      The Erlang representation for BMPString and UniversalString is either a list of ASCII values or a list of quadruples. The quadruple representation associates to the Unicode standard representation of characters. The ASCII characters are all represented by quadruples beginning with three zeros like {0,0,0,65} for @@ -421,26 +421,26 @@

      in file PrimStrings.asn1:

      PrimStrings DEFINITIONS AUTOMATIC TAGS ::=
       BEGIN
          BMP ::= BMPString
      -END

      Encoding and decoding some strings:

      1> asn1ct:compile('PrimStrings', [ber]).
      +END

      Encoding and decoding some strings:

      1> asn1ct:compile('PrimStrings', [ber]).
       ok
      -2> {ok,Bytes1} = 'PrimStrings':encode('BMP', [{0,0,53,53},{0,0,45,56}]).
      -{ok,<<30,4,53,54,45,56>>}
      -3> 'PrimStrings':decode('BMP', Bytes1).
      -{ok,[{0,0,53,53},{0,0,45,56}]}
      -4> {ok,Bytes2} = 'PrimStrings':encode('BMP', [{0,0,53,53},{0,0,0,65}]).
      -{ok,<<30,4,53,53,0,65>>}
      -5> 'PrimStrings':decode('BMP', Bytes2).
      -{ok,[{0,0,53,53},65]}
      -6> {ok,Bytes3} = 'PrimStrings':encode('BMP', "BMP string").
      -{ok,<<30,20,0,66,0,77,0,80,0,32,0,115,0,116,0,114,0,105,0,110,0,103>>}
      -7> 'PrimStrings':decode('BMP', Bytes3).
      -{ok,"BMP string"}

      Type UTF8String is represented as a UTF-8 encoded binary in Erlang. Such +2> {ok,Bytes1} = 'PrimStrings':encode('BMP', [{0,0,53,53},{0,0,45,56}]). +{ok,<<30,4,53,54,45,56>>} +3> 'PrimStrings':decode('BMP', Bytes1). +{ok,[{0,0,53,53},{0,0,45,56}]} +4> {ok,Bytes2} = 'PrimStrings':encode('BMP', [{0,0,53,53},{0,0,0,65}]). +{ok,<<30,4,53,53,0,65>>} +5> 'PrimStrings':decode('BMP', Bytes2). +{ok,[{0,0,53,53},65]} +6> {ok,Bytes3} = 'PrimStrings':encode('BMP', "BMP string"). +{ok,<<30,20,0,66,0,77,0,80,0,32,0,115,0,116,0,114,0,105,0,110,0,103>>} +7> 'PrimStrings':decode('BMP', Bytes3). +{ok,"BMP string"}

    Type UTF8String is represented as a UTF-8 encoded binary in Erlang. Such binaries can be created directly using the binary syntax or by converting from a list of Unicode code points using function unicode:characters_to_binary/1.

    The following shows examples of how UTF-8 encoded binaries can be created and manipulated:

    1> Gs = "Мой маленький Гном".
    -[1052,1086,1081,32,1084,1072,1083,1077,1085,1100,1082,1080,
    - 1081,32,1043,1085,1086,1084]
    -2> Gbin = unicode:characters_to_binary(Gs).
    +[1052,1086,1081,32,1084,1072,1083,1077,1085,1100,1082,1080,
    + 1081,32,1043,1085,1086,1084]
    +2> Gbin = unicode:characters_to_binary(Gs).
     <<208,156,208,190,208,185,32,208,188,208,176,208,187,208,
       181,208,189,209,140,208,186,208,184,208,185,32,208,147,
       208,...>>
    @@ -448,22 +448,22 @@ 

    <<208,156,208,190,208,185,32,208,188,208,176,208,187,208, 181,208,189,209,140,208,186,208,184,208,185,32,208,147, 208,...>> -4> Gs = unicode:characters_to_list(Gbin). -[1052,1086,1081,32,1084,1072,1083,1077,1085,1100,1082,1080, - 1081,32,1043,1085,1086,1084]

    For details, see the unicode module in STDLIB.

    In the following example, this ASN.1 specification is used:

    UTF DEFINITIONS AUTOMATIC TAGS ::=
    +4> Gs = unicode:characters_to_list(Gbin).
    +[1052,1086,1081,32,1084,1072,1083,1077,1085,1100,1082,1080,
    + 1081,32,1043,1085,1086,1084]

    For details, see the unicode module in STDLIB.

    In the following example, this ASN.1 specification is used:

    UTF DEFINITIONS AUTOMATIC TAGS ::=
     BEGIN
        UTF ::= UTF8String
    -END

    Encoding and decoding a string with Unicode characters:

    5> asn1ct:compile('UTF', [ber]).
    +END

    Encoding and decoding a string with Unicode characters:

    5> asn1ct:compile('UTF', [ber]).
     ok
    -6> {ok,Bytes1} = 'UTF':encode('UTF', <<"Гном"/utf8>>).
    -{ok,<<12,8,208,147,208,189,208,190,208,188>>}
    -7> {ok,Bin1} = 'UTF':decode('UTF', Bytes1).
    -{ok,<<208,147,208,189,208,190,208,188>>}
    -8> io:format("~ts\n", [Bin1]).
    +6> {ok,Bytes1} = 'UTF':encode('UTF', <<"Гном"/utf8>>).
    +{ok,<<12,8,208,147,208,189,208,190,208,188>>}
    +7> {ok,Bin1} = 'UTF':decode('UTF', Bytes1).
    +{ok,<<208,147,208,189,208,190,208,188>>}
    +8> io:format("~ts\n", [Bin1]).
     Гном
     ok
    -9> unicode:characters_to_list(Bin1).
    -[1043,1085,1086,1084]

    +9> unicode:characters_to_list(Bin1). +[1043,1085,1086,1084]

    @@ -499,15 +499,15 @@

    The structured types of ASN.1 are constructed from other types in a manner similar to the concepts of arrays and structs in C.

    A SEQUENCE in ASN.1 is comparable with a struct in C and a record in Erlang. A -SEQUENCE can be defined as follows:

    Pdu ::= SEQUENCE {
    +SEQUENCE can be defined as follows:

    Pdu ::= SEQUENCE {
        a INTEGER,
        b REAL,
        c OBJECT IDENTIFIER,
    -   d NULL }

    This is a 4-component structure called Pdu. By default, a SEQUENCE is + d NULL }

    This is a 4-component structure called Pdu. By default, a SEQUENCE is represented by a record in Erlang. It can also be represented as a map; see Map representation for SEQUENCE and SET. For each SEQUENCE and SET in an ASN.1 module an Erlang record declaration is -generated. For Pdu, a record like the following is defined:

    -record('Pdu', {a, b, c, d}).

    The record declarations for a module M are placed in a separate M.hrl file.

    Values can be assigned in Erlang as follows:

    MyPdu = #'Pdu'{a=22,b=77.99,c={0,1,2,3,4},d='NULL'}.

    The decode functions return a record as result when decoding a SEQUENCE or a +generated. For Pdu, a record like the following is defined:

    -record('Pdu', {a, b, c, d}).

    The record declarations for a module M are placed in a separate M.hrl file.

    Values can be assigned in Erlang as follows:

    MyPdu = #'Pdu'{a=22,b=77.99,c={0,1,2,3,4},d='NULL'}.

    The decode functions return a record as result when decoding a SEQUENCE or a SET.

    A SEQUENCE and a SET can contain a component with a DEFAULT keyword followed by the actual value, which is the default value. The DEFAULT keyword means that the application doing the encoding can omit encoding of the value, @@ -532,21 +532,21 @@

    Seq3 ::= SEQUENCE { bs BIT STRING {a(0), b(1), c(2)} DEFAULT {a, c} } -END

    Example where the BER encoder is able to omit encoding of the default values:

    1> asn1ct:compile('File', [ber]).
    +END

    Example where the BER encoder is able to omit encoding of the default values:

    1> asn1ct:compile('File', [ber]).
     ok
    -2> 'File':encode('Seq1', {'Seq1',asn1_DEFAULT,asn1_DEFAULT}).
    -{ok,<<48,0>>}
    -3> 'File':encode('Seq1', {'Seq1',1,{'Seq2',true,15}}).
    -{ok,<<48,0>>}

    Example with a named BIT STRING where the BER encoder does not omit the -encoding:

    4> 'File':encode('Seq3', {'Seq3',asn1_DEFAULT).
    -{ok,<<48,0>>}
    -5> 'File':encode('Seq3', {'Seq3',<<16#101:3>>).
    -{ok,<<48,4,128,2,5,160>>}

    The DER encoder omits the encoding for the same BIT STRING:

    6> asn1ct:compile('File', [ber,der]).
    +2> 'File':encode('Seq1', {'Seq1',asn1_DEFAULT,asn1_DEFAULT}).
    +{ok,<<48,0>>}
    +3> 'File':encode('Seq1', {'Seq1',1,{'Seq2',true,15}}).
    +{ok,<<48,0>>}

    Example with a named BIT STRING where the BER encoder does not omit the +encoding:

    4> 'File':encode('Seq3', {'Seq3',asn1_DEFAULT).
    +{ok,<<48,0>>}
    +5> 'File':encode('Seq3', {'Seq3',<<16#101:3>>).
    +{ok,<<48,4,128,2,5,160>>}

    The DER encoder omits the encoding for the same BIT STRING:

    6> asn1ct:compile('File', [ber,der]).
     ok
    -7> 'File':encode('Seq3', {'Seq3',asn1_DEFAULT).
    -{ok,<<48,0>>}
    -8> 'File':encode('Seq3', {'Seq3',<<16#101:3>>).
    -{ok,<<48,0>>}

    +7> 'File':encode('Seq3', {'Seq3',asn1_DEFAULT). +{ok,<<48,0>>} +8> 'File':encode('Seq3', {'Seq3',<<16#101:3>>). +{ok,<<48,0>>}

    @@ -582,14 +582,14 @@

    b BOOLEAN OPTIONAL, c IA5String } -END

    Optional fields are to be omitted from the map if they have no value:

    1> asn1ct:compile('File', [per,maps]).
    +END

    Optional fields are to be omitted from the map if they have no value:

    1> asn1ct:compile('File', [per,maps]).
     ok
    -2> {ok,E} = 'File':encode('Seq1', #{a=>0,c=>"string"}).
    -{ok,<<128,1,0,6,115,116,114,105,110,103>>}

    When decoding, optional fields will be omitted from the map:

    3> 'File':decode('Seq1', E).
    -{ok,#{a => 0,c => "string"}}

    Default values can be omitted from the map:

    4> {ok,E2} = 'File':encode('Seq1', #{c=>"string"}).
    -{ok,<<0,6,115,116,114,105,110,103>>}
    -5> 'File':decode('Seq1', E2).
    -{ok,#{a => 42,c => "string"}}

    Note

    It is not allowed to use the atoms asn1_VALUE and asn1_DEFAULT with maps.

    +2> {ok,E} = 'File':encode('Seq1', #{a=>0,c=>"string"}). +{ok,<<128,1,0,6,115,116,114,105,110,103>>}

    When decoding, optional fields will be omitted from the map:

    3> 'File':decode('Seq1', E).
    +{ok,#{a => 0,c => "string"}}

    Default values can be omitted from the map:

    4> {ok,E2} = 'File':encode('Seq1', #{c=>"string"}).
    +{ok,<<0,6,115,116,114,105,110,103>>}
    +5> 'File':decode('Seq1', E2).
    +{ok,#{a => 42,c => "string"}}

    Note

    It is not allowed to use the atoms asn1_VALUE and asn1_DEFAULT with maps.

    @@ -602,8 +602,8 @@

    x REAL, y INTEGER, z OBJECT IDENTIFIER } -END

    It is then possible to assign values as follows:

    TVal1 = {y,17},
    -TVal2 = {z,{0,1,2}},

    A CHOICE value is always represented as the tuple {ChoiceAlternative, Val} +END

    It is then possible to assign values as follows:

    TVal1 = {y,17},
    +TVal2 = {z,{0,1,2}},

    A CHOICE value is always represented as the tuple {ChoiceAlternative, Val} where ChoiceAlternative is an atom denoting the selected choice alternative.

    Extensible CHOICE

    When a CHOICE contains an extension marker and the decoder detects an unknown alternative of the CHOICE, the value is represented as follows:

    {asn1_ExtAlt, BytesForOpenType}

    Here BytesForOpenType is a list of bytes constituting the encoding of the "unknown" CHOICE alternative.

    @@ -669,8 +669,8 @@

    x REAL, y INTEGER, z OBJECT IDENTIFIER } - END

    SEQUENCE b can be encoded as follows in Erlang:

    1> 'EmbeddedExample':encode('B', {'B',[4,5,6,7,8],{x,"7.77"}}).
    -{ok,<<5,56,0,8,3,55,55,55,46,69,45,50>>}

    + END

    SEQUENCE b can be encoded as follows in Erlang:

    1> 'EmbeddedExample':encode('B', {'B',[4,5,6,7,8],{x,"7.77"}}).
    +{ok,<<5,56,0,8,3,55,55,55,46,69,45,50>>}

    @@ -696,10 +696,10 @@

    a INTEGER, b FooType } } -FooType ::= [3] VisibleString

    The following records are generated because of type Emb:

    -record('Emb,{a, b, c}).
    --record('Emb_b',{a, b = asn1_DEFAULT}). % the embedded SET type

    Values of type Emb can be assigned as follows:

    V = #'Emb'{a=["qqqq",[1,2,255]],
    -           b = #'Emb_b'{a=99},
    -           c ={b,"Can you see this"}}.

    For an embedded type of type SEQUENCE/SET in a SEQUENCE/SET, the record +FooType ::= [3] VisibleString

    The following records are generated because of type Emb:

    -record('Emb,{a, b, c}).
    +-record('Emb_b',{a, b = asn1_DEFAULT}). % the embedded SET type

    Values of type Emb can be assigned as follows:

    V = #'Emb'{a=["qqqq",[1,2,255]],
    +           b = #'Emb_b'{a=99},
    +           c ={b,"Can you see this"}}.

    For an embedded type of type SEQUENCE/SET in a SEQUENCE/SET, the record name is extended with an underscore and the component name. If the embedded structure is deeper with the SEQUENCE, SET, or CHOICE types in the line, each component name/alternative name is added to the record name.

    Example:

    Seq ::= SEQUENCE{
    @@ -708,7 +708,7 @@ 

    c INTEGER } } -}

    This results in the following record:

    -record('Seq_a_b',{c}).

    If the structured type has a component with an embedded SEQUENCE OF/SET OF +}

    This results in the following record:

    -record('Seq_a_b',{c}).

    If the structured type has a component with an embedded SEQUENCE OF/SET OF which embedded type in turn is a SEQUENCE/SET, it gives a record with the SEQUENCE OF/SET OF addition as in the following example:

    Seq ::= SEQUENCE {
         a SEQUENCE OF SEQUENCE {
    @@ -717,8 +717,8 @@ 

    c SET OF SEQUENCE { d } -}

    This results in the following records:

    -record('Seq_a_SEQOF'{b}).
    --record('Seq_c_SETOF'{d}).

    A parameterized type is to be considered as an embedded type. Each time such a +}

    This results in the following records:

    -record('Seq_a_SEQOF'{b}).
    +-record('Seq_c_SETOF'{d}).

    A parameterized type is to be considered as an embedded type. Each time such a type is referenced, an instance of it is defined. Thus, in the following example a record with name 'Seq_b' is generated in the .hrl file and is used to hold values:

    Seq ::= SEQUENCE {
    @@ -733,15 +733,15 @@ 

    Recursive Types

    -

    Types that refer to themselves are called recursive types. Example:

    Rec ::= CHOICE {
    +

    Types that refer to themselves are called recursive types. Example:

    Rec ::= CHOICE {
          nothing NULL,
    -     something SEQUENCE {
    +     something SEQUENCE {
               a INTEGER,
               b OCTET STRING,
    -          c Rec }}

    This is allowed in ASN.1 and the ASN.1-to-Erlang compiler supports this -recursive type. A value for this type is assigned in Erlang as follows:

    V = {something,#'Rec_something'{a = 77,
    +          c Rec }}

    This is allowed in ASN.1 and the ASN.1-to-Erlang compiler supports this +recursive type. A value for this type is assigned in Erlang as follows:

    V = {something,#'Rec_something'{a = 77,
                                     b = "some octets here",
    -                                c = {nothing,'NULL'}}}.

    + c = {nothing,'NULL'}}}.

    @@ -750,22 +750,22 @@

    Values can be assigned to an ASN.1 type within the ASN.1 code itself, as opposed to the actions in the previous section where a value was assigned to an ASN.1 type in Erlang. The full value syntax of ASN.1 is supported and X.680 describes -in detail how to assign values in ASN.1. A short example:

    TT ::= SEQUENCE {
    +in detail how to assign values in ASN.1. A short example:

    TT ::= SEQUENCE {
        a INTEGER,
    -   b SET OF OCTET STRING }
    +   b SET OF OCTET STRING }
     
    -tt TT ::= {a 77,b {"kalle","kula"}}

    The value defined here can be used in several ways. It can, for example, be used +tt TT ::= {a 77,b {"kalle","kula"}}

    The value defined here can be used in several ways. It can, for example, be used as the value in some DEFAULT component:

    SS ::= SET {
         s OBJECT IDENTIFIER,
         val TT DEFAULT tt }

    It can also be used from inside an Erlang program. If this ASN.1 code is defined in ASN.1 module Values, the ASN.1 value tt can be reached from Erlang as a -function call to 'Values':tt() as in the following example:

    1> Val = 'Values':tt().
    -{'TT',77,["kalle","kula"]}
    -2> {ok,Bytes} = 'Values':encode('TT',Val).
    -{ok,<<48,18,128,1,77,161,13,4,5,107,97,108,108,101,4,4,
    -      107,117,108,97>>}
    -4> 'Values':decode('TT',Bytes).
    -{ok,{'TT',77,["kalle","kula"]}}
    +function call to 'Values':tt() as in the following example:

    1> Val = 'Values':tt().
    +{'TT',77,["kalle","kula"]}
    +2> {ok,Bytes} = 'Values':encode('TT',Val).
    +{ok,<<48,18,128,1,77,161,13,4,5,107,97,108,108,101,4,4,
    +      107,117,108,97>>}
    +4> 'Values':decode('TT',Bytes).
    +{ok,{'TT',77,["kalle","kula"]}}
     5>

    This example shows that a function is generated by the compiler that returns a valid Erlang representation of the value, although the value is of a complex type.

    Furthermore, if the option maps is not used, a macro is generated for each @@ -818,10 +818,10 @@

    object1 | object2}

    You cannot encode a class, object, or object set, only refer to it when defining other ASN.1 entities. Typically you refer to a class as well as to object sets by table constraints and component relation constraints (X.682) in ASN.1 types, -as in the following:

    StartMessage  ::= SEQUENCE {
    -    msgId  GENERAL-PROCEDURE.&id  ({GENERAL-PROCEDURES}),
    -    content GENERAL-PROCEDURE.&Message ({GENERAL-PROCEDURES}{@msgId}),
    -    }

    In type StartMessage, the constraint following field content tells that in a +as in the following:

    StartMessage  ::= SEQUENCE {
    +    msgId  GENERAL-PROCEDURE.&id  ({GENERAL-PROCEDURES}),
    +    content GENERAL-PROCEDURE.&Message ({GENERAL-PROCEDURES}{@msgId}),
    +    }

    In type StartMessage, the constraint following field content tells that in a value of type StartMessage the value in field content must come from the same object that is chosen by field msgId.

    So, the value #'StartMessage'{msgId="home",content="Any Printable String"} is legal to encode as a StartMessage value. However, the value diff --git a/prs/8803/lib/asn1-5.3/doc/html/asn1_spec.html b/prs/8803/lib/asn1-5.3/doc/html/asn1_spec.html index 1f2f8580b031d..0c787b31da77e 100644 --- a/prs/8803/lib/asn1-5.3/doc/html/asn1_spec.html +++ b/prs/8803/lib/asn1-5.3/doc/html/asn1_spec.html @@ -165,37 +165,37 @@

    exclusive decode is enabled. This function decodes the parts that were left undecoded during the exclusive decode.

    Both functions are described in the following.

    If the exclusive decode function has, for example, the name decode_exclusive and an ASN.1 encoded message Bin is to be exclusive decoded, the call is as -follows:

    {ok,ExclMessage} = 'MyModule':decode_exclusive(Bin)

    The result ExclMessage has the same structure as a +follows:

    {ok,ExclMessage} = 'MyModule':decode_exclusive(Bin)

    The result ExclMessage has the same structure as a complete decode would have, except for the parts of the top type that were not decoded. The undecoded parts are on their places in the structure on format {TypeKey,UndecodedValue}.

    Each undecoded part that is to be decoded must be fed into function -decode_part/2 as follows:

    {ok,PartMessage} = 'MyModule':decode_part(TypeKey, UndecodedValue)

    +decode_part/2 as follows:

    {ok,PartMessage} = 'MyModule':decode_part(TypeKey, UndecodedValue)

    Writing an Exclusive Decode Instruction

    -

    This instruction is written in the configuration file in the following format:

    ExclusiveDecodeInstruction = {exclusive_decode,{ModuleName,DecodeInstructions}}.
    +

    This instruction is written in the configuration file in the following format:

    ExclusiveDecodeInstruction = {exclusive_decode,{ModuleName,DecodeInstructions}}.
     
    -ModuleName = atom()
    +ModuleName = atom()
     
    -DecodeInstructions = [DecodeInstruction]+
    +DecodeInstructions = [DecodeInstruction]+
     
    -DecodeInstruction = {ExclusiveDecodeFunctionName,TypeList}
    +DecodeInstruction = {ExclusiveDecodeFunctionName,TypeList}
     
    -ExclusiveDecodeFunctionName = atom()
    +ExclusiveDecodeFunctionName = atom()
     
    -TypeList = [TopType,ElementList]
    +TypeList = [TopType,ElementList]
     
    -ElementList = [Element]+
    +ElementList = [Element]+
     
    -Element = {Name,parts} |
    -          {Name,undecoded} |
    -          {Name,ElementList}
    +Element = {Name,parts} |
    +          {Name,undecoded} |
    +          {Name,ElementList}
     
    -TopType = atom()
    +TopType = atom()
     
    -Name = atom()

    The instruction must be a valid Erlang term terminated by a dot.

    In TypeList the path from the top type to each undecoded subcomponent is +Name = atom()

    The instruction must be a valid Erlang term terminated by a dot.

    In TypeList the path from the top type to each undecoded subcomponent is described. TopType is the name of a top-level type in the ASN.1 specification. The action for each component in ElementList is described by one of:

    • {Name,parts}
    • {Name,undecoded}
    • {Name,ElementList}

    The use and effect of the actions are as follows:

    • {Name,undecoded} - Leaves the element undecoded. The type of Name can be any ASN.1 type. The value of element Name is returned as a tuple (as @@ -261,78 +261,78 @@

      ['Button',[{number,undecoded}]]}]}}.

    The following figure shows the bytes of a Window:status message. The components buttonList and actions are excluded from decode. Only state and enabled are decoded when decode__Window_exclusive is called.

    Bytes of a Window:status Message

    Here follows an example of how the module. Note that option no_ok_wrapper is -used to make the example more concise.

    1> asn1ct:compile('GUI', [ber,asn1config,no_ok_wrapper]).
    +used to make the example more concise.

    1> asn1ct:compile('GUI', [ber,asn1config,no_ok_wrapper]).
     ok
    -2> rr('GUI').
    -['Action','Button','Status']
    -3> ButtonMsg = #'Button'{number=123,on=true}.
    -#'Button'{number = 123,on = true}
    -4> ButtonBytes = 'GUI':encode('Button', ButtonMsg).
    +2> rr('GUI').
    +['Action','Button','Status']
    +3> ButtonMsg = #'Button'{number=123,on=true}.
    +#'Button'{number = 123,on = true}
    +4> ButtonBytes = 'GUI':encode('Button', ButtonMsg).
     <<48,6,128,1,123,129,1,255>>
    -5> ExclusiveMsgButton = 'GUI':decode_Button_exclusive(ButtonBytes).
    -#'Button'{number = {'Button_number',<<128,1,123>>},
    -          on = true}
    -6> {UndecKey,UndecBytes} = ExclusiveMsgButton#'Button'.number.
    -{'Button_number',<<128,1,123>>}
    -7> 'GUI':decode_part(UndecKey, UndecBytes).
    +5> ExclusiveMsgButton = 'GUI':decode_Button_exclusive(ButtonBytes).
    +#'Button'{number = {'Button_number',<<128,1,123>>},
    +          on = true}
    +6> {UndecKey,UndecBytes} = ExclusiveMsgButton#'Button'.number.
    +{'Button_number',<<128,1,123>>}
    +7> 'GUI':decode_part(UndecKey, UndecBytes).
     123
     8> WindowMsg =
    -{status,{'Status',35,
    -   [{'Button',3,true},
    -    {'Button',4,false},
    -    {'Button',5,true},
    -    {'Button',6,true},
    -    {'Button',7,false}],
    +{status,{'Status',35,
    +   [{'Button',3,true},
    +    {'Button',4,false},
    +    {'Button',5,true},
    +    {'Button',6,true},
    +    {'Button',7,false}],
        false,
    -   {possibleActions,[{'Action',16,{'Button',17,true}}]}}}.
    -{status,#'Status'{state = 35,
    -        buttonList = [#'Button'{number = 3,on = true},
    -                      #'Button'{number = 4,on = false},
    -                      #'Button'{number = 5,on = true},
    -                      #'Button'{number = 6,on = true},
    -                      #'Button'{number = 7,on = false}],
    +   {possibleActions,[{'Action',16,{'Button',17,true}}]}}}.
    +{status,#'Status'{state = 35,
    +        buttonList = [#'Button'{number = 3,on = true},
    +                      #'Button'{number = 4,on = false},
    +                      #'Button'{number = 5,on = true},
    +                      #'Button'{number = 6,on = true},
    +                      #'Button'{number = 7,on = false}],
             enabled = false,
    -        actions = {possibleActions,[#'Action'{number = 16,
    -                                              handle = #'Button'{number = 17,on = true}}]}}}
    -9> WindowBytes = 'GUI':encode('Window', WindowMsg).
    +        actions = {possibleActions,[#'Action'{number = 16,
    +                                              handle = #'Button'{number = 17,on = true}}]}}}
    +9> WindowBytes = 'GUI':encode('Window', WindowMsg).
     <<161,65,128,1,35,161,40,48,6,128,1,3,129,1,255,48,6,128,
       1,4,129,1,0,48,6,128,1,5,129,...>>
    -10> {status,#'Status'{buttonList={UndecWindowKey,UndecWindowParts}}} =
    -'GUI':decode_Window_exclusive(WindowBytes).
    -{status,#'Status'{state = 35,
    -                  buttonList = {'Status_buttonList',[<<48,6,128,1,3,129,1,
    +10> {status,#'Status'{buttonList={UndecWindowKey,UndecWindowParts}}} =
    +'GUI':decode_Window_exclusive(WindowBytes).
    +{status,#'Status'{state = 35,
    +                  buttonList = {'Status_buttonList',[<<48,6,128,1,3,129,1,
                                                            255>>,
                                                          <<48,6,128,1,4,129,1,0>>,
                                                          <<48,6,128,1,5,129,1,255>>,
                                                          <<48,6,128,1,6,129,1,255>>,
    -                                                     <<48,6,128,1,7,129,1,0>>]},
    +                                                     <<48,6,128,1,7,129,1,0>>]},
                       enabled = false,
    -                  actions = {'Status_actions',<<163,15,160,13,48,11,128,
    +                  actions = {'Status_actions',<<163,15,160,13,48,11,128,
                                                     1,16,161,6,128,1,17,129,
    -                                                1,255>>}}}
    -11> 'GUI':decode_part(UndecWindowKey, UndecWindowParts).
    -[#'Button'{number = 3,on = true},
    - #'Button'{number = 4,on = false},
    - #'Button'{number = 5,on = true},
    - #'Button'{number = 6,on = true},
    - #'Button'{number = 7,on = false}]
    -12> 'GUI':decode_part(UndecWindowKey, hd(UndecWindowParts)).
    -#'Button'{number = 3,on = true}
    -13> {status,#'Status'{actions={ChoiceKey,ChoiceUndec}}} = v(10).
    -{status,#'Status'{state = 35,
    -                  buttonList = {'Status_buttonList',[<<48,6,128,1,3,129,1,
    +                                                1,255>>}}}
    +11> 'GUI':decode_part(UndecWindowKey, UndecWindowParts).
    +[#'Button'{number = 3,on = true},
    + #'Button'{number = 4,on = false},
    + #'Button'{number = 5,on = true},
    + #'Button'{number = 6,on = true},
    + #'Button'{number = 7,on = false}]
    +12> 'GUI':decode_part(UndecWindowKey, hd(UndecWindowParts)).
    +#'Button'{number = 3,on = true}
    +13> {status,#'Status'{actions={ChoiceKey,ChoiceUndec}}} = v(10).
    +{status,#'Status'{state = 35,
    +                  buttonList = {'Status_buttonList',[<<48,6,128,1,3,129,1,
                                                            255>>,
                                                          <<48,6,128,1,4,129,1,0>>,
                                                          <<48,6,128,1,5,129,1,255>>,
                                                          <<48,6,128,1,6,129,1,255>>,
    -                                                     <<48,6,128,1,7,129,1,0>>]},
    +                                                     <<48,6,128,1,7,129,1,0>>]},
                       enabled = false,
    -                  actions = {'Status_actions',<<163,15,160,13,48,11,128,
    +                  actions = {'Status_actions',<<163,15,160,13,48,11,128,
                                                     1,16,161,6,128,1,17,129,
    -                                                1,255>>}}}
    -14> 'GUI':decode_part(ChoiceKey, ChoiceUndec).
    -{possibleActions,[#'Action'{number = 16,
    -                            handle = #'Button'{number = 17,on = true}}]}

    + 1,255>>}}} +14> 'GUI':decode_part(ChoiceKey, ChoiceUndec). +{possibleActions,[#'Action'{number = 16, + handle = #'Button'{number = 17,on = true}}]}

    @@ -369,23 +369,23 @@

    Writing a Selective Decode Instruction

    One or more selective decode functions can be described in a configuration file. -Use the following notation:

    SelectiveDecodeInstruction = {selective_decode,{ModuleName,DecodeInstructions}}.
    +Use the following notation:

    SelectiveDecodeInstruction = {selective_decode,{ModuleName,DecodeInstructions}}.
     
    -ModuleName = atom()
    +ModuleName = atom()
     
    -DecodeInstructions = [DecodeInstruction]+
    +DecodeInstructions = [DecodeInstruction]+
     
    -DecodeInstruction = {SelectiveDecodeFunctionName,TypeList}
    +DecodeInstruction = {SelectiveDecodeFunctionName,TypeList}
     
    -SelectiveDecodeFunctionName = atom()
    +SelectiveDecodeFunctionName = atom()
     
    -TypeList = [TopType|ElementList]
    +TypeList = [TopType|ElementList]
     
     ElementList = Name|ListSelector
     
    -Name = atom()
    +Name = atom()
     
    -ListSelector = [integer()]

    The instruction must be a valid Erlang term terminated by a dot.

    • ModuleName is the same as the name of the ASN.1 specification, but without +ListSelector = [integer()]

    The instruction must be a valid Erlang term terminated by a dot.

    • ModuleName is the same as the name of the ASN.1 specification, but without the extension.
    • DecodeInstruction is a tuple with your chosen function name and the components from the top type that leads to the single type you want to decode. Make sure to choose a name of your function that is not the same as any of the @@ -406,53 +406,53 @@

      In this example, the same ASN.1 specification as in section Writing an Exclusive Decode Instruction is used. The -following is a valid selective decode instruction:

      {selective_decode,
      -    {'GUI',
      -        [{selected_decode_Window1,
      -            ['Window',status,buttonList,
      -             [1],
      -             number]},
      - {selected_decode_Action,
      -     ['Action',handle,number]},
      - {selected_decode_Window2,
      -     ['Window',
      +following is a valid selective decode instruction:

      {selective_decode,
      +    {'GUI',
      +        [{selected_decode_Window1,
      +            ['Window',status,buttonList,
      +             [1],
      +             number]},
      + {selected_decode_Action,
      +     ['Action',handle,number]},
      + {selected_decode_Window2,
      +     ['Window',
             status,
             actions,
             possibleActions,
      -      [1],
      -      handle,number]}]}}.

      The first instruction, + [1], + handle,number]}]}}.

      The first instruction, {selected_decode_Window1,['Window',status,buttonList,[1],number]} is described in the previous section.

      The second instruction, {selected_decode_Action,['Action',handle,number]}, takes component number in the handle component of type Action. If the value is ValAction = {'Action',17,{'Button',4711,false}}, the internal value 4711 is to be picked by selected_decode_Action. In an Erlang terminal it looks -as follows:

      1> asn1ct:compile('GUI', [ber,asn1config,no_ok_wrapper]).
      +as follows:

      1> asn1ct:compile('GUI', [ber,asn1config,no_ok_wrapper]).
       ok
      -2> ValAction = {'Action',17,{'Button',4711,false}}.
      -{'Action',17,{'Button',4711,false}}
      -3> Bytes = 'GUI':encode('Action',ValAction).
      +2> ValAction = {'Action',17,{'Button',4711,false}}.
      +{'Action',17,{'Button',4711,false}}
      +3> Bytes = 'GUI':encode('Action',ValAction).
       <<48,18,2,1,17,160,13,172,11,171,9,48,7,128,2,18,103,129,1,0>>
      -4> 'GUI':selected_decode_Action(Bytes).
      +4> 'GUI':selected_decode_Action(Bytes).
       4711

      The third instruction, ['Window',status,actions,possibleActions,[1],handle,number], works as follows:

      • Step 1: Starts with type Window.
      • Step 2: Takes component status of Window that is of type Status.
      • Step 3: Takes actions of type Status.
      • Step 4: Takes possibleActions of the internally defined CHOICE type.
      • Step 5: Goes into the first component of SEQUENCE OF by [1]. That component is of type Action.
      • Step 6: Takes component handle.
      • Step 7: Takes component number of type Button.

      The following figure shows which components are in TypeList ['Window',status,actions,possibleActions,[1],handle,number]:

      Elements Specified in Configuration File for Selective Decode of a Subvalue in a Window Message

      In the following figure, only the marked element is decoded by selected_decode_Window2:

      Bytes of a Window:status Message

      With the following example, you can examine that both selected_decode_Window2 -and selected_decode_Window1 decodes the intended subvalue of value Val:

      1> Val = {status,{'Status',12,
      -                    [{'Button',13,true},
      -                     {'Button',14,false},
      -                     {'Button',15,true},
      -                     {'Button',16,false}],
      +and selected_decode_Window1 decodes the intended subvalue of value Val:

      1> Val = {status,{'Status',12,
      +                    [{'Button',13,true},
      +                     {'Button',14,false},
      +                     {'Button',15,true},
      +                     {'Button',16,false}],
                           true,
      -                    {possibleActions,[{'Action',17,{'Button',18,false}},
      -                                      {'Action',19,{'Button',20,true}},
      -                                      {'Action',21,{'Button',22,false}}]}}}.
      -2> Bin = 'GUI':encode('Window',Val).
      +                    {possibleActions,[{'Action',17,{'Button',18,false}},
      +                                      {'Action',19,{'Button',20,true}},
      +                                      {'Action',21,{'Button',22,false}}]}}}.
      +2> Bin = 'GUI':encode('Window',Val).
       <<161,89,128,1,12,161,32,48,6,128,1,13,129,1,255,48,6,128,
         1,14,129,1,0,48,6,128,1,15,129,...>>
      -4> 'GUI':selected_decode_Window1(Bin).
      +4> 'GUI':selected_decode_Window1(Bin).
       13
      -5> 'GUI':selected_decode_Window2(Bin).
      +5> 'GUI':selected_decode_Window2(Bin).
       18
      diff --git a/prs/8803/lib/asn1-5.3/doc/html/asn1ct.html b/prs/8803/lib/asn1-5.3/doc/html/asn1ct.html index 9ff824444e405..ac1ea317dfaba 100644 --- a/prs/8803/lib/asn1-5.3/doc/html/asn1ct.html +++ b/prs/8803/lib/asn1-5.3/doc/html/asn1ct.html @@ -495,9 +495,9 @@

      test/3

      mostly work for old specifications based on the 1997 standard for ASN.1, but not for most modern-style applications. Another limitation is that the test functions may not work if options that change code generations strategies such -as the options macro_name_prefix and record_name_prefix have been used.

      • test/1 iterates over all types in Module.
      • test/2 tests type Type with a random value.
      • test/3 tests type Type with Value.

      Schematically, the following occurs for each type in the module:

      {ok, Value} = asn1ct:value(Module, Type),
      -{ok, Bytes} = Module:encode(Type, Value),
      -{ok, Value} = Module:decode(Type, Bytes).

      The test functions use the *.asn1db files for all included modules. If they +as the options macro_name_prefix and record_name_prefix have been used.

      • test/1 iterates over all types in Module.
      • test/2 tests type Type with a random value.
      • test/3 tests type Type with Value.

      Schematically, the following occurs for each type in the module:

      {ok, Value} = asn1ct:value(Module, Type),
      +{ok, Bytes} = Module:encode(Type, Value),
      +{ok, Value} = Module:decode(Type, Bytes).

      The test functions use the *.asn1db files for all included modules. If they are located in a different directory than the current working directory, use the include option to add paths. This is only needed when automatically generating values. For static values using Value no options are needed.

      diff --git a/prs/8803/lib/asn1-5.3/doc/html/dist/search_data-06A31C18.js b/prs/8803/lib/asn1-5.3/doc/html/dist/search_data-06A31C18.js deleted file mode 100644 index de884d388837b..0000000000000 --- a/prs/8803/lib/asn1-5.3/doc/html/dist/search_data-06A31C18.js +++ /dev/null @@ -1 +0,0 @@ -searchData={"items":[{"type":"module","title":"asn1ct","doc":"ASN.1 compiler and compile-time support functions\n\nThe ASN.1 compiler takes an ASN.1 module as input and generates a corresponding\nErlang module, which can encode and decode the specified data types.\nAlternatively, the compiler takes a specification module specifying all input\nmodules, and generates a module with encode/decode functions. In addition, some\ngeneric functions can be used during development of applications that handles\nASN.1 data (encoded as `BER` or `PER`).\n\n> #### Note {: .info }\n>\n> By default in Erlang/OTP 17, the representation of the `BIT STRING` and\n> `OCTET STRING` types as Erlang terms were changed. `BIT STRING` values are now\n> Erlang bit strings and `OCTET STRING` values are binaries. Also, an undecoded\n> open type is now wrapped in an `asn1_OPENTYPE` tuple. For details, see\n> [BIT STRING](asn1_getting_started.md#bit-string),\n> [OCTET STRING](asn1_getting_started.md#octet-string), and\n> [ASN.1 Information Objects](asn1_getting_started.md#Information-Object) in the\n> User's Guide.\n>\n> To revert to the old representation of the types, use option\n> `legacy_erlang_types`.","ref":"asn1ct.html"},{"type":"function","title":"asn1ct.compile/1","doc":"","ref":"asn1ct.html#compile/1"},{"type":"function","title":"asn1ct.compile/2","doc":"Compiles the ASN.1 module `Asn1Module` and generates an Erlang module\n`Asn1Module.erl` with encode and decode functions for all types defined in\nthe ASN.1 module.\n\nFor each ASN.1 value defined in the module, an Erlang function that\nreturns the value in Erlang representation is generated.\n\nIf `Asn1Module` is a filename without extension, first `\".asn1\"` is assumed,\nthen `\".asn\"`, and finally `\".py\"` (to be compatible with the old ASN.1\ncompiler). `Asn1Module` can be a full pathname (relative or absolute) including\nfilename with (or without) extension.[](){: #asn1set }\n\nIf it is needed to compile a set of `ASN.1` modules into an Erlang\nfile with encode/decode functions, list all involved files in a\nconfiguration file, one line per file. This configuration file must\nhave a double extension `\".set.asn1\"` (`\".asn1\"` can alternatively be\n`\".asn\"` or `\".py\"`). If the input files are `File1.asn1`,\n`File2.asn1`, and `File3.asn1`, the configuration file should look as\nfollows:\n\n```text\nFile1.asn1\nFile2.asn1\nFile3.asn1\n```\n\nThe output files in this case get their names from the configuration file. If\nthe configuration file is named `SetOfFiles.set.asn1`, the names of the output\nfiles are `SetOfFiles.hrl, SetOfFiles.erl, and SetOfFiles.asn1db`.\n\nSometimes in a system of `ASN.1` modules, different modules can have\ndifferent default tag modes, for example, one uses `AUTOMATIC` and\nanother `IMPLICIT`. The multi-file compilation resolves the default\ntagging as if the modules were compiled separately.\n\nName collisions is an unwanted effect that can occur in multi-file\ncompilation. The compiler solves this problem in one of two ways:\n\n- If the definitions are identical, the output module keeps only one definition\n with the original name.\n- If the definitions have the same name and differs in the definition, they are\n renamed. The new names are the definition name and the original module name\n concatenated.\n\nIf a name collision occurs, the compiler reports a `\"NOTICE: ...\"` message that\ntells if a definition was renamed, and the new name that must be used to\nencode/decode data.\n\n`Options` is a list with options specific for the ASN.1 compiler and options\nthat are applied to the Erlang compiler. The ASN.1 compiler passes on any\nunrecognized options to the Erlang compiler. The available options are as follows:\n\n- **`ber | per | uper | jer`** - The encoding rule to be used. The\n supported encoding rules are Basic Encoding Rules (`ber`), Packed\n Encoding Rules (`per`) aligned, PER unaligned (`uper`), and JSON\n Encoding Rules (`jer`). The `jer` option can be used by itself to\n generate a module that only supports encoding/decoding of JER, or it\n can be used as a supplementary option to `ber`, `per`, and `uper`,\n in which case a module that handles both the main encoding rules and\n JER will be generated. In that case, the exported functions for JER\n will be `jer_encode(Type, Value)` and `jer_decode(Type, Bytes)`.\n\n JER (ITU-T X.697) are experimental in OTP 22. There is support for a\n subset of the X.697 standard, for example there is no support for:\n\n - JER encoding instructions\n - the REAL type\n\n > #### Change {: .info }\n >\n > In Erlang/OTP 27 and later, module `m:json` in STDLIB is used for\n > encoding and decoding JSON. Before Erlang/OTP 27, it was necessary\n > to provide an external JSON library.\n\n If the encoding rule option is omitted, `ber` is the default.\n\n The generated Erlang module always gets the same name as the ASN.1 module.\n Therefore, only one encoding rule per ASN.1 module can be used at runtime.\n\n- **`der`** - With this option the Distinguished Encoding Rules (`der`) is\n chosen. DER is regarded as a specialized variant of the BER encoding rule.\n Therefore, this option only makes sense together with option `ber`. This\n option sometimes adds sorting and value checks when encoding, which implies\n slower encoding. The decoding routines are the same as for `ber`.\n\n- **`maps`** - This option changes the representation of the types `SEQUENCE`\n and `SET` to use maps (instead of records). This option also suppresses the\n generation of `.hrl` files.\n\n For details, see section\n [Map representation for SEQUENCE and SET](asn1_getting_started.md#MAP_SEQ_SET)\n in the User's Guide.\n\n- **`compact_bit_string`** - The `BIT STRING` type is decoded to \"compact\n notation\".\n\n **This option is not recommended for new code.**\n\n For details, see section [BIT STRING](asn1_getting_started.md#bit-string) in\n the User's Guide.\n\n This option implies option `legacy_erlang_types`, and it cannot be combined\n with option `maps`.\n\n- **`legacy_bit_string`** - The `BIT STRING` type is decoded to the legacy\n format, that is, a list of zeroes and ones.\n\n **This option is not recommended for new code.**\n\n For details, see section [BIT STRING](asn1_getting_started.md#bit-string) in\n the User's Guide\n\n This option implies option `legacy_erlang_types`, and it cannot be combined\n with option `maps`.\n\n- **`legacy_erlang_types`** - Use the same Erlang types to represent\n `BIT STRING` and `OCTET STRING` as in Erlang/OTP R16.\n\n **This option is not recommended for new code.**\n\n For details, see section [BIT STRING](asn1_getting_started.md#bit-string) and\n section [OCTET STRING](asn1_getting_started.md#octet-string) in the User's\n Guide.\n\n This option cannot be combined with option `maps`.\n\n- **`{n2n, EnumTypeName}`** - Tells the compiler to generate functions for\n conversion between names (as atoms) and numbers and conversely for the\n specified `EnumTypeName`. There can be multiple occurrences of this option to\n specify several type names. The type names must be declared as `ENUMERATIONS`\n in the ASN.1 specification.\n\n If `EnumTypeName` does not exist in the ASN.1 specification, the compilation\n stops with an error code.\n\n The generated conversion functions are named `name2num_EnumTypeName/1` and\n `num2name_EnumTypeName/1`.\n\n- **`noobj`** - Do not compile (that is, do not produce object code) the\n generated `.erl` file. If this option is omitted, the generated Erlang module\n is compiled.\n\n- **`{i, IncludeDir}`** - Adds `IncludeDir` to the search-path for `.asn1db` and\n ASN.1 source files. The compiler tries to open an `.asn1db` file when a\n module imports definitions from another ASN.1 module. If no `.asn1db` file\n is found, the ASN.1 source file is parsed. Several `{i, IncludeDir}` can be\n given.\n\n- **`{outdir, Dir}`** - Specifies directory `Dir` where all generated files are\n to be placed. If this option is omitted, the files are placed in the current\n directory.\n\n- **`asn1config`** - When using one of the specialized decodes, exclusive or\n selective decode, instructions must be given in a configuration file. Option\n `asn1config` enables specialized decodes and takes the configuration file in\n concern. The configuration file has the same name as the ASN.1 specification,\n but with extension `.asn1config`.\n\n For instructions for exclusive decode, see section\n [Exclusive Decode](asn1_spec.md#Exclusive-Instruction) in the User's Guide.\n\n For instructions for selective decode, see section\n [Selective Decode](asn1_spec.md#Selective-Instruction) in the User's Guide.\n\n- **`undec_rest`** - By default when decoding, any bytes following the\n end of an ASN.1 data structure are discarded. If an ASN.1 module is\n compiled with option `undec_rest`, the decode function returns a\n tuple `{ok, Value, Rest}`, where `Rest` is the bytes following the ASN.1\n data structure. `Rest` can be a list or a binary.\n\n- **`no_ok_wrapper`** - With this option, the generated `encode/2` and\n `decode/2` functions do not wrap a successful return value in an `{ok,...}`\n tuple. If any error occurs, an exception will be raised.\n\n- **`{macro_name_prefix, Prefix}`** - All macro names generated by the compiler\n are prefixed with `Prefix`. This is useful when multiple protocols that\n contain macros with identical names are included in a single module.\n\n- **`{record_name_prefix, Prefix}`** - All record names generated by the\n compiler are prefixed with `Prefix`. This is useful when multiple protocols\n that contain records with identical names are included in a single module.\n\n- **`verbose`** - Causes more verbose information from the compiler describing\n what it is doing.\n\n- **`warnings_as_errors`** - Causes warnings to be treated as errors.\n\n- **`deterministic`** - Causes all non-deterministic options to be stripped from\n the `-asn1_info()` attribute.\n\nUnrecognized options are passed on to the Erlang compiler when the generated\n`.erl` file is compiled.\n\nThe compiler generates the following files:\n\n- `Asn1Module.hrl` (if any `SET` or `SEQUENCE` is defined)\n- `Asn1Module.erl` \\- Erlang module with encode, decode, and value functions\n- `Asn1Module.asn1db` \\- Intermediate format used by the compiler when modules\n `IMPORT` definitions from each other.","ref":"asn1ct.html#compile/2"},{"type":"function","title":"asn1ct.test/1","doc":"Tests encoding and decoding of all types in `Module`.\n\nFor more details, see `test/3`.","ref":"asn1ct.html#test/1"},{"type":"function","title":"asn1ct.test/2","doc":"Tests encoding and decoding of `Module`.\n\nIf the second argument is given as atom `Type`, that type is tested.\n\nIf the second argument is given as list `Options`, that are the options\nthat are used for testing all types in the module.\n\nFor more details, see `test/3`.","ref":"asn1ct.html#test/2"},{"type":"function","title":"asn1ct.test/3","doc":"Performs a test of encode and decode of types in `Module`.\n\nThe generated functions are called by this function. This function is\nuseful for testing to ensure that the generated encode and decode\nfunctions as well as the general runtime support work as expected.\n\n> #### Note {: .info }\n>\n> Currently, the `test` functions have many limitations. Essentially, they will\n> mostly work for old specifications based on the 1997 standard for ASN.1, but\n> not for most modern-style applications. Another limitation is that the `test`\n> functions may not work if options that change code generations strategies such\n> as the options `macro_name_prefix` and `record_name_prefix` have been used.\n\n- [`test/1`](`test/1`) iterates over all types in `Module`.\n- [`test/2`](`test/2`) tests type `Type` with a random value.\n- [`test/3`](`test/3`) tests type `Type` with `Value`.\n\nSchematically, the following occurs for each type in the module:\n\n```erlang\n{ok, Value} = asn1ct:value(Module, Type),\n{ok, Bytes} = Module:encode(Type, Value),\n{ok, Value} = Module:decode(Type, Bytes).\n```\n\nThe `test` functions use the `*.asn1db` files for all included modules. If they\nare located in a different directory than the current working directory, use the\n`include` option to add paths. This is only needed when automatically generating\nvalues. For static values using `Value` no options are needed.","ref":"asn1ct.html#test/3"},{"type":"function","title":"asn1ct.value/2","doc":"Returns an Erlang term that is an example of a valid Erlang representation of a\nvalue of the ASN.1 type `Type`.\n\nThe value is a random value and subsequent calls to this function will\nfor most types return different values.\n\n> #### Note {: .info }\n>\n> Currently, the `value` function has many limitations. Essentially, it will\n> mostly work for old specifications based on the 1997 standard for ASN.1, but\n> not for most modern-style applications. Another limitation is that the `value`\n> function may not work if options that change code generations strategies such\n> as the options `macro_name_prefix` and `record_name_prefix` have been used.","ref":"asn1ct.html#value/2"},{"type":"extras","title":"asn1 Release Notes","doc":"\n# asn1 Release Notes\n\nThis document describes the changes made to the asn1 application.","ref":"notes.html"},{"type":"extras","title":"Asn1 5.3 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Multiple bugs has been eliminated in the [specialized decode feature](`e:asn1:asn1_spec.md`).\n\n Own Id: OTP-18813 Aux Id: [PR-7790]\n\n[PR-7790]: https://github.com/erlang/otp/pull/7790","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Specs have been added to all `asn1ct` API functions.\n\n Own Id: OTP-18804 Aux Id: [PR-7738]\n\n- The documentation has been migrated to use Markdown and ExDoc.\n\n Own Id: OTP-18955 Aux Id: [PR-8026]\n\n- The `jer` (JSON Encoding Rules) for ASN.1 now use the new `m:json` module for encoding and decoding JSON. Thus, there is no longer any need for an external JSON library.\n\n Own Id: OTP-19018 Aux Id: [PR-8241]\n\n[PR-7738]: https://github.com/erlang/otp/pull/7738\n[PR-8026]: https://github.com/erlang/otp/pull/8026\n[PR-8241]: https://github.com/erlang/otp/pull/8241","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 5.2.2 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-2-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"* An ASN.1 module that contains named `BIT STRING` values would fail to compiled if both the BER and JER back-ends were enabled.\n\n Own Id: OTP-19039 Aux Id: GH-8291, PR-8297","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.2.1 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-2-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Fix benign warning from gcc 11 about mismatching call to free().\n\n Own Id: OTP-18844","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.2 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- The ASN.1 compiler would ignore a constraint such as `(SIZE (1..4), ...)`,\n causing incorrect behavior of the encoding and decoding function for the PER\n and UPER backends. Corrected to handle the constraint in the same way as\n `(SIZE (1..4, ...))`.\n\n Own Id: OTP-18729 Aux Id: PR-7575","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- The JER backend has been internally refactored in a way that is compatible for\n applications that use the documented API. However, for a group of ASN.1\n modules that depend on each other (for example, `S1AP-PDU-Descriptions`,\n S1AP-Contents, and so on), all modules in the group must be recompiled if on\n of the group members is recompiled.\n\n Own Id: OTP-18748 Aux Id: ERIERL-957, PR-7637","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 5.1 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- The ASN.1 compiler used to reject correctly specified RELATIVE-OID values\n containing other RELATIVE-OID values. This is now corrected.\n\n Own Id: OTP-18534 Aux Id: ERIERL-737, PR-7039","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Minor code improvements.\n\n Own Id: OTP-18441\n\n- Handling of `on_load` modules during boot has been improved by adding an extra\n step in the boot order for embedded mode that runs all `on_load` handlers,\n instead of relying on explicit invocation of them, later, when the kernel\n supervision tree starts.\n\n This is mostly a code improvement and OTP internal simplification to avoid\n future bugs and to simplify code maintenance.\n\n Own Id: OTP-18447","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 5.0.21.1 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-21-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Fix benign warning from gcc 11 about mismatching call to free().\n\n Own Id: OTP-18844","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.21 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-21"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- For the `per` and `uper` ASN.1 encoding rules, encoding and decoding the\n `SEQUENCE OF` and `SET OF` constructs with 16384 items or more is now\n supported.\n\n Own Id: OTP-18245 Aux Id: ERIERL-859","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.20 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-20"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- There is a new configure option, `--enable-deterministic-build`, which will\n apply the `deterministic` compiler option when building Erlang/OTP. The\n `deterministic` option has been improved to eliminate more sources of\n non-determinism in several applications.\n\n Own Id: OTP-18165 Aux Id: PR-5965","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 5.0.19 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-19"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- The atom `maybe` has been quoted in the source code.\n\n Own Id: OTP-17980","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.18.2 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-18-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Fix benign warning from gcc 11 about mismatching call to free().\n\n Own Id: OTP-18844","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.18.1 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-18-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- For the `per` and `uper` ASN.1 encoding rules, encoding and decoding the\n `SEQUENCE OF` and `SET OF` constructs with 16384 items or more is now\n supported.\n\n Own Id: OTP-18245 Aux Id: ERIERL-859","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.18 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-18"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Add support for the `maps` option in combination with the `jer` backend.\n\n Own Id: OTP-17959 Aux Id: GH-5757","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.17 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-17"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- A parameterized type with a SEQUENCE with extension (\"...\") made the compiler\n backend to crash. The previous fix for this in GH-4514 was not complete.\n\n Own Id: OTP-17522 Aux Id: GH-4902","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.16 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-16"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Fixed a bug in the `asn1` compiler that potentially could cause it to fail to\n open a file.\n\n Own Id: OTP-17387 Aux Id: OTP-17123","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.15.1 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-15-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- A parameterized type with a SEQUENCE with extension (\"...\") made the compiler\n backend to crash. The previous fix for this in GH-4514 was not complete.\n\n Own Id: OTP-17522 Aux Id: GH-4902","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.15 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-15"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- A parameterized type with a SEQUENCE with extension (\"...\") made the compiler\n backend to crash.\n\n Own Id: OTP-17227 Aux Id: GH-4514\n\n- For JER encoding rules an INTEGER value outside the declared range is now\n reported as error during decode.\n\n Own Id: OTP-17306 Aux Id: ERIERL-506","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- For the JER encoding rules, the declared order of the fields in a SEQUENCE is\n now maintained in the resulting JSON object. Previously a map was used which\n caused an undefined order of the fields which was not friendly for debugging.\n\n Own Id: OTP-17297 Aux Id: ERIERL-607","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 5.0.14 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-14"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Changes in order to build on the Haiku operating system.\n\n Thanks to Calvin Buckley\n\n Own Id: OTP-16707 Aux Id: PR-2638","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 5.0.13 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-13"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Adhere to the ASN.1 specification for hstring & bstring lexical items. That is\n they may include white space.\n\n Own Id: OTP-16490","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Refactored the internal handling of deprecated and removed functions.\n\n Own Id: OTP-16469\n\n- Improve handling of ellipsis in a CHOICE\n\n Own Id: OTP-16554 Aux Id: ERL-1189","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 5.0.12 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-12"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Dialyzer warnings of type `no_match` are now suppressed in the generated\n files.\n\n Own Id: OTP-16636 Aux Id: ERIERL-145","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 5.0.11 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-11"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- The compiler now has limited support for the JSON encoding rules (ITU-T X.697\n ASN.1 encoding rules: Specification of JavaScript Object Notation Encoding\n Rules).\n\n Own Id: OTP-16030","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 5.0.10 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-10"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Fix 'DEFAULT' with 'OCTET STRING' and 'SEQUENCE OF CHOICE' with extensions.\n\n Own Id: OTP-16542 Aux Id: PR-2159","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 5.0.9 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-9"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- All incorrect (that is, all) uses of \"can not\" has been corrected to \"cannot\"\n in source code comments, documentation, examples, and so on.\n\n Own Id: OTP-14282 Aux Id: PR-1891\n\n- Corrected problems with the following value definitions:\n\n - value of SEQUENCE OF CHOICE with extensions\n - value of CHOICE with extensions\n - DEFAULT used with OCTET STRING\n\n Own Id: OTP-15697 Aux Id: PR-2159","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.8 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-8"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Handle erroneous length during decode (BER only) without crashing.\n\n Own Id: OTP-15470 Aux Id: ERIERL-278","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.7 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-7"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- A bug in ASN.1 BER decoding has been fixed. When decoding a recursively\n enclosed term the length was not propagated to that term decoding, so if the\n length of the enclosed term was longer than the enclosing that error was not\n detected.\n\n A hard coded C stack limitation for decoding recursive ASN.1 terms has been\n introduced. This is currently set to 8 kWords giving a nesting depth of about\n 1000 levels. Deeper terms can not be decoded, which should not be much of a\n real world limitation.\n\n Own Id: OTP-14440 Aux Id: ERIERL-220","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.6 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-6"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Update to use the new string api instead of the old.\n\n Own Id: OTP-15036","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 5.0.5.2 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-5-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Handle erroneous length during decode (BER only) without crashing.\n\n Own Id: OTP-15470 Aux Id: ERIERL-278","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.5.1 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-5-1"},{"type":"extras","title":"Known Bugs and Problems - asn1 Release Notes","doc":"- A bug in ASN.1 BER decoding has been fixed. When decoding a recursively\n enclosed term the length was not propagated to that term decoding, so if the\n length of the enclosed term was longer than the enclosing that error was not\n detected\n\n A hard coded C stack limitation for decoding recursive ASN.1 terms has been\n introduced. This is currently set to 8 kWords giving a nesting depth of about\n 1000 levels. Deeper terms can not be decoded, which should not be much of a\n real world limitation.\n\n Own Id: OTP-14440 Aux Id: ERIERL-220","ref":"notes.html#known-bugs-and-problems"},{"type":"extras","title":"Asn1 5.0.5 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-5"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Dialyzer suppression has been added for the generated ASN.1 helper function\n to_bitstring/1 that previously created irrelevant warnings.\n\n Own Id: OTP-13882 Aux Id: ERIERL-144","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.4 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-4"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- There was a issue with BER encoding and the `undec_rest` option in generated\n decoders. An exception could be thrown instead of returning an error tuple.\n\n Own Id: OTP-14786 Aux Id: ERL-518\n\n- The asn1ct:test functions crashed on decoders generated with options\n `no_ok_wrapper`, `undec_rest`.\n\n Own Id: OTP-14787 Aux Id: ERL-518","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.3 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Compiling an ASN.1 module using the option \\{n2n, EnumTypeName\\} when\n EnumTypeName contains a hyphen like for example Cause-Misc caused syntax\n errors when compiling the generated Erlang code. This is now corrected.\n\n Own Id: OTP-14495 Aux Id: ERL-437","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.2 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Default values now work in extension for PER, so if you give the atom\n `asn1_DEFAULT` instead of a value it will become the default value.\n\n Own Id: OTP-13011 Aux Id: ERIERL-60","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0.1 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Fixed compilation error of generated code caused by a missing quotation of\n function names as part of an external call for encoding.\n\n Own Id: OTP-14519 Aux Id: ERIERL-49","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 5.0 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-5-0"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Add compile option `-compile(no_native)` in modules with `on_load` directive\n which is not yet supported by HiPE.\n\n Own Id: OTP-14316 Aux Id: PR-1390","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- The `error` tuple returned from the `encode` and `decode` functions will now\n include the stack backtrace to make it easier to understand what went wrong.\n\n Own Id: OTP-13961\n\n- The deprecated module `asn1rt` has been removed. The deprecated functions\n `asn1ct:encode/3` and `asn1ct:decode/3` have been removed. The undocumented\n function `asn1ct:encode/2` has been removed.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-14146\n\n- The new '`maps`' option changes the representation of the types `SEQUENCE` and\n `SET` to be maps (instead of records).\n\n Own Id: OTP-14219","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 4.0.4 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-4-0-4"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Compiling multiple ASN.1 modules in the same directory with parallel make\n (make -j) should now be safe.\n\n Own Id: OTP-13624","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 4.0.3 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-4-0-3"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Internal changes\n\n Own Id: OTP-13551","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 4.0.2 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-4-0-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- When compiling to the PER format, the ASN.1 compiler would crash when\n attempting to compile an ASN.1 module with a constrained INTEGER with more\n than 65536 values and named values. (Thanks to Ingars for reporting this bug.)\n\n Own Id: OTP-13257\n\n- The ASN.1 compiler will now emit Dialyzer suppressions for improper lists.\n Thus, there is no longer any need to use `--Wno_improper_lists` when analyzing\n modules generated by the ASN.1 compiler.\n\n Own Id: OTP-13324","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 4.0.1 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-4-0-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Trying to encode an empty named BIT STRING in BER would fail with a\n `function_clause` exception. (Thanks to Svilen Ivanov for reporting this bug.)\n\n Own Id: OTP-13149","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 4.0 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-4-0"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Many bugs have been eliminated in the ASN.1 compiler so that it can now\n successfully compile many more ASN.1 specifications. Error messages have also\n been improved.\n\n Own Id: OTP-12395","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- The documentation for `asn1ct:test/1,2,3` and `asn1ct:value/2` has been\n updated with information about the limitations of the functions.\n\n Own Id: OTP-12765 Aux Id: seq12866, seq12867","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 3.0.4 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-3-0-4"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- The ASN.1 compiler would crash if a SEQUENCE ended with a double set of\n ellipses (`...`).\n\n Own Id: OTP-12546 Aux Id: seq12815","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 3.0.3 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-3-0-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- When decoding BER, primitives with an indefinite length will be immediately\n rejected. (Thanks to Simon Cornish for reporting this bug.)\n\n Own Id: OTP-12205\n\n- BER: A bug with compliance to X.680 (200811) s31.2.7 has been fixed.\n Basically, when TagDefault is AUTOMATIC then tags are IMPLICIT unless EXPLICIT\n is given.\n\n Own Id: OTP-12318\n\n- Usage of the `EXTERNAL` 1994 variant type was broken.\n\n Own Id: OTP-12326","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 3.0.2 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-3-0-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Several problems where the ASN.1 compiler would crash when attempting to\n compile correct specifications have been corrected.\n\n Own Id: OTP-12125\n\n- Robustness when decoding incorrect BER messages has been improved.\n\n Own Id: OTP-12145","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 3.0.1 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-3-0-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- The ASN.1 compiler now generates code that don't trigger Dialyzer warnings.\n Along the way, a few minor bugs were fixed.\n\n Own Id: OTP-11372 Aux Id: seq12397","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 3.0 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-3-0"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Subtyping an extensible ENUMERATED would cause an compilation error. (Thanks\n to Morten Nygaard Åsnes for reporting this bug.)\n\n Own Id: OTP-11700\n\n- When specifying the value for an OCTET STRING in a specification, the ASN.1\n standard clearly states that the value must be either a bstring or an hstring,\n but NOT a cstring. The ASN.1 compiler will now generate a compilation error if\n the value of an OCTET STRING is given as a character string.\n\n That is, the following example is now illegal:\n\n `string OCTET STRING ::= \"Now illegal\"`\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-11727\n\n- Application upgrade (appup) files are corrected for the following\n applications:\n\n `asn1, common_test, compiler, crypto, debugger, dialyzer, edoc, eldap, erl_docgen, et, eunit, gs, hipe, inets, observer, odbc, os_mon, otp_mibs, parsetools, percept, public_key, reltool, runtime_tools, ssh, syntax_tools, test_server, tools, typer, webtool, wx, xmerl`\n\n A new test utility for testing appup files is added to test_server. This is\n now used by most applications in OTP.\n\n (Thanks to Tobias Schlager)\n\n Own Id: OTP-11744","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- By giving --enable-static-\\{nifs,drivers\\} to configure it is now possible to\n statically linking of nifs and drivers to the main Erlang VM binary. At the\n moment only the asn1 and crypto nifs of the Erlang/OTP nifs and drivers have\n been prepared to be statically linked. For more details see the Installation\n Guide in the System documentation.\n\n Own Id: OTP-11258\n\n- Code generation for the `per` and `uper` backends has been somewhat improved.\n\n Own Id: OTP-11573\n\n- The OCTET STRING and BIT STRING types now have a more natural mapping to\n Erlang types (binary and bitstring, respectively), which is more efficient and\n will avoid useless conversions between lists and binaries/bitstrings.\n\n This is an incompatible change. To revert to the old mapping to support\n existing applications, use the `legacy_erlang_types` option.\n\n Impact: There is a potential for better performance, as it is now possible to\n avoid conversions between lists and binaries both in the generated ASN.1\n encode/decode code and in the application itself.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-11594\n\n- All functions in the `asn1rt` module, as well as `asn1ct:decode/3` and\n `asn1ct:encode/3`, are now deprecated.\n\n Own Id: OTP-11731\n\n- Generated .hrl files are now protected from being included more than once.\n\n Own Id: OTP-11804","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 2.0.4 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-2-0-4"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- The default value for a `BIT STRING` would not always be recognized, causing\n the encoding to be incorrect for the DER/PER/UPER encodings.\n\n Own Id: OTP-11319\n\n- The ASN.1 application would fail to build if the `.erlang` file printed\n something to standard output.\n\n Own Id: OTP-11360\n\n- An union of integer ranges in an INTEGER constraint could sometimes be\n interpreted as the intersection of the range.\n\n Own Id: OTP-11411 Aux Id: seq12443\n\n- Extensible, multiple single value constraints (such as `INTEGER (1|17, ...)`)\n would be incorrectly encoded.\n\n Own Id: OTP-11415\n\n- The ASN.1 compiler would fail to compile a constraint with values given for\n the extension part (such as `INTEGER (1..10, ..., 11..20)`).\n\n Own Id: OTP-11504","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- The new option '`no_ok_wrapper`' generates M:encode/2 and M:decode/2 functions\n that don't wrap the return value in an \\{ok,...\\} tuple.\n\n Own Id: OTP-11314","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 2.0.3 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-2-0-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Open types greater than 16383 bytes will now be correctly encoded and decoded.\n\n Own Id: OTP-11262 Aux Id: seq12386, OTP-11223","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- For the PER and UPER formats, code generation especially for encoding has been\n improved.\n\n When encoding BIT STRINGs, values longer than the maximum size for the BIT\n STRING type would be truncated silently - they now cause an exception.\n\n Open types greater than 16383 bytes will now be correctly encoded and decoded.\n\n IMPORTANT NOTE: For ASN.1 specifications that depend on each other, such as\n the S1AP-\\* specifications, it is important to recompile all specifications\n (compiling some with this version of the compiler and some with an older\n version will not work).\n\n Own Id: OTP-11300","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 2.0.2 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-2-0-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Fix some Makefile rules that didn't support silent rules. Thanks to Anthony\n Ramine.\n\n Own Id: OTP-11111\n\n- PER/UPER: A semi-constrained INTEGER with a non-zero lower bound would be\n incorrectly decoded. This bug was introduced in R16.\n\n PER/UPER: Given `INTEGER (10..MAX, ...)`, attempting to decode any integer\n below 10 would cause the encoder to enter an infinite loop.\n\n PER/UPER: For a type with an extensible SIZE constraint, sizes outside of the\n root range were incorrectly encoded.\n\n Given a constraint such as `(SIZE (5, ...))`, encoding a size less than 5\n would fail (PER/UPER). Similarly, for BER decoding would fail.\n\n PER: The encoder did not align a known multiplier string (such as IA5String)\n of length 16 bits (exactly) to an octet boundary.\n\n In rare circumstances, DEFAULT values for the UPER backend could be wrongly\n encoded.\n\n Own Id: OTP-11134\n\n- UPER: The compiler would crash when compiling an ENUMERATED having more than\n 63 extended values.\n\n PER/UPER: A SEQUENCE with more 64 extended values could not be decoded.\n\n Own Id: OTP-11153\n\n- When decoding a SEQUENCE defined inline inside a an extension addition group,\n the record named generated by the decoding code would not match the name in\n the generated .hrl file.\n\n Own Id: OTP-11154 Aux Id: seq12339","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Postscript files no longer needed for the generation of PDF files have been\n removed.\n\n Own Id: OTP-11016","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 2.0.1.2 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-2-0-1-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- When an object set is an actual parameter, the extension marker for the object\n set could get lost (which would cause the decoding of unknown values to fail).\n\n Own Id: OTP-10995 Aux Id: seq12290","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 2.0.1.1 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-2-0-1-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- The generated decoder for the 'per' and 'uper' backends did not correctly\n decode ENUMERATEDs with a single value.\n\n The generated encoder for the 'per' and 'uper' backends generated an empty\n binary for a top-level type that did not need to be encoded (such as an\n ENUMERATED with a single value). The correct result should be a binary\n containing a 0 byte.\n\n Own Id: OTP-10916 Aux Id: seq12270","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 2.0.1 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-2-0-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Fixed broken table constraints within a SET OF or SEQUENCE OF for the BER\n backend.\n\n Own Id: OTP-10853 Aux Id: seq12245","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 2.0 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-2-0"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Encoding SEQUENCEs with multiple extension addition groups with optional\n values could fail (depending both on the specification and whether all values\n were provided).\n\n Own Id: OTP-10664","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- The options for the ASN.1 compiler has been drastically simplified. The\n backend is chosen by using `ber`, `per`, or `uper`. The options `optimize`,\n `nif`, and `driver` are no longer needed. The old options will still work, but\n will issue a warning.\n\n Another change is that generated `encode/2` function will always return a\n binary (some backends used to return an iolist).\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-10410 Aux Id: kunagi-254 \\[165]\n\n- The ASN.1 compiler generates faster decode functions for PER and UPER. Some\n minor improvements have also been made for PER/UPER encoding, and to the BER\n backend.\n\n Own Id: OTP-10519 Aux Id: kunagi-322 \\[233]\n\n- The ASN.1 compiler will now always include necessary run-time functions in the\n generated Erlang modules (except for `asn1rt_nif` which is still needed). If\n the option '`inline`' is used the ASN.1 compiler will generate a warning. But\n if '`{inline,OutputFile}`' is use, the ASN.1 compiler will refuse to compile\n the file. (Use a `.set.asn` file if you need to remove the output file.)\n\n The '`BIT STRING`' type will now be decoded as Erlang bitstrings by default.\n Use the new `legacy_bit_string` option to encode as lists of ones and zeroes.\n (The `compact_bit_string` option still works as before.)\n\n Open types are now always returned as binaries (when there is no information\n allowing them to be decoded).\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-10588 Aux Id: kunagi-341 \\[252]","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.8.1 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-8-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- ASN.1 decoders generated with the options `-bber_bin +optimize +nif` would\n decode open types with a size larger than 511 incorrectly. That bug could\n cause decoding by `public_key` to fail. The bug was in the NIF library\n `asn1_erl_nif.so`; therefore there is no need re-compile ASN.1 specifications\n that had the problem.\n\n Own Id: OTP-10805 Aux Id: seq12244\n\n- Encoding SEQUENCEs with multiple extension addition groups with optional\n values could fail (depending both on the specification and whether all values\n were provided).\n\n Own Id: OTP-10811 Aux Id: OTP-10664","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 1.8 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-8"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Encoding and decoding of integer ranges can now be done with an upper bound\n larger than the previous limit of 16^10. The new upper bound in per encoding\n and decodings for constrained whole numbers is 2^2040 (close to 16^508)\n\n Own Id: OTP-10128\n\n- Per encoding/decoding now works correctly for single value subtyping of an\n integer type where a subtype is a predefined value. Previously a predefined\n value could cause a non-valid range-check in the generated Erlang code for per\n encoding/decoding due to a bug in the constraint checking.\n\n Own Id: OTP-10139\n\n- Fix typo error in selected decode function (Thanks to Artem Teslenko)\n\n Own Id: OTP-10152\n\n- Better error indication when detecting unexpected tags during decoding of BER\n encoded data.\n\n Own Id: OTP-10186\n\n- asn1rt_check: Fix transform_to_EXTERNAL1990 for binary input (Thanks to Harald\n Welte)\n\n Own Id: OTP-10233","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Add support for multiple ExtensionAdditionGroups\n\n Own Id: OTP-10058\n\n- Add support for extensible enumeration types in n2n generated functions.\n\n Own Id: OTP-10144","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.7 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-7"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Some ASN.1 INTEGER type and SEQUENCE constructor variants previously not\n handled by the ASN.1 compiler are now correctly handled\n\n Own Id: OTP-9688\n\n- An INTEGER with a value constraint where unions are used e.g. X1 ::= INTEGER\n (1..4 | 6 | 8 | 10 | 20) is not handled correctly. For PER the value is\n encoded in wrong number of bits.\n\n Own Id: OTP-9946","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.6.19 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-19"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- The linked-in driver used for ber decode and per encode has been replaced with\n nifs. To enable the usage of nifs pass the nif option to erlc or\n asn1rt:compile when compiling. If you previously used the linked-in driver,\n you have to recompile your ASN1 modules with the current version of asn1\n application as the linked-in driver modules have been removed.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-9419\n\n- A few of the heavy calculations which are done for encoding and decoding\n operations when dealing with SEQUENCE OF and DEFAULT in runtime have been\n moved to be done in compile time instead.\n\n Own Id: OTP-9440\n\n- When compiling an ASN.1 ber module with the +nif option, the module will use a\n new nif for ber encoding, increasing performance by about 5%.\n\n Own Id: OTP-9441\n\n- Tuple funs (a two-element tuple with a module name and a function) are now\n officially deprecated and will be removed in R16. Use '`fun M:F/A`' instead.\n To make you aware that your system uses tuple funs, the very first time a\n tuple fun is applied, a warning will be sent to the error logger.\n\n Own Id: OTP-9649","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.6.18 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-18"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Implement or fix -Werror option\n\n If -Werror is enabled and there are warnings no output file is written. Also\n make sure that error/warning reporting is consistent. (Thanks to Tuncer Ayaz)\n\n Own Id: OTP-9536","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 1.6.17 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-17"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Test cases which started failing when timer:tc was changed to not catch are\n corrected.\n\n Own Id: OTP-9286\n\n- The bounds checking in the asn1_erl_driver when the length value of a TLV is a\n Long Definite Length is corrected. Thanks to Vance Shipley.\n\n Own Id: OTP-9303","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 1.6.16 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-16"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- asn1ct: Make formatting of errors and warnings consistent\n\n Consistently format warning and error reports. Warning and error options from\n erlc now also work in asnc1ct. (thanks to Tuncer Ayaz)\n\n Own Id: OTP-9062\n\n- Shut off some dialyzer warnings\n\n Own Id: OTP-9063","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Crash in asn1ct_check, componentrelation_leadingattr fixed. (Thanks to\n Stephane Pamelard for finding the bug)\n\n Own Id: OTP-9092","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.6.15 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-15"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- The encoding of ExtensionAdditionGroup (for PER and UPER) is corrected.\n\n Own Id: OTP-8866 Aux Id: OTP-8797, SEQ-11557\n\n- A race condition when several processes in parallel start to do encode/decode\n using the driver could cause an error log regarding crashing port owner\n process. This race is now eliminated.\n\n Own Id: OTP-8948 Aux Id: seq11733","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 1.6.14.1 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-14-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Extension Addition Groups are now supported by the parser and in all backends.\n\n Own Id: OTP-8598 Aux Id: seq-11557\n\n- Extension Addition Groups are now supported in nested types within a SEQUENCE\n and CHOICE as well (missed that in previous fix)\n\n Own Id: OTP-8797 Aux Id: seq-11557","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Bug in UNALIGNED PER regarding encoding and decoding of constrained numbers\n with a valuerange > 1024. (Thanks to Vincent de Phily)\n\n Own Id: OTP-8779\n\n- Minor corrections in the User Guide.\n\n Own Id: OTP-8829","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.6.14 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-14"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- By default, the ASN.1 compiler is now silent in the absence of warnings or\n errors. The new '`verbose`' option or the '`-v`' option for `erlc` can be\n given to show extra information (for instance, about the files that are\n generated). (Thanks to Tuncer Ayaz.)\n\n Own Id: OTP-8565","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.6.13 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-13"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Harmless buffer overflow by one byte in asn1 and ram_file_drv.\n\n Own Id: OTP-8451","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Cross compilation improvements and other build system improvements.\n\n Most notable:\n\n - Lots of cross compilation improvements. The old cross compilation support\n was more or less non-existing as well as broken. Please, note that the cross\n compilation support should still be considered as experimental. Also note\n that old cross compilation configurations cannot be used without\n modifications. For more information on cross compiling Erlang/OTP see the\n `$ERL_TOP/INSTALL-CROSS.md` file.\n - Support for staged install using\n [DESTDIR](http://www.gnu.org/prep/standards/html_node/DESTDIR.html). The old\n broken `INSTALL_PREFIX` has also been fixed. For more information see the\n `$ERL_TOP/INSTALL.md` file.\n - Documentation of the `release` target of the top `Makefile`. For more\n information see the `$ERL_TOP/INSTALL.md` file.\n - `make install` now by default creates relative symbolic links instead of\n absolute ones. For more information see the `$ERL_TOP/INSTALL.md` file.\n - `$ERL_TOP/configure --help=recursive` now works and prints help for all\n applications with `configure` scripts.\n - Doing `make install`, or `make release` directly after `make all` no longer\n triggers miscellaneous rebuilds.\n - Existing bootstrap system is now used when doing `make install`, or\n `make release` without a preceding `make all`.\n - The `crypto` and `ssl` applications use the same runtime library path when\n dynamically linking against `libssl.so` and `libcrypto.so`. The runtime\n library search path has also been extended.\n - The `configure` scripts of `erl_interface` and `odbc` now search for thread\n libraries and thread library quirks the same way as ERTS do.\n - The `configure` script of the `odbc` application now also looks for odbc\n libraries in `lib64` and `lib/64` directories when building on a 64-bit\n system.\n - The `config.h.in` file in the `erl_interface` application is now\n automatically generated in instead of statically updated which reduces the\n risk of `configure` tests without any effect.\n\n (Thanks to Henrik Riomar for suggestions and testing)\n\n (Thanks to Winston Smith for the AVR32-Linux cross configuration and testing)\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-8323\n\n- Add support for prefixing macro names generated by the compiler\n\n This is useful when multiple protocols that contains macros with identical\n names are included in a single module.\n\n Add the missing `record_name_prefix` compiler option to the documentation.\n\n Own Id: OTP-8453\n\n- Cleanups suggested by tidier and modernization of types and specs.\n\n Own Id: OTP-8455\n\n- Support for `EXTENSIBILITY IMPLIED` and `SET/SEQ OF NamedType` is added.\n\n Own Id: OTP-8463","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.6.12 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-12"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- The documentation is now built with open source tools (xsltproc and fop) that\n exists on most platforms. One visible change is that the frames are removed.\n\n Own Id: OTP-8256","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.6.11 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-11"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- A new option `{n2n,TypeName}` can be used to enable generation of conversion\n functions from name to number and vice versa for selected ENUMERATION types.\n The option can be repeated many times in order to specify several types in the\n same file. \n If the `TypeName` specified does not exists or is not an ENUMERATION type, the\n compilation will be terminated with an error code. \n Below follows an example on how to use the option from the command line with\n `erlc`: \n `erlc -bper+\"{n2n,'CauseMisc'}\" +\"{n2n,'CausePcl'}\" MyModyle.asn`\n\n Own Id: OTP-8136 Aux Id: seq11347\n\n- Range checks added for BIT STRING with fixed SIZE constraint.\n\n Own Id: OTP-7972 Aux Id: seq11280\n\n- Now support multiple-line comments in asn1-specs as specified in ASN1 X.680\n (07/2002), section 11.6.4\n\n Own Id: OTP-8043\n\n- Now parses and adds abstract syntax for PATTERN subtype constraint. No other\n action is taken on this type of constraint.\n\n Own Id: OTP-8046\n\n- The ASN1 subtype constraint `CONTAINING Type`,\n `CONTAINING Type ENCODED BY Value` and `ENCODED BY Value` now is parsed.\n Abstract syntax is added but no further action in generated code is taken.\n\n Own Id: OTP-8047","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.6.10 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-10"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- A faulty receive case that catch-ed all messages in the initialization of the\n driver has been removed, the initialization has been restructured.\n\n Own Id: OTP-7954 Aux Id: seq11220","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- The anonymous part of the decode that splits the ASN1 TLV into Tag Value\n tuples has been optimized.\n\n Own Id: OTP-7953","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.6.9 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-9"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Error that caused crash when drivers were loaded is now corrected. Parallel\n driver for asn1 now enabled.\n\n Own Id: OTP-7904 Aux Id: seq11220","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Optimized code for ENUMERATION type in encoder/decoder.\n\n Own Id: OTP-7909","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.6.8.1 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-8-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Removed parallel-driver functionality due to failure when loading the driver.\n\n Own Id: OTP-7900 Aux Id: seq11220","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Generated code now uses guards that is not obsolete, e.g.\n [`is_integer/1`](`is_integer/1`) instead of `integer/1`.\n\n Own Id: OTP-7910","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.6.8 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-8"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- A BIT STRING with a size constraint that has a single value and an extension\n as in `BIT STRING (SIZE (16,...))` was erroneous encoded/decoded. This is now\n corrected and follows X.691 Section 15.6.\n\n Own Id: OTP-7876 Aux Id: seq11220","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 1.6.7 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-7"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Now asn1 starts multiple drivers to enable simultaneous encode/decode in\n different processes for the asn1-backends using linked-in driver.\n\n Own Id: OTP-7801","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.6.6 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-6"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Decode of an open_type when the value was empty tagged type encoded with\n indefinite length failed. This is now corrected.\n\n Own Id: OTP-7759 Aux Id: seq11166\n\n- Encode of BIT STRING with size of exact length, on compact_bit_string format\n in UNALIGNED PER failed when value had the right size, i.e. no padding needed.\n\n Own Id: OTP-7763 Aux Id: seq11182","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 1.6.5 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-5"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- For a BIT STRING with SIZE constraint higher than 255 compiled with\n `[per_bin,optimize, compact_bit_string]` an improper io-list was created and\n sent to the c-driver for complete encoding. This error has been resolved.\n\n Own Id: OTP-7734 Aux Id: seq11170","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 1.6.4 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-4"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- A a SEQUENCE OF with a type that is a CHOICE with ellipses occurred falsely a\n compile error. The error causing that is now removed.\n\n Own Id: OTP-7708 Aux Id: seq11136","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 1.6.3 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- constrained number with a value-range greater than 512 now has the proper\n interpretation of the values that causes shift to the next number of units\n (bits), According to limit condition `2^m < \"range\" =< 2^(m + 1)` then the\n number of bits are m + 1.\n\n Own Id: OTP-7681 Aux Id: seq11114","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Can now handle default values of simple types that is provided on its own\n format, i.e. not just as asn1_DEFAULT.\n\n Own Id: OTP-7678 Aux Id: seq11114","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.6.2 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- comparison of two value definitions failed due to new module name field in\n valuedef record. It is now corrected.\n\n Own Id: OTP-7608","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Asn1 1.6.1 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Bug regarding propagation of parameters of parameterized type fixed.\n\n Own Id: OTP-7174 Aux Id: seq10864\n\n- A bug, related to instantiation of a parameterized type with a type definition\n in the parameter-list, has been removed. The definition of the parameter type\n was in another module than the instance definition causing limited module\n info.\n\n Own Id: OTP-7299 Aux Id: seq10864\n\n- Removed hard-coded name that may cause name collision.\n\n Own Id: OTP-7322 Aux Id: seq10864\n\n- Object set of a class with id with properties UNIQUE OPTIONAL and the id field\n is lacking in the object is for now treated as a object without a unique\n identifier, i.e. no table is generated for this object.\n\n Own Id: OTP-7332 Aux Id: seq10864\n\n- Compiler crashed when failed to handle a OID as ValueFromObject.\n\n Own Id: OTP-7476 Aux Id: seq10999\n\n- A corrupted encoding may cause a loop when a buffer of at least two bytes of\n zero matches tag and length of a SET component. This behavior occurred only\n with decoder generated with `ber` or `ber_bin` options. Now a control breaks\n the loop.\n\n Own Id: OTP-7533\n\n- Encode of BIT STRING longer than 255 bits with a `SIZE(integer())` constraint\n caused a crash when spec was compiled with `per_bin, optimize` options.\n\n Own Id: OTP-7602 Aux Id: seq11079","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Now supports REAL type of base 2 and 10\n\n Own Id: OTP-7166 Aux Id: seq10864\n\n- By the asn1 compiler option `{record_name_prefix Name}` a prefix is chosen to\n the name of the record generated in the .hrl and used in the generated .erl\n files.\n\n Own Id: OTP-7204 Aux Id: seq10853\n\n- The TypeFromObject production now covered\n\n Own Id: OTP-7295 Aux Id: seq10468\n\n- Extended support for ObjectSetFromObjects. Production occurred as a part of\n the RootElementSetSpec of the ObjectSetSpec. Added also support for Exclusion\n of Element in ObjectSetSpec.\n\n Own Id: OTP-7306 Aux Id: seq10864\n\n- Now implements RELATIVE-OID\n\n Own Id: OTP-7334 Aux Id: seq10864","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.6 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-6"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Now is ordering, according to the canonical order, of components in a SET\n added. Canonical order is described in X.691 9.2 and X.680 8.6\n\n Own Id: OTP-7375 Aux Id: unaligned PER\n\n- The precedence rules for extended constraints have been misinterpreted. The\n rule says for instance that if there are more than one constraint on a type\n that have extension-mark, only the last of the extension-marks would be kept.\n This affects the encoding of PER and is now corrected.\n\n Own Id: OTP-7400 Aux Id: OTP-7335\n\n- A constrained number with a single-value constraint that is extensible was\n falsely encoded/decoded in aligned/unaligned PER. This is now corrected.\n\n Own Id: OTP-7403","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- The ASN.1 compiler has got a new backend supporting PER UNALIGNED. Previously\n it was only support for PER ALIGNED.\n\n Own Id: OTP-7335\n\n- Now the asn1-compiler handles unions and intersections of PermittedAlphabet\n constraints.\n\n Own Id: OTP-7374 Aux Id: unaligned PER\n\n- With the undocumented option `no_final_padding` the whole encoded message is\n not padded to a border of a byte. Thus the returned encoded message is a\n `bitstring`.\n\n Own Id: OTP-7407","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.5.2 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-5-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- When duplicates of object fields were removed only one table access function\n for each unique identifier value was generated. This can occur when several\n object sets are merged by use of ObjectSetFromObjects.\n\n Own Id: OTP-7263 Aux Id: seq10864\n\n- DER: For some complex types and components with reference to type in several\n steps the default value check function was not generated. This is now fixed.\n\n Own Id: OTP-7268 Aux Id: seq10684\n\n- Now is the tag in a tagged type as parameter propagated to the instance.\n\n Own Id: OTP-7273 Aux Id: seq10864","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Added type T61String that is similar to TeletexString\n\n Own Id: OTP-7264 Aux Id: seq10864","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.5.1 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-5-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- A bug related to renaming of types has been fixed.This occurred using the\n .set.asn functionality.\n\n Own Id: OTP-7149 Aux Id: seq10853\n\n- syntax error in ASN1 value now correctly shown\n\n Own Id: OTP-7154 Aux Id: seq10864\n\n- Now a COMPONENTS OF construct in a parameterized type is expanded correctly\n\n Own Id: OTP-7155 Aux Id: seq10864\n\n- Now the asn1-compiler also handles empty SEQUENCE DEFAULT values as `{}`.\n\n Own Id: OTP-7169 Aux Id: seq10864\n\n- Now SelectionType gets the tag of the selected type.\n\n Own Id: OTP-7171 Aux Id: seq10864\n\n- Correction of generated code for decode of an open type in a SEQUECNE OF/ SET\n OF\n\n Own Id: OTP-7193 Aux Id: seq10875","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Misc improvements and bug corrections regarding default values.\n\n Own Id: OTP-7199 Aux Id: seq10864","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.5 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-5"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Now generating records in .hrl file for instances of parameterized SEQUENCE or\n SET.\n\n Own Id: OTP-6835\n\n- Optimization using bitstr in encode/decode functions. Active with\n `[per_bin, optimize]` options.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-6882","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.4.6 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-4-6"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Parsing and encoding/decoding of type constrained with SIZE with extension is\n now recovered.\n\n Own Id: OTP-6763\n\n- `inline` failed because trying to use a removed module.\n\n Own Id: OTP-6769\n\n- Fixed problem with a reference to a type from an object. The failure was\n caused bye change of type name when using `inline` option.\n\n Own Id: OTP-6770\n\n- Handling of decode pattern for exclusive decode was false in the case when an\n un-decoded component had more than one following elements that should be\n decoded.\n\n Own Id: OTP-6786","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- Now the asn1-compiler supports two root lists in SEQUENCE and SET according to\n alternative three in ComponentTypeLists (X.680 07/2002 section 24.1), i.e.\n with an extension list between two ellipses.\n\n Own Id: OTP-5067 Aux Id: seq8452","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Asn1 1.4.5 - asn1 Release Notes","doc":"","ref":"notes.html#asn1-1-4-5"},{"type":"extras","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","doc":"- Merging modules by `inline` earlier disabled the driver (used in modules\n generated with \\[optimized]/\\[optimized,driver] options). Now this is\n repaired.\n\n Own Id: OTP-6601\n\n- Checking phase now aware of which module an INSTANCE OF is declared in.\n\n Own Id: OTP-6702","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - asn1 Release Notes","doc":"- The compiler now handle all forms of ObjectSetSpec according to ITU-T\n recommendation X.681 (ISO/IEC 8824-2:2002).\n\n Own Id: OTP-6698\n\n- Enhanced support of referencing object sets by ObjectSetFromObjects.\n\n Own Id: OTP-6707\n\n- Support for parameterized object in an object set.\n\n Own Id: OTP-6717","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Introduction","doc":"\n# Introduction\n\nThe `asn1` application provides the following:\n\n- An ASN.1 compiler for Erlang, which generates encode and decode functions to\n be used by Erlang programs sending and receiving ASN.1-specified data.\n- Runtime functions used by the generated code.\n- Support for the following encoding rules:\n - Basic Encoding Rules (BER)\n - Distinguished Encoding Rules (DER), a specialized form of BER that is used\n in security-conscious applications\n - Packed Encoding Rules (PER), both the aligned and unaligned variant\n - JSON Encoding Rules (JER)","ref":"asn1_introduction.html"},{"type":"extras","title":"Scope - Introduction","doc":"This application covers all features of ASN.1 up to the 1997 edition of the\nspecification. In the 2002 edition, new features were introduced. The following\nfeatures of the 2002 edition are fully or partly supported:\n\n- Decimal notation (for example, `\"1.5e3`) for REAL values. The NR1, NR2, and\n NR3 formats as explained in ISO 6093 are supported.\n- The `RELATIVE-OID` type for relative object identifiers is fully supported.\n- The subtype constraint (`CONTAINING`/`ENCODED BY`) to constrain the content of\n an octet string or a bit string is parsed when compiling, but no further\n action is taken. This constraint is not a PER-visible constraint.\n- The subtype constraint by regular expressions (`PATTERN`) for character string\n types is parsed when compiling, but no further action is taken. This\n constraint is not a PER-visible constraint.\n- Multiple-line comments as in C, `/* ... */`, are supported.","ref":"asn1_introduction.html#scope"},{"type":"extras","title":"Prerequisites - Introduction","doc":"It is assumed that the reader is familiar with the Erlang programming language,\nconcepts of OTP, and is familiar with the ASN.1 notation. The ASN.1 notation is\ndocumented in the standard definition X.680, which is the primary text. It can\nalso be helpful, but not necessary, to read the standard definitions X.681,\nX.682, X.683, X.690, and X.691.\n\nA good book explaining those reference texts is Dubuisson: ASN.1 - Communication\nBetween Heterogeneous Systems, is free to download at\n[http://www.oss.com/asn1/dubuisson.html](http://www.oss.com/asn1/dubuisson.html).","ref":"asn1_introduction.html#prerequisites"},{"type":"extras","title":"ASN.1","doc":"\n# ASN.1","ref":"asn1_overview.html"},{"type":"extras","title":"Introduction - ASN.1","doc":"ASN.1 is a formal language for describing data structures to be exchanged\nbetween distributed computer systems. The purpose of ASN.1 is to have a platform\nand programming language independent notation to express types using a\nstandardized set of rules for the transformation of values of a defined type\ninto a stream of bytes. This stream of bytes can then be sent on any type of\ncommunication channel. This way, two applications written in different\nprogramming languages running on different computers, and with different\ninternal representation of data, can exchange instances of structured data\ntypes.","ref":"asn1_overview.html#introduction"},{"type":"extras","title":"Getting Started","doc":"\n# Getting Started","ref":"asn1_getting_started.html"},{"type":"extras","title":"Example - Getting Started","doc":"The following example demonstrates the basic functionality used to run the\nErlang ASN.1 compiler.\n\nCreate a file named `People.asn` containing the following:\n\n```text\nPeople DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\n Person ::= SEQUENCE {\n name PrintableString,\n location INTEGER {home(0),field(1),roving(2)},\n age INTEGER OPTIONAL\n }\nEND\n```\n\nThis file must be compiled before it can be used. The ASN.1 compiler checks that\nthe syntax is correct and that the text represents proper ASN.1 code before\ngenerating an abstract syntax tree. The code generator then uses the abstract\nsyntax tree to generate code.\n\nThe generated Erlang files are placed in the current directory or in the\ndirectory specified with option `{outdir,Dir}`.\n\nThe compiler can be called from the Erlang shell like this:\n\n```erlang\n1> asn1ct:compile(\"People\", [ber]).\nok\n```\n\nOption `verbose` can be added to get information about the generated files:\n\n```erlang\n2> asn1ct:compile(\"People\", [ber,verbose]).\nErlang ASN.1 compiling \"People.asn\"\n--{generated,\"People.asn1db\"}--\n--{generated,\"People.hrl\"}--\n--{generated,\"People.erl\"}--\nok\n```\n\nASN.1 module `People` is now accepted and the abstract syntax tree is saved in\nfile `People.asn1db`. The generated Erlang code is compiled using the Erlang\ncompiler and loaded into the Erlang runtime system. There is now an API for\n`encode/2` and `decode/2` in module `People`, which is called like this:\n\n```\n'People':encode( , )\n```\n\nor:\n\n```\n'People':decode( , )\n```\n\nAssume that there is a network application that receives instances of the ASN.1\ndefined type `Person`, modifies, and sends them back again:\n\n```erlang\nreceive\n {Port,{data,Bytes}} ->\n case 'People':decode('Person',Bytes) of\n {ok,P} ->\n {ok,Answer} = 'People':encode('Person',mk_answer(P)),\n Port ! {self(),{command,Answer}};\n {error,Reason} ->\n exit({error,Reason})\n end\n end,\n```\n\nIn this example, a series of bytes is received from an external source and the\nbytes are then decoded into a valid Erlang term. This was achieved with the call\n`'People':decode('Person',Bytes)`, which returned an Erlang value of the ASN.1\ntype `Person`. Then an answer was constructed and encoded using\n`'People':encode('Person',Answer)`, which takes an instance of a defined ASN.1\ntype and transforms it to a binary according to the BER or PER encoding rules.\n\nThe encoder and decoder can also be run from the shell:\n\n```erlang\n2> Rockstar = {'Person',\"Some Name\",roving,50}.\n{'Person',\"Some Name\",roving,50}\n3> {ok,Bin} = 'People':encode('Person',Rockstar).\n{ok,<<243,17,19,9,83,111,109,101,32,78,97,109,101,2,1,2,\n 2,1,50>>}\n4> {ok,Person} = 'People':decode('Person',Bin).\n{ok,{'Person',\"Some Name\",roving,50}}\n```","ref":"asn1_getting_started.html#example"},{"type":"extras","title":"Module Dependencies - Getting Started","doc":"It is common that ASN.1 modules import defined types, values, and other entities\nfrom another ASN.1 module.\n\nEarlier versions of the ASN.1 compiler required that modules that were imported\nfrom had to be compiled before the module that imported. This caused problems\nwhen ASN.1 modules had circular dependencies.\n\nReferenced modules are now parsed when the compiler finds an entity that is\nimported. No code is generated for the referenced module. However, the compiled\nmodules rely on that the referenced modules are also compiled.","ref":"asn1_getting_started.html#module-dependencies"},{"type":"extras","title":"ASN.1 Application User Interface - Getting Started","doc":"The `ASN.1` application provides the following two separate user interfaces:\n\n- The module `asn1ct`, which provides the compile-time functions (including the\n compiler)\n- The module `asn1rt_nif`, which provides the runtime functions for the ASN.1\n decoder for the BER back end\n\nThe reason for this division of the interfaces into compile-time and runtime is\nthat only runtime modules (`asn1rt_nif`) need to be loaded in an embedded system.","ref":"asn1_getting_started.html#asn-1-application-user-interface"},{"type":"extras","title":"Compile-Time Functions - Getting Started","doc":"The ASN.1 compiler can be started directly from the command line by the `erlc`\nprogram. This is convenient when compiling many ASN.1 files from the command\nline or when using Makefiles. Here some examples showing of how `erlc` can\ncompile ASN.1 modules:\n\n```text\nerlc Person.asn\nerlc -bper Person.asn\nerlc -bber ../Example.asn\nerlc -o ../asnfiles -I ../asnfiles -I /usr/local/standards/asn1 Person.asn\n```\n\nUseful options for the ASN.1 compiler:\n\n- **`-b[ber | per | uper | jer]`** - Choice of encoding rules. If omitted, `ber`\n is the default.\n\n- **`-o OutDirectory`** - Where to put the generated files. Default is the\n current directory.\n\n- **`-I IncludeDir`** - Where to search for `.asn1db` files and ASN.1 source\n specs to resolve references to other modules. This option can be repeated many\n times if there are several places to search in. The compiler searches the\n current directory first.\n\n- **`+der`** - DER encoding rule. Only when using option `-bber`.\n\n- **`+jer`** - Functions `jer_encode/2` and `jer_decode/2` for JSON encoding\n rules are generated together with functions for `ber` or `per`. Only to be\n used when the main encoding option is `-bber`, `-bper` or `-buper`.\n\n- **`+maps`** - Use maps instead of records to represent the `SEQUENCE` and\n `SET` types. No `.hrl` files will be generated. See the section\n [Map representation for SEQUENCE and SET](asn1_getting_started.md#MAP_SEQ_SET)\n for more information.\n\n- **`+asn1config`** - This functionality works together with option `ber`. It\n enables the specialized decodes, see section\n [Specialized Decode](asn1_spec.md).\n\n- **`+undec_rest`** - A buffer that holds a message being decoded can also have\n trailing bytes. If those trailing bytes are important, they can be returned\n along with the decoded value by compiling the ASN.1 specification with option\n `+undec_rest`. The return value from the decoder is `{ok,Value,Rest}` where\n `Rest` is a binary containing the trailing bytes.\n\n- **`+'Any Erlc Option'`** - Any option can be added to the Erlang compiler when\n compiling the generated Erlang files. Any option unrecognized by the ASN.1\n compiler is passed to the Erlang compiler.\n\nFor a complete description of `erlc`, see ERTS Reference Manual.\n\nThe compiler and other compile-time functions can also be started from the\nErlang shell. Here follows a brief description of the primary functions. For a\ncomplete description of each function, see module `asn1ct` in the\n[ASN.1 Reference Manual](`m:asn1ct`).\n\nThe compiler is started by `asn1ct:compile/1` with default options, or\n`asn1ct:compile/2` if explicit options are given.\n\nExample:\n\n```text\nasn1ct:compile(\"H323-MESSAGES\").\n```\n\nThis is equivalent to:\n\n```text\nasn1ct:compile(\"H323-MESSAGES\", [ber]).\n```\n\nIf PER encoding is wanted:\n\n```text\nasn1ct:compile(\"H323-MESSAGES\", [per]).\n```\n\nThe generic encode and decode functions can be called as follows:\n\n```text\n'H323-MESSAGES':encode('SomeChoiceType', {call,<<\"octetstring\">>}).\n'H323-MESSAGES':decode('SomeChoiceType', Bytes).\n```","ref":"asn1_getting_started.html#compile-time-functions"},{"type":"extras","title":"Runtime Functions - Getting Started","doc":"When an ASN.1 specification is compiled with option `ber`, the `asn1rt_nif`\nmodule and the NIF library in `asn1/priv_dir` are needed at runtime.\n\nBy calling function `info/0` in a generated module, you get information about\nwhich compiler options were used.","ref":"asn1_getting_started.html#runtime-functions"},{"type":"extras","title":"Errors - Getting Started","doc":"Errors detected at compile-time are displayed on the screen together with line\nnumbers indicating where in the source file the respective error was detected.\nIf no errors are found, an Erlang ASN.1 module is created.\n\nThe runtime encoders and decoders execute within a `catch` and return `{ok, Data}`\nor `{error, {asn1, Description}}` where `Description` is an Erlang term\ndescribing the error.\n\nCurrently, `Description` looks like this: `{ErrorDescription, StackTrace}`.\nApplications should not depend on the exact contents of `Description` as it\ncould change in the future.","ref":"asn1_getting_started.html#errors"},{"type":"extras","title":"Multi-File Compilation - Getting Started","doc":"There are various reasons for using multi-file compilation:\n\n- To choose the name for the generated module, for example, because you need to\n compile the same specs for different encoding rules.\n- You want only one resulting module.\n\nSpecify which ASN.1 specs to compile in a module with extension `.set.asn`.\nChoose a module name and provide the names of the ASN.1 specs. For example, if\nyou have the specs `File1.asn`, `File2.asn`, and `File3.asn`, your module\n`MyModule.set.asn` looks as follows:\n\n```text\nFile1.asn\nFile2.asn\nFile3.asn\n```\n\nIf you compile with the following, the result is one merged module\n`MyModule.erl` with the generated code from the three ASN.1 specs:\n\n```text\n% erlc MyModule.set.asn\n```","ref":"asn1_getting_started.html#multi-file-compilation"},{"type":"extras","title":"Note about tags - Getting Started","doc":"Tags used to be important for all users of ASN.1, because it was necessary to\nto manually add tags to certain constructs in order for the ASN.1 specification to\nbe valid. Example of an old-style specification:\n\n```erlang\nTags DEFINITIONS ::=\nBEGIN\n Afters ::= CHOICE { cheese [0] IA5String,\n dessert [1] IA5String }\nEND\n```\n\nWithout the tags (the numbers in square brackets) the ASN.1 compiler refused to\ncompile the file.\n\nIn 1994 the global tagging mode `AUTOMATIC TAGS` was introduced. By putting\n`AUTOMATIC TAGS` in the module header, the ASN.1 compiler automatically adds\ntags when needed. The following is the same specification in `AUTOMATIC TAGS`\nmode:\n\n```erlang\nTags DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\n Afters ::= CHOICE { cheese IA5String,\n dessert IA5String }\nEND\n```\n\n[](){: #ASN1Types }","ref":"asn1_getting_started.html#note-about-tags"},{"type":"extras","title":"ASN.1 Types - Getting Started","doc":"This section describes the ASN.1 types including their functionality, purpose,\nand how values are assigned in Erlang.\n\nASN.1 has both primitive and constructed types:\n\n| _Primitive Types_ | _Constructed Types_ |\n| -------------------------------------------------------------- | ------------------------------------------------------------ |\n| [BOOLEAN](asn1_getting_started.md#boolean) | [SEQUENCE](asn1_getting_started.md#sequence) |\n| [INTEGER](asn1_getting_started.md#integer) | [SET](asn1_getting_started.md#set) |\n| [REAL](asn1_getting_started.md#real) | [CHOICE](asn1_getting_started.md#choice) |\n| [NULL](asn1_getting_started.md#null) | [SET OF and SEQUENCE OF](asn1_getting_started.md#SOF) |\n| [ENUMERATED](asn1_getting_started.md#enumerated) | [ANY](asn1_getting_started.md#ANY) |\n| [BIT STRING](asn1_getting_started.md#bit-string) | [ANY DEFINED BY](asn1_getting_started.md#ANY) |\n| [OCTET STRING](asn1_getting_started.md#octet-string) | [EXTERNAL](asn1_getting_started.md#NegotiationTypes) |\n| [Character Strings](asn1_getting_started.md#character-strings) | [EMBEDDED PDV](asn1_getting_started.md#NegotiationTypes) |\n| [OBJECT IDENTIFIER](asn1_getting_started.md#object-identifier) | [CHARACTER STRING](asn1_getting_started.md#NegotiationTypes) |\n| [Object Descriptor](asn1_getting_started.md#object-descriptor) | |\n| [TIME Types](asn1_getting_started.md#The-TIME-types) | |\n\n_Table: Supported ASN.1 Types_\n\n[](){: #TypeNameValue }\n\n> #### Note {: .info }\n>\n> The values of each ASN.1 type have their own representation in Erlang, as\n> described in the following sections. Users must provide these values for\n> encoding according to the representation, as shown in the following example:\n\n```text\nOperational ::= BOOLEAN --ASN.1 definition\n```\n\nIn Erlang code it can look as follows:\n\n```erlang\nVal = true,\n{ok,Bytes} = MyModule:encode('Operational', Val),\n```","ref":"asn1_getting_started.html#asn-1-types"},{"type":"extras","title":"BOOLEAN - Getting Started","doc":"Booleans in ASN.1 express values that can be either `TRUE` or `FALSE`. The\nmeanings assigned to `TRUE` and `FALSE` are outside the scope of this text.\n\nIn ASN.1 it is possible to have:\n\n```text\nOperational ::= BOOLEAN\n```\n\nAssigning a value to type `Operational` in Erlang is possible by using the\nfollowing Erlang code:\n\n```erlang\nMyvar1 = true,\n```\n\nThus, in Erlang the atoms `true` and `false` are used to encode a boolean value.","ref":"asn1_getting_started.html#boolean"},{"type":"extras","title":"INTEGER - Getting Started","doc":"An ASN.1 INTEGER is represented by an integer in Erlang.\n\nThe concept of subtyping can be applied to integers and to other ASN.1 types.\nThe details of subtyping are not explained here; for more information, see\nX.680. Various syntaxes are allowed when defining a type as an integer:\n\n```erlang\nT1 ::= INTEGER\nT2 ::= INTEGER (-2..7)\nT3 ::= INTEGER (0..MAX)\nT4 ::= INTEGER (0<..MAX)\nT5 ::= INTEGER (MIN<..-99)\nT6 ::= INTEGER {red(0),blue(1),white(2)}\n```\n\nThe Erlang representation of an ASN.1 `INTEGER` is an integer or an atom if a\n`Named Number List` (see `T6` in the previous list) is specified.\n\nThe following is an example of Erlang code that assigns values for the types in\nthe previous list:\n\n```erlang\nT1value = 0,\nT2value = 6,\nT6value1 = blue,\nT6value2 = 0,\nT6value3 = white\n```\n\nThese Erlang variables are now bound to valid instances of ASN.1 defined types.\nThis style of value can be passed directly to the encoder for transformation\ninto a series of bytes.\n\nThe decoder returns an atom if the value corresponds to a symbol in the\n`Named Number List`.","ref":"asn1_getting_started.html#integer"},{"type":"extras","title":"REAL - Getting Started","doc":"The following ASN.1 type is used for real numbers:\n\n```text\nR1 ::= REAL\n```\n\nIt is assigned a value in Erlang as follows:\n\n```text\nR1value1 = \"2.14\",\nR1value2 = {256,10,-2},\n```\n\nIn the last line, notice that the tuple \\{256,10,-2\\} is the real number 2.56 in\na special notation, which encodes faster than simply stating the number as\n`\"2.56\"`. The arity three tuple is `{Mantissa,Base,Exponent}`, that is,\nMantissa \\* Base^Exponent.","ref":"asn1_getting_started.html#real"},{"type":"extras","title":"NULL - Getting Started","doc":"The type `NULL` is suitable where supply and recognition of a value is important\nbut the actual value is not.\n\n```text\nNotype ::= NULL\n```\n\nThis type is assigned in Erlang as follows:\n\n```text\nN1 = 'NULL',\n```\n\nThe actual value is the quoted atom `'NULL'`.","ref":"asn1_getting_started.html#null"},{"type":"extras","title":"ENUMERATED - Getting Started","doc":"The type `ENUMERATED` can be used when the value you want to describe can only\ntake one of a set of predefined values. Example:\n\n```text\nDaysOfTheWeek ::= ENUMERATED {\n sunday(1),monday(2),tuesday(3),\n wednesday(4),thursday(5),friday(6),saturday(7) }\n```\n\nFor example, to assign a weekday value in Erlang, use the same atom as in the\n`Enumerations` of the type definition:\n\n```text\nDay1 = saturday,\n```\n\nThe enumerated type is similar to an integer type, when defined with a set of\npredefined values. The difference is that an enumerated type can only have\nspecified values, whereas an integer can have any value.","ref":"asn1_getting_started.html#enumerated"},{"type":"extras","title":"BIT STRING - Getting Started","doc":"The type `BIT STRING` can be used to model information that is made up of\narbitrary length series of bits. It is intended to be used for selection of\nflags, not for binary files.\n\nIn ASN.1, `BIT STRING` definitions can look as follows:\n\n```erlang\nBits1 ::= BIT STRING\nBits2 ::= BIT STRING {foo(0),bar(1),gnu(2),gnome(3),punk(14)}\n```\n\nThe following two notations are available for representation of `BIT STRING`\nvalues in Erlang and as input to the encode functions:\n\n1. A bitstring. By default, a `BIT STRING` with no symbolic names is decoded to\n an Erlang bitstring.\n1. A list of atoms corresponding to atoms in the `NamedBitList` in the\n `BIT STRING` definition. A `BIT STRING` with symbolic names is always decoded\n to the format shown in the following example:\n\n```text\nBits1Val1 = <<0:1,1:1,0:1,1:1,1:1>>,\nBits2Val1 = [gnu,punk],\nBits2Val2 = <<2#1110:4>>,\nBits2Val3 = [bar,gnu,gnome],\n```\n\n`Bits2Val2` and `Bits2Val3` denote the same value.\n\n`Bits2Val1` is assigned symbolic values. The assignment means that the bits\ncorresponding to `gnu` and `punk`, that is, bits 2 and 14 are set to 1, and the\nrest are set to 0. The symbolic values are shown as a list of values. If a named\nvalue, which is not specified in the type definition, is shown, a runtime error\noccurs.\n\n`BIT STRING`s can also be subtyped with, for example, a `SIZE` specification:\n\n```text\nBits3 ::= BIT STRING (SIZE(0..31))\n```\n\nThis means that no bit higher than 31 can be set.\n\n#### Deprecated Representations for BIT STRING\n\nIn addition to the representations described earlier, the following deprecated\nrepresentations are available if the specification has been compiled with option\n`legacy_erlang_types`:\n\n1. Aa a list of binary digits (0 or 1). This format is accepted as input to the\n encode functions, and a `BIT STRING` is decoded to this format if option\n `legacy_bit_string` is given.\n1. As `{Unused,Binary}` where `Unused` denotes how many trailing zero-bits 0-7\n that are unused in the least significant byte in `Binary`. This format is\n accepted as input to the encode functions, and a `BIT STRING` is decoded to\n this format if `compact_bit_string` has been given.\n1. As a hexadecimal number (or an integer). Avoid this as it is easy to\n misinterpret a `BIT STRING` value in this format.","ref":"asn1_getting_started.html#bit-string"},{"type":"extras","title":"OCTET STRING - Getting Started","doc":"`OCTET STRING` is the simplest of all ASN.1 types. `OCTET STRING` only moves or\ntransfers, for example, binary files or other unstructured information complying\nwith two rules: the bytes consist of octets and encoding is not required.\n\nIt is possible to have the following ASN.1 type definitions:\n\n```erlang\nO1 ::= OCTET STRING\nO2 ::= OCTET STRING (SIZE(28))\n```\n\nWith the following example assignments in Erlang:\n\n```text\nO1Val = <<17,13,19,20,0,0,255,254>>,\nO2Val = <<\"must be exactly 28 chars....\">>,\n```\n\nBy default, an `OCTET STRING` is always represented as an Erlang binary. If the\nspecification has been compiled with option `legacy_erlang_types`, the encode\nfunctions accept both lists and binaries, and the decode functions decode an\n`OCTET STRING` to a list.","ref":"asn1_getting_started.html#octet-string"},{"type":"extras","title":"Character Strings - Getting Started","doc":"ASN.1 supports a wide variety of character sets. The main difference between an\n`OCTET STRING` and a character string is that the `OCTET STRING` has no imposed\nsemantics on the bytes delivered.\n\nHowever, when using, for example, `IA5String` (which closely resembles ASCII),\nbyte 65 (in decimal notation) _means_ character 'A'.\n\nFor example, if a defined type is to be a VideotexString and an octet is\nreceived with the unsigned integer value `X`, the octet is to be interpreted as\nspecified in standard ITU-T T.100, T.101.\n\nThe ASN.1 compiler does not determine the correct interpretation of\neach BER string octet value with different character strings. The application is\nresponsible for interpretation of octets. Therefore, from the BER string point\nof view, octets are very similar to character strings and are compiled in the\nsame way.\n\nWhen PER is used, there is a significant difference in the encoding scheme\nfor `OCTET STRING`s and other strings. The constraints specified for a type\nare especially important for PER, because they affect the encoding.\n\nExamples:\n\n```erlang\nDigs ::= NumericString (SIZE(1..3))\nTextFile ::= IA5String (SIZE(0..64000))\n```\n\nThe corresponding Erlang assignments:\n\n```c\nDigsVal1 = \"456\",\nDigsVal2 = \"123\",\nTextFileVal1 = \"abc...xyz...\",\nTextFileVal2 = [88,76,55,44,99,121 .......... a lot of characters here ....]\n```\n\nThe Erlang representation for `BMPString` and `UniversalString` is either a list\nof ASCII values or a list of quadruples. The quadruple representation associates\nto the Unicode standard representation of characters. The ASCII characters are\nall represented by quadruples beginning with three zeros like `{0,0,0,65}` for\ncharacter 'A'. When decoding a value for these strings, the result is a list of\nquadruples, or integers when the value is an ASCII character.\n\nThe following example shows how it works. Assume the following specification is\nin file `PrimStrings.asn1`:\n\n```text\nPrimStrings DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\n BMP ::= BMPString\nEND\n```\n\nEncoding and decoding some strings:\n\n```erlang\n1> asn1ct:compile('PrimStrings', [ber]).\nok\n2> {ok,Bytes1} = 'PrimStrings':encode('BMP', [{0,0,53,53},{0,0,45,56}]).\n{ok,<<30,4,53,54,45,56>>}\n3> 'PrimStrings':decode('BMP', Bytes1).\n{ok,[{0,0,53,53},{0,0,45,56}]}\n4> {ok,Bytes2} = 'PrimStrings':encode('BMP', [{0,0,53,53},{0,0,0,65}]).\n{ok,<<30,4,53,53,0,65>>}\n5> 'PrimStrings':decode('BMP', Bytes2).\n{ok,[{0,0,53,53},65]}\n6> {ok,Bytes3} = 'PrimStrings':encode('BMP', \"BMP string\").\n{ok,<<30,20,0,66,0,77,0,80,0,32,0,115,0,116,0,114,0,105,0,110,0,103>>}\n7> 'PrimStrings':decode('BMP', Bytes3).\n{ok,\"BMP string\"}\n```\n\nType `UTF8String` is represented as a UTF-8 encoded binary in Erlang. Such\nbinaries can be created directly using the binary syntax or by converting from a\nlist of Unicode code points using function `unicode:characters_to_binary/1`.\n\nThe following shows examples of how UTF-8 encoded binaries can be created and\nmanipulated:\n\n```erlang\n1> Gs = \"Мой маленький Гном\".\n[1052,1086,1081,32,1084,1072,1083,1077,1085,1100,1082,1080,\n 1081,32,1043,1085,1086,1084]\n2> Gbin = unicode:characters_to_binary(Gs).\n<<208,156,208,190,208,185,32,208,188,208,176,208,187,208,\n 181,208,189,209,140,208,186,208,184,208,185,32,208,147,\n 208,...>>\n3> Gbin = <<\"Мой маленький Гном\"/utf8>>.\n<<208,156,208,190,208,185,32,208,188,208,176,208,187,208,\n 181,208,189,209,140,208,186,208,184,208,185,32,208,147,\n 208,...>>\n4> Gs = unicode:characters_to_list(Gbin).\n[1052,1086,1081,32,1084,1072,1083,1077,1085,1100,1082,1080,\n 1081,32,1043,1085,1086,1084]\n```\n\nFor details, see the `m:unicode` module in STDLIB.\n\nIn the following example, this ASN.1 specification is used:\n\n```text\nUTF DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\n UTF ::= UTF8String\nEND\n```\n\nEncoding and decoding a string with Unicode characters:\n\n```erlang\n5> asn1ct:compile('UTF', [ber]).\nok\n6> {ok,Bytes1} = 'UTF':encode('UTF', <<\"Гном\"/utf8>>).\n{ok,<<12,8,208,147,208,189,208,190,208,188>>}\n7> {ok,Bin1} = 'UTF':decode('UTF', Bytes1).\n{ok,<<208,147,208,189,208,190,208,188>>}\n8> io:format(\"~ts\\n\", [Bin1]).\nГном\nok\n9> unicode:characters_to_list(Bin1).\n[1043,1085,1086,1084]\n```","ref":"asn1_getting_started.html#character-strings"},{"type":"extras","title":"OBJECT IDENTIFIER - Getting Started","doc":"The type `OBJECT IDENTIFIER` is used whenever a unique identity is required. An\nASN.1 module, a transfer syntax, and so on, is identified with an\n`OBJECT IDENTIFIER`. Assume the following example:\n\n```erlang\nOid ::= OBJECT IDENTIFIER\n```\n\nTherefore, the following example is a valid Erlang instance of type `Oid`:\n\n```text\nOidVal1 = {1,2,55},\n```\n\nThe `OBJECT IDENTIFIER` value is a tuple with the consecutive integer values.\n\nThe first value is limited to the values 0, 1, or 2. The second value must be in\nthe range 0 through 39 when the first value is 0 or 1.\n\nThe `OBJECT IDENTIFIER` is an important type and it is widely used within\ndifferent standards to identify various objects uniquely. Dubuisson: _ASN.1 -\nCommunication Between Heterogeneous Systems_ includes an easy-to-understand\ndescription of the use of `OBJECT IDENTIFIER`.","ref":"asn1_getting_started.html#object-identifier"},{"type":"extras","title":"Object Descriptor - Getting Started","doc":"Values of this type can be assigned a value as an ordinary string as follows:\n\n```text\n\"This is the value of an Object descriptor\"\n```\n\n[](){: #The-TIME-types }","ref":"asn1_getting_started.html#object-descriptor"},{"type":"extras","title":"TIME Types - Getting Started","doc":"Two time types are defined within ASN.1: Generalized Time and Universal Time\nCoordinated (UTC). Both are assigned a value as an ordinary string within double\nquotes, for example, `\"19820102070533.8\"`.\n\nFor DER encoding, the compiler does not check the validity of the time values.\nThe DER requirements upon those strings are regarded as a matter for the\napplication to fulfill.","ref":"asn1_getting_started.html#time-types"},{"type":"extras","title":"SEQUENCE - Getting Started","doc":"The structured types of ASN.1 are constructed from other types in a manner\nsimilar to the concepts of arrays and structs in C.\n\nA `SEQUENCE` in ASN.1 is comparable with a struct in C and a record in Erlang. A\n`SEQUENCE` can be defined as follows:\n\n```erlang\nPdu ::= SEQUENCE {\n a INTEGER,\n b REAL,\n c OBJECT IDENTIFIER,\n d NULL }\n```\n\nThis is a 4-component structure called `Pdu`. By default, a `SEQUENCE` is\nrepresented by a record in Erlang. It can also be represented as a map; see\n[Map representation for SEQUENCE and SET](asn1_getting_started.md#MAP_SEQ_SET).\nFor each `SEQUENCE` and `SET` in an ASN.1 module an Erlang record declaration is\ngenerated. For `Pdu`, a record like the following is defined:\n\n```erlang\n-record('Pdu', {a, b, c, d}).\n```\n\nThe record declarations for a module `M` are placed in a separate `M.hrl` file.\n\nValues can be assigned in Erlang as follows:\n\n```erlang\nMyPdu = #'Pdu'{a=22,b=77.99,c={0,1,2,3,4},d='NULL'}.\n```\n\nThe decode functions return a record as result when decoding a `SEQUENCE` or a\n`SET`.\n\nA `SEQUENCE` and a `SET` can contain a component with a `DEFAULT` keyword\nfollowed by the actual value, which is the default value. The `DEFAULT` keyword\nmeans that the application doing the encoding can omit encoding of the value,\nwhich results in fewer bytes to send to the receiving application.\n\nAn application can use the atom `asn1_DEFAULT` to indicate that the encoding is\nto be omitted for that position in the `SEQUENCE`.\n\nDepending on the encoding rules, the encoder can also compare the given value to\nthe default value and automatically omit the encoding if the values are equal.\nHow much effort the encoder makes to compare the values depends on the encoding\nrules. The DER encoding rules forbid encoding a value equal to the default\nvalue, so it has a more thorough and time-consuming comparison than the encoders\nfor the other encoding rules.\n\nIn the following example, this ASN.1 specification is used:\n\n```text\nFile DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\nSeq1 ::= SEQUENCE {\n a INTEGER DEFAULT 1,\n b Seq2 DEFAULT {aa TRUE, bb 15}\n}\n\nSeq2 ::= SEQUENCE {\n aa BOOLEAN,\n bb INTEGER\n}\n\nSeq3 ::= SEQUENCE {\n bs BIT STRING {a(0), b(1), c(2)} DEFAULT {a, c}\n}\nEND\n```\n\nExample where the BER encoder is able to omit encoding of the default values:\n\n```erlang\n1> asn1ct:compile('File', [ber]).\nok\n2> 'File':encode('Seq1', {'Seq1',asn1_DEFAULT,asn1_DEFAULT}).\n{ok,<<48,0>>}\n3> 'File':encode('Seq1', {'Seq1',1,{'Seq2',true,15}}).\n{ok,<<48,0>>}\n```\n\nExample with a named `BIT STRING` where the BER encoder does not omit the\nencoding:\n\n```erlang\n4> 'File':encode('Seq3', {'Seq3',asn1_DEFAULT).\n{ok,<<48,0>>}\n5> 'File':encode('Seq3', {'Seq3',<<16#101:3>>).\n{ok,<<48,4,128,2,5,160>>}\n```\n\nThe DER encoder omits the encoding for the same `BIT STRING`:\n\n```erlang\n6> asn1ct:compile('File', [ber,der]).\nok\n7> 'File':encode('Seq3', {'Seq3',asn1_DEFAULT).\n{ok,<<48,0>>}\n8> 'File':encode('Seq3', {'Seq3',<<16#101:3>>).\n{ok,<<48,0>>}\n```","ref":"asn1_getting_started.html#sequence"},{"type":"extras","title":"SET - Getting Started","doc":"In Erlang, the `SET` type is used exactly as `SEQUENCE`. Notice that if BER or\nDER encoding rules are used, decoding a `SET` is slower than decoding a\n`SEQUENCE` because the components must be sorted.","ref":"asn1_getting_started.html#set"},{"type":"extras","title":"Extensibility for SEQUENCE and SET - Getting Started","doc":"When a `SEQUENCE` or `SET` contains an extension marker and extension components\nas the following, the type can get more components in newer versions of the\nASN.1 spec:\n\n```text\nSExt ::= SEQUENCE {\n a INTEGER,\n ...,\n b BOOLEAN }\n```\n\nIn this case it has got a new component `b`. Thus, incoming messages that are\ndecoded can have more or fever components than this one.\n\nThe component `b` is treated as an original component when encoding a message.\nIn this case, as it is not an optional element, it must be encoded.\n\nDuring decoding, the `b` field of the record gets the decoded value of the `b`\ncomponent, if present, otherwise the value `asn1_NOVALUE`.\n\n[](){: #MAP_SEQ_SET }","ref":"asn1_getting_started.html#extensibility-for-sequence-and-set"},{"type":"extras","title":"Map representation for SEQUENCE and SET - Getting Started","doc":"If the ASN.1 module has been compiled with option `maps`, the types `SEQUENCE`\nand `SET` are represented as maps.\n\nIn the following example, this ASN.1 specification is used:\n\n```text\nFile DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\nSeq1 ::= SEQUENCE {\n a INTEGER DEFAULT 42,\n b BOOLEAN OPTIONAL,\n c IA5String\n}\nEND\n```\n\nOptional fields are to be omitted from the map if they have no value:\n\n```erlang\n1> asn1ct:compile('File', [per,maps]).\nok\n2> {ok,E} = 'File':encode('Seq1', #{a=>0,c=>\"string\"}).\n{ok,<<128,1,0,6,115,116,114,105,110,103>>}\n```\n\nWhen decoding, optional fields will be omitted from the map:\n\n```erlang\n3> 'File':decode('Seq1', E).\n{ok,#{a => 0,c => \"string\"}}\n```\n\nDefault values can be omitted from the map:\n\n```erlang\n4> {ok,E2} = 'File':encode('Seq1', #{c=>\"string\"}).\n{ok,<<0,6,115,116,114,105,110,103>>}\n5> 'File':decode('Seq1', E2).\n{ok,#{a => 42,c => \"string\"}}\n```\n\n> #### Note {: .info }\n>\n> It is not allowed to use the atoms `asn1_VALUE` and `asn1_DEFAULT` with maps.","ref":"asn1_getting_started.html#map-representation-for-sequence-and-set"},{"type":"extras","title":"CHOICE - Getting Started","doc":"The type `CHOICE` is a space saver and is similar to the concept of union in\nC.\n\nAssume the following:\n\n```text\nSomeModuleName DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\nT ::= CHOICE {\n x REAL,\n y INTEGER,\n z OBJECT IDENTIFIER }\nEND\n```\n\nIt is then possible to assign values as follows:\n\n```erlang\nTVal1 = {y,17},\nTVal2 = {z,{0,1,2}},\n```\n\nA `CHOICE` value is always represented as the tuple `{ChoiceAlternative, Val}`\nwhere `ChoiceAlternative` is an atom denoting the selected choice alternative.\n\n#### Extensible CHOICE\n\nWhen a `CHOICE` contains an extension marker and the decoder detects an unknown\nalternative of the `CHOICE`, the value is represented as follows:\n\n```text\n{asn1_ExtAlt, BytesForOpenType}\n```\n\nHere `BytesForOpenType` is a list of bytes constituting the encoding of the\n\"unknown\" `CHOICE` alternative.\n\n[](){: #SOF }","ref":"asn1_getting_started.html#choice"},{"type":"extras","title":"SET OF and SEQUENCE OF - Getting Started","doc":"The types `SET OF` and `SEQUENCE OF` correspond to the concept of an array in\nseveral programming languages. The Erlang syntax for both types is\nstraightforward, for example:\n\n```text\nArr1 ::= SET SIZE (5) OF INTEGER (4..9)\nArr2 ::= SEQUENCE OF OCTET STRING\n```\n\nIn Erlang the following can apply:\n\n```text\nArr1Val = [4,5,6,7,8],\nArr2Val = [\"abc\",[14,34,54],\"Octets\"],\n```\n\nNotice that the definition of type `SET OF` implies that the order of the\ncomponents is undefined, but in practice there is no difference between `SET OF`\nand `SEQUENCE OF`. The ASN.1 compiler for Erlang does not randomize the order of\nthe `SET OF` components before encoding.\n\nHowever, for a value of type `SET OF`, the DER encoding format requires the\nelements to be sent in ascending order of their encoding, which implies an\nexpensive sorting procedure in runtime. Therefore it is recommended to use\n`SEQUENCE OF` instead of `SET OF` if possible.\n\n[](){: #ANY }","ref":"asn1_getting_started.html#set-of-and-sequence-of"},{"type":"extras","title":"ANY and ANY DEFINED BY - Getting Started","doc":"The types `ANY` and `ANY DEFINED BY` have been removed from the standard\nsince 1994. It is recommended not to use these types any more. They can,\nhowever, exist in some old ASN.1 modules. The idea with this type was to leave a\n\"hole\" in a definition where it was possible to put unspecified data of any\nkind, even non-ASN.1 data.\n\nA value of this type is encoded as an `open type`.\n\nInstead of `ANY` and `ANY DEFINED BY`, it is recommended to use\ninformation object classes, table constraints, and parameterization. In\nparticular the construct `TYPE-IDENTIFIER.@Type` accomplishes the same as the\ndeprecated `ANY`.\n\nAlso see [Information objects](asn1_getting_started.md#Information-Object).\n\n[](){: #NegotiationTypes }","ref":"asn1_getting_started.html#any-and-any-defined-by"},{"type":"extras","title":"EXTERNAL, EMBEDDED PDV, and CHARACTER STRING - Getting Started","doc":"The types `EXTERNAL`, `EMBEDDED PDV`, and `CHARACTER STRING` are used in\npresentation layer negotiation. They are encoded according to their associated\ntype, see X.680.\n\nThe type `EXTERNAL` had a slightly different associated type before 1994. X.691\nstates that encoding must follow the older associated type. So, generated\nencode/decode functions convert values of the newer format to the older format\nbefore encoding. This implies that it is allowed to use `EXTERNAL` type values\nof either format for encoding. Decoded values are always returned in the newer\nformat.","ref":"asn1_getting_started.html#external-embedded-pdv-and-character-string"},{"type":"extras","title":"Embedded Named Types - Getting Started","doc":"The structured types previously described can have other named types as their\ncomponents. The general syntax to assign a value to component `C` of a named\nASN.1 type `T` in Erlang is the record syntax `#'T'{'C'=Value}`. Here `Value`\ncan be a value of yet another type `T2`, for example:\n\n```text\nEmbeddedExample DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\nB ::= SEQUENCE {\n a Arr1,\n b T }\n\nArr1 ::= SET SIZE (5) OF INTEGER (4..9)\n\nT ::= CHOICE {\n x REAL,\n y INTEGER,\n z OBJECT IDENTIFIER }\n END\n```\n\n`SEQUENCE` `b` can be encoded as follows in Erlang:\n\n```erlang\n1> 'EmbeddedExample':encode('B', {'B',[4,5,6,7,8],{x,\"7.77\"}}).\n{ok,<<5,56,0,8,3,55,55,55,46,69,45,50>>}\n```","ref":"asn1_getting_started.html#embedded-named-types"},{"type":"extras","title":"Naming of Records in .hrl Files - Getting Started","doc":"When the option `maps` is given, no `.hrl` files will be generated. The rest of\nthis section describes the behavior of the compiler when `maps` is not used.\n\nWhen an ASN.1 specification is compiled, all defined types of type `SET` or\n`SEQUENCE` result in a corresponding record in the generated `.hrl` file. This\nis because the values for `SET` and `SEQUENCE` are represented as records by\ndefault.\n\nSome special cases of this functionality are presented in the next section.","ref":"asn1_getting_started.html#naming-of-records-in-hrl-files"},{"type":"extras","title":"Embedded Structured Types - Getting Started","doc":"In ASN.1 it is also possible to have components that are themselves structured\ntypes. For example, it is possible to have the following:\n\n```text\nEmb ::= SEQUENCE {\n a SEQUENCE OF OCTET STRING,\n b SET {\n a INTEGER,\n b INTEGER DEFAULT 66},\n c CHOICE {\n a INTEGER,\n b FooType } }\n\nFooType ::= [3] VisibleString\n```\n\nThe following records are generated because of type `Emb`:\n\n```erlang\n-record('Emb,{a, b, c}).\n-record('Emb_b',{a, b = asn1_DEFAULT}). % the embedded SET type\n```\n\nValues of type `Emb` can be assigned as follows:\n\n```erlang\nV = #'Emb'{a=[\"qqqq\",[1,2,255]],\n b = #'Emb_b'{a=99},\n c ={b,\"Can you see this\"}}.\n```\n\nFor an embedded type of type `SEQUENCE`/`SET` in a `SEQUENCE`/`SET`, the record\nname is extended with an underscore and the component name. If the embedded\nstructure is deeper with the `SEQUENCE`, `SET`, or `CHOICE` types in the line,\neach component name/alternative name is added to the record name.\n\nExample:\n\n```text\nSeq ::= SEQUENCE{\n a CHOICE{\n b SEQUENCE {\n c INTEGER\n }\n }\n}\n```\n\nThis results in the following record:\n\n```erlang\n-record('Seq_a_b',{c}).\n```\n\nIf the structured type has a component with an embedded `SEQUENCE OF`/`SET OF`\nwhich embedded type in turn is a `SEQUENCE`/`SET`, it gives a record with the\n`SEQUENCE OF`/`SET OF` addition as in the following example:\n\n```text\nSeq ::= SEQUENCE {\n a SEQUENCE OF SEQUENCE {\n b\n }\n c SET OF SEQUENCE {\n d\n }\n}\n```\n\nThis results in the following records:\n\n```erlang\n-record('Seq_a_SEQOF'{b}).\n-record('Seq_c_SETOF'{d}).\n```\n\nA parameterized type is to be considered as an embedded type. Each time such a\ntype is referenced, an instance of it is defined. Thus, in the following example\na record with name `'Seq_b'` is generated in the `.hrl` file and is used to hold\nvalues:\n\n```text\nSeq ::= SEQUENCE {\n b PType{INTEGER}\n}\n\nPType{T} ::= SEQUENCE{\n id T\n}\n```","ref":"asn1_getting_started.html#embedded-structured-types"},{"type":"extras","title":"Recursive Types - Getting Started","doc":"Types that refer to themselves are called recursive types. Example:\n\n```erlang\nRec ::= CHOICE {\n nothing NULL,\n something SEQUENCE {\n a INTEGER,\n b OCTET STRING,\n c Rec }}\n```\n\nThis is allowed in ASN.1 and the ASN.1-to-Erlang compiler supports this\nrecursive type. A value for this type is assigned in Erlang as follows:\n\n```erlang\nV = {something,#'Rec_something'{a = 77,\n b = \"some octets here\",\n c = {nothing,'NULL'}}}.\n```","ref":"asn1_getting_started.html#recursive-types"},{"type":"extras","title":"ASN.1 Values - Getting Started","doc":"Values can be assigned to an ASN.1 type within the ASN.1 code itself, as opposed\nto the actions in the previous section where a value was assigned to an ASN.1\ntype in Erlang. The full value syntax of ASN.1 is supported and X.680 describes\nin detail how to assign values in ASN.1. A short example:\n\n```erlang\nTT ::= SEQUENCE {\n a INTEGER,\n b SET OF OCTET STRING }\n\ntt TT ::= {a 77,b {\"kalle\",\"kula\"}}\n```\n\nThe value defined here can be used in several ways. It can, for example, be used\nas the value in some `DEFAULT` component:\n\n```text\nSS ::= SET {\n s OBJECT IDENTIFIER,\n val TT DEFAULT tt }\n```\n\nIt can also be used from inside an Erlang program. If this ASN.1 code is defined\nin ASN.1 module `Values`, the ASN.1 value `tt` can be reached from Erlang as a\nfunction call to `'Values':tt()` as in the following example:\n\n```erlang\n1> Val = 'Values':tt().\n{'TT',77,[\"kalle\",\"kula\"]}\n2> {ok,Bytes} = 'Values':encode('TT',Val).\n{ok,<<48,18,128,1,77,161,13,4,5,107,97,108,108,101,4,4,\n 107,117,108,97>>}\n4> 'Values':decode('TT',Bytes).\n{ok,{'TT',77,[\"kalle\",\"kula\"]}}\n5>\n```\n\nThis example shows that a function is generated by the compiler that returns a\nvalid Erlang representation of the value, although the value is of a complex\ntype.\n\nFurthermore, if the option `maps` is not used, a macro is generated for each\nvalue in the `.hrl` file. So, the defined value `tt` can also be extracted by\n`?tt` in application code.","ref":"asn1_getting_started.html#asn-1-values"},{"type":"extras","title":"Macros - Getting Started","doc":"The type `MACRO` is not supported. It is no longer part of the ASN.1 standard.\n\n[](){: #Information-Object }","ref":"asn1_getting_started.html#macros"},{"type":"extras","title":"ASN.1 Information Objects (X.681) - Getting Started","doc":"Information Object Classes, Information Objects, and Information Object Sets (in\nthe following called classes, objects, and object sets, respectively) are\ndefined in the standard definition X.681. Only a brief explanation is given\nhere.\n\nThese constructs makes it possible to define open types, that is, values of that\ntype can be of any ASN.1 type. Also, relationships can be defined between\ndifferent types and values, as classes can hold types, values, objects, object\nsets, and other classes in their fields. A class can be defined in ASN.1 as\nfollows:\n\n```text\nGENERAL-PROCEDURE ::= CLASS {\n &Message,\n &Reply OPTIONAL,\n &Error OPTIONAL,\n &id PrintableString UNIQUE\n}\nWITH SYNTAX {\n NEW MESSAGE &Message\n [REPLY &Reply]\n [ERROR &Error]\n ADDRESS &id\n}\n```\n\nAn object is an instance of a class. An object set is a set containing objects\nof a specified class. A definition can look as follows:\n\n```text\nobject1 GENERAL-PROCEDURE ::= {\n NEW MESSAGE PrintableString\n ADDRESS \"home\"\n}\n\nobject2 GENERAL-PROCEDURE ::= {\n NEW MESSAGE INTEGER\n ERROR INTEGER\n ADDRESS \"remote\"\n}\n```\n\nThe object `object1` is an instance of the class `GENERAL-PROCEDURE` and has one\ntype field and one fixed type value field. The object `object2` has also an\noptional field `ERROR`, which is a type field. The field `ADDRESS` is a `UNIQUE`\nfield. Objects in an object set must have unique values in their `UNIQUE` field,\nas in `GENERAL-PROCEDURES`:\n\n```text\nGENERAL-PROCEDURES GENERAL-PROCEDURE ::= {\n object1 | object2}\n```\n\nYou cannot encode a class, object, or object set, only refer to it when defining\nother ASN.1 entities. Typically you refer to a class as well as to object sets\nby table constraints and component relation constraints (X.682) in ASN.1 types,\nas in the following:\n\n```erlang\nStartMessage ::= SEQUENCE {\n msgId GENERAL-PROCEDURE.&id ({GENERAL-PROCEDURES}),\n content GENERAL-PROCEDURE.&Message ({GENERAL-PROCEDURES}{@msgId}),\n }\n```\n\nIn type `StartMessage`, the constraint following field `content` tells that in a\nvalue of type `StartMessage` the value in field `content` must come from the\nsame object that is chosen by field `msgId`.\n\nSo, the value `#'StartMessage'{msgId=\"home\",content=\"Any Printable String\"}` is\nlegal to encode as a `StartMessage` value. However, the value\n`#'StartMessage'{msgId=\"remote\", content=\"Some String\"}` is illegal as the\nconstraint in `StartMessage` tells that when you have chosen a value from a\nspecific object in object set `GENERAL-PROCEDURES` in field `msgId`, you must\nchoose a value from that same object in the content field too. In this second\ncase, it is to be any `INTEGER` value.\n\n`StartMessage` can in field `content` be encoded with a value of any type that\nan object in object set `GENERAL-PROCEDURES` has in its `NEW MESSAGE` field.\nThis field refers to a type field `&Message` in the class. Field `msgId` is\nalways encoded as a `PrintableString`, as the field refers to a fixed type in\nthe class.\n\nIn practice, object sets are usually declared to be extensible so that more\nobjects can be added to the set later. Extensibility is indicated as follows:\n\n```text\nGENERAL-PROCEDURES GENERAL-PROCEDURE ::= {\n object1 | object2, ...}\n```\n\nWhen decoding a type that uses an extensible set constraint, it is always\npossible that the value in field `UNIQUE` is unknown (that is, the type has been\nencoded with a later version of the ASN.1 specification). The unencoded data is\nthen returned wrapped in a tuple as follows:\n\n```text\n{asn1_OPENTYPE,Binary}\n```\n\nHere `Binary` is an Erlang binary that contains the encoded data. (If option\n`legacy_erlang_types` has been given, only the binary is returned.)","ref":"asn1_getting_started.html#asn-1-information-objects-x-681"},{"type":"extras","title":"Parameterization (X.683) - Getting Started","doc":"Parameterization, which is defined in X.683, can be used when defining types,\nvalues, value sets, classes, objects, or object sets. A part of a definition can\nbe supplied as a parameter. For example, if a `Type` is used in a definition\nwith a certain purpose, you want the type name to express the intention. This\ncan be done with parameterization.\n\nWhen many types (or another ASN.1 entity) only differ in some minor cases, but\nthe structure of the types is similar, only one general type can be defined and\nthe differences can be supplied through parameters.\n\nExample of use of parameterization:\n\n```text\nGeneral{Type} ::= SEQUENCE\n{\n number INTEGER,\n string Type\n}\n\nT1 ::= General{PrintableString}\n\nT2 ::= General{BIT STRING}\n```\n\nAn example of a value that can be encoded as type `T1` is `{12,\"hello\"}`.\n\nNotice that the compiler does not generate encode/decode functions for\nparameterized types, only for the instances of the parameterized types.\nTherefore, if a file contains the types `General{}`, `T1`, and `T2` as in the\nprevious example, encode/decode functions are only generated for `T1` and `T2`.","ref":"asn1_getting_started.html#parameterization-x-683"},{"type":"extras","title":"Specialized Decodes","doc":"\n# Specialized Decodes\n\n[](){: #SpecializedDecodes }\n\nWhen performance is of highest priority and one is interested in a limited part\nof the ASN.1 encoded message before deciding what to do with the rest of it, an\noption is to decode only a part of the message. This situation can be a server\nthat has to decide the addressee of a message. The addressee can be interested\nin the entire message, but the server can be a bottleneck that you want to spare\nany unnecessary load.\n\nInstead of making two _complete decodes_ (the normal case of decode), one in the\nserver and one in the addressee, it is only necessary to make one _specialized\ndecode_ (in the server) and another complete decode (in the addressee). This\nsection describes the following specialized decode functionality:\n\n- _Exclusive decode_\n- _Selected decode_\n\nThis functionality is only provided when using `BER` (option `ber`).","ref":"asn1_spec.html"},{"type":"extras","title":"Exclusive Decode - Specialized Decodes","doc":"The basic idea with exclusive decode is to specify which parts of the message\nyou want to exclude from being decoded. These parts remain encoded and are\nreturned in the value structure as binaries. The undecoded parts can be decoded\nlater by calling the `decode_part/2` function.","ref":"asn1_spec.html#exclusive-decode"},{"type":"extras","title":"Procedure - Specialized Decodes","doc":"To perform an exclusive decode:\n\n- _Step 1:_ Decide the name of the function for the exclusive decode.\n- _Step 2:_ Include the following instructions in a configuration file:\n\n - The name of the exclusive decode function\n - The name of the ASN.1 specification\n - A notation that tells which parts of the message structure to be excluded\n from decode\n\n- _Step 3_ Compile with the additional option `asn1config`. The compiler\n searches for a configuration file with the same name as the ASN.1\n specification but with extension `.asn1config`. This configuration file is not\n the same as used for compilation of a set of files. See section\n [Writing an Exclusive Decode Instruction.](asn1_spec.md#UndecodedPart)","ref":"asn1_spec.html#procedure"},{"type":"extras","title":"User Interface - Specialized Decodes","doc":"The runtime user interface for exclusive decode comprises the following two\nfunctions:\n\n- A function for an exclusive decode, whose name the user decides in the\n configuration file\n- A `decode_part/2` function generated by the ASN.1 compiler when\n exclusive decode is enabled. This function decodes the parts that\n were left undecoded during the exclusive decode.\n\nBoth functions are described in the following.\n\nIf the exclusive decode function has, for example, the name `decode_exclusive`\nand an ASN.1 encoded message `Bin` is to be exclusive decoded, the call is as\nfollows:\n\n```erlang\n{ok,ExclMessage} = 'MyModule':decode_exclusive(Bin)\n```\n\n[](){: #UndecodedPart } The result `ExclMessage` has the same structure as a\ncomplete decode would have, except for the parts of the top type that were not\ndecoded. The undecoded parts are on their places in the structure on format\n`{TypeKey,UndecodedValue}`.\n\nEach undecoded part that is to be decoded must be fed into function\n`decode_part/2` as follows:\n\n```erlang\n{ok,PartMessage} = 'MyModule':decode_part(TypeKey, UndecodedValue)\n```\n\n[](){: #Exclusive-Instruction }","ref":"asn1_spec.html#user-interface"},{"type":"extras","title":"Writing an Exclusive Decode Instruction - Specialized Decodes","doc":"This instruction is written in the configuration file in the following format:\n\n```erlang\nExclusiveDecodeInstruction = {exclusive_decode,{ModuleName,DecodeInstructions}}.\n\nModuleName = atom()\n\nDecodeInstructions = [DecodeInstruction]+\n\nDecodeInstruction = {ExclusiveDecodeFunctionName,TypeList}\n\nExclusiveDecodeFunctionName = atom()\n\nTypeList = [TopType,ElementList]\n\nElementList = [Element]+\n\nElement = {Name,parts} |\n {Name,undecoded} |\n {Name,ElementList}\n\nTopType = atom()\n\nName = atom()\n```\n\nThe instruction must be a valid Erlang term terminated by a dot.\n\nIn `TypeList` the path from the top type to each undecoded subcomponent is\ndescribed. `TopType` is the name of a top-level type in the ASN.1 specification.\nThe action for each component in `ElementList` is described by one of:\n\n- `{Name,parts}`\n- `{Name,undecoded}`\n- `{Name,ElementList}`\n\nThe use and effect of the actions are as follows:\n\n- **`{Name,undecoded}`** - Leaves the element undecoded. The type of `Name` can\n be any ASN.1 type. The value of element `Name` is returned as a tuple (as\n mentioned in the previous section) in the value structure of the top type.\n\n- **`{Name,parts}`** - The type of `Name` must be either `SEQUENCE OF` or\n `SET OF`. The action implies that the different components of `Name` are left\n undecoded. The value of `Name` is returned as a tuple (as mentioned in the\n previous section) where the second element is a list of binaries. This is\n because the representation of a `SEQUENCE OF` or a `SET OF` in Erlang is a\n list of its internal type. Any of the elements in this list or the entire list\n can be decoded by function `decodepart`.\n\n- **`{Name,ElementList}`** - This action is used when one or more of the\n subtypes of `Name` is exclusively decoded.\n\n`Name` in these actions can be a component name of a `SEQUENCE OF` or a\n`SET OF`, or a name of an alternative in a `CHOICE`.","ref":"asn1_spec.html#writing-an-exclusive-decode-instruction"},{"type":"extras","title":"Example - Specialized Decodes","doc":"In this examples, the definitions from the following ASN.1 specification are\nused:\n\n```text\n\nGUI DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n\n Action ::= SEQUENCE {\n number INTEGER DEFAULT 15,\n handle Handle DEFAULT {number 12, on TRUE}\n }\n\n Key ::= Button\n Handle ::= Key\n\n Button ::= SEQUENCE {\n number INTEGER,\n on BOOLEAN\n }\n\n Window ::= CHOICE {\n vsn INTEGER,\n status Status\n }\n\n Status ::= SEQUENCE {\n state INTEGER,\n buttonList SEQUENCE OF Button,\n enabled BOOLEAN OPTIONAL,\n actions CHOICE {\n possibleActions SEQUENCE OF Action,\n noOfActions INTEGER\n }\n }\n\nEND\n```\n\n{: #Asn1spec }\n\nIf `Button` is a top type and it is needed to exclude component `number` from\ndecode, `TypeList` in the instruction in the configuration file is\n`['Button',[{number,undecoded}]]`. If you call the decode function\n`decode_Button_exclusive`, `DecodeInstruction` is\n`{decode_Button_exclusive,['Button',[{number,undecoded}]]}`.\n\nAnother top type is `Window` whose subcomponent actions in type `Status` and the\nparts of component `buttonList` are to be left undecoded. For this type, the\nfunction is named `decode__Window_exclusive`. The complete\n`Exclusive_Decode_Instruction` configuration is as follows:\n\n```text\n\n{exclusive_decode,\n {'GUI',\n [{decode_Window_exclusive,\n ['Window',[{status,[{buttonList,parts},{actions,undecoded}]}]]},\n {decode_Button_exclusive,\n ['Button',[{number,undecoded}]]}]}}.\n```\n\nThe following figure shows the bytes of a `Window:status` message. The\ncomponents `buttonList` and `actions` are excluded from decode. Only `state` and\n`enabled` are decoded when `decode__Window_exclusive` is called.\n\n![Bytes of a Window:status Message](assets/exclusive_Win_But.gif \"Bytes of a Window:status Message\")\n\nHere follows an example of how the module. Note that option `no_ok_wrapper` is\nused to make the example more concise.\n\n```erlang\n1> asn1ct:compile('GUI', [ber,asn1config,no_ok_wrapper]).\nok\n2> rr('GUI').\n['Action','Button','Status']\n3> ButtonMsg = #'Button'{number=123,on=true}.\n#'Button'{number = 123,on = true}\n4> ButtonBytes = 'GUI':encode('Button', ButtonMsg).\n<<48,6,128,1,123,129,1,255>>\n5> ExclusiveMsgButton = 'GUI':decode_Button_exclusive(ButtonBytes).\n#'Button'{number = {'Button_number',<<128,1,123>>},\n on = true}\n6> {UndecKey,UndecBytes} = ExclusiveMsgButton#'Button'.number.\n{'Button_number',<<128,1,123>>}\n7> 'GUI':decode_part(UndecKey, UndecBytes).\n123\n8> WindowMsg =\n{status,{'Status',35,\n [{'Button',3,true},\n {'Button',4,false},\n {'Button',5,true},\n {'Button',6,true},\n {'Button',7,false}],\n false,\n {possibleActions,[{'Action',16,{'Button',17,true}}]}}}.\n{status,#'Status'{state = 35,\n buttonList = [#'Button'{number = 3,on = true},\n #'Button'{number = 4,on = false},\n #'Button'{number = 5,on = true},\n #'Button'{number = 6,on = true},\n #'Button'{number = 7,on = false}],\n enabled = false,\n actions = {possibleActions,[#'Action'{number = 16,\n handle = #'Button'{number = 17,on = true}}]}}}\n9> WindowBytes = 'GUI':encode('Window', WindowMsg).\n<<161,65,128,1,35,161,40,48,6,128,1,3,129,1,255,48,6,128,\n 1,4,129,1,0,48,6,128,1,5,129,...>>\n10> {status,#'Status'{buttonList={UndecWindowKey,UndecWindowParts}}} =\n'GUI':decode_Window_exclusive(WindowBytes).\n{status,#'Status'{state = 35,\n buttonList = {'Status_buttonList',[<<48,6,128,1,3,129,1,\n 255>>,\n <<48,6,128,1,4,129,1,0>>,\n <<48,6,128,1,5,129,1,255>>,\n <<48,6,128,1,6,129,1,255>>,\n <<48,6,128,1,7,129,1,0>>]},\n enabled = false,\n actions = {'Status_actions',<<163,15,160,13,48,11,128,\n 1,16,161,6,128,1,17,129,\n 1,255>>}}}\n11> 'GUI':decode_part(UndecWindowKey, UndecWindowParts).\n[#'Button'{number = 3,on = true},\n #'Button'{number = 4,on = false},\n #'Button'{number = 5,on = true},\n #'Button'{number = 6,on = true},\n #'Button'{number = 7,on = false}]\n12> 'GUI':decode_part(UndecWindowKey, hd(UndecWindowParts)).\n#'Button'{number = 3,on = true}\n13> {status,#'Status'{actions={ChoiceKey,ChoiceUndec}}} = v(10).\n{status,#'Status'{state = 35,\n buttonList = {'Status_buttonList',[<<48,6,128,1,3,129,1,\n 255>>,\n <<48,6,128,1,4,129,1,0>>,\n <<48,6,128,1,5,129,1,255>>,\n <<48,6,128,1,6,129,1,255>>,\n <<48,6,128,1,7,129,1,0>>]},\n enabled = false,\n actions = {'Status_actions',<<163,15,160,13,48,11,128,\n 1,16,161,6,128,1,17,129,\n 1,255>>}}}\n14> 'GUI':decode_part(ChoiceKey, ChoiceUndec).\n{possibleActions,[#'Action'{number = 16,\n handle = #'Button'{number = 17,on = true}}]}\n```","ref":"asn1_spec.html#example"},{"type":"extras","title":"Selective Decode - Specialized Decodes","doc":"Selective decode decodes a single subtype of a constructed value. This is the\nfastest method to extract a subvalue. Selective decode is typically used when\none want to inspect, for example, a version number to be able to decide how to\nhandle the entire value.","ref":"asn1_spec.html#selective-decode"},{"type":"extras","title":"Procedure - Specialized Decodes","doc":"To perform a selective decode:\n\n- _Step 1:_ Include the following instructions in the configuration file:\n\n - The name of the user function\n - The name of the ASN.1 specification\n - A notation that tells which part of the type to be decoded\n\n- _Step 2:_ Compile with the additional option `asn1config`. The compiler\n searches for a configuration file with the same name as the ASN.1\n specification, but with extension `.asn1config`. In the same file you can also\n provide configuration specifications for exclusive decode. The generated\n Erlang module has the usual functionality for encode/decode preserved and the\n specialized decode functionality added.","ref":"asn1_spec.html#procedure"},{"type":"extras","title":"User Interface - Specialized Decodes","doc":"The only new user interface function is the one provided by the user in the\nconfiguration file.\n\nFor example, if the configuration file includes the specification\n`{selective_decode,{'ModuleName',[{selected_decode_Window,TypeList}]}}` do the\nselective decode by\n`{ok,Result} = 'ModuleName':selected_decode_Window(EncodedBinary).`\n\n[](){: #Selective-Instruction }","ref":"asn1_spec.html#user-interface"},{"type":"extras","title":"Writing a Selective Decode Instruction - Specialized Decodes","doc":"One or more selective decode functions can be described in a configuration file.\nUse the following notation:\n\n```erlang\nSelectiveDecodeInstruction = {selective_decode,{ModuleName,DecodeInstructions}}.\n\nModuleName = atom()\n\nDecodeInstructions = [DecodeInstruction]+\n\nDecodeInstruction = {SelectiveDecodeFunctionName,TypeList}\n\nSelectiveDecodeFunctionName = atom()\n\nTypeList = [TopType|ElementList]\n\nElementList = Name|ListSelector\n\nName = atom()\n\nListSelector = [integer()]\n```\n\nThe instruction must be a valid Erlang term terminated by a dot.\n\n- `ModuleName` is the same as the name of the ASN.1 specification, but without\n the extension.\n- `DecodeInstruction` is a tuple with your chosen function name and the\n components from the top type that leads to the single type you want to decode.\n Make sure to choose a name of your function that is not the same as any of the\n generated functions.\n- The first element of `TypeList` is the top type of the encoded message. In\n `ElementList`, it is followed by each of the component names that leads to\n selected type.\n- Each name in `ElementList` must be a constructed type except the last name,\n which can be any type.\n- `ListSelector` makes it possible to choose one of the encoded components in a\n `SEQUENCE OF` or a `SET OF`. It is also possible to go further in that\n component and pick a subtype of that to decode. So, in the `TypeList`:\n `['Window',status,buttonList,[1],number]`, component `buttonList` must be of\n type `SEQUENCE OF` or `SET OF`.\n\nIn the example, component `number` of the first of the encoded elements in the\n`SEQUENCE OF` `buttonList` is selected. This applies on the ASN.1 specification\nin section [Writing an Exclusive Decode Instruction](asn1_spec.md#Asn1spec).","ref":"asn1_spec.html#writing-a-selective-decode-instruction"},{"type":"extras","title":"Example - Specialized Decodes","doc":"In this example, the same ASN.1 specification as in section\n[Writing an Exclusive Decode Instruction](asn1_spec.md#Asn1spec) is used. The\nfollowing is a valid selective decode instruction:\n\n```erlang\n{selective_decode,\n {'GUI',\n [{selected_decode_Window1,\n ['Window',status,buttonList,\n [1],\n number]},\n {selected_decode_Action,\n ['Action',handle,number]},\n {selected_decode_Window2,\n ['Window',\n status,\n actions,\n possibleActions,\n [1],\n handle,number]}]}}.\n```\n\nThe first instruction,\n`{selected_decode_Window1,['Window',status,buttonList,[1],number]}` is described\nin the previous section.\n\nThe second instruction, `{selected_decode_Action,['Action',handle,number]}`,\ntakes component `number` in the `handle` component of type `Action`. If the\nvalue is `ValAction = {'Action',17,{'Button',4711,false}}`, the internal value\n4711 is to be picked by `selected_decode_Action`. In an Erlang terminal it looks\nas follows:\n\n```erlang\n1> asn1ct:compile('GUI', [ber,asn1config,no_ok_wrapper]).\nok\n2> ValAction = {'Action',17,{'Button',4711,false}}.\n{'Action',17,{'Button',4711,false}}\n3> Bytes = 'GUI':encode('Action',ValAction).\n<<48,18,2,1,17,160,13,172,11,171,9,48,7,128,2,18,103,129,1,0>>\n4> 'GUI':selected_decode_Action(Bytes).\n4711\n```\n\nThe third instruction,\n`['Window',status,actions,possibleActions,[1],handle,number]`, works as follows:\n\n- _Step 1:_ Starts with type `Window`.\n- _Step 2:_ Takes component `status` of `Window` that is of type `Status`.\n- _Step 3:_ Takes _actions_ of type `Status`.\n- _Step 4:_ Takes `possibleActions` of the internally defined `CHOICE` type.\n- _Step 5:_ Goes into the first component of `SEQUENCE OF` by `[1]`. That\n component is of type `Action`.\n- _Step 6:_ Takes component `handle`.\n- _Step 7:_ Takes component `number` of type `Button`.\n\nThe following figure shows which components are in `TypeList`\n`['Window',status,actions,possibleActions,[1],handle,number]`:\n\n![Elements Specified in Configuration File for Selective Decode of a Subvalue in a Window Message](assets/selective_TypeList.gif \"Elements Specified in Configuration File for Selective Decode of a Subvalue in a Window Message\")\n\nIn the following figure, only the marked element is decoded by\n`selected_decode_Window2`:\n\n![Bytes of a Window:status Message](assets/selective_Window2.gif \"Bytes of a Window:status Message\")\n\nWith the following example, you can examine that both `selected_decode_Window2`\nand `selected_decode_Window1` decodes the intended subvalue of value `Val`:\n\n```erlang\n1> Val = {status,{'Status',12,\n [{'Button',13,true},\n {'Button',14,false},\n {'Button',15,true},\n {'Button',16,false}],\n true,\n {possibleActions,[{'Action',17,{'Button',18,false}},\n {'Action',19,{'Button',20,true}},\n {'Action',21,{'Button',22,false}}]}}}.\n2> Bin = 'GUI':encode('Window',Val).\n<<161,89,128,1,12,161,32,48,6,128,1,13,129,1,255,48,6,128,\n 1,14,129,1,0,48,6,128,1,15,129,...>>\n4> 'GUI':selected_decode_Window1(Bin).\n13\n5> 'GUI':selected_decode_Window2(Bin).\n18\n```","ref":"asn1_spec.html#example"}],"content_type":"text/plain","producer":{"name":"ex_doc","version":[48,46,51,52,46,49]}} \ No newline at end of file diff --git a/prs/8803/lib/asn1-5.3/doc/html/dist/search_data-965B670D.js b/prs/8803/lib/asn1-5.3/doc/html/dist/search_data-965B670D.js new file mode 100644 index 0000000000000..dcd837321a312 --- /dev/null +++ b/prs/8803/lib/asn1-5.3/doc/html/dist/search_data-965B670D.js @@ -0,0 +1 @@ +searchData={"items":[{"type":"module","doc":"ASN.1 compiler and compile-time support functions\n\nThe ASN.1 compiler takes an ASN.1 module as input and generates a corresponding\nErlang module, which can encode and decode the specified data types.\nAlternatively, the compiler takes a specification module specifying all input\nmodules, and generates a module with encode/decode functions. In addition, some\ngeneric functions can be used during development of applications that handles\nASN.1 data (encoded as `BER` or `PER`).\n\n> #### Note {: .info }\n>\n> By default in Erlang/OTP 17, the representation of the `BIT STRING` and\n> `OCTET STRING` types as Erlang terms were changed. `BIT STRING` values are now\n> Erlang bit strings and `OCTET STRING` values are binaries. Also, an undecoded\n> open type is now wrapped in an `asn1_OPENTYPE` tuple. For details, see\n> [BIT STRING](asn1_getting_started.md#bit-string),\n> [OCTET STRING](asn1_getting_started.md#octet-string), and\n> [ASN.1 Information Objects](asn1_getting_started.md#Information-Object) in the\n> User's Guide.\n>\n> To revert to the old representation of the types, use option\n> `legacy_erlang_types`.","title":"asn1ct","ref":"asn1ct.html"},{"type":"function","doc":"","title":"asn1ct.compile/1","ref":"asn1ct.html#compile/1"},{"type":"function","doc":"Compiles the ASN.1 module `Asn1Module` and generates an Erlang module\n`Asn1Module.erl` with encode and decode functions for all types defined in\nthe ASN.1 module.\n\nFor each ASN.1 value defined in the module, an Erlang function that\nreturns the value in Erlang representation is generated.\n\nIf `Asn1Module` is a filename without extension, first `\".asn1\"` is assumed,\nthen `\".asn\"`, and finally `\".py\"` (to be compatible with the old ASN.1\ncompiler). `Asn1Module` can be a full pathname (relative or absolute) including\nfilename with (or without) extension.[](){: #asn1set }\n\nIf it is needed to compile a set of `ASN.1` modules into an Erlang\nfile with encode/decode functions, list all involved files in a\nconfiguration file, one line per file. This configuration file must\nhave a double extension `\".set.asn1\"` (`\".asn1\"` can alternatively be\n`\".asn\"` or `\".py\"`). If the input files are `File1.asn1`,\n`File2.asn1`, and `File3.asn1`, the configuration file should look as\nfollows:\n\n```text\nFile1.asn1\nFile2.asn1\nFile3.asn1\n```\n\nThe output files in this case get their names from the configuration file. If\nthe configuration file is named `SetOfFiles.set.asn1`, the names of the output\nfiles are `SetOfFiles.hrl, SetOfFiles.erl, and SetOfFiles.asn1db`.\n\nSometimes in a system of `ASN.1` modules, different modules can have\ndifferent default tag modes, for example, one uses `AUTOMATIC` and\nanother `IMPLICIT`. The multi-file compilation resolves the default\ntagging as if the modules were compiled separately.\n\nName collisions is an unwanted effect that can occur in multi-file\ncompilation. The compiler solves this problem in one of two ways:\n\n- If the definitions are identical, the output module keeps only one definition\n with the original name.\n- If the definitions have the same name and differs in the definition, they are\n renamed. The new names are the definition name and the original module name\n concatenated.\n\nIf a name collision occurs, the compiler reports a `\"NOTICE: ...\"` message that\ntells if a definition was renamed, and the new name that must be used to\nencode/decode data.\n\n`Options` is a list with options specific for the ASN.1 compiler and options\nthat are applied to the Erlang compiler. The ASN.1 compiler passes on any\nunrecognized options to the Erlang compiler. The available options are as follows:\n\n- **`ber | per | uper | jer`** - The encoding rule to be used. The\n supported encoding rules are Basic Encoding Rules (`ber`), Packed\n Encoding Rules (`per`) aligned, PER unaligned (`uper`), and JSON\n Encoding Rules (`jer`). The `jer` option can be used by itself to\n generate a module that only supports encoding/decoding of JER, or it\n can be used as a supplementary option to `ber`, `per`, and `uper`,\n in which case a module that handles both the main encoding rules and\n JER will be generated. In that case, the exported functions for JER\n will be `jer_encode(Type, Value)` and `jer_decode(Type, Bytes)`.\n\n JER (ITU-T X.697) are experimental in OTP 22. There is support for a\n subset of the X.697 standard, for example there is no support for:\n\n - JER encoding instructions\n - the REAL type\n\n > #### Change {: .info }\n >\n > In Erlang/OTP 27 and later, module `m:json` in STDLIB is used for\n > encoding and decoding JSON. Before Erlang/OTP 27, it was necessary\n > to provide an external JSON library.\n\n If the encoding rule option is omitted, `ber` is the default.\n\n The generated Erlang module always gets the same name as the ASN.1 module.\n Therefore, only one encoding rule per ASN.1 module can be used at runtime.\n\n- **`der`** - With this option the Distinguished Encoding Rules (`der`) is\n chosen. DER is regarded as a specialized variant of the BER encoding rule.\n Therefore, this option only makes sense together with option `ber`. This\n option sometimes adds sorting and value checks when encoding, which implies\n slower encoding. The decoding routines are the same as for `ber`.\n\n- **`maps`** - This option changes the representation of the types `SEQUENCE`\n and `SET` to use maps (instead of records). This option also suppresses the\n generation of `.hrl` files.\n\n For details, see section\n [Map representation for SEQUENCE and SET](asn1_getting_started.md#MAP_SEQ_SET)\n in the User's Guide.\n\n- **`compact_bit_string`** - The `BIT STRING` type is decoded to \"compact\n notation\".\n\n **This option is not recommended for new code.**\n\n For details, see section [BIT STRING](asn1_getting_started.md#bit-string) in\n the User's Guide.\n\n This option implies option `legacy_erlang_types`, and it cannot be combined\n with option `maps`.\n\n- **`legacy_bit_string`** - The `BIT STRING` type is decoded to the legacy\n format, that is, a list of zeroes and ones.\n\n **This option is not recommended for new code.**\n\n For details, see section [BIT STRING](asn1_getting_started.md#bit-string) in\n the User's Guide\n\n This option implies option `legacy_erlang_types`, and it cannot be combined\n with option `maps`.\n\n- **`legacy_erlang_types`** - Use the same Erlang types to represent\n `BIT STRING` and `OCTET STRING` as in Erlang/OTP R16.\n\n **This option is not recommended for new code.**\n\n For details, see section [BIT STRING](asn1_getting_started.md#bit-string) and\n section [OCTET STRING](asn1_getting_started.md#octet-string) in the User's\n Guide.\n\n This option cannot be combined with option `maps`.\n\n- **`{n2n, EnumTypeName}`** - Tells the compiler to generate functions for\n conversion between names (as atoms) and numbers and conversely for the\n specified `EnumTypeName`. There can be multiple occurrences of this option to\n specify several type names. The type names must be declared as `ENUMERATIONS`\n in the ASN.1 specification.\n\n If `EnumTypeName` does not exist in the ASN.1 specification, the compilation\n stops with an error code.\n\n The generated conversion functions are named `name2num_EnumTypeName/1` and\n `num2name_EnumTypeName/1`.\n\n- **`noobj`** - Do not compile (that is, do not produce object code) the\n generated `.erl` file. If this option is omitted, the generated Erlang module\n is compiled.\n\n- **`{i, IncludeDir}`** - Adds `IncludeDir` to the search-path for `.asn1db` and\n ASN.1 source files. The compiler tries to open an `.asn1db` file when a\n module imports definitions from another ASN.1 module. If no `.asn1db` file\n is found, the ASN.1 source file is parsed. Several `{i, IncludeDir}` can be\n given.\n\n- **`{outdir, Dir}`** - Specifies directory `Dir` where all generated files are\n to be placed. If this option is omitted, the files are placed in the current\n directory.\n\n- **`asn1config`** - When using one of the specialized decodes, exclusive or\n selective decode, instructions must be given in a configuration file. Option\n `asn1config` enables specialized decodes and takes the configuration file in\n concern. The configuration file has the same name as the ASN.1 specification,\n but with extension `.asn1config`.\n\n For instructions for exclusive decode, see section\n [Exclusive Decode](asn1_spec.md#Exclusive-Instruction) in the User's Guide.\n\n For instructions for selective decode, see section\n [Selective Decode](asn1_spec.md#Selective-Instruction) in the User's Guide.\n\n- **`undec_rest`** - By default when decoding, any bytes following the\n end of an ASN.1 data structure are discarded. If an ASN.1 module is\n compiled with option `undec_rest`, the decode function returns a\n tuple `{ok, Value, Rest}`, where `Rest` is the bytes following the ASN.1\n data structure. `Rest` can be a list or a binary.\n\n- **`no_ok_wrapper`** - With this option, the generated `encode/2` and\n `decode/2` functions do not wrap a successful return value in an `{ok,...}`\n tuple. If any error occurs, an exception will be raised.\n\n- **`{macro_name_prefix, Prefix}`** - All macro names generated by the compiler\n are prefixed with `Prefix`. This is useful when multiple protocols that\n contain macros with identical names are included in a single module.\n\n- **`{record_name_prefix, Prefix}`** - All record names generated by the\n compiler are prefixed with `Prefix`. This is useful when multiple protocols\n that contain records with identical names are included in a single module.\n\n- **`verbose`** - Causes more verbose information from the compiler describing\n what it is doing.\n\n- **`warnings_as_errors`** - Causes warnings to be treated as errors.\n\n- **`deterministic`** - Causes all non-deterministic options to be stripped from\n the `-asn1_info()` attribute.\n\nUnrecognized options are passed on to the Erlang compiler when the generated\n`.erl` file is compiled.\n\nThe compiler generates the following files:\n\n- `Asn1Module.hrl` (if any `SET` or `SEQUENCE` is defined)\n- `Asn1Module.erl` \\- Erlang module with encode, decode, and value functions\n- `Asn1Module.asn1db` \\- Intermediate format used by the compiler when modules\n `IMPORT` definitions from each other.","title":"asn1ct.compile/2","ref":"asn1ct.html#compile/2"},{"type":"function","doc":"Tests encoding and decoding of all types in `Module`.\n\nFor more details, see `test/3`.","title":"asn1ct.test/1","ref":"asn1ct.html#test/1"},{"type":"function","doc":"Tests encoding and decoding of `Module`.\n\nIf the second argument is given as atom `Type`, that type is tested.\n\nIf the second argument is given as list `Options`, that are the options\nthat are used for testing all types in the module.\n\nFor more details, see `test/3`.","title":"asn1ct.test/2","ref":"asn1ct.html#test/2"},{"type":"function","doc":"Performs a test of encode and decode of types in `Module`.\n\nThe generated functions are called by this function. This function is\nuseful for testing to ensure that the generated encode and decode\nfunctions as well as the general runtime support work as expected.\n\n> #### Note {: .info }\n>\n> Currently, the `test` functions have many limitations. Essentially, they will\n> mostly work for old specifications based on the 1997 standard for ASN.1, but\n> not for most modern-style applications. Another limitation is that the `test`\n> functions may not work if options that change code generations strategies such\n> as the options `macro_name_prefix` and `record_name_prefix` have been used.\n\n- [`test/1`](`test/1`) iterates over all types in `Module`.\n- [`test/2`](`test/2`) tests type `Type` with a random value.\n- [`test/3`](`test/3`) tests type `Type` with `Value`.\n\nSchematically, the following occurs for each type in the module:\n\n```erlang\n{ok, Value} = asn1ct:value(Module, Type),\n{ok, Bytes} = Module:encode(Type, Value),\n{ok, Value} = Module:decode(Type, Bytes).\n```\n\nThe `test` functions use the `*.asn1db` files for all included modules. If they\nare located in a different directory than the current working directory, use the\n`include` option to add paths. This is only needed when automatically generating\nvalues. For static values using `Value` no options are needed.","title":"asn1ct.test/3","ref":"asn1ct.html#test/3"},{"type":"function","doc":"Returns an Erlang term that is an example of a valid Erlang representation of a\nvalue of the ASN.1 type `Type`.\n\nThe value is a random value and subsequent calls to this function will\nfor most types return different values.\n\n> #### Note {: .info }\n>\n> Currently, the `value` function has many limitations. Essentially, it will\n> mostly work for old specifications based on the 1997 standard for ASN.1, but\n> not for most modern-style applications. Another limitation is that the `value`\n> function may not work if options that change code generations strategies such\n> as the options `macro_name_prefix` and `record_name_prefix` have been used.","title":"asn1ct.value/2","ref":"asn1ct.html#value/2"},{"type":"extras","doc":"\n# asn1 Release Notes\n\nThis document describes the changes made to the asn1 application.","title":"asn1 Release Notes","ref":"notes.html"},{"type":"extras","doc":"","title":"Asn1 5.3 - asn1 Release Notes","ref":"notes.html#asn1-5-3"},{"type":"extras","doc":"- Multiple bugs has been eliminated in the [specialized decode feature](`e:asn1:asn1_spec.md`).\n\n Own Id: OTP-18813 Aux Id: [PR-7790]\n\n[PR-7790]: https://github.com/erlang/otp/pull/7790","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Specs have been added to all `asn1ct` API functions.\n\n Own Id: OTP-18804 Aux Id: [PR-7738]\n\n- The documentation has been migrated to use Markdown and ExDoc.\n\n Own Id: OTP-18955 Aux Id: [PR-8026]\n\n- The `jer` (JSON Encoding Rules) for ASN.1 now use the new `m:json` module for encoding and decoding JSON. Thus, there is no longer any need for an external JSON library.\n\n Own Id: OTP-19018 Aux Id: [PR-8241]\n\n[PR-7738]: https://github.com/erlang/otp/pull/7738\n[PR-8026]: https://github.com/erlang/otp/pull/8026\n[PR-8241]: https://github.com/erlang/otp/pull/8241","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 5.2.2 - asn1 Release Notes","ref":"notes.html#asn1-5-2-2"},{"type":"extras","doc":"* An ASN.1 module that contains named `BIT STRING` values would fail to compiled if both the BER and JER back-ends were enabled.\n\n Own Id: OTP-19039 Aux Id: GH-8291, PR-8297","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.2.1 - asn1 Release Notes","ref":"notes.html#asn1-5-2-1"},{"type":"extras","doc":"- Fix benign warning from gcc 11 about mismatching call to free().\n\n Own Id: OTP-18844","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.2 - asn1 Release Notes","ref":"notes.html#asn1-5-2"},{"type":"extras","doc":"- The ASN.1 compiler would ignore a constraint such as `(SIZE (1..4), ...)`,\n causing incorrect behavior of the encoding and decoding function for the PER\n and UPER backends. Corrected to handle the constraint in the same way as\n `(SIZE (1..4, ...))`.\n\n Own Id: OTP-18729 Aux Id: PR-7575","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The JER backend has been internally refactored in a way that is compatible for\n applications that use the documented API. However, for a group of ASN.1\n modules that depend on each other (for example, `S1AP-PDU-Descriptions`,\n S1AP-Contents, and so on), all modules in the group must be recompiled if on\n of the group members is recompiled.\n\n Own Id: OTP-18748 Aux Id: ERIERL-957, PR-7637","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 5.1 - asn1 Release Notes","ref":"notes.html#asn1-5-1"},{"type":"extras","doc":"- The ASN.1 compiler used to reject correctly specified RELATIVE-OID values\n containing other RELATIVE-OID values. This is now corrected.\n\n Own Id: OTP-18534 Aux Id: ERIERL-737, PR-7039","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Minor code improvements.\n\n Own Id: OTP-18441\n\n- Handling of `on_load` modules during boot has been improved by adding an extra\n step in the boot order for embedded mode that runs all `on_load` handlers,\n instead of relying on explicit invocation of them, later, when the kernel\n supervision tree starts.\n\n This is mostly a code improvement and OTP internal simplification to avoid\n future bugs and to simplify code maintenance.\n\n Own Id: OTP-18447","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 5.0.21.1 - asn1 Release Notes","ref":"notes.html#asn1-5-0-21-1"},{"type":"extras","doc":"- Fix benign warning from gcc 11 about mismatching call to free().\n\n Own Id: OTP-18844","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.21 - asn1 Release Notes","ref":"notes.html#asn1-5-0-21"},{"type":"extras","doc":"- For the `per` and `uper` ASN.1 encoding rules, encoding and decoding the\n `SEQUENCE OF` and `SET OF` constructs with 16384 items or more is now\n supported.\n\n Own Id: OTP-18245 Aux Id: ERIERL-859","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.20 - asn1 Release Notes","ref":"notes.html#asn1-5-0-20"},{"type":"extras","doc":"- There is a new configure option, `--enable-deterministic-build`, which will\n apply the `deterministic` compiler option when building Erlang/OTP. The\n `deterministic` option has been improved to eliminate more sources of\n non-determinism in several applications.\n\n Own Id: OTP-18165 Aux Id: PR-5965","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 5.0.19 - asn1 Release Notes","ref":"notes.html#asn1-5-0-19"},{"type":"extras","doc":"- The atom `maybe` has been quoted in the source code.\n\n Own Id: OTP-17980","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.18.2 - asn1 Release Notes","ref":"notes.html#asn1-5-0-18-2"},{"type":"extras","doc":"- Fix benign warning from gcc 11 about mismatching call to free().\n\n Own Id: OTP-18844","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.18.1 - asn1 Release Notes","ref":"notes.html#asn1-5-0-18-1"},{"type":"extras","doc":"- For the `per` and `uper` ASN.1 encoding rules, encoding and decoding the\n `SEQUENCE OF` and `SET OF` constructs with 16384 items or more is now\n supported.\n\n Own Id: OTP-18245 Aux Id: ERIERL-859","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.18 - asn1 Release Notes","ref":"notes.html#asn1-5-0-18"},{"type":"extras","doc":"- Add support for the `maps` option in combination with the `jer` backend.\n\n Own Id: OTP-17959 Aux Id: GH-5757","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.17 - asn1 Release Notes","ref":"notes.html#asn1-5-0-17"},{"type":"extras","doc":"- A parameterized type with a SEQUENCE with extension (\"...\") made the compiler\n backend to crash. The previous fix for this in GH-4514 was not complete.\n\n Own Id: OTP-17522 Aux Id: GH-4902","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.16 - asn1 Release Notes","ref":"notes.html#asn1-5-0-16"},{"type":"extras","doc":"- Fixed a bug in the `asn1` compiler that potentially could cause it to fail to\n open a file.\n\n Own Id: OTP-17387 Aux Id: OTP-17123","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.15.1 - asn1 Release Notes","ref":"notes.html#asn1-5-0-15-1"},{"type":"extras","doc":"- A parameterized type with a SEQUENCE with extension (\"...\") made the compiler\n backend to crash. The previous fix for this in GH-4514 was not complete.\n\n Own Id: OTP-17522 Aux Id: GH-4902","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.15 - asn1 Release Notes","ref":"notes.html#asn1-5-0-15"},{"type":"extras","doc":"- A parameterized type with a SEQUENCE with extension (\"...\") made the compiler\n backend to crash.\n\n Own Id: OTP-17227 Aux Id: GH-4514\n\n- For JER encoding rules an INTEGER value outside the declared range is now\n reported as error during decode.\n\n Own Id: OTP-17306 Aux Id: ERIERL-506","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- For the JER encoding rules, the declared order of the fields in a SEQUENCE is\n now maintained in the resulting JSON object. Previously a map was used which\n caused an undefined order of the fields which was not friendly for debugging.\n\n Own Id: OTP-17297 Aux Id: ERIERL-607","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 5.0.14 - asn1 Release Notes","ref":"notes.html#asn1-5-0-14"},{"type":"extras","doc":"- Changes in order to build on the Haiku operating system.\n\n Thanks to Calvin Buckley\n\n Own Id: OTP-16707 Aux Id: PR-2638","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 5.0.13 - asn1 Release Notes","ref":"notes.html#asn1-5-0-13"},{"type":"extras","doc":"- Adhere to the ASN.1 specification for hstring & bstring lexical items. That is\n they may include white space.\n\n Own Id: OTP-16490","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Refactored the internal handling of deprecated and removed functions.\n\n Own Id: OTP-16469\n\n- Improve handling of ellipsis in a CHOICE\n\n Own Id: OTP-16554 Aux Id: ERL-1189","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 5.0.12 - asn1 Release Notes","ref":"notes.html#asn1-5-0-12"},{"type":"extras","doc":"- Dialyzer warnings of type `no_match` are now suppressed in the generated\n files.\n\n Own Id: OTP-16636 Aux Id: ERIERL-145","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 5.0.11 - asn1 Release Notes","ref":"notes.html#asn1-5-0-11"},{"type":"extras","doc":"- The compiler now has limited support for the JSON encoding rules (ITU-T X.697\n ASN.1 encoding rules: Specification of JavaScript Object Notation Encoding\n Rules).\n\n Own Id: OTP-16030","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 5.0.10 - asn1 Release Notes","ref":"notes.html#asn1-5-0-10"},{"type":"extras","doc":"- Fix 'DEFAULT' with 'OCTET STRING' and 'SEQUENCE OF CHOICE' with extensions.\n\n Own Id: OTP-16542 Aux Id: PR-2159","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 5.0.9 - asn1 Release Notes","ref":"notes.html#asn1-5-0-9"},{"type":"extras","doc":"- All incorrect (that is, all) uses of \"can not\" has been corrected to \"cannot\"\n in source code comments, documentation, examples, and so on.\n\n Own Id: OTP-14282 Aux Id: PR-1891\n\n- Corrected problems with the following value definitions:\n\n - value of SEQUENCE OF CHOICE with extensions\n - value of CHOICE with extensions\n - DEFAULT used with OCTET STRING\n\n Own Id: OTP-15697 Aux Id: PR-2159","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.8 - asn1 Release Notes","ref":"notes.html#asn1-5-0-8"},{"type":"extras","doc":"- Handle erroneous length during decode (BER only) without crashing.\n\n Own Id: OTP-15470 Aux Id: ERIERL-278","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.7 - asn1 Release Notes","ref":"notes.html#asn1-5-0-7"},{"type":"extras","doc":"- A bug in ASN.1 BER decoding has been fixed. When decoding a recursively\n enclosed term the length was not propagated to that term decoding, so if the\n length of the enclosed term was longer than the enclosing that error was not\n detected.\n\n A hard coded C stack limitation for decoding recursive ASN.1 terms has been\n introduced. This is currently set to 8 kWords giving a nesting depth of about\n 1000 levels. Deeper terms can not be decoded, which should not be much of a\n real world limitation.\n\n Own Id: OTP-14440 Aux Id: ERIERL-220","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.6 - asn1 Release Notes","ref":"notes.html#asn1-5-0-6"},{"type":"extras","doc":"- Update to use the new string api instead of the old.\n\n Own Id: OTP-15036","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 5.0.5.2 - asn1 Release Notes","ref":"notes.html#asn1-5-0-5-2"},{"type":"extras","doc":"- Handle erroneous length during decode (BER only) without crashing.\n\n Own Id: OTP-15470 Aux Id: ERIERL-278","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.5.1 - asn1 Release Notes","ref":"notes.html#asn1-5-0-5-1"},{"type":"extras","doc":"- A bug in ASN.1 BER decoding has been fixed. When decoding a recursively\n enclosed term the length was not propagated to that term decoding, so if the\n length of the enclosed term was longer than the enclosing that error was not\n detected\n\n A hard coded C stack limitation for decoding recursive ASN.1 terms has been\n introduced. This is currently set to 8 kWords giving a nesting depth of about\n 1000 levels. Deeper terms can not be decoded, which should not be much of a\n real world limitation.\n\n Own Id: OTP-14440 Aux Id: ERIERL-220","title":"Known Bugs and Problems - asn1 Release Notes","ref":"notes.html#known-bugs-and-problems"},{"type":"extras","doc":"","title":"Asn1 5.0.5 - asn1 Release Notes","ref":"notes.html#asn1-5-0-5"},{"type":"extras","doc":"- Dialyzer suppression has been added for the generated ASN.1 helper function\n to_bitstring/1 that previously created irrelevant warnings.\n\n Own Id: OTP-13882 Aux Id: ERIERL-144","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.4 - asn1 Release Notes","ref":"notes.html#asn1-5-0-4"},{"type":"extras","doc":"- There was a issue with BER encoding and the `undec_rest` option in generated\n decoders. An exception could be thrown instead of returning an error tuple.\n\n Own Id: OTP-14786 Aux Id: ERL-518\n\n- The asn1ct:test functions crashed on decoders generated with options\n `no_ok_wrapper`, `undec_rest`.\n\n Own Id: OTP-14787 Aux Id: ERL-518","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.3 - asn1 Release Notes","ref":"notes.html#asn1-5-0-3"},{"type":"extras","doc":"- Compiling an ASN.1 module using the option \\{n2n, EnumTypeName\\} when\n EnumTypeName contains a hyphen like for example Cause-Misc caused syntax\n errors when compiling the generated Erlang code. This is now corrected.\n\n Own Id: OTP-14495 Aux Id: ERL-437","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.2 - asn1 Release Notes","ref":"notes.html#asn1-5-0-2"},{"type":"extras","doc":"- Default values now work in extension for PER, so if you give the atom\n `asn1_DEFAULT` instead of a value it will become the default value.\n\n Own Id: OTP-13011 Aux Id: ERIERL-60","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0.1 - asn1 Release Notes","ref":"notes.html#asn1-5-0-1"},{"type":"extras","doc":"- Fixed compilation error of generated code caused by a missing quotation of\n function names as part of an external call for encoding.\n\n Own Id: OTP-14519 Aux Id: ERIERL-49","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 5.0 - asn1 Release Notes","ref":"notes.html#asn1-5-0"},{"type":"extras","doc":"- Add compile option `-compile(no_native)` in modules with `on_load` directive\n which is not yet supported by HiPE.\n\n Own Id: OTP-14316 Aux Id: PR-1390","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The `error` tuple returned from the `encode` and `decode` functions will now\n include the stack backtrace to make it easier to understand what went wrong.\n\n Own Id: OTP-13961\n\n- The deprecated module `asn1rt` has been removed. The deprecated functions\n `asn1ct:encode/3` and `asn1ct:decode/3` have been removed. The undocumented\n function `asn1ct:encode/2` has been removed.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-14146\n\n- The new '`maps`' option changes the representation of the types `SEQUENCE` and\n `SET` to be maps (instead of records).\n\n Own Id: OTP-14219","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 4.0.4 - asn1 Release Notes","ref":"notes.html#asn1-4-0-4"},{"type":"extras","doc":"- Compiling multiple ASN.1 modules in the same directory with parallel make\n (make -j) should now be safe.\n\n Own Id: OTP-13624","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 4.0.3 - asn1 Release Notes","ref":"notes.html#asn1-4-0-3"},{"type":"extras","doc":"- Internal changes\n\n Own Id: OTP-13551","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 4.0.2 - asn1 Release Notes","ref":"notes.html#asn1-4-0-2"},{"type":"extras","doc":"- When compiling to the PER format, the ASN.1 compiler would crash when\n attempting to compile an ASN.1 module with a constrained INTEGER with more\n than 65536 values and named values. (Thanks to Ingars for reporting this bug.)\n\n Own Id: OTP-13257\n\n- The ASN.1 compiler will now emit Dialyzer suppressions for improper lists.\n Thus, there is no longer any need to use `--Wno_improper_lists` when analyzing\n modules generated by the ASN.1 compiler.\n\n Own Id: OTP-13324","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 4.0.1 - asn1 Release Notes","ref":"notes.html#asn1-4-0-1"},{"type":"extras","doc":"- Trying to encode an empty named BIT STRING in BER would fail with a\n `function_clause` exception. (Thanks to Svilen Ivanov for reporting this bug.)\n\n Own Id: OTP-13149","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 4.0 - asn1 Release Notes","ref":"notes.html#asn1-4-0"},{"type":"extras","doc":"- Many bugs have been eliminated in the ASN.1 compiler so that it can now\n successfully compile many more ASN.1 specifications. Error messages have also\n been improved.\n\n Own Id: OTP-12395","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The documentation for `asn1ct:test/1,2,3` and `asn1ct:value/2` has been\n updated with information about the limitations of the functions.\n\n Own Id: OTP-12765 Aux Id: seq12866, seq12867","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 3.0.4 - asn1 Release Notes","ref":"notes.html#asn1-3-0-4"},{"type":"extras","doc":"- The ASN.1 compiler would crash if a SEQUENCE ended with a double set of\n ellipses (`...`).\n\n Own Id: OTP-12546 Aux Id: seq12815","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 3.0.3 - asn1 Release Notes","ref":"notes.html#asn1-3-0-3"},{"type":"extras","doc":"- When decoding BER, primitives with an indefinite length will be immediately\n rejected. (Thanks to Simon Cornish for reporting this bug.)\n\n Own Id: OTP-12205\n\n- BER: A bug with compliance to X.680 (200811) s31.2.7 has been fixed.\n Basically, when TagDefault is AUTOMATIC then tags are IMPLICIT unless EXPLICIT\n is given.\n\n Own Id: OTP-12318\n\n- Usage of the `EXTERNAL` 1994 variant type was broken.\n\n Own Id: OTP-12326","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 3.0.2 - asn1 Release Notes","ref":"notes.html#asn1-3-0-2"},{"type":"extras","doc":"- Several problems where the ASN.1 compiler would crash when attempting to\n compile correct specifications have been corrected.\n\n Own Id: OTP-12125\n\n- Robustness when decoding incorrect BER messages has been improved.\n\n Own Id: OTP-12145","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 3.0.1 - asn1 Release Notes","ref":"notes.html#asn1-3-0-1"},{"type":"extras","doc":"- The ASN.1 compiler now generates code that don't trigger Dialyzer warnings.\n Along the way, a few minor bugs were fixed.\n\n Own Id: OTP-11372 Aux Id: seq12397","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 3.0 - asn1 Release Notes","ref":"notes.html#asn1-3-0"},{"type":"extras","doc":"- Subtyping an extensible ENUMERATED would cause an compilation error. (Thanks\n to Morten Nygaard Åsnes for reporting this bug.)\n\n Own Id: OTP-11700\n\n- When specifying the value for an OCTET STRING in a specification, the ASN.1\n standard clearly states that the value must be either a bstring or an hstring,\n but NOT a cstring. The ASN.1 compiler will now generate a compilation error if\n the value of an OCTET STRING is given as a character string.\n\n That is, the following example is now illegal:\n\n `string OCTET STRING ::= \"Now illegal\"`\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-11727\n\n- Application upgrade (appup) files are corrected for the following\n applications:\n\n `asn1, common_test, compiler, crypto, debugger, dialyzer, edoc, eldap, erl_docgen, et, eunit, gs, hipe, inets, observer, odbc, os_mon, otp_mibs, parsetools, percept, public_key, reltool, runtime_tools, ssh, syntax_tools, test_server, tools, typer, webtool, wx, xmerl`\n\n A new test utility for testing appup files is added to test_server. This is\n now used by most applications in OTP.\n\n (Thanks to Tobias Schlager)\n\n Own Id: OTP-11744","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- By giving --enable-static-\\{nifs,drivers\\} to configure it is now possible to\n statically linking of nifs and drivers to the main Erlang VM binary. At the\n moment only the asn1 and crypto nifs of the Erlang/OTP nifs and drivers have\n been prepared to be statically linked. For more details see the Installation\n Guide in the System documentation.\n\n Own Id: OTP-11258\n\n- Code generation for the `per` and `uper` backends has been somewhat improved.\n\n Own Id: OTP-11573\n\n- The OCTET STRING and BIT STRING types now have a more natural mapping to\n Erlang types (binary and bitstring, respectively), which is more efficient and\n will avoid useless conversions between lists and binaries/bitstrings.\n\n This is an incompatible change. To revert to the old mapping to support\n existing applications, use the `legacy_erlang_types` option.\n\n Impact: There is a potential for better performance, as it is now possible to\n avoid conversions between lists and binaries both in the generated ASN.1\n encode/decode code and in the application itself.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-11594\n\n- All functions in the `asn1rt` module, as well as `asn1ct:decode/3` and\n `asn1ct:encode/3`, are now deprecated.\n\n Own Id: OTP-11731\n\n- Generated .hrl files are now protected from being included more than once.\n\n Own Id: OTP-11804","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 2.0.4 - asn1 Release Notes","ref":"notes.html#asn1-2-0-4"},{"type":"extras","doc":"- The default value for a `BIT STRING` would not always be recognized, causing\n the encoding to be incorrect for the DER/PER/UPER encodings.\n\n Own Id: OTP-11319\n\n- The ASN.1 application would fail to build if the `.erlang` file printed\n something to standard output.\n\n Own Id: OTP-11360\n\n- An union of integer ranges in an INTEGER constraint could sometimes be\n interpreted as the intersection of the range.\n\n Own Id: OTP-11411 Aux Id: seq12443\n\n- Extensible, multiple single value constraints (such as `INTEGER (1|17, ...)`)\n would be incorrectly encoded.\n\n Own Id: OTP-11415\n\n- The ASN.1 compiler would fail to compile a constraint with values given for\n the extension part (such as `INTEGER (1..10, ..., 11..20)`).\n\n Own Id: OTP-11504","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The new option '`no_ok_wrapper`' generates M:encode/2 and M:decode/2 functions\n that don't wrap the return value in an \\{ok,...\\} tuple.\n\n Own Id: OTP-11314","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 2.0.3 - asn1 Release Notes","ref":"notes.html#asn1-2-0-3"},{"type":"extras","doc":"- Open types greater than 16383 bytes will now be correctly encoded and decoded.\n\n Own Id: OTP-11262 Aux Id: seq12386, OTP-11223","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- For the PER and UPER formats, code generation especially for encoding has been\n improved.\n\n When encoding BIT STRINGs, values longer than the maximum size for the BIT\n STRING type would be truncated silently - they now cause an exception.\n\n Open types greater than 16383 bytes will now be correctly encoded and decoded.\n\n IMPORTANT NOTE: For ASN.1 specifications that depend on each other, such as\n the S1AP-\\* specifications, it is important to recompile all specifications\n (compiling some with this version of the compiler and some with an older\n version will not work).\n\n Own Id: OTP-11300","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 2.0.2 - asn1 Release Notes","ref":"notes.html#asn1-2-0-2"},{"type":"extras","doc":"- Fix some Makefile rules that didn't support silent rules. Thanks to Anthony\n Ramine.\n\n Own Id: OTP-11111\n\n- PER/UPER: A semi-constrained INTEGER with a non-zero lower bound would be\n incorrectly decoded. This bug was introduced in R16.\n\n PER/UPER: Given `INTEGER (10..MAX, ...)`, attempting to decode any integer\n below 10 would cause the encoder to enter an infinite loop.\n\n PER/UPER: For a type with an extensible SIZE constraint, sizes outside of the\n root range were incorrectly encoded.\n\n Given a constraint such as `(SIZE (5, ...))`, encoding a size less than 5\n would fail (PER/UPER). Similarly, for BER decoding would fail.\n\n PER: The encoder did not align a known multiplier string (such as IA5String)\n of length 16 bits (exactly) to an octet boundary.\n\n In rare circumstances, DEFAULT values for the UPER backend could be wrongly\n encoded.\n\n Own Id: OTP-11134\n\n- UPER: The compiler would crash when compiling an ENUMERATED having more than\n 63 extended values.\n\n PER/UPER: A SEQUENCE with more 64 extended values could not be decoded.\n\n Own Id: OTP-11153\n\n- When decoding a SEQUENCE defined inline inside a an extension addition group,\n the record named generated by the decoding code would not match the name in\n the generated .hrl file.\n\n Own Id: OTP-11154 Aux Id: seq12339","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Postscript files no longer needed for the generation of PDF files have been\n removed.\n\n Own Id: OTP-11016","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 2.0.1.2 - asn1 Release Notes","ref":"notes.html#asn1-2-0-1-2"},{"type":"extras","doc":"- When an object set is an actual parameter, the extension marker for the object\n set could get lost (which would cause the decoding of unknown values to fail).\n\n Own Id: OTP-10995 Aux Id: seq12290","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 2.0.1.1 - asn1 Release Notes","ref":"notes.html#asn1-2-0-1-1"},{"type":"extras","doc":"- The generated decoder for the 'per' and 'uper' backends did not correctly\n decode ENUMERATEDs with a single value.\n\n The generated encoder for the 'per' and 'uper' backends generated an empty\n binary for a top-level type that did not need to be encoded (such as an\n ENUMERATED with a single value). The correct result should be a binary\n containing a 0 byte.\n\n Own Id: OTP-10916 Aux Id: seq12270","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 2.0.1 - asn1 Release Notes","ref":"notes.html#asn1-2-0-1"},{"type":"extras","doc":"- Fixed broken table constraints within a SET OF or SEQUENCE OF for the BER\n backend.\n\n Own Id: OTP-10853 Aux Id: seq12245","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 2.0 - asn1 Release Notes","ref":"notes.html#asn1-2-0"},{"type":"extras","doc":"- Encoding SEQUENCEs with multiple extension addition groups with optional\n values could fail (depending both on the specification and whether all values\n were provided).\n\n Own Id: OTP-10664","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The options for the ASN.1 compiler has been drastically simplified. The\n backend is chosen by using `ber`, `per`, or `uper`. The options `optimize`,\n `nif`, and `driver` are no longer needed. The old options will still work, but\n will issue a warning.\n\n Another change is that generated `encode/2` function will always return a\n binary (some backends used to return an iolist).\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-10410 Aux Id: kunagi-254 \\[165]\n\n- The ASN.1 compiler generates faster decode functions for PER and UPER. Some\n minor improvements have also been made for PER/UPER encoding, and to the BER\n backend.\n\n Own Id: OTP-10519 Aux Id: kunagi-322 \\[233]\n\n- The ASN.1 compiler will now always include necessary run-time functions in the\n generated Erlang modules (except for `asn1rt_nif` which is still needed). If\n the option '`inline`' is used the ASN.1 compiler will generate a warning. But\n if '`{inline,OutputFile}`' is use, the ASN.1 compiler will refuse to compile\n the file. (Use a `.set.asn` file if you need to remove the output file.)\n\n The '`BIT STRING`' type will now be decoded as Erlang bitstrings by default.\n Use the new `legacy_bit_string` option to encode as lists of ones and zeroes.\n (The `compact_bit_string` option still works as before.)\n\n Open types are now always returned as binaries (when there is no information\n allowing them to be decoded).\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-10588 Aux Id: kunagi-341 \\[252]","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.8.1 - asn1 Release Notes","ref":"notes.html#asn1-1-8-1"},{"type":"extras","doc":"- ASN.1 decoders generated with the options `-bber_bin +optimize +nif` would\n decode open types with a size larger than 511 incorrectly. That bug could\n cause decoding by `public_key` to fail. The bug was in the NIF library\n `asn1_erl_nif.so`; therefore there is no need re-compile ASN.1 specifications\n that had the problem.\n\n Own Id: OTP-10805 Aux Id: seq12244\n\n- Encoding SEQUENCEs with multiple extension addition groups with optional\n values could fail (depending both on the specification and whether all values\n were provided).\n\n Own Id: OTP-10811 Aux Id: OTP-10664","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 1.8 - asn1 Release Notes","ref":"notes.html#asn1-1-8"},{"type":"extras","doc":"- Encoding and decoding of integer ranges can now be done with an upper bound\n larger than the previous limit of 16^10. The new upper bound in per encoding\n and decodings for constrained whole numbers is 2^2040 (close to 16^508)\n\n Own Id: OTP-10128\n\n- Per encoding/decoding now works correctly for single value subtyping of an\n integer type where a subtype is a predefined value. Previously a predefined\n value could cause a non-valid range-check in the generated Erlang code for per\n encoding/decoding due to a bug in the constraint checking.\n\n Own Id: OTP-10139\n\n- Fix typo error in selected decode function (Thanks to Artem Teslenko)\n\n Own Id: OTP-10152\n\n- Better error indication when detecting unexpected tags during decoding of BER\n encoded data.\n\n Own Id: OTP-10186\n\n- asn1rt_check: Fix transform_to_EXTERNAL1990 for binary input (Thanks to Harald\n Welte)\n\n Own Id: OTP-10233","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add support for multiple ExtensionAdditionGroups\n\n Own Id: OTP-10058\n\n- Add support for extensible enumeration types in n2n generated functions.\n\n Own Id: OTP-10144","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.7 - asn1 Release Notes","ref":"notes.html#asn1-1-7"},{"type":"extras","doc":"- Some ASN.1 INTEGER type and SEQUENCE constructor variants previously not\n handled by the ASN.1 compiler are now correctly handled\n\n Own Id: OTP-9688\n\n- An INTEGER with a value constraint where unions are used e.g. X1 ::= INTEGER\n (1..4 | 6 | 8 | 10 | 20) is not handled correctly. For PER the value is\n encoded in wrong number of bits.\n\n Own Id: OTP-9946","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.6.19 - asn1 Release Notes","ref":"notes.html#asn1-1-6-19"},{"type":"extras","doc":"- The linked-in driver used for ber decode and per encode has been replaced with\n nifs. To enable the usage of nifs pass the nif option to erlc or\n asn1rt:compile when compiling. If you previously used the linked-in driver,\n you have to recompile your ASN1 modules with the current version of asn1\n application as the linked-in driver modules have been removed.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-9419\n\n- A few of the heavy calculations which are done for encoding and decoding\n operations when dealing with SEQUENCE OF and DEFAULT in runtime have been\n moved to be done in compile time instead.\n\n Own Id: OTP-9440\n\n- When compiling an ASN.1 ber module with the +nif option, the module will use a\n new nif for ber encoding, increasing performance by about 5%.\n\n Own Id: OTP-9441\n\n- Tuple funs (a two-element tuple with a module name and a function) are now\n officially deprecated and will be removed in R16. Use '`fun M:F/A`' instead.\n To make you aware that your system uses tuple funs, the very first time a\n tuple fun is applied, a warning will be sent to the error logger.\n\n Own Id: OTP-9649","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.6.18 - asn1 Release Notes","ref":"notes.html#asn1-1-6-18"},{"type":"extras","doc":"- Implement or fix -Werror option\n\n If -Werror is enabled and there are warnings no output file is written. Also\n make sure that error/warning reporting is consistent. (Thanks to Tuncer Ayaz)\n\n Own Id: OTP-9536","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 1.6.17 - asn1 Release Notes","ref":"notes.html#asn1-1-6-17"},{"type":"extras","doc":"- Test cases which started failing when timer:tc was changed to not catch are\n corrected.\n\n Own Id: OTP-9286\n\n- The bounds checking in the asn1_erl_driver when the length value of a TLV is a\n Long Definite Length is corrected. Thanks to Vance Shipley.\n\n Own Id: OTP-9303","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 1.6.16 - asn1 Release Notes","ref":"notes.html#asn1-1-6-16"},{"type":"extras","doc":"- asn1ct: Make formatting of errors and warnings consistent\n\n Consistently format warning and error reports. Warning and error options from\n erlc now also work in asnc1ct. (thanks to Tuncer Ayaz)\n\n Own Id: OTP-9062\n\n- Shut off some dialyzer warnings\n\n Own Id: OTP-9063","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Crash in asn1ct_check, componentrelation_leadingattr fixed. (Thanks to\n Stephane Pamelard for finding the bug)\n\n Own Id: OTP-9092","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.6.15 - asn1 Release Notes","ref":"notes.html#asn1-1-6-15"},{"type":"extras","doc":"- The encoding of ExtensionAdditionGroup (for PER and UPER) is corrected.\n\n Own Id: OTP-8866 Aux Id: OTP-8797, SEQ-11557\n\n- A race condition when several processes in parallel start to do encode/decode\n using the driver could cause an error log regarding crashing port owner\n process. This race is now eliminated.\n\n Own Id: OTP-8948 Aux Id: seq11733","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 1.6.14.1 - asn1 Release Notes","ref":"notes.html#asn1-1-6-14-1"},{"type":"extras","doc":"- Extension Addition Groups are now supported by the parser and in all backends.\n\n Own Id: OTP-8598 Aux Id: seq-11557\n\n- Extension Addition Groups are now supported in nested types within a SEQUENCE\n and CHOICE as well (missed that in previous fix)\n\n Own Id: OTP-8797 Aux Id: seq-11557","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Bug in UNALIGNED PER regarding encoding and decoding of constrained numbers\n with a valuerange > 1024. (Thanks to Vincent de Phily)\n\n Own Id: OTP-8779\n\n- Minor corrections in the User Guide.\n\n Own Id: OTP-8829","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.6.14 - asn1 Release Notes","ref":"notes.html#asn1-1-6-14"},{"type":"extras","doc":"- By default, the ASN.1 compiler is now silent in the absence of warnings or\n errors. The new '`verbose`' option or the '`-v`' option for `erlc` can be\n given to show extra information (for instance, about the files that are\n generated). (Thanks to Tuncer Ayaz.)\n\n Own Id: OTP-8565","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.6.13 - asn1 Release Notes","ref":"notes.html#asn1-1-6-13"},{"type":"extras","doc":"- Harmless buffer overflow by one byte in asn1 and ram_file_drv.\n\n Own Id: OTP-8451","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Cross compilation improvements and other build system improvements.\n\n Most notable:\n\n - Lots of cross compilation improvements. The old cross compilation support\n was more or less non-existing as well as broken. Please, note that the cross\n compilation support should still be considered as experimental. Also note\n that old cross compilation configurations cannot be used without\n modifications. For more information on cross compiling Erlang/OTP see the\n `$ERL_TOP/INSTALL-CROSS.md` file.\n - Support for staged install using\n [DESTDIR](http://www.gnu.org/prep/standards/html_node/DESTDIR.html). The old\n broken `INSTALL_PREFIX` has also been fixed. For more information see the\n `$ERL_TOP/INSTALL.md` file.\n - Documentation of the `release` target of the top `Makefile`. For more\n information see the `$ERL_TOP/INSTALL.md` file.\n - `make install` now by default creates relative symbolic links instead of\n absolute ones. For more information see the `$ERL_TOP/INSTALL.md` file.\n - `$ERL_TOP/configure --help=recursive` now works and prints help for all\n applications with `configure` scripts.\n - Doing `make install`, or `make release` directly after `make all` no longer\n triggers miscellaneous rebuilds.\n - Existing bootstrap system is now used when doing `make install`, or\n `make release` without a preceding `make all`.\n - The `crypto` and `ssl` applications use the same runtime library path when\n dynamically linking against `libssl.so` and `libcrypto.so`. The runtime\n library search path has also been extended.\n - The `configure` scripts of `erl_interface` and `odbc` now search for thread\n libraries and thread library quirks the same way as ERTS do.\n - The `configure` script of the `odbc` application now also looks for odbc\n libraries in `lib64` and `lib/64` directories when building on a 64-bit\n system.\n - The `config.h.in` file in the `erl_interface` application is now\n automatically generated in instead of statically updated which reduces the\n risk of `configure` tests without any effect.\n\n (Thanks to Henrik Riomar for suggestions and testing)\n\n (Thanks to Winston Smith for the AVR32-Linux cross configuration and testing)\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-8323\n\n- Add support for prefixing macro names generated by the compiler\n\n This is useful when multiple protocols that contains macros with identical\n names are included in a single module.\n\n Add the missing `record_name_prefix` compiler option to the documentation.\n\n Own Id: OTP-8453\n\n- Cleanups suggested by tidier and modernization of types and specs.\n\n Own Id: OTP-8455\n\n- Support for `EXTENSIBILITY IMPLIED` and `SET/SEQ OF NamedType` is added.\n\n Own Id: OTP-8463","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.6.12 - asn1 Release Notes","ref":"notes.html#asn1-1-6-12"},{"type":"extras","doc":"- The documentation is now built with open source tools (xsltproc and fop) that\n exists on most platforms. One visible change is that the frames are removed.\n\n Own Id: OTP-8256","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.6.11 - asn1 Release Notes","ref":"notes.html#asn1-1-6-11"},{"type":"extras","doc":"- A new option `{n2n,TypeName}` can be used to enable generation of conversion\n functions from name to number and vice versa for selected ENUMERATION types.\n The option can be repeated many times in order to specify several types in the\n same file. \n If the `TypeName` specified does not exists or is not an ENUMERATION type, the\n compilation will be terminated with an error code. \n Below follows an example on how to use the option from the command line with\n `erlc`: \n `erlc -bper+\"{n2n,'CauseMisc'}\" +\"{n2n,'CausePcl'}\" MyModyle.asn`\n\n Own Id: OTP-8136 Aux Id: seq11347\n\n- Range checks added for BIT STRING with fixed SIZE constraint.\n\n Own Id: OTP-7972 Aux Id: seq11280\n\n- Now support multiple-line comments in asn1-specs as specified in ASN1 X.680\n (07/2002), section 11.6.4\n\n Own Id: OTP-8043\n\n- Now parses and adds abstract syntax for PATTERN subtype constraint. No other\n action is taken on this type of constraint.\n\n Own Id: OTP-8046\n\n- The ASN1 subtype constraint `CONTAINING Type`,\n `CONTAINING Type ENCODED BY Value` and `ENCODED BY Value` now is parsed.\n Abstract syntax is added but no further action in generated code is taken.\n\n Own Id: OTP-8047","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.6.10 - asn1 Release Notes","ref":"notes.html#asn1-1-6-10"},{"type":"extras","doc":"- A faulty receive case that catch-ed all messages in the initialization of the\n driver has been removed, the initialization has been restructured.\n\n Own Id: OTP-7954 Aux Id: seq11220","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The anonymous part of the decode that splits the ASN1 TLV into Tag Value\n tuples has been optimized.\n\n Own Id: OTP-7953","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.6.9 - asn1 Release Notes","ref":"notes.html#asn1-1-6-9"},{"type":"extras","doc":"- Error that caused crash when drivers were loaded is now corrected. Parallel\n driver for asn1 now enabled.\n\n Own Id: OTP-7904 Aux Id: seq11220","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Optimized code for ENUMERATION type in encoder/decoder.\n\n Own Id: OTP-7909","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.6.8.1 - asn1 Release Notes","ref":"notes.html#asn1-1-6-8-1"},{"type":"extras","doc":"- Removed parallel-driver functionality due to failure when loading the driver.\n\n Own Id: OTP-7900 Aux Id: seq11220","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Generated code now uses guards that is not obsolete, e.g.\n [`is_integer/1`](`is_integer/1`) instead of `integer/1`.\n\n Own Id: OTP-7910","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.6.8 - asn1 Release Notes","ref":"notes.html#asn1-1-6-8"},{"type":"extras","doc":"- A BIT STRING with a size constraint that has a single value and an extension\n as in `BIT STRING (SIZE (16,...))` was erroneous encoded/decoded. This is now\n corrected and follows X.691 Section 15.6.\n\n Own Id: OTP-7876 Aux Id: seq11220","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 1.6.7 - asn1 Release Notes","ref":"notes.html#asn1-1-6-7"},{"type":"extras","doc":"- Now asn1 starts multiple drivers to enable simultaneous encode/decode in\n different processes for the asn1-backends using linked-in driver.\n\n Own Id: OTP-7801","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.6.6 - asn1 Release Notes","ref":"notes.html#asn1-1-6-6"},{"type":"extras","doc":"- Decode of an open_type when the value was empty tagged type encoded with\n indefinite length failed. This is now corrected.\n\n Own Id: OTP-7759 Aux Id: seq11166\n\n- Encode of BIT STRING with size of exact length, on compact_bit_string format\n in UNALIGNED PER failed when value had the right size, i.e. no padding needed.\n\n Own Id: OTP-7763 Aux Id: seq11182","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 1.6.5 - asn1 Release Notes","ref":"notes.html#asn1-1-6-5"},{"type":"extras","doc":"- For a BIT STRING with SIZE constraint higher than 255 compiled with\n `[per_bin,optimize, compact_bit_string]` an improper io-list was created and\n sent to the c-driver for complete encoding. This error has been resolved.\n\n Own Id: OTP-7734 Aux Id: seq11170","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 1.6.4 - asn1 Release Notes","ref":"notes.html#asn1-1-6-4"},{"type":"extras","doc":"- A a SEQUENCE OF with a type that is a CHOICE with ellipses occurred falsely a\n compile error. The error causing that is now removed.\n\n Own Id: OTP-7708 Aux Id: seq11136","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 1.6.3 - asn1 Release Notes","ref":"notes.html#asn1-1-6-3"},{"type":"extras","doc":"- constrained number with a value-range greater than 512 now has the proper\n interpretation of the values that causes shift to the next number of units\n (bits), According to limit condition `2^m < \"range\" =< 2^(m + 1)` then the\n number of bits are m + 1.\n\n Own Id: OTP-7681 Aux Id: seq11114","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Can now handle default values of simple types that is provided on its own\n format, i.e. not just as asn1_DEFAULT.\n\n Own Id: OTP-7678 Aux Id: seq11114","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.6.2 - asn1 Release Notes","ref":"notes.html#asn1-1-6-2"},{"type":"extras","doc":"- comparison of two value definitions failed due to new module name field in\n valuedef record. It is now corrected.\n\n Own Id: OTP-7608","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Asn1 1.6.1 - asn1 Release Notes","ref":"notes.html#asn1-1-6-1"},{"type":"extras","doc":"- Bug regarding propagation of parameters of parameterized type fixed.\n\n Own Id: OTP-7174 Aux Id: seq10864\n\n- A bug, related to instantiation of a parameterized type with a type definition\n in the parameter-list, has been removed. The definition of the parameter type\n was in another module than the instance definition causing limited module\n info.\n\n Own Id: OTP-7299 Aux Id: seq10864\n\n- Removed hard-coded name that may cause name collision.\n\n Own Id: OTP-7322 Aux Id: seq10864\n\n- Object set of a class with id with properties UNIQUE OPTIONAL and the id field\n is lacking in the object is for now treated as a object without a unique\n identifier, i.e. no table is generated for this object.\n\n Own Id: OTP-7332 Aux Id: seq10864\n\n- Compiler crashed when failed to handle a OID as ValueFromObject.\n\n Own Id: OTP-7476 Aux Id: seq10999\n\n- A corrupted encoding may cause a loop when a buffer of at least two bytes of\n zero matches tag and length of a SET component. This behavior occurred only\n with decoder generated with `ber` or `ber_bin` options. Now a control breaks\n the loop.\n\n Own Id: OTP-7533\n\n- Encode of BIT STRING longer than 255 bits with a `SIZE(integer())` constraint\n caused a crash when spec was compiled with `per_bin, optimize` options.\n\n Own Id: OTP-7602 Aux Id: seq11079","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Now supports REAL type of base 2 and 10\n\n Own Id: OTP-7166 Aux Id: seq10864\n\n- By the asn1 compiler option `{record_name_prefix Name}` a prefix is chosen to\n the name of the record generated in the .hrl and used in the generated .erl\n files.\n\n Own Id: OTP-7204 Aux Id: seq10853\n\n- The TypeFromObject production now covered\n\n Own Id: OTP-7295 Aux Id: seq10468\n\n- Extended support for ObjectSetFromObjects. Production occurred as a part of\n the RootElementSetSpec of the ObjectSetSpec. Added also support for Exclusion\n of Element in ObjectSetSpec.\n\n Own Id: OTP-7306 Aux Id: seq10864\n\n- Now implements RELATIVE-OID\n\n Own Id: OTP-7334 Aux Id: seq10864","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.6 - asn1 Release Notes","ref":"notes.html#asn1-1-6"},{"type":"extras","doc":"- Now is ordering, according to the canonical order, of components in a SET\n added. Canonical order is described in X.691 9.2 and X.680 8.6\n\n Own Id: OTP-7375 Aux Id: unaligned PER\n\n- The precedence rules for extended constraints have been misinterpreted. The\n rule says for instance that if there are more than one constraint on a type\n that have extension-mark, only the last of the extension-marks would be kept.\n This affects the encoding of PER and is now corrected.\n\n Own Id: OTP-7400 Aux Id: OTP-7335\n\n- A constrained number with a single-value constraint that is extensible was\n falsely encoded/decoded in aligned/unaligned PER. This is now corrected.\n\n Own Id: OTP-7403","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The ASN.1 compiler has got a new backend supporting PER UNALIGNED. Previously\n it was only support for PER ALIGNED.\n\n Own Id: OTP-7335\n\n- Now the asn1-compiler handles unions and intersections of PermittedAlphabet\n constraints.\n\n Own Id: OTP-7374 Aux Id: unaligned PER\n\n- With the undocumented option `no_final_padding` the whole encoded message is\n not padded to a border of a byte. Thus the returned encoded message is a\n `bitstring`.\n\n Own Id: OTP-7407","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.5.2 - asn1 Release Notes","ref":"notes.html#asn1-1-5-2"},{"type":"extras","doc":"- When duplicates of object fields were removed only one table access function\n for each unique identifier value was generated. This can occur when several\n object sets are merged by use of ObjectSetFromObjects.\n\n Own Id: OTP-7263 Aux Id: seq10864\n\n- DER: For some complex types and components with reference to type in several\n steps the default value check function was not generated. This is now fixed.\n\n Own Id: OTP-7268 Aux Id: seq10684\n\n- Now is the tag in a tagged type as parameter propagated to the instance.\n\n Own Id: OTP-7273 Aux Id: seq10864","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Added type T61String that is similar to TeletexString\n\n Own Id: OTP-7264 Aux Id: seq10864","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.5.1 - asn1 Release Notes","ref":"notes.html#asn1-1-5-1"},{"type":"extras","doc":"- A bug related to renaming of types has been fixed.This occurred using the\n .set.asn functionality.\n\n Own Id: OTP-7149 Aux Id: seq10853\n\n- syntax error in ASN1 value now correctly shown\n\n Own Id: OTP-7154 Aux Id: seq10864\n\n- Now a COMPONENTS OF construct in a parameterized type is expanded correctly\n\n Own Id: OTP-7155 Aux Id: seq10864\n\n- Now the asn1-compiler also handles empty SEQUENCE DEFAULT values as `{}`.\n\n Own Id: OTP-7169 Aux Id: seq10864\n\n- Now SelectionType gets the tag of the selected type.\n\n Own Id: OTP-7171 Aux Id: seq10864\n\n- Correction of generated code for decode of an open type in a SEQUECNE OF/ SET\n OF\n\n Own Id: OTP-7193 Aux Id: seq10875","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Misc improvements and bug corrections regarding default values.\n\n Own Id: OTP-7199 Aux Id: seq10864","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.5 - asn1 Release Notes","ref":"notes.html#asn1-1-5"},{"type":"extras","doc":"- Now generating records in .hrl file for instances of parameterized SEQUENCE or\n SET.\n\n Own Id: OTP-6835\n\n- Optimization using bitstr in encode/decode functions. Active with\n `[per_bin, optimize]` options.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-6882","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.4.6 - asn1 Release Notes","ref":"notes.html#asn1-1-4-6"},{"type":"extras","doc":"- Parsing and encoding/decoding of type constrained with SIZE with extension is\n now recovered.\n\n Own Id: OTP-6763\n\n- `inline` failed because trying to use a removed module.\n\n Own Id: OTP-6769\n\n- Fixed problem with a reference to a type from an object. The failure was\n caused bye change of type name when using `inline` option.\n\n Own Id: OTP-6770\n\n- Handling of decode pattern for exclusive decode was false in the case when an\n un-decoded component had more than one following elements that should be\n decoded.\n\n Own Id: OTP-6786","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Now the asn1-compiler supports two root lists in SEQUENCE and SET according to\n alternative three in ComponentTypeLists (X.680 07/2002 section 24.1), i.e.\n with an extension list between two ellipses.\n\n Own Id: OTP-5067 Aux Id: seq8452","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Asn1 1.4.5 - asn1 Release Notes","ref":"notes.html#asn1-1-4-5"},{"type":"extras","doc":"- Merging modules by `inline` earlier disabled the driver (used in modules\n generated with \\[optimized]/\\[optimized,driver] options). Now this is\n repaired.\n\n Own Id: OTP-6601\n\n- Checking phase now aware of which module an INSTANCE OF is declared in.\n\n Own Id: OTP-6702","title":"Fixed Bugs and Malfunctions - asn1 Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The compiler now handle all forms of ObjectSetSpec according to ITU-T\n recommendation X.681 (ISO/IEC 8824-2:2002).\n\n Own Id: OTP-6698\n\n- Enhanced support of referencing object sets by ObjectSetFromObjects.\n\n Own Id: OTP-6707\n\n- Support for parameterized object in an object set.\n\n Own Id: OTP-6717","title":"Improvements and New Features - asn1 Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"\n# Introduction\n\nThe `asn1` application provides the following:\n\n- An ASN.1 compiler for Erlang, which generates encode and decode functions to\n be used by Erlang programs sending and receiving ASN.1-specified data.\n- Runtime functions used by the generated code.\n- Support for the following encoding rules:\n - Basic Encoding Rules (BER)\n - Distinguished Encoding Rules (DER), a specialized form of BER that is used\n in security-conscious applications\n - Packed Encoding Rules (PER), both the aligned and unaligned variant\n - JSON Encoding Rules (JER)","title":"Introduction","ref":"asn1_introduction.html"},{"type":"extras","doc":"This application covers all features of ASN.1 up to the 1997 edition of the\nspecification. In the 2002 edition, new features were introduced. The following\nfeatures of the 2002 edition are fully or partly supported:\n\n- Decimal notation (for example, `\"1.5e3`) for REAL values. The NR1, NR2, and\n NR3 formats as explained in ISO 6093 are supported.\n- The `RELATIVE-OID` type for relative object identifiers is fully supported.\n- The subtype constraint (`CONTAINING`/`ENCODED BY`) to constrain the content of\n an octet string or a bit string is parsed when compiling, but no further\n action is taken. This constraint is not a PER-visible constraint.\n- The subtype constraint by regular expressions (`PATTERN`) for character string\n types is parsed when compiling, but no further action is taken. This\n constraint is not a PER-visible constraint.\n- Multiple-line comments as in C, `/* ... */`, are supported.","title":"Scope - Introduction","ref":"asn1_introduction.html#scope"},{"type":"extras","doc":"It is assumed that the reader is familiar with the Erlang programming language,\nconcepts of OTP, and is familiar with the ASN.1 notation. The ASN.1 notation is\ndocumented in the standard definition X.680, which is the primary text. It can\nalso be helpful, but not necessary, to read the standard definitions X.681,\nX.682, X.683, X.690, and X.691.\n\nA good book explaining those reference texts is Dubuisson: ASN.1 - Communication\nBetween Heterogeneous Systems, is free to download at\n[http://www.oss.com/asn1/dubuisson.html](http://www.oss.com/asn1/dubuisson.html).","title":"Prerequisites - Introduction","ref":"asn1_introduction.html#prerequisites"},{"type":"extras","doc":"\n# ASN.1","title":"ASN.1","ref":"asn1_overview.html"},{"type":"extras","doc":"ASN.1 is a formal language for describing data structures to be exchanged\nbetween distributed computer systems. The purpose of ASN.1 is to have a platform\nand programming language independent notation to express types using a\nstandardized set of rules for the transformation of values of a defined type\ninto a stream of bytes. This stream of bytes can then be sent on any type of\ncommunication channel. This way, two applications written in different\nprogramming languages running on different computers, and with different\ninternal representation of data, can exchange instances of structured data\ntypes.","title":"Introduction - ASN.1","ref":"asn1_overview.html#introduction"},{"type":"extras","doc":"\n# Getting Started","title":"Getting Started","ref":"asn1_getting_started.html"},{"type":"extras","doc":"The following example demonstrates the basic functionality used to run the\nErlang ASN.1 compiler.\n\nCreate a file named `People.asn` containing the following:\n\n```text\nPeople DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\n Person ::= SEQUENCE {\n name PrintableString,\n location INTEGER {home(0),field(1),roving(2)},\n age INTEGER OPTIONAL\n }\nEND\n```\n\nThis file must be compiled before it can be used. The ASN.1 compiler checks that\nthe syntax is correct and that the text represents proper ASN.1 code before\ngenerating an abstract syntax tree. The code generator then uses the abstract\nsyntax tree to generate code.\n\nThe generated Erlang files are placed in the current directory or in the\ndirectory specified with option `{outdir,Dir}`.\n\nThe compiler can be called from the Erlang shell like this:\n\n```erlang\n1> asn1ct:compile(\"People\", [ber]).\nok\n```\n\nOption `verbose` can be added to get information about the generated files:\n\n```erlang\n2> asn1ct:compile(\"People\", [ber,verbose]).\nErlang ASN.1 compiling \"People.asn\"\n--{generated,\"People.asn1db\"}--\n--{generated,\"People.hrl\"}--\n--{generated,\"People.erl\"}--\nok\n```\n\nASN.1 module `People` is now accepted and the abstract syntax tree is saved in\nfile `People.asn1db`. The generated Erlang code is compiled using the Erlang\ncompiler and loaded into the Erlang runtime system. There is now an API for\n`encode/2` and `decode/2` in module `People`, which is called like this:\n\n```\n'People':encode( , )\n```\n\nor:\n\n```\n'People':decode( , )\n```\n\nAssume that there is a network application that receives instances of the ASN.1\ndefined type `Person`, modifies, and sends them back again:\n\n```erlang\nreceive\n {Port,{data,Bytes}} ->\n case 'People':decode('Person',Bytes) of\n {ok,P} ->\n {ok,Answer} = 'People':encode('Person',mk_answer(P)),\n Port ! {self(),{command,Answer}};\n {error,Reason} ->\n exit({error,Reason})\n end\n end,\n```\n\nIn this example, a series of bytes is received from an external source and the\nbytes are then decoded into a valid Erlang term. This was achieved with the call\n`'People':decode('Person',Bytes)`, which returned an Erlang value of the ASN.1\ntype `Person`. Then an answer was constructed and encoded using\n`'People':encode('Person',Answer)`, which takes an instance of a defined ASN.1\ntype and transforms it to a binary according to the BER or PER encoding rules.\n\nThe encoder and decoder can also be run from the shell:\n\n```erlang\n2> Rockstar = {'Person',\"Some Name\",roving,50}.\n{'Person',\"Some Name\",roving,50}\n3> {ok,Bin} = 'People':encode('Person',Rockstar).\n{ok,<<243,17,19,9,83,111,109,101,32,78,97,109,101,2,1,2,\n 2,1,50>>}\n4> {ok,Person} = 'People':decode('Person',Bin).\n{ok,{'Person',\"Some Name\",roving,50}}\n```","title":"Example - Getting Started","ref":"asn1_getting_started.html#example"},{"type":"extras","doc":"It is common that ASN.1 modules import defined types, values, and other entities\nfrom another ASN.1 module.\n\nEarlier versions of the ASN.1 compiler required that modules that were imported\nfrom had to be compiled before the module that imported. This caused problems\nwhen ASN.1 modules had circular dependencies.\n\nReferenced modules are now parsed when the compiler finds an entity that is\nimported. No code is generated for the referenced module. However, the compiled\nmodules rely on that the referenced modules are also compiled.","title":"Module Dependencies - Getting Started","ref":"asn1_getting_started.html#module-dependencies"},{"type":"extras","doc":"The `ASN.1` application provides the following two separate user interfaces:\n\n- The module `asn1ct`, which provides the compile-time functions (including the\n compiler)\n- The module `asn1rt_nif`, which provides the runtime functions for the ASN.1\n decoder for the BER back end\n\nThe reason for this division of the interfaces into compile-time and runtime is\nthat only runtime modules (`asn1rt_nif`) need to be loaded in an embedded system.","title":"ASN.1 Application User Interface - Getting Started","ref":"asn1_getting_started.html#asn-1-application-user-interface"},{"type":"extras","doc":"The ASN.1 compiler can be started directly from the command line by the `erlc`\nprogram. This is convenient when compiling many ASN.1 files from the command\nline or when using Makefiles. Here some examples showing of how `erlc` can\ncompile ASN.1 modules:\n\n```text\nerlc Person.asn\nerlc -bper Person.asn\nerlc -bber ../Example.asn\nerlc -o ../asnfiles -I ../asnfiles -I /usr/local/standards/asn1 Person.asn\n```\n\nUseful options for the ASN.1 compiler:\n\n- **`-b[ber | per | uper | jer]`** - Choice of encoding rules. If omitted, `ber`\n is the default.\n\n- **`-o OutDirectory`** - Where to put the generated files. Default is the\n current directory.\n\n- **`-I IncludeDir`** - Where to search for `.asn1db` files and ASN.1 source\n specs to resolve references to other modules. This option can be repeated many\n times if there are several places to search in. The compiler searches the\n current directory first.\n\n- **`+der`** - DER encoding rule. Only when using option `-bber`.\n\n- **`+jer`** - Functions `jer_encode/2` and `jer_decode/2` for JSON encoding\n rules are generated together with functions for `ber` or `per`. Only to be\n used when the main encoding option is `-bber`, `-bper` or `-buper`.\n\n- **`+maps`** - Use maps instead of records to represent the `SEQUENCE` and\n `SET` types. No `.hrl` files will be generated. See the section\n [Map representation for SEQUENCE and SET](asn1_getting_started.md#MAP_SEQ_SET)\n for more information.\n\n- **`+asn1config`** - This functionality works together with option `ber`. It\n enables the specialized decodes, see section\n [Specialized Decode](asn1_spec.md).\n\n- **`+undec_rest`** - A buffer that holds a message being decoded can also have\n trailing bytes. If those trailing bytes are important, they can be returned\n along with the decoded value by compiling the ASN.1 specification with option\n `+undec_rest`. The return value from the decoder is `{ok,Value,Rest}` where\n `Rest` is a binary containing the trailing bytes.\n\n- **`+'Any Erlc Option'`** - Any option can be added to the Erlang compiler when\n compiling the generated Erlang files. Any option unrecognized by the ASN.1\n compiler is passed to the Erlang compiler.\n\nFor a complete description of `erlc`, see ERTS Reference Manual.\n\nThe compiler and other compile-time functions can also be started from the\nErlang shell. Here follows a brief description of the primary functions. For a\ncomplete description of each function, see module `asn1ct` in the\n[ASN.1 Reference Manual](`m:asn1ct`).\n\nThe compiler is started by `asn1ct:compile/1` with default options, or\n`asn1ct:compile/2` if explicit options are given.\n\nExample:\n\n```text\nasn1ct:compile(\"H323-MESSAGES\").\n```\n\nThis is equivalent to:\n\n```text\nasn1ct:compile(\"H323-MESSAGES\", [ber]).\n```\n\nIf PER encoding is wanted:\n\n```text\nasn1ct:compile(\"H323-MESSAGES\", [per]).\n```\n\nThe generic encode and decode functions can be called as follows:\n\n```text\n'H323-MESSAGES':encode('SomeChoiceType', {call,<<\"octetstring\">>}).\n'H323-MESSAGES':decode('SomeChoiceType', Bytes).\n```","title":"Compile-Time Functions - Getting Started","ref":"asn1_getting_started.html#compile-time-functions"},{"type":"extras","doc":"When an ASN.1 specification is compiled with option `ber`, the `asn1rt_nif`\nmodule and the NIF library in `asn1/priv_dir` are needed at runtime.\n\nBy calling function `info/0` in a generated module, you get information about\nwhich compiler options were used.","title":"Runtime Functions - Getting Started","ref":"asn1_getting_started.html#runtime-functions"},{"type":"extras","doc":"Errors detected at compile-time are displayed on the screen together with line\nnumbers indicating where in the source file the respective error was detected.\nIf no errors are found, an Erlang ASN.1 module is created.\n\nThe runtime encoders and decoders execute within a `catch` and return `{ok, Data}`\nor `{error, {asn1, Description}}` where `Description` is an Erlang term\ndescribing the error.\n\nCurrently, `Description` looks like this: `{ErrorDescription, StackTrace}`.\nApplications should not depend on the exact contents of `Description` as it\ncould change in the future.","title":"Errors - Getting Started","ref":"asn1_getting_started.html#errors"},{"type":"extras","doc":"There are various reasons for using multi-file compilation:\n\n- To choose the name for the generated module, for example, because you need to\n compile the same specs for different encoding rules.\n- You want only one resulting module.\n\nSpecify which ASN.1 specs to compile in a module with extension `.set.asn`.\nChoose a module name and provide the names of the ASN.1 specs. For example, if\nyou have the specs `File1.asn`, `File2.asn`, and `File3.asn`, your module\n`MyModule.set.asn` looks as follows:\n\n```text\nFile1.asn\nFile2.asn\nFile3.asn\n```\n\nIf you compile with the following, the result is one merged module\n`MyModule.erl` with the generated code from the three ASN.1 specs:\n\n```text\n% erlc MyModule.set.asn\n```","title":"Multi-File Compilation - Getting Started","ref":"asn1_getting_started.html#multi-file-compilation"},{"type":"extras","doc":"Tags used to be important for all users of ASN.1, because it was necessary to\nto manually add tags to certain constructs in order for the ASN.1 specification to\nbe valid. Example of an old-style specification:\n\n```erlang\nTags DEFINITIONS ::=\nBEGIN\n Afters ::= CHOICE { cheese [0] IA5String,\n dessert [1] IA5String }\nEND\n```\n\nWithout the tags (the numbers in square brackets) the ASN.1 compiler refused to\ncompile the file.\n\nIn 1994 the global tagging mode `AUTOMATIC TAGS` was introduced. By putting\n`AUTOMATIC TAGS` in the module header, the ASN.1 compiler automatically adds\ntags when needed. The following is the same specification in `AUTOMATIC TAGS`\nmode:\n\n```erlang\nTags DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\n Afters ::= CHOICE { cheese IA5String,\n dessert IA5String }\nEND\n```\n\n[](){: #ASN1Types }","title":"Note about tags - Getting Started","ref":"asn1_getting_started.html#note-about-tags"},{"type":"extras","doc":"This section describes the ASN.1 types including their functionality, purpose,\nand how values are assigned in Erlang.\n\nASN.1 has both primitive and constructed types:\n\n| _Primitive Types_ | _Constructed Types_ |\n| -------------------------------------------------------------- | ------------------------------------------------------------ |\n| [BOOLEAN](asn1_getting_started.md#boolean) | [SEQUENCE](asn1_getting_started.md#sequence) |\n| [INTEGER](asn1_getting_started.md#integer) | [SET](asn1_getting_started.md#set) |\n| [REAL](asn1_getting_started.md#real) | [CHOICE](asn1_getting_started.md#choice) |\n| [NULL](asn1_getting_started.md#null) | [SET OF and SEQUENCE OF](asn1_getting_started.md#SOF) |\n| [ENUMERATED](asn1_getting_started.md#enumerated) | [ANY](asn1_getting_started.md#ANY) |\n| [BIT STRING](asn1_getting_started.md#bit-string) | [ANY DEFINED BY](asn1_getting_started.md#ANY) |\n| [OCTET STRING](asn1_getting_started.md#octet-string) | [EXTERNAL](asn1_getting_started.md#NegotiationTypes) |\n| [Character Strings](asn1_getting_started.md#character-strings) | [EMBEDDED PDV](asn1_getting_started.md#NegotiationTypes) |\n| [OBJECT IDENTIFIER](asn1_getting_started.md#object-identifier) | [CHARACTER STRING](asn1_getting_started.md#NegotiationTypes) |\n| [Object Descriptor](asn1_getting_started.md#object-descriptor) | |\n| [TIME Types](asn1_getting_started.md#The-TIME-types) | |\n\n_Table: Supported ASN.1 Types_\n\n[](){: #TypeNameValue }\n\n> #### Note {: .info }\n>\n> The values of each ASN.1 type have their own representation in Erlang, as\n> described in the following sections. Users must provide these values for\n> encoding according to the representation, as shown in the following example:\n\n```text\nOperational ::= BOOLEAN --ASN.1 definition\n```\n\nIn Erlang code it can look as follows:\n\n```erlang\nVal = true,\n{ok,Bytes} = MyModule:encode('Operational', Val),\n```","title":"ASN.1 Types - Getting Started","ref":"asn1_getting_started.html#asn-1-types"},{"type":"extras","doc":"Booleans in ASN.1 express values that can be either `TRUE` or `FALSE`. The\nmeanings assigned to `TRUE` and `FALSE` are outside the scope of this text.\n\nIn ASN.1 it is possible to have:\n\n```text\nOperational ::= BOOLEAN\n```\n\nAssigning a value to type `Operational` in Erlang is possible by using the\nfollowing Erlang code:\n\n```erlang\nMyvar1 = true,\n```\n\nThus, in Erlang the atoms `true` and `false` are used to encode a boolean value.","title":"BOOLEAN - Getting Started","ref":"asn1_getting_started.html#boolean"},{"type":"extras","doc":"An ASN.1 INTEGER is represented by an integer in Erlang.\n\nThe concept of subtyping can be applied to integers and to other ASN.1 types.\nThe details of subtyping are not explained here; for more information, see\nX.680. Various syntaxes are allowed when defining a type as an integer:\n\n```erlang\nT1 ::= INTEGER\nT2 ::= INTEGER (-2..7)\nT3 ::= INTEGER (0..MAX)\nT4 ::= INTEGER (0<..MAX)\nT5 ::= INTEGER (MIN<..-99)\nT6 ::= INTEGER {red(0),blue(1),white(2)}\n```\n\nThe Erlang representation of an ASN.1 `INTEGER` is an integer or an atom if a\n`Named Number List` (see `T6` in the previous list) is specified.\n\nThe following is an example of Erlang code that assigns values for the types in\nthe previous list:\n\n```erlang\nT1value = 0,\nT2value = 6,\nT6value1 = blue,\nT6value2 = 0,\nT6value3 = white\n```\n\nThese Erlang variables are now bound to valid instances of ASN.1 defined types.\nThis style of value can be passed directly to the encoder for transformation\ninto a series of bytes.\n\nThe decoder returns an atom if the value corresponds to a symbol in the\n`Named Number List`.","title":"INTEGER - Getting Started","ref":"asn1_getting_started.html#integer"},{"type":"extras","doc":"The following ASN.1 type is used for real numbers:\n\n```text\nR1 ::= REAL\n```\n\nIt is assigned a value in Erlang as follows:\n\n```text\nR1value1 = \"2.14\",\nR1value2 = {256,10,-2},\n```\n\nIn the last line, notice that the tuple \\{256,10,-2\\} is the real number 2.56 in\na special notation, which encodes faster than simply stating the number as\n`\"2.56\"`. The arity three tuple is `{Mantissa,Base,Exponent}`, that is,\nMantissa \\* Base^Exponent.","title":"REAL - Getting Started","ref":"asn1_getting_started.html#real"},{"type":"extras","doc":"The type `NULL` is suitable where supply and recognition of a value is important\nbut the actual value is not.\n\n```text\nNotype ::= NULL\n```\n\nThis type is assigned in Erlang as follows:\n\n```text\nN1 = 'NULL',\n```\n\nThe actual value is the quoted atom `'NULL'`.","title":"NULL - Getting Started","ref":"asn1_getting_started.html#null"},{"type":"extras","doc":"The type `ENUMERATED` can be used when the value you want to describe can only\ntake one of a set of predefined values. Example:\n\n```text\nDaysOfTheWeek ::= ENUMERATED {\n sunday(1),monday(2),tuesday(3),\n wednesday(4),thursday(5),friday(6),saturday(7) }\n```\n\nFor example, to assign a weekday value in Erlang, use the same atom as in the\n`Enumerations` of the type definition:\n\n```text\nDay1 = saturday,\n```\n\nThe enumerated type is similar to an integer type, when defined with a set of\npredefined values. The difference is that an enumerated type can only have\nspecified values, whereas an integer can have any value.","title":"ENUMERATED - Getting Started","ref":"asn1_getting_started.html#enumerated"},{"type":"extras","doc":"The type `BIT STRING` can be used to model information that is made up of\narbitrary length series of bits. It is intended to be used for selection of\nflags, not for binary files.\n\nIn ASN.1, `BIT STRING` definitions can look as follows:\n\n```erlang\nBits1 ::= BIT STRING\nBits2 ::= BIT STRING {foo(0),bar(1),gnu(2),gnome(3),punk(14)}\n```\n\nThe following two notations are available for representation of `BIT STRING`\nvalues in Erlang and as input to the encode functions:\n\n1. A bitstring. By default, a `BIT STRING` with no symbolic names is decoded to\n an Erlang bitstring.\n1. A list of atoms corresponding to atoms in the `NamedBitList` in the\n `BIT STRING` definition. A `BIT STRING` with symbolic names is always decoded\n to the format shown in the following example:\n\n```text\nBits1Val1 = <<0:1,1:1,0:1,1:1,1:1>>,\nBits2Val1 = [gnu,punk],\nBits2Val2 = <<2#1110:4>>,\nBits2Val3 = [bar,gnu,gnome],\n```\n\n`Bits2Val2` and `Bits2Val3` denote the same value.\n\n`Bits2Val1` is assigned symbolic values. The assignment means that the bits\ncorresponding to `gnu` and `punk`, that is, bits 2 and 14 are set to 1, and the\nrest are set to 0. The symbolic values are shown as a list of values. If a named\nvalue, which is not specified in the type definition, is shown, a runtime error\noccurs.\n\n`BIT STRING`s can also be subtyped with, for example, a `SIZE` specification:\n\n```text\nBits3 ::= BIT STRING (SIZE(0..31))\n```\n\nThis means that no bit higher than 31 can be set.\n\n#### Deprecated Representations for BIT STRING\n\nIn addition to the representations described earlier, the following deprecated\nrepresentations are available if the specification has been compiled with option\n`legacy_erlang_types`:\n\n1. Aa a list of binary digits (0 or 1). This format is accepted as input to the\n encode functions, and a `BIT STRING` is decoded to this format if option\n `legacy_bit_string` is given.\n1. As `{Unused,Binary}` where `Unused` denotes how many trailing zero-bits 0-7\n that are unused in the least significant byte in `Binary`. This format is\n accepted as input to the encode functions, and a `BIT STRING` is decoded to\n this format if `compact_bit_string` has been given.\n1. As a hexadecimal number (or an integer). Avoid this as it is easy to\n misinterpret a `BIT STRING` value in this format.","title":"BIT STRING - Getting Started","ref":"asn1_getting_started.html#bit-string"},{"type":"extras","doc":"`OCTET STRING` is the simplest of all ASN.1 types. `OCTET STRING` only moves or\ntransfers, for example, binary files or other unstructured information complying\nwith two rules: the bytes consist of octets and encoding is not required.\n\nIt is possible to have the following ASN.1 type definitions:\n\n```erlang\nO1 ::= OCTET STRING\nO2 ::= OCTET STRING (SIZE(28))\n```\n\nWith the following example assignments in Erlang:\n\n```text\nO1Val = <<17,13,19,20,0,0,255,254>>,\nO2Val = <<\"must be exactly 28 chars....\">>,\n```\n\nBy default, an `OCTET STRING` is always represented as an Erlang binary. If the\nspecification has been compiled with option `legacy_erlang_types`, the encode\nfunctions accept both lists and binaries, and the decode functions decode an\n`OCTET STRING` to a list.","title":"OCTET STRING - Getting Started","ref":"asn1_getting_started.html#octet-string"},{"type":"extras","doc":"ASN.1 supports a wide variety of character sets. The main difference between an\n`OCTET STRING` and a character string is that the `OCTET STRING` has no imposed\nsemantics on the bytes delivered.\n\nHowever, when using, for example, `IA5String` (which closely resembles ASCII),\nbyte 65 (in decimal notation) _means_ character 'A'.\n\nFor example, if a defined type is to be a VideotexString and an octet is\nreceived with the unsigned integer value `X`, the octet is to be interpreted as\nspecified in standard ITU-T T.100, T.101.\n\nThe ASN.1 compiler does not determine the correct interpretation of\neach BER string octet value with different character strings. The application is\nresponsible for interpretation of octets. Therefore, from the BER string point\nof view, octets are very similar to character strings and are compiled in the\nsame way.\n\nWhen PER is used, there is a significant difference in the encoding scheme\nfor `OCTET STRING`s and other strings. The constraints specified for a type\nare especially important for PER, because they affect the encoding.\n\nExamples:\n\n```erlang\nDigs ::= NumericString (SIZE(1..3))\nTextFile ::= IA5String (SIZE(0..64000))\n```\n\nThe corresponding Erlang assignments:\n\n```c\nDigsVal1 = \"456\",\nDigsVal2 = \"123\",\nTextFileVal1 = \"abc...xyz...\",\nTextFileVal2 = [88,76,55,44,99,121 .......... a lot of characters here ....]\n```\n\nThe Erlang representation for `BMPString` and `UniversalString` is either a list\nof ASCII values or a list of quadruples. The quadruple representation associates\nto the Unicode standard representation of characters. The ASCII characters are\nall represented by quadruples beginning with three zeros like `{0,0,0,65}` for\ncharacter 'A'. When decoding a value for these strings, the result is a list of\nquadruples, or integers when the value is an ASCII character.\n\nThe following example shows how it works. Assume the following specification is\nin file `PrimStrings.asn1`:\n\n```text\nPrimStrings DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\n BMP ::= BMPString\nEND\n```\n\nEncoding and decoding some strings:\n\n```erlang\n1> asn1ct:compile('PrimStrings', [ber]).\nok\n2> {ok,Bytes1} = 'PrimStrings':encode('BMP', [{0,0,53,53},{0,0,45,56}]).\n{ok,<<30,4,53,54,45,56>>}\n3> 'PrimStrings':decode('BMP', Bytes1).\n{ok,[{0,0,53,53},{0,0,45,56}]}\n4> {ok,Bytes2} = 'PrimStrings':encode('BMP', [{0,0,53,53},{0,0,0,65}]).\n{ok,<<30,4,53,53,0,65>>}\n5> 'PrimStrings':decode('BMP', Bytes2).\n{ok,[{0,0,53,53},65]}\n6> {ok,Bytes3} = 'PrimStrings':encode('BMP', \"BMP string\").\n{ok,<<30,20,0,66,0,77,0,80,0,32,0,115,0,116,0,114,0,105,0,110,0,103>>}\n7> 'PrimStrings':decode('BMP', Bytes3).\n{ok,\"BMP string\"}\n```\n\nType `UTF8String` is represented as a UTF-8 encoded binary in Erlang. Such\nbinaries can be created directly using the binary syntax or by converting from a\nlist of Unicode code points using function `unicode:characters_to_binary/1`.\n\nThe following shows examples of how UTF-8 encoded binaries can be created and\nmanipulated:\n\n```erlang\n1> Gs = \"Мой маленький Гном\".\n[1052,1086,1081,32,1084,1072,1083,1077,1085,1100,1082,1080,\n 1081,32,1043,1085,1086,1084]\n2> Gbin = unicode:characters_to_binary(Gs).\n<<208,156,208,190,208,185,32,208,188,208,176,208,187,208,\n 181,208,189,209,140,208,186,208,184,208,185,32,208,147,\n 208,...>>\n3> Gbin = <<\"Мой маленький Гном\"/utf8>>.\n<<208,156,208,190,208,185,32,208,188,208,176,208,187,208,\n 181,208,189,209,140,208,186,208,184,208,185,32,208,147,\n 208,...>>\n4> Gs = unicode:characters_to_list(Gbin).\n[1052,1086,1081,32,1084,1072,1083,1077,1085,1100,1082,1080,\n 1081,32,1043,1085,1086,1084]\n```\n\nFor details, see the `m:unicode` module in STDLIB.\n\nIn the following example, this ASN.1 specification is used:\n\n```text\nUTF DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\n UTF ::= UTF8String\nEND\n```\n\nEncoding and decoding a string with Unicode characters:\n\n```erlang\n5> asn1ct:compile('UTF', [ber]).\nok\n6> {ok,Bytes1} = 'UTF':encode('UTF', <<\"Гном\"/utf8>>).\n{ok,<<12,8,208,147,208,189,208,190,208,188>>}\n7> {ok,Bin1} = 'UTF':decode('UTF', Bytes1).\n{ok,<<208,147,208,189,208,190,208,188>>}\n8> io:format(\"~ts\\n\", [Bin1]).\nГном\nok\n9> unicode:characters_to_list(Bin1).\n[1043,1085,1086,1084]\n```","title":"Character Strings - Getting Started","ref":"asn1_getting_started.html#character-strings"},{"type":"extras","doc":"The type `OBJECT IDENTIFIER` is used whenever a unique identity is required. An\nASN.1 module, a transfer syntax, and so on, is identified with an\n`OBJECT IDENTIFIER`. Assume the following example:\n\n```erlang\nOid ::= OBJECT IDENTIFIER\n```\n\nTherefore, the following example is a valid Erlang instance of type `Oid`:\n\n```text\nOidVal1 = {1,2,55},\n```\n\nThe `OBJECT IDENTIFIER` value is a tuple with the consecutive integer values.\n\nThe first value is limited to the values 0, 1, or 2. The second value must be in\nthe range 0 through 39 when the first value is 0 or 1.\n\nThe `OBJECT IDENTIFIER` is an important type and it is widely used within\ndifferent standards to identify various objects uniquely. Dubuisson: _ASN.1 -\nCommunication Between Heterogeneous Systems_ includes an easy-to-understand\ndescription of the use of `OBJECT IDENTIFIER`.","title":"OBJECT IDENTIFIER - Getting Started","ref":"asn1_getting_started.html#object-identifier"},{"type":"extras","doc":"Values of this type can be assigned a value as an ordinary string as follows:\n\n```text\n\"This is the value of an Object descriptor\"\n```\n\n[](){: #The-TIME-types }","title":"Object Descriptor - Getting Started","ref":"asn1_getting_started.html#object-descriptor"},{"type":"extras","doc":"Two time types are defined within ASN.1: Generalized Time and Universal Time\nCoordinated (UTC). Both are assigned a value as an ordinary string within double\nquotes, for example, `\"19820102070533.8\"`.\n\nFor DER encoding, the compiler does not check the validity of the time values.\nThe DER requirements upon those strings are regarded as a matter for the\napplication to fulfill.","title":"TIME Types - Getting Started","ref":"asn1_getting_started.html#time-types"},{"type":"extras","doc":"The structured types of ASN.1 are constructed from other types in a manner\nsimilar to the concepts of arrays and structs in C.\n\nA `SEQUENCE` in ASN.1 is comparable with a struct in C and a record in Erlang. A\n`SEQUENCE` can be defined as follows:\n\n```erlang\nPdu ::= SEQUENCE {\n a INTEGER,\n b REAL,\n c OBJECT IDENTIFIER,\n d NULL }\n```\n\nThis is a 4-component structure called `Pdu`. By default, a `SEQUENCE` is\nrepresented by a record in Erlang. It can also be represented as a map; see\n[Map representation for SEQUENCE and SET](asn1_getting_started.md#MAP_SEQ_SET).\nFor each `SEQUENCE` and `SET` in an ASN.1 module an Erlang record declaration is\ngenerated. For `Pdu`, a record like the following is defined:\n\n```erlang\n-record('Pdu', {a, b, c, d}).\n```\n\nThe record declarations for a module `M` are placed in a separate `M.hrl` file.\n\nValues can be assigned in Erlang as follows:\n\n```erlang\nMyPdu = #'Pdu'{a=22,b=77.99,c={0,1,2,3,4},d='NULL'}.\n```\n\nThe decode functions return a record as result when decoding a `SEQUENCE` or a\n`SET`.\n\nA `SEQUENCE` and a `SET` can contain a component with a `DEFAULT` keyword\nfollowed by the actual value, which is the default value. The `DEFAULT` keyword\nmeans that the application doing the encoding can omit encoding of the value,\nwhich results in fewer bytes to send to the receiving application.\n\nAn application can use the atom `asn1_DEFAULT` to indicate that the encoding is\nto be omitted for that position in the `SEQUENCE`.\n\nDepending on the encoding rules, the encoder can also compare the given value to\nthe default value and automatically omit the encoding if the values are equal.\nHow much effort the encoder makes to compare the values depends on the encoding\nrules. The DER encoding rules forbid encoding a value equal to the default\nvalue, so it has a more thorough and time-consuming comparison than the encoders\nfor the other encoding rules.\n\nIn the following example, this ASN.1 specification is used:\n\n```text\nFile DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\nSeq1 ::= SEQUENCE {\n a INTEGER DEFAULT 1,\n b Seq2 DEFAULT {aa TRUE, bb 15}\n}\n\nSeq2 ::= SEQUENCE {\n aa BOOLEAN,\n bb INTEGER\n}\n\nSeq3 ::= SEQUENCE {\n bs BIT STRING {a(0), b(1), c(2)} DEFAULT {a, c}\n}\nEND\n```\n\nExample where the BER encoder is able to omit encoding of the default values:\n\n```erlang\n1> asn1ct:compile('File', [ber]).\nok\n2> 'File':encode('Seq1', {'Seq1',asn1_DEFAULT,asn1_DEFAULT}).\n{ok,<<48,0>>}\n3> 'File':encode('Seq1', {'Seq1',1,{'Seq2',true,15}}).\n{ok,<<48,0>>}\n```\n\nExample with a named `BIT STRING` where the BER encoder does not omit the\nencoding:\n\n```erlang\n4> 'File':encode('Seq3', {'Seq3',asn1_DEFAULT).\n{ok,<<48,0>>}\n5> 'File':encode('Seq3', {'Seq3',<<16#101:3>>).\n{ok,<<48,4,128,2,5,160>>}\n```\n\nThe DER encoder omits the encoding for the same `BIT STRING`:\n\n```erlang\n6> asn1ct:compile('File', [ber,der]).\nok\n7> 'File':encode('Seq3', {'Seq3',asn1_DEFAULT).\n{ok,<<48,0>>}\n8> 'File':encode('Seq3', {'Seq3',<<16#101:3>>).\n{ok,<<48,0>>}\n```","title":"SEQUENCE - Getting Started","ref":"asn1_getting_started.html#sequence"},{"type":"extras","doc":"In Erlang, the `SET` type is used exactly as `SEQUENCE`. Notice that if BER or\nDER encoding rules are used, decoding a `SET` is slower than decoding a\n`SEQUENCE` because the components must be sorted.","title":"SET - Getting Started","ref":"asn1_getting_started.html#set"},{"type":"extras","doc":"When a `SEQUENCE` or `SET` contains an extension marker and extension components\nas the following, the type can get more components in newer versions of the\nASN.1 spec:\n\n```text\nSExt ::= SEQUENCE {\n a INTEGER,\n ...,\n b BOOLEAN }\n```\n\nIn this case it has got a new component `b`. Thus, incoming messages that are\ndecoded can have more or fever components than this one.\n\nThe component `b` is treated as an original component when encoding a message.\nIn this case, as it is not an optional element, it must be encoded.\n\nDuring decoding, the `b` field of the record gets the decoded value of the `b`\ncomponent, if present, otherwise the value `asn1_NOVALUE`.\n\n[](){: #MAP_SEQ_SET }","title":"Extensibility for SEQUENCE and SET - Getting Started","ref":"asn1_getting_started.html#extensibility-for-sequence-and-set"},{"type":"extras","doc":"If the ASN.1 module has been compiled with option `maps`, the types `SEQUENCE`\nand `SET` are represented as maps.\n\nIn the following example, this ASN.1 specification is used:\n\n```text\nFile DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\nSeq1 ::= SEQUENCE {\n a INTEGER DEFAULT 42,\n b BOOLEAN OPTIONAL,\n c IA5String\n}\nEND\n```\n\nOptional fields are to be omitted from the map if they have no value:\n\n```erlang\n1> asn1ct:compile('File', [per,maps]).\nok\n2> {ok,E} = 'File':encode('Seq1', #{a=>0,c=>\"string\"}).\n{ok,<<128,1,0,6,115,116,114,105,110,103>>}\n```\n\nWhen decoding, optional fields will be omitted from the map:\n\n```erlang\n3> 'File':decode('Seq1', E).\n{ok,#{a => 0,c => \"string\"}}\n```\n\nDefault values can be omitted from the map:\n\n```erlang\n4> {ok,E2} = 'File':encode('Seq1', #{c=>\"string\"}).\n{ok,<<0,6,115,116,114,105,110,103>>}\n5> 'File':decode('Seq1', E2).\n{ok,#{a => 42,c => \"string\"}}\n```\n\n> #### Note {: .info }\n>\n> It is not allowed to use the atoms `asn1_VALUE` and `asn1_DEFAULT` with maps.","title":"Map representation for SEQUENCE and SET - Getting Started","ref":"asn1_getting_started.html#map-representation-for-sequence-and-set"},{"type":"extras","doc":"The type `CHOICE` is a space saver and is similar to the concept of union in\nC.\n\nAssume the following:\n\n```text\nSomeModuleName DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\nT ::= CHOICE {\n x REAL,\n y INTEGER,\n z OBJECT IDENTIFIER }\nEND\n```\n\nIt is then possible to assign values as follows:\n\n```erlang\nTVal1 = {y,17},\nTVal2 = {z,{0,1,2}},\n```\n\nA `CHOICE` value is always represented as the tuple `{ChoiceAlternative, Val}`\nwhere `ChoiceAlternative` is an atom denoting the selected choice alternative.\n\n#### Extensible CHOICE\n\nWhen a `CHOICE` contains an extension marker and the decoder detects an unknown\nalternative of the `CHOICE`, the value is represented as follows:\n\n```text\n{asn1_ExtAlt, BytesForOpenType}\n```\n\nHere `BytesForOpenType` is a list of bytes constituting the encoding of the\n\"unknown\" `CHOICE` alternative.\n\n[](){: #SOF }","title":"CHOICE - Getting Started","ref":"asn1_getting_started.html#choice"},{"type":"extras","doc":"The types `SET OF` and `SEQUENCE OF` correspond to the concept of an array in\nseveral programming languages. The Erlang syntax for both types is\nstraightforward, for example:\n\n```text\nArr1 ::= SET SIZE (5) OF INTEGER (4..9)\nArr2 ::= SEQUENCE OF OCTET STRING\n```\n\nIn Erlang the following can apply:\n\n```text\nArr1Val = [4,5,6,7,8],\nArr2Val = [\"abc\",[14,34,54],\"Octets\"],\n```\n\nNotice that the definition of type `SET OF` implies that the order of the\ncomponents is undefined, but in practice there is no difference between `SET OF`\nand `SEQUENCE OF`. The ASN.1 compiler for Erlang does not randomize the order of\nthe `SET OF` components before encoding.\n\nHowever, for a value of type `SET OF`, the DER encoding format requires the\nelements to be sent in ascending order of their encoding, which implies an\nexpensive sorting procedure in runtime. Therefore it is recommended to use\n`SEQUENCE OF` instead of `SET OF` if possible.\n\n[](){: #ANY }","title":"SET OF and SEQUENCE OF - Getting Started","ref":"asn1_getting_started.html#set-of-and-sequence-of"},{"type":"extras","doc":"The types `ANY` and `ANY DEFINED BY` have been removed from the standard\nsince 1994. It is recommended not to use these types any more. They can,\nhowever, exist in some old ASN.1 modules. The idea with this type was to leave a\n\"hole\" in a definition where it was possible to put unspecified data of any\nkind, even non-ASN.1 data.\n\nA value of this type is encoded as an `open type`.\n\nInstead of `ANY` and `ANY DEFINED BY`, it is recommended to use\ninformation object classes, table constraints, and parameterization. In\nparticular the construct `TYPE-IDENTIFIER.@Type` accomplishes the same as the\ndeprecated `ANY`.\n\nAlso see [Information objects](asn1_getting_started.md#Information-Object).\n\n[](){: #NegotiationTypes }","title":"ANY and ANY DEFINED BY - Getting Started","ref":"asn1_getting_started.html#any-and-any-defined-by"},{"type":"extras","doc":"The types `EXTERNAL`, `EMBEDDED PDV`, and `CHARACTER STRING` are used in\npresentation layer negotiation. They are encoded according to their associated\ntype, see X.680.\n\nThe type `EXTERNAL` had a slightly different associated type before 1994. X.691\nstates that encoding must follow the older associated type. So, generated\nencode/decode functions convert values of the newer format to the older format\nbefore encoding. This implies that it is allowed to use `EXTERNAL` type values\nof either format for encoding. Decoded values are always returned in the newer\nformat.","title":"EXTERNAL, EMBEDDED PDV, and CHARACTER STRING - Getting Started","ref":"asn1_getting_started.html#external-embedded-pdv-and-character-string"},{"type":"extras","doc":"The structured types previously described can have other named types as their\ncomponents. The general syntax to assign a value to component `C` of a named\nASN.1 type `T` in Erlang is the record syntax `#'T'{'C'=Value}`. Here `Value`\ncan be a value of yet another type `T2`, for example:\n\n```text\nEmbeddedExample DEFINITIONS AUTOMATIC TAGS ::=\nBEGIN\nB ::= SEQUENCE {\n a Arr1,\n b T }\n\nArr1 ::= SET SIZE (5) OF INTEGER (4..9)\n\nT ::= CHOICE {\n x REAL,\n y INTEGER,\n z OBJECT IDENTIFIER }\n END\n```\n\n`SEQUENCE` `b` can be encoded as follows in Erlang:\n\n```erlang\n1> 'EmbeddedExample':encode('B', {'B',[4,5,6,7,8],{x,\"7.77\"}}).\n{ok,<<5,56,0,8,3,55,55,55,46,69,45,50>>}\n```","title":"Embedded Named Types - Getting Started","ref":"asn1_getting_started.html#embedded-named-types"},{"type":"extras","doc":"When the option `maps` is given, no `.hrl` files will be generated. The rest of\nthis section describes the behavior of the compiler when `maps` is not used.\n\nWhen an ASN.1 specification is compiled, all defined types of type `SET` or\n`SEQUENCE` result in a corresponding record in the generated `.hrl` file. This\nis because the values for `SET` and `SEQUENCE` are represented as records by\ndefault.\n\nSome special cases of this functionality are presented in the next section.","title":"Naming of Records in .hrl Files - Getting Started","ref":"asn1_getting_started.html#naming-of-records-in-hrl-files"},{"type":"extras","doc":"In ASN.1 it is also possible to have components that are themselves structured\ntypes. For example, it is possible to have the following:\n\n```text\nEmb ::= SEQUENCE {\n a SEQUENCE OF OCTET STRING,\n b SET {\n a INTEGER,\n b INTEGER DEFAULT 66},\n c CHOICE {\n a INTEGER,\n b FooType } }\n\nFooType ::= [3] VisibleString\n```\n\nThe following records are generated because of type `Emb`:\n\n```erlang\n-record('Emb,{a, b, c}).\n-record('Emb_b',{a, b = asn1_DEFAULT}). % the embedded SET type\n```\n\nValues of type `Emb` can be assigned as follows:\n\n```erlang\nV = #'Emb'{a=[\"qqqq\",[1,2,255]],\n b = #'Emb_b'{a=99},\n c ={b,\"Can you see this\"}}.\n```\n\nFor an embedded type of type `SEQUENCE`/`SET` in a `SEQUENCE`/`SET`, the record\nname is extended with an underscore and the component name. If the embedded\nstructure is deeper with the `SEQUENCE`, `SET`, or `CHOICE` types in the line,\neach component name/alternative name is added to the record name.\n\nExample:\n\n```text\nSeq ::= SEQUENCE{\n a CHOICE{\n b SEQUENCE {\n c INTEGER\n }\n }\n}\n```\n\nThis results in the following record:\n\n```erlang\n-record('Seq_a_b',{c}).\n```\n\nIf the structured type has a component with an embedded `SEQUENCE OF`/`SET OF`\nwhich embedded type in turn is a `SEQUENCE`/`SET`, it gives a record with the\n`SEQUENCE OF`/`SET OF` addition as in the following example:\n\n```text\nSeq ::= SEQUENCE {\n a SEQUENCE OF SEQUENCE {\n b\n }\n c SET OF SEQUENCE {\n d\n }\n}\n```\n\nThis results in the following records:\n\n```erlang\n-record('Seq_a_SEQOF'{b}).\n-record('Seq_c_SETOF'{d}).\n```\n\nA parameterized type is to be considered as an embedded type. Each time such a\ntype is referenced, an instance of it is defined. Thus, in the following example\na record with name `'Seq_b'` is generated in the `.hrl` file and is used to hold\nvalues:\n\n```text\nSeq ::= SEQUENCE {\n b PType{INTEGER}\n}\n\nPType{T} ::= SEQUENCE{\n id T\n}\n```","title":"Embedded Structured Types - Getting Started","ref":"asn1_getting_started.html#embedded-structured-types"},{"type":"extras","doc":"Types that refer to themselves are called recursive types. Example:\n\n```erlang\nRec ::= CHOICE {\n nothing NULL,\n something SEQUENCE {\n a INTEGER,\n b OCTET STRING,\n c Rec }}\n```\n\nThis is allowed in ASN.1 and the ASN.1-to-Erlang compiler supports this\nrecursive type. A value for this type is assigned in Erlang as follows:\n\n```erlang\nV = {something,#'Rec_something'{a = 77,\n b = \"some octets here\",\n c = {nothing,'NULL'}}}.\n```","title":"Recursive Types - Getting Started","ref":"asn1_getting_started.html#recursive-types"},{"type":"extras","doc":"Values can be assigned to an ASN.1 type within the ASN.1 code itself, as opposed\nto the actions in the previous section where a value was assigned to an ASN.1\ntype in Erlang. The full value syntax of ASN.1 is supported and X.680 describes\nin detail how to assign values in ASN.1. A short example:\n\n```erlang\nTT ::= SEQUENCE {\n a INTEGER,\n b SET OF OCTET STRING }\n\ntt TT ::= {a 77,b {\"kalle\",\"kula\"}}\n```\n\nThe value defined here can be used in several ways. It can, for example, be used\nas the value in some `DEFAULT` component:\n\n```text\nSS ::= SET {\n s OBJECT IDENTIFIER,\n val TT DEFAULT tt }\n```\n\nIt can also be used from inside an Erlang program. If this ASN.1 code is defined\nin ASN.1 module `Values`, the ASN.1 value `tt` can be reached from Erlang as a\nfunction call to `'Values':tt()` as in the following example:\n\n```erlang\n1> Val = 'Values':tt().\n{'TT',77,[\"kalle\",\"kula\"]}\n2> {ok,Bytes} = 'Values':encode('TT',Val).\n{ok,<<48,18,128,1,77,161,13,4,5,107,97,108,108,101,4,4,\n 107,117,108,97>>}\n4> 'Values':decode('TT',Bytes).\n{ok,{'TT',77,[\"kalle\",\"kula\"]}}\n5>\n```\n\nThis example shows that a function is generated by the compiler that returns a\nvalid Erlang representation of the value, although the value is of a complex\ntype.\n\nFurthermore, if the option `maps` is not used, a macro is generated for each\nvalue in the `.hrl` file. So, the defined value `tt` can also be extracted by\n`?tt` in application code.","title":"ASN.1 Values - Getting Started","ref":"asn1_getting_started.html#asn-1-values"},{"type":"extras","doc":"The type `MACRO` is not supported. It is no longer part of the ASN.1 standard.\n\n[](){: #Information-Object }","title":"Macros - Getting Started","ref":"asn1_getting_started.html#macros"},{"type":"extras","doc":"Information Object Classes, Information Objects, and Information Object Sets (in\nthe following called classes, objects, and object sets, respectively) are\ndefined in the standard definition X.681. Only a brief explanation is given\nhere.\n\nThese constructs makes it possible to define open types, that is, values of that\ntype can be of any ASN.1 type. Also, relationships can be defined between\ndifferent types and values, as classes can hold types, values, objects, object\nsets, and other classes in their fields. A class can be defined in ASN.1 as\nfollows:\n\n```text\nGENERAL-PROCEDURE ::= CLASS {\n &Message,\n &Reply OPTIONAL,\n &Error OPTIONAL,\n &id PrintableString UNIQUE\n}\nWITH SYNTAX {\n NEW MESSAGE &Message\n [REPLY &Reply]\n [ERROR &Error]\n ADDRESS &id\n}\n```\n\nAn object is an instance of a class. An object set is a set containing objects\nof a specified class. A definition can look as follows:\n\n```text\nobject1 GENERAL-PROCEDURE ::= {\n NEW MESSAGE PrintableString\n ADDRESS \"home\"\n}\n\nobject2 GENERAL-PROCEDURE ::= {\n NEW MESSAGE INTEGER\n ERROR INTEGER\n ADDRESS \"remote\"\n}\n```\n\nThe object `object1` is an instance of the class `GENERAL-PROCEDURE` and has one\ntype field and one fixed type value field. The object `object2` has also an\noptional field `ERROR`, which is a type field. The field `ADDRESS` is a `UNIQUE`\nfield. Objects in an object set must have unique values in their `UNIQUE` field,\nas in `GENERAL-PROCEDURES`:\n\n```text\nGENERAL-PROCEDURES GENERAL-PROCEDURE ::= {\n object1 | object2}\n```\n\nYou cannot encode a class, object, or object set, only refer to it when defining\nother ASN.1 entities. Typically you refer to a class as well as to object sets\nby table constraints and component relation constraints (X.682) in ASN.1 types,\nas in the following:\n\n```erlang\nStartMessage ::= SEQUENCE {\n msgId GENERAL-PROCEDURE.&id ({GENERAL-PROCEDURES}),\n content GENERAL-PROCEDURE.&Message ({GENERAL-PROCEDURES}{@msgId}),\n }\n```\n\nIn type `StartMessage`, the constraint following field `content` tells that in a\nvalue of type `StartMessage` the value in field `content` must come from the\nsame object that is chosen by field `msgId`.\n\nSo, the value `#'StartMessage'{msgId=\"home\",content=\"Any Printable String\"}` is\nlegal to encode as a `StartMessage` value. However, the value\n`#'StartMessage'{msgId=\"remote\", content=\"Some String\"}` is illegal as the\nconstraint in `StartMessage` tells that when you have chosen a value from a\nspecific object in object set `GENERAL-PROCEDURES` in field `msgId`, you must\nchoose a value from that same object in the content field too. In this second\ncase, it is to be any `INTEGER` value.\n\n`StartMessage` can in field `content` be encoded with a value of any type that\nan object in object set `GENERAL-PROCEDURES` has in its `NEW MESSAGE` field.\nThis field refers to a type field `&Message` in the class. Field `msgId` is\nalways encoded as a `PrintableString`, as the field refers to a fixed type in\nthe class.\n\nIn practice, object sets are usually declared to be extensible so that more\nobjects can be added to the set later. Extensibility is indicated as follows:\n\n```text\nGENERAL-PROCEDURES GENERAL-PROCEDURE ::= {\n object1 | object2, ...}\n```\n\nWhen decoding a type that uses an extensible set constraint, it is always\npossible that the value in field `UNIQUE` is unknown (that is, the type has been\nencoded with a later version of the ASN.1 specification). The unencoded data is\nthen returned wrapped in a tuple as follows:\n\n```text\n{asn1_OPENTYPE,Binary}\n```\n\nHere `Binary` is an Erlang binary that contains the encoded data. (If option\n`legacy_erlang_types` has been given, only the binary is returned.)","title":"ASN.1 Information Objects (X.681) - Getting Started","ref":"asn1_getting_started.html#asn-1-information-objects-x-681"},{"type":"extras","doc":"Parameterization, which is defined in X.683, can be used when defining types,\nvalues, value sets, classes, objects, or object sets. A part of a definition can\nbe supplied as a parameter. For example, if a `Type` is used in a definition\nwith a certain purpose, you want the type name to express the intention. This\ncan be done with parameterization.\n\nWhen many types (or another ASN.1 entity) only differ in some minor cases, but\nthe structure of the types is similar, only one general type can be defined and\nthe differences can be supplied through parameters.\n\nExample of use of parameterization:\n\n```text\nGeneral{Type} ::= SEQUENCE\n{\n number INTEGER,\n string Type\n}\n\nT1 ::= General{PrintableString}\n\nT2 ::= General{BIT STRING}\n```\n\nAn example of a value that can be encoded as type `T1` is `{12,\"hello\"}`.\n\nNotice that the compiler does not generate encode/decode functions for\nparameterized types, only for the instances of the parameterized types.\nTherefore, if a file contains the types `General{}`, `T1`, and `T2` as in the\nprevious example, encode/decode functions are only generated for `T1` and `T2`.","title":"Parameterization (X.683) - Getting Started","ref":"asn1_getting_started.html#parameterization-x-683"},{"type":"extras","doc":"\n# Specialized Decodes\n\n[](){: #SpecializedDecodes }\n\nWhen performance is of highest priority and one is interested in a limited part\nof the ASN.1 encoded message before deciding what to do with the rest of it, an\noption is to decode only a part of the message. This situation can be a server\nthat has to decide the addressee of a message. The addressee can be interested\nin the entire message, but the server can be a bottleneck that you want to spare\nany unnecessary load.\n\nInstead of making two _complete decodes_ (the normal case of decode), one in the\nserver and one in the addressee, it is only necessary to make one _specialized\ndecode_ (in the server) and another complete decode (in the addressee). This\nsection describes the following specialized decode functionality:\n\n- _Exclusive decode_\n- _Selected decode_\n\nThis functionality is only provided when using `BER` (option `ber`).","title":"Specialized Decodes","ref":"asn1_spec.html"},{"type":"extras","doc":"The basic idea with exclusive decode is to specify which parts of the message\nyou want to exclude from being decoded. These parts remain encoded and are\nreturned in the value structure as binaries. The undecoded parts can be decoded\nlater by calling the `decode_part/2` function.","title":"Exclusive Decode - Specialized Decodes","ref":"asn1_spec.html#exclusive-decode"},{"type":"extras","doc":"To perform an exclusive decode:\n\n- _Step 1:_ Decide the name of the function for the exclusive decode.\n- _Step 2:_ Include the following instructions in a configuration file:\n\n - The name of the exclusive decode function\n - The name of the ASN.1 specification\n - A notation that tells which parts of the message structure to be excluded\n from decode\n\n- _Step 3_ Compile with the additional option `asn1config`. The compiler\n searches for a configuration file with the same name as the ASN.1\n specification but with extension `.asn1config`. This configuration file is not\n the same as used for compilation of a set of files. See section\n [Writing an Exclusive Decode Instruction.](asn1_spec.md#UndecodedPart)","title":"Procedure - Specialized Decodes","ref":"asn1_spec.html#procedure"},{"type":"extras","doc":"The runtime user interface for exclusive decode comprises the following two\nfunctions:\n\n- A function for an exclusive decode, whose name the user decides in the\n configuration file\n- A `decode_part/2` function generated by the ASN.1 compiler when\n exclusive decode is enabled. This function decodes the parts that\n were left undecoded during the exclusive decode.\n\nBoth functions are described in the following.\n\nIf the exclusive decode function has, for example, the name `decode_exclusive`\nand an ASN.1 encoded message `Bin` is to be exclusive decoded, the call is as\nfollows:\n\n```erlang\n{ok,ExclMessage} = 'MyModule':decode_exclusive(Bin)\n```\n\n[](){: #UndecodedPart } The result `ExclMessage` has the same structure as a\ncomplete decode would have, except for the parts of the top type that were not\ndecoded. The undecoded parts are on their places in the structure on format\n`{TypeKey,UndecodedValue}`.\n\nEach undecoded part that is to be decoded must be fed into function\n`decode_part/2` as follows:\n\n```erlang\n{ok,PartMessage} = 'MyModule':decode_part(TypeKey, UndecodedValue)\n```\n\n[](){: #Exclusive-Instruction }","title":"User Interface - Specialized Decodes","ref":"asn1_spec.html#user-interface"},{"type":"extras","doc":"This instruction is written in the configuration file in the following format:\n\n```erlang\nExclusiveDecodeInstruction = {exclusive_decode,{ModuleName,DecodeInstructions}}.\n\nModuleName = atom()\n\nDecodeInstructions = [DecodeInstruction]+\n\nDecodeInstruction = {ExclusiveDecodeFunctionName,TypeList}\n\nExclusiveDecodeFunctionName = atom()\n\nTypeList = [TopType,ElementList]\n\nElementList = [Element]+\n\nElement = {Name,parts} |\n {Name,undecoded} |\n {Name,ElementList}\n\nTopType = atom()\n\nName = atom()\n```\n\nThe instruction must be a valid Erlang term terminated by a dot.\n\nIn `TypeList` the path from the top type to each undecoded subcomponent is\ndescribed. `TopType` is the name of a top-level type in the ASN.1 specification.\nThe action for each component in `ElementList` is described by one of:\n\n- `{Name,parts}`\n- `{Name,undecoded}`\n- `{Name,ElementList}`\n\nThe use and effect of the actions are as follows:\n\n- **`{Name,undecoded}`** - Leaves the element undecoded. The type of `Name` can\n be any ASN.1 type. The value of element `Name` is returned as a tuple (as\n mentioned in the previous section) in the value structure of the top type.\n\n- **`{Name,parts}`** - The type of `Name` must be either `SEQUENCE OF` or\n `SET OF`. The action implies that the different components of `Name` are left\n undecoded. The value of `Name` is returned as a tuple (as mentioned in the\n previous section) where the second element is a list of binaries. This is\n because the representation of a `SEQUENCE OF` or a `SET OF` in Erlang is a\n list of its internal type. Any of the elements in this list or the entire list\n can be decoded by function `decodepart`.\n\n- **`{Name,ElementList}`** - This action is used when one or more of the\n subtypes of `Name` is exclusively decoded.\n\n`Name` in these actions can be a component name of a `SEQUENCE OF` or a\n`SET OF`, or a name of an alternative in a `CHOICE`.","title":"Writing an Exclusive Decode Instruction - Specialized Decodes","ref":"asn1_spec.html#writing-an-exclusive-decode-instruction"},{"type":"extras","doc":"In this examples, the definitions from the following ASN.1 specification are\nused:\n\n```text\n\nGUI DEFINITIONS AUTOMATIC TAGS ::= BEGIN\n\n Action ::= SEQUENCE {\n number INTEGER DEFAULT 15,\n handle Handle DEFAULT {number 12, on TRUE}\n }\n\n Key ::= Button\n Handle ::= Key\n\n Button ::= SEQUENCE {\n number INTEGER,\n on BOOLEAN\n }\n\n Window ::= CHOICE {\n vsn INTEGER,\n status Status\n }\n\n Status ::= SEQUENCE {\n state INTEGER,\n buttonList SEQUENCE OF Button,\n enabled BOOLEAN OPTIONAL,\n actions CHOICE {\n possibleActions SEQUENCE OF Action,\n noOfActions INTEGER\n }\n }\n\nEND\n```\n\n{: #Asn1spec }\n\nIf `Button` is a top type and it is needed to exclude component `number` from\ndecode, `TypeList` in the instruction in the configuration file is\n`['Button',[{number,undecoded}]]`. If you call the decode function\n`decode_Button_exclusive`, `DecodeInstruction` is\n`{decode_Button_exclusive,['Button',[{number,undecoded}]]}`.\n\nAnother top type is `Window` whose subcomponent actions in type `Status` and the\nparts of component `buttonList` are to be left undecoded. For this type, the\nfunction is named `decode__Window_exclusive`. The complete\n`Exclusive_Decode_Instruction` configuration is as follows:\n\n```text\n\n{exclusive_decode,\n {'GUI',\n [{decode_Window_exclusive,\n ['Window',[{status,[{buttonList,parts},{actions,undecoded}]}]]},\n {decode_Button_exclusive,\n ['Button',[{number,undecoded}]]}]}}.\n```\n\nThe following figure shows the bytes of a `Window:status` message. The\ncomponents `buttonList` and `actions` are excluded from decode. Only `state` and\n`enabled` are decoded when `decode__Window_exclusive` is called.\n\n![Bytes of a Window:status Message](assets/exclusive_Win_But.gif \"Bytes of a Window:status Message\")\n\nHere follows an example of how the module. Note that option `no_ok_wrapper` is\nused to make the example more concise.\n\n```erlang\n1> asn1ct:compile('GUI', [ber,asn1config,no_ok_wrapper]).\nok\n2> rr('GUI').\n['Action','Button','Status']\n3> ButtonMsg = #'Button'{number=123,on=true}.\n#'Button'{number = 123,on = true}\n4> ButtonBytes = 'GUI':encode('Button', ButtonMsg).\n<<48,6,128,1,123,129,1,255>>\n5> ExclusiveMsgButton = 'GUI':decode_Button_exclusive(ButtonBytes).\n#'Button'{number = {'Button_number',<<128,1,123>>},\n on = true}\n6> {UndecKey,UndecBytes} = ExclusiveMsgButton#'Button'.number.\n{'Button_number',<<128,1,123>>}\n7> 'GUI':decode_part(UndecKey, UndecBytes).\n123\n8> WindowMsg =\n{status,{'Status',35,\n [{'Button',3,true},\n {'Button',4,false},\n {'Button',5,true},\n {'Button',6,true},\n {'Button',7,false}],\n false,\n {possibleActions,[{'Action',16,{'Button',17,true}}]}}}.\n{status,#'Status'{state = 35,\n buttonList = [#'Button'{number = 3,on = true},\n #'Button'{number = 4,on = false},\n #'Button'{number = 5,on = true},\n #'Button'{number = 6,on = true},\n #'Button'{number = 7,on = false}],\n enabled = false,\n actions = {possibleActions,[#'Action'{number = 16,\n handle = #'Button'{number = 17,on = true}}]}}}\n9> WindowBytes = 'GUI':encode('Window', WindowMsg).\n<<161,65,128,1,35,161,40,48,6,128,1,3,129,1,255,48,6,128,\n 1,4,129,1,0,48,6,128,1,5,129,...>>\n10> {status,#'Status'{buttonList={UndecWindowKey,UndecWindowParts}}} =\n'GUI':decode_Window_exclusive(WindowBytes).\n{status,#'Status'{state = 35,\n buttonList = {'Status_buttonList',[<<48,6,128,1,3,129,1,\n 255>>,\n <<48,6,128,1,4,129,1,0>>,\n <<48,6,128,1,5,129,1,255>>,\n <<48,6,128,1,6,129,1,255>>,\n <<48,6,128,1,7,129,1,0>>]},\n enabled = false,\n actions = {'Status_actions',<<163,15,160,13,48,11,128,\n 1,16,161,6,128,1,17,129,\n 1,255>>}}}\n11> 'GUI':decode_part(UndecWindowKey, UndecWindowParts).\n[#'Button'{number = 3,on = true},\n #'Button'{number = 4,on = false},\n #'Button'{number = 5,on = true},\n #'Button'{number = 6,on = true},\n #'Button'{number = 7,on = false}]\n12> 'GUI':decode_part(UndecWindowKey, hd(UndecWindowParts)).\n#'Button'{number = 3,on = true}\n13> {status,#'Status'{actions={ChoiceKey,ChoiceUndec}}} = v(10).\n{status,#'Status'{state = 35,\n buttonList = {'Status_buttonList',[<<48,6,128,1,3,129,1,\n 255>>,\n <<48,6,128,1,4,129,1,0>>,\n <<48,6,128,1,5,129,1,255>>,\n <<48,6,128,1,6,129,1,255>>,\n <<48,6,128,1,7,129,1,0>>]},\n enabled = false,\n actions = {'Status_actions',<<163,15,160,13,48,11,128,\n 1,16,161,6,128,1,17,129,\n 1,255>>}}}\n14> 'GUI':decode_part(ChoiceKey, ChoiceUndec).\n{possibleActions,[#'Action'{number = 16,\n handle = #'Button'{number = 17,on = true}}]}\n```","title":"Example - Specialized Decodes","ref":"asn1_spec.html#example"},{"type":"extras","doc":"Selective decode decodes a single subtype of a constructed value. This is the\nfastest method to extract a subvalue. Selective decode is typically used when\none want to inspect, for example, a version number to be able to decide how to\nhandle the entire value.","title":"Selective Decode - Specialized Decodes","ref":"asn1_spec.html#selective-decode"},{"type":"extras","doc":"To perform a selective decode:\n\n- _Step 1:_ Include the following instructions in the configuration file:\n\n - The name of the user function\n - The name of the ASN.1 specification\n - A notation that tells which part of the type to be decoded\n\n- _Step 2:_ Compile with the additional option `asn1config`. The compiler\n searches for a configuration file with the same name as the ASN.1\n specification, but with extension `.asn1config`. In the same file you can also\n provide configuration specifications for exclusive decode. The generated\n Erlang module has the usual functionality for encode/decode preserved and the\n specialized decode functionality added.","title":"Procedure - Specialized Decodes","ref":"asn1_spec.html#procedure"},{"type":"extras","doc":"The only new user interface function is the one provided by the user in the\nconfiguration file.\n\nFor example, if the configuration file includes the specification\n`{selective_decode,{'ModuleName',[{selected_decode_Window,TypeList}]}}` do the\nselective decode by\n`{ok,Result} = 'ModuleName':selected_decode_Window(EncodedBinary).`\n\n[](){: #Selective-Instruction }","title":"User Interface - Specialized Decodes","ref":"asn1_spec.html#user-interface"},{"type":"extras","doc":"One or more selective decode functions can be described in a configuration file.\nUse the following notation:\n\n```erlang\nSelectiveDecodeInstruction = {selective_decode,{ModuleName,DecodeInstructions}}.\n\nModuleName = atom()\n\nDecodeInstructions = [DecodeInstruction]+\n\nDecodeInstruction = {SelectiveDecodeFunctionName,TypeList}\n\nSelectiveDecodeFunctionName = atom()\n\nTypeList = [TopType|ElementList]\n\nElementList = Name|ListSelector\n\nName = atom()\n\nListSelector = [integer()]\n```\n\nThe instruction must be a valid Erlang term terminated by a dot.\n\n- `ModuleName` is the same as the name of the ASN.1 specification, but without\n the extension.\n- `DecodeInstruction` is a tuple with your chosen function name and the\n components from the top type that leads to the single type you want to decode.\n Make sure to choose a name of your function that is not the same as any of the\n generated functions.\n- The first element of `TypeList` is the top type of the encoded message. In\n `ElementList`, it is followed by each of the component names that leads to\n selected type.\n- Each name in `ElementList` must be a constructed type except the last name,\n which can be any type.\n- `ListSelector` makes it possible to choose one of the encoded components in a\n `SEQUENCE OF` or a `SET OF`. It is also possible to go further in that\n component and pick a subtype of that to decode. So, in the `TypeList`:\n `['Window',status,buttonList,[1],number]`, component `buttonList` must be of\n type `SEQUENCE OF` or `SET OF`.\n\nIn the example, component `number` of the first of the encoded elements in the\n`SEQUENCE OF` `buttonList` is selected. This applies on the ASN.1 specification\nin section [Writing an Exclusive Decode Instruction](asn1_spec.md#Asn1spec).","title":"Writing a Selective Decode Instruction - Specialized Decodes","ref":"asn1_spec.html#writing-a-selective-decode-instruction"},{"type":"extras","doc":"In this example, the same ASN.1 specification as in section\n[Writing an Exclusive Decode Instruction](asn1_spec.md#Asn1spec) is used. The\nfollowing is a valid selective decode instruction:\n\n```erlang\n{selective_decode,\n {'GUI',\n [{selected_decode_Window1,\n ['Window',status,buttonList,\n [1],\n number]},\n {selected_decode_Action,\n ['Action',handle,number]},\n {selected_decode_Window2,\n ['Window',\n status,\n actions,\n possibleActions,\n [1],\n handle,number]}]}}.\n```\n\nThe first instruction,\n`{selected_decode_Window1,['Window',status,buttonList,[1],number]}` is described\nin the previous section.\n\nThe second instruction, `{selected_decode_Action,['Action',handle,number]}`,\ntakes component `number` in the `handle` component of type `Action`. If the\nvalue is `ValAction = {'Action',17,{'Button',4711,false}}`, the internal value\n4711 is to be picked by `selected_decode_Action`. In an Erlang terminal it looks\nas follows:\n\n```erlang\n1> asn1ct:compile('GUI', [ber,asn1config,no_ok_wrapper]).\nok\n2> ValAction = {'Action',17,{'Button',4711,false}}.\n{'Action',17,{'Button',4711,false}}\n3> Bytes = 'GUI':encode('Action',ValAction).\n<<48,18,2,1,17,160,13,172,11,171,9,48,7,128,2,18,103,129,1,0>>\n4> 'GUI':selected_decode_Action(Bytes).\n4711\n```\n\nThe third instruction,\n`['Window',status,actions,possibleActions,[1],handle,number]`, works as follows:\n\n- _Step 1:_ Starts with type `Window`.\n- _Step 2:_ Takes component `status` of `Window` that is of type `Status`.\n- _Step 3:_ Takes _actions_ of type `Status`.\n- _Step 4:_ Takes `possibleActions` of the internally defined `CHOICE` type.\n- _Step 5:_ Goes into the first component of `SEQUENCE OF` by `[1]`. That\n component is of type `Action`.\n- _Step 6:_ Takes component `handle`.\n- _Step 7:_ Takes component `number` of type `Button`.\n\nThe following figure shows which components are in `TypeList`\n`['Window',status,actions,possibleActions,[1],handle,number]`:\n\n![Elements Specified in Configuration File for Selective Decode of a Subvalue in a Window Message](assets/selective_TypeList.gif \"Elements Specified in Configuration File for Selective Decode of a Subvalue in a Window Message\")\n\nIn the following figure, only the marked element is decoded by\n`selected_decode_Window2`:\n\n![Bytes of a Window:status Message](assets/selective_Window2.gif \"Bytes of a Window:status Message\")\n\nWith the following example, you can examine that both `selected_decode_Window2`\nand `selected_decode_Window1` decodes the intended subvalue of value `Val`:\n\n```erlang\n1> Val = {status,{'Status',12,\n [{'Button',13,true},\n {'Button',14,false},\n {'Button',15,true},\n {'Button',16,false}],\n true,\n {possibleActions,[{'Action',17,{'Button',18,false}},\n {'Action',19,{'Button',20,true}},\n {'Action',21,{'Button',22,false}}]}}}.\n2> Bin = 'GUI':encode('Window',Val).\n<<161,89,128,1,12,161,32,48,6,128,1,13,129,1,255,48,6,128,\n 1,14,129,1,0,48,6,128,1,15,129,...>>\n4> 'GUI':selected_decode_Window1(Bin).\n13\n5> 'GUI':selected_decode_Window2(Bin).\n18\n```","title":"Example - Specialized Decodes","ref":"asn1_spec.html#example"}],"content_type":"text/plain","producer":{"name":"ex_doc","version":[48,46,51,52,46,49]}} \ No newline at end of file diff --git a/prs/8803/lib/asn1-5.3/doc/html/search.html b/prs/8803/lib/asn1-5.3/doc/html/search.html index 41ebb9fc3d468..c1af2f1c94ca9 100644 --- a/prs/8803/lib/asn1-5.3/doc/html/search.html +++ b/prs/8803/lib/asn1-5.3/doc/html/search.html @@ -122,7 +122,7 @@

      - +

    The default StatisticsSpec is:

    • For sequential commands:

      [{"Function calls", fun cmnd_names/1},
      + {"Length of command sequences", fun print_frequency_ranges/0,
      +                                                  fun num_calls/1}]
    • For parallel commands:

      [{"Distribution sequential/parallel", fun sequential_parallel/1},
      + {"Function calls", fun cmnd_names/1},
      + {"Length of command sequences", fun print_frequency_ranges/0,
      +                                                  fun num_calls/1}]
    diff --git a/prs/8803/lib/common_test-1.27/doc/html/ct_property_test_chapter.html b/prs/8803/lib/common_test-1.27/doc/html/ct_property_test_chapter.html index 008935656b424..92b05231ea6c0 100644 --- a/prs/8803/lib/common_test-1.27/doc/html/ct_property_test_chapter.html +++ b/prs/8803/lib/common_test-1.27/doc/html/ct_property_test_chapter.html @@ -147,51 +147,51 @@

    Introductory Example

    Assume that we want to test the lists:sort/1 function.

    We need a property to test the function. In normal way, we create -property_test/ct_prop.erl module in the test directory in our application:

    -module(ct_prop).
    --export([prop_sort/0]).
    +property_test/ct_prop.erl module in the test directory in our application:

    -module(ct_prop).
    +-export([prop_sort/0]).
     
     %%% This will include the .hrl file for the installed testing tool:
    --include_lib("common_test/include/ct_property_test.hrl").
    +-include_lib("common_test/include/ct_property_test.hrl").
     
     %%% The property we want to check:
     %%%   For all possibly unsorted lists,
     %%%   the result of lists:sort/1 is sorted.
    -prop_sort() ->
    -    ?FORALL(UnSorted, list(),
    -            is_sorted(lists:sort(UnSorted))
    -           ).
    +prop_sort() ->
    +    ?FORALL(UnSorted, list(),
    +            is_sorted(lists:sort(UnSorted))
    +           ).
     
     %%% Function to check that a list is sorted:
    -is_sorted([]) ->
    +is_sorted([]) ->
         true;
    -is_sorted([_]) ->
    +is_sorted([_]) ->
         true;
    -is_sorted([H1,H2|SortedTail]) when H1 =< H2 ->
    -    is_sorted([H2|SortedTail]);
    -is_sorted(_) ->
    -    false.

    We also need a CommonTest test suite:

    -module(ct_property_test_SUITE).
    --compile(export_all). % Only in tests!
    +is_sorted([H1,H2|SortedTail]) when H1 =< H2 ->
    +    is_sorted([H2|SortedTail]);
    +is_sorted(_) ->
    +    false.

    We also need a CommonTest test suite:

    -module(ct_property_test_SUITE).
    +-compile(export_all). % Only in tests!
     
    --include_lib("common_test/include/ct.hrl").
    +-include_lib("common_test/include/ct.hrl").
     
    -all() -> [prop_sort
    -         ].
    +all() -> [prop_sort
    +         ].
     
     %%% First prepare Config and compile the property tests for the found tool:
    -init_per_suite(Config) ->
    -    ct_property_test:init_per_suite(Config).
    +init_per_suite(Config) ->
    +    ct_property_test:init_per_suite(Config).
     
    -end_per_suite(Config) ->
    +end_per_suite(Config) ->
         Config.
     
     %%%================================================================
     %%% Test suites
     %%%
    -prop_sort(Config) ->
    -    ct_property_test:quickcheck(
    -      ct_prop:prop_sort(),
    +prop_sort(Config) ->
    +    ct_property_test:quickcheck(
    +      ct_prop:prop_sort(),
           Config
    -     ).

    We run it as usual, for example with ct_run in the OS shell:

    ..../test$ ct_run -suite ct_property_test_SUITE
    +     ).

    We run it as usual, for example with ct_run in the OS shell:

    ..../test$ ct_run -suite ct_property_test_SUITE
     .....
     Common Test: Running make in test directories...
     
    @@ -221,13 +221,13 @@ 

    A stateful testing example

    Assume a test that generates some parallel stateful commands, and runs 300 -tests:

    prop_parallel(Config) ->
    -    numtests(300,
    -             ?FORALL(Cmds, parallel_commands(?MODULE),
    +tests:

    prop_parallel(Config) ->
    +    numtests(300,
    +             ?FORALL(Cmds, parallel_commands(?MODULE),
                          begin
    -                         RunResult = run_parallel_commands(?MODULE, Cmds),
    -                         ct_property_test:present_result(?MODULE, Cmds, RunResult, Config)
    -                     end)).

    The ct_property_test:present_result/4 is a help function for printing some + RunResult = run_parallel_commands(?MODULE, Cmds), + ct_property_test:present_result(?MODULE, Cmds, RunResult, Config) + end)).

    The ct_property_test:present_result/4 is a help function for printing some statistics in the CommonTest log file.

    Our example test could for example be a simple test of an ftp server, where we perform get, put and delete requests, some of them in parallel. Per default, the result has three sections:

    *** User 2019-12-11 13:28:17.504 ***
    diff --git a/prs/8803/lib/common_test-1.27/doc/html/ct_run_cmd.html b/prs/8803/lib/common_test-1.27/doc/html/ct_run_cmd.html
    index 0c451729c97f4..ee963d0dad6ef 100644
    --- a/prs/8803/lib/common_test-1.27/doc/html/ct_run_cmd.html
    +++ b/prs/8803/lib/common_test-1.27/doc/html/ct_run_cmd.html
    @@ -251,10 +251,10 @@ 

    Run Common Test in Interactive Mode

     ct_run -shell
    -  [-config ConfigFile1 ConfigFile2 ... ConfigFileN]
    -  [-userconfig CallbackModule1 ConfigString1 and CallbackModule2
    -   ConfigString2 and .. and CallbackModuleN ConfigStringN]
    -  [-decrypt_key Key] | [-decrypt_file KeyFile]

    + [-config ConfigFile1 ConfigFile2 ... ConfigFileN] + [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 + ConfigString2 and .. and CallbackModuleN ConfigStringN] + [-decrypt_key Key] | [-decrypt_file KeyFile]

    diff --git a/prs/8803/lib/common_test-1.27/doc/html/ct_snmp.html b/prs/8803/lib/common_test-1.27/doc/html/ct_snmp.html index 3a9b8ffe2e60e..203c06e723f06 100644 --- a/prs/8803/lib/common_test-1.27/doc/html/ct_snmp.html +++ b/prs/8803/lib/common_test-1.27/doc/html/ct_snmp.html @@ -150,15 +150,15 @@

    Optional.

  • {agent_target_param_def, [term()] | {data_dir_file, rel_path()}} - Optional.

  • Parameter MgrAgentConfName in the functions is to be a name you allocate in your test suite using a require statement. Example (where -MgrAgentConfName = snmp_mgr_agent):

    suite() -> [{require, snmp_mgr_agent, snmp}].

    or

    ct:require(snmp_mgr_agent, snmp).

    Notice that USM users are needed for SNMPv3 configuration and are not to be +MgrAgentConfName = snmp_mgr_agent):

    suite() -> [{require, snmp_mgr_agent, snmp}].

    or

    ct:require(snmp_mgr_agent, snmp).

    Notice that USM users are needed for SNMPv3 configuration and are not to be confused with users.

    SNMP traps, inform, and report messages are handled by the user callback module. For details, see the SNMP application.

    It is recommended to use the .hrl files created by the Erlang/OTP MIB compiler to define the Object Identifiers (OIDs). For example, to get the Erlang node -name from erlNodeTable in the OTP-MIB:

    Oid = ?erlNodeEntry ++ [?erlNodeName, 1]

    Furthermore, values can be set for SNMP application configuration parameters, +name from erlNodeTable in the OTP-MIB:

    Oid = ?erlNodeEntry ++ [?erlNodeName, 1]

    Furthermore, values can be set for SNMP application configuration parameters, config, server, net_if, and so on (for a list of valid parameters and types, see the User's Guide for the SNMP application). -This is done by defining a configuration data variable on the following form:

    {snmp_app, [{manager, [snmp_app_manager_params()]},
    -            {agent, [snmp_app_agent_params()]}]}.

    A name for the data must be allocated in the suite using require (see the +This is done by defining a configuration data variable on the following form:

    {snmp_app, [{manager, [snmp_app_manager_params()]},
    +            {agent, [snmp_app_agent_params()]}]}.

    A name for the data must be allocated in the suite using require (see the example above). Pass this name as argument SnmpAppConfName to ct_snmp:start/3. ct_snmp specifies default values for some SNMP application configuration parameters (such as {verbosity,trace} for diff --git a/prs/8803/lib/common_test-1.27/doc/html/ct_ssh.html b/prs/8803/lib/common_test-1.27/doc/html/ct_ssh.html index a61cd8f17d514..367eb9e1eec33 100644 --- a/prs/8803/lib/common_test-1.27/doc/html/ct_ssh.html +++ b/prs/8803/lib/common_test-1.27/doc/html/ct_ssh.html @@ -133,14 +133,14 @@

    that have been started on existing SSH connections (that is, when the original connection type is ssh). Whenever the connection type is sftp, use the SSH connection reference only.

    The following options are valid for specifying an SSH/SFTP connection (that is, -can be used as configuration elements):

    [{ConnType, Addr},
    - {port, Port},
    - {user, UserName}
    - {password, Pwd}
    - {user_dir, String}
    - {public_key_alg, PubKeyAlg}
    - {connect_timeout, Timeout}
    - {key_cb, KeyCallbackMod}]

    ConnType = ssh | sftp.

    For other types, see ssh.

    All time-out parameters in ct_ssh functions are values in milliseconds.

    +can be used as configuration elements):

    [{ConnType, Addr},
    + {port, Port},
    + {user, UserName}
    + {password, Pwd}
    + {user_dir, String}
    + {public_key_alg, PubKeyAlg}
    + {connect_timeout, Timeout}
    + {key_cb, KeyCallbackMod}]

    ConnType = ssh | sftp.

    For other types, see ssh.

    All time-out parameters in ct_ssh functions are values in milliseconds.

    diff --git a/prs/8803/lib/common_test-1.27/doc/html/ct_telnet.html b/prs/8803/lib/common_test-1.27/doc/html/ct_telnet.html index 92cae9fbd29d8..596c8f1e84e56 100644 --- a/prs/8803/lib/common_test-1.27/doc/html/ct_telnet.html +++ b/prs/8803/lib/common_test-1.27/doc/html/ct_telnet.html @@ -136,14 +136,14 @@

    true
  • Polling limit (max number of times to poll to get a remaining string terminated) = 0
  • Polling interval (sleep time between polls) = 1 second
  • The TCP_NODELAY option for the telnet socket is disabled (set to false) per default
  • These parameters can be modified by the user with the following configuration -term:

    {telnet_settings, [{connect_timeout,Millisec},
    -                   {command_timeout,Millisec},
    -                   {reconnection_attempts,N},
    -                   {reconnection_interval,Millisec},
    -                   {keep_alive,Bool},
    -                   {poll_limit,N},
    -                   {poll_interval,Millisec},
    -                   {tcp_nodelay,Bool}]}.

    Millisec = integer(), N = integer()

    Enter the telnet_settings term in a configuration file included in the test +term:

    {telnet_settings, [{connect_timeout,Millisec},
    +                   {command_timeout,Millisec},
    +                   {reconnection_attempts,N},
    +                   {reconnection_interval,Millisec},
    +                   {keep_alive,Bool},
    +                   {poll_limit,N},
    +                   {poll_interval,Millisec},
    +                   {tcp_nodelay,Bool}]}.

    Millisec = integer(), N = integer()

    Enter the telnet_settings term in a configuration file included in the test and ct_telnet retrieves the information automatically.

    keep_alive can be specified per connection, if necessary. For details, see unix_telnet.

    @@ -158,8 +158,8 @@

    such as expect/3. However, ct_telnet can be configured to use a special purpose event handler, implemented in ct_conn_log_h, for logging all Telnet traffic. To use this handler, install a Common Test hook named -cth_conn_log. Example (using the test suite information function):

    suite() ->
    -    [{ct_hooks, [{cth_conn_log, [{conn_mod(),hook_options()}]}]}].

    conn_mod() is the name of the Common Test module implementing the connection +cth_conn_log. Example (using the test suite information function):

    suite() ->
    +    [{ct_hooks, [{cth_conn_log, [{conn_mod(),hook_options()}]}]}].

    conn_mod() is the name of the Common Test module implementing the connection protocol, that is, ct_telnet.

    The cth_conn_log hook performs unformatted logging of Telnet data to a separate text file. All Telnet communication is captured and printed, including any data sent from the server. The link to this text file is located at the top @@ -172,15 +172,15 @@

    default value of this option is raw, which results in the behavior described above. If the value is set to html, all Telnet communication is printed to the test case HTML log instead.

    All cth_conn_log hook options described can also be specified in a -configuration file with configuration variable ct_conn_log.

    Example:

    {ct_conn_log, [{ct_telnet,[{log_type,raw},
    -                           {hosts,[key_or_name()]}]}]}

    Note

    Hook options specified in a configuration file overwrite any hard-coded hook +configuration file with configuration variable ct_conn_log.

    Example:

    {ct_conn_log, [{ct_telnet,[{log_type,raw},
    +                           {hosts,[key_or_name()]}]}]}

    Note

    Hook options specified in a configuration file overwrite any hard-coded hook options in the test suite.

    Logging Example:

    The following ct_hooks statement causes printing of Telnet traffic to separate logs for the connections server1 and server2. Traffic for any other -connections is logged in the default Telnet log.

    suite() ->
    -    [{ct_hooks,
    -      [{cth_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}]}].

    As previously explained, this specification can also be provided by an entry -like the following in a configuration file:

    {ct_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}.

    In this case the ct_hooks statement in the test suite can look as follows:

    suite() ->
    -    [{ct_hooks, [{cth_conn_log, []}]}].

    +connections is logged in the default Telnet log.

    suite() ->
    +    [{ct_hooks,
    +      [{cth_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}]}].

    As previously explained, this specification can also be provided by an entry +like the following in a configuration file:

    {ct_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}.

    In this case the ct_hooks statement in the test suite can look as follows:

    suite() ->
    +    [{ct_hooks, [{cth_conn_log, []}]}].

    @@ -889,9 +889,9 @@

    expect(Connection, Patterns, Opts)

    instead of only one Match. Also HaltReason is returned.

  • sequence - All patterns must be matched in a sequence. A match is not concluded until all patterns are matched. This option can be interrupted by one or more HaltPatterns. MatchList is always returned, that is, a list of -Match instead of only one Match. Also HaltReason is returned.

  • Example 1:

    expect(Connection,[{abc,"ABC"},{xyz,"XYZ"}],[sequence,{halt,[{nnn,"NNN"}]}])

    First this tries to match "ABC", and then "XYZ", but if "NNN" appears, the +Match instead of only one Match. Also HaltReason is returned.

    Example 1:

    expect(Connection,[{abc,"ABC"},{xyz,"XYZ"}],[sequence,{halt,[{nnn,"NNN"}]}])

    First this tries to match "ABC", and then "XYZ", but if "NNN" appears, the function returns {error,{nnn,["NNN"]}}. If both "ABC" and "XYZ" are -matched, the function returns {ok,[AbcMatch,XyzMatch]}.

    Example 2:

    expect(Connection,[{abc,"ABC"},{xyz,"XYZ"}],[{repeat,2},{halt,[{nnn,"NNN"}]}])

    This tries to match "ABC" or "XYZ" twice. If "NNN" appears, the function +matched, the function returns {ok,[AbcMatch,XyzMatch]}.

    Example 2:

    expect(Connection,[{abc,"ABC"},{xyz,"XYZ"}],[{repeat,2},{halt,[{nnn,"NNN"}]}])

    This tries to match "ABC" or "XYZ" twice. If "NNN" appears, the function returns HaltReason = {nnn,["NNN"]}.

    Options repeat and sequence can be combined to match a sequence multiple times.

    diff --git a/prs/8803/lib/common_test-1.27/doc/html/dependencies_chapter.html b/prs/8803/lib/common_test-1.27/doc/html/dependencies_chapter.html index 03c7d494b29f8..f4b40c8633a53 100644 --- a/prs/8803/lib/common_test-1.27/doc/html/dependencies_chapter.html +++ b/prs/8803/lib/common_test-1.27/doc/html/dependencies_chapter.html @@ -161,65 +161,65 @@

    start and stop functionality separately.) The configuration can also be implemented as a common function, maybe grouped with the start function. Finally, the testing of connecting and disconnecting a client can be grouped -into one test case. The resulting suite can look as follows:

    -module(my_server_SUITE).
    --compile(export_all).
    --include_lib("ct.hrl").
    +into one test case. The resulting suite can look as follows:

    -module(my_server_SUITE).
    +-compile(export_all).
    +-include_lib("ct.hrl").
     
     %%% init and end functions...
     
    -suite() -> [{require,my_server_cfg}].
    +suite() -> [{require,my_server_cfg}].
     
    -init_per_testcase(start_and_stop, Config) ->
    +init_per_testcase(start_and_stop, Config) ->
         Config;
     
    -init_per_testcase(config, Config) ->
    -    [{server_pid,start_server()} | Config];
    +init_per_testcase(config, Config) ->
    +    [{server_pid,start_server()} | Config];
     
    -init_per_testcase(_, Config) ->
    -    ServerPid = start_server(),
    -    configure_server(),
    -    [{server_pid,ServerPid} | Config].
    +init_per_testcase(_, Config) ->
    +    ServerPid = start_server(),
    +    configure_server(),
    +    [{server_pid,ServerPid} | Config].
     
    -end_per_testcase(start_and_stop, _) ->
    +end_per_testcase(start_and_stop, _) ->
         ok;
     
    -end_per_testcase(_, Config) ->
    -    ServerPid = proplists:get_value(server_pid, Config),
    -    stop_server(ServerPid).
    +end_per_testcase(_, Config) ->
    +    ServerPid = proplists:get_value(server_pid, Config),
    +    stop_server(ServerPid).
     
     %%% test cases...
     
    -all() -> [start_and_stop, config, connect_and_disconnect].
    +all() -> [start_and_stop, config, connect_and_disconnect].
     
     %% test that starting and stopping works
    -start_and_stop(_) ->
    -    ServerPid = start_server(),
    -    stop_server(ServerPid).
    +start_and_stop(_) ->
    +    ServerPid = start_server(),
    +    stop_server(ServerPid).
     
     %% configuration test
    -config(Config) ->
    -    ServerPid = proplists:get_value(server_pid, Config),
    -    configure_server(ServerPid).
    +config(Config) ->
    +    ServerPid = proplists:get_value(server_pid, Config),
    +    configure_server(ServerPid).
     
     %% test connecting and disconnecting client
    -connect_and_disconnect(Config) ->
    -    ServerPid = proplists:get_value(server_pid, Config),
    -    {ok,SessionId} = my_server:connect(ServerPid),
    -    ok = my_server:disconnect(ServerPid, SessionId).
    +connect_and_disconnect(Config) ->
    +    ServerPid = proplists:get_value(server_pid, Config),
    +    {ok,SessionId} = my_server:connect(ServerPid),
    +    ok = my_server:disconnect(ServerPid, SessionId).
     
     %%% common functions...
     
    -start_server() ->
    -    {ok,ServerPid} = my_server:start(),
    +start_server() ->
    +    {ok,ServerPid} = my_server:start(),
         ServerPid.
     
    -stop_server(ServerPid) ->
    -    ok = my_server:stop(),
    +stop_server(ServerPid) ->
    +    ok = my_server:stop(),
         ok.
     
    -configure_server(ServerPid) ->
    -    ServerCfgData = ct:get_config(my_server_cfg),
    -    ok = my_server:configure(ServerPid, ServerCfgData),
    +configure_server(ServerPid) ->
    +    ServerCfgData = ct:get_config(my_server_cfg),
    +    ok = my_server:configure(ServerPid, ServerCfgData),
         ok.

    @@ -247,40 +247,40 @@

    data is to be saved by finction end_per_suite and read by function init_per_suite in the suite that follows. When passing data between suites, Saver carries the name -of the test suite.

    Example:

    -module(server_b_SUITE).
    --compile(export_all).
    --include_lib("ct.hrl").
    +of the test suite.

    Example:

    -module(server_b_SUITE).
    +-compile(export_all).
    +-include_lib("ct.hrl").
     
     %%% init and end functions...
     
    -init_per_suite(Config) ->
    +init_per_suite(Config) ->
         %% read config saved by previous test suite
    -    {server_a_SUITE,OldConfig} = proplists:get_value(saved_config, Config),
    +    {server_a_SUITE,OldConfig} = proplists:get_value(saved_config, Config),
         %% extract server identity (comes from server_a_SUITE)
    -    ServerId = proplists:get_value(server_id, OldConfig),
    -    SessionId = connect_to_server(ServerId),
    -    [{ids,{ServerId,SessionId}} | Config].
    +    ServerId = proplists:get_value(server_id, OldConfig),
    +    SessionId = connect_to_server(ServerId),
    +    [{ids,{ServerId,SessionId}} | Config].
     
    -end_per_suite(Config) ->
    +end_per_suite(Config) ->
         %% save config for server_c_SUITE (session_id and server_id)
    -    {save_config,Config}
    +    {save_config,Config}
     
     %%% test cases...
     
    -all() -> [allocate, deallocate].
    +all() -> [allocate, deallocate].
     
    -allocate(Config) ->
    -    {ServerId,SessionId} = proplists:get_value(ids, Config),
    -    {ok,Handle} = allocate_resource(ServerId, SessionId),
    +allocate(Config) ->
    +    {ServerId,SessionId} = proplists:get_value(ids, Config),
    +    {ok,Handle} = allocate_resource(ServerId, SessionId),
         %% save handle for deallocation test
    -    NewConfig = [{handle,Handle}],
    -    {save_config,NewConfig}.
    -
    -deallocate(Config) ->
    -    {ServerId,SessionId} = proplists:get_value(ids, Config),
    -    {allocate,OldConfig} = proplists:get_value(saved_config, Config),
    -    Handle = proplists:get_value(handle, OldConfig),
    -    ok = deallocate_resource(ServerId, SessionId, Handle).

    To save Config data from a test case that is to be skipped, return tuple + NewConfig = [{handle,Handle}], + {save_config,NewConfig}. + +deallocate(Config) -> + {ServerId,SessionId} = proplists:get_value(ids, Config), + {allocate,OldConfig} = proplists:get_value(saved_config, Config), + Handle = proplists:get_value(handle, OldConfig), + ok = deallocate_resource(ServerId, SessionId, Handle).

    To save Config data from a test case that is to be skipped, return tuple {skip_and_save,Reason,ConfigList}.

    The result is that the test case is skipped with Reason printed to the log file (as described earlier) and ConfigList is saved for the next test case. ConfigList can be read using proplists:get_value(saved_config, Config), as @@ -300,22 +300,22 @@

    property. Test case groups are defined through function groups/0 in the test suite (for details, see section Test Case Groups.

    For example, to ensure that if allocate in server_b_SUITE crashes, -deallocate is skipped, the following sequence can be defined:

    groups() -> [{alloc_and_dealloc, [sequence], [alloc,dealloc]}].

    Assume that the suite contains the test case get_resource_status that is -independent of the other two cases, then function all can look as follows:

    all() -> [{group,alloc_and_dealloc}, get_resource_status].

    If alloc succeeds, dealloc is also executed. If alloc fails however, +deallocate is skipped, the following sequence can be defined:

    groups() -> [{alloc_and_dealloc, [sequence], [alloc,dealloc]}].

    Assume that the suite contains the test case get_resource_status that is +independent of the other two cases, then function all can look as follows:

    all() -> [{group,alloc_and_dealloc}, get_resource_status].

    If alloc succeeds, dealloc is also executed. If alloc fails however, dealloc is not executed but marked as SKIPPED in the HTML log. get_resource_status runs no matter what happens to the alloc_and_dealloc cases.

    Test cases in a sequence are executed in order until all succeed or one fails. If one fails, all following cases in the sequence are skipped. The cases in the sequence that have succeeded up to that point are reported as successful in the -log. Any number of sequences can be specified.

    Example:

    groups() -> [{scenarioA, [sequence], [testA1, testA2]},
    -             {scenarioB, [sequence], [testB1, testB2, testB3]}].
    +log. Any number of sequences can be specified.

    Example:

    groups() -> [{scenarioA, [sequence], [testA1, testA2]},
    +             {scenarioB, [sequence], [testB1, testB2, testB3]}].
     
    -all() -> [test1,
    +all() -> [test1,
               test2,
    -          {group,scenarioA},
    +          {group,scenarioA},
               test3,
    -          {group,scenarioB},
    -          test4].

    A sequence group can have subgroups. Such subgroups can have any property, that + {group,scenarioB}, + test4].

    A sequence group can have subgroups. Such subgroups can have any property, that is, they are not required to also be sequences. If you want the status of the subgroup to affect the sequence on the level above, return {return_group_result,Status} from diff --git a/prs/8803/lib/common_test-1.27/doc/html/dist/search_data-1A83014C.js b/prs/8803/lib/common_test-1.27/doc/html/dist/search_data-1A83014C.js deleted file mode 100644 index 99c6d74ae901c..0000000000000 --- a/prs/8803/lib/common_test-1.27/doc/html/dist/search_data-1A83014C.js +++ /dev/null @@ -1 +0,0 @@ -searchData={"items":[{"type":"module","title":"ct","doc":"Main user interface for the `Common Test` framework.\n\nThis module implements the command-line interface for running tests and basic\nfunctions for `Common Test` case issues, such as configuration and logging.\n\nThe framework stores configuration values in a property list usually named\n`Config`. The list contains information about the test run added by the\nframework itself and may also contain user-provided values. The configuration is\npassed into individual test cases as well as support functions if defined.\n\nPossible configuration variables include:\n\n- `data_dir` \\- Data file directory\n- `priv_dir` \\- Scratch file directory\n- Whatever added by [`init_per_suite/1`](`c:ct_suite:init_per_suite/1`) or\n [`init_per_testcase/2`](`c:ct_suite:init_per_testcase/2`) in the test suite.\n\n> #### Warning {: .warning }\n>\n> The `?config` macro, used to receive individual config values from the\n> `Config` property list, is deprecated. Please use `proplists:get_value/2-3`\n> instead.","ref":"ct.html"},{"type":"function","title":"ct.abort_current_testcase/1","doc":"Aborts the currently executing test case. The user must know with certainty\nwhich test case is currently executing. The function is therefore only safe to\ncall from a function that has been called (or synchronously invoked) by the test\ncase.\n\n`Reason`, the reason for aborting the test case, is printed in the test case\nlog.","ref":"ct.html#abort_current_testcase/1"},{"type":"function","title":"ct.add_config/2","doc":"Loads configuration variables using the specified callback module and\nconfiguration string. The callback module is to be either loaded or present in\nthe code path. Loaded configuration variables can later be removed using\nfunction [`ct:remove_config/2`](`remove_config/2`).","ref":"ct.html#add_config/2"},{"type":"function","title":"ct.break/1","doc":"Cancels any active timetrap and pauses the execution of the current test case\nuntil the user calls function `continue/0`. The user can then interact with the\nErlang node running the tests, for example, for debugging purposes or for\nmanually executing a part of the test case. If a parallel group is executing,\n[`ct:break/2`](`break/2`) is to be called instead.\n\nA cancelled timetrap is not automatically reactivated after the break, but must\nbe started explicitly with [`ct:timetrap/1`](`timetrap/1`).\n\nIn order for the break/continue functionality to work, `Common Test` must\nrelease the shell process controlling `stdin`. This is done by setting start\noption `release_shell` to `true`. For details, see section\n[Running Tests from the Erlang Shell or from an Erlang Program](run_test_chapter.md#erlang_shell_or_program)\nin the User's Guide.","ref":"ct.html#break/1"},{"type":"function","title":"ct.break/2","doc":"Works the same way as [`ct:break/1`](`break/1`), only argument `TestCase` makes\nit possible to pause a test case executing in a parallel group. Function\n[`ct:continue/1`](`continue/1`) is to be used to resume execution of `TestCase`.\n\nFor details, see [`ct:break/1`](`break/1`).","ref":"ct.html#break/2"},{"type":"function","title":"ct.capture_get/0","doc":"","ref":"ct.html#capture_get/0"},{"type":"function","title":"ct.capture_get/1","doc":"Returns and purges the list of text strings buffered during the latest session\nof capturing printouts to `stdout`. Log categories that are to be ignored in\n`ListOfStrings` can be specified with `ExclCategories`. If\n`ExclCategories = []`, no filtering takes place.\n\nSee also [`ct:capture_start/0`](`capture_start/0`),\n[`ct:capture_stop/0`](`capture_stop/0`), [`ct:log/3`](`log/3`).","ref":"ct.html#capture_get/1"},{"type":"function","title":"ct.capture_start/0","doc":"Starts capturing all text strings printed to `stdout` during execution of the\ntest case.\n\nSee also [`ct:capture_get/1`](`capture_get/1`),\n[`ct:capture_stop/0`](`capture_stop/0`).","ref":"ct.html#capture_start/0"},{"type":"function","title":"ct.capture_stop/0","doc":"Stops capturing text strings (a session started with `capture_start/0`).\n\nSee also [`ct:capture_get/1`](`capture_get/1`),\n[`ct:capture_start/0`](`capture_start/0`).","ref":"ct.html#capture_stop/0"},{"type":"function","title":"ct.comment/1","doc":"Prints the specified `Comment` in the comment field in the table on the test\nsuite result page.\n\nIf called several times, only the last comment is printed. The test case return\nvalue `{comment,Comment}` overwrites the string set by this function.","ref":"ct.html#comment/1"},{"type":"function","title":"ct.comment/2","doc":"Prints the formatted string in the comment field in the table on the test suite\nresult page.\n\nArguments `Format` and `Args` are used in a call to `io_lib:format/2` to create\nthe comment string. The behavior of [`comment/2`](`comment/2`) is otherwise the\nsame as function [`ct:comment/1`](`comment/1`).","ref":"ct.html#comment/2"},{"type":"function","title":"ct.continue/0","doc":"This function must be called to continue after a test case (not executing in a\nparallel group) has called function [`ct:break/1`](`break/1`).","ref":"ct.html#continue/0"},{"type":"function","title":"ct.continue/1","doc":"This function must be called to continue after a test case has called\n[`ct:break/2`](`break/2`). If the paused test case, `TestCase`, executes in a\nparallel group, this function, rather than `continue/0`, must be used to let the\ntest case proceed.","ref":"ct.html#continue/1"},{"type":"function","title":"ct.decrypt_config_file/2","doc":"Decrypts `EncryptFileName`, previously generated with\n[`ct:encrypt_config_file/2,3`](`encrypt_config_file/2`). The original file\ncontents is saved in the target file. The encryption key, a string, must be\navailable in a text file named `.ct_config.crypt`, either in the current\ndirectory, or the home directory of the user (it is searched for in that order).","ref":"ct.html#decrypt_config_file/2"},{"type":"function","title":"ct.decrypt_config_file/3","doc":"Decrypts `EncryptFileName`, previously generated with\n[`ct:encrypt_config_file/2,3`](`encrypt_config_file/2`). The original file\ncontents is saved in the target file. The key must have the same value as that\nused for encryption.","ref":"ct.html#decrypt_config_file/3"},{"type":"function","title":"ct.encrypt_config_file/2","doc":"Encrypts the source configuration file with DES3 and saves the result in file\n`EncryptFileName`. The key, a string, must be available in a text file named\n`.ct_config.crypt`, either in the current directory, or the home directory of\nthe user (it is searched for in that order).\n\nFor information about using encrypted configuration files when running tests,\nsee section\n[Encrypted Configuration Files](config_file_chapter.md#encrypted_config_files)\nin the User's Guide.\n\nFor details on DES3 encryption/decryption, see application\n[`Crypto`](`e:crypto:index.html`).","ref":"ct.html#encrypt_config_file/2"},{"type":"function","title":"ct.encrypt_config_file/3","doc":"Encrypts the source configuration file with DES3 and saves the result in the\ntarget file `EncryptFileName`. The encryption key to use is either the value in\n`{key,Key}` or the value stored in the file specified by `{file,File}`.\n\nFor information about using encrypted configuration files when running tests,\nsee section\n[Encrypted Configuration Files](config_file_chapter.md#encrypted_config_files)\nin the User's Guide.\n\nFor details on DES3 encryption/decryption, see application\n[`Crypto`](`e:crypto:index.html`).","ref":"ct.html#encrypt_config_file/3"},{"type":"function","title":"ct.fail/1","doc":"Terminates a test case with the specified error `Reason`.","ref":"ct.html#fail/1"},{"type":"function","title":"ct.fail/2","doc":"Terminates a test case with an error message specified by a format string and a\nlist of values (used as arguments to `io_lib:format/2`).","ref":"ct.html#fail/2"},{"type":"function","title":"ct.get_config/1","doc":"","ref":"ct.html#get_config/1"},{"type":"function","title":"ct.get_config/2","doc":"","ref":"ct.html#get_config/2"},{"type":"function","title":"ct.get_config/3","doc":"Reads configuration data values.\n\nReturns the matching values or configuration elements, given a configuration\nvariable key or its associated name (if one has been specified with\n[`ct:require/2`](`require/2`) or a `require` statement).\n\n_Example:_\n\nGiven the following configuration file:\n\n```erlang\n{unix,[{telnet,IpAddr},\n {user,[{username,Username},\n {password,Password}]}]}.\n```\n\nThen:\n\n```erlang\nct:get_config(unix,Default) -> [{telnet,IpAddr},\n {user, [{username,Username}, {password,Password}]}]\nct:get_config({unix,telnet},Default) -> IpAddr\nct:get_config({unix,user,username},Default) -> Username\nct:get_config({unix,ftp},Default) -> Default\nct:get_config(unknownkey,Default) -> Default\n```\n\nIf a configuration variable key has been associated with a name (by\n[`ct:require/2`](`require/2`) or a `require` statement), the name can be used\ninstead of the key to read the value:\n\n```erlang\nct:require(myuser,{unix,user}) -> ok.\nct:get_config(myuser,Default) -> [{username,Username}, {password,Password}]\n```\n\nIf a configuration variable is defined in multiple files, use option `all` to\naccess all possible values. The values are returned in a list. The order of the\nelements corresponds to the order that the configuration files were specified at\nstartup.\n\nIf configuration elements (key-value tuples) are to be returned as result\ninstead of values, use option `element`. The returned elements are then on the\nform `{Required,Value}`.\n\nSee also [`ct:get_config/1`](`get_config/1`),\n[`ct:get_config/2`](`get_config/2`), [`ct:require/1`](`require/1`),\n[`ct:require/2`](`require/2`).","ref":"ct.html#get_config/3"},{"type":"function","title":"ct.get_event_mgr_ref/0","doc":"Gets a reference to the `Common Test` event manager. The reference can be used\nto, for example, add a user-specific event handler while tests are running.\n\n_Example:_\n\n```erlang\ngen_event:add_handler(ct:get_event_mgr_ref(), my_ev_h, [])\n```","ref":"ct.html#get_event_mgr_ref/0"},{"type":"function","title":"ct.get_progname/0","doc":"Returns the command used to start this Erlang instance. If this information\ncould not be found, the string `\"no_prog_name\"` is returned.","ref":"ct.html#get_progname/0"},{"type":"function","title":"ct.get_status/0","doc":"Returns status of ongoing test. The returned list contains information about\nwhich test case is executing (a list of cases when a parallel test case group is\nexecuting), as well as counters for successful, failed, skipped, and total test\ncases so far.","ref":"ct.html#get_status/0"},{"type":"function","title":"ct.get_target_name/1","doc":"Returns the name of the target that the specified connection belongs to.","ref":"ct.html#get_target_name/1"},{"type":"function","title":"ct.get_testspec_terms/0","doc":"Gets a list of all test specification terms used to configure and run this test.","ref":"ct.html#get_testspec_terms/0"},{"type":"function","title":"ct.get_testspec_terms/1","doc":"Reads one or more terms from the test specification used to configure and run\nthis test. `Tag` is any valid test specification tag, for example, `label`,\n`config`, or `logdir`. User-specific terms are also available to read if option\n`allow_user_terms` is set.\n\nAll value tuples returned, except user terms, have the node name as first\nelement.\n\nTo read test terms, use `Tag = tests` (rather than `suites`, `groups`, or\n`cases`). `Value` is then the list of _all_ tests on the form\n`[{Node,Dir,[{TestSpec,GroupsAndCases1},...]},...]`, where\n`GroupsAndCases = [{Group,[Case]}] | [Case]`.","ref":"ct.html#get_testspec_terms/1"},{"type":"function","title":"ct.get_timetrap_info/0","doc":"Reads information about the timetrap set for the current test case. `Scaling`\nindicates if `Common Test` will attempt to compensate timetraps automatically\nfor runtime delays introduced by, for example, tools like cover. `ScaleVal` is\nthe value of the current scaling multiplier (always 1 if scaling is disabled).\nNote the `Time` is not the scaled result.","ref":"ct.html#get_timetrap_info/0"},{"type":"function","title":"ct.get_verbosity/1","doc":"This function returns the verbosity level for the specified logging category.\nSee the [User's Guide](write_test_chapter.md#logging) for details. Use the value\n`default` to read the general verbosity level.","ref":"ct.html#get_verbosity/1"},{"type":"function","title":"ct.install/1","doc":"Installs configuration files and event handlers.\n\nRun this function once before the first test.\n\n_Example:_\n\n```erlang\ninstall([{config,[\"config_node.ctc\",\"config_user.ctc\"]}])\n```\n\nThis function is automatically run by program `ct_run`.","ref":"ct.html#install/1"},{"type":"function","title":"ct.listenv/1","doc":"Performs command `listenv` on the specified Telnet connection and returns the\nresult as a list of key-value pairs.","ref":"ct.html#listenv/1"},{"type":"function","title":"ct.log/1","doc":"Equivalent to [`log(default, ?STD_IMPORTANCE, Format, [], [])`](`log/5`).","ref":"ct.html#log/1"},{"type":"function","title":"ct.log/2","doc":"","ref":"ct.html#log/2"},{"type":"function","title":"ct.log/3","doc":"","ref":"ct.html#log/3"},{"type":"function","title":"ct.log/4","doc":"","ref":"ct.html#log/4"},{"type":"function","title":"ct.log/5","doc":"Prints from a test case to the log file.\n\nThis function is meant for printing a string directly from a test case to the\ntest case log file.\n\nDefault `Category` is `default`, default `Importance` is `?STD_IMPORTANCE`, and\ndefault value for `FormatArgs` is `[]`.\n\nFor details on `Category`, `Importance` and the `no_css` option, see section\n[Logging - Categories and Verbosity Levels](write_test_chapter.md#logging) in\nthe User's Guide.\n\nCommon Test will not escape special HTML characters (<, > and &) in the text\nprinted with this function, unless the `esc_chars` option is used.","ref":"ct.html#log/5"},{"type":"function","title":"ct.make_priv_dir/0","doc":"If the test is started with option `create_priv_dir` set to `manual_per_tc`, in\norder for the test case to use the private directory, it must first create it by\ncalling this function.","ref":"ct.html#make_priv_dir/0"},{"type":"function","title":"ct.notify/2","doc":"Sends an asynchronous notification of type `Name` with `Data`to the Common Test\nevent manager. This can later be caught by any installed event manager.\n\nSee also `m:gen_event`.","ref":"ct.html#notify/2"},{"type":"function","title":"ct.pal/1","doc":"Equivalent to [`pal(default, ?STD_IMPORTANCE, Format, [])`](`pal/4`).","ref":"ct.html#pal/1"},{"type":"function","title":"ct.pal/2","doc":"","ref":"ct.html#pal/2"},{"type":"function","title":"ct.pal/3","doc":"","ref":"ct.html#pal/3"},{"type":"function","title":"ct.pal/4","doc":"","ref":"ct.html#pal/4"},{"type":"function","title":"ct.pal/5","doc":"Prints and logs from a test case.\n\nThis function is meant for printing a string from a test case, both to the test\ncase log file and to the console.\n\nDefault `Category` is `default`, default `Importance` is `?STD_IMPORTANCE`, and\ndefault value for `FormatArgs` is `[]`.\n\nFor details on `Category` and `Importance`, see section\n[Logging - Categories and Verbosity Levels](write_test_chapter.md#logging) in\nthe User's Guide.\n\nNote that special characters in the text (<, > and &) will be escaped by Common\nTest before the text is printed to the log file.","ref":"ct.html#pal/5"},{"type":"function","title":"ct.parse_table/1","doc":"Parses the printout from an SQL table and returns a list of tuples.\n\nThe printout to parse is typically the result of a `select` command in SQL. The\nreturned `Table` is a list of tuples, where each tuple is a row in the table.\n\n`Heading` is a tuple of strings representing the headings of each column in the\ntable.","ref":"ct.html#parse_table/1"},{"type":"function","title":"ct.print/1","doc":"Equivalent to [`print(default, ?STD_IMPORTANCE, Format, [], [])`](`print/5`).","ref":"ct.html#print/1"},{"type":"function","title":"ct.print/2","doc":"","ref":"ct.html#print/2"},{"type":"function","title":"ct.print/3","doc":"","ref":"ct.html#print/3"},{"type":"function","title":"ct.print/4","doc":"","ref":"ct.html#print/4"},{"type":"function","title":"ct.print/5","doc":"Prints from a test case to the console.\n\nThis function is meant for printing a string from a test case to the console.\n\nDefault `Category` is `default`, default `Importance` is `?STD_IMPORTANCE`, and\ndefault value for `FormatArgs` is `[]`.\n\nFor details on `Category` and `Importance`, see section\n[Logging - Categories and Verbosity Levels](write_test_chapter.md#logging) in\nthe User's Guide.","ref":"ct.html#print/5"},{"type":"function","title":"ct.reload_config/1","doc":"Reloads configuration file containing specified configuration key.\n\nThis function updates the configuration data from which the specified\nconfiguration variable was read, and returns the (possibly) new value of this\nvariable.\n\nIf some variables were present in the configuration, but are not loaded using\nthis function, they are removed from the configuration table together with their\naliases.","ref":"ct.html#reload_config/1"},{"type":"function","title":"ct.remaining_test_procs/0","doc":"This function will return the identity of test- and group leader processes that\nare still running at the time of this call. `TestProcs` are processes in the\nsystem that have a Common Test IO process as group leader. `SharedGL` is the\ncentral Common Test IO process, responsible for printing to log files for\nconfiguration functions and sequentially executing test cases. `OtherGLs` are\nCommon Test IO processes that print to log files for test cases in parallel test\ncase groups.\n\nThe process information returned by this function may be used to locate and\nterminate remaining processes after tests have finished executing. The function\nwould typically by called from Common Test Hook functions.\n\nNote that processes that execute configuration functions or test cases are never\nincluded in `TestProcs`. It is therefore safe to use post configuration hook\nfunctions (such as post_end_per_suite, post_end_per_group,\npost_end_per_testcase) to terminate all processes in `TestProcs` that have the\ncurrent group leader process as its group leader.\n\nNote also that the shared group leader (`SharedGL`) must never be terminated by\nthe user, only by Common Test. Group leader processes for parallel test case\ngroups (`OtherGLs`) may however be terminated in post_end_per_group hook\nfunctions.","ref":"ct.html#remaining_test_procs/0"},{"type":"function","title":"ct.remove_config/2","doc":"Removes configuration variables (together with their aliases) that were loaded\nwith specified callback module and configuration string.","ref":"ct.html#remove_config/2"},{"type":"function","title":"ct.require/1","doc":"Checks if the required configuration is available. Arbitrarily deep tuples can\nbe specified as `Required`. Only the last element of the tuple can be a list of\n`SubKey`s.\n\n_Example 1._ Require the variable `myvar`:\n\n```erlang\nok = ct:require(myvar).\n```\n\nIn this case the configuration file must at least contain:\n\n```erlang\n{myvar,Value}.\n```\n\n_Example 2._ Require key `myvar` with subkeys `sub1` and `sub2`:\n\n```erlang\nok = ct:require({myvar,[sub1,sub2]}).\n```\n\nIn this case the configuration file must at least contain:\n\n```erlang\n{myvar,[{sub1,Value},{sub2,Value}]}.\n```\n\n_Example 3._ Require key `myvar` with subkey `sub1` with `subsub1`:\n\n```erlang\nok = ct:require({myvar,sub1,sub2}).\n```\n\nIn this case the configuration file must at least contain:\n\n```erlang\n{myvar,[{sub1,[{sub2,Value}]}]}.\n```\n\nSee also [`ct:get_config/1`](`get_config/1`),\n[`ct:get_config/2`](`get_config/2`), [`ct:get_config/3`](`get_config/3`),\n[`ct:require/2`](`require/2`).","ref":"ct.html#require/1"},{"type":"function","title":"ct.require/2","doc":"Checks if the required configuration is available and gives it a name. The\nsemantics for `Required` is the same as in [`ct:require/1`](`require/1`) except\nthat a list of `SubKey`s cannot be specified.\n\nIf the requested data is available, the subentry is associated with `Name` so\nthat the value of the element can be read with\n[`ct:get_config/1,2`](`get_config/1`) provided `Name` is used instead of the\nwhole `Required` term.\n\n_Example:_\n\nRequire one node with a Telnet connection and an FTP connection. Name the node\n`a`:\n\n```erlang\nok = ct:require(a,{machine,node}).\n```\n\nAll references to this node can then use the node name. For example, a file over\nFTP is fetched like follows:\n\n```erlang\nok = ct:ftp_get(a,RemoteFile,LocalFile).\n```\n\nFor this to work, the configuration file must at least contain:\n\n```erlang\n{machine,[{node,[{telnet,IpAddr},{ftp,IpAddr}]}]}.\n```\n\n> #### Note {: .info }\n>\n> The behavior of this function changed radically in `Common Test` 1\\.6.2. To\n> keep some backwards compatibility, it is still possible to do:\n> `ct:require(a,{node,[telnet,ftp]}).` This associates the name `a` with the\n> top-level `node` entry. For this to work, the configuration file must at least\n> contain: `{node,[{telnet,IpAddr},{ftp,IpAddr}]}.`\n\nSee also [`ct:get_config/1`](`get_config/1`),\n[`ct:get_config/2`](`get_config/2`), [`ct:get_config/3`](`get_config/3`),\n[`ct:require/1`](`require/1`).","ref":"ct.html#require/2"},{"type":"function","title":"ct.run/1","doc":"Runs all test cases in all suites in the specified directories.\n\nSee also [`ct:run/3`](`run/3`).","ref":"ct.html#run/1"},{"type":"function","title":"ct.run/2","doc":"Runs all test cases in the specified suite.\n\nSee also [`ct:run/3`](`run/3`).","ref":"ct.html#run/2"},{"type":"function","title":"ct.run/3","doc":"Runs the specified test cases.\n\nRequires that [`ct:install/1`](`install/1`) has been run first.\n\nSuites (`*_SUITE.erl`) files must be stored in `TestDir` or `TestDir/test`. All\nsuites are compiled when the test is run.","ref":"ct.html#run/3"},{"type":"function","title":"ct.run_test/1","doc":"Runs tests as specified by the combination of options in `Opts`. The options are\nthe same as those used with program `ct_run`, see\n[Run Tests from Command Line](ct_run_cmd.md#ct_run) in the `ct_run` manual page.\n\nHere a `TestDir` can be used to point out the path to a `Suite`. Option\n`testcase` corresponds to option `-case` in program `ct_run`. Configuration\nfiles specified in `Opts` are installed automatically at startup.\n\n`TestRunnerPid` is returned if `release_shell == true`. For details, see\n[`ct:break/1`](`break/1`).\n\n`Reason` indicates the type of error encountered.","ref":"ct.html#run_test/1"},{"type":"function","title":"ct.run_testspec/1","doc":"Runs a test specified by `TestSpec`. The same terms are used as in test\nspecification files.\n\n`Reason` indicates the type of error encountered.","ref":"ct.html#run_testspec/1"},{"type":"function","title":"ct.set_verbosity/2","doc":"Use this function to set, or modify, the verbosity level for a logging category.\nSee the [User's Guide](write_test_chapter.md#logging) for details. Use the value\n`default` to set the general verbosity level.","ref":"ct.html#set_verbosity/2"},{"type":"function","title":"ct.sleep/1","doc":"This function, similar to `timer:sleep/1` in STDLIB, suspends the test case for\na specified time. However, this function also multiplies `Time` with the\n`multiply_timetraps` value (if set) and under certain circumstances also scales\nup the time automatically if `scale_timetraps` is set to `true` (default is\n`false`).","ref":"ct.html#sleep/1"},{"type":"function","title":"ct.start_interactive/0","doc":"Starts `Common Test` in interactive mode.\n\nFrom this mode, all test case support functions can be executed directly from\nthe Erlang shell. The interactive mode can also be started from the OS command\nline with `ct_run -shell [-config File...]`.\n\nIf any functions (for example, Telnet or FTP) using \"required configuration\ndata\" are to be called from the Erlang shell, configuration data must first be\nrequired with [`ct:require/2`](`require/2`).\n\n_Example:_\n\n```erlang\n> ct:require(unix_telnet, unix).\nok\n> ct_telnet:open(unix_telnet).\n{ok,<0.105.0>}\n> ct_telnet:cmd(unix_telnet, \"ls .\").\n{ok,[\"ls\",\"file1 ...\",...]}\n```","ref":"ct.html#start_interactive/0"},{"type":"function","title":"ct.step/3","doc":"Steps through a test case with the debugger.\n\nSee also [`ct:run/3`](`run/3`).","ref":"ct.html#step/3"},{"type":"function","title":"ct.step/4","doc":"Steps through a test case with the debugger. If option `config` has been\nspecified, breakpoints are also set on the configuration functions in `Suite`.\n\nSee also [`ct:run/3`](`run/3`).","ref":"ct.html#step/4"},{"type":"function","title":"ct.stop_interactive/0","doc":"Exits the interactive mode.\n\nSee also [`ct:start_interactive/0`](`start_interactive/0`).","ref":"ct.html#stop_interactive/0"},{"type":"function","title":"ct.sync_notify/2","doc":"Sends a synchronous notification of type `Name` with `Data` to the `Common Test`\nevent manager. This can later be caught by any installed event manager.\n\nSee also `m:gen_event`.","ref":"ct.html#sync_notify/2"},{"type":"function","title":"ct.testcases/2","doc":"Returns all test cases in the specified suite.","ref":"ct.html#testcases/2"},{"type":"function","title":"ct.timetrap/1","doc":"Sets a new timetrap for the running test case.\n\nIf the argument is `Func`, the timetrap is triggered when this function returns.\n`Func` can also return a new `Time` value, which in that case is the value for\nthe new timetrap.","ref":"ct.html#timetrap/1"},{"type":"function","title":"ct.userdata/2","doc":"Returns any data specified with tag `userdata` in the list of tuples returned\nfrom [`suite/0`](`c:ct_suite:suite/0`).","ref":"ct.html#userdata/2"},{"type":"function","title":"ct.userdata/3","doc":"Returns any data specified with tag `userdata` in the list of tuples returned\nfrom `Suite:group(GroupName)` or `Suite:Case()`.","ref":"ct.html#userdata/3"},{"type":"type","title":"ct.config_key/0","doc":"A configuration key which exists in a configuration file","ref":"ct.html#t:config_key/0"},{"type":"type","title":"ct.conn_log_mod/0","doc":"","ref":"ct.html#t:conn_log_mod/0"},{"type":"type","title":"ct.conn_log_option/0","doc":"","ref":"ct.html#t:conn_log_option/0"},{"type":"type","title":"ct.conn_log_options/0","doc":"Options that can be given to the `cth_conn_log` hook, which is used for logging\nof NETCONF and Telnet connections. See [ct_netconfc](`m:ct_netconfc#Logging`) or\n[ct_telnet](`m:ct_telnet#module-logging`) for description and examples of how to use\nthis hook.","ref":"ct.html#t:conn_log_options/0"},{"type":"type","title":"ct.conn_log_type/0","doc":"","ref":"ct.html#t:conn_log_type/0"},{"type":"type","title":"ct.handle/0","doc":"The identity (handle) of a connection.","ref":"ct.html#t:handle/0"},{"type":"type","title":"ct.key_or_name/0","doc":"","ref":"ct.html#t:key_or_name/0"},{"type":"type","title":"ct.target_name/0","doc":"A name and association to configuration data introduced through a require\nstatement, or a call to [`ct:require/2`](`require/2`), for example,\n`ct:require(mynodename,{node,[telnet]})`.","ref":"ct.html#t:target_name/0"},{"type":"module","title":"ct_cover","doc":"`Common Test` framework code coverage support module.\n\nThis module exports help functions for performing code coverage analysis.","ref":"ct_cover.html"},{"type":"function","title":"ct_cover.add_nodes/1","doc":"Adds nodes to current cover test. Notice that this only works if cover support\nis active.\n\nTo have effect, this function is to be called from `init_per_suite/1` (see\n`m:ct_suite`) before any tests are performed.","ref":"ct_cover.html#add_nodes/1"},{"type":"function","title":"ct_cover.cross_cover_analyse/2","doc":"Accumulates cover results over multiple tests. See section\n[Cross Cover Analysis](cover_chapter.md#cross_cover) in the User's Guide.","ref":"ct_cover.html#cross_cover_analyse/2"},{"type":"function","title":"ct_cover.remove_nodes/1","doc":"Removes nodes from the current cover test.\n\nCall this function to stop cover test on nodes previously added with\n[`ct_cover:add_nodes/1`](`add_nodes/1`). Results on the remote node are\ntransferred to the `Common Test` node.","ref":"ct_cover.html#remove_nodes/1"},{"type":"module","title":"ct_ftp","doc":"FTP client module (based on the `ftp` application).","ref":"ct_ftp.html"},{"type":"function","title":"ct_ftp.cd/2","doc":"Changes directory on remote host.","ref":"ct_ftp.html#cd/2"},{"type":"function","title":"ct_ftp.close/1","doc":"Closes the FTP connection.","ref":"ct_ftp.html#close/1"},{"type":"function","title":"ct_ftp.delete/2","doc":"Deletes a file on remote host.","ref":"ct_ftp.html#delete/2"},{"type":"function","title":"ct_ftp.get/3","doc":"Opens an FTP connection and fetches a file from the remote host.\n\n`RemoteFile` and `LocalFile` must be absolute paths.\n\nThe configuration file must be as for [`ct_ftp:put/3`](`put/3`).\n\nSee also `ct:require/2`.","ref":"ct_ftp.html#get/3"},{"type":"function","title":"ct_ftp.ls/2","doc":"Lists directory `Dir`.","ref":"ct_ftp.html#ls/2"},{"type":"function","title":"ct_ftp.open/1","doc":"Opens an FTP connection to the specified node.\n\nYou can open a connection for a particular `Name` and use the same name as\nreference for all following subsequent operations. If you want the connection to\nbe associated with `Handle` instead (if you, for example, need to open multiple\nconnections to a host), use `Key`, the configuration variable name, to specify\nthe target. A connection without an associated target name can only be closed\nwith the handle value.\n\nFor information on how to create a new `Name`, see `ct:require/2`.","ref":"ct_ftp.html#open/1"},{"type":"function","title":"ct_ftp.put/3","doc":"Opens an FTP connection and sends a file to the remote host.\n\n`LocalFile` and `RemoteFile` must be absolute paths.\n\nIf the target host is a \"special\" node, the FTP address must be specified in the\nconfiguration file as follows:\n\n```erlang\n{node,[{ftp,IpAddr}]}.\n```\n\nIf the target host is something else, for example, a UNIX host, the\nconfiguration file must also include the username and password (both strings):\n\n```erlang\n{unix,[{ftp,IpAddr},\n {username,Username},\n {password,Password}]}.\n```\n\nSee also `ct:require/2`.","ref":"ct_ftp.html#put/3"},{"type":"function","title":"ct_ftp.recv/2","doc":"Fetches a file over FTP.\n\nThe file gets the same name on the local host.\n\nSee also [`ct_ftp:recv/3`](`recv/3`).","ref":"ct_ftp.html#recv/2"},{"type":"function","title":"ct_ftp.recv/3","doc":"Fetches a file over FTP.\n\nThe file is named `LocalFile` on the local host.","ref":"ct_ftp.html#recv/3"},{"type":"function","title":"ct_ftp.send/2","doc":"Sends a file over FTP.\n\nThe file gets the same name on the remote host.\n\nSee also [`ct_ftp:send/3`](`send/3`).","ref":"ct_ftp.html#send/2"},{"type":"function","title":"ct_ftp.send/3","doc":"Sends a file over FTP.\n\nThe file is named `RemoteFile` on the remote host.","ref":"ct_ftp.html#send/3"},{"type":"function","title":"ct_ftp.type/2","doc":"Changes the file transfer type.","ref":"ct_ftp.html#type/2"},{"type":"type","title":"ct_ftp.connection/0","doc":"Reference to opened FTP connection associated to either a `handle` or `target_name`.","ref":"ct_ftp.html#t:connection/0"},{"type":"type","title":"ct_ftp.handle/0","doc":"Handle for a specific FTP connection, see module `m:ct`.","ref":"ct_ftp.html#t:handle/0"},{"type":"behaviour","title":"ct_hooks","doc":"A callback interface on top of Common Test.\n\nThe _Common Test Hook (CTH)_ framework allows extensions of the default behavior\nof `Common Test` by callbacks before and after all test suite calls. It is\nintended for advanced users of `Common Test` who want to abstract out behavior\nthat is common to multiple test suites.\n\nIn brief, CTH allows you to:\n\n- Manipulate the runtime configuration before each suite configuration call.\n- Manipulate the return of all suite configuration calls and by extension the\n result of the test themselves.\n\nThe following sections describe the mandatory and optional CTH functions that\n`Common Test` calls during test execution. For more details, see section\n[Common Test Hooks](ct_hooks_chapter.md) in the User's Guide.\n\nFor information about how to add a CTH to your suite, see section\n[Installing a CTH](ct_hooks_chapter.md#installing) in the User's Guide.\n\n> #### Note {: .info }\n>\n> For a minimal example of a CTH, see section\n> [Example CTH](ct_hooks_chapter.md#example) in the User's Guide.","ref":"ct_hooks.html"},{"type":"callback","title":"ct_hooks.id/1","doc":"The `Id` identifies a CTH instance uniquely. If two CTHs return the same `Id`,\nthe second CTH is ignored and subsequent calls to the CTH are only made to the\nfirst instance. For details, see section\n[Installing a CTH](ct_hooks_chapter.md#installing) in the User's Guide.\n\nThis function is _not_ to have any side effects, as it can be called multiple\ntimes by `Common Test`.\n\nIf not implemented, the CTH acts as if this function returned a call to\n`make_ref/0`.","ref":"ct_hooks.html#c:id/1"},{"type":"callback","title":"ct_hooks.init/2","doc":"This function is always called before any other callback function. Use it to\ninitiate any common state. It is to return a state for this CTH.\n\n`Id` is either the return value of [`ct_hooks:id/1`](`c:id/1`), or a `reference`\n(created using `erlang:make_ref/0` in ERTS) if [`ct_hooks:id/1`](`c:id/1`) is\nnot implemented.\n\n`Priority` is the relative priority of this hook. Hooks with a lower priority\nare executed first. If no priority is specified, it is set to `0`.\n\nFor details about hook execution order, see section\n[CTH Execution Order](ct_hooks_chapter.md#cth_execution_order) in the User's\nGuide.\n\nFor details about when `init` is called, see section\n[CTH Scope](ct_hooks_chapter.md#scope) in the User's Guide.","ref":"ct_hooks.html#c:init/2"},{"type":"callback","title":"ct_hooks.on_tc_fail/4","doc":"This function is called whenever a test case (or configuration function) fails.\nIt is called after the post function is called for the failed test case.\n\nThat is:\n\n- If `init_per_suite` fails, this function is called after\n [`post_init_per_suite`](`c:post_init_per_suite/4`).\n- If a test case fails, this function is called after\n [`post_end_per_testcase`](`c:post_end_per_testcase/5`).\n\nIf the failed test case belongs to a test case group, the second argument is a\ntuple `{FuncName,GroupName}`, otherwise only the function name.\n\nThe data that comes with `Reason` follows the same format as\n[`FailReason`](event_handler_chapter.md#failreason) in event\n[`tc_done`](event_handler_chapter.md#tc_done). For details, see section\n[Event Handling](event_handler_chapter.md#events) in the User's Guide.\n\nIf [`Module:on_tc_fail/4`](`c:on_tc_fail/4`) is not exported, common_test will\nattempt to call `Module:on_tc_fail(TestName, Reason, CTHState)` instead. This is\nfor backwards compatibility.","ref":"ct_hooks.html#c:on_tc_fail/4"},{"type":"callback","title":"ct_hooks.on_tc_skip/4","doc":"This function is called whenever a test case (or configuration function) is\nskipped. It is called after the post function is called for the skipped test\ncase.\n\nThat is:\n\n- If `init_per_group` is skipped, this function is called after\n [`post_init_per_group`](`c:post_init_per_group/5`).\n- If a test case is skipped, this function is called after\n [`post_end_per_testcase`](`c:post_end_per_testcase/5`).\n\nIf the skipped test case belongs to a test case group, the second argument is a\ntuple `{FuncName,GroupName}`, otherwise only the function name.\n\nThe data that comes with `Reason` follows the same format as events\n[`tc_auto_skip`](event_handler_chapter.md#tc_auto_skip) and\n[`tc_user_skip`](event_handler_chapter.md#tc_user_skip) For details, see section\n[Event Handling](event_handler_chapter.md#events) in the User's Guide.\n\nIf [`Module:on_tc_skip/4`](`c:on_tc_skip/4`) is not exported, common_test will\nattempt to call `Module:on_tc_skip(TestName, Reason, CTHState)` instead. This is\nfor backwards compatibility.","ref":"ct_hooks.html#c:on_tc_skip/4"},{"type":"callback","title":"ct_hooks.post_all/3","doc":"This function is called after [`all/0`](`c:ct_suite:all/0`). It is used to\nmodify the set of test cases and test group to be executed, for instance to add\nor remove test cases and groups, change group properties, or even skip all tests\nin the suite.\n\n`Return` is what [`all/0`](`c:ct_suite:all/0`) returned, that is, a list of test\ncases and groups to be executed, or a tuple `{skip,Reason}`.\n\n`GroupDefs` is what [`groups/0`](`c:ct_suite:groups/0`) or the\n[`post_groups/2`](`c:post_groups/2`) hook returned, that is, a list of group\ndefinitions.\n\n`NewReturn` is the possibly modified version of `Return`.\n\nThis function is called only if the CTH is added before `init_per_suite` is run.\nFor details, see section [CTH Scope](ct_hooks_chapter.md#scope) in the User's\nGuide.\n\nNotice that for CTHs that are installed by means of the\n[`suite/0`](`c:ct_suite:suite/0`) function, `post_all/2` is called before the\n`c:init/2` hook function. However, for CTHs that are installed by means of the\nCT start flag, the `c:init/2` function is called first.\n\n> #### Note {: .info }\n>\n> Prior to each test execution, Common Test does a simulated test run in order\n> to count test suites, groups and cases for logging purposes. This causes the\n> [`post_all/3`](`c:post_all/3`) hook function to always be called twice. For\n> this reason, side effects are best avoided in this callback.","ref":"ct_hooks.html#c:post_all/3"},{"type":"callback","title":"ct_hooks.post_end_per_group/5","doc":"This function is called after [`end_per_group`](`c:ct_suite:end_per_group/2`) if\nit exists. It behaves the same way as\n[`post_init_per_suite`](`c:post_init_per_suite/4`), but for function\n[end_per_group](`c:ct_suite:end_per_group/2`) instead.\n\nIf [`Module:post_end_per_group/5`](`c:post_end_per_group/5`) is not exported,\ncommon_test will attempt to call\n`Module:post_end_per_group(GroupName, Config, Return, CTHState)` instead. This\nis for backwards compatibility.","ref":"ct_hooks.html#c:post_end_per_group/5"},{"type":"callback","title":"ct_hooks.post_end_per_suite/4","doc":"This function is called after [`end_per_suite`](`c:ct_suite:end_per_suite/1`) if\nit exists. It behaves the same way as\n[`post_init_per_suite`](`c:post_init_per_suite/4`), but for function\n[`end_per_suite`](`c:ct_suite:end_per_suite/1`) instead.","ref":"ct_hooks.html#c:post_end_per_suite/4"},{"type":"callback","title":"ct_hooks.post_end_per_testcase/5","doc":"This function is called after\n[`end_per_testcase`](`c:ct_suite:end_per_testcase/2`) if it exists. It behaves\nthe same way as [`post_end_per_suite`](`c:post_end_per_suite/4`), but for\nfunction [`end_per_testcase`](`c:ct_suite:end_per_testcase/2`) instead.\n\nIf [`Module:post_end_per_testcase/5`](`c:post_end_per_testcase/5`) is not\nexported, common_test will attempt to call\n`Module:post_end_per_testcase(TestcaseName, Config, Return, CTHState)` instead.\nThis is for backwards compatibility.","ref":"ct_hooks.html#c:post_end_per_testcase/5"},{"type":"callback","title":"ct_hooks.post_groups/2","doc":"This function is called after [`groups/0`](`c:ct_suite:groups/0`). It is used to\nmodify the test group definitions, for instance to add or remove groups or\nchange group properties.\n\n`GroupDefs` is what [`groups/0`](`c:ct_suite:groups/0`) returned, that is, a\nlist of group definitions.\n\n`NewGroupDefs` is the possibly modified version of this list.\n\nThis function is called only if the CTH is added before `init_per_suite` is run.\nFor details, see section [CTH Scope](ct_hooks_chapter.md#scope) in the User's\nGuide.\n\nNotice that for CTHs that are installed by means of the\n[`suite/0`](`c:ct_suite:suite/0`) function, [`post_groups/2`](`c:post_groups/2`)\nis called before the `c:init/2` hook function. However, for CTHs that are\ninstalled by means of the CT start flag, the `c:init/2` function is called\nfirst.\n\n> #### Note {: .info }\n>\n> Prior to each test execution, Common Test does a simulated test run in order\n> to count test suites, groups and cases for logging purposes. This causes the\n> [`post_groups/2`](`c:post_groups/2`) hook function to always be called twice.\n> For this reason, side effects are best avoided in this callback.","ref":"ct_hooks.html#c:post_groups/2"},{"type":"callback","title":"ct_hooks.post_init_per_group/5","doc":"This function is called after [`init_per_group`](`c:ct_suite:init_per_group/2`)\nif it exists. It behaves the same way as\n[`post_init_per_suite`](`c:post_init_per_suite/4`), but for function\n[`init_per_group`](`c:ct_suite:init_per_group/2`) instead.\n\nIf [`Module:post_init_per_group/5`](`c:post_init_per_group/5`) is not exported,\ncommon_test will attempt to call\n`Module:post_init_per_group(GroupName, Config, Return, CTHState)` instead. This\nis for backwards compatibility.","ref":"ct_hooks.html#c:post_init_per_group/5"},{"type":"callback","title":"ct_hooks.post_init_per_suite/4","doc":"This function is called after [`init_per_suite`](`c:ct_suite:init_per_suite/1`)\nif it exists. It typically contains extra checks to ensure that all the correct\ndependencies are started correctly.\n\n`Return` is what [`init_per_suite`](`c:ct_suite:init_per_suite/1`) returned,\nthat is, `{fail,Reason}`, `{skip,Reason}`, a `Config` list, or a term describing\nhow [`init_per_suite`](`c:ct_suite:init_per_suite/1`) failed.\n\n`NewReturn` is the possibly modified return value of\n[`init_per_suite`](`c:ct_suite:init_per_suite/1`). To recover from a failure in\n[`init_per_suite`](`c:ct_suite:init_per_suite/1`), return `ConfigList` with the\n`tc_status` element removed. For more details, see\n[Post Hooks](ct_hooks_chapter.md#post) in section \"Manipulating Tests\" in the\nUser's Guide.\n\n`CTHState` is the current internal state of the CTH.\n\nThis function is called only if the CTH is added before or in `init_per_suite`.\nFor details, see section [CTH Scope](ct_hooks_chapter.md#scope) in the User's\nGuide.","ref":"ct_hooks.html#c:post_init_per_suite/4"},{"type":"callback","title":"ct_hooks.post_init_per_testcase/5","doc":"This function is called after\n[`init_per_testcase`](`c:ct_suite:init_per_testcase/2`) if it exists. It behaves\nthe same way as [`post_init_per_suite`](`c:post_init_per_suite/4`), but for\nfunction [`init_per_testcase`](`c:ct_suite:init_per_testcase/2`) instead.\n\nIf [`Module:post_init_per_testcase/5`](`c:post_init_per_testcase/5`) is not\nexported, common_test will attempt to call\n`Module:post_init_per_testcase(TestcaseName, Config, Return, CTHState)` instead.\nThis is for backwards compatibility.","ref":"ct_hooks.html#c:post_init_per_testcase/5"},{"type":"callback","title":"ct_hooks.pre_end_per_group/4","doc":"This function is called before [`end_per_group`](`c:ct_suite:end_per_group/2`)\nif it exists. It behaves the same way as\n[`pre_init_per_suite`](`c:pre_init_per_suite/3`), but for function\n[`end_per_group`](`c:ct_suite:end_per_group/2`) instead.\n\nIf [`Module:pre_end_per_group/4`](`c:pre_end_per_group/4`) is not exported,\ncommon_test will attempt to call\n`Module:pre_end_per_group(GroupName, EndData, CTHState)` instead. This is for\nbackwards compatibility.","ref":"ct_hooks.html#c:pre_end_per_group/4"},{"type":"callback","title":"ct_hooks.pre_end_per_suite/3","doc":"This function is called before [`end_per_suite`](`c:ct_suite:end_per_suite/1`)\nif it exists. It behaves the same way as\n[`pre_init_per_suite`](`c:pre_init_per_suite/3`), but for function\n[`end_per_suite`](`c:ct_suite:end_per_suite/1`) instead.","ref":"ct_hooks.html#c:pre_end_per_suite/3"},{"type":"callback","title":"ct_hooks.pre_end_per_testcase/4","doc":"This function is called before\n[`end_per_testcase`](`c:ct_suite:end_per_testcase/2`) if it exists. It behaves\nthe same way as [`pre_end_per_suite`](`c:pre_end_per_suite/3`), but for function\n[`end_per_testcase`](`c:ct_suite:end_per_testcase/2`) instead.\n\nThis function cannot change the result of the test case by returning skip or\nfail tuples, but it may insert items in `Config` that can be read in\n`end_per_testcase/2` or in\n[`post_end_per_testcase/5`](`c:post_end_per_testcase/5`).\n\nIf [`Module:pre_end_per_testcase/4`](`c:pre_end_per_testcase/4`) is not\nexported, common_test will attempt to call\n`Module:pre_end_per_testcase(TestcaseName, EndData, CTHState)` instead. This is\nfor backwards compatibility.","ref":"ct_hooks.html#c:pre_end_per_testcase/4"},{"type":"callback","title":"ct_hooks.pre_init_per_group/4","doc":"This function is called before [`init_per_group`](`c:ct_suite:init_per_group/2`)\nif it exists. It behaves the same way as\n[`pre_init_per_suite`](`c:pre_init_per_suite/3`), but for function\n[`init_per_group`](`c:ct_suite:init_per_group/2`) instead.\n\nIf [`Module:pre_init_per_group/4`](`c:pre_init_per_group/4`) is not exported,\ncommon_test will attempt to call\n`Module:pre_init_per_group(GroupName, InitData, CTHState)` instead. This is for\nbackwards compatibility.","ref":"ct_hooks.html#c:pre_init_per_group/4"},{"type":"callback","title":"ct_hooks.pre_init_per_suite/3","doc":"This function is called before [`init_per_suite`](`c:ct_suite:init_per_suite/1`)\nif it exists. It typically contains initialization/logging that must be done\nbefore `init_per_suite` is called. If `{skip,Reason}` or `{fail,Reason}` is\nreturned, `init_per_suite` and all test cases of the suite are skipped and\n`Reason` printed in the overview log of the suite.\n\n`SuiteName` is the name of the suite to be run.\n\n`InitData` is the original configuration list of the test suite, or a\n`SkipOrFail` tuple if a previous CTH has returned this.\n\n`CTHState` is the current internal state of the CTH.\n\n`Return` is the result of the `init_per_suite` function. If it is\n`{skip,Reason}` or `{fail,Reason}`,\n[`init_per_suite`](`c:ct_suite:init_per_suite/1`) is never called, instead the\ninitiation is considered to be skipped or failed, respectively. If a `NewConfig`\nlist is returned, [`init_per_suite`](`c:ct_suite:init_per_suite/1`) is called\nwith that `NewConfig` list. For more details, see section\n[Pre Hooks](ct_hooks_chapter.md#pre) in the User's Guide.\n\nThis function is called only if the CTH is added before `init_per_suite is run`.\nFor details, see section [CTH Scope](ct_hooks_chapter.md#scope) in the User's\nGuide.","ref":"ct_hooks.html#c:pre_init_per_suite/3"},{"type":"callback","title":"ct_hooks.pre_init_per_testcase/4","doc":"This function is called before\n[`init_per_testcase`](`c:ct_suite:init_per_testcase/2`) if it exists. It behaves\nthe same way as [`pre_init_per_suite`](`c:pre_init_per_suite/3`), but for\nfunction [`init_per_testcase`](`c:ct_suite:init_per_testcase/2`) instead.\n\nIf [`Module:pre_init_per_testcase/4`](`c:pre_init_per_testcase/4`) is not\nexported, common_test will attempt to call\n`Module:pre_init_per_testcase(TestcaseName, InitData, CTHState)` instead. This\nis for backwards compatibility.\n\nCTHs cannot be added here right now. That feature may be added in a later\nrelease, but it would right now break backwards compatibility.","ref":"ct_hooks.html#c:pre_init_per_testcase/4"},{"type":"callback","title":"ct_hooks.terminate/1","doc":"This function is called at the end of a CTH [scope](ct_hooks_chapter.md#scope).\nThe returned term is ignored.","ref":"ct_hooks.html#c:terminate/1"},{"type":"module","title":"ct_master","doc":"Distributed test execution control for `Common Test`.\n\nThis module exports functions for running `Common Test` nodes on multiple hosts\nin parallel.","ref":"ct_master.html"},{"type":"function","title":"ct_master.abort/0","doc":"Stops all running tests.","ref":"ct_master.html#abort/0"},{"type":"function","title":"ct_master.abort/1","doc":"Stops tests on specified nodes.","ref":"ct_master.html#abort/1"},{"type":"function","title":"ct_master.basic_html/1","doc":"If set to `true`, the `ct_master logs` are written on a primitive HTML format,\nnot using the `Common Test` CSS style sheet.","ref":"ct_master.html#basic_html/1"},{"type":"function","title":"ct_master.get_event_mgr_ref/0","doc":"Gets a reference to the `Common Test` master event manager. The reference can be\nused to, for example, add a user-specific event handler while tests are running.\n\n_Example:_\n\n```erlang\ngen_event:add_handler(ct_master:get_event_mgr_ref(), my_ev_h, [])\n```","ref":"ct_master.html#get_event_mgr_ref/0"},{"type":"function","title":"ct_master.progress/0","doc":"Returns test progress. If `Status` is `ongoing`, tests are running on the node\nand are not yet finished.","ref":"ct_master.html#progress/0"},{"type":"function","title":"ct_master.run/1","doc":"Run tests on spawned nodes as specified in `TestSpecs` (see `run/4`).\n\nEquivalent to [`run(TestSpecs, false, [], [])`](`run/4`) if\ncalled with TestSpecs being list of strings;\n\nEquivalent to [`run([TS], false, [], [])`](`run/4`) if\ncalled with TS being string.","ref":"ct_master.html#run/1"},{"type":"function","title":"ct_master.run/3","doc":"","ref":"ct_master.html#run/3"},{"type":"function","title":"ct_master.run/4","doc":"Tests are spawned on the nodes as specified in `TestSpecs`. Each specification\nin `TestSpec` is handled separately. However, it is also possible to specify a\nlist of specifications to be merged into one specification before the tests are\nexecuted. Any test without a particular node specification is also executed on\nthe nodes in `InclNodes`. Nodes in the `ExclNodes` list are excluded from the\ntest.","ref":"ct_master.html#run/4"},{"type":"function","title":"ct_master.run_on_node/2","doc":"","ref":"ct_master.html#run_on_node/2"},{"type":"function","title":"ct_master.run_on_node/3","doc":"Tests are spawned on `Node` according to `TestSpecs`.","ref":"ct_master.html#run_on_node/3"},{"type":"function","title":"ct_master.run_test/2","doc":"Tests are spawned on `Node` using `ct:run_test/1`","ref":"ct_master.html#run_test/2"},{"type":"type","title":"ct_master.test_spec/0","doc":"Filename of test spec to be executed.","ref":"ct_master.html#t:test_spec/0"},{"type":"module","title":"ct_netconfc","doc":"NETCONF client module.\n\nNETCONF client module compliant with RFC 6241, NETCONF Configuration Protocol,\nand RFC 6242, Using the NETCONF Configuration Protocol over Secure SHell (SSH),\nand with support for RFC 5277, NETCONF Event Notifications.\n\n[](){: #Connecting }\n\n_Connecting to a NETCONF server_\n\nCall [`connect/1,2`](`connect/1`) to establish a connection to a server, then\npass the returned handle to [`session/1-3`](`session/1`) to establish a NETCONF\nsession on a new SSH channel. Each call to [`session/1-3`](`session/1`)\nestablishes a new session on the same connection, and results in a hello message\nto the server.\n\nAlternately, [`open/1,2`](`open/1`) can be used to establish a single session on\na dedicated connection. (Or, equivalently, [`only_open/1,2`](`only_open/1`)\nfollowed by [`hello/1-3`](`hello/1`).)\n\nConnect/session options can be specified in a configuration file with entries\nlike the following.\n\n```erlang\n{server_id(), [option()]}.\n```\n\nThe `t:server_id/0` or an associated `t:ct:target_name/0` can then be passed to\nthe aforementioned functions to use the referenced configuration.\n\n[](){: #Signaling }\n\n_Signaling_\n\nProtocol operations in the NETCONF protocol are realized as remote procedure\ncalls (RPCs) from client to server and a corresponding reply from server to\nclient. RPCs are sent using like-named functions (eg.\n[`edit_config/3-5`](`edit_config/3`) to send an edit-config RPC), with the\nserver reply as return value. There are functions for each RPC defined in RFC\n6241 and the create-subscription RPC from RFC 5277, all of which are wrappers on\n[`send_rpc/2,3`](`send_rpc/2`), that can be used to send an arbitrary RPC not\ndefined in RFC 6241 or RFC 5277.\n\nAll of the signaling functions have one variant with a `Timeout` argument and\none without, corresponding to an infinite timeout. The latter is inappropriate\nin most cases since a non-response by the server or a missing message-id causes\nthe call to hang indefinitely.\n\n[](){: #Logging }\n\n_Logging_\n\nThe NETCONF server uses `error_logger` for logging of NETCONF traffic. A special\npurpose error handler is implemented in `ct_conn_log_h`. To use this error\nhandler, add the `cth_conn_log` hook in the test suite, for example:\n\n```erlang\nsuite() ->\n [{ct_hooks, [{cth_conn_log, [{ct:conn_log_mod(), ct:conn_log_options()}]}]}].\n```\n\n`conn_log_mod()` is the name of the `Common Test` module implementing the\nconnection protocol, for example, `ct_netconfc`.\n\nHook option `log_type` specifies the type of logging:\n\n- **`raw`** - The sent and received NETCONF data is logged to a separate text\n file \"as is\" without any formatting. A link to the file is added to the test\n case HTML log.\n\n- **`pretty`** - The sent and received NETCONF data is logged to a separate text\n file with XML data nicely indented. A link to the file is added to the test\n case HTML log.\n\n- **`html (default)`** - The sent and received NETCONF traffic is pretty printed\n directly in the test case HTML log.\n\n- **`silent`** - NETCONF traffic is not logged.\n\nBy default, all NETCONF traffic is logged in one single log file. However,\ndifferent connections can be logged in separate files. To do this, use hook\noption `hosts` and list the names of the servers/connections to be used in the\nsuite. The connections must be named for this to work, that is, they must be\nopened with `open/2`.\n\nOption `hosts` has no effect if `log_type` is set to `html` or `silent`.\n\nThe hook options can also be specified in a configuration file with\nconfiguration variable `ct_conn_log`:\n\n```erlang\n{ct_conn_log,[{ct:conn_log_mod(), ct:conn_log_options()}]}.\n```\n\nFor example:\n\n```erlang\n{ct_conn_log,[{ct_netconfc,[{log_type,pretty},\n {hosts,[ct:key_or_name()]}]}]}\n```\n\n> #### Note {: .info }\n>\n> Hook options specified in a configuration file overwrite the hard-coded hook\n> options in the test suite.\n\n_Logging Example 1:_\n\n[](){: #Logging_example_1 }\n\nThe following `ct_hooks` statement causes pretty printing of NETCONF traffic to\nseparate logs for the connections named `nc_server1` and `nc_server2`. Any other\nconnections are logged to default NETCONF log.\n\n```erlang\nsuite() ->\n [{ct_hooks, [{cth_conn_log, [{ct_netconfc,[{log_type,pretty}},\n {hosts,[nc_server1,nc_server2]}]}\n ]}]}].\n```\n\nConnections must be opened as follows:\n\n```erlang\nopen(nc_server1,[...]),\nopen(nc_server2,[...]).\n```\n\n_Logging Example 2:_\n\n[](){: #Logging_example_2 }\n\nThe following configuration file causes raw logging of all NETCONF traffic in to\none single text file:\n\n```erlang\n{ct_conn_log,[{ct_netconfc,[{log_type,raw}]}]}.\n```\n\nThe `ct_hooks` statement must look as follows:\n\n```erlang\nsuite() ->\n [{ct_hooks, [{cth_conn_log, []}]}].\n```\n\nThe same `ct_hooks` statement without the configuration file would cause HTML\nlogging of all NETCONF connections in to the test case HTML log.","ref":"ct_netconfc.html"},{"type":"function","title":"ct_netconfc.action/2","doc":"","ref":"ct_netconfc.html#action/2"},{"type":"function","title":"ct_netconfc.action/3","doc":"Executes an action. If the return type is void, `ok` is returned instead of\n`{ok,[simple_xml()]}`.","ref":"ct_netconfc.html#action/3"},{"type":"function","title":"ct_netconfc.close_session/1","doc":"","ref":"ct_netconfc.html#close_session/1"},{"type":"function","title":"ct_netconfc.close_session/2","doc":"Requests graceful termination of the session associated with the client.\n\nWhen a NETCONF server receives a `close-session` request, it gracefully closes\nthe session. The server releases any locks and resources associated with the\nsession and gracefully closes any associated connections. Any NETCONF requests\nreceived after a `close-session` request are ignored.","ref":"ct_netconfc.html#close_session/2"},{"type":"function","title":"ct_netconfc.connect/1","doc":"Opens an SSH connection to a NETCONF server.\n\nIf the server options are specified in a configuration file, use `connect/2`\ninstead.\n\nThe opaque `t:handle/0` reference returned from this function is required as\nconnection identifier when opening sessions over this connection, see\n[`session/1-3`](`session/1`).","ref":"ct_netconfc.html#connect/1"},{"type":"function","title":"ct_netconfc.connect/2","doc":"Open an SSH connection to a named NETCONF server.\n\nIf `KeyOrName` is a configured `t:server_id/0` or a `target_name()` associated\nwith such an Id, then the options for this server are fetched from the\nconfiguration file.\n\nThe options list is added to those of the configuration file. If an option is\nspecified in both lists, the configuration file takes precedence.\n\nIf the server is not specified in a configuration file, use `connect/1` instead.\n\nThe opaque `t:handle/0` reference returned from this function can be used as\nconnection identifier when opening sessions over this connection, see\n[`session/1-3`](`session/1`). However, if `KeyOrName` is a `target_name()`, that\nis, if the server is named through a call to `ct:require/2` or a `require`\nstatement in the test suite, then this name can be used instead of `t:handle/0`.","ref":"ct_netconfc.html#connect/2"},{"type":"function","title":"ct_netconfc.copy_config/3","doc":"","ref":"ct_netconfc.html#copy_config/3"},{"type":"function","title":"ct_netconfc.copy_config/4","doc":"Copies configuration data.\n\nWhich source and target options that can be issued depends on the capabilities\nsupported by the server. That is, `:candidate` and/or `:startup` are required.","ref":"ct_netconfc.html#copy_config/4"},{"type":"function","title":"ct_netconfc.create_subscription/2","doc":"","ref":"ct_netconfc.html#create_subscription/2"},{"type":"function","title":"ct_netconfc.create_subscription/3","doc":"Creates a subscription for event notifications by sending an RFC 5277\ncreate-subscription RPC to the server. The calling process receives events as\nmessages of type `t:notification/0`.\n\nFrom RFC 5722, 2.1 Subscribing to Receive Event Notifications:\n\n- **`Stream`** - Indicates which stream of event is of interest. If not present,\n events in the default NETCONF stream are sent.\n\n- **`Filter`** - Indicates which subset of all possible events is of interest.\n The parameter format is the same as that of the filter parameter in the\n NETCONF protocol operations. If not present, all events not precluded by other\n parameters are sent.\n\n- **`StartTime`** - Used to trigger the replay feature and indicate that the\n replay is to start at the time specified. If `StartTime` is not present, this\n is not a replay subscription. It is not valid to specify start times that are\n later than the current time. If `StartTime` is specified earlier than the log\n can support, the replay begins with the earliest available notification. This\n parameter is of type `dateTime` and compliant to RFC 3339. Implementations\n must support time zones.\n\n- **`StopTime`** - Used with the optional replay feature to indicate the newest\n notifications of interest. If `StopTime` is not present, the notifications\n continues until the subscription is terminated. Must be used with and be later\n than `StartTime`. Values of `StopTime` in the future are valid. This parameter\n is of type `dateTime` and compliant to RFC 3339. Implementations must support\n time zones.\n\nSee RFC 5277 for more details. The requirement that `StopTime` must only be used\nwith `StartTime` is not enforced, to allow an invalid request to be sent to the\nserver.\n\nPrior to OTP 22.1, this function was documented as having 15 variants in 6\narities. These are still exported for backwards compatibility, but no longer\ndocumented. The map-based variants documented above provide the same\nfunctionality with simpler arguments.\n\n> #### Note {: .info }\n>\n> create-subscription is no longer the only RPC with which NETCONF notifications\n> can be ordered: RFC 8639 adds establish-subscription and future RFCs may add\n> other methods. Specify a `receiver` option at session creation to provide a\n> destination for incoming notifications independently of a call to\n> [`create_subscription/2,3`](`create_subscription/2`), and use\n> [`send_rpc/2,3`](`send_rpc/2`) to send establish-subscription and other\n> arbitrary RPCs.","ref":"ct_netconfc.html#create_subscription/3"},{"type":"function","title":"ct_netconfc.delete_config/2","doc":"","ref":"ct_netconfc.html#delete_config/2"},{"type":"function","title":"ct_netconfc.delete_config/3","doc":"Deletes configuration data.\n\nThe running configuration cannot be deleted and `:candidate` or `:startup` must\nbe advertised by the server.","ref":"ct_netconfc.html#delete_config/3"},{"type":"function","title":"ct_netconfc.disconnect/1","doc":"Closes the given SSH connection.\n\nIf there are open NETCONF sessions on the connection, these will be brutally\naborted. To avoid this, close each session with\n[`close_session/1,2`](`close_session/1`)","ref":"ct_netconfc.html#disconnect/1"},{"type":"function","title":"ct_netconfc.edit_config/3","doc":"","ref":"ct_netconfc.html#edit_config/3"},{"type":"function","title":"ct_netconfc.edit_config/4","doc":"","ref":"ct_netconfc.html#edit_config/4"},{"type":"function","title":"ct_netconfc.edit_config/5","doc":"Edits configuration data.\n\nBy default only the running target is available, unless the server includes\n`:candidate` or `:startup` in its list of capabilities.\n\n`OptParams` can be used for specifying optional parameters (`default-operation`,\n`test-option`, or `error-option`) to be added to the `edit-config` request. The\nvalue must be a list containing valid simple XML, for example:\n\n```erlang\n[{'default-operation', [\"none\"]},\n {'error-option', [\"rollback-on-error\"]}]\n```\n\nIf `OptParams` is not given, the default value `[]` is used.","ref":"ct_netconfc.html#edit_config/5"},{"type":"function","title":"ct_netconfc.get/2","doc":"","ref":"ct_netconfc.html#get/2"},{"type":"function","title":"ct_netconfc.get/3","doc":"Gets data.\n\nThis operation returns both configuration and state data from the server.\n\nFilter type `xpath` can be used only if the server supports `:xpath`.","ref":"ct_netconfc.html#get/3"},{"type":"function","title":"ct_netconfc.get_capabilities/1","doc":"","ref":"ct_netconfc.html#get_capabilities/1"},{"type":"function","title":"ct_netconfc.get_capabilities/2","doc":"Returns the server capabilities as received in its hello message.","ref":"ct_netconfc.html#get_capabilities/2"},{"type":"function","title":"ct_netconfc.get_config/3","doc":"","ref":"ct_netconfc.html#get_config/3"},{"type":"function","title":"ct_netconfc.get_config/4","doc":"Gets configuration data.\n\nTo be able to access another source than `running`, the server must advertise\n`:candidate` and/or `:startup`.\n\nFilter type `xpath` can be used only if the server supports `:xpath`.","ref":"ct_netconfc.html#get_config/4"},{"type":"function","title":"ct_netconfc.get_event_streams/1","doc":"","ref":"ct_netconfc.html#get_event_streams/1"},{"type":"function","title":"ct_netconfc.get_event_streams/2","doc":"","ref":"ct_netconfc.html#get_event_streams/2"},{"type":"function","title":"ct_netconfc.get_event_streams/3","doc":"Sends a request to get the specified event streams.\n\n`Streams` is a list of stream names. The following filter is sent to the NETCONF\nserver in a `get` request:\n\n```text\n \n \n \n StreamName1 \n \n \n StreamName2 \n \n ...\n \n \n```\n\nIf `Streams` is an empty list, _all_ streams are requested by sending the\nfollowing filter:\n\n```text\n \n \n \n```\n\nIf more complex filtering is needed, use [`ct_netconfc:get/2,3`](`get/2`) and\nspecify the exact filter according to \"XML Schema for Event Notifications\" in\nRFC 5277.","ref":"ct_netconfc.html#get_event_streams/3"},{"type":"function","title":"ct_netconfc.get_session_id/1","doc":"","ref":"ct_netconfc.html#get_session_id/1"},{"type":"function","title":"ct_netconfc.get_session_id/2","doc":"Returns the session Id associated with the specified client.","ref":"ct_netconfc.html#get_session_id/2"},{"type":"function","title":"ct_netconfc.hello/1","doc":"","ref":"ct_netconfc.html#hello/1"},{"type":"function","title":"ct_netconfc.hello/2","doc":"","ref":"ct_netconfc.html#hello/2"},{"type":"function","title":"ct_netconfc.hello/3","doc":"Exchanges `hello` messages with the server. Returns when the server hello has\nbeen received or after the specified timeout.\n\nNote that capabilities for an outgoing hello can be passed directly to `open/2`.","ref":"ct_netconfc.html#hello/3"},{"type":"function","title":"ct_netconfc.kill_session/2","doc":"","ref":"ct_netconfc.html#kill_session/2"},{"type":"function","title":"ct_netconfc.kill_session/3","doc":"Forces termination of the session associated with the supplied session Id.\n\nThe server side must abort any ongoing operations, release any locks and\nresources associated with the session, and close any associated connections.\n\nOnly if the server is in the confirmed commit phase, the configuration is\nrestored to its state before entering the confirmed commit phase. Otherwise, no\nconfiguration rollback is performed.\n\nIf the specified `SessionId` is equal to the current session Id, an error is\nreturned.","ref":"ct_netconfc.html#kill_session/3"},{"type":"function","title":"ct_netconfc.lock/2","doc":"","ref":"ct_netconfc.html#lock/2"},{"type":"function","title":"ct_netconfc.lock/3","doc":"Locks the configuration target.\n\nWhich target parameters that can be used depends on if `:candidate` and/or\n`:startup` are supported by the server. If successful, the configuration system\nof the device is unavailable to other clients (NETCONF, CORBA, SNMP, and so on).\nLocks are intended to be short-lived.\n\nOperation [`kill_session/2,3`](`kill_session/2`) can be used to force the\nrelease of a lock owned by another NETCONF session. How this is achieved by the\nserver side is implementation-specific.","ref":"ct_netconfc.html#lock/3"},{"type":"function","title":"ct_netconfc.only_open/1","doc":"Opens a NETCONF session, but does not send `hello`.\n\nAs `open/1`, but does not send a `hello` message.","ref":"ct_netconfc.html#only_open/1"},{"type":"function","title":"ct_netconfc.only_open/2","doc":"Opens a named NETCONF session, but does not send `hello`.\n\nAs `open/2`, but does not send a `hello` message.","ref":"ct_netconfc.html#only_open/2"},{"type":"function","title":"ct_netconfc.open/1","doc":"Opens a NETCONF session and exchanges `hello` messages.\n\nIf the server options are specified in a configuration file, or if a named\nclient is needed for logging purposes (see section\n[Logging](`m:ct_netconfc#Logging`) in this module), use `open/2` instead.\n\nThe opaque `t:handle/0` reference returned from this function is required as\nclient identifier when calling any other function in this module.","ref":"ct_netconfc.html#open/1"},{"type":"function","title":"ct_netconfc.open/2","doc":"Opens a named NETCONF session and exchanges `hello` messages.\n\nIf `KeyOrName` is a configured `t:server_id/0` or a `target_name()` associated\nwith such an Id, then the options for this server are fetched from the\nconfiguration file.\n\nThe options list is added to those of the configuration file. If an option is\nspecified in both lists, the configuration file take precedence.\n\nIf the server is not specified in a configuration file, use `open/1` instead.\n\nThe opaque `t:handle/0` reference returned from this function can be used as\nclient identifier when calling any other function in this module. However, if\n`KeyOrName` is a `target_name()`, that is, if the server is named through a call\nto `ct:require/2` or a `require` statement in the test suite, then this name can\nbe used instead of `t:handle/0`.\n\nSee also `ct:require/2`.","ref":"ct_netconfc.html#open/2"},{"type":"function","title":"ct_netconfc.send/2","doc":"","ref":"ct_netconfc.html#send/2"},{"type":"function","title":"ct_netconfc.send/3","doc":"Sends an XML document to the server.\n\nThe specified XML document is sent \"as is\" to the server. This function can be\nused for sending XML documents that cannot be expressed by other interface\nfunctions in this module.","ref":"ct_netconfc.html#send/3"},{"type":"function","title":"ct_netconfc.send_rpc/2","doc":"","ref":"ct_netconfc.html#send_rpc/2"},{"type":"function","title":"ct_netconfc.send_rpc/3","doc":"Sends a NETCONF `rpc` request to the server.\n\nThe specified XML document is wrapped in a valid NETCONF `rpc` request and sent\nto the server. The `message-id` and namespace attributes are added to element\n`rpc`.\n\nThis function can be used for sending `rpc` requests that cannot be expressed by\nother interface functions in this module.","ref":"ct_netconfc.html#send_rpc/3"},{"type":"function","title":"ct_netconfc.session/1","doc":"","ref":"ct_netconfc.html#session/1"},{"type":"function","title":"ct_netconfc.session/2","doc":"","ref":"ct_netconfc.html#session/2"},{"type":"function","title":"ct_netconfc.session/3","doc":"Opens a NETCONF session as a channel on the given SSH connection, and exchanges\nhello messages with the server.\n\nThe opaque `t:handle/0` reference returned from this function can be used as\nclient identifier when calling any other function in this module. However, if\n`KeyOrName` is used and it is a `target_name()`, that is, if the server is named\nthrough a call to `ct:require/2` or a `require` statement in the test suite,\nthen this name can be used instead of `t:handle/0`.","ref":"ct_netconfc.html#session/3"},{"type":"function","title":"ct_netconfc.unlock/2","doc":"","ref":"ct_netconfc.html#unlock/2"},{"type":"function","title":"ct_netconfc.unlock/3","doc":"Unlocks the configuration target.\n\nIf the client earlier has acquired a lock through [`lock/2,3`](`lock/2`), this\noperation releases the associated lock. To access another target than `running`,\nthe server must support `:candidate` and/or `:startup`.","ref":"ct_netconfc.html#unlock/3"},{"type":"type","title":"ct_netconfc.client/0","doc":"Handle to a NETCONF session, as required by signaling functions.","ref":"ct_netconfc.html#t:client/0"},{"type":"type","title":"ct_netconfc.error_reason/0","doc":"","ref":"ct_netconfc.html#t:error_reason/0"},{"type":"opaque","title":"ct_netconfc.handle/0","doc":"Handle to a connection to a NETCONF server as returned by\n[`connect/1,2`](`connect/1`), or to a session as returned by\n[`session/1-3`](`session/1`), [`open/1,2`](`open/1`), or\n[`only_open/1,2`](`only_open/1`).","ref":"ct_netconfc.html#t:handle/0"},{"type":"type","title":"ct_netconfc.host/0","doc":"","ref":"ct_netconfc.html#t:host/0"},{"type":"type","title":"ct_netconfc.netconf_db/0","doc":"","ref":"ct_netconfc.html#t:netconf_db/0"},{"type":"type","title":"ct_netconfc.notification/0","doc":"Event notification messages sent as a result of calls to\n[`create_subscription/2,3`](`create_subscription/2`).","ref":"ct_netconfc.html#t:notification/0"},{"type":"type","title":"ct_netconfc.option/0","doc":"Options `host` and `port` specify the server endpoint to which to connect, and\nare passed directly to [`ssh:connect/4`](`ssh:connect/3`), as are arbitrary ssh\noptions. Common options are `user`, `password` and `user_dir`.\n\nOption `timeout` specifies the number of milliseconds to allow for connection\nestablishment and, if the function in question results in an outgoing hello\nmessage, reception of the server hello. The timeout applies to connection and\nhello independently; one timeout for connection establishment, another for hello\nreception.\n\nOption `receiver` specifies a destination for incoming notification messages; a\nleft operand of the send operator (`!`). If not specified then a process calling\n[`create_subscription/2,3`](`create_subscription/2`) becomes the receiver, but\nexplicitly setting a receiver makes it possible to receive notifications that\nare not ordered by calling this function. Multiple receiver options can be\nspecified.\n\nReceiver options are ignored by connect/1-3.\n\nOption `capability` specifies the content of a corresponding element in an\noutgoing hello message, each option specifying the content of a single element.\nIf no base NETCONF capability is configured then the RFC 4741 1.0 capability,\n\"urn:ietf:params:netconf:base:1.0\", is added, otherwise not. In particular, the\nRFC 6241 1.1 capability must be explicitly configured. NETCONF capabilities can\nbe specified using the shorthand notation defined in RFC 6241, any capability\nstring starting with a colon being prefixed by either \"urn:ietf:params:netconf\"\nor \"urn:ietf:params:netconf:capability\", as appropriate.\n\nCapability options are ignored by connect/1-3 and only_open/1-2, which don't\nresult in an outgoing hello message.","ref":"ct_netconfc.html#t:option/0"},{"type":"type","title":"ct_netconfc.server_id/0","doc":"Identity of connection or session configuration in a configuration file.","ref":"ct_netconfc.html#t:server_id/0"},{"type":"type","title":"ct_netconfc.session_option/0","doc":"","ref":"ct_netconfc.html#t:session_option/0"},{"type":"type","title":"ct_netconfc.simple_xml/0","doc":"Representation of XML, as described in application\n[`xmerl`](`e:xmerl:index.html`).","ref":"ct_netconfc.html#t:simple_xml/0"},{"type":"type","title":"ct_netconfc.stream_data/0","doc":"","ref":"ct_netconfc.html#t:stream_data/0"},{"type":"type","title":"ct_netconfc.stream_name/0","doc":"","ref":"ct_netconfc.html#t:stream_name/0"},{"type":"type","title":"ct_netconfc.streams/0","doc":"Stream information as returned by\n[`get_event_streams/1-3`](`get_event_streams/1`). See RFC 5277, \"XML Schema for\nEvent Notifications\", for detail on the format of the string values.","ref":"ct_netconfc.html#t:streams/0"},{"type":"type","title":"ct_netconfc.xml_attribute_tag/0","doc":"","ref":"ct_netconfc.html#t:xml_attribute_tag/0"},{"type":"type","title":"ct_netconfc.xml_attribute_value/0","doc":"","ref":"ct_netconfc.html#t:xml_attribute_value/0"},{"type":"type","title":"ct_netconfc.xml_attributes/0","doc":"","ref":"ct_netconfc.html#t:xml_attributes/0"},{"type":"type","title":"ct_netconfc.xml_content/0","doc":"","ref":"ct_netconfc.html#t:xml_content/0"},{"type":"type","title":"ct_netconfc.xml_tag/0","doc":"","ref":"ct_netconfc.html#t:xml_tag/0"},{"type":"type","title":"ct_netconfc.xpath/0","doc":"","ref":"ct_netconfc.html#t:xpath/0"},{"type":"type","title":"ct_netconfc.xs_datetime/0","doc":"Date and time of a startTime/stopTime element in an RFC 5277 create-subscription\nrequest. Of XML primitive type `dateTime`, which has the (informal) form\n\n```text\n[-]YYYY-MM-DDThh:mm:ss[.s][Z|(+|-)hh:mm]\n```\n\nwhere `T` and `Z` are literal and `.s` is one or more fractional seconds.","ref":"ct_netconfc.html#t:xs_datetime/0"},{"type":"module","title":"ct_property_test","doc":"Support in Common Test for running property-based tests.\n\nThis module helps running property-based tests in the `Common Test` framework.\nOne (or more) of the property testing tools\n\n- [QuickCheck](http://www.quviq.com),\n- [PropEr](https://proper-testing.github.io) or\n- [Triq](https://github.com/krestenkrab/triq)\n\nis assumed to be installed.\n\nThe idea with this module is to have a `Common Test` test suite calling a\nproperty testing tool with special property test suites as defined by that tool.\nThe tests are collected in the `test` directory of the application. The `test`\ndirectory has a subdirectory `property_test`, where everything needed for the\nproperty tests are collected. The usual Erlang application directory structure\nis assumed.\n\nA typical `Common Test` test suite using `ct_property_test` is organized as\nfollows:\n\n```erlang\n-module(my_prop_test_SUITE).\n-compile(export_all).\n\n-include_lib(\"common_test/include/ct.hrl\").\n\nall() -> [prop_ftp_case].\n\ninit_per_suite(Config) ->\n ct_property_test:init_per_suite(Config).\n\n%%%---- test case\nprop_ftp_case(Config) ->\n ct_property_test:quickcheck(\n ftp_simple_client_server:prop_ftp(),\n Config\n ).\n```\n\nand the the property test module (in this example\n`ftp_simple_client_server.erl`) as almost a usual property testing module (More\nexamples are in [the User's Guide](ct_property_test_chapter.md)):\n\n```erlang\n-module(ftp_simple_client_server).\n-export([prop_ftp/0...]).\n\n-include_lib(\"common_test/include/ct_property_test.hrl\").\n\nprop_ftp() ->\n ?FORALL( ....\n```","ref":"ct_property_test.html"},{"type":"function","title":"ct_property_test.cmnd_names/1","doc":"Returns a list of commands (function calls) generated in the `Cmnd` sequence,\nwithout Module, Arguments and other details.\n\nFor more information see: `present_result/5`.","ref":"ct_property_test.html#cmnd_names/1"},{"type":"function","title":"ct_property_test.init_per_suite/1","doc":"Initializes and extends `Config` for property based testing.\n\nThis function investigates if support is available for either\n[QuickCheck](http://www.quviq.com), [PropEr](https://proper-testing.github.io)\nor [Triq](https://github.com/krestenkrab/triq) and compiles the properties with\nthe first tool found. It is supposed to be called in the\n[`init_per_suite/1`](`init_per_suite/1`) function in a CommonTest test suite.\n\nWhich tools to check for, and in which order could be set with the option\n`{prop_tools, list(eqc|proper|triq)}` in the CommonTest configuration `Config`.\nThe default value is `[eqc, proper, triq]` with `eqc` being the first one\nsearched for.\n\nIf no support is found for any tool, this function returns\n`{skip, Explanation}`.\n\nIn case of other errors, this function returns\n`{fail, Explanation}`.\n\nIf support is found, the option `{property_test_tool,ToolModule}` with the\nselected tool main module name (`eqc`, `proper` or `triq`) is added to the list\n`Config` which then is returned.\n\nThe property tests are assumed to be in a subdirectory named `property_test`.\nAll found Erlang files in that directory are compiled with one of the macros\n`'EQC'`, `'PROPER'` or `'TRIQ'` set, depending on which tool that is first\nfound. This could make parts of the Erlang property tests code to be included or\nexcluded with the macro directives `-ifdef(Macro).` or `-ifndef(Macro).`.\n\nThe file(s) in the `property_test` subdirectory could, or should, include the\nct_property_test include file:\n\n```erlang\n-include_lib(\"common_test/include/ct_property_test.hrl\").\n```\n\nThis included file will:\n\n- Include the correct tool's include file\n- Set the macro `'MOD_eqc'` to the correct module name for the selected tool.\n That is, the macro `'MOD_eqc'` is set to either `eqc`, `proper` or `triq`.","ref":"ct_property_test.html#init_per_suite/1"},{"type":"function","title":"ct_property_test.num_calls/1","doc":"Returns number of command calls in a test case.\n\nFor more information see: `present_result/5`.","ref":"ct_property_test.html#num_calls/1"},{"type":"function","title":"ct_property_test.present_result/4","doc":"","ref":"ct_property_test.html#present_result/4"},{"type":"function","title":"ct_property_test.present_result/5","doc":"Presents the result of _stateful (statem) property testing_ using the aggregate\nfunction in PropEr, QuickCheck or other similar property testing tool.\n\nIt is assumed to be called inside the property called by `quickcheck/2`:\n\n```erlang\n...\nRunResult = run_parallel_commands(?MODULE, Cmds),\nct_property_test:present_result(?MODULE, Cmds, RunResult, Config)\n...\n```\n\nSee the [User's Guide](ct_property_test_chapter.md#stateful1) for an example of\nthe usage and of the default printout.\n\nThe `StatisticsSpec` is a list of the tuples:\n\n- `{Title::string(), CollectFun::fun/1}`\n- `{Title::string(), FrequencyFun::/0, CollectFun::fun/1}`\n\nEach tuple will produce one table in the order of their places in the list.\n\n- `Title` will be the title of one result table\n- `CollectFun` is called with one argument: the `Cmds`. It should return a list\n of the values to be counted. The following pre-defined functions exist:\n - `ct_property_test:cmnd_names/1` returns a list of commands (function calls)\n generated in the `Cmnd` sequence, without Module, Arguments and other\n details.\n - `ct_property_test:num_calls/1` returns a list of the length of commands\n lists\n - `ct_property_test:sequential_parallel/1` returns a list with information\n about sequential and parallel parts from `Tool:parallel_commands/1,2`\n- `FrequencyFun/0` returns a fun/1 which is supposed to take a list of items as\n input, and return an iolist which will be printed as the table. Per default,\n the number of each item is counted and the percentage is printed for each. The\n list \\[a,b,a,a,c] could for example return\n\n ```erlang\n [\"a 60%\\n\",\"b 20%\\n\",\"c 20%\\n\"]\n ```\n\n which will be printed by the `print_fun`. The default `print_fun` will print\n it as:\n\n ```text\n a 60%\n b 20%\n c 20%\n ```\n\nThe default `StatisticsSpec` is:\n\n- For sequential commands:\n\n ```erlang\n [{\"Function calls\", fun cmnd_names/1},\n {\"Length of command sequences\", fun print_frequency_ranges/0,\n fun num_calls/1}]\n ```\n\n- For parallel commands:\n\n ```erlang\n [{\"Distribution sequential/parallel\", fun sequential_parallel/1},\n {\"Function calls\", fun cmnd_names/1},\n {\"Length of command sequences\", fun print_frequency_ranges/0,\n fun num_calls/1}]\n ```","ref":"ct_property_test.html#present_result/5"},{"type":"function","title":"ct_property_test.quickcheck/2","doc":"Calls the selected tool's function for running the `Property`. It is usually and\nby historical reasons called quickcheck, and that is why that name is used in\nthis module (`ct_property_test`).\n\nThe result is returned in a form suitable for `Common Test` test suites.\n\nThis function is intended to be called in test cases in test suites.","ref":"ct_property_test.html#quickcheck/2"},{"type":"function","title":"ct_property_test.sequential_parallel/1","doc":"Returns a list with information about sequential and parallel parts.\n\nFor more information see: `present_result/5`.","ref":"ct_property_test.html#sequential_parallel/1"},{"type":"type","title":"ct_property_test.arguments/0","doc":"","ref":"ct_property_test.html#t:arguments/0"},{"type":"type","title":"ct_property_test.command/0","doc":"","ref":"ct_property_test.html#t:command/0"},{"type":"type","title":"ct_property_test.command_list/0","doc":"","ref":"ct_property_test.html#t:command_list/0"},{"type":"type","title":"ct_property_test.dynamic_state/0","doc":"","ref":"ct_property_test.html#t:dynamic_state/0"},{"type":"type","title":"ct_property_test.function_name/0","doc":"","ref":"ct_property_test.html#t:function_name/0"},{"type":"type","title":"ct_property_test.history/0","doc":"","ref":"ct_property_test.html#t:history/0"},{"type":"type","title":"ct_property_test.init_command/0","doc":"","ref":"ct_property_test.html#t:init_command/0"},{"type":"type","title":"ct_property_test.parallel_testcase/0","doc":"","ref":"ct_property_test.html#t:parallel_testcase/0"},{"type":"type","title":"ct_property_test.set_command/0","doc":"","ref":"ct_property_test.html#t:set_command/0"},{"type":"type","title":"ct_property_test.statem_result/0","doc":"","ref":"ct_property_test.html#t:statem_result/0"},{"type":"type","title":"ct_property_test.symbolic_call/0","doc":"","ref":"ct_property_test.html#t:symbolic_call/0"},{"type":"type","title":"ct_property_test.symbolic_state/0","doc":"","ref":"ct_property_test.html#t:symbolic_state/0"},{"type":"type","title":"ct_property_test.symbolic_var/0","doc":"","ref":"ct_property_test.html#t:symbolic_var/0"},{"type":"module","title":"ct_rpc","doc":"`Common Test` specific layer on Erlang/OTP `rpc`.","ref":"ct_rpc.html"},{"type":"function","title":"ct_rpc.app_node/2","doc":"From a set of candidate nodes determines which of them is running the\napplication `App`. If none of the candidate nodes is running `App`, the function\nmakes the test case calling this function to fail. This function is the same as\ncalling [`app_node(App, Candidates, true)`](`app_node/3`).","ref":"ct_rpc.html#app_node/2"},{"type":"function","title":"ct_rpc.app_node/3","doc":"Same as [`ct_rpc:app_node/2`](`app_node/2`), except that argument `FailOnBadRPC`\ndetermines if the search for a candidate node is to stop if `badrpc` is received\nat some point.","ref":"ct_rpc.html#app_node/3"},{"type":"function","title":"ct_rpc.app_node/4","doc":"Same as [`ct_rpc:app_node/2`](`app_node/2`), except that argument `FailOnBadRPC`\ndetermines if the search for a candidate node is to stop if `badrpc` is received\nat some point.\n\nThe cookie on the client node is set to `Cookie` for this `rpc` operation (used\nto match the server node cookie).","ref":"ct_rpc.html#app_node/4"},{"type":"function","title":"ct_rpc.call/4","doc":"","ref":"ct_rpc.html#call/4"},{"type":"function","title":"ct_rpc.call/5","doc":"Evaluates [`apply(Module, Function, Args)`](`apply/3`) on the node `Node`.\nReturns either whatever `Function` returns, or `{badrpc, Reason}` if the remote\nprocedure call fails. If `Node` is `{Fun, FunArgs}`, applying `Fun` to `FunArgs`\nis to return a node name.","ref":"ct_rpc.html#call/5"},{"type":"function","title":"ct_rpc.call/6","doc":"Evaluates [`apply(Module, Function, Args)`](`apply/3`) on the node `Node`.\nReturns either whatever `Function` returns, or `{badrpc, Reason}` if the remote\nprocedure call fails. If `Node` is `{Fun, FunArgs}`, applying `Fun` to `FunArgs`\nis to return a node name.\n\nThe cookie on the client node is set to `Cookie` for this `rpc` operation (used\nto match the server node cookie).","ref":"ct_rpc.html#call/6"},{"type":"function","title":"ct_rpc.cast/4","doc":"Evaluates [`apply(Module, Function, Args)`](`apply/3`) on the node `Node`. No\nresponse is delivered and the process that makes the call is not suspended until\nthe evaluation is completed as in the case of `call/3,4`. If `Node` is\n`{Fun, FunArgs}`, applying `Fun` to `FunArgs` is to return a node name.","ref":"ct_rpc.html#cast/4"},{"type":"function","title":"ct_rpc.cast/5","doc":"Evaluates [`apply(Module, Function, Args)`](`apply/3`) on the node `Node`. No\nresponse is delivered and the process that makes the call is not suspended until\nthe evaluation is completed as in the case of `call/3,4`. If `Node` is\n`{Fun, FunArgs}`, applying `Fun` to `FunArgs` is to return a node name.\n\nThe cookie on the client node is set to `Cookie` for this `rpc` operation (used\nto match the server node cookie).","ref":"ct_rpc.html#cast/5"},{"type":"module","title":"ct_slave","doc":"`Common Test` framework functions for starting and stopping nodes for\nLarge-Scale Testing.\n\nThis module exports functions used by the `Common Test` Master to start and stop\n\"slave\" nodes. It is the default callback module for the `{init, node_start}`\nterm in the Test Specification.","ref":"ct_slave.html"},{"type":"function","title":"ct_slave.start/1","doc":"Starts an Erlang node with name `Node` on the local host.\n\nSee also [`ct_slave:start/3`](`start/3`).","ref":"ct_slave.html#start/1"},{"type":"function","title":"ct_slave.start/2","doc":"Starts an Erlang node with default options on a specified host, or on the local\nhost with specified options. That is, the call is interpreted as\n[`start(Host, Node)`](`start/2`) when the second argument is atom-valued and\n[`start(Node, Opts)`](`start/2`) when it is list-valued.\n\nSee also [`ct_slave:start/3`](`start/3`).","ref":"ct_slave.html#start/2"},{"type":"function","title":"ct_slave.start/3","doc":"Starts an Erlang node with name `Node` on host `Host` as specified by the\ncombination of options in `Opts`.\n\nOptions `Username` and `Password` are used to log on to the remote host `Host`.\n`Username`, if omitted, defaults to the current username. `Password` is empty by\ndefault.\n\nA list of functions specified in option `Startup` are executed after startup of\nthe node. Notice that all used modules are to be present in the code path on\n`Host`.\n\nThe time-outs are applied as follows:\n\n- **`BootTimeout`** - The time to start the Erlang node, in seconds. Defaults to\n 3 seconds. If the node is not pingable within this time, the result\n `{error, boot_timeout, NodeName}` is returned.\n\n- **`InitTimeout`** - The time to wait for the node until it calls the internal\n callback function informing master about a successful startup. Defaults to 1\n second. In case of a timed out message, the result\n `{error, init_timeout, NodeName}` is returned.\n\n- **`StartupTimeout`** - The time to wait until the node stops to run\n `StartupFunctions`. Defaults to 1 second. If this time-out occurs, the result\n `{error, startup_timeout, NodeName}` is returned.\n\n_Options:_\n\n- **`monitor_master`** - Specifies if the slave node is to be stopped if the\n master node stops. Defaults to `false`.\n\n- **`kill_if_fail`** - Specifies if the slave node is to be killed if a time-out\n occurs during initialization or startup. Defaults to `true`. Notice that the\n node can also be still alive it the boot time-out occurred, but it is not\n killed in this case.\n\n- **`erl_flags`** - Specifies which flags are added to the parameters of the\n executable `erl`.\n\n- **`env`** - Specifies a list of environment variables that will extend the\n environment.\n\n_Special return values:_\n\n- `{error, already_started, NodeName}` if the node with the specified name is\n already started on a specified host.\n- `{error, started_not_connected, NodeName}` if the node is started, but not\n connected to the master node.\n- `{error, not_alive, NodeName}` if the node on which\n [`ct_slave:start/3`](`start/3`) is called, is not alive. Notice that\n `NodeName` is the name of the current node in this case.","ref":"ct_slave.html#start/3"},{"type":"function","title":"ct_slave.stop/1","doc":"Stops the running Erlang node with name `Node` on the local host.","ref":"ct_slave.html#stop/1"},{"type":"function","title":"ct_slave.stop/2","doc":"Stops the running Erlang node with name `Node` on host `Host`.","ref":"ct_slave.html#stop/2"},{"type":"type","title":"ct_slave.start_options/0","doc":"Options used for starting `ct_slave` node.","ref":"ct_slave.html#t:start_options/0"},{"type":"type","title":"ct_slave.stop_options/0","doc":"Options used for stopping `ct_slave` node.","ref":"ct_slave.html#t:stop_options/0"},{"type":"module","title":"ct_snmp","doc":"`Common Test` user interface module for the `SNMP` application.\n\nThe purpose of this module is to simplify SNMP configuration for the test case\nwriter. Many test cases can use default values for common operations and then no\nSNMP configuration files need to be supplied. When it is necessary to change\nparticular configuration parameters, a subset of the relevant SNMP configuration\nfiles can be passed to `ct_snmp` by `Common Test` configuration files. For more\nspecialized configuration parameters, a simple SNMP configuration file can be\nplaced in the test suite data directory. To simplify the test suite,\n`Common Test` keeps track of some of the SNMP manager information. This way the\ntest suite does not have to handle as many input parameters as if it had to\ninterface wthe OTP SNMP manager directly.\n\n_Configurable SNMP Manager and Agent Parameters:_\n\nManager configuration:\n\n- **`[{start_manager, boolean()}`** - Optional. Default is `true`.\n\n- **`{users, [{user_name(), [call_back_module(), user_data()]}]}`** - Optional.\n\n- **`{usm_users, [{usm_user_name(), [usm_config()]}]}`** - Optional. SNMPv3\n only.\n\n- **`{managed_agents,[{agent_name(), [user_name(), agent_ip(), agent_port(), [agent_config()]]}]}`** -\n `managed_agents` is optional.\n\n- **`{max_msg_size, integer()}`** - Optional. Default is `484`.\n\n- **`{mgr_port, integer()}`** - Optional. Default is `5000`.\n\n- **`{engine _id, string()}`** - Optional. Default is `\"mgrEngine\"`.\n\nAgent configuration:\n\n- **`{start_agent, boolean()}`** - Optional. Default is `false`.\n\n- **`{agent_sysname, string()}`** - Optional. Default is `\"ct_test\"`.\n\n- **`{agent_manager_ip, manager_ip()}`** - Optional. Default is `localhost`.\n\n- **`{agent_vsns, list()}`** - Optional. Default is `[v2]`.\n\n- **`{agent_trap_udp, integer()}`** - Optional. Default is `5000`.\n\n- **`{agent_udp, integer()}`** - Optional. Default is `4000`.\n\n- **`{agent_notify_type, atom()}`** - Optional. Default is `trap`.\n\n- **`{agent_sec_type, sec_type()}`** - Optional. Default is `none`.\n\n- **`{agent_passwd, string()}`** - Optional. Default is `\"\"`.\n\n- **`{agent_engine_id, string()}`** - Optional. Default is `\"agentEngine\"`.\n\n- **`{agent_max_msg_size, string()}`** - Optional. Default is `484`.\n\nThe following parameters represents the SNMP configuration files `context.conf`,\n`standard.conf`, `community.conf`, `vacm.conf`, `usm.conf`, `notify.conf`,\n`target_addr.conf`, and `target_params.conf`. Notice that all values in\n`agent.conf` can be modified by the parameters listed above. All these\nconfiguration files have default values set by the `SNMP` application. These\nvalues can be overridden by suppling a list of valid configuration values or a\nfile located in the test suites data directory, which can produce a list of\nvalid configuration values if you apply function `file:consult/1` to the file.\n\n- **`{agent_contexts, [term()] | {data_dir_file, rel_path()}}`** - Optional.\n\n- **`{agent_community, [term()] | {data_dir_file, rel_path()}}`** - Optional.\n\n- **`{agent_sysinfo, [term()] | {data_dir_file, rel_path()}}`** - Optional.\n\n- **`{agent_vacm, [term()] | {data_dir_file, rel_path()}}`** - Optional.\n\n- **`{agent_usm, [term()] | {data_dir_file, rel_path()}}`** - Optional.\n\n- **`{agent_notify_def, [term()] | {data_dir_file, rel_path()}}`** - Optional.\n\n- **`{agent_target_address_def, [term()] | {data_dir_file, rel_path()}}`** -\n Optional.\n\n- **`{agent_target_param_def, [term()] | {data_dir_file, rel_path()}}`** -\n Optional.\n\nParameter `MgrAgentConfName` in the functions is to be a name you allocate in\nyour test suite using a `require` statement. Example (where\n`MgrAgentConfName = snmp_mgr_agent`):\n\n```erlang\nsuite() -> [{require, snmp_mgr_agent, snmp}].\n```\n\nor\n\n```erlang\nct:require(snmp_mgr_agent, snmp).\n```\n\nNotice that USM users are needed for SNMPv3 configuration and are not to be\nconfused with users.\n\nSNMP traps, inform, and report messages are handled by the user callback module.\nFor details, see the [`SNMP`](`e:snmp:index.html`) application.\n\nIt is recommended to use the `.hrl` files created by the Erlang/OTP MIB compiler\nto define the Object Identifiers (OIDs). For example, to get the Erlang node\nname from `erlNodeTable` in the OTP-MIB:\n\n```erlang\nOid = ?erlNodeEntry ++ [?erlNodeName, 1]\n```\n\nFurthermore, values can be set for `SNMP` application configuration parameters,\n`config`, `server`, `net_if`, and so on (for a list of valid parameters and\ntypes, see the [`User's Guide for the SNMP application`](`e:snmp:index.html`)).\nThis is done by defining a configuration data variable on the following form:\n\n```erlang\n{snmp_app, [{manager, [snmp_app_manager_params()]},\n {agent, [snmp_app_agent_params()]}]}.\n```\n\nA name for the data must be allocated in the suite using `require` (see the\nexample above). Pass this name as argument `SnmpAppConfName` to\n[`ct_snmp:start/3`](`start/3`). `ct_snmp` specifies default values for some\n`SNMP` application configuration parameters (such as `{verbosity,trace}` for\nparameter `config`). This set of defaults is merged with the parameters\nspecified by the user. The user values override `ct_snmp` defaults.","ref":"ct_snmp.html"},{"type":"function","title":"ct_snmp.get_next_values/3","doc":"Issues a synchronous SNMP `get next` request.","ref":"ct_snmp.html#get_next_values/3"},{"type":"function","title":"ct_snmp.get_values/3","doc":"Issues a synchronous SNMP `get` request.","ref":"ct_snmp.html#get_values/3"},{"type":"function","title":"ct_snmp.load_mibs/1","doc":"Loads the MIBs into agent `snmp_master_agent`.","ref":"ct_snmp.html#load_mibs/1"},{"type":"function","title":"ct_snmp.register_agents/2","doc":"Explicitly instructs the manager to handle this agent. Corresponds to making an\nentry in `agents.conf`.\n\nThis function tries to register the specified managed agents, without checking\nif any of them exist. To change a registered managed agent, the agent must first\nbe unregistered.","ref":"ct_snmp.html#register_agents/2"},{"type":"function","title":"ct_snmp.register_users/2","doc":"Registers the manager entity (=user) responsible for specific agent(s).\nCorresponds to making an entry in `users.conf`.\n\nThis function tries to register the specified users, without checking if any of\nthem exist. To change a registered user, the user must first be unregistered.","ref":"ct_snmp.html#register_users/2"},{"type":"function","title":"ct_snmp.register_usm_users/2","doc":"Explicitly instructs the manager to handle this USM user. Corresponds to making\nan entry in `usm.conf`.\n\nThis function tries to register the specified users, without checking if any of\nthem exist. To change a registered user, the user must first be unregistered.","ref":"ct_snmp.html#register_usm_users/2"},{"type":"function","title":"ct_snmp.set_info/1","doc":"Returns a list of all successful `set` requests performed in the test case in\nreverse order. The list contains the involved user and agent, the value before\n`set`, and the new value. This is intended to simplify the cleanup in function\n`end_per_testcase`, that is, the undoing of the `set` requests and their\npossible side-effects.","ref":"ct_snmp.html#set_info/1"},{"type":"function","title":"ct_snmp.set_values/4","doc":"Issues a synchronous SNMP `set` request.","ref":"ct_snmp.html#set_values/4"},{"type":"function","title":"ct_snmp.start/2","doc":"","ref":"ct_snmp.html#start/2"},{"type":"function","title":"ct_snmp.start/3","doc":"Starts an SNMP manager and/or agent. In the manager case, registrations of users\nand agents, as specified by the configuration `MgrAgentConfName`, are performed.\nWhen using SNMPv3, called USM users are also registered. Users, `usm_users`, and\nmanaged agents can also be registered later using\n[`ct_snmp:register_users/2`](`register_users/2`),\n[`ct_snmp:register_agents/2`](`register_agents/2`), and\n[`ct_snmp:register_usm_users/2`](`register_usm_users/2`).\n\nThe agent started is called `snmp_master_agent`. Use\n[`ct_snmp:load_mibs/1`](`load_mibs/1`) to load MIBs into the agent.\n\nWith `SnmpAppConfName` SNMP applications can be configured with parameters\n`config`, `mibs`, `net_if`, and so on. The values are merged with (and possibly\noverride) default values set by `ct_snmp`.","ref":"ct_snmp.html#start/3"},{"type":"function","title":"ct_snmp.stop/1","doc":"Stops the SNMP manager and/or agent, and removes all files created.","ref":"ct_snmp.html#stop/1"},{"type":"function","title":"ct_snmp.unload_mibs/1","doc":"Unloads the MIBs from agent `snmp_master_agent`.","ref":"ct_snmp.html#unload_mibs/1"},{"type":"function","title":"ct_snmp.unregister_agents/1","doc":"Unregisters all managed agents.","ref":"ct_snmp.html#unregister_agents/1"},{"type":"function","title":"ct_snmp.unregister_agents/2","doc":"Unregisters the specified managed agents.","ref":"ct_snmp.html#unregister_agents/2"},{"type":"function","title":"ct_snmp.unregister_users/1","doc":"Unregisters all users.","ref":"ct_snmp.html#unregister_users/1"},{"type":"function","title":"ct_snmp.unregister_users/2","doc":"Unregisters the specified users.","ref":"ct_snmp.html#unregister_users/2"},{"type":"function","title":"ct_snmp.unregister_usm_users/1","doc":"Unregisters all USM users.","ref":"ct_snmp.html#unregister_usm_users/1"},{"type":"function","title":"ct_snmp.unregister_usm_users/2","doc":"Unregisters the specified USM users.","ref":"ct_snmp.html#unregister_usm_users/2"},{"type":"type","title":"ct_snmp.agent_config/0","doc":"","ref":"ct_snmp.html#t:agent_config/0"},{"type":"type","title":"ct_snmp.agent_ip/0","doc":"","ref":"ct_snmp.html#t:agent_ip/0"},{"type":"type","title":"ct_snmp.agent_name/0","doc":"","ref":"ct_snmp.html#t:agent_name/0"},{"type":"type","title":"ct_snmp.agent_port/0","doc":"","ref":"ct_snmp.html#t:agent_port/0"},{"type":"type","title":"ct_snmp.call_back_module/0","doc":"","ref":"ct_snmp.html#t:call_back_module/0"},{"type":"type","title":"ct_snmp.error_index/0","doc":"","ref":"ct_snmp.html#t:error_index/0"},{"type":"type","title":"ct_snmp.error_status/0","doc":"","ref":"ct_snmp.html#t:error_status/0"},{"type":"type","title":"ct_snmp.ip/0","doc":"","ref":"ct_snmp.html#t:ip/0"},{"type":"type","title":"ct_snmp.manager_ip/0","doc":"","ref":"ct_snmp.html#t:manager_ip/0"},{"type":"type","title":"ct_snmp.oid/0","doc":"","ref":"ct_snmp.html#t:oid/0"},{"type":"type","title":"ct_snmp.oids/0","doc":"","ref":"ct_snmp.html#t:oids/0"},{"type":"type","title":"ct_snmp.rel_path/0","doc":"","ref":"ct_snmp.html#t:rel_path/0"},{"type":"type","title":"ct_snmp.sec_type/0","doc":"","ref":"ct_snmp.html#t:sec_type/0"},{"type":"type","title":"ct_snmp.snmp_app_agent_params/0","doc":"","ref":"ct_snmp.html#t:snmp_app_agent_params/0"},{"type":"type","title":"ct_snmp.snmp_app_manager_params/0","doc":"","ref":"ct_snmp.html#t:snmp_app_manager_params/0"},{"type":"type","title":"ct_snmp.snmpreply/0","doc":"","ref":"ct_snmp.html#t:snmpreply/0"},{"type":"type","title":"ct_snmp.user_data/0","doc":"","ref":"ct_snmp.html#t:user_data/0"},{"type":"type","title":"ct_snmp.user_name/0","doc":"","ref":"ct_snmp.html#t:user_name/0"},{"type":"type","title":"ct_snmp.usm_config/0","doc":"","ref":"ct_snmp.html#t:usm_config/0"},{"type":"type","title":"ct_snmp.usm_user_name/0","doc":"","ref":"ct_snmp.html#t:usm_user_name/0"},{"type":"type","title":"ct_snmp.value_type/0","doc":"","ref":"ct_snmp.html#t:value_type/0"},{"type":"type","title":"ct_snmp.var_and_val/0","doc":"","ref":"ct_snmp.html#t:var_and_val/0"},{"type":"type","title":"ct_snmp.varbind/0","doc":"","ref":"ct_snmp.html#t:varbind/0"},{"type":"type","title":"ct_snmp.varbinds/0","doc":"","ref":"ct_snmp.html#t:varbinds/0"},{"type":"type","title":"ct_snmp.varsandvals/0","doc":"These data types are described in the documentation for the\n[`SNMP`](`e:snmp:index.html`) application.","ref":"ct_snmp.html#t:varsandvals/0"},{"type":"module","title":"ct_ssh","doc":"SSH/SFTP client module.\n\nThis module uses application `SSH`, which provides detailed information about,\nfor example, functions, types, and options.\n\nArgument `Server` in the SFTP functions is only to be used for SFTP sessions\nthat have been started on existing SSH connections (that is, when the original\nconnection type is `ssh`). Whenever the connection type is `sftp`, use the SSH\nconnection reference only.\n\nThe following options are valid for specifying an SSH/SFTP connection (that is,\ncan be used as configuration elements):\n\n```erlang\n[{ConnType, Addr},\n {port, Port},\n {user, UserName}\n {password, Pwd}\n {user_dir, String}\n {public_key_alg, PubKeyAlg}\n {connect_timeout, Timeout}\n {key_cb, KeyCallbackMod}]\n```\n\n`ConnType = ssh | sftp`.\n\nFor other types, see `m:ssh`.\n\nAll time-out parameters in `ct_ssh` functions are values in milliseconds.","ref":"ct_ssh.html"},{"type":"function","title":"ct_ssh.apread/4","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#apread/4"},{"type":"function","title":"ct_ssh.apread/5","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#apread/5"},{"type":"function","title":"ct_ssh.apwrite/4","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#apwrite/4"},{"type":"function","title":"ct_ssh.apwrite/5","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#apwrite/5"},{"type":"function","title":"ct_ssh.aread/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#aread/3"},{"type":"function","title":"ct_ssh.aread/4","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#aread/4"},{"type":"function","title":"ct_ssh.awrite/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#awrite/3"},{"type":"function","title":"ct_ssh.awrite/4","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#awrite/4"},{"type":"function","title":"ct_ssh.close/2","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#close/2"},{"type":"function","title":"ct_ssh.close/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#close/3"},{"type":"function","title":"ct_ssh.connect/1","doc":"","ref":"ct_ssh.html#connect/1"},{"type":"function","title":"ct_ssh.connect/2","doc":"Opens an SSH or SFTP connection using the information associated with `KeyOrName`\n(see `connect/3`).\n\nEquivalent to [`connect(KeyOrName, ConnType, [])`](`connect/3`) if\ncalled with ConnType being atom.\n\nEquivalent to [`connect(KeyOrName, host, ExtraOpts)`](`connect/3`) if\ncalled with ExtraOpts being list.","ref":"ct_ssh.html#connect/2"},{"type":"function","title":"ct_ssh.connect/3","doc":"Opens an SSH or SFTP connection using the information associated with\n`KeyOrName`.\n\nIf `Name` (an alias name for `Key`) is used to identify the connection, this\nname can be used as connection reference for subsequent calls. Only one open\nconnection at a time associated with `Name` is possible. If `Key` is used, the\nreturned handle must be used for subsequent calls (multiple connections can be\nopened using the configuration data specified by `Key`).\n\nFor information on how to create a new `Name`, see `ct:require/2`.\n\n`ConnType` always overrides the type specified in the address tuple in the\nconfiguration data (and in `ExtraOpts`). So it is possible to, for example, open\nan SFTP connection directly using data originally specifying an SSH connection.\nValue `host` means that the connection type specified by the host option (either\nin the configuration data or in `ExtraOpts`) is used.\n\n`ExtraOpts` (optional) are extra SSH options to be added to the configuration\ndata for `KeyOrName`. The extra options override any existing options with the\nsame key in the configuration data. For details on valid SSH options, see\napplication [`SSH`](`e:ssh:index.html`).","ref":"ct_ssh.html#connect/3"},{"type":"function","title":"ct_ssh.del_dir/2","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#del_dir/2"},{"type":"function","title":"ct_ssh.del_dir/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#del_dir/3"},{"type":"function","title":"ct_ssh.delete/2","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#delete/2"},{"type":"function","title":"ct_ssh.delete/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#delete/3"},{"type":"function","title":"ct_ssh.disconnect/1","doc":"Closes an SSH/SFTP connection.","ref":"ct_ssh.html#disconnect/1"},{"type":"function","title":"ct_ssh.exec/2","doc":"","ref":"ct_ssh.html#exec/2"},{"type":"function","title":"ct_ssh.exec/3","doc":"Requests server to perform `Command`, (see `exec/4`).\n\nEquivalent to [`exec(SSH, undefined, Command, Timeout)`](`exec/4`) if\ncalled with Command being string.\n\nEquivalent to [`exec(SSH, ChannelId, Command, DefaultTimeout)`](`exec/4`) if\ncalled with ChannelId being integer.","ref":"ct_ssh.html#exec/3"},{"type":"function","title":"ct_ssh.exec/4","doc":"Requests server to perform `Command`. A previously opened session channel is\nused for the request. `Data` is received from the server as a result of the\ncommand.","ref":"ct_ssh.html#exec/4"},{"type":"function","title":"ct_ssh.get_file_info/2","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#get_file_info/2"},{"type":"function","title":"ct_ssh.get_file_info/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#get_file_info/3"},{"type":"function","title":"ct_ssh.list_dir/2","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#list_dir/2"},{"type":"function","title":"ct_ssh.list_dir/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#list_dir/3"},{"type":"function","title":"ct_ssh.make_dir/2","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#make_dir/2"},{"type":"function","title":"ct_ssh.make_dir/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#make_dir/3"},{"type":"function","title":"ct_ssh.make_symlink/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#make_symlink/3"},{"type":"function","title":"ct_ssh.make_symlink/4","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#make_symlink/4"},{"type":"function","title":"ct_ssh.open/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#open/3"},{"type":"function","title":"ct_ssh.open/4","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#open/4"},{"type":"function","title":"ct_ssh.opendir/2","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#opendir/2"},{"type":"function","title":"ct_ssh.opendir/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#opendir/3"},{"type":"function","title":"ct_ssh.position/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#position/3"},{"type":"function","title":"ct_ssh.position/4","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#position/4"},{"type":"function","title":"ct_ssh.pread/4","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#pread/4"},{"type":"function","title":"ct_ssh.pread/5","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#pread/5"},{"type":"function","title":"ct_ssh.pwrite/4","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#pwrite/4"},{"type":"function","title":"ct_ssh.pwrite/5","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#pwrite/5"},{"type":"function","title":"ct_ssh.read/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#read/3"},{"type":"function","title":"ct_ssh.read/4","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#read/4"},{"type":"function","title":"ct_ssh.read_file/2","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#read_file/2"},{"type":"function","title":"ct_ssh.read_file/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#read_file/3"},{"type":"function","title":"ct_ssh.read_file_info/2","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#read_file_info/2"},{"type":"function","title":"ct_ssh.read_file_info/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#read_file_info/3"},{"type":"function","title":"ct_ssh.read_link/2","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#read_link/2"},{"type":"function","title":"ct_ssh.read_link/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#read_link/3"},{"type":"function","title":"ct_ssh.read_link_info/2","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#read_link_info/2"},{"type":"function","title":"ct_ssh.read_link_info/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#read_link_info/3"},{"type":"function","title":"ct_ssh.receive_response/2","doc":"","ref":"ct_ssh.html#receive_response/2"},{"type":"function","title":"ct_ssh.receive_response/3","doc":"Receives expected data from server on the specified session channel\n(see `receive_response/4`).\n\nEquivalent to [`receive_response(SSH, ChannelId, End, DefaultTimeout)`](`receive_response/4`) if\ncalled with End being function.\n\nEquivalent to [`receive_response(SSH, ChannelId, close, Timeout)`](`receive_response/4`) if\ncalled with Timeout being integer.","ref":"ct_ssh.html#receive_response/3"},{"type":"function","title":"ct_ssh.receive_response/4","doc":"Receives expected data from server on the specified session channel.\n\nIf `End == close`, data is returned to the caller when the channel is closed by\nthe server. If a time-out occurs before this happens, the function returns\n`{timeout,Data}` (where `Data` is the data received so far).\n\nIf `End == timeout`, a time-out is expected and `{ok,Data}` is returned both in\nthe case of a time-out and when the channel is closed.\n\nIf `End` is a fun, this fun is called with one argument, the data value in a\nreceived `ssh_cm` message (see `m:ssh_connection`. The fun is to return either\n`true` to end the receiving operation (and have the so far collected data\nreturned) or `false` to wait for more data from the server. Even if a fun is\nsupplied, the function returns immediately if the server closes the channel).","ref":"ct_ssh.html#receive_response/4"},{"type":"function","title":"ct_ssh.rename/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#rename/3"},{"type":"function","title":"ct_ssh.rename/4","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#rename/4"},{"type":"function","title":"ct_ssh.send/3","doc":"","ref":"ct_ssh.html#send/3"},{"type":"function","title":"ct_ssh.send/4","doc":"Sends data to server on specified session channel (see `send/5`).\n\nEquivalent to [`send(SSH, ChannelId, 0, Data, Timeout)`](`send/5`) if\ncalled with Timeout being integer.\n\nEquivalent to [`send(SSH, ChannelId, Type, Data, DefaultTimeout)`](`send/5`) if\ncalled with Type being integer.","ref":"ct_ssh.html#send/4"},{"type":"function","title":"ct_ssh.send/5","doc":"Sends data to server on specified session channel.","ref":"ct_ssh.html#send/5"},{"type":"function","title":"ct_ssh.send_and_receive/3","doc":"","ref":"ct_ssh.html#send_and_receive/3"},{"type":"function","title":"ct_ssh.send_and_receive/4","doc":"Sends data to server on specified session channel and waits to receive the\nserver response (see `send_and_receive/6`).\n\nEquivalent to\n[`send_and_receive(SSH, ChannelId, 0, Data, End, DefaultTimeout)`](`send_and_receive/6`)\nif called with End being function.\n\nEquivalent to\n[`send_and_receive(SSH, ChannelId, 0, Data, close, Timeout)`](`send_and_receive/6`)\nif called with Timeout being integer.\n\nEquivalent to\n[`send_and_receive(SSH, ChannelId, Type, Data, close, DefaultTimeout)`](`send_and_receive/6`)\nif called with Type being integer.","ref":"ct_ssh.html#send_and_receive/4"},{"type":"function","title":"ct_ssh.send_and_receive/5","doc":"Sends data to server on specified session channel and waits to receive the\nserver response (see `send_and_receive/6`).\n\nEquivalent to\n[`send_and_receive(SSH, ChannelId, 0, Data, End, Timeout)`](`send_and_receive/6`) if\ncalled with Timeout being integer.\n\nEquivalent to\n[`send_and_receive(SSH, ChannelId, Type, Data, close, Timeout)`](`send_and_receive/6`) if\ncalled with Type being integer.\n\nEquivalent to\n[`send_and_receive(SSH, ChannelId, Type, Data, End, DefaultTimeout)`](`send_and_receive/6`) if\ncalled with End being function.","ref":"ct_ssh.html#send_and_receive/5"},{"type":"function","title":"ct_ssh.send_and_receive/6","doc":"Sends data to server on specified session channel and waits to receive the\nserver response.\n\nFor details on argument `End`, see\n[`ct_ssh:receive_response/4`](`receive_response/4`).","ref":"ct_ssh.html#send_and_receive/6"},{"type":"function","title":"ct_ssh.session_close/2","doc":"Closes an SSH session channel.","ref":"ct_ssh.html#session_close/2"},{"type":"function","title":"ct_ssh.session_open/1","doc":"","ref":"ct_ssh.html#session_open/1"},{"type":"function","title":"ct_ssh.session_open/2","doc":"Opens a channel for an SSH session.","ref":"ct_ssh.html#session_open/2"},{"type":"function","title":"ct_ssh.sftp_connect/1","doc":"Starts an SFTP session on an already existing SSH connection. `Server`\nidentifies the new session and must be specified whenever SFTP requests are to\nbe sent.","ref":"ct_ssh.html#sftp_connect/1"},{"type":"function","title":"ct_ssh.shell/2","doc":"","ref":"ct_ssh.html#shell/2"},{"type":"function","title":"ct_ssh.shell/3","doc":"Requests that the user's default shell (typically defined in `/etc/passwd` in Unix\nsystems) is executed at the server end.","ref":"ct_ssh.html#shell/3"},{"type":"function","title":"ct_ssh.subsystem/3","doc":"","ref":"ct_ssh.html#subsystem/3"},{"type":"function","title":"ct_ssh.subsystem/4","doc":"Sends a request to execute a predefined subsystem.","ref":"ct_ssh.html#subsystem/4"},{"type":"function","title":"ct_ssh.write/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#write/3"},{"type":"function","title":"ct_ssh.write/4","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#write/4"},{"type":"function","title":"ct_ssh.write_file/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#write_file/3"},{"type":"function","title":"ct_ssh.write_file/4","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#write_file/4"},{"type":"function","title":"ct_ssh.write_file_info/3","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#write_file_info/3"},{"type":"function","title":"ct_ssh.write_file_info/4","doc":"For information and other types, see `m:ssh_sftp`.","ref":"ct_ssh.html#write_file_info/4"},{"type":"type","title":"ct_ssh.connection/0","doc":"Reference to opened SSH/SFTP connection associated to either a `handle` or `target_name`.","ref":"ct_ssh.html#t:connection/0"},{"type":"type","title":"ct_ssh.connection_type/0","doc":"Connection type used for connect.","ref":"ct_ssh.html#t:connection_type/0"},{"type":"type","title":"ct_ssh.handle/0","doc":"Handle for a specific SSH/SFTP connection, see module `m:ct`.","ref":"ct_ssh.html#t:handle/0"},{"type":"type","title":"ct_ssh.ssh_channel_id/0","doc":"Data type representing a channel inside a connection.\n\n\"For `ssh_channel_id`, see module `m:ssh`.\".","ref":"ct_ssh.html#t:ssh_channel_id/0"},{"type":"type","title":"ct_ssh.ssh_data_type_code/0","doc":"The valid values are `0` (\"normal\") and `1` (\"stderr\"), see\n[RFC 4254, Section 5.2](https://tools.ietf.org/html/rfc4254#page-8).","ref":"ct_ssh.html#t:ssh_data_type_code/0"},{"type":"behaviour","title":"ct_suite","doc":"The following section describes the mandatory and optional test suite functions\nthat `Common Test` calls during test execution. For more details, see section\n[Writing Test Suites](write_test_chapter.md) in the User's Guide.","ref":"ct_suite.html"},{"type":"callback","title":"ct_suite.all/0","doc":"Returns the list of all test cases and test case groups in the test suite module\nto be executed.\n\nThis list also specifies the order the cases and groups are\nexecuted by `Common Test`. A test case is represented by an atom, the name of\nthe test case function, or a `testcase` tuple indicating that the test case\nshall be repeated. A test case group is represented by a `group` tuple, where\n`GroupName`, an atom, is the name of the group (defined in\n[`Module:groups/0`](`c:groups/0`)). Execution properties for groups can also be\nspecified, both for a top-level group and for any of its subgroups. Group\nexecution properties specified here override properties in the group definition\n(see [`Module:groups/0`](`c:groups/0`)). (With value `default`, the group\ndefinition properties are used).\n\nIf `{skip, Reason}` is returned, all test cases in the module are skipped and\n`Reason` is printed on the HTML result page.\n\nFor details on groups, see section\n[Test Case Groups](write_test_chapter.md#test_case_groups) in the User's Guide.","ref":"ct_suite.html#c:all/0"},{"type":"callback","title":"ct_suite.end_per_group/2","doc":"This function is called after the execution of a test case group is finished. It\nis meant to be used for cleaning up after [`Module:init_per_group/2`](`c:init_per_group/2`).\n\nA status value for a nested subgroup can be returned with `{return_group_result, Status}`.\nThe status can be retrieved in [`Module:end_per_group/2`](`c:end_per_group/2`) for the group on\nthe level above. The status is also used by `Common Test` for deciding if\nexecution of a group is to proceed if property `sequence` or `repeat_until_*` is\nset.\n\nFor details about test case groups, see section\n[Test Case Groups](write_test_chapter.md#test_case_groups) in the User's Guide.\n\nIf this function is defined, then\n[`Module:init_per_group/2`](`c:init_per_group/2`) must also be defined.","ref":"ct_suite.html#c:end_per_group/2"},{"type":"callback","title":"ct_suite.end_per_suite/1","doc":"This function is called as the last test case in the suite. It is meant to be\nused for cleaning up after [`Module:init_per_suite/1`](`c:init_per_suite/1`).\n\nFor information on `save_config`, see section\n[Saving Configuration Data](dependencies_chapter.md#save_config) in the User's\nGuide.\n\nIf this function is defined, then\n[`Module:init_per_suite/1`](`c:init_per_suite/1`) must also be defined.","ref":"ct_suite.html#c:end_per_suite/1"},{"type":"callback","title":"ct_suite.end_per_testcase/2","doc":"This function is called after each test case, and can be used to clean up after\n[`Module:init_per_testcase/2`](`c:init_per_testcase/2`) and the test case.\n\nAny return value (besides `{fail, Reason}` and `{save_config, SaveConfig}`) is\nignored. By returning `{fail, Reason}`, `TestCase` is marked as faulty (even\nthough it was successful in the sense that it returned a value instead of\nterminating).\n\nFor information on `save_config`, see section\n[Saving Configuration Data](dependencies_chapter.md#save_config) in the User's\nGuide.\n\nIf this function is defined, then\n[`Module:init_per_testcase/2`](`c:init_per_testcase/2`) must also be defined.","ref":"ct_suite.html#c:end_per_testcase/2"},{"type":"callback","title":"ct_suite.group/1","doc":"The test case group information function. It is supposed to return a list of\ntagged tuples that specify various properties related to the execution of a test\ncase group (that is, its test cases and subgroups). Properties set by\n[`Module:group/1`](`c:group/1`) override properties with the same key that have\nbeen set previously by [`Module:suite/0`](`c:suite/0`).\n\nTag `timetrap` sets the maximum time that each test case is allowed to execute\n(including [`Module:init_per_testcase/2`](`c:init_per_testcase/2`) and\n[`Module:end_per_testcase/2`](`c:end_per_testcase/2`)). If the timetrap time is\nexceeded, the test case fails with reason `timetrap_timeout`. A `TimeFunc`\nfunction can be used to set a new timetrap by returning a `TimeVal`. It can also\nbe used to trigger a timetrap time-out by, at some point, returning a value\nother than a `TimeVal`. For details, see section\n[Timetrap Time-Outs](write_test_chapter.md#timetraps) in the User's Guide.\n\nTag `require` specifies configuration variables required by test cases (or\nconfiguration functions) in the suite. If the required configuration variables\nare not found in any of the configuration files, all test cases in this group\nare skipped. For details about the `require` functionality, see function\n[`ct:require/1,2`](`ct:require/1`).\n\nWith `userdata`, the user can specify any test case group related information\nthat can be read by calling `ct:userdata/2`.\n\nTag `ct_hooks` specifies the [Common Test Hooks](ct_hooks_chapter.md) to be run\nwith this suite.\n\nOther tuples than the ones defined are ignored.\n\nFor details about the test case group information function, see section\n[Group Information Function](write_test_chapter.md#group_info) in the User's\nGuide.","ref":"ct_suite.html#c:group/1"},{"type":"callback","title":"ct_suite.groups/0","doc":"Defines test case groups. For details, see section\n[Test Case Groups](write_test_chapter.md#test_case_groups) in the User's Guide.","ref":"ct_suite.html#c:groups/0"},{"type":"callback","title":"ct_suite.init_per_group/2","doc":"This configuration function is called before execution of a test case group. It\ntypically contains initializations that are common for all test cases and\nsubgroups in the group, and that must only be performed once.\n\n`GroupName` is the name of the group, as specified in the group definition (see\n[`Module:groups/0`](`c:groups/0`)). Parameter `Config` is the configuration data\nthat can be modified. The return value of this function is given as `Config` to\nall test cases and subgroups in the group.\n\nIf `{skip, Reason}` is returned, all test cases in the group are skipped and\n`Reason` is printed in the overview log for the group.\n\nFor information about test case groups, see section\n[Test Case Groups](write_test_chapter.md#test_case_groups) in the User's Guide.\n\nIf this function is defined, then\n[`Module:end_per_group/2`](`c:end_per_group/2`) must also be defined.","ref":"ct_suite.html#c:init_per_group/2"},{"type":"callback","title":"ct_suite.init_per_suite/1","doc":"This configuration function is called as the first function in the suite. It\ntypically contains initializations that are common for all test cases in the\nsuite, and that must only be done once.\n\nParameter `Config` is the configuration\ndata that can be modified. Whatever is returned from this function is specified\nas `Config` to all configuration functions and test cases in the suite.\n\nIf `{skip, Reason}` is returned, all test cases in the suite are skipped and\n`Reason` is printed in the overview log for the suite.\n\nFor information on `save_config` and `skip_and_save`, see section\n[Saving Configuration Data](dependencies_chapter.md#save_config) in the User's\nGuide.\n\nIf this function is defined, then\n[`Module:end_per_suite/1`](`c:end_per_suite/1`) must also be defined.","ref":"ct_suite.html#c:init_per_suite/1"},{"type":"callback","title":"ct_suite.init_per_testcase/2","doc":"This function is called before each test case.\n\nArgument `TestCase` is the test case name, and `Config` (list of key-value tuples)\nis the configuration data that can be modified. The `NewConfig` list returned from this\nfunction is given as `Config` to the test case.\n\nIf `{fail, Reason}` is returned, the test case is marked as failed without being executed.\n\nIf `{skip, Reason}` is returned, the test case is skipped and `Reason` is\nprinted in the overview log for the suite.\n\nIf this function is defined, then\n[`Module:end_per_testcase/2`](`c:end_per_testcase/2`) must also be defined.","ref":"ct_suite.html#c:init_per_testcase/2"},{"type":"callback","title":"ct_suite.suite/0","doc":"The test suite information function. Returns a list of tagged tuples specifying\nvarious properties related to the execution of this test suite (common for all\ntest cases in the suite).\n\nTag `timetrap` sets the maximum time that each test case is allowed to execute\n(including [`Module:init_per_testcase/2`](`c:init_per_testcase/2`) and\n[`Module:end_per_testcase/2`](`c:end_per_testcase/2`)). If the timetrap time is\nexceeded, the test case fails with reason `timetrap_timeout`. A `TimeFunc`\nfunction can be used to set a new timetrap by returning a `TimeVal`. It can also\nbe used to trigger a timetrap time-out by, at some point, returning a value\nother than a `TimeVal`. For details, see section\n[Timetrap Time-Outs](write_test_chapter.md#timetraps) in the User's Guide.\n\nTag `require` specifies configuration variables required by test cases (or\nconfiguration functions) in the suite. If the required configuration variables\nare not found in any of the configuration files, all test cases are skipped. For\ndetails about the `require` functionality, see function\n[`ct:require/1,2`](`ct:require/1`).\n\nWith `userdata`, the user can specify any test suite-related information, which\ncan be read by calling `ct:userdata/2`.\n\nTag `ct_hooks` specifies the [Common Test Hooks](ct_hooks_chapter.md) to be run\nwith this suite.\n\nOther tuples than the ones defined are ignored.\n\nFor details about the test suite information function, see section\n[Test Suite Information Function](write_test_chapter.md#suite) in the User's\nGuide.","ref":"ct_suite.html#c:suite/0"},{"type":"callback","title":"ct_suite.Testcase/0","doc":"The test case information function. It is supposed to return a list of tagged\ntuples that specify various properties related to the execution of this\nparticular test case. Properties set by [`Module:Testcase/0`](`c:'Testcase'/0`)\noverride properties set previously for the test case by\n[`Module:group/1`](`c:group/1`) or [`Module:suite/0`](`c:suite/0`).\n\nTag `timetrap` sets the maximum time that the test case is allowed to execute.\nIf the timetrap time is exceeded, the test case fails with reason\n`timetrap_timeout`. [`Module:init_per_testcase/2`](`c:init_per_testcase/2`) and\n[`Module:end_per_testcase/2`](`c:end_per_testcase/2`) are included in the\ntimetrap time. A `TimeFunc` function can be used to set a new timetrap by\nreturning a `TimeVal`. It can also be used to trigger a timetrap time-out by, at\nsome point, returning a value other than a `TimeVal`. For details, see section\n[Timetrap Time-Outs](write_test_chapter.md#timetraps) in the User's Guide.\n\nTag `require` specifies configuration variables that are required by the test\ncase (or [`init_per_testcase/2`](`c:init_per_testcase/2`) or\n[`end_per_testcase/2`](`c:end_per_testcase/2`)). If the required configuration\nvariables are not found in any of the configuration files, the test case is\nskipped. For details about the `require` functionality, see function\n[`ct:require/1,2`](`ct:require/1`).\n\nIf `timetrap` or `require` is not set, the default values specified by\n[`Module:suite/0`](`c:suite/0`) (or [`Module:group/1`](`c:group/1`)) are used.\n\nWith `userdata`, the user can specify any test case-related information that can\nbe read by calling `ct:userdata/3`.\n\nOther tuples than the ones defined are ignored.\n\nFor details about the test case information function, see section\n[Test Case Information Function](write_test_chapter.md#info_function) in the\nUser's Guide.","ref":"ct_suite.html#c:Testcase/0"},{"type":"callback","title":"ct_suite.Testcase/1","doc":"The implementation of a test case. Call the functions to test and check the\nresult. If something fails, ensure the function causes a runtime error or call\n[`ct:fail/1,2`](`ct:fail/1`) (which also causes the test case process to\nterminate).\n\nElements from the `Config` list can, for example, be read with\n`proplists:get_value/2` in STDLIB.\n\nPossible return values are:\n\n- **`{fail, Reason}`** - The test case is considered failed, and the `Reason`\n will be logged.\n\n- **`{skip, Reason}`** - The test case is considered skipped, and the `Reason`\n will be logged.\n\n- **`{comment, Comment}`** - The test case is considered successful, and the\n `Comment` will be logged.\n\n- **`{save_config, SaveConfig}`** - The test case is considered successful, and\n the `SaveConfig` will be stored in the `Config` (see section\n [Saving Configuration Data](dependencies_chapter.md#save_config) in the User's\n Guide).\n\n- **`{skip_and_save, Reason, SaveConfig}`** - The test case is considered\n skipped, the `Reason` will be logged, and the `SaveConfig` will be stored in\n the `Config` (see section\n [Saving Configuration Data](dependencies_chapter.md#save_config) in the User's\n Guide).\n\nIf the function returns any other term, the test case is considered successful.\n\nIf the test case function crashes, it is considered failed.\n\nFor details about test case implementation, see section\n[Test Cases](write_test_chapter.md#test_cases) in the User's Guide.","ref":"ct_suite.html#c:Testcase/1"},{"type":"type","title":"ct_suite.ct_config/0","doc":"The configuration data that can be modified.","ref":"ct_suite.html#t:ct_config/0"},{"type":"type","title":"ct_suite.ct_group_def/0","doc":"The test group definition, as returned by [`Module:groups/0`](`c:groups/0`).","ref":"ct_suite.html#t:ct_group_def/0"},{"type":"type","title":"ct_suite.ct_group_props/0","doc":"","ref":"ct_suite.html#t:ct_group_props/0"},{"type":"type","title":"ct_suite.ct_group_props_ref/0","doc":"","ref":"ct_suite.html#t:ct_group_props_ref/0"},{"type":"type","title":"ct_suite.ct_group_ref/0","doc":"","ref":"ct_suite.html#t:ct_group_ref/0"},{"type":"type","title":"ct_suite.ct_group_repeat_type/0","doc":"","ref":"ct_suite.html#t:ct_group_repeat_type/0"},{"type":"type","title":"ct_suite.ct_groupname/0","doc":"The name of the test group.","ref":"ct_suite.html#t:ct_groupname/0"},{"type":"type","title":"ct_suite.ct_hooks/0","doc":"","ref":"ct_suite.html#t:ct_hooks/0"},{"type":"type","title":"ct_suite.ct_info/0","doc":"The test suite information, as returned by [`Module:suite/0`](`c:suite/0`),\n[`Module:group/1`](`c:group/1`) and [`Module:Testcase/0`](`c:'Testcase'/0`).","ref":"ct_suite.html#t:ct_info/0"},{"type":"type","title":"ct_suite.ct_info_required/0","doc":"","ref":"ct_suite.html#t:ct_info_required/0"},{"type":"type","title":"ct_suite.ct_info_required_subkeys/0","doc":"","ref":"ct_suite.html#t:ct_info_required_subkeys/0"},{"type":"type","title":"ct_suite.ct_info_timetrap/0","doc":"","ref":"ct_suite.html#t:ct_info_timetrap/0"},{"type":"type","title":"ct_suite.ct_info_timetrap_fun/0","doc":"","ref":"ct_suite.html#t:ct_info_timetrap_fun/0"},{"type":"type","title":"ct_suite.ct_status/0","doc":"The status value for a nested subgroup.","ref":"ct_suite.html#t:ct_status/0"},{"type":"type","title":"ct_suite.ct_subgroups_def/0","doc":"","ref":"ct_suite.html#t:ct_subgroups_def/0"},{"type":"type","title":"ct_suite.ct_test_def/0","doc":"The test suite definition, as returned by [`Module:all/0`](`c:all/0`).","ref":"ct_suite.html#t:ct_test_def/0"},{"type":"type","title":"ct_suite.ct_test_repeat/0","doc":"","ref":"ct_suite.html#t:ct_test_repeat/0"},{"type":"type","title":"ct_suite.ct_testcase_ref/0","doc":"","ref":"ct_suite.html#t:ct_testcase_ref/0"},{"type":"type","title":"ct_suite.ct_testcase_repeat_prop/0","doc":"","ref":"ct_suite.html#t:ct_testcase_repeat_prop/0"},{"type":"type","title":"ct_suite.ct_testname/0","doc":"The name of the testcase function.","ref":"ct_suite.html#t:ct_testname/0"},{"type":"module","title":"ct_telnet","doc":"`Common Test` specific layer on top of Telnet client `ct_telnet_client.erl`.\n\nUse this module to set up Telnet connections, send commands, and perform string\nmatching on the result. For information about how to use `ct_telnet` and\nconfigure connections, specifically for UNIX hosts, see the `m:unix_telnet`\nmanual page.\n\nDefault values defined in `ct_telnet`:\n\n[](){: #Default_values }\n\n- Connection timeout (time to wait for connection) = 10 seconds\n- Command timeout (time to wait for a command to return) = 10 seconds\n- Max number of reconnection attempts = 3\n- Reconnection interval (time to wait in between reconnection attempts) = 5\n seconds\n- Keep alive (sends NOP to the server every 8 sec if connection is idle) =\n `true`\n- Polling limit (max number of times to poll to get a remaining string\n terminated) = 0\n- Polling interval (sleep time between polls) = 1 second\n- The TCP_NODELAY option for the telnet socket is disabled (set to `false`) per\n default\n\nThese parameters can be modified by the user with the following configuration\nterm:\n\n```erlang\n{telnet_settings, [{connect_timeout,Millisec},\n {command_timeout,Millisec},\n {reconnection_attempts,N},\n {reconnection_interval,Millisec},\n {keep_alive,Bool},\n {poll_limit,N},\n {poll_interval,Millisec},\n {tcp_nodelay,Bool}]}.\n```\n\n`Millisec = integer(), N = integer()`\n\nEnter the `telnet_settings` term in a configuration file included in the test\nand `ct_telnet` retrieves the information automatically.\n\n`keep_alive` can be specified per connection, if necessary. For details, see\n`m:unix_telnet`.","ref":"ct_telnet.html"},{"type":"module","title":"Logging - ct_telnet","doc":"[](){: #Logging }\n\nThe default logging behavior of `ct_telnet` is to print information about\nperformed operations, commands, and their corresponding results to the test case\nHTML log. The following is not printed to the HTML log: text strings sent from\nthe Telnet server that are not explicitly received by a `ct_telnet` function,\nsuch as [`expect/3`](`expect/3`). However, `ct_telnet` can be configured to use\na special purpose event handler, implemented in `ct_conn_log_h`, for logging\n_all_ Telnet traffic. To use this handler, install a `Common Test` hook named\n`cth_conn_log`. Example (using the test suite information function):\n\n```erlang\nsuite() ->\n [{ct_hooks, [{cth_conn_log, [{conn_mod(),hook_options()}]}]}].\n```\n\n`conn_mod()` is the name of the `Common Test` module implementing the connection\nprotocol, that is, `ct_telnet`.\n\nThe `cth_conn_log` hook performs unformatted logging of Telnet data to a\nseparate text file. All Telnet communication is captured and printed, including\nany data sent from the server. The link to this text file is located at the top\nof the test case HTML log.\n\nBy default, data for all Telnet connections is logged in one common file (named\n`default`), which can get messy, for example, if multiple Telnet sessions are\nrunning in parallel. Therefore a separate log file can be created for each\nconnection. To configure this, use hook option `hosts` and list the names of the\nservers/connections to be used in the suite. The connections must be named for\nthis to work (see [`ct_telnet:open/1,2,3,4`](`open/1`)).\n\nHook option `log_type` can be used to change the `cth_conn_log` behavior. The\ndefault value of this option is `raw`, which results in the behavior described\nabove. If the value is set to `html`, all Telnet communication is printed to the\ntest case HTML log instead.\n\nAll `cth_conn_log` hook options described can also be specified in a\nconfiguration file with configuration variable `ct_conn_log`.\n\n_Example:_\n\n```erlang\n{ct_conn_log, [{ct_telnet,[{log_type,raw},\n {hosts,[key_or_name()]}]}]}\n```\n\n> #### Note {: .info }\n>\n> Hook options specified in a configuration file overwrite any hard-coded hook\n> options in the test suite.\n\n[](){: #Logging_example }\n\n_Logging Example:_\n\nThe following `ct_hooks` statement causes printing of Telnet traffic to separate\nlogs for the connections `server1` and `server2`. Traffic for any other\nconnections is logged in the default Telnet log.\n\n```erlang\nsuite() ->\n [{ct_hooks,\n [{cth_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}]}].\n```\n\nAs previously explained, this specification can also be provided by an entry\nlike the following in a configuration file:\n\n```erlang\n{ct_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}.\n```\n\nIn this case the `ct_hooks` statement in the test suite can look as follows:\n\n```erlang\nsuite() ->\n [{ct_hooks, [{cth_conn_log, []}]}].\n```","ref":"ct_telnet.html#module-logging"},{"type":"module","title":"See Also - ct_telnet","doc":"`m:unix_telnet`","ref":"ct_telnet.html#module-see-also"},{"type":"function","title":"ct_telnet.close/1","doc":"Closes the Telnet connection and stops the process managing it.\n\nA connection can be associated with a target name and/or a handle. If\n`Connection` has no associated target name, it can only be closed with the\nhandle value (see [`ct_telnet:open/4`](`open/4`)).","ref":"ct_telnet.html#close/1"},{"type":"function","title":"ct_telnet.cmd/2","doc":"","ref":"ct_telnet.html#cmd/2"},{"type":"function","title":"ct_telnet.cmd/3","doc":"Sends a command through Telnet and waits for prompt.\n\nBy default, this function adds \"\\\\n\" to the end of the specified command. If\nthis is not desired, use option `{newline,false}`. This is necessary, for\nexample, when sending Telnet command sequences prefixed with character Interpret\nAs Command (IAC). Option `{newline,string()}` can also be used if a different\nline end than \"\\\\n\" is required, for instance `{newline,\"\\r\\n\"}`, to add both\ncarriage return and newline characters.\n\nOption `timeout` specifies how long the client must wait for prompt. If the time\nexpires, the function returns `{error,timeout}`. For information about the\ndefault value for the command timeout, see the\n[list of default values](`m:ct_telnet#Default_values`) in the beginning of this\nmodule.","ref":"ct_telnet.html#cmd/3"},{"type":"function","title":"ct_telnet.cmdf/3","doc":"","ref":"ct_telnet.html#cmdf/3"},{"type":"function","title":"ct_telnet.cmdf/4","doc":"Sends a Telnet command and waits for prompt (uses a format string and a list of\narguments to build the command).\n\nFor details, see [`ct_telnet:cmd/3`](`cmd/3`).","ref":"ct_telnet.html#cmdf/4"},{"type":"function","title":"ct_telnet.expect/2","doc":"","ref":"ct_telnet.html#expect/2"},{"type":"function","title":"ct_telnet.expect/3","doc":"Gets data from Telnet and waits for the expected pattern.\n\n`Pattern` can be a POSIX regular expression. The function returns when a pattern\nis successfully matched (at least one, in the case of multiple patterns).\n\n`RxMatch` is a list of matched strings. It looks as follows\n`[FullMatch, SubMatch1, SubMatch2, ...]`, where `FullMatch` is the string\nmatched by the whole regular expression, and `SubMatchN` is the string that\nmatched subexpression number `N`. Subexpressions are denoted with `'(' ')'` in\nthe regular expression.\n\nIf a `Tag` is specified, the returned `Match` also includes the matched `Tag`.\nOtherwise, only `RxMatch` is returned.\n\n_Options:_\n\n- **`idle_timeout`** - Indicates that the function must return if the Telnet\n client is idle (that is, if no data is received) for more than `IdleTimeout`\n milliseconds. Default time-out is 10 seconds.\n\n- **`total_timeout`** - Sets a time limit for the complete `expect` operation.\n After `TotalTimeout` milliseconds, `{error,timeout}` is returned. Default is\n `infinity` (that is, no time limit).\n\n- **`ignore_prompt | no_prompt_check`** - >The function returns when a prompt is\n received, even if no pattern has yet been matched, and\n `{error,{prompt,Prompt}}` is returned. However, this behavior can be modified\n with option `ignore_prompt` or option `no_prompt_check`, which tells `expect`\n to return only when a match is found or after a time-out.\n\n- **`ignore_prompt`** - `ct_telnet` ignores any prompt found. This option is\n useful if data sent by the server can include a pattern matching prompt\n `regexp` (as returned by `TargedMod:get_prompt_regexp/0`), but is not to not\n cause the function to return.\n\n- **`no_prompt_check`** - `ct_telnet` does not search for a prompt at all. This\n is useful if, for example, `Pattern` itself matches the prompt.\n\n- **`wait_for_prompt`** - Forces `ct_telnet` to wait until the prompt string is\n received before returning (even if a pattern has already been matched). This\n is equal to calling\n [`expect(Conn, Patterns++[{prompt,Prompt}], [sequence|Opts])`](`expect/3`).\n Notice that option `idle_timeout` and `total_timeout` can abort the operation\n of waiting for prompt.\n\n- **`repeat | repeat, N`** - The pattern(s) must be matched multiple times. If\n `N` is specified, the pattern(s) are matched `N` times, and the function\n returns `HaltReason = done`. This option can be interrupted by one or more\n `HaltPatterns`. `MatchList` is always returned, that is, a list of `Match`\n instead of only one `Match`. Also `HaltReason` is returned.\n\n- **`sequence`** - All patterns must be matched in a sequence. A match is not\n concluded until all patterns are matched. This option can be interrupted by\n one or more `HaltPatterns`. `MatchList` is always returned, that is, a list of\n `Match` instead of only one `Match`. Also `HaltReason` is returned.\n\n_Example 1:_\n\n```erlang\nexpect(Connection,[{abc,\"ABC\"},{xyz,\"XYZ\"}],[sequence,{halt,[{nnn,\"NNN\"}]}])\n```\n\nFirst this tries to match `\"ABC\"`, and then `\"XYZ\"`, but if `\"NNN\"` appears, the\nfunction returns `{error,{nnn,[\"NNN\"]}}`. If both `\"ABC\"` and `\"XYZ\"` are\nmatched, the function returns `{ok,[AbcMatch,XyzMatch]}`.\n\n_Example 2:_\n\n```erlang\nexpect(Connection,[{abc,\"ABC\"},{xyz,\"XYZ\"}],[{repeat,2},{halt,[{nnn,\"NNN\"}]}])\n```\n\nThis tries to match `\"ABC\"` or `\"XYZ\"` twice. If `\"NNN\"` appears, the function\nreturns `HaltReason = {nnn,[\"NNN\"]}`.\n\nOptions `repeat` and `sequence` can be combined to match a sequence multiple\ntimes.","ref":"ct_telnet.html#expect/3"},{"type":"function","title":"ct_telnet.get_data/1","doc":"Gets all data received by the Telnet client since the last command was sent.\nOnly newline-terminated strings are returned. If the last received string has\nnot yet been terminated, the connection can be polled automatically until the\nstring is complete.\n\nThe polling feature is controlled by the configuration values `poll_limit` and\n`poll_interval` and is by default disabled. This means that the function\nimmediately returns all complete strings received and saves a remaining\nnon-terminated string for a later `get_data` call.","ref":"ct_telnet.html#get_data/1"},{"type":"function","title":"ct_telnet.open/1","doc":"","ref":"ct_telnet.html#open/1"},{"type":"function","title":"ct_telnet.open/2","doc":"Opens a Telnet connection to the specified target host.","ref":"ct_telnet.html#open/2"},{"type":"function","title":"ct_telnet.open/3","doc":"","ref":"ct_telnet.html#open/3"},{"type":"function","title":"ct_telnet.open/4","doc":"Opens a Telnet connection to the specified target host.\n\nThe target data must exist in a configuration file. The connection can be\nassociated with `Name` and/or the returned `Handle`. To allocate a name for the\ntarget, use one of the following alternatives:\n\n- `ct:require/2` in a test case\n- A `require` statement in the suite information function (`suite/0`)\n- A `require` statement in a test case information function\n\nIf you want the connection to be associated with `Handle` only (if you, for\nexample, need to open multiple connections to a host), use `Key`, the\nconfiguration variable name, to specify the target. Notice that a connection\nwithout an associated target name can only be closed with the `Handle` value.\n\n`TargetMod` is a module that exports the functions\n`connect(Ip, Port, KeepAlive, Extra)` and `get_prompt_regexp()` for the\nspecified `TargetType` (for example, `unix_telnet`).\n\nSee also `ct:require/2`.","ref":"ct_telnet.html#open/4"},{"type":"function","title":"ct_telnet.send/2","doc":"","ref":"ct_telnet.html#send/2"},{"type":"function","title":"ct_telnet.send/3","doc":"Sends a Telnet command and returns immediately.\n\nBy default, this function adds \"\\\\n\" to the end of the specified command. If\nthis is not desired, option `{newline,false}` can be used. This is necessary,\nfor example, when sending Telnet command sequences prefixed with character\nInterpret As Command (IAC). Option `{newline,string()}` can also be used if a\ndifferent line end than \"\\\\n\" is required, for instance `{newline,\"\\r\\n\"}`, to\nadd both carriage return and newline characters.\n\nThe resulting output from the command can be read with\n[`ct_telnet:get_data/2`](`get_data/1`) or [`ct_telnet:expect/2,3`](`expect/2`).","ref":"ct_telnet.html#send/3"},{"type":"function","title":"ct_telnet.sendf/3","doc":"","ref":"ct_telnet.html#sendf/3"},{"type":"function","title":"ct_telnet.sendf/4","doc":"Sends a Telnet command and returns immediately (uses a format string and a list\nof arguments to build the command).\n\nFor details, see [`ct_telnet:send/3`](`send/3`).","ref":"ct_telnet.html#sendf/4"},{"type":"type","title":"ct_telnet.connection/0","doc":"Reference to opened Telnet connection associated to either a `handle` or `target_name`.","ref":"ct_telnet.html#t:connection/0"},{"type":"type","title":"ct_telnet.connection_type/0","doc":"Telnet connection_type, valid values: 'telnet' | 'ts1' | 'ts2'.","ref":"ct_telnet.html#t:connection_type/0"},{"type":"type","title":"ct_telnet.handle/0","doc":"Handle for a specific Telnet connection, see module `m:ct`.","ref":"ct_telnet.html#t:handle/0"},{"type":"type","title":"ct_telnet.newline_option/0","doc":"See `cmd/3` for explanation.","ref":"ct_telnet.html#t:newline_option/0"},{"type":"type","title":"ct_telnet.prompt_regexp/0","doc":"Regular expression matching all possible prompts for a specific target type.\n`regexp` must not have any groups, that is, when matching, `re:run/3` (in\nSTDLIB) must return a list with one single element.","ref":"ct_telnet.html#t:prompt_regexp/0"},{"type":"module","title":"ct_testspec","doc":"Parsing of test specifications for `Common Test`.\n\nThis module exports help functions for parsing of test specifications.","ref":"ct_testspec.html"},{"type":"function","title":"ct_testspec.get_tests/1","doc":"Parse the given test specification files and return the tests to run and skip.\n\n[](){: #add_nodes-1 }\n\nIf `SpecsIn=[Spec1,Spec2,...]`, separate tests will be created per\nspecification. If `SpecsIn=[[Spec1,Spec2,...]]`, all specifications will be\nmerge into one test.\n\nFor each test, a `{Specs,Tests}` element is returned, where `Specs` is a list of\nall included test specifications, and `Tests` specifies actual tests to run/skip\nper node.","ref":"ct_testspec.html#get_tests/1"},{"type":"module","title":"unix_telnet","doc":"Callback module for `m:ct_telnet`, for connecting to a Telnet server on a UNIX\nhost.\n\nIt requires the following entry in the configuration file:\n\n```erlang\n{unix,[{telnet,HostNameOrIpAddress},\n {port,PortNum}, % optional\n {username,UserName},\n {password,Password},\n {keep_alive,Bool}]}. % optional\n```\n\nTo communicate through Telnet to the host specified by `HostNameOrIpAddress`,\nuse the interface functions in `m:ct_telnet`, for example, `open(Name)` and\n`cmd(Name,Cmd)`.\n\n`Name` is the name you allocated to the Unix host in your `require` statement,\nfor example:\n\n```erlang\nsuite() -> [{require,Name,{unix,[telnet]}}].\n```\n\nor\n\n```erlang\nct:require(Name,{unix,[telnet]}).\n```\n\nThe \"keep alive\" activity (that is, that `Common Test` sends NOP to the server\nevery 10 seconds if the connection is idle) can be enabled or disabled for one\nparticular connection as described here. It can be disabled for all connections\nusing `telnet_settings` (see `m:ct_telnet`).\n\nThe `{port,PortNum}` tuple is optional and if omitted, default Telnet port 23 is\nused. Also the `keep_alive` tuple is optional, and the value default to `true`\n(enabled).","ref":"unix_telnet.html"},{"type":"module","title":"See Also - unix_telnet","doc":"`m:ct`, `m:ct_telnet`","ref":"unix_telnet.html#module-see-also"},{"type":"function","title":"unix_telnet.connect/7","doc":"Callback for `ct_telnet.erl`.\n\n[](){: #connect-6 }\n\nSetup Telnet connection to a Unix host.","ref":"unix_telnet.html#connect/7"},{"type":"function","title":"unix_telnet.get_prompt_regexp/0","doc":"Callback for `ct_telnet.erl`.\n\nReturns a suitable `regexp` string matching common prompts for users on Unix\nhosts.","ref":"unix_telnet.html#get_prompt_regexp/0"},{"type":"extras","title":"Common Test Application","doc":"\n# Common Test Application\n\nA framework for automated testing of any target nodes.","ref":"common_test_app.html"},{"type":"extras","title":"Description - Common Test Application","doc":"The `Common Test` framework is an environment for implementing and performing\nautomatic and semi-automatic execution of test cases.\n\nIn brief, `Common Test` supports:\n\n- Automated execution of test suites (sets of test cases)\n- Logging of events during execution\n- HTML presentation of test suite results\n- HTML presentation of test suite code\n- Support functions for test suite authors\n- Step-by-step execution of test cases","ref":"common_test_app.html#description"},{"type":"extras","title":"Common Test Release Notes","doc":"\n# Common Test Release Notes","ref":"notes.html"},{"type":"extras","title":"Common_Test 1.27 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-27"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Calls to `ct:capture_start/0` and `ct:capture_stop/0` are now synchronous to ensure that all output is captured.\n\n Own Id: OTP-18658 Aux Id: [PR-7380]\n\n- The order in which multiple hooks are executed can now be reversed after each config function. See [CTH Execution Order](`e:common_test:ct_hooks_chapter.md#cth_execution_order`).\n\n Own Id: OTP-18682 Aux Id: [GH-7397], [PR-7496], ERIERL-43\n\n- The default CSS will now include a basic dark mode handling if it is preferred by the browser.\n\n Own Id: OTP-18761 Aux Id: [PR-7428]\n\n- `-callback` attributes have been added to `m:ct_suite` and `m:ct_hooks`.\n\n Own Id: OTP-18781 Aux Id: [PR-7701]\n\n- The built-in [cth_log_redirect](`e:common_test:ct_hooks_chapter.md#built-in-cths`) hook can now be configured to replace default logger reports in terminal with HTML logs.\n\n Own Id: OTP-18875 Aux Id: [PR-7891]\n\n- Error handling for the `m:ct_property_test` framework has been enhanced.\n\n Own Id: OTP-18881 Aux Id: [PR-7824]\n\n- Enhance test case documentation, making it clear how a test case can be failed.\n\n Own Id: OTP-18892 Aux Id: [PR-7869]\n\n- The failing line in the test source code is now colored to make it easier to find on the screen.\n\n Own Id: OTP-18898 Aux Id: [PR-7917]\n\n- Function specifications and types have been added to all public API functions.\n\n Own Id: OTP-18913\n\n- The documentation has been migrated to use Markdown and ExDoc.\n\n Own Id: OTP-18955 Aux Id: [PR-8026]\n\n- The suite execution elapsed time is now included in the index page.\n\n Own Id: OTP-18981 Aux Id: [GH-7972], [PR-8112]\n\n[PR-7380]: https://github.com/erlang/otp/pull/7380\n[GH-7397]: https://github.com/erlang/otp/issues/7397\n[PR-7496]: https://github.com/erlang/otp/pull/7496\n[PR-7428]: https://github.com/erlang/otp/pull/7428\n[PR-7701]: https://github.com/erlang/otp/pull/7701\n[PR-7891]: https://github.com/erlang/otp/pull/7891\n[PR-7824]: https://github.com/erlang/otp/pull/7824\n[PR-7869]: https://github.com/erlang/otp/pull/7869\n[PR-7917]: https://github.com/erlang/otp/pull/7917\n[PR-8026]: https://github.com/erlang/otp/pull/8026\n[GH-7972]: https://github.com/erlang/otp/issues/7972\n[PR-8112]: https://github.com/erlang/otp/pull/8112","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.26.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-26-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"* With this change, the last column in common_test testcase log file is modified to now show the total sum of each time in the table rows, and Elapsed Time which is a clock time spent to run above functions. The Elapsed Time is the same time that was previously a total.\n\n Own Id: OTP-18960","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.26.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-26-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"* Fix how CT finds Erlang/OTP releases for compatability testing. This functionality is only used to test Erlang/OTP.\n\n Own Id: OTP-18932","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.26 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-26"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- With this change, common_test returns an error when suite with a badly defined\n group is executed.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-18728 Aux Id: PR-7487, PR-7674\n\n- With this change, stylesheet option is applied to all HTML report pages.\n\n Own Id: OTP-18760\n\n- Update all html tags to be instead.\n\n Own Id: OTP-18799 Aux Id: PR-7695","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- This change fixes docs, so that historically deprecated ?config macro is no\n longer recommended to be used.\n\n Own Id: OTP-18858 Aux Id: PR-7825","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.25.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-25-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- With this change, ct_hooks manual refers to CTH execution order section in\n user guide.\n\n Own Id: OTP-14480 Aux Id: ERIERL-43, OTP-11894, PR-7455\n\n- With this change, Config data from pre_end_per_testcase hook is delivered to\n post_end_per_testcase callback in case of testcase timetrap or linked process\n crash.\n\n Own Id: OTP-18579 Aux Id: GH-7119\n\n- With this change, remaining references to not supported vts tool in ct_run are\n removed (mainly relates to docs and ct_run help message).\n\n Own Id: OTP-18615 Aux Id: PR-7234\n\n- With this change, prompt search functionality in ct_telnet handles unicode\n input.\n\n Own Id: OTP-18664 Aux Id: ERIERL-959\n\n- Expanded the documentation about how to use the `standard_io`,\n `standard_error` and `user` I/O devices.\n\n Added the types [`io:standard_io/0`](`t:io:standard_io/0`),\n `io:standard:error/0` and [`io:user/0`](`t:io:user/0`).\n\n Own Id: OTP-18676 Aux Id: PR-7473 GH-7459","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.25 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-25"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- This change improves Common Test docs (CT hook example code) and adds Emacs\n skeleton with hook code.\n\n Own Id: OTP-18377 Aux Id: PR-6437","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Updated common_test with a more robust way to fetch old releases, while\n ignoring the current release.\n\n Own Id: OTP-18259 Aux Id: PR-5924\n\n- \\- re-write the XML `ct` module documentation into erlang types to make\n Dialyzer able to catch more precise errors\n\n Own Id: OTP-18340\n\n- Deprecates `dbg:stop_clear/0` because it is simply a function alias to\n `dbg:stop/0`\n\n Own Id: OTP-18478 Aux Id: GH-6903","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.24.0.3 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-24-0-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"* With this change, the last column in common_test testcase log file is modified to now show the total sum of each time in the table rows, and Elapsed Time which is a clock time spent to run above functions. The Elapsed Time is the same time that was previously a total.\n\n Own Id: OTP-18960","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.24.0.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-24-0-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"* Fix how CT finds Erlang/OTP releases for compatability testing. This functionality is only used to test Erlang/OTP.\n\n Own Id: OTP-18932","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.24.0.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-24-0-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- With this change, prompt search functionality in ct_telnet handles unicode\n input.\n\n Own Id: OTP-18664 Aux Id: ERIERL-959","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.24 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-24"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Renamed undocumented macro `CT_PEER/3` to `CT_PEER_REL/3`.\n\n Own Id: OTP-18460","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.23.3 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-23-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Change timeout to infinity for gen_server calls in cth_log_redirect\n\n Own Id: OTP-18363 Aux Id: ERIERL-879","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.23.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-23-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Fix starting of peer nodes on old releases when the compile server was active\n and the current Erlang installation contained non-latin1 characters in its\n path.\n\n Own Id: OTP-18255 Aux Id: PR-6314","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.23.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-23-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Fix cth_surefire to handle when a suite is not compiled with `debug_info`.\n This bug has been present since Erlang/OTP 25.0.\n\n Own Id: OTP-18208 Aux Id: ERIERL-852 PR-6229","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Common Test now preserves stack traces for throws.\n\n Own Id: OTP-18138 Aux Id: GH-5719, PR-6029","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.23 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-23"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Fix bug when running parallel test cases and together with one or more ct\n hooks that would cause the hook lock process to crash and produce printouts in\n the ct logs.\n\n Own Id: OTP-17881 Aux Id: PR-5581","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Input for `configure` scripts adapted to `autoconf` 2\\.71.\n\n Own Id: OTP-17414 Aux Id: PR-4967\n\n- Remove unused and undocumented tracer node functionality.\n\n Own Id: OTP-17676 Aux Id: PR-5021\n\n- The new module `peer` supersedes the `slave` module. The `slave` module is now\n deprecated and will be removed in OTP 27.\n\n `peer` contains an extended and more robust API for starting erlang nodes.\n\n Own Id: OTP-17720 Aux Id: PR-5162\n\n- The cth_surefire ct hook has been updated to include the file and line number\n of the executed test case in the xml output.\n\n The performance of the hook has also been improved greatly for test runs with\n many test cases.\n\n Own Id: OTP-17882 Aux Id: PR-5581","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.22.1.3 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-22-1-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"* With this change, the last column in common_test testcase log file is modified to now show the total sum of each time in the table rows, and Elapsed Time which is a clock time spent to run above functions. The Elapsed Time is the same time that was previously a total.\n\n Own Id: OTP-18960","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.22.1.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-22-1-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"* Fix how CT finds Erlang/OTP releases for compatability testing. This functionality is only used to test Erlang/OTP.\n\n Own Id: OTP-18932","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.22.1.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-22-1-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Change timeout to infinity for gen_server calls in cth_log_redirect\n\n Own Id: OTP-18363 Aux Id: ERIERL-879","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.22.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-22-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- OTP internal test fix.\n\n Own Id: OTP-17888","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.22 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-22"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Before this change, group handling grammar was ambiguous and also group paths\n did not support test specs.\n\n Own Id: OTP-17664 Aux Id: GH-5088, PR-5242\n\n- Before this change, it was not possible to link to a particular header entry\n in Common Test log. Change adds right aligned anchor icons in HTML test logs.\n\n Own Id: OTP-17790 Aux Id: PR-5375","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.21 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-21"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Float allowed as multiply_timetraps parameter.\n\n Own Id: OTP-17413 Aux Id: PR-4767\n\n- Remove usage of legacy API macro and functions.\n\n Own Id: OTP-17632 Aux Id: PR-5022","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.20.5 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-20-5"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- An incoming NETCONF notification received before a call to\n ct_netconfc:create_subscription/\\* caused the connection process to fail with\n badarg. Unexpected notifications are now logged in the same way as other\n unexpected messages.\n\n Own Id: OTP-17506","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Add 'receiver' option to ct_netconfc\n\n To allow a destination for incoming NETCONF notifications to be specified at\n sessions creation. Previously, a caller of create_subscription/\\* became the\n destination, but RFC 5277 create-subscription is no longer the only way in\n which NETCONF notifications can be ordered.\n\n Own Id: OTP-17509","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.20.4 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-20-4"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Commit of generated `configure` script.\n\n Own Id: OTP-17420 Aux Id: OTP-17398, GH-4821","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.20.3 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-20-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The option `release_shell` could crash when used together with the `spec`\n option.\n\n Own Id: OTP-16940 Aux Id: ERL-1335","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- The experimental HiPE application has been removed, together with all related\n functionality in other applications.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-16963\n\n- Fixed warnings in code matching on underscore prefixed variables.\n\n Own Id: OTP-17385 Aux Id: OTP-17123","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.20.2.3 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-20-2-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- OTP internal test fix.\n\n Own Id: OTP-17888","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.20.2.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-20-2-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- An incoming NETCONF notification received before a call to\n ct_netconfc:create_subscription/\\* caused the connection process to fail with\n badarg. Unexpected notifications are now logged in the same way as other\n unexpected messages.\n\n Own Id: OTP-17506","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Add 'receiver' option to ct_netconfc\n\n To allow a destination for incoming NETCONF notifications to be specified at\n sessions creation. Previously, a caller of create_subscription/\\* became the\n destination, but RFC 5277 create-subscription is no longer the only way in\n which NETCONF notifications can be ordered.\n\n Own Id: OTP-17509","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.20.2.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-20-2-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Commit of generated `configure` script.\n\n Own Id: OTP-17420 Aux Id: OTP-17398, GH-4821","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.20.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-20-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Before this change Config leaked between test groups in case of a subgroup was\n skipped (GH-3480).\n\n Own Id: OTP-17347 Aux Id: GH-3480,ERL-1439","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.20.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-20-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- A race condition could cause ct_netconfc:open/_ to return a dysfunctional\n handle, resulting in errors when invoking other api functions on it, and\n making it impossible to establish a new connection to the server in question.\n Similar symptoms were possible with open/_ in modules ct_ssh and ct_telnet.\n\n Internal messages from common_test processes could be left in the caller's\n message queue after a timeout when invoking call/\\* in modules ct_netconfc and\n ct_ssh. An internal process used by module ct_telnet could leak memory due to\n stray messages.\n\n Calls to ct_telnet:open/\\* and ct_telnet:get_data/1 could hang indefinitely if\n the TCP connection to the server was lost.\n\n Own Id: OTP-17328 Aux Id: ERIERL-631","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.20 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-20"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Various address sanitizer support.\n\n Own Id: OTP-16959 Aux Id: PR-2965","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.19.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-19-1"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Add behaviour for test suites\n\n Own Id: OTP-17070","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.19 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-19"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- The function `ct_property_test:init_tool/1` is added for the cases when the\n user does not want ct_property_test to compile properties. init_tool/1 can be\n used to set the property_test_tool config value.\n\n Own Id: OTP-16029 Aux Id: PR-2145\n\n- The built-in Common Test Hook, `cth_log_redirect`, has been updated to use the\n system `default` Logger handler's configuration instead of its own. See the\n section on [Built-in Hooks](ct_hooks_chapter.md#built-in-cths) in the Common\n Test User's Guide.\n\n Own Id: OTP-16273\n\n- Calls of deprecated functions in the\n [Old Crypto API](`e:crypto:new_api.md#the-old-api`) are replaced by calls of\n their [substitutions](`e:crypto:new_api.md#the-new-api`).\n\n Own Id: OTP-16346","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.18.2.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-18-2-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- OTP internal test fix.\n\n Own Id: OTP-17888","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.18.2.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-18-2-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Commit of generated `configure` script.\n\n Own Id: OTP-17420 Aux Id: OTP-17398, GH-4821","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.18.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-18-2"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Document incl_apps cover option\n\n Own Id: OTP-16039 Aux Id: ERL-795\n\n- The `ct_property_test` has now a report function for results of stateful\n testing.\n\n Own Id: OTP-16340\n\n- Don't hide error reasons from user\n\n Own Id: OTP-16364 Aux Id: PR-2480","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.18.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-18-1"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- The ct_property_test logging is improved.\n\n Own Id: OTP-16287","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.18 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-18"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- If a ct hook is installed in the `suite/0` function in a test suite, then the\n hook's `terminate/1` function would be called several times without it's\n `init/2` function being called first. This is now corrected.\n\n Own Id: OTP-15863 Aux Id: ERIERL-370\n\n- If `init_per_testcase` fails, the test itself is skipped. According to the\n documentation, it should be possible to change the result to failed in a hook\n function. The only available hook function in this case is\n `post_init_per_testcase`, but changing the return value there did not affect\n the test case result. This is now corrected.\n\n Own Id: OTP-15869 Aux Id: ERIERL-350","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Add ct_netconfc support for NETCONF 1.1 (RFC 6241). The 1.1 base capability\n can be sent in hello, and RFC 6242 chunk framing is applied when both client\n and server advertise 1.1 support.\n\n Own Id: OTP-15789\n\n- Correct lib_dir paths in common_tests opaque data structure that is passed to\n ct_release_test callback modules in functions upgrade_init/2,\n upgrade_upgraded/2 and upgrade_downgraded/2. The incorrect paths may cause\n confusion when debugging although it will not cause any incorrect behavior on\n the part of common_test as it is currently not used.\n\n Own Id: OTP-15934","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.17.3 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-17-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- All incorrect (that is, all) uses of \"can not\" has been corrected to \"cannot\"\n in source code comments, documentation, examples, and so on.\n\n Own Id: OTP-14282 Aux Id: PR-1891","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Use `ssh` instead of `rsh` as the default remote shell.\n\n Own Id: OTP-15633 Aux Id: PR-1787","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.17.2.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-17-2-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- If a ct hook is installed in the `suite/0` function in a test suite, then the\n hook's `terminate/1` function would be called several times without it's\n `init/2` function being called first. This is now corrected.\n\n Own Id: OTP-15863 Aux Id: ERIERL-370\n\n- If `init_per_testcase` fails, the test itself is skipped. According to the\n documentation, it should be possible to change the result to failed in a hook\n function. The only available hook function in this case is\n `post_init_per_testcase`, but changing the return value there did not affect\n the test case result. This is now corrected.\n\n Own Id: OTP-15869 Aux Id: ERIERL-350","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.17.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-17-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The test result when a hook function fails is in general the same as if the\n function that the hook is associated with fails. For example, if\n `post_init_per_testcase` fails the result is that the test case is skipped, as\n is the case when `init_per_testcase` fails.This, however, was earlier not true\n for timetrap timeouts or other error situations where the process running the\n hook function was killed. This is now corrected, so the error handling should\n be the same no matter how the hook function fails.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-15717 Aux Id: ERIERL-334\n\n- In some rare cases, when two common_test nodes used the same log directory, a\n timing problem could occur which caused common_test to crash because it's log\n cache file was unexpectedly empty. This is now corrected.\n\n Own Id: OTP-15758 Aux Id: ERIERL-342","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Two new common_test hook functions are introduced:\n\n `post_groups/2`, which is called after `Suite:groups/0` \n `post_all/3`, which is called after `Suite:all/0`\n\n These functions allow modifying the return values from the `groups/0` and\n `all/0` functions, respectively.\n\n A new term, `{testcase,TestCase,RepeatProperties}` is now also allowed in the\n return from `all/0`. This can be used for repeating a single test case a\n specific number of times, or until it fails or succeeds once.\n\n Own Id: OTP-14746 Aux Id: ERIERL-143","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.17.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-17-1"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- OTP internal test improvements.\n\n Own Id: OTP-15716","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.17 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-17"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- A bug caused `ct:encrypt_config_file/3` and `ct:decrypt_config_file/3` to fail\n with `badmatch` if input parameter `KeyOrFile` was `{key,string()}`. This is\n now corrected.\n\n Own Id: OTP-15540\n\n- The status of a test case which failed with timetrap timeout in\n `end_per_testcase` could not be modified by returning `{fail,Reason}` from a\n `post_end_per_testcase` hook function. This is now corrected.\n\n Own Id: OTP-15584 Aux Id: ERIERL-282","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- A new variant of the `newline` option to `ct_telnet:cmd/3` and\n `ct_telnet:send/3` is added, which allows to specify a string to append as\n newline indicator on a command. By default, the value is \"\\\\n\", but in some\n cases it is required to be \"\\\\r\\\\n\", which this option allows.\n\n A faulty regular expression given as parameter to `ct_telnet:expect/2,3` would\n earlier crash and look like an internal error in common_test. A better error\n indication is now given, but the test case will still fail.\n\n Own Id: OTP-15229 Aux Id: ERIERL-203\n\n- Since the yang RFC allows more than one top element of config data in an\n `edit-config` element, `ct_netconfc:edit_config/3,4,5` can now take a list of\n XML elements.\n\n Own Id: OTP-15298","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.16.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-16-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The Logger handler cth_log_redirect earlier called the report callback\n (report_cb) before calling the logger formatter. In some cases this would\n fail, since cth_log_redirect could not handle report callbacks with two\n arguments. This is now corrected, so only the formatter will call the report\n callback.\n\n Own Id: OTP-15307","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.16 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-16"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Use the compiler option `nowarn_export_all` to disable `export_all` warnings\n when automatically compiling test suites.\n\n Own Id: OTP-14810\n\n- Use uri_string module instead of http_uri.\n\n Own Id: OTP-14902","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.15.4.4 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-15-4-4"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- The ct_property_test logging is improved.\n\n Own Id: OTP-16287","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.15.4.3 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-15-4-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- If a ct hook is installed in the `suite/0` function in a test suite, then the\n hook's `terminate/1` function would be called several times without it's\n `init/2` function being called first. This is now corrected.\n\n Own Id: OTP-15863 Aux Id: ERIERL-370\n\n- If `init_per_testcase` fails, the test itself is skipped. According to the\n documentation, it should be possible to change the result to failed in a hook\n function. The only available hook function in this case is\n `post_init_per_testcase`, but changing the return value there did not affect\n the test case result. This is now corrected.\n\n Own Id: OTP-15869 Aux Id: ERIERL-350","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.15.4.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-15-4-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The test result when a hook function fails is in general the same as if the\n function that the hook is associated with fails. For example, if\n `post_init_per_testcase` fails the result is that the test case is skipped, as\n is the case when `init_per_testcase` fails.This, however, was earlier not true\n for timetrap timeouts or other error situations where the process running the\n hook function was killed. This is now corrected, so the error handling should\n be the same no matter how the hook function fails.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-15717 Aux Id: ERIERL-334\n\n- In some rare cases, when two common_test nodes used the same log directory, a\n timing problem could occur which caused common_test to crash because it's log\n cache file was unexpectedly empty. This is now corrected.\n\n Own Id: OTP-15758 Aux Id: ERIERL-342","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Two new common_test hook functions are introduced:\n\n `post_groups/2`, which is called after `Suite:groups/0` \n `post_all/3`, which is called after `Suite:all/0`\n\n These functions allow modifying the return values from the `groups/0` and\n `all/0` functions, respectively.\n\n A new term, `{testcase,TestCase,RepeatProperties}` is now also allowed in the\n return from `all/0`. This can be used for repeating a single test case a\n specific number of times, or until it fails or succeeds once.\n\n Own Id: OTP-14746 Aux Id: ERIERL-143\n\n- OTP internal test improvements.\n\n Own Id: OTP-15716","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.15.4.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-15-4-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The status of a test case which failed with timetrap timeout in\n `end_per_testcase` could not be modified by returning `{fail,Reason}` from a\n `post_end_per_testcase` hook function. This is now corrected.\n\n Own Id: OTP-15584 Aux Id: ERIERL-282","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.15.4.0.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-15-4-0-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The status of a test case which failed with timetrap timeout in\n `end_per_testcase` could not be modified by returning `{fail,Reason}` from a\n `post_end_per_testcase` hook function. This is now corrected.\n\n Own Id: OTP-15584 Aux Id: ERIERL-282","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.15.4 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-15-4"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Fixed problem with 'skip_groups' in combination with 'all suites' option in\n test specification.\n\n Own Id: OTP-14953","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.15.3 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-15-3"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- A new function, `ct:remaining_test_procs/0`, returns the identity of test- and\n group leader processes that are still running at the time of the call.\n\n Own Id: OTP-13832\n\n- A \"latest test result\" link is now displayed in the footer of each test index\n page, which performs a jump to the most recently generated test index. This is\n useful for making quick comparisons of results between test runs without\n having to traverse the log file tree.\n\n Own Id: OTP-14281","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.15.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-15-2"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- General Unicode improvements.\n\n Own Id: OTP-14462","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.15.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-15-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- In OTP-20.0, the behavior of c, make, and ct_make was changed so that in some\n cases the beam files by default would be written to the directory where the\n source files were found. This is now changed back to the old behavior so beam\n files are by default written to current directory.\n\n Own Id: OTP-14489 Aux Id: ERL-438","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.15 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-15"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Errors in the documentation for user HTML stylesheets have been corrected.\n\n Own Id: OTP-14332 Aux Id: seq13299\n\n- Internal code change: Calls to `catch` followed by a call to\n `erlang:get_stacktrace/0` has been rewritten to use `try` instead of `catch`\n to make the code future-proof.\n\n Own Id: OTP-14400","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- The `ct_slave` modules now handle nodenames in the same way as nodenames\n passed to `-sname`. That means `ct_slave:start('b@127.0.0.1').` will now work.\n\n Own Id: OTP-13806\n\n- Added the new option, `keep_logs`. If setting the value for this option to an\n integer, N, common_test will remove all ct_run.\\* directories in the current\n log directory, except the N newest.\n\n Own Id: OTP-14179\n\n- The existing `ct_netconfc:open/1,2` opens an SSH connection with one SSH\n channel realizing one Netconf session. To allow testing of multiple sessions\n over the same SSH connection, the following functions are added to\n `ct_netconfc`:\n\n \\* `connect/1,2` \\- establish an SSH connection _ `disconnect/1` \\- close the\n given SSH connection _ `session/1,2,3` \\- open an ssh channel on the given\n connection and send 'hello' to start a Netconf session\n\n Own Id: OTP-14284\n\n- Miscellaneous updates due to atoms containing arbitrary Unicode characters.\n\n Own Id: OTP-14285\n\n- The function ct_ssh:shell/2,3 is added.\n\n Own Id: OTP-14415 Aux Id: seq13315","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.14 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-14"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The following corrections and improvements are done in the common_test hook\n handling:\n\n - An extra argument, `Suite`, is added as the first argument to each of the\n following hook callback functions:\n\n - `pre_init_per_group`\n - `post_init_per_group`\n - `pre_end_per_group`\n - `post_end_per_group`\n - `pre_init_per_testcase`\n - `post_init_per_testcase`\n - `pre_end_per_testcase`\n - `post_end_per_testcase`\n - `on_tc_fail`\n - `on_tc_skip`\n\n For backwards compatibility, if the new function is not exported from a hook\n callback module, `common_test` will fall back to the old interface and call\n the function without the `Suite` argument.\n\n - If either `init_per_suite` or `end_per_suite` exists, but not the other,\n then the non-existing function will be reported as failed with reason\n `undef` in the test log. The same goes for `init/end_per_group`. This has\n always been a requirement according to the user's guide, but now\n `common_test` is more explicit in the report.\n - If `init_per_suite` was exported from a test suite, but not `end_per_suite`,\n then `pre/post_end_per_suite` was called with `Suite=ct_framework` instead\n of the correct suite name. This is now corrected.\n - If `end_per_group` was exported from a suite, but not `init_per_group`, then\n `end_per_group` was never called. This is now corrected.\n - Tests that were skipped before calling `pre_init_per_*` got faulty calls to\n the corresponding `post_init_per_*`. E.g. if a test was skipped because\n `suite/0` failed, then `post_init_per_suite` would be called even though\n `pre_init_per_suite` and `init_per_suite` were not called. This is now\n corrected so a `post_*` callback will never be called unless the\n corresponding `pre_*` callback has been called first.\n - Tests that were skipped before or in `init_per_testcase` got faulty calls to\n `pre_end_per_testcase` and `post_end_per_testcase`. This is now corrected so\n `pre/post_end_per_testcase` are not called when `end_per_testcase` is not\n called.\n - If an exit signal causes the test case process to die while running\n `init_per_testcase`, the case was earlier reported as failed with reason\n `{skip,...}`. This is now corrected so the case will be marked as skipped.\n - If an exist signal causes the test case process to die while running\n `end_per_testcase`, the case was earlier marked as failed. This is now\n corrected so the status of the test case is not changed - there is only a\n warning added to the comment field.\n - If a test case was skipped because of option `{force_stop,skip_rest}` or\n because of a failed sequence, then no `tc_start` event would be sent, only\n `tc_done`. This is now corrected so both events are sent.\n - When skipping or failing in a configuration function, the configuration\n function itself would get `{auto_skipped,Reason}`, `{skipped,Reason}` or\n `{failed,Reason}` in the hook callbacks `on_tc_skip` or `on_tc_fail`. The\n other test cases that were skipped as a result of this would only get\n `Reason` in `on_tc_skip`. This is now corrected so even the configuration\n function that caused the skip/fail will only get `Reason` in the hook\n callback.\n\n Own Id: OTP-10599 Aux Id: kunagi-344 \\[255]\n\n- When a test case was skipped by a `skip_cases` statement in a test spec, then\n `cth_surefire` would erroneously mark the previous test case as skipped in the\n xml report. The actually skipped test case would not be present in the xml\n report at all. This is now corrected.\n\n Own Id: OTP-14129 Aux Id: seq13244\n\n- The `multiply_timetraps` and `scale_timetraps` options did not work with test\n specifications, which has been corrected.\n\n Own Id: OTP-14210","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- ct_testspec:get_tests/1 is added. This is used by rebar3 to get all\n directories that must be compiled when running tests from testspec - instead\n of implementing testspec parsing in rebar3.\n\n Own Id: OTP-14132","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.13 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-13"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Some types of printouts to screen during test runs (including\n `ct:print/1,2,3,4`) used the local `user` process as IO device and these\n printouts would not be visible when e.g. running tests via a shell on a remote\n node. A default Common Test group leader process has been introduced to solve\n the problem. This process routes printouts to the group leader of the starting\n process, if available, otherwise to `user`.\n\n Own Id: OTP-13973 Aux Id: ERL-279\n\n- Some Common Test processes, that act as I/O group leaders for test cases,\n would not terminate as expected at the end of test runs. This error has been\n corrected.\n\n Own Id: OTP-14026 Aux Id: ERL-287\n\n- The logging verbosity feature was incorrectly documented. The default\n verbosity levels for test runs is e.g. not 50 (`?STD_VERBOSITY`), but 100\n (`?MAX_VERBOSITY`). Also, some of the examples had errors and flaws. The\n corresponding chapter (5.18) in the User's Guide has been updated.\n\n Own Id: OTP-14044 Aux Id: seq13223","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- A feature to let the user specify headings to log printouts has been added.\n The heading is specified as `{heading,string()}` in the `Opts` list argument\n to `ct:pal/3,4,5`, `ct:print/3,4,5`, or `ct:log/3,4,5`. If the heading option\n is omitted, the category name, or `\"User\"`, is used as the heading instead.\n\n Own Id: OTP-14043 Aux Id: seq13226","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.12.3 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-12-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- If the telnet server would pause during transmission of a line of text before\n terminating the line, the `ct_telnet:expect/3` function would print the line\n twice in the test case HTML log. This problem has been fixed.\n\n Own Id: OTP-13730 Aux Id: seq13135\n\n- The functions `ct:set_verbosity/2` and `ct:get_verbosity/1` have been added in\n order to make it possible for test cases, CT Hooks, or test framework\n functions, to modify and read verbosity levels for logging.\n\n Own Id: OTP-13841\n\n- `make` (tools) and `ct_make` (common_test) would crash if an Erlang source\n file contained a `-warning()` directive.\n\n Own Id: OTP-13855","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.12.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-12-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The following modules were missing in common_test.app.src: ct_groups,\n ct_property_test, ct_release_test, ct_webtool, ct_webtool_sup, test_server_gl.\n They have now been added.\n\n Own Id: OTP-13475\n\n- Common Test printed incorrect timestamps for received error reports.\n\n Own Id: OTP-13615 Aux Id: seq13124","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.12.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-12-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The `nodelay` option used to be enabled (`true`) by default for sockets opened\n by the Common Test telnet client. This appeared to cause communication\n problems with telnet servers on some systems, and therefore the option is no\n longer used. Its value may instead be specified in the telnet connection\n settings. See the man page for `ct_telnet` for details. Please note that the\n interface function `connect` in `unix_telnet` has been updated with an extra\n argument and is now `unix_telnet:connect/7`.\n\n Own Id: OTP-13462 Aux Id: seq13077\n\n- Fix bug in cth_surefire: When a pre_init_per_suite hook fails before reaching\n the cth_surefire:pre_init_per_suite, cth_surefire produced incorrect XML.\n\n Own Id: OTP-13513\n\n- The `ct:get_timetrap_info/0` function has been updated to return more\n information about timetrap scaling.\n\n Own Id: OTP-13535\n\n- A problem with stylesheet HTML tags getting incorrectly escaped by Common Test\n has been corrected.\n\n Own Id: OTP-13536\n\n- The `ct_run` start flag `-no_esc_chars` and `ct:run_test/1` start option\n `{esc_chars,Bool}` have been introduced to make it possible to disable\n automatic escaping of characters. Automatic escaping of special HTML\n characters printed with `io:format/1,2` and `ct:pal/1,2,3,4` was introduced in\n Common Test 1.12. The new flag/option may be used to disable this feature for\n backwards compatibility reasons. (The option is also supported in test\n specifications).\n\n Own Id: OTP-13537","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.12 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-12"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- This update fixes the problem with generic printouts in the html log file not\n having special characters escaped. Printouts made with `io:format/2` and\n `ct:pal/2` will now get special characters escaped automatically. Common Test\n will not attempt to escape characters printed with `ct:log/2` since it is\n assumed that the user may want to print html tagged data using this function.\n A new function, `ct:log/5`, has been added, which offers optional escaping of\n characters. The latter function may also be used to print text to the log\n without headers and CSS class wrapping (analogue to `io:format/2`).\n\n Own Id: OTP-13003 Aux Id: seq13005\n\n- Commit 4cf832f1ad163f5b25dd8a6f2d314c169c23c82f erroneously removed logging of\n open and close of netconf connections. This is now corrected.\n\n Own Id: OTP-13386\n\n- The directory to which nodes started with `test_server:start_node/3` writes\n their erl_crash.dump is changed. The crashdumps were earlier written to the\n directory of test_server.beam, but in later versions of Microsoft Windows this\n is no longer writable (even for administrators). The framework (common_test)\n log directory is now used instead.\n\n Own Id: OTP-13388","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- This update makes it possible to specify multiple instances of the same group\n or test case in one test specification term in order to repeat execution.\n Example:\n `{groups, \"./\", my_SUITE, [my_group, my_group], {cases, all}}, or {cases, \"./\", my_SUITE, [my_tc, my_tc, my_tc]}.`\n\n Own Id: OTP-13241 Aux Id: seq12979\n\n- Two new CT hook functions have been added: `post_init_per_testcase/4` and\n `pre_end_per_testcase/3`. With these hook functions, it is possible to perform\n arbitrary actions (including modifications of test execution, test state and\n results) immediately before and after the execution of the test case.\n\n Own Id: OTP-13242 Aux Id: seq12991\n\n- The `ct_netconfc` was earlier very restrictive as to which SSH options the\n user could set. This is now changed, and any SSH option is now allowed. The\n netconf client will simply pass on any option, which it does not recognize, to\n SSH.\n\n Own Id: OTP-13338 Aux Id: seq13053,seq13069","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.11.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-11-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- If a ssh package contained more than one netconf end tag, then the second end\n tag was never detected in ct_netconfc:handle_data. Instead it was included in\n the XML data given to the xmerl parser, which then failed. The problem was\n introduced by OTP-13007, and has now been corrected.\n\n Own Id: OTP-13323","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.11.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-11-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- When data from the netconf server was split into many ssh packages, the\n netconf client performed really bad. This is now improved.\n\n Own Id: OTP-13007\n\n- In ct_netconfc, if a timer expired 'at the same time' as the server sent the\n rpc-reply, the timeout message might already be in the client's message queue\n when the client removed the timer ref from its 'pending' list. This caused a\n crash in the client since the timer ref could no longer be found when handling\n the timeout message. This problem is now fixed by always flushing the timeout\n message from the message queue when canceling a timer.\n\n Own Id: OTP-13008\n\n- The error logger handler ct_conn_log_h did not respect the 'silent' option,\n and tried to print to an undefined file descriptor. This has been corrected.\n\n Own Id: OTP-13035\n\n- If the user would let the test run proceed after test suite compilation\n failure, Common Test did not set the exit status to indicate failure as\n expected. This has been corrected. Also, the 'abort_if_missing_suites' option\n now makes Common Test abort the test run without asking the user if\n compilation fails, even if access to stdin/stdout exists.\n\n Own Id: OTP-13173 Aux Id: seq12978\n\n- With the Common Test 'create_priv_dir' start option set to 'auto_per_tc', the\n name of the priv directory for a configuration function could clash with the\n name of the priv directory for a test case, which would cause Test Server\n failure. This error has been corrected.\n\n Own Id: OTP-13181","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.11 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-11"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The status of an aborted test due to test suite compilation error has changed\n from 'auto_skipped' to 'failed'. This affects both the textual log file, event\n handling and CT hook callbacks. The logging of compilation failures has also\n been improved, especially in the case of multiple test suites failing\n compilation.\n\n Own Id: OTP-10816\n\n- The Test Server source code parser (erl2html2) failed to handle the macro\n tuple in the syntax tree returned by epp_dodger. This error has been\n corrected.\n\n Own Id: OTP-12740\n\n- New options to make it possible to specify ssh_port in a .spec file:\n \\[\\{node_start, [\\{ssh_port, 9999\\}]\\}].\n\n And also to specify additional ssh options like paths to public-key files:\n \\[\\{node_start, [\\{ssh_opts, [\\{user_dir, \"/home/shrek/e2/\"\\}]\\}]\\}].\n\n Own Id: OTP-12809","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Earlier there was no way to add optional parameters like default-operation to\n an edit-config request sent with ct_netconfc:edit_config/3,4, you had to use\n ct_netconfc:send_rpc/2,3. For simplicity and completion, a new optional\n argument, OptParams, is now added to the edit_config function.\n\n Own Id: OTP-10446 Aux Id: kunagi-266 \\[177]\n\n- When running OTP tests using the ts interface, it is now possible to specify\n so called test categories per OTP application. A test category is represented\n by a CT test specification and defines an arbitrary subset of existing test\n suites, groups and cases. Examples of test categories are 'smoke' (smoke\n tests) and 'bench' (benchmarks). (Call ts:help() for more info). Also,\n functions for reading terms from the current test specification during test,\n ct:get_testspec_terms/0 and ct:get_testspec_terms/1, have been implemented.\n\n Own Id: OTP-11962\n\n- Obsolete scripts and make file operations have been removed and the\n installation chapter in the Common Test User's Guide has been updated.\n\n Own Id: OTP-12421\n\n- The 'keep_alive' interval has been reduced to 8 seconds, which is two seconds\n shorter than the default 'idle_timeout' value for ct_telnet:expect/3. This\n way, the telnet server receives a NOP message (which might trigger an action)\n before the operation times out. Also the TCP option 'nodelay' has been enabled\n per default for all telnet connections, in order to reduce the risk for\n communication timeouts.\n\n Own Id: OTP-12678 Aux Id: seq12818\n\n- When the ct_run program is executed without any flags, \"-dir .\" is now used as\n default start flag. Similarly, the option \\{dir,\".\"\\} is used by ct:run_test/1\n if called with an empty list. Also, the help text (ct_run -help) has been\n updated, as well as the Running Tests chapter in the Common Test User's Guide.\n\n Own Id: OTP-12684 Aux Id: seq12865","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.10.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-10-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- A fault in the Common Test logger process, that caused the application to\n crash when running on a long name node, has been corrected.\n\n Own Id: OTP-12643\n\n- A 'wait_for_prompt' option in ct_telnet:expect/3 has been introduced which\n forces the function to not return until a prompt string has been received,\n even if other expect patterns have already been found.\n\n Own Id: OTP-12688 Aux Id: seq12818\n\n- If the last expression in a test case causes a timetrap timeout, the stack\n trace is ignored and not printed to the test case log file. This happens\n because the \\{Suite,TestCase,Line\\} info is not available in the stack trace\n in this scenario, due to tail call elimination. Common Test has been modified\n to handle this situation by inserting a \\{Suite,TestCase,last_expr\\} tuple in\n the correct place and printing the stack trace as expected.\n\n Own Id: OTP-12697 Aux Id: seq12848\n\n- Fixed a buffer problem in ct_netconfc which could cause that some messages\n where buffered forever.\n\n Own Id: OTP-12698 Aux Id: seq12844\n\n- The VTS mode in Common Test has been modified to use a private version of the\n Webtool application (ct_webtool).\n\n Own Id: OTP-12704 Aux Id: OTP-10922\n\n- Add possibility to add user capabilities in `ct_netconfc:hello/3`.\n\n Own Id: OTP-12707 Aux Id: seq12846","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.10 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-10"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The tests overview file, index.html, did not always get updated correctly\n after a new test run. This was because of a bug in the Common Test log cache\n mechanism which has now been corrected.\n\n Own Id: OTP-11400\n\n- When a successful test case returns, Common Test should, according to the\n documentation, send a tc_done event to the event handlers with Result = ok in\n the data field. However, Common Test sets Result to the return value of the\n test case instead. Common Test has been modified now to comply with the\n documentation.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-12279 Aux Id: seq12737, OTP-12531\n\n- A ct_telnet:expect/3 call could never be aborted before an idle_timeout, even\n if total_timeout had been set to a lower value (i.e. a shorter time). This\n problem has been fixed.\n\n Own Id: OTP-12335\n\n- The undocumented return value \\{skipped,Reason\\} from config functions and\n test cases was handled inconsistently. Test cases were e.g. reported as\n \"skipped\" to CT Hook functions, but \"successful\" to event handlers. Now, the\n above return value is consistently handled the same way as \\{skip,Reason\\} and\n this has also been documented.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-12359 Aux Id: seq12760\n\n- The Erlang source code to HTML generator would sometimes fail because\n epp:parse_erl_form/1 could not find and expand required macros in included\n header files. The problem has been solved by making sure common_test always\n passes the full include path to epp. Also, a bug that could cause\n erl_syntax:revert/1 to fail because of a badly formed syntax tree has been\n corrected.\n\n Own Id: OTP-12419\n\n- A missing group option in the ct_run help text has been added.\n\n Own Id: OTP-12433 Aux Id: seq12788\n\n- Printouts by means of ct:log/2/3 or ct:pal/2/3 from the hook functions\n on_tc_fail/2 and on_tc_skip/2 would (quite unexpectedly) end up in the\n \"unexpected i/o\" log file instead of in the test case log file. This behaviour\n has been changed so that now, all printouts (including stdio printouts) from\n these hook functions will be routed to the test case log file.\n\n Own Id: OTP-12468\n\n- ct_netconfc:action/3 will now - if the return type is void - accept an RPC\n reply on the form \\{ok,\\[simple_xml()]\\}, and in this event return only the\n atom ok.\n\n Own Id: OTP-12491 Aux Id: seq12797\n\n- OTP-11971 erroneously changed the handling of relative paths for incl_dirs\n specified in the cover spec file. This is now corrected so these are expected\n to be relative to the directory where the cover spec file itself is stored\n\n Own Id: OTP-12498 Aux Id: OTP-11971\n\n- Some test cases have been updated to use ct:sleep/1 instead of timer:sleep/1.\n The reason being that the sleep times need to be scaled to compensate for slow\n execution (e.g. when cover is running).\n\n Own Id: OTP-12574","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Common Test now exports a function, ct:get_event_mgr_ref/0, that returns the\n name of the Common Test event manager. This makes it possible to plug in event\n handlers to the event manager while tests are running (using the gen_event\n API).\n\n Own Id: OTP-12506 Aux Id: seq12802\n\n- When a test case (or configuration function) fails because of an exit signal\n from a linked process, Common Test previously passed only the reason for\n process termination to the CT post hook functions and the event handlers (in\n the tc_done event). This has been changed so that now the tuple\n \\{'EXIT',ReasonForProcessTermination\\} is passed instead. This makes it much\n easier in the CT post hook functions to distinguish a failure of this sort\n from other types of errors and from the return value of a successful test\n case.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-12531 Aux Id: OTP-12279\n\n- A new feature has been introduced in ct_telnet:get_data/1 that makes it\n possible to automatically poll the telnet connection in case an incomplete\n string (one that has not yet been terminated by a newline) remains in the\n receive buffer. The polling is controlled by two new telnet config values,\n which are documented in the ct_telnet reference manual. The polling mechanism\n is disabled by default (making the get_data/1 function backwards compatible).\n\n Own Id: OTP-12627","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.9 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-9"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The source code to html code generator in Test Server (and Common Test) would\n fail to generate anchors in the html code for functions with non-expandable\n macros, resulting in bad html links to such functions. This correction lets\n the code generator ignore macros that can't be expanded (i.e. not pre-process\n them), so that correct anchors will always be produced.\n\n Own Id: OTP-11766 Aux Id: seq12556\n\n- OTP-11971 erroneously changed the handling of relative paths (import/export\n files) specified in the cover spec file. This is now corrected so these are\n expected to be relative to the directory where the cover spec file itself is\n stored.\n\n Own Id: OTP-12031\n\n- Common Test would sometimes crash while trying to print large amounts of SASL\n reports to log on a computer with a slow file system. This problem (due to an\n error in IO message buffering in ct_logs) has been fixed.\n\n Own Id: OTP-12159\n\n- The common_test telnet client, ct_telnet and friends, had some unstable test\n cases. Some of these were caused by the unix_telnet callback sending an extra\n newline after sending the password. This caused the sever to send an extra\n prompt back which confused the tests. The extra newline is no longer sent.\n\n Also, debug printouts and logging from the telnet client is improved, and some\n test cases are slightly modified in order to stabilize the test.\n\n Own Id: OTP-12329\n\n- ct_netconfc did not expect the return value \\{error,timeout\\} from\n ssh_connection:subsystem/4. This has been corrected.\n\n Own Id: OTP-12334","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- A new option, `{newline,boolean()}` is added to all functions in `ct_telnet`\n that send data (command strings) to the telnet server. By default, `ct_telnet`\n adds a newline to all command strings, and by setting the new option to\n `false` this behavior is turned off.\n\n Own Id: OTP-12252 Aux Id: seq12730\n\n- Distribute `autoconf` helpers to applications at build time instead of having\n multiple identical copies committed in the repository.\n\n Own Id: OTP-12348","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.8.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-8-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Ticket OTP-11971 introduced a runtime dependency towards test_server-3.7.1,\n since the interface between test_server and common_test was changed.\n Erroneously, the common_test.app file was not updated according to this. This\n has now been corrected.\n\n Own Id: OTP-12037","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Warning: this is experimental and may disappear or change without previous\n warning.\n\n Experimental support for running Quickcheck and PropEr tests from common_test\n suites is added to common_test. See the reference manual for the new module\n `ct_property_testing`.\n\n Experimental property tests are added under\n `lib/{inet,ssh}/test/property_test`. They can be run directly or from the\n commont_test suites `inet/ftp_property_test_SUITE.erl` and\n `ssh/test/ssh_property_test_SUITE.erl`.\n\n See the code in the `test` directories and the man page for details.\n\n (Thanks to Tuncer Ayaz for a patch adding Triq)\n\n Own Id: OTP-12119","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.8.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-8-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Substrings in long telnet messages would sometimes get wrongly reversed. This\n error has been corrected.\n\n Own Id: OTP-11871 Aux Id: seq12581\n\n- The basic_html logging mode in Common Test (for compatibility with old\n browsers) generated HTML code with unbalanced tags. This has been fixed.\n\n Own Id: OTP-11917 Aux Id: seq12598\n\n- The mechanism for running code cover analysis with common_test has been\n improved. Earlier, if a test run consisted of multiple tests, cover would be\n started and stopped for each test. This would give \"intermediate\" cover logs\n available from the \"Coverage log\" link on the test suite result pages. To\n accumulate cover data over all tests, the 'export' option had to be used in\n the cover spec file. This was not well documented, and the functionality was\n quite confusing.\n\n Using the 'nodes' option in the cover spec file would fail when the test run\n consisted of multiple tests, since the specified nodes would only be included\n in the cover analysis of the first test.\n\n The repeated compilation and analysis of the same modules was also very time\n consuming.\n\n To overcome these problems, ct will now only cover compile and analyze modules\n once per test run, i.e. once for each cover spec file. The log file is\n available via a new button on the top level index page. The old \"Coverage log\"\n links on the test suite result pages still exist, but they all point to the\n same log containing the accumulated result.\n\n Own Id: OTP-11971\n\n- If multiple tests would run simultaneously on different Erlang nodes, writing\n their logs to the same directory, then there would often be entries in the\n all_runs.html log file showing incomplete results (all zeroes) upon\n completion. This problem was caused by a bug in the Common Test log cache\n mechanism, which has been fixed.\n\n Own Id: OTP-11988 Aux Id: seq12611","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.8 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-8"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The error generated if a test case process received an exit from a linked\n process while executing init_per_testcase/2, was handled incorrectly by Common\n Test. The problem has been solved, and Common Test now reports this type of\n error correctly, with proper error reason and exit location as well.\n\n Own Id: OTP-11643\n\n- Running a parallel test case group with two or more instances of the same test\n case would result in identical log file names, and one test case instance\n would overwrite the log file of another. This problem has been solved.\n\n Own Id: OTP-11644\n\n- Application upgrade (appup) files are corrected for the following\n applications:\n\n `asn1, common_test, compiler, crypto, debugger, dialyzer, edoc, eldap, erl_docgen, et, eunit, gs, hipe, inets, observer, odbc, os_mon, otp_mibs, parsetools, percept, public_key, reltool, runtime_tools, ssh, syntax_tools, test_server, tools, typer, webtool, wx, xmerl`\n\n A new test utility for testing appup files is added to test_server. This is\n now used by most applications in OTP.\n\n (Thanks to Tobias Schlager)\n\n Own Id: OTP-11744\n\n- The `cth_surefire` hook would crash in `pre_init_per_suite/3` if a previous\n hook returned `{skip,Reason}` or `{fail,Reason}` instead of a `Config` list.\n This error has been corrected, and `cth_surefire` will now simply propagate\n the received `InitData` value instead.\n\n Own Id: OTP-11811\n\n- Specs of return values are corrected for `ct_netconfc:get/2,3`,\n `ct_netconfc:get_config/3,4`, `ct_netconfc:action/2,3`,\n `ct_netconfc:send_rpc/2,3` and `ct_netconfc:send/2,3`.\n\n Own Id: OTP-11834 Aux Id: seq12574","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- ct_telnet can now log all communication taking place during a telnet session.\n Previously, only information about ct_telnet operations and commands, as well\n as explicitly requested data from the server, was logged.\n\n Furthermore, a logging mechanism based on an Error Logger event handler and a\n dedicated Common Test hook, `cth_conn_log`, now makes it possible to print\n data for individual connections to separate log files. Please see the\n `ct_telnet` reference manual for more information and examples.\n\n Important note: A new argument, `ConnName` has been added to the\n `unix_telnet:connect/5` callback function. This forces users that use private\n ct_telnet callback modules to update their code according to\n `unix_telnet:connect/6`. Please see the `unix_telnet` reference manual and\n source code module for details.\n\n Own Id: OTP-11440 Aux Id: seq12457\n\n- A new timeout option has been introduced for the `ct_telnet:expect/3`\n function. With `{total_timeout,Time}` it's possible to set a time limit for\n the complete expect operation. After `Time` milliseconds, `expect/3` returns\n `{error,timeout}`. The default value used if `total_timeout` is not specified,\n is infinity (i.e. no time limit). Please see the `ct_telnet` reference manual\n for more information.\n\n Own Id: OTP-11689\n\n- Some function specs are corrected or moved and some edoc comments are\n corrected in order to allow use of edoc. (Thanks to Pierre Fenoll)\n\n Own Id: OTP-11702\n\n- Test case group name information has been added to the data sent with\n `tc_user_skip` and `tc_auto_skip` event messages, as well as the data passed\n in calls to the CT Hook functions `on_tc_skip/3` and `on_tc_fail/3`. The\n modification only affects the function name element/argument. This value\n remains an atom if the test case in question does not belong to a test case\n group. Otherwise a tuple `{FuncName,GroupName}` (`{atom(),atom()}`) is passed\n instead.\n\n Note that this change may (depending on the patterns used for matching)\n require modifications of user event handlers and hook modules. Please see the\n Event Handling chapter in the Common Test User's Guide, and the reference\n manual for `ct_hooks`, for details.\n\n Note also that the Test Server framework callback function `report/2` has been\n modified. This change only affects users with test frameworks interfacing Test\n Server rather than Common Test. See the `test_server_ctrl` reference manual\n for details.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-11732 Aux Id: seq12541\n\n- If Common Test can't prompt the user to abort or continue the test run when\n one or more test suites fail to compile, a new option,\n `{abort_if_missing_suites,Bool}`, can be used to specify whether it should\n proceed with the test run, or stop execution. The default value of `Bool` is\n `false` (i.e. to proceed even if suites are missing).\n\n Own Id: OTP-11769","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Known Bugs and Problems - Common Test Release Notes","doc":"- common_test: Fix problems reported by Dialyzer.\n\n Own Id: OTP-11525","ref":"notes.html#known-bugs-and-problems"},{"type":"extras","title":"Common_Test 1.7.4 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-7-4"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Return values from group and testcase info functions are now properly checked,\n and associated test cases are auto skipped if a return value is invalid.\n\n Own Id: OTP-10631 Aux Id: kunagi-345 \\[256]\n\n- The way Common Test handles skipping of test cases has been updated. In\n previous versions, returning `{skip,Reason}` from a configuration function\n (such as init_per_suite or init_per_group), resulted in all affected test\n cases getting skipped with status `auto_skipped`. This was inappropriate,\n since this status is supposed to be used to inform that Common Test has taken\n the initiative to skip something (e.g. a test case group if init_per_group\n failed). Therefore, in this version of Common Test, whenever the user skips a\n suite, group, or individual test case (by means of a configuration function or\n test specification term), the affected test cases get the status\n `user_skipped` instead.\n\n This update has meant a few changes that may affect Common Test users in\n various ways:\n\n - The test results and statistics will be affected, which is important to know\n when running regression tests and comparing results to previous test runs.\n - Users that read or parse the textual log file `suite.log` will notice that\n an auto skipped function is now reported as `auto_skipped` rather than\n `skipped` as before.\n - When `require` fails in an info function (such as suite/0 or group/1), all\n affected configuration functions and test cases are marked as\n `auto_skipped`.\n - If Common Test detects an error in the test suite (such as e.g. an invalid\n all/0 function), all affected configuration functions and test cases are\n marked as `auto_skipped`.\n - If a repeated test run session reaches a deadline with `force_stop` enabled,\n all remaining test cases are marked as `auto_skipped` rather than\n `user_skipped` as before.\n - The event messages that Common Test generates during test runs have been\n affected by this update. For details see OTP-11524.\n\n Own Id: OTP-11305 Aux Id: OTP-11524\n\n- Returning \\{skip, Reason\\} from a pre_end_per_group/3 user hook function would\n result in an exit in the Common Test cth_log_redirect hook. This problem has\n been solved.\n\n Own Id: OTP-11409 Aux Id: seq12446\n\n- When the netconf server did not respond to the close-session request, the call\n to ct_netconfc:close_session/2 would hang forever waiting for the netconf\n client to terminate. This has been corrected. The client will now always\n terminate (and take down the connection) if the close-session request times\n out.\n\n Own Id: OTP-11478","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Fix cth_log_redirect.erl to fulfill gen_event behaviour. Thanks to Roberto\n Aloi.\n\n Own Id: OTP-11401\n\n- The first argument of the CT hook callback function `on_tc_skip/3` has been\n modified. When this function is called for `init_per_group` or\n `end_per_group`, the value of the first argument is now\n `{init_per_group,GroupName}` or `{end_per_group,GroupName}`.\n\n Own Id: OTP-11523\n\n- The following modifications have been made to the event messages that Common\n Test sends during test execution:\n\n - For the `tc_auto_skip` event, the value of the `Func` element has changed\n from `end_per_group` to `{end_per_group,GroupName}`.\n - When `require` fails in an info function, such as suite/0 or group/1, the\n init configuration function is now reported as `auto_skipped` instead of\n `skipped`, with the `tc_done` event.\n - When `require` fails in an info function because of a configuration name\n already in use, the `tc_done` event now reports the error with a tuple (of\n size 2) tagged `failed` instead of `skipped`.\n\n Please see the Event Handling chapter in the Common Test User's Guide for\n reference.\n\n Own Id: OTP-11524 Aux Id: OTP-11305","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.7.3 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-7-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Documentation is added for ct_netconfc:send and ct_netconfc:send_rpc.\n\n Own Id: OTP-11132\n\n- ct_netconfc:create_subscription only allowed one XML element inside the\n 'filter' element. According to RFC5277 it should be allowed to add any number\n of elements inside the filter, so this is now corrected.\n\n Own Id: OTP-11166\n\n- The error handler installed by the Common Test hook cth_log_redirect did not\n respond to init:stop/1/2. This has been corrected.\n\n Own Id: OTP-11175 Aux Id: seq12356\n\n- Calling ct:pal/2 or ct:print/2 when Common Test was not running, would cause\n an exit. This has been changed and the string is now simply printed to stdout\n instead.\n\n Own Id: OTP-11176\n\n- Fixed problem with the cth_log_redirect hook making calls to an undefined\n function in ct_logs.\n\n Own Id: OTP-11238\n\n- When running tests with the 'repeat' option, the Common Test utility process\n did not always terminate quickly enough after a test run, causing the start of\n the next run to fail. A monitor is now used to ensure termination of the\n utility process after each test run.\n\n Own Id: OTP-11244 Aux Id: seq12396\n\n- Test Server installed an error handler (test_server_h) only to be able to\n write the name of the current test case to stdout whenever it received an\n error- or progress report. This functionality was not useful and has been\n removed. The built-in Common Test hook, cth_log_redirect, has instead been\n improved to now also tag all error- and progress reports in the log with\n suite-, group-, and/or test case name.\n\n Own Id: OTP-11263 Aux Id: seq12251","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- A new log, the \"Pre- and Post Test I/O Log\", has been introduced, which makes\n it possible to capture error- and progress reports, as well as printouts made\n with ct:log/2 and ct:pal/2, before and after a test run. (Some minor\n improvements of the logging system have been made at the same time). Links to\n the new log are found on the Common Test Framework Log page. The Common Test\n User's Guide has been updated with information about the new log and also with\n a new section on how to synchronize external applications with Common Test by\n means of the CT Hook init and terminate functions.\n\n Own Id: OTP-11272","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.7.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-7-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- A design flaw in the generic connection handling in Common Test made it\n impossible to implement a connection handler that could map multiple\n connection names (i.e. configuration variable aliases) to single connection\n pids. This problem has been solved.\n\n Own Id: OTP-10126 Aux Id: kunagi-178 \\[89]\n\n- If a telnet connection is hanging, then a call to ct_telnet:close/1 will time\n out after 5 seconds and the connection process is brutally killed. In some\n cases the connection would not be unregistered and attempts at opening a new\n connection with the same name would make common_test try to reuse the same\n connection since it believed that it was still alive. This has been\n corrected - a killed connection is now always unregistered.\n\n Own Id: OTP-10648 Aux Id: seq12212\n\n- Test performance has been improved by means of a cache for the top level HTML\n index logs (all_runs.html and index.html, in the logdir directory). This\n solves problems with slow start up times and test execution times increasing\n with the number of ct_run directories stored in logdir. The cached index\n entries are stored in RAM during test execution and are saved to file in\n logdir (for faster start up times) whenever a test run finishes.\n\n Own Id: OTP-10855\n\n- Testing of the test specification functionality has been improved and a couple\n of minor bugs have been discovered and corrected.\n\n Own Id: OTP-10857\n\n- Links to the top level index files in some HTML footers had disappeared. This\n error has been corrected. Also, a problem with the suite overview log file not\n being closed properly has been solved.\n\n Own Id: OTP-11046\n\n- Common Test would, in case of timetrap error, print a warning in the log if\n end_per_testcase wasn't implemented in the suite, even though it's an optional\n function. This printout has been removed.\n\n Own Id: OTP-11052","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- If it could not be decided which test case a certain log printout belonged to,\n the common test framework log was earlier used. Such printouts are now instead\n sent to unexpected_io.log.html in test_server so that there is only one place\n to look for \"missing\" printouts.\n\n Own Id: OTP-10494 Aux Id: kunagi-319 \\[230]\n\n- Make cover smarter about finding source from beam.\n\n In particular, search using the source path in module_info if the current\n heuristic fails.\n\n Own Id: OTP-10902\n\n- Add a variant of ct_slave:start/2 that starts a node with specified options on\n the local host.\n\n Own Id: OTP-10920\n\n- Integrate elliptic curve contribution from Andreas Schultz\n\n In order to be able to support elliptic curve cipher suites in SSL/TLS,\n additions to handle elliptic curve infrastructure has been added to public_key\n and crypto.\n\n This also has resulted in a rewrite of the crypto API to gain consistency and\n remove unnecessary overhead. All OTP applications using crypto has been\n updated to use the new API.\n\n Impact: Elliptic curve cryptography (ECC) offers equivalent security with\n smaller key sizes than other public key algorithms. Smaller key sizes result\n in savings for power, memory, bandwidth, and computational cost that make ECC\n especially attractive for constrained environments.\n\n Own Id: OTP-11009\n\n- Postscript files no longer needed for the generation of PDF files have been\n removed.\n\n Own Id: OTP-11016\n\n- A link is added from the red error printout in a test case log (for a failed\n test case) to the full error description at the end of the log. The reason for\n this is that the error description in the red field is sometimes truncated at\n 50 characters in order to keep the log as short and easy to read as possible.\n\n Own Id: OTP-11044 Aux Id: seq12304\n\n- A new option 'no_prompt_check' is added to ct_telnet:expect/3. If this option\n is used, ct_telnet will not wait for a prompt or a newline before attempting\n to match the given pattern.\n\n Own Id: OTP-11095","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.7.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-7-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- If an event handler installed in the CT Master event manager took too long to\n respond during the termination phase, CT Master crashed because of a timeout\n after 5 secs. This would leave the system in a bad state. The problem has been\n solved by means of a 30 min timeout value and if CT Master gets a timeout\n after that time, it now kills the event manager and shuts down properly.\n\n Own Id: OTP-10634 Aux Id: kunagi-347 \\[258]\n\n- Printing with any of the ct printout functions from an event handler installed\n by Common Test, would cause a deadlock. This problem has been solved.\n\n Own Id: OTP-10826 Aux Id: seq12250\n\n- Using the force_stop flag/option to interrupt a test run caused a crash in\n Common Test. This problem has been solved.\n\n Own Id: OTP-10832","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Removed deprecated run_test program, use ct_run instead.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-9052","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Known Bugs and Problems - Common Test Release Notes","doc":"- Test case execution time increases with size of test run.\n\n Own Id: OTP-10855","ref":"notes.html#known-bugs-and-problems"},{"type":"extras","title":"Common_Test 1.7 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-7"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Severe errors detected by `test_server` (e.g. if log files directories cannot\n be created) will now be reported to `common_test` and noted in the\n `common_test` logs.\n\n Own Id: OTP-9769 Aux Id: kunagi-202 \\[113]\n\n- The earlier undocumented cross cover feature for accumulating cover data over\n multiple tests has now been fixed and documented.\n\n Own Id: OTP-9870 Aux Id: kunagi-206 \\[117]\n\n- If a busy test case generated lots of error messages,\n cth_log_redirect:post_end_per_testcase would crash with a timeout while\n waiting for the error logger to finish handling all error reports. The default\n timer was 5 seconds. This has now been extended to 5 minutes.\n\n Own Id: OTP-10040 Aux Id: kunagi-173 \\[84]\n\n- When a test case failed because of a timetrap time out, the `Config` data for\n the case was lost in the following call to `end_per_testcase/2`, and also in\n calls to the CT Hook function `post_end_per_testcase/4`. This problem has been\n solved and the `Config` data is now correctly passed to the above functions\n after a timetrap timeout failure.\n\n Own Id: OTP-10070 Aux Id: kunagi-175 \\[86]\n\n- Some calls to deprecated and removed functions in snmp are removed from\n ct_snmp.\n\n Own Id: OTP-10088 Aux Id: kunagi-176 \\[87]\n\n- In test_server, the same process would supervise the currently running test\n case and be group leader (and IO server) for the test case. Furthermore, when\n running parallel test cases, new temporary supervisor/group leader processes\n were spawned and the process that was group leader for sequential test cases\n would not be active. That would lead to several problems:\n\n \\* Processes started by init_per_suite will inherit the group leader of the\n init_per_suite process (and that group leader would not process IO requests\n when parallel test cases was running). If later a parallel test case caused\n such a processto print using (for example) io:format/2, the calling would\n hang.\n\n \\* Similarly, if a process was spawned from a parallel test case, it would\n inherit the temporary group leader for that parallel test case. If that\n spawned process later - when the group of parallel tests have finished -\n attempted to print something, its group leader would be dead and there would\n be `badarg` exception.\n\n Those problems have been solved by having group leaders separate from the\n processes that supervises the test cases, and keeping temporary group leader\n process for parallel test cases alive until no more process in the system use\n them as group leaders.\n\n Also, a new `unexpected_io.log` log file (reachable from the summary page of\n each test suite) has been introduced. All unexpected IO will be printed into\n it(for example, IO to a group leader for a parallel test case that has\n finished).\n\n Own Id: OTP-10101 Aux Id: OTP-10125\n\n- Some bugfixes in `ct_snmp:`\n\n - ct_snmp will now use the value of the 'agent_vsns' config variable when\n setting the 'variables' parameter to snmp application agent configuration.\n Earlier this had to be done separately - i.e. the supported versions had to\n be specified twice.\n - Snmp application failed to write notify.conf since ct_snmp gave the notify\n type as a string instead of an atom. This has been corrected.\n\n Own Id: OTP-10432\n\n- Some bugfixes in `ct_snmp`:\n\n - Functions `register_users/2`, `register_agents/2` and\n `register_usm_users/2`, and the corresponding `unregister_*/1` functions\n were not executable. These are corrected/rewritten.\n - Function `update_usm_users/2` is removed, and an unregister function is\n added instead. Update can now be done with unregister_usm_users and then\n register_usm_users.\n - Functions `unregister_*/2` are added, so specific users/agents/usm users can\n be unregistered.\n - Function `unload_mibs/1` is added for completeness.\n - Overriding configuration files did not work, since the files were written in\n priv_dir instead of in the configuration dir (priv_dir/conf). This has been\n corrected.\n - Arguments to `register_usm_users/2` were faulty documented. This has been\n corrected.\n\n Own Id: OTP-10434 Aux Id: kunagi-264 \\[175]\n\n- Faulty exported specs in common test has been corrected to\n `ct_netconfc:hook_options/0` and [`inet:hostname/0`](`t:inet:hostname/0`)\n\n Own Id: OTP-10601\n\n- The netconf client in common_test did not adjust the window after receiving\n data. Due to this, the client stopped receiving data after a while. This has\n been corrected.\n\n Own Id: OTP-10646","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- It is now possible to let a test specification include other test\n specifications. Included specs can either be joined with the source spec (and\n all other joined specs), resulting in one single test run, or they can be\n executed in separate test runs. Also, a start flag/option, `join_specs`, has\n been introduced, to be used in combination with the `spec` option. With\n `join_specs`, Common Test can be told to either join multiple test\n specifications, or run them separately. Without `join_specs`, the latter\n behaviour is default. Note that this is a change compared to earlier versions\n of Common Test, where specifications could only be joined. More information\n can be found in the Running Tests chapter in the User's Guide (see the Test\n Specifications section).\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-9881 Aux Id: kunagi-350 \\[261]\n\n- The `ct_slave:start/3` function now supports an `{env,[{Var,Value}]}` option\n to extend environment for the slave node.\n\n Own Id: OTP-10469 Aux Id: kunagi-317 \\[228]\n\n- Some examples overflowing the width of PDF pages have been corrected.\n\n Own Id: OTP-10665\n\n- Update common test modules to handle unicode:\n\n - Use UTF-8 encoding for all HTML files, except the HTML version of the test\n suite generated with erl2html2:convert, which will have the same encoding as\n the original test suite (.erl) file.\n - Encode link targets in HTML files with test_server_ctrl:uri_encode/1.\n - Use unicode modifier 't' with ~s when appropriate.\n - Use unicode:characters_to_list and unicode:characters_to_binary for\n conversion between binaries and strings instead of binary_to_list and\n list_to_binary.\n\n Own Id: OTP-10783","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Known Bugs and Problems - Common Test Release Notes","doc":"- CT drops error reason when groups/0 crashes.\n\n Own Id: OTP-10631 Aux Id: kunagi-345 \\[256]\n\n- Event handler on a ct_master node causes hanging.\n\n Own Id: OTP-10634 Aux Id: kunagi-347 \\[258]\n\n- CT fails to open telnet conn after a timetrap timeout.\n\n Own Id: OTP-10648 Aux Id: seq12212","ref":"notes.html#known-bugs-and-problems"},{"type":"extras","title":"Common_Test 1.6.3.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-6-3-1"},{"type":"extras","title":"Known Bugs and Problems - Common Test Release Notes","doc":"- The following corrections/changes are done in the cth_surefire hook:\n\n - Earlier there would always be a 'properties' element under the 'testsuites'\n element. This would exist even if there were no 'property' element inside\n it. This has been changed so if there are no 'property' elements to display,\n then there will not be a 'properties' element either.\n - The XML file will now (unless other is specified) be stored in the top log\n directory. Earlier, the default directory would be the current working\n directory for the erlang node, which would mostly, but not always, be the\n top log directory.\n - The 'hostname' attribute in the 'testsuite' element would earlier never have\n the correct value. This has been corrected.\n - The 'errors' attribute in the 'testsuite' element would earlier display the\n number of failed testcases. This has been changed and will now always have\n the value 0, while the 'failures' attribute will show the number of failed\n testcases.\n - A new attribute 'skipped' is added to the 'testsuite' element. This will\n display the number of skipped testcases. These would earlier be included in\n the number of failed test cases.\n - The total number of tests displayed by the 'tests' attribute in the\n 'testsuite' element would earlier include init/end_per_suite and\n init/end_per_group. This is no longer the case. The 'tests' attribute will\n now only count \"real\" test cases.\n - Earlier, auto skipped test cases would have no value in the 'log' attribute.\n This is now corrected.\n - A new attributes 'log' is added to the 'testsuite' element.\n - A new option named 'url_base' is added for this hook. If this option is\n used, a new attribute named 'url' will be added to the 'testcase' and\n 'testsuite' elements.\n\n Own Id: OTP-10589","ref":"notes.html#known-bugs-and-problems"},{"type":"extras","title":"Common_Test 1.6.3 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-6-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The ct:run_test/1 option 'config' only worked with a single config file, not a\n list of files. This has been fixed.\n\n Own Id: OTP-10495\n\n- ct_netconfc:close_session sometimes returned \\{error,closed\\} because the ssh\n connection was closed (from the server side) before the rpc-reply was received\n by the client. This is normal and cannot be helped. It has been corrected so\n the return will be 'ok' in this case. Other error situations will still give\n \\{error,Reason\\}.\n\n Own Id: OTP-10510 Aux Id: kunagi-320 \\[231]\n\n- ct_netconfc:close_session sometimes returned \\{error,closed\\} or (if the\n connection was named) \\{error,\\{process_down,Pid,normal\\}\\} because the ssh\n connection was closed (from the server side) before the rpc-reply was received\n by the client. This is normal and cannot be helped. It has been corrected so\n the return will be 'ok' in this situation.\n\n Own Id: OTP-10570\n\n- Fix bug where ct:require of same name with same config would return\n name_in_use.\n\n Own Id: OTP-10572","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- A new test case group search functionality has been implemented that makes\n Common Test search automatically through the group definitions tree (the\n return value of groups/0) and create tests for all paths of nested groups that\n match the specification. It also allows for specifying unique paths to sub\n groups in order to avoid execution of unwanted tests. This new feature can be\n used whenever starting a test run by means of the ct_run program, the\n ct:run_test/1 API function, or a Test Specification. Details can be found in\n the Test Case Group Execution section in the Running Tests chapter.\n\n Own Id: OTP-10466 Aux Id: kunagi-276 \\[187]","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Known Bugs and Problems - Common Test Release Notes","doc":"- Restore Config data if lost when test case fails.\n\n Own Id: OTP-10070 Aux Id: kunagi-175 \\[86]\n\n- IO server error in test_server.\n\n Own Id: OTP-10125 Aux Id: OTP-10101, kunagi-177 \\[88]\n\n- Faulty connection handling in common_test.\n\n Own Id: OTP-10126 Aux Id: kunagi-178 \\[89]","ref":"notes.html#known-bugs-and-problems"},{"type":"extras","title":"Common_Test 1.6.2.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-6-2-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The interactive mode (ct_run -shell) would not start properly. This error has\n been fixed.\n\n Own Id: OTP-10414","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Common_Test 1.6.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-6-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- If a CT hook function caused a crash, this could in some situations cause\n Common Test to terminate due to an illegal IO operation. This error has been\n corrected.\n\n Own Id: OTP-10050 Aux Id: seq12039\n\n- The Common Test documentation states that timetraps are never active during\n execution of CT hook functions. This was only true for post hook functions,\n not for pre hook functions. The code for CT hooks has been modified to behave\n according to the documentation.\n\n Own Id: OTP-10069\n\n- If a CT hook function would call the exit/1 or throw/1 BIF (possibly\n indirectly, e.g. as a result of a timeout in gen_server:call/3), Common Test\n would hang. This problem has been fixed.\n\n Own Id: OTP-10072 Aux Id: seq12053\n\n- The documentation has been updated with information about how to deal with\n chaining of hooks which return fail/skip.\n\n Own Id: OTP-10077 Aux Id: seq12048\n\n- When ct_hooks called the id/1 functions of multiple hooks, it would reverse\n the order of the hooks and call the proceeding init/2 calls in the wrong\n order. This has been fixed.\n\n Own Id: OTP-10135\n\n- The surefire hook now correctly handles autoskipped initialization and test\n functions.\n\n Own Id: OTP-10158\n\n- The ct:get_status/0 function failed to report status if a parallel test case\n group was running at the time of the call. This has been fixed and the return\n value for the function has been updated. Please see the ct reference manual\n for details.\n\n Own Id: OTP-10172","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- The support for \"silent connections\" has been updated to include ssh. Also, a\n silent_connections term has been added to the set of test specification terms.\n\n Own Id: OTP-9625 Aux Id: seq11918\n\n- It is now possible to specify an arbitrarily large tuple as the requires\n config data when using require and ct:get_config. See the ct:get_config and\n ct:require reference manual pages for details about which keys are allowed.\n\n This change introduces a backwards incompatibility in the `ct:require/2`\n interface. Previously when doing `ct:require(a_name,{key,subkey})`, a_name\n would be associated with key. This has been changed to that `a_name` is\n associated with `subkey`. This change also effects using `require` in an\n suite/group/testcase info function.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-9626 Aux Id: seq11920\n\n- The ct_run program now sets the OS process exit status before it ends. Value 0\n indicates a successful test result, 1 indicates one or more failed or\n auto-skipped test cases, and 2 indicates test execution failure.\n\n Own Id: OTP-9865 Aux Id: OTP-10087\n\n- It is now possible to sort the HTML tables by clicking on the header elements.\n In order to reset a sorted table, the browser window should simply be\n refreshed. This feature requires that the browser supports javascript, and has\n javascript execution enabled. If the 'ct_run -basic_html' flag is used, no\n javascript code is included in the generated HTML code.\n\n Own Id: OTP-9896 Aux Id: seq12034, OTP-9835\n\n- A netconf client, ct_netconfc, is added to common_test. It supports basic\n netconf functionality over SSH. In order to allow testing of both success and\n failure cases, it is intentionally written to allow non-standard behavior.\n\n Own Id: OTP-10025\n\n- The test specification term \\{define,Constant,Value\\} has been introduced,\n which makes it possible to replace constant names (atom()) with values\n (term()) in arbitrary test specification terms. The 'define' makes the (now\n deprecated) 'alias' term obsolete. More details, including examples, can be\n found in the Test Specifications chapter in the Common Test User's Guide.\n\n Own Id: OTP-10049\n\n- Verbosity levels for log printouts has been added. This makes it possible to\n specify preferred verbosity for different categories of log printouts, as well\n as general printouts (such as standard IO), to allow control over which\n strings get printed and which get ignored. New versions of the Common Test\n logging functions, ct:log, ct:pal and ct:print, have been introduced, with a\n new Importance argument added. The Importance value is compared to the\n verbosity level at runtime. More information can be found in the chapter about\n Logging in the Common Test User's Guide.\n\n Own Id: OTP-10067 Aux Id: seq12050\n\n- The return values of ct:run_test/1 and ct:run_testspec/1 have been changed\n from an uninformative 'ok' (independent of the test outcome) to a value,\n \\{Ok,Failed,\\{UserSkipped,AutoSkipped\\}\\} (all integers), that presents the\n final test case result, or a value, \\{error,Reason\\}, that informs about fatal\n test execution failure. See details in the reference manual for ct.\n\n Own Id: OTP-10087 Aux Id: OTP-9865\n\n- The test specification syntax has been updated with new and missing terms,\n such as 'define', 'verbosity', 'auto_compile', 'stylesheet',\n 'silent_connections', 'basic_html' and 'release_shell'. See the Test\n Specification chapter in the Common Test User's Guide for details.\n\n Own Id: OTP-10089 Aux Id: OTP-10049\n\n- It is now possible to pause execution of a test case, by calling the\n ct:break/1/2 function. Execution is resumed with a call to ct:continue/0/1.\n Break/continue also works for test cases executing in parallel. See the ct\n reference manual for details.\n\n Own Id: OTP-10127\n\n- It is now possible to send user defined events from a testcase which will be\n picked up by the installed event handler.\n\n Own Id: OTP-10157\n\n- A new start option, release_shell, for ct:run_test/1, has been added, which\n makes Common Test release the shell process after the test suite compilation\n phase is finished. For details, see the Running Tests chapter in the User's\n Guide.\n\n Own Id: OTP-10248 Aux Id: OTP-10127","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.6.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-6-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Common Test adds the test suite directories to the code path before executing\n the tests. These directories should also be removed from the code path at the\n end of the test run, which, prior to this fix, was not performed.\n\n Own Id: OTP-9595\n\n- An entry is now created in the index.html file (i.e. the overview file for the\n test run) for each repeated test during a test run. This was previously not\n the case. Note that in the top level (logdir) index file, however, only the\n last test result is listed. For example, given the test spec:\n \\[\\{merge_tests,false\\},\\{dirs,\"test1\"\\},\\{dirs,\"test1\"\\}]. In the index file\n for the test run (under Logdir/ct_run.Node.Date.Time), both tests are listed.\n In the top level index file (under Logdir), only the last test is listed (one\n has to find the previous results through the all_runs.html file).\n\n Own Id: OTP-9634 Aux Id: seq11924\n\n- After a test case timeout or abortion, the end_per_testcase function executes\n on a new dedicated process. The group leader for this process should be set to\n the IO server for the test case, which was not done properly. The result of\n this error was that no warnings about end_per_testcase failing or timing out\n were ever printed in the test case log. Also, help functions such as e.g.\n test_server:stop_node/1, attempting to synchronize with the IO server, would\n hang. The fault has been corrected.\n\n Own Id: OTP-9666\n\n- The ct:get_status/0 function would cause the calling process to receive 'DOWN'\n messages if no tests were running at the time of the call. This bug has been\n fixed.\n\n Own Id: OTP-9830 Aux Id: seq11975\n\n- A deadlock situation could occur if Common Test is forwarding error_handler\n printouts to Test Server at the same time a new test case is starting. This\n error has been fixed.\n\n Own Id: OTP-9894\n\n- A link to the ct_run program is now created, as expected, in the installation\n bin directory (default /usr/local/bin) during 'make install'.\n\n Own Id: OTP-9898\n\n- Using the repeat, duration or until option with ct:run_test/1, would cause an\n infinite loop. This has been fixed.\n\n Own Id: OTP-9899\n\n- Two or more test cases executing in parallel and printing to screen at the\n same time with ct:pal/2/3 or ct:print/2/3 could write into each other's\n \"slots\" and create a mess of mixed strings. In order to avoid this, only a\n single IO message is now ever sent per printout call.\n\n Own Id: OTP-9900 Aux Id: OTP-9904\n\n- When a test case was killed because of a timetrap timeout, the current\n location (suite, case and line) was not printed correctly in the log files.\n This has been corrected.\n\n Own Id: OTP-9930 Aux Id: seq12002\n\n- The wrong exit location was printed in the log file when ct:fail/1 or\n ct_fail/2 was called.\n\n Own Id: OTP-9933 Aux Id: seq12002\n\n- Test Server and Common Test would add new error handlers with each test run\n and fail to remove previously added ones. In the case of Test Server, this\n would only happen if SASL was not running on the test node. This has been\n fixed.\n\n Own Id: OTP-9941 Aux Id: seq12009\n\n- If a test case process was terminated due to an exit signal from a linked\n process, Test Server failed to report the correct name of the suite and case\n to the framework. This has been corrected.\n\n Own Id: OTP-9958 Aux Id: OTP-9855\n\n- When starting a test with ct_run and adding a directory to the code path using\n -pa or -pz (preceding -erl_args), Common Test would delete any existing\n directory in the code path with the same base name (see filename:basename/1)\n as the directory being added. This has been fixed.\n\n Own Id: OTP-9964\n\n- If passing two or more directories with the same base name (see\n filename:basename/1) to Common Test with ct_run -pa, only one of the\n directories would actually be added.\n\n Own Id: OTP-9975 Aux Id: seq12019\n\n- Configuration data required by the group info function was deleted before the\n call to post_end_per_group, which made it impossible for the hook function to\n read and use the data in question. This has been fixed.\n\n Own Id: OTP-9989\n\n- Disabling built-in hooks in a test specification was ignored, this has now\n been fixed.\n\n Own Id: OTP-10009\n\n- Various typographical errors corrected in documentation for common_test,\n driver, erl_driver and windows installation instructions. (Thanks to Tuncer\n Ayaz)\n\n Own Id: OTP-10037","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- A new optional feature has been introduced that enables Common Test to\n generate priv_dir directory names that are unique for each test case or config\n function. The name of the option/flag is 'create_priv_dir' and it can be set\n to value 'auto_per_run' (which is the default, existing, behaviour), or\n 'auto_per_tc' or 'manual_per_tc'. If 'auto_per_tc' is used, Test Server\n creates a dedicated priv_dir automatically for each test case (which can be\n very expensive in case of many and/or repeated cases). If 'manual_per_tc' is\n used, the user needs to create the priv_dir explicitly by calling the new\n function ct:make_priv_dir/0.\n\n Own Id: OTP-9659 Aux Id: seq11930\n\n- A column for test case group name has been added to the suite overview HTML\n log file.\n\n Own Id: OTP-9730 Aux Id: seq11952\n\n- It is now possible to use the post_end_per_testcase CT hook function to print\n a comment for a test case in the overview log file, even if the test case gets\n killed by a timetrap or unknown exit signal, or if the end_per_testcase\n function times out.\n\n Own Id: OTP-9855 Aux Id: seq11979\n\n- The pre- and post CT hook functions are now always called for all\n configuration functions, even for configuration functions that are not\n implemented in the test suite.\n\n Own Id: OTP-9880 Aux Id: seq11993\n\n- Common Test will now print error information (with a time stamp) in the test\n case log file immediately when a test case fails. This makes it easier to see\n when, in time, the fault actually occurred, and aid the job of locating\n relevant trace and debug printouts in the log.\n\n Own Id: OTP-9904 Aux Id: seq11985, OTP-9900\n\n- Test Server has been modified to check the SASL errlog_type parameter when\n receiving an error logger event, so that it doesn't print reports of type that\n the user has disabled.\n\n Own Id: OTP-9955 Aux Id: seq12013\n\n- The test specification term 'skip_groups' was implemented in Common Test v1.6.\n It was never documented however, which has now been attended to. Please see\n the Test Specifications chapter in the User's Guide for information.\n\n Own Id: OTP-9972\n\n- The Common Test Master has been updated to use a CSS style sheet for the html\n log files.\n\n Own Id: OTP-9973\n\n- If the init_per_group/2 and end_per_group/2 functions are not implemented in\n the test suite, Common Test calls it's own local init- and end functions -\n previously named ct_init_per_group/2 and ct_end_per_group/2 - when a group is\n executed. These functions have been renamed init_per_group/2 and\n end_per_group/2 respectively. Note that this may affect any user event handler\n identifying events by the old names.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-9986 Aux Id: OTP-9992\n\n- By specifying a user defined function (\\{M,F,A\\} or fun) as timetrap value,\n either by means of an info function or by calling ct:timetrap/1, it is now\n possible to set a timetrap that will be triggered when the user function\n returns.\n\n Own Id: OTP-9988 Aux Id: OTP-9501, seq11894\n\n- If the optional configuration functions init_per_suite/1 and end_per_suite/1\n are not implemented in the test suite, local Common Test versions of these\n functions are called instead, and will be displayed in the overview log file.\n Any printouts made by the pre- or post_init_per_suite and pre- or\n post_end_per_suite hook functions are saved in the log files for these\n functions.\n\n Own Id: OTP-9992\n\n- A hook has been added to common test which outputs surefire XML for usage\n together with CI tools such as Jenkins. To enable the hook pass '-ct_hooks\n cth_surefire' to ct_run. See the CTH documentation for more details.\n\n Own Id: OTP-9995","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.6 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-6"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- A Getting Started chapter has been added to the Common Test User's Guide.\n\n Own Id: OTP-9156\n\n- The test case group info function has been implemented in Common Test. Before\n execution of a test case group, a call is now made to\n `TestSuite:group(GroupName)`. The function returns a list of test properties,\n e.g. to specify timetrap values, require configuration data, etc (analogue to\n the test suite- and test case info function). The scope of the properties set\n by `group(GroupName)` is all test cases and sub-groups of group `GroupName`.\n\n Own Id: OTP-9235\n\n- Common Test hooks are now in a final supported version. The Common Test hooks\n allow you to abstract out initialization behaviour that is common to multiple\n test suites into one place and also extend the behaviour of a suite without\n changing the suite itself. For more information see the Common Test user's\n guide.\n\n Own Id: OTP-9449\n\n- A new built-in common test hook has been added which captures error_logger and\n SASL event and prints them in the testcase log. To disable this (and any other\n built-in hooks) pass 'enable_builtin_hooks false' to common test.\n\n Own Id: OTP-9543\n\n- Common Test now calls info functions also for the `init/end_per_suite/1` and\n `init/end_per_group/2` configuration functions. These can be used e.g. to set\n timetraps and require external configuration data relevant only for the\n configuration functions in question (without affecting properties set for\n groups and test cases in the suite). The info function for\n `init/end_per_suite(Config)` is `init/end_per_suite()`, and for\n `init/end_per_group(GroupName,Config)` it's `init/end_per_group(GroupName)`.\n Info functions cannot be used with `init/end_per_testcase(TestCase, Config)`,\n since these configuration functions execute on the test case process and will\n use the same properties as the test case (i.e. properties set by the test case\n info function, `TestCase()`).\n\n Own Id: OTP-9569\n\n- It's now possible to read the full name of the test case log file during\n execution. One way to do this is to lookup it up as value of the key\n `tc_logfile` in the test case `Config` list (which means it can also be read\n by a pre- or post Common Test hook function). The data is also sent with the\n event `#event{name=tc_logfile,data={{Suite,Func},LogFileName}}`, and can be\n read by any installed event handler.\n\n Own Id: OTP-9676 Aux Id: seq11941\n\n- The look of the HTML log files generated by Common Test and Test Server has\n been improved (and made easier to customize) by means of a CSS file.\n\n Own Id: OTP-9706\n\n- Functions ct:fail(Format, Args) and ct:comment(Format, Args) have been added\n in order to make printouts of formatted error and comment strings easier (no\n need for the user to call io_lib:format/2 explicitly).\n\n Own Id: OTP-9709 Aux Id: seq11951\n\n- The order in which ct hooks are executed for cleanup hooks (i.e. _*end_per*_\n hooks) has been reversed.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-9774 Aux Id: seq11913\n\n- Printouts to stdout may be captured during test case execution. This is useful\n in order to e.g. read and parse tty printouts from the SUT during test case\n execution (if necessary, say, to determine the outcome of the test). The\n capturing session is started with `ct:capture_start/0`, and stopped with\n `ct:capture_stop/0`. The list of buffered strings is read and purged with\n `ct:capture_get/0/1`. It's possible to filter out printouts made with\n `ct:log/2/3` and `ct:pal/2/3` from the captured list of strings. This is done\n by calling `capture_get/1` with a list of log categories to exclude.\n\n Own Id: OTP-9775\n\n- The syntax for specifying test case groups in the all/0 list has been extended\n to include execution properties for both groups and sub-groups. The properties\n specified in all/0 for a group overrides the properties specified in the group\n declaration (in groups/0). The main purpose of this extension is to make it\n possible to run the same set of tests, but with different properties, without\n having to declare copies of the group in question. Also, the same syntax may\n be used in test specifications in order to change properties of groups at the\n time of execution, without having to edit the test suite. Please see the\n User's Guide for details and examples.\n\n Own Id: OTP-9809 Aux Id: OTP-9235","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Known Bugs and Problems - Common Test Release Notes","doc":"- Fix problems in CT/TS due to line numbers in exceptions.\n\n Own Id: OTP-9203","ref":"notes.html#known-bugs-and-problems"},{"type":"extras","title":"Common_Test 1.5.5 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-5-5"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- An error in how comments are colored in the test suite overview html log file\n has been corrected. As result, a new framework callback function,\n format_comment/1, has been introduced.\n\n Own Id: OTP-9237\n\n- Automatically generated init- and end-configuration functions for test case\n groups caused incorrect execution order of test cases. This has been\n corrected.\n\n Own Id: OTP-9369\n\n- If multiple directories were specified with the 'logdir' flag/option, Common\n Test would crash. This has been fixed so that an error is properly reported\n instead.\n\n Own Id: OTP-9370\n\n- If ct:log/2 was called with bad arguments, this could cause the Common Test IO\n handling process to crash. This fault has been corrected.\n\n Own Id: OTP-9371 Aux Id: OTP-8933\n\n- A bug has been fixed that made Test Server call the end_tc/3 framework\n function with an incorrect module name as first argument.\n\n Own Id: OTP-9379 Aux Id: seq11863\n\n- If a timetrap timeout occurred during execution of a function in a lib module\n (i.e. a function called directly or indirectly from a test case), the Suite\n argument in the end_tc/3 framework callback function would not correctly\n contain the name of the test suite, but the lib module. (This would only\n happen if the lib module was compiled with ct.hrl included). This error has\n been solved.\n\n Own Id: OTP-9398\n\n- Corrections of the vts mode. It will now report errors (about e.g. incorrect\n config files) instead of crashing or hanging. Furthermore, the requirement\n that the test directory name must have a \"\\_test\" suffix has been removed.\n Also, a workaround has been implemented for the limitation that the file\n browser (in many web browsers) will only return the basic file name, not the\n full directory path (which made it impossible to have config files in other\n directories than the main test directory).\n\n Own Id: OTP-9429\n\n- Add a proplist() type\n\n Recently I was adding specs to an API and found that there is no canonical\n proplist() type defined. (Thanks to Ryan Zezeski)\n\n Own Id: OTP-9499\n\n- It is now possible to use the 'step' flag/option to run the debugger for test\n suites that contain test case groups. This previously caused Common Test to\n crash. If 'step config' is specified, breakpoints are now also automatically\n set on init_per_group and end_per_group. Note that breakpoints are always set\n automatically on test case functions and this is true also for grouped cases.\n\n Own Id: OTP-9518 Aux Id: OTP-8933\n\n- The test index page was not refreshed at the start of each test suite which\n made it impossible to follow test execution by means of refreshing the browser\n window (no links to follow). This has been fixed.\n\n Own Id: OTP-9520 Aux Id: OTP-8933\n\n- If a test suite would start with a test case group defined without the\n init_per_group/2 and end_per_group/2 function, init_per_suite/1 would not\n execute initially and logging of the test run would fail. This error has been\n fixed.\n\n Own Id: OTP-9584\n\n- The \"Missing Suites\" link from the top level index page was incorrect and has\n been fixed.\n\n Own Id: OTP-9592","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Various corrections and updates to improve the handling and reporting of\n errors.\n\n Own Id: OTP-8933\n\n- The dir and suite start option can now be used in combination. E.g. executing\n my_SUITE in directory my_tests can either be specified as \"ct_run -suite\n my_tests/my_SUITE\" or as \"ct_run -dir my_tests -suite my_SUITE\". Furthermore,\n the specification: ct:run_test(\\[\\{suite,[\"./my_SUITE\"]\\},\\{testcase,t1\\}]) is\n now interpreted as ct:run_test(\\[\\{suite,\"./my_SUITE\"\\},\\{testcase,t1\\}]),\n i.e. only testcase t1 in test suite my_SUITE - not all cases - will be\n executed.\n\n Own Id: OTP-9155\n\n- A new option, 'logopts', has been introduced, to make it possible to modify\n some aspects of the logging behaviour in Common Test (or Test Server). For\n example, whenever an io printout is made, test_server adds newline (\\\\n) to\n the end of the output string. This may not always be a preferred action and\n can therefore be disabled by means of \"ct_run ... -logopts no_nl\" (or\n ct:run_test(\\[..., \\{logopts,[no_nl]\\}])). A new framework callback function,\n get_logopts/0, has been introduced (see the ct_framework module for details).\n\n Own Id: OTP-9372 Aux Id: OTP-9396\n\n- A new option, 'logopts', has been introduced, to make it possible to modify\n some aspects of the logging behaviour in Common Test (or Test Server). For\n example, if the html version of the test suite source code should not be\n generated during the test run (and consequently be unavailable in the log file\n system), the feature may be disabled by means of \"ct_run ... -logopts no_src\"\n (or ct:run_test(\\[..., \\{logopts,[no_src]\\}])). A new framework callback\n function, get_logopts/0, has been introduced (see the ct_framework module for\n details).\n\n Own Id: OTP-9396 Aux Id: seq11869, OTP-9372\n\n- CT Hooks can now be assigned a priority. The priority of a CTH determines when\n it should execute in relation to other CTHs. The CTH with the lowest priority\n will be executed first, CTHs with equal priority will be executed in the order\n which they were installed.\n\n Own Id: OTP-9445\n\n- It is now possible to use a tuple \\{M,F,A\\}, or a fun, as timetrap\n specification in the suite info function or test case info functions. The\n function must return a valid timeout value, as documented in the common_test\n man page and in the User's Guide.\n\n Own Id: OTP-9501 Aux Id: seq11894\n\n- A new built-in common test hook has been added which captures error_logger and\n SASL event and prints them in the testcase log. To disable this (and any other\n built-in hooks) pass 'enable_builtin_hooks false' to common test.\n\n Own Id: OTP-9543\n\n- Common Test now has the possibility to have built-in hooks which are started\n by default when any test is run. To disable built-in hooks pass\n 'enable_builtin_hooks false' to common test. See the common test hooks\n documentation for more details.\n\n Own Id: OTP-9564","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.5.4 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-5-4"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- It was previously not possible to use timetrap value 'infinity' with\n ct:timetrap/1. This has been fixed.\n\n Own Id: OTP-9159\n\n- The Common Test VTS mode has been updated to be able to report test results of\n suites that include test case groups (when it would previously crash).\n\n Own Id: OTP-9195\n\n- Common Test now refreshes the very top level index.html page at the start of\n each individual test in a test run, so that progress of the ongoing test can\n be tracked by following the link to its overview page.\n\n Own Id: OTP-9210 Aux Id: OTP-9054\n\n- A bug that made it impossible to cancel the previous timetrap when calling\n ct:timetrap/1 has been corrected.\n\n Own Id: OTP-9233 Aux Id: OTP-9159\n\n- Fix bug which would make cth's to not be removed when out of scope when adding\n a cth in suite/0 and crashing in pre_init_per_suite.\n\n Own Id: OTP-9264","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- It is now possible to return a tuple \\{fail,Reason\\} from init_per_testcase/2.\n The result is that the associated test case gets logged as failed without ever\n executing.\n\n Own Id: OTP-9160 Aux Id: seq11502\n\n- Common Test now accepts, but ignores, empty test case group specifications.\n\n Own Id: OTP-9161","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.5.3 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-5-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Added an option to test specs which allow the execution of tests as is,\n instead of doing merging of tests on the same \"level\". See the merge_tests\n directive the test specification documentation.\n\n Own Id: OTP-9026 Aux Id: seq11768","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Alpha release of Common Test Hooks (CTH). CTHs allow the users of common test\n to abstract out common behaviours from test suites in a much more elegant and\n flexible way than was possible before. Note that the addition of this feature\n may introduce minor changes in the undocumented behaviour of the interface\n between common_test and test_server.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-8851","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.5.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-5-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Updated ct:get_status documentation to describe no_tests_running return value.\n\n Own Id: OTP-8895 Aux Id: seq11701\n\n- Fixed race condition test failures in the test suites testing common test's\n parallel groups feature.\n\n Own Id: OTP-8921\n\n- The include directive of testspecs now work when used on a remote node.\n\n Own Id: OTP-8935 Aux Id: seq11731","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- ct:parse_table can now handle multiline sql rows\n\n Own Id: OTP-8907 Aux Id: seq11702\n\n- The run_test executable has been renamed to the less generic ct_run to better\n work with other applications. run_test will remain until R16B at which point\n it will be removed.\n\n Own Id: OTP-8936","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.5.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-5-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Returning \\{return_group_result,failed\\} from end_per_group in a group that is\n part of a sequence, did not cause the proceeding cases (or groups) to get\n skipped. This has been fixed.\n\n Own Id: OTP-8753 Aux Id: seq11644\n\n- ct:install now works as the documentation describes.\n\n Own Id: OTP-8818 Aux Id: seq-11666","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Common Test has been updated to handle start options and test specification\n terms for test case groups (and test cases in groups). Also, an option named\n 'label', has been added that associates the test run with a name that Common\n Test prints in the overview HTML logs.\n\n Own Id: OTP-8725 Aux Id: OTP-8727\n\n- Andrey Pampukha has been added to the AUTHORS file. Thank you Andrey for your\n work on configuration data handling, Large Scale Testing improvements, and\n other useful updates and fixes.\n\n Own Id: OTP-8803\n\n- The Configuration Data chapter in the User's Guide has been updated.\n\n Own Id: OTP-8804\n\n- Milliseconds are now included in timestamps in Common Test log entries.\n (Thanks to Tomas Johansson.)\n\n Own Id: OTP-8808","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.5 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-5"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- Process calls using monitors in Common Test would not clear the inbox of\n remaining DOWN messages. This has been fixed.\n\n Own Id: OTP-8621 Aux Id: seq11560","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- It is now possible for the user to provide specific callback modules that\n handle test configuration data, so that data on arbitrary form can be accessed\n (e.g. by reading files or by communicating with a configuration server\n process). Two default callback modules have been introduced in Common Test:\n ct_config_plain and ct_config_xml. The former is used to handle the\n traditional Common Test configuration files (with terms on key-value tuple\n form) and the latter to handle configuration data on XML representation.\n\n Own Id: OTP-8485\n\n- It is now possible to execute test suites that are not necessarily available\n on the local file system, but have been loaded on the test node in advance\n (e.g. sent as binaries from a remote node and loaded by RPC). A requirement is\n that the no_auto_compile (or \\{auto_compile,false\\}) parameter has been set.\n\n Own Id: OTP-8490 Aux Id: seq11500\n\n- Test Server will now call the end_per_testcase/2 function even if the test\n case has been terminated explicitly (with abort_current_testcase/1), or after\n a timetrap timeout. Under these circumstances the return value of\n end_per_testcase is completely ignored. Therefore the function will not be\n able to change the reason for test case termination by returning\n \\{fail,Reason\\}, nor will it be able to save data with \\{save_config,Data\\}.\n\n Own Id: OTP-8500 Aux Id: seq11521\n\n- It is now possible to use the test specification term 'init' to start Common\n Test nodes automatically, as well as have initial function calls evaluated on\n the nodes. A default callback module for the 'init' term, ct_slave, has been\n introduced to enable Common Test Master to perform host login and node startup\n operations over ssh.\n\n Own Id: OTP-8570\n\n- The run_test script has been replaced by a program (with the same name) which\n can be executed without explicit installation. The start flags are the same as\n for the legacy start script.\n\n Own Id: OTP-8650\n\n- Previously, a repeat property of a test case group specified the number of\n times the group should be repeated after the main test run. I.e. \\{repeat,N\\}\n would case the group to execute 1+N times. To be consistent with the behaviour\n of the run_test repeat option, this has been changed. N now specifies the\n absolute number of executions instead.\n\n Own Id: OTP-8689 Aux Id: seq11502\n\n- With the run_test -erl_args option, it's possible to divide the options on the\n run_test command line into ones that Common Test should process (those\n preceding -erl_args, and ones it should ignore (those succeeding -erl_args).\n Options preceding -erl_args that Common Test doesn't recognize are also\n ignored (i.e. the same behaviour as earlier versions of Common Test).\n\n Own Id: OTP-8690 Aux Id: OTP-8650\n\n- Directories added with -pa or -pz in the pre-erl_args part of the run_test\n command line will be converted from relative to absolute, this to avoid\n problems loading user modules when Common Test switches working directory\n during the test run.\n\n Own Id: OTP-8691 Aux Id: OTP-8650\n\n- The timetrap handling has been made more user controllable by means of new\n start options and new ct interface functions. With the 'multiply_timetraps'\n start option, it's possible to specify a value which all timetrap timeout\n values get multiplied by. This is useful e.g. to extend the timetraps\n temporarily while running cover or trace. The 'scale_timetraps' start option\n switches on or off the Test Server timetrap scaling feature (which tries to\n detect if the tests may benefit from extended timetraps, e.g. due to running\n certain test tools, and performs the scaling automatically). Furthermore, the\n ct:timetrap/1 function has been introduced, which makes it possible to\n set/reset timetraps during test execution. Also, a ct:sleep/1 function is now\n available, which takes the timetrap parameters into account when calculating\n the time to suspend the process.\n\n Own Id: OTP-8693\n\n- A new run_test start option, event_handler_init, has been added that takes a\n start argument which gets passed to the init function of the event handler.\n\n Own Id: OTP-8694","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.4.7 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-4-7"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The auto compilation feature of Common Test did not recognize if a header file\n included in a test suite was modified (if the dir start flag/option was used).\n This has been fixed.\n\n Own Id: OTP-8396 Aux Id: seq11488, OTP-8311","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- The tc_status value in the Config list for a test case that has failed because\n of a timetrap timeout, has changed from \\{tc_status,timeout\\} to\n \\{tc_status,timetrap_timeout\\}.\n\n Own Id: OTP-8302\n\n- The documentation is now possible to build in an open source environment after\n a number of bugs are fixed and some features are added in the documentation\n build process.\n\n \\- The arity calculation is updated.\n\n \\- The module prefix used in the function names for bif's are removed in the\n generated links so the links will look like\n \"http://www.erlang.org/doc/man/erlang.html#append_element-2\" instead of\n \"http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2\".\n\n \\- Enhanced the menu positioning in the html documentation when a new page is\n loaded.\n\n \\- A number of corrections in the generation of man pages (thanks to Sergei\n Golovan)\n\n \\- The legal notice is taken from the xml book file so OTP's build process can\n be used for non OTP applications.\n\n Own Id: OTP-8343\n\n- It is now possible to include the `ct.hrl` using the -include_lib directive.\n (Thanks to Fred Hebert.)\n\n Own Id: OTP-8379\n\n- The telnet client in Common Test sent \\[IAC,DO,NOP] to the server in attempt\n to keep the connection alive. This is not a valid sequence according to the\n standard, and some telnet servers would terminate the connection because of\n it. The client has been changed to send \\[IAC,NOP] every 10 secs instead,\n which should be a valid sequence. The client does not negotiate this type of\n \"keep alive\" message with the server, and if it causes problems, the user may\n disable the keep alive feature by adding \\{keep_alive,false\\} to the telnet\n configuration data for the server/connection. Please see the ct_telnet and\n unix_telnet manual pages for details.\n\n Own Id: OTP-8450 Aux Id: OTP-8311","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.4.6 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-4-6"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- If the init_per_testcase/2 function fails, the test case now gets marked and\n counted as auto skipped, not user skipped (which would previously happen).\n\n Own Id: OTP-8289","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- The documentation is now built with open source tools (xsltproc and fop) that\n exists on most platforms. One visible change is that the frames are removed.\n\n Own Id: OTP-8201\n\n- For a failed test case, the tc_done event is supposed to report info on the\n form \\{failed,Error\\}. Only Error was reported, however, which has now been\n fixed.\n\n Own Id: OTP-8235 Aux Id: seq-11414\n\n- It is now possible to fail a test case from the end_per_testcase/2 function,\n by returning \\{fail,Reason\\}.\n\n Own Id: OTP-8284\n\n- It is now possible to fail a test case by having the end_tc/3 framework\n function return \\{fail,Reason\\} for the test case.\n\n Own Id: OTP-8285\n\n- The test_server framework API (e.g. the end_tc/3 function) has been modified.\n See the test_server_ctrl documentation for details.\n\n Own Id: OTP-8286 Aux Id: OTP-8285, OTP-8287\n\n- Various updates of the test events have been implemented. The data field for\n some events, such as tc_done and tc_auto_skip has been modified to make\n pattern matching on the data easier and more consistent. Also the order in\n which some events are received has been altered. E.g. the tc_auto_skip event\n for a test case now comes after the tc_done for the failed configuration\n function (not before) which makes more sense. Note that no new events have\n been added and that the event record remains unchanged.\n\n Own Id: OTP-8287 Aux Id: OTP-8235\n\n- The marquee used for test names on the all_runs.html page has been removed on\n request. Note that the test name field has the full text string in a title\n tag, which is displayed when hovering the mouse pointer over it (i.e. if the\n web browser supports title tags).\n\n Own Id: OTP-8288\n\n- It is now possible to refresh the top level index files in an arbitrary log\n directory by specifying a \\{refresh_logs,LogDir\\} tuple in the ct:run_test/1\n options list. Also the -refresh_logs flag for the run_test script has been\n extended to take an optional LogDir argument, i.e. -refresh_logs \\[LogDir]. If\n no LogDir is specified, current working directory is assumed, unless the log\n directory is set with the -logdir flag.\n\n Own Id: OTP-8290\n\n- It was previously required that test suites were located under a test object\n (or OTP application) sub-directory named \"test\" (or under a directory named\n \" \\_test\"). This has been changed so that Common Test now looks for\n suites primarily in a test sub-directory only if the directory exists.\n Otherwise it will assume the suites are stored in the same directory the user\n specifies with e.g. the 'dir' start flag/option.\n\n Own Id: OTP-8294","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.4.5 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-4-5"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- The Common Test logger process crashed if a test case in a sequence (declared\n with sequences/0) failed. This fault has been corrected.\n\n Own Id: OTP-8089 Aux Id: seq11334","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Various updates and fixes in Common Test and Test Server.\n\n Own Id: OTP-8045 Aux Id: OTP-8089,OTP-8105,OTP-8163\n\n- Errors in coverage data collection and analysis were difficult to detect. The\n logging has been improved so that more information about e.g. imported and\n missing modules is printed to the html log files.\n\n Own Id: OTP-8163 Aux Id: seq11374\n\n- The Common Test HTML overview pages have been improved. It is now possible to\n see if a test case has been skipped explicitly or because a configuration\n function has failed. Also, the history page (all_runs.html) now has scrolling\n text displaying the test names. The old format (showing names as a truncated\n string) can still be generated by means of the flag/option 'basic_html'.\n\n Own Id: OTP-8177","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.4.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-4-2"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Various corrections and improvements of Common Test and Test Server.\n\n Own Id: OTP-7981","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.4.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-4-1"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Minor updates and corrections.\n\n Own Id: OTP-7897","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.4 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-4"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- A support client module for SSH and SFTP, ct_ssh, has been introduced in\n Common Test.\n\n Own Id: OTP-7838\n\n- Test case groups have been introduced. With this feature it's possible to\n execute groups (possibly nested) of test cases, each group wrapped with a call\n to function init_per_group/2 and end_per_group/2. Group definitions are done\n by means of the new call-back function groups/0, which should return a list of\n definitions. A group definition contains a name tag, a list of properties and\n a list of test cases (including possible nested group definitions). The\n properties make it possible to execute test cases in parallel, in sequence and\n in shuffled order. It is also possible to repeat test cases according to\n different criteria. The properties can be combined, making it possible to e.g.\n repeat a conf case a certain number of times and execute the test cases in\n different (random) order every time. Available properties are: parallel,\n sequence, shuffle, repeat, repeat_until_all_ok, repeat_until_any_ok,\n repeat_until_any_fail and repeat_until_all_fail. Please see the Common Test\n User's Guide for details.\n\n Own Id: OTP-7839 Aux Id: OTP-7511\n\n- It is now possible to use DES3 encrypted configuration files with Common Test.\n\n Own Id: OTP-7842 Aux Id: OTP-7838\n\n- In previous versions of Common Test, only one FTP connection could be opened\n per configuration target name. This has been updated so that multiple\n connections may be opened. The possibility to use named connections is still\n supported.\n\n Own Id: OTP-7853 Aux Id: OTP-7838\n\n- The Erlang mode for Emacs has been updated with new and modified skeletons for\n Common Test and TS. Syntax for test case groups in Common Test (and conf cases\n with properties in TS) has been added and a new minimal Common Test suite\n skeleton has been introduced.\n\n Own Id: OTP-7856","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.3.6 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-3-6"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- When running a test which includes all suites in a test directory, if the auto\n compilation would fail for one suite, all following suites would be excluded\n from the test. This was an unwanted behaviour and has been corrected. Now all\n suites will always be compiled and only the failing ones excluded from the\n test (and logged as missing).\n\n Own Id: OTP-7750 Aux Id: OTP-7803\n\n- The step functionality in Common Test (based on interaction with Debugger) was\n broken. This has been fixed, and some new step features have also been added.\n Please see the Common Test User's Guide for details.\n\n Own Id: OTP-7800 Aux Id: seq11106","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- It is now possible for the user to specify include directories that Common\n Test will pass along to the compiler when suite and help modules are being\n compiled (which Common Test performs automatically before running tests).\n\n Own Id: OTP-7803 Aux Id: OTP-7750","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.3.5 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-3-5"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","doc":"- If the Erlang runtime system was started without access to an erlang shell\n (e.g. -noshell), compilation errors would cause a crash in the Common Test\n application. Without access to a shell, Common Test cannot prompt the user to\n choose to continue or abort the test session, but must assume that the session\n should proceed.\n\n Own Id: OTP-7749 Aux Id: seq11175, seq11180","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- It is now possible for the Common Test user to disable the auto-compile\n feature. This is done by specifying the run_test flag -no_auto_compile, or the\n ct:run_test/1 option \\{auto_compile,false\\}.\n\n Own Id: OTP-7663\n\n- A new function, ct:get_config/3, has been added to Common Test that makes it\n possible to - if a particular config variable has been defined in multiple\n config files - return all matching values for the variable. The order of the\n elements in the returned list is the same as the specified order of the config\n files.\n\n Own Id: OTP-7758 Aux Id: seq11158\n\n- Because a telnet connection was always identified by a config variable alias,\n it was impossible to open multiple connections using the same telnet host data\n entry in the config file. This limitation has been removed by making it\n possible to associate a connection with handle value only (i.e. multiple\n connections may be opened using the same config variable). See\n ct_telnet:open/4 for details.\n\n Own Id: OTP-7781\n\n- A new syntax for defining default config data values has been introduced. In\n previous versions of Common Test, to define and access a default value for a\n config variable (in the suite info- or test case info function), an alias name\n had to be used. With the new syntax you may define default values without\n reference to aliases, like this: \\{default_config,VarName,DefaultValue\\}.\n Please see the User's Guide for more info.\n\n Own Id: OTP-7782\n\n- In previous versions of Common Test, whenever a config variable got associated\n with a name (by means of a require statement), the config variable name was\n replaced with the new name. This introduced unwanted dependencies between test\n cases (e.g. if one test case would introduce a new name, the following test\n cases could no longer access the config data by means of the original\n variable). This functionality has now been updated so that when new names are\n introduced with require, they become aliases (references) instead of\n replacements. Hence, config data elements can always, at any time, be accessed\n by means of the original config variable names.\n\n Own Id: OTP-7783","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.3.4 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-3-4"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Common Test now uses the re application instead of the previous rx driver to\n perform regular expression matching on telnet strings. Since re works on all\n supported operating systems, it is now possible to run telnet sessions also on\n platforms such as e.g. Windows (which was not the case with the previous rx\n driver). Note that the rx driver is obsolete from now on, and will be removed\n from Common Test after OTP R12B.\n\n Own Id: OTP-7528","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.3.3 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-3-3"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- Various updates and improvements, plus some minor bug fixes, have been\n implemented in Common Test and Test Server.\n\n Own Id: OTP-7112\n\n- It is now possible, by means of the new function ct:abort_current_testcase/1\n or test_server_ctrl:abort_current_testcase/1, to abort the currently executing\n test case.\n\n Own Id: OTP-7518 Aux Id: OTP-7112","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.3.2 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-3-2"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- The configure test of the rx lib in Common Test was not performed during the\n general OTP application configuration phase. This made e.g. autoconf\n impossible. This has been changed to correspond with the normal OTP build\n procedure.\n\n Own Id: OTP-7379","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Common_Test 1.3.1 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-3-1"},{"type":"extras","title":"Improvements and New Features - Common Test Release Notes","doc":"- The rx library, included with common_test, failed to build on some\n architectures because the -fPIC compiler option was missing.\n\n Own Id: OTP-7111","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"common_test 1.3.0 - Common Test Release Notes","doc":"","ref":"notes.html#common_test-1-3-0"},{"type":"extras","title":"Introduction","doc":"\n# Introduction","ref":"introduction.html"},{"type":"extras","title":"Scope - Introduction","doc":"`Common Test` is a portable application for automated testing. It is suitable\nfor:\n\n- Black-box testing of target systems of any type (that is, not necessarily\n implemented in Erlang). This is performed through standard O&M interfaces\n (such as SNMP, HTTP, CORBA, and Telnet) and, if necessary, through\n user-specific interfaces (often called test ports).\n- White-box testing of Erlang/OTP programs. This is easily done by calling the\n target API functions directly from the test case functions.\n\n`Common Test` also integrates use of the OTP `m:cover` tool in application Tools\nfor code coverage analysis of Erlang/OTP programs.\n\n`Common Test` executes test suite programs automatically, without operator\ninteraction. Test progress and results are printed to logs in HTML format,\neasily browsed with a standard web browser. `Common Test` also sends\nnotifications about progress and results through an OTP event manager to event\nhandlers plugged in to the system. This way, users can integrate their own\nprograms for, for example, logging, database storing, or supervision with\n`Common Test`.\n\n`Common Test` provides libraries with useful support functions to fill various\ntesting needs and requirements. There is, for example, support for flexible test\ndeclarations through test specifications. There is also support for central\nconfiguration and control of multiple independent test sessions (to different\ntarget systems) running in parallel.","ref":"introduction.html#scope"},{"type":"extras","title":"Prerequisites - Introduction","doc":"It is assumed that the reader is familiar with the Erlang programming language.","ref":"introduction.html#prerequisites"},{"type":"extras","title":"Common Test Basics","doc":"\n# Common Test Basics\n\n[](){: #basics }","ref":"basics_chapter.html"},{"type":"extras","title":"General - Common Test Basics","doc":"The `Common Test` framework is a tool that supports implementation and automated\nexecution of test cases to any types of target systems. `Common Test` is the\nmain tool being used in all testing- and verification activities that are part\nof Erlang/OTP system development and maintenance.\n\nTest cases can be executed individually or in batches. `Common Test` also\nfeatures a distributed testing mode with central control and logging. With this\nfeature, multiple systems can be tested independently in one common session.\nThis is useful, for example, when running automated large-scale regression\ntests.\n\nThe System Under Test (SUT) can consist of one or more target nodes.\n`Common Test` contains a generic test server that, together with other test\nutilities, is used to perform test case execution. The tests can be started from\na GUI, from the OS shell, or from an Erlang shell. _Test suites_ are files\n(Erlang modules) that contain the _test cases_ (Erlang functions) to be\nexecuted. _Support modules_ provide functions that the test cases use to do the\ntests.\n\nIn a black-box testing scenario, `Common Test`\\-based test programs connect to\nthe target system(s) through standard O&M and CLI protocols. `Common Test`\nprovides implementations of, and wrapper interfaces to, some of these protocols\n(most of which exist as standalone components and applications in OTP). The\nwrappers simplify configuration and add verbosity for logging purposes.\n`Common Test` is continuously extended with useful support modules. However,\nnotice that it is a straightforward task to use any Erlang/OTP component for\ntesting purposes with `Common Test`, without needing a `Common Test` wrapper for\nit. It is as simple as calling Erlang functions. A number of target-independent\ninterfaces are supported in `Common Test`, such as Generic Telnet and FTP. These\ncan be specialized or used directly for controlling instruments, traffic load\ngenerators, and so on.\n\n`Common Test` is also a very useful tool for white-box testing Erlang code (for\nexample, module testing), as the test programs can call exported Erlang\nfunctions directly. There is very little overhead required for implementing\nbasic test suites and executing simple tests. For black-box testing Erlang\nsoftware, Erlang RPC and standard O&M interfaces can be used for example.\n\nA test case can handle several connections to one or more target systems,\ninstruments, and traffic generators in parallel to perform the necessary actions\nfor a test. The handling of many connections in parallel is one of the major\nstrengths of `Common Test`, thanks to the efficient support for concurrency in\nthe Erlang runtime system, which `Common Test` users can take great advantage\nof.","ref":"basics_chapter.html#general"},{"type":"extras","title":"Test Suite Organization - Common Test Basics","doc":"Test suites are organized in test directories and each test suite can have a\nseparate data directory. Typically, these files and directories are\nversion-controlled similar to other forms of source code (possibly by a version\ncontrol system like GIT or Subversion). However, `Common Test` does not itself\nput any requirements on (or has any awareness of) possible file and directory\nversions.","ref":"basics_chapter.html#test-suite-organization"},{"type":"extras","title":"Support Libraries - Common Test Basics","doc":"Support libraries contain functions that are useful for all test suites, or for\ntest suites in a specific functional area or subsystem. In addition to the\ngeneral support libraries provided by the `Common Test` framework, and the\nvarious libraries and applications provided by Erlang/OTP, there can also be a\nneed for customized (user specific) support libraries.","ref":"basics_chapter.html#support-libraries"},{"type":"extras","title":"Suites and Test Cases - Common Test Basics","doc":"Testing is performed by running test suites (sets of test cases) or individual\ntest cases. A test suite is implemented as an Erlang module named\n` _SUITE.erl` which contains a number of test cases. A test case is\nan Erlang function that tests one or more things. The test case is the smallest\nunit that the `Common Test` test server deals with.\n\nSets of test cases, called test case groups, can also be defined. A test case\ngroup can have execution properties associated with it. Execution properties\nspecify if the test cases in the group are to be executed in random order, in\nparallel, or in sequence, and if the execution of the group is to be repeated.\nTest case groups can also be nested (that is, a group can, besides test cases,\ncontain subgroups).\n\nBesides test cases and groups, the test suite can also contain configuration\nfunctions. These functions are meant to be used for setting up (and verifying)\nenvironment and state in the SUT (and/or the `Common Test` host node), required\nfor the tests to execute correctly. Examples of operations are: Opening a\nconnection to the SUT, initializing a database, running an installation script,\nand so on. Configuration can be performed per suite, per test case group, and\nper individual test case.\n\nThe test suite module must conform to a [callback interface](`m:ct_suite`)\nspecified by the `Common Test` test server. For details, see section\n[Writing Test Suites](write_test_chapter.md#intro).\n\nA test case is considered successful if it returns to the caller, no matter what\nthe returned value is. However, a few return values have special meaning as\nfollows:\n\n- `{skip,Reason}` indicates that the test case is skipped.\n- `{comment,Comment}` prints a comment in the log for the test case.\n- `{save_config,Config}` makes the `Common Test` test server pass `Config` to\n the next test case.\n\nA test case failure is specified as a runtime error (a crash), no matter what\nthe reason for termination is. If you use Erlang pattern matching effectively,\nyou can take advantage of this property. The result is concise and readable test\ncase functions that look much more like scripts than actual programs. A simple\nexample:\n\n```erlang\nsession(_Config) ->\n {started,ServerId} = my_server:start(),\n {clients,[]} = my_server:get_clients(ServerId),\n MyId = self(),\n connected = my_server:connect(ServerId, MyId),\n {clients,[MyId]} = my_server:get_clients(ServerId),\n disconnected = my_server:disconnect(ServerId, MyId),\n {clients,[]} = my_server:get_clients(ServerId),\n stopped = my_server:stop(ServerId).\n```\n\nAs a test suite runs, all information (including output to `stdout`) is recorded\nin many different log files. A minimum of information is displayed in the user\nconsole (only start and stop information, plus a note for each failed test\ncase).\n\nThe result from each test case is recorded in a dedicated HTML log file, created\nfor the particular test run. An overview page displays each test case\nrepresented by a table row showing total execution time, if the case was\nsuccessful, failed, or skipped, plus an optional user comment. For a failed test\ncase, the reason for termination is also printed in the comment field. The\noverview page has a link to each test case log file, providing simple navigation\nwith any standard HTML browser.\n\n> #### Note {: .info }\n>\n> In the last row where totals are presented the time shown here is a sum of\n> rows, which are above (not accounting for parallel testcases).\n> On the other hand \"Elapsed Time\" is a clock time spent to run testcases.\n>\n\n[](){: #External_Interfaces }","ref":"basics_chapter.html#suites-and-test-cases"},{"type":"extras","title":"External Interfaces - Common Test Basics","doc":"The `Common Test` test server requires that the test suite defines and exports\nthe following mandatory or optional callback functions:\n\n- **`all()`** - Returns a list of all test cases and groups in the suite.\n (Mandatory)\n\n- **`suite()`** - Information function used to return properties for the suite.\n (Optional)\n\n- **`groups()`** - For declaring test case groups. (Optional)\n\n- **`init_per_suite(Config)`** - Suite level configuration function, executed\n before the first test case. (Optional)\n\n- **`end_per_suite(Config)`** - Suite level configuration function, executed\n after the last test case. (Optional)\n\n- **`group(GroupName)`** - Information function used to return properties for a\n test case group. (Optional)\n\n- **`init_per_group(GroupName, Config)`** - Configuration function for a group,\n executed before the first test case. (Optional)\n\n- **`end_per_group(GroupName, Config)`** - Configuration function for a group,\n executed after the last test case. (Optional)\n\n- **`init_per_testcase(TestCase, Config)`** - Configuration function for a\n testcase, executed before each test case. (Optional)\n\n- **`end_per_testcase(TestCase, Config)`** - Configuration function for a\n testcase, executed after each test case. (Optional)\n\nFor each test case, the `Common Test` test server expects the following\nfunctions:\n\n- **Testcasename()** - Information function that returns a list of test case\n properties. (Optional)\n\n- **Testcasename(Config)** - The test case function.","ref":"basics_chapter.html#external-interfaces"},{"type":"extras","title":"Getting Started","doc":"\n# Getting Started","ref":"getting_started_chapter.html"},{"type":"extras","title":"Introduction for Newcomers - Getting Started","doc":"The purpose of this section is to let the newcomer get started in quickly\nwriting and executing some first simple tests with a \"learning by example\"\napproach. Most explanations are left for later sections. If you are not much\ninto \"learning by example\" and prefer more technical details, go ahead and skip\nto the next section.\n\nThis section demonstrates how simple it is to write a basic (yet for many module\ntesting purposes, often sufficiently complex) test suite and execute its test\ncases. This is not necessarily obvious when you read the remaining sections in\nthis User's Guide.\n\n> #### Note {: .info }\n>\n> To understand what is discussed and examplified here, we recommended you to\n> first read section [Common Test Basics](basics_chapter.md#basics).","ref":"getting_started_chapter.html#introduction-for-newcomers"},{"type":"extras","title":"Test Case Execution - Getting Started","doc":"Execution of test cases is handled as follows:\n\n![Successful and Unsuccessful Test Case Execution](assets/tc_execution.gif \"Successful and Unsuccessful Test Case Execution\")\n\nFor each test case that `Common Test` is ordered to execute, it spawns a\ndedicated process on which the test case function starts running. (In parallel\nto the test case process, an idle waiting timer process is started, which is\nlinked to the test case process. If the timer process runs out of waiting time,\nit sends an exit signal to terminate the test case process. This is called a\n_timetrap_).\n\nIn scenario 1, the test case process terminates normally after `case A` has\nfinished executing its test code without detecting any errors. The test case\nfunction returns a value and `Common Test` logs the test case as successful.\n\nIn scenario 2, an error is detected during test `case B` execution. This causes\nthe test `case B` function to generate an exception and, as a result, the test\ncase process exits with reason other than normal. `Common Test` logs this as an\nunsuccessful (Failed) test case.\n\nAs you can understand from the illustration, `Common Test` requires a test case\nto generate a runtime error to indicate failure (for example, by causing a bad\nmatch error or by calling [`exit/1`](`exit/1`), preferably through the help\nfunction [`ct:fail/1,2`](`ct:fail/1`)). A successful execution is indicated by a\nnormal return from the test case function.","ref":"getting_started_chapter.html#test-case-execution"},{"type":"extras","title":"A Simple Test Suite - Getting Started","doc":"As shown in section [Common Test Basics](basics_chapter.md#External_Interfaces),\nthe test suite module implements [callback functions](`m:ct_suite`) (mandatory\nor optional) for various purposes, for example:\n\n- Init/end configuration function for the test suite\n- Init/end configuration function for a test case\n- Init/end configuration function for a test case group\n- Test cases\n\nThe configuration functions are optional. The following example is a test suite\nwithout configuration functions, including one simple test case, to check that\nmodule `mymod` exists (that is, can be successfully loaded by the code server):\n\n```erlang\n-module(my1st_SUITE).\n-compile(export_all).\n\nall() ->\n [mod_exists].\n\nmod_exists(_) ->\n {module,mymod} = code:load_file(mymod).\n```\n\nIf the operation fails, a bad match error occurs that terminates the test case.","ref":"getting_started_chapter.html#a-simple-test-suite"},{"type":"extras","title":"A Test Suite with Configuration Functions - Getting Started","doc":"If you need to perform configuration operations to run your test, you can\nimplement configuration functions in your suite. The result from a configuration\nfunction is configuration data, or `Config`. This is a list of key-value tuples\nthat get passed from the configuration function to the test cases (possibly\nthrough configuration functions on \"lower level\"). The data flow looks as\nfollows:\n\n![Configuration Data Flow in a Suite](assets/config.gif \"Configuration Data Flow in a Suite\")\n\nThe following example shows a test suite that uses configuration functions to\nopen and close a log file for the test cases (an operation that is unnecessary\nand irrelevant to perform by each test case):\n\n```erlang\n-module(check_log_SUITE).\n-export([all/0, init_per_suite/1, end_per_suite/1]).\n-export([check_restart_result/1, check_no_errors/1]).\n\n-define(value(Key,Config), proplists:get_value(Key,Config)).\n\nall() -> [check_restart_result, check_no_errors].\n\ninit_per_suite(InitConfigData) ->\n [{logref,open_log()} | InitConfigData].\n\nend_per_suite(ConfigData) ->\n close_log(?value(logref, ConfigData)).\n\ncheck_restart_result(ConfigData) ->\n TestData = read_log(restart, ?value(logref, ConfigData)),\n {match,_Line} = search_for(\"restart successful\", TestData).\n\ncheck_no_errors(ConfigData) ->\n TestData = read_log(all, ?value(logref, ConfigData)),\n case search_for(\"error\", TestData) of\n {match,Line} -> ct:fail({error_found_in_log,Line});\n nomatch -> ok\n end.\n```\n\nThe test cases verify, by parsing a log file, that our SUT has performed a\nsuccessful restart and that no unexpected errors are printed.\n\nTo execute the test cases in the recent test suite, type the following on the\nUNIX/Linux command line (assuming that the suite module is in the current\nworking directory):\n\n```text\n$ ct_run -dir .\n```\n\nor:\n\n```text\n$ ct_run -suite check_log_SUITE\n```\n\nTo use the Erlang shell to run our test, you can evaluate the following call:\n\n```erlang\n1> ct:run_test([{dir, \".\"}]).\n```\n\nor:\n\n```erlang\n1> ct:run_test([{suite, \"check_log_SUITE\"}]).\n```\n\nThe result from running the test is printed in log files in HTML format (stored\nin unique log directories on a different level). The following illustration\nshows the log file structure:\n\n![HTML Log File Structure](assets/html_logs.gif \"HTML Log File Structure\")","ref":"getting_started_chapter.html#a-test-suite-with-configuration-functions"},{"type":"extras","title":"Questions and Answers - Getting Started","doc":"Here follows some questions that you might have after reading this section with\ncorresponding tips and links to the answers:\n\n- _Question:_ \"How and where can I specify variable data for my tests that must\n not be hard-coded in the test suites (such as hostnames, addresses, and user\n login data)?\"\n\n _Answer:_ See section\n [External Configuration Data](config_file_chapter.md#top).\n\n- _Question:_ \"Is there a way to declare different tests and run them in one\n session without having to write my own scripts? Also, can such declarations be\n used for regression testing?\"\n\n _Answer:_ See section\n [Test Specifications](run_test_chapter.md#test_specifications) in section\n Running Tests and Analyzing Results.\n\n- _Question:_ \"Can test cases and/or test runs be automatically repeated?\"\n\n _Answer:_ Learn more about\n [Test Case Groups](write_test_chapter.md#test_case_groups) and read about\n start flags/options in section [Running Tests](run_test_chapter.md#ct_run) and\n in the Reference Manual.\n\n- _Question:_ \"Does `Common Test` execute my test cases in sequence or in\n parallel?\"\n\n _Answer:_ See [Test Case Groups](write_test_chapter.md#test_case_groups) in\n section Writing Test Suites.\n\n- _Question:_ \"What is the syntax for timetraps (mentioned earlier), and how do\n I set them?\"\n\n _Answer:_ This is explained in the\n [Timetrap Time-Outs](write_test_chapter.md#timetraps) part of section Writing\n Test Suites.\n\n- _Question:_ \"What functions are available for logging and printing?\"\n\n _Answer:_ See [Logging](write_test_chapter.md#logging) in section Writing Test\n Suites.\n\n- _Question:_ \"I need data files for my tests. Where do I store them\n preferably?\"\n\n _Answer:_ See\n [Data and Private Directories](write_test_chapter.md#data_priv_dir).\n\n- _Question:_ \"Can I start with a test suite example, please?\"\n\n _Answer:_ [Welcome\\!](example_chapter.md#top)\n\nYou probably want to get started on your own first test suites now, while at the\nsame time digging deeper into the `Common Test` User's Guide and Reference\nManual. There are much more to learn about the things that have been introduced\nin this section. There are also many other useful features to learn, so please\ncontinue to the other sections and have fun.","ref":"getting_started_chapter.html#questions-and-answers"},{"type":"extras","title":"Installation","doc":"\n# Installation\n\n[](){: #general }","ref":"install_chapter.html"},{"type":"extras","title":"General Information - Installation","doc":"The two main interfaces for running tests with `Common Test` are an executable\nprogram named [`ct_run`](ct_run_cmd.md) and the Erlang module `m:ct`. `ct_run`\nis compiled for the underlying operating system (for example, Unix/Linux or\nWindows) during the build of the Erlang/OTP system, and is installed\nautomatically with other executable programs in the top level `bin` directory of\nErlang/OTP. The `ct` interface functions can be called from the Erlang shell, or\nfrom any Erlang function, on any supported platform.\n\nThe `Common Test` application is installed with the Erlang/OTP system. No extra\ninstallation step is required to start using `Common Test` through the `ct_run`\nexecutable program, and/or the interface functions in the `ct` module.","ref":"install_chapter.html#general-information"},{"type":"extras","title":"Writing Test Suites","doc":"\n# Writing Test Suites\n\n[](){: #intro }","ref":"write_test_chapter.html"},{"type":"extras","title":"Support for Test Suite Authors - Writing Test Suites","doc":"The `m:ct` module provides the main interface for writing test cases. This\nincludes for example, the following:\n\n- Functions for printing and logging\n- Functions for reading configuration data\n- Function for terminating a test case with error reason\n- Function for adding comments to the HTML overview page\n\nFor details about these functions, see module `m:ct`.\n\nThe `Common Test` application also includes other modules named\n`ct_ `, which provide various support, mainly simplified use of\ncommunication protocols such as RPC, SNMP, FTP, Telnet, and others.","ref":"write_test_chapter.html#support-for-test-suite-authors"},{"type":"extras","title":"Test Suites - Writing Test Suites","doc":"A test suite is an ordinary Erlang module that contains test cases. It is\nrecommended that the module has a name on the form `*_SUITE.erl`. Otherwise, the\ndirectory and auto compilation function in `Common Test` cannot locate it (at\nleast not by default).\n\nIt is also recommended that the `ct.hrl` header file is included in all test\nsuite modules.\n\nEach test suite module must export function [`all/0`](`c:ct_suite:all/0`), which\nreturns the list of all test case groups and test cases to be executed in that\nmodule.\n\nThe callback functions to be implemented by the test suite are all listed in\nmodule [ct_suite ](`m:ct_suite`). They are also described in more detail later\nin this User's Guide.","ref":"write_test_chapter.html#test-suites"},{"type":"extras","title":"Init and End per Suite - Writing Test Suites","doc":"Each test suite module can contain the optional configuration functions\n[`init_per_suite/1`](`c:ct_suite:init_per_suite/1`) and\n[`end_per_suite/1`](`c:ct_suite:end_per_suite/1`). If the init function is\ndefined, so must the end function be.\n\nIf `init_per_suite` exists, it is called initially before the test cases are\nexecuted. It typically contains initializations common for all test cases in the\nsuite, which are only to be performed once. `init_per_suite` is recommended for\nsetting up and verifying state and environment on the System Under Test (SUT) or\nthe `Common Test` host node, or both, so that the test cases in the suite\nexecutes correctly. The following are examples of initial configuration\noperations:\n\n- Opening a connection to the SUT\n- Initializing a database\n- Running an installation script\n\n`end_per_suite` is called as the final stage of the test suite execution (after\nthe last test case has finished). The function is meant to be used for cleaning\nup after `init_per_suite`.\n\n`init_per_suite` and `end_per_suite` execute on dedicated Erlang processes, just\nlike the test cases do. The result of these functions is however not included in\nthe test run statistics of successful, failed, and skipped cases.\n\nThe argument to `init_per_suite` is `Config`, that is, the same key-value list\nof runtime configuration data that each test case takes as input argument.\n`init_per_suite` can modify this parameter with information that the test cases\nneed. The possibly modified `Config` list is the return value of the function.\n\nIf `init_per_suite` fails, all test cases in the test suite are skipped\nautomatically (so called _auto skipped_), including `end_per_suite`.\n\nNotice that if `init_per_suite` and `end_per_suite` do not exist in the suite,\n`Common Test` calls dummy functions (with the same names) instead, so that\noutput generated by hook functions can be saved to the log files for these\ndummies. For details, see [Common Test Hooks](ct_hooks_chapter.md#manipulating).\n\n[](){: #per_testcase }","ref":"write_test_chapter.html#init-and-end-per-suite"},{"type":"extras","title":"Init and End per Test Case - Writing Test Suites","doc":"Each test suite module can contain the optional configuration functions\n[`init_per_testcase/2`](`c:ct_suite:init_per_testcase/2`) and\n[`end_per_testcase/2`](`c:ct_suite:end_per_testcase/2`). If the init function is\ndefined, so must the end function be.\n\nIf `init_per_testcase` exists, it is called before each test case in the suite.\nIt typically contains initialization that must be done for each test case\n(analog to `init_per_suite` for the suite).\n\n`end_per_testcase/2` is called after each test case has finished, enabling\ncleanup after `init_per_testcase`.\n\n> #### Note {: .info }\n>\n> If `end_per_testcase` crashes, however, test results are unaffected. At the\n> same time, this occurrence is reported in the test execution logs.\n\nThe first argument to these functions is the name of the test case. This value\ncan be used with pattern matching in function clauses or conditional expressions\nto choose different initialization and cleanup routines for different test\ncases, or perform the same routine for many, or all, test cases.\n\nThe second argument is the `Config` key-value list of runtime configuration\ndata, which has the same value as the list returned by `init_per_suite`.\n`init_per_testcase/2` can modify this parameter or return it \"as is\". The return\nvalue of `init_per_testcase/2` is passed as parameter `Config` to the test case\nitself.\n\nThe return value of `end_per_testcase/2` is ignored by the test server, with\nexception of the [`save_config`](dependencies_chapter.md#save_config) and `fail`\ntuple.\n\n`end_per_testcase` can check if the test case was successful. (which in turn can\ndetermine how cleanup is to be performed). This is done by reading the value\ntagged with `tc_status` from `Config`. The value is one of the following:\n\n- `ok`\n- `{failed,Reason}`\n\n where `Reason` is `timetrap_timeout`, information from [`exit/1`](`exit/1`),\n or details of a runtime error\n\n- `{skipped,Reason}`\n\n where `Reason` is a user-specific term\n\nFunction `end_per_testcase/2` is even called if a test case terminates because\nof a call to `ct:abort_current_testcase/1`, or after a timetrap time-out.\nHowever, `end_per_testcase` then executes on a different process than the test\ncase function. In this situation, `end_per_testcase` cannot change the reason\nfor test case termination by returning `{fail,Reason}` or save data with\n`{save_config,Data}`.\n\nThe test case is skipped in the following two cases:\n\n- If `init_per_testcase` crashes (called _auto skipped_).\n- If `init_per_testcase` returns a tuple `{skip,Reason}` (called _user\n skipped_).\n\nThe test case can also be marked as failed without executing it by returning a\ntuple `{fail,Reason}` from `init_per_testcase`.\n\n> #### Note {: .info }\n>\n> If `init_per_testcase` crashes, or returns `{skip,Reason}` or `{fail,Reason}`,\n> function `end_per_testcase` is not called.\n\nIf it is determined during execution of `end_per_testcase` that the status of a\nsuccessful test case is to be changed to failed, `end_per_testcase` can return\nthe tuple `{fail,Reason}` (where `Reason` describes why the test case fails).\n\nAs `init_per_testcase` and `end_per_testcase` execute on the same Erlang process\nas the test case, printouts from these configuration functions are included in\nthe test case log file.\n\n[](){: #test_cases }","ref":"write_test_chapter.html#init-and-end-per-test-case"},{"type":"extras","title":"Test Cases - Writing Test Suites","doc":"The smallest unit that the test server is concerned with is a test case. Each\ntest case can test many things, for example, make several calls to the same\ninterface function with different parameters.\n\nThe author can choose to put many or few tests into each test case. Some things\nto keep in mind follows:\n\n- Many small test cases tend to result in extra, and possibly duplicated code,\n as well as slow test execution because of large overhead for initializations\n and cleanups. Avoid duplicated code, for example, by using common help\n functions. Otherwise, the resulting suite becomes difficult to read and\n understand, and expensive to maintain.\n- Larger test cases make it harder to tell what went wrong if it fails. Also,\n large portions of test code risk being skipped when errors occur.\n- Readability and maintainability suffer when test cases become too large and\n extensive. It is not certain that the resulting log files reflect very well\n the number of tests performed.\n\nThe test case function takes one argument, `Config`, which contains\nconfiguration information such as `data_dir` and `priv_dir`. (For details about\nthese, see section\n[Data and Private Directories](write_test_chapter.md#data_priv_dir). The value\nof `Config` at the time of the call, is the same as the return value from\n`init_per_testcase`, mentioned earlier.\n\n> #### Note {: .info }\n>\n> The test case function argument `Config` is not to be confused with the\n> information that can be retrieved from the configuration files (using\n> [`ct:get_config/1/2`](`ct:get_config/1`)). The test case argument `Config` is\n> to be used for runtime configuration of the test suite and the test cases,\n> while configuration files are to contain data related to the SUT. These two\n> types of configuration data are handled differently.\n\nAs parameter `Config` is a list of key-value tuples, that is, a data type called\na property list, it can be handled by the `m:proplists` module. A value can, for\nexample, be searched for and returned with function `proplists:get_value/2`.\nAlso, or alternatively, the general `m:lists` module contains useful functions.\nNormally, the only operations performed on `Config` are insertion (adding a\ntuple to the head of the list) and lookup. To look up a value in the config,\n`proplists:get_value` can be used. For example:\n`PrivDir = proplists:get_value(priv_dir, Config)`.\n\nThe test case result can be customized in several ways. See the manual for\n[`Module:Testcase/1`](`c:ct_suite:'Testcase'/1`) in the `m:ct_suite` module for\ndetails.\n\n[](){: #info_function }","ref":"write_test_chapter.html#test-cases"},{"type":"extras","title":"Test Case Information Function - Writing Test Suites","doc":"For each test case function there can be an extra function with the same name\nbut without arguments. This is the test case information function. It is\nexpected to return a list of tagged tuples that specifies various properties\nregarding the test case.\n\nThe following tags have special meaning:\n\n- **`timetrap`** - Sets the maximum time the test case is allowed to execute. If\n this time is exceeded, the test case fails with reason `timetrap_timeout`.\n Notice that `init_per_testcase` and `end_per_testcase` are included in the\n timetrap time. For details, see section\n [Timetrap Time-Outs](write_test_chapter.md#timetraps).\n\n- **`userdata`** - Specifies any data related to the test case. This data can be\n retrieved at any time using the `ct:userdata/3` utility function.\n\n- **`silent_connections`** - For details, see section\n [Silent Connections](run_test_chapter.md#silent_connections).\n\n- **`require`** - Specifies configuration variables required by the test case.\n If the required configuration variables are not found in any of the test\n system configuration files, the test case is skipped.\n\n A required variable can also be given a default value to be used if the\n variable is not found in any configuration file. To specify a default value,\n add a tuple on the form `{default_config,ConfigVariableName,Value}` to the\n test case information list (the position in the list is irrelevant).\n\n _Examples:_\n\n ```erlang\n testcase1() ->\n [{require, ftp},\n {default_config, ftp, [{ftp, \"my_ftp_host\"},\n {username, \"aladdin\"},\n {password, \"sesame\"}]}}].\n ```\n\n ```erlang\n testcase2() ->\n [{require, unix_telnet, unix},\n {require, {unix, [telnet, username, password]}},\n {default_config, unix, [{telnet, \"my_telnet_host\"},\n {username, \"aladdin\"},\n {password, \"sesame\"}]}}].\n ```\n\nFor more information about `require`, see section\n[Requiring and Reading Configuration Data](config_file_chapter.md#require_config_data)\nin section External Configuration Data and function\n[`ct:require/1/2`](`ct:require/1`).\n\n> #### Note {: .info }\n>\n> Specifying a default value for a required variable can result in a test case\n> always getting executed. This might not be a desired behavior.\n\nIf `timetrap` or `require`, or both, is not set specifically for a particular\ntest case, default values specified by function\n[`suite/0`](`c:ct_suite:suite/0`) are used.\n\nTags other than the earlier mentioned are ignored by the test server.\n\nAn example of a test case information function follows:\n\n```erlang\nreboot_node() ->\n [\n {timetrap,{seconds,60}},\n {require,interfaces},\n {userdata,\n [{description,\"System Upgrade: RpuAddition Normal RebootNode\"},\n {fts,\"http://someserver.ericsson.se/test_doc4711.pdf\"}]}\n ].\n```\n\n[](){: #suite }","ref":"write_test_chapter.html#test-case-information-function"},{"type":"extras","title":"Test Suite Information Function - Writing Test Suites","doc":"Function [`suite/0`](`c:ct_suite:suite/0`) can, for example, be used in a test\nsuite module to set a default `timetrap` value and to `require` external\nconfiguration data. If a test case, or a group information function also\nspecifies any of the information tags, it overrides the default values set by\n`suite/0`. For details, see\n[Test Case Information Function](write_test_chapter.md#info_function) and\n[Test Case Groups](write_test_chapter.md#test_case_groups).\n\nThe following options can also be specified with the suite information list:\n\n- `stylesheet`, see [HTML Style Sheets](run_test_chapter.md#html_stylesheet)\n- `userdata`, see\n [Test Case Information Function](write_test_chapter.md#info_function)\n- `silent_connections`, see\n [Silent Connections](run_test_chapter.md#silent_connections)\n\nAn example of the suite information function follows:\n\n```erlang\nsuite() ->\n [\n {timetrap,{minutes,10}},\n {require,global_names},\n {userdata,[{info,\"This suite tests database transactions.\"}]},\n {silent_connections,[telnet]},\n {stylesheet,\"db_testing.css\"}\n ].\n```\n\n[](){: #test_case_groups }","ref":"write_test_chapter.html#test-suite-information-function"},{"type":"extras","title":"Test Case Groups - Writing Test Suites","doc":"A test case group is a set of test cases sharing configuration functions and\nexecution properties. Test case groups are defined by function\n[`groups/0`](`c:ct_suite:groups/0`) that should return a term having the\nfollowing syntax:\n\n```text\ngroups() -> GroupDefs\n\nTypes:\n\nGroupDefs = [GroupDef]\nGroupDef = {GroupName,Properties,GroupsAndTestCases}\nGroupName = atom()\nGroupsAndTestCases = [GroupDef | {group,GroupName} | TestCase |\n {testcase,TestCase,TCRepeatProps}]\nTestCase = atom()\nTCRepeatProps = [{repeat,N} | {repeat_until_ok,N} | {repeat_until_fail,N}]\n```\n\n`GroupName` is the name of the group and must be unique within the test suite\nmodule. Groups can be nested, by including a group definition within the\n`GroupsAndTestCases` list of another group. `Properties` is the list of\nexecution properties for the group. The possible values are as follows:\n\n```erlang\nProperties = [parallel | sequence | Shuffle | {GroupRepeatType,N}]\nShuffle = shuffle | {shuffle,Seed}\nSeed = {integer(),integer(),integer()}\nGroupRepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |\n repeat_until_any_ok | repeat_until_any_fail\nN = integer() | forever\n```\n\n_Explanations:_\n\n- **`parallel`** - `Common Test` executes all test cases in the group in\n parallel.\n\n- **`sequence`** - The cases are executed in a sequence as described in section\n [Sequences](dependencies_chapter.md#sequences) in section Dependencies Between\n Test Cases and Suites.\n\n- **`shuffle`** - The cases in the group are executed in random order.\n\n- **`repeat, repeat_until_*`** - Orders `Common Test` to repeat execution of all\n the cases in the group a given number of times, or until any, or all, cases\n fail or succeed.\n\n_Example:_\n\n```erlang\ngroups() -> [{group1, [parallel], [test1a,test1b]},\n {group2, [shuffle,sequence], [test2a,test2b,test2c]}].\n```\n\nTo specify in which order groups are to be executed (also with respect to test\ncases that are not part of any group), add tuples on the form\n`{group,GroupName}` to the `all/0` list.\n\n_Example:_\n\n```erlang\nall() -> [testcase1, {group,group1}, {testcase,testcase2,[{repeat,10}]}, {group,group2}].\n```\n\nExecution properties with a group tuple in `all/0`:\n`{group,GroupName,Properties}` can also be specified. These properties override\nthose specified in the group definition (see `groups/0` earlier). This way, the\nsame set of tests can be run, but with different properties, without having to\nmake copies of the group definition in question.\n\nIf a group contains subgroups, the execution properties for these can also be\nspecified in the group tuple: `{group,GroupName,Properties,SubGroups}` Where,\n`SubGroups` is a list of tuples, `{GroupName,Properties}` or\n`{GroupName,Properties,SubGroups}` representing the subgroups. Any subgroups\ndefined in `groups/0` for a group, that are not specified in the `SubGroups`\nlist, executes with their predefined properties.\n\n_Example:_\n\n```erlang\ngroups() -> [{tests1, [], [{tests2, [], [t2a,t2b]},\n {tests3, [], [t31,t3b]}]}].\n```\n\nTo execute group `tests1` twice with different properties for `tests2` each\ntime:\n\n```erlang\nall() ->\n [{group, tests1, default, [{tests2, [parallel]}]},\n {group, tests1, default, [{tests2, [shuffle,{repeat,10}]}]}].\n```\n\nThis is equivalent to the following specification:\n\n```erlang\nall() ->\n [{group, tests1, default, [{tests2, [parallel]},\n {tests3, default}]},\n {group, tests1, default, [{tests2, [shuffle,{repeat,10}]},\n {tests3, default}]}].\n```\n\nValue `default` states that the predefined properties are to be used.\n\nThe following example shows how to override properties in a scenario with deeply\nnested groups:\n\n```erlang\ngroups() ->\n [{tests1, [], [{group, tests2}]},\n {tests2, [], [{group, tests3}]},\n {tests3, [{repeat,2}], [t3a,t3b,t3c]}].\n\nall() ->\n [{group, tests1, default,\n [{tests2, default,\n [{tests3, [parallel,{repeat,100}]}]}]}].\n```\n\nFor ease of readability, all syntax definitions can be replaced by a function\ncall whose return value should match the expected syntax case.\n\n_Example:_\n\n```erlang\nall() ->\n [{group, tests1, default, test_cases()},\n {group, tests1, default, [shuffle_test(),\n {tests3, default}]}].\ntest_cases() ->\n [{tests2, [parallel]}, {tests3, default}].\n\nshuffle_test() ->\n {tests2, [shuffle,{repeat,10}]}.\n```\n\nThe described syntax can also be used in test specifications to change group\nproperties at the time of execution, without having to edit the test suite. For\nmore information, see section\n[Test Specifications](run_test_chapter.md#test_specifications) in section\nRunning Tests and Analyzing Results.\n\nAs illustrated, properties can be combined. If, for example, `shuffle`,\n`repeat_until_any_fail`, and `sequence` are all specified, the test cases in the\ngroup are executed repeatedly, and in random order, until a test case fails.\nThen execution is immediately stopped and the remaining cases are skipped.\n\nBefore execution of a group begins, the configuration function\n[`init_per_group(GroupName, Config)`](`c:ct_suite:init_per_group/2`) is called.\nThe list of tuples returned from this function is passed to the test cases in\nthe usual manner by argument `Config`. `init_per_group/2` is meant to be used\nfor initializations common for the test cases in the group. After execution of\nthe group is finished, function\n[`end_per_group(GroupName, Config)`](`c:ct_suite:end_per_group/2`) is called.\nThis function is meant to be used for cleaning up after `init_per_group/2`. If\nthe init function is defined, so must the end function be.\n\nWhenever a group is executed, if `init_per_group` and `end_per_group` do not\nexist in the suite, `Common Test` calls dummy functions (with the same names)\ninstead. Output generated by hook functions are saved to the log files for these\ndummies. For more information, see section\n[Manipulating Tests](ct_hooks_chapter.md#manipulating) in section Common Test\nHooks.\n\n> #### Note {: .info }\n>\n> `init_per_testcase/2` and `end_per_testcase/2` are always called for each\n> individual test case, no matter if the case belongs to a group or not.\n\nThe properties for a group are always printed in the top of the HTML log for\n`init_per_group/2`. The total execution time for a group is included at the\nbottom of the log for `end_per_group/2`.\n\nTest case groups can be nested so sets of groups can be configured with the same\n`init_per_group/2` and `end_per_group/2` functions. Nested groups can be defined\nby including a group definition, or a group name reference, in the test case\nlist of another group.\n\n_Example:_\n\n```erlang\ngroups() -> [{group1, [shuffle], [test1a,\n {group2, [], [test2a,test2b]},\n test1b]},\n {group3, [], [{group,group4},\n {group,group5}]},\n {group4, [parallel], [test4a,test4b]},\n {group5, [sequence], [test5a,test5b,test5c]}].\n```\n\nIn the previous example, if `all/0` returns group name references in the order\n`[{group,group1},{group,group3}]`, the order of the configuration functions and\ntest cases becomes the following (notice that `init_per_testcase/2` and\n`end_per_testcase/2:` are also always called, but not included in this example\nfor simplification):\n\n```text\ninit_per_group(group1, Config) -> Config1 (*)\n test1a(Config1)\n init_per_group(group2, Config1) -> Config2\n test2a(Config2), test2b(Config2)\n end_per_group(group2, Config2)\n test1b(Config1)\nend_per_group(group1, Config1)\ninit_per_group(group3, Config) -> Config3\n init_per_group(group4, Config3) -> Config4\n test4a(Config4), test4b(Config4) (**)\n end_per_group(group4, Config4)\n init_per_group(group5, Config3) -> Config5\n test5a(Config5), test5b(Config5), test5c(Config5)\n end_per_group(group5, Config5)\nend_per_group(group3, Config3)\n```\n\n(\\*) The order of test case `test1a`, `test1b`, and `group2` is undefined, as\n`group1` has a shuffle property.\n\n(\\*\\*) These cases are not executed in order, but in parallel.\n\nProperties are not inherited from top-level groups to nested subgroups. For\ninstance, in the previous example, the test cases in `group2` are not executed\nin random order (which is the property of `group1`).","ref":"write_test_chapter.html#test-case-groups"},{"type":"extras","title":"Parallel Property and Nested Groups - Writing Test Suites","doc":"If a group has a parallel property, its test cases are spawned simultaneously\nand get executed in parallel. However, a test case is not allowed to execute in\nparallel with `end_per_group/2`, which means that the time to execute a parallel\ngroup is equal to the execution time of the slowest test case in the group. A\nnegative side effect of running test cases in parallel is that the HTML summary\npages are not updated with links to the individual test case logs until function\n`end_per_group/2` for the group has finished.\n\nA group nested under a parallel group starts executing in parallel with previous\n(parallel) test cases (no matter what properties the nested group has). However,\nas test cases are never executed in parallel with `init_per_group/2` or\n`end_per_group/2` of the same group, it is only after a nested group has\nfinished that remaining parallel cases in the previous group become spawned.","ref":"write_test_chapter.html#parallel-property-and-nested-groups"},{"type":"extras","title":"Parallel Test Cases and I/O - Writing Test Suites","doc":"A parallel test case has a private I/O server as its group leader. (For a\ndescription of the group leader concept, see [ERTS](`e:erts:index.html`)). The\ncentral I/O server process, which handles the output from regular test cases and\nconfiguration functions, does not respond to I/O messages during execution of\nparallel groups. This is important to understand to avoid certain traps, like\nthe following:\n\nIf a process, `P`, is spawned during execution of, for example,\n`init_per_suite/1`, it inherits the group leader of the `init_per_suite`\nprocess. This group leader is the central I/O server process mentioned earlier.\nIf, at a later time, _during parallel test case execution_, some event triggers\nprocess `P` to call [`io:format/1/2`](`io:format/1`), that call never returns\n(as the group leader is in a non-responsive state) and causes `P` to hang.","ref":"write_test_chapter.html#parallel-test-cases-and-i-o"},{"type":"extras","title":"Repeated Groups - Writing Test Suites","doc":"[](){: #repeated_groups }\n\nA test case group can be repeated a certain number of times (specified by an\ninteger) or indefinitely (specified by `forever`). The repetition can also be\nstopped too early if any or all cases fail or succeed, that is, if any of the\nproperties `repeat_until_any_fail`, `repeat_until_any_ok`,\n`repeat_until_all_fail`, or `repeat_until_all_ok` is used. If the basic `repeat`\nproperty is used, status of test cases is irrelevant for the repeat operation.\n\nThe status of a subgroup can be returned (`ok` or `failed`), to affect the\nexecution of the group on the level above. This is accomplished by, in\n`end_per_group/2`, looking up the value of `tc_group_properties` in the `Config`\nlist and checking the result of the test cases in the group. If status `failed`\nis to be returned from the group as a result, `end_per_group/2` is to return the\nvalue `{return_group_result,failed}`. The status of a subgroup is taken into\naccount by `Common Test` when evaluating if execution of a group is to be\nrepeated or not (unless the basic `repeat` property is used).\n\nThe value of `tc_group_properties` is a list of status tuples, each with the key\n`ok`, `skipped`, and `failed`. The value of a status tuple is a list with names\nof test cases that have been executed with the corresponding status as result.\n\nThe following is an example of how to return the status from a group:\n\n```erlang\nend_per_group(_Group, Config) ->\n Status = proplists:get_value(tc_group_result, Config),\n case proplists:get_value(failed, Status) of\n [] -> % no failed cases\n {return_group_result,ok};\n _Failed -> % one or more failed\n {return_group_result,failed}\n end.\n```\n\nIt is also possible, in `end_per_group/2`, to check the status of a subgroup\n(maybe to determine what status the current group is to return). This is as\nsimple as illustrated in the previous example, only the group name is stored in\na tuple `{group_result,GroupName}`, which can be searched for in the status\nlists.\n\n_Example:_\n\n```erlang\nend_per_group(group1, Config) ->\n Status = proplists:get_value(tc_group_result, Config),\n Failed = proplists:get_value(failed, Status),\n case lists:member({group_result,group2}, Failed) of\n true ->\n {return_group_result,failed};\n false ->\n {return_group_result,ok}\n end;\n...\n```\n\n> #### Note {: .info }\n>\n> When a test case group is repeated, the configuration functions\n> `init_per_group/2` and `end_per_group/2` are also always called with each\n> repetition.","ref":"write_test_chapter.html#repeated-groups"},{"type":"extras","title":"Shuffled Test Case Order - Writing Test Suites","doc":"The order in which test cases in a group are executed is under normal\ncircumstances the same as the order specified in the test case list in the group\ndefinition. With property `shuffle` set, however, `Common Test` instead executes\nthe test cases in random order.\n\nYou can provide a seed value (a tuple of three integers) with the shuffle\nproperty `{shuffle,Seed}`. This way, the same shuffling order can be created\nevery time the group is executed. If no seed value is specified, `Common Test`\ncreates a \"random\" seed for the shuffling operation (using the return value of\n`erlang:timestamp/0`). The seed value is always printed to the\n`init_per_group/2` log file so that it can be used to recreate the same\nexecution order in a subsequent test run.\n\n> #### Note {: .info }\n>\n> If a shuffled test case group is repeated, the seed is not reset between\n> turns.\n\nIf a subgroup is specified in a group with a `shuffle` property, the execution\norder of this subgroup in relation to the test cases (and other subgroups) in\nthe group, is random. The order of the test cases in the subgroup is however not\nrandom (unless the subgroup has a `shuffle` property).\n\n[](){: #group_info }","ref":"write_test_chapter.html#shuffled-test-case-order"},{"type":"extras","title":"Group Information Function - Writing Test Suites","doc":"The test case group information function, `group(GroupName)`, serves the same\npurpose as the suite- and test case information functions previously described.\nHowever, the scope for the group information function, is all test cases and\nsubgroups in the group in question (`GroupName`).\n\n_Example:_\n\n```erlang\ngroup(connection_tests) ->\n [{require,login_data},\n {timetrap,1000}].\n```\n\nThe group information properties override those set with the suite information\nfunction, and can in turn be overridden by test case information properties. For\na list of valid information properties and more general information, see the\n[Test Case Information Function](write_test_chapter.md#info_function).","ref":"write_test_chapter.html#group-information-function"},{"type":"extras","title":"Information Functions for Init- and End-Configuration - Writing Test Suites","doc":"Information functions can also be used for functions `init_per_suite`,\n`end_per_suite`, `init_per_group`, and `end_per_group`, and they work the same\nway as with the\n[Test Case Information Function](write_test_chapter.md#info_function). This is\nuseful, for example, for setting timetraps and requiring external configuration\ndata relevant only for the configuration function in question (without affecting\nproperties set for groups and test cases in the suite).\n\nThe information function `init/end_per_suite()` is called for\n`init/end_per_suite(Config)`, and information function\n`init/end_per_group(GroupName)` is called for\n`init/end_per_group(GroupName,Config)`. However, information functions cannot be\nused with `init/end_per_testcase(TestCase, Config)`, as these configuration\nfunctions execute on the test case process and use the same properties as the\ntest case (that is, the properties set by the test case information function,\n`TestCase()`). For a list of valid information properties and more general\ninformation, see the\n[Test Case Information Function](write_test_chapter.md#info_function).\n\n[](){: #data_priv_dir }","ref":"write_test_chapter.html#information-functions-for-init-and-end-configuration"},{"type":"extras","title":"Data and Private Directories - Writing Test Suites","doc":"In the data directory, `data_dir`, the test module has its own files needed for\nthe testing. The name of `data_dir` is the name of the test suite followed by\n`\"_data\"`. For example, `\"some_path/foo_SUITE.beam\"` has the data directory\n`\"some_path/foo_SUITE_data/\"`. Use this directory for portability, that is, to\navoid hardcoding directory names in your suite. As the data directory is stored\nin the same directory as your test suite, you can rely on its existence at\nruntime, even if the path to your test suite directory has changed between test\nsuite implementation and execution.\n\n`priv_dir` is the private directory for the test cases. This directory can be\nused whenever a test case (or configuration function) needs to write something\nto file. The name of the private directory is generated by `Common Test`, which\nalso creates the directory.\n\nBy default, `Common Test` creates one central private directory per test run,\nshared by all test cases. This is not always suitable. Especially if the same\ntest cases are executed multiple times during a test run (that is, if they\nbelong to a test case group with property `repeat`) and there is a risk that\nfiles in the private directory get overwritten. Under these circumstances,\n`Common Test` can be configured to create one dedicated private directory per\ntest case and execution instead. This is accomplished with the flag/option\n`create_priv_dir` (to be used with the [`ct_run`](ct_run_cmd.md) program, the\n`ct:run_test/1` function, or as test specification term). There are three\npossible values for this option as follows:\n\n- `auto_per_run`\n- `auto_per_tc`\n- `manual_per_tc`\n\nThe first value indicates the default `priv_dir` behavior, that is, one private\ndirectory created per test run. The two latter values tell `Common Test` to\ngenerate a unique test directory name per test case and execution. If the auto\nversion is used, _all_ private directories are created automatically. This can\nbecome very inefficient for test runs with many test cases or repetitions, or\nboth. Therefore, if the manual version is used instead, the test case must tell\n`Common Test` to create `priv_dir` when it needs it. It does this by calling the\nfunction `ct:make_priv_dir/0`.\n\n> #### Note {: .info }\n>\n> Do not depend on the current working directory for reading and writing data\n> files, as this is not portable. All scratch files are to be written in the\n> `priv_dir` and all data files are to be located in `data_dir`. Also, the\n> `Common Test` server sets the current working directory to the test case log\n> directory at the start of every case.","ref":"write_test_chapter.html#data-and-private-directories"},{"type":"extras","title":"Execution Environment - Writing Test Suites","doc":"Each test case is executed by a dedicated Erlang process. The process is spawned\nwhen the test case starts, and terminated when the test case is finished. The\nconfiguration functions `init_per_testcase` and `end_per_testcase` execute on\nthe same process as the test case.\n\nThe configuration functions `init_per_suite` and `end_per_suite` execute, like\ntest cases, on dedicated Erlang processes.\n\n[](){: #timetraps }","ref":"write_test_chapter.html#execution-environment"},{"type":"extras","title":"Timetrap Time-Outs - Writing Test Suites","doc":"The default time limit for a test case is 30 minutes, unless a `timetrap` is\nspecified either by the suite-, group-, or test case information function. The\ntimetrap time-out value defined by `suite/0` is the value that is used for each\ntest case in the suite (and for the configuration functions `init_per_suite/1`,\n`end_per_suite/1`, `init_per_group/2`, and `end_per_group/2`). A timetrap value\ndefined by `group(GroupName)` overrides one defined by `suite()` and is used for\neach test case in group `GroupName`, and any of its subgroups. If a timetrap\nvalue is defined by `group/1` for a subgroup, it overrides that of its higher\nlevel groups. Timetrap values set by individual test cases (by the test case\ninformation function) override both group- and suite- level timetraps.\n\nA timetrap can also be set or reset dynamically during the execution of a test\ncase, or configuration function. This is done by calling `ct:timetrap/1`. This\nfunction cancels the current timetrap and starts a new one (that stays active\nuntil time-out, or end of the current function).\n\nTimetrap values can be extended with a multiplier value specified at startup\nwith option `multiply_timetraps`. It is also possible to let the test server\ndecide to scale up timetrap time-out values automatically. That is, if tools\nsuch as `cover` or `trace` are running during the test. This feature is disabled\nby default and can be enabled with start option `scale_timetraps`.\n\nIf a test case needs to suspend itself for a time that also gets multiplied by\n`multiply_timetraps` (and possibly also scaled up if `scale_timetraps` is\nenabled), the function `ct:sleep/1` can be used (instead of, for example,\n`timer:sleep/1`).\n\nA function (`fun/0` or `{Mod,Func,Args}` (MFA) tuple) can be specified as\ntimetrap value in the suite-, group- and test case information function, and as\nargument to function `ct:timetrap/1`.\n\n_Examples:_\n\n`{timetrap,{my_test_utils,timetrap,[?MODULE,system_start]}}`\n\n`ct:timetrap(fun() -> my_timetrap(TestCaseName, Config) end)`\n\nThe user timetrap function can be used for two things as follows:\n\n- To act as a timetrap. The time-out is triggered when the function returns.\n- To return a timetrap time value (other than a function).\n\nBefore execution of the timetrap function (which is performed on a parallel,\ndedicated timetrap process), `Common Test` cancels any previously set timer for\nthe test case or configuration function. When the timetrap function returns, the\ntime-out is triggered, _unless_ the return value is a valid timetrap time, such\nas an integer, or a `{SecMinOrHourTag,Time}` tuple (for details, see module\n`m:ct_suite`). If a time value is returned, a new timetrap is started to\ngenerate a time-out after the specified time.\n\nThe user timetrap function can return a time value after a delay. The effective\ntimetrap time is then the delay time _plus_ the returned time.\n\n[](){: #logging }","ref":"write_test_chapter.html#timetrap-time-outs"},{"type":"extras","title":"Logging - Categories and Verbosity Levels - Writing Test Suites","doc":"`Common Test` provides the following three main functions for printing strings:\n\n- `ct:log(Category, Importance, Format, FormatArgs, Opts)`\n- `ct:print(Category, Importance, Format, FormatArgs)`\n- `ct:pal(Category, Importance, Format, FormatArgs)`\n\nThe [`log/1,2,3,4,5`](`ct:log/1`) function prints a string to the test case log\nfile. The [`print/1,2,3,4`](`ct:print/1`) function prints the string to screen.\nThe [`pal/1,2,3,4`](`ct:pal/1`) function prints the same string both to file and\nscreen. The functions are described in module `m:ct`.\n\nThe optional `Category` argument can be used to categorize the log printout.\nCategories can be used for two things as follows:\n\n- To compare the importance of the printout to a specific verbosity level.\n- To format the printout according to a user-specific HTML Style Sheet (CSS).\n\nArgument `Importance` specifies a level of importance that, compared to a\nverbosity level (general and/or set per category), determines if the printout is\nto be visible. `Importance` is any integer in the range 0..99. Predefined\nconstants exist in the `ct.hrl` header file. The default importance level,\n`?STD_IMPORTANCE` (used if argument `Importance` is not provided), is 50. This\nis also the importance used for standard I/O, for example, from printouts made\nwith `io:format/2`, `io:put_chars/1`, and so on.\n\n`Importance` is compared to a verbosity level set by the `verbosity` start\nflag/option. The level can be set per category or generally, or both. If\n`verbosity` is not set by the user, a level of 100 (`?MAX_VERBOSITY` = all\nprintouts visible) is used as default value. `Common Test` performs the\nfollowing test:\n\n```text\nImportance >= (100-VerbosityLevel)\n```\n\nThe constant `?STD_VERBOSITY` has value 50 (see `ct.hrl`). At this level, all\nstandard I/O gets printed. If a lower verbosity level is set, standard I/O\nprintouts are ignored. Verbosity level 0 effectively turns all logging off\n(except from printouts made by `Common Test` itself).\n\nThe general verbosity level is not associated with any particular category. This\nlevel sets the threshold for the standard I/O printouts, uncategorized\n`ct:log/print/pal` printouts, and printouts for categories with undefined\nverbosity level.\n\n_Examples:_\n\nSome printouts during test case execution:\n\n```erlang\nio:format(\"1. Standard IO, importance = ~w~n\", [?STD_IMPORTANCE]),\nct:log(\"2. Uncategorized, importance = ~w\", [?STD_IMPORTANCE]),\n ct:log(info, \"3. Categorized info, importance = ~w\", [?STD_IMPORTANCE]),\n ct:log(info, ?LOW_IMPORTANCE, \"4. Categorized info, importance = ~w\", [?LOW_IMPORTANCE]),\n ct:log(error, ?HI_IMPORTANCE, \"5. Categorized error, importance = ~w\", [?HI_IMPORTANCE]),\n ct:log(error, ?MAX_IMPORTANCE, \"6. Categorized error, importance = ~w\", [?MAX_IMPORTANCE]),\n```\n\nIf starting the test with a general verbosity level of 50 (`?STD_VERBOSITY`):\n\n```text\n$ ct_run -verbosity 50\n```\n\nthe following is printed:\n\n```text\n1. Standard IO, importance = 50\n2. Uncategorized, importance = 50\n3. Categorized info, importance = 50\n5. Categorized error, importance = 75\n6. Categorized error, importance = 99\n```\n\nIf starting the test with:\n\n```text\n$ ct_run -verbosity 1 and info 75\n```\n\nthe following is printed:\n\n```erlang\n3. Categorized info, importance = 50\n4. Categorized info, importance = 25\n6. Categorized error, importance = 99\n```\n\nNote that the category argument is not required in order to only specify the\nimportance of a printout. Example:\n\n```erlang\nct:pal(?LOW_IMPORTANCE, \"Info report: ~p\", [Info])\n```\n\nOr perhaps in combination with constants:\n\n```erlang\n-define(INFO, ?LOW_IMPORTANCE).\n-define(ERROR, ?HI_IMPORTANCE).\n\nct:log(?INFO, \"Info report: ~p\", [Info])\nct:pal(?ERROR, \"Error report: ~p\", [Error])\n```\n\nThe functions `ct:set_verbosity/2` and `ct:get_verbosity/1` may be used to\nmodify and read verbosity levels during test execution.\n\nThe arguments `Format` and `FormatArgs` in `ct:log/print/pal` are always passed\non to the STDLIB function `io:format/3` (For details, see the `m:io` manual\npage).\n\n`ct:pal/4` and `ct:log/5` add headers to strings being printed to the log file.\nThe strings are also wrapped in div tags with a CSS class attribute, so that\nstylesheet formatting can be applied. To disable this feature for a printout\n(i.e. to get a result similar to using `io:format/2`), call `ct:log/5` with the\n`no_css` option.\n\nHow categories can be mapped to CSS tags is documented in section\n[HTML Style Sheets](run_test_chapter.md#html_stylesheet) in section Running\nTests and Analyzing Results.\n\nCommon Test will escape special HTML characters (<, > and &) in printouts to the\nlog file made with `ct:pal/4` and `io:format/2`. In order to print strings with\nHTML tags to the log, use the `ct:log/3,4,5` function. The character escaping\nfeature is per default disabled for `ct:log/3,4,5` but can be enabled with the\n`esc_chars` option in the `Opts` list, see [`ct:log/3,4,5`](`ct:log/5`).\n\nIf the character escaping feature needs to be disabled (typically for backwards\ncompatibility reasons), use the `ct_run` start flag `-no_esc_chars`, or the\n`ct:run_test/1` start option `{esc_chars,Bool}` (this start option is also\nsupported in test specifications).\n\nFor more information about log files, see section\n[Log Files](run_test_chapter.md#log_files) in section Running Tests and\nAnalyzing Results.","ref":"write_test_chapter.html#logging-categories-and-verbosity-levels"},{"type":"extras","title":"Illegal Dependencies - Writing Test Suites","doc":"Even though it is highly efficient to write test suites with the `Common Test`\nframework, mistakes can be made, mainly because of illegal dependencies. Some of\nthe more frequent mistakes from our own experience with running the Erlang/OTP\ntest suites follows:\n\n- Depending on current directory, and writing there:\n\n This is a common error in test suites. It is assumed that the current\n directory is the same as the author used as current directory when the test\n case was developed. Many test cases even try to write scratch files to this\n directory. Instead `data_dir` and `priv_dir` are to be used to locate data and\n for writing scratch files.\n\n- Depending on execution order:\n\n During development of test suites, make no assumptions on the execution order\n of the test cases or suites. For example, a test case must not assume that a\n server it depends on is already started by a previous test case. Reasons for\n this follows:\n\n - The user/operator can specify the order at will, and maybe a different\n execution order is sometimes more relevant or efficient.\n - If the user specifies a whole directory of test suites for the test, the\n execution order of the suites depends on how the files are listed by the\n operating system, which varies between systems.\n - If a user wants to run only a subset of a test suite, there is no way one\n test case could successfully depend on another.\n\n- Depending on Unix:\n\n Running Unix commands through `os:cmd` are likely not to work on non-Unix\n platforms.\n\n- Nested test cases:\n\n Starting a test case from another not only tests the same thing twice, but\n also makes it harder to follow what is being tested. Also, if the called test\n case fails for some reason, so do the caller. This way, one error gives cause\n to several error reports, which is to be avoided.\n\n Functionality common for many test case functions can be implemented in common\n help functions. If these functions are useful for test cases across suites,\n put the help functions into common help modules.\n\n- Failure to crash or exit when things go wrong:\n\n Making requests without checking that the return value indicates success can\n be OK if the test case fails later, but it is never acceptable just to print\n an error message (into the log file) and return successfully. Such test cases\n do harm, as they create a false sense of security when overviewing the test\n results.\n\n- Messing up for subsequent test cases:\n\n Test cases are to restore as much of the execution environment as possible, so\n that subsequent test cases do not crash because of their execution order. The\n function [`end_per_testcase`](`c:ct_suite:end_per_testcase/2`) is suitable for\n this.","ref":"write_test_chapter.html#illegal-dependencies"},{"type":"extras","title":"Test Structure","doc":"\n# Test Structure","ref":"test_structure_chapter.html"},{"type":"extras","title":"General - Test Structure","doc":"A test is performed by running one or more test suites. A test suite consists of\ntest cases, configuration functions, and information functions. Test cases can\nbe grouped in so called test case groups. A test suite is an Erlang module and\ntest cases are implemented as Erlang functions. Test suites are stored in test\ndirectories.\n\n[](){: #skipping_test_cases }","ref":"test_structure_chapter.html#general"},{"type":"extras","title":"Skipping Test Cases - Test Structure","doc":"Certain test cases can be skipped, for example, if you know beforehand that a\nspecific test case fails. The reason can be functionality that is not yet\nimplemented, a bug that is known but not yet fixed, or some functionality that\ndoes not work or is not applicable on a specific platform.\n\nTest cases can be skipped in the following ways:\n\n- Using `skip_suites` and `skip_cases` terms in\n [test specifications](run_test_chapter.md#test_specifications).\n- Returning `{skip,Reason}` from function\n [`init_per_testcase/2`](`c:ct_suite:init_per_testcase/2`) or\n [`init_per_suite/1`](`c:ct_suite:init_per_suite/1`).\n- Returning `{skip,Reason}` from the execution clause of the test case. The\n execution clause is called, so the author must ensure that the test case does\n not run.\n\nWhen a test case is skipped, it is noted as `SKIPPED` in the HTML log.","ref":"test_structure_chapter.html#skipping-test-cases"},{"type":"extras","title":"Definition of Terms - Test Structure","doc":"- **_Auto-skipped test case_** - When a configuration function fails (that is,\n terminates unexpectedly), the test cases depending on the configuration\n function are skipped automatically by `Common Test`. The status of the test\n cases is then \"auto-skipped\". Test cases are also \"auto-skipped\" by\n `Common Test` if the required configuration data is unavailable at runtime.\n\n- **_Configuration function_** - A function in a test suite that is meant to be\n used for setting up, cleaning up, and/or verifying the state and environment\n on the System Under Test (SUT) and/or the `Common Test` host node, so that a\n test case (or a set of test cases) can execute correctly.\n\n- **_Configuration file_** - A file containing data related to a test and/or an\n SUT, for example, protocol server addresses, client login details, and\n hardware interface addresses. That is, any data that is to be handled as\n variable in the suite and not be hard-coded.\n\n- **_Configuration variable_** - A name (an Erlang atom) associated with a data\n value read from a configuration file.\n\n- **`data_dir`** - Data directory for a test suite. This directory contains any\n files used by the test suite, for example, extra Erlang modules, binaries, or\n data files.\n\n- **_Information function_** - A function in a test suite that returns a list of\n properties (read by the `Common Test` server) that describes the conditions\n for executing the test cases in the suite.\n\n- **_Major log file_** - An overview and summary log file for one or more test\n suites.\n\n- **_Minor log file_** - A log file for one particular test case. Also called\n the test case log file.\n\n- **`priv_dir`** - Private directory for a test suite. This directory is to be\n used when the test suite needs to write to files.\n\n- **`ct_run`** - The name of an executable program that can be used as an\n interface for specifying and running tests with `Common Test`.\n\n- **_Test case_** - A single test included in a test suite. A test case is\n implemented as a function in a test suite module.\n\n- **_Test case group_** - A set of test cases sharing configuration functions\n and execution properties. The execution properties specify if the test cases\n in the group are to be executed in random order, in parallel, or in sequence,\n and if the execution of the group is be repeated. Test case groups can also be\n nested. That is, a group can, besides test cases, contain subgroups.\n\n- **_Test suite_** - An Erlang module containing a collection of test cases for\n a specific functional area.\n\n- **_Test directory_** - A directory containing one or more test suite modules,\n that is, a group of test suites.\n\n- **_Argument_ `Config`** - A list of key-value tuples (that is, a property\n list) containing runtime configuration data passed from the configuration\n functions to the test cases.\n\n- **_User-skipped test case_** - The status of a test case explicitly skipped in\n any of the ways described in section\n [Skipping Test Cases](test_structure_chapter.md#skipping_test_cases).","ref":"test_structure_chapter.html#definition-of-terms"},{"type":"extras","title":"Examples and Templates","doc":"\n# Examples and Templates\n\n[](){: #top }","ref":"example_chapter.html"},{"type":"extras","title":"Test Suite Example - Examples and Templates","doc":"The following example test suite shows some tests of a database server:\n\n```erlang\n-module(db_data_type_SUITE).\n\n-include_lib(\"common_test/include/ct.hrl\").\n\n%% Test server callbacks\n-export([suite/0, all/0,\n init_per_suite/1, end_per_suite/1,\n init_per_testcase/2, end_per_testcase/2]).\n\n%% Test cases\n-export([string/1, integer/1]).\n\n-define(CONNECT_STR, \"DSN=sqlserver;UID=alladin;PWD=sesame\").\n\n%%--------------------------------------------------------------------\n%% COMMON TEST CALLBACK FUNCTIONS\n%%--------------------------------------------------------------------\n\n%%--------------------------------------------------------------------\n%% Function: suite() -> Info\n%%\n%% Info = [tuple()]\n%% List of key/value pairs.\n%%\n%% Description: Returns list of tuples to set default properties\n%% for the suite.\n%%--------------------------------------------------------------------\nsuite() ->\n [{timetrap,{minutes,1}}].\n\n%%--------------------------------------------------------------------\n%% Function: init_per_suite(Config0) -> Config1\n%%\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%%\n%% Description: Initialization before the suite.\n%%--------------------------------------------------------------------\ninit_per_suite(Config) ->\n {ok, Ref} = db:connect(?CONNECT_STR, []),\n TableName = db_lib:unique_table_name(),\n [{con_ref, Ref },{table_name, TableName}| Config].\n\n%%--------------------------------------------------------------------\n%% Function: end_per_suite(Config) -> term()\n%%\n%% Config = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%%\n%% Description: Cleanup after the suite.\n%%--------------------------------------------------------------------\nend_per_suite(Config) ->\n Ref = proplists:get_value(con_ref, Config),\n db:disconnect(Ref),\n ok.\n\n%%--------------------------------------------------------------------\n%% Function: init_per_testcase(TestCase, Config0) -> Config1\n%%\n%% TestCase = atom()\n%% Name of the test case that is about to run.\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%%\n%% Description: Initialization before each test case.\n%%--------------------------------------------------------------------\ninit_per_testcase(Case, Config) ->\n Ref = proplists:get_value(con_ref, Config),\n TableName = proplists:get_value(table_name, Config),\n ok = db:create_table(Ref, TableName, table_type(Case)),\n Config.\n\n%%--------------------------------------------------------------------\n%% Function: end_per_testcase(TestCase, Config) -> term()\n%%\n%% TestCase = atom()\n%% Name of the test case that is finished.\n%% Config = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%%\n%% Description: Cleanup after each test case.\n%%--------------------------------------------------------------------\nend_per_testcase(_Case, Config) ->\n Ref = proplists:get_value(con_ref, Config),\n TableName = proplists:get_value(table_name, Config),\n ok = db:delete_table(Ref, TableName),\n ok.\n\n%%--------------------------------------------------------------------\n%% Function: all() -> GroupsAndTestCases\n%%\n%% GroupsAndTestCases = [{group,GroupName} | TestCase]\n%% GroupName = atom()\n%% Name of a test case group.\n%% TestCase = atom()\n%% Name of a test case.\n%%\n%% Description: Returns the list of groups and test cases that\n%% are to be executed.\n%%--------------------------------------------------------------------\nall() ->\n [string, integer].\n\n\n%%--------------------------------------------------------------------\n%% TEST CASES\n%%--------------------------------------------------------------------\n\nstring(Config) ->\n insert_and_lookup(dummy_key, \"Dummy string\", Config).\n\ninteger(Config) ->\n insert_and_lookup(dummy_key, 42, Config).\n\n\ninsert_and_lookup(Key, Value, Config) ->\n Ref = proplists:get_value(con_ref, Config),\n TableName = proplists:get_value(table_name, Config),\n ok = db:insert(Ref, TableName, Key, Value),\n [Value] = db:lookup(Ref, TableName, Key),\n ok = db:delete(Ref, TableName, Key),\n [] = db:lookup(Ref, TableName, Key),\n ok.\n```","ref":"example_chapter.html#test-suite-example"},{"type":"extras","title":"Test Suite Templates - Examples and Templates","doc":"The Erlang mode for the Emacs editor includes two `Common Test` test suite\ntemplates, one with extensive information in the function headers, and one with\nminimal information. A test suite template provides a quick start for\nimplementing a suite from scratch and gives a good overview of the available\ncallback functions. The two templates follows:\n\n_Large Common Test Suite_\n\n```erlang\n%%%-------------------------------------------------------------------\n%%% File : example_SUITE.erl\n%%% Author :\n%%% Description :\n%%%\n%%% Created :\n%%%-------------------------------------------------------------------\n-module(example_SUITE).\n\n%% Note: This directive should only be used in test suites.\n-compile(export_all).\n\n-include_lib(\"common_test/include/ct.hrl\").\n\n%%--------------------------------------------------------------------\n%% COMMON TEST CALLBACK FUNCTIONS\n%%--------------------------------------------------------------------\n\n%%--------------------------------------------------------------------\n%% Function: suite() -> Info\n%%\n%% Info = [tuple()]\n%% List of key/value pairs.\n%%\n%% Description: Returns list of tuples to set default properties\n%% for the suite.\n%%\n%% Note: The suite/0 function is only meant to be used to return\n%% default data values, not perform any other operations.\n%%--------------------------------------------------------------------\nsuite() ->\n [{timetrap,{minutes,10}}].\n\n%%--------------------------------------------------------------------\n%% Function: init_per_suite(Config0) ->\n%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}\n%%\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%% Reason = term()\n%% The reason for skipping the suite.\n%%\n%% Description: Initialization before the suite.\n%%\n%% Note: This function is free to add any key/value pairs to the Config\n%% variable, but should NOT alter/remove any existing entries.\n%%--------------------------------------------------------------------\ninit_per_suite(Config) ->\n Config.\n\n%%--------------------------------------------------------------------\n%% Function: end_per_suite(Config0) -> term() | {save_config,Config1}\n%%\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%%\n%% Description: Cleanup after the suite.\n%%--------------------------------------------------------------------\nend_per_suite(_Config) ->\n ok.\n\n%%--------------------------------------------------------------------\n%% Function: init_per_group(GroupName, Config0) ->\n%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}\n%%\n%% GroupName = atom()\n%% Name of the test case group that is about to run.\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding configuration data for the group.\n%% Reason = term()\n%% The reason for skipping all test cases and subgroups in the group.\n%%\n%% Description: Initialization before each test case group.\n%%--------------------------------------------------------------------\ninit_per_group(_GroupName, Config) ->\n Config.\n\n%%--------------------------------------------------------------------\n%% Function: end_per_group(GroupName, Config0) ->\n%% term() | {save_config,Config1}\n%%\n%% GroupName = atom()\n%% Name of the test case group that is finished.\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding configuration data for the group.\n%%\n%% Description: Cleanup after each test case group.\n%%--------------------------------------------------------------------\nend_per_group(_GroupName, _Config) ->\n ok.\n\n%%--------------------------------------------------------------------\n%% Function: init_per_testcase(TestCase, Config0) ->\n%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}\n%%\n%% TestCase = atom()\n%% Name of the test case that is about to run.\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%% Reason = term()\n%% The reason for skipping the test case.\n%%\n%% Description: Initialization before each test case.\n%%\n%% Note: This function is free to add any key/value pairs to the Config\n%% variable, but should NOT alter/remove any existing entries.\n%%--------------------------------------------------------------------\ninit_per_testcase(_TestCase, Config) ->\n Config.\n\n%%--------------------------------------------------------------------\n%% Function: end_per_testcase(TestCase, Config0) ->\n%% term() | {save_config,Config1} | {fail,Reason}\n%%\n%% TestCase = atom()\n%% Name of the test case that is finished.\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%% Reason = term()\n%% The reason for failing the test case.\n%%\n%% Description: Cleanup after each test case.\n%%--------------------------------------------------------------------\nend_per_testcase(_TestCase, _Config) ->\n ok.\n\n%%--------------------------------------------------------------------\n%% Function: groups() -> [Group]\n%%\n%% Group = {GroupName,Properties,GroupsAndTestCases}\n%% GroupName = atom()\n%% The name of the group.\n%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]\n%% Group properties that may be combined.\n%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]\n%% TestCase = atom()\n%% The name of a test case.\n%% Shuffle = shuffle | {shuffle,Seed}\n%% To get cases executed in random order.\n%% Seed = {integer(),integer(),integer()}\n%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |\n%% repeat_until_any_ok | repeat_until_any_fail\n%% To get execution of cases repeated.\n%% N = integer() | forever\n%%\n%% Description: Returns a list of test case group definitions.\n%%--------------------------------------------------------------------\ngroups() ->\n [].\n\n%%--------------------------------------------------------------------\n%% Function: all() -> GroupsAndTestCases | {skip,Reason}\n%%\n%% GroupsAndTestCases = [{group,GroupName} | TestCase]\n%% GroupName = atom()\n%% Name of a test case group.\n%% TestCase = atom()\n%% Name of a test case.\n%% Reason = term()\n%% The reason for skipping all groups and test cases.\n%%\n%% Description: Returns the list of groups and test cases that\n%% are to be executed.\n%%--------------------------------------------------------------------\nall() ->\n [my_test_case].\n\n\n%%--------------------------------------------------------------------\n%% TEST CASES\n%%--------------------------------------------------------------------\n\n%%--------------------------------------------------------------------\n%% Function: TestCase() -> Info\n%%\n%% Info = [tuple()]\n%% List of key/value pairs.\n%%\n%% Description: Test case info function - returns list of tuples to set\n%% properties for the test case.\n%%\n%% Note: This function is only meant to be used to return a list of\n%% values, not perform any other operations.\n%%--------------------------------------------------------------------\nmy_test_case() ->\n [].\n\n%%--------------------------------------------------------------------\n%% Function: TestCase(Config0) ->\n%% ok | exit() | {skip,Reason} | {comment,Comment} |\n%% {save_config,Config1} | {skip_and_save,Reason,Config1}\n%%\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%% Reason = term()\n%% The reason for skipping the test case.\n%% Comment = term()\n%% A comment about the test case that will be printed in the html log.\n%%\n%% Description: Test case function. (The name of it must be specified in\n%% the all/0 list or in a test case group for the test case\n%% to be executed).\n%%--------------------------------------------------------------------\nmy_test_case(_Config) ->\n ok.\n```\n\n_Small Common Test Suite_\n\n```erlang\n%%%-------------------------------------------------------------------\n%%% File : example_SUITE.erl\n%%% Author :\n%%% Description :\n%%%\n%%% Created :\n%%%-------------------------------------------------------------------\n-module(example_SUITE).\n\n-compile(export_all).\n\n-include_lib(\"common_test/include/ct.hrl\").\n\n%%--------------------------------------------------------------------\n%% Function: suite() -> Info\n%% Info = [tuple()]\n%%--------------------------------------------------------------------\nsuite() ->\n [{timetrap,{seconds,30}}].\n\n%%--------------------------------------------------------------------\n%% Function: init_per_suite(Config0) ->\n%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}\n%% Config0 = Config1 = [tuple()]\n%% Reason = term()\n%%--------------------------------------------------------------------\ninit_per_suite(Config) ->\n Config.\n\n%%--------------------------------------------------------------------\n%% Function: end_per_suite(Config0) -> term() | {save_config,Config1}\n%% Config0 = Config1 = [tuple()]\n%%--------------------------------------------------------------------\nend_per_suite(_Config) ->\n ok.\n\n%%--------------------------------------------------------------------\n%% Function: init_per_group(GroupName, Config0) ->\n%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}\n%% GroupName = atom()\n%% Config0 = Config1 = [tuple()]\n%% Reason = term()\n%%--------------------------------------------------------------------\ninit_per_group(_GroupName, Config) ->\n Config.\n\n%%--------------------------------------------------------------------\n%% Function: end_per_group(GroupName, Config0) ->\n%% term() | {save_config,Config1}\n%% GroupName = atom()\n%% Config0 = Config1 = [tuple()]\n%%--------------------------------------------------------------------\nend_per_group(_GroupName, _Config) ->\n ok.\n\n%%--------------------------------------------------------------------\n%% Function: init_per_testcase(TestCase, Config0) ->\n%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}\n%% TestCase = atom()\n%% Config0 = Config1 = [tuple()]\n%% Reason = term()\n%%--------------------------------------------------------------------\ninit_per_testcase(_TestCase, Config) ->\n Config.\n\n%%--------------------------------------------------------------------\n%% Function: end_per_testcase(TestCase, Config0) ->\n%% term() | {save_config,Config1} | {fail,Reason}\n%% TestCase = atom()\n%% Config0 = Config1 = [tuple()]\n%% Reason = term()\n%%--------------------------------------------------------------------\nend_per_testcase(_TestCase, _Config) ->\n ok.\n\n%%--------------------------------------------------------------------\n%% Function: groups() -> [Group]\n%% Group = {GroupName,Properties,GroupsAndTestCases}\n%% GroupName = atom()\n%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]\n%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]\n%% TestCase = atom()\n%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}\n%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |\n%% repeat_until_any_ok | repeat_until_any_fail\n%% N = integer() | forever\n%%--------------------------------------------------------------------\ngroups() ->\n [].\n\n%%--------------------------------------------------------------------\n%% Function: all() -> GroupsAndTestCases | {skip,Reason}\n%% GroupsAndTestCases = [{group,GroupName} | TestCase]\n%% GroupName = atom()\n%% TestCase = atom()\n%% Reason = term()\n%%--------------------------------------------------------------------\nall() ->\n [my_test_case].\n\n%%--------------------------------------------------------------------\n%% Function: TestCase() -> Info\n%% Info = [tuple()]\n%%--------------------------------------------------------------------\nmy_test_case() ->\n [].\n\n%%--------------------------------------------------------------------\n%% Function: TestCase(Config0) ->\n%% ok | exit() | {skip,Reason} | {comment,Comment} |\n%% {save_config,Config1} | {skip_and_save,Reason,Config1}\n%% Config0 = Config1 = [tuple()]\n%% Reason = term()\n%% Comment = term()\n%%--------------------------------------------------------------------\nmy_test_case(_Config) ->\n ok.\n```","ref":"example_chapter.html#test-suite-templates"},{"type":"extras","title":"Running Tests and Analyzing Results","doc":"\n# Running Tests and Analyzing Results","ref":"run_test_chapter.html"},{"type":"extras","title":"Using the Common Test Framework - Running Tests and Analyzing Results","doc":"The `Common Test` framework provides a high-level operator interface for\ntesting, providing the following features:\n\n- Automatic compilation of test suites (and help modules)\n- Creation of extra HTML pages for improved overview.\n- Single-command interface for running all available tests\n- Handling of configuration files specifying data related to the System Under\n Test (SUT) (and any other variable data)\n- Mode for running multiple independent test sessions in parallel with central\n control and configuration","ref":"run_test_chapter.html#using-the-common-test-framework"},{"type":"extras","title":"Automatic Compilation of Test Suites and Help Modules - Running Tests and Analyzing Results","doc":"When `Common Test` starts, it automatically attempts to compile any suites\nincluded in the specified tests. If particular suites are specified, only those\nsuites are compiled. If a particular test object directory is specified (meaning\nall suites in this directory are to be part of the test), `Common Test` runs\nfunction `make:all/1` in the directory to compile the suites.\n\nIf compilation fails for one or more suites, the compilation errors are printed\nto tty and the operator is asked if the test run is to proceed without the\nmissing suites, or be aborted. If the operator chooses to proceed, the tests\nhaving missing suites are noted in the HTML log. If `Common Test` is unable to\nprompt the user after compilation failure (if `Common Test` does not control\n`stdin`), the test run proceeds automatically without the missing suites. This\nbehavior can however be modified with the `ct_run` flag\n`-abort_if_missing_suites`, or the `ct:run_test/1` option\n`{abort_if_missing_suites,TrueOrFalse}`. If `abort_if_missing_suites` is set to\n`true`, the test run stops immediately if some suites fail to compile.\n\nAny help module (that is, regular Erlang module with name not ending with\n\"\\_SUITE\") that resides in the same test object directory as a suite, which is\npart of the test, is also automatically compiled. A help module is not mistaken\nfor a test suite (unless it has a \"\\_SUITE\" name). All help modules in a\nparticular test object directory are compiled, no matter if all or only\nparticular suites in the directory are part of the test.\n\nIf test suites or help modules include header files stored in other locations\nthan the test directory, these include directories can be specified by using\nflag `-include` with [`ct_run`](ct_run_cmd.md), or option `include` with\n`ct:run_test/1`. Also, an include path can be specified with an OS environment\nvariable, `CT_INCLUDE_PATH`.\n\n_Example (bash):_\n\n`$ export CT_INCLUDE_PATH=~testuser/common_suite_files/include:~testuser/common_lib_files/include`\n\n`Common Test` passes all include directories (specified either with flag/option\n`include`, or variable `CT_INCLUDE_PATH` , or both, to the compiler.\n\nInclude directories can also be specified in test specifications, see\n[Test Specifications](run_test_chapter.md#test_specifications).\n\nIf the user wants to run all test suites for a test object (or an OTP\napplication) by specifying only the top directory (for example, with start\nflag/option `dir`), `Common Test` primarily looks for test suite modules in a\nsubdirectory named `test`. If this subdirectory does not exist, the specified\ntop directory is assumed to be the test directory, and test suites are read from\nthere instead.\n\nTo disable the automatic compilation feature, use flag `-no_auto_compile` with\n`ct_run`, or option `{auto_compile,false}` with `ct:run_test/1`. With automatic\ncompilation disabled, the user is responsible for compiling the test suite\nmodules (and any help modules) before the test run. If the modules cannot be\nloaded from the local file system during startup of `Common Test`, the user must\npreload the modules before starting the test. `Common Test` only verifies that\nthe specified test suites exist (that is, that they are, or can be, loaded).\nThis is useful, for example, if the test suites are transferred and loaded as\nbinaries through RPC from a remote node.\n\n[](){: #ct_run }","ref":"run_test_chapter.html#automatic-compilation-of-test-suites-and-help-modules"},{"type":"extras","title":"Running Tests from the OS Command Line - Running Tests and Analyzing Results","doc":"The [`ct_run`](ct_run_cmd.md) program can be used for running tests from the OS\ncommand line, for example, as follows:\n\n- `ct_run -config -dir `\n- `ct_run -config -suite `\n- `ct_run -userconfig -suite `\n- `ct_run -config -suite -group -case `\n\n_Examples:_\n\n```text\n$ ct_run -config $CFGS/sys1.cfg $CFGS/sys2.cfg -dir $SYS1_TEST $SYS2_TEST\n$ ct_run -userconfig ct_config_xml $CFGS/sys1.xml $CFGS/sys2.xml -dir $SYS1_TEST $SYS2_TEST\n$ ct_run -suite $SYS1_TEST/setup_SUITE $SYS2_TEST/config_SUITE\n$ ct_run -suite $SYS1_TEST/setup_SUITE -case start stop\n$ ct_run -suite $SYS1_TEST/setup_SUITE -group installation -case start stop\n```\n\nThe flags `dir`, `suite`, and `group/case` can be combined. For example, to run\n`x_SUITE` and `y_SUITE` in directory `testdir`, as follows:\n\n```text\n$ ct_run -dir ./testdir -suite x_SUITE y_SUITE\n```\n\nThis has the same effect as the following:\n\n```text\n$ ct_run -suite ./testdir/x_SUITE ./testdir/y_SUITE\n```\n\nFor details, see\n[Test Case Group Execution](run_test_chapter.md#group_execution).\n\nThe following flags can also be used with [`ct_run`](ct_run_cmd.md):\n\n- **`-help`** - Lists all available start flags.\n\n- **`-logdir `** - Specifies where the HTML log files are to be written.\n\n- **`-label `** - Associates the test run with a name that\n gets printed in the overview HTML log files.\n\n- **`-refresh_logs`** - Refreshes the top-level HTML index files.\n\n- **`-shell`** - Starts interactive shell mode (described later).\n\n- **`-step [step_opts]`** - Steps through test cases using the Erlang Debugger\n (described later).\n\n- **`-spec `** - Uses test specification as input (described later).\n\n- **`-allow_user_terms`** - Allows user-specific terms in a test specification\n (described later).\n\n- **`-silent_connections [conn_types]`** - , tells `Common Test` to suppress\n printouts for specified connections (described later).\n\n- **`-stylesheet `** - Points out a user HTML style sheet (described\n later).\n\n- **`-cover `** - To perform code coverage test (see\n [Code Coverage Analysis](cover_chapter.md#cover)).\n\n- **`-cover_stop `** - To specify if the `cover` tool is to be stopped\n after the test is completed (see\n [Code Coverage Analysis](cover_chapter.md#cover_stop)).\n\n- **`-event_handler `** - To install\n [event handlers](event_handler_chapter.md#event_handling).\n\n- **`-event_handler_init `** - To install\n [event handlers](event_handler_chapter.md#event_handling) including start\n arguments.\n\n- **`-ct_hooks `** - To install\n [Common Test Hooks](ct_hooks_chapter.md#installing) including start arguments.\n\n- **`-ct_hooks_order [test|config]`** - To modify\n [Common Test Hooks](ct_hooks_chapter.md#installing) execution order.\n\n- **`-enable_builtin_hooks `** - To enable or disable\n [Built-in Common Test Hooks](ct_hooks_chapter.md#builtin_cths). Default is\n `true`.\n\n- **`-include`** - Specifies include directories (described earlier).\n\n- **`-no_auto_compile`** - Disables the automatic test suite compilation feature\n (described earlier).\n\n- **`-abort_if_missing_suites`** - Aborts the test run if one or more suites\n fail to compile (described earlier).\n\n- **`-multiply_timetraps `** - Extends\n [timetrap time-out](write_test_chapter.md#timetraps) values.\n\n- **`-scale_timetraps `** - Enables automatic\n [timetrap time-out](write_test_chapter.md#timetraps) scaling.\n\n- **`-repeat `** - Tells `Common Test` to repeat the tests `n` times\n (described later).\n\n- **`-duration `** - Tells `Common Test` to repeat the tests for duration\n of time (described later).\n\n- **`-until `** - Tells `Common Test` to repeat the tests until\n `stop_time` (described later).\n\n- **`-force_stop [skip_rest]`** - On time-out, the test run is aborted when the\n current test job is finished. If `skip_rest` is provided, the remaining test\n cases in the current test job are skipped (described later).\n\n- **`-decrypt_key `** - Provides a decryption key for\n [encrypted configuration files](config_file_chapter.md#encrypted_config_files).\n\n- **`-decrypt_file `** - Points out a file containing a decryption key\n for\n [encrypted configuration files](config_file_chapter.md#encrypted_config_files).\n\n- **`-basic_html`** - Switches off HTML enhancements that can be incompatible\n with older browsers.\n\n- **`-logopts `** - Enables modification of the logging behavior, see\n [Log options](run_test_chapter.md#logopts).\n\n- **`-verbosity `** - Sets\n [verbosity levels for printouts](write_test_chapter.md#logging).\n\n- **`-no_esc_chars`** - Disables automatic escaping of special HTML characters.\n See the [Logging chapter](write_test_chapter.md#logging).\n\n> #### Note {: .info }\n>\n> Directories passed to `Common Test` can have either relative or absolute\n> paths.\n\n> #### Note {: .info }\n>\n> Any start flags to the Erlang runtime system (application ERTS) can also be\n> passed as parameters to `ct_run`. It is, for example, useful to be able to\n> pass directories to be added to the Erlang code server search path with flag\n> `-pa` or `-pz`. If you have common help- or library modules for test suites\n> (separately compiled), stored in other directories than the test suite\n> directories, these `help/lib` directories are preferably added to the code\n> path this way.\n>\n> _Example:_\n>\n> `$ ct_run -dir ./chat_server -logdir ./chat_server/testlogs -pa $PWD/chat_server/ebin`\n>\n> The absolute path of directory `chat_server/ebin` is here passed to the code\n> server. This is essential because relative paths are stored by the code server\n> as relative, and `Common Test` changes the current working directory of ERTS\n> during the test run.\n\nThe `ct_run` program sets the exit status before shutting down. The following\nvalues are defined:\n\n- `0` indicates a successful testrun, that is, without failed or auto-skipped\n test cases.\n- `1` indicates that one or more test cases have failed, or have been\n auto-skipped.\n- `2` indicates that the test execution has failed because of, for example,\n compilation errors, or an illegal return value from an information function.\n\nIf auto-skipped test cases do not affect the exit status. The default behavior\ncan be changed using start flag:\n\n```text\n-exit_status ignore_config\n```\n\n> #### Note {: .info }\n>\n> Executing `ct_run` without start flags is equal to the command:\n> `ct_run -dir ./`\n\nFor more information about the `ct_run` program, see module\n[`ct_run`](ct_run_cmd.md) and section\n[Installation](install_chapter.md#general).\n\n[](){: #erlang_shell_or_program }","ref":"run_test_chapter.html#running-tests-from-the-os-command-line"},{"type":"extras","title":"Running Tests from the Erlang Shell or from an Erlang Program - Running Tests and Analyzing Results","doc":"`Common Test` provides an Erlang API for running tests. The main (and most\nflexible) function for specifying and executing tests is `ct:run_test/1`. It\ntakes the same start parameters as [`ct_run`](run_test_chapter.md#ct_run), but\nthe flags are instead specified as options in a list of key-value tuples. For\nexample, a test specified with `ct_run` as follows:\n\n`$ ct_run -suite ./my_SUITE -logdir ./results`\n\nis with `ct:run_test/1` specified as:\n\n`1> ct:run_test([{suite,\"./my_SUITE\"},{logdir,\"./results\"}]).`\n\nThe function returns the test result, represented by the tuple\n`{Ok,Failed,{UserSkipped,AutoSkipped}}`, where each element is an integer. If\ntest execution fails, the function returns the tuple `{error,Reason}`, where the\nterm `Reason` explains the failure.\n\nThe default start option `{dir,Cwd}` (to run all suites in the current working\ndirectory) is used if the function is called with an empty list of options.","ref":"run_test_chapter.html#running-tests-from-the-erlang-shell-or-from-an-erlang-program"},{"type":"extras","title":"Releasing the Erlang Shell - Running Tests and Analyzing Results","doc":"During execution of tests started with `ct:run_test/1`, the Erlang shell\nprocess, controlling `stdin`, remains the top-level process of the `Common Test`\nsystem of processes. Consequently, the Erlang shell is not available for\ninteraction during the test run. If this is not desirable, for example, because\nthe shell is needed for debugging purposes or for interaction with the SUT\nduring test execution, set start option `release_shell` to `true` (in the call\nto `ct:run_test/1` or by using the corresponding test specification term,\ndescribed later). This makes `Common Test` release the shell immediately after\nthe test suite compilation stage. To accomplish this, a test runner process is\nspawned to take control of the test execution. The effect is that\n`ct:run_test/1` returns the pid of this process rather than the test result,\nwhich instead is printed to tty at the end of the test run.\n\n> #### Note {: .info }\n>\n> To use the functions [`ct:break/1,2`](`ct:break/1`) and\n> [`ct:continue/0,1`](`ct:continue/0`), `release_shell` _must_ be set to `true`.\n\nFor details, see `ct:run_test/1` manual page.\n\n[](){: #group_execution }","ref":"run_test_chapter.html#releasing-the-erlang-shell"},{"type":"extras","title":"Test Case Group Execution - Running Tests and Analyzing Results","doc":"With the `ct_run` flag, or `ct:run_test/1` option `group`, one or more test case\ngroups can be specified, optionally in combination with specific test cases. The\nsyntax for specifying groups on the command line is as follows:\n\n```text\n$ ct_run -group [-case ]\n```\n\nThe syntax in the Erlang shell is as follows:\n\n```erlang\n1> ct:run_test([{group,GroupsNamesOrPaths}, {case,Cases}]).\n```\n\nParameter `group_names_or_paths` specifies one or more group names and/or one or\nmore group paths. At startup, `Common Test` searches for matching groups in the\ngroup definitions tree (that is, the list returned from `Suite:groups/0`; for\ndetails, see section [Test Case Groups](write_test_chapter.md#test_case_groups).\n\nGiven a group name, say `g`, `Common Test` searches for all paths leading to\n`g`. By path is meant a sequence of nested groups, which must be followed to get\nfrom the top-level group to `g`. To execute the test cases in group `g`,\n`Common Test` must call the `init_per_group/2` function for each group in the\npath to `g`, and all corresponding `end_per_group/2` functions afterwards. This\nis because the configuration of a test case in `g` (and its `Config` input data)\ndepends on `init_per_testcase(TestCase, Config)` and its return value, which in\nturn depends on `init_per_group(g, Config)` and its return value, which in turn\ndepends on `init_per_group/2` of the group above `g`, and so on, all the way up\nto the top-level group.\n\nThis means that if there is more than one way to locate a group (and its test\ncases) in a path, the result of the group search operation is a number of tests,\nall of which are to be performed. `Common Test` interprets a group specification\nthat consists of a single name as follows:\n\n\"Search and find all paths in the group definitions tree that lead to the\nspecified group and, for each path, create a test that does the following, in\norder:\n\n1. Executes all configuration functions in the path to the specified group.\n1. Executes all, or all matching, test cases in this group.\n1. Executes all, or all matching, test cases in all subgroups of the group.\"\n\nThe user can specify a specific group path with parameter\n`group_names_or_paths`. With this type of specification execution of unwanted\ngroups (in otherwise matching paths), and/or the execution of subgroups can be\navoided. The command line syntax of the group path is a list of group names in\nthe path, for example:\n\n`$ ct_run -suite \"./x_SUITE\" -group [g1,g3,g4] -case tc1 tc5`\n\nThe syntax in the Erlang shell is as follows (requires a list within the groups\nlist):\n\n`1> ct:run_test([{suite,\"./x_SUITE\"}, {group,[[g1,g3,g4]]}, {testcase,[tc1,tc5]}]).`\n\nThe last group in the specified path is the terminating group in the test, that\nis, no subgroups following this group are executed. In the previous example,\n`g4` is the terminating group. Hence, `Common Test` executes a test that calls\nall `init` configuration functions in the path to `g4`, that is, `g1..g3..g4`.\nIt then calls test cases `tc1` and `tc5` in `g4`, and finally all `end`\nconfiguration functions in order `g4..g3..g1`.\n\n> #### Note {: .info }\n>\n> The group path specification does not necessarily have to include _all_ groups\n> in the path to the terminating group. `Common Test` searches for all matching\n> paths if an incomplete group path is specified.\n\n> #### Note {: .info }\n>\n> Group names and group paths can be combined with parameter\n> `group_names_or_paths`. Each element is treated as an individual specification\n> in combination with parameter `cases`. The following examples illustrates\n> this.\n\n_Examples:_\n\n```erlang\n-module(x_SUITE).\n...\n%% The group definitions:\ngroups() ->\n [{top1,[],[tc11,tc12,\n {sub11,[],[tc12,tc13]},\n {sub12,[],[tc14,tc15,\n \t\t {sub121,[],[tc12,tc16]}]}]},\n\n {top2,[],[{group,sub21},{group,sub22}]},\n {sub21,[],[tc21,{group,sub2X2}]},\n {sub22,[],[{group,sub221},tc21,tc22,{group,sub2X2}]},\n {sub221,[],[tc21,tc23]},\n {sub2X2,[],[tc21,tc24]}].\n```\n\nThe following executes two tests, one for all cases and all subgroups under\n`top1`, and one for all under `top2`:\n\n```text\n$ ct_run -suite \"x_SUITE\" -group all\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,all}]).\n```\n\nUsing `-group top1 top2`, or `{group,[top1,top2]}` gives the same result.\n\nThe following executes one test for all cases and subgroups under `top1`:\n\n```text\n$ ct_run -suite \"x_SUITE\" -group top1\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,[top1]}]).\n```\n\nThe following runs a test executing `tc12` in `top1` and any subgroup under\n`top1` where it can be found (`sub11` and `sub121`):\n\n```text\n$ ct_run -suite \"x_SUITE\" -group top1 -case tc12\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,[top1]}, {testcase,[tc12]}]).\n```\n\nThe following executes `tc12` _only_ in group `top1`:\n\n```text\n$ ct_run -suite \"x_SUITE\" -group [top1] -case tc12\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,[[top1]]}, {testcase,[tc12]}]).\n```\n\nThe following searches `top1` and all its subgroups for `tc16` resulting in that\nthis test case executes in group `sub121`:\n\n```text\n$ ct_run -suite \"x_SUITE\" -group top1 -case tc16\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,[top1]}, {testcase,[tc16]}]).\n```\n\nUsing the specific path `-group [sub121]` or `{group,[[sub121]]}` gives the same\nresult in this example.\n\nThe following executes two tests, one including all cases and subgroups under\n`sub12`, and one with _only_ the test cases in `sub12`:\n\n```text\n$ ct_run -suite \"x_SUITE\" -group sub12 [sub12]\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,[sub12,[sub12]]}]).\n```\n\nIn the following example, `Common Test` finds and executes two tests, one for\nthe path from `top2` to `sub2X2` through `sub21`, and one from `top2` to\n`sub2X2` through `sub22`:\n\n```text\n$ ct_run -suite \"x_SUITE\" -group sub2X2\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,[sub2X2]}]).\n```\n\nIn the following example, by specifying the unique path\n`top2 -> sub21 -> sub2X2`, only one test is executed. The second possible path,\nfrom `top2` to `sub2X2` (from the former example) is discarded:\n\n```text\n$ ct_run -suite \"x_SUITE\" -group [sub21,sub2X2]\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,[[sub21,sub2X2]]}]).\n```\n\nThe following executes only the test cases for `sub22` and in reverse order\ncompared to the group definition:\n\n```text\n$ ct_run -suite \"x_SUITE\" -group [sub22] -case tc22 tc21\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,[[sub22]]}, {testcase,[tc22,tc21]}]).\n```\n\nIf a test case belonging to a group (according to the group definition) is\nexecuted without a group specification, that is, simply by (using the command\nline):\n\n`$ ct_run -suite \"my_SUITE\" -case my_tc`\n\nor (using the Erlang shell):\n\n`1> ct:run_test([{suite,\"my_SUITE\"}, {testcase,my_tc}]).`\n\nthen `Common Test` ignores the group definition and executes the test case in\nthe scope of the test suite only (no group configuration functions are called).\n\nThe group specification feature, as presented in this section, can also be used\nin [Test Specifications](run_test_chapter.md#test_specifications) (with some\nextra features added).","ref":"run_test_chapter.html#test-case-group-execution"},{"type":"extras","title":"Running the Interactive Shell Mode - Running Tests and Analyzing Results","doc":"You can start `Common Test` in an interactive shell mode where no automatic\ntesting is performed. Instead, `Common Test` starts its utility processes,\ninstalls configuration data (if any), and waits for the user to call functions\n(typically test case support functions) from the Erlang shell.\n\nThe shell mode is useful, for example, for debugging test suites, analyzing and\ndebugging the SUT during \"simulated\" test case execution, and trying out various\noperations during test suite development.\n\nTo start the interactive shell mode, start an Erlang shell manually and call\n`ct:install/1` to install any configuration data you might need (use `[]` as\nargument otherwise). Then call `ct:start_interactive/0` to start `Common Test`.\n\nIf you use the `ct_run` program, you can start the Erlang shell and\n`Common Test` in one go by using the flag `-shell` and, optionally, flag\n`-config` and/or `-userconfig`.\n\n_Examples:_\n\n- `ct_run -shell`\n- `ct_run -shell -config cfg/db.cfg`\n- `ct_run -shell -userconfig db_login testuser x523qZ`\n\nIf no configuration file is specified with command `ct_run`, a warning is\ndisplayed. If `Common Test` has been run from the same directory earlier, the\nsame configuration file(s) are used again. If `Common Test` has not been run\nfrom this directory before, no configuration files are available.\n\nIf any functions using \"required configuration data\" (for example, functions\n`ct_telnet` or `ct_ftp`) are to be called from the Erlang shell, first require\nconfiguration data with [`ct:require/1,2`](`ct:require/1`). This is equivalent\nto a `require` statement in the\n[Test Suite Information Function](write_test_chapter.md#suite) or in the\n[Test Case Information Function](write_test_chapter.md#info_function).\n\n_Example:_\n\n```erlang\n1> ct:require(unix_telnet, unix).\nok\n2> ct_telnet:open(unix_telnet).\n{ok,<0.105.0>}\n4> ct_telnet:cmd(unix_telnet, \"ls .\").\n{ok,[\"ls .\",\"file1 ...\",...]}\n```\n\nEverything that `Common Test` normally prints in the test case logs, are in the\ninteractive mode written to a log named `ctlog.html` in directory\n`ct_run. `. A link to this file is available in the file named\n`last_interactive.html` in the directory from which you execute `ct_run`.\nSpecifying a different root directory for the logs than the current working\ndirectory is not supported.\n\nIf you wish to exit the interactive mode (for example, to start an automated\ntest run with `ct:run_test/1`), call function `ct:stop_interactive/0`. This\nshuts down the running `ct` application. Associations between configuration\nnames and data created with `require` are consequently deleted. Function\n`ct:start_interactive/0` takes you back into interactive mode, but the previous\nstate is not restored.","ref":"run_test_chapter.html#running-the-interactive-shell-mode"},{"type":"extras","title":"Step-by-Step Execution of Test Cases with the Erlang Debugger - Running Tests and Analyzing Results","doc":"Using `ct_run -step [opts]`, or by passing option `{step,Opts}` to\n`ct:run_test/1`, the following is possible:\n\n- Get the Erlang Debugger started automatically.\n- Use its graphical interface to investigate the state of the current test case.\n- Execute the test case step-by-step and/or set execution breakpoints.\n\nIf no extra options are specified with flag/option `step`, breakpoints are set\nautomatically on the test cases that are to be executed by `Common Test`, and\nthose functions only. If step option `config` is specified, breakpoints are also\ninitially set on the configuration functions in the suite, that is,\n`init_per_suite/1`, `end_per_suite/1`, `init_per_group/2`, `end_per_group/2`,\n`init_per_testcase/2` and `end_per_testcase/2`.\n\n`Common Test` enables the Debugger auto-attach feature, which means that for\nevery new interpreted test case function that starts to execute, a new trace\nwindow automatically pops up (as each test case executes on a dedicated Erlang\nprocess). Whenever a new test case starts, `Common Test` attempts to close the\ninactive trace window of the previous test case. However, if you prefer\n`Common Test` to leave inactive trace windows, use option `keep_inactive`.\n\nThe step functionality can be used together with flag/option `suite` and `suite`\n\\+ `case/testcase`, but not together with `dir`.\n\n[](){: #test_specifications }","ref":"run_test_chapter.html#step-by-step-execution-of-test-cases-with-the-erlang-debugger"},{"type":"extras","title":"Test Specifications - Running Tests and Analyzing Results","doc":"","ref":"run_test_chapter.html#test-specifications"},{"type":"extras","title":"General Description - Running Tests and Analyzing Results","doc":"The most flexible way to specify what to test, is to use a test specification,\nwhich is a sequence of Erlang terms. The terms are normally declared in one or\nmore text files (see `ct:run_test/1`), but can also be passed to `Common Test`\non the form of a list (see `ct:run_testspec/1`). There are two general types of\nterms: configuration terms and test specification terms.\n\nWith configuration terms it is, for example, possible to do the following:\n\n- Label the test run (similar to `ct_run -label`).\n- Evaluate any expressions before starting the test.\n- Import configuration data (similar to `ct_run -config/-userconfig`).\n- Specify the top-level HTML log directory (similar to `ct_run -logdir`).\n- Enable code coverage analysis (similar to `ct_run -cover`).\n- Install `Common Test Hooks` (similar to `ct_run -ch_hooks`).\n- Install `event_handler` plugins (similar to `ct_run -event_handler`).\n- Specify include directories to be passed to the compiler for automatic\n compilation (similar to `ct_run -include`).\n- Disable the auto-compilation feature (similar to `ct_run -no_auto_compile`).\n- Set verbosity levels (similar to `ct_run -verbosity`).\n\nConfiguration terms can be combined with `ct_run` start flags or `ct:run_test/1`\noptions. The result is, for some flags/options and terms, that the values are\nmerged (for example, configuration files, include directories, verbosity levels,\nand silent connections) and for others that the start flags/options override the\ntest specification terms (for example, log directory, label, style sheet, and\nauto-compilation).\n\nWith test specification terms, it is possible to state exactly which tests to\nrun and in which order. A test term specifies either one or more suites, one or\nmore test case groups (possibly nested), or one or more test cases in a group\n(or in multiple groups) or in a suite.\n\nAny number of test terms can be declared in sequence. `Common Test` compiles by\ndefault the terms into one or more tests to be performed in one resulting test\nrun. A term that specifies a set of test cases \"swallows\" one that only\nspecifies a subset of these cases. For example, the result of merging one term\nspecifying that all cases in suite S are to be executed, with another term\nspecifying only test case X and Y in S, is a test of all cases in S. However, if\na term specifying test case X and Y in S is merged with a term specifying case Z\nin S, the result is a test of X, Y, and Z in S. To disable this behavior, that\nis, to instead perform each test sequentially in a \"script-like\" manner, set\nterm `merge_tests` to `false` in the test specification.\n\nA test term can also specify one or more test suites, groups, or test cases to\nbe skipped. Skipped suites, groups, and cases are not executed and show up in\nthe HTML log files as `SKIPPED`.","ref":"run_test_chapter.html#general-description"},{"type":"extras","title":"Using Multiple Test Specification Files - Running Tests and Analyzing Results","doc":"When multiple test specification files are specified at startup (either with\n`ct_run -spec file1 file2 ...` or `ct:run_test([{spec, [File1,File2,...]}])`),\n`Common Test` either executes one test run per specification file, or joins the\nfiles and performs all tests within one single test run. The first behavior is\nthe default one. The latter requires that start flag/option `join_specs` is\nprovided, for example,\n`run_test -spec ./my_tests1.ts ./my_tests2.ts -join_specs`.\n\nJoining a number of specifications, or running them separately, can also be\naccomplished with (and can be combined with) test specification file inclusion.","ref":"run_test_chapter.html#using-multiple-test-specification-files"},{"type":"extras","title":"Test Specification File Inclusion - Running Tests and Analyzing Results","doc":"With the term `specs`, a test specification can include other specifications. An\nincluded specification can either be joined with the source specification or\nused to produce a separate test run (as with start flag/option `join_specs`\nabove).\n\n_Example:_\n\n```erlang\n%% In specification file \"a.spec\"\n{specs, join, [\"b.spec\", \"c.spec\"]}.\n{specs, separate, [\"d.spec\", \"e.spec\"]}.\n%% Config and test terms follow\n...\n```\n\nIn this example, the test terms defined in files \"b.spec\" and \"c.spec\" are\njoined with the terms in source specification \"a.spec\" (if any). The inclusion\nof specifications \"d.spec\" and \"e.spec\" results in two separate, and\nindependent, test runs (one for each included specification).\n\nOption `join` does not imply that the test terms are merged, only that all tests\nare executed in one single test run.\n\nJoined specifications share common configuration settings, such as the list of\n`config` files or `include` directories. For configurations that cannot be\ncombined, such as settings for `logdir` or `verbosity`, it is up to the user to\nensure there are no clashes when the test specifications are joined.\nSpecifications included with option `separate` do not share configuration\nsettings with the source specification. This is useful, for example, if there\nare clashing configuration settings in included specifications, making it them\nimpossible to join.\n\nIf `{merge_tests,true}` is set in the source specification (which is the default\nsetting), terms in joined specifications are merged with terms in the source\nspecification (according to the description of `merge_tests` earlier).\n\nNotice that it is always the `merge_tests` setting in the source specification\nthat is used when joined with other specifications. Say, for example, that a\nsource specification A, with tests TA1 and TA2, has `{merge_tests,false}` set,\nand that it includes another specification, B, with tests TB1 and TB2, that has\n`{merge_tests,true}` set. The result is that the test series\n`TA1,TA2,merge(TB1,TB2)` is executed. The opposite `merge_tests` settings would\nresult in the test series `merge(merge(TA1,TA2),TB1,TB2)`.\n\nThe term `specs` can be used to nest specifications, that is, have one\nspecification include other specifications, which in turn include others, and so\nno","ref":"run_test_chapter.html#test-specification-file-inclusion"},{"type":"extras","title":"Test Case Groups - Running Tests and Analyzing Results","doc":"When a test case group is specified, the resulting test executes function\n`init_per_group`, followed by all test cases and subgroups (including their\nconfiguration functions), and finally function `end_per_group`. Also, if\nparticular test cases in a group are specified, `init_per_group` and\n`end_per_group`, for the group in question, are called. If a group defined (in\n`Suite:groups/0`) as a subgroup of another group, is specified (or if particular\ntest cases of a subgroup are), `Common Test` calls the configuration functions\nfor the top-level groups and for the subgroup in question (making it possible to\npass configuration data all the way from `init_per_suite` down to the test cases\nin the subgroup).\n\nThe test specification uses the same mechanism for specifying test case groups\nthrough names and paths, as explained in section\n[Test Case Group Execution](run_test_chapter.md#group_execution), with the\naddition of element `GroupSpec`.\n\nElement `GroupSpec` makes it possible to specify group execution properties that\noverrides those in the group definition (that is, in `groups/0`). Execution\nproperties for subgroups might be overridden as well. This feature makes it\npossible to change properties of groups at the time of execution, without having\nto edit the test suite. The same feature is available for `group` elements in\nthe `Suite:all/0` list. For details and examples, see section\n[Test Case Groups](write_test_chapter.md#test_case_groups).","ref":"run_test_chapter.html#test-case-groups"},{"type":"extras","title":"Test Specification Syntax - Running Tests and Analyzing Results","doc":"Test specifications can be used to run tests both in a single test host\nenvironment and in a distributed `Common Test` environment (Large Scale\nTesting). The node parameters in term `init` are only relevant in the latter\n(see section [Test Specifications](ct_master_chapter.md#test_specifications) in\nLarge Scale Testing). For details about the various terms, see the corresponding\nsections in the User's Guide, for example, the following:\n\n- The [`ct_run` program](run_test_chapter.md#ct_run) for an overview of\n available start flags (as most flags have a corresponding configuration term)\n- [Logging](write_test_chapter.md#logging) (for terms `verbosity`, `stylesheet`,\n `basic_html` and `esc_chars`)\n- [External Configuration Data](config_file_chapter.md#top) (for terms `config`\n and `userconfig`)\n- [Event Handling](event_handler_chapter.md#event_handling) (for the\n `event_handler` term)\n- [Common Test Hooks](ct_hooks_chapter.md#installing) (for term `ct_hooks`)\n\n_Configuration terms:_\n\n```erlang\n{merge_tests, Bool}.\n\n{define, Constant, Value}.\n\n{specs, InclSpecsOption, TestSpecs}.\n\n{node, NodeAlias, Node}.\n\n{init, InitOptions}.\n{init, [NodeAlias], InitOptions}.\n\n{label, Label}.\n{label, NodeRefs, Label}.\n\n{verbosity, VerbosityLevels}.\n{verbosity, NodeRefs, VerbosityLevels}.\n\n{stylesheet, CSSFile}.\n{stylesheet, NodeRefs, CSSFile}.\n\n{silent_connections, ConnTypes}.\n{silent_connections, NodeRefs, ConnTypes}.\n\n{multiply_timetraps, N}.\n{multiply_timetraps, NodeRefs, N}.\n\n{scale_timetraps, Bool}.\n{scale_timetraps, NodeRefs, Bool}.\n\n{cover, CoverSpecFile}.\n{cover, NodeRefs, CoverSpecFile}.\n\n{cover_stop, Bool}.\n{cover_stop, NodeRefs, Bool}.\n\n{include, IncludeDirs}.\n{include, NodeRefs, IncludeDirs}.\n\n{auto_compile, Bool},\n{auto_compile, NodeRefs, Bool},\n\n{abort_if_missing_suites, Bool},\n{abort_if_missing_suites, NodeRefs, Bool},\n\n{config, ConfigFiles}.\n{config, ConfigDir, ConfigBaseNames}.\n{config, NodeRefs, ConfigFiles}.\n{config, NodeRefs, ConfigDir, ConfigBaseNames}.\n\n{userconfig, {CallbackModule, ConfigStrings}}.\n{userconfig, NodeRefs, {CallbackModule, ConfigStrings}}.\n\n{logdir, LogDir}.\n{logdir, NodeRefs, LogDir}.\n\n{logopts, LogOpts}.\n{logopts, NodeRefs, LogOpts}.\n\n{create_priv_dir, PrivDirOption}.\n{create_priv_dir, NodeRefs, PrivDirOption}.\n\n{event_handler, EventHandlers}.\n{event_handler, NodeRefs, EventHandlers}.\n{event_handler, EventHandlers, InitArgs}.\n{event_handler, NodeRefs, EventHandlers, InitArgs}.\n\n{ct_hooks, CTHModules}.\n{ct_hooks, NodeRefs, CTHModules}.\n\n{ct_hooks_order, CTHOrder}.\n\n{enable_builtin_hooks, Bool}.\n\n{basic_html, Bool}.\n{basic_html, NodeRefs, Bool}.\n\n{esc_chars, Bool}.\n{esc_chars, NodeRefs, Bool}.\n\n{release_shell, Bool}.\n```\n\n_Test terms:_\n\n```erlang\n{suites, Dir, Suites}.\n{suites, NodeRefs, Dir, Suites}.\n\n{groups, Dir, Suite, Groups}.\n{groups, NodeRefs, Dir, Suite, Groups}.\n\n{groups, Dir, Suite, Groups, {cases,Cases}}.\n{groups, NodeRefs, Dir, Suite, Groups, {cases,Cases}}.\n\n{cases, Dir, Suite, Cases}.\n{cases, NodeRefs, Dir, Suite, Cases}.\n\n{skip_suites, Dir, Suites, Comment}.\n{skip_suites, NodeRefs, Dir, Suites, Comment}.\n\n{skip_groups, Dir, Suite, GroupNames, Comment}.\n{skip_groups, NodeRefs, Dir, Suite, GroupNames, Comment}.\n\n{skip_cases, Dir, Suite, Cases, Comment}.\n{skip_cases, NodeRefs, Dir, Suite, Cases, Comment}.\n```\n\n[](){: #types } _Types:_\n\n```erlang\nBool = true | false\nConstant = atom()\nValue = term()\nInclSpecsOption = join | separate\nTestSpecs = string() | [string()]\nNodeAlias = atom()\nNode = node()\nNodeRef = NodeAlias | Node | master\nNodeRefs = all_nodes | [NodeRef] | NodeRef\nInitOptions = term()\nLabel = atom() | string()\nVerbosityLevels = integer() | [{Category,integer()}]\nCategory = atom()\nCSSFile = string()\nConnTypes = all | [atom()]\nN = integer()\nCoverSpecFile = string()\nIncludeDirs = string() | [string()]\nConfigFiles = string() | [string()]\nConfigDir = string()\nConfigBaseNames = string() | [string()]\nCallbackModule = atom()\nConfigStrings = string() | [string()]\nLogDir = string()\nLogOpts = [term()]\nPrivDirOption = auto_per_run | auto_per_tc | manual_per_tc\nEventHandlers = atom() | [atom()]\nInitArgs = [term()]\nCTHModules = [CTHModule |\n \t {CTHModule, CTHInitArgs} |\n \t {CTHModule, CTHInitArgs, CTHPriority}]\nCTHModule = atom()\nCTHInitArgs = term()\nCTHOrder = test | config\nDir = string()\nSuites = atom() | [atom()] | all\nSuite = atom()\nGroups = GroupPath | GroupSpec | [GroupSpec] | all\nGroupPath = [[GroupSpec]]\nGroupSpec = GroupName | {GroupName,Properties} | {GroupName,Properties,[GroupSpec]}\nGroupName = atom()\nGroupNames = GroupName | [GroupName]\nCases = atom() | [atom()] | all\nComment = string() | \"\"\n```\n\nThe difference between the `config` terms above is that with `ConfigDir`,\n`ConfigBaseNames` is a list of base names, that is, without directory paths.\n`ConfigFiles` must be full names, including paths. For example, the following\ntwo terms have the same meaning:\n\n```erlang\n{config, [\"/home/testuser/tests/config/nodeA.cfg\",\n \"/home/testuser/tests/config/nodeB.cfg\"]}.\n\n{config, \"/home/testuser/tests/config\", [\"nodeA.cfg\",\"nodeB.cfg\"]}.\n```\n\n> #### Note {: .info }\n>\n> Any relative paths, specified in the test specification, are relative to the\n> directory containing the test specification file if\n> `ct_run -spec TestSpecFile ...` or `ct:run:test([{spec,TestSpecFile},...])`\n> executes the test.\n>\n> The path is relative to the top-level log directory if\n> `ct:run:testspec(TestSpec)` executes the test.","ref":"run_test_chapter.html#test-specification-syntax"},{"type":"extras","title":"Constants - Running Tests and Analyzing Results","doc":"The term `define` introduces a constant that is used to replace the name\n`Constant` with `Value`, wherever it is found in the test specification. This\nreplacement occurs during an initial iteration through the test specification.\nConstants can be used anywhere in the test specification, for example, in any\nlists and tuples, and even in strings and inside the value part of other\nconstant definitions. A constant can also be part of a node name, but that is\nthe only place where a constant can be part of an atom.\n\n> #### Note {: .info }\n>\n> For the sake of readability, the name of the constant must always begin with\n> an uppercase letter, or a `$`, `?`, or `_`. This means that it must always be\n> single quoted (as the constant name is an atom, not text).\n\nThe main benefit of constants is that they can be used to reduce the size (and\navoid repetition) of long strings, such as file paths.\n\n_Examples:_\n\n```erlang\n%% 1a. no constant\n{config, \"/home/testuser/tests/config\", [\"nodeA.cfg\",\"nodeB.cfg\"]}.\n{suites, \"/home/testuser/tests/suites\", all}.\n\n%% 1b. with constant\n{define, 'TESTDIR', \"/home/testuser/tests\"}.\n{config, \"'TESTDIR'/config\", [\"nodeA.cfg\",\"nodeB.cfg\"]}.\n{suites, \"'TESTDIR'/suites\", all}.\n\n%% 2a. no constants\n{config, [testnode@host1, testnode@host2], \"../config\", [\"nodeA.cfg\",\"nodeB.cfg\"]}.\n{suites, [testnode@host1, testnode@host2], \"../suites\", [x_SUITE, y_SUITE]}.\n\n%% 2b. with constants\n{define, 'NODE', testnode}.\n{define, 'NODES', ['NODE'@host1, 'NODE'@host2]}.\n{config, 'NODES', \"../config\", [\"nodeA.cfg\",\"nodeB.cfg\"]}.\n{suites, 'NODES', \"../suites\", [x_SUITE, y_SUITE]}.\n```\n\nConstants make the test specification term `alias`, in previous versions of\n`Common Test`, redundant. This term is deprecated but remains supported in\nupcoming `Common Test` releases. Replacing `alias` terms with `define` is\nstrongly recommended though. An example of such replacement follows:\n\n```erlang\n%% using the old alias term\n{config, \"/home/testuser/tests/config/nodeA.cfg\"}.\n{alias, suite_dir, \"/home/testuser/tests/suites\"}.\n{groups, suite_dir, x_SUITE, group1}.\n\n%% replacing with constants\n{define, 'TestDir', \"/home/testuser/tests\"}.\n{define, 'CfgDir', \"'TestDir'/config\"}.\n{define, 'SuiteDir', \"'TestDir'/suites\"}.\n{config, 'CfgDir', \"nodeA.cfg\"}.\n{groups, 'SuiteDir', x_SUITE, group1}.\n```\n\nConstants can well replace term `node` also, but this still has a declarative\nvalue, mainly when used in combination with `NodeRefs == all_nodes` (see\n[Types](run_test_chapter.md#types)).","ref":"run_test_chapter.html#constants"},{"type":"extras","title":"Example - Running Tests and Analyzing Results","doc":"Here follows a simple test specification example:\n\n```erlang\n{define, 'Top', \"/home/test\"}.\n{define, 'T1', \"'Top'/t1\"}.\n{define, 'T2', \"'Top'/t2\"}.\n{define, 'T3', \"'Top'/t3\"}.\n{define, 'CfgFile', \"config.cfg\"}.\n\n{logdir, \"'Top'/logs\"}.\n\n{config, [\"'T1'/'CfgFile'\", \"'T2'/'CfgFile'\", \"'T3'/'CfgFile'\"]}.\n\n{suites, 'T1', all}.\n{skip_suites, 'T1', [t1B_SUITE,t1D_SUITE], \"Not implemented\"}.\n{skip_cases, 'T1', t1A_SUITE, [test3,test4], \"Irrelevant\"}.\n{skip_cases, 'T1', t1C_SUITE, [test1], \"Ignore\"}.\n\n{suites, 'T2', [t2B_SUITE,t2C_SUITE]}.\n{cases, 'T2', t2A_SUITE, [test4,test1,test7]}.\n\n{skip_suites, 'T3', all, \"Not implemented\"}.\n```\n\nThe example specifies the following:\n\n- The specified `logdir` directory is used for storing the HTML log files (in\n subdirectories tagged with node name, date, and time).\n- The variables in the specified test system configuration files are imported\n for the test.\n- The first test to run includes all suites for system `t1`. Suites `t1B` and\n `t1D` are excluded from the test. Test cases `test3` and `test4` in `t1A` and\n `test1` case in `t1C` are also excluded from the test.\n- The second test to run is for system `t2`. The included suites are `t2B` and\n `t2C`. Test cases `test4`, `test1`, and `test7` in suite `t2A` are also\n included. The test cases are executed in the specified order.\n- The last test to run is for system `t3`. Here, all suites are skipped and this\n is explicitly noted in the log files.","ref":"run_test_chapter.html#example"},{"type":"extras","title":"The init Term - Running Tests and Analyzing Results","doc":"With term `init` it is possible to specify initialization options for nodes\ndefined in the test specification. There are options to start the node and to\nevaluate any function on the node. For details, see section\n[Automatic Startup of Test Target Nodes](ct_master_chapter.md#ct_slave) in\nsection Using Common Test for Large Scale Testing.","ref":"run_test_chapter.html#the-init-term"},{"type":"extras","title":"User-Specific Terms - Running Tests and Analyzing Results","doc":"The user can provide a test specification including (for `Common Test`)\nunrecognizable terms. If this is desired, use flag `-allow_user_terms` when\nstarting tests with `ct_run`. This forces `Common Test` to ignore unrecognizable\nterms. In this mode, `Common Test` is not able to check the specification for\nerrors as efficiently as if the scanner runs in default mode. If `ct:run_test/1`\nis used for starting the tests, the relaxed scanner mode is enabled by tuple\n`{allow_user_terms,true}`.","ref":"run_test_chapter.html#user-specific-terms"},{"type":"extras","title":"Reading Test Specification Terms - Running Tests and Analyzing Results","doc":"Terms in the current test specification (that is, the specification that has\nbeen used to configure and run the current test) can be looked up. The function\n[`get_testspec_terms()`](`ct:get_testspec_terms/0`) returns a list of all test\nspecification terms (both configuration terms and test terms), and\n`get_testspec_terms(Tags)` returns the term (or a list of terms) matching the\ntag (or tags) in `Tags`.\n\nFor example, in the test specification:\n\n```erlang\n...\n{label, my_server_smoke_test}.\n{config, \"../../my_server_setup.cfg\"}.\n{config, \"../../my_server_interface.cfg\"}.\n...\n```\n\nAnd in, for example, a test suite or a `Common Test Hook` function:\n\n```erlang\n...\n[{label,[{_Node,TestType}]}, {config,CfgFiles}] =\n ct:get_testspec_terms([label,config]),\n\n[verify_my_server_cfg(TestType, CfgFile) || {Node,CfgFile} <- CfgFiles,\n Node == node()];\n...\n```\n\n[](){: #log_files }","ref":"run_test_chapter.html#reading-test-specification-terms"},{"type":"extras","title":"Log Files - Running Tests and Analyzing Results","doc":"As the execution of the test suites proceed, events are logged in the following\nfour different ways:\n\n- Text to the operator console.\n- Suite-related information is sent to the major log file.\n- Case-related information is sent to the minor log file.\n- The HTML overview log file is updated with test results.\n- A link to all runs executed from a certain directory is written in the log\n named `all_runs.html` and direct links to all tests (the latest results) are\n written to the top-level `index.html`.\n\nTypically the operator, possibly running hundreds or thousands of test cases,\ndoes not want to fill the console with details about, or printouts from,\nspecific test cases. By default, the operator only sees the following:\n\n- A confirmation that the test has started and information about how many test\n cases are executed in total.\n- A small note about each failed test case.\n- A summary of all the run test cases.\n- A confirmation when the test run is complete.\n- Some special information, such as error reports, progress reports, and\n printouts written with `erlang:display/1`, or `io:format/3` specifically\n addressed to a receiver other than [`standard_io`](`t:io:standard_io/0`) (for\n example, the default group leader process `user`).\n\nTo dig deeper into the general results, or the result of a specific test case,\nthe operator can do so by following the links in the HTML presentation and read\nthe major or minor log files. The \"all_runs.html\" page is a good starting point.\nIt is located in `logdir` and contains a link to each test run, including a\nquick overview (with date and time, node name, number of tests, test names, and\ntest result totals).\n\nAn \"index.html\" page is written for each test run (that is, stored in the\n`ct_run` directory tagged with node name, date, and time). This file provides an\noverview of all individual tests performed in the same test run. The test names\nfollow the following convention:\n\n- `TopLevelDir.TestDir` (all suites in `TestDir` executed)\n- `TopLevelDir.TestDir:suites` (specific suites executed)\n- `TopLevelDir.TestDir.Suite` (all cases in `Suite` executed)\n- `TopLevelDir.TestDir.Suite:cases` (specific test cases executed)\n- `TopLevelDir.TestDir.Suite.Case` (only `Case` executed)\n\nThe \"test run index\" page includes a link to the `Common Test` Framework Log\nfile in which information about imported configuration data and general test\nprogress is written. This log file is useful to get snapshot information about\nthe test run during execution. It can also be helpful when analyzing test\nresults or debugging test suites.\n\nThe \"test run index\" page indicates if a test has missing suites (that is,\nsuites that `Common Test` failed to compile). Names of the missing suites can be\nfound in the `Common Test` Framework Log file.\n\nThe major log file shows a detailed report of the test run. It includes test\nsuite and test case names, execution time, the exact reason for failures, and so\non. The information is available in both a file with textual and with HTML\nrepresentation. The HTML file shows a summary that gives a good overview of the\ntest run. It also has links to each individual test case log file for quick\nviewing with an HTML browser.\n\nThe minor log files contain full details of every single test case, each in a\nseparate file. This way, it is straightforward to compare the latest results to\nthat of previous test runs, even if the set of test cases changes. If\napplication SASL is running, its logs are also printed to the current minor log\nfile by the [cth_log_redirect built-in hook](ct_hooks_chapter.md#builtin_cths).\n\nThe full name of the minor log file (that is, the name of the file including the\nabsolute directory path) can be read during execution of the test case. It comes\nas value in tuple `{tc_logfile,LogFileName}` in the `Config` list (which means\nit can also be read by a pre- or post `Common Test Hook` function). Also, at the\nstart of a test case, this data is sent with an event to any installed event\nhandler. For details, see section\n[Event Handling](event_handler_chapter.md#event_handling).\n\nThe log files are written continuously during a test run and links are always\ncreated initially when a test starts. Thevtest progress can therefore be\nfollowed simply by refreshing pages in the HTML browser. Statistics totals are\nnot presented until a test is complete however.\n\n[](){: #logopts }","ref":"run_test_chapter.html#log-files"},{"type":"extras","title":"Log Options - Running Tests and Analyzing Results","doc":"With start flag `logopts` options that modify some aspects of the logging\nbehavior can be specified. The following options are available:\n\n- **`no_src`** - The HTML version of the test suite source code is not generated\n during the test run (and is consequently not available in the log file\n system).\n\n- **`no_nl`** - `Common Test` does not add a newline character `(\\n)` to the end\n of an output string that it receives from a call to, for example,\n `io:format/2`, and which it prints to the test case log.\n\nFor example, if a test is started with:\n\n`$ ct_run -suite my_SUITE -logopts no_nl`\n\nthen printouts during the test made by successive calls to `io:format(\"x\")`,\nappears in the test case log as:\n\n`xxx`\n\ninstead of each `x` printed on a new line, which is the default behavior.\n\n[](){: #table_sorting }","ref":"run_test_chapter.html#log-options"},{"type":"extras","title":"Sorting HTML Table Columns - Running Tests and Analyzing Results","doc":"By clicking the name in the column header of any table (for example, \"Ok\",\n\"Case\", \"Time\", and so on), the table rows are sorted in whatever order makes\nsense for the type of value (for example, numerical for \"Ok\" or \"Time\", and\nalphabetical for \"Case\"). The sorting is performed through JavaScript code,\nautomatically inserted into the HTML log files. `Common Test` uses the\n[jQuery](http://jquery.com) library and the\n[tablesorter](https://mottie.github.io/tablesorter/docs/) plugin, with\ncustomized sorting functions, for this implementation.","ref":"run_test_chapter.html#sorting-html-table-columns"},{"type":"extras","title":"The Unexpected I/O Log - Running Tests and Analyzing Results","doc":"The test suites overview page includes a link to the Unexpected I/O Log. In this\nlog, `Common Test` saves printouts made with [`ct:log/1,2,3,4,5`](`ct:log/2`)\nand [`ct:pal/1,2,3,4,5`](`ct:pal/2`), as well as captured system error- and\nprogress reports, which cannot be associated with particular test cases and\ntherefore cannot be written to individual test case log files. This occurs, for\nexample, if a log printout is made from an external process (not a test case\nprocess), _or_ if an error- or progress report comes in, during a short interval\nwhile `Common Test` is not executing a test case or configuration function, _or_\nwhile `Common Test` is currently executing a parallel test case group.\n\n[](){: #pre_post_test_io_log }","ref":"run_test_chapter.html#the-unexpected-i-o-log"},{"type":"extras","title":"The Pre- and Post Test I/O Log - Running Tests and Analyzing Results","doc":"The `Common Test` Framework Log page includes links to the Pre- and Post Test\nI/O Log. In this log, `Common Test` saves printouts made with `ct:log/1,2,3,4,5`\nand `ct:pal/1,2,3,4,5`, as well as captured system error- and progress reports,\nwhich take place before, and after, the test run. Examples of this are printouts\nfrom a CT hook init- or terminate function, or progress reports generated when\nan OTP application is started from a CT hook init function. Another example is\nan error report generated because of a failure when an external application is\nstopped from a CT hook terminate function. All information in these examples\nends up in the Pre- and Post Test I/O Log. For more information on how to\nsynchronize test runs with external user applications, see section\n[Synchronizing](ct_hooks_chapter.md#synchronizing) in section Common Test Hooks.\n\n> #### Note {: .info }\n>\n> Logging to file with `ct:log/1,2,3,4,5` or `ct:pal/1,2,3,4,5` only works when\n> `Common Test` is running. Printouts with `ct:pal/1,2,3,4,5` are however always\n> displayed on screen.\n\n[](){: #delete_old_logs }","ref":"run_test_chapter.html#the-pre-and-post-test-i-o-log"},{"type":"extras","title":"Delete Old Logs - Running Tests and Analyzing Results","doc":"`Common Test` can automatically delete old log. This is specified with the\n`keep_logs` option. The default value for this option is `all`, which means that\nno logs are deleted. If the value is set to an integer, `N`, `Common Test`\ndeletes all `ct_run. ` directories, except the `N` newest.\n\n[](){: #html_stylesheet }","ref":"run_test_chapter.html#delete-old-logs"},{"type":"extras","title":"HTML Style Sheets - Running Tests and Analyzing Results","doc":"`Common Test` uses an HTML Style Sheet (CSS file) to control the look of the\nHTML log files generated during test runs. If the log files are not displayed\ncorrectly in the browser of your choice, or you prefer a more primitive (\"pre\n`Common Test` v1.6\") look of the logs, use the start flag/option:\n\n```text\nbasic_html\n```\n\nThis disables the use of style sheets and JavaScripts (see\n[Sorting HTML Table Columns](run_test_chapter.md#table_sorting)).\n\n`Common Test` includes an _optional_ feature to allow user HTML style sheets for\ncustomizing printouts. The functions in `ct` that print to a test case HTML log\nfile (`log/3,4,5` and `pal/3,4,5`) accept `Category` as first argument. With\nthis argument a category can be specified that can be mapped to a named `div`\nselector in a CSS rule-set. This is useful, especially for coloring text\ndifferently depending on the type of (or reason for) the printout. Say you want\none particular background color for test system configuration information, a\ndifferent one for test system state information, and finally one for errors\ndetected by the test case functions. The corresponding style sheet can look as\nfollows:\n\n```css\ndiv.sys_config { background:blue }\ndiv.sys_state { background:yellow }\ndiv.error { background:red }\n```\n\nCommon Test prints the text from `ct:log/3,4,5` or `ct:pal/3,4,5` inside a `pre`\nelement nested under the named `div` element. Since the `pre` selector has a\npredefined CSS rule (in file `ct_default.css`) for the attributes `color`,\n`font-family` and `font-size`, if a user wants to change any of the predefined\nattribute settings, a new rule for `pre` must be added to the user stylesheet.\nExample:\n\n```text\ndiv.error pre { color:white }\n```\n\nHere, white text is used instead of the default black for `div.error` printouts\n(and no other attribute settings for `pre` are affected).\n\nTo install the CSS file (`Common Test` inlines the definition in the HTML code),\nthe file name can be provided when executing `ct_run`.\n\n_Example:_\n\n```text\n$ ct_run -dir $TEST/prog -stylesheet $TEST/styles/test_categories.css\n```\n\nCategories in a CSS file installed with flag `-stylesheet` are on a global test\nlevel in the sense that they can be used in any suite that is part of the test\nrun.\n\nStyle sheets can also be installed on a per suite and per test case basis.\n\n_Example:_\n\n```erlang\n-module(my_SUITE).\n...\nsuite() -> [..., {stylesheet,\"suite_categories.css\"}, ...].\n...\nmy_testcase(_) ->\n ...\n ct:log(sys_config, \"Test node version: ~p\", [VersionInfo]),\n ...\n ct:log(sys_state, \"Connections: ~p\", [ConnectionInfo]),\n ...\n ct:pal(error, \"Error ~p detected! Info: ~p\", [SomeFault,ErrorInfo]),\n ct:fail(SomeFault).\n```\n\nIf the style sheet is installed as in this example, the categories are private\nto the suite in question. They can be used by all test cases in the suite, but\ncannot be used by other suites. A suite private style sheet, if specified, is\nused in favor of a global style sheet (one specified with flag `-stylesheet`). A\nstylesheet tuple (as returned by `suite/0` above) can also be returned from a\ntest case information function. In this case the categories specified in the\nstyle sheet can only be used in that particular test case. A test case private\nstyle sheet is used in favor of a suite or global level style sheet.\n\nIn a tuple `{stylesheet,CSSFile}`, if `CSSFile` is specified with a path, for\nexample, `\"$TEST/styles/categories.css\"`, this full name is used to locate the\nfile. However, if only the file name is specified, for example,\n`categories.css`, the CSS file is assumed to be located in the data directory,\n`data_dir`, of the suite. The latter use is recommended, as it is portable\ncompared to hard coding path names in the suite.\n\nArgument `Category` in the previous example can have the value (atom)\n`sys_config` (blue background), `sys_state` (yellow background), or `error`\n(white text on red background).\n\n[](){: #repeating_tests }","ref":"run_test_chapter.html#html-style-sheets"},{"type":"extras","title":"Repeating Tests - Running Tests and Analyzing Results","doc":"You can order `Common Test` to repeat the tests you specify. You can choose to\nrepeat tests a number of times, repeat tests for a specific period of time, or\nrepeat tests until a particular stop time is reached. If repetition is\ncontrolled by time, an action for `Common Test` to take upon time-out can be\nspecified. Either `Common Test` performs all tests in the current run before\nstopping, or it stops when the current test job is finished. Repetition can be\nactivated by `ct_run` start flags, or tuples in the `ct:run:test/1` option list\nargument. The flags (options in parentheses) are the following:\n\n- `-repeat N ({repeat,N})`, where `N` is a positive integer\n- `-duration DurTime ({duration,DurTime})`, where `DurTime` is the duration\n- `-until StopTime ({until,StopTime})`, where `StopTime` is finish time\n- `-force_stop ({force_stop,true})`\n- `-force_stop skip_rest ({force_stop,skip_rest})`\n\n- **`DurTime`** - The duration time is specified as `HHMMSS`, for example,\n `-duration 012030` or `{duration,\"012030\"}`\n\n , which means that the tests are executed and (if time allows) repeated until\n time-out occurs after 1 hour, 20 minutes, and 30 seconds.\n\n- **`StopTime`** - The finish time can be specified as `HHMMSS` and is then\n interpreted as a time today (or possibly tomorrow), but can also be specified\n as `YYMoMoDDHHMMSS`, for example, `-until 071001120000` or\n `{until,\"071001120000\"}`. This means that the tests are executed and (if time\n allows) repeated, until 12 o'clock on the 1st of October 2007.\n\nWhen time-out occurs, `Common Test` never aborts the ongoing test case, as this\ncan leave the SUT in an undefined, and possibly bad, state. Instead\n`Common Test`, by default, finishes the current test run before stopping. If\nflag `force_stop` is specified, `Common Test` stops when the current test job is\nfinished. If flag `force_stop` is specified with `skip_rest`, `Common Test` only\ncompletes the current test case and skips the remaining tests in the test job.\n\n> #### Note {: .info }\n>\n> As `Common Test` always finishes at least the current test case, the time\n> specified with `duration` or `until` is never definitive.\n\nLog files from every repeated test run is saved in normal `Common Test` fashion\n(described earlier).\n\n`Common Test` might later support an optional feature to only store the last\n(and possibly the first) set of logs of repeated test runs, but for now the user\nmust be careful not to run out of disk space if tests are repeated during long\nperiods of time.\n\nFor each test run that is part of a repeated session, information about the\nparticular test run is printed in the `Common Test` Framework Log. The\ninformation includes the repetition number, remaining time, and so on.\n\n_Example 1:_\n\n```text\n$ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -duration 001000 -force_stop\n```\n\nHere, the suites in test directory `to1`, followed by the suites in `to2`, are\nexecuted in one test run. A time-out event occurs after 10 minutes. As long as\nthere is time left, `Common Test` repeats the test run (that is, starting over\nwith test `to1`). After time-out, `Common Test` stops when the current job is\nfinished (because of flag `force_stop`). As a result, the specified test run can\nbe aborted after test `to1` and before test `to2`.\n\n_Example 2:_\n\n```text\n$ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -duration 001000 -forces_stop skip_rest\n```\n\nHere, the same tests as in Example 1 are run, but with flag `force_stop` set to\n`skip_rest`. If time-out occurs while executing tests in directory `to1`, the\nremaining test cases in `to1` are skipped and the test is aborted without\nrunning the tests in `to2` another time. If time-out occurs while executing\ntests in directory `to2`, the remaining test cases in `to2` are skipped and the\ntest is aborted.\n\n_Example 3:_\n\n```text\n$ date\nFri Sep 28 15:00:00 MEST 2007\n\n$ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -until 160000\n```\n\nHere, the same test run as in the previous examples are executed (and possibly\nrepeated). However, when the time-out occurs, after 1 hour, `Common Test`\nfinishes the entire test run before stopping (that is, both `to1` and `to2` are\nalways executed in the same test run).\n\n_Example 4:_\n\n```text\n$ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -repeat 5\n```\n\nHere, the test run, including both the `to1` and the `to2` test, is repeated\nfive times.\n\n> #### Note {: .info }\n>\n> Do not confuse this feature with the `repeat` property of a test case group.\n> The options described here are used to repeat execution of entire test runs,\n> while the `repeat` property of a test case group makes it possible to repeat\n> execution of sets of test cases within a suite. For more information about the\n> latter, see section\n> [Test Case Groups ](write_test_chapter.md#test_case_groups)in section Writing\n> Test Suites.\n\n[](){: #silent_connections }","ref":"run_test_chapter.html#repeating-tests"},{"type":"extras","title":"Silent Connections - Running Tests and Analyzing Results","doc":"The protocol handling processes in `Common Test`, implemented by `ct_telnet`,\n`ct_ssh`, `ct_ftp`, and so on, do verbose printing to the test case logs. This\ncan be switched off with flag `-silent_connections`:\n\n```text\nct_run -silent_connections [conn_types]\n```\n\nHere, `conn_types` specifies SSH, Telnet, FTP, RPC, and/or SNMP.\n\n_Example 1:_\n\n```text\nct_run ... -silent_connections ssh telnet\n```\n\nThis switches off logging for SSH and Telnet connections.\n\n_Example 2:_\n\n```text\nct_run ... -silent_connections\n```\n\nThis switches off logging for all connection types.\n\nFatal communication error and reconnection attempts are always printed, even if\nlogging has been suppressed for the connection type in question. However,\noperations such as sending and receiving data are performed silently.\n\n`silent_connections` can also be specified in a test suite. This is accomplished\nby returning a tuple, `{silent_connections,ConnTypes}`, in the `suite/0` or test\ncase information list. If `ConnTypes` is a list of atoms (SSH, Telnet, FTP, RPC\nand/or SNMP), output for any corresponding connections are suppressed. Full\nlogging is by default enabled for any connection of type not specified in\n`ConnTypes`. Hence, if `ConnTypes` is the empty list, logging is enabled for all\nconnections.\n\n_Example 3:_\n\n```erlang\n-module(my_SUITE).\n\nsuite() -> [..., {silent_connections,[telnet,ssh]}, ...].\n\n...\n\nmy_testcase1() ->\n [{silent_connections,[ssh]}].\n\nmy_testcase1(_) ->\n ...\n\nmy_testcase2(_) ->\n ...\n```\n\nIn this example, `suite/0` tells `Common Test` to suppress printouts from Telnet\nand SSH connections. This is valid for all test cases. However, `my_testcase1/0`\nspecifies that for this test case, only SSH is to be silent. The result is that\n`my_testcase1` gets Telnet information (if any) printed in the log, but not SSH\ninformation. `my_testcase2` gets no information from either connection printed.\n\n`silent_connections` can also be specified with a term in a test specification\n(see section [Test Specifications](run_test_chapter.md#test_specifications) in\nsection Running Tests and Analyzing Results). Connections provided with start\nflag/option `silent_connections` are merged with any connections listed in the\ntest specification.\n\nStart flag/option `silent_connections` and the test specification term override\nany settings made by the information functions inside the test suite.\n\n> #### Note {: .info }\n>\n> In the current `Common Test` version, the `silent_connections` feature only\n> works for Telnet and SSH connections. Support for other connection types can\n> be added in future `Common Test` versions.","ref":"run_test_chapter.html#silent-connections"},{"type":"extras","title":"External Configuration Data","doc":"\n# External Configuration Data\n\n[](){: #top }","ref":"config_file_chapter.html"},{"type":"extras","title":"General - External Configuration Data","doc":"To avoid hard-coding data values related to the test and/or System Under Test\n(SUT) in the test suites, the data can instead be specified through\nconfiguration files or strings that `Common Test` reads before the start of a\ntest run. External configuration data makes it possible to change test\nproperties without modifying the test suites using the data. Examples of\nconfiguration data follows:\n\n- Addresses to the test plant or other instruments\n- User login information\n- Names of files needed by the test\n- Names of programs to be executed during the test\n- Any other variable needed by the test","ref":"config_file_chapter.html#general"},{"type":"extras","title":"Syntax - External Configuration Data","doc":"A configuration file can contain any number of elements of the type:\n\n```erlang\n{CfgVarName,Value}.\n```\n\nwhere\n\n```erlang\nCfgVarName = atom()\nValue = term() | [{CfgVarName,Value}]\n```","ref":"config_file_chapter.html#syntax"},{"type":"extras","title":"Requiring and Reading Configuration Data - External Configuration Data","doc":"[](){: #require_config_data }\n\nIn a test suite, one must _require_ that a configuration variable (`CfgVarName`\nin the previous definition) exists before attempting to read the associated\nvalue in a test case or configuration function.\n\n`require` is an assert statement, which can be part of the\n[Test Suite Information Function](write_test_chapter.md#suite) or\n[Test Case Information Function](write_test_chapter.md#info_function). If the\nrequired variable is unavailable, the test is skipped (unless a default value\nhas been specified, see section\n[Test Case Information Function](write_test_chapter.md#info_function) for\ndetails). Also, function [`ct:require/1/2`](`ct:require/1`) can be called from a\ntest case to check if a specific variable is available. The return value from\nthis function must be checked explicitly and appropriate action be taken\ndepending on the result (for example, to skip the test case if the variable in\nquestion does not exist).\n\nA `require` statement in the test suite information case or test case\ninformation-list is to look like `{require,CfgVarName}` or\n`{require,AliasName,CfgVarName}`. The arguments `AliasName` and `CfgVarName` are\nthe same as the arguments to [`ct:require/1,2`](`ct:require/1`). `AliasName`\nbecomes an alias for the configuration variable, and can be used as reference to\nthe configuration data value. The configuration variable can be associated with\nany number of alias names, but each name must be unique within the same test\nsuite. The two main uses for alias names follows:\n\n- To identify connections (described later).\n- To help adapt configuration data to a test suite (or test case) and improve\n readability.\n\nTo read the value of a configuration variable, use function\n[`get_config/1,2,3`](`ct:get_config/1`).\n\n_Example:_\n\n```erlang\nsuite() ->\n [{require, domain, 'CONN_SPEC_DNS_SUFFIX'}].\n\n...\n\ntestcase(Config) ->\n Domain = ct:get_config(domain),\n ...\n```","ref":"config_file_chapter.html#requiring-and-reading-configuration-data"},{"type":"extras","title":"Using Configuration Variables Defined in Multiple Files - External Configuration Data","doc":"If a configuration variable is defined in multiple files and you want to access\nall possible values, use function `ct:get_config/3` and specify `all` in the\noptions list. The values are then returned in a list and the order of the\nelements corresponds to the order that the configuration files were specified at\nstartup.","ref":"config_file_chapter.html#using-configuration-variables-defined-in-multiple-files"},{"type":"extras","title":"Encrypted Configuration Files - External Configuration Data","doc":"[](){: #encrypted_config_files }\n\nConfiguration files containing sensitive data can be encrypted if they must be\nstored in open and shared directories.\n\nTo have `Common Test` encrypt a specified file using function `DES3` in\napplication `Crypto`, call\n[`ct:encrypt_config_file/2,3`](`ct:encrypt_config_file/2`) The encrypted file\ncan then be used as a regular configuration file in combination with other\nencrypted files or normal text files. However, the key for decrypting the\nconfiguration file must be provided when running the test. This can be done with\nflag/option `decrypt_key` or `decrypt_file`, or a key file in a predefined\nlocation.\n\n`Common Test` also provides decryption functions,\n[`ct:decrypt_config_file/2,3`](`ct:decrypt_config_file/2`), for recreating the\noriginal text files.","ref":"config_file_chapter.html#encrypted-configuration-files"},{"type":"extras","title":"Opening Connections Using Configuration Data - External Configuration Data","doc":"Two different methods for opening a connection using the support functions in,\nfor example, `m:ct_ssh`, `m:ct_ftp`, and `m:ct_telnet` follows:\n\n- Using a configuration target name (an alias) as reference.\n- Using the configuration variable as reference.\n\nWhen a target name is used for referencing the configuration data (that\nspecifies the connection to be opened), the same name can be used as connection\nidentity in all subsequent calls related to the connection (also for closing\nit). Only one open connection per target name is possible. If you attempt to\nopen a new connection using a name already associated with an open connection,\n`Common Test` returns the already existing handle so the previously opened\nconnection is used. This feature makes it possible to call the function for\nopening a particular connection whenever useful. An action like this does not\nnecessarily open any new connections unless it is required (which could be the\ncase if, for example, the previous connection has been closed unexpectedly by\nthe server). Using named connections also removes the need to pass handle\nreferences around in the suite for these connections.\n\nWhen a configuration variable name is used as reference to the data specifying\nthe connection, the handle returned as a result of opening the connection must\nbe used in all subsequent calls (also for closing the connection). Repeated\ncalls to the open function with the same variable name as reference results in\nmultiple connections being opened. This can be useful, for example, if a test\ncase needs to open multiple connections to the same server on the target node\n(using the same configuration data for each connection).","ref":"config_file_chapter.html#opening-connections-using-configuration-data"},{"type":"extras","title":"User-Specific Configuration Data Formats - External Configuration Data","doc":"The user can specify configuration data on a different format than key-value\ntuples in a text file, as described so far. The data can, for example, be read\nfrom any files, fetched from the web over HTTP, or requested from a\nuser-specific process. To support this, `Common Test` provides a callback module\nplugin mechanism to handle configuration data.","ref":"config_file_chapter.html#user-specific-configuration-data-formats"},{"type":"extras","title":"Default Callback Modules for Handling Configuration Data - External Configuration Data","doc":"`Common Test` includes default callback modules for handling configuration data\nspecified in standard configuration files (described earlier) and in XML files\nas follows:\n\n- `ct_config_plain` \\- for reading configuration files with key-value tuples\n (standard format). This handler is used to parse configuration files if no\n user callback is specified.\n- `ct_config_xml` \\- for reading configuration data from XML files.","ref":"config_file_chapter.html#default-callback-modules-for-handling-configuration-data"},{"type":"extras","title":"Using XML Configuration Files - External Configuration Data","doc":"An example of an XML configuration file follows:\n\n```xml\n \n \n \"targethost\" \n \"tester\" \n \"letmein\" \n \n \"/test/loadmodules\" \n \n```\n\nOnce read, this file produces the same configuration variables as the following\ntext file:\n\n```erlang\n{ftp_host, [{ftp,\"targethost\"},\n {username,\"tester\"},\n {password,\"letmein\"}]}.\n\n{lm_directory, \"/test/loadmodules\"}.\n```","ref":"config_file_chapter.html#using-xml-configuration-files"},{"type":"extras","title":"Implement a User-Specific Handler - External Configuration Data","doc":"The user-specific handler can be written to handle special configuration file\nformats. The parameter can be either file names or configuration strings (the\nempty list is valid).\n\nThe callback module implementing the handler is responsible for checking the\ncorrectness of configuration strings.\n\nTo validate the configuration strings, the callback module is to have function\n`Callback:check_parameter/1` exported.\n\nThe input argument is passed from `Common Test`, as defined in the test\nspecification, or specified as an option to `ct_run` or `ct:run_test`.\n\nThe return value is to be any of the following values, indicating if the\nspecified configuration parameter is valid:\n\n- `{ok, {file, FileName}}` \\- the parameter is a file name and the file exists.\n- `{ok, {config, ConfigString}}` \\- the parameter is a configuration string and\n it is correct.\n- `{error, {nofile, FileName}}` \\- there is no file with the specified name in\n the current directory.\n- `{error, {wrong_config, ConfigString}}` \\- the configuration string is wrong.\n\nThe function `Callback:read_config/1` is to be exported from the callback module\nto read configuration data, initially before the tests start, or as a result of\ndata being reloaded during test execution. The input argument is the same as for\nfunction `check_parameter/1`.\n\nThe return value is to be either of the following:\n\n- `{ok, Config}` \\- if the configuration variables are read successfully.\n- `{error, {Error, ErrorDetails}}` \\- if the callback module fails to proceed\n with the specified configuration parameters.\n\n`Config` is the proper Erlang key-value list, with possible key-value sublists\nas values, like the earlier configuration file example:\n\n```erlang\n[{ftp_host, [{ftp, \"targethost\"}, {username, \"tester\"}, {password, \"letmein\"}]},\n {lm_directory, \"/test/loadmodules\"}]\n```","ref":"config_file_chapter.html#implement-a-user-specific-handler"},{"type":"extras","title":"Examples of Configuration Data Handling - External Configuration Data","doc":"A configuration file for using the FTP client to access files on a remote host\ncan look as follows:\n\n```erlang\n{ftp_host, [{ftp,\"targethost\"},\n {username,\"tester\"},\n {password,\"letmein\"}]}.\n\n{lm_directory, \"/test/loadmodules\"}.\n```\n\nThe XML version shown earlier can also be used, but it is to be explicitly\nspecified that the `ct_config_xml` callback module is to be used by\n`Common Test`.\n\nThe following is an example of how to assert that the configuration data is\navailable and can be used for an FTP session:\n\n```erlang\ninit_per_testcase(ftptest, Config) ->\n {ok,_} = ct_ftp:open(ftp),\n Config.\n\nend_per_testcase(ftptest, _Config) ->\n ct_ftp:close(ftp).\n\nftptest() ->\n [{require,ftp,ftp_host},\n {require,lm_directory}].\n\nftptest(Config) ->\n Remote = filename:join(ct:get_config(lm_directory), \"loadmodX\"),\n Local = filename:join(proplists:get_value(priv_dir,Config), \"loadmodule\"),\n ok = ct_ftp:recv(ftp, Remote, Local),\n ...\n```\n\nThe following is an example of how the functions in the previous example can be\nrewritten if it is necessary to open multiple connections to the FTP server:\n\n```erlang\ninit_per_testcase(ftptest, Config) ->\n {ok,Handle1} = ct_ftp:open(ftp_host),\n {ok,Handle2} = ct_ftp:open(ftp_host),\n [{ftp_handles,[Handle1,Handle2]} | Config].\n\nend_per_testcase(ftptest, Config) ->\n lists:foreach(fun(Handle) -> ct_ftp:close(Handle) end,\n proplists:get_value(ftp_handles,Config)).\n\nftptest() ->\n [{require,ftp_host},\n {require,lm_directory}].\n\nftptest(Config) ->\n Remote = filename:join(ct:get_config(lm_directory), \"loadmodX\"),\n Local = filename:join(proplists:get_value(priv_dir,Config), \"loadmodule\"),\n [Handle | MoreHandles] = proplists:get_value(ftp_handles,Config),\n ok = ct_ftp:recv(Handle, Remote, Local),\n ...\n```","ref":"config_file_chapter.html#examples-of-configuration-data-handling"},{"type":"extras","title":"Example of User-Specific Configuration Handler - External Configuration Data","doc":"A simple configuration handling driver, asking an external server for\nconfiguration data, can be implemented as follows:\n\n```erlang\n-module(config_driver).\n-export([read_config/1, check_parameter/1]).\n\nread_config(ServerName)->\n ServerModule = list_to_atom(ServerName),\n ServerModule:start(),\n ServerModule:get_config().\n\ncheck_parameter(ServerName)->\n ServerModule = list_to_atom(ServerName),\n case code:is_loaded(ServerModule) of\n {file, _}->\n {ok, {config, ServerName}};\n false->\n case code:load_file(ServerModule) of\n {module, ServerModule}->\n {ok, {config, ServerName}};\n {error, nofile}->\n {error, {wrong_config, \"File not found: \" ++ ServerName ++ \".beam\"}}\n end\n end.\n```\n\nThe configuration string for this driver can be `config_server`, if the\n`config_server.erl` module that follows is compiled and exists in the code path\nduring test execution:\n\n```erlang\n-module(config_server).\n-export([start/0, stop/0, init/1, get_config/0, loop/0]).\n\n-define(REGISTERED_NAME, ct_test_config_server).\n\nstart()->\n case whereis(?REGISTERED_NAME) of\n undefined->\n spawn(?MODULE, init, [?REGISTERED_NAME]),\n wait();\n _Pid->\n ok\n end,\n ?REGISTERED_NAME.\n\ninit(Name)->\n register(Name, self()),\n loop().\n\nget_config()->\n call(self(), get_config).\n\nstop()->\n call(self(), stop).\n\ncall(Client, Request)->\n case whereis(?REGISTERED_NAME) of\n undefined->\n {error, {not_started, Request}};\n Pid->\n Pid ! {Client, Request},\n receive\n Reply->\n {ok, Reply}\n after 4000->\n {error, {timeout, Request}}\n end\n end.\n\nloop()->\n receive\n {Pid, stop}->\n Pid ! ok;\n {Pid, get_config}->\n {D,T} = erlang:localtime(),\n Pid !\n [{localtime, [{date, D}, {time, T}]},\n {node, erlang:node()},\n {now, erlang:now()},\n {config_server_pid, self()},\n {config_server_vsn, ?vsn}],\n ?MODULE:loop()\n end.\n\nwait()->\n case whereis(?REGISTERED_NAME) of\n undefined->\n wait();\n _Pid->\n ok\n end.\n```\n\nHere, the handler also provides for dynamically reloading of configuration\nvariables. If [`ct:reload_config(localtime)`](`ct:reload_config/1`) is called\nfrom the test case function, all variables loaded with\n`config_driver:read_config/1` are updated with their latest values, and the new\nvalue for variable `localtime` is returned.","ref":"config_file_chapter.html#example-of-user-specific-configuration-handler"},{"type":"extras","title":"Code Coverage Analysis","doc":"\n# Code Coverage Analysis\n\n[](){: #cover }","ref":"cover_chapter.html"},{"type":"extras","title":"General - Code Coverage Analysis","doc":"Although `Common Test` was created primarily for black-box testing, nothing\nprevents it from working perfectly as a white-box testing tool as well. This is\nespecially true when the application to test is written in Erlang. Then the test\nports are easily realized with Erlang function calls.\n\nWhen white-box testing an Erlang application, it is useful to be able to measure\nthe code coverage of the test. `Common Test` provides simple access to the OTP\nCover tool for this purpose. `Common Test` handles all necessary communication\nwith the Cover tool (starting, compiling, analysing, and so on). The\n`Common Test` user only needs to specify the extent of the code coverage\nanalysis.","ref":"cover_chapter.html#general"},{"type":"extras","title":"Use - Code Coverage Analysis","doc":"To specify the modules to be included in the code coverage test, provide a cover\nspecification file. With this file you can point out specific modules or specify\ndirectories containing modules to be included in the analysis. You can also\nspecify modules to be excluded from the analysis.\n\nIf you are testing a distributed Erlang application, it is likely that code you\nwant included in the code coverage analysis gets executed on another Erlang node\nthan the one `Common Test` is running on. If so, you must specify these other\nnodes in the cover specification file or add them dynamically to the code\ncoverage set of nodes. For details on the latter, see module `m:ct_cover`.\n\nIn the cover specification file you can also specify your required level of the\ncode coverage analysis; `details` or `overview`. In detailed mode, you get a\ncoverage overview page, showing per module and total coverage percentages. You\nalso get an HTML file printed for each module included in the analysis showing\nexactly what parts of the code have been executed during the test. In overview\nmode, only the code coverage overview page is printed.\n\nYou can choose to export and import code coverage data between tests. If you\nspecify the name of an export file in the cover specification file,\n`Common Test` exports collected coverage data to this file at the end of the\ntest. You can similarly specify previously exported data to be imported and\nincluded in the analysis for a test (multiple import files can be specified).\nThis way, the total code coverage can be analyzed without necessarily running\nall tests at once.\n\nTo activate the code coverage support, specify the name of the cover\nspecification file as you start `Common Test`. Do this by using flag `-cover`\nwith [`ct_run`](ct_run_cmd.md), for example:\n\n```text\n$ ct_run -dir $TESTOBJS/db -cover $TESTOBJS/db/config/db.coverspec\n```\n\nYou can also pass the cover specification file name in a call to\n`ct:run_test/1`, by adding a `{cover,CoverSpec}` tuple to argument `Opts`.\n\nYou can also enable code coverage in your test specifications (see section\n[Test Specifications](run_test_chapter.md#test_specifications) in section\nRunning Tests and Analyzing Results).\n\n[](){: #cover_stop }","ref":"cover_chapter.html#use"},{"type":"extras","title":"Stopping the Cover Tool When Tests Are Completed - Code Coverage Analysis","doc":"By default, the Cover tool is automatically stopped when the tests are\ncompleted. This causes the original (non-cover compiled) modules to be loaded\nback into the test node. If a process at this point still runs old code of any\nof the modules that are cover compiled, meaning that it has not done any fully\nqualified function call after the cover compilation, the process is killed. To\navoid this, set the value of option `cover_stop` to `false`. This means that the\nmodules stay cover compiled. Therefore, this is only recommended if the Erlang\nnodes under test are terminated after the test is completed, or if cover can be\nmanually stopped.\n\nThe option can be set by using flag `-cover_stop` with `ct_run`, by adding\n`{cover_stop,true|false}` to argument `Opts` to `ct:run_test/1`, or by adding a\n`cover_stop` term in the test specification (see section\n[Test Specifications](run_test_chapter.md#test_specifications) in section\nRunning Tests and Analyzing Results).","ref":"cover_chapter.html#stopping-the-cover-tool-when-tests-are-completed"},{"type":"extras","title":"The Cover Specification File - Code Coverage Analysis","doc":"","ref":"cover_chapter.html#the-cover-specification-file"},{"type":"extras","title":"General Config - Code Coverage Analysis","doc":"Here follows the general configuration terms that are allowed in a cover\nspecification file:\n\n```erlang\n%% List of Nodes on which cover will be active during test.\n%% Nodes = [atom()]\n{nodes, Nodes}.\n\n%% Files with previously exported cover data to include in analysis.\n%% CoverDataFiles = [string()]\n{import, CoverDataFiles}.\n\n%% Cover data file to export from this session.\n%% CoverDataFile = string()\n{export, CoverDataFile}.\n\n%% Cover analysis level.\n%% Level = details | overview\n{level, Level}.\n\n%% Directories to include in cover.\n%% Dirs = [string()]\n{incl_dirs, Dirs}.\n\n%% Directories, including subdirectories, to include.\n{incl_dirs_r, Dirs}.\n\n%% Specific modules to include in cover.\n%% Mods = [atom()]\n{incl_mods, Mods}.\n\n%% Directories to exclude in cover.\n{excl_dirs, Dirs}.\n\n%% Directories, including subdirectories, to exclude.\n{excl_dirs_r, Dirs}.\n\n%% Specific modules to exclude in cover.\n{excl_mods, Mods}.\n\n%% Cross cover compilation\n%% Tag = atom(), an identifier for a test run\n%% Mod = [atom()], modules to compile for accumulated analysis\n{cross,[{Tag,Mods}]}.\n```\n\nThe terms `incl_dirs_r` and `excl_dirs_r` tell `Common Test` to search the\nspecified directories recursively and include or exclude any module found during\nthe search. The terms `incl_dirs` and `excl_dirs` result in a non-recursive\nsearch for modules (that is, only modules found in the specified directories are\nincluded or excluded).\n\n> #### Note {: .info }\n>\n> Directories containing Erlang modules to be included in a code coverage test\n> must exist in the code server path. Otherwise, the Cover tool fails to\n> recompile the modules. It is not sufficient to specify these directories in\n> the cover specification file for `Common Test`.","ref":"cover_chapter.html#general-config"},{"type":"extras","title":"OTP application Config - Code Coverage Analysis","doc":"When using a cover specification in the testing of an OTP application itself,\nthere is a special incl_app directive that includes the applications modules for\nthe cover compilation.\n\n```erlang\n{incl_app, AppName, Cover :: overview | details}.\n```\n\n> #### Note {: .info }\n>\n> If you desire to also use some other general cover configuration together with\n> this option you should insert the AppName in between the option and its value\n> creating a three tuple.\n\n[](){: #cross_cover }","ref":"cover_chapter.html#otp-application-config"},{"type":"extras","title":"Cross Cover Analysis - Code Coverage Analysis","doc":"The cross cover mechanism allows cover analysis of modules across multiple\ntests. It is useful if some code, for example, a library module, is used by many\ndifferent tests and the accumulated cover result is desirable.\n\nThis can also be achieved in a more customized way by using parameter `export`\nin the cover specification and analysing the result off line. However, the cross\ncover mechanism is a built-in solution that also provides logging.\n\nThe mechanism is easiest explained by an example:\n\nAssume that there are two systems, `s1` and `s2`, that are tested in separate\ntest runs. System `s1` contains a library module `m1` tested by test run `s1`\nand is included in the cover specification of `s1` as follows:\n\n```text\ns1.cover:\n {incl_mods,[m1]}.\n```\n\nWhen analysing code coverage, the result for `m1` can be seen in the cover log\nin the `s1` test result.\n\nNow, imagine that as `m1` is a library module, it is also often used by system\n`s2`. Test run `s2` does not specifically test `m1`, but it can still be\ninteresting to see which parts of `m1` that are covered by the `s2` tests. To do\nthis, `m1` can be included also in the cover specification of `s2` as follows:\n\n```text\ns2.cover:\n {incl_mods,[m1]}.\n```\n\nThis gives an entry for `m1` also in the cover log for test run `s2`. The\nproblem is that this only reflects the coverage by `s2` tests, not the\naccumulated result over `s1` and `s2`. This is where the cross cover mechanism\ncomes in handy.\n\nIf instead the cover specification for `s2` is like the following:\n\n```text\ns2.cover:\n {cross,[{s1,[m1]}]}.\n```\n\nThen `m1` is cover compiled in test run `s2`, but not shown in the coverage log.\nInstead, if `ct_cover:cross_cover_analyse/2` is called after both `s1` and `s2`\ntest runs are completed, the accumulated result for `m1` is available in the\ncross cover log for test run `s1`.\n\nThe call to the analyze function must be as follows:\n\n```erlang\nct_cover:cross_cover_analyse(Level, [{s1,S1LogDir},{s2,S2LogDir}]).\n```\n\nHere, `S1LogDir` and `S2LogDir` are the directories named ` .logs` for\neach test respectively.\n\nNotice the tags `s1` and `s2`, which are used in the cover specification file\nand in the call to `ct_cover:cross_cover_analyse/2`. The purpose of these is\nonly to map the modules specified in the cover specification to the log\ndirectory specified in the call to the analyze function. The tag name has no\nmeaning beyond this.","ref":"cover_chapter.html#cross-cover-analysis"},{"type":"extras","title":"Logging - Code Coverage Analysis","doc":"To view the result of a code coverage test, click the button labeled \"COVER LOG\"\nin the top-level index page for the test run.\n\nBefore Erlang/OTP 17.1, if your test run consisted of multiple tests, cover\nwould be started and stopped for each test within the test run. Separate logs\nwould be available through the \"Coverage log\" link on the test suite result\npages. These links are still available, but now they all point to the same page\nas the button on the top-level index page. The log contains the accumulated\nresults for the complete test run. For details about this change, see the\nrelease notes.\n\nThe button takes you to the code coverage overview page. If you have\nsuccessfully performed a detailed coverage analysis, links to each individual\nmodule coverage page are found here.\n\nIf cross cover analysis is performed, and there are accumulated coverage results\nfor the current test, the link \"Coverdata collected over all tests\" takes you to\nthese results.","ref":"cover_chapter.html#logging"},{"type":"extras","title":"Using Common Test for Large-Scale Testing","doc":"\n# Using Common Test for Large-Scale Testing","ref":"ct_master_chapter.html"},{"type":"extras","title":"General - Using Common Test for Large-Scale Testing","doc":"Large-scale automated testing requires running multiple independent test\nsessions in parallel. This is accomplished by running some `Common Test` nodes\non one or more hosts, testing different target systems. Configuring, starting,\nand controlling the test nodes independently can be a cumbersome operation. To\naid this kind of automated large-scale testing, `Common Test` offers a master\ntest node component, `Common Test` Master, which handles central configuration\nand control in a system of distributed `Common Test` nodes.\n\nThe `Common Test` Master server runs on one dedicated Erlang node and uses\ndistributed Erlang to communicate with any number of `Common Test` test nodes,\neach hosting a regular `Common Test` server. Test specifications are used as\ninput to specify what to test on which test nodes, using what configuration.\n\nThe `Common Test` Master server writes progress information to HTML log files\nsimilarly to the regular `Common Test` server. The logs contain test statistics\nand links to the log files written by each independent `Common Test` server.\n\nThe `Common Test` Master API is exported by module `m:ct_master`.","ref":"ct_master_chapter.html#general"},{"type":"extras","title":"Use - Using Common Test for Large-Scale Testing","doc":"`Common Test` Master requires all test nodes to be on the same network and share\na common file system. `Common Test` Master cannot start test nodes\nautomatically. The nodes must be started in advance for `Common Test` Master to\nbe able to start test sessions on them.\n\nTests are started by calling [`ct_master:run(TestSpecs)`](`ct_master:run/1`) or\n[`ct_master:run(TestSpecs, InclNodes, ExclNodes)`](`ct_master:run/3`)\n\n`TestSpecs` is either the name of a test specification file (string) or a list\nof test specifications. If it is a list, the specifications are handled (and the\ncorresponding tests executed) in sequence. An element in a `TestSpecs` list can\nalso be list of test specifications. The specifications in such a list are\nmerged into one combined specification before test execution.\n\n_Example:_\n\n```erlang\nct_master:run([\"ts1\",\"ts2\",[\"ts3\",\"ts4\"]])\n```\n\nHere, the tests specified by \"ts1\" run first, then the tests specified by \"ts2\",\nand finally the tests specified by both \"ts3\" and \"ts4\".\n\nThe `InclNodes` argument to `run/3` is a list of node names. Function `run/3`\nruns the tests in `TestSpecs` just like `run/1`, but also takes any test in\n`TestSpecs`, which is not explicitly tagged with a particular node name, and\nexecute it on the nodes listed in `InclNodes`. By using `run/3` this way, any\ntest specification can be used, with or without node information, in a\nlarge-scale test environment.\n\n`ExclNodes` is a list of nodes to be excluded from the test. That is, tests that\nare specified in the test specification to run on a particular node are not\nperformed if that node is listed in `ExclNodes` at runtime.\n\nIf `Common Test` Master fails initially to connect to any of the test nodes\nspecified in a test specification or in the `InclNodes` list, the operator is\nprompted with the option to either start over again (after manually checking the\nstatus of the nodes in question), to run without the missing nodes, or to abort\nthe operation.\n\nWhen tests start, `Common Test` Master displays information to console about the\ninvolved nodes. `Common Test` Master also reports when tests finish,\nsuccessfully or unsuccessfully. If connection is lost to a node, the test on\nthat node is considered finished. `Common Test` Master does not attempt to\nre-establish contact with the failing node.\n\nAt any time, to get the current status of the test nodes, call function\n[`ct_master:progress()`](`ct_master:progress/0`).\n\nTo stop one or more tests, use function\n[`ct_master:abort()`](`ct_master:abort/0`) (to stop all) or\n[`ct_master:abort(Nodes)`](`ct_master:abort/1`).\n\nFor details about the `Common Test` Master API, see module `m:ct_master`.\n\n[](){: #test_specifications }","ref":"ct_master_chapter.html#use"},{"type":"extras","title":"Test Specifications - Using Common Test for Large-Scale Testing","doc":"The test specifications used as input to `Common Test` Master are fully\ncompatible with the specifications used as input to the regular `Common Test`\nserver. The syntax is described in section\n[Test Specifications](run_test_chapter.md#test_specifications) in section\nRunning Tests and Analyzing Results.\n\nAll test specification terms can have a `NodeRefs` element. This element\nspecifies which node or nodes a configuration operation or a test is to be\nexecuted on. `NodeRefs` is defined as follows:\n\n`NodeRefs = all_nodes | [NodeRef] | NodeRef`\n\n`NodeRef = NodeAlias | node() | master`\n\nA `NodeAlias` (`t:atom/0`) is used in a test specification as a reference to a\nnode name (so the node name only needs to be declared once, which also can be\nachieved using constants). The alias is declared with a `node` term as follows:\n\n`{node, NodeAlias, NodeName}`\n\nIf `NodeRefs` has the value `all_nodes`, the operation or test is performed on\nall specified test nodes. (Declaring a term without a `NodeRefs` element has the\nsame effect). If `NodeRefs` has the value `master`, the operation is only\nperformed on the `Common Test` Master node (namely set the log directory or\ninstall an event handler).\n\nConsider the example in section\n[Test Specifications](run_test_chapter.md#test_specifications) in section\nRunning Tests and Analysing Results, now extended with node information and\nintended to be executed by `Common Test` Master:\n\n```erlang\n{define, 'Top', \"/home/test\"}.\n{define, 'T1', \"'Top'/t1\"}.\n{define, 'T2', \"'Top'/t2\"}.\n{define, 'T3', \"'Top'/t3\"}.\n{define, 'CfgFile', \"config.cfg\"}.\n{define, 'Node', ct_node}.\n\n{node, node1, 'Node@host_x'}.\n{node, node2, 'Node@host_y'}.\n\n{logdir, master, \"'Top'/master_logs\"}.\n{logdir, \"'Top'/logs\"}.\n\n{config, node1, \"'T1'/'CfgFile'\"}.\n{config, node2, \"'T2'/'CfgFile'\"}.\n{config, \"'T3'/'CfgFile'\"}.\n\n{suites, node1, 'T1', all}.\n{skip_suites, node1, 'T1', [t1B_SUITE,t1D_SUITE], \"Not implemented\"}.\n{skip_cases, node1, 'T1', t1A_SUITE, [test3,test4], \"Irrelevant\"}.\n{skip_cases, node1, 'T1', t1C_SUITE, [test1], \"Ignore\"}.\n\n{suites, node2, 'T2', [t2B_SUITE,t2C_SUITE]}.\n{cases, node2, 'T2', t2A_SUITE, [test4,test1,test7]}.\n\n{skip_suites, 'T3', all, \"Not implemented\"}.\n```\n\nThis example specifies the same tests as the original example. But now if\nstarted with a call to `ct_master:run(TestSpecName)`, test `t1` is executed on\nnode `ct_node@host_x` (`node1`), test `t2` on `ct_node@host_y` (`node2`) and\ntest `t3` on both `node1` and `node2`. Configuration file `t1` is only read on\n`node1` and configuration file `t2` only on `node2`, while the configuration\nfile `t3` is read on both `node1` and `node2`. Both test nodes write log files\nto the same directory. (However, the `Common Test` Master node uses a different\nlog directory than the test nodes.)\n\nIf the test session is instead started with a call to\n`ct_master:run(TestSpecName, [ct_node@host_z], [ct_node@host_x])`, the result is\nthat test `t1` does not run on `ct_node@host_x` (or any other node) while test\n`t3` runs on both `ct_node@host_y` and `ct_node@host_z`.\n\nA nice feature is that a test specification that includes node information can\nstill be used as input to the regular `Common Test` server (as described in\nsection [Test Specifications](run_test_chapter.md#test_specifications)). The\nresult is that any test specified to run on a node with the same name as the\n`Common Test` node in question (typically `ct@somehost` if started with the\n`ct_run` program), is performed. Tests without explicit node association are\nalways performed too, of course.","ref":"ct_master_chapter.html#test-specifications"},{"type":"extras","title":"Automatic Startup of Test Target Nodes - Using Common Test for Large-Scale Testing","doc":"[](){: #ct_slave }\n\nInitial actions can be started and performed automatically on test target nodes\nusing test specification term `init`.\n\nTwo subterms are supported, `node_start` and `eval`.\n\n_Example:_\n\n```erlang\n{node, node1, node1@host1}.\n{node, node2, node1@host2}.\n{node, node3, node2@host2}.\n{node, node4, node1@host3}.\n{init, node1, [{node_start, [{callback_module, my_slave_callback}]}]}.\n{init, [node2, node3], {node_start, [{username, \"ct_user\"}, {password, \"ct_password\"}]}}.\n{init, node4, {eval, {module, function, []}}}.\n```\n\nThis test specification declares that `node1@host1` is to be started using the\nuser callback function `callback_module:my_slave_callback/0`, and nodes\n`node1@host2` and `node2@host2` are to be started with the default callback\nmodule `ct_slave`. The specified username and password are used to log on to\nremote host `host2`. Also, function `module:function/0` is evaluated on\n`node1@host3`, and the result of this call is printed to the log.\n\nThe default callback module `m:ct_slave`, has the following features:\n\n- Starting Erlang target nodes on local or remote hosts (application `SSH` is\n used for communication).\n- Ability to start an Erlang emulator with more flags (any flags supported by\n `erl` are supported).\n- Supervision of a node being started using internal callback functions. Used to\n prevent hanging nodes. (Configurable.)\n- Monitoring of the master node by the slaves. A slave node can be stopped if\n the master node terminates. (Configurable.)\n- Execution of user functions after a slave node is started. Functions can be\n specified as a list of `{Module, Function, Arguments}` tuples.\n\n> #### Note {: .info }\n>\n> An `eval` term for the node and `startup_functions` in the `node_start`\n> options list can be specified. In this case, the node is started first, then\n> the `startup_functions` are executed, and finally functions specified with\n> `eval` are called.","ref":"ct_master_chapter.html#automatic-startup-of-test-target-nodes"},{"type":"extras","title":"Event Handling","doc":"\n# Event Handling\n\n[](){: #event_handling }","ref":"event_handler_chapter.html"},{"type":"extras","title":"General - Event Handling","doc":"The operator of a `Common Test` system can receive event notifications\ncontinuously during a test run. For example, `Common Test` reports when a test\ncase starts and stops, the current count of successful, failed, and skipped\ncases, and so on. This information can be used for different purposes such as\nlogging progress and results in another format than HTML, saving statistics to a\ndatabase for report generation, and test system supervision.\n\n`Common Test` has a framework for event handling based on the OTP event manager\nconcept and `gen_event` behavior. When the `Common Test` server starts, it\nspawns an event manager. During test execution the manager gets a notification\nfrom the server when something of potential interest happens. Any event handler\nplugged into the event manager can match on events of interest, take action, or\npass the information on. The event handlers are Erlang modules implemented by\nthe `Common Test` user according to the `gen_event` behavior (for details, see\nmodule `m:gen_event` and section [`gen_event Behaviour`](`e:system:events.md`)\nin OTP Design Principles in the System Documentation).\n\nA `Common Test` server always starts an event manager. The server also plugs in\na default event handler, which only purpose is to relay notifications to a\nglobally registered `Common Test` Master event manager (if a `Common Test`\nMaster server is running in the system). The `Common Test` Master also spawns an\nevent manager at startup. Event handlers plugged into this manager receives the\nevents from all the test nodes, plus information from the `Common Test` Master\nserver.\n\nUser-specific event handlers can be plugged into a `Common Test` event manager,\neither by telling `Common Test` to install them before the test run (described\nlater), or by adding the handlers dynamically during the test run using\n`gen_event:add_handler/3` or `gen_event:add_sup_handler/3`. In the latter\nscenario, the reference of the `Common Test` event manager is required. To get\nit, call `ct:get_event_mgr_ref/0` or (on the `Common Test` Master node)\n`ct_master:get_event_mgr_ref/0`.\n\n[](){: #usage }","ref":"event_handler_chapter.html#general"},{"type":"extras","title":"Use - Event Handling","doc":"Event handlers can be installed by an `event_handler` start flag\n([`ct_run`](ct_run_cmd.md)) or option `ct:run_test/1`, where the argument\nspecifies the names of one or more event handler modules.\n\n_Example:_\n\n`$ ct_run -suite test/my_SUITE -event_handler handlers/my_evh1 handlers/my_evh2 -pa $PWD/handlers`\n\nTo pass start arguments to the event handler init function, use option\n`ct_run -event_handler_init` instead of `-event_handler`.\n\n> #### Note {: .info }\n>\n> All event handler modules must have `gen_event` behavior. These modules must\n> be precompiled and their locations must be added explicitly to the Erlang code\n> server search path (as in the previous example).\n\nAn event_handler tuple in argument `Opts` has the following definition (see\n`ct:run_test/1`):\n\n```erlang\n{event_handler,EventHandlers}\n\nEventHandlers = EH | [EH]\nEH = atom() | {atom(),InitArgs} | {[atom()],InitArgs}\nInitArgs = [term()]\n```\n\nIn the following example, two event handlers for the `my_SUITE` test are\ninstalled:\n\n```erlang\n1> ct:run_test([{suite,\"test/my_SUITE\"},{event_handler,[my_evh1,{my_evh2,[node()]}]}]).\n```\n\nEvent handler `my_evh1` is started with `[]` as argument to the init function.\nEvent handler `my_evh2` is started with the name of the current node in the init\nargument list.\n\nEvent handlers can also be plugged in using one of the following\n[test specification](run_test_chapter.md#test_specifications) terms:\n\n- `{event_handler, EventHandlers}`\n- `{event_handler, EventHandlers, InitArgs}`\n- `{event_handler, NodeRefs, EventHandlers}`\n- `{event_handler, NodeRefs, EventHandlers, InitArgs}`\n\n`EventHandlers` is a list of module names. Before a test session starts, the\ninit function of each plugged in event handler is called (with the `InitArgs`\nlist as argument or `[]` if no start arguments are specified).\n\nTo plug in a handler to the `Common Test` Master event manager, specify `master`\nas the node in `NodeRefs`.\n\nTo be able to match on events, the event handler module must include the header\nfile `ct_event.hrl`. An event is a record with the following definition:\n\n`#event{name, node, data}`\n\n- **`name`** - Label (type) of the event.\n\n- **`node`** - Name of the node that the event originated from (only relevant\n for `Common Test` Master event handlers).\n\n- **`data`** - Specific for the event.\n\n[](){: #events }","ref":"event_handler_chapter.html#use"},{"type":"extras","title":"General Events - Event Handling","doc":"The general events are as follows:\n\n- **`#event{name = start_logging, data = LogDir}`** - `LogDir = string()`,\n top-level log directory for the test run.\n\n This event indicates that the logging process of `Common Test` has started\n successfully and is ready to receive I/O messages.\n\n- **`#event{name = stop_logging, data = []}`** - This event indicates that the\n logging process of `Common Test` was shut down at the end of the test run.\n\n- **`#event{name = test_start, data = {StartTime,LogDir}}`** -\n `StartTime = {date(),time()}`, test run start date and time.\n\n `LogDir = string()`, top-level log directory for the test run.\n\n This event indicates that `Common Test` has finished initial preparations and\n begins executing test cases.\n\n- **`#event{name = test_done, data = EndTime}`** - `EndTime = {date(),time()}`,\n date and time the test run finished.\n\n This event indicates that the last test case has been executed and\n `Common Test` is shutting down.\n\n- **`#event{name = start_info, data = {Tests,Suites,Cases}}`** -\n `Tests = integer()`, number of tests.\n\n `Suites = integer()`, total number of suites.\n\n `Cases = integer() | unknown`, total number of test cases.\n\n This event gives initial test run information that can be interpreted as:\n \"This test run will execute `Tests` separate tests, in total containing\n `Cases` number of test cases, in `Suites` number of suites\". However, if a\n test case group with a repeat property exists in any test, the total number of\n test cases cannot be calculated (unknown).\n\n- **`#event{name = tc_start, data = {Suite,FuncOrGroup}}`** - `Suite = atom()`,\n name of the test suite.\n\n `FuncOrGroup = Func | {Conf,GroupName,GroupProperties}`\n\n `Func = atom()`, name of test case or configuration function.\n\n `Conf = init_per_group | end_per_group`, group configuration function.\n\n `GroupName = atom()`, name of the group.\n\n `GroupProperties = list()`, list of execution properties for the group.\n\n This event informs about the start of a test case, or a group configuration\n function. The event is sent also for `init_per_suite` and `end_per_suite`, but\n not for `init_per_testcase` and `end_per_testcase`. If a group configuration\n function starts, the group name and execution properties are also specified.\n\n- **`#event{name = tc_logfile, data = {{Suite,Func},LogFileName}}`** -\n `Suite = atom()`, name of the test suite.\n\n `Func = atom()`, name of test case or configuration function.\n\n `LogFileName = string()`, full name of the test case log file.\n\n This event is sent at the start of each test case (and configuration function\n except `init/end_per_testcase`) and carries information about the full name\n (that is, the file name including the absolute directory path) of the current\n test case log file.\n\n- **`#event{name = tc_done, data = {Suite,FuncOrGroup,Result}}`** - [](){:\n #tc_done } `Suite = atom()`, name of the suite.\n\n `FuncOrGroup = Func | {Conf,GroupName,GroupProperties}`\n\n `Func = atom()`, name of test case or configuration function.\n\n `Conf = init_per_group | end_per_group`, group configuration function.\n\n `GroupName = unknown | atom()`, name of the group (unknown if init- or end\n function times out).\n\n `GroupProperties = list()`, list of execution properties for the group.\n\n `Result = ok | {auto_skipped,SkipReason} | {skipped,SkipReason} | {failed,FailReason}`,\n the result.\n\n [](){: #skipreason }\n `SkipReason = {require_failed,RequireInfo} | {require_failed_in_suite0,RequireInfo} | {failed,{Suite,init_per_testcase,FailInfo}} | UserTerm`,\n why the case was skipped.\n\n [](){: #failreason }\n `FailReason = {error,FailInfo} | {error,{RunTimeError,StackTrace}} | {timetrap_timeout,integer()} | {failed,{Suite,end_per_testcase,FailInfo}}`,\n reason for failure.\n\n `RequireInfo = {not_available,atom() | tuple()}`, why require failed.\n\n `FailInfo = {timetrap_timeout,integer()} | {RunTimeError,StackTrace} | UserTerm`,\n error details.\n\n `RunTimeError = term()`, a runtime error, for example, `badmatch` or `undef`.\n\n `StackTrace = list()`, list of function calls preceding a runtime error.\n\n `UserTerm = term()`, any data specified by user, or [`exit/1`](`exit/1`)\n information.\n\n This event informs about the end of a test case or a configuration function\n (see event `tc_start` for details on element `FuncOrGroup`). With this event\n comes the final result of the function in question. It is possible to\n determine on the top level of `Result` if the function was successful, skipped\n (by the user), or if it failed.\n\n It is also possible to dig deeper and, for example, perform pattern matching\n on the various reasons for skipped or failed. Notice that `{'EXIT',Reason}`\n tuples are translated into `{error,Reason}`. Notice also that if a\n `{failed,{Suite,end_per_testcase,FailInfo}` result is received, the test case\n was successful, but `end_per_testcase` for the case failed.\n\n- **`#event{name = tc_auto_skip, data = {Suite,TestName,Reason}}`** - [](){:\n #tc_auto_skip } `Suite = atom()`, the name of the suite.\n\n `TestName = init_per_suite | end_per_suite | {init_per_group,GroupName} | {end_per_group,GroupName} | {FuncName,GroupName} | FuncName`\n\n `FuncName = atom()`, the name of the test case or configuration function.\n\n `GroupName = atom()`, the name of the test case group.\n\n `Reason = {failed,FailReason} | {require_failed_in_suite0,RequireInfo}`,\n reason for auto-skipping `Func`.\n\n `FailReason = {Suite,ConfigFunc,FailInfo}} | {Suite,FailedCaseInSequence}`,\n reason for failure.\n\n `RequireInfo = {not_available,atom() | tuple()}`, why require failed.\n\n `ConfigFunc = init_per_suite | init_per_group`\n\n `FailInfo = {timetrap_timeout,integer()} | {RunTimeError,StackTrace} | bad_return | UserTerm`,\n error details.\n\n `FailedCaseInSequence = atom()`, the name of a case that failed in a sequence.\n\n `RunTimeError = term()`, a runtime error, for example `badmatch` or `undef`.\n\n `StackTrace = list()`, list of function calls preceding a runtime error.\n\n `UserTerm = term()`, any data specified by user, or [`exit/1`](`exit/1`)\n information.\n\n This event is sent for every test case or configuration function that\n `Common Test` has skipped automatically because of either a failed\n `init_per_suite` or `init_per_group`, a failed `require` in `suite/0`, or a\n failed test case in a sequence. Notice that this event is never received as a\n result of a test case getting skipped because of `init_per_testcase` failing,\n as that information is carried with event `tc_done`. If a failed test case\n belongs to a test case group, the second data element is a tuple\n `{FuncName,GroupName}`, otherwise only the function name.\n\n- **`#event{name = tc_user_skip, data = {Suite,TestName,Comment}}`** - [](){:\n #tc_user_skip } `Suite = atom()`, the name of the suite.\n\n `TestName = init_per_suite | end_per_suite | {init_per_group,GroupName} | {end_per_group,GroupName} | {FuncName,GroupName} | FuncName`\n\n `FuncName = atom()`, the name of the test case or configuration function.\n\n `GroupName = atom()`, the name of the test case group.\n\n `Comment = string()`, why the test case was skipped.\n\n This event specifies that a test case was skipped by the user. It is only\n received if the skip is declared in a test specification. Otherwise, user skip\n information is received as a `{skipped,SkipReason}` result in event `tc_done`\n for the test case. If a skipped test case belongs to a test case group, the\n second data element is a tuple `{FuncName,GroupName}`, otherwise only the\n function name.\n\n- **`#event{name = test_stats, data = {Ok,Failed,Skipped}}`** -\n `Ok = integer()`, current number of successful test cases.\n\n `Failed = integer()`, current number of failed test cases.\n\n `Skipped = {UserSkipped,AutoSkipped}`\n\n `UserSkipped = integer()`, current number of user-skipped test cases.\n\n `AutoSkipped = integer()`, current number of auto-skipped test cases.\n\n This is a statistics event with current count of successful, skipped, and\n failed test cases so far. This event is sent after the end of each test case,\n immediately following event `tc_done`.","ref":"event_handler_chapter.html#general-events"},{"type":"extras","title":"Internal Events - Event Handling","doc":"The internal events are as follows:\n\n- **`#event{name = start_make, data = Dir}`** - `Dir = string()`, running make\n in this directory.\n\n This internal event says that `Common Test` starts compiling modules in\n directory `Dir`.\n\n- **`#event{name = finished_make, data = Dir}`** - `Dir = string()`, finished\n running make in this directory.\n\n This internal event says that `Common Test` is finished compiling modules in\n directory `Dir`.\n\n- **`#event{name = start_write_file, data = FullNameFile}`** -\n `FullNameFile = string(), full name of the file.`\n\n This internal event is used by the `Common Test` Master process to synchronize\n particular file operations.\n\n- **`#event{name = finished_write_file, data = FullNameFile}`** -\n `FullNameFile = string(), full name of the file.`\n\n This internal event is used by the `Common Test` Master process to synchronize\n particular file operations.","ref":"event_handler_chapter.html#internal-events"},{"type":"extras","title":"Notes - Event Handling","doc":"The events are also documented in `ct_event.erl`. This module can serve as an\nexample of what an event handler for the `Common Test` event manager can look\nlike.\n\n> #### Note {: .info }\n>\n> To ensure that printouts to `stdout` (or printouts made with\n> [`ct:log/2,3`](`ct:log/2`) or [`ct:pal,2,3`](`ct:pal/2`)) get written to the\n> test case log file, and not to the `Common Test` framework log, you can\n> synchronize with the `Common Test` server by matching on events `tc_start` and\n> `tc_done`. In the period between these events, all I/O is directed to the test\n> case log file. These events are sent synchronously to avoid potential timing\n> problems (for example, that the test case log file is closed just before an\n> I/O message from an external process gets through). Knowing this, you need to\n> be careful that your `handle_event/2` callback function does not stall the\n> test execution, possibly causing unexpected behavior as a result.","ref":"event_handler_chapter.html#notes"},{"type":"extras","title":"Dependencies between Test Cases and Suites","doc":"\n# Dependencies between Test Cases and Suites","ref":"dependencies_chapter.html"},{"type":"extras","title":"General - Dependencies between Test Cases and Suites","doc":"When creating test suites, it is strongly recommended to not create dependencies\nbetween test cases, that is, letting test cases depend on the result of previous\ntest cases. There are various reasons for this, such as, the following:\n\n- It makes it impossible to run test cases individually.\n- It makes it impossible to run test cases in a different order.\n- It makes debugging difficult (as a fault can be the result of a problem in a\n different test case than the one failing).\n- There are no good and explicit ways to declare dependencies, so it can be\n difficult to see and understand these in test suite code and in test logs.\n- Extending, restructuring, and maintaining test suites with test case\n dependencies is difficult.\n\nThere are often sufficient means to work around the need for test case\ndependencies. Generally, the problem is related to the state of the System Under\nTest (SUT). The action of one test case can change the system state. For some\nother test case to run properly, this new state must be known.\n\nInstead of passing data between test cases, it is recommended that the test\ncases read the state from the SUT and perform assertions (that is, let the test\ncase run if the state is as expected, otherwise reset or fail). It is also\nrecommended to use the state to set variables necessary for the test case to\nexecute properly. Common actions can often be implemented as library functions\nfor test cases to call to set the SUT in a required state. (Such common actions\ncan also be separately tested, if necessary, to ensure that they work as\nexpected). It is sometimes also possible, but not always desirable, to group\ntests together in one test case, that is, let a test case perform a \"scenario\"\ntest (a test consisting of subtests).\n\nConsider, for example, a server application under test. The following\nfunctionality is to be tested:\n\n- Starting the server\n- Configuring the server\n- Connecting a client to the server\n- Disconnecting a client from the server\n- Stopping the server\n\nThere are obvious dependencies between the listed functions. The server cannot\nbe configured if it has not first been started, a client cannot be connected\nuntil the server is properly configured, and so on. If we want to have one test\ncase for each function, we might be tempted to try to always run the test cases\nin the stated order and carry possible data (identities, handles, and so on)\nbetween the cases and therefore introduce dependencies between them.\n\nTo avoid this, we can consider starting and stopping the server for every test.\nWe can thus implement the start and stop action as common functions to be called\nfrom [`init_per_testcase`](`c:ct_suite:init_per_testcase/2`) and\n[`end_per_testcase`](`c:ct_suite:end_per_testcase/2`). (Remember to test the\nstart and stop functionality separately.) The configuration can also be\nimplemented as a common function, maybe grouped with the start function.\nFinally, the testing of connecting and disconnecting a client can be grouped\ninto one test case. The resulting suite can look as follows:\n\n```erlang\n-module(my_server_SUITE).\n-compile(export_all).\n-include_lib(\"ct.hrl\").\n\n%%% init and end functions...\n\nsuite() -> [{require,my_server_cfg}].\n\ninit_per_testcase(start_and_stop, Config) ->\n Config;\n\ninit_per_testcase(config, Config) ->\n [{server_pid,start_server()} | Config];\n\ninit_per_testcase(_, Config) ->\n ServerPid = start_server(),\n configure_server(),\n [{server_pid,ServerPid} | Config].\n\nend_per_testcase(start_and_stop, _) ->\n ok;\n\nend_per_testcase(_, Config) ->\n ServerPid = proplists:get_value(server_pid, Config),\n stop_server(ServerPid).\n\n%%% test cases...\n\nall() -> [start_and_stop, config, connect_and_disconnect].\n\n%% test that starting and stopping works\nstart_and_stop(_) ->\n ServerPid = start_server(),\n stop_server(ServerPid).\n\n%% configuration test\nconfig(Config) ->\n ServerPid = proplists:get_value(server_pid, Config),\n configure_server(ServerPid).\n\n%% test connecting and disconnecting client\nconnect_and_disconnect(Config) ->\n ServerPid = proplists:get_value(server_pid, Config),\n {ok,SessionId} = my_server:connect(ServerPid),\n ok = my_server:disconnect(ServerPid, SessionId).\n\n%%% common functions...\n\nstart_server() ->\n {ok,ServerPid} = my_server:start(),\n ServerPid.\n\nstop_server(ServerPid) ->\n ok = my_server:stop(),\n ok.\n\nconfigure_server(ServerPid) ->\n ServerCfgData = ct:get_config(my_server_cfg),\n ok = my_server:configure(ServerPid, ServerCfgData),\n ok.\n```\n\n[](){: #save_config }","ref":"dependencies_chapter.html#general"},{"type":"extras","title":"Saving Configuration Data - Dependencies between Test Cases and Suites","doc":"Sometimes it is impossible, or infeasible, to implement independent test cases.\nMaybe it is not possible to read the SUT state. Maybe resetting the SUT is\nimpossible and it takes too long time to restart the system. In situations where\ntest case dependency is necessary, CT offers a structured way to carry data from\none test case to the next. The same mechanism can also be used to carry data\nfrom one test suite to the next.\n\nThe mechanism for passing data is called `save_config`. The idea is that one\ntest case (or suite) can save the current value of `Config`, or any list of\nkey-value tuples, so that the next executing test case (or test suite) can read\nit. The configuration data is not saved permanently but can only be passed from\none case (or suite) to the next.\n\nTo save `Config` data, return tuple `{save_config,ConfigList}` from\n`end_per_testcase` or from the main test case function.\n\nTo read data saved by a previous test case, use `proplists:get_value` with a\n`saved_config` key as follows:\n\n`{Saver,ConfigList} = proplists:get_value(saved_config, Config)`\n\n`Saver` (`t:atom/0`) is the name of the previous test case (where the data was\nsaved). The `proplists:get_value` function can be used to extract particular\ndata also from the recalled `ConfigList`. It is strongly recommended that\n`Saver` is always matched to the expected name of the saving test case. This\nway, problems because of restructuring of the test suite can be avoided. Also,\nit makes the dependency more explicit and the test suite easier to read and\nmaintain.\n\nTo pass data from one test suite to another, the same mechanism is used. The\ndata is to be saved by finction [`end_per_suite`](`c:ct_suite:end_per_suite/1`)\nand read by function [`init_per_suite`](`c:ct_suite:init_per_suite/1`) in the\nsuite that follows. When passing data between suites, `Saver` carries the name\nof the test suite.\n\n_Example:_\n\n```erlang\n-module(server_b_SUITE).\n-compile(export_all).\n-include_lib(\"ct.hrl\").\n\n%%% init and end functions...\n\ninit_per_suite(Config) ->\n %% read config saved by previous test suite\n {server_a_SUITE,OldConfig} = proplists:get_value(saved_config, Config),\n %% extract server identity (comes from server_a_SUITE)\n ServerId = proplists:get_value(server_id, OldConfig),\n SessionId = connect_to_server(ServerId),\n [{ids,{ServerId,SessionId}} | Config].\n\nend_per_suite(Config) ->\n %% save config for server_c_SUITE (session_id and server_id)\n {save_config,Config}\n\n%%% test cases...\n\nall() -> [allocate, deallocate].\n\nallocate(Config) ->\n {ServerId,SessionId} = proplists:get_value(ids, Config),\n {ok,Handle} = allocate_resource(ServerId, SessionId),\n %% save handle for deallocation test\n NewConfig = [{handle,Handle}],\n {save_config,NewConfig}.\n\ndeallocate(Config) ->\n {ServerId,SessionId} = proplists:get_value(ids, Config),\n {allocate,OldConfig} = proplists:get_value(saved_config, Config),\n Handle = proplists:get_value(handle, OldConfig),\n ok = deallocate_resource(ServerId, SessionId, Handle).\n```\n\nTo save `Config` data from a test case that is to be skipped, return tuple\n`{skip_and_save,Reason,ConfigList}`.\n\nThe result is that the test case is skipped with `Reason` printed to the log\nfile (as described earlier) and `ConfigList` is saved for the next test case.\n`ConfigList` can be read using `proplists:get_value(saved_config, Config)`, as\ndescribed earlier. `skip_and_save` can also be returned from `init_per_suite`.\nIn this case, the saved data can be read by `init_per_suite` in the suite that\nfollows.","ref":"dependencies_chapter.html#saving-configuration-data"},{"type":"extras","title":"Sequences - Dependencies between Test Cases and Suites","doc":"Sometimes test cases depend on each other so that if one case fails, the\nfollowing tests are not to be executed. Typically, if the `save_config` facility\nis used and a test case that is expected to save data crashes, the following\ncase cannot run. `Common Test` offers a way to declare such dependencies, called\nsequences.\n\nA sequence of test cases is defined as a test case group with a `sequence`\nproperty. Test case groups are defined through function `groups/0` in the test\nsuite (for details, see section\n[Test Case Groups](write_test_chapter.md#test_case_groups).\n\nFor example, to ensure that if `allocate` in `server_b_SUITE` crashes,\n`deallocate` is skipped, the following sequence can be defined:\n\n```erlang\ngroups() -> [{alloc_and_dealloc, [sequence], [alloc,dealloc]}].\n```\n\nAssume that the suite contains the test case `get_resource_status` that is\nindependent of the other two cases, then function `all` can look as follows:\n\n```erlang\nall() -> [{group,alloc_and_dealloc}, get_resource_status].\n```\n\nIf `alloc` succeeds, `dealloc` is also executed. If `alloc` fails however,\n`dealloc` is not executed but marked as `SKIPPED` in the HTML log.\n`get_resource_status` runs no matter what happens to the `alloc_and_dealloc`\ncases.\n\nTest cases in a sequence are executed in order until all succeed or one fails.\nIf one fails, all following cases in the sequence are skipped. The cases in the\nsequence that have succeeded up to that point are reported as successful in the\nlog. Any number of sequences can be specified.\n\n_Example:_\n\n```erlang\ngroups() -> [{scenarioA, [sequence], [testA1, testA2]},\n {scenarioB, [sequence], [testB1, testB2, testB3]}].\n\nall() -> [test1,\n test2,\n {group,scenarioA},\n test3,\n {group,scenarioB},\n test4].\n```\n\nA sequence group can have subgroups. Such subgroups can have any property, that\nis, they are not required to also be sequences. If you want the status of the\nsubgroup to affect the sequence on the level above, return\n`{return_group_result,Status}` from\n[`end_per_group/2`](`c:ct_suite:end_per_group/2`), as described in section\n[Repeated Groups](write_test_chapter.md#repeated_groups) in Writing Test Suites.\nA failed subgroup (`Status == failed`) causes the execution of a sequence to\nfail in the same way a test case does.","ref":"dependencies_chapter.html#sequences"},{"type":"extras","title":"Common Test Hooks","doc":"\n# Common Test Hooks","ref":"ct_hooks_chapter.html"},{"type":"extras","title":"General - Common Test Hooks","doc":"The _Common Test Hook (CTH)_ framework allows extensions of the default behavior\nof `Common Test` using hooks before and after all test suite calls. CTHs allow\nadvanced `Common Test` users to abstract out behavior that is common to multiple\ntest suites without littering all test suites with library calls. This can be\nused for logging, starting, and monitoring external systems, building C files\nneeded by the tests, and so on.\n\nIn brief, CTH allows you to do the following:\n\n- Manipulate the runtime configuration before each suite configuration call.\n- Manipulate the return of all suite configuration calls, and in extension, the\n result of the tests themselves.\n\nThe following sections describe how to use CTHs, when they are run, and how to\nmanipulate the test results in a CTH.\n\n> #### Warning {: .warning }\n>\n> When executing within a CTH, all timetraps are shut off. So if your CTH never\n> returns, the entire test run is stalled.\n\n[](){: #installing }","ref":"ct_hooks_chapter.html#general"},{"type":"extras","title":"Installing a CTH - Common Test Hooks","doc":"A CTH can be installed in multiple ways in your test run. You can do it for all\ntests in a run, for specific test suites, and for specific groups within a test\nsuite. If you want a CTH to be present in all test suites within your test run,\nthere are three ways to accomplish that, as follows:\n\n- Add `-ct_hooks` as an argument to [ct_run](run_test_chapter.md#ct_run). To add\n multiple CTHs using this method, append them to each other using the keyword\n `and`, that is, `ct_run -ct_hooks cth1 [{debug,true}] and cth2 ...`.\n- Add tag `ct_hooks` to your\n [Test Specification](run_test_chapter.md#test_specifications).\n- Add tag `ct_hooks` to your call to `ct:run_test/1`.\n\nCTHs can also be added within a test suite. This is done by returning\n`{ct_hooks,[CTH]}` in the configuration list from\n[suite/0](`c:ct_suite:suite/0`),\n[init_per_suite/1](`c:ct_suite:init_per_suite/1`), or\n[init_per_group/2](`c:ct_suite:init_per_group/2`).\n\nIn this case, `CTH` can either be only the module name of the CTH or a tuple\nwith the module name and the initial arguments, and optionally the hook priority\nof the CTH. For example, one of the following:\n\n- `{ct_hooks,[my_cth_module]}`\n- `{ct_hooks,[{my_cth_module,[{debug,true}]}]}`\n- `{ct_hooks,[{my_cth_module,[{debug,true}],500}]}`\n\nNote that regardless of how you install a CTH, its BEAM file must be available\nin the code path when Common Test runs. `ct_run` accepts the `-pa` command line\noption.","ref":"ct_hooks_chapter.html#installing-a-cth"},{"type":"extras","title":"Overriding CTHs - Common Test Hooks","doc":"By default, each installation of a CTH causes a new instance of it to be\nactivated. This can cause problems if you want to override CTHs in test\nspecifications while still having them in the suite information function. The\n[id/1](`c:ct_hooks:id/1`) callback exists to address this problem. By returning\nthe same `id` in both places, `Common Test` knows that this CTH is already\ninstalled and does not try to install it again.\n\n[](){: #cth_execution_order }","ref":"ct_hooks_chapter.html#overriding-cths"},{"type":"extras","title":"CTH Execution Order - Common Test Hooks","doc":"By default, each installed CTH is executed in the order in which they are\ninstalled for init calls, and then reversed for end calls. This order can be\nreferred to as test-centric, as the order is reversed after a testcase is\nexecuted and corresponds to the default value (`test`) of `ct_hooks_order`\noption.\n\nThe installation-based order is not always desired, so `Common Test` allows the\nuser to specify a priority for each hook. The priority can be specified in the\nCTH function [init/2](`c:ct_hooks:init/2`) or when installing the hook. The\npriority specified at installation overrides the priority returned by the CTH.\n\nIn some cases, the reversed order for all end calls is not desired, and instead,\nthe user might prefer the reversed order for post hook calls. Such behavior can\nbe enabled with `ct_hooks_order` option with `config` value. When this option is\nenabled, the execution order is configuration-centric, as the reversed order\nhappens after each configuration function and not in relation to testcase.\n\nNote that the `ct_hooks_order` option is considered as a global framework\nsetting. In case when option is configured multiple times framework with process\nonly the first value.\n\nThe `ct_hooks_order` option can be set as: `ct_run` argument, in test\nspecification or [suite/0](`c:ct_suite:suite/0`) return value.\n\n[](){: #scope }","ref":"ct_hooks_chapter.html#cth-execution-order"},{"type":"extras","title":"CTH Scope - Common Test Hooks","doc":"Once the CTH is installed into a certain test run it remains there until its\nscope is expired. The scope of a CTH depends on when it is installed, see the\nfollowing table. Function [init/2](`c:ct_hooks:init/2`) is called at the\nbeginning of the scope and function [terminate/1](`c:ct_hooks:terminate/1`) is\ncalled when the scope ends.\n\n| _CTH installed in_ | _CTH scope begins before_ | _CTH scope ends after_ |\n| ------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |\n| [ct_run](run_test_chapter.md#ct_run) | the first test suite is to be run | the last test suite has been run |\n| [ct:run_test](`ct:run_test/1`) | the first test suite is run | the last test suite has been run |\n| [Test Specification](run_test_chapter.md#test_specifications) | the first test suite is run | the last test suite has been run |\n| [suite/0](`c:ct_suite:suite/0`) | [pre_init_per_suite/3](`c:ct_hooks:pre_init_per_suite/3`) is called | [post_end_per_suite/4](`c:ct_hooks:post_end_per_suite/4`) has been called for that test suite |\n| [init_per_suite/1](`c:ct_suite:init_per_suite/1`) | [post_init_per_suite/4](`c:ct_hooks:post_init_per_suite/4`) is called | [post_end_per_suite/4](`c:ct_hooks:post_end_per_suite/4`) has been called for that test suite |\n| [init_per_group/2](`c:ct_suite:init_per_group/2`) | [post_init_per_group/5](`c:ct_hooks:post_init_per_group/5`) is called | [post_end_per_group/5](`c:ct_hooks:post_end_per_group/5`) has been called for that group |\n\n_Table: Scope of a CTH_","ref":"ct_hooks_chapter.html#cth-scope"},{"type":"extras","title":"CTH Processes and Tables - Common Test Hooks","doc":"CTHs are run with the same process scoping as normal test suites, that is, a\ndifferent process executes the `init_per_suite` hooks then the `init_per_group`\nor `per_testcase` hooks. So if you want to spawn a process in the CTH, you\ncannot link with the CTH process, as it exits after the post hook ends. Also, if\nyou for some reason need an ETS table with your CTH, you must spawn a process\nthat handles it.","ref":"ct_hooks_chapter.html#cth-processes-and-tables"},{"type":"extras","title":"External Configuration Data and Logging - Common Test Hooks","doc":"Configuration data values in the CTH can be read by calling\n[`ct:get_config/1,2,3`](`ct:get_config/1`) (as explained in section\n[Requiring and Reading Configuration Data](config_file_chapter.md#require_config_data)).\nThe configuration variables in question must, as always, first have been\nrequired by a suite-, group-, or test case information function, or by function\n[`ct:require/1/2`](`ct:require/1`). The latter can also be used in CT hook\nfunctions.\n\nThe CT hook functions can call any logging function in the `ct` interface to\nprint information to the log files, or to add comments in the suite overview\npage.\n\n[](){: #manipulating }","ref":"ct_hooks_chapter.html#external-configuration-data-and-logging"},{"type":"extras","title":"Manipulating Tests - Common Test Hooks","doc":"Through CTHs the results of tests and configuration functions can be\nmanipulated. The main purpose to do this with CTHs is to allow common patterns\nto be abstracted out from test suites and applied to multiple test suites\nwithout duplicating any code. All the callback functions for a CTH follow a\ncommon interface described hereafter.\n\n`Common Test` always calls all available hook functions, even pre- and post\nhooks for configuration functions that are not implemented in the suite. For\nexample, `pre_init_per_suite(x_SUITE, ...)` and\n`post_init_per_suite(x_SUITE, ...)` are called for test suite `x_SUITE`, even if\nit does not export `init_per_suite/1`. With this feature hooks can be used as\nconfiguration fallbacks, and all configuration functions can be replaced with\nhook functions.\n\n[](){: #pre }","ref":"ct_hooks_chapter.html#manipulating-tests"},{"type":"extras","title":"Pre Hooks - Common Test Hooks","doc":"In a CTH, the behavior can be hooked in before the following functions:\n\n- [`init_per_suite`](`c:ct_suite:init_per_suite/1`)\n- [`init_per_group`](`c:ct_suite:init_per_group/2`)\n- [`init_per_testcase`](`c:ct_suite:init_per_testcase/2`)\n- [`end_per_testcase`](`c:ct_suite:end_per_testcase/2`)\n- [`end_per_group`](`c:ct_suite:end_per_group/2`)\n- [`end_per_suite`](`c:ct_suite:end_per_suite/1`)\n\nThis is done in the CTH functions called `pre_ `. These\nfunctions take the arguments `SuiteName`, `Name` (group or test case name, if\napplicable), `Config`, and `CTHState`. The return value of the CTH function is\nalways a combination of a result for the suite/group/test and an updated\n`CTHState`.\n\nTo let the test suite continue on executing, return the configuration list that\nyou want the test to use as the result.\n\nAll pre hooks, except `pre_end_per_testcase/4`, can skip or fail the test by\nreturning a tuple with `skip` or `fail`, and a reason as the result.\n\n_Example:_\n\n```erlang\npre_init_per_suite(SuiteName, Config, CTHState) ->\n case db:connect() of\n {error,_Reason} ->\n {{fail, \"Could not connect to DB\"}, CTHState};\n {ok, Handle} ->\n {[{db_handle, Handle} | Config], CTHState#state{ handle = Handle }}\n end.\n```\n\n> #### Note {: .info }\n>\n> If you use multiple CTHs, the first part of the return tuple is used as input\n> for the next CTH. So in the previous example the next CTH can get\n> `{fail,Reason}` as the second parameter. If you have many CTHs interacting, do\n> not let each CTH return `fail` or `skip`. Instead, return that an action is to\n> be taken through the `Config` list and implement a CTH that, at the end, takes\n> the correct action.\n\n[](){: #post }","ref":"ct_hooks_chapter.html#pre-hooks"},{"type":"extras","title":"Post Hooks - Common Test Hooks","doc":"In a CTH, behavior can be hooked in after the following functions:\n\n- [`init_per_suite`](`c:ct_suite:init_per_suite/1`)\n- [`init_per_group`](`c:ct_suite:init_per_group/2`)\n- [`init_per_testcase`](`c:ct_suite:init_per_testcase/2`)\n- [`end_per_testcase`](`c:ct_suite:end_per_testcase/2`)\n- [`end_per_group`](`c:ct_suite:end_per_group/2`)\n- [`end_per_suite`](`c:ct_suite:end_per_suite/1`)\n\nThis is done in the CTH functions called `post_ `. These\nfunctions take the arguments `SuiteName`, `Name` (group or test case name, if\napplicable), `Config`, `Return`, and `CTHState`. `Config` in this case is the\nsame `Config` as the testcase is called with. `Return` is the value returned by\nthe testcase. If the testcase fails by crashing, `Return` is\n`{'EXIT',{{Error,Reason},Stacktrace}}`.\n\nThe return value of the CTH function is always a combination of a result for the\nsuite/group/test and an updated `CTHState`. If you do not want the callback to\naffect the outcome of the test, return the `Return` data as it is given to the\nCTH. You can also modify the test result. By returning the `Config` list with\nelement `tc_status` removed, you can recover from a test failure. As in all the\npre hooks, it is also possible to fail/skip the test case in the post hook.\n\n_Example:_\n\n```erlang\npost_end_per_testcase(_Suite, _TC, Config, {'EXIT',{_,_}}, CTHState) ->\n case db:check_consistency() of\n true ->\n %% DB is good, pass the test.\n {proplists:delete(tc_status, Config), CTHState};\n false ->\n %% DB is not good, mark as skipped instead of failing\n {{skip, \"DB is inconsistent!\"}, CTHState}\n end;\npost_end_per_testcase(_Suite, _TC, Config, Return, CTHState) ->\n %% Do nothing if tc does not crash.\n {Return, CTHState}.\n```\n\n> #### Note {: .info }\n>\n> Do recover from a testcase failure using CTHs only a last resort. If used\n> wrongly, it can be very difficult to determine which tests that pass or fail\n> in a test run.","ref":"ct_hooks_chapter.html#post-hooks"},{"type":"extras","title":"Skip and Fail Hooks - Common Test Hooks","doc":"After any post hook has been executed for all installed CTHs,\n[on_tc_fail](`c:ct_hooks:on_tc_fail/4`) or\n[on_tc_skip](`c:ct_hooks:on_tc_skip/4`) is called if the testcase failed or was\nskipped, respectively. You cannot affect the outcome of the tests any further at\nthis point.\n\n[](){: #synchronizing }","ref":"ct_hooks_chapter.html#skip-and-fail-hooks"},{"type":"extras","title":"Synchronizing External User Applications with Common Test - Common Test Hooks","doc":"CTHs can be used to synchronize test runs with external user applications. The\ninit function can, for example, start and/or communicate with an application\nthat has the purpose of preparing the SUT for an upcoming test run, or\ninitialize a database for saving test data to during the test run. The terminate\nfunction can similarly order such an application to reset the SUT after the test\nrun, and/or tell the application to finish active sessions and terminate. Any\nsystem error- or progress reports generated during the init- or termination\nstage are saved in the\n[Pre- and Post Test I/O Log](run_test_chapter.md#pre_post_test_io_log). (This is\nalso true for any printouts made with `ct:log/2` and `ct:pal/2`).\n\nTo ensure that `Common Test` does not start executing tests, or closes its log\nfiles and shuts down, before the external application is ready for it,\n`Common Test` can be synchronized with the application. During startup and\nshutdown, `Common Test` can be suspended, simply by having a CTH evaluate a\n`receive` expression in the init- or terminate function. The macros\n`?CT_HOOK_INIT_PROCESS` (the process executing the hook init function) and\n`?CT_HOOK_TERMINATE_PROCESS` (the process executing the hook terminate function)\neach specifies the name of the correct `Common Test` process to send a message\nto. This is done to return from the `receive`. These macros are defined in\n`ct.hrl`.\n\n[](){: #example }","ref":"ct_hooks_chapter.html#synchronizing-external-user-applications-with-common-test"},{"type":"extras","title":"Example CTH - Common Test Hooks","doc":"The following CTH logs information about a test run into a format parseable by\n`file:consult/1` (in Kernel):\n\n```erlang\n%%% Common Test Example Common Test Hook module.\n%%%\n%%% To use this hook, on the command line:\n%%% ct_run -suite example_SUITE -pa . -ct_hooks example_cth\n%%%\n%%% Note `-pa .`: the hook beam file must be in the code path when installing.\n-module(example_cth).\n\n%% Mandatory Callbacks\n-export([init/2]).\n\n%% Optional Callbacks\n-export([id/1]).\n\n-export([pre_init_per_suite/3]).\n-export([post_end_per_suite/4]).\n\n-export([pre_init_per_testcase/4]).\n-export([post_end_per_testcase/5]).\n\n-export([on_tc_skip/4]).\n\n-export([terminate/1]).\n\n%% This hook state is threaded through all the callbacks.\n-record(state, {filename, total, suite_total, ts, tcs, data, skipped}).\n%% This example hook prints its results to a file, see terminate/1.\n-record(test_run, {total, skipped, suites}).\n\n%% Return a unique id for this CTH.\n%% Using the filename means the hook can be used with different\n%% log files to separate timing data within the same test run.\n%% See Installing a CTH for more information.\nid(Opts) ->\n %% the path is relative to the test run directory\n proplists:get_value(filename, Opts, \"example_cth.log\").\n\n%% Always called before any other callback function. Use this to initiate\n%% any common state.\ninit(Id, _Opts) ->\n {ok, #state{filename = Id, total = 0, data = []}}.\n\n%% Called before init_per_suite is called.\npre_init_per_suite(_Suite,Config,State) ->\n {Config, State#state{suite_total = 0, tcs = []}}.\n\n%% Called after end_per_suite.\npost_end_per_suite(Suite,_Config,Return,State) ->\n Data = {suites, Suite, State#state.suite_total,\n lists:reverse(State#state.tcs)},\n {Return, State#state{data = [Data | State#state.data],\n total = State#state.total + State#state.suite_total}}.\n\n%% Called before each init_per_testcase.\npre_init_per_testcase(_Suite,_TC,Config,State) ->\n Now = erlang:monotonic_time(microsecond),\n {Config, State#state{ts = Now, suite_total = State#state.suite_total + 1}}.\n\n%% Called after each end_per_testcase.\npost_end_per_testcase(Suite,TC,_Config,Return,State) ->\n Now = erlang:monotonic_time(microsecond),\n TCInfo = {testcase, Suite, TC, Return, Now - State#state.ts},\n {Return, State#state{ts = undefined, tcs = [TCInfo | State#state.tcs]}}.\n\n%% Called when a test case is skipped by either user action\n%% or due to an init function failing.\non_tc_skip(_Suite, _TC, _Reason, State) ->\n State#state{skipped = State#state.skipped + 1}.\n\n%% Called when the scope of the CTH is done.\nterminate(State) ->\n %% use append to avoid data loss if the path is reused\n {ok, File} = file:open(State#state.filename, [write, append]),\n io:format(File, \"~p.~n\", [results(State)]),\n file:close(File),\n ok.\n\nresults(State) ->\n #state{skipped = Skipped, data = Data, total = Total} = State,\n #test_run{total = Total, skipped = Skipped, suites = lists:reverse(Data)}.\n```\n\n[](){: #builtin_cths }","ref":"ct_hooks_chapter.html#example-cth"},{"type":"extras","title":"Built-In CTHs - Common Test Hooks","doc":"`Common Test` is delivered with some general-purpose CTHs that can be enabled by\nthe user to provide generic testing functionality. Some of these CTHs are\nenabled by default when `common_test` is started to run. They can be disabled by\nsetting `enable_builtin_hooks` to `false` on the command line or in the test\nspecification. The following two CTHs are delivered with `Common Test`:\n\n- **`cth_log_redirect`** - Built-in\n\n Captures all log events that would normally be printed by the default logger\n handler, and prints them to the current test case log. If an event cannot be\n associated with a test case, it is printed in the `Common Test` framework log.\n This happens for test cases running in parallel and events occurring\n in-between test cases.\n\n The log events are handled using a [Logger](`m:logger`) handler called\n cth_log_redirect. The formatting and level is copied from the current\n `default` handler when the cth is started. If you want to use another level\n either change the `default` handler level before starting common_test, or use\n the `logger:set_handler_config/3` API.\n\n This hook supports the following options:\n\n - **`{mode, add}`** - Add `cth_log_redirect` to the default logging handler:\n Logs will be emitted to both standard output via the default handler, and\n into the Common Test HTML logs. This is the default behaviour.\n\n - **`{mode, replace}`** - Replace the `default` logging handler with\n `cth_log_redirect` instead of logging to both the default handler and this\n handler. This effectively silences any logger output which would normally be\n printed to standard output during test runs. To enable this mode, you can\n pass the following options to `ct_run`:\n\n `-enable_builtin_hooks false -ct_hooks cth_log_redirect [{mode,replace}]`\n\n- **`cth_surefire`** - Not built-in\n\n Captures all test results and outputs them as surefire XML into a file. The\n created file is by default called `junit_report.xml`. The file name can be\n changed by setting option `path` for this hook, for example:\n\n `-ct_hooks cth_surefire [{path,\"/tmp/report.xml\"}]`\n\n If option `url_base` is set, an extra attribute named `url` is added to each\n `testsuite` and `testcase` XML element. The value is constructed from\n `url_base` and a relative path to the test suite or test case log,\n respectively, for example:\n\n `-ct_hooks cth_surefire [{url_base, \"http://myserver.com/\"}]`\n\n gives an URL attribute value similar to\n\n `\"http://myserver.com/ct_run.ct@myhost.2012-12-12_11.19.39/ x86_64-unknown-linux-gnu.my_test.logs/run.2012-12-12_11.19.39/suite.log.html\"`\n\n Surefire XML can, for example, be used by Jenkins to display test results.","ref":"ct_hooks_chapter.html#built-in-cths"},{"type":"extras","title":"Some Thoughts about Testing","doc":"\n# Some Thoughts about Testing","ref":"why_test_chapter.html"},{"type":"extras","title":"Goals - Some Thoughts about Testing","doc":"It is not possible to prove that a program is correct by testing. On the\ncontrary, it has been formally proven that it is impossible to prove programs in\ngeneral by testing. Theoretical program proofs or plain examination of code can\nbe viable options for those wishing to certify that a program is correct. The\ntest server, as it is based on testing, cannot be used for certification. Its\nintended use is instead to (cost effectively) _find bugs_. A successful test\nsuite is one that reveals a bug. If a test suite results in OK, then we know\nvery little that we did not know before.","ref":"why_test_chapter.html#goals"},{"type":"extras","title":"What to Test - Some Thoughts about Testing","doc":"There are many kinds of test suites. Some concentrate on calling every function\nor command (in the documented way) in a certain interface. Some others do the\nsame, but use all kinds of illegal parameters, and verify that the server stays\nalive and rejects the requests with reasonable error codes. Some test suites\nsimulate an application (typically consisting of a few modules of an\napplication), some try to do tricky requests in general, and some test suites\neven test internal functions with help of special Load Modules on target.\n\nAnother interesting category of test suites is the one checking that fixed bugs\ndo not reoccur. When a bugfix is introduced, a test case that checks for that\nspecific bug is written and submitted to the affected test suites.\n\nAim for finding bugs. Write whatever test that has the highest probability of\nfinding a bug, now or in the future. Concentrate more on the critical parts.\nBugs in critical subsystems are much more expensive than others.\n\nAim for functionality testing rather than implementation details. Implementation\ndetails change quite often, and the test suites are to be long lived.\nImplementation details often differ on different platforms and versions. If\nimplementation details must be tested, try to factor them out into separate test\ncases. These test cases can later be rewritten or skipped.\n\nAlso, aim for testing everything once, no less, no more. It is not effective\nhaving every test case fail only because one function in the interface changed.","ref":"why_test_chapter.html#what-to-test"},{"type":"extras","title":"Common Test's Property Testing Support: ct_property_test","doc":"\n# Common Test's Property Testing Support: ct_property_test","ref":"ct_property_test_chapter.html"},{"type":"extras","title":"General - Common Test's Property Testing Support: ct_property_test","doc":"The _Common Test Property Testing Support (ct_property_test)_ is an aid to run\nproperty based testing tools in Common Test test suites.\n\nBasic knowledge of property based testing is assumed in the following. It is\nalso assumed that at least one of the following property based testing tools is\ninstalled and available in the library path:\n\n- [QuickCheck](http://www.quviq.com),\n- [PropEr](https://proper-testing.github.io) or\n- [Triq](https://github.com/krestenkrab/triq)\n\n[](){: #supported }","ref":"ct_property_test_chapter.html#general"},{"type":"extras","title":"What Is Supported? - Common Test's Property Testing Support: ct_property_test","doc":"The [ct_property_test](`m:ct_property_test#`) module does the following:\n\n- Compiles the files with property tests in the subdirectory `property_test`\n- Tests properties in those files using the first found Property Testing Tool.\n- Saves the results - that is the printouts - in the usual Common Test Log","ref":"ct_property_test_chapter.html#what-is-supported"},{"type":"extras","title":"Introductory Example - Common Test's Property Testing Support: ct_property_test","doc":"Assume that we want to test the lists:sort/1 function.\n\nWe need a property to test the function. In normal way, we create\n`property_test/ct_prop.erl` module in the `test` directory in our application:\n\n```erlang\n-module(ct_prop).\n-export([prop_sort/0]).\n\n%%% This will include the .hrl file for the installed testing tool:\n-include_lib(\"common_test/include/ct_property_test.hrl\").\n\n%%% The property we want to check:\n%%% For all possibly unsorted lists,\n%%% the result of lists:sort/1 is sorted.\nprop_sort() ->\n ?FORALL(UnSorted, list(),\n is_sorted(lists:sort(UnSorted))\n ).\n\n%%% Function to check that a list is sorted:\nis_sorted([]) ->\n true;\nis_sorted([_]) ->\n true;\nis_sorted([H1,H2|SortedTail]) when H1 = \n is_sorted([H2|SortedTail]);\nis_sorted(_) ->\n false.\n```\n\nWe also need a CommonTest test suite:\n\n```erlang\n-module(ct_property_test_SUITE).\n-compile(export_all). % Only in tests!\n\n-include_lib(\"common_test/include/ct.hrl\").\n\nall() -> [prop_sort\n ].\n\n%%% First prepare Config and compile the property tests for the found tool:\ninit_per_suite(Config) ->\n ct_property_test:init_per_suite(Config).\n\nend_per_suite(Config) ->\n Config.\n\n%%%================================================================\n%%% Test suites\n%%%\nprop_sort(Config) ->\n ct_property_test:quickcheck(\n ct_prop:prop_sort(),\n Config\n ).\n```\n\nWe run it as usual, for example with ct_run in the OS shell:\n\n```text\n..../test$ ct_run -suite ct_property_test_SUITE\n.....\nCommon Test: Running make in test directories...\n\nTEST INFO: 1 test(s), 1 case(s) in 1 suite(s)\n\nTesting lib.common_test.ct_property_test_SUITE: Starting test, 1 test cases\n\n----------------------------------------------------\n2019-12-18 10:44:46.293\nFound property tester proper\nat \"/home/X/lib/proper/ebin/proper.beam\"\n\n\n----------------------------------------------------\n2019-12-18 10:44:46.294\nCompiling in \"/home/..../test/property_test\"\n Deleted: [\"ct_prop.beam\"]\n ErlFiles: [\"ct_prop.erl\"]\n MacroDefs: [{d,'PROPER'}]\n\nTesting lib.common_test.ct_property_test_SUITE: TEST COMPLETE, 1 ok, 0 failed of 1 test cases\n\n....\n```\n\n[](){: #stateful1 }","ref":"ct_property_test_chapter.html#introductory-example"},{"type":"extras","title":"A stateful testing example - Common Test's Property Testing Support: ct_property_test","doc":"Assume a test that generates some parallel stateful commands, and runs 300\ntests:\n\n```erlang\nprop_parallel(Config) ->\n numtests(300,\n ?FORALL(Cmds, parallel_commands(?MODULE),\n begin\n RunResult = run_parallel_commands(?MODULE, Cmds),\n ct_property_test:present_result(?MODULE, Cmds, RunResult, Config)\n end)).\n```\n\nThe `ct_property_test:present_result/4` is a help function for printing some\nstatistics in the CommonTest log file.\n\nOur example test could for example be a simple test of an ftp server, where we\nperform get, put and delete requests, some of them in parallel. Per default, the\nresult has three sections:\n\n```text\n*** User 2019-12-11 13:28:17.504 ***\n\nDistribution sequential/parallel\n\n 57.7% sequential\n 28.0% parallel_2\n 14.3% parallel_1\n\n\n\n*** User 2019-12-11 13:28:17.505 ***\n\nFunction calls\n\n 44.4% get\n 39.3% put\n 16.3% delete\n\n\n\n*** User 2019-12-11 13:28:17.505 ***\n\nLength of command sequences\n\nRange : Number in range\n-------:----------------\n 0 - 4: 8 2.7% <-- min=3\n 5 - 9: 44 14.7%\n10 - 14: 74 24.7%\n15 - 19: 60 20.0% <-- mean=18.7 <-- median=16.0\n20 - 24: 38 12.7%\n25 - 29: 26 8.7%\n30 - 34: 19 6.3%\n35 - 39: 19 6.3%\n40 - 44: 8 2.7%\n45 - 49: 4 1.3% <-- max=47\n ------\n 300\n```\n\nThe first part - _Distribution sequential/parallel_ \\- shows the distribution in\nthe sequential and parallel part of the result of parallel_commands/1. See any\nproperty testing tool for an explanation of this function. The table shows that\nof all commands (get and put in our case), 57.7% are executed in the sequential\npart prior to the parallel part, 28.0% are executed in the first parallel list\nand the rest in the second parallel list.\n\nThe second part - _Function calls_ \\- shows the distribution of the three calls\nin the generated command lists. We see that all of the three calls are executed.\nIf it was so that we thought that we also generated a fourth call, a table like\nthis shows that we failed with that.\n\nThe third and final part - _Length of command sequences_ \\- show statistics of\nthe generated command sequences. We see that the shortest list has three\nelementes while the longest has 47 elements. The mean and median values are also\nshown. Further we could for example see that only 2.7% of the lists (that is\neight lists) only has three or four elements.","ref":"ct_property_test_chapter.html#a-stateful-testing-example"},{"type":"extras","title":"ct_run","doc":"\n# ct_run\n\nProgram used for starting Common Test from the OS command line.","ref":"ct_run_cmd.html"},{"type":"extras","title":"Description - ct_run","doc":"The `ct_run` program is automatically installed with Erlang/OTP and the\n`Common Test` application (for more information, see section\n[Installation](install_chapter.md) in the User's Guide). The program accepts\ndifferent start flags. Some flags trigger `ct_run` to start `Common Test` and\npass on data to it. Some flags start an Erlang node prepared for running\n`Common Test` in a particular mode.\n\nThe interface function `ct:run_test/1`, corresponding to the `ct_run` program,\nis used for starting `Common Test` from the Erlang shell (or an Erlang program).\nFor details, see the `m:ct` manual page.\n\n`ct_run` also accepts Erlang emulator flags. These are used when `ct_run` calls\n`erl` to start the Erlang node (this makes it possible to add directories to the\ncode server path, change the cookie on the node, start more applications, and so\non).\n\nWith the optional flag `-erl_args`, options on the `ct_run` command line can be\ndivided into two groups:\n\n- One group that `Common Test` is to process (those preceding `-erl_args`).\n- One group that `Common Test` is to ignore and pass on directly to the emulator\n (those following `-erl_args`).\n\nOptions preceding `-erl_args` that `Common Test` does not recognize are also\npassed on to the emulator untouched. By `-erl_args` the user can specify flags\nwith the same name, but with different destinations, on the `ct_run` command\nline.\n\nIf flags `-pa` or `-pz` are specified in the `Common Test` group of options\n(preceding `-erl_args`), relative directories are converted to absolute and\nreinserted into the code path by `Common Test`. This is to avoid problems\nloading user modules when `Common Test` changes working directory during test\nruns. However, `Common Test` ignores flags `-pa` and `-pz` following `-erl_args`\non the command line. These directories are added to the code path normally (that\nis, on specified form).\n\nExit status is set before the program ends. Value `0` indicates a successful\ntest result, `1` indicates one or more failed or auto-skipped test cases, and\n`2` indicates test execution failure.\n\nIf `ct_run` is called with option `-help`, it prints all valid start flags to\n`stdout`.\n\n[](){: #ct_run }","ref":"ct_run_cmd.html#description"},{"type":"extras","title":"Run Tests from Command Line - ct_run","doc":"```text\n ct_run -dir TestDir1 TestDir2 .. TestDirN |\n [-dir TestDir] -suite Suite1 Suite2 .. SuiteN\n [-group Groups1 Groups2 .. GroupsN] [-case Case1 Case2 .. CaseN]\n [-step [config | keep_inactive]]\n [-config ConfigFile1 ConfigFile2 .. ConfigFileN]\n [-userconfig CallbackModule1 ConfigString1 and CallbackModule2\n ConfigString2 and .. CallbackModuleN ConfigStringN]\n [-decrypt_key Key] | [-decrypt_file KeyFile]\n [-label Label]\n [-logdir LogDir]\n [-logopts LogOpts]\n [-verbosity GenVLevel | [Category1 VLevel1 and\n Category2 VLevel2 and .. CategoryN VLevelN]]\n [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]\n [-stylesheet CSSFile]\n [-cover CoverCfgFile]\n [-cover_stop Bool]\n [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] |\n [-event_handler_init EvHandler1 InitArg1 and\n EvHandler2 InitArg2 and .. EvHandlerN InitArgN]\n [-include InclDir1 InclDir2 .. InclDirN]\n [-no_auto_compile]\n [-abort_if_missing_suites]\n [-multiply_timetraps Multiplier]\n [-scale_timetraps]\n [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]\n [-repeat N] |\n [-duration HHMMSS [-force_stop [skip_rest]]] |\n [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]\n [-basic_html]\n [-no_esc_chars]\n [-keep_logs all | NLogs]\n [-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and ..\n CTHModuleN CTHOptsN]\n [-ct_hooks_order test | config]\n [-exit_status ignore_config]\n [-help]\n```","ref":"ct_run_cmd.html#run-tests-from-command-line"},{"type":"extras","title":"Run Tests using Test Specification - ct_run","doc":"```text\n ct_run -spec TestSpec1 TestSpec2 .. TestSpecN\n [-join_specs]\n [-config ConfigFile1 ConfigFile2 .. ConfigFileN]\n [-userconfig CallbackModule1 ConfigString1 and CallbackModule2\n ConfigString2 and .. and CallbackModuleN ConfigStringN]\n [-decrypt_key Key] | [-decrypt_file KeyFile]\n [-label Label]\n [-logdir LogDir]\n [-logopts LogOpts]\n [-verbosity GenVLevel | [Category1 VLevel1 and\n Category2 VLevel2 and .. CategoryN VLevelN]]\n [-allow_user_terms]\n [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]\n [-stylesheet CSSFile]\n [-cover CoverCfgFile]\n [-cover_stop Bool]\n [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] |\n [-event_handler_init EvHandler1 InitArg1 and\n EvHandler2 InitArg2 and .. EvHandlerN InitArgN]\n [-include InclDir1 InclDir2 .. InclDirN]\n [-no_auto_compile]\n [-abort_if_missing_suites]\n [-multiply_timetraps Multiplier]\n [-scale_timetraps]\n [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]\n [-repeat N] |\n [-duration HHMMSS [-force_stop [skip_rest]]] |\n [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]\n [-basic_html]\n [-no_esc_chars]\n [-keep_logs all | NLogs]\n [-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and ..\n CTHModuleN CTHOptsN]\n [-ct_hooks_order test | config]\n [-exit_status ignore_config]\n```","ref":"ct_run_cmd.html#run-tests-using-test-specification"},{"type":"extras","title":"Refresh HTML Index Files - ct_run","doc":"```text\n ct_run -refresh_logs [-logdir LogDir] [-basic_html]\n [-keep_logs all | NLogs]\n```","ref":"ct_run_cmd.html#refresh-html-index-files"},{"type":"extras","title":"Run Common Test in Interactive Mode - ct_run","doc":"```erlang\n ct_run -shell\n [-config ConfigFile1 ConfigFile2 ... ConfigFileN]\n [-userconfig CallbackModule1 ConfigString1 and CallbackModule2\n ConfigString2 and .. and CallbackModuleN ConfigStringN]\n [-decrypt_key Key] | [-decrypt_file KeyFile]\n```","ref":"ct_run_cmd.html#run-common-test-in-interactive-mode"},{"type":"extras","title":"Start a Common Test Master Node - ct_run","doc":"```text\n ct_run -ctmaster\n```","ref":"ct_run_cmd.html#start-a-common-test-master-node"},{"type":"extras","title":"See Also - ct_run","doc":"For information about the start flags, see section\n[Running Tests and Analyzing Results](run_test_chapter.md) in the User's Guide.","ref":"ct_run_cmd.html#see-also"}],"content_type":"text/plain","producer":{"name":"ex_doc","version":[48,46,51,52,46,49]}} \ No newline at end of file diff --git a/prs/8803/lib/common_test-1.27/doc/html/dist/search_data-5DA668F7.js b/prs/8803/lib/common_test-1.27/doc/html/dist/search_data-5DA668F7.js new file mode 100644 index 0000000000000..19ee9f11cb09d --- /dev/null +++ b/prs/8803/lib/common_test-1.27/doc/html/dist/search_data-5DA668F7.js @@ -0,0 +1 @@ +searchData={"items":[{"type":"module","doc":"Main user interface for the `Common Test` framework.\n\nThis module implements the command-line interface for running tests and basic\nfunctions for `Common Test` case issues, such as configuration and logging.\n\nThe framework stores configuration values in a property list usually named\n`Config`. The list contains information about the test run added by the\nframework itself and may also contain user-provided values. The configuration is\npassed into individual test cases as well as support functions if defined.\n\nPossible configuration variables include:\n\n- `data_dir` \\- Data file directory\n- `priv_dir` \\- Scratch file directory\n- Whatever added by [`init_per_suite/1`](`c:ct_suite:init_per_suite/1`) or\n [`init_per_testcase/2`](`c:ct_suite:init_per_testcase/2`) in the test suite.\n\n> #### Warning {: .warning }\n>\n> The `?config` macro, used to receive individual config values from the\n> `Config` property list, is deprecated. Please use `proplists:get_value/2-3`\n> instead.","title":"ct","ref":"ct.html"},{"type":"function","doc":"Aborts the currently executing test case. The user must know with certainty\nwhich test case is currently executing. The function is therefore only safe to\ncall from a function that has been called (or synchronously invoked) by the test\ncase.\n\n`Reason`, the reason for aborting the test case, is printed in the test case\nlog.","title":"ct.abort_current_testcase/1","ref":"ct.html#abort_current_testcase/1"},{"type":"function","doc":"Loads configuration variables using the specified callback module and\nconfiguration string. The callback module is to be either loaded or present in\nthe code path. Loaded configuration variables can later be removed using\nfunction [`ct:remove_config/2`](`remove_config/2`).","title":"ct.add_config/2","ref":"ct.html#add_config/2"},{"type":"function","doc":"Cancels any active timetrap and pauses the execution of the current test case\nuntil the user calls function `continue/0`. The user can then interact with the\nErlang node running the tests, for example, for debugging purposes or for\nmanually executing a part of the test case. If a parallel group is executing,\n[`ct:break/2`](`break/2`) is to be called instead.\n\nA cancelled timetrap is not automatically reactivated after the break, but must\nbe started explicitly with [`ct:timetrap/1`](`timetrap/1`).\n\nIn order for the break/continue functionality to work, `Common Test` must\nrelease the shell process controlling `stdin`. This is done by setting start\noption `release_shell` to `true`. For details, see section\n[Running Tests from the Erlang Shell or from an Erlang Program](run_test_chapter.md#erlang_shell_or_program)\nin the User's Guide.","title":"ct.break/1","ref":"ct.html#break/1"},{"type":"function","doc":"Works the same way as [`ct:break/1`](`break/1`), only argument `TestCase` makes\nit possible to pause a test case executing in a parallel group. Function\n[`ct:continue/1`](`continue/1`) is to be used to resume execution of `TestCase`.\n\nFor details, see [`ct:break/1`](`break/1`).","title":"ct.break/2","ref":"ct.html#break/2"},{"type":"function","doc":"","title":"ct.capture_get/0","ref":"ct.html#capture_get/0"},{"type":"function","doc":"Returns and purges the list of text strings buffered during the latest session\nof capturing printouts to `stdout`. Log categories that are to be ignored in\n`ListOfStrings` can be specified with `ExclCategories`. If\n`ExclCategories = []`, no filtering takes place.\n\nSee also [`ct:capture_start/0`](`capture_start/0`),\n[`ct:capture_stop/0`](`capture_stop/0`), [`ct:log/3`](`log/3`).","title":"ct.capture_get/1","ref":"ct.html#capture_get/1"},{"type":"function","doc":"Starts capturing all text strings printed to `stdout` during execution of the\ntest case.\n\nSee also [`ct:capture_get/1`](`capture_get/1`),\n[`ct:capture_stop/0`](`capture_stop/0`).","title":"ct.capture_start/0","ref":"ct.html#capture_start/0"},{"type":"function","doc":"Stops capturing text strings (a session started with `capture_start/0`).\n\nSee also [`ct:capture_get/1`](`capture_get/1`),\n[`ct:capture_start/0`](`capture_start/0`).","title":"ct.capture_stop/0","ref":"ct.html#capture_stop/0"},{"type":"function","doc":"Prints the specified `Comment` in the comment field in the table on the test\nsuite result page.\n\nIf called several times, only the last comment is printed. The test case return\nvalue `{comment,Comment}` overwrites the string set by this function.","title":"ct.comment/1","ref":"ct.html#comment/1"},{"type":"function","doc":"Prints the formatted string in the comment field in the table on the test suite\nresult page.\n\nArguments `Format` and `Args` are used in a call to `io_lib:format/2` to create\nthe comment string. The behavior of [`comment/2`](`comment/2`) is otherwise the\nsame as function [`ct:comment/1`](`comment/1`).","title":"ct.comment/2","ref":"ct.html#comment/2"},{"type":"function","doc":"This function must be called to continue after a test case (not executing in a\nparallel group) has called function [`ct:break/1`](`break/1`).","title":"ct.continue/0","ref":"ct.html#continue/0"},{"type":"function","doc":"This function must be called to continue after a test case has called\n[`ct:break/2`](`break/2`). If the paused test case, `TestCase`, executes in a\nparallel group, this function, rather than `continue/0`, must be used to let the\ntest case proceed.","title":"ct.continue/1","ref":"ct.html#continue/1"},{"type":"function","doc":"Decrypts `EncryptFileName`, previously generated with\n[`ct:encrypt_config_file/2,3`](`encrypt_config_file/2`). The original file\ncontents is saved in the target file. The encryption key, a string, must be\navailable in a text file named `.ct_config.crypt`, either in the current\ndirectory, or the home directory of the user (it is searched for in that order).","title":"ct.decrypt_config_file/2","ref":"ct.html#decrypt_config_file/2"},{"type":"function","doc":"Decrypts `EncryptFileName`, previously generated with\n[`ct:encrypt_config_file/2,3`](`encrypt_config_file/2`). The original file\ncontents is saved in the target file. The key must have the same value as that\nused for encryption.","title":"ct.decrypt_config_file/3","ref":"ct.html#decrypt_config_file/3"},{"type":"function","doc":"Encrypts the source configuration file with DES3 and saves the result in file\n`EncryptFileName`. The key, a string, must be available in a text file named\n`.ct_config.crypt`, either in the current directory, or the home directory of\nthe user (it is searched for in that order).\n\nFor information about using encrypted configuration files when running tests,\nsee section\n[Encrypted Configuration Files](config_file_chapter.md#encrypted_config_files)\nin the User's Guide.\n\nFor details on DES3 encryption/decryption, see application\n[`Crypto`](`e:crypto:index.html`).","title":"ct.encrypt_config_file/2","ref":"ct.html#encrypt_config_file/2"},{"type":"function","doc":"Encrypts the source configuration file with DES3 and saves the result in the\ntarget file `EncryptFileName`. The encryption key to use is either the value in\n`{key,Key}` or the value stored in the file specified by `{file,File}`.\n\nFor information about using encrypted configuration files when running tests,\nsee section\n[Encrypted Configuration Files](config_file_chapter.md#encrypted_config_files)\nin the User's Guide.\n\nFor details on DES3 encryption/decryption, see application\n[`Crypto`](`e:crypto:index.html`).","title":"ct.encrypt_config_file/3","ref":"ct.html#encrypt_config_file/3"},{"type":"function","doc":"Terminates a test case with the specified error `Reason`.","title":"ct.fail/1","ref":"ct.html#fail/1"},{"type":"function","doc":"Terminates a test case with an error message specified by a format string and a\nlist of values (used as arguments to `io_lib:format/2`).","title":"ct.fail/2","ref":"ct.html#fail/2"},{"type":"function","doc":"","title":"ct.get_config/1","ref":"ct.html#get_config/1"},{"type":"function","doc":"","title":"ct.get_config/2","ref":"ct.html#get_config/2"},{"type":"function","doc":"Reads configuration data values.\n\nReturns the matching values or configuration elements, given a configuration\nvariable key or its associated name (if one has been specified with\n[`ct:require/2`](`require/2`) or a `require` statement).\n\n_Example:_\n\nGiven the following configuration file:\n\n```erlang\n{unix,[{telnet,IpAddr},\n {user,[{username,Username},\n {password,Password}]}]}.\n```\n\nThen:\n\n```erlang\nct:get_config(unix,Default) -> [{telnet,IpAddr},\n {user, [{username,Username}, {password,Password}]}]\nct:get_config({unix,telnet},Default) -> IpAddr\nct:get_config({unix,user,username},Default) -> Username\nct:get_config({unix,ftp},Default) -> Default\nct:get_config(unknownkey,Default) -> Default\n```\n\nIf a configuration variable key has been associated with a name (by\n[`ct:require/2`](`require/2`) or a `require` statement), the name can be used\ninstead of the key to read the value:\n\n```erlang\nct:require(myuser,{unix,user}) -> ok.\nct:get_config(myuser,Default) -> [{username,Username}, {password,Password}]\n```\n\nIf a configuration variable is defined in multiple files, use option `all` to\naccess all possible values. The values are returned in a list. The order of the\nelements corresponds to the order that the configuration files were specified at\nstartup.\n\nIf configuration elements (key-value tuples) are to be returned as result\ninstead of values, use option `element`. The returned elements are then on the\nform `{Required,Value}`.\n\nSee also [`ct:get_config/1`](`get_config/1`),\n[`ct:get_config/2`](`get_config/2`), [`ct:require/1`](`require/1`),\n[`ct:require/2`](`require/2`).","title":"ct.get_config/3","ref":"ct.html#get_config/3"},{"type":"function","doc":"Gets a reference to the `Common Test` event manager. The reference can be used\nto, for example, add a user-specific event handler while tests are running.\n\n_Example:_\n\n```erlang\ngen_event:add_handler(ct:get_event_mgr_ref(), my_ev_h, [])\n```","title":"ct.get_event_mgr_ref/0","ref":"ct.html#get_event_mgr_ref/0"},{"type":"function","doc":"Returns the command used to start this Erlang instance. If this information\ncould not be found, the string `\"no_prog_name\"` is returned.","title":"ct.get_progname/0","ref":"ct.html#get_progname/0"},{"type":"function","doc":"Returns status of ongoing test. The returned list contains information about\nwhich test case is executing (a list of cases when a parallel test case group is\nexecuting), as well as counters for successful, failed, skipped, and total test\ncases so far.","title":"ct.get_status/0","ref":"ct.html#get_status/0"},{"type":"function","doc":"Returns the name of the target that the specified connection belongs to.","title":"ct.get_target_name/1","ref":"ct.html#get_target_name/1"},{"type":"function","doc":"Gets a list of all test specification terms used to configure and run this test.","title":"ct.get_testspec_terms/0","ref":"ct.html#get_testspec_terms/0"},{"type":"function","doc":"Reads one or more terms from the test specification used to configure and run\nthis test. `Tag` is any valid test specification tag, for example, `label`,\n`config`, or `logdir`. User-specific terms are also available to read if option\n`allow_user_terms` is set.\n\nAll value tuples returned, except user terms, have the node name as first\nelement.\n\nTo read test terms, use `Tag = tests` (rather than `suites`, `groups`, or\n`cases`). `Value` is then the list of _all_ tests on the form\n`[{Node,Dir,[{TestSpec,GroupsAndCases1},...]},...]`, where\n`GroupsAndCases = [{Group,[Case]}] | [Case]`.","title":"ct.get_testspec_terms/1","ref":"ct.html#get_testspec_terms/1"},{"type":"function","doc":"Reads information about the timetrap set for the current test case. `Scaling`\nindicates if `Common Test` will attempt to compensate timetraps automatically\nfor runtime delays introduced by, for example, tools like cover. `ScaleVal` is\nthe value of the current scaling multiplier (always 1 if scaling is disabled).\nNote the `Time` is not the scaled result.","title":"ct.get_timetrap_info/0","ref":"ct.html#get_timetrap_info/0"},{"type":"function","doc":"This function returns the verbosity level for the specified logging category.\nSee the [User's Guide](write_test_chapter.md#logging) for details. Use the value\n`default` to read the general verbosity level.","title":"ct.get_verbosity/1","ref":"ct.html#get_verbosity/1"},{"type":"function","doc":"Installs configuration files and event handlers.\n\nRun this function once before the first test.\n\n_Example:_\n\n```erlang\ninstall([{config,[\"config_node.ctc\",\"config_user.ctc\"]}])\n```\n\nThis function is automatically run by program `ct_run`.","title":"ct.install/1","ref":"ct.html#install/1"},{"type":"function","doc":"Performs command `listenv` on the specified Telnet connection and returns the\nresult as a list of key-value pairs.","title":"ct.listenv/1","ref":"ct.html#listenv/1"},{"type":"function","doc":"Equivalent to [`log(default, ?STD_IMPORTANCE, Format, [], [])`](`log/5`).","title":"ct.log/1","ref":"ct.html#log/1"},{"type":"function","doc":"","title":"ct.log/2","ref":"ct.html#log/2"},{"type":"function","doc":"","title":"ct.log/3","ref":"ct.html#log/3"},{"type":"function","doc":"","title":"ct.log/4","ref":"ct.html#log/4"},{"type":"function","doc":"Prints from a test case to the log file.\n\nThis function is meant for printing a string directly from a test case to the\ntest case log file.\n\nDefault `Category` is `default`, default `Importance` is `?STD_IMPORTANCE`, and\ndefault value for `FormatArgs` is `[]`.\n\nFor details on `Category`, `Importance` and the `no_css` option, see section\n[Logging - Categories and Verbosity Levels](write_test_chapter.md#logging) in\nthe User's Guide.\n\nCommon Test will not escape special HTML characters (<, > and &) in the text\nprinted with this function, unless the `esc_chars` option is used.","title":"ct.log/5","ref":"ct.html#log/5"},{"type":"function","doc":"If the test is started with option `create_priv_dir` set to `manual_per_tc`, in\norder for the test case to use the private directory, it must first create it by\ncalling this function.","title":"ct.make_priv_dir/0","ref":"ct.html#make_priv_dir/0"},{"type":"function","doc":"Sends an asynchronous notification of type `Name` with `Data`to the Common Test\nevent manager. This can later be caught by any installed event manager.\n\nSee also `m:gen_event`.","title":"ct.notify/2","ref":"ct.html#notify/2"},{"type":"function","doc":"Equivalent to [`pal(default, ?STD_IMPORTANCE, Format, [])`](`pal/4`).","title":"ct.pal/1","ref":"ct.html#pal/1"},{"type":"function","doc":"","title":"ct.pal/2","ref":"ct.html#pal/2"},{"type":"function","doc":"","title":"ct.pal/3","ref":"ct.html#pal/3"},{"type":"function","doc":"","title":"ct.pal/4","ref":"ct.html#pal/4"},{"type":"function","doc":"Prints and logs from a test case.\n\nThis function is meant for printing a string from a test case, both to the test\ncase log file and to the console.\n\nDefault `Category` is `default`, default `Importance` is `?STD_IMPORTANCE`, and\ndefault value for `FormatArgs` is `[]`.\n\nFor details on `Category` and `Importance`, see section\n[Logging - Categories and Verbosity Levels](write_test_chapter.md#logging) in\nthe User's Guide.\n\nNote that special characters in the text (<, > and &) will be escaped by Common\nTest before the text is printed to the log file.","title":"ct.pal/5","ref":"ct.html#pal/5"},{"type":"function","doc":"Parses the printout from an SQL table and returns a list of tuples.\n\nThe printout to parse is typically the result of a `select` command in SQL. The\nreturned `Table` is a list of tuples, where each tuple is a row in the table.\n\n`Heading` is a tuple of strings representing the headings of each column in the\ntable.","title":"ct.parse_table/1","ref":"ct.html#parse_table/1"},{"type":"function","doc":"Equivalent to [`print(default, ?STD_IMPORTANCE, Format, [], [])`](`print/5`).","title":"ct.print/1","ref":"ct.html#print/1"},{"type":"function","doc":"","title":"ct.print/2","ref":"ct.html#print/2"},{"type":"function","doc":"","title":"ct.print/3","ref":"ct.html#print/3"},{"type":"function","doc":"","title":"ct.print/4","ref":"ct.html#print/4"},{"type":"function","doc":"Prints from a test case to the console.\n\nThis function is meant for printing a string from a test case to the console.\n\nDefault `Category` is `default`, default `Importance` is `?STD_IMPORTANCE`, and\ndefault value for `FormatArgs` is `[]`.\n\nFor details on `Category` and `Importance`, see section\n[Logging - Categories and Verbosity Levels](write_test_chapter.md#logging) in\nthe User's Guide.","title":"ct.print/5","ref":"ct.html#print/5"},{"type":"function","doc":"Reloads configuration file containing specified configuration key.\n\nThis function updates the configuration data from which the specified\nconfiguration variable was read, and returns the (possibly) new value of this\nvariable.\n\nIf some variables were present in the configuration, but are not loaded using\nthis function, they are removed from the configuration table together with their\naliases.","title":"ct.reload_config/1","ref":"ct.html#reload_config/1"},{"type":"function","doc":"This function will return the identity of test- and group leader processes that\nare still running at the time of this call. `TestProcs` are processes in the\nsystem that have a Common Test IO process as group leader. `SharedGL` is the\ncentral Common Test IO process, responsible for printing to log files for\nconfiguration functions and sequentially executing test cases. `OtherGLs` are\nCommon Test IO processes that print to log files for test cases in parallel test\ncase groups.\n\nThe process information returned by this function may be used to locate and\nterminate remaining processes after tests have finished executing. The function\nwould typically by called from Common Test Hook functions.\n\nNote that processes that execute configuration functions or test cases are never\nincluded in `TestProcs`. It is therefore safe to use post configuration hook\nfunctions (such as post_end_per_suite, post_end_per_group,\npost_end_per_testcase) to terminate all processes in `TestProcs` that have the\ncurrent group leader process as its group leader.\n\nNote also that the shared group leader (`SharedGL`) must never be terminated by\nthe user, only by Common Test. Group leader processes for parallel test case\ngroups (`OtherGLs`) may however be terminated in post_end_per_group hook\nfunctions.","title":"ct.remaining_test_procs/0","ref":"ct.html#remaining_test_procs/0"},{"type":"function","doc":"Removes configuration variables (together with their aliases) that were loaded\nwith specified callback module and configuration string.","title":"ct.remove_config/2","ref":"ct.html#remove_config/2"},{"type":"function","doc":"Checks if the required configuration is available. Arbitrarily deep tuples can\nbe specified as `Required`. Only the last element of the tuple can be a list of\n`SubKey`s.\n\n_Example 1._ Require the variable `myvar`:\n\n```erlang\nok = ct:require(myvar).\n```\n\nIn this case the configuration file must at least contain:\n\n```erlang\n{myvar,Value}.\n```\n\n_Example 2._ Require key `myvar` with subkeys `sub1` and `sub2`:\n\n```erlang\nok = ct:require({myvar,[sub1,sub2]}).\n```\n\nIn this case the configuration file must at least contain:\n\n```erlang\n{myvar,[{sub1,Value},{sub2,Value}]}.\n```\n\n_Example 3._ Require key `myvar` with subkey `sub1` with `subsub1`:\n\n```erlang\nok = ct:require({myvar,sub1,sub2}).\n```\n\nIn this case the configuration file must at least contain:\n\n```erlang\n{myvar,[{sub1,[{sub2,Value}]}]}.\n```\n\nSee also [`ct:get_config/1`](`get_config/1`),\n[`ct:get_config/2`](`get_config/2`), [`ct:get_config/3`](`get_config/3`),\n[`ct:require/2`](`require/2`).","title":"ct.require/1","ref":"ct.html#require/1"},{"type":"function","doc":"Checks if the required configuration is available and gives it a name. The\nsemantics for `Required` is the same as in [`ct:require/1`](`require/1`) except\nthat a list of `SubKey`s cannot be specified.\n\nIf the requested data is available, the subentry is associated with `Name` so\nthat the value of the element can be read with\n[`ct:get_config/1,2`](`get_config/1`) provided `Name` is used instead of the\nwhole `Required` term.\n\n_Example:_\n\nRequire one node with a Telnet connection and an FTP connection. Name the node\n`a`:\n\n```erlang\nok = ct:require(a,{machine,node}).\n```\n\nAll references to this node can then use the node name. For example, a file over\nFTP is fetched like follows:\n\n```erlang\nok = ct:ftp_get(a,RemoteFile,LocalFile).\n```\n\nFor this to work, the configuration file must at least contain:\n\n```erlang\n{machine,[{node,[{telnet,IpAddr},{ftp,IpAddr}]}]}.\n```\n\n> #### Note {: .info }\n>\n> The behavior of this function changed radically in `Common Test` 1\\.6.2. To\n> keep some backwards compatibility, it is still possible to do:\n> `ct:require(a,{node,[telnet,ftp]}).` This associates the name `a` with the\n> top-level `node` entry. For this to work, the configuration file must at least\n> contain: `{node,[{telnet,IpAddr},{ftp,IpAddr}]}.`\n\nSee also [`ct:get_config/1`](`get_config/1`),\n[`ct:get_config/2`](`get_config/2`), [`ct:get_config/3`](`get_config/3`),\n[`ct:require/1`](`require/1`).","title":"ct.require/2","ref":"ct.html#require/2"},{"type":"function","doc":"Runs all test cases in all suites in the specified directories.\n\nSee also [`ct:run/3`](`run/3`).","title":"ct.run/1","ref":"ct.html#run/1"},{"type":"function","doc":"Runs all test cases in the specified suite.\n\nSee also [`ct:run/3`](`run/3`).","title":"ct.run/2","ref":"ct.html#run/2"},{"type":"function","doc":"Runs the specified test cases.\n\nRequires that [`ct:install/1`](`install/1`) has been run first.\n\nSuites (`*_SUITE.erl`) files must be stored in `TestDir` or `TestDir/test`. All\nsuites are compiled when the test is run.","title":"ct.run/3","ref":"ct.html#run/3"},{"type":"function","doc":"Runs tests as specified by the combination of options in `Opts`. The options are\nthe same as those used with program `ct_run`, see\n[Run Tests from Command Line](ct_run_cmd.md#ct_run) in the `ct_run` manual page.\n\nHere a `TestDir` can be used to point out the path to a `Suite`. Option\n`testcase` corresponds to option `-case` in program `ct_run`. Configuration\nfiles specified in `Opts` are installed automatically at startup.\n\n`TestRunnerPid` is returned if `release_shell == true`. For details, see\n[`ct:break/1`](`break/1`).\n\n`Reason` indicates the type of error encountered.","title":"ct.run_test/1","ref":"ct.html#run_test/1"},{"type":"function","doc":"Runs a test specified by `TestSpec`. The same terms are used as in test\nspecification files.\n\n`Reason` indicates the type of error encountered.","title":"ct.run_testspec/1","ref":"ct.html#run_testspec/1"},{"type":"function","doc":"Use this function to set, or modify, the verbosity level for a logging category.\nSee the [User's Guide](write_test_chapter.md#logging) for details. Use the value\n`default` to set the general verbosity level.","title":"ct.set_verbosity/2","ref":"ct.html#set_verbosity/2"},{"type":"function","doc":"This function, similar to `timer:sleep/1` in STDLIB, suspends the test case for\na specified time. However, this function also multiplies `Time` with the\n`multiply_timetraps` value (if set) and under certain circumstances also scales\nup the time automatically if `scale_timetraps` is set to `true` (default is\n`false`).","title":"ct.sleep/1","ref":"ct.html#sleep/1"},{"type":"function","doc":"Starts `Common Test` in interactive mode.\n\nFrom this mode, all test case support functions can be executed directly from\nthe Erlang shell. The interactive mode can also be started from the OS command\nline with `ct_run -shell [-config File...]`.\n\nIf any functions (for example, Telnet or FTP) using \"required configuration\ndata\" are to be called from the Erlang shell, configuration data must first be\nrequired with [`ct:require/2`](`require/2`).\n\n_Example:_\n\n```erlang\n> ct:require(unix_telnet, unix).\nok\n> ct_telnet:open(unix_telnet).\n{ok,<0.105.0>}\n> ct_telnet:cmd(unix_telnet, \"ls .\").\n{ok,[\"ls\",\"file1 ...\",...]}\n```","title":"ct.start_interactive/0","ref":"ct.html#start_interactive/0"},{"type":"function","doc":"Steps through a test case with the debugger.\n\nSee also [`ct:run/3`](`run/3`).","title":"ct.step/3","ref":"ct.html#step/3"},{"type":"function","doc":"Steps through a test case with the debugger. If option `config` has been\nspecified, breakpoints are also set on the configuration functions in `Suite`.\n\nSee also [`ct:run/3`](`run/3`).","title":"ct.step/4","ref":"ct.html#step/4"},{"type":"function","doc":"Exits the interactive mode.\n\nSee also [`ct:start_interactive/0`](`start_interactive/0`).","title":"ct.stop_interactive/0","ref":"ct.html#stop_interactive/0"},{"type":"function","doc":"Sends a synchronous notification of type `Name` with `Data` to the `Common Test`\nevent manager. This can later be caught by any installed event manager.\n\nSee also `m:gen_event`.","title":"ct.sync_notify/2","ref":"ct.html#sync_notify/2"},{"type":"function","doc":"Returns all test cases in the specified suite.","title":"ct.testcases/2","ref":"ct.html#testcases/2"},{"type":"function","doc":"Sets a new timetrap for the running test case.\n\nIf the argument is `Func`, the timetrap is triggered when this function returns.\n`Func` can also return a new `Time` value, which in that case is the value for\nthe new timetrap.","title":"ct.timetrap/1","ref":"ct.html#timetrap/1"},{"type":"function","doc":"Returns any data specified with tag `userdata` in the list of tuples returned\nfrom [`suite/0`](`c:ct_suite:suite/0`).","title":"ct.userdata/2","ref":"ct.html#userdata/2"},{"type":"function","doc":"Returns any data specified with tag `userdata` in the list of tuples returned\nfrom `Suite:group(GroupName)` or `Suite:Case()`.","title":"ct.userdata/3","ref":"ct.html#userdata/3"},{"type":"type","doc":"A configuration key which exists in a configuration file","title":"ct.config_key/0","ref":"ct.html#t:config_key/0"},{"type":"type","doc":"","title":"ct.conn_log_mod/0","ref":"ct.html#t:conn_log_mod/0"},{"type":"type","doc":"","title":"ct.conn_log_option/0","ref":"ct.html#t:conn_log_option/0"},{"type":"type","doc":"Options that can be given to the `cth_conn_log` hook, which is used for logging\nof NETCONF and Telnet connections. See [ct_netconfc](`m:ct_netconfc#Logging`) or\n[ct_telnet](`m:ct_telnet#module-logging`) for description and examples of how to use\nthis hook.","title":"ct.conn_log_options/0","ref":"ct.html#t:conn_log_options/0"},{"type":"type","doc":"","title":"ct.conn_log_type/0","ref":"ct.html#t:conn_log_type/0"},{"type":"type","doc":"The identity (handle) of a connection.","title":"ct.handle/0","ref":"ct.html#t:handle/0"},{"type":"type","doc":"","title":"ct.key_or_name/0","ref":"ct.html#t:key_or_name/0"},{"type":"type","doc":"A name and association to configuration data introduced through a require\nstatement, or a call to [`ct:require/2`](`require/2`), for example,\n`ct:require(mynodename,{node,[telnet]})`.","title":"ct.target_name/0","ref":"ct.html#t:target_name/0"},{"type":"module","doc":"`Common Test` framework code coverage support module.\n\nThis module exports help functions for performing code coverage analysis.","title":"ct_cover","ref":"ct_cover.html"},{"type":"function","doc":"Adds nodes to current cover test. Notice that this only works if cover support\nis active.\n\nTo have effect, this function is to be called from `init_per_suite/1` (see\n`m:ct_suite`) before any tests are performed.","title":"ct_cover.add_nodes/1","ref":"ct_cover.html#add_nodes/1"},{"type":"function","doc":"Accumulates cover results over multiple tests. See section\n[Cross Cover Analysis](cover_chapter.md#cross_cover) in the User's Guide.","title":"ct_cover.cross_cover_analyse/2","ref":"ct_cover.html#cross_cover_analyse/2"},{"type":"function","doc":"Removes nodes from the current cover test.\n\nCall this function to stop cover test on nodes previously added with\n[`ct_cover:add_nodes/1`](`add_nodes/1`). Results on the remote node are\ntransferred to the `Common Test` node.","title":"ct_cover.remove_nodes/1","ref":"ct_cover.html#remove_nodes/1"},{"type":"module","doc":"FTP client module (based on the `ftp` application).","title":"ct_ftp","ref":"ct_ftp.html"},{"type":"function","doc":"Changes directory on remote host.","title":"ct_ftp.cd/2","ref":"ct_ftp.html#cd/2"},{"type":"function","doc":"Closes the FTP connection.","title":"ct_ftp.close/1","ref":"ct_ftp.html#close/1"},{"type":"function","doc":"Deletes a file on remote host.","title":"ct_ftp.delete/2","ref":"ct_ftp.html#delete/2"},{"type":"function","doc":"Opens an FTP connection and fetches a file from the remote host.\n\n`RemoteFile` and `LocalFile` must be absolute paths.\n\nThe configuration file must be as for [`ct_ftp:put/3`](`put/3`).\n\nSee also `ct:require/2`.","title":"ct_ftp.get/3","ref":"ct_ftp.html#get/3"},{"type":"function","doc":"Lists directory `Dir`.","title":"ct_ftp.ls/2","ref":"ct_ftp.html#ls/2"},{"type":"function","doc":"Opens an FTP connection to the specified node.\n\nYou can open a connection for a particular `Name` and use the same name as\nreference for all following subsequent operations. If you want the connection to\nbe associated with `Handle` instead (if you, for example, need to open multiple\nconnections to a host), use `Key`, the configuration variable name, to specify\nthe target. A connection without an associated target name can only be closed\nwith the handle value.\n\nFor information on how to create a new `Name`, see `ct:require/2`.","title":"ct_ftp.open/1","ref":"ct_ftp.html#open/1"},{"type":"function","doc":"Opens an FTP connection and sends a file to the remote host.\n\n`LocalFile` and `RemoteFile` must be absolute paths.\n\nIf the target host is a \"special\" node, the FTP address must be specified in the\nconfiguration file as follows:\n\n```erlang\n{node,[{ftp,IpAddr}]}.\n```\n\nIf the target host is something else, for example, a UNIX host, the\nconfiguration file must also include the username and password (both strings):\n\n```erlang\n{unix,[{ftp,IpAddr},\n {username,Username},\n {password,Password}]}.\n```\n\nSee also `ct:require/2`.","title":"ct_ftp.put/3","ref":"ct_ftp.html#put/3"},{"type":"function","doc":"Fetches a file over FTP.\n\nThe file gets the same name on the local host.\n\nSee also [`ct_ftp:recv/3`](`recv/3`).","title":"ct_ftp.recv/2","ref":"ct_ftp.html#recv/2"},{"type":"function","doc":"Fetches a file over FTP.\n\nThe file is named `LocalFile` on the local host.","title":"ct_ftp.recv/3","ref":"ct_ftp.html#recv/3"},{"type":"function","doc":"Sends a file over FTP.\n\nThe file gets the same name on the remote host.\n\nSee also [`ct_ftp:send/3`](`send/3`).","title":"ct_ftp.send/2","ref":"ct_ftp.html#send/2"},{"type":"function","doc":"Sends a file over FTP.\n\nThe file is named `RemoteFile` on the remote host.","title":"ct_ftp.send/3","ref":"ct_ftp.html#send/3"},{"type":"function","doc":"Changes the file transfer type.","title":"ct_ftp.type/2","ref":"ct_ftp.html#type/2"},{"type":"type","doc":"Reference to opened FTP connection associated to either a `handle` or `target_name`.","title":"ct_ftp.connection/0","ref":"ct_ftp.html#t:connection/0"},{"type":"type","doc":"Handle for a specific FTP connection, see module `m:ct`.","title":"ct_ftp.handle/0","ref":"ct_ftp.html#t:handle/0"},{"type":"behaviour","doc":"A callback interface on top of Common Test.\n\nThe _Common Test Hook (CTH)_ framework allows extensions of the default behavior\nof `Common Test` by callbacks before and after all test suite calls. It is\nintended for advanced users of `Common Test` who want to abstract out behavior\nthat is common to multiple test suites.\n\nIn brief, CTH allows you to:\n\n- Manipulate the runtime configuration before each suite configuration call.\n- Manipulate the return of all suite configuration calls and by extension the\n result of the test themselves.\n\nThe following sections describe the mandatory and optional CTH functions that\n`Common Test` calls during test execution. For more details, see section\n[Common Test Hooks](ct_hooks_chapter.md) in the User's Guide.\n\nFor information about how to add a CTH to your suite, see section\n[Installing a CTH](ct_hooks_chapter.md#installing) in the User's Guide.\n\n> #### Note {: .info }\n>\n> For a minimal example of a CTH, see section\n> [Example CTH](ct_hooks_chapter.md#example) in the User's Guide.","title":"ct_hooks","ref":"ct_hooks.html"},{"type":"callback","doc":"The `Id` identifies a CTH instance uniquely. If two CTHs return the same `Id`,\nthe second CTH is ignored and subsequent calls to the CTH are only made to the\nfirst instance. For details, see section\n[Installing a CTH](ct_hooks_chapter.md#installing) in the User's Guide.\n\nThis function is _not_ to have any side effects, as it can be called multiple\ntimes by `Common Test`.\n\nIf not implemented, the CTH acts as if this function returned a call to\n`make_ref/0`.","title":"ct_hooks.id/1","ref":"ct_hooks.html#c:id/1"},{"type":"callback","doc":"This function is always called before any other callback function. Use it to\ninitiate any common state. It is to return a state for this CTH.\n\n`Id` is either the return value of [`ct_hooks:id/1`](`c:id/1`), or a `reference`\n(created using `erlang:make_ref/0` in ERTS) if [`ct_hooks:id/1`](`c:id/1`) is\nnot implemented.\n\n`Priority` is the relative priority of this hook. Hooks with a lower priority\nare executed first. If no priority is specified, it is set to `0`.\n\nFor details about hook execution order, see section\n[CTH Execution Order](ct_hooks_chapter.md#cth_execution_order) in the User's\nGuide.\n\nFor details about when `init` is called, see section\n[CTH Scope](ct_hooks_chapter.md#scope) in the User's Guide.","title":"ct_hooks.init/2","ref":"ct_hooks.html#c:init/2"},{"type":"callback","doc":"This function is called whenever a test case (or configuration function) fails.\nIt is called after the post function is called for the failed test case.\n\nThat is:\n\n- If `init_per_suite` fails, this function is called after\n [`post_init_per_suite`](`c:post_init_per_suite/4`).\n- If a test case fails, this function is called after\n [`post_end_per_testcase`](`c:post_end_per_testcase/5`).\n\nIf the failed test case belongs to a test case group, the second argument is a\ntuple `{FuncName,GroupName}`, otherwise only the function name.\n\nThe data that comes with `Reason` follows the same format as\n[`FailReason`](event_handler_chapter.md#failreason) in event\n[`tc_done`](event_handler_chapter.md#tc_done). For details, see section\n[Event Handling](event_handler_chapter.md#events) in the User's Guide.\n\nIf [`Module:on_tc_fail/4`](`c:on_tc_fail/4`) is not exported, common_test will\nattempt to call `Module:on_tc_fail(TestName, Reason, CTHState)` instead. This is\nfor backwards compatibility.","title":"ct_hooks.on_tc_fail/4","ref":"ct_hooks.html#c:on_tc_fail/4"},{"type":"callback","doc":"This function is called whenever a test case (or configuration function) is\nskipped. It is called after the post function is called for the skipped test\ncase.\n\nThat is:\n\n- If `init_per_group` is skipped, this function is called after\n [`post_init_per_group`](`c:post_init_per_group/5`).\n- If a test case is skipped, this function is called after\n [`post_end_per_testcase`](`c:post_end_per_testcase/5`).\n\nIf the skipped test case belongs to a test case group, the second argument is a\ntuple `{FuncName,GroupName}`, otherwise only the function name.\n\nThe data that comes with `Reason` follows the same format as events\n[`tc_auto_skip`](event_handler_chapter.md#tc_auto_skip) and\n[`tc_user_skip`](event_handler_chapter.md#tc_user_skip) For details, see section\n[Event Handling](event_handler_chapter.md#events) in the User's Guide.\n\nIf [`Module:on_tc_skip/4`](`c:on_tc_skip/4`) is not exported, common_test will\nattempt to call `Module:on_tc_skip(TestName, Reason, CTHState)` instead. This is\nfor backwards compatibility.","title":"ct_hooks.on_tc_skip/4","ref":"ct_hooks.html#c:on_tc_skip/4"},{"type":"callback","doc":"This function is called after [`all/0`](`c:ct_suite:all/0`). It is used to\nmodify the set of test cases and test group to be executed, for instance to add\nor remove test cases and groups, change group properties, or even skip all tests\nin the suite.\n\n`Return` is what [`all/0`](`c:ct_suite:all/0`) returned, that is, a list of test\ncases and groups to be executed, or a tuple `{skip,Reason}`.\n\n`GroupDefs` is what [`groups/0`](`c:ct_suite:groups/0`) or the\n[`post_groups/2`](`c:post_groups/2`) hook returned, that is, a list of group\ndefinitions.\n\n`NewReturn` is the possibly modified version of `Return`.\n\nThis function is called only if the CTH is added before `init_per_suite` is run.\nFor details, see section [CTH Scope](ct_hooks_chapter.md#scope) in the User's\nGuide.\n\nNotice that for CTHs that are installed by means of the\n[`suite/0`](`c:ct_suite:suite/0`) function, `post_all/2` is called before the\n`c:init/2` hook function. However, for CTHs that are installed by means of the\nCT start flag, the `c:init/2` function is called first.\n\n> #### Note {: .info }\n>\n> Prior to each test execution, Common Test does a simulated test run in order\n> to count test suites, groups and cases for logging purposes. This causes the\n> [`post_all/3`](`c:post_all/3`) hook function to always be called twice. For\n> this reason, side effects are best avoided in this callback.","title":"ct_hooks.post_all/3","ref":"ct_hooks.html#c:post_all/3"},{"type":"callback","doc":"This function is called after [`end_per_group`](`c:ct_suite:end_per_group/2`) if\nit exists. It behaves the same way as\n[`post_init_per_suite`](`c:post_init_per_suite/4`), but for function\n[end_per_group](`c:ct_suite:end_per_group/2`) instead.\n\nIf [`Module:post_end_per_group/5`](`c:post_end_per_group/5`) is not exported,\ncommon_test will attempt to call\n`Module:post_end_per_group(GroupName, Config, Return, CTHState)` instead. This\nis for backwards compatibility.","title":"ct_hooks.post_end_per_group/5","ref":"ct_hooks.html#c:post_end_per_group/5"},{"type":"callback","doc":"This function is called after [`end_per_suite`](`c:ct_suite:end_per_suite/1`) if\nit exists. It behaves the same way as\n[`post_init_per_suite`](`c:post_init_per_suite/4`), but for function\n[`end_per_suite`](`c:ct_suite:end_per_suite/1`) instead.","title":"ct_hooks.post_end_per_suite/4","ref":"ct_hooks.html#c:post_end_per_suite/4"},{"type":"callback","doc":"This function is called after\n[`end_per_testcase`](`c:ct_suite:end_per_testcase/2`) if it exists. It behaves\nthe same way as [`post_end_per_suite`](`c:post_end_per_suite/4`), but for\nfunction [`end_per_testcase`](`c:ct_suite:end_per_testcase/2`) instead.\n\nIf [`Module:post_end_per_testcase/5`](`c:post_end_per_testcase/5`) is not\nexported, common_test will attempt to call\n`Module:post_end_per_testcase(TestcaseName, Config, Return, CTHState)` instead.\nThis is for backwards compatibility.","title":"ct_hooks.post_end_per_testcase/5","ref":"ct_hooks.html#c:post_end_per_testcase/5"},{"type":"callback","doc":"This function is called after [`groups/0`](`c:ct_suite:groups/0`). It is used to\nmodify the test group definitions, for instance to add or remove groups or\nchange group properties.\n\n`GroupDefs` is what [`groups/0`](`c:ct_suite:groups/0`) returned, that is, a\nlist of group definitions.\n\n`NewGroupDefs` is the possibly modified version of this list.\n\nThis function is called only if the CTH is added before `init_per_suite` is run.\nFor details, see section [CTH Scope](ct_hooks_chapter.md#scope) in the User's\nGuide.\n\nNotice that for CTHs that are installed by means of the\n[`suite/0`](`c:ct_suite:suite/0`) function, [`post_groups/2`](`c:post_groups/2`)\nis called before the `c:init/2` hook function. However, for CTHs that are\ninstalled by means of the CT start flag, the `c:init/2` function is called\nfirst.\n\n> #### Note {: .info }\n>\n> Prior to each test execution, Common Test does a simulated test run in order\n> to count test suites, groups and cases for logging purposes. This causes the\n> [`post_groups/2`](`c:post_groups/2`) hook function to always be called twice.\n> For this reason, side effects are best avoided in this callback.","title":"ct_hooks.post_groups/2","ref":"ct_hooks.html#c:post_groups/2"},{"type":"callback","doc":"This function is called after [`init_per_group`](`c:ct_suite:init_per_group/2`)\nif it exists. It behaves the same way as\n[`post_init_per_suite`](`c:post_init_per_suite/4`), but for function\n[`init_per_group`](`c:ct_suite:init_per_group/2`) instead.\n\nIf [`Module:post_init_per_group/5`](`c:post_init_per_group/5`) is not exported,\ncommon_test will attempt to call\n`Module:post_init_per_group(GroupName, Config, Return, CTHState)` instead. This\nis for backwards compatibility.","title":"ct_hooks.post_init_per_group/5","ref":"ct_hooks.html#c:post_init_per_group/5"},{"type":"callback","doc":"This function is called after [`init_per_suite`](`c:ct_suite:init_per_suite/1`)\nif it exists. It typically contains extra checks to ensure that all the correct\ndependencies are started correctly.\n\n`Return` is what [`init_per_suite`](`c:ct_suite:init_per_suite/1`) returned,\nthat is, `{fail,Reason}`, `{skip,Reason}`, a `Config` list, or a term describing\nhow [`init_per_suite`](`c:ct_suite:init_per_suite/1`) failed.\n\n`NewReturn` is the possibly modified return value of\n[`init_per_suite`](`c:ct_suite:init_per_suite/1`). To recover from a failure in\n[`init_per_suite`](`c:ct_suite:init_per_suite/1`), return `ConfigList` with the\n`tc_status` element removed. For more details, see\n[Post Hooks](ct_hooks_chapter.md#post) in section \"Manipulating Tests\" in the\nUser's Guide.\n\n`CTHState` is the current internal state of the CTH.\n\nThis function is called only if the CTH is added before or in `init_per_suite`.\nFor details, see section [CTH Scope](ct_hooks_chapter.md#scope) in the User's\nGuide.","title":"ct_hooks.post_init_per_suite/4","ref":"ct_hooks.html#c:post_init_per_suite/4"},{"type":"callback","doc":"This function is called after\n[`init_per_testcase`](`c:ct_suite:init_per_testcase/2`) if it exists. It behaves\nthe same way as [`post_init_per_suite`](`c:post_init_per_suite/4`), but for\nfunction [`init_per_testcase`](`c:ct_suite:init_per_testcase/2`) instead.\n\nIf [`Module:post_init_per_testcase/5`](`c:post_init_per_testcase/5`) is not\nexported, common_test will attempt to call\n`Module:post_init_per_testcase(TestcaseName, Config, Return, CTHState)` instead.\nThis is for backwards compatibility.","title":"ct_hooks.post_init_per_testcase/5","ref":"ct_hooks.html#c:post_init_per_testcase/5"},{"type":"callback","doc":"This function is called before [`end_per_group`](`c:ct_suite:end_per_group/2`)\nif it exists. It behaves the same way as\n[`pre_init_per_suite`](`c:pre_init_per_suite/3`), but for function\n[`end_per_group`](`c:ct_suite:end_per_group/2`) instead.\n\nIf [`Module:pre_end_per_group/4`](`c:pre_end_per_group/4`) is not exported,\ncommon_test will attempt to call\n`Module:pre_end_per_group(GroupName, EndData, CTHState)` instead. This is for\nbackwards compatibility.","title":"ct_hooks.pre_end_per_group/4","ref":"ct_hooks.html#c:pre_end_per_group/4"},{"type":"callback","doc":"This function is called before [`end_per_suite`](`c:ct_suite:end_per_suite/1`)\nif it exists. It behaves the same way as\n[`pre_init_per_suite`](`c:pre_init_per_suite/3`), but for function\n[`end_per_suite`](`c:ct_suite:end_per_suite/1`) instead.","title":"ct_hooks.pre_end_per_suite/3","ref":"ct_hooks.html#c:pre_end_per_suite/3"},{"type":"callback","doc":"This function is called before\n[`end_per_testcase`](`c:ct_suite:end_per_testcase/2`) if it exists. It behaves\nthe same way as [`pre_end_per_suite`](`c:pre_end_per_suite/3`), but for function\n[`end_per_testcase`](`c:ct_suite:end_per_testcase/2`) instead.\n\nThis function cannot change the result of the test case by returning skip or\nfail tuples, but it may insert items in `Config` that can be read in\n`end_per_testcase/2` or in\n[`post_end_per_testcase/5`](`c:post_end_per_testcase/5`).\n\nIf [`Module:pre_end_per_testcase/4`](`c:pre_end_per_testcase/4`) is not\nexported, common_test will attempt to call\n`Module:pre_end_per_testcase(TestcaseName, EndData, CTHState)` instead. This is\nfor backwards compatibility.","title":"ct_hooks.pre_end_per_testcase/4","ref":"ct_hooks.html#c:pre_end_per_testcase/4"},{"type":"callback","doc":"This function is called before [`init_per_group`](`c:ct_suite:init_per_group/2`)\nif it exists. It behaves the same way as\n[`pre_init_per_suite`](`c:pre_init_per_suite/3`), but for function\n[`init_per_group`](`c:ct_suite:init_per_group/2`) instead.\n\nIf [`Module:pre_init_per_group/4`](`c:pre_init_per_group/4`) is not exported,\ncommon_test will attempt to call\n`Module:pre_init_per_group(GroupName, InitData, CTHState)` instead. This is for\nbackwards compatibility.","title":"ct_hooks.pre_init_per_group/4","ref":"ct_hooks.html#c:pre_init_per_group/4"},{"type":"callback","doc":"This function is called before [`init_per_suite`](`c:ct_suite:init_per_suite/1`)\nif it exists. It typically contains initialization/logging that must be done\nbefore `init_per_suite` is called. If `{skip,Reason}` or `{fail,Reason}` is\nreturned, `init_per_suite` and all test cases of the suite are skipped and\n`Reason` printed in the overview log of the suite.\n\n`SuiteName` is the name of the suite to be run.\n\n`InitData` is the original configuration list of the test suite, or a\n`SkipOrFail` tuple if a previous CTH has returned this.\n\n`CTHState` is the current internal state of the CTH.\n\n`Return` is the result of the `init_per_suite` function. If it is\n`{skip,Reason}` or `{fail,Reason}`,\n[`init_per_suite`](`c:ct_suite:init_per_suite/1`) is never called, instead the\ninitiation is considered to be skipped or failed, respectively. If a `NewConfig`\nlist is returned, [`init_per_suite`](`c:ct_suite:init_per_suite/1`) is called\nwith that `NewConfig` list. For more details, see section\n[Pre Hooks](ct_hooks_chapter.md#pre) in the User's Guide.\n\nThis function is called only if the CTH is added before `init_per_suite is run`.\nFor details, see section [CTH Scope](ct_hooks_chapter.md#scope) in the User's\nGuide.","title":"ct_hooks.pre_init_per_suite/3","ref":"ct_hooks.html#c:pre_init_per_suite/3"},{"type":"callback","doc":"This function is called before\n[`init_per_testcase`](`c:ct_suite:init_per_testcase/2`) if it exists. It behaves\nthe same way as [`pre_init_per_suite`](`c:pre_init_per_suite/3`), but for\nfunction [`init_per_testcase`](`c:ct_suite:init_per_testcase/2`) instead.\n\nIf [`Module:pre_init_per_testcase/4`](`c:pre_init_per_testcase/4`) is not\nexported, common_test will attempt to call\n`Module:pre_init_per_testcase(TestcaseName, InitData, CTHState)` instead. This\nis for backwards compatibility.\n\nCTHs cannot be added here right now. That feature may be added in a later\nrelease, but it would right now break backwards compatibility.","title":"ct_hooks.pre_init_per_testcase/4","ref":"ct_hooks.html#c:pre_init_per_testcase/4"},{"type":"callback","doc":"This function is called at the end of a CTH [scope](ct_hooks_chapter.md#scope).\nThe returned term is ignored.","title":"ct_hooks.terminate/1","ref":"ct_hooks.html#c:terminate/1"},{"type":"module","doc":"Distributed test execution control for `Common Test`.\n\nThis module exports functions for running `Common Test` nodes on multiple hosts\nin parallel.","title":"ct_master","ref":"ct_master.html"},{"type":"function","doc":"Stops all running tests.","title":"ct_master.abort/0","ref":"ct_master.html#abort/0"},{"type":"function","doc":"Stops tests on specified nodes.","title":"ct_master.abort/1","ref":"ct_master.html#abort/1"},{"type":"function","doc":"If set to `true`, the `ct_master logs` are written on a primitive HTML format,\nnot using the `Common Test` CSS style sheet.","title":"ct_master.basic_html/1","ref":"ct_master.html#basic_html/1"},{"type":"function","doc":"Gets a reference to the `Common Test` master event manager. The reference can be\nused to, for example, add a user-specific event handler while tests are running.\n\n_Example:_\n\n```erlang\ngen_event:add_handler(ct_master:get_event_mgr_ref(), my_ev_h, [])\n```","title":"ct_master.get_event_mgr_ref/0","ref":"ct_master.html#get_event_mgr_ref/0"},{"type":"function","doc":"Returns test progress. If `Status` is `ongoing`, tests are running on the node\nand are not yet finished.","title":"ct_master.progress/0","ref":"ct_master.html#progress/0"},{"type":"function","doc":"Run tests on spawned nodes as specified in `TestSpecs` (see `run/4`).\n\nEquivalent to [`run(TestSpecs, false, [], [])`](`run/4`) if\ncalled with TestSpecs being list of strings;\n\nEquivalent to [`run([TS], false, [], [])`](`run/4`) if\ncalled with TS being string.","title":"ct_master.run/1","ref":"ct_master.html#run/1"},{"type":"function","doc":"","title":"ct_master.run/3","ref":"ct_master.html#run/3"},{"type":"function","doc":"Tests are spawned on the nodes as specified in `TestSpecs`. Each specification\nin `TestSpec` is handled separately. However, it is also possible to specify a\nlist of specifications to be merged into one specification before the tests are\nexecuted. Any test without a particular node specification is also executed on\nthe nodes in `InclNodes`. Nodes in the `ExclNodes` list are excluded from the\ntest.","title":"ct_master.run/4","ref":"ct_master.html#run/4"},{"type":"function","doc":"","title":"ct_master.run_on_node/2","ref":"ct_master.html#run_on_node/2"},{"type":"function","doc":"Tests are spawned on `Node` according to `TestSpecs`.","title":"ct_master.run_on_node/3","ref":"ct_master.html#run_on_node/3"},{"type":"function","doc":"Tests are spawned on `Node` using `ct:run_test/1`","title":"ct_master.run_test/2","ref":"ct_master.html#run_test/2"},{"type":"type","doc":"Filename of test spec to be executed.","title":"ct_master.test_spec/0","ref":"ct_master.html#t:test_spec/0"},{"type":"module","doc":"NETCONF client module.\n\nNETCONF client module compliant with RFC 6241, NETCONF Configuration Protocol,\nand RFC 6242, Using the NETCONF Configuration Protocol over Secure SHell (SSH),\nand with support for RFC 5277, NETCONF Event Notifications.\n\n[](){: #Connecting }\n\n_Connecting to a NETCONF server_\n\nCall [`connect/1,2`](`connect/1`) to establish a connection to a server, then\npass the returned handle to [`session/1-3`](`session/1`) to establish a NETCONF\nsession on a new SSH channel. Each call to [`session/1-3`](`session/1`)\nestablishes a new session on the same connection, and results in a hello message\nto the server.\n\nAlternately, [`open/1,2`](`open/1`) can be used to establish a single session on\na dedicated connection. (Or, equivalently, [`only_open/1,2`](`only_open/1`)\nfollowed by [`hello/1-3`](`hello/1`).)\n\nConnect/session options can be specified in a configuration file with entries\nlike the following.\n\n```erlang\n{server_id(), [option()]}.\n```\n\nThe `t:server_id/0` or an associated `t:ct:target_name/0` can then be passed to\nthe aforementioned functions to use the referenced configuration.\n\n[](){: #Signaling }\n\n_Signaling_\n\nProtocol operations in the NETCONF protocol are realized as remote procedure\ncalls (RPCs) from client to server and a corresponding reply from server to\nclient. RPCs are sent using like-named functions (eg.\n[`edit_config/3-5`](`edit_config/3`) to send an edit-config RPC), with the\nserver reply as return value. There are functions for each RPC defined in RFC\n6241 and the create-subscription RPC from RFC 5277, all of which are wrappers on\n[`send_rpc/2,3`](`send_rpc/2`), that can be used to send an arbitrary RPC not\ndefined in RFC 6241 or RFC 5277.\n\nAll of the signaling functions have one variant with a `Timeout` argument and\none without, corresponding to an infinite timeout. The latter is inappropriate\nin most cases since a non-response by the server or a missing message-id causes\nthe call to hang indefinitely.\n\n[](){: #Logging }\n\n_Logging_\n\nThe NETCONF server uses `error_logger` for logging of NETCONF traffic. A special\npurpose error handler is implemented in `ct_conn_log_h`. To use this error\nhandler, add the `cth_conn_log` hook in the test suite, for example:\n\n```erlang\nsuite() ->\n [{ct_hooks, [{cth_conn_log, [{ct:conn_log_mod(), ct:conn_log_options()}]}]}].\n```\n\n`conn_log_mod()` is the name of the `Common Test` module implementing the\nconnection protocol, for example, `ct_netconfc`.\n\nHook option `log_type` specifies the type of logging:\n\n- **`raw`** - The sent and received NETCONF data is logged to a separate text\n file \"as is\" without any formatting. A link to the file is added to the test\n case HTML log.\n\n- **`pretty`** - The sent and received NETCONF data is logged to a separate text\n file with XML data nicely indented. A link to the file is added to the test\n case HTML log.\n\n- **`html (default)`** - The sent and received NETCONF traffic is pretty printed\n directly in the test case HTML log.\n\n- **`silent`** - NETCONF traffic is not logged.\n\nBy default, all NETCONF traffic is logged in one single log file. However,\ndifferent connections can be logged in separate files. To do this, use hook\noption `hosts` and list the names of the servers/connections to be used in the\nsuite. The connections must be named for this to work, that is, they must be\nopened with `open/2`.\n\nOption `hosts` has no effect if `log_type` is set to `html` or `silent`.\n\nThe hook options can also be specified in a configuration file with\nconfiguration variable `ct_conn_log`:\n\n```erlang\n{ct_conn_log,[{ct:conn_log_mod(), ct:conn_log_options()}]}.\n```\n\nFor example:\n\n```erlang\n{ct_conn_log,[{ct_netconfc,[{log_type,pretty},\n {hosts,[ct:key_or_name()]}]}]}\n```\n\n> #### Note {: .info }\n>\n> Hook options specified in a configuration file overwrite the hard-coded hook\n> options in the test suite.\n\n_Logging Example 1:_\n\n[](){: #Logging_example_1 }\n\nThe following `ct_hooks` statement causes pretty printing of NETCONF traffic to\nseparate logs for the connections named `nc_server1` and `nc_server2`. Any other\nconnections are logged to default NETCONF log.\n\n```erlang\nsuite() ->\n [{ct_hooks, [{cth_conn_log, [{ct_netconfc,[{log_type,pretty}},\n {hosts,[nc_server1,nc_server2]}]}\n ]}]}].\n```\n\nConnections must be opened as follows:\n\n```erlang\nopen(nc_server1,[...]),\nopen(nc_server2,[...]).\n```\n\n_Logging Example 2:_\n\n[](){: #Logging_example_2 }\n\nThe following configuration file causes raw logging of all NETCONF traffic in to\none single text file:\n\n```erlang\n{ct_conn_log,[{ct_netconfc,[{log_type,raw}]}]}.\n```\n\nThe `ct_hooks` statement must look as follows:\n\n```erlang\nsuite() ->\n [{ct_hooks, [{cth_conn_log, []}]}].\n```\n\nThe same `ct_hooks` statement without the configuration file would cause HTML\nlogging of all NETCONF connections in to the test case HTML log.","title":"ct_netconfc","ref":"ct_netconfc.html"},{"type":"function","doc":"","title":"ct_netconfc.action/2","ref":"ct_netconfc.html#action/2"},{"type":"function","doc":"Executes an action. If the return type is void, `ok` is returned instead of\n`{ok,[simple_xml()]}`.","title":"ct_netconfc.action/3","ref":"ct_netconfc.html#action/3"},{"type":"function","doc":"","title":"ct_netconfc.close_session/1","ref":"ct_netconfc.html#close_session/1"},{"type":"function","doc":"Requests graceful termination of the session associated with the client.\n\nWhen a NETCONF server receives a `close-session` request, it gracefully closes\nthe session. The server releases any locks and resources associated with the\nsession and gracefully closes any associated connections. Any NETCONF requests\nreceived after a `close-session` request are ignored.","title":"ct_netconfc.close_session/2","ref":"ct_netconfc.html#close_session/2"},{"type":"function","doc":"Opens an SSH connection to a NETCONF server.\n\nIf the server options are specified in a configuration file, use `connect/2`\ninstead.\n\nThe opaque `t:handle/0` reference returned from this function is required as\nconnection identifier when opening sessions over this connection, see\n[`session/1-3`](`session/1`).","title":"ct_netconfc.connect/1","ref":"ct_netconfc.html#connect/1"},{"type":"function","doc":"Open an SSH connection to a named NETCONF server.\n\nIf `KeyOrName` is a configured `t:server_id/0` or a `target_name()` associated\nwith such an Id, then the options for this server are fetched from the\nconfiguration file.\n\nThe options list is added to those of the configuration file. If an option is\nspecified in both lists, the configuration file takes precedence.\n\nIf the server is not specified in a configuration file, use `connect/1` instead.\n\nThe opaque `t:handle/0` reference returned from this function can be used as\nconnection identifier when opening sessions over this connection, see\n[`session/1-3`](`session/1`). However, if `KeyOrName` is a `target_name()`, that\nis, if the server is named through a call to `ct:require/2` or a `require`\nstatement in the test suite, then this name can be used instead of `t:handle/0`.","title":"ct_netconfc.connect/2","ref":"ct_netconfc.html#connect/2"},{"type":"function","doc":"","title":"ct_netconfc.copy_config/3","ref":"ct_netconfc.html#copy_config/3"},{"type":"function","doc":"Copies configuration data.\n\nWhich source and target options that can be issued depends on the capabilities\nsupported by the server. That is, `:candidate` and/or `:startup` are required.","title":"ct_netconfc.copy_config/4","ref":"ct_netconfc.html#copy_config/4"},{"type":"function","doc":"","title":"ct_netconfc.create_subscription/2","ref":"ct_netconfc.html#create_subscription/2"},{"type":"function","doc":"Creates a subscription for event notifications by sending an RFC 5277\ncreate-subscription RPC to the server. The calling process receives events as\nmessages of type `t:notification/0`.\n\nFrom RFC 5722, 2.1 Subscribing to Receive Event Notifications:\n\n- **`Stream`** - Indicates which stream of event is of interest. If not present,\n events in the default NETCONF stream are sent.\n\n- **`Filter`** - Indicates which subset of all possible events is of interest.\n The parameter format is the same as that of the filter parameter in the\n NETCONF protocol operations. If not present, all events not precluded by other\n parameters are sent.\n\n- **`StartTime`** - Used to trigger the replay feature and indicate that the\n replay is to start at the time specified. If `StartTime` is not present, this\n is not a replay subscription. It is not valid to specify start times that are\n later than the current time. If `StartTime` is specified earlier than the log\n can support, the replay begins with the earliest available notification. This\n parameter is of type `dateTime` and compliant to RFC 3339. Implementations\n must support time zones.\n\n- **`StopTime`** - Used with the optional replay feature to indicate the newest\n notifications of interest. If `StopTime` is not present, the notifications\n continues until the subscription is terminated. Must be used with and be later\n than `StartTime`. Values of `StopTime` in the future are valid. This parameter\n is of type `dateTime` and compliant to RFC 3339. Implementations must support\n time zones.\n\nSee RFC 5277 for more details. The requirement that `StopTime` must only be used\nwith `StartTime` is not enforced, to allow an invalid request to be sent to the\nserver.\n\nPrior to OTP 22.1, this function was documented as having 15 variants in 6\narities. These are still exported for backwards compatibility, but no longer\ndocumented. The map-based variants documented above provide the same\nfunctionality with simpler arguments.\n\n> #### Note {: .info }\n>\n> create-subscription is no longer the only RPC with which NETCONF notifications\n> can be ordered: RFC 8639 adds establish-subscription and future RFCs may add\n> other methods. Specify a `receiver` option at session creation to provide a\n> destination for incoming notifications independently of a call to\n> [`create_subscription/2,3`](`create_subscription/2`), and use\n> [`send_rpc/2,3`](`send_rpc/2`) to send establish-subscription and other\n> arbitrary RPCs.","title":"ct_netconfc.create_subscription/3","ref":"ct_netconfc.html#create_subscription/3"},{"type":"function","doc":"","title":"ct_netconfc.delete_config/2","ref":"ct_netconfc.html#delete_config/2"},{"type":"function","doc":"Deletes configuration data.\n\nThe running configuration cannot be deleted and `:candidate` or `:startup` must\nbe advertised by the server.","title":"ct_netconfc.delete_config/3","ref":"ct_netconfc.html#delete_config/3"},{"type":"function","doc":"Closes the given SSH connection.\n\nIf there are open NETCONF sessions on the connection, these will be brutally\naborted. To avoid this, close each session with\n[`close_session/1,2`](`close_session/1`)","title":"ct_netconfc.disconnect/1","ref":"ct_netconfc.html#disconnect/1"},{"type":"function","doc":"","title":"ct_netconfc.edit_config/3","ref":"ct_netconfc.html#edit_config/3"},{"type":"function","doc":"","title":"ct_netconfc.edit_config/4","ref":"ct_netconfc.html#edit_config/4"},{"type":"function","doc":"Edits configuration data.\n\nBy default only the running target is available, unless the server includes\n`:candidate` or `:startup` in its list of capabilities.\n\n`OptParams` can be used for specifying optional parameters (`default-operation`,\n`test-option`, or `error-option`) to be added to the `edit-config` request. The\nvalue must be a list containing valid simple XML, for example:\n\n```erlang\n[{'default-operation', [\"none\"]},\n {'error-option', [\"rollback-on-error\"]}]\n```\n\nIf `OptParams` is not given, the default value `[]` is used.","title":"ct_netconfc.edit_config/5","ref":"ct_netconfc.html#edit_config/5"},{"type":"function","doc":"","title":"ct_netconfc.get/2","ref":"ct_netconfc.html#get/2"},{"type":"function","doc":"Gets data.\n\nThis operation returns both configuration and state data from the server.\n\nFilter type `xpath` can be used only if the server supports `:xpath`.","title":"ct_netconfc.get/3","ref":"ct_netconfc.html#get/3"},{"type":"function","doc":"","title":"ct_netconfc.get_capabilities/1","ref":"ct_netconfc.html#get_capabilities/1"},{"type":"function","doc":"Returns the server capabilities as received in its hello message.","title":"ct_netconfc.get_capabilities/2","ref":"ct_netconfc.html#get_capabilities/2"},{"type":"function","doc":"","title":"ct_netconfc.get_config/3","ref":"ct_netconfc.html#get_config/3"},{"type":"function","doc":"Gets configuration data.\n\nTo be able to access another source than `running`, the server must advertise\n`:candidate` and/or `:startup`.\n\nFilter type `xpath` can be used only if the server supports `:xpath`.","title":"ct_netconfc.get_config/4","ref":"ct_netconfc.html#get_config/4"},{"type":"function","doc":"","title":"ct_netconfc.get_event_streams/1","ref":"ct_netconfc.html#get_event_streams/1"},{"type":"function","doc":"","title":"ct_netconfc.get_event_streams/2","ref":"ct_netconfc.html#get_event_streams/2"},{"type":"function","doc":"Sends a request to get the specified event streams.\n\n`Streams` is a list of stream names. The following filter is sent to the NETCONF\nserver in a `get` request:\n\n```text\n \n \n \n StreamName1 \n \n \n StreamName2 \n \n ...\n \n \n```\n\nIf `Streams` is an empty list, _all_ streams are requested by sending the\nfollowing filter:\n\n```text\n \n \n \n```\n\nIf more complex filtering is needed, use [`ct_netconfc:get/2,3`](`get/2`) and\nspecify the exact filter according to \"XML Schema for Event Notifications\" in\nRFC 5277.","title":"ct_netconfc.get_event_streams/3","ref":"ct_netconfc.html#get_event_streams/3"},{"type":"function","doc":"","title":"ct_netconfc.get_session_id/1","ref":"ct_netconfc.html#get_session_id/1"},{"type":"function","doc":"Returns the session Id associated with the specified client.","title":"ct_netconfc.get_session_id/2","ref":"ct_netconfc.html#get_session_id/2"},{"type":"function","doc":"","title":"ct_netconfc.hello/1","ref":"ct_netconfc.html#hello/1"},{"type":"function","doc":"","title":"ct_netconfc.hello/2","ref":"ct_netconfc.html#hello/2"},{"type":"function","doc":"Exchanges `hello` messages with the server. Returns when the server hello has\nbeen received or after the specified timeout.\n\nNote that capabilities for an outgoing hello can be passed directly to `open/2`.","title":"ct_netconfc.hello/3","ref":"ct_netconfc.html#hello/3"},{"type":"function","doc":"","title":"ct_netconfc.kill_session/2","ref":"ct_netconfc.html#kill_session/2"},{"type":"function","doc":"Forces termination of the session associated with the supplied session Id.\n\nThe server side must abort any ongoing operations, release any locks and\nresources associated with the session, and close any associated connections.\n\nOnly if the server is in the confirmed commit phase, the configuration is\nrestored to its state before entering the confirmed commit phase. Otherwise, no\nconfiguration rollback is performed.\n\nIf the specified `SessionId` is equal to the current session Id, an error is\nreturned.","title":"ct_netconfc.kill_session/3","ref":"ct_netconfc.html#kill_session/3"},{"type":"function","doc":"","title":"ct_netconfc.lock/2","ref":"ct_netconfc.html#lock/2"},{"type":"function","doc":"Locks the configuration target.\n\nWhich target parameters that can be used depends on if `:candidate` and/or\n`:startup` are supported by the server. If successful, the configuration system\nof the device is unavailable to other clients (NETCONF, CORBA, SNMP, and so on).\nLocks are intended to be short-lived.\n\nOperation [`kill_session/2,3`](`kill_session/2`) can be used to force the\nrelease of a lock owned by another NETCONF session. How this is achieved by the\nserver side is implementation-specific.","title":"ct_netconfc.lock/3","ref":"ct_netconfc.html#lock/3"},{"type":"function","doc":"Opens a NETCONF session, but does not send `hello`.\n\nAs `open/1`, but does not send a `hello` message.","title":"ct_netconfc.only_open/1","ref":"ct_netconfc.html#only_open/1"},{"type":"function","doc":"Opens a named NETCONF session, but does not send `hello`.\n\nAs `open/2`, but does not send a `hello` message.","title":"ct_netconfc.only_open/2","ref":"ct_netconfc.html#only_open/2"},{"type":"function","doc":"Opens a NETCONF session and exchanges `hello` messages.\n\nIf the server options are specified in a configuration file, or if a named\nclient is needed for logging purposes (see section\n[Logging](`m:ct_netconfc#Logging`) in this module), use `open/2` instead.\n\nThe opaque `t:handle/0` reference returned from this function is required as\nclient identifier when calling any other function in this module.","title":"ct_netconfc.open/1","ref":"ct_netconfc.html#open/1"},{"type":"function","doc":"Opens a named NETCONF session and exchanges `hello` messages.\n\nIf `KeyOrName` is a configured `t:server_id/0` or a `target_name()` associated\nwith such an Id, then the options for this server are fetched from the\nconfiguration file.\n\nThe options list is added to those of the configuration file. If an option is\nspecified in both lists, the configuration file take precedence.\n\nIf the server is not specified in a configuration file, use `open/1` instead.\n\nThe opaque `t:handle/0` reference returned from this function can be used as\nclient identifier when calling any other function in this module. However, if\n`KeyOrName` is a `target_name()`, that is, if the server is named through a call\nto `ct:require/2` or a `require` statement in the test suite, then this name can\nbe used instead of `t:handle/0`.\n\nSee also `ct:require/2`.","title":"ct_netconfc.open/2","ref":"ct_netconfc.html#open/2"},{"type":"function","doc":"","title":"ct_netconfc.send/2","ref":"ct_netconfc.html#send/2"},{"type":"function","doc":"Sends an XML document to the server.\n\nThe specified XML document is sent \"as is\" to the server. This function can be\nused for sending XML documents that cannot be expressed by other interface\nfunctions in this module.","title":"ct_netconfc.send/3","ref":"ct_netconfc.html#send/3"},{"type":"function","doc":"","title":"ct_netconfc.send_rpc/2","ref":"ct_netconfc.html#send_rpc/2"},{"type":"function","doc":"Sends a NETCONF `rpc` request to the server.\n\nThe specified XML document is wrapped in a valid NETCONF `rpc` request and sent\nto the server. The `message-id` and namespace attributes are added to element\n`rpc`.\n\nThis function can be used for sending `rpc` requests that cannot be expressed by\nother interface functions in this module.","title":"ct_netconfc.send_rpc/3","ref":"ct_netconfc.html#send_rpc/3"},{"type":"function","doc":"","title":"ct_netconfc.session/1","ref":"ct_netconfc.html#session/1"},{"type":"function","doc":"","title":"ct_netconfc.session/2","ref":"ct_netconfc.html#session/2"},{"type":"function","doc":"Opens a NETCONF session as a channel on the given SSH connection, and exchanges\nhello messages with the server.\n\nThe opaque `t:handle/0` reference returned from this function can be used as\nclient identifier when calling any other function in this module. However, if\n`KeyOrName` is used and it is a `target_name()`, that is, if the server is named\nthrough a call to `ct:require/2` or a `require` statement in the test suite,\nthen this name can be used instead of `t:handle/0`.","title":"ct_netconfc.session/3","ref":"ct_netconfc.html#session/3"},{"type":"function","doc":"","title":"ct_netconfc.unlock/2","ref":"ct_netconfc.html#unlock/2"},{"type":"function","doc":"Unlocks the configuration target.\n\nIf the client earlier has acquired a lock through [`lock/2,3`](`lock/2`), this\noperation releases the associated lock. To access another target than `running`,\nthe server must support `:candidate` and/or `:startup`.","title":"ct_netconfc.unlock/3","ref":"ct_netconfc.html#unlock/3"},{"type":"type","doc":"Handle to a NETCONF session, as required by signaling functions.","title":"ct_netconfc.client/0","ref":"ct_netconfc.html#t:client/0"},{"type":"type","doc":"","title":"ct_netconfc.error_reason/0","ref":"ct_netconfc.html#t:error_reason/0"},{"type":"opaque","doc":"Handle to a connection to a NETCONF server as returned by\n[`connect/1,2`](`connect/1`), or to a session as returned by\n[`session/1-3`](`session/1`), [`open/1,2`](`open/1`), or\n[`only_open/1,2`](`only_open/1`).","title":"ct_netconfc.handle/0","ref":"ct_netconfc.html#t:handle/0"},{"type":"type","doc":"","title":"ct_netconfc.host/0","ref":"ct_netconfc.html#t:host/0"},{"type":"type","doc":"","title":"ct_netconfc.netconf_db/0","ref":"ct_netconfc.html#t:netconf_db/0"},{"type":"type","doc":"Event notification messages sent as a result of calls to\n[`create_subscription/2,3`](`create_subscription/2`).","title":"ct_netconfc.notification/0","ref":"ct_netconfc.html#t:notification/0"},{"type":"type","doc":"Options `host` and `port` specify the server endpoint to which to connect, and\nare passed directly to [`ssh:connect/4`](`ssh:connect/3`), as are arbitrary ssh\noptions. Common options are `user`, `password` and `user_dir`.\n\nOption `timeout` specifies the number of milliseconds to allow for connection\nestablishment and, if the function in question results in an outgoing hello\nmessage, reception of the server hello. The timeout applies to connection and\nhello independently; one timeout for connection establishment, another for hello\nreception.\n\nOption `receiver` specifies a destination for incoming notification messages; a\nleft operand of the send operator (`!`). If not specified then a process calling\n[`create_subscription/2,3`](`create_subscription/2`) becomes the receiver, but\nexplicitly setting a receiver makes it possible to receive notifications that\nare not ordered by calling this function. Multiple receiver options can be\nspecified.\n\nReceiver options are ignored by connect/1-3.\n\nOption `capability` specifies the content of a corresponding element in an\noutgoing hello message, each option specifying the content of a single element.\nIf no base NETCONF capability is configured then the RFC 4741 1.0 capability,\n\"urn:ietf:params:netconf:base:1.0\", is added, otherwise not. In particular, the\nRFC 6241 1.1 capability must be explicitly configured. NETCONF capabilities can\nbe specified using the shorthand notation defined in RFC 6241, any capability\nstring starting with a colon being prefixed by either \"urn:ietf:params:netconf\"\nor \"urn:ietf:params:netconf:capability\", as appropriate.\n\nCapability options are ignored by connect/1-3 and only_open/1-2, which don't\nresult in an outgoing hello message.","title":"ct_netconfc.option/0","ref":"ct_netconfc.html#t:option/0"},{"type":"type","doc":"Identity of connection or session configuration in a configuration file.","title":"ct_netconfc.server_id/0","ref":"ct_netconfc.html#t:server_id/0"},{"type":"type","doc":"","title":"ct_netconfc.session_option/0","ref":"ct_netconfc.html#t:session_option/0"},{"type":"type","doc":"Representation of XML, as described in application\n[`xmerl`](`e:xmerl:index.html`).","title":"ct_netconfc.simple_xml/0","ref":"ct_netconfc.html#t:simple_xml/0"},{"type":"type","doc":"","title":"ct_netconfc.stream_data/0","ref":"ct_netconfc.html#t:stream_data/0"},{"type":"type","doc":"","title":"ct_netconfc.stream_name/0","ref":"ct_netconfc.html#t:stream_name/0"},{"type":"type","doc":"Stream information as returned by\n[`get_event_streams/1-3`](`get_event_streams/1`). See RFC 5277, \"XML Schema for\nEvent Notifications\", for detail on the format of the string values.","title":"ct_netconfc.streams/0","ref":"ct_netconfc.html#t:streams/0"},{"type":"type","doc":"","title":"ct_netconfc.xml_attribute_tag/0","ref":"ct_netconfc.html#t:xml_attribute_tag/0"},{"type":"type","doc":"","title":"ct_netconfc.xml_attribute_value/0","ref":"ct_netconfc.html#t:xml_attribute_value/0"},{"type":"type","doc":"","title":"ct_netconfc.xml_attributes/0","ref":"ct_netconfc.html#t:xml_attributes/0"},{"type":"type","doc":"","title":"ct_netconfc.xml_content/0","ref":"ct_netconfc.html#t:xml_content/0"},{"type":"type","doc":"","title":"ct_netconfc.xml_tag/0","ref":"ct_netconfc.html#t:xml_tag/0"},{"type":"type","doc":"","title":"ct_netconfc.xpath/0","ref":"ct_netconfc.html#t:xpath/0"},{"type":"type","doc":"Date and time of a startTime/stopTime element in an RFC 5277 create-subscription\nrequest. Of XML primitive type `dateTime`, which has the (informal) form\n\n```text\n[-]YYYY-MM-DDThh:mm:ss[.s][Z|(+|-)hh:mm]\n```\n\nwhere `T` and `Z` are literal and `.s` is one or more fractional seconds.","title":"ct_netconfc.xs_datetime/0","ref":"ct_netconfc.html#t:xs_datetime/0"},{"type":"module","doc":"Support in Common Test for running property-based tests.\n\nThis module helps running property-based tests in the `Common Test` framework.\nOne (or more) of the property testing tools\n\n- [QuickCheck](http://www.quviq.com),\n- [PropEr](https://proper-testing.github.io) or\n- [Triq](https://github.com/krestenkrab/triq)\n\nis assumed to be installed.\n\nThe idea with this module is to have a `Common Test` test suite calling a\nproperty testing tool with special property test suites as defined by that tool.\nThe tests are collected in the `test` directory of the application. The `test`\ndirectory has a subdirectory `property_test`, where everything needed for the\nproperty tests are collected. The usual Erlang application directory structure\nis assumed.\n\nA typical `Common Test` test suite using `ct_property_test` is organized as\nfollows:\n\n```erlang\n-module(my_prop_test_SUITE).\n-compile(export_all).\n\n-include_lib(\"common_test/include/ct.hrl\").\n\nall() -> [prop_ftp_case].\n\ninit_per_suite(Config) ->\n ct_property_test:init_per_suite(Config).\n\n%%%---- test case\nprop_ftp_case(Config) ->\n ct_property_test:quickcheck(\n ftp_simple_client_server:prop_ftp(),\n Config\n ).\n```\n\nand the the property test module (in this example\n`ftp_simple_client_server.erl`) as almost a usual property testing module (More\nexamples are in [the User's Guide](ct_property_test_chapter.md)):\n\n```erlang\n-module(ftp_simple_client_server).\n-export([prop_ftp/0...]).\n\n-include_lib(\"common_test/include/ct_property_test.hrl\").\n\nprop_ftp() ->\n ?FORALL( ....\n```","title":"ct_property_test","ref":"ct_property_test.html"},{"type":"function","doc":"Returns a list of commands (function calls) generated in the `Cmnd` sequence,\nwithout Module, Arguments and other details.\n\nFor more information see: `present_result/5`.","title":"ct_property_test.cmnd_names/1","ref":"ct_property_test.html#cmnd_names/1"},{"type":"function","doc":"Initializes and extends `Config` for property based testing.\n\nThis function investigates if support is available for either\n[QuickCheck](http://www.quviq.com), [PropEr](https://proper-testing.github.io)\nor [Triq](https://github.com/krestenkrab/triq) and compiles the properties with\nthe first tool found. It is supposed to be called in the\n[`init_per_suite/1`](`init_per_suite/1`) function in a CommonTest test suite.\n\nWhich tools to check for, and in which order could be set with the option\n`{prop_tools, list(eqc|proper|triq)}` in the CommonTest configuration `Config`.\nThe default value is `[eqc, proper, triq]` with `eqc` being the first one\nsearched for.\n\nIf no support is found for any tool, this function returns\n`{skip, Explanation}`.\n\nIn case of other errors, this function returns\n`{fail, Explanation}`.\n\nIf support is found, the option `{property_test_tool,ToolModule}` with the\nselected tool main module name (`eqc`, `proper` or `triq`) is added to the list\n`Config` which then is returned.\n\nThe property tests are assumed to be in a subdirectory named `property_test`.\nAll found Erlang files in that directory are compiled with one of the macros\n`'EQC'`, `'PROPER'` or `'TRIQ'` set, depending on which tool that is first\nfound. This could make parts of the Erlang property tests code to be included or\nexcluded with the macro directives `-ifdef(Macro).` or `-ifndef(Macro).`.\n\nThe file(s) in the `property_test` subdirectory could, or should, include the\nct_property_test include file:\n\n```erlang\n-include_lib(\"common_test/include/ct_property_test.hrl\").\n```\n\nThis included file will:\n\n- Include the correct tool's include file\n- Set the macro `'MOD_eqc'` to the correct module name for the selected tool.\n That is, the macro `'MOD_eqc'` is set to either `eqc`, `proper` or `triq`.","title":"ct_property_test.init_per_suite/1","ref":"ct_property_test.html#init_per_suite/1"},{"type":"function","doc":"Returns number of command calls in a test case.\n\nFor more information see: `present_result/5`.","title":"ct_property_test.num_calls/1","ref":"ct_property_test.html#num_calls/1"},{"type":"function","doc":"","title":"ct_property_test.present_result/4","ref":"ct_property_test.html#present_result/4"},{"type":"function","doc":"Presents the result of _stateful (statem) property testing_ using the aggregate\nfunction in PropEr, QuickCheck or other similar property testing tool.\n\nIt is assumed to be called inside the property called by `quickcheck/2`:\n\n```erlang\n...\nRunResult = run_parallel_commands(?MODULE, Cmds),\nct_property_test:present_result(?MODULE, Cmds, RunResult, Config)\n...\n```\n\nSee the [User's Guide](ct_property_test_chapter.md#stateful1) for an example of\nthe usage and of the default printout.\n\nThe `StatisticsSpec` is a list of the tuples:\n\n- `{Title::string(), CollectFun::fun/1}`\n- `{Title::string(), FrequencyFun::/0, CollectFun::fun/1}`\n\nEach tuple will produce one table in the order of their places in the list.\n\n- `Title` will be the title of one result table\n- `CollectFun` is called with one argument: the `Cmds`. It should return a list\n of the values to be counted. The following pre-defined functions exist:\n - `ct_property_test:cmnd_names/1` returns a list of commands (function calls)\n generated in the `Cmnd` sequence, without Module, Arguments and other\n details.\n - `ct_property_test:num_calls/1` returns a list of the length of commands\n lists\n - `ct_property_test:sequential_parallel/1` returns a list with information\n about sequential and parallel parts from `Tool:parallel_commands/1,2`\n- `FrequencyFun/0` returns a fun/1 which is supposed to take a list of items as\n input, and return an iolist which will be printed as the table. Per default,\n the number of each item is counted and the percentage is printed for each. The\n list \\[a,b,a,a,c] could for example return\n\n ```erlang\n [\"a 60%\\n\",\"b 20%\\n\",\"c 20%\\n\"]\n ```\n\n which will be printed by the `print_fun`. The default `print_fun` will print\n it as:\n\n ```text\n a 60%\n b 20%\n c 20%\n ```\n\nThe default `StatisticsSpec` is:\n\n- For sequential commands:\n\n ```erlang\n [{\"Function calls\", fun cmnd_names/1},\n {\"Length of command sequences\", fun print_frequency_ranges/0,\n fun num_calls/1}]\n ```\n\n- For parallel commands:\n\n ```erlang\n [{\"Distribution sequential/parallel\", fun sequential_parallel/1},\n {\"Function calls\", fun cmnd_names/1},\n {\"Length of command sequences\", fun print_frequency_ranges/0,\n fun num_calls/1}]\n ```","title":"ct_property_test.present_result/5","ref":"ct_property_test.html#present_result/5"},{"type":"function","doc":"Calls the selected tool's function for running the `Property`. It is usually and\nby historical reasons called quickcheck, and that is why that name is used in\nthis module (`ct_property_test`).\n\nThe result is returned in a form suitable for `Common Test` test suites.\n\nThis function is intended to be called in test cases in test suites.","title":"ct_property_test.quickcheck/2","ref":"ct_property_test.html#quickcheck/2"},{"type":"function","doc":"Returns a list with information about sequential and parallel parts.\n\nFor more information see: `present_result/5`.","title":"ct_property_test.sequential_parallel/1","ref":"ct_property_test.html#sequential_parallel/1"},{"type":"type","doc":"","title":"ct_property_test.arguments/0","ref":"ct_property_test.html#t:arguments/0"},{"type":"type","doc":"","title":"ct_property_test.command/0","ref":"ct_property_test.html#t:command/0"},{"type":"type","doc":"","title":"ct_property_test.command_list/0","ref":"ct_property_test.html#t:command_list/0"},{"type":"type","doc":"","title":"ct_property_test.dynamic_state/0","ref":"ct_property_test.html#t:dynamic_state/0"},{"type":"type","doc":"","title":"ct_property_test.function_name/0","ref":"ct_property_test.html#t:function_name/0"},{"type":"type","doc":"","title":"ct_property_test.history/0","ref":"ct_property_test.html#t:history/0"},{"type":"type","doc":"","title":"ct_property_test.init_command/0","ref":"ct_property_test.html#t:init_command/0"},{"type":"type","doc":"","title":"ct_property_test.parallel_testcase/0","ref":"ct_property_test.html#t:parallel_testcase/0"},{"type":"type","doc":"","title":"ct_property_test.set_command/0","ref":"ct_property_test.html#t:set_command/0"},{"type":"type","doc":"","title":"ct_property_test.statem_result/0","ref":"ct_property_test.html#t:statem_result/0"},{"type":"type","doc":"","title":"ct_property_test.symbolic_call/0","ref":"ct_property_test.html#t:symbolic_call/0"},{"type":"type","doc":"","title":"ct_property_test.symbolic_state/0","ref":"ct_property_test.html#t:symbolic_state/0"},{"type":"type","doc":"","title":"ct_property_test.symbolic_var/0","ref":"ct_property_test.html#t:symbolic_var/0"},{"type":"module","doc":"`Common Test` specific layer on Erlang/OTP `rpc`.","title":"ct_rpc","ref":"ct_rpc.html"},{"type":"function","doc":"From a set of candidate nodes determines which of them is running the\napplication `App`. If none of the candidate nodes is running `App`, the function\nmakes the test case calling this function to fail. This function is the same as\ncalling [`app_node(App, Candidates, true)`](`app_node/3`).","title":"ct_rpc.app_node/2","ref":"ct_rpc.html#app_node/2"},{"type":"function","doc":"Same as [`ct_rpc:app_node/2`](`app_node/2`), except that argument `FailOnBadRPC`\ndetermines if the search for a candidate node is to stop if `badrpc` is received\nat some point.","title":"ct_rpc.app_node/3","ref":"ct_rpc.html#app_node/3"},{"type":"function","doc":"Same as [`ct_rpc:app_node/2`](`app_node/2`), except that argument `FailOnBadRPC`\ndetermines if the search for a candidate node is to stop if `badrpc` is received\nat some point.\n\nThe cookie on the client node is set to `Cookie` for this `rpc` operation (used\nto match the server node cookie).","title":"ct_rpc.app_node/4","ref":"ct_rpc.html#app_node/4"},{"type":"function","doc":"","title":"ct_rpc.call/4","ref":"ct_rpc.html#call/4"},{"type":"function","doc":"Evaluates [`apply(Module, Function, Args)`](`apply/3`) on the node `Node`.\nReturns either whatever `Function` returns, or `{badrpc, Reason}` if the remote\nprocedure call fails. If `Node` is `{Fun, FunArgs}`, applying `Fun` to `FunArgs`\nis to return a node name.","title":"ct_rpc.call/5","ref":"ct_rpc.html#call/5"},{"type":"function","doc":"Evaluates [`apply(Module, Function, Args)`](`apply/3`) on the node `Node`.\nReturns either whatever `Function` returns, or `{badrpc, Reason}` if the remote\nprocedure call fails. If `Node` is `{Fun, FunArgs}`, applying `Fun` to `FunArgs`\nis to return a node name.\n\nThe cookie on the client node is set to `Cookie` for this `rpc` operation (used\nto match the server node cookie).","title":"ct_rpc.call/6","ref":"ct_rpc.html#call/6"},{"type":"function","doc":"Evaluates [`apply(Module, Function, Args)`](`apply/3`) on the node `Node`. No\nresponse is delivered and the process that makes the call is not suspended until\nthe evaluation is completed as in the case of `call/3,4`. If `Node` is\n`{Fun, FunArgs}`, applying `Fun` to `FunArgs` is to return a node name.","title":"ct_rpc.cast/4","ref":"ct_rpc.html#cast/4"},{"type":"function","doc":"Evaluates [`apply(Module, Function, Args)`](`apply/3`) on the node `Node`. No\nresponse is delivered and the process that makes the call is not suspended until\nthe evaluation is completed as in the case of `call/3,4`. If `Node` is\n`{Fun, FunArgs}`, applying `Fun` to `FunArgs` is to return a node name.\n\nThe cookie on the client node is set to `Cookie` for this `rpc` operation (used\nto match the server node cookie).","title":"ct_rpc.cast/5","ref":"ct_rpc.html#cast/5"},{"type":"module","doc":"`Common Test` framework functions for starting and stopping nodes for\nLarge-Scale Testing.\n\nThis module exports functions used by the `Common Test` Master to start and stop\n\"slave\" nodes. It is the default callback module for the `{init, node_start}`\nterm in the Test Specification.","title":"ct_slave","ref":"ct_slave.html"},{"type":"function","doc":"Starts an Erlang node with name `Node` on the local host.\n\nSee also [`ct_slave:start/3`](`start/3`).","title":"ct_slave.start/1","ref":"ct_slave.html#start/1"},{"type":"function","doc":"Starts an Erlang node with default options on a specified host, or on the local\nhost with specified options. That is, the call is interpreted as\n[`start(Host, Node)`](`start/2`) when the second argument is atom-valued and\n[`start(Node, Opts)`](`start/2`) when it is list-valued.\n\nSee also [`ct_slave:start/3`](`start/3`).","title":"ct_slave.start/2","ref":"ct_slave.html#start/2"},{"type":"function","doc":"Starts an Erlang node with name `Node` on host `Host` as specified by the\ncombination of options in `Opts`.\n\nOptions `Username` and `Password` are used to log on to the remote host `Host`.\n`Username`, if omitted, defaults to the current username. `Password` is empty by\ndefault.\n\nA list of functions specified in option `Startup` are executed after startup of\nthe node. Notice that all used modules are to be present in the code path on\n`Host`.\n\nThe time-outs are applied as follows:\n\n- **`BootTimeout`** - The time to start the Erlang node, in seconds. Defaults to\n 3 seconds. If the node is not pingable within this time, the result\n `{error, boot_timeout, NodeName}` is returned.\n\n- **`InitTimeout`** - The time to wait for the node until it calls the internal\n callback function informing master about a successful startup. Defaults to 1\n second. In case of a timed out message, the result\n `{error, init_timeout, NodeName}` is returned.\n\n- **`StartupTimeout`** - The time to wait until the node stops to run\n `StartupFunctions`. Defaults to 1 second. If this time-out occurs, the result\n `{error, startup_timeout, NodeName}` is returned.\n\n_Options:_\n\n- **`monitor_master`** - Specifies if the slave node is to be stopped if the\n master node stops. Defaults to `false`.\n\n- **`kill_if_fail`** - Specifies if the slave node is to be killed if a time-out\n occurs during initialization or startup. Defaults to `true`. Notice that the\n node can also be still alive it the boot time-out occurred, but it is not\n killed in this case.\n\n- **`erl_flags`** - Specifies which flags are added to the parameters of the\n executable `erl`.\n\n- **`env`** - Specifies a list of environment variables that will extend the\n environment.\n\n_Special return values:_\n\n- `{error, already_started, NodeName}` if the node with the specified name is\n already started on a specified host.\n- `{error, started_not_connected, NodeName}` if the node is started, but not\n connected to the master node.\n- `{error, not_alive, NodeName}` if the node on which\n [`ct_slave:start/3`](`start/3`) is called, is not alive. Notice that\n `NodeName` is the name of the current node in this case.","title":"ct_slave.start/3","ref":"ct_slave.html#start/3"},{"type":"function","doc":"Stops the running Erlang node with name `Node` on the local host.","title":"ct_slave.stop/1","ref":"ct_slave.html#stop/1"},{"type":"function","doc":"Stops the running Erlang node with name `Node` on host `Host`.","title":"ct_slave.stop/2","ref":"ct_slave.html#stop/2"},{"type":"type","doc":"Options used for starting `ct_slave` node.","title":"ct_slave.start_options/0","ref":"ct_slave.html#t:start_options/0"},{"type":"type","doc":"Options used for stopping `ct_slave` node.","title":"ct_slave.stop_options/0","ref":"ct_slave.html#t:stop_options/0"},{"type":"module","doc":"`Common Test` user interface module for the `SNMP` application.\n\nThe purpose of this module is to simplify SNMP configuration for the test case\nwriter. Many test cases can use default values for common operations and then no\nSNMP configuration files need to be supplied. When it is necessary to change\nparticular configuration parameters, a subset of the relevant SNMP configuration\nfiles can be passed to `ct_snmp` by `Common Test` configuration files. For more\nspecialized configuration parameters, a simple SNMP configuration file can be\nplaced in the test suite data directory. To simplify the test suite,\n`Common Test` keeps track of some of the SNMP manager information. This way the\ntest suite does not have to handle as many input parameters as if it had to\ninterface wthe OTP SNMP manager directly.\n\n_Configurable SNMP Manager and Agent Parameters:_\n\nManager configuration:\n\n- **`[{start_manager, boolean()}`** - Optional. Default is `true`.\n\n- **`{users, [{user_name(), [call_back_module(), user_data()]}]}`** - Optional.\n\n- **`{usm_users, [{usm_user_name(), [usm_config()]}]}`** - Optional. SNMPv3\n only.\n\n- **`{managed_agents,[{agent_name(), [user_name(), agent_ip(), agent_port(), [agent_config()]]}]}`** -\n `managed_agents` is optional.\n\n- **`{max_msg_size, integer()}`** - Optional. Default is `484`.\n\n- **`{mgr_port, integer()}`** - Optional. Default is `5000`.\n\n- **`{engine _id, string()}`** - Optional. Default is `\"mgrEngine\"`.\n\nAgent configuration:\n\n- **`{start_agent, boolean()}`** - Optional. Default is `false`.\n\n- **`{agent_sysname, string()}`** - Optional. Default is `\"ct_test\"`.\n\n- **`{agent_manager_ip, manager_ip()}`** - Optional. Default is `localhost`.\n\n- **`{agent_vsns, list()}`** - Optional. Default is `[v2]`.\n\n- **`{agent_trap_udp, integer()}`** - Optional. Default is `5000`.\n\n- **`{agent_udp, integer()}`** - Optional. Default is `4000`.\n\n- **`{agent_notify_type, atom()}`** - Optional. Default is `trap`.\n\n- **`{agent_sec_type, sec_type()}`** - Optional. Default is `none`.\n\n- **`{agent_passwd, string()}`** - Optional. Default is `\"\"`.\n\n- **`{agent_engine_id, string()}`** - Optional. Default is `\"agentEngine\"`.\n\n- **`{agent_max_msg_size, string()}`** - Optional. Default is `484`.\n\nThe following parameters represents the SNMP configuration files `context.conf`,\n`standard.conf`, `community.conf`, `vacm.conf`, `usm.conf`, `notify.conf`,\n`target_addr.conf`, and `target_params.conf`. Notice that all values in\n`agent.conf` can be modified by the parameters listed above. All these\nconfiguration files have default values set by the `SNMP` application. These\nvalues can be overridden by suppling a list of valid configuration values or a\nfile located in the test suites data directory, which can produce a list of\nvalid configuration values if you apply function `file:consult/1` to the file.\n\n- **`{agent_contexts, [term()] | {data_dir_file, rel_path()}}`** - Optional.\n\n- **`{agent_community, [term()] | {data_dir_file, rel_path()}}`** - Optional.\n\n- **`{agent_sysinfo, [term()] | {data_dir_file, rel_path()}}`** - Optional.\n\n- **`{agent_vacm, [term()] | {data_dir_file, rel_path()}}`** - Optional.\n\n- **`{agent_usm, [term()] | {data_dir_file, rel_path()}}`** - Optional.\n\n- **`{agent_notify_def, [term()] | {data_dir_file, rel_path()}}`** - Optional.\n\n- **`{agent_target_address_def, [term()] | {data_dir_file, rel_path()}}`** -\n Optional.\n\n- **`{agent_target_param_def, [term()] | {data_dir_file, rel_path()}}`** -\n Optional.\n\nParameter `MgrAgentConfName` in the functions is to be a name you allocate in\nyour test suite using a `require` statement. Example (where\n`MgrAgentConfName = snmp_mgr_agent`):\n\n```erlang\nsuite() -> [{require, snmp_mgr_agent, snmp}].\n```\n\nor\n\n```erlang\nct:require(snmp_mgr_agent, snmp).\n```\n\nNotice that USM users are needed for SNMPv3 configuration and are not to be\nconfused with users.\n\nSNMP traps, inform, and report messages are handled by the user callback module.\nFor details, see the [`SNMP`](`e:snmp:index.html`) application.\n\nIt is recommended to use the `.hrl` files created by the Erlang/OTP MIB compiler\nto define the Object Identifiers (OIDs). For example, to get the Erlang node\nname from `erlNodeTable` in the OTP-MIB:\n\n```erlang\nOid = ?erlNodeEntry ++ [?erlNodeName, 1]\n```\n\nFurthermore, values can be set for `SNMP` application configuration parameters,\n`config`, `server`, `net_if`, and so on (for a list of valid parameters and\ntypes, see the [`User's Guide for the SNMP application`](`e:snmp:index.html`)).\nThis is done by defining a configuration data variable on the following form:\n\n```erlang\n{snmp_app, [{manager, [snmp_app_manager_params()]},\n {agent, [snmp_app_agent_params()]}]}.\n```\n\nA name for the data must be allocated in the suite using `require` (see the\nexample above). Pass this name as argument `SnmpAppConfName` to\n[`ct_snmp:start/3`](`start/3`). `ct_snmp` specifies default values for some\n`SNMP` application configuration parameters (such as `{verbosity,trace}` for\nparameter `config`). This set of defaults is merged with the parameters\nspecified by the user. The user values override `ct_snmp` defaults.","title":"ct_snmp","ref":"ct_snmp.html"},{"type":"function","doc":"Issues a synchronous SNMP `get next` request.","title":"ct_snmp.get_next_values/3","ref":"ct_snmp.html#get_next_values/3"},{"type":"function","doc":"Issues a synchronous SNMP `get` request.","title":"ct_snmp.get_values/3","ref":"ct_snmp.html#get_values/3"},{"type":"function","doc":"Loads the MIBs into agent `snmp_master_agent`.","title":"ct_snmp.load_mibs/1","ref":"ct_snmp.html#load_mibs/1"},{"type":"function","doc":"Explicitly instructs the manager to handle this agent. Corresponds to making an\nentry in `agents.conf`.\n\nThis function tries to register the specified managed agents, without checking\nif any of them exist. To change a registered managed agent, the agent must first\nbe unregistered.","title":"ct_snmp.register_agents/2","ref":"ct_snmp.html#register_agents/2"},{"type":"function","doc":"Registers the manager entity (=user) responsible for specific agent(s).\nCorresponds to making an entry in `users.conf`.\n\nThis function tries to register the specified users, without checking if any of\nthem exist. To change a registered user, the user must first be unregistered.","title":"ct_snmp.register_users/2","ref":"ct_snmp.html#register_users/2"},{"type":"function","doc":"Explicitly instructs the manager to handle this USM user. Corresponds to making\nan entry in `usm.conf`.\n\nThis function tries to register the specified users, without checking if any of\nthem exist. To change a registered user, the user must first be unregistered.","title":"ct_snmp.register_usm_users/2","ref":"ct_snmp.html#register_usm_users/2"},{"type":"function","doc":"Returns a list of all successful `set` requests performed in the test case in\nreverse order. The list contains the involved user and agent, the value before\n`set`, and the new value. This is intended to simplify the cleanup in function\n`end_per_testcase`, that is, the undoing of the `set` requests and their\npossible side-effects.","title":"ct_snmp.set_info/1","ref":"ct_snmp.html#set_info/1"},{"type":"function","doc":"Issues a synchronous SNMP `set` request.","title":"ct_snmp.set_values/4","ref":"ct_snmp.html#set_values/4"},{"type":"function","doc":"","title":"ct_snmp.start/2","ref":"ct_snmp.html#start/2"},{"type":"function","doc":"Starts an SNMP manager and/or agent. In the manager case, registrations of users\nand agents, as specified by the configuration `MgrAgentConfName`, are performed.\nWhen using SNMPv3, called USM users are also registered. Users, `usm_users`, and\nmanaged agents can also be registered later using\n[`ct_snmp:register_users/2`](`register_users/2`),\n[`ct_snmp:register_agents/2`](`register_agents/2`), and\n[`ct_snmp:register_usm_users/2`](`register_usm_users/2`).\n\nThe agent started is called `snmp_master_agent`. Use\n[`ct_snmp:load_mibs/1`](`load_mibs/1`) to load MIBs into the agent.\n\nWith `SnmpAppConfName` SNMP applications can be configured with parameters\n`config`, `mibs`, `net_if`, and so on. The values are merged with (and possibly\noverride) default values set by `ct_snmp`.","title":"ct_snmp.start/3","ref":"ct_snmp.html#start/3"},{"type":"function","doc":"Stops the SNMP manager and/or agent, and removes all files created.","title":"ct_snmp.stop/1","ref":"ct_snmp.html#stop/1"},{"type":"function","doc":"Unloads the MIBs from agent `snmp_master_agent`.","title":"ct_snmp.unload_mibs/1","ref":"ct_snmp.html#unload_mibs/1"},{"type":"function","doc":"Unregisters all managed agents.","title":"ct_snmp.unregister_agents/1","ref":"ct_snmp.html#unregister_agents/1"},{"type":"function","doc":"Unregisters the specified managed agents.","title":"ct_snmp.unregister_agents/2","ref":"ct_snmp.html#unregister_agents/2"},{"type":"function","doc":"Unregisters all users.","title":"ct_snmp.unregister_users/1","ref":"ct_snmp.html#unregister_users/1"},{"type":"function","doc":"Unregisters the specified users.","title":"ct_snmp.unregister_users/2","ref":"ct_snmp.html#unregister_users/2"},{"type":"function","doc":"Unregisters all USM users.","title":"ct_snmp.unregister_usm_users/1","ref":"ct_snmp.html#unregister_usm_users/1"},{"type":"function","doc":"Unregisters the specified USM users.","title":"ct_snmp.unregister_usm_users/2","ref":"ct_snmp.html#unregister_usm_users/2"},{"type":"type","doc":"","title":"ct_snmp.agent_config/0","ref":"ct_snmp.html#t:agent_config/0"},{"type":"type","doc":"","title":"ct_snmp.agent_ip/0","ref":"ct_snmp.html#t:agent_ip/0"},{"type":"type","doc":"","title":"ct_snmp.agent_name/0","ref":"ct_snmp.html#t:agent_name/0"},{"type":"type","doc":"","title":"ct_snmp.agent_port/0","ref":"ct_snmp.html#t:agent_port/0"},{"type":"type","doc":"","title":"ct_snmp.call_back_module/0","ref":"ct_snmp.html#t:call_back_module/0"},{"type":"type","doc":"","title":"ct_snmp.error_index/0","ref":"ct_snmp.html#t:error_index/0"},{"type":"type","doc":"","title":"ct_snmp.error_status/0","ref":"ct_snmp.html#t:error_status/0"},{"type":"type","doc":"","title":"ct_snmp.ip/0","ref":"ct_snmp.html#t:ip/0"},{"type":"type","doc":"","title":"ct_snmp.manager_ip/0","ref":"ct_snmp.html#t:manager_ip/0"},{"type":"type","doc":"","title":"ct_snmp.oid/0","ref":"ct_snmp.html#t:oid/0"},{"type":"type","doc":"","title":"ct_snmp.oids/0","ref":"ct_snmp.html#t:oids/0"},{"type":"type","doc":"","title":"ct_snmp.rel_path/0","ref":"ct_snmp.html#t:rel_path/0"},{"type":"type","doc":"","title":"ct_snmp.sec_type/0","ref":"ct_snmp.html#t:sec_type/0"},{"type":"type","doc":"","title":"ct_snmp.snmp_app_agent_params/0","ref":"ct_snmp.html#t:snmp_app_agent_params/0"},{"type":"type","doc":"","title":"ct_snmp.snmp_app_manager_params/0","ref":"ct_snmp.html#t:snmp_app_manager_params/0"},{"type":"type","doc":"","title":"ct_snmp.snmpreply/0","ref":"ct_snmp.html#t:snmpreply/0"},{"type":"type","doc":"","title":"ct_snmp.user_data/0","ref":"ct_snmp.html#t:user_data/0"},{"type":"type","doc":"","title":"ct_snmp.user_name/0","ref":"ct_snmp.html#t:user_name/0"},{"type":"type","doc":"","title":"ct_snmp.usm_config/0","ref":"ct_snmp.html#t:usm_config/0"},{"type":"type","doc":"","title":"ct_snmp.usm_user_name/0","ref":"ct_snmp.html#t:usm_user_name/0"},{"type":"type","doc":"","title":"ct_snmp.value_type/0","ref":"ct_snmp.html#t:value_type/0"},{"type":"type","doc":"","title":"ct_snmp.var_and_val/0","ref":"ct_snmp.html#t:var_and_val/0"},{"type":"type","doc":"","title":"ct_snmp.varbind/0","ref":"ct_snmp.html#t:varbind/0"},{"type":"type","doc":"","title":"ct_snmp.varbinds/0","ref":"ct_snmp.html#t:varbinds/0"},{"type":"type","doc":"These data types are described in the documentation for the\n[`SNMP`](`e:snmp:index.html`) application.","title":"ct_snmp.varsandvals/0","ref":"ct_snmp.html#t:varsandvals/0"},{"type":"module","doc":"SSH/SFTP client module.\n\nThis module uses application `SSH`, which provides detailed information about,\nfor example, functions, types, and options.\n\nArgument `Server` in the SFTP functions is only to be used for SFTP sessions\nthat have been started on existing SSH connections (that is, when the original\nconnection type is `ssh`). Whenever the connection type is `sftp`, use the SSH\nconnection reference only.\n\nThe following options are valid for specifying an SSH/SFTP connection (that is,\ncan be used as configuration elements):\n\n```erlang\n[{ConnType, Addr},\n {port, Port},\n {user, UserName}\n {password, Pwd}\n {user_dir, String}\n {public_key_alg, PubKeyAlg}\n {connect_timeout, Timeout}\n {key_cb, KeyCallbackMod}]\n```\n\n`ConnType = ssh | sftp`.\n\nFor other types, see `m:ssh`.\n\nAll time-out parameters in `ct_ssh` functions are values in milliseconds.","title":"ct_ssh","ref":"ct_ssh.html"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.apread/4","ref":"ct_ssh.html#apread/4"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.apread/5","ref":"ct_ssh.html#apread/5"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.apwrite/4","ref":"ct_ssh.html#apwrite/4"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.apwrite/5","ref":"ct_ssh.html#apwrite/5"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.aread/3","ref":"ct_ssh.html#aread/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.aread/4","ref":"ct_ssh.html#aread/4"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.awrite/3","ref":"ct_ssh.html#awrite/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.awrite/4","ref":"ct_ssh.html#awrite/4"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.close/2","ref":"ct_ssh.html#close/2"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.close/3","ref":"ct_ssh.html#close/3"},{"type":"function","doc":"","title":"ct_ssh.connect/1","ref":"ct_ssh.html#connect/1"},{"type":"function","doc":"Opens an SSH or SFTP connection using the information associated with `KeyOrName`\n(see `connect/3`).\n\nEquivalent to [`connect(KeyOrName, ConnType, [])`](`connect/3`) if\ncalled with ConnType being atom.\n\nEquivalent to [`connect(KeyOrName, host, ExtraOpts)`](`connect/3`) if\ncalled with ExtraOpts being list.","title":"ct_ssh.connect/2","ref":"ct_ssh.html#connect/2"},{"type":"function","doc":"Opens an SSH or SFTP connection using the information associated with\n`KeyOrName`.\n\nIf `Name` (an alias name for `Key`) is used to identify the connection, this\nname can be used as connection reference for subsequent calls. Only one open\nconnection at a time associated with `Name` is possible. If `Key` is used, the\nreturned handle must be used for subsequent calls (multiple connections can be\nopened using the configuration data specified by `Key`).\n\nFor information on how to create a new `Name`, see `ct:require/2`.\n\n`ConnType` always overrides the type specified in the address tuple in the\nconfiguration data (and in `ExtraOpts`). So it is possible to, for example, open\nan SFTP connection directly using data originally specifying an SSH connection.\nValue `host` means that the connection type specified by the host option (either\nin the configuration data or in `ExtraOpts`) is used.\n\n`ExtraOpts` (optional) are extra SSH options to be added to the configuration\ndata for `KeyOrName`. The extra options override any existing options with the\nsame key in the configuration data. For details on valid SSH options, see\napplication [`SSH`](`e:ssh:index.html`).","title":"ct_ssh.connect/3","ref":"ct_ssh.html#connect/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.del_dir/2","ref":"ct_ssh.html#del_dir/2"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.del_dir/3","ref":"ct_ssh.html#del_dir/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.delete/2","ref":"ct_ssh.html#delete/2"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.delete/3","ref":"ct_ssh.html#delete/3"},{"type":"function","doc":"Closes an SSH/SFTP connection.","title":"ct_ssh.disconnect/1","ref":"ct_ssh.html#disconnect/1"},{"type":"function","doc":"","title":"ct_ssh.exec/2","ref":"ct_ssh.html#exec/2"},{"type":"function","doc":"Requests server to perform `Command`, (see `exec/4`).\n\nEquivalent to [`exec(SSH, undefined, Command, Timeout)`](`exec/4`) if\ncalled with Command being string.\n\nEquivalent to [`exec(SSH, ChannelId, Command, DefaultTimeout)`](`exec/4`) if\ncalled with ChannelId being integer.","title":"ct_ssh.exec/3","ref":"ct_ssh.html#exec/3"},{"type":"function","doc":"Requests server to perform `Command`. A previously opened session channel is\nused for the request. `Data` is received from the server as a result of the\ncommand.","title":"ct_ssh.exec/4","ref":"ct_ssh.html#exec/4"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.get_file_info/2","ref":"ct_ssh.html#get_file_info/2"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.get_file_info/3","ref":"ct_ssh.html#get_file_info/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.list_dir/2","ref":"ct_ssh.html#list_dir/2"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.list_dir/3","ref":"ct_ssh.html#list_dir/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.make_dir/2","ref":"ct_ssh.html#make_dir/2"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.make_dir/3","ref":"ct_ssh.html#make_dir/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.make_symlink/3","ref":"ct_ssh.html#make_symlink/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.make_symlink/4","ref":"ct_ssh.html#make_symlink/4"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.open/3","ref":"ct_ssh.html#open/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.open/4","ref":"ct_ssh.html#open/4"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.opendir/2","ref":"ct_ssh.html#opendir/2"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.opendir/3","ref":"ct_ssh.html#opendir/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.position/3","ref":"ct_ssh.html#position/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.position/4","ref":"ct_ssh.html#position/4"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.pread/4","ref":"ct_ssh.html#pread/4"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.pread/5","ref":"ct_ssh.html#pread/5"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.pwrite/4","ref":"ct_ssh.html#pwrite/4"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.pwrite/5","ref":"ct_ssh.html#pwrite/5"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.read/3","ref":"ct_ssh.html#read/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.read/4","ref":"ct_ssh.html#read/4"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.read_file/2","ref":"ct_ssh.html#read_file/2"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.read_file/3","ref":"ct_ssh.html#read_file/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.read_file_info/2","ref":"ct_ssh.html#read_file_info/2"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.read_file_info/3","ref":"ct_ssh.html#read_file_info/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.read_link/2","ref":"ct_ssh.html#read_link/2"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.read_link/3","ref":"ct_ssh.html#read_link/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.read_link_info/2","ref":"ct_ssh.html#read_link_info/2"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.read_link_info/3","ref":"ct_ssh.html#read_link_info/3"},{"type":"function","doc":"","title":"ct_ssh.receive_response/2","ref":"ct_ssh.html#receive_response/2"},{"type":"function","doc":"Receives expected data from server on the specified session channel\n(see `receive_response/4`).\n\nEquivalent to [`receive_response(SSH, ChannelId, End, DefaultTimeout)`](`receive_response/4`) if\ncalled with End being function.\n\nEquivalent to [`receive_response(SSH, ChannelId, close, Timeout)`](`receive_response/4`) if\ncalled with Timeout being integer.","title":"ct_ssh.receive_response/3","ref":"ct_ssh.html#receive_response/3"},{"type":"function","doc":"Receives expected data from server on the specified session channel.\n\nIf `End == close`, data is returned to the caller when the channel is closed by\nthe server. If a time-out occurs before this happens, the function returns\n`{timeout,Data}` (where `Data` is the data received so far).\n\nIf `End == timeout`, a time-out is expected and `{ok,Data}` is returned both in\nthe case of a time-out and when the channel is closed.\n\nIf `End` is a fun, this fun is called with one argument, the data value in a\nreceived `ssh_cm` message (see `m:ssh_connection`. The fun is to return either\n`true` to end the receiving operation (and have the so far collected data\nreturned) or `false` to wait for more data from the server. Even if a fun is\nsupplied, the function returns immediately if the server closes the channel).","title":"ct_ssh.receive_response/4","ref":"ct_ssh.html#receive_response/4"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.rename/3","ref":"ct_ssh.html#rename/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.rename/4","ref":"ct_ssh.html#rename/4"},{"type":"function","doc":"","title":"ct_ssh.send/3","ref":"ct_ssh.html#send/3"},{"type":"function","doc":"Sends data to server on specified session channel (see `send/5`).\n\nEquivalent to [`send(SSH, ChannelId, 0, Data, Timeout)`](`send/5`) if\ncalled with Timeout being integer.\n\nEquivalent to [`send(SSH, ChannelId, Type, Data, DefaultTimeout)`](`send/5`) if\ncalled with Type being integer.","title":"ct_ssh.send/4","ref":"ct_ssh.html#send/4"},{"type":"function","doc":"Sends data to server on specified session channel.","title":"ct_ssh.send/5","ref":"ct_ssh.html#send/5"},{"type":"function","doc":"","title":"ct_ssh.send_and_receive/3","ref":"ct_ssh.html#send_and_receive/3"},{"type":"function","doc":"Sends data to server on specified session channel and waits to receive the\nserver response (see `send_and_receive/6`).\n\nEquivalent to\n[`send_and_receive(SSH, ChannelId, 0, Data, End, DefaultTimeout)`](`send_and_receive/6`)\nif called with End being function.\n\nEquivalent to\n[`send_and_receive(SSH, ChannelId, 0, Data, close, Timeout)`](`send_and_receive/6`)\nif called with Timeout being integer.\n\nEquivalent to\n[`send_and_receive(SSH, ChannelId, Type, Data, close, DefaultTimeout)`](`send_and_receive/6`)\nif called with Type being integer.","title":"ct_ssh.send_and_receive/4","ref":"ct_ssh.html#send_and_receive/4"},{"type":"function","doc":"Sends data to server on specified session channel and waits to receive the\nserver response (see `send_and_receive/6`).\n\nEquivalent to\n[`send_and_receive(SSH, ChannelId, 0, Data, End, Timeout)`](`send_and_receive/6`) if\ncalled with Timeout being integer.\n\nEquivalent to\n[`send_and_receive(SSH, ChannelId, Type, Data, close, Timeout)`](`send_and_receive/6`) if\ncalled with Type being integer.\n\nEquivalent to\n[`send_and_receive(SSH, ChannelId, Type, Data, End, DefaultTimeout)`](`send_and_receive/6`) if\ncalled with End being function.","title":"ct_ssh.send_and_receive/5","ref":"ct_ssh.html#send_and_receive/5"},{"type":"function","doc":"Sends data to server on specified session channel and waits to receive the\nserver response.\n\nFor details on argument `End`, see\n[`ct_ssh:receive_response/4`](`receive_response/4`).","title":"ct_ssh.send_and_receive/6","ref":"ct_ssh.html#send_and_receive/6"},{"type":"function","doc":"Closes an SSH session channel.","title":"ct_ssh.session_close/2","ref":"ct_ssh.html#session_close/2"},{"type":"function","doc":"","title":"ct_ssh.session_open/1","ref":"ct_ssh.html#session_open/1"},{"type":"function","doc":"Opens a channel for an SSH session.","title":"ct_ssh.session_open/2","ref":"ct_ssh.html#session_open/2"},{"type":"function","doc":"Starts an SFTP session on an already existing SSH connection. `Server`\nidentifies the new session and must be specified whenever SFTP requests are to\nbe sent.","title":"ct_ssh.sftp_connect/1","ref":"ct_ssh.html#sftp_connect/1"},{"type":"function","doc":"","title":"ct_ssh.shell/2","ref":"ct_ssh.html#shell/2"},{"type":"function","doc":"Requests that the user's default shell (typically defined in `/etc/passwd` in Unix\nsystems) is executed at the server end.","title":"ct_ssh.shell/3","ref":"ct_ssh.html#shell/3"},{"type":"function","doc":"","title":"ct_ssh.subsystem/3","ref":"ct_ssh.html#subsystem/3"},{"type":"function","doc":"Sends a request to execute a predefined subsystem.","title":"ct_ssh.subsystem/4","ref":"ct_ssh.html#subsystem/4"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.write/3","ref":"ct_ssh.html#write/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.write/4","ref":"ct_ssh.html#write/4"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.write_file/3","ref":"ct_ssh.html#write_file/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.write_file/4","ref":"ct_ssh.html#write_file/4"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.write_file_info/3","ref":"ct_ssh.html#write_file_info/3"},{"type":"function","doc":"For information and other types, see `m:ssh_sftp`.","title":"ct_ssh.write_file_info/4","ref":"ct_ssh.html#write_file_info/4"},{"type":"type","doc":"Reference to opened SSH/SFTP connection associated to either a `handle` or `target_name`.","title":"ct_ssh.connection/0","ref":"ct_ssh.html#t:connection/0"},{"type":"type","doc":"Connection type used for connect.","title":"ct_ssh.connection_type/0","ref":"ct_ssh.html#t:connection_type/0"},{"type":"type","doc":"Handle for a specific SSH/SFTP connection, see module `m:ct`.","title":"ct_ssh.handle/0","ref":"ct_ssh.html#t:handle/0"},{"type":"type","doc":"Data type representing a channel inside a connection.\n\n\"For `ssh_channel_id`, see module `m:ssh`.\".","title":"ct_ssh.ssh_channel_id/0","ref":"ct_ssh.html#t:ssh_channel_id/0"},{"type":"type","doc":"The valid values are `0` (\"normal\") and `1` (\"stderr\"), see\n[RFC 4254, Section 5.2](https://tools.ietf.org/html/rfc4254#page-8).","title":"ct_ssh.ssh_data_type_code/0","ref":"ct_ssh.html#t:ssh_data_type_code/0"},{"type":"behaviour","doc":"The following section describes the mandatory and optional test suite functions\nthat `Common Test` calls during test execution. For more details, see section\n[Writing Test Suites](write_test_chapter.md) in the User's Guide.","title":"ct_suite","ref":"ct_suite.html"},{"type":"callback","doc":"Returns the list of all test cases and test case groups in the test suite module\nto be executed.\n\nThis list also specifies the order the cases and groups are\nexecuted by `Common Test`. A test case is represented by an atom, the name of\nthe test case function, or a `testcase` tuple indicating that the test case\nshall be repeated. A test case group is represented by a `group` tuple, where\n`GroupName`, an atom, is the name of the group (defined in\n[`Module:groups/0`](`c:groups/0`)). Execution properties for groups can also be\nspecified, both for a top-level group and for any of its subgroups. Group\nexecution properties specified here override properties in the group definition\n(see [`Module:groups/0`](`c:groups/0`)). (With value `default`, the group\ndefinition properties are used).\n\nIf `{skip, Reason}` is returned, all test cases in the module are skipped and\n`Reason` is printed on the HTML result page.\n\nFor details on groups, see section\n[Test Case Groups](write_test_chapter.md#test_case_groups) in the User's Guide.","title":"ct_suite.all/0","ref":"ct_suite.html#c:all/0"},{"type":"callback","doc":"This function is called after the execution of a test case group is finished. It\nis meant to be used for cleaning up after [`Module:init_per_group/2`](`c:init_per_group/2`).\n\nA status value for a nested subgroup can be returned with `{return_group_result, Status}`.\nThe status can be retrieved in [`Module:end_per_group/2`](`c:end_per_group/2`) for the group on\nthe level above. The status is also used by `Common Test` for deciding if\nexecution of a group is to proceed if property `sequence` or `repeat_until_*` is\nset.\n\nFor details about test case groups, see section\n[Test Case Groups](write_test_chapter.md#test_case_groups) in the User's Guide.\n\nIf this function is defined, then\n[`Module:init_per_group/2`](`c:init_per_group/2`) must also be defined.","title":"ct_suite.end_per_group/2","ref":"ct_suite.html#c:end_per_group/2"},{"type":"callback","doc":"This function is called as the last test case in the suite. It is meant to be\nused for cleaning up after [`Module:init_per_suite/1`](`c:init_per_suite/1`).\n\nFor information on `save_config`, see section\n[Saving Configuration Data](dependencies_chapter.md#save_config) in the User's\nGuide.\n\nIf this function is defined, then\n[`Module:init_per_suite/1`](`c:init_per_suite/1`) must also be defined.","title":"ct_suite.end_per_suite/1","ref":"ct_suite.html#c:end_per_suite/1"},{"type":"callback","doc":"This function is called after each test case, and can be used to clean up after\n[`Module:init_per_testcase/2`](`c:init_per_testcase/2`) and the test case.\n\nAny return value (besides `{fail, Reason}` and `{save_config, SaveConfig}`) is\nignored. By returning `{fail, Reason}`, `TestCase` is marked as faulty (even\nthough it was successful in the sense that it returned a value instead of\nterminating).\n\nFor information on `save_config`, see section\n[Saving Configuration Data](dependencies_chapter.md#save_config) in the User's\nGuide.\n\nIf this function is defined, then\n[`Module:init_per_testcase/2`](`c:init_per_testcase/2`) must also be defined.","title":"ct_suite.end_per_testcase/2","ref":"ct_suite.html#c:end_per_testcase/2"},{"type":"callback","doc":"The test case group information function. It is supposed to return a list of\ntagged tuples that specify various properties related to the execution of a test\ncase group (that is, its test cases and subgroups). Properties set by\n[`Module:group/1`](`c:group/1`) override properties with the same key that have\nbeen set previously by [`Module:suite/0`](`c:suite/0`).\n\nTag `timetrap` sets the maximum time that each test case is allowed to execute\n(including [`Module:init_per_testcase/2`](`c:init_per_testcase/2`) and\n[`Module:end_per_testcase/2`](`c:end_per_testcase/2`)). If the timetrap time is\nexceeded, the test case fails with reason `timetrap_timeout`. A `TimeFunc`\nfunction can be used to set a new timetrap by returning a `TimeVal`. It can also\nbe used to trigger a timetrap time-out by, at some point, returning a value\nother than a `TimeVal`. For details, see section\n[Timetrap Time-Outs](write_test_chapter.md#timetraps) in the User's Guide.\n\nTag `require` specifies configuration variables required by test cases (or\nconfiguration functions) in the suite. If the required configuration variables\nare not found in any of the configuration files, all test cases in this group\nare skipped. For details about the `require` functionality, see function\n[`ct:require/1,2`](`ct:require/1`).\n\nWith `userdata`, the user can specify any test case group related information\nthat can be read by calling `ct:userdata/2`.\n\nTag `ct_hooks` specifies the [Common Test Hooks](ct_hooks_chapter.md) to be run\nwith this suite.\n\nOther tuples than the ones defined are ignored.\n\nFor details about the test case group information function, see section\n[Group Information Function](write_test_chapter.md#group_info) in the User's\nGuide.","title":"ct_suite.group/1","ref":"ct_suite.html#c:group/1"},{"type":"callback","doc":"Defines test case groups. For details, see section\n[Test Case Groups](write_test_chapter.md#test_case_groups) in the User's Guide.","title":"ct_suite.groups/0","ref":"ct_suite.html#c:groups/0"},{"type":"callback","doc":"This configuration function is called before execution of a test case group. It\ntypically contains initializations that are common for all test cases and\nsubgroups in the group, and that must only be performed once.\n\n`GroupName` is the name of the group, as specified in the group definition (see\n[`Module:groups/0`](`c:groups/0`)). Parameter `Config` is the configuration data\nthat can be modified. The return value of this function is given as `Config` to\nall test cases and subgroups in the group.\n\nIf `{skip, Reason}` is returned, all test cases in the group are skipped and\n`Reason` is printed in the overview log for the group.\n\nFor information about test case groups, see section\n[Test Case Groups](write_test_chapter.md#test_case_groups) in the User's Guide.\n\nIf this function is defined, then\n[`Module:end_per_group/2`](`c:end_per_group/2`) must also be defined.","title":"ct_suite.init_per_group/2","ref":"ct_suite.html#c:init_per_group/2"},{"type":"callback","doc":"This configuration function is called as the first function in the suite. It\ntypically contains initializations that are common for all test cases in the\nsuite, and that must only be done once.\n\nParameter `Config` is the configuration\ndata that can be modified. Whatever is returned from this function is specified\nas `Config` to all configuration functions and test cases in the suite.\n\nIf `{skip, Reason}` is returned, all test cases in the suite are skipped and\n`Reason` is printed in the overview log for the suite.\n\nFor information on `save_config` and `skip_and_save`, see section\n[Saving Configuration Data](dependencies_chapter.md#save_config) in the User's\nGuide.\n\nIf this function is defined, then\n[`Module:end_per_suite/1`](`c:end_per_suite/1`) must also be defined.","title":"ct_suite.init_per_suite/1","ref":"ct_suite.html#c:init_per_suite/1"},{"type":"callback","doc":"This function is called before each test case.\n\nArgument `TestCase` is the test case name, and `Config` (list of key-value tuples)\nis the configuration data that can be modified. The `NewConfig` list returned from this\nfunction is given as `Config` to the test case.\n\nIf `{fail, Reason}` is returned, the test case is marked as failed without being executed.\n\nIf `{skip, Reason}` is returned, the test case is skipped and `Reason` is\nprinted in the overview log for the suite.\n\nIf this function is defined, then\n[`Module:end_per_testcase/2`](`c:end_per_testcase/2`) must also be defined.","title":"ct_suite.init_per_testcase/2","ref":"ct_suite.html#c:init_per_testcase/2"},{"type":"callback","doc":"The test suite information function. Returns a list of tagged tuples specifying\nvarious properties related to the execution of this test suite (common for all\ntest cases in the suite).\n\nTag `timetrap` sets the maximum time that each test case is allowed to execute\n(including [`Module:init_per_testcase/2`](`c:init_per_testcase/2`) and\n[`Module:end_per_testcase/2`](`c:end_per_testcase/2`)). If the timetrap time is\nexceeded, the test case fails with reason `timetrap_timeout`. A `TimeFunc`\nfunction can be used to set a new timetrap by returning a `TimeVal`. It can also\nbe used to trigger a timetrap time-out by, at some point, returning a value\nother than a `TimeVal`. For details, see section\n[Timetrap Time-Outs](write_test_chapter.md#timetraps) in the User's Guide.\n\nTag `require` specifies configuration variables required by test cases (or\nconfiguration functions) in the suite. If the required configuration variables\nare not found in any of the configuration files, all test cases are skipped. For\ndetails about the `require` functionality, see function\n[`ct:require/1,2`](`ct:require/1`).\n\nWith `userdata`, the user can specify any test suite-related information, which\ncan be read by calling `ct:userdata/2`.\n\nTag `ct_hooks` specifies the [Common Test Hooks](ct_hooks_chapter.md) to be run\nwith this suite.\n\nOther tuples than the ones defined are ignored.\n\nFor details about the test suite information function, see section\n[Test Suite Information Function](write_test_chapter.md#suite) in the User's\nGuide.","title":"ct_suite.suite/0","ref":"ct_suite.html#c:suite/0"},{"type":"callback","doc":"The test case information function. It is supposed to return a list of tagged\ntuples that specify various properties related to the execution of this\nparticular test case. Properties set by [`Module:Testcase/0`](`c:'Testcase'/0`)\noverride properties set previously for the test case by\n[`Module:group/1`](`c:group/1`) or [`Module:suite/0`](`c:suite/0`).\n\nTag `timetrap` sets the maximum time that the test case is allowed to execute.\nIf the timetrap time is exceeded, the test case fails with reason\n`timetrap_timeout`. [`Module:init_per_testcase/2`](`c:init_per_testcase/2`) and\n[`Module:end_per_testcase/2`](`c:end_per_testcase/2`) are included in the\ntimetrap time. A `TimeFunc` function can be used to set a new timetrap by\nreturning a `TimeVal`. It can also be used to trigger a timetrap time-out by, at\nsome point, returning a value other than a `TimeVal`. For details, see section\n[Timetrap Time-Outs](write_test_chapter.md#timetraps) in the User's Guide.\n\nTag `require` specifies configuration variables that are required by the test\ncase (or [`init_per_testcase/2`](`c:init_per_testcase/2`) or\n[`end_per_testcase/2`](`c:end_per_testcase/2`)). If the required configuration\nvariables are not found in any of the configuration files, the test case is\nskipped. For details about the `require` functionality, see function\n[`ct:require/1,2`](`ct:require/1`).\n\nIf `timetrap` or `require` is not set, the default values specified by\n[`Module:suite/0`](`c:suite/0`) (or [`Module:group/1`](`c:group/1`)) are used.\n\nWith `userdata`, the user can specify any test case-related information that can\nbe read by calling `ct:userdata/3`.\n\nOther tuples than the ones defined are ignored.\n\nFor details about the test case information function, see section\n[Test Case Information Function](write_test_chapter.md#info_function) in the\nUser's Guide.","title":"ct_suite.Testcase/0","ref":"ct_suite.html#c:Testcase/0"},{"type":"callback","doc":"The implementation of a test case. Call the functions to test and check the\nresult. If something fails, ensure the function causes a runtime error or call\n[`ct:fail/1,2`](`ct:fail/1`) (which also causes the test case process to\nterminate).\n\nElements from the `Config` list can, for example, be read with\n`proplists:get_value/2` in STDLIB.\n\nPossible return values are:\n\n- **`{fail, Reason}`** - The test case is considered failed, and the `Reason`\n will be logged.\n\n- **`{skip, Reason}`** - The test case is considered skipped, and the `Reason`\n will be logged.\n\n- **`{comment, Comment}`** - The test case is considered successful, and the\n `Comment` will be logged.\n\n- **`{save_config, SaveConfig}`** - The test case is considered successful, and\n the `SaveConfig` will be stored in the `Config` (see section\n [Saving Configuration Data](dependencies_chapter.md#save_config) in the User's\n Guide).\n\n- **`{skip_and_save, Reason, SaveConfig}`** - The test case is considered\n skipped, the `Reason` will be logged, and the `SaveConfig` will be stored in\n the `Config` (see section\n [Saving Configuration Data](dependencies_chapter.md#save_config) in the User's\n Guide).\n\nIf the function returns any other term, the test case is considered successful.\n\nIf the test case function crashes, it is considered failed.\n\nFor details about test case implementation, see section\n[Test Cases](write_test_chapter.md#test_cases) in the User's Guide.","title":"ct_suite.Testcase/1","ref":"ct_suite.html#c:Testcase/1"},{"type":"type","doc":"The configuration data that can be modified.","title":"ct_suite.ct_config/0","ref":"ct_suite.html#t:ct_config/0"},{"type":"type","doc":"The test group definition, as returned by [`Module:groups/0`](`c:groups/0`).","title":"ct_suite.ct_group_def/0","ref":"ct_suite.html#t:ct_group_def/0"},{"type":"type","doc":"","title":"ct_suite.ct_group_props/0","ref":"ct_suite.html#t:ct_group_props/0"},{"type":"type","doc":"","title":"ct_suite.ct_group_props_ref/0","ref":"ct_suite.html#t:ct_group_props_ref/0"},{"type":"type","doc":"","title":"ct_suite.ct_group_ref/0","ref":"ct_suite.html#t:ct_group_ref/0"},{"type":"type","doc":"","title":"ct_suite.ct_group_repeat_type/0","ref":"ct_suite.html#t:ct_group_repeat_type/0"},{"type":"type","doc":"The name of the test group.","title":"ct_suite.ct_groupname/0","ref":"ct_suite.html#t:ct_groupname/0"},{"type":"type","doc":"","title":"ct_suite.ct_hooks/0","ref":"ct_suite.html#t:ct_hooks/0"},{"type":"type","doc":"The test suite information, as returned by [`Module:suite/0`](`c:suite/0`),\n[`Module:group/1`](`c:group/1`) and [`Module:Testcase/0`](`c:'Testcase'/0`).","title":"ct_suite.ct_info/0","ref":"ct_suite.html#t:ct_info/0"},{"type":"type","doc":"","title":"ct_suite.ct_info_required/0","ref":"ct_suite.html#t:ct_info_required/0"},{"type":"type","doc":"","title":"ct_suite.ct_info_required_subkeys/0","ref":"ct_suite.html#t:ct_info_required_subkeys/0"},{"type":"type","doc":"","title":"ct_suite.ct_info_timetrap/0","ref":"ct_suite.html#t:ct_info_timetrap/0"},{"type":"type","doc":"","title":"ct_suite.ct_info_timetrap_fun/0","ref":"ct_suite.html#t:ct_info_timetrap_fun/0"},{"type":"type","doc":"The status value for a nested subgroup.","title":"ct_suite.ct_status/0","ref":"ct_suite.html#t:ct_status/0"},{"type":"type","doc":"","title":"ct_suite.ct_subgroups_def/0","ref":"ct_suite.html#t:ct_subgroups_def/0"},{"type":"type","doc":"The test suite definition, as returned by [`Module:all/0`](`c:all/0`).","title":"ct_suite.ct_test_def/0","ref":"ct_suite.html#t:ct_test_def/0"},{"type":"type","doc":"","title":"ct_suite.ct_test_repeat/0","ref":"ct_suite.html#t:ct_test_repeat/0"},{"type":"type","doc":"","title":"ct_suite.ct_testcase_ref/0","ref":"ct_suite.html#t:ct_testcase_ref/0"},{"type":"type","doc":"","title":"ct_suite.ct_testcase_repeat_prop/0","ref":"ct_suite.html#t:ct_testcase_repeat_prop/0"},{"type":"type","doc":"The name of the testcase function.","title":"ct_suite.ct_testname/0","ref":"ct_suite.html#t:ct_testname/0"},{"type":"module","doc":"`Common Test` specific layer on top of Telnet client `ct_telnet_client.erl`.\n\nUse this module to set up Telnet connections, send commands, and perform string\nmatching on the result. For information about how to use `ct_telnet` and\nconfigure connections, specifically for UNIX hosts, see the `m:unix_telnet`\nmanual page.\n\nDefault values defined in `ct_telnet`:\n\n[](){: #Default_values }\n\n- Connection timeout (time to wait for connection) = 10 seconds\n- Command timeout (time to wait for a command to return) = 10 seconds\n- Max number of reconnection attempts = 3\n- Reconnection interval (time to wait in between reconnection attempts) = 5\n seconds\n- Keep alive (sends NOP to the server every 8 sec if connection is idle) =\n `true`\n- Polling limit (max number of times to poll to get a remaining string\n terminated) = 0\n- Polling interval (sleep time between polls) = 1 second\n- The TCP_NODELAY option for the telnet socket is disabled (set to `false`) per\n default\n\nThese parameters can be modified by the user with the following configuration\nterm:\n\n```erlang\n{telnet_settings, [{connect_timeout,Millisec},\n {command_timeout,Millisec},\n {reconnection_attempts,N},\n {reconnection_interval,Millisec},\n {keep_alive,Bool},\n {poll_limit,N},\n {poll_interval,Millisec},\n {tcp_nodelay,Bool}]}.\n```\n\n`Millisec = integer(), N = integer()`\n\nEnter the `telnet_settings` term in a configuration file included in the test\nand `ct_telnet` retrieves the information automatically.\n\n`keep_alive` can be specified per connection, if necessary. For details, see\n`m:unix_telnet`.","title":"ct_telnet","ref":"ct_telnet.html"},{"type":"module","doc":"[](){: #Logging }\n\nThe default logging behavior of `ct_telnet` is to print information about\nperformed operations, commands, and their corresponding results to the test case\nHTML log. The following is not printed to the HTML log: text strings sent from\nthe Telnet server that are not explicitly received by a `ct_telnet` function,\nsuch as [`expect/3`](`expect/3`). However, `ct_telnet` can be configured to use\na special purpose event handler, implemented in `ct_conn_log_h`, for logging\n_all_ Telnet traffic. To use this handler, install a `Common Test` hook named\n`cth_conn_log`. Example (using the test suite information function):\n\n```erlang\nsuite() ->\n [{ct_hooks, [{cth_conn_log, [{conn_mod(),hook_options()}]}]}].\n```\n\n`conn_mod()` is the name of the `Common Test` module implementing the connection\nprotocol, that is, `ct_telnet`.\n\nThe `cth_conn_log` hook performs unformatted logging of Telnet data to a\nseparate text file. All Telnet communication is captured and printed, including\nany data sent from the server. The link to this text file is located at the top\nof the test case HTML log.\n\nBy default, data for all Telnet connections is logged in one common file (named\n`default`), which can get messy, for example, if multiple Telnet sessions are\nrunning in parallel. Therefore a separate log file can be created for each\nconnection. To configure this, use hook option `hosts` and list the names of the\nservers/connections to be used in the suite. The connections must be named for\nthis to work (see [`ct_telnet:open/1,2,3,4`](`open/1`)).\n\nHook option `log_type` can be used to change the `cth_conn_log` behavior. The\ndefault value of this option is `raw`, which results in the behavior described\nabove. If the value is set to `html`, all Telnet communication is printed to the\ntest case HTML log instead.\n\nAll `cth_conn_log` hook options described can also be specified in a\nconfiguration file with configuration variable `ct_conn_log`.\n\n_Example:_\n\n```erlang\n{ct_conn_log, [{ct_telnet,[{log_type,raw},\n {hosts,[key_or_name()]}]}]}\n```\n\n> #### Note {: .info }\n>\n> Hook options specified in a configuration file overwrite any hard-coded hook\n> options in the test suite.\n\n[](){: #Logging_example }\n\n_Logging Example:_\n\nThe following `ct_hooks` statement causes printing of Telnet traffic to separate\nlogs for the connections `server1` and `server2`. Traffic for any other\nconnections is logged in the default Telnet log.\n\n```erlang\nsuite() ->\n [{ct_hooks,\n [{cth_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}]}].\n```\n\nAs previously explained, this specification can also be provided by an entry\nlike the following in a configuration file:\n\n```erlang\n{ct_conn_log, [{ct_telnet,[{hosts,[server1,server2]}]}]}.\n```\n\nIn this case the `ct_hooks` statement in the test suite can look as follows:\n\n```erlang\nsuite() ->\n [{ct_hooks, [{cth_conn_log, []}]}].\n```","title":"Logging - ct_telnet","ref":"ct_telnet.html#module-logging"},{"type":"module","doc":"`m:unix_telnet`","title":"See Also - ct_telnet","ref":"ct_telnet.html#module-see-also"},{"type":"function","doc":"Closes the Telnet connection and stops the process managing it.\n\nA connection can be associated with a target name and/or a handle. If\n`Connection` has no associated target name, it can only be closed with the\nhandle value (see [`ct_telnet:open/4`](`open/4`)).","title":"ct_telnet.close/1","ref":"ct_telnet.html#close/1"},{"type":"function","doc":"","title":"ct_telnet.cmd/2","ref":"ct_telnet.html#cmd/2"},{"type":"function","doc":"Sends a command through Telnet and waits for prompt.\n\nBy default, this function adds \"\\\\n\" to the end of the specified command. If\nthis is not desired, use option `{newline,false}`. This is necessary, for\nexample, when sending Telnet command sequences prefixed with character Interpret\nAs Command (IAC). Option `{newline,string()}` can also be used if a different\nline end than \"\\\\n\" is required, for instance `{newline,\"\\r\\n\"}`, to add both\ncarriage return and newline characters.\n\nOption `timeout` specifies how long the client must wait for prompt. If the time\nexpires, the function returns `{error,timeout}`. For information about the\ndefault value for the command timeout, see the\n[list of default values](`m:ct_telnet#Default_values`) in the beginning of this\nmodule.","title":"ct_telnet.cmd/3","ref":"ct_telnet.html#cmd/3"},{"type":"function","doc":"","title":"ct_telnet.cmdf/3","ref":"ct_telnet.html#cmdf/3"},{"type":"function","doc":"Sends a Telnet command and waits for prompt (uses a format string and a list of\narguments to build the command).\n\nFor details, see [`ct_telnet:cmd/3`](`cmd/3`).","title":"ct_telnet.cmdf/4","ref":"ct_telnet.html#cmdf/4"},{"type":"function","doc":"","title":"ct_telnet.expect/2","ref":"ct_telnet.html#expect/2"},{"type":"function","doc":"Gets data from Telnet and waits for the expected pattern.\n\n`Pattern` can be a POSIX regular expression. The function returns when a pattern\nis successfully matched (at least one, in the case of multiple patterns).\n\n`RxMatch` is a list of matched strings. It looks as follows\n`[FullMatch, SubMatch1, SubMatch2, ...]`, where `FullMatch` is the string\nmatched by the whole regular expression, and `SubMatchN` is the string that\nmatched subexpression number `N`. Subexpressions are denoted with `'(' ')'` in\nthe regular expression.\n\nIf a `Tag` is specified, the returned `Match` also includes the matched `Tag`.\nOtherwise, only `RxMatch` is returned.\n\n_Options:_\n\n- **`idle_timeout`** - Indicates that the function must return if the Telnet\n client is idle (that is, if no data is received) for more than `IdleTimeout`\n milliseconds. Default time-out is 10 seconds.\n\n- **`total_timeout`** - Sets a time limit for the complete `expect` operation.\n After `TotalTimeout` milliseconds, `{error,timeout}` is returned. Default is\n `infinity` (that is, no time limit).\n\n- **`ignore_prompt | no_prompt_check`** - >The function returns when a prompt is\n received, even if no pattern has yet been matched, and\n `{error,{prompt,Prompt}}` is returned. However, this behavior can be modified\n with option `ignore_prompt` or option `no_prompt_check`, which tells `expect`\n to return only when a match is found or after a time-out.\n\n- **`ignore_prompt`** - `ct_telnet` ignores any prompt found. This option is\n useful if data sent by the server can include a pattern matching prompt\n `regexp` (as returned by `TargedMod:get_prompt_regexp/0`), but is not to not\n cause the function to return.\n\n- **`no_prompt_check`** - `ct_telnet` does not search for a prompt at all. This\n is useful if, for example, `Pattern` itself matches the prompt.\n\n- **`wait_for_prompt`** - Forces `ct_telnet` to wait until the prompt string is\n received before returning (even if a pattern has already been matched). This\n is equal to calling\n [`expect(Conn, Patterns++[{prompt,Prompt}], [sequence|Opts])`](`expect/3`).\n Notice that option `idle_timeout` and `total_timeout` can abort the operation\n of waiting for prompt.\n\n- **`repeat | repeat, N`** - The pattern(s) must be matched multiple times. If\n `N` is specified, the pattern(s) are matched `N` times, and the function\n returns `HaltReason = done`. This option can be interrupted by one or more\n `HaltPatterns`. `MatchList` is always returned, that is, a list of `Match`\n instead of only one `Match`. Also `HaltReason` is returned.\n\n- **`sequence`** - All patterns must be matched in a sequence. A match is not\n concluded until all patterns are matched. This option can be interrupted by\n one or more `HaltPatterns`. `MatchList` is always returned, that is, a list of\n `Match` instead of only one `Match`. Also `HaltReason` is returned.\n\n_Example 1:_\n\n```erlang\nexpect(Connection,[{abc,\"ABC\"},{xyz,\"XYZ\"}],[sequence,{halt,[{nnn,\"NNN\"}]}])\n```\n\nFirst this tries to match `\"ABC\"`, and then `\"XYZ\"`, but if `\"NNN\"` appears, the\nfunction returns `{error,{nnn,[\"NNN\"]}}`. If both `\"ABC\"` and `\"XYZ\"` are\nmatched, the function returns `{ok,[AbcMatch,XyzMatch]}`.\n\n_Example 2:_\n\n```erlang\nexpect(Connection,[{abc,\"ABC\"},{xyz,\"XYZ\"}],[{repeat,2},{halt,[{nnn,\"NNN\"}]}])\n```\n\nThis tries to match `\"ABC\"` or `\"XYZ\"` twice. If `\"NNN\"` appears, the function\nreturns `HaltReason = {nnn,[\"NNN\"]}`.\n\nOptions `repeat` and `sequence` can be combined to match a sequence multiple\ntimes.","title":"ct_telnet.expect/3","ref":"ct_telnet.html#expect/3"},{"type":"function","doc":"Gets all data received by the Telnet client since the last command was sent.\nOnly newline-terminated strings are returned. If the last received string has\nnot yet been terminated, the connection can be polled automatically until the\nstring is complete.\n\nThe polling feature is controlled by the configuration values `poll_limit` and\n`poll_interval` and is by default disabled. This means that the function\nimmediately returns all complete strings received and saves a remaining\nnon-terminated string for a later `get_data` call.","title":"ct_telnet.get_data/1","ref":"ct_telnet.html#get_data/1"},{"type":"function","doc":"","title":"ct_telnet.open/1","ref":"ct_telnet.html#open/1"},{"type":"function","doc":"Opens a Telnet connection to the specified target host.","title":"ct_telnet.open/2","ref":"ct_telnet.html#open/2"},{"type":"function","doc":"","title":"ct_telnet.open/3","ref":"ct_telnet.html#open/3"},{"type":"function","doc":"Opens a Telnet connection to the specified target host.\n\nThe target data must exist in a configuration file. The connection can be\nassociated with `Name` and/or the returned `Handle`. To allocate a name for the\ntarget, use one of the following alternatives:\n\n- `ct:require/2` in a test case\n- A `require` statement in the suite information function (`suite/0`)\n- A `require` statement in a test case information function\n\nIf you want the connection to be associated with `Handle` only (if you, for\nexample, need to open multiple connections to a host), use `Key`, the\nconfiguration variable name, to specify the target. Notice that a connection\nwithout an associated target name can only be closed with the `Handle` value.\n\n`TargetMod` is a module that exports the functions\n`connect(Ip, Port, KeepAlive, Extra)` and `get_prompt_regexp()` for the\nspecified `TargetType` (for example, `unix_telnet`).\n\nSee also `ct:require/2`.","title":"ct_telnet.open/4","ref":"ct_telnet.html#open/4"},{"type":"function","doc":"","title":"ct_telnet.send/2","ref":"ct_telnet.html#send/2"},{"type":"function","doc":"Sends a Telnet command and returns immediately.\n\nBy default, this function adds \"\\\\n\" to the end of the specified command. If\nthis is not desired, option `{newline,false}` can be used. This is necessary,\nfor example, when sending Telnet command sequences prefixed with character\nInterpret As Command (IAC). Option `{newline,string()}` can also be used if a\ndifferent line end than \"\\\\n\" is required, for instance `{newline,\"\\r\\n\"}`, to\nadd both carriage return and newline characters.\n\nThe resulting output from the command can be read with\n[`ct_telnet:get_data/2`](`get_data/1`) or [`ct_telnet:expect/2,3`](`expect/2`).","title":"ct_telnet.send/3","ref":"ct_telnet.html#send/3"},{"type":"function","doc":"","title":"ct_telnet.sendf/3","ref":"ct_telnet.html#sendf/3"},{"type":"function","doc":"Sends a Telnet command and returns immediately (uses a format string and a list\nof arguments to build the command).\n\nFor details, see [`ct_telnet:send/3`](`send/3`).","title":"ct_telnet.sendf/4","ref":"ct_telnet.html#sendf/4"},{"type":"type","doc":"Reference to opened Telnet connection associated to either a `handle` or `target_name`.","title":"ct_telnet.connection/0","ref":"ct_telnet.html#t:connection/0"},{"type":"type","doc":"Telnet connection_type, valid values: 'telnet' | 'ts1' | 'ts2'.","title":"ct_telnet.connection_type/0","ref":"ct_telnet.html#t:connection_type/0"},{"type":"type","doc":"Handle for a specific Telnet connection, see module `m:ct`.","title":"ct_telnet.handle/0","ref":"ct_telnet.html#t:handle/0"},{"type":"type","doc":"See `cmd/3` for explanation.","title":"ct_telnet.newline_option/0","ref":"ct_telnet.html#t:newline_option/0"},{"type":"type","doc":"Regular expression matching all possible prompts for a specific target type.\n`regexp` must not have any groups, that is, when matching, `re:run/3` (in\nSTDLIB) must return a list with one single element.","title":"ct_telnet.prompt_regexp/0","ref":"ct_telnet.html#t:prompt_regexp/0"},{"type":"module","doc":"Parsing of test specifications for `Common Test`.\n\nThis module exports help functions for parsing of test specifications.","title":"ct_testspec","ref":"ct_testspec.html"},{"type":"function","doc":"Parse the given test specification files and return the tests to run and skip.\n\n[](){: #add_nodes-1 }\n\nIf `SpecsIn=[Spec1,Spec2,...]`, separate tests will be created per\nspecification. If `SpecsIn=[[Spec1,Spec2,...]]`, all specifications will be\nmerge into one test.\n\nFor each test, a `{Specs,Tests}` element is returned, where `Specs` is a list of\nall included test specifications, and `Tests` specifies actual tests to run/skip\nper node.","title":"ct_testspec.get_tests/1","ref":"ct_testspec.html#get_tests/1"},{"type":"module","doc":"Callback module for `m:ct_telnet`, for connecting to a Telnet server on a UNIX\nhost.\n\nIt requires the following entry in the configuration file:\n\n```erlang\n{unix,[{telnet,HostNameOrIpAddress},\n {port,PortNum}, % optional\n {username,UserName},\n {password,Password},\n {keep_alive,Bool}]}. % optional\n```\n\nTo communicate through Telnet to the host specified by `HostNameOrIpAddress`,\nuse the interface functions in `m:ct_telnet`, for example, `open(Name)` and\n`cmd(Name,Cmd)`.\n\n`Name` is the name you allocated to the Unix host in your `require` statement,\nfor example:\n\n```erlang\nsuite() -> [{require,Name,{unix,[telnet]}}].\n```\n\nor\n\n```erlang\nct:require(Name,{unix,[telnet]}).\n```\n\nThe \"keep alive\" activity (that is, that `Common Test` sends NOP to the server\nevery 10 seconds if the connection is idle) can be enabled or disabled for one\nparticular connection as described here. It can be disabled for all connections\nusing `telnet_settings` (see `m:ct_telnet`).\n\nThe `{port,PortNum}` tuple is optional and if omitted, default Telnet port 23 is\nused. Also the `keep_alive` tuple is optional, and the value default to `true`\n(enabled).","title":"unix_telnet","ref":"unix_telnet.html"},{"type":"module","doc":"`m:ct`, `m:ct_telnet`","title":"See Also - unix_telnet","ref":"unix_telnet.html#module-see-also"},{"type":"function","doc":"Callback for `ct_telnet.erl`.\n\n[](){: #connect-6 }\n\nSetup Telnet connection to a Unix host.","title":"unix_telnet.connect/7","ref":"unix_telnet.html#connect/7"},{"type":"function","doc":"Callback for `ct_telnet.erl`.\n\nReturns a suitable `regexp` string matching common prompts for users on Unix\nhosts.","title":"unix_telnet.get_prompt_regexp/0","ref":"unix_telnet.html#get_prompt_regexp/0"},{"type":"extras","doc":"\n# Common Test Application\n\nA framework for automated testing of any target nodes.","title":"Common Test Application","ref":"common_test_app.html"},{"type":"extras","doc":"The `Common Test` framework is an environment for implementing and performing\nautomatic and semi-automatic execution of test cases.\n\nIn brief, `Common Test` supports:\n\n- Automated execution of test suites (sets of test cases)\n- Logging of events during execution\n- HTML presentation of test suite results\n- HTML presentation of test suite code\n- Support functions for test suite authors\n- Step-by-step execution of test cases","title":"Description - Common Test Application","ref":"common_test_app.html#description"},{"type":"extras","doc":"\n# Common Test Release Notes","title":"Common Test Release Notes","ref":"notes.html"},{"type":"extras","doc":"","title":"Common_Test 1.27 - Common Test Release Notes","ref":"notes.html#common_test-1-27"},{"type":"extras","doc":"- Calls to `ct:capture_start/0` and `ct:capture_stop/0` are now synchronous to ensure that all output is captured.\n\n Own Id: OTP-18658 Aux Id: [PR-7380]\n\n- The order in which multiple hooks are executed can now be reversed after each config function. See [CTH Execution Order](`e:common_test:ct_hooks_chapter.md#cth_execution_order`).\n\n Own Id: OTP-18682 Aux Id: [GH-7397], [PR-7496], ERIERL-43\n\n- The default CSS will now include a basic dark mode handling if it is preferred by the browser.\n\n Own Id: OTP-18761 Aux Id: [PR-7428]\n\n- `-callback` attributes have been added to `m:ct_suite` and `m:ct_hooks`.\n\n Own Id: OTP-18781 Aux Id: [PR-7701]\n\n- The built-in [cth_log_redirect](`e:common_test:ct_hooks_chapter.md#built-in-cths`) hook can now be configured to replace default logger reports in terminal with HTML logs.\n\n Own Id: OTP-18875 Aux Id: [PR-7891]\n\n- Error handling for the `m:ct_property_test` framework has been enhanced.\n\n Own Id: OTP-18881 Aux Id: [PR-7824]\n\n- Enhance test case documentation, making it clear how a test case can be failed.\n\n Own Id: OTP-18892 Aux Id: [PR-7869]\n\n- The failing line in the test source code is now colored to make it easier to find on the screen.\n\n Own Id: OTP-18898 Aux Id: [PR-7917]\n\n- Function specifications and types have been added to all public API functions.\n\n Own Id: OTP-18913\n\n- The documentation has been migrated to use Markdown and ExDoc.\n\n Own Id: OTP-18955 Aux Id: [PR-8026]\n\n- The suite execution elapsed time is now included in the index page.\n\n Own Id: OTP-18981 Aux Id: [GH-7972], [PR-8112]\n\n[PR-7380]: https://github.com/erlang/otp/pull/7380\n[GH-7397]: https://github.com/erlang/otp/issues/7397\n[PR-7496]: https://github.com/erlang/otp/pull/7496\n[PR-7428]: https://github.com/erlang/otp/pull/7428\n[PR-7701]: https://github.com/erlang/otp/pull/7701\n[PR-7891]: https://github.com/erlang/otp/pull/7891\n[PR-7824]: https://github.com/erlang/otp/pull/7824\n[PR-7869]: https://github.com/erlang/otp/pull/7869\n[PR-7917]: https://github.com/erlang/otp/pull/7917\n[PR-8026]: https://github.com/erlang/otp/pull/8026\n[GH-7972]: https://github.com/erlang/otp/issues/7972\n[PR-8112]: https://github.com/erlang/otp/pull/8112","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.26.2 - Common Test Release Notes","ref":"notes.html#common_test-1-26-2"},{"type":"extras","doc":"* With this change, the last column in common_test testcase log file is modified to now show the total sum of each time in the table rows, and Elapsed Time which is a clock time spent to run above functions. The Elapsed Time is the same time that was previously a total.\n\n Own Id: OTP-18960","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.26.1 - Common Test Release Notes","ref":"notes.html#common_test-1-26-1"},{"type":"extras","doc":"* Fix how CT finds Erlang/OTP releases for compatability testing. This functionality is only used to test Erlang/OTP.\n\n Own Id: OTP-18932","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.26 - Common Test Release Notes","ref":"notes.html#common_test-1-26"},{"type":"extras","doc":"- With this change, common_test returns an error when suite with a badly defined\n group is executed.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-18728 Aux Id: PR-7487, PR-7674\n\n- With this change, stylesheet option is applied to all HTML report pages.\n\n Own Id: OTP-18760\n\n- Update all html tags to be instead.\n\n Own Id: OTP-18799 Aux Id: PR-7695","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- This change fixes docs, so that historically deprecated ?config macro is no\n longer recommended to be used.\n\n Own Id: OTP-18858 Aux Id: PR-7825","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.25.1 - Common Test Release Notes","ref":"notes.html#common_test-1-25-1"},{"type":"extras","doc":"- With this change, ct_hooks manual refers to CTH execution order section in\n user guide.\n\n Own Id: OTP-14480 Aux Id: ERIERL-43, OTP-11894, PR-7455\n\n- With this change, Config data from pre_end_per_testcase hook is delivered to\n post_end_per_testcase callback in case of testcase timetrap or linked process\n crash.\n\n Own Id: OTP-18579 Aux Id: GH-7119\n\n- With this change, remaining references to not supported vts tool in ct_run are\n removed (mainly relates to docs and ct_run help message).\n\n Own Id: OTP-18615 Aux Id: PR-7234\n\n- With this change, prompt search functionality in ct_telnet handles unicode\n input.\n\n Own Id: OTP-18664 Aux Id: ERIERL-959\n\n- Expanded the documentation about how to use the `standard_io`,\n `standard_error` and `user` I/O devices.\n\n Added the types [`io:standard_io/0`](`t:io:standard_io/0`),\n `io:standard:error/0` and [`io:user/0`](`t:io:user/0`).\n\n Own Id: OTP-18676 Aux Id: PR-7473 GH-7459","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.25 - Common Test Release Notes","ref":"notes.html#common_test-1-25"},{"type":"extras","doc":"- This change improves Common Test docs (CT hook example code) and adds Emacs\n skeleton with hook code.\n\n Own Id: OTP-18377 Aux Id: PR-6437","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Updated common_test with a more robust way to fetch old releases, while\n ignoring the current release.\n\n Own Id: OTP-18259 Aux Id: PR-5924\n\n- \\- re-write the XML `ct` module documentation into erlang types to make\n Dialyzer able to catch more precise errors\n\n Own Id: OTP-18340\n\n- Deprecates `dbg:stop_clear/0` because it is simply a function alias to\n `dbg:stop/0`\n\n Own Id: OTP-18478 Aux Id: GH-6903","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.24.0.3 - Common Test Release Notes","ref":"notes.html#common_test-1-24-0-3"},{"type":"extras","doc":"* With this change, the last column in common_test testcase log file is modified to now show the total sum of each time in the table rows, and Elapsed Time which is a clock time spent to run above functions. The Elapsed Time is the same time that was previously a total.\n\n Own Id: OTP-18960","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.24.0.2 - Common Test Release Notes","ref":"notes.html#common_test-1-24-0-2"},{"type":"extras","doc":"* Fix how CT finds Erlang/OTP releases for compatability testing. This functionality is only used to test Erlang/OTP.\n\n Own Id: OTP-18932","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.24.0.1 - Common Test Release Notes","ref":"notes.html#common_test-1-24-0-1"},{"type":"extras","doc":"- With this change, prompt search functionality in ct_telnet handles unicode\n input.\n\n Own Id: OTP-18664 Aux Id: ERIERL-959","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.24 - Common Test Release Notes","ref":"notes.html#common_test-1-24"},{"type":"extras","doc":"- Renamed undocumented macro `CT_PEER/3` to `CT_PEER_REL/3`.\n\n Own Id: OTP-18460","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.23.3 - Common Test Release Notes","ref":"notes.html#common_test-1-23-3"},{"type":"extras","doc":"- Change timeout to infinity for gen_server calls in cth_log_redirect\n\n Own Id: OTP-18363 Aux Id: ERIERL-879","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.23.2 - Common Test Release Notes","ref":"notes.html#common_test-1-23-2"},{"type":"extras","doc":"- Fix starting of peer nodes on old releases when the compile server was active\n and the current Erlang installation contained non-latin1 characters in its\n path.\n\n Own Id: OTP-18255 Aux Id: PR-6314","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.23.1 - Common Test Release Notes","ref":"notes.html#common_test-1-23-1"},{"type":"extras","doc":"- Fix cth_surefire to handle when a suite is not compiled with `debug_info`.\n This bug has been present since Erlang/OTP 25.0.\n\n Own Id: OTP-18208 Aux Id: ERIERL-852 PR-6229","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Common Test now preserves stack traces for throws.\n\n Own Id: OTP-18138 Aux Id: GH-5719, PR-6029","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.23 - Common Test Release Notes","ref":"notes.html#common_test-1-23"},{"type":"extras","doc":"- Fix bug when running parallel test cases and together with one or more ct\n hooks that would cause the hook lock process to crash and produce printouts in\n the ct logs.\n\n Own Id: OTP-17881 Aux Id: PR-5581","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Input for `configure` scripts adapted to `autoconf` 2\\.71.\n\n Own Id: OTP-17414 Aux Id: PR-4967\n\n- Remove unused and undocumented tracer node functionality.\n\n Own Id: OTP-17676 Aux Id: PR-5021\n\n- The new module `peer` supersedes the `slave` module. The `slave` module is now\n deprecated and will be removed in OTP 27.\n\n `peer` contains an extended and more robust API for starting erlang nodes.\n\n Own Id: OTP-17720 Aux Id: PR-5162\n\n- The cth_surefire ct hook has been updated to include the file and line number\n of the executed test case in the xml output.\n\n The performance of the hook has also been improved greatly for test runs with\n many test cases.\n\n Own Id: OTP-17882 Aux Id: PR-5581","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.22.1.3 - Common Test Release Notes","ref":"notes.html#common_test-1-22-1-3"},{"type":"extras","doc":"* With this change, the last column in common_test testcase log file is modified to now show the total sum of each time in the table rows, and Elapsed Time which is a clock time spent to run above functions. The Elapsed Time is the same time that was previously a total.\n\n Own Id: OTP-18960","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.22.1.2 - Common Test Release Notes","ref":"notes.html#common_test-1-22-1-2"},{"type":"extras","doc":"* Fix how CT finds Erlang/OTP releases for compatability testing. This functionality is only used to test Erlang/OTP.\n\n Own Id: OTP-18932","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.22.1.1 - Common Test Release Notes","ref":"notes.html#common_test-1-22-1-1"},{"type":"extras","doc":"- Change timeout to infinity for gen_server calls in cth_log_redirect\n\n Own Id: OTP-18363 Aux Id: ERIERL-879","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.22.1 - Common Test Release Notes","ref":"notes.html#common_test-1-22-1"},{"type":"extras","doc":"- OTP internal test fix.\n\n Own Id: OTP-17888","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.22 - Common Test Release Notes","ref":"notes.html#common_test-1-22"},{"type":"extras","doc":"- Before this change, group handling grammar was ambiguous and also group paths\n did not support test specs.\n\n Own Id: OTP-17664 Aux Id: GH-5088, PR-5242\n\n- Before this change, it was not possible to link to a particular header entry\n in Common Test log. Change adds right aligned anchor icons in HTML test logs.\n\n Own Id: OTP-17790 Aux Id: PR-5375","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.21 - Common Test Release Notes","ref":"notes.html#common_test-1-21"},{"type":"extras","doc":"- Float allowed as multiply_timetraps parameter.\n\n Own Id: OTP-17413 Aux Id: PR-4767\n\n- Remove usage of legacy API macro and functions.\n\n Own Id: OTP-17632 Aux Id: PR-5022","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.20.5 - Common Test Release Notes","ref":"notes.html#common_test-1-20-5"},{"type":"extras","doc":"- An incoming NETCONF notification received before a call to\n ct_netconfc:create_subscription/\\* caused the connection process to fail with\n badarg. Unexpected notifications are now logged in the same way as other\n unexpected messages.\n\n Own Id: OTP-17506","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add 'receiver' option to ct_netconfc\n\n To allow a destination for incoming NETCONF notifications to be specified at\n sessions creation. Previously, a caller of create_subscription/\\* became the\n destination, but RFC 5277 create-subscription is no longer the only way in\n which NETCONF notifications can be ordered.\n\n Own Id: OTP-17509","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.20.4 - Common Test Release Notes","ref":"notes.html#common_test-1-20-4"},{"type":"extras","doc":"- Commit of generated `configure` script.\n\n Own Id: OTP-17420 Aux Id: OTP-17398, GH-4821","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.20.3 - Common Test Release Notes","ref":"notes.html#common_test-1-20-3"},{"type":"extras","doc":"- The option `release_shell` could crash when used together with the `spec`\n option.\n\n Own Id: OTP-16940 Aux Id: ERL-1335","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The experimental HiPE application has been removed, together with all related\n functionality in other applications.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-16963\n\n- Fixed warnings in code matching on underscore prefixed variables.\n\n Own Id: OTP-17385 Aux Id: OTP-17123","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.20.2.3 - Common Test Release Notes","ref":"notes.html#common_test-1-20-2-3"},{"type":"extras","doc":"- OTP internal test fix.\n\n Own Id: OTP-17888","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.20.2.2 - Common Test Release Notes","ref":"notes.html#common_test-1-20-2-2"},{"type":"extras","doc":"- An incoming NETCONF notification received before a call to\n ct_netconfc:create_subscription/\\* caused the connection process to fail with\n badarg. Unexpected notifications are now logged in the same way as other\n unexpected messages.\n\n Own Id: OTP-17506","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add 'receiver' option to ct_netconfc\n\n To allow a destination for incoming NETCONF notifications to be specified at\n sessions creation. Previously, a caller of create_subscription/\\* became the\n destination, but RFC 5277 create-subscription is no longer the only way in\n which NETCONF notifications can be ordered.\n\n Own Id: OTP-17509","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.20.2.1 - Common Test Release Notes","ref":"notes.html#common_test-1-20-2-1"},{"type":"extras","doc":"- Commit of generated `configure` script.\n\n Own Id: OTP-17420 Aux Id: OTP-17398, GH-4821","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.20.2 - Common Test Release Notes","ref":"notes.html#common_test-1-20-2"},{"type":"extras","doc":"- Before this change Config leaked between test groups in case of a subgroup was\n skipped (GH-3480).\n\n Own Id: OTP-17347 Aux Id: GH-3480,ERL-1439","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.20.1 - Common Test Release Notes","ref":"notes.html#common_test-1-20-1"},{"type":"extras","doc":"- A race condition could cause ct_netconfc:open/_ to return a dysfunctional\n handle, resulting in errors when invoking other api functions on it, and\n making it impossible to establish a new connection to the server in question.\n Similar symptoms were possible with open/_ in modules ct_ssh and ct_telnet.\n\n Internal messages from common_test processes could be left in the caller's\n message queue after a timeout when invoking call/\\* in modules ct_netconfc and\n ct_ssh. An internal process used by module ct_telnet could leak memory due to\n stray messages.\n\n Calls to ct_telnet:open/\\* and ct_telnet:get_data/1 could hang indefinitely if\n the TCP connection to the server was lost.\n\n Own Id: OTP-17328 Aux Id: ERIERL-631","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.20 - Common Test Release Notes","ref":"notes.html#common_test-1-20"},{"type":"extras","doc":"- Various address sanitizer support.\n\n Own Id: OTP-16959 Aux Id: PR-2965","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.19.1 - Common Test Release Notes","ref":"notes.html#common_test-1-19-1"},{"type":"extras","doc":"- Add behaviour for test suites\n\n Own Id: OTP-17070","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.19 - Common Test Release Notes","ref":"notes.html#common_test-1-19"},{"type":"extras","doc":"- The function `ct_property_test:init_tool/1` is added for the cases when the\n user does not want ct_property_test to compile properties. init_tool/1 can be\n used to set the property_test_tool config value.\n\n Own Id: OTP-16029 Aux Id: PR-2145\n\n- The built-in Common Test Hook, `cth_log_redirect`, has been updated to use the\n system `default` Logger handler's configuration instead of its own. See the\n section on [Built-in Hooks](ct_hooks_chapter.md#built-in-cths) in the Common\n Test User's Guide.\n\n Own Id: OTP-16273\n\n- Calls of deprecated functions in the\n [Old Crypto API](`e:crypto:new_api.md#the-old-api`) are replaced by calls of\n their [substitutions](`e:crypto:new_api.md#the-new-api`).\n\n Own Id: OTP-16346","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.18.2.2 - Common Test Release Notes","ref":"notes.html#common_test-1-18-2-2"},{"type":"extras","doc":"- OTP internal test fix.\n\n Own Id: OTP-17888","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.18.2.1 - Common Test Release Notes","ref":"notes.html#common_test-1-18-2-1"},{"type":"extras","doc":"- Commit of generated `configure` script.\n\n Own Id: OTP-17420 Aux Id: OTP-17398, GH-4821","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.18.2 - Common Test Release Notes","ref":"notes.html#common_test-1-18-2"},{"type":"extras","doc":"- Document incl_apps cover option\n\n Own Id: OTP-16039 Aux Id: ERL-795\n\n- The `ct_property_test` has now a report function for results of stateful\n testing.\n\n Own Id: OTP-16340\n\n- Don't hide error reasons from user\n\n Own Id: OTP-16364 Aux Id: PR-2480","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.18.1 - Common Test Release Notes","ref":"notes.html#common_test-1-18-1"},{"type":"extras","doc":"- The ct_property_test logging is improved.\n\n Own Id: OTP-16287","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.18 - Common Test Release Notes","ref":"notes.html#common_test-1-18"},{"type":"extras","doc":"- If a ct hook is installed in the `suite/0` function in a test suite, then the\n hook's `terminate/1` function would be called several times without it's\n `init/2` function being called first. This is now corrected.\n\n Own Id: OTP-15863 Aux Id: ERIERL-370\n\n- If `init_per_testcase` fails, the test itself is skipped. According to the\n documentation, it should be possible to change the result to failed in a hook\n function. The only available hook function in this case is\n `post_init_per_testcase`, but changing the return value there did not affect\n the test case result. This is now corrected.\n\n Own Id: OTP-15869 Aux Id: ERIERL-350","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add ct_netconfc support for NETCONF 1.1 (RFC 6241). The 1.1 base capability\n can be sent in hello, and RFC 6242 chunk framing is applied when both client\n and server advertise 1.1 support.\n\n Own Id: OTP-15789\n\n- Correct lib_dir paths in common_tests opaque data structure that is passed to\n ct_release_test callback modules in functions upgrade_init/2,\n upgrade_upgraded/2 and upgrade_downgraded/2. The incorrect paths may cause\n confusion when debugging although it will not cause any incorrect behavior on\n the part of common_test as it is currently not used.\n\n Own Id: OTP-15934","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.17.3 - Common Test Release Notes","ref":"notes.html#common_test-1-17-3"},{"type":"extras","doc":"- All incorrect (that is, all) uses of \"can not\" has been corrected to \"cannot\"\n in source code comments, documentation, examples, and so on.\n\n Own Id: OTP-14282 Aux Id: PR-1891","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Use `ssh` instead of `rsh` as the default remote shell.\n\n Own Id: OTP-15633 Aux Id: PR-1787","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.17.2.1 - Common Test Release Notes","ref":"notes.html#common_test-1-17-2-1"},{"type":"extras","doc":"- If a ct hook is installed in the `suite/0` function in a test suite, then the\n hook's `terminate/1` function would be called several times without it's\n `init/2` function being called first. This is now corrected.\n\n Own Id: OTP-15863 Aux Id: ERIERL-370\n\n- If `init_per_testcase` fails, the test itself is skipped. According to the\n documentation, it should be possible to change the result to failed in a hook\n function. The only available hook function in this case is\n `post_init_per_testcase`, but changing the return value there did not affect\n the test case result. This is now corrected.\n\n Own Id: OTP-15869 Aux Id: ERIERL-350","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.17.2 - Common Test Release Notes","ref":"notes.html#common_test-1-17-2"},{"type":"extras","doc":"- The test result when a hook function fails is in general the same as if the\n function that the hook is associated with fails. For example, if\n `post_init_per_testcase` fails the result is that the test case is skipped, as\n is the case when `init_per_testcase` fails.This, however, was earlier not true\n for timetrap timeouts or other error situations where the process running the\n hook function was killed. This is now corrected, so the error handling should\n be the same no matter how the hook function fails.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-15717 Aux Id: ERIERL-334\n\n- In some rare cases, when two common_test nodes used the same log directory, a\n timing problem could occur which caused common_test to crash because it's log\n cache file was unexpectedly empty. This is now corrected.\n\n Own Id: OTP-15758 Aux Id: ERIERL-342","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Two new common_test hook functions are introduced:\n\n `post_groups/2`, which is called after `Suite:groups/0` \n `post_all/3`, which is called after `Suite:all/0`\n\n These functions allow modifying the return values from the `groups/0` and\n `all/0` functions, respectively.\n\n A new term, `{testcase,TestCase,RepeatProperties}` is now also allowed in the\n return from `all/0`. This can be used for repeating a single test case a\n specific number of times, or until it fails or succeeds once.\n\n Own Id: OTP-14746 Aux Id: ERIERL-143","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.17.1 - Common Test Release Notes","ref":"notes.html#common_test-1-17-1"},{"type":"extras","doc":"- OTP internal test improvements.\n\n Own Id: OTP-15716","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.17 - Common Test Release Notes","ref":"notes.html#common_test-1-17"},{"type":"extras","doc":"- A bug caused `ct:encrypt_config_file/3` and `ct:decrypt_config_file/3` to fail\n with `badmatch` if input parameter `KeyOrFile` was `{key,string()}`. This is\n now corrected.\n\n Own Id: OTP-15540\n\n- The status of a test case which failed with timetrap timeout in\n `end_per_testcase` could not be modified by returning `{fail,Reason}` from a\n `post_end_per_testcase` hook function. This is now corrected.\n\n Own Id: OTP-15584 Aux Id: ERIERL-282","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- A new variant of the `newline` option to `ct_telnet:cmd/3` and\n `ct_telnet:send/3` is added, which allows to specify a string to append as\n newline indicator on a command. By default, the value is \"\\\\n\", but in some\n cases it is required to be \"\\\\r\\\\n\", which this option allows.\n\n A faulty regular expression given as parameter to `ct_telnet:expect/2,3` would\n earlier crash and look like an internal error in common_test. A better error\n indication is now given, but the test case will still fail.\n\n Own Id: OTP-15229 Aux Id: ERIERL-203\n\n- Since the yang RFC allows more than one top element of config data in an\n `edit-config` element, `ct_netconfc:edit_config/3,4,5` can now take a list of\n XML elements.\n\n Own Id: OTP-15298","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.16.1 - Common Test Release Notes","ref":"notes.html#common_test-1-16-1"},{"type":"extras","doc":"- The Logger handler cth_log_redirect earlier called the report callback\n (report_cb) before calling the logger formatter. In some cases this would\n fail, since cth_log_redirect could not handle report callbacks with two\n arguments. This is now corrected, so only the formatter will call the report\n callback.\n\n Own Id: OTP-15307","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.16 - Common Test Release Notes","ref":"notes.html#common_test-1-16"},{"type":"extras","doc":"- Use the compiler option `nowarn_export_all` to disable `export_all` warnings\n when automatically compiling test suites.\n\n Own Id: OTP-14810\n\n- Use uri_string module instead of http_uri.\n\n Own Id: OTP-14902","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.15.4.4 - Common Test Release Notes","ref":"notes.html#common_test-1-15-4-4"},{"type":"extras","doc":"- The ct_property_test logging is improved.\n\n Own Id: OTP-16287","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.15.4.3 - Common Test Release Notes","ref":"notes.html#common_test-1-15-4-3"},{"type":"extras","doc":"- If a ct hook is installed in the `suite/0` function in a test suite, then the\n hook's `terminate/1` function would be called several times without it's\n `init/2` function being called first. This is now corrected.\n\n Own Id: OTP-15863 Aux Id: ERIERL-370\n\n- If `init_per_testcase` fails, the test itself is skipped. According to the\n documentation, it should be possible to change the result to failed in a hook\n function. The only available hook function in this case is\n `post_init_per_testcase`, but changing the return value there did not affect\n the test case result. This is now corrected.\n\n Own Id: OTP-15869 Aux Id: ERIERL-350","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.15.4.2 - Common Test Release Notes","ref":"notes.html#common_test-1-15-4-2"},{"type":"extras","doc":"- The test result when a hook function fails is in general the same as if the\n function that the hook is associated with fails. For example, if\n `post_init_per_testcase` fails the result is that the test case is skipped, as\n is the case when `init_per_testcase` fails.This, however, was earlier not true\n for timetrap timeouts or other error situations where the process running the\n hook function was killed. This is now corrected, so the error handling should\n be the same no matter how the hook function fails.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-15717 Aux Id: ERIERL-334\n\n- In some rare cases, when two common_test nodes used the same log directory, a\n timing problem could occur which caused common_test to crash because it's log\n cache file was unexpectedly empty. This is now corrected.\n\n Own Id: OTP-15758 Aux Id: ERIERL-342","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Two new common_test hook functions are introduced:\n\n `post_groups/2`, which is called after `Suite:groups/0` \n `post_all/3`, which is called after `Suite:all/0`\n\n These functions allow modifying the return values from the `groups/0` and\n `all/0` functions, respectively.\n\n A new term, `{testcase,TestCase,RepeatProperties}` is now also allowed in the\n return from `all/0`. This can be used for repeating a single test case a\n specific number of times, or until it fails or succeeds once.\n\n Own Id: OTP-14746 Aux Id: ERIERL-143\n\n- OTP internal test improvements.\n\n Own Id: OTP-15716","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.15.4.1 - Common Test Release Notes","ref":"notes.html#common_test-1-15-4-1"},{"type":"extras","doc":"- The status of a test case which failed with timetrap timeout in\n `end_per_testcase` could not be modified by returning `{fail,Reason}` from a\n `post_end_per_testcase` hook function. This is now corrected.\n\n Own Id: OTP-15584 Aux Id: ERIERL-282","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.15.4.0.1 - Common Test Release Notes","ref":"notes.html#common_test-1-15-4-0-1"},{"type":"extras","doc":"- The status of a test case which failed with timetrap timeout in\n `end_per_testcase` could not be modified by returning `{fail,Reason}` from a\n `post_end_per_testcase` hook function. This is now corrected.\n\n Own Id: OTP-15584 Aux Id: ERIERL-282","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.15.4 - Common Test Release Notes","ref":"notes.html#common_test-1-15-4"},{"type":"extras","doc":"- Fixed problem with 'skip_groups' in combination with 'all suites' option in\n test specification.\n\n Own Id: OTP-14953","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.15.3 - Common Test Release Notes","ref":"notes.html#common_test-1-15-3"},{"type":"extras","doc":"- A new function, `ct:remaining_test_procs/0`, returns the identity of test- and\n group leader processes that are still running at the time of the call.\n\n Own Id: OTP-13832\n\n- A \"latest test result\" link is now displayed in the footer of each test index\n page, which performs a jump to the most recently generated test index. This is\n useful for making quick comparisons of results between test runs without\n having to traverse the log file tree.\n\n Own Id: OTP-14281","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.15.2 - Common Test Release Notes","ref":"notes.html#common_test-1-15-2"},{"type":"extras","doc":"- General Unicode improvements.\n\n Own Id: OTP-14462","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.15.1 - Common Test Release Notes","ref":"notes.html#common_test-1-15-1"},{"type":"extras","doc":"- In OTP-20.0, the behavior of c, make, and ct_make was changed so that in some\n cases the beam files by default would be written to the directory where the\n source files were found. This is now changed back to the old behavior so beam\n files are by default written to current directory.\n\n Own Id: OTP-14489 Aux Id: ERL-438","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.15 - Common Test Release Notes","ref":"notes.html#common_test-1-15"},{"type":"extras","doc":"- Errors in the documentation for user HTML stylesheets have been corrected.\n\n Own Id: OTP-14332 Aux Id: seq13299\n\n- Internal code change: Calls to `catch` followed by a call to\n `erlang:get_stacktrace/0` has been rewritten to use `try` instead of `catch`\n to make the code future-proof.\n\n Own Id: OTP-14400","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The `ct_slave` modules now handle nodenames in the same way as nodenames\n passed to `-sname`. That means `ct_slave:start('b@127.0.0.1').` will now work.\n\n Own Id: OTP-13806\n\n- Added the new option, `keep_logs`. If setting the value for this option to an\n integer, N, common_test will remove all ct_run.\\* directories in the current\n log directory, except the N newest.\n\n Own Id: OTP-14179\n\n- The existing `ct_netconfc:open/1,2` opens an SSH connection with one SSH\n channel realizing one Netconf session. To allow testing of multiple sessions\n over the same SSH connection, the following functions are added to\n `ct_netconfc`:\n\n \\* `connect/1,2` \\- establish an SSH connection _ `disconnect/1` \\- close the\n given SSH connection _ `session/1,2,3` \\- open an ssh channel on the given\n connection and send 'hello' to start a Netconf session\n\n Own Id: OTP-14284\n\n- Miscellaneous updates due to atoms containing arbitrary Unicode characters.\n\n Own Id: OTP-14285\n\n- The function ct_ssh:shell/2,3 is added.\n\n Own Id: OTP-14415 Aux Id: seq13315","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.14 - Common Test Release Notes","ref":"notes.html#common_test-1-14"},{"type":"extras","doc":"- The following corrections and improvements are done in the common_test hook\n handling:\n\n - An extra argument, `Suite`, is added as the first argument to each of the\n following hook callback functions:\n\n - `pre_init_per_group`\n - `post_init_per_group`\n - `pre_end_per_group`\n - `post_end_per_group`\n - `pre_init_per_testcase`\n - `post_init_per_testcase`\n - `pre_end_per_testcase`\n - `post_end_per_testcase`\n - `on_tc_fail`\n - `on_tc_skip`\n\n For backwards compatibility, if the new function is not exported from a hook\n callback module, `common_test` will fall back to the old interface and call\n the function without the `Suite` argument.\n\n - If either `init_per_suite` or `end_per_suite` exists, but not the other,\n then the non-existing function will be reported as failed with reason\n `undef` in the test log. The same goes for `init/end_per_group`. This has\n always been a requirement according to the user's guide, but now\n `common_test` is more explicit in the report.\n - If `init_per_suite` was exported from a test suite, but not `end_per_suite`,\n then `pre/post_end_per_suite` was called with `Suite=ct_framework` instead\n of the correct suite name. This is now corrected.\n - If `end_per_group` was exported from a suite, but not `init_per_group`, then\n `end_per_group` was never called. This is now corrected.\n - Tests that were skipped before calling `pre_init_per_*` got faulty calls to\n the corresponding `post_init_per_*`. E.g. if a test was skipped because\n `suite/0` failed, then `post_init_per_suite` would be called even though\n `pre_init_per_suite` and `init_per_suite` were not called. This is now\n corrected so a `post_*` callback will never be called unless the\n corresponding `pre_*` callback has been called first.\n - Tests that were skipped before or in `init_per_testcase` got faulty calls to\n `pre_end_per_testcase` and `post_end_per_testcase`. This is now corrected so\n `pre/post_end_per_testcase` are not called when `end_per_testcase` is not\n called.\n - If an exit signal causes the test case process to die while running\n `init_per_testcase`, the case was earlier reported as failed with reason\n `{skip,...}`. This is now corrected so the case will be marked as skipped.\n - If an exist signal causes the test case process to die while running\n `end_per_testcase`, the case was earlier marked as failed. This is now\n corrected so the status of the test case is not changed - there is only a\n warning added to the comment field.\n - If a test case was skipped because of option `{force_stop,skip_rest}` or\n because of a failed sequence, then no `tc_start` event would be sent, only\n `tc_done`. This is now corrected so both events are sent.\n - When skipping or failing in a configuration function, the configuration\n function itself would get `{auto_skipped,Reason}`, `{skipped,Reason}` or\n `{failed,Reason}` in the hook callbacks `on_tc_skip` or `on_tc_fail`. The\n other test cases that were skipped as a result of this would only get\n `Reason` in `on_tc_skip`. This is now corrected so even the configuration\n function that caused the skip/fail will only get `Reason` in the hook\n callback.\n\n Own Id: OTP-10599 Aux Id: kunagi-344 \\[255]\n\n- When a test case was skipped by a `skip_cases` statement in a test spec, then\n `cth_surefire` would erroneously mark the previous test case as skipped in the\n xml report. The actually skipped test case would not be present in the xml\n report at all. This is now corrected.\n\n Own Id: OTP-14129 Aux Id: seq13244\n\n- The `multiply_timetraps` and `scale_timetraps` options did not work with test\n specifications, which has been corrected.\n\n Own Id: OTP-14210","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- ct_testspec:get_tests/1 is added. This is used by rebar3 to get all\n directories that must be compiled when running tests from testspec - instead\n of implementing testspec parsing in rebar3.\n\n Own Id: OTP-14132","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.13 - Common Test Release Notes","ref":"notes.html#common_test-1-13"},{"type":"extras","doc":"- Some types of printouts to screen during test runs (including\n `ct:print/1,2,3,4`) used the local `user` process as IO device and these\n printouts would not be visible when e.g. running tests via a shell on a remote\n node. A default Common Test group leader process has been introduced to solve\n the problem. This process routes printouts to the group leader of the starting\n process, if available, otherwise to `user`.\n\n Own Id: OTP-13973 Aux Id: ERL-279\n\n- Some Common Test processes, that act as I/O group leaders for test cases,\n would not terminate as expected at the end of test runs. This error has been\n corrected.\n\n Own Id: OTP-14026 Aux Id: ERL-287\n\n- The logging verbosity feature was incorrectly documented. The default\n verbosity levels for test runs is e.g. not 50 (`?STD_VERBOSITY`), but 100\n (`?MAX_VERBOSITY`). Also, some of the examples had errors and flaws. The\n corresponding chapter (5.18) in the User's Guide has been updated.\n\n Own Id: OTP-14044 Aux Id: seq13223","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- A feature to let the user specify headings to log printouts has been added.\n The heading is specified as `{heading,string()}` in the `Opts` list argument\n to `ct:pal/3,4,5`, `ct:print/3,4,5`, or `ct:log/3,4,5`. If the heading option\n is omitted, the category name, or `\"User\"`, is used as the heading instead.\n\n Own Id: OTP-14043 Aux Id: seq13226","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.12.3 - Common Test Release Notes","ref":"notes.html#common_test-1-12-3"},{"type":"extras","doc":"- If the telnet server would pause during transmission of a line of text before\n terminating the line, the `ct_telnet:expect/3` function would print the line\n twice in the test case HTML log. This problem has been fixed.\n\n Own Id: OTP-13730 Aux Id: seq13135\n\n- The functions `ct:set_verbosity/2` and `ct:get_verbosity/1` have been added in\n order to make it possible for test cases, CT Hooks, or test framework\n functions, to modify and read verbosity levels for logging.\n\n Own Id: OTP-13841\n\n- `make` (tools) and `ct_make` (common_test) would crash if an Erlang source\n file contained a `-warning()` directive.\n\n Own Id: OTP-13855","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.12.2 - Common Test Release Notes","ref":"notes.html#common_test-1-12-2"},{"type":"extras","doc":"- The following modules were missing in common_test.app.src: ct_groups,\n ct_property_test, ct_release_test, ct_webtool, ct_webtool_sup, test_server_gl.\n They have now been added.\n\n Own Id: OTP-13475\n\n- Common Test printed incorrect timestamps for received error reports.\n\n Own Id: OTP-13615 Aux Id: seq13124","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.12.1 - Common Test Release Notes","ref":"notes.html#common_test-1-12-1"},{"type":"extras","doc":"- The `nodelay` option used to be enabled (`true`) by default for sockets opened\n by the Common Test telnet client. This appeared to cause communication\n problems with telnet servers on some systems, and therefore the option is no\n longer used. Its value may instead be specified in the telnet connection\n settings. See the man page for `ct_telnet` for details. Please note that the\n interface function `connect` in `unix_telnet` has been updated with an extra\n argument and is now `unix_telnet:connect/7`.\n\n Own Id: OTP-13462 Aux Id: seq13077\n\n- Fix bug in cth_surefire: When a pre_init_per_suite hook fails before reaching\n the cth_surefire:pre_init_per_suite, cth_surefire produced incorrect XML.\n\n Own Id: OTP-13513\n\n- The `ct:get_timetrap_info/0` function has been updated to return more\n information about timetrap scaling.\n\n Own Id: OTP-13535\n\n- A problem with stylesheet HTML tags getting incorrectly escaped by Common Test\n has been corrected.\n\n Own Id: OTP-13536\n\n- The `ct_run` start flag `-no_esc_chars` and `ct:run_test/1` start option\n `{esc_chars,Bool}` have been introduced to make it possible to disable\n automatic escaping of characters. Automatic escaping of special HTML\n characters printed with `io:format/1,2` and `ct:pal/1,2,3,4` was introduced in\n Common Test 1.12. The new flag/option may be used to disable this feature for\n backwards compatibility reasons. (The option is also supported in test\n specifications).\n\n Own Id: OTP-13537","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.12 - Common Test Release Notes","ref":"notes.html#common_test-1-12"},{"type":"extras","doc":"- This update fixes the problem with generic printouts in the html log file not\n having special characters escaped. Printouts made with `io:format/2` and\n `ct:pal/2` will now get special characters escaped automatically. Common Test\n will not attempt to escape characters printed with `ct:log/2` since it is\n assumed that the user may want to print html tagged data using this function.\n A new function, `ct:log/5`, has been added, which offers optional escaping of\n characters. The latter function may also be used to print text to the log\n without headers and CSS class wrapping (analogue to `io:format/2`).\n\n Own Id: OTP-13003 Aux Id: seq13005\n\n- Commit 4cf832f1ad163f5b25dd8a6f2d314c169c23c82f erroneously removed logging of\n open and close of netconf connections. This is now corrected.\n\n Own Id: OTP-13386\n\n- The directory to which nodes started with `test_server:start_node/3` writes\n their erl_crash.dump is changed. The crashdumps were earlier written to the\n directory of test_server.beam, but in later versions of Microsoft Windows this\n is no longer writable (even for administrators). The framework (common_test)\n log directory is now used instead.\n\n Own Id: OTP-13388","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- This update makes it possible to specify multiple instances of the same group\n or test case in one test specification term in order to repeat execution.\n Example:\n `{groups, \"./\", my_SUITE, [my_group, my_group], {cases, all}}, or {cases, \"./\", my_SUITE, [my_tc, my_tc, my_tc]}.`\n\n Own Id: OTP-13241 Aux Id: seq12979\n\n- Two new CT hook functions have been added: `post_init_per_testcase/4` and\n `pre_end_per_testcase/3`. With these hook functions, it is possible to perform\n arbitrary actions (including modifications of test execution, test state and\n results) immediately before and after the execution of the test case.\n\n Own Id: OTP-13242 Aux Id: seq12991\n\n- The `ct_netconfc` was earlier very restrictive as to which SSH options the\n user could set. This is now changed, and any SSH option is now allowed. The\n netconf client will simply pass on any option, which it does not recognize, to\n SSH.\n\n Own Id: OTP-13338 Aux Id: seq13053,seq13069","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.11.2 - Common Test Release Notes","ref":"notes.html#common_test-1-11-2"},{"type":"extras","doc":"- If a ssh package contained more than one netconf end tag, then the second end\n tag was never detected in ct_netconfc:handle_data. Instead it was included in\n the XML data given to the xmerl parser, which then failed. The problem was\n introduced by OTP-13007, and has now been corrected.\n\n Own Id: OTP-13323","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.11.1 - Common Test Release Notes","ref":"notes.html#common_test-1-11-1"},{"type":"extras","doc":"- When data from the netconf server was split into many ssh packages, the\n netconf client performed really bad. This is now improved.\n\n Own Id: OTP-13007\n\n- In ct_netconfc, if a timer expired 'at the same time' as the server sent the\n rpc-reply, the timeout message might already be in the client's message queue\n when the client removed the timer ref from its 'pending' list. This caused a\n crash in the client since the timer ref could no longer be found when handling\n the timeout message. This problem is now fixed by always flushing the timeout\n message from the message queue when canceling a timer.\n\n Own Id: OTP-13008\n\n- The error logger handler ct_conn_log_h did not respect the 'silent' option,\n and tried to print to an undefined file descriptor. This has been corrected.\n\n Own Id: OTP-13035\n\n- If the user would let the test run proceed after test suite compilation\n failure, Common Test did not set the exit status to indicate failure as\n expected. This has been corrected. Also, the 'abort_if_missing_suites' option\n now makes Common Test abort the test run without asking the user if\n compilation fails, even if access to stdin/stdout exists.\n\n Own Id: OTP-13173 Aux Id: seq12978\n\n- With the Common Test 'create_priv_dir' start option set to 'auto_per_tc', the\n name of the priv directory for a configuration function could clash with the\n name of the priv directory for a test case, which would cause Test Server\n failure. This error has been corrected.\n\n Own Id: OTP-13181","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.11 - Common Test Release Notes","ref":"notes.html#common_test-1-11"},{"type":"extras","doc":"- The status of an aborted test due to test suite compilation error has changed\n from 'auto_skipped' to 'failed'. This affects both the textual log file, event\n handling and CT hook callbacks. The logging of compilation failures has also\n been improved, especially in the case of multiple test suites failing\n compilation.\n\n Own Id: OTP-10816\n\n- The Test Server source code parser (erl2html2) failed to handle the macro\n tuple in the syntax tree returned by epp_dodger. This error has been\n corrected.\n\n Own Id: OTP-12740\n\n- New options to make it possible to specify ssh_port in a .spec file:\n \\[\\{node_start, [\\{ssh_port, 9999\\}]\\}].\n\n And also to specify additional ssh options like paths to public-key files:\n \\[\\{node_start, [\\{ssh_opts, [\\{user_dir, \"/home/shrek/e2/\"\\}]\\}]\\}].\n\n Own Id: OTP-12809","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Earlier there was no way to add optional parameters like default-operation to\n an edit-config request sent with ct_netconfc:edit_config/3,4, you had to use\n ct_netconfc:send_rpc/2,3. For simplicity and completion, a new optional\n argument, OptParams, is now added to the edit_config function.\n\n Own Id: OTP-10446 Aux Id: kunagi-266 \\[177]\n\n- When running OTP tests using the ts interface, it is now possible to specify\n so called test categories per OTP application. A test category is represented\n by a CT test specification and defines an arbitrary subset of existing test\n suites, groups and cases. Examples of test categories are 'smoke' (smoke\n tests) and 'bench' (benchmarks). (Call ts:help() for more info). Also,\n functions for reading terms from the current test specification during test,\n ct:get_testspec_terms/0 and ct:get_testspec_terms/1, have been implemented.\n\n Own Id: OTP-11962\n\n- Obsolete scripts and make file operations have been removed and the\n installation chapter in the Common Test User's Guide has been updated.\n\n Own Id: OTP-12421\n\n- The 'keep_alive' interval has been reduced to 8 seconds, which is two seconds\n shorter than the default 'idle_timeout' value for ct_telnet:expect/3. This\n way, the telnet server receives a NOP message (which might trigger an action)\n before the operation times out. Also the TCP option 'nodelay' has been enabled\n per default for all telnet connections, in order to reduce the risk for\n communication timeouts.\n\n Own Id: OTP-12678 Aux Id: seq12818\n\n- When the ct_run program is executed without any flags, \"-dir .\" is now used as\n default start flag. Similarly, the option \\{dir,\".\"\\} is used by ct:run_test/1\n if called with an empty list. Also, the help text (ct_run -help) has been\n updated, as well as the Running Tests chapter in the Common Test User's Guide.\n\n Own Id: OTP-12684 Aux Id: seq12865","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.10.1 - Common Test Release Notes","ref":"notes.html#common_test-1-10-1"},{"type":"extras","doc":"- A fault in the Common Test logger process, that caused the application to\n crash when running on a long name node, has been corrected.\n\n Own Id: OTP-12643\n\n- A 'wait_for_prompt' option in ct_telnet:expect/3 has been introduced which\n forces the function to not return until a prompt string has been received,\n even if other expect patterns have already been found.\n\n Own Id: OTP-12688 Aux Id: seq12818\n\n- If the last expression in a test case causes a timetrap timeout, the stack\n trace is ignored and not printed to the test case log file. This happens\n because the \\{Suite,TestCase,Line\\} info is not available in the stack trace\n in this scenario, due to tail call elimination. Common Test has been modified\n to handle this situation by inserting a \\{Suite,TestCase,last_expr\\} tuple in\n the correct place and printing the stack trace as expected.\n\n Own Id: OTP-12697 Aux Id: seq12848\n\n- Fixed a buffer problem in ct_netconfc which could cause that some messages\n where buffered forever.\n\n Own Id: OTP-12698 Aux Id: seq12844\n\n- The VTS mode in Common Test has been modified to use a private version of the\n Webtool application (ct_webtool).\n\n Own Id: OTP-12704 Aux Id: OTP-10922\n\n- Add possibility to add user capabilities in `ct_netconfc:hello/3`.\n\n Own Id: OTP-12707 Aux Id: seq12846","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.10 - Common Test Release Notes","ref":"notes.html#common_test-1-10"},{"type":"extras","doc":"- The tests overview file, index.html, did not always get updated correctly\n after a new test run. This was because of a bug in the Common Test log cache\n mechanism which has now been corrected.\n\n Own Id: OTP-11400\n\n- When a successful test case returns, Common Test should, according to the\n documentation, send a tc_done event to the event handlers with Result = ok in\n the data field. However, Common Test sets Result to the return value of the\n test case instead. Common Test has been modified now to comply with the\n documentation.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-12279 Aux Id: seq12737, OTP-12531\n\n- A ct_telnet:expect/3 call could never be aborted before an idle_timeout, even\n if total_timeout had been set to a lower value (i.e. a shorter time). This\n problem has been fixed.\n\n Own Id: OTP-12335\n\n- The undocumented return value \\{skipped,Reason\\} from config functions and\n test cases was handled inconsistently. Test cases were e.g. reported as\n \"skipped\" to CT Hook functions, but \"successful\" to event handlers. Now, the\n above return value is consistently handled the same way as \\{skip,Reason\\} and\n this has also been documented.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-12359 Aux Id: seq12760\n\n- The Erlang source code to HTML generator would sometimes fail because\n epp:parse_erl_form/1 could not find and expand required macros in included\n header files. The problem has been solved by making sure common_test always\n passes the full include path to epp. Also, a bug that could cause\n erl_syntax:revert/1 to fail because of a badly formed syntax tree has been\n corrected.\n\n Own Id: OTP-12419\n\n- A missing group option in the ct_run help text has been added.\n\n Own Id: OTP-12433 Aux Id: seq12788\n\n- Printouts by means of ct:log/2/3 or ct:pal/2/3 from the hook functions\n on_tc_fail/2 and on_tc_skip/2 would (quite unexpectedly) end up in the\n \"unexpected i/o\" log file instead of in the test case log file. This behaviour\n has been changed so that now, all printouts (including stdio printouts) from\n these hook functions will be routed to the test case log file.\n\n Own Id: OTP-12468\n\n- ct_netconfc:action/3 will now - if the return type is void - accept an RPC\n reply on the form \\{ok,\\[simple_xml()]\\}, and in this event return only the\n atom ok.\n\n Own Id: OTP-12491 Aux Id: seq12797\n\n- OTP-11971 erroneously changed the handling of relative paths for incl_dirs\n specified in the cover spec file. This is now corrected so these are expected\n to be relative to the directory where the cover spec file itself is stored\n\n Own Id: OTP-12498 Aux Id: OTP-11971\n\n- Some test cases have been updated to use ct:sleep/1 instead of timer:sleep/1.\n The reason being that the sleep times need to be scaled to compensate for slow\n execution (e.g. when cover is running).\n\n Own Id: OTP-12574","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Common Test now exports a function, ct:get_event_mgr_ref/0, that returns the\n name of the Common Test event manager. This makes it possible to plug in event\n handlers to the event manager while tests are running (using the gen_event\n API).\n\n Own Id: OTP-12506 Aux Id: seq12802\n\n- When a test case (or configuration function) fails because of an exit signal\n from a linked process, Common Test previously passed only the reason for\n process termination to the CT post hook functions and the event handlers (in\n the tc_done event). This has been changed so that now the tuple\n \\{'EXIT',ReasonForProcessTermination\\} is passed instead. This makes it much\n easier in the CT post hook functions to distinguish a failure of this sort\n from other types of errors and from the return value of a successful test\n case.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-12531 Aux Id: OTP-12279\n\n- A new feature has been introduced in ct_telnet:get_data/1 that makes it\n possible to automatically poll the telnet connection in case an incomplete\n string (one that has not yet been terminated by a newline) remains in the\n receive buffer. The polling is controlled by two new telnet config values,\n which are documented in the ct_telnet reference manual. The polling mechanism\n is disabled by default (making the get_data/1 function backwards compatible).\n\n Own Id: OTP-12627","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.9 - Common Test Release Notes","ref":"notes.html#common_test-1-9"},{"type":"extras","doc":"- The source code to html code generator in Test Server (and Common Test) would\n fail to generate anchors in the html code for functions with non-expandable\n macros, resulting in bad html links to such functions. This correction lets\n the code generator ignore macros that can't be expanded (i.e. not pre-process\n them), so that correct anchors will always be produced.\n\n Own Id: OTP-11766 Aux Id: seq12556\n\n- OTP-11971 erroneously changed the handling of relative paths (import/export\n files) specified in the cover spec file. This is now corrected so these are\n expected to be relative to the directory where the cover spec file itself is\n stored.\n\n Own Id: OTP-12031\n\n- Common Test would sometimes crash while trying to print large amounts of SASL\n reports to log on a computer with a slow file system. This problem (due to an\n error in IO message buffering in ct_logs) has been fixed.\n\n Own Id: OTP-12159\n\n- The common_test telnet client, ct_telnet and friends, had some unstable test\n cases. Some of these were caused by the unix_telnet callback sending an extra\n newline after sending the password. This caused the sever to send an extra\n prompt back which confused the tests. The extra newline is no longer sent.\n\n Also, debug printouts and logging from the telnet client is improved, and some\n test cases are slightly modified in order to stabilize the test.\n\n Own Id: OTP-12329\n\n- ct_netconfc did not expect the return value \\{error,timeout\\} from\n ssh_connection:subsystem/4. This has been corrected.\n\n Own Id: OTP-12334","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- A new option, `{newline,boolean()}` is added to all functions in `ct_telnet`\n that send data (command strings) to the telnet server. By default, `ct_telnet`\n adds a newline to all command strings, and by setting the new option to\n `false` this behavior is turned off.\n\n Own Id: OTP-12252 Aux Id: seq12730\n\n- Distribute `autoconf` helpers to applications at build time instead of having\n multiple identical copies committed in the repository.\n\n Own Id: OTP-12348","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.8.2 - Common Test Release Notes","ref":"notes.html#common_test-1-8-2"},{"type":"extras","doc":"- Ticket OTP-11971 introduced a runtime dependency towards test_server-3.7.1,\n since the interface between test_server and common_test was changed.\n Erroneously, the common_test.app file was not updated according to this. This\n has now been corrected.\n\n Own Id: OTP-12037","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Warning: this is experimental and may disappear or change without previous\n warning.\n\n Experimental support for running Quickcheck and PropEr tests from common_test\n suites is added to common_test. See the reference manual for the new module\n `ct_property_testing`.\n\n Experimental property tests are added under\n `lib/{inet,ssh}/test/property_test`. They can be run directly or from the\n commont_test suites `inet/ftp_property_test_SUITE.erl` and\n `ssh/test/ssh_property_test_SUITE.erl`.\n\n See the code in the `test` directories and the man page for details.\n\n (Thanks to Tuncer Ayaz for a patch adding Triq)\n\n Own Id: OTP-12119","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.8.1 - Common Test Release Notes","ref":"notes.html#common_test-1-8-1"},{"type":"extras","doc":"- Substrings in long telnet messages would sometimes get wrongly reversed. This\n error has been corrected.\n\n Own Id: OTP-11871 Aux Id: seq12581\n\n- The basic_html logging mode in Common Test (for compatibility with old\n browsers) generated HTML code with unbalanced tags. This has been fixed.\n\n Own Id: OTP-11917 Aux Id: seq12598\n\n- The mechanism for running code cover analysis with common_test has been\n improved. Earlier, if a test run consisted of multiple tests, cover would be\n started and stopped for each test. This would give \"intermediate\" cover logs\n available from the \"Coverage log\" link on the test suite result pages. To\n accumulate cover data over all tests, the 'export' option had to be used in\n the cover spec file. This was not well documented, and the functionality was\n quite confusing.\n\n Using the 'nodes' option in the cover spec file would fail when the test run\n consisted of multiple tests, since the specified nodes would only be included\n in the cover analysis of the first test.\n\n The repeated compilation and analysis of the same modules was also very time\n consuming.\n\n To overcome these problems, ct will now only cover compile and analyze modules\n once per test run, i.e. once for each cover spec file. The log file is\n available via a new button on the top level index page. The old \"Coverage log\"\n links on the test suite result pages still exist, but they all point to the\n same log containing the accumulated result.\n\n Own Id: OTP-11971\n\n- If multiple tests would run simultaneously on different Erlang nodes, writing\n their logs to the same directory, then there would often be entries in the\n all_runs.html log file showing incomplete results (all zeroes) upon\n completion. This problem was caused by a bug in the Common Test log cache\n mechanism, which has been fixed.\n\n Own Id: OTP-11988 Aux Id: seq12611","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.8 - Common Test Release Notes","ref":"notes.html#common_test-1-8"},{"type":"extras","doc":"- The error generated if a test case process received an exit from a linked\n process while executing init_per_testcase/2, was handled incorrectly by Common\n Test. The problem has been solved, and Common Test now reports this type of\n error correctly, with proper error reason and exit location as well.\n\n Own Id: OTP-11643\n\n- Running a parallel test case group with two or more instances of the same test\n case would result in identical log file names, and one test case instance\n would overwrite the log file of another. This problem has been solved.\n\n Own Id: OTP-11644\n\n- Application upgrade (appup) files are corrected for the following\n applications:\n\n `asn1, common_test, compiler, crypto, debugger, dialyzer, edoc, eldap, erl_docgen, et, eunit, gs, hipe, inets, observer, odbc, os_mon, otp_mibs, parsetools, percept, public_key, reltool, runtime_tools, ssh, syntax_tools, test_server, tools, typer, webtool, wx, xmerl`\n\n A new test utility for testing appup files is added to test_server. This is\n now used by most applications in OTP.\n\n (Thanks to Tobias Schlager)\n\n Own Id: OTP-11744\n\n- The `cth_surefire` hook would crash in `pre_init_per_suite/3` if a previous\n hook returned `{skip,Reason}` or `{fail,Reason}` instead of a `Config` list.\n This error has been corrected, and `cth_surefire` will now simply propagate\n the received `InitData` value instead.\n\n Own Id: OTP-11811\n\n- Specs of return values are corrected for `ct_netconfc:get/2,3`,\n `ct_netconfc:get_config/3,4`, `ct_netconfc:action/2,3`,\n `ct_netconfc:send_rpc/2,3` and `ct_netconfc:send/2,3`.\n\n Own Id: OTP-11834 Aux Id: seq12574","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- ct_telnet can now log all communication taking place during a telnet session.\n Previously, only information about ct_telnet operations and commands, as well\n as explicitly requested data from the server, was logged.\n\n Furthermore, a logging mechanism based on an Error Logger event handler and a\n dedicated Common Test hook, `cth_conn_log`, now makes it possible to print\n data for individual connections to separate log files. Please see the\n `ct_telnet` reference manual for more information and examples.\n\n Important note: A new argument, `ConnName` has been added to the\n `unix_telnet:connect/5` callback function. This forces users that use private\n ct_telnet callback modules to update their code according to\n `unix_telnet:connect/6`. Please see the `unix_telnet` reference manual and\n source code module for details.\n\n Own Id: OTP-11440 Aux Id: seq12457\n\n- A new timeout option has been introduced for the `ct_telnet:expect/3`\n function. With `{total_timeout,Time}` it's possible to set a time limit for\n the complete expect operation. After `Time` milliseconds, `expect/3` returns\n `{error,timeout}`. The default value used if `total_timeout` is not specified,\n is infinity (i.e. no time limit). Please see the `ct_telnet` reference manual\n for more information.\n\n Own Id: OTP-11689\n\n- Some function specs are corrected or moved and some edoc comments are\n corrected in order to allow use of edoc. (Thanks to Pierre Fenoll)\n\n Own Id: OTP-11702\n\n- Test case group name information has been added to the data sent with\n `tc_user_skip` and `tc_auto_skip` event messages, as well as the data passed\n in calls to the CT Hook functions `on_tc_skip/3` and `on_tc_fail/3`. The\n modification only affects the function name element/argument. This value\n remains an atom if the test case in question does not belong to a test case\n group. Otherwise a tuple `{FuncName,GroupName}` (`{atom(),atom()}`) is passed\n instead.\n\n Note that this change may (depending on the patterns used for matching)\n require modifications of user event handlers and hook modules. Please see the\n Event Handling chapter in the Common Test User's Guide, and the reference\n manual for `ct_hooks`, for details.\n\n Note also that the Test Server framework callback function `report/2` has been\n modified. This change only affects users with test frameworks interfacing Test\n Server rather than Common Test. See the `test_server_ctrl` reference manual\n for details.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-11732 Aux Id: seq12541\n\n- If Common Test can't prompt the user to abort or continue the test run when\n one or more test suites fail to compile, a new option,\n `{abort_if_missing_suites,Bool}`, can be used to specify whether it should\n proceed with the test run, or stop execution. The default value of `Bool` is\n `false` (i.e. to proceed even if suites are missing).\n\n Own Id: OTP-11769","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"- common_test: Fix problems reported by Dialyzer.\n\n Own Id: OTP-11525","title":"Known Bugs and Problems - Common Test Release Notes","ref":"notes.html#known-bugs-and-problems"},{"type":"extras","doc":"","title":"Common_Test 1.7.4 - Common Test Release Notes","ref":"notes.html#common_test-1-7-4"},{"type":"extras","doc":"- Return values from group and testcase info functions are now properly checked,\n and associated test cases are auto skipped if a return value is invalid.\n\n Own Id: OTP-10631 Aux Id: kunagi-345 \\[256]\n\n- The way Common Test handles skipping of test cases has been updated. In\n previous versions, returning `{skip,Reason}` from a configuration function\n (such as init_per_suite or init_per_group), resulted in all affected test\n cases getting skipped with status `auto_skipped`. This was inappropriate,\n since this status is supposed to be used to inform that Common Test has taken\n the initiative to skip something (e.g. a test case group if init_per_group\n failed). Therefore, in this version of Common Test, whenever the user skips a\n suite, group, or individual test case (by means of a configuration function or\n test specification term), the affected test cases get the status\n `user_skipped` instead.\n\n This update has meant a few changes that may affect Common Test users in\n various ways:\n\n - The test results and statistics will be affected, which is important to know\n when running regression tests and comparing results to previous test runs.\n - Users that read or parse the textual log file `suite.log` will notice that\n an auto skipped function is now reported as `auto_skipped` rather than\n `skipped` as before.\n - When `require` fails in an info function (such as suite/0 or group/1), all\n affected configuration functions and test cases are marked as\n `auto_skipped`.\n - If Common Test detects an error in the test suite (such as e.g. an invalid\n all/0 function), all affected configuration functions and test cases are\n marked as `auto_skipped`.\n - If a repeated test run session reaches a deadline with `force_stop` enabled,\n all remaining test cases are marked as `auto_skipped` rather than\n `user_skipped` as before.\n - The event messages that Common Test generates during test runs have been\n affected by this update. For details see OTP-11524.\n\n Own Id: OTP-11305 Aux Id: OTP-11524\n\n- Returning \\{skip, Reason\\} from a pre_end_per_group/3 user hook function would\n result in an exit in the Common Test cth_log_redirect hook. This problem has\n been solved.\n\n Own Id: OTP-11409 Aux Id: seq12446\n\n- When the netconf server did not respond to the close-session request, the call\n to ct_netconfc:close_session/2 would hang forever waiting for the netconf\n client to terminate. This has been corrected. The client will now always\n terminate (and take down the connection) if the close-session request times\n out.\n\n Own Id: OTP-11478","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Fix cth_log_redirect.erl to fulfill gen_event behaviour. Thanks to Roberto\n Aloi.\n\n Own Id: OTP-11401\n\n- The first argument of the CT hook callback function `on_tc_skip/3` has been\n modified. When this function is called for `init_per_group` or\n `end_per_group`, the value of the first argument is now\n `{init_per_group,GroupName}` or `{end_per_group,GroupName}`.\n\n Own Id: OTP-11523\n\n- The following modifications have been made to the event messages that Common\n Test sends during test execution:\n\n - For the `tc_auto_skip` event, the value of the `Func` element has changed\n from `end_per_group` to `{end_per_group,GroupName}`.\n - When `require` fails in an info function, such as suite/0 or group/1, the\n init configuration function is now reported as `auto_skipped` instead of\n `skipped`, with the `tc_done` event.\n - When `require` fails in an info function because of a configuration name\n already in use, the `tc_done` event now reports the error with a tuple (of\n size 2) tagged `failed` instead of `skipped`.\n\n Please see the Event Handling chapter in the Common Test User's Guide for\n reference.\n\n Own Id: OTP-11524 Aux Id: OTP-11305","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.7.3 - Common Test Release Notes","ref":"notes.html#common_test-1-7-3"},{"type":"extras","doc":"- Documentation is added for ct_netconfc:send and ct_netconfc:send_rpc.\n\n Own Id: OTP-11132\n\n- ct_netconfc:create_subscription only allowed one XML element inside the\n 'filter' element. According to RFC5277 it should be allowed to add any number\n of elements inside the filter, so this is now corrected.\n\n Own Id: OTP-11166\n\n- The error handler installed by the Common Test hook cth_log_redirect did not\n respond to init:stop/1/2. This has been corrected.\n\n Own Id: OTP-11175 Aux Id: seq12356\n\n- Calling ct:pal/2 or ct:print/2 when Common Test was not running, would cause\n an exit. This has been changed and the string is now simply printed to stdout\n instead.\n\n Own Id: OTP-11176\n\n- Fixed problem with the cth_log_redirect hook making calls to an undefined\n function in ct_logs.\n\n Own Id: OTP-11238\n\n- When running tests with the 'repeat' option, the Common Test utility process\n did not always terminate quickly enough after a test run, causing the start of\n the next run to fail. A monitor is now used to ensure termination of the\n utility process after each test run.\n\n Own Id: OTP-11244 Aux Id: seq12396\n\n- Test Server installed an error handler (test_server_h) only to be able to\n write the name of the current test case to stdout whenever it received an\n error- or progress report. This functionality was not useful and has been\n removed. The built-in Common Test hook, cth_log_redirect, has instead been\n improved to now also tag all error- and progress reports in the log with\n suite-, group-, and/or test case name.\n\n Own Id: OTP-11263 Aux Id: seq12251","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- A new log, the \"Pre- and Post Test I/O Log\", has been introduced, which makes\n it possible to capture error- and progress reports, as well as printouts made\n with ct:log/2 and ct:pal/2, before and after a test run. (Some minor\n improvements of the logging system have been made at the same time). Links to\n the new log are found on the Common Test Framework Log page. The Common Test\n User's Guide has been updated with information about the new log and also with\n a new section on how to synchronize external applications with Common Test by\n means of the CT Hook init and terminate functions.\n\n Own Id: OTP-11272","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.7.2 - Common Test Release Notes","ref":"notes.html#common_test-1-7-2"},{"type":"extras","doc":"- A design flaw in the generic connection handling in Common Test made it\n impossible to implement a connection handler that could map multiple\n connection names (i.e. configuration variable aliases) to single connection\n pids. This problem has been solved.\n\n Own Id: OTP-10126 Aux Id: kunagi-178 \\[89]\n\n- If a telnet connection is hanging, then a call to ct_telnet:close/1 will time\n out after 5 seconds and the connection process is brutally killed. In some\n cases the connection would not be unregistered and attempts at opening a new\n connection with the same name would make common_test try to reuse the same\n connection since it believed that it was still alive. This has been\n corrected - a killed connection is now always unregistered.\n\n Own Id: OTP-10648 Aux Id: seq12212\n\n- Test performance has been improved by means of a cache for the top level HTML\n index logs (all_runs.html and index.html, in the logdir directory). This\n solves problems with slow start up times and test execution times increasing\n with the number of ct_run directories stored in logdir. The cached index\n entries are stored in RAM during test execution and are saved to file in\n logdir (for faster start up times) whenever a test run finishes.\n\n Own Id: OTP-10855\n\n- Testing of the test specification functionality has been improved and a couple\n of minor bugs have been discovered and corrected.\n\n Own Id: OTP-10857\n\n- Links to the top level index files in some HTML footers had disappeared. This\n error has been corrected. Also, a problem with the suite overview log file not\n being closed properly has been solved.\n\n Own Id: OTP-11046\n\n- Common Test would, in case of timetrap error, print a warning in the log if\n end_per_testcase wasn't implemented in the suite, even though it's an optional\n function. This printout has been removed.\n\n Own Id: OTP-11052","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- If it could not be decided which test case a certain log printout belonged to,\n the common test framework log was earlier used. Such printouts are now instead\n sent to unexpected_io.log.html in test_server so that there is only one place\n to look for \"missing\" printouts.\n\n Own Id: OTP-10494 Aux Id: kunagi-319 \\[230]\n\n- Make cover smarter about finding source from beam.\n\n In particular, search using the source path in module_info if the current\n heuristic fails.\n\n Own Id: OTP-10902\n\n- Add a variant of ct_slave:start/2 that starts a node with specified options on\n the local host.\n\n Own Id: OTP-10920\n\n- Integrate elliptic curve contribution from Andreas Schultz\n\n In order to be able to support elliptic curve cipher suites in SSL/TLS,\n additions to handle elliptic curve infrastructure has been added to public_key\n and crypto.\n\n This also has resulted in a rewrite of the crypto API to gain consistency and\n remove unnecessary overhead. All OTP applications using crypto has been\n updated to use the new API.\n\n Impact: Elliptic curve cryptography (ECC) offers equivalent security with\n smaller key sizes than other public key algorithms. Smaller key sizes result\n in savings for power, memory, bandwidth, and computational cost that make ECC\n especially attractive for constrained environments.\n\n Own Id: OTP-11009\n\n- Postscript files no longer needed for the generation of PDF files have been\n removed.\n\n Own Id: OTP-11016\n\n- A link is added from the red error printout in a test case log (for a failed\n test case) to the full error description at the end of the log. The reason for\n this is that the error description in the red field is sometimes truncated at\n 50 characters in order to keep the log as short and easy to read as possible.\n\n Own Id: OTP-11044 Aux Id: seq12304\n\n- A new option 'no_prompt_check' is added to ct_telnet:expect/3. If this option\n is used, ct_telnet will not wait for a prompt or a newline before attempting\n to match the given pattern.\n\n Own Id: OTP-11095","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.7.1 - Common Test Release Notes","ref":"notes.html#common_test-1-7-1"},{"type":"extras","doc":"- If an event handler installed in the CT Master event manager took too long to\n respond during the termination phase, CT Master crashed because of a timeout\n after 5 secs. This would leave the system in a bad state. The problem has been\n solved by means of a 30 min timeout value and if CT Master gets a timeout\n after that time, it now kills the event manager and shuts down properly.\n\n Own Id: OTP-10634 Aux Id: kunagi-347 \\[258]\n\n- Printing with any of the ct printout functions from an event handler installed\n by Common Test, would cause a deadlock. This problem has been solved.\n\n Own Id: OTP-10826 Aux Id: seq12250\n\n- Using the force_stop flag/option to interrupt a test run caused a crash in\n Common Test. This problem has been solved.\n\n Own Id: OTP-10832","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Removed deprecated run_test program, use ct_run instead.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-9052","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"- Test case execution time increases with size of test run.\n\n Own Id: OTP-10855","title":"Known Bugs and Problems - Common Test Release Notes","ref":"notes.html#known-bugs-and-problems"},{"type":"extras","doc":"","title":"Common_Test 1.7 - Common Test Release Notes","ref":"notes.html#common_test-1-7"},{"type":"extras","doc":"- Severe errors detected by `test_server` (e.g. if log files directories cannot\n be created) will now be reported to `common_test` and noted in the\n `common_test` logs.\n\n Own Id: OTP-9769 Aux Id: kunagi-202 \\[113]\n\n- The earlier undocumented cross cover feature for accumulating cover data over\n multiple tests has now been fixed and documented.\n\n Own Id: OTP-9870 Aux Id: kunagi-206 \\[117]\n\n- If a busy test case generated lots of error messages,\n cth_log_redirect:post_end_per_testcase would crash with a timeout while\n waiting for the error logger to finish handling all error reports. The default\n timer was 5 seconds. This has now been extended to 5 minutes.\n\n Own Id: OTP-10040 Aux Id: kunagi-173 \\[84]\n\n- When a test case failed because of a timetrap time out, the `Config` data for\n the case was lost in the following call to `end_per_testcase/2`, and also in\n calls to the CT Hook function `post_end_per_testcase/4`. This problem has been\n solved and the `Config` data is now correctly passed to the above functions\n after a timetrap timeout failure.\n\n Own Id: OTP-10070 Aux Id: kunagi-175 \\[86]\n\n- Some calls to deprecated and removed functions in snmp are removed from\n ct_snmp.\n\n Own Id: OTP-10088 Aux Id: kunagi-176 \\[87]\n\n- In test_server, the same process would supervise the currently running test\n case and be group leader (and IO server) for the test case. Furthermore, when\n running parallel test cases, new temporary supervisor/group leader processes\n were spawned and the process that was group leader for sequential test cases\n would not be active. That would lead to several problems:\n\n \\* Processes started by init_per_suite will inherit the group leader of the\n init_per_suite process (and that group leader would not process IO requests\n when parallel test cases was running). If later a parallel test case caused\n such a processto print using (for example) io:format/2, the calling would\n hang.\n\n \\* Similarly, if a process was spawned from a parallel test case, it would\n inherit the temporary group leader for that parallel test case. If that\n spawned process later - when the group of parallel tests have finished -\n attempted to print something, its group leader would be dead and there would\n be `badarg` exception.\n\n Those problems have been solved by having group leaders separate from the\n processes that supervises the test cases, and keeping temporary group leader\n process for parallel test cases alive until no more process in the system use\n them as group leaders.\n\n Also, a new `unexpected_io.log` log file (reachable from the summary page of\n each test suite) has been introduced. All unexpected IO will be printed into\n it(for example, IO to a group leader for a parallel test case that has\n finished).\n\n Own Id: OTP-10101 Aux Id: OTP-10125\n\n- Some bugfixes in `ct_snmp:`\n\n - ct_snmp will now use the value of the 'agent_vsns' config variable when\n setting the 'variables' parameter to snmp application agent configuration.\n Earlier this had to be done separately - i.e. the supported versions had to\n be specified twice.\n - Snmp application failed to write notify.conf since ct_snmp gave the notify\n type as a string instead of an atom. This has been corrected.\n\n Own Id: OTP-10432\n\n- Some bugfixes in `ct_snmp`:\n\n - Functions `register_users/2`, `register_agents/2` and\n `register_usm_users/2`, and the corresponding `unregister_*/1` functions\n were not executable. These are corrected/rewritten.\n - Function `update_usm_users/2` is removed, and an unregister function is\n added instead. Update can now be done with unregister_usm_users and then\n register_usm_users.\n - Functions `unregister_*/2` are added, so specific users/agents/usm users can\n be unregistered.\n - Function `unload_mibs/1` is added for completeness.\n - Overriding configuration files did not work, since the files were written in\n priv_dir instead of in the configuration dir (priv_dir/conf). This has been\n corrected.\n - Arguments to `register_usm_users/2` were faulty documented. This has been\n corrected.\n\n Own Id: OTP-10434 Aux Id: kunagi-264 \\[175]\n\n- Faulty exported specs in common test has been corrected to\n `ct_netconfc:hook_options/0` and [`inet:hostname/0`](`t:inet:hostname/0`)\n\n Own Id: OTP-10601\n\n- The netconf client in common_test did not adjust the window after receiving\n data. Due to this, the client stopped receiving data after a while. This has\n been corrected.\n\n Own Id: OTP-10646","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- It is now possible to let a test specification include other test\n specifications. Included specs can either be joined with the source spec (and\n all other joined specs), resulting in one single test run, or they can be\n executed in separate test runs. Also, a start flag/option, `join_specs`, has\n been introduced, to be used in combination with the `spec` option. With\n `join_specs`, Common Test can be told to either join multiple test\n specifications, or run them separately. Without `join_specs`, the latter\n behaviour is default. Note that this is a change compared to earlier versions\n of Common Test, where specifications could only be joined. More information\n can be found in the Running Tests chapter in the User's Guide (see the Test\n Specifications section).\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-9881 Aux Id: kunagi-350 \\[261]\n\n- The `ct_slave:start/3` function now supports an `{env,[{Var,Value}]}` option\n to extend environment for the slave node.\n\n Own Id: OTP-10469 Aux Id: kunagi-317 \\[228]\n\n- Some examples overflowing the width of PDF pages have been corrected.\n\n Own Id: OTP-10665\n\n- Update common test modules to handle unicode:\n\n - Use UTF-8 encoding for all HTML files, except the HTML version of the test\n suite generated with erl2html2:convert, which will have the same encoding as\n the original test suite (.erl) file.\n - Encode link targets in HTML files with test_server_ctrl:uri_encode/1.\n - Use unicode modifier 't' with ~s when appropriate.\n - Use unicode:characters_to_list and unicode:characters_to_binary for\n conversion between binaries and strings instead of binary_to_list and\n list_to_binary.\n\n Own Id: OTP-10783","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"- CT drops error reason when groups/0 crashes.\n\n Own Id: OTP-10631 Aux Id: kunagi-345 \\[256]\n\n- Event handler on a ct_master node causes hanging.\n\n Own Id: OTP-10634 Aux Id: kunagi-347 \\[258]\n\n- CT fails to open telnet conn after a timetrap timeout.\n\n Own Id: OTP-10648 Aux Id: seq12212","title":"Known Bugs and Problems - Common Test Release Notes","ref":"notes.html#known-bugs-and-problems"},{"type":"extras","doc":"","title":"Common_Test 1.6.3.1 - Common Test Release Notes","ref":"notes.html#common_test-1-6-3-1"},{"type":"extras","doc":"- The following corrections/changes are done in the cth_surefire hook:\n\n - Earlier there would always be a 'properties' element under the 'testsuites'\n element. This would exist even if there were no 'property' element inside\n it. This has been changed so if there are no 'property' elements to display,\n then there will not be a 'properties' element either.\n - The XML file will now (unless other is specified) be stored in the top log\n directory. Earlier, the default directory would be the current working\n directory for the erlang node, which would mostly, but not always, be the\n top log directory.\n - The 'hostname' attribute in the 'testsuite' element would earlier never have\n the correct value. This has been corrected.\n - The 'errors' attribute in the 'testsuite' element would earlier display the\n number of failed testcases. This has been changed and will now always have\n the value 0, while the 'failures' attribute will show the number of failed\n testcases.\n - A new attribute 'skipped' is added to the 'testsuite' element. This will\n display the number of skipped testcases. These would earlier be included in\n the number of failed test cases.\n - The total number of tests displayed by the 'tests' attribute in the\n 'testsuite' element would earlier include init/end_per_suite and\n init/end_per_group. This is no longer the case. The 'tests' attribute will\n now only count \"real\" test cases.\n - Earlier, auto skipped test cases would have no value in the 'log' attribute.\n This is now corrected.\n - A new attributes 'log' is added to the 'testsuite' element.\n - A new option named 'url_base' is added for this hook. If this option is\n used, a new attribute named 'url' will be added to the 'testcase' and\n 'testsuite' elements.\n\n Own Id: OTP-10589","title":"Known Bugs and Problems - Common Test Release Notes","ref":"notes.html#known-bugs-and-problems"},{"type":"extras","doc":"","title":"Common_Test 1.6.3 - Common Test Release Notes","ref":"notes.html#common_test-1-6-3"},{"type":"extras","doc":"- The ct:run_test/1 option 'config' only worked with a single config file, not a\n list of files. This has been fixed.\n\n Own Id: OTP-10495\n\n- ct_netconfc:close_session sometimes returned \\{error,closed\\} because the ssh\n connection was closed (from the server side) before the rpc-reply was received\n by the client. This is normal and cannot be helped. It has been corrected so\n the return will be 'ok' in this case. Other error situations will still give\n \\{error,Reason\\}.\n\n Own Id: OTP-10510 Aux Id: kunagi-320 \\[231]\n\n- ct_netconfc:close_session sometimes returned \\{error,closed\\} or (if the\n connection was named) \\{error,\\{process_down,Pid,normal\\}\\} because the ssh\n connection was closed (from the server side) before the rpc-reply was received\n by the client. This is normal and cannot be helped. It has been corrected so\n the return will be 'ok' in this situation.\n\n Own Id: OTP-10570\n\n- Fix bug where ct:require of same name with same config would return\n name_in_use.\n\n Own Id: OTP-10572","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- A new test case group search functionality has been implemented that makes\n Common Test search automatically through the group definitions tree (the\n return value of groups/0) and create tests for all paths of nested groups that\n match the specification. It also allows for specifying unique paths to sub\n groups in order to avoid execution of unwanted tests. This new feature can be\n used whenever starting a test run by means of the ct_run program, the\n ct:run_test/1 API function, or a Test Specification. Details can be found in\n the Test Case Group Execution section in the Running Tests chapter.\n\n Own Id: OTP-10466 Aux Id: kunagi-276 \\[187]","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"- Restore Config data if lost when test case fails.\n\n Own Id: OTP-10070 Aux Id: kunagi-175 \\[86]\n\n- IO server error in test_server.\n\n Own Id: OTP-10125 Aux Id: OTP-10101, kunagi-177 \\[88]\n\n- Faulty connection handling in common_test.\n\n Own Id: OTP-10126 Aux Id: kunagi-178 \\[89]","title":"Known Bugs and Problems - Common Test Release Notes","ref":"notes.html#known-bugs-and-problems"},{"type":"extras","doc":"","title":"Common_Test 1.6.2.1 - Common Test Release Notes","ref":"notes.html#common_test-1-6-2-1"},{"type":"extras","doc":"- The interactive mode (ct_run -shell) would not start properly. This error has\n been fixed.\n\n Own Id: OTP-10414","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Common_Test 1.6.2 - Common Test Release Notes","ref":"notes.html#common_test-1-6-2"},{"type":"extras","doc":"- If a CT hook function caused a crash, this could in some situations cause\n Common Test to terminate due to an illegal IO operation. This error has been\n corrected.\n\n Own Id: OTP-10050 Aux Id: seq12039\n\n- The Common Test documentation states that timetraps are never active during\n execution of CT hook functions. This was only true for post hook functions,\n not for pre hook functions. The code for CT hooks has been modified to behave\n according to the documentation.\n\n Own Id: OTP-10069\n\n- If a CT hook function would call the exit/1 or throw/1 BIF (possibly\n indirectly, e.g. as a result of a timeout in gen_server:call/3), Common Test\n would hang. This problem has been fixed.\n\n Own Id: OTP-10072 Aux Id: seq12053\n\n- The documentation has been updated with information about how to deal with\n chaining of hooks which return fail/skip.\n\n Own Id: OTP-10077 Aux Id: seq12048\n\n- When ct_hooks called the id/1 functions of multiple hooks, it would reverse\n the order of the hooks and call the proceeding init/2 calls in the wrong\n order. This has been fixed.\n\n Own Id: OTP-10135\n\n- The surefire hook now correctly handles autoskipped initialization and test\n functions.\n\n Own Id: OTP-10158\n\n- The ct:get_status/0 function failed to report status if a parallel test case\n group was running at the time of the call. This has been fixed and the return\n value for the function has been updated. Please see the ct reference manual\n for details.\n\n Own Id: OTP-10172","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The support for \"silent connections\" has been updated to include ssh. Also, a\n silent_connections term has been added to the set of test specification terms.\n\n Own Id: OTP-9625 Aux Id: seq11918\n\n- It is now possible to specify an arbitrarily large tuple as the requires\n config data when using require and ct:get_config. See the ct:get_config and\n ct:require reference manual pages for details about which keys are allowed.\n\n This change introduces a backwards incompatibility in the `ct:require/2`\n interface. Previously when doing `ct:require(a_name,{key,subkey})`, a_name\n would be associated with key. This has been changed to that `a_name` is\n associated with `subkey`. This change also effects using `require` in an\n suite/group/testcase info function.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-9626 Aux Id: seq11920\n\n- The ct_run program now sets the OS process exit status before it ends. Value 0\n indicates a successful test result, 1 indicates one or more failed or\n auto-skipped test cases, and 2 indicates test execution failure.\n\n Own Id: OTP-9865 Aux Id: OTP-10087\n\n- It is now possible to sort the HTML tables by clicking on the header elements.\n In order to reset a sorted table, the browser window should simply be\n refreshed. This feature requires that the browser supports javascript, and has\n javascript execution enabled. If the 'ct_run -basic_html' flag is used, no\n javascript code is included in the generated HTML code.\n\n Own Id: OTP-9896 Aux Id: seq12034, OTP-9835\n\n- A netconf client, ct_netconfc, is added to common_test. It supports basic\n netconf functionality over SSH. In order to allow testing of both success and\n failure cases, it is intentionally written to allow non-standard behavior.\n\n Own Id: OTP-10025\n\n- The test specification term \\{define,Constant,Value\\} has been introduced,\n which makes it possible to replace constant names (atom()) with values\n (term()) in arbitrary test specification terms. The 'define' makes the (now\n deprecated) 'alias' term obsolete. More details, including examples, can be\n found in the Test Specifications chapter in the Common Test User's Guide.\n\n Own Id: OTP-10049\n\n- Verbosity levels for log printouts has been added. This makes it possible to\n specify preferred verbosity for different categories of log printouts, as well\n as general printouts (such as standard IO), to allow control over which\n strings get printed and which get ignored. New versions of the Common Test\n logging functions, ct:log, ct:pal and ct:print, have been introduced, with a\n new Importance argument added. The Importance value is compared to the\n verbosity level at runtime. More information can be found in the chapter about\n Logging in the Common Test User's Guide.\n\n Own Id: OTP-10067 Aux Id: seq12050\n\n- The return values of ct:run_test/1 and ct:run_testspec/1 have been changed\n from an uninformative 'ok' (independent of the test outcome) to a value,\n \\{Ok,Failed,\\{UserSkipped,AutoSkipped\\}\\} (all integers), that presents the\n final test case result, or a value, \\{error,Reason\\}, that informs about fatal\n test execution failure. See details in the reference manual for ct.\n\n Own Id: OTP-10087 Aux Id: OTP-9865\n\n- The test specification syntax has been updated with new and missing terms,\n such as 'define', 'verbosity', 'auto_compile', 'stylesheet',\n 'silent_connections', 'basic_html' and 'release_shell'. See the Test\n Specification chapter in the Common Test User's Guide for details.\n\n Own Id: OTP-10089 Aux Id: OTP-10049\n\n- It is now possible to pause execution of a test case, by calling the\n ct:break/1/2 function. Execution is resumed with a call to ct:continue/0/1.\n Break/continue also works for test cases executing in parallel. See the ct\n reference manual for details.\n\n Own Id: OTP-10127\n\n- It is now possible to send user defined events from a testcase which will be\n picked up by the installed event handler.\n\n Own Id: OTP-10157\n\n- A new start option, release_shell, for ct:run_test/1, has been added, which\n makes Common Test release the shell process after the test suite compilation\n phase is finished. For details, see the Running Tests chapter in the User's\n Guide.\n\n Own Id: OTP-10248 Aux Id: OTP-10127","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.6.1 - Common Test Release Notes","ref":"notes.html#common_test-1-6-1"},{"type":"extras","doc":"- Common Test adds the test suite directories to the code path before executing\n the tests. These directories should also be removed from the code path at the\n end of the test run, which, prior to this fix, was not performed.\n\n Own Id: OTP-9595\n\n- An entry is now created in the index.html file (i.e. the overview file for the\n test run) for each repeated test during a test run. This was previously not\n the case. Note that in the top level (logdir) index file, however, only the\n last test result is listed. For example, given the test spec:\n \\[\\{merge_tests,false\\},\\{dirs,\"test1\"\\},\\{dirs,\"test1\"\\}]. In the index file\n for the test run (under Logdir/ct_run.Node.Date.Time), both tests are listed.\n In the top level index file (under Logdir), only the last test is listed (one\n has to find the previous results through the all_runs.html file).\n\n Own Id: OTP-9634 Aux Id: seq11924\n\n- After a test case timeout or abortion, the end_per_testcase function executes\n on a new dedicated process. The group leader for this process should be set to\n the IO server for the test case, which was not done properly. The result of\n this error was that no warnings about end_per_testcase failing or timing out\n were ever printed in the test case log. Also, help functions such as e.g.\n test_server:stop_node/1, attempting to synchronize with the IO server, would\n hang. The fault has been corrected.\n\n Own Id: OTP-9666\n\n- The ct:get_status/0 function would cause the calling process to receive 'DOWN'\n messages if no tests were running at the time of the call. This bug has been\n fixed.\n\n Own Id: OTP-9830 Aux Id: seq11975\n\n- A deadlock situation could occur if Common Test is forwarding error_handler\n printouts to Test Server at the same time a new test case is starting. This\n error has been fixed.\n\n Own Id: OTP-9894\n\n- A link to the ct_run program is now created, as expected, in the installation\n bin directory (default /usr/local/bin) during 'make install'.\n\n Own Id: OTP-9898\n\n- Using the repeat, duration or until option with ct:run_test/1, would cause an\n infinite loop. This has been fixed.\n\n Own Id: OTP-9899\n\n- Two or more test cases executing in parallel and printing to screen at the\n same time with ct:pal/2/3 or ct:print/2/3 could write into each other's\n \"slots\" and create a mess of mixed strings. In order to avoid this, only a\n single IO message is now ever sent per printout call.\n\n Own Id: OTP-9900 Aux Id: OTP-9904\n\n- When a test case was killed because of a timetrap timeout, the current\n location (suite, case and line) was not printed correctly in the log files.\n This has been corrected.\n\n Own Id: OTP-9930 Aux Id: seq12002\n\n- The wrong exit location was printed in the log file when ct:fail/1 or\n ct_fail/2 was called.\n\n Own Id: OTP-9933 Aux Id: seq12002\n\n- Test Server and Common Test would add new error handlers with each test run\n and fail to remove previously added ones. In the case of Test Server, this\n would only happen if SASL was not running on the test node. This has been\n fixed.\n\n Own Id: OTP-9941 Aux Id: seq12009\n\n- If a test case process was terminated due to an exit signal from a linked\n process, Test Server failed to report the correct name of the suite and case\n to the framework. This has been corrected.\n\n Own Id: OTP-9958 Aux Id: OTP-9855\n\n- When starting a test with ct_run and adding a directory to the code path using\n -pa or -pz (preceding -erl_args), Common Test would delete any existing\n directory in the code path with the same base name (see filename:basename/1)\n as the directory being added. This has been fixed.\n\n Own Id: OTP-9964\n\n- If passing two or more directories with the same base name (see\n filename:basename/1) to Common Test with ct_run -pa, only one of the\n directories would actually be added.\n\n Own Id: OTP-9975 Aux Id: seq12019\n\n- Configuration data required by the group info function was deleted before the\n call to post_end_per_group, which made it impossible for the hook function to\n read and use the data in question. This has been fixed.\n\n Own Id: OTP-9989\n\n- Disabling built-in hooks in a test specification was ignored, this has now\n been fixed.\n\n Own Id: OTP-10009\n\n- Various typographical errors corrected in documentation for common_test,\n driver, erl_driver and windows installation instructions. (Thanks to Tuncer\n Ayaz)\n\n Own Id: OTP-10037","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- A new optional feature has been introduced that enables Common Test to\n generate priv_dir directory names that are unique for each test case or config\n function. The name of the option/flag is 'create_priv_dir' and it can be set\n to value 'auto_per_run' (which is the default, existing, behaviour), or\n 'auto_per_tc' or 'manual_per_tc'. If 'auto_per_tc' is used, Test Server\n creates a dedicated priv_dir automatically for each test case (which can be\n very expensive in case of many and/or repeated cases). If 'manual_per_tc' is\n used, the user needs to create the priv_dir explicitly by calling the new\n function ct:make_priv_dir/0.\n\n Own Id: OTP-9659 Aux Id: seq11930\n\n- A column for test case group name has been added to the suite overview HTML\n log file.\n\n Own Id: OTP-9730 Aux Id: seq11952\n\n- It is now possible to use the post_end_per_testcase CT hook function to print\n a comment for a test case in the overview log file, even if the test case gets\n killed by a timetrap or unknown exit signal, or if the end_per_testcase\n function times out.\n\n Own Id: OTP-9855 Aux Id: seq11979\n\n- The pre- and post CT hook functions are now always called for all\n configuration functions, even for configuration functions that are not\n implemented in the test suite.\n\n Own Id: OTP-9880 Aux Id: seq11993\n\n- Common Test will now print error information (with a time stamp) in the test\n case log file immediately when a test case fails. This makes it easier to see\n when, in time, the fault actually occurred, and aid the job of locating\n relevant trace and debug printouts in the log.\n\n Own Id: OTP-9904 Aux Id: seq11985, OTP-9900\n\n- Test Server has been modified to check the SASL errlog_type parameter when\n receiving an error logger event, so that it doesn't print reports of type that\n the user has disabled.\n\n Own Id: OTP-9955 Aux Id: seq12013\n\n- The test specification term 'skip_groups' was implemented in Common Test v1.6.\n It was never documented however, which has now been attended to. Please see\n the Test Specifications chapter in the User's Guide for information.\n\n Own Id: OTP-9972\n\n- The Common Test Master has been updated to use a CSS style sheet for the html\n log files.\n\n Own Id: OTP-9973\n\n- If the init_per_group/2 and end_per_group/2 functions are not implemented in\n the test suite, Common Test calls it's own local init- and end functions -\n previously named ct_init_per_group/2 and ct_end_per_group/2 - when a group is\n executed. These functions have been renamed init_per_group/2 and\n end_per_group/2 respectively. Note that this may affect any user event handler\n identifying events by the old names.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-9986 Aux Id: OTP-9992\n\n- By specifying a user defined function (\\{M,F,A\\} or fun) as timetrap value,\n either by means of an info function or by calling ct:timetrap/1, it is now\n possible to set a timetrap that will be triggered when the user function\n returns.\n\n Own Id: OTP-9988 Aux Id: OTP-9501, seq11894\n\n- If the optional configuration functions init_per_suite/1 and end_per_suite/1\n are not implemented in the test suite, local Common Test versions of these\n functions are called instead, and will be displayed in the overview log file.\n Any printouts made by the pre- or post_init_per_suite and pre- or\n post_end_per_suite hook functions are saved in the log files for these\n functions.\n\n Own Id: OTP-9992\n\n- A hook has been added to common test which outputs surefire XML for usage\n together with CI tools such as Jenkins. To enable the hook pass '-ct_hooks\n cth_surefire' to ct_run. See the CTH documentation for more details.\n\n Own Id: OTP-9995","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.6 - Common Test Release Notes","ref":"notes.html#common_test-1-6"},{"type":"extras","doc":"- A Getting Started chapter has been added to the Common Test User's Guide.\n\n Own Id: OTP-9156\n\n- The test case group info function has been implemented in Common Test. Before\n execution of a test case group, a call is now made to\n `TestSuite:group(GroupName)`. The function returns a list of test properties,\n e.g. to specify timetrap values, require configuration data, etc (analogue to\n the test suite- and test case info function). The scope of the properties set\n by `group(GroupName)` is all test cases and sub-groups of group `GroupName`.\n\n Own Id: OTP-9235\n\n- Common Test hooks are now in a final supported version. The Common Test hooks\n allow you to abstract out initialization behaviour that is common to multiple\n test suites into one place and also extend the behaviour of a suite without\n changing the suite itself. For more information see the Common Test user's\n guide.\n\n Own Id: OTP-9449\n\n- A new built-in common test hook has been added which captures error_logger and\n SASL event and prints them in the testcase log. To disable this (and any other\n built-in hooks) pass 'enable_builtin_hooks false' to common test.\n\n Own Id: OTP-9543\n\n- Common Test now calls info functions also for the `init/end_per_suite/1` and\n `init/end_per_group/2` configuration functions. These can be used e.g. to set\n timetraps and require external configuration data relevant only for the\n configuration functions in question (without affecting properties set for\n groups and test cases in the suite). The info function for\n `init/end_per_suite(Config)` is `init/end_per_suite()`, and for\n `init/end_per_group(GroupName,Config)` it's `init/end_per_group(GroupName)`.\n Info functions cannot be used with `init/end_per_testcase(TestCase, Config)`,\n since these configuration functions execute on the test case process and will\n use the same properties as the test case (i.e. properties set by the test case\n info function, `TestCase()`).\n\n Own Id: OTP-9569\n\n- It's now possible to read the full name of the test case log file during\n execution. One way to do this is to lookup it up as value of the key\n `tc_logfile` in the test case `Config` list (which means it can also be read\n by a pre- or post Common Test hook function). The data is also sent with the\n event `#event{name=tc_logfile,data={{Suite,Func},LogFileName}}`, and can be\n read by any installed event handler.\n\n Own Id: OTP-9676 Aux Id: seq11941\n\n- The look of the HTML log files generated by Common Test and Test Server has\n been improved (and made easier to customize) by means of a CSS file.\n\n Own Id: OTP-9706\n\n- Functions ct:fail(Format, Args) and ct:comment(Format, Args) have been added\n in order to make printouts of formatted error and comment strings easier (no\n need for the user to call io_lib:format/2 explicitly).\n\n Own Id: OTP-9709 Aux Id: seq11951\n\n- The order in which ct hooks are executed for cleanup hooks (i.e. _*end_per*_\n hooks) has been reversed.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-9774 Aux Id: seq11913\n\n- Printouts to stdout may be captured during test case execution. This is useful\n in order to e.g. read and parse tty printouts from the SUT during test case\n execution (if necessary, say, to determine the outcome of the test). The\n capturing session is started with `ct:capture_start/0`, and stopped with\n `ct:capture_stop/0`. The list of buffered strings is read and purged with\n `ct:capture_get/0/1`. It's possible to filter out printouts made with\n `ct:log/2/3` and `ct:pal/2/3` from the captured list of strings. This is done\n by calling `capture_get/1` with a list of log categories to exclude.\n\n Own Id: OTP-9775\n\n- The syntax for specifying test case groups in the all/0 list has been extended\n to include execution properties for both groups and sub-groups. The properties\n specified in all/0 for a group overrides the properties specified in the group\n declaration (in groups/0). The main purpose of this extension is to make it\n possible to run the same set of tests, but with different properties, without\n having to declare copies of the group in question. Also, the same syntax may\n be used in test specifications in order to change properties of groups at the\n time of execution, without having to edit the test suite. Please see the\n User's Guide for details and examples.\n\n Own Id: OTP-9809 Aux Id: OTP-9235","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"- Fix problems in CT/TS due to line numbers in exceptions.\n\n Own Id: OTP-9203","title":"Known Bugs and Problems - Common Test Release Notes","ref":"notes.html#known-bugs-and-problems"},{"type":"extras","doc":"","title":"Common_Test 1.5.5 - Common Test Release Notes","ref":"notes.html#common_test-1-5-5"},{"type":"extras","doc":"- An error in how comments are colored in the test suite overview html log file\n has been corrected. As result, a new framework callback function,\n format_comment/1, has been introduced.\n\n Own Id: OTP-9237\n\n- Automatically generated init- and end-configuration functions for test case\n groups caused incorrect execution order of test cases. This has been\n corrected.\n\n Own Id: OTP-9369\n\n- If multiple directories were specified with the 'logdir' flag/option, Common\n Test would crash. This has been fixed so that an error is properly reported\n instead.\n\n Own Id: OTP-9370\n\n- If ct:log/2 was called with bad arguments, this could cause the Common Test IO\n handling process to crash. This fault has been corrected.\n\n Own Id: OTP-9371 Aux Id: OTP-8933\n\n- A bug has been fixed that made Test Server call the end_tc/3 framework\n function with an incorrect module name as first argument.\n\n Own Id: OTP-9379 Aux Id: seq11863\n\n- If a timetrap timeout occurred during execution of a function in a lib module\n (i.e. a function called directly or indirectly from a test case), the Suite\n argument in the end_tc/3 framework callback function would not correctly\n contain the name of the test suite, but the lib module. (This would only\n happen if the lib module was compiled with ct.hrl included). This error has\n been solved.\n\n Own Id: OTP-9398\n\n- Corrections of the vts mode. It will now report errors (about e.g. incorrect\n config files) instead of crashing or hanging. Furthermore, the requirement\n that the test directory name must have a \"\\_test\" suffix has been removed.\n Also, a workaround has been implemented for the limitation that the file\n browser (in many web browsers) will only return the basic file name, not the\n full directory path (which made it impossible to have config files in other\n directories than the main test directory).\n\n Own Id: OTP-9429\n\n- Add a proplist() type\n\n Recently I was adding specs to an API and found that there is no canonical\n proplist() type defined. (Thanks to Ryan Zezeski)\n\n Own Id: OTP-9499\n\n- It is now possible to use the 'step' flag/option to run the debugger for test\n suites that contain test case groups. This previously caused Common Test to\n crash. If 'step config' is specified, breakpoints are now also automatically\n set on init_per_group and end_per_group. Note that breakpoints are always set\n automatically on test case functions and this is true also for grouped cases.\n\n Own Id: OTP-9518 Aux Id: OTP-8933\n\n- The test index page was not refreshed at the start of each test suite which\n made it impossible to follow test execution by means of refreshing the browser\n window (no links to follow). This has been fixed.\n\n Own Id: OTP-9520 Aux Id: OTP-8933\n\n- If a test suite would start with a test case group defined without the\n init_per_group/2 and end_per_group/2 function, init_per_suite/1 would not\n execute initially and logging of the test run would fail. This error has been\n fixed.\n\n Own Id: OTP-9584\n\n- The \"Missing Suites\" link from the top level index page was incorrect and has\n been fixed.\n\n Own Id: OTP-9592","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Various corrections and updates to improve the handling and reporting of\n errors.\n\n Own Id: OTP-8933\n\n- The dir and suite start option can now be used in combination. E.g. executing\n my_SUITE in directory my_tests can either be specified as \"ct_run -suite\n my_tests/my_SUITE\" or as \"ct_run -dir my_tests -suite my_SUITE\". Furthermore,\n the specification: ct:run_test(\\[\\{suite,[\"./my_SUITE\"]\\},\\{testcase,t1\\}]) is\n now interpreted as ct:run_test(\\[\\{suite,\"./my_SUITE\"\\},\\{testcase,t1\\}]),\n i.e. only testcase t1 in test suite my_SUITE - not all cases - will be\n executed.\n\n Own Id: OTP-9155\n\n- A new option, 'logopts', has been introduced, to make it possible to modify\n some aspects of the logging behaviour in Common Test (or Test Server). For\n example, whenever an io printout is made, test_server adds newline (\\\\n) to\n the end of the output string. This may not always be a preferred action and\n can therefore be disabled by means of \"ct_run ... -logopts no_nl\" (or\n ct:run_test(\\[..., \\{logopts,[no_nl]\\}])). A new framework callback function,\n get_logopts/0, has been introduced (see the ct_framework module for details).\n\n Own Id: OTP-9372 Aux Id: OTP-9396\n\n- A new option, 'logopts', has been introduced, to make it possible to modify\n some aspects of the logging behaviour in Common Test (or Test Server). For\n example, if the html version of the test suite source code should not be\n generated during the test run (and consequently be unavailable in the log file\n system), the feature may be disabled by means of \"ct_run ... -logopts no_src\"\n (or ct:run_test(\\[..., \\{logopts,[no_src]\\}])). A new framework callback\n function, get_logopts/0, has been introduced (see the ct_framework module for\n details).\n\n Own Id: OTP-9396 Aux Id: seq11869, OTP-9372\n\n- CT Hooks can now be assigned a priority. The priority of a CTH determines when\n it should execute in relation to other CTHs. The CTH with the lowest priority\n will be executed first, CTHs with equal priority will be executed in the order\n which they were installed.\n\n Own Id: OTP-9445\n\n- It is now possible to use a tuple \\{M,F,A\\}, or a fun, as timetrap\n specification in the suite info function or test case info functions. The\n function must return a valid timeout value, as documented in the common_test\n man page and in the User's Guide.\n\n Own Id: OTP-9501 Aux Id: seq11894\n\n- A new built-in common test hook has been added which captures error_logger and\n SASL event and prints them in the testcase log. To disable this (and any other\n built-in hooks) pass 'enable_builtin_hooks false' to common test.\n\n Own Id: OTP-9543\n\n- Common Test now has the possibility to have built-in hooks which are started\n by default when any test is run. To disable built-in hooks pass\n 'enable_builtin_hooks false' to common test. See the common test hooks\n documentation for more details.\n\n Own Id: OTP-9564","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.5.4 - Common Test Release Notes","ref":"notes.html#common_test-1-5-4"},{"type":"extras","doc":"- It was previously not possible to use timetrap value 'infinity' with\n ct:timetrap/1. This has been fixed.\n\n Own Id: OTP-9159\n\n- The Common Test VTS mode has been updated to be able to report test results of\n suites that include test case groups (when it would previously crash).\n\n Own Id: OTP-9195\n\n- Common Test now refreshes the very top level index.html page at the start of\n each individual test in a test run, so that progress of the ongoing test can\n be tracked by following the link to its overview page.\n\n Own Id: OTP-9210 Aux Id: OTP-9054\n\n- A bug that made it impossible to cancel the previous timetrap when calling\n ct:timetrap/1 has been corrected.\n\n Own Id: OTP-9233 Aux Id: OTP-9159\n\n- Fix bug which would make cth's to not be removed when out of scope when adding\n a cth in suite/0 and crashing in pre_init_per_suite.\n\n Own Id: OTP-9264","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- It is now possible to return a tuple \\{fail,Reason\\} from init_per_testcase/2.\n The result is that the associated test case gets logged as failed without ever\n executing.\n\n Own Id: OTP-9160 Aux Id: seq11502\n\n- Common Test now accepts, but ignores, empty test case group specifications.\n\n Own Id: OTP-9161","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.5.3 - Common Test Release Notes","ref":"notes.html#common_test-1-5-3"},{"type":"extras","doc":"- Added an option to test specs which allow the execution of tests as is,\n instead of doing merging of tests on the same \"level\". See the merge_tests\n directive the test specification documentation.\n\n Own Id: OTP-9026 Aux Id: seq11768","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Alpha release of Common Test Hooks (CTH). CTHs allow the users of common test\n to abstract out common behaviours from test suites in a much more elegant and\n flexible way than was possible before. Note that the addition of this feature\n may introduce minor changes in the undocumented behaviour of the interface\n between common_test and test_server.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-8851","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.5.2 - Common Test Release Notes","ref":"notes.html#common_test-1-5-2"},{"type":"extras","doc":"- Updated ct:get_status documentation to describe no_tests_running return value.\n\n Own Id: OTP-8895 Aux Id: seq11701\n\n- Fixed race condition test failures in the test suites testing common test's\n parallel groups feature.\n\n Own Id: OTP-8921\n\n- The include directive of testspecs now work when used on a remote node.\n\n Own Id: OTP-8935 Aux Id: seq11731","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- ct:parse_table can now handle multiline sql rows\n\n Own Id: OTP-8907 Aux Id: seq11702\n\n- The run_test executable has been renamed to the less generic ct_run to better\n work with other applications. run_test will remain until R16B at which point\n it will be removed.\n\n Own Id: OTP-8936","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.5.1 - Common Test Release Notes","ref":"notes.html#common_test-1-5-1"},{"type":"extras","doc":"- Returning \\{return_group_result,failed\\} from end_per_group in a group that is\n part of a sequence, did not cause the proceeding cases (or groups) to get\n skipped. This has been fixed.\n\n Own Id: OTP-8753 Aux Id: seq11644\n\n- ct:install now works as the documentation describes.\n\n Own Id: OTP-8818 Aux Id: seq-11666","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Common Test has been updated to handle start options and test specification\n terms for test case groups (and test cases in groups). Also, an option named\n 'label', has been added that associates the test run with a name that Common\n Test prints in the overview HTML logs.\n\n Own Id: OTP-8725 Aux Id: OTP-8727\n\n- Andrey Pampukha has been added to the AUTHORS file. Thank you Andrey for your\n work on configuration data handling, Large Scale Testing improvements, and\n other useful updates and fixes.\n\n Own Id: OTP-8803\n\n- The Configuration Data chapter in the User's Guide has been updated.\n\n Own Id: OTP-8804\n\n- Milliseconds are now included in timestamps in Common Test log entries.\n (Thanks to Tomas Johansson.)\n\n Own Id: OTP-8808","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.5 - Common Test Release Notes","ref":"notes.html#common_test-1-5"},{"type":"extras","doc":"- Process calls using monitors in Common Test would not clear the inbox of\n remaining DOWN messages. This has been fixed.\n\n Own Id: OTP-8621 Aux Id: seq11560","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- It is now possible for the user to provide specific callback modules that\n handle test configuration data, so that data on arbitrary form can be accessed\n (e.g. by reading files or by communicating with a configuration server\n process). Two default callback modules have been introduced in Common Test:\n ct_config_plain and ct_config_xml. The former is used to handle the\n traditional Common Test configuration files (with terms on key-value tuple\n form) and the latter to handle configuration data on XML representation.\n\n Own Id: OTP-8485\n\n- It is now possible to execute test suites that are not necessarily available\n on the local file system, but have been loaded on the test node in advance\n (e.g. sent as binaries from a remote node and loaded by RPC). A requirement is\n that the no_auto_compile (or \\{auto_compile,false\\}) parameter has been set.\n\n Own Id: OTP-8490 Aux Id: seq11500\n\n- Test Server will now call the end_per_testcase/2 function even if the test\n case has been terminated explicitly (with abort_current_testcase/1), or after\n a timetrap timeout. Under these circumstances the return value of\n end_per_testcase is completely ignored. Therefore the function will not be\n able to change the reason for test case termination by returning\n \\{fail,Reason\\}, nor will it be able to save data with \\{save_config,Data\\}.\n\n Own Id: OTP-8500 Aux Id: seq11521\n\n- It is now possible to use the test specification term 'init' to start Common\n Test nodes automatically, as well as have initial function calls evaluated on\n the nodes. A default callback module for the 'init' term, ct_slave, has been\n introduced to enable Common Test Master to perform host login and node startup\n operations over ssh.\n\n Own Id: OTP-8570\n\n- The run_test script has been replaced by a program (with the same name) which\n can be executed without explicit installation. The start flags are the same as\n for the legacy start script.\n\n Own Id: OTP-8650\n\n- Previously, a repeat property of a test case group specified the number of\n times the group should be repeated after the main test run. I.e. \\{repeat,N\\}\n would case the group to execute 1+N times. To be consistent with the behaviour\n of the run_test repeat option, this has been changed. N now specifies the\n absolute number of executions instead.\n\n Own Id: OTP-8689 Aux Id: seq11502\n\n- With the run_test -erl_args option, it's possible to divide the options on the\n run_test command line into ones that Common Test should process (those\n preceding -erl_args, and ones it should ignore (those succeeding -erl_args).\n Options preceding -erl_args that Common Test doesn't recognize are also\n ignored (i.e. the same behaviour as earlier versions of Common Test).\n\n Own Id: OTP-8690 Aux Id: OTP-8650\n\n- Directories added with -pa or -pz in the pre-erl_args part of the run_test\n command line will be converted from relative to absolute, this to avoid\n problems loading user modules when Common Test switches working directory\n during the test run.\n\n Own Id: OTP-8691 Aux Id: OTP-8650\n\n- The timetrap handling has been made more user controllable by means of new\n start options and new ct interface functions. With the 'multiply_timetraps'\n start option, it's possible to specify a value which all timetrap timeout\n values get multiplied by. This is useful e.g. to extend the timetraps\n temporarily while running cover or trace. The 'scale_timetraps' start option\n switches on or off the Test Server timetrap scaling feature (which tries to\n detect if the tests may benefit from extended timetraps, e.g. due to running\n certain test tools, and performs the scaling automatically). Furthermore, the\n ct:timetrap/1 function has been introduced, which makes it possible to\n set/reset timetraps during test execution. Also, a ct:sleep/1 function is now\n available, which takes the timetrap parameters into account when calculating\n the time to suspend the process.\n\n Own Id: OTP-8693\n\n- A new run_test start option, event_handler_init, has been added that takes a\n start argument which gets passed to the init function of the event handler.\n\n Own Id: OTP-8694","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.4.7 - Common Test Release Notes","ref":"notes.html#common_test-1-4-7"},{"type":"extras","doc":"- The auto compilation feature of Common Test did not recognize if a header file\n included in a test suite was modified (if the dir start flag/option was used).\n This has been fixed.\n\n Own Id: OTP-8396 Aux Id: seq11488, OTP-8311","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The tc_status value in the Config list for a test case that has failed because\n of a timetrap timeout, has changed from \\{tc_status,timeout\\} to\n \\{tc_status,timetrap_timeout\\}.\n\n Own Id: OTP-8302\n\n- The documentation is now possible to build in an open source environment after\n a number of bugs are fixed and some features are added in the documentation\n build process.\n\n \\- The arity calculation is updated.\n\n \\- The module prefix used in the function names for bif's are removed in the\n generated links so the links will look like\n \"http://www.erlang.org/doc/man/erlang.html#append_element-2\" instead of\n \"http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2\".\n\n \\- Enhanced the menu positioning in the html documentation when a new page is\n loaded.\n\n \\- A number of corrections in the generation of man pages (thanks to Sergei\n Golovan)\n\n \\- The legal notice is taken from the xml book file so OTP's build process can\n be used for non OTP applications.\n\n Own Id: OTP-8343\n\n- It is now possible to include the `ct.hrl` using the -include_lib directive.\n (Thanks to Fred Hebert.)\n\n Own Id: OTP-8379\n\n- The telnet client in Common Test sent \\[IAC,DO,NOP] to the server in attempt\n to keep the connection alive. This is not a valid sequence according to the\n standard, and some telnet servers would terminate the connection because of\n it. The client has been changed to send \\[IAC,NOP] every 10 secs instead,\n which should be a valid sequence. The client does not negotiate this type of\n \"keep alive\" message with the server, and if it causes problems, the user may\n disable the keep alive feature by adding \\{keep_alive,false\\} to the telnet\n configuration data for the server/connection. Please see the ct_telnet and\n unix_telnet manual pages for details.\n\n Own Id: OTP-8450 Aux Id: OTP-8311","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.4.6 - Common Test Release Notes","ref":"notes.html#common_test-1-4-6"},{"type":"extras","doc":"- If the init_per_testcase/2 function fails, the test case now gets marked and\n counted as auto skipped, not user skipped (which would previously happen).\n\n Own Id: OTP-8289","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The documentation is now built with open source tools (xsltproc and fop) that\n exists on most platforms. One visible change is that the frames are removed.\n\n Own Id: OTP-8201\n\n- For a failed test case, the tc_done event is supposed to report info on the\n form \\{failed,Error\\}. Only Error was reported, however, which has now been\n fixed.\n\n Own Id: OTP-8235 Aux Id: seq-11414\n\n- It is now possible to fail a test case from the end_per_testcase/2 function,\n by returning \\{fail,Reason\\}.\n\n Own Id: OTP-8284\n\n- It is now possible to fail a test case by having the end_tc/3 framework\n function return \\{fail,Reason\\} for the test case.\n\n Own Id: OTP-8285\n\n- The test_server framework API (e.g. the end_tc/3 function) has been modified.\n See the test_server_ctrl documentation for details.\n\n Own Id: OTP-8286 Aux Id: OTP-8285, OTP-8287\n\n- Various updates of the test events have been implemented. The data field for\n some events, such as tc_done and tc_auto_skip has been modified to make\n pattern matching on the data easier and more consistent. Also the order in\n which some events are received has been altered. E.g. the tc_auto_skip event\n for a test case now comes after the tc_done for the failed configuration\n function (not before) which makes more sense. Note that no new events have\n been added and that the event record remains unchanged.\n\n Own Id: OTP-8287 Aux Id: OTP-8235\n\n- The marquee used for test names on the all_runs.html page has been removed on\n request. Note that the test name field has the full text string in a title\n tag, which is displayed when hovering the mouse pointer over it (i.e. if the\n web browser supports title tags).\n\n Own Id: OTP-8288\n\n- It is now possible to refresh the top level index files in an arbitrary log\n directory by specifying a \\{refresh_logs,LogDir\\} tuple in the ct:run_test/1\n options list. Also the -refresh_logs flag for the run_test script has been\n extended to take an optional LogDir argument, i.e. -refresh_logs \\[LogDir]. If\n no LogDir is specified, current working directory is assumed, unless the log\n directory is set with the -logdir flag.\n\n Own Id: OTP-8290\n\n- It was previously required that test suites were located under a test object\n (or OTP application) sub-directory named \"test\" (or under a directory named\n \" \\_test\"). This has been changed so that Common Test now looks for\n suites primarily in a test sub-directory only if the directory exists.\n Otherwise it will assume the suites are stored in the same directory the user\n specifies with e.g. the 'dir' start flag/option.\n\n Own Id: OTP-8294","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.4.5 - Common Test Release Notes","ref":"notes.html#common_test-1-4-5"},{"type":"extras","doc":"- The Common Test logger process crashed if a test case in a sequence (declared\n with sequences/0) failed. This fault has been corrected.\n\n Own Id: OTP-8089 Aux Id: seq11334","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Various updates and fixes in Common Test and Test Server.\n\n Own Id: OTP-8045 Aux Id: OTP-8089,OTP-8105,OTP-8163\n\n- Errors in coverage data collection and analysis were difficult to detect. The\n logging has been improved so that more information about e.g. imported and\n missing modules is printed to the html log files.\n\n Own Id: OTP-8163 Aux Id: seq11374\n\n- The Common Test HTML overview pages have been improved. It is now possible to\n see if a test case has been skipped explicitly or because a configuration\n function has failed. Also, the history page (all_runs.html) now has scrolling\n text displaying the test names. The old format (showing names as a truncated\n string) can still be generated by means of the flag/option 'basic_html'.\n\n Own Id: OTP-8177","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.4.2 - Common Test Release Notes","ref":"notes.html#common_test-1-4-2"},{"type":"extras","doc":"- Various corrections and improvements of Common Test and Test Server.\n\n Own Id: OTP-7981","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.4.1 - Common Test Release Notes","ref":"notes.html#common_test-1-4-1"},{"type":"extras","doc":"- Minor updates and corrections.\n\n Own Id: OTP-7897","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.4 - Common Test Release Notes","ref":"notes.html#common_test-1-4"},{"type":"extras","doc":"- A support client module for SSH and SFTP, ct_ssh, has been introduced in\n Common Test.\n\n Own Id: OTP-7838\n\n- Test case groups have been introduced. With this feature it's possible to\n execute groups (possibly nested) of test cases, each group wrapped with a call\n to function init_per_group/2 and end_per_group/2. Group definitions are done\n by means of the new call-back function groups/0, which should return a list of\n definitions. A group definition contains a name tag, a list of properties and\n a list of test cases (including possible nested group definitions). The\n properties make it possible to execute test cases in parallel, in sequence and\n in shuffled order. It is also possible to repeat test cases according to\n different criteria. The properties can be combined, making it possible to e.g.\n repeat a conf case a certain number of times and execute the test cases in\n different (random) order every time. Available properties are: parallel,\n sequence, shuffle, repeat, repeat_until_all_ok, repeat_until_any_ok,\n repeat_until_any_fail and repeat_until_all_fail. Please see the Common Test\n User's Guide for details.\n\n Own Id: OTP-7839 Aux Id: OTP-7511\n\n- It is now possible to use DES3 encrypted configuration files with Common Test.\n\n Own Id: OTP-7842 Aux Id: OTP-7838\n\n- In previous versions of Common Test, only one FTP connection could be opened\n per configuration target name. This has been updated so that multiple\n connections may be opened. The possibility to use named connections is still\n supported.\n\n Own Id: OTP-7853 Aux Id: OTP-7838\n\n- The Erlang mode for Emacs has been updated with new and modified skeletons for\n Common Test and TS. Syntax for test case groups in Common Test (and conf cases\n with properties in TS) has been added and a new minimal Common Test suite\n skeleton has been introduced.\n\n Own Id: OTP-7856","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.3.6 - Common Test Release Notes","ref":"notes.html#common_test-1-3-6"},{"type":"extras","doc":"- When running a test which includes all suites in a test directory, if the auto\n compilation would fail for one suite, all following suites would be excluded\n from the test. This was an unwanted behaviour and has been corrected. Now all\n suites will always be compiled and only the failing ones excluded from the\n test (and logged as missing).\n\n Own Id: OTP-7750 Aux Id: OTP-7803\n\n- The step functionality in Common Test (based on interaction with Debugger) was\n broken. This has been fixed, and some new step features have also been added.\n Please see the Common Test User's Guide for details.\n\n Own Id: OTP-7800 Aux Id: seq11106","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- It is now possible for the user to specify include directories that Common\n Test will pass along to the compiler when suite and help modules are being\n compiled (which Common Test performs automatically before running tests).\n\n Own Id: OTP-7803 Aux Id: OTP-7750","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.3.5 - Common Test Release Notes","ref":"notes.html#common_test-1-3-5"},{"type":"extras","doc":"- If the Erlang runtime system was started without access to an erlang shell\n (e.g. -noshell), compilation errors would cause a crash in the Common Test\n application. Without access to a shell, Common Test cannot prompt the user to\n choose to continue or abort the test session, but must assume that the session\n should proceed.\n\n Own Id: OTP-7749 Aux Id: seq11175, seq11180","title":"Fixed Bugs and Malfunctions - Common Test Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- It is now possible for the Common Test user to disable the auto-compile\n feature. This is done by specifying the run_test flag -no_auto_compile, or the\n ct:run_test/1 option \\{auto_compile,false\\}.\n\n Own Id: OTP-7663\n\n- A new function, ct:get_config/3, has been added to Common Test that makes it\n possible to - if a particular config variable has been defined in multiple\n config files - return all matching values for the variable. The order of the\n elements in the returned list is the same as the specified order of the config\n files.\n\n Own Id: OTP-7758 Aux Id: seq11158\n\n- Because a telnet connection was always identified by a config variable alias,\n it was impossible to open multiple connections using the same telnet host data\n entry in the config file. This limitation has been removed by making it\n possible to associate a connection with handle value only (i.e. multiple\n connections may be opened using the same config variable). See\n ct_telnet:open/4 for details.\n\n Own Id: OTP-7781\n\n- A new syntax for defining default config data values has been introduced. In\n previous versions of Common Test, to define and access a default value for a\n config variable (in the suite info- or test case info function), an alias name\n had to be used. With the new syntax you may define default values without\n reference to aliases, like this: \\{default_config,VarName,DefaultValue\\}.\n Please see the User's Guide for more info.\n\n Own Id: OTP-7782\n\n- In previous versions of Common Test, whenever a config variable got associated\n with a name (by means of a require statement), the config variable name was\n replaced with the new name. This introduced unwanted dependencies between test\n cases (e.g. if one test case would introduce a new name, the following test\n cases could no longer access the config data by means of the original\n variable). This functionality has now been updated so that when new names are\n introduced with require, they become aliases (references) instead of\n replacements. Hence, config data elements can always, at any time, be accessed\n by means of the original config variable names.\n\n Own Id: OTP-7783","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.3.4 - Common Test Release Notes","ref":"notes.html#common_test-1-3-4"},{"type":"extras","doc":"- Common Test now uses the re application instead of the previous rx driver to\n perform regular expression matching on telnet strings. Since re works on all\n supported operating systems, it is now possible to run telnet sessions also on\n platforms such as e.g. Windows (which was not the case with the previous rx\n driver). Note that the rx driver is obsolete from now on, and will be removed\n from Common Test after OTP R12B.\n\n Own Id: OTP-7528","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.3.3 - Common Test Release Notes","ref":"notes.html#common_test-1-3-3"},{"type":"extras","doc":"- Various updates and improvements, plus some minor bug fixes, have been\n implemented in Common Test and Test Server.\n\n Own Id: OTP-7112\n\n- It is now possible, by means of the new function ct:abort_current_testcase/1\n or test_server_ctrl:abort_current_testcase/1, to abort the currently executing\n test case.\n\n Own Id: OTP-7518 Aux Id: OTP-7112","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.3.2 - Common Test Release Notes","ref":"notes.html#common_test-1-3-2"},{"type":"extras","doc":"- The configure test of the rx lib in Common Test was not performed during the\n general OTP application configuration phase. This made e.g. autoconf\n impossible. This has been changed to correspond with the normal OTP build\n procedure.\n\n Own Id: OTP-7379","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Common_Test 1.3.1 - Common Test Release Notes","ref":"notes.html#common_test-1-3-1"},{"type":"extras","doc":"- The rx library, included with common_test, failed to build on some\n architectures because the -fPIC compiler option was missing.\n\n Own Id: OTP-7111","title":"Improvements and New Features - Common Test Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"common_test 1.3.0 - Common Test Release Notes","ref":"notes.html#common_test-1-3-0"},{"type":"extras","doc":"\n# Introduction","title":"Introduction","ref":"introduction.html"},{"type":"extras","doc":"`Common Test` is a portable application for automated testing. It is suitable\nfor:\n\n- Black-box testing of target systems of any type (that is, not necessarily\n implemented in Erlang). This is performed through standard O&M interfaces\n (such as SNMP, HTTP, CORBA, and Telnet) and, if necessary, through\n user-specific interfaces (often called test ports).\n- White-box testing of Erlang/OTP programs. This is easily done by calling the\n target API functions directly from the test case functions.\n\n`Common Test` also integrates use of the OTP `m:cover` tool in application Tools\nfor code coverage analysis of Erlang/OTP programs.\n\n`Common Test` executes test suite programs automatically, without operator\ninteraction. Test progress and results are printed to logs in HTML format,\neasily browsed with a standard web browser. `Common Test` also sends\nnotifications about progress and results through an OTP event manager to event\nhandlers plugged in to the system. This way, users can integrate their own\nprograms for, for example, logging, database storing, or supervision with\n`Common Test`.\n\n`Common Test` provides libraries with useful support functions to fill various\ntesting needs and requirements. There is, for example, support for flexible test\ndeclarations through test specifications. There is also support for central\nconfiguration and control of multiple independent test sessions (to different\ntarget systems) running in parallel.","title":"Scope - Introduction","ref":"introduction.html#scope"},{"type":"extras","doc":"It is assumed that the reader is familiar with the Erlang programming language.","title":"Prerequisites - Introduction","ref":"introduction.html#prerequisites"},{"type":"extras","doc":"\n# Common Test Basics\n\n[](){: #basics }","title":"Common Test Basics","ref":"basics_chapter.html"},{"type":"extras","doc":"The `Common Test` framework is a tool that supports implementation and automated\nexecution of test cases to any types of target systems. `Common Test` is the\nmain tool being used in all testing- and verification activities that are part\nof Erlang/OTP system development and maintenance.\n\nTest cases can be executed individually or in batches. `Common Test` also\nfeatures a distributed testing mode with central control and logging. With this\nfeature, multiple systems can be tested independently in one common session.\nThis is useful, for example, when running automated large-scale regression\ntests.\n\nThe System Under Test (SUT) can consist of one or more target nodes.\n`Common Test` contains a generic test server that, together with other test\nutilities, is used to perform test case execution. The tests can be started from\na GUI, from the OS shell, or from an Erlang shell. _Test suites_ are files\n(Erlang modules) that contain the _test cases_ (Erlang functions) to be\nexecuted. _Support modules_ provide functions that the test cases use to do the\ntests.\n\nIn a black-box testing scenario, `Common Test`\\-based test programs connect to\nthe target system(s) through standard O&M and CLI protocols. `Common Test`\nprovides implementations of, and wrapper interfaces to, some of these protocols\n(most of which exist as standalone components and applications in OTP). The\nwrappers simplify configuration and add verbosity for logging purposes.\n`Common Test` is continuously extended with useful support modules. However,\nnotice that it is a straightforward task to use any Erlang/OTP component for\ntesting purposes with `Common Test`, without needing a `Common Test` wrapper for\nit. It is as simple as calling Erlang functions. A number of target-independent\ninterfaces are supported in `Common Test`, such as Generic Telnet and FTP. These\ncan be specialized or used directly for controlling instruments, traffic load\ngenerators, and so on.\n\n`Common Test` is also a very useful tool for white-box testing Erlang code (for\nexample, module testing), as the test programs can call exported Erlang\nfunctions directly. There is very little overhead required for implementing\nbasic test suites and executing simple tests. For black-box testing Erlang\nsoftware, Erlang RPC and standard O&M interfaces can be used for example.\n\nA test case can handle several connections to one or more target systems,\ninstruments, and traffic generators in parallel to perform the necessary actions\nfor a test. The handling of many connections in parallel is one of the major\nstrengths of `Common Test`, thanks to the efficient support for concurrency in\nthe Erlang runtime system, which `Common Test` users can take great advantage\nof.","title":"General - Common Test Basics","ref":"basics_chapter.html#general"},{"type":"extras","doc":"Test suites are organized in test directories and each test suite can have a\nseparate data directory. Typically, these files and directories are\nversion-controlled similar to other forms of source code (possibly by a version\ncontrol system like GIT or Subversion). However, `Common Test` does not itself\nput any requirements on (or has any awareness of) possible file and directory\nversions.","title":"Test Suite Organization - Common Test Basics","ref":"basics_chapter.html#test-suite-organization"},{"type":"extras","doc":"Support libraries contain functions that are useful for all test suites, or for\ntest suites in a specific functional area or subsystem. In addition to the\ngeneral support libraries provided by the `Common Test` framework, and the\nvarious libraries and applications provided by Erlang/OTP, there can also be a\nneed for customized (user specific) support libraries.","title":"Support Libraries - Common Test Basics","ref":"basics_chapter.html#support-libraries"},{"type":"extras","doc":"Testing is performed by running test suites (sets of test cases) or individual\ntest cases. A test suite is implemented as an Erlang module named\n` _SUITE.erl` which contains a number of test cases. A test case is\nan Erlang function that tests one or more things. The test case is the smallest\nunit that the `Common Test` test server deals with.\n\nSets of test cases, called test case groups, can also be defined. A test case\ngroup can have execution properties associated with it. Execution properties\nspecify if the test cases in the group are to be executed in random order, in\nparallel, or in sequence, and if the execution of the group is to be repeated.\nTest case groups can also be nested (that is, a group can, besides test cases,\ncontain subgroups).\n\nBesides test cases and groups, the test suite can also contain configuration\nfunctions. These functions are meant to be used for setting up (and verifying)\nenvironment and state in the SUT (and/or the `Common Test` host node), required\nfor the tests to execute correctly. Examples of operations are: Opening a\nconnection to the SUT, initializing a database, running an installation script,\nand so on. Configuration can be performed per suite, per test case group, and\nper individual test case.\n\nThe test suite module must conform to a [callback interface](`m:ct_suite`)\nspecified by the `Common Test` test server. For details, see section\n[Writing Test Suites](write_test_chapter.md#intro).\n\nA test case is considered successful if it returns to the caller, no matter what\nthe returned value is. However, a few return values have special meaning as\nfollows:\n\n- `{skip,Reason}` indicates that the test case is skipped.\n- `{comment,Comment}` prints a comment in the log for the test case.\n- `{save_config,Config}` makes the `Common Test` test server pass `Config` to\n the next test case.\n\nA test case failure is specified as a runtime error (a crash), no matter what\nthe reason for termination is. If you use Erlang pattern matching effectively,\nyou can take advantage of this property. The result is concise and readable test\ncase functions that look much more like scripts than actual programs. A simple\nexample:\n\n```erlang\nsession(_Config) ->\n {started,ServerId} = my_server:start(),\n {clients,[]} = my_server:get_clients(ServerId),\n MyId = self(),\n connected = my_server:connect(ServerId, MyId),\n {clients,[MyId]} = my_server:get_clients(ServerId),\n disconnected = my_server:disconnect(ServerId, MyId),\n {clients,[]} = my_server:get_clients(ServerId),\n stopped = my_server:stop(ServerId).\n```\n\nAs a test suite runs, all information (including output to `stdout`) is recorded\nin many different log files. A minimum of information is displayed in the user\nconsole (only start and stop information, plus a note for each failed test\ncase).\n\nThe result from each test case is recorded in a dedicated HTML log file, created\nfor the particular test run. An overview page displays each test case\nrepresented by a table row showing total execution time, if the case was\nsuccessful, failed, or skipped, plus an optional user comment. For a failed test\ncase, the reason for termination is also printed in the comment field. The\noverview page has a link to each test case log file, providing simple navigation\nwith any standard HTML browser.\n\n> #### Note {: .info }\n>\n> In the last row where totals are presented the time shown here is a sum of\n> rows, which are above (not accounting for parallel testcases).\n> On the other hand \"Elapsed Time\" is a clock time spent to run testcases.\n>\n\n[](){: #External_Interfaces }","title":"Suites and Test Cases - Common Test Basics","ref":"basics_chapter.html#suites-and-test-cases"},{"type":"extras","doc":"The `Common Test` test server requires that the test suite defines and exports\nthe following mandatory or optional callback functions:\n\n- **`all()`** - Returns a list of all test cases and groups in the suite.\n (Mandatory)\n\n- **`suite()`** - Information function used to return properties for the suite.\n (Optional)\n\n- **`groups()`** - For declaring test case groups. (Optional)\n\n- **`init_per_suite(Config)`** - Suite level configuration function, executed\n before the first test case. (Optional)\n\n- **`end_per_suite(Config)`** - Suite level configuration function, executed\n after the last test case. (Optional)\n\n- **`group(GroupName)`** - Information function used to return properties for a\n test case group. (Optional)\n\n- **`init_per_group(GroupName, Config)`** - Configuration function for a group,\n executed before the first test case. (Optional)\n\n- **`end_per_group(GroupName, Config)`** - Configuration function for a group,\n executed after the last test case. (Optional)\n\n- **`init_per_testcase(TestCase, Config)`** - Configuration function for a\n testcase, executed before each test case. (Optional)\n\n- **`end_per_testcase(TestCase, Config)`** - Configuration function for a\n testcase, executed after each test case. (Optional)\n\nFor each test case, the `Common Test` test server expects the following\nfunctions:\n\n- **Testcasename()** - Information function that returns a list of test case\n properties. (Optional)\n\n- **Testcasename(Config)** - The test case function.","title":"External Interfaces - Common Test Basics","ref":"basics_chapter.html#external-interfaces"},{"type":"extras","doc":"\n# Getting Started","title":"Getting Started","ref":"getting_started_chapter.html"},{"type":"extras","doc":"The purpose of this section is to let the newcomer get started in quickly\nwriting and executing some first simple tests with a \"learning by example\"\napproach. Most explanations are left for later sections. If you are not much\ninto \"learning by example\" and prefer more technical details, go ahead and skip\nto the next section.\n\nThis section demonstrates how simple it is to write a basic (yet for many module\ntesting purposes, often sufficiently complex) test suite and execute its test\ncases. This is not necessarily obvious when you read the remaining sections in\nthis User's Guide.\n\n> #### Note {: .info }\n>\n> To understand what is discussed and examplified here, we recommended you to\n> first read section [Common Test Basics](basics_chapter.md#basics).","title":"Introduction for Newcomers - Getting Started","ref":"getting_started_chapter.html#introduction-for-newcomers"},{"type":"extras","doc":"Execution of test cases is handled as follows:\n\n![Successful and Unsuccessful Test Case Execution](assets/tc_execution.gif \"Successful and Unsuccessful Test Case Execution\")\n\nFor each test case that `Common Test` is ordered to execute, it spawns a\ndedicated process on which the test case function starts running. (In parallel\nto the test case process, an idle waiting timer process is started, which is\nlinked to the test case process. If the timer process runs out of waiting time,\nit sends an exit signal to terminate the test case process. This is called a\n_timetrap_).\n\nIn scenario 1, the test case process terminates normally after `case A` has\nfinished executing its test code without detecting any errors. The test case\nfunction returns a value and `Common Test` logs the test case as successful.\n\nIn scenario 2, an error is detected during test `case B` execution. This causes\nthe test `case B` function to generate an exception and, as a result, the test\ncase process exits with reason other than normal. `Common Test` logs this as an\nunsuccessful (Failed) test case.\n\nAs you can understand from the illustration, `Common Test` requires a test case\nto generate a runtime error to indicate failure (for example, by causing a bad\nmatch error or by calling [`exit/1`](`exit/1`), preferably through the help\nfunction [`ct:fail/1,2`](`ct:fail/1`)). A successful execution is indicated by a\nnormal return from the test case function.","title":"Test Case Execution - Getting Started","ref":"getting_started_chapter.html#test-case-execution"},{"type":"extras","doc":"As shown in section [Common Test Basics](basics_chapter.md#External_Interfaces),\nthe test suite module implements [callback functions](`m:ct_suite`) (mandatory\nor optional) for various purposes, for example:\n\n- Init/end configuration function for the test suite\n- Init/end configuration function for a test case\n- Init/end configuration function for a test case group\n- Test cases\n\nThe configuration functions are optional. The following example is a test suite\nwithout configuration functions, including one simple test case, to check that\nmodule `mymod` exists (that is, can be successfully loaded by the code server):\n\n```erlang\n-module(my1st_SUITE).\n-compile(export_all).\n\nall() ->\n [mod_exists].\n\nmod_exists(_) ->\n {module,mymod} = code:load_file(mymod).\n```\n\nIf the operation fails, a bad match error occurs that terminates the test case.","title":"A Simple Test Suite - Getting Started","ref":"getting_started_chapter.html#a-simple-test-suite"},{"type":"extras","doc":"If you need to perform configuration operations to run your test, you can\nimplement configuration functions in your suite. The result from a configuration\nfunction is configuration data, or `Config`. This is a list of key-value tuples\nthat get passed from the configuration function to the test cases (possibly\nthrough configuration functions on \"lower level\"). The data flow looks as\nfollows:\n\n![Configuration Data Flow in a Suite](assets/config.gif \"Configuration Data Flow in a Suite\")\n\nThe following example shows a test suite that uses configuration functions to\nopen and close a log file for the test cases (an operation that is unnecessary\nand irrelevant to perform by each test case):\n\n```erlang\n-module(check_log_SUITE).\n-export([all/0, init_per_suite/1, end_per_suite/1]).\n-export([check_restart_result/1, check_no_errors/1]).\n\n-define(value(Key,Config), proplists:get_value(Key,Config)).\n\nall() -> [check_restart_result, check_no_errors].\n\ninit_per_suite(InitConfigData) ->\n [{logref,open_log()} | InitConfigData].\n\nend_per_suite(ConfigData) ->\n close_log(?value(logref, ConfigData)).\n\ncheck_restart_result(ConfigData) ->\n TestData = read_log(restart, ?value(logref, ConfigData)),\n {match,_Line} = search_for(\"restart successful\", TestData).\n\ncheck_no_errors(ConfigData) ->\n TestData = read_log(all, ?value(logref, ConfigData)),\n case search_for(\"error\", TestData) of\n {match,Line} -> ct:fail({error_found_in_log,Line});\n nomatch -> ok\n end.\n```\n\nThe test cases verify, by parsing a log file, that our SUT has performed a\nsuccessful restart and that no unexpected errors are printed.\n\nTo execute the test cases in the recent test suite, type the following on the\nUNIX/Linux command line (assuming that the suite module is in the current\nworking directory):\n\n```text\n$ ct_run -dir .\n```\n\nor:\n\n```text\n$ ct_run -suite check_log_SUITE\n```\n\nTo use the Erlang shell to run our test, you can evaluate the following call:\n\n```erlang\n1> ct:run_test([{dir, \".\"}]).\n```\n\nor:\n\n```erlang\n1> ct:run_test([{suite, \"check_log_SUITE\"}]).\n```\n\nThe result from running the test is printed in log files in HTML format (stored\nin unique log directories on a different level). The following illustration\nshows the log file structure:\n\n![HTML Log File Structure](assets/html_logs.gif \"HTML Log File Structure\")","title":"A Test Suite with Configuration Functions - Getting Started","ref":"getting_started_chapter.html#a-test-suite-with-configuration-functions"},{"type":"extras","doc":"Here follows some questions that you might have after reading this section with\ncorresponding tips and links to the answers:\n\n- _Question:_ \"How and where can I specify variable data for my tests that must\n not be hard-coded in the test suites (such as hostnames, addresses, and user\n login data)?\"\n\n _Answer:_ See section\n [External Configuration Data](config_file_chapter.md#top).\n\n- _Question:_ \"Is there a way to declare different tests and run them in one\n session without having to write my own scripts? Also, can such declarations be\n used for regression testing?\"\n\n _Answer:_ See section\n [Test Specifications](run_test_chapter.md#test_specifications) in section\n Running Tests and Analyzing Results.\n\n- _Question:_ \"Can test cases and/or test runs be automatically repeated?\"\n\n _Answer:_ Learn more about\n [Test Case Groups](write_test_chapter.md#test_case_groups) and read about\n start flags/options in section [Running Tests](run_test_chapter.md#ct_run) and\n in the Reference Manual.\n\n- _Question:_ \"Does `Common Test` execute my test cases in sequence or in\n parallel?\"\n\n _Answer:_ See [Test Case Groups](write_test_chapter.md#test_case_groups) in\n section Writing Test Suites.\n\n- _Question:_ \"What is the syntax for timetraps (mentioned earlier), and how do\n I set them?\"\n\n _Answer:_ This is explained in the\n [Timetrap Time-Outs](write_test_chapter.md#timetraps) part of section Writing\n Test Suites.\n\n- _Question:_ \"What functions are available for logging and printing?\"\n\n _Answer:_ See [Logging](write_test_chapter.md#logging) in section Writing Test\n Suites.\n\n- _Question:_ \"I need data files for my tests. Where do I store them\n preferably?\"\n\n _Answer:_ See\n [Data and Private Directories](write_test_chapter.md#data_priv_dir).\n\n- _Question:_ \"Can I start with a test suite example, please?\"\n\n _Answer:_ [Welcome\\!](example_chapter.md#top)\n\nYou probably want to get started on your own first test suites now, while at the\nsame time digging deeper into the `Common Test` User's Guide and Reference\nManual. There are much more to learn about the things that have been introduced\nin this section. There are also many other useful features to learn, so please\ncontinue to the other sections and have fun.","title":"Questions and Answers - Getting Started","ref":"getting_started_chapter.html#questions-and-answers"},{"type":"extras","doc":"\n# Installation\n\n[](){: #general }","title":"Installation","ref":"install_chapter.html"},{"type":"extras","doc":"The two main interfaces for running tests with `Common Test` are an executable\nprogram named [`ct_run`](ct_run_cmd.md) and the Erlang module `m:ct`. `ct_run`\nis compiled for the underlying operating system (for example, Unix/Linux or\nWindows) during the build of the Erlang/OTP system, and is installed\nautomatically with other executable programs in the top level `bin` directory of\nErlang/OTP. The `ct` interface functions can be called from the Erlang shell, or\nfrom any Erlang function, on any supported platform.\n\nThe `Common Test` application is installed with the Erlang/OTP system. No extra\ninstallation step is required to start using `Common Test` through the `ct_run`\nexecutable program, and/or the interface functions in the `ct` module.","title":"General Information - Installation","ref":"install_chapter.html#general-information"},{"type":"extras","doc":"\n# Writing Test Suites\n\n[](){: #intro }","title":"Writing Test Suites","ref":"write_test_chapter.html"},{"type":"extras","doc":"The `m:ct` module provides the main interface for writing test cases. This\nincludes for example, the following:\n\n- Functions for printing and logging\n- Functions for reading configuration data\n- Function for terminating a test case with error reason\n- Function for adding comments to the HTML overview page\n\nFor details about these functions, see module `m:ct`.\n\nThe `Common Test` application also includes other modules named\n`ct_ `, which provide various support, mainly simplified use of\ncommunication protocols such as RPC, SNMP, FTP, Telnet, and others.","title":"Support for Test Suite Authors - Writing Test Suites","ref":"write_test_chapter.html#support-for-test-suite-authors"},{"type":"extras","doc":"A test suite is an ordinary Erlang module that contains test cases. It is\nrecommended that the module has a name on the form `*_SUITE.erl`. Otherwise, the\ndirectory and auto compilation function in `Common Test` cannot locate it (at\nleast not by default).\n\nIt is also recommended that the `ct.hrl` header file is included in all test\nsuite modules.\n\nEach test suite module must export function [`all/0`](`c:ct_suite:all/0`), which\nreturns the list of all test case groups and test cases to be executed in that\nmodule.\n\nThe callback functions to be implemented by the test suite are all listed in\nmodule [ct_suite ](`m:ct_suite`). They are also described in more detail later\nin this User's Guide.","title":"Test Suites - Writing Test Suites","ref":"write_test_chapter.html#test-suites"},{"type":"extras","doc":"Each test suite module can contain the optional configuration functions\n[`init_per_suite/1`](`c:ct_suite:init_per_suite/1`) and\n[`end_per_suite/1`](`c:ct_suite:end_per_suite/1`). If the init function is\ndefined, so must the end function be.\n\nIf `init_per_suite` exists, it is called initially before the test cases are\nexecuted. It typically contains initializations common for all test cases in the\nsuite, which are only to be performed once. `init_per_suite` is recommended for\nsetting up and verifying state and environment on the System Under Test (SUT) or\nthe `Common Test` host node, or both, so that the test cases in the suite\nexecutes correctly. The following are examples of initial configuration\noperations:\n\n- Opening a connection to the SUT\n- Initializing a database\n- Running an installation script\n\n`end_per_suite` is called as the final stage of the test suite execution (after\nthe last test case has finished). The function is meant to be used for cleaning\nup after `init_per_suite`.\n\n`init_per_suite` and `end_per_suite` execute on dedicated Erlang processes, just\nlike the test cases do. The result of these functions is however not included in\nthe test run statistics of successful, failed, and skipped cases.\n\nThe argument to `init_per_suite` is `Config`, that is, the same key-value list\nof runtime configuration data that each test case takes as input argument.\n`init_per_suite` can modify this parameter with information that the test cases\nneed. The possibly modified `Config` list is the return value of the function.\n\nIf `init_per_suite` fails, all test cases in the test suite are skipped\nautomatically (so called _auto skipped_), including `end_per_suite`.\n\nNotice that if `init_per_suite` and `end_per_suite` do not exist in the suite,\n`Common Test` calls dummy functions (with the same names) instead, so that\noutput generated by hook functions can be saved to the log files for these\ndummies. For details, see [Common Test Hooks](ct_hooks_chapter.md#manipulating).\n\n[](){: #per_testcase }","title":"Init and End per Suite - Writing Test Suites","ref":"write_test_chapter.html#init-and-end-per-suite"},{"type":"extras","doc":"Each test suite module can contain the optional configuration functions\n[`init_per_testcase/2`](`c:ct_suite:init_per_testcase/2`) and\n[`end_per_testcase/2`](`c:ct_suite:end_per_testcase/2`). If the init function is\ndefined, so must the end function be.\n\nIf `init_per_testcase` exists, it is called before each test case in the suite.\nIt typically contains initialization that must be done for each test case\n(analog to `init_per_suite` for the suite).\n\n`end_per_testcase/2` is called after each test case has finished, enabling\ncleanup after `init_per_testcase`.\n\n> #### Note {: .info }\n>\n> If `end_per_testcase` crashes, however, test results are unaffected. At the\n> same time, this occurrence is reported in the test execution logs.\n\nThe first argument to these functions is the name of the test case. This value\ncan be used with pattern matching in function clauses or conditional expressions\nto choose different initialization and cleanup routines for different test\ncases, or perform the same routine for many, or all, test cases.\n\nThe second argument is the `Config` key-value list of runtime configuration\ndata, which has the same value as the list returned by `init_per_suite`.\n`init_per_testcase/2` can modify this parameter or return it \"as is\". The return\nvalue of `init_per_testcase/2` is passed as parameter `Config` to the test case\nitself.\n\nThe return value of `end_per_testcase/2` is ignored by the test server, with\nexception of the [`save_config`](dependencies_chapter.md#save_config) and `fail`\ntuple.\n\n`end_per_testcase` can check if the test case was successful. (which in turn can\ndetermine how cleanup is to be performed). This is done by reading the value\ntagged with `tc_status` from `Config`. The value is one of the following:\n\n- `ok`\n- `{failed,Reason}`\n\n where `Reason` is `timetrap_timeout`, information from [`exit/1`](`exit/1`),\n or details of a runtime error\n\n- `{skipped,Reason}`\n\n where `Reason` is a user-specific term\n\nFunction `end_per_testcase/2` is even called if a test case terminates because\nof a call to `ct:abort_current_testcase/1`, or after a timetrap time-out.\nHowever, `end_per_testcase` then executes on a different process than the test\ncase function. In this situation, `end_per_testcase` cannot change the reason\nfor test case termination by returning `{fail,Reason}` or save data with\n`{save_config,Data}`.\n\nThe test case is skipped in the following two cases:\n\n- If `init_per_testcase` crashes (called _auto skipped_).\n- If `init_per_testcase` returns a tuple `{skip,Reason}` (called _user\n skipped_).\n\nThe test case can also be marked as failed without executing it by returning a\ntuple `{fail,Reason}` from `init_per_testcase`.\n\n> #### Note {: .info }\n>\n> If `init_per_testcase` crashes, or returns `{skip,Reason}` or `{fail,Reason}`,\n> function `end_per_testcase` is not called.\n\nIf it is determined during execution of `end_per_testcase` that the status of a\nsuccessful test case is to be changed to failed, `end_per_testcase` can return\nthe tuple `{fail,Reason}` (where `Reason` describes why the test case fails).\n\nAs `init_per_testcase` and `end_per_testcase` execute on the same Erlang process\nas the test case, printouts from these configuration functions are included in\nthe test case log file.\n\n[](){: #test_cases }","title":"Init and End per Test Case - Writing Test Suites","ref":"write_test_chapter.html#init-and-end-per-test-case"},{"type":"extras","doc":"The smallest unit that the test server is concerned with is a test case. Each\ntest case can test many things, for example, make several calls to the same\ninterface function with different parameters.\n\nThe author can choose to put many or few tests into each test case. Some things\nto keep in mind follows:\n\n- Many small test cases tend to result in extra, and possibly duplicated code,\n as well as slow test execution because of large overhead for initializations\n and cleanups. Avoid duplicated code, for example, by using common help\n functions. Otherwise, the resulting suite becomes difficult to read and\n understand, and expensive to maintain.\n- Larger test cases make it harder to tell what went wrong if it fails. Also,\n large portions of test code risk being skipped when errors occur.\n- Readability and maintainability suffer when test cases become too large and\n extensive. It is not certain that the resulting log files reflect very well\n the number of tests performed.\n\nThe test case function takes one argument, `Config`, which contains\nconfiguration information such as `data_dir` and `priv_dir`. (For details about\nthese, see section\n[Data and Private Directories](write_test_chapter.md#data_priv_dir). The value\nof `Config` at the time of the call, is the same as the return value from\n`init_per_testcase`, mentioned earlier.\n\n> #### Note {: .info }\n>\n> The test case function argument `Config` is not to be confused with the\n> information that can be retrieved from the configuration files (using\n> [`ct:get_config/1/2`](`ct:get_config/1`)). The test case argument `Config` is\n> to be used for runtime configuration of the test suite and the test cases,\n> while configuration files are to contain data related to the SUT. These two\n> types of configuration data are handled differently.\n\nAs parameter `Config` is a list of key-value tuples, that is, a data type called\na property list, it can be handled by the `m:proplists` module. A value can, for\nexample, be searched for and returned with function `proplists:get_value/2`.\nAlso, or alternatively, the general `m:lists` module contains useful functions.\nNormally, the only operations performed on `Config` are insertion (adding a\ntuple to the head of the list) and lookup. To look up a value in the config,\n`proplists:get_value` can be used. For example:\n`PrivDir = proplists:get_value(priv_dir, Config)`.\n\nThe test case result can be customized in several ways. See the manual for\n[`Module:Testcase/1`](`c:ct_suite:'Testcase'/1`) in the `m:ct_suite` module for\ndetails.\n\n[](){: #info_function }","title":"Test Cases - Writing Test Suites","ref":"write_test_chapter.html#test-cases"},{"type":"extras","doc":"For each test case function there can be an extra function with the same name\nbut without arguments. This is the test case information function. It is\nexpected to return a list of tagged tuples that specifies various properties\nregarding the test case.\n\nThe following tags have special meaning:\n\n- **`timetrap`** - Sets the maximum time the test case is allowed to execute. If\n this time is exceeded, the test case fails with reason `timetrap_timeout`.\n Notice that `init_per_testcase` and `end_per_testcase` are included in the\n timetrap time. For details, see section\n [Timetrap Time-Outs](write_test_chapter.md#timetraps).\n\n- **`userdata`** - Specifies any data related to the test case. This data can be\n retrieved at any time using the `ct:userdata/3` utility function.\n\n- **`silent_connections`** - For details, see section\n [Silent Connections](run_test_chapter.md#silent_connections).\n\n- **`require`** - Specifies configuration variables required by the test case.\n If the required configuration variables are not found in any of the test\n system configuration files, the test case is skipped.\n\n A required variable can also be given a default value to be used if the\n variable is not found in any configuration file. To specify a default value,\n add a tuple on the form `{default_config,ConfigVariableName,Value}` to the\n test case information list (the position in the list is irrelevant).\n\n _Examples:_\n\n ```erlang\n testcase1() ->\n [{require, ftp},\n {default_config, ftp, [{ftp, \"my_ftp_host\"},\n {username, \"aladdin\"},\n {password, \"sesame\"}]}}].\n ```\n\n ```erlang\n testcase2() ->\n [{require, unix_telnet, unix},\n {require, {unix, [telnet, username, password]}},\n {default_config, unix, [{telnet, \"my_telnet_host\"},\n {username, \"aladdin\"},\n {password, \"sesame\"}]}}].\n ```\n\nFor more information about `require`, see section\n[Requiring and Reading Configuration Data](config_file_chapter.md#require_config_data)\nin section External Configuration Data and function\n[`ct:require/1/2`](`ct:require/1`).\n\n> #### Note {: .info }\n>\n> Specifying a default value for a required variable can result in a test case\n> always getting executed. This might not be a desired behavior.\n\nIf `timetrap` or `require`, or both, is not set specifically for a particular\ntest case, default values specified by function\n[`suite/0`](`c:ct_suite:suite/0`) are used.\n\nTags other than the earlier mentioned are ignored by the test server.\n\nAn example of a test case information function follows:\n\n```erlang\nreboot_node() ->\n [\n {timetrap,{seconds,60}},\n {require,interfaces},\n {userdata,\n [{description,\"System Upgrade: RpuAddition Normal RebootNode\"},\n {fts,\"http://someserver.ericsson.se/test_doc4711.pdf\"}]}\n ].\n```\n\n[](){: #suite }","title":"Test Case Information Function - Writing Test Suites","ref":"write_test_chapter.html#test-case-information-function"},{"type":"extras","doc":"Function [`suite/0`](`c:ct_suite:suite/0`) can, for example, be used in a test\nsuite module to set a default `timetrap` value and to `require` external\nconfiguration data. If a test case, or a group information function also\nspecifies any of the information tags, it overrides the default values set by\n`suite/0`. For details, see\n[Test Case Information Function](write_test_chapter.md#info_function) and\n[Test Case Groups](write_test_chapter.md#test_case_groups).\n\nThe following options can also be specified with the suite information list:\n\n- `stylesheet`, see [HTML Style Sheets](run_test_chapter.md#html_stylesheet)\n- `userdata`, see\n [Test Case Information Function](write_test_chapter.md#info_function)\n- `silent_connections`, see\n [Silent Connections](run_test_chapter.md#silent_connections)\n\nAn example of the suite information function follows:\n\n```erlang\nsuite() ->\n [\n {timetrap,{minutes,10}},\n {require,global_names},\n {userdata,[{info,\"This suite tests database transactions.\"}]},\n {silent_connections,[telnet]},\n {stylesheet,\"db_testing.css\"}\n ].\n```\n\n[](){: #test_case_groups }","title":"Test Suite Information Function - Writing Test Suites","ref":"write_test_chapter.html#test-suite-information-function"},{"type":"extras","doc":"A test case group is a set of test cases sharing configuration functions and\nexecution properties. Test case groups are defined by function\n[`groups/0`](`c:ct_suite:groups/0`) that should return a term having the\nfollowing syntax:\n\n```text\ngroups() -> GroupDefs\n\nTypes:\n\nGroupDefs = [GroupDef]\nGroupDef = {GroupName,Properties,GroupsAndTestCases}\nGroupName = atom()\nGroupsAndTestCases = [GroupDef | {group,GroupName} | TestCase |\n {testcase,TestCase,TCRepeatProps}]\nTestCase = atom()\nTCRepeatProps = [{repeat,N} | {repeat_until_ok,N} | {repeat_until_fail,N}]\n```\n\n`GroupName` is the name of the group and must be unique within the test suite\nmodule. Groups can be nested, by including a group definition within the\n`GroupsAndTestCases` list of another group. `Properties` is the list of\nexecution properties for the group. The possible values are as follows:\n\n```erlang\nProperties = [parallel | sequence | Shuffle | {GroupRepeatType,N}]\nShuffle = shuffle | {shuffle,Seed}\nSeed = {integer(),integer(),integer()}\nGroupRepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |\n repeat_until_any_ok | repeat_until_any_fail\nN = integer() | forever\n```\n\n_Explanations:_\n\n- **`parallel`** - `Common Test` executes all test cases in the group in\n parallel.\n\n- **`sequence`** - The cases are executed in a sequence as described in section\n [Sequences](dependencies_chapter.md#sequences) in section Dependencies Between\n Test Cases and Suites.\n\n- **`shuffle`** - The cases in the group are executed in random order.\n\n- **`repeat, repeat_until_*`** - Orders `Common Test` to repeat execution of all\n the cases in the group a given number of times, or until any, or all, cases\n fail or succeed.\n\n_Example:_\n\n```erlang\ngroups() -> [{group1, [parallel], [test1a,test1b]},\n {group2, [shuffle,sequence], [test2a,test2b,test2c]}].\n```\n\nTo specify in which order groups are to be executed (also with respect to test\ncases that are not part of any group), add tuples on the form\n`{group,GroupName}` to the `all/0` list.\n\n_Example:_\n\n```erlang\nall() -> [testcase1, {group,group1}, {testcase,testcase2,[{repeat,10}]}, {group,group2}].\n```\n\nExecution properties with a group tuple in `all/0`:\n`{group,GroupName,Properties}` can also be specified. These properties override\nthose specified in the group definition (see `groups/0` earlier). This way, the\nsame set of tests can be run, but with different properties, without having to\nmake copies of the group definition in question.\n\nIf a group contains subgroups, the execution properties for these can also be\nspecified in the group tuple: `{group,GroupName,Properties,SubGroups}` Where,\n`SubGroups` is a list of tuples, `{GroupName,Properties}` or\n`{GroupName,Properties,SubGroups}` representing the subgroups. Any subgroups\ndefined in `groups/0` for a group, that are not specified in the `SubGroups`\nlist, executes with their predefined properties.\n\n_Example:_\n\n```erlang\ngroups() -> [{tests1, [], [{tests2, [], [t2a,t2b]},\n {tests3, [], [t31,t3b]}]}].\n```\n\nTo execute group `tests1` twice with different properties for `tests2` each\ntime:\n\n```erlang\nall() ->\n [{group, tests1, default, [{tests2, [parallel]}]},\n {group, tests1, default, [{tests2, [shuffle,{repeat,10}]}]}].\n```\n\nThis is equivalent to the following specification:\n\n```erlang\nall() ->\n [{group, tests1, default, [{tests2, [parallel]},\n {tests3, default}]},\n {group, tests1, default, [{tests2, [shuffle,{repeat,10}]},\n {tests3, default}]}].\n```\n\nValue `default` states that the predefined properties are to be used.\n\nThe following example shows how to override properties in a scenario with deeply\nnested groups:\n\n```erlang\ngroups() ->\n [{tests1, [], [{group, tests2}]},\n {tests2, [], [{group, tests3}]},\n {tests3, [{repeat,2}], [t3a,t3b,t3c]}].\n\nall() ->\n [{group, tests1, default,\n [{tests2, default,\n [{tests3, [parallel,{repeat,100}]}]}]}].\n```\n\nFor ease of readability, all syntax definitions can be replaced by a function\ncall whose return value should match the expected syntax case.\n\n_Example:_\n\n```erlang\nall() ->\n [{group, tests1, default, test_cases()},\n {group, tests1, default, [shuffle_test(),\n {tests3, default}]}].\ntest_cases() ->\n [{tests2, [parallel]}, {tests3, default}].\n\nshuffle_test() ->\n {tests2, [shuffle,{repeat,10}]}.\n```\n\nThe described syntax can also be used in test specifications to change group\nproperties at the time of execution, without having to edit the test suite. For\nmore information, see section\n[Test Specifications](run_test_chapter.md#test_specifications) in section\nRunning Tests and Analyzing Results.\n\nAs illustrated, properties can be combined. If, for example, `shuffle`,\n`repeat_until_any_fail`, and `sequence` are all specified, the test cases in the\ngroup are executed repeatedly, and in random order, until a test case fails.\nThen execution is immediately stopped and the remaining cases are skipped.\n\nBefore execution of a group begins, the configuration function\n[`init_per_group(GroupName, Config)`](`c:ct_suite:init_per_group/2`) is called.\nThe list of tuples returned from this function is passed to the test cases in\nthe usual manner by argument `Config`. `init_per_group/2` is meant to be used\nfor initializations common for the test cases in the group. After execution of\nthe group is finished, function\n[`end_per_group(GroupName, Config)`](`c:ct_suite:end_per_group/2`) is called.\nThis function is meant to be used for cleaning up after `init_per_group/2`. If\nthe init function is defined, so must the end function be.\n\nWhenever a group is executed, if `init_per_group` and `end_per_group` do not\nexist in the suite, `Common Test` calls dummy functions (with the same names)\ninstead. Output generated by hook functions are saved to the log files for these\ndummies. For more information, see section\n[Manipulating Tests](ct_hooks_chapter.md#manipulating) in section Common Test\nHooks.\n\n> #### Note {: .info }\n>\n> `init_per_testcase/2` and `end_per_testcase/2` are always called for each\n> individual test case, no matter if the case belongs to a group or not.\n\nThe properties for a group are always printed in the top of the HTML log for\n`init_per_group/2`. The total execution time for a group is included at the\nbottom of the log for `end_per_group/2`.\n\nTest case groups can be nested so sets of groups can be configured with the same\n`init_per_group/2` and `end_per_group/2` functions. Nested groups can be defined\nby including a group definition, or a group name reference, in the test case\nlist of another group.\n\n_Example:_\n\n```erlang\ngroups() -> [{group1, [shuffle], [test1a,\n {group2, [], [test2a,test2b]},\n test1b]},\n {group3, [], [{group,group4},\n {group,group5}]},\n {group4, [parallel], [test4a,test4b]},\n {group5, [sequence], [test5a,test5b,test5c]}].\n```\n\nIn the previous example, if `all/0` returns group name references in the order\n`[{group,group1},{group,group3}]`, the order of the configuration functions and\ntest cases becomes the following (notice that `init_per_testcase/2` and\n`end_per_testcase/2:` are also always called, but not included in this example\nfor simplification):\n\n```text\ninit_per_group(group1, Config) -> Config1 (*)\n test1a(Config1)\n init_per_group(group2, Config1) -> Config2\n test2a(Config2), test2b(Config2)\n end_per_group(group2, Config2)\n test1b(Config1)\nend_per_group(group1, Config1)\ninit_per_group(group3, Config) -> Config3\n init_per_group(group4, Config3) -> Config4\n test4a(Config4), test4b(Config4) (**)\n end_per_group(group4, Config4)\n init_per_group(group5, Config3) -> Config5\n test5a(Config5), test5b(Config5), test5c(Config5)\n end_per_group(group5, Config5)\nend_per_group(group3, Config3)\n```\n\n(\\*) The order of test case `test1a`, `test1b`, and `group2` is undefined, as\n`group1` has a shuffle property.\n\n(\\*\\*) These cases are not executed in order, but in parallel.\n\nProperties are not inherited from top-level groups to nested subgroups. For\ninstance, in the previous example, the test cases in `group2` are not executed\nin random order (which is the property of `group1`).","title":"Test Case Groups - Writing Test Suites","ref":"write_test_chapter.html#test-case-groups"},{"type":"extras","doc":"If a group has a parallel property, its test cases are spawned simultaneously\nand get executed in parallel. However, a test case is not allowed to execute in\nparallel with `end_per_group/2`, which means that the time to execute a parallel\ngroup is equal to the execution time of the slowest test case in the group. A\nnegative side effect of running test cases in parallel is that the HTML summary\npages are not updated with links to the individual test case logs until function\n`end_per_group/2` for the group has finished.\n\nA group nested under a parallel group starts executing in parallel with previous\n(parallel) test cases (no matter what properties the nested group has). However,\nas test cases are never executed in parallel with `init_per_group/2` or\n`end_per_group/2` of the same group, it is only after a nested group has\nfinished that remaining parallel cases in the previous group become spawned.","title":"Parallel Property and Nested Groups - Writing Test Suites","ref":"write_test_chapter.html#parallel-property-and-nested-groups"},{"type":"extras","doc":"A parallel test case has a private I/O server as its group leader. (For a\ndescription of the group leader concept, see [ERTS](`e:erts:index.html`)). The\ncentral I/O server process, which handles the output from regular test cases and\nconfiguration functions, does not respond to I/O messages during execution of\nparallel groups. This is important to understand to avoid certain traps, like\nthe following:\n\nIf a process, `P`, is spawned during execution of, for example,\n`init_per_suite/1`, it inherits the group leader of the `init_per_suite`\nprocess. This group leader is the central I/O server process mentioned earlier.\nIf, at a later time, _during parallel test case execution_, some event triggers\nprocess `P` to call [`io:format/1/2`](`io:format/1`), that call never returns\n(as the group leader is in a non-responsive state) and causes `P` to hang.","title":"Parallel Test Cases and I/O - Writing Test Suites","ref":"write_test_chapter.html#parallel-test-cases-and-i-o"},{"type":"extras","doc":"[](){: #repeated_groups }\n\nA test case group can be repeated a certain number of times (specified by an\ninteger) or indefinitely (specified by `forever`). The repetition can also be\nstopped too early if any or all cases fail or succeed, that is, if any of the\nproperties `repeat_until_any_fail`, `repeat_until_any_ok`,\n`repeat_until_all_fail`, or `repeat_until_all_ok` is used. If the basic `repeat`\nproperty is used, status of test cases is irrelevant for the repeat operation.\n\nThe status of a subgroup can be returned (`ok` or `failed`), to affect the\nexecution of the group on the level above. This is accomplished by, in\n`end_per_group/2`, looking up the value of `tc_group_properties` in the `Config`\nlist and checking the result of the test cases in the group. If status `failed`\nis to be returned from the group as a result, `end_per_group/2` is to return the\nvalue `{return_group_result,failed}`. The status of a subgroup is taken into\naccount by `Common Test` when evaluating if execution of a group is to be\nrepeated or not (unless the basic `repeat` property is used).\n\nThe value of `tc_group_properties` is a list of status tuples, each with the key\n`ok`, `skipped`, and `failed`. The value of a status tuple is a list with names\nof test cases that have been executed with the corresponding status as result.\n\nThe following is an example of how to return the status from a group:\n\n```erlang\nend_per_group(_Group, Config) ->\n Status = proplists:get_value(tc_group_result, Config),\n case proplists:get_value(failed, Status) of\n [] -> % no failed cases\n {return_group_result,ok};\n _Failed -> % one or more failed\n {return_group_result,failed}\n end.\n```\n\nIt is also possible, in `end_per_group/2`, to check the status of a subgroup\n(maybe to determine what status the current group is to return). This is as\nsimple as illustrated in the previous example, only the group name is stored in\na tuple `{group_result,GroupName}`, which can be searched for in the status\nlists.\n\n_Example:_\n\n```erlang\nend_per_group(group1, Config) ->\n Status = proplists:get_value(tc_group_result, Config),\n Failed = proplists:get_value(failed, Status),\n case lists:member({group_result,group2}, Failed) of\n true ->\n {return_group_result,failed};\n false ->\n {return_group_result,ok}\n end;\n...\n```\n\n> #### Note {: .info }\n>\n> When a test case group is repeated, the configuration functions\n> `init_per_group/2` and `end_per_group/2` are also always called with each\n> repetition.","title":"Repeated Groups - Writing Test Suites","ref":"write_test_chapter.html#repeated-groups"},{"type":"extras","doc":"The order in which test cases in a group are executed is under normal\ncircumstances the same as the order specified in the test case list in the group\ndefinition. With property `shuffle` set, however, `Common Test` instead executes\nthe test cases in random order.\n\nYou can provide a seed value (a tuple of three integers) with the shuffle\nproperty `{shuffle,Seed}`. This way, the same shuffling order can be created\nevery time the group is executed. If no seed value is specified, `Common Test`\ncreates a \"random\" seed for the shuffling operation (using the return value of\n`erlang:timestamp/0`). The seed value is always printed to the\n`init_per_group/2` log file so that it can be used to recreate the same\nexecution order in a subsequent test run.\n\n> #### Note {: .info }\n>\n> If a shuffled test case group is repeated, the seed is not reset between\n> turns.\n\nIf a subgroup is specified in a group with a `shuffle` property, the execution\norder of this subgroup in relation to the test cases (and other subgroups) in\nthe group, is random. The order of the test cases in the subgroup is however not\nrandom (unless the subgroup has a `shuffle` property).\n\n[](){: #group_info }","title":"Shuffled Test Case Order - Writing Test Suites","ref":"write_test_chapter.html#shuffled-test-case-order"},{"type":"extras","doc":"The test case group information function, `group(GroupName)`, serves the same\npurpose as the suite- and test case information functions previously described.\nHowever, the scope for the group information function, is all test cases and\nsubgroups in the group in question (`GroupName`).\n\n_Example:_\n\n```erlang\ngroup(connection_tests) ->\n [{require,login_data},\n {timetrap,1000}].\n```\n\nThe group information properties override those set with the suite information\nfunction, and can in turn be overridden by test case information properties. For\na list of valid information properties and more general information, see the\n[Test Case Information Function](write_test_chapter.md#info_function).","title":"Group Information Function - Writing Test Suites","ref":"write_test_chapter.html#group-information-function"},{"type":"extras","doc":"Information functions can also be used for functions `init_per_suite`,\n`end_per_suite`, `init_per_group`, and `end_per_group`, and they work the same\nway as with the\n[Test Case Information Function](write_test_chapter.md#info_function). This is\nuseful, for example, for setting timetraps and requiring external configuration\ndata relevant only for the configuration function in question (without affecting\nproperties set for groups and test cases in the suite).\n\nThe information function `init/end_per_suite()` is called for\n`init/end_per_suite(Config)`, and information function\n`init/end_per_group(GroupName)` is called for\n`init/end_per_group(GroupName,Config)`. However, information functions cannot be\nused with `init/end_per_testcase(TestCase, Config)`, as these configuration\nfunctions execute on the test case process and use the same properties as the\ntest case (that is, the properties set by the test case information function,\n`TestCase()`). For a list of valid information properties and more general\ninformation, see the\n[Test Case Information Function](write_test_chapter.md#info_function).\n\n[](){: #data_priv_dir }","title":"Information Functions for Init- and End-Configuration - Writing Test Suites","ref":"write_test_chapter.html#information-functions-for-init-and-end-configuration"},{"type":"extras","doc":"In the data directory, `data_dir`, the test module has its own files needed for\nthe testing. The name of `data_dir` is the name of the test suite followed by\n`\"_data\"`. For example, `\"some_path/foo_SUITE.beam\"` has the data directory\n`\"some_path/foo_SUITE_data/\"`. Use this directory for portability, that is, to\navoid hardcoding directory names in your suite. As the data directory is stored\nin the same directory as your test suite, you can rely on its existence at\nruntime, even if the path to your test suite directory has changed between test\nsuite implementation and execution.\n\n`priv_dir` is the private directory for the test cases. This directory can be\nused whenever a test case (or configuration function) needs to write something\nto file. The name of the private directory is generated by `Common Test`, which\nalso creates the directory.\n\nBy default, `Common Test` creates one central private directory per test run,\nshared by all test cases. This is not always suitable. Especially if the same\ntest cases are executed multiple times during a test run (that is, if they\nbelong to a test case group with property `repeat`) and there is a risk that\nfiles in the private directory get overwritten. Under these circumstances,\n`Common Test` can be configured to create one dedicated private directory per\ntest case and execution instead. This is accomplished with the flag/option\n`create_priv_dir` (to be used with the [`ct_run`](ct_run_cmd.md) program, the\n`ct:run_test/1` function, or as test specification term). There are three\npossible values for this option as follows:\n\n- `auto_per_run`\n- `auto_per_tc`\n- `manual_per_tc`\n\nThe first value indicates the default `priv_dir` behavior, that is, one private\ndirectory created per test run. The two latter values tell `Common Test` to\ngenerate a unique test directory name per test case and execution. If the auto\nversion is used, _all_ private directories are created automatically. This can\nbecome very inefficient for test runs with many test cases or repetitions, or\nboth. Therefore, if the manual version is used instead, the test case must tell\n`Common Test` to create `priv_dir` when it needs it. It does this by calling the\nfunction `ct:make_priv_dir/0`.\n\n> #### Note {: .info }\n>\n> Do not depend on the current working directory for reading and writing data\n> files, as this is not portable. All scratch files are to be written in the\n> `priv_dir` and all data files are to be located in `data_dir`. Also, the\n> `Common Test` server sets the current working directory to the test case log\n> directory at the start of every case.","title":"Data and Private Directories - Writing Test Suites","ref":"write_test_chapter.html#data-and-private-directories"},{"type":"extras","doc":"Each test case is executed by a dedicated Erlang process. The process is spawned\nwhen the test case starts, and terminated when the test case is finished. The\nconfiguration functions `init_per_testcase` and `end_per_testcase` execute on\nthe same process as the test case.\n\nThe configuration functions `init_per_suite` and `end_per_suite` execute, like\ntest cases, on dedicated Erlang processes.\n\n[](){: #timetraps }","title":"Execution Environment - Writing Test Suites","ref":"write_test_chapter.html#execution-environment"},{"type":"extras","doc":"The default time limit for a test case is 30 minutes, unless a `timetrap` is\nspecified either by the suite-, group-, or test case information function. The\ntimetrap time-out value defined by `suite/0` is the value that is used for each\ntest case in the suite (and for the configuration functions `init_per_suite/1`,\n`end_per_suite/1`, `init_per_group/2`, and `end_per_group/2`). A timetrap value\ndefined by `group(GroupName)` overrides one defined by `suite()` and is used for\neach test case in group `GroupName`, and any of its subgroups. If a timetrap\nvalue is defined by `group/1` for a subgroup, it overrides that of its higher\nlevel groups. Timetrap values set by individual test cases (by the test case\ninformation function) override both group- and suite- level timetraps.\n\nA timetrap can also be set or reset dynamically during the execution of a test\ncase, or configuration function. This is done by calling `ct:timetrap/1`. This\nfunction cancels the current timetrap and starts a new one (that stays active\nuntil time-out, or end of the current function).\n\nTimetrap values can be extended with a multiplier value specified at startup\nwith option `multiply_timetraps`. It is also possible to let the test server\ndecide to scale up timetrap time-out values automatically. That is, if tools\nsuch as `cover` or `trace` are running during the test. This feature is disabled\nby default and can be enabled with start option `scale_timetraps`.\n\nIf a test case needs to suspend itself for a time that also gets multiplied by\n`multiply_timetraps` (and possibly also scaled up if `scale_timetraps` is\nenabled), the function `ct:sleep/1` can be used (instead of, for example,\n`timer:sleep/1`).\n\nA function (`fun/0` or `{Mod,Func,Args}` (MFA) tuple) can be specified as\ntimetrap value in the suite-, group- and test case information function, and as\nargument to function `ct:timetrap/1`.\n\n_Examples:_\n\n`{timetrap,{my_test_utils,timetrap,[?MODULE,system_start]}}`\n\n`ct:timetrap(fun() -> my_timetrap(TestCaseName, Config) end)`\n\nThe user timetrap function can be used for two things as follows:\n\n- To act as a timetrap. The time-out is triggered when the function returns.\n- To return a timetrap time value (other than a function).\n\nBefore execution of the timetrap function (which is performed on a parallel,\ndedicated timetrap process), `Common Test` cancels any previously set timer for\nthe test case or configuration function. When the timetrap function returns, the\ntime-out is triggered, _unless_ the return value is a valid timetrap time, such\nas an integer, or a `{SecMinOrHourTag,Time}` tuple (for details, see module\n`m:ct_suite`). If a time value is returned, a new timetrap is started to\ngenerate a time-out after the specified time.\n\nThe user timetrap function can return a time value after a delay. The effective\ntimetrap time is then the delay time _plus_ the returned time.\n\n[](){: #logging }","title":"Timetrap Time-Outs - Writing Test Suites","ref":"write_test_chapter.html#timetrap-time-outs"},{"type":"extras","doc":"`Common Test` provides the following three main functions for printing strings:\n\n- `ct:log(Category, Importance, Format, FormatArgs, Opts)`\n- `ct:print(Category, Importance, Format, FormatArgs)`\n- `ct:pal(Category, Importance, Format, FormatArgs)`\n\nThe [`log/1,2,3,4,5`](`ct:log/1`) function prints a string to the test case log\nfile. The [`print/1,2,3,4`](`ct:print/1`) function prints the string to screen.\nThe [`pal/1,2,3,4`](`ct:pal/1`) function prints the same string both to file and\nscreen. The functions are described in module `m:ct`.\n\nThe optional `Category` argument can be used to categorize the log printout.\nCategories can be used for two things as follows:\n\n- To compare the importance of the printout to a specific verbosity level.\n- To format the printout according to a user-specific HTML Style Sheet (CSS).\n\nArgument `Importance` specifies a level of importance that, compared to a\nverbosity level (general and/or set per category), determines if the printout is\nto be visible. `Importance` is any integer in the range 0..99. Predefined\nconstants exist in the `ct.hrl` header file. The default importance level,\n`?STD_IMPORTANCE` (used if argument `Importance` is not provided), is 50. This\nis also the importance used for standard I/O, for example, from printouts made\nwith `io:format/2`, `io:put_chars/1`, and so on.\n\n`Importance` is compared to a verbosity level set by the `verbosity` start\nflag/option. The level can be set per category or generally, or both. If\n`verbosity` is not set by the user, a level of 100 (`?MAX_VERBOSITY` = all\nprintouts visible) is used as default value. `Common Test` performs the\nfollowing test:\n\n```text\nImportance >= (100-VerbosityLevel)\n```\n\nThe constant `?STD_VERBOSITY` has value 50 (see `ct.hrl`). At this level, all\nstandard I/O gets printed. If a lower verbosity level is set, standard I/O\nprintouts are ignored. Verbosity level 0 effectively turns all logging off\n(except from printouts made by `Common Test` itself).\n\nThe general verbosity level is not associated with any particular category. This\nlevel sets the threshold for the standard I/O printouts, uncategorized\n`ct:log/print/pal` printouts, and printouts for categories with undefined\nverbosity level.\n\n_Examples:_\n\nSome printouts during test case execution:\n\n```erlang\nio:format(\"1. Standard IO, importance = ~w~n\", [?STD_IMPORTANCE]),\nct:log(\"2. Uncategorized, importance = ~w\", [?STD_IMPORTANCE]),\n ct:log(info, \"3. Categorized info, importance = ~w\", [?STD_IMPORTANCE]),\n ct:log(info, ?LOW_IMPORTANCE, \"4. Categorized info, importance = ~w\", [?LOW_IMPORTANCE]),\n ct:log(error, ?HI_IMPORTANCE, \"5. Categorized error, importance = ~w\", [?HI_IMPORTANCE]),\n ct:log(error, ?MAX_IMPORTANCE, \"6. Categorized error, importance = ~w\", [?MAX_IMPORTANCE]),\n```\n\nIf starting the test with a general verbosity level of 50 (`?STD_VERBOSITY`):\n\n```text\n$ ct_run -verbosity 50\n```\n\nthe following is printed:\n\n```text\n1. Standard IO, importance = 50\n2. Uncategorized, importance = 50\n3. Categorized info, importance = 50\n5. Categorized error, importance = 75\n6. Categorized error, importance = 99\n```\n\nIf starting the test with:\n\n```text\n$ ct_run -verbosity 1 and info 75\n```\n\nthe following is printed:\n\n```erlang\n3. Categorized info, importance = 50\n4. Categorized info, importance = 25\n6. Categorized error, importance = 99\n```\n\nNote that the category argument is not required in order to only specify the\nimportance of a printout. Example:\n\n```erlang\nct:pal(?LOW_IMPORTANCE, \"Info report: ~p\", [Info])\n```\n\nOr perhaps in combination with constants:\n\n```erlang\n-define(INFO, ?LOW_IMPORTANCE).\n-define(ERROR, ?HI_IMPORTANCE).\n\nct:log(?INFO, \"Info report: ~p\", [Info])\nct:pal(?ERROR, \"Error report: ~p\", [Error])\n```\n\nThe functions `ct:set_verbosity/2` and `ct:get_verbosity/1` may be used to\nmodify and read verbosity levels during test execution.\n\nThe arguments `Format` and `FormatArgs` in `ct:log/print/pal` are always passed\non to the STDLIB function `io:format/3` (For details, see the `m:io` manual\npage).\n\n`ct:pal/4` and `ct:log/5` add headers to strings being printed to the log file.\nThe strings are also wrapped in div tags with a CSS class attribute, so that\nstylesheet formatting can be applied. To disable this feature for a printout\n(i.e. to get a result similar to using `io:format/2`), call `ct:log/5` with the\n`no_css` option.\n\nHow categories can be mapped to CSS tags is documented in section\n[HTML Style Sheets](run_test_chapter.md#html_stylesheet) in section Running\nTests and Analyzing Results.\n\nCommon Test will escape special HTML characters (<, > and &) in printouts to the\nlog file made with `ct:pal/4` and `io:format/2`. In order to print strings with\nHTML tags to the log, use the `ct:log/3,4,5` function. The character escaping\nfeature is per default disabled for `ct:log/3,4,5` but can be enabled with the\n`esc_chars` option in the `Opts` list, see [`ct:log/3,4,5`](`ct:log/5`).\n\nIf the character escaping feature needs to be disabled (typically for backwards\ncompatibility reasons), use the `ct_run` start flag `-no_esc_chars`, or the\n`ct:run_test/1` start option `{esc_chars,Bool}` (this start option is also\nsupported in test specifications).\n\nFor more information about log files, see section\n[Log Files](run_test_chapter.md#log_files) in section Running Tests and\nAnalyzing Results.","title":"Logging - Categories and Verbosity Levels - Writing Test Suites","ref":"write_test_chapter.html#logging-categories-and-verbosity-levels"},{"type":"extras","doc":"Even though it is highly efficient to write test suites with the `Common Test`\nframework, mistakes can be made, mainly because of illegal dependencies. Some of\nthe more frequent mistakes from our own experience with running the Erlang/OTP\ntest suites follows:\n\n- Depending on current directory, and writing there:\n\n This is a common error in test suites. It is assumed that the current\n directory is the same as the author used as current directory when the test\n case was developed. Many test cases even try to write scratch files to this\n directory. Instead `data_dir` and `priv_dir` are to be used to locate data and\n for writing scratch files.\n\n- Depending on execution order:\n\n During development of test suites, make no assumptions on the execution order\n of the test cases or suites. For example, a test case must not assume that a\n server it depends on is already started by a previous test case. Reasons for\n this follows:\n\n - The user/operator can specify the order at will, and maybe a different\n execution order is sometimes more relevant or efficient.\n - If the user specifies a whole directory of test suites for the test, the\n execution order of the suites depends on how the files are listed by the\n operating system, which varies between systems.\n - If a user wants to run only a subset of a test suite, there is no way one\n test case could successfully depend on another.\n\n- Depending on Unix:\n\n Running Unix commands through `os:cmd` are likely not to work on non-Unix\n platforms.\n\n- Nested test cases:\n\n Starting a test case from another not only tests the same thing twice, but\n also makes it harder to follow what is being tested. Also, if the called test\n case fails for some reason, so do the caller. This way, one error gives cause\n to several error reports, which is to be avoided.\n\n Functionality common for many test case functions can be implemented in common\n help functions. If these functions are useful for test cases across suites,\n put the help functions into common help modules.\n\n- Failure to crash or exit when things go wrong:\n\n Making requests without checking that the return value indicates success can\n be OK if the test case fails later, but it is never acceptable just to print\n an error message (into the log file) and return successfully. Such test cases\n do harm, as they create a false sense of security when overviewing the test\n results.\n\n- Messing up for subsequent test cases:\n\n Test cases are to restore as much of the execution environment as possible, so\n that subsequent test cases do not crash because of their execution order. The\n function [`end_per_testcase`](`c:ct_suite:end_per_testcase/2`) is suitable for\n this.","title":"Illegal Dependencies - Writing Test Suites","ref":"write_test_chapter.html#illegal-dependencies"},{"type":"extras","doc":"\n# Test Structure","title":"Test Structure","ref":"test_structure_chapter.html"},{"type":"extras","doc":"A test is performed by running one or more test suites. A test suite consists of\ntest cases, configuration functions, and information functions. Test cases can\nbe grouped in so called test case groups. A test suite is an Erlang module and\ntest cases are implemented as Erlang functions. Test suites are stored in test\ndirectories.\n\n[](){: #skipping_test_cases }","title":"General - Test Structure","ref":"test_structure_chapter.html#general"},{"type":"extras","doc":"Certain test cases can be skipped, for example, if you know beforehand that a\nspecific test case fails. The reason can be functionality that is not yet\nimplemented, a bug that is known but not yet fixed, or some functionality that\ndoes not work or is not applicable on a specific platform.\n\nTest cases can be skipped in the following ways:\n\n- Using `skip_suites` and `skip_cases` terms in\n [test specifications](run_test_chapter.md#test_specifications).\n- Returning `{skip,Reason}` from function\n [`init_per_testcase/2`](`c:ct_suite:init_per_testcase/2`) or\n [`init_per_suite/1`](`c:ct_suite:init_per_suite/1`).\n- Returning `{skip,Reason}` from the execution clause of the test case. The\n execution clause is called, so the author must ensure that the test case does\n not run.\n\nWhen a test case is skipped, it is noted as `SKIPPED` in the HTML log.","title":"Skipping Test Cases - Test Structure","ref":"test_structure_chapter.html#skipping-test-cases"},{"type":"extras","doc":"- **_Auto-skipped test case_** - When a configuration function fails (that is,\n terminates unexpectedly), the test cases depending on the configuration\n function are skipped automatically by `Common Test`. The status of the test\n cases is then \"auto-skipped\". Test cases are also \"auto-skipped\" by\n `Common Test` if the required configuration data is unavailable at runtime.\n\n- **_Configuration function_** - A function in a test suite that is meant to be\n used for setting up, cleaning up, and/or verifying the state and environment\n on the System Under Test (SUT) and/or the `Common Test` host node, so that a\n test case (or a set of test cases) can execute correctly.\n\n- **_Configuration file_** - A file containing data related to a test and/or an\n SUT, for example, protocol server addresses, client login details, and\n hardware interface addresses. That is, any data that is to be handled as\n variable in the suite and not be hard-coded.\n\n- **_Configuration variable_** - A name (an Erlang atom) associated with a data\n value read from a configuration file.\n\n- **`data_dir`** - Data directory for a test suite. This directory contains any\n files used by the test suite, for example, extra Erlang modules, binaries, or\n data files.\n\n- **_Information function_** - A function in a test suite that returns a list of\n properties (read by the `Common Test` server) that describes the conditions\n for executing the test cases in the suite.\n\n- **_Major log file_** - An overview and summary log file for one or more test\n suites.\n\n- **_Minor log file_** - A log file for one particular test case. Also called\n the test case log file.\n\n- **`priv_dir`** - Private directory for a test suite. This directory is to be\n used when the test suite needs to write to files.\n\n- **`ct_run`** - The name of an executable program that can be used as an\n interface for specifying and running tests with `Common Test`.\n\n- **_Test case_** - A single test included in a test suite. A test case is\n implemented as a function in a test suite module.\n\n- **_Test case group_** - A set of test cases sharing configuration functions\n and execution properties. The execution properties specify if the test cases\n in the group are to be executed in random order, in parallel, or in sequence,\n and if the execution of the group is be repeated. Test case groups can also be\n nested. That is, a group can, besides test cases, contain subgroups.\n\n- **_Test suite_** - An Erlang module containing a collection of test cases for\n a specific functional area.\n\n- **_Test directory_** - A directory containing one or more test suite modules,\n that is, a group of test suites.\n\n- **_Argument_ `Config`** - A list of key-value tuples (that is, a property\n list) containing runtime configuration data passed from the configuration\n functions to the test cases.\n\n- **_User-skipped test case_** - The status of a test case explicitly skipped in\n any of the ways described in section\n [Skipping Test Cases](test_structure_chapter.md#skipping_test_cases).","title":"Definition of Terms - Test Structure","ref":"test_structure_chapter.html#definition-of-terms"},{"type":"extras","doc":"\n# Examples and Templates\n\n[](){: #top }","title":"Examples and Templates","ref":"example_chapter.html"},{"type":"extras","doc":"The following example test suite shows some tests of a database server:\n\n```erlang\n-module(db_data_type_SUITE).\n\n-include_lib(\"common_test/include/ct.hrl\").\n\n%% Test server callbacks\n-export([suite/0, all/0,\n init_per_suite/1, end_per_suite/1,\n init_per_testcase/2, end_per_testcase/2]).\n\n%% Test cases\n-export([string/1, integer/1]).\n\n-define(CONNECT_STR, \"DSN=sqlserver;UID=alladin;PWD=sesame\").\n\n%%--------------------------------------------------------------------\n%% COMMON TEST CALLBACK FUNCTIONS\n%%--------------------------------------------------------------------\n\n%%--------------------------------------------------------------------\n%% Function: suite() -> Info\n%%\n%% Info = [tuple()]\n%% List of key/value pairs.\n%%\n%% Description: Returns list of tuples to set default properties\n%% for the suite.\n%%--------------------------------------------------------------------\nsuite() ->\n [{timetrap,{minutes,1}}].\n\n%%--------------------------------------------------------------------\n%% Function: init_per_suite(Config0) -> Config1\n%%\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%%\n%% Description: Initialization before the suite.\n%%--------------------------------------------------------------------\ninit_per_suite(Config) ->\n {ok, Ref} = db:connect(?CONNECT_STR, []),\n TableName = db_lib:unique_table_name(),\n [{con_ref, Ref },{table_name, TableName}| Config].\n\n%%--------------------------------------------------------------------\n%% Function: end_per_suite(Config) -> term()\n%%\n%% Config = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%%\n%% Description: Cleanup after the suite.\n%%--------------------------------------------------------------------\nend_per_suite(Config) ->\n Ref = proplists:get_value(con_ref, Config),\n db:disconnect(Ref),\n ok.\n\n%%--------------------------------------------------------------------\n%% Function: init_per_testcase(TestCase, Config0) -> Config1\n%%\n%% TestCase = atom()\n%% Name of the test case that is about to run.\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%%\n%% Description: Initialization before each test case.\n%%--------------------------------------------------------------------\ninit_per_testcase(Case, Config) ->\n Ref = proplists:get_value(con_ref, Config),\n TableName = proplists:get_value(table_name, Config),\n ok = db:create_table(Ref, TableName, table_type(Case)),\n Config.\n\n%%--------------------------------------------------------------------\n%% Function: end_per_testcase(TestCase, Config) -> term()\n%%\n%% TestCase = atom()\n%% Name of the test case that is finished.\n%% Config = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%%\n%% Description: Cleanup after each test case.\n%%--------------------------------------------------------------------\nend_per_testcase(_Case, Config) ->\n Ref = proplists:get_value(con_ref, Config),\n TableName = proplists:get_value(table_name, Config),\n ok = db:delete_table(Ref, TableName),\n ok.\n\n%%--------------------------------------------------------------------\n%% Function: all() -> GroupsAndTestCases\n%%\n%% GroupsAndTestCases = [{group,GroupName} | TestCase]\n%% GroupName = atom()\n%% Name of a test case group.\n%% TestCase = atom()\n%% Name of a test case.\n%%\n%% Description: Returns the list of groups and test cases that\n%% are to be executed.\n%%--------------------------------------------------------------------\nall() ->\n [string, integer].\n\n\n%%--------------------------------------------------------------------\n%% TEST CASES\n%%--------------------------------------------------------------------\n\nstring(Config) ->\n insert_and_lookup(dummy_key, \"Dummy string\", Config).\n\ninteger(Config) ->\n insert_and_lookup(dummy_key, 42, Config).\n\n\ninsert_and_lookup(Key, Value, Config) ->\n Ref = proplists:get_value(con_ref, Config),\n TableName = proplists:get_value(table_name, Config),\n ok = db:insert(Ref, TableName, Key, Value),\n [Value] = db:lookup(Ref, TableName, Key),\n ok = db:delete(Ref, TableName, Key),\n [] = db:lookup(Ref, TableName, Key),\n ok.\n```","title":"Test Suite Example - Examples and Templates","ref":"example_chapter.html#test-suite-example"},{"type":"extras","doc":"The Erlang mode for the Emacs editor includes two `Common Test` test suite\ntemplates, one with extensive information in the function headers, and one with\nminimal information. A test suite template provides a quick start for\nimplementing a suite from scratch and gives a good overview of the available\ncallback functions. The two templates follows:\n\n_Large Common Test Suite_\n\n```erlang\n%%%-------------------------------------------------------------------\n%%% File : example_SUITE.erl\n%%% Author :\n%%% Description :\n%%%\n%%% Created :\n%%%-------------------------------------------------------------------\n-module(example_SUITE).\n\n%% Note: This directive should only be used in test suites.\n-compile(export_all).\n\n-include_lib(\"common_test/include/ct.hrl\").\n\n%%--------------------------------------------------------------------\n%% COMMON TEST CALLBACK FUNCTIONS\n%%--------------------------------------------------------------------\n\n%%--------------------------------------------------------------------\n%% Function: suite() -> Info\n%%\n%% Info = [tuple()]\n%% List of key/value pairs.\n%%\n%% Description: Returns list of tuples to set default properties\n%% for the suite.\n%%\n%% Note: The suite/0 function is only meant to be used to return\n%% default data values, not perform any other operations.\n%%--------------------------------------------------------------------\nsuite() ->\n [{timetrap,{minutes,10}}].\n\n%%--------------------------------------------------------------------\n%% Function: init_per_suite(Config0) ->\n%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}\n%%\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%% Reason = term()\n%% The reason for skipping the suite.\n%%\n%% Description: Initialization before the suite.\n%%\n%% Note: This function is free to add any key/value pairs to the Config\n%% variable, but should NOT alter/remove any existing entries.\n%%--------------------------------------------------------------------\ninit_per_suite(Config) ->\n Config.\n\n%%--------------------------------------------------------------------\n%% Function: end_per_suite(Config0) -> term() | {save_config,Config1}\n%%\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%%\n%% Description: Cleanup after the suite.\n%%--------------------------------------------------------------------\nend_per_suite(_Config) ->\n ok.\n\n%%--------------------------------------------------------------------\n%% Function: init_per_group(GroupName, Config0) ->\n%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}\n%%\n%% GroupName = atom()\n%% Name of the test case group that is about to run.\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding configuration data for the group.\n%% Reason = term()\n%% The reason for skipping all test cases and subgroups in the group.\n%%\n%% Description: Initialization before each test case group.\n%%--------------------------------------------------------------------\ninit_per_group(_GroupName, Config) ->\n Config.\n\n%%--------------------------------------------------------------------\n%% Function: end_per_group(GroupName, Config0) ->\n%% term() | {save_config,Config1}\n%%\n%% GroupName = atom()\n%% Name of the test case group that is finished.\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding configuration data for the group.\n%%\n%% Description: Cleanup after each test case group.\n%%--------------------------------------------------------------------\nend_per_group(_GroupName, _Config) ->\n ok.\n\n%%--------------------------------------------------------------------\n%% Function: init_per_testcase(TestCase, Config0) ->\n%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}\n%%\n%% TestCase = atom()\n%% Name of the test case that is about to run.\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%% Reason = term()\n%% The reason for skipping the test case.\n%%\n%% Description: Initialization before each test case.\n%%\n%% Note: This function is free to add any key/value pairs to the Config\n%% variable, but should NOT alter/remove any existing entries.\n%%--------------------------------------------------------------------\ninit_per_testcase(_TestCase, Config) ->\n Config.\n\n%%--------------------------------------------------------------------\n%% Function: end_per_testcase(TestCase, Config0) ->\n%% term() | {save_config,Config1} | {fail,Reason}\n%%\n%% TestCase = atom()\n%% Name of the test case that is finished.\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%% Reason = term()\n%% The reason for failing the test case.\n%%\n%% Description: Cleanup after each test case.\n%%--------------------------------------------------------------------\nend_per_testcase(_TestCase, _Config) ->\n ok.\n\n%%--------------------------------------------------------------------\n%% Function: groups() -> [Group]\n%%\n%% Group = {GroupName,Properties,GroupsAndTestCases}\n%% GroupName = atom()\n%% The name of the group.\n%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]\n%% Group properties that may be combined.\n%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]\n%% TestCase = atom()\n%% The name of a test case.\n%% Shuffle = shuffle | {shuffle,Seed}\n%% To get cases executed in random order.\n%% Seed = {integer(),integer(),integer()}\n%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |\n%% repeat_until_any_ok | repeat_until_any_fail\n%% To get execution of cases repeated.\n%% N = integer() | forever\n%%\n%% Description: Returns a list of test case group definitions.\n%%--------------------------------------------------------------------\ngroups() ->\n [].\n\n%%--------------------------------------------------------------------\n%% Function: all() -> GroupsAndTestCases | {skip,Reason}\n%%\n%% GroupsAndTestCases = [{group,GroupName} | TestCase]\n%% GroupName = atom()\n%% Name of a test case group.\n%% TestCase = atom()\n%% Name of a test case.\n%% Reason = term()\n%% The reason for skipping all groups and test cases.\n%%\n%% Description: Returns the list of groups and test cases that\n%% are to be executed.\n%%--------------------------------------------------------------------\nall() ->\n [my_test_case].\n\n\n%%--------------------------------------------------------------------\n%% TEST CASES\n%%--------------------------------------------------------------------\n\n%%--------------------------------------------------------------------\n%% Function: TestCase() -> Info\n%%\n%% Info = [tuple()]\n%% List of key/value pairs.\n%%\n%% Description: Test case info function - returns list of tuples to set\n%% properties for the test case.\n%%\n%% Note: This function is only meant to be used to return a list of\n%% values, not perform any other operations.\n%%--------------------------------------------------------------------\nmy_test_case() ->\n [].\n\n%%--------------------------------------------------------------------\n%% Function: TestCase(Config0) ->\n%% ok | exit() | {skip,Reason} | {comment,Comment} |\n%% {save_config,Config1} | {skip_and_save,Reason,Config1}\n%%\n%% Config0 = Config1 = [tuple()]\n%% A list of key/value pairs, holding the test case configuration.\n%% Reason = term()\n%% The reason for skipping the test case.\n%% Comment = term()\n%% A comment about the test case that will be printed in the html log.\n%%\n%% Description: Test case function. (The name of it must be specified in\n%% the all/0 list or in a test case group for the test case\n%% to be executed).\n%%--------------------------------------------------------------------\nmy_test_case(_Config) ->\n ok.\n```\n\n_Small Common Test Suite_\n\n```erlang\n%%%-------------------------------------------------------------------\n%%% File : example_SUITE.erl\n%%% Author :\n%%% Description :\n%%%\n%%% Created :\n%%%-------------------------------------------------------------------\n-module(example_SUITE).\n\n-compile(export_all).\n\n-include_lib(\"common_test/include/ct.hrl\").\n\n%%--------------------------------------------------------------------\n%% Function: suite() -> Info\n%% Info = [tuple()]\n%%--------------------------------------------------------------------\nsuite() ->\n [{timetrap,{seconds,30}}].\n\n%%--------------------------------------------------------------------\n%% Function: init_per_suite(Config0) ->\n%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}\n%% Config0 = Config1 = [tuple()]\n%% Reason = term()\n%%--------------------------------------------------------------------\ninit_per_suite(Config) ->\n Config.\n\n%%--------------------------------------------------------------------\n%% Function: end_per_suite(Config0) -> term() | {save_config,Config1}\n%% Config0 = Config1 = [tuple()]\n%%--------------------------------------------------------------------\nend_per_suite(_Config) ->\n ok.\n\n%%--------------------------------------------------------------------\n%% Function: init_per_group(GroupName, Config0) ->\n%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}\n%% GroupName = atom()\n%% Config0 = Config1 = [tuple()]\n%% Reason = term()\n%%--------------------------------------------------------------------\ninit_per_group(_GroupName, Config) ->\n Config.\n\n%%--------------------------------------------------------------------\n%% Function: end_per_group(GroupName, Config0) ->\n%% term() | {save_config,Config1}\n%% GroupName = atom()\n%% Config0 = Config1 = [tuple()]\n%%--------------------------------------------------------------------\nend_per_group(_GroupName, _Config) ->\n ok.\n\n%%--------------------------------------------------------------------\n%% Function: init_per_testcase(TestCase, Config0) ->\n%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}\n%% TestCase = atom()\n%% Config0 = Config1 = [tuple()]\n%% Reason = term()\n%%--------------------------------------------------------------------\ninit_per_testcase(_TestCase, Config) ->\n Config.\n\n%%--------------------------------------------------------------------\n%% Function: end_per_testcase(TestCase, Config0) ->\n%% term() | {save_config,Config1} | {fail,Reason}\n%% TestCase = atom()\n%% Config0 = Config1 = [tuple()]\n%% Reason = term()\n%%--------------------------------------------------------------------\nend_per_testcase(_TestCase, _Config) ->\n ok.\n\n%%--------------------------------------------------------------------\n%% Function: groups() -> [Group]\n%% Group = {GroupName,Properties,GroupsAndTestCases}\n%% GroupName = atom()\n%% Properties = [parallel | sequence | Shuffle | {RepeatType,N}]\n%% GroupsAndTestCases = [Group | {group,GroupName} | TestCase]\n%% TestCase = atom()\n%% Shuffle = shuffle | {shuffle,{integer(),integer(),integer()}}\n%% RepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |\n%% repeat_until_any_ok | repeat_until_any_fail\n%% N = integer() | forever\n%%--------------------------------------------------------------------\ngroups() ->\n [].\n\n%%--------------------------------------------------------------------\n%% Function: all() -> GroupsAndTestCases | {skip,Reason}\n%% GroupsAndTestCases = [{group,GroupName} | TestCase]\n%% GroupName = atom()\n%% TestCase = atom()\n%% Reason = term()\n%%--------------------------------------------------------------------\nall() ->\n [my_test_case].\n\n%%--------------------------------------------------------------------\n%% Function: TestCase() -> Info\n%% Info = [tuple()]\n%%--------------------------------------------------------------------\nmy_test_case() ->\n [].\n\n%%--------------------------------------------------------------------\n%% Function: TestCase(Config0) ->\n%% ok | exit() | {skip,Reason} | {comment,Comment} |\n%% {save_config,Config1} | {skip_and_save,Reason,Config1}\n%% Config0 = Config1 = [tuple()]\n%% Reason = term()\n%% Comment = term()\n%%--------------------------------------------------------------------\nmy_test_case(_Config) ->\n ok.\n```","title":"Test Suite Templates - Examples and Templates","ref":"example_chapter.html#test-suite-templates"},{"type":"extras","doc":"\n# Running Tests and Analyzing Results","title":"Running Tests and Analyzing Results","ref":"run_test_chapter.html"},{"type":"extras","doc":"The `Common Test` framework provides a high-level operator interface for\ntesting, providing the following features:\n\n- Automatic compilation of test suites (and help modules)\n- Creation of extra HTML pages for improved overview.\n- Single-command interface for running all available tests\n- Handling of configuration files specifying data related to the System Under\n Test (SUT) (and any other variable data)\n- Mode for running multiple independent test sessions in parallel with central\n control and configuration","title":"Using the Common Test Framework - Running Tests and Analyzing Results","ref":"run_test_chapter.html#using-the-common-test-framework"},{"type":"extras","doc":"When `Common Test` starts, it automatically attempts to compile any suites\nincluded in the specified tests. If particular suites are specified, only those\nsuites are compiled. If a particular test object directory is specified (meaning\nall suites in this directory are to be part of the test), `Common Test` runs\nfunction `make:all/1` in the directory to compile the suites.\n\nIf compilation fails for one or more suites, the compilation errors are printed\nto tty and the operator is asked if the test run is to proceed without the\nmissing suites, or be aborted. If the operator chooses to proceed, the tests\nhaving missing suites are noted in the HTML log. If `Common Test` is unable to\nprompt the user after compilation failure (if `Common Test` does not control\n`stdin`), the test run proceeds automatically without the missing suites. This\nbehavior can however be modified with the `ct_run` flag\n`-abort_if_missing_suites`, or the `ct:run_test/1` option\n`{abort_if_missing_suites,TrueOrFalse}`. If `abort_if_missing_suites` is set to\n`true`, the test run stops immediately if some suites fail to compile.\n\nAny help module (that is, regular Erlang module with name not ending with\n\"\\_SUITE\") that resides in the same test object directory as a suite, which is\npart of the test, is also automatically compiled. A help module is not mistaken\nfor a test suite (unless it has a \"\\_SUITE\" name). All help modules in a\nparticular test object directory are compiled, no matter if all or only\nparticular suites in the directory are part of the test.\n\nIf test suites or help modules include header files stored in other locations\nthan the test directory, these include directories can be specified by using\nflag `-include` with [`ct_run`](ct_run_cmd.md), or option `include` with\n`ct:run_test/1`. Also, an include path can be specified with an OS environment\nvariable, `CT_INCLUDE_PATH`.\n\n_Example (bash):_\n\n`$ export CT_INCLUDE_PATH=~testuser/common_suite_files/include:~testuser/common_lib_files/include`\n\n`Common Test` passes all include directories (specified either with flag/option\n`include`, or variable `CT_INCLUDE_PATH` , or both, to the compiler.\n\nInclude directories can also be specified in test specifications, see\n[Test Specifications](run_test_chapter.md#test_specifications).\n\nIf the user wants to run all test suites for a test object (or an OTP\napplication) by specifying only the top directory (for example, with start\nflag/option `dir`), `Common Test` primarily looks for test suite modules in a\nsubdirectory named `test`. If this subdirectory does not exist, the specified\ntop directory is assumed to be the test directory, and test suites are read from\nthere instead.\n\nTo disable the automatic compilation feature, use flag `-no_auto_compile` with\n`ct_run`, or option `{auto_compile,false}` with `ct:run_test/1`. With automatic\ncompilation disabled, the user is responsible for compiling the test suite\nmodules (and any help modules) before the test run. If the modules cannot be\nloaded from the local file system during startup of `Common Test`, the user must\npreload the modules before starting the test. `Common Test` only verifies that\nthe specified test suites exist (that is, that they are, or can be, loaded).\nThis is useful, for example, if the test suites are transferred and loaded as\nbinaries through RPC from a remote node.\n\n[](){: #ct_run }","title":"Automatic Compilation of Test Suites and Help Modules - Running Tests and Analyzing Results","ref":"run_test_chapter.html#automatic-compilation-of-test-suites-and-help-modules"},{"type":"extras","doc":"The [`ct_run`](ct_run_cmd.md) program can be used for running tests from the OS\ncommand line, for example, as follows:\n\n- `ct_run -config -dir `\n- `ct_run -config -suite `\n- `ct_run -userconfig -suite `\n- `ct_run -config -suite -group -case `\n\n_Examples:_\n\n```text\n$ ct_run -config $CFGS/sys1.cfg $CFGS/sys2.cfg -dir $SYS1_TEST $SYS2_TEST\n$ ct_run -userconfig ct_config_xml $CFGS/sys1.xml $CFGS/sys2.xml -dir $SYS1_TEST $SYS2_TEST\n$ ct_run -suite $SYS1_TEST/setup_SUITE $SYS2_TEST/config_SUITE\n$ ct_run -suite $SYS1_TEST/setup_SUITE -case start stop\n$ ct_run -suite $SYS1_TEST/setup_SUITE -group installation -case start stop\n```\n\nThe flags `dir`, `suite`, and `group/case` can be combined. For example, to run\n`x_SUITE` and `y_SUITE` in directory `testdir`, as follows:\n\n```text\n$ ct_run -dir ./testdir -suite x_SUITE y_SUITE\n```\n\nThis has the same effect as the following:\n\n```text\n$ ct_run -suite ./testdir/x_SUITE ./testdir/y_SUITE\n```\n\nFor details, see\n[Test Case Group Execution](run_test_chapter.md#group_execution).\n\nThe following flags can also be used with [`ct_run`](ct_run_cmd.md):\n\n- **`-help`** - Lists all available start flags.\n\n- **`-logdir `** - Specifies where the HTML log files are to be written.\n\n- **`-label `** - Associates the test run with a name that\n gets printed in the overview HTML log files.\n\n- **`-refresh_logs`** - Refreshes the top-level HTML index files.\n\n- **`-shell`** - Starts interactive shell mode (described later).\n\n- **`-step [step_opts]`** - Steps through test cases using the Erlang Debugger\n (described later).\n\n- **`-spec `** - Uses test specification as input (described later).\n\n- **`-allow_user_terms`** - Allows user-specific terms in a test specification\n (described later).\n\n- **`-silent_connections [conn_types]`** - , tells `Common Test` to suppress\n printouts for specified connections (described later).\n\n- **`-stylesheet `** - Points out a user HTML style sheet (described\n later).\n\n- **`-cover `** - To perform code coverage test (see\n [Code Coverage Analysis](cover_chapter.md#cover)).\n\n- **`-cover_stop `** - To specify if the `cover` tool is to be stopped\n after the test is completed (see\n [Code Coverage Analysis](cover_chapter.md#cover_stop)).\n\n- **`-event_handler `** - To install\n [event handlers](event_handler_chapter.md#event_handling).\n\n- **`-event_handler_init `** - To install\n [event handlers](event_handler_chapter.md#event_handling) including start\n arguments.\n\n- **`-ct_hooks `** - To install\n [Common Test Hooks](ct_hooks_chapter.md#installing) including start arguments.\n\n- **`-ct_hooks_order [test|config]`** - To modify\n [Common Test Hooks](ct_hooks_chapter.md#installing) execution order.\n\n- **`-enable_builtin_hooks `** - To enable or disable\n [Built-in Common Test Hooks](ct_hooks_chapter.md#builtin_cths). Default is\n `true`.\n\n- **`-include`** - Specifies include directories (described earlier).\n\n- **`-no_auto_compile`** - Disables the automatic test suite compilation feature\n (described earlier).\n\n- **`-abort_if_missing_suites`** - Aborts the test run if one or more suites\n fail to compile (described earlier).\n\n- **`-multiply_timetraps `** - Extends\n [timetrap time-out](write_test_chapter.md#timetraps) values.\n\n- **`-scale_timetraps `** - Enables automatic\n [timetrap time-out](write_test_chapter.md#timetraps) scaling.\n\n- **`-repeat `** - Tells `Common Test` to repeat the tests `n` times\n (described later).\n\n- **`-duration `** - Tells `Common Test` to repeat the tests for duration\n of time (described later).\n\n- **`-until `** - Tells `Common Test` to repeat the tests until\n `stop_time` (described later).\n\n- **`-force_stop [skip_rest]`** - On time-out, the test run is aborted when the\n current test job is finished. If `skip_rest` is provided, the remaining test\n cases in the current test job are skipped (described later).\n\n- **`-decrypt_key `** - Provides a decryption key for\n [encrypted configuration files](config_file_chapter.md#encrypted_config_files).\n\n- **`-decrypt_file `** - Points out a file containing a decryption key\n for\n [encrypted configuration files](config_file_chapter.md#encrypted_config_files).\n\n- **`-basic_html`** - Switches off HTML enhancements that can be incompatible\n with older browsers.\n\n- **`-logopts `** - Enables modification of the logging behavior, see\n [Log options](run_test_chapter.md#logopts).\n\n- **`-verbosity `** - Sets\n [verbosity levels for printouts](write_test_chapter.md#logging).\n\n- **`-no_esc_chars`** - Disables automatic escaping of special HTML characters.\n See the [Logging chapter](write_test_chapter.md#logging).\n\n> #### Note {: .info }\n>\n> Directories passed to `Common Test` can have either relative or absolute\n> paths.\n\n> #### Note {: .info }\n>\n> Any start flags to the Erlang runtime system (application ERTS) can also be\n> passed as parameters to `ct_run`. It is, for example, useful to be able to\n> pass directories to be added to the Erlang code server search path with flag\n> `-pa` or `-pz`. If you have common help- or library modules for test suites\n> (separately compiled), stored in other directories than the test suite\n> directories, these `help/lib` directories are preferably added to the code\n> path this way.\n>\n> _Example:_\n>\n> `$ ct_run -dir ./chat_server -logdir ./chat_server/testlogs -pa $PWD/chat_server/ebin`\n>\n> The absolute path of directory `chat_server/ebin` is here passed to the code\n> server. This is essential because relative paths are stored by the code server\n> as relative, and `Common Test` changes the current working directory of ERTS\n> during the test run.\n\nThe `ct_run` program sets the exit status before shutting down. The following\nvalues are defined:\n\n- `0` indicates a successful testrun, that is, without failed or auto-skipped\n test cases.\n- `1` indicates that one or more test cases have failed, or have been\n auto-skipped.\n- `2` indicates that the test execution has failed because of, for example,\n compilation errors, or an illegal return value from an information function.\n\nIf auto-skipped test cases do not affect the exit status. The default behavior\ncan be changed using start flag:\n\n```text\n-exit_status ignore_config\n```\n\n> #### Note {: .info }\n>\n> Executing `ct_run` without start flags is equal to the command:\n> `ct_run -dir ./`\n\nFor more information about the `ct_run` program, see module\n[`ct_run`](ct_run_cmd.md) and section\n[Installation](install_chapter.md#general).\n\n[](){: #erlang_shell_or_program }","title":"Running Tests from the OS Command Line - Running Tests and Analyzing Results","ref":"run_test_chapter.html#running-tests-from-the-os-command-line"},{"type":"extras","doc":"`Common Test` provides an Erlang API for running tests. The main (and most\nflexible) function for specifying and executing tests is `ct:run_test/1`. It\ntakes the same start parameters as [`ct_run`](run_test_chapter.md#ct_run), but\nthe flags are instead specified as options in a list of key-value tuples. For\nexample, a test specified with `ct_run` as follows:\n\n`$ ct_run -suite ./my_SUITE -logdir ./results`\n\nis with `ct:run_test/1` specified as:\n\n`1> ct:run_test([{suite,\"./my_SUITE\"},{logdir,\"./results\"}]).`\n\nThe function returns the test result, represented by the tuple\n`{Ok,Failed,{UserSkipped,AutoSkipped}}`, where each element is an integer. If\ntest execution fails, the function returns the tuple `{error,Reason}`, where the\nterm `Reason` explains the failure.\n\nThe default start option `{dir,Cwd}` (to run all suites in the current working\ndirectory) is used if the function is called with an empty list of options.","title":"Running Tests from the Erlang Shell or from an Erlang Program - Running Tests and Analyzing Results","ref":"run_test_chapter.html#running-tests-from-the-erlang-shell-or-from-an-erlang-program"},{"type":"extras","doc":"During execution of tests started with `ct:run_test/1`, the Erlang shell\nprocess, controlling `stdin`, remains the top-level process of the `Common Test`\nsystem of processes. Consequently, the Erlang shell is not available for\ninteraction during the test run. If this is not desirable, for example, because\nthe shell is needed for debugging purposes or for interaction with the SUT\nduring test execution, set start option `release_shell` to `true` (in the call\nto `ct:run_test/1` or by using the corresponding test specification term,\ndescribed later). This makes `Common Test` release the shell immediately after\nthe test suite compilation stage. To accomplish this, a test runner process is\nspawned to take control of the test execution. The effect is that\n`ct:run_test/1` returns the pid of this process rather than the test result,\nwhich instead is printed to tty at the end of the test run.\n\n> #### Note {: .info }\n>\n> To use the functions [`ct:break/1,2`](`ct:break/1`) and\n> [`ct:continue/0,1`](`ct:continue/0`), `release_shell` _must_ be set to `true`.\n\nFor details, see `ct:run_test/1` manual page.\n\n[](){: #group_execution }","title":"Releasing the Erlang Shell - Running Tests and Analyzing Results","ref":"run_test_chapter.html#releasing-the-erlang-shell"},{"type":"extras","doc":"With the `ct_run` flag, or `ct:run_test/1` option `group`, one or more test case\ngroups can be specified, optionally in combination with specific test cases. The\nsyntax for specifying groups on the command line is as follows:\n\n```text\n$ ct_run -group [-case ]\n```\n\nThe syntax in the Erlang shell is as follows:\n\n```erlang\n1> ct:run_test([{group,GroupsNamesOrPaths}, {case,Cases}]).\n```\n\nParameter `group_names_or_paths` specifies one or more group names and/or one or\nmore group paths. At startup, `Common Test` searches for matching groups in the\ngroup definitions tree (that is, the list returned from `Suite:groups/0`; for\ndetails, see section [Test Case Groups](write_test_chapter.md#test_case_groups).\n\nGiven a group name, say `g`, `Common Test` searches for all paths leading to\n`g`. By path is meant a sequence of nested groups, which must be followed to get\nfrom the top-level group to `g`. To execute the test cases in group `g`,\n`Common Test` must call the `init_per_group/2` function for each group in the\npath to `g`, and all corresponding `end_per_group/2` functions afterwards. This\nis because the configuration of a test case in `g` (and its `Config` input data)\ndepends on `init_per_testcase(TestCase, Config)` and its return value, which in\nturn depends on `init_per_group(g, Config)` and its return value, which in turn\ndepends on `init_per_group/2` of the group above `g`, and so on, all the way up\nto the top-level group.\n\nThis means that if there is more than one way to locate a group (and its test\ncases) in a path, the result of the group search operation is a number of tests,\nall of which are to be performed. `Common Test` interprets a group specification\nthat consists of a single name as follows:\n\n\"Search and find all paths in the group definitions tree that lead to the\nspecified group and, for each path, create a test that does the following, in\norder:\n\n1. Executes all configuration functions in the path to the specified group.\n1. Executes all, or all matching, test cases in this group.\n1. Executes all, or all matching, test cases in all subgroups of the group.\"\n\nThe user can specify a specific group path with parameter\n`group_names_or_paths`. With this type of specification execution of unwanted\ngroups (in otherwise matching paths), and/or the execution of subgroups can be\navoided. The command line syntax of the group path is a list of group names in\nthe path, for example:\n\n`$ ct_run -suite \"./x_SUITE\" -group [g1,g3,g4] -case tc1 tc5`\n\nThe syntax in the Erlang shell is as follows (requires a list within the groups\nlist):\n\n`1> ct:run_test([{suite,\"./x_SUITE\"}, {group,[[g1,g3,g4]]}, {testcase,[tc1,tc5]}]).`\n\nThe last group in the specified path is the terminating group in the test, that\nis, no subgroups following this group are executed. In the previous example,\n`g4` is the terminating group. Hence, `Common Test` executes a test that calls\nall `init` configuration functions in the path to `g4`, that is, `g1..g3..g4`.\nIt then calls test cases `tc1` and `tc5` in `g4`, and finally all `end`\nconfiguration functions in order `g4..g3..g1`.\n\n> #### Note {: .info }\n>\n> The group path specification does not necessarily have to include _all_ groups\n> in the path to the terminating group. `Common Test` searches for all matching\n> paths if an incomplete group path is specified.\n\n> #### Note {: .info }\n>\n> Group names and group paths can be combined with parameter\n> `group_names_or_paths`. Each element is treated as an individual specification\n> in combination with parameter `cases`. The following examples illustrates\n> this.\n\n_Examples:_\n\n```erlang\n-module(x_SUITE).\n...\n%% The group definitions:\ngroups() ->\n [{top1,[],[tc11,tc12,\n {sub11,[],[tc12,tc13]},\n {sub12,[],[tc14,tc15,\n \t\t {sub121,[],[tc12,tc16]}]}]},\n\n {top2,[],[{group,sub21},{group,sub22}]},\n {sub21,[],[tc21,{group,sub2X2}]},\n {sub22,[],[{group,sub221},tc21,tc22,{group,sub2X2}]},\n {sub221,[],[tc21,tc23]},\n {sub2X2,[],[tc21,tc24]}].\n```\n\nThe following executes two tests, one for all cases and all subgroups under\n`top1`, and one for all under `top2`:\n\n```text\n$ ct_run -suite \"x_SUITE\" -group all\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,all}]).\n```\n\nUsing `-group top1 top2`, or `{group,[top1,top2]}` gives the same result.\n\nThe following executes one test for all cases and subgroups under `top1`:\n\n```text\n$ ct_run -suite \"x_SUITE\" -group top1\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,[top1]}]).\n```\n\nThe following runs a test executing `tc12` in `top1` and any subgroup under\n`top1` where it can be found (`sub11` and `sub121`):\n\n```text\n$ ct_run -suite \"x_SUITE\" -group top1 -case tc12\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,[top1]}, {testcase,[tc12]}]).\n```\n\nThe following executes `tc12` _only_ in group `top1`:\n\n```text\n$ ct_run -suite \"x_SUITE\" -group [top1] -case tc12\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,[[top1]]}, {testcase,[tc12]}]).\n```\n\nThe following searches `top1` and all its subgroups for `tc16` resulting in that\nthis test case executes in group `sub121`:\n\n```text\n$ ct_run -suite \"x_SUITE\" -group top1 -case tc16\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,[top1]}, {testcase,[tc16]}]).\n```\n\nUsing the specific path `-group [sub121]` or `{group,[[sub121]]}` gives the same\nresult in this example.\n\nThe following executes two tests, one including all cases and subgroups under\n`sub12`, and one with _only_ the test cases in `sub12`:\n\n```text\n$ ct_run -suite \"x_SUITE\" -group sub12 [sub12]\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,[sub12,[sub12]]}]).\n```\n\nIn the following example, `Common Test` finds and executes two tests, one for\nthe path from `top2` to `sub2X2` through `sub21`, and one from `top2` to\n`sub2X2` through `sub22`:\n\n```text\n$ ct_run -suite \"x_SUITE\" -group sub2X2\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,[sub2X2]}]).\n```\n\nIn the following example, by specifying the unique path\n`top2 -> sub21 -> sub2X2`, only one test is executed. The second possible path,\nfrom `top2` to `sub2X2` (from the former example) is discarded:\n\n```text\n$ ct_run -suite \"x_SUITE\" -group [sub21,sub2X2]\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,[[sub21,sub2X2]]}]).\n```\n\nThe following executes only the test cases for `sub22` and in reverse order\ncompared to the group definition:\n\n```text\n$ ct_run -suite \"x_SUITE\" -group [sub22] -case tc22 tc21\n```\n```erlang\n1> ct:run_test([{suite,\"x_SUITE\"}, {group,[[sub22]]}, {testcase,[tc22,tc21]}]).\n```\n\nIf a test case belonging to a group (according to the group definition) is\nexecuted without a group specification, that is, simply by (using the command\nline):\n\n`$ ct_run -suite \"my_SUITE\" -case my_tc`\n\nor (using the Erlang shell):\n\n`1> ct:run_test([{suite,\"my_SUITE\"}, {testcase,my_tc}]).`\n\nthen `Common Test` ignores the group definition and executes the test case in\nthe scope of the test suite only (no group configuration functions are called).\n\nThe group specification feature, as presented in this section, can also be used\nin [Test Specifications](run_test_chapter.md#test_specifications) (with some\nextra features added).","title":"Test Case Group Execution - Running Tests and Analyzing Results","ref":"run_test_chapter.html#test-case-group-execution"},{"type":"extras","doc":"You can start `Common Test` in an interactive shell mode where no automatic\ntesting is performed. Instead, `Common Test` starts its utility processes,\ninstalls configuration data (if any), and waits for the user to call functions\n(typically test case support functions) from the Erlang shell.\n\nThe shell mode is useful, for example, for debugging test suites, analyzing and\ndebugging the SUT during \"simulated\" test case execution, and trying out various\noperations during test suite development.\n\nTo start the interactive shell mode, start an Erlang shell manually and call\n`ct:install/1` to install any configuration data you might need (use `[]` as\nargument otherwise). Then call `ct:start_interactive/0` to start `Common Test`.\n\nIf you use the `ct_run` program, you can start the Erlang shell and\n`Common Test` in one go by using the flag `-shell` and, optionally, flag\n`-config` and/or `-userconfig`.\n\n_Examples:_\n\n- `ct_run -shell`\n- `ct_run -shell -config cfg/db.cfg`\n- `ct_run -shell -userconfig db_login testuser x523qZ`\n\nIf no configuration file is specified with command `ct_run`, a warning is\ndisplayed. If `Common Test` has been run from the same directory earlier, the\nsame configuration file(s) are used again. If `Common Test` has not been run\nfrom this directory before, no configuration files are available.\n\nIf any functions using \"required configuration data\" (for example, functions\n`ct_telnet` or `ct_ftp`) are to be called from the Erlang shell, first require\nconfiguration data with [`ct:require/1,2`](`ct:require/1`). This is equivalent\nto a `require` statement in the\n[Test Suite Information Function](write_test_chapter.md#suite) or in the\n[Test Case Information Function](write_test_chapter.md#info_function).\n\n_Example:_\n\n```erlang\n1> ct:require(unix_telnet, unix).\nok\n2> ct_telnet:open(unix_telnet).\n{ok,<0.105.0>}\n4> ct_telnet:cmd(unix_telnet, \"ls .\").\n{ok,[\"ls .\",\"file1 ...\",...]}\n```\n\nEverything that `Common Test` normally prints in the test case logs, are in the\ninteractive mode written to a log named `ctlog.html` in directory\n`ct_run. `. A link to this file is available in the file named\n`last_interactive.html` in the directory from which you execute `ct_run`.\nSpecifying a different root directory for the logs than the current working\ndirectory is not supported.\n\nIf you wish to exit the interactive mode (for example, to start an automated\ntest run with `ct:run_test/1`), call function `ct:stop_interactive/0`. This\nshuts down the running `ct` application. Associations between configuration\nnames and data created with `require` are consequently deleted. Function\n`ct:start_interactive/0` takes you back into interactive mode, but the previous\nstate is not restored.","title":"Running the Interactive Shell Mode - Running Tests and Analyzing Results","ref":"run_test_chapter.html#running-the-interactive-shell-mode"},{"type":"extras","doc":"Using `ct_run -step [opts]`, or by passing option `{step,Opts}` to\n`ct:run_test/1`, the following is possible:\n\n- Get the Erlang Debugger started automatically.\n- Use its graphical interface to investigate the state of the current test case.\n- Execute the test case step-by-step and/or set execution breakpoints.\n\nIf no extra options are specified with flag/option `step`, breakpoints are set\nautomatically on the test cases that are to be executed by `Common Test`, and\nthose functions only. If step option `config` is specified, breakpoints are also\ninitially set on the configuration functions in the suite, that is,\n`init_per_suite/1`, `end_per_suite/1`, `init_per_group/2`, `end_per_group/2`,\n`init_per_testcase/2` and `end_per_testcase/2`.\n\n`Common Test` enables the Debugger auto-attach feature, which means that for\nevery new interpreted test case function that starts to execute, a new trace\nwindow automatically pops up (as each test case executes on a dedicated Erlang\nprocess). Whenever a new test case starts, `Common Test` attempts to close the\ninactive trace window of the previous test case. However, if you prefer\n`Common Test` to leave inactive trace windows, use option `keep_inactive`.\n\nThe step functionality can be used together with flag/option `suite` and `suite`\n\\+ `case/testcase`, but not together with `dir`.\n\n[](){: #test_specifications }","title":"Step-by-Step Execution of Test Cases with the Erlang Debugger - Running Tests and Analyzing Results","ref":"run_test_chapter.html#step-by-step-execution-of-test-cases-with-the-erlang-debugger"},{"type":"extras","doc":"","title":"Test Specifications - Running Tests and Analyzing Results","ref":"run_test_chapter.html#test-specifications"},{"type":"extras","doc":"The most flexible way to specify what to test, is to use a test specification,\nwhich is a sequence of Erlang terms. The terms are normally declared in one or\nmore text files (see `ct:run_test/1`), but can also be passed to `Common Test`\non the form of a list (see `ct:run_testspec/1`). There are two general types of\nterms: configuration terms and test specification terms.\n\nWith configuration terms it is, for example, possible to do the following:\n\n- Label the test run (similar to `ct_run -label`).\n- Evaluate any expressions before starting the test.\n- Import configuration data (similar to `ct_run -config/-userconfig`).\n- Specify the top-level HTML log directory (similar to `ct_run -logdir`).\n- Enable code coverage analysis (similar to `ct_run -cover`).\n- Install `Common Test Hooks` (similar to `ct_run -ch_hooks`).\n- Install `event_handler` plugins (similar to `ct_run -event_handler`).\n- Specify include directories to be passed to the compiler for automatic\n compilation (similar to `ct_run -include`).\n- Disable the auto-compilation feature (similar to `ct_run -no_auto_compile`).\n- Set verbosity levels (similar to `ct_run -verbosity`).\n\nConfiguration terms can be combined with `ct_run` start flags or `ct:run_test/1`\noptions. The result is, for some flags/options and terms, that the values are\nmerged (for example, configuration files, include directories, verbosity levels,\nand silent connections) and for others that the start flags/options override the\ntest specification terms (for example, log directory, label, style sheet, and\nauto-compilation).\n\nWith test specification terms, it is possible to state exactly which tests to\nrun and in which order. A test term specifies either one or more suites, one or\nmore test case groups (possibly nested), or one or more test cases in a group\n(or in multiple groups) or in a suite.\n\nAny number of test terms can be declared in sequence. `Common Test` compiles by\ndefault the terms into one or more tests to be performed in one resulting test\nrun. A term that specifies a set of test cases \"swallows\" one that only\nspecifies a subset of these cases. For example, the result of merging one term\nspecifying that all cases in suite S are to be executed, with another term\nspecifying only test case X and Y in S, is a test of all cases in S. However, if\na term specifying test case X and Y in S is merged with a term specifying case Z\nin S, the result is a test of X, Y, and Z in S. To disable this behavior, that\nis, to instead perform each test sequentially in a \"script-like\" manner, set\nterm `merge_tests` to `false` in the test specification.\n\nA test term can also specify one or more test suites, groups, or test cases to\nbe skipped. Skipped suites, groups, and cases are not executed and show up in\nthe HTML log files as `SKIPPED`.","title":"General Description - Running Tests and Analyzing Results","ref":"run_test_chapter.html#general-description"},{"type":"extras","doc":"When multiple test specification files are specified at startup (either with\n`ct_run -spec file1 file2 ...` or `ct:run_test([{spec, [File1,File2,...]}])`),\n`Common Test` either executes one test run per specification file, or joins the\nfiles and performs all tests within one single test run. The first behavior is\nthe default one. The latter requires that start flag/option `join_specs` is\nprovided, for example,\n`run_test -spec ./my_tests1.ts ./my_tests2.ts -join_specs`.\n\nJoining a number of specifications, or running them separately, can also be\naccomplished with (and can be combined with) test specification file inclusion.","title":"Using Multiple Test Specification Files - Running Tests and Analyzing Results","ref":"run_test_chapter.html#using-multiple-test-specification-files"},{"type":"extras","doc":"With the term `specs`, a test specification can include other specifications. An\nincluded specification can either be joined with the source specification or\nused to produce a separate test run (as with start flag/option `join_specs`\nabove).\n\n_Example:_\n\n```erlang\n%% In specification file \"a.spec\"\n{specs, join, [\"b.spec\", \"c.spec\"]}.\n{specs, separate, [\"d.spec\", \"e.spec\"]}.\n%% Config and test terms follow\n...\n```\n\nIn this example, the test terms defined in files \"b.spec\" and \"c.spec\" are\njoined with the terms in source specification \"a.spec\" (if any). The inclusion\nof specifications \"d.spec\" and \"e.spec\" results in two separate, and\nindependent, test runs (one for each included specification).\n\nOption `join` does not imply that the test terms are merged, only that all tests\nare executed in one single test run.\n\nJoined specifications share common configuration settings, such as the list of\n`config` files or `include` directories. For configurations that cannot be\ncombined, such as settings for `logdir` or `verbosity`, it is up to the user to\nensure there are no clashes when the test specifications are joined.\nSpecifications included with option `separate` do not share configuration\nsettings with the source specification. This is useful, for example, if there\nare clashing configuration settings in included specifications, making it them\nimpossible to join.\n\nIf `{merge_tests,true}` is set in the source specification (which is the default\nsetting), terms in joined specifications are merged with terms in the source\nspecification (according to the description of `merge_tests` earlier).\n\nNotice that it is always the `merge_tests` setting in the source specification\nthat is used when joined with other specifications. Say, for example, that a\nsource specification A, with tests TA1 and TA2, has `{merge_tests,false}` set,\nand that it includes another specification, B, with tests TB1 and TB2, that has\n`{merge_tests,true}` set. The result is that the test series\n`TA1,TA2,merge(TB1,TB2)` is executed. The opposite `merge_tests` settings would\nresult in the test series `merge(merge(TA1,TA2),TB1,TB2)`.\n\nThe term `specs` can be used to nest specifications, that is, have one\nspecification include other specifications, which in turn include others, and so\nno","title":"Test Specification File Inclusion - Running Tests and Analyzing Results","ref":"run_test_chapter.html#test-specification-file-inclusion"},{"type":"extras","doc":"When a test case group is specified, the resulting test executes function\n`init_per_group`, followed by all test cases and subgroups (including their\nconfiguration functions), and finally function `end_per_group`. Also, if\nparticular test cases in a group are specified, `init_per_group` and\n`end_per_group`, for the group in question, are called. If a group defined (in\n`Suite:groups/0`) as a subgroup of another group, is specified (or if particular\ntest cases of a subgroup are), `Common Test` calls the configuration functions\nfor the top-level groups and for the subgroup in question (making it possible to\npass configuration data all the way from `init_per_suite` down to the test cases\nin the subgroup).\n\nThe test specification uses the same mechanism for specifying test case groups\nthrough names and paths, as explained in section\n[Test Case Group Execution](run_test_chapter.md#group_execution), with the\naddition of element `GroupSpec`.\n\nElement `GroupSpec` makes it possible to specify group execution properties that\noverrides those in the group definition (that is, in `groups/0`). Execution\nproperties for subgroups might be overridden as well. This feature makes it\npossible to change properties of groups at the time of execution, without having\nto edit the test suite. The same feature is available for `group` elements in\nthe `Suite:all/0` list. For details and examples, see section\n[Test Case Groups](write_test_chapter.md#test_case_groups).","title":"Test Case Groups - Running Tests and Analyzing Results","ref":"run_test_chapter.html#test-case-groups"},{"type":"extras","doc":"Test specifications can be used to run tests both in a single test host\nenvironment and in a distributed `Common Test` environment (Large Scale\nTesting). The node parameters in term `init` are only relevant in the latter\n(see section [Test Specifications](ct_master_chapter.md#test_specifications) in\nLarge Scale Testing). For details about the various terms, see the corresponding\nsections in the User's Guide, for example, the following:\n\n- The [`ct_run` program](run_test_chapter.md#ct_run) for an overview of\n available start flags (as most flags have a corresponding configuration term)\n- [Logging](write_test_chapter.md#logging) (for terms `verbosity`, `stylesheet`,\n `basic_html` and `esc_chars`)\n- [External Configuration Data](config_file_chapter.md#top) (for terms `config`\n and `userconfig`)\n- [Event Handling](event_handler_chapter.md#event_handling) (for the\n `event_handler` term)\n- [Common Test Hooks](ct_hooks_chapter.md#installing) (for term `ct_hooks`)\n\n_Configuration terms:_\n\n```erlang\n{merge_tests, Bool}.\n\n{define, Constant, Value}.\n\n{specs, InclSpecsOption, TestSpecs}.\n\n{node, NodeAlias, Node}.\n\n{init, InitOptions}.\n{init, [NodeAlias], InitOptions}.\n\n{label, Label}.\n{label, NodeRefs, Label}.\n\n{verbosity, VerbosityLevels}.\n{verbosity, NodeRefs, VerbosityLevels}.\n\n{stylesheet, CSSFile}.\n{stylesheet, NodeRefs, CSSFile}.\n\n{silent_connections, ConnTypes}.\n{silent_connections, NodeRefs, ConnTypes}.\n\n{multiply_timetraps, N}.\n{multiply_timetraps, NodeRefs, N}.\n\n{scale_timetraps, Bool}.\n{scale_timetraps, NodeRefs, Bool}.\n\n{cover, CoverSpecFile}.\n{cover, NodeRefs, CoverSpecFile}.\n\n{cover_stop, Bool}.\n{cover_stop, NodeRefs, Bool}.\n\n{include, IncludeDirs}.\n{include, NodeRefs, IncludeDirs}.\n\n{auto_compile, Bool},\n{auto_compile, NodeRefs, Bool},\n\n{abort_if_missing_suites, Bool},\n{abort_if_missing_suites, NodeRefs, Bool},\n\n{config, ConfigFiles}.\n{config, ConfigDir, ConfigBaseNames}.\n{config, NodeRefs, ConfigFiles}.\n{config, NodeRefs, ConfigDir, ConfigBaseNames}.\n\n{userconfig, {CallbackModule, ConfigStrings}}.\n{userconfig, NodeRefs, {CallbackModule, ConfigStrings}}.\n\n{logdir, LogDir}.\n{logdir, NodeRefs, LogDir}.\n\n{logopts, LogOpts}.\n{logopts, NodeRefs, LogOpts}.\n\n{create_priv_dir, PrivDirOption}.\n{create_priv_dir, NodeRefs, PrivDirOption}.\n\n{event_handler, EventHandlers}.\n{event_handler, NodeRefs, EventHandlers}.\n{event_handler, EventHandlers, InitArgs}.\n{event_handler, NodeRefs, EventHandlers, InitArgs}.\n\n{ct_hooks, CTHModules}.\n{ct_hooks, NodeRefs, CTHModules}.\n\n{ct_hooks_order, CTHOrder}.\n\n{enable_builtin_hooks, Bool}.\n\n{basic_html, Bool}.\n{basic_html, NodeRefs, Bool}.\n\n{esc_chars, Bool}.\n{esc_chars, NodeRefs, Bool}.\n\n{release_shell, Bool}.\n```\n\n_Test terms:_\n\n```erlang\n{suites, Dir, Suites}.\n{suites, NodeRefs, Dir, Suites}.\n\n{groups, Dir, Suite, Groups}.\n{groups, NodeRefs, Dir, Suite, Groups}.\n\n{groups, Dir, Suite, Groups, {cases,Cases}}.\n{groups, NodeRefs, Dir, Suite, Groups, {cases,Cases}}.\n\n{cases, Dir, Suite, Cases}.\n{cases, NodeRefs, Dir, Suite, Cases}.\n\n{skip_suites, Dir, Suites, Comment}.\n{skip_suites, NodeRefs, Dir, Suites, Comment}.\n\n{skip_groups, Dir, Suite, GroupNames, Comment}.\n{skip_groups, NodeRefs, Dir, Suite, GroupNames, Comment}.\n\n{skip_cases, Dir, Suite, Cases, Comment}.\n{skip_cases, NodeRefs, Dir, Suite, Cases, Comment}.\n```\n\n[](){: #types } _Types:_\n\n```erlang\nBool = true | false\nConstant = atom()\nValue = term()\nInclSpecsOption = join | separate\nTestSpecs = string() | [string()]\nNodeAlias = atom()\nNode = node()\nNodeRef = NodeAlias | Node | master\nNodeRefs = all_nodes | [NodeRef] | NodeRef\nInitOptions = term()\nLabel = atom() | string()\nVerbosityLevels = integer() | [{Category,integer()}]\nCategory = atom()\nCSSFile = string()\nConnTypes = all | [atom()]\nN = integer()\nCoverSpecFile = string()\nIncludeDirs = string() | [string()]\nConfigFiles = string() | [string()]\nConfigDir = string()\nConfigBaseNames = string() | [string()]\nCallbackModule = atom()\nConfigStrings = string() | [string()]\nLogDir = string()\nLogOpts = [term()]\nPrivDirOption = auto_per_run | auto_per_tc | manual_per_tc\nEventHandlers = atom() | [atom()]\nInitArgs = [term()]\nCTHModules = [CTHModule |\n \t {CTHModule, CTHInitArgs} |\n \t {CTHModule, CTHInitArgs, CTHPriority}]\nCTHModule = atom()\nCTHInitArgs = term()\nCTHOrder = test | config\nDir = string()\nSuites = atom() | [atom()] | all\nSuite = atom()\nGroups = GroupPath | GroupSpec | [GroupSpec] | all\nGroupPath = [[GroupSpec]]\nGroupSpec = GroupName | {GroupName,Properties} | {GroupName,Properties,[GroupSpec]}\nGroupName = atom()\nGroupNames = GroupName | [GroupName]\nCases = atom() | [atom()] | all\nComment = string() | \"\"\n```\n\nThe difference between the `config` terms above is that with `ConfigDir`,\n`ConfigBaseNames` is a list of base names, that is, without directory paths.\n`ConfigFiles` must be full names, including paths. For example, the following\ntwo terms have the same meaning:\n\n```erlang\n{config, [\"/home/testuser/tests/config/nodeA.cfg\",\n \"/home/testuser/tests/config/nodeB.cfg\"]}.\n\n{config, \"/home/testuser/tests/config\", [\"nodeA.cfg\",\"nodeB.cfg\"]}.\n```\n\n> #### Note {: .info }\n>\n> Any relative paths, specified in the test specification, are relative to the\n> directory containing the test specification file if\n> `ct_run -spec TestSpecFile ...` or `ct:run:test([{spec,TestSpecFile},...])`\n> executes the test.\n>\n> The path is relative to the top-level log directory if\n> `ct:run:testspec(TestSpec)` executes the test.","title":"Test Specification Syntax - Running Tests and Analyzing Results","ref":"run_test_chapter.html#test-specification-syntax"},{"type":"extras","doc":"The term `define` introduces a constant that is used to replace the name\n`Constant` with `Value`, wherever it is found in the test specification. This\nreplacement occurs during an initial iteration through the test specification.\nConstants can be used anywhere in the test specification, for example, in any\nlists and tuples, and even in strings and inside the value part of other\nconstant definitions. A constant can also be part of a node name, but that is\nthe only place where a constant can be part of an atom.\n\n> #### Note {: .info }\n>\n> For the sake of readability, the name of the constant must always begin with\n> an uppercase letter, or a `$`, `?`, or `_`. This means that it must always be\n> single quoted (as the constant name is an atom, not text).\n\nThe main benefit of constants is that they can be used to reduce the size (and\navoid repetition) of long strings, such as file paths.\n\n_Examples:_\n\n```erlang\n%% 1a. no constant\n{config, \"/home/testuser/tests/config\", [\"nodeA.cfg\",\"nodeB.cfg\"]}.\n{suites, \"/home/testuser/tests/suites\", all}.\n\n%% 1b. with constant\n{define, 'TESTDIR', \"/home/testuser/tests\"}.\n{config, \"'TESTDIR'/config\", [\"nodeA.cfg\",\"nodeB.cfg\"]}.\n{suites, \"'TESTDIR'/suites\", all}.\n\n%% 2a. no constants\n{config, [testnode@host1, testnode@host2], \"../config\", [\"nodeA.cfg\",\"nodeB.cfg\"]}.\n{suites, [testnode@host1, testnode@host2], \"../suites\", [x_SUITE, y_SUITE]}.\n\n%% 2b. with constants\n{define, 'NODE', testnode}.\n{define, 'NODES', ['NODE'@host1, 'NODE'@host2]}.\n{config, 'NODES', \"../config\", [\"nodeA.cfg\",\"nodeB.cfg\"]}.\n{suites, 'NODES', \"../suites\", [x_SUITE, y_SUITE]}.\n```\n\nConstants make the test specification term `alias`, in previous versions of\n`Common Test`, redundant. This term is deprecated but remains supported in\nupcoming `Common Test` releases. Replacing `alias` terms with `define` is\nstrongly recommended though. An example of such replacement follows:\n\n```erlang\n%% using the old alias term\n{config, \"/home/testuser/tests/config/nodeA.cfg\"}.\n{alias, suite_dir, \"/home/testuser/tests/suites\"}.\n{groups, suite_dir, x_SUITE, group1}.\n\n%% replacing with constants\n{define, 'TestDir', \"/home/testuser/tests\"}.\n{define, 'CfgDir', \"'TestDir'/config\"}.\n{define, 'SuiteDir', \"'TestDir'/suites\"}.\n{config, 'CfgDir', \"nodeA.cfg\"}.\n{groups, 'SuiteDir', x_SUITE, group1}.\n```\n\nConstants can well replace term `node` also, but this still has a declarative\nvalue, mainly when used in combination with `NodeRefs == all_nodes` (see\n[Types](run_test_chapter.md#types)).","title":"Constants - Running Tests and Analyzing Results","ref":"run_test_chapter.html#constants"},{"type":"extras","doc":"Here follows a simple test specification example:\n\n```erlang\n{define, 'Top', \"/home/test\"}.\n{define, 'T1', \"'Top'/t1\"}.\n{define, 'T2', \"'Top'/t2\"}.\n{define, 'T3', \"'Top'/t3\"}.\n{define, 'CfgFile', \"config.cfg\"}.\n\n{logdir, \"'Top'/logs\"}.\n\n{config, [\"'T1'/'CfgFile'\", \"'T2'/'CfgFile'\", \"'T3'/'CfgFile'\"]}.\n\n{suites, 'T1', all}.\n{skip_suites, 'T1', [t1B_SUITE,t1D_SUITE], \"Not implemented\"}.\n{skip_cases, 'T1', t1A_SUITE, [test3,test4], \"Irrelevant\"}.\n{skip_cases, 'T1', t1C_SUITE, [test1], \"Ignore\"}.\n\n{suites, 'T2', [t2B_SUITE,t2C_SUITE]}.\n{cases, 'T2', t2A_SUITE, [test4,test1,test7]}.\n\n{skip_suites, 'T3', all, \"Not implemented\"}.\n```\n\nThe example specifies the following:\n\n- The specified `logdir` directory is used for storing the HTML log files (in\n subdirectories tagged with node name, date, and time).\n- The variables in the specified test system configuration files are imported\n for the test.\n- The first test to run includes all suites for system `t1`. Suites `t1B` and\n `t1D` are excluded from the test. Test cases `test3` and `test4` in `t1A` and\n `test1` case in `t1C` are also excluded from the test.\n- The second test to run is for system `t2`. The included suites are `t2B` and\n `t2C`. Test cases `test4`, `test1`, and `test7` in suite `t2A` are also\n included. The test cases are executed in the specified order.\n- The last test to run is for system `t3`. Here, all suites are skipped and this\n is explicitly noted in the log files.","title":"Example - Running Tests and Analyzing Results","ref":"run_test_chapter.html#example"},{"type":"extras","doc":"With term `init` it is possible to specify initialization options for nodes\ndefined in the test specification. There are options to start the node and to\nevaluate any function on the node. For details, see section\n[Automatic Startup of Test Target Nodes](ct_master_chapter.md#ct_slave) in\nsection Using Common Test for Large Scale Testing.","title":"The init Term - Running Tests and Analyzing Results","ref":"run_test_chapter.html#the-init-term"},{"type":"extras","doc":"The user can provide a test specification including (for `Common Test`)\nunrecognizable terms. If this is desired, use flag `-allow_user_terms` when\nstarting tests with `ct_run`. This forces `Common Test` to ignore unrecognizable\nterms. In this mode, `Common Test` is not able to check the specification for\nerrors as efficiently as if the scanner runs in default mode. If `ct:run_test/1`\nis used for starting the tests, the relaxed scanner mode is enabled by tuple\n`{allow_user_terms,true}`.","title":"User-Specific Terms - Running Tests and Analyzing Results","ref":"run_test_chapter.html#user-specific-terms"},{"type":"extras","doc":"Terms in the current test specification (that is, the specification that has\nbeen used to configure and run the current test) can be looked up. The function\n[`get_testspec_terms()`](`ct:get_testspec_terms/0`) returns a list of all test\nspecification terms (both configuration terms and test terms), and\n`get_testspec_terms(Tags)` returns the term (or a list of terms) matching the\ntag (or tags) in `Tags`.\n\nFor example, in the test specification:\n\n```erlang\n...\n{label, my_server_smoke_test}.\n{config, \"../../my_server_setup.cfg\"}.\n{config, \"../../my_server_interface.cfg\"}.\n...\n```\n\nAnd in, for example, a test suite or a `Common Test Hook` function:\n\n```erlang\n...\n[{label,[{_Node,TestType}]}, {config,CfgFiles}] =\n ct:get_testspec_terms([label,config]),\n\n[verify_my_server_cfg(TestType, CfgFile) || {Node,CfgFile} <- CfgFiles,\n Node == node()];\n...\n```\n\n[](){: #log_files }","title":"Reading Test Specification Terms - Running Tests and Analyzing Results","ref":"run_test_chapter.html#reading-test-specification-terms"},{"type":"extras","doc":"As the execution of the test suites proceed, events are logged in the following\nfour different ways:\n\n- Text to the operator console.\n- Suite-related information is sent to the major log file.\n- Case-related information is sent to the minor log file.\n- The HTML overview log file is updated with test results.\n- A link to all runs executed from a certain directory is written in the log\n named `all_runs.html` and direct links to all tests (the latest results) are\n written to the top-level `index.html`.\n\nTypically the operator, possibly running hundreds or thousands of test cases,\ndoes not want to fill the console with details about, or printouts from,\nspecific test cases. By default, the operator only sees the following:\n\n- A confirmation that the test has started and information about how many test\n cases are executed in total.\n- A small note about each failed test case.\n- A summary of all the run test cases.\n- A confirmation when the test run is complete.\n- Some special information, such as error reports, progress reports, and\n printouts written with `erlang:display/1`, or `io:format/3` specifically\n addressed to a receiver other than [`standard_io`](`t:io:standard_io/0`) (for\n example, the default group leader process `user`).\n\nTo dig deeper into the general results, or the result of a specific test case,\nthe operator can do so by following the links in the HTML presentation and read\nthe major or minor log files. The \"all_runs.html\" page is a good starting point.\nIt is located in `logdir` and contains a link to each test run, including a\nquick overview (with date and time, node name, number of tests, test names, and\ntest result totals).\n\nAn \"index.html\" page is written for each test run (that is, stored in the\n`ct_run` directory tagged with node name, date, and time). This file provides an\noverview of all individual tests performed in the same test run. The test names\nfollow the following convention:\n\n- `TopLevelDir.TestDir` (all suites in `TestDir` executed)\n- `TopLevelDir.TestDir:suites` (specific suites executed)\n- `TopLevelDir.TestDir.Suite` (all cases in `Suite` executed)\n- `TopLevelDir.TestDir.Suite:cases` (specific test cases executed)\n- `TopLevelDir.TestDir.Suite.Case` (only `Case` executed)\n\nThe \"test run index\" page includes a link to the `Common Test` Framework Log\nfile in which information about imported configuration data and general test\nprogress is written. This log file is useful to get snapshot information about\nthe test run during execution. It can also be helpful when analyzing test\nresults or debugging test suites.\n\nThe \"test run index\" page indicates if a test has missing suites (that is,\nsuites that `Common Test` failed to compile). Names of the missing suites can be\nfound in the `Common Test` Framework Log file.\n\nThe major log file shows a detailed report of the test run. It includes test\nsuite and test case names, execution time, the exact reason for failures, and so\non. The information is available in both a file with textual and with HTML\nrepresentation. The HTML file shows a summary that gives a good overview of the\ntest run. It also has links to each individual test case log file for quick\nviewing with an HTML browser.\n\nThe minor log files contain full details of every single test case, each in a\nseparate file. This way, it is straightforward to compare the latest results to\nthat of previous test runs, even if the set of test cases changes. If\napplication SASL is running, its logs are also printed to the current minor log\nfile by the [cth_log_redirect built-in hook](ct_hooks_chapter.md#builtin_cths).\n\nThe full name of the minor log file (that is, the name of the file including the\nabsolute directory path) can be read during execution of the test case. It comes\nas value in tuple `{tc_logfile,LogFileName}` in the `Config` list (which means\nit can also be read by a pre- or post `Common Test Hook` function). Also, at the\nstart of a test case, this data is sent with an event to any installed event\nhandler. For details, see section\n[Event Handling](event_handler_chapter.md#event_handling).\n\nThe log files are written continuously during a test run and links are always\ncreated initially when a test starts. Thevtest progress can therefore be\nfollowed simply by refreshing pages in the HTML browser. Statistics totals are\nnot presented until a test is complete however.\n\n[](){: #logopts }","title":"Log Files - Running Tests and Analyzing Results","ref":"run_test_chapter.html#log-files"},{"type":"extras","doc":"With start flag `logopts` options that modify some aspects of the logging\nbehavior can be specified. The following options are available:\n\n- **`no_src`** - The HTML version of the test suite source code is not generated\n during the test run (and is consequently not available in the log file\n system).\n\n- **`no_nl`** - `Common Test` does not add a newline character `(\\n)` to the end\n of an output string that it receives from a call to, for example,\n `io:format/2`, and which it prints to the test case log.\n\nFor example, if a test is started with:\n\n`$ ct_run -suite my_SUITE -logopts no_nl`\n\nthen printouts during the test made by successive calls to `io:format(\"x\")`,\nappears in the test case log as:\n\n`xxx`\n\ninstead of each `x` printed on a new line, which is the default behavior.\n\n[](){: #table_sorting }","title":"Log Options - Running Tests and Analyzing Results","ref":"run_test_chapter.html#log-options"},{"type":"extras","doc":"By clicking the name in the column header of any table (for example, \"Ok\",\n\"Case\", \"Time\", and so on), the table rows are sorted in whatever order makes\nsense for the type of value (for example, numerical for \"Ok\" or \"Time\", and\nalphabetical for \"Case\"). The sorting is performed through JavaScript code,\nautomatically inserted into the HTML log files. `Common Test` uses the\n[jQuery](http://jquery.com) library and the\n[tablesorter](https://mottie.github.io/tablesorter/docs/) plugin, with\ncustomized sorting functions, for this implementation.","title":"Sorting HTML Table Columns - Running Tests and Analyzing Results","ref":"run_test_chapter.html#sorting-html-table-columns"},{"type":"extras","doc":"The test suites overview page includes a link to the Unexpected I/O Log. In this\nlog, `Common Test` saves printouts made with [`ct:log/1,2,3,4,5`](`ct:log/2`)\nand [`ct:pal/1,2,3,4,5`](`ct:pal/2`), as well as captured system error- and\nprogress reports, which cannot be associated with particular test cases and\ntherefore cannot be written to individual test case log files. This occurs, for\nexample, if a log printout is made from an external process (not a test case\nprocess), _or_ if an error- or progress report comes in, during a short interval\nwhile `Common Test` is not executing a test case or configuration function, _or_\nwhile `Common Test` is currently executing a parallel test case group.\n\n[](){: #pre_post_test_io_log }","title":"The Unexpected I/O Log - Running Tests and Analyzing Results","ref":"run_test_chapter.html#the-unexpected-i-o-log"},{"type":"extras","doc":"The `Common Test` Framework Log page includes links to the Pre- and Post Test\nI/O Log. In this log, `Common Test` saves printouts made with `ct:log/1,2,3,4,5`\nand `ct:pal/1,2,3,4,5`, as well as captured system error- and progress reports,\nwhich take place before, and after, the test run. Examples of this are printouts\nfrom a CT hook init- or terminate function, or progress reports generated when\nan OTP application is started from a CT hook init function. Another example is\nan error report generated because of a failure when an external application is\nstopped from a CT hook terminate function. All information in these examples\nends up in the Pre- and Post Test I/O Log. For more information on how to\nsynchronize test runs with external user applications, see section\n[Synchronizing](ct_hooks_chapter.md#synchronizing) in section Common Test Hooks.\n\n> #### Note {: .info }\n>\n> Logging to file with `ct:log/1,2,3,4,5` or `ct:pal/1,2,3,4,5` only works when\n> `Common Test` is running. Printouts with `ct:pal/1,2,3,4,5` are however always\n> displayed on screen.\n\n[](){: #delete_old_logs }","title":"The Pre- and Post Test I/O Log - Running Tests and Analyzing Results","ref":"run_test_chapter.html#the-pre-and-post-test-i-o-log"},{"type":"extras","doc":"`Common Test` can automatically delete old log. This is specified with the\n`keep_logs` option. The default value for this option is `all`, which means that\nno logs are deleted. If the value is set to an integer, `N`, `Common Test`\ndeletes all `ct_run. ` directories, except the `N` newest.\n\n[](){: #html_stylesheet }","title":"Delete Old Logs - Running Tests and Analyzing Results","ref":"run_test_chapter.html#delete-old-logs"},{"type":"extras","doc":"`Common Test` uses an HTML Style Sheet (CSS file) to control the look of the\nHTML log files generated during test runs. If the log files are not displayed\ncorrectly in the browser of your choice, or you prefer a more primitive (\"pre\n`Common Test` v1.6\") look of the logs, use the start flag/option:\n\n```text\nbasic_html\n```\n\nThis disables the use of style sheets and JavaScripts (see\n[Sorting HTML Table Columns](run_test_chapter.md#table_sorting)).\n\n`Common Test` includes an _optional_ feature to allow user HTML style sheets for\ncustomizing printouts. The functions in `ct` that print to a test case HTML log\nfile (`log/3,4,5` and `pal/3,4,5`) accept `Category` as first argument. With\nthis argument a category can be specified that can be mapped to a named `div`\nselector in a CSS rule-set. This is useful, especially for coloring text\ndifferently depending on the type of (or reason for) the printout. Say you want\none particular background color for test system configuration information, a\ndifferent one for test system state information, and finally one for errors\ndetected by the test case functions. The corresponding style sheet can look as\nfollows:\n\n```css\ndiv.sys_config { background:blue }\ndiv.sys_state { background:yellow }\ndiv.error { background:red }\n```\n\nCommon Test prints the text from `ct:log/3,4,5` or `ct:pal/3,4,5` inside a `pre`\nelement nested under the named `div` element. Since the `pre` selector has a\npredefined CSS rule (in file `ct_default.css`) for the attributes `color`,\n`font-family` and `font-size`, if a user wants to change any of the predefined\nattribute settings, a new rule for `pre` must be added to the user stylesheet.\nExample:\n\n```text\ndiv.error pre { color:white }\n```\n\nHere, white text is used instead of the default black for `div.error` printouts\n(and no other attribute settings for `pre` are affected).\n\nTo install the CSS file (`Common Test` inlines the definition in the HTML code),\nthe file name can be provided when executing `ct_run`.\n\n_Example:_\n\n```text\n$ ct_run -dir $TEST/prog -stylesheet $TEST/styles/test_categories.css\n```\n\nCategories in a CSS file installed with flag `-stylesheet` are on a global test\nlevel in the sense that they can be used in any suite that is part of the test\nrun.\n\nStyle sheets can also be installed on a per suite and per test case basis.\n\n_Example:_\n\n```erlang\n-module(my_SUITE).\n...\nsuite() -> [..., {stylesheet,\"suite_categories.css\"}, ...].\n...\nmy_testcase(_) ->\n ...\n ct:log(sys_config, \"Test node version: ~p\", [VersionInfo]),\n ...\n ct:log(sys_state, \"Connections: ~p\", [ConnectionInfo]),\n ...\n ct:pal(error, \"Error ~p detected! Info: ~p\", [SomeFault,ErrorInfo]),\n ct:fail(SomeFault).\n```\n\nIf the style sheet is installed as in this example, the categories are private\nto the suite in question. They can be used by all test cases in the suite, but\ncannot be used by other suites. A suite private style sheet, if specified, is\nused in favor of a global style sheet (one specified with flag `-stylesheet`). A\nstylesheet tuple (as returned by `suite/0` above) can also be returned from a\ntest case information function. In this case the categories specified in the\nstyle sheet can only be used in that particular test case. A test case private\nstyle sheet is used in favor of a suite or global level style sheet.\n\nIn a tuple `{stylesheet,CSSFile}`, if `CSSFile` is specified with a path, for\nexample, `\"$TEST/styles/categories.css\"`, this full name is used to locate the\nfile. However, if only the file name is specified, for example,\n`categories.css`, the CSS file is assumed to be located in the data directory,\n`data_dir`, of the suite. The latter use is recommended, as it is portable\ncompared to hard coding path names in the suite.\n\nArgument `Category` in the previous example can have the value (atom)\n`sys_config` (blue background), `sys_state` (yellow background), or `error`\n(white text on red background).\n\n[](){: #repeating_tests }","title":"HTML Style Sheets - Running Tests and Analyzing Results","ref":"run_test_chapter.html#html-style-sheets"},{"type":"extras","doc":"You can order `Common Test` to repeat the tests you specify. You can choose to\nrepeat tests a number of times, repeat tests for a specific period of time, or\nrepeat tests until a particular stop time is reached. If repetition is\ncontrolled by time, an action for `Common Test` to take upon time-out can be\nspecified. Either `Common Test` performs all tests in the current run before\nstopping, or it stops when the current test job is finished. Repetition can be\nactivated by `ct_run` start flags, or tuples in the `ct:run:test/1` option list\nargument. The flags (options in parentheses) are the following:\n\n- `-repeat N ({repeat,N})`, where `N` is a positive integer\n- `-duration DurTime ({duration,DurTime})`, where `DurTime` is the duration\n- `-until StopTime ({until,StopTime})`, where `StopTime` is finish time\n- `-force_stop ({force_stop,true})`\n- `-force_stop skip_rest ({force_stop,skip_rest})`\n\n- **`DurTime`** - The duration time is specified as `HHMMSS`, for example,\n `-duration 012030` or `{duration,\"012030\"}`\n\n , which means that the tests are executed and (if time allows) repeated until\n time-out occurs after 1 hour, 20 minutes, and 30 seconds.\n\n- **`StopTime`** - The finish time can be specified as `HHMMSS` and is then\n interpreted as a time today (or possibly tomorrow), but can also be specified\n as `YYMoMoDDHHMMSS`, for example, `-until 071001120000` or\n `{until,\"071001120000\"}`. This means that the tests are executed and (if time\n allows) repeated, until 12 o'clock on the 1st of October 2007.\n\nWhen time-out occurs, `Common Test` never aborts the ongoing test case, as this\ncan leave the SUT in an undefined, and possibly bad, state. Instead\n`Common Test`, by default, finishes the current test run before stopping. If\nflag `force_stop` is specified, `Common Test` stops when the current test job is\nfinished. If flag `force_stop` is specified with `skip_rest`, `Common Test` only\ncompletes the current test case and skips the remaining tests in the test job.\n\n> #### Note {: .info }\n>\n> As `Common Test` always finishes at least the current test case, the time\n> specified with `duration` or `until` is never definitive.\n\nLog files from every repeated test run is saved in normal `Common Test` fashion\n(described earlier).\n\n`Common Test` might later support an optional feature to only store the last\n(and possibly the first) set of logs of repeated test runs, but for now the user\nmust be careful not to run out of disk space if tests are repeated during long\nperiods of time.\n\nFor each test run that is part of a repeated session, information about the\nparticular test run is printed in the `Common Test` Framework Log. The\ninformation includes the repetition number, remaining time, and so on.\n\n_Example 1:_\n\n```text\n$ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -duration 001000 -force_stop\n```\n\nHere, the suites in test directory `to1`, followed by the suites in `to2`, are\nexecuted in one test run. A time-out event occurs after 10 minutes. As long as\nthere is time left, `Common Test` repeats the test run (that is, starting over\nwith test `to1`). After time-out, `Common Test` stops when the current job is\nfinished (because of flag `force_stop`). As a result, the specified test run can\nbe aborted after test `to1` and before test `to2`.\n\n_Example 2:_\n\n```text\n$ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -duration 001000 -forces_stop skip_rest\n```\n\nHere, the same tests as in Example 1 are run, but with flag `force_stop` set to\n`skip_rest`. If time-out occurs while executing tests in directory `to1`, the\nremaining test cases in `to1` are skipped and the test is aborted without\nrunning the tests in `to2` another time. If time-out occurs while executing\ntests in directory `to2`, the remaining test cases in `to2` are skipped and the\ntest is aborted.\n\n_Example 3:_\n\n```text\n$ date\nFri Sep 28 15:00:00 MEST 2007\n\n$ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -until 160000\n```\n\nHere, the same test run as in the previous examples are executed (and possibly\nrepeated). However, when the time-out occurs, after 1 hour, `Common Test`\nfinishes the entire test run before stopping (that is, both `to1` and `to2` are\nalways executed in the same test run).\n\n_Example 4:_\n\n```text\n$ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -repeat 5\n```\n\nHere, the test run, including both the `to1` and the `to2` test, is repeated\nfive times.\n\n> #### Note {: .info }\n>\n> Do not confuse this feature with the `repeat` property of a test case group.\n> The options described here are used to repeat execution of entire test runs,\n> while the `repeat` property of a test case group makes it possible to repeat\n> execution of sets of test cases within a suite. For more information about the\n> latter, see section\n> [Test Case Groups ](write_test_chapter.md#test_case_groups)in section Writing\n> Test Suites.\n\n[](){: #silent_connections }","title":"Repeating Tests - Running Tests and Analyzing Results","ref":"run_test_chapter.html#repeating-tests"},{"type":"extras","doc":"The protocol handling processes in `Common Test`, implemented by `ct_telnet`,\n`ct_ssh`, `ct_ftp`, and so on, do verbose printing to the test case logs. This\ncan be switched off with flag `-silent_connections`:\n\n```text\nct_run -silent_connections [conn_types]\n```\n\nHere, `conn_types` specifies SSH, Telnet, FTP, RPC, and/or SNMP.\n\n_Example 1:_\n\n```text\nct_run ... -silent_connections ssh telnet\n```\n\nThis switches off logging for SSH and Telnet connections.\n\n_Example 2:_\n\n```text\nct_run ... -silent_connections\n```\n\nThis switches off logging for all connection types.\n\nFatal communication error and reconnection attempts are always printed, even if\nlogging has been suppressed for the connection type in question. However,\noperations such as sending and receiving data are performed silently.\n\n`silent_connections` can also be specified in a test suite. This is accomplished\nby returning a tuple, `{silent_connections,ConnTypes}`, in the `suite/0` or test\ncase information list. If `ConnTypes` is a list of atoms (SSH, Telnet, FTP, RPC\nand/or SNMP), output for any corresponding connections are suppressed. Full\nlogging is by default enabled for any connection of type not specified in\n`ConnTypes`. Hence, if `ConnTypes` is the empty list, logging is enabled for all\nconnections.\n\n_Example 3:_\n\n```erlang\n-module(my_SUITE).\n\nsuite() -> [..., {silent_connections,[telnet,ssh]}, ...].\n\n...\n\nmy_testcase1() ->\n [{silent_connections,[ssh]}].\n\nmy_testcase1(_) ->\n ...\n\nmy_testcase2(_) ->\n ...\n```\n\nIn this example, `suite/0` tells `Common Test` to suppress printouts from Telnet\nand SSH connections. This is valid for all test cases. However, `my_testcase1/0`\nspecifies that for this test case, only SSH is to be silent. The result is that\n`my_testcase1` gets Telnet information (if any) printed in the log, but not SSH\ninformation. `my_testcase2` gets no information from either connection printed.\n\n`silent_connections` can also be specified with a term in a test specification\n(see section [Test Specifications](run_test_chapter.md#test_specifications) in\nsection Running Tests and Analyzing Results). Connections provided with start\nflag/option `silent_connections` are merged with any connections listed in the\ntest specification.\n\nStart flag/option `silent_connections` and the test specification term override\nany settings made by the information functions inside the test suite.\n\n> #### Note {: .info }\n>\n> In the current `Common Test` version, the `silent_connections` feature only\n> works for Telnet and SSH connections. Support for other connection types can\n> be added in future `Common Test` versions.","title":"Silent Connections - Running Tests and Analyzing Results","ref":"run_test_chapter.html#silent-connections"},{"type":"extras","doc":"\n# External Configuration Data\n\n[](){: #top }","title":"External Configuration Data","ref":"config_file_chapter.html"},{"type":"extras","doc":"To avoid hard-coding data values related to the test and/or System Under Test\n(SUT) in the test suites, the data can instead be specified through\nconfiguration files or strings that `Common Test` reads before the start of a\ntest run. External configuration data makes it possible to change test\nproperties without modifying the test suites using the data. Examples of\nconfiguration data follows:\n\n- Addresses to the test plant or other instruments\n- User login information\n- Names of files needed by the test\n- Names of programs to be executed during the test\n- Any other variable needed by the test","title":"General - External Configuration Data","ref":"config_file_chapter.html#general"},{"type":"extras","doc":"A configuration file can contain any number of elements of the type:\n\n```erlang\n{CfgVarName,Value}.\n```\n\nwhere\n\n```erlang\nCfgVarName = atom()\nValue = term() | [{CfgVarName,Value}]\n```","title":"Syntax - External Configuration Data","ref":"config_file_chapter.html#syntax"},{"type":"extras","doc":"[](){: #require_config_data }\n\nIn a test suite, one must _require_ that a configuration variable (`CfgVarName`\nin the previous definition) exists before attempting to read the associated\nvalue in a test case or configuration function.\n\n`require` is an assert statement, which can be part of the\n[Test Suite Information Function](write_test_chapter.md#suite) or\n[Test Case Information Function](write_test_chapter.md#info_function). If the\nrequired variable is unavailable, the test is skipped (unless a default value\nhas been specified, see section\n[Test Case Information Function](write_test_chapter.md#info_function) for\ndetails). Also, function [`ct:require/1/2`](`ct:require/1`) can be called from a\ntest case to check if a specific variable is available. The return value from\nthis function must be checked explicitly and appropriate action be taken\ndepending on the result (for example, to skip the test case if the variable in\nquestion does not exist).\n\nA `require` statement in the test suite information case or test case\ninformation-list is to look like `{require,CfgVarName}` or\n`{require,AliasName,CfgVarName}`. The arguments `AliasName` and `CfgVarName` are\nthe same as the arguments to [`ct:require/1,2`](`ct:require/1`). `AliasName`\nbecomes an alias for the configuration variable, and can be used as reference to\nthe configuration data value. The configuration variable can be associated with\nany number of alias names, but each name must be unique within the same test\nsuite. The two main uses for alias names follows:\n\n- To identify connections (described later).\n- To help adapt configuration data to a test suite (or test case) and improve\n readability.\n\nTo read the value of a configuration variable, use function\n[`get_config/1,2,3`](`ct:get_config/1`).\n\n_Example:_\n\n```erlang\nsuite() ->\n [{require, domain, 'CONN_SPEC_DNS_SUFFIX'}].\n\n...\n\ntestcase(Config) ->\n Domain = ct:get_config(domain),\n ...\n```","title":"Requiring and Reading Configuration Data - External Configuration Data","ref":"config_file_chapter.html#requiring-and-reading-configuration-data"},{"type":"extras","doc":"If a configuration variable is defined in multiple files and you want to access\nall possible values, use function `ct:get_config/3` and specify `all` in the\noptions list. The values are then returned in a list and the order of the\nelements corresponds to the order that the configuration files were specified at\nstartup.","title":"Using Configuration Variables Defined in Multiple Files - External Configuration Data","ref":"config_file_chapter.html#using-configuration-variables-defined-in-multiple-files"},{"type":"extras","doc":"[](){: #encrypted_config_files }\n\nConfiguration files containing sensitive data can be encrypted if they must be\nstored in open and shared directories.\n\nTo have `Common Test` encrypt a specified file using function `DES3` in\napplication `Crypto`, call\n[`ct:encrypt_config_file/2,3`](`ct:encrypt_config_file/2`) The encrypted file\ncan then be used as a regular configuration file in combination with other\nencrypted files or normal text files. However, the key for decrypting the\nconfiguration file must be provided when running the test. This can be done with\nflag/option `decrypt_key` or `decrypt_file`, or a key file in a predefined\nlocation.\n\n`Common Test` also provides decryption functions,\n[`ct:decrypt_config_file/2,3`](`ct:decrypt_config_file/2`), for recreating the\noriginal text files.","title":"Encrypted Configuration Files - External Configuration Data","ref":"config_file_chapter.html#encrypted-configuration-files"},{"type":"extras","doc":"Two different methods for opening a connection using the support functions in,\nfor example, `m:ct_ssh`, `m:ct_ftp`, and `m:ct_telnet` follows:\n\n- Using a configuration target name (an alias) as reference.\n- Using the configuration variable as reference.\n\nWhen a target name is used for referencing the configuration data (that\nspecifies the connection to be opened), the same name can be used as connection\nidentity in all subsequent calls related to the connection (also for closing\nit). Only one open connection per target name is possible. If you attempt to\nopen a new connection using a name already associated with an open connection,\n`Common Test` returns the already existing handle so the previously opened\nconnection is used. This feature makes it possible to call the function for\nopening a particular connection whenever useful. An action like this does not\nnecessarily open any new connections unless it is required (which could be the\ncase if, for example, the previous connection has been closed unexpectedly by\nthe server). Using named connections also removes the need to pass handle\nreferences around in the suite for these connections.\n\nWhen a configuration variable name is used as reference to the data specifying\nthe connection, the handle returned as a result of opening the connection must\nbe used in all subsequent calls (also for closing the connection). Repeated\ncalls to the open function with the same variable name as reference results in\nmultiple connections being opened. This can be useful, for example, if a test\ncase needs to open multiple connections to the same server on the target node\n(using the same configuration data for each connection).","title":"Opening Connections Using Configuration Data - External Configuration Data","ref":"config_file_chapter.html#opening-connections-using-configuration-data"},{"type":"extras","doc":"The user can specify configuration data on a different format than key-value\ntuples in a text file, as described so far. The data can, for example, be read\nfrom any files, fetched from the web over HTTP, or requested from a\nuser-specific process. To support this, `Common Test` provides a callback module\nplugin mechanism to handle configuration data.","title":"User-Specific Configuration Data Formats - External Configuration Data","ref":"config_file_chapter.html#user-specific-configuration-data-formats"},{"type":"extras","doc":"`Common Test` includes default callback modules for handling configuration data\nspecified in standard configuration files (described earlier) and in XML files\nas follows:\n\n- `ct_config_plain` \\- for reading configuration files with key-value tuples\n (standard format). This handler is used to parse configuration files if no\n user callback is specified.\n- `ct_config_xml` \\- for reading configuration data from XML files.","title":"Default Callback Modules for Handling Configuration Data - External Configuration Data","ref":"config_file_chapter.html#default-callback-modules-for-handling-configuration-data"},{"type":"extras","doc":"An example of an XML configuration file follows:\n\n```xml\n \n \n \"targethost\" \n \"tester\" \n \"letmein\" \n \n \"/test/loadmodules\" \n \n```\n\nOnce read, this file produces the same configuration variables as the following\ntext file:\n\n```erlang\n{ftp_host, [{ftp,\"targethost\"},\n {username,\"tester\"},\n {password,\"letmein\"}]}.\n\n{lm_directory, \"/test/loadmodules\"}.\n```","title":"Using XML Configuration Files - External Configuration Data","ref":"config_file_chapter.html#using-xml-configuration-files"},{"type":"extras","doc":"The user-specific handler can be written to handle special configuration file\nformats. The parameter can be either file names or configuration strings (the\nempty list is valid).\n\nThe callback module implementing the handler is responsible for checking the\ncorrectness of configuration strings.\n\nTo validate the configuration strings, the callback module is to have function\n`Callback:check_parameter/1` exported.\n\nThe input argument is passed from `Common Test`, as defined in the test\nspecification, or specified as an option to `ct_run` or `ct:run_test`.\n\nThe return value is to be any of the following values, indicating if the\nspecified configuration parameter is valid:\n\n- `{ok, {file, FileName}}` \\- the parameter is a file name and the file exists.\n- `{ok, {config, ConfigString}}` \\- the parameter is a configuration string and\n it is correct.\n- `{error, {nofile, FileName}}` \\- there is no file with the specified name in\n the current directory.\n- `{error, {wrong_config, ConfigString}}` \\- the configuration string is wrong.\n\nThe function `Callback:read_config/1` is to be exported from the callback module\nto read configuration data, initially before the tests start, or as a result of\ndata being reloaded during test execution. The input argument is the same as for\nfunction `check_parameter/1`.\n\nThe return value is to be either of the following:\n\n- `{ok, Config}` \\- if the configuration variables are read successfully.\n- `{error, {Error, ErrorDetails}}` \\- if the callback module fails to proceed\n with the specified configuration parameters.\n\n`Config` is the proper Erlang key-value list, with possible key-value sublists\nas values, like the earlier configuration file example:\n\n```erlang\n[{ftp_host, [{ftp, \"targethost\"}, {username, \"tester\"}, {password, \"letmein\"}]},\n {lm_directory, \"/test/loadmodules\"}]\n```","title":"Implement a User-Specific Handler - External Configuration Data","ref":"config_file_chapter.html#implement-a-user-specific-handler"},{"type":"extras","doc":"A configuration file for using the FTP client to access files on a remote host\ncan look as follows:\n\n```erlang\n{ftp_host, [{ftp,\"targethost\"},\n {username,\"tester\"},\n {password,\"letmein\"}]}.\n\n{lm_directory, \"/test/loadmodules\"}.\n```\n\nThe XML version shown earlier can also be used, but it is to be explicitly\nspecified that the `ct_config_xml` callback module is to be used by\n`Common Test`.\n\nThe following is an example of how to assert that the configuration data is\navailable and can be used for an FTP session:\n\n```erlang\ninit_per_testcase(ftptest, Config) ->\n {ok,_} = ct_ftp:open(ftp),\n Config.\n\nend_per_testcase(ftptest, _Config) ->\n ct_ftp:close(ftp).\n\nftptest() ->\n [{require,ftp,ftp_host},\n {require,lm_directory}].\n\nftptest(Config) ->\n Remote = filename:join(ct:get_config(lm_directory), \"loadmodX\"),\n Local = filename:join(proplists:get_value(priv_dir,Config), \"loadmodule\"),\n ok = ct_ftp:recv(ftp, Remote, Local),\n ...\n```\n\nThe following is an example of how the functions in the previous example can be\nrewritten if it is necessary to open multiple connections to the FTP server:\n\n```erlang\ninit_per_testcase(ftptest, Config) ->\n {ok,Handle1} = ct_ftp:open(ftp_host),\n {ok,Handle2} = ct_ftp:open(ftp_host),\n [{ftp_handles,[Handle1,Handle2]} | Config].\n\nend_per_testcase(ftptest, Config) ->\n lists:foreach(fun(Handle) -> ct_ftp:close(Handle) end,\n proplists:get_value(ftp_handles,Config)).\n\nftptest() ->\n [{require,ftp_host},\n {require,lm_directory}].\n\nftptest(Config) ->\n Remote = filename:join(ct:get_config(lm_directory), \"loadmodX\"),\n Local = filename:join(proplists:get_value(priv_dir,Config), \"loadmodule\"),\n [Handle | MoreHandles] = proplists:get_value(ftp_handles,Config),\n ok = ct_ftp:recv(Handle, Remote, Local),\n ...\n```","title":"Examples of Configuration Data Handling - External Configuration Data","ref":"config_file_chapter.html#examples-of-configuration-data-handling"},{"type":"extras","doc":"A simple configuration handling driver, asking an external server for\nconfiguration data, can be implemented as follows:\n\n```erlang\n-module(config_driver).\n-export([read_config/1, check_parameter/1]).\n\nread_config(ServerName)->\n ServerModule = list_to_atom(ServerName),\n ServerModule:start(),\n ServerModule:get_config().\n\ncheck_parameter(ServerName)->\n ServerModule = list_to_atom(ServerName),\n case code:is_loaded(ServerModule) of\n {file, _}->\n {ok, {config, ServerName}};\n false->\n case code:load_file(ServerModule) of\n {module, ServerModule}->\n {ok, {config, ServerName}};\n {error, nofile}->\n {error, {wrong_config, \"File not found: \" ++ ServerName ++ \".beam\"}}\n end\n end.\n```\n\nThe configuration string for this driver can be `config_server`, if the\n`config_server.erl` module that follows is compiled and exists in the code path\nduring test execution:\n\n```erlang\n-module(config_server).\n-export([start/0, stop/0, init/1, get_config/0, loop/0]).\n\n-define(REGISTERED_NAME, ct_test_config_server).\n\nstart()->\n case whereis(?REGISTERED_NAME) of\n undefined->\n spawn(?MODULE, init, [?REGISTERED_NAME]),\n wait();\n _Pid->\n ok\n end,\n ?REGISTERED_NAME.\n\ninit(Name)->\n register(Name, self()),\n loop().\n\nget_config()->\n call(self(), get_config).\n\nstop()->\n call(self(), stop).\n\ncall(Client, Request)->\n case whereis(?REGISTERED_NAME) of\n undefined->\n {error, {not_started, Request}};\n Pid->\n Pid ! {Client, Request},\n receive\n Reply->\n {ok, Reply}\n after 4000->\n {error, {timeout, Request}}\n end\n end.\n\nloop()->\n receive\n {Pid, stop}->\n Pid ! ok;\n {Pid, get_config}->\n {D,T} = erlang:localtime(),\n Pid !\n [{localtime, [{date, D}, {time, T}]},\n {node, erlang:node()},\n {now, erlang:now()},\n {config_server_pid, self()},\n {config_server_vsn, ?vsn}],\n ?MODULE:loop()\n end.\n\nwait()->\n case whereis(?REGISTERED_NAME) of\n undefined->\n wait();\n _Pid->\n ok\n end.\n```\n\nHere, the handler also provides for dynamically reloading of configuration\nvariables. If [`ct:reload_config(localtime)`](`ct:reload_config/1`) is called\nfrom the test case function, all variables loaded with\n`config_driver:read_config/1` are updated with their latest values, and the new\nvalue for variable `localtime` is returned.","title":"Example of User-Specific Configuration Handler - External Configuration Data","ref":"config_file_chapter.html#example-of-user-specific-configuration-handler"},{"type":"extras","doc":"\n# Code Coverage Analysis\n\n[](){: #cover }","title":"Code Coverage Analysis","ref":"cover_chapter.html"},{"type":"extras","doc":"Although `Common Test` was created primarily for black-box testing, nothing\nprevents it from working perfectly as a white-box testing tool as well. This is\nespecially true when the application to test is written in Erlang. Then the test\nports are easily realized with Erlang function calls.\n\nWhen white-box testing an Erlang application, it is useful to be able to measure\nthe code coverage of the test. `Common Test` provides simple access to the OTP\nCover tool for this purpose. `Common Test` handles all necessary communication\nwith the Cover tool (starting, compiling, analysing, and so on). The\n`Common Test` user only needs to specify the extent of the code coverage\nanalysis.","title":"General - Code Coverage Analysis","ref":"cover_chapter.html#general"},{"type":"extras","doc":"To specify the modules to be included in the code coverage test, provide a cover\nspecification file. With this file you can point out specific modules or specify\ndirectories containing modules to be included in the analysis. You can also\nspecify modules to be excluded from the analysis.\n\nIf you are testing a distributed Erlang application, it is likely that code you\nwant included in the code coverage analysis gets executed on another Erlang node\nthan the one `Common Test` is running on. If so, you must specify these other\nnodes in the cover specification file or add them dynamically to the code\ncoverage set of nodes. For details on the latter, see module `m:ct_cover`.\n\nIn the cover specification file you can also specify your required level of the\ncode coverage analysis; `details` or `overview`. In detailed mode, you get a\ncoverage overview page, showing per module and total coverage percentages. You\nalso get an HTML file printed for each module included in the analysis showing\nexactly what parts of the code have been executed during the test. In overview\nmode, only the code coverage overview page is printed.\n\nYou can choose to export and import code coverage data between tests. If you\nspecify the name of an export file in the cover specification file,\n`Common Test` exports collected coverage data to this file at the end of the\ntest. You can similarly specify previously exported data to be imported and\nincluded in the analysis for a test (multiple import files can be specified).\nThis way, the total code coverage can be analyzed without necessarily running\nall tests at once.\n\nTo activate the code coverage support, specify the name of the cover\nspecification file as you start `Common Test`. Do this by using flag `-cover`\nwith [`ct_run`](ct_run_cmd.md), for example:\n\n```text\n$ ct_run -dir $TESTOBJS/db -cover $TESTOBJS/db/config/db.coverspec\n```\n\nYou can also pass the cover specification file name in a call to\n`ct:run_test/1`, by adding a `{cover,CoverSpec}` tuple to argument `Opts`.\n\nYou can also enable code coverage in your test specifications (see section\n[Test Specifications](run_test_chapter.md#test_specifications) in section\nRunning Tests and Analyzing Results).\n\n[](){: #cover_stop }","title":"Use - Code Coverage Analysis","ref":"cover_chapter.html#use"},{"type":"extras","doc":"By default, the Cover tool is automatically stopped when the tests are\ncompleted. This causes the original (non-cover compiled) modules to be loaded\nback into the test node. If a process at this point still runs old code of any\nof the modules that are cover compiled, meaning that it has not done any fully\nqualified function call after the cover compilation, the process is killed. To\navoid this, set the value of option `cover_stop` to `false`. This means that the\nmodules stay cover compiled. Therefore, this is only recommended if the Erlang\nnodes under test are terminated after the test is completed, or if cover can be\nmanually stopped.\n\nThe option can be set by using flag `-cover_stop` with `ct_run`, by adding\n`{cover_stop,true|false}` to argument `Opts` to `ct:run_test/1`, or by adding a\n`cover_stop` term in the test specification (see section\n[Test Specifications](run_test_chapter.md#test_specifications) in section\nRunning Tests and Analyzing Results).","title":"Stopping the Cover Tool When Tests Are Completed - Code Coverage Analysis","ref":"cover_chapter.html#stopping-the-cover-tool-when-tests-are-completed"},{"type":"extras","doc":"","title":"The Cover Specification File - Code Coverage Analysis","ref":"cover_chapter.html#the-cover-specification-file"},{"type":"extras","doc":"Here follows the general configuration terms that are allowed in a cover\nspecification file:\n\n```erlang\n%% List of Nodes on which cover will be active during test.\n%% Nodes = [atom()]\n{nodes, Nodes}.\n\n%% Files with previously exported cover data to include in analysis.\n%% CoverDataFiles = [string()]\n{import, CoverDataFiles}.\n\n%% Cover data file to export from this session.\n%% CoverDataFile = string()\n{export, CoverDataFile}.\n\n%% Cover analysis level.\n%% Level = details | overview\n{level, Level}.\n\n%% Directories to include in cover.\n%% Dirs = [string()]\n{incl_dirs, Dirs}.\n\n%% Directories, including subdirectories, to include.\n{incl_dirs_r, Dirs}.\n\n%% Specific modules to include in cover.\n%% Mods = [atom()]\n{incl_mods, Mods}.\n\n%% Directories to exclude in cover.\n{excl_dirs, Dirs}.\n\n%% Directories, including subdirectories, to exclude.\n{excl_dirs_r, Dirs}.\n\n%% Specific modules to exclude in cover.\n{excl_mods, Mods}.\n\n%% Cross cover compilation\n%% Tag = atom(), an identifier for a test run\n%% Mod = [atom()], modules to compile for accumulated analysis\n{cross,[{Tag,Mods}]}.\n```\n\nThe terms `incl_dirs_r` and `excl_dirs_r` tell `Common Test` to search the\nspecified directories recursively and include or exclude any module found during\nthe search. The terms `incl_dirs` and `excl_dirs` result in a non-recursive\nsearch for modules (that is, only modules found in the specified directories are\nincluded or excluded).\n\n> #### Note {: .info }\n>\n> Directories containing Erlang modules to be included in a code coverage test\n> must exist in the code server path. Otherwise, the Cover tool fails to\n> recompile the modules. It is not sufficient to specify these directories in\n> the cover specification file for `Common Test`.","title":"General Config - Code Coverage Analysis","ref":"cover_chapter.html#general-config"},{"type":"extras","doc":"When using a cover specification in the testing of an OTP application itself,\nthere is a special incl_app directive that includes the applications modules for\nthe cover compilation.\n\n```erlang\n{incl_app, AppName, Cover :: overview | details}.\n```\n\n> #### Note {: .info }\n>\n> If you desire to also use some other general cover configuration together with\n> this option you should insert the AppName in between the option and its value\n> creating a three tuple.\n\n[](){: #cross_cover }","title":"OTP application Config - Code Coverage Analysis","ref":"cover_chapter.html#otp-application-config"},{"type":"extras","doc":"The cross cover mechanism allows cover analysis of modules across multiple\ntests. It is useful if some code, for example, a library module, is used by many\ndifferent tests and the accumulated cover result is desirable.\n\nThis can also be achieved in a more customized way by using parameter `export`\nin the cover specification and analysing the result off line. However, the cross\ncover mechanism is a built-in solution that also provides logging.\n\nThe mechanism is easiest explained by an example:\n\nAssume that there are two systems, `s1` and `s2`, that are tested in separate\ntest runs. System `s1` contains a library module `m1` tested by test run `s1`\nand is included in the cover specification of `s1` as follows:\n\n```text\ns1.cover:\n {incl_mods,[m1]}.\n```\n\nWhen analysing code coverage, the result for `m1` can be seen in the cover log\nin the `s1` test result.\n\nNow, imagine that as `m1` is a library module, it is also often used by system\n`s2`. Test run `s2` does not specifically test `m1`, but it can still be\ninteresting to see which parts of `m1` that are covered by the `s2` tests. To do\nthis, `m1` can be included also in the cover specification of `s2` as follows:\n\n```text\ns2.cover:\n {incl_mods,[m1]}.\n```\n\nThis gives an entry for `m1` also in the cover log for test run `s2`. The\nproblem is that this only reflects the coverage by `s2` tests, not the\naccumulated result over `s1` and `s2`. This is where the cross cover mechanism\ncomes in handy.\n\nIf instead the cover specification for `s2` is like the following:\n\n```text\ns2.cover:\n {cross,[{s1,[m1]}]}.\n```\n\nThen `m1` is cover compiled in test run `s2`, but not shown in the coverage log.\nInstead, if `ct_cover:cross_cover_analyse/2` is called after both `s1` and `s2`\ntest runs are completed, the accumulated result for `m1` is available in the\ncross cover log for test run `s1`.\n\nThe call to the analyze function must be as follows:\n\n```erlang\nct_cover:cross_cover_analyse(Level, [{s1,S1LogDir},{s2,S2LogDir}]).\n```\n\nHere, `S1LogDir` and `S2LogDir` are the directories named ` .logs` for\neach test respectively.\n\nNotice the tags `s1` and `s2`, which are used in the cover specification file\nand in the call to `ct_cover:cross_cover_analyse/2`. The purpose of these is\nonly to map the modules specified in the cover specification to the log\ndirectory specified in the call to the analyze function. The tag name has no\nmeaning beyond this.","title":"Cross Cover Analysis - Code Coverage Analysis","ref":"cover_chapter.html#cross-cover-analysis"},{"type":"extras","doc":"To view the result of a code coverage test, click the button labeled \"COVER LOG\"\nin the top-level index page for the test run.\n\nBefore Erlang/OTP 17.1, if your test run consisted of multiple tests, cover\nwould be started and stopped for each test within the test run. Separate logs\nwould be available through the \"Coverage log\" link on the test suite result\npages. These links are still available, but now they all point to the same page\nas the button on the top-level index page. The log contains the accumulated\nresults for the complete test run. For details about this change, see the\nrelease notes.\n\nThe button takes you to the code coverage overview page. If you have\nsuccessfully performed a detailed coverage analysis, links to each individual\nmodule coverage page are found here.\n\nIf cross cover analysis is performed, and there are accumulated coverage results\nfor the current test, the link \"Coverdata collected over all tests\" takes you to\nthese results.","title":"Logging - Code Coverage Analysis","ref":"cover_chapter.html#logging"},{"type":"extras","doc":"\n# Using Common Test for Large-Scale Testing","title":"Using Common Test for Large-Scale Testing","ref":"ct_master_chapter.html"},{"type":"extras","doc":"Large-scale automated testing requires running multiple independent test\nsessions in parallel. This is accomplished by running some `Common Test` nodes\non one or more hosts, testing different target systems. Configuring, starting,\nand controlling the test nodes independently can be a cumbersome operation. To\naid this kind of automated large-scale testing, `Common Test` offers a master\ntest node component, `Common Test` Master, which handles central configuration\nand control in a system of distributed `Common Test` nodes.\n\nThe `Common Test` Master server runs on one dedicated Erlang node and uses\ndistributed Erlang to communicate with any number of `Common Test` test nodes,\neach hosting a regular `Common Test` server. Test specifications are used as\ninput to specify what to test on which test nodes, using what configuration.\n\nThe `Common Test` Master server writes progress information to HTML log files\nsimilarly to the regular `Common Test` server. The logs contain test statistics\nand links to the log files written by each independent `Common Test` server.\n\nThe `Common Test` Master API is exported by module `m:ct_master`.","title":"General - Using Common Test for Large-Scale Testing","ref":"ct_master_chapter.html#general"},{"type":"extras","doc":"`Common Test` Master requires all test nodes to be on the same network and share\na common file system. `Common Test` Master cannot start test nodes\nautomatically. The nodes must be started in advance for `Common Test` Master to\nbe able to start test sessions on them.\n\nTests are started by calling [`ct_master:run(TestSpecs)`](`ct_master:run/1`) or\n[`ct_master:run(TestSpecs, InclNodes, ExclNodes)`](`ct_master:run/3`)\n\n`TestSpecs` is either the name of a test specification file (string) or a list\nof test specifications. If it is a list, the specifications are handled (and the\ncorresponding tests executed) in sequence. An element in a `TestSpecs` list can\nalso be list of test specifications. The specifications in such a list are\nmerged into one combined specification before test execution.\n\n_Example:_\n\n```erlang\nct_master:run([\"ts1\",\"ts2\",[\"ts3\",\"ts4\"]])\n```\n\nHere, the tests specified by \"ts1\" run first, then the tests specified by \"ts2\",\nand finally the tests specified by both \"ts3\" and \"ts4\".\n\nThe `InclNodes` argument to `run/3` is a list of node names. Function `run/3`\nruns the tests in `TestSpecs` just like `run/1`, but also takes any test in\n`TestSpecs`, which is not explicitly tagged with a particular node name, and\nexecute it on the nodes listed in `InclNodes`. By using `run/3` this way, any\ntest specification can be used, with or without node information, in a\nlarge-scale test environment.\n\n`ExclNodes` is a list of nodes to be excluded from the test. That is, tests that\nare specified in the test specification to run on a particular node are not\nperformed if that node is listed in `ExclNodes` at runtime.\n\nIf `Common Test` Master fails initially to connect to any of the test nodes\nspecified in a test specification or in the `InclNodes` list, the operator is\nprompted with the option to either start over again (after manually checking the\nstatus of the nodes in question), to run without the missing nodes, or to abort\nthe operation.\n\nWhen tests start, `Common Test` Master displays information to console about the\ninvolved nodes. `Common Test` Master also reports when tests finish,\nsuccessfully or unsuccessfully. If connection is lost to a node, the test on\nthat node is considered finished. `Common Test` Master does not attempt to\nre-establish contact with the failing node.\n\nAt any time, to get the current status of the test nodes, call function\n[`ct_master:progress()`](`ct_master:progress/0`).\n\nTo stop one or more tests, use function\n[`ct_master:abort()`](`ct_master:abort/0`) (to stop all) or\n[`ct_master:abort(Nodes)`](`ct_master:abort/1`).\n\nFor details about the `Common Test` Master API, see module `m:ct_master`.\n\n[](){: #test_specifications }","title":"Use - Using Common Test for Large-Scale Testing","ref":"ct_master_chapter.html#use"},{"type":"extras","doc":"The test specifications used as input to `Common Test` Master are fully\ncompatible with the specifications used as input to the regular `Common Test`\nserver. The syntax is described in section\n[Test Specifications](run_test_chapter.md#test_specifications) in section\nRunning Tests and Analyzing Results.\n\nAll test specification terms can have a `NodeRefs` element. This element\nspecifies which node or nodes a configuration operation or a test is to be\nexecuted on. `NodeRefs` is defined as follows:\n\n`NodeRefs = all_nodes | [NodeRef] | NodeRef`\n\n`NodeRef = NodeAlias | node() | master`\n\nA `NodeAlias` (`t:atom/0`) is used in a test specification as a reference to a\nnode name (so the node name only needs to be declared once, which also can be\nachieved using constants). The alias is declared with a `node` term as follows:\n\n`{node, NodeAlias, NodeName}`\n\nIf `NodeRefs` has the value `all_nodes`, the operation or test is performed on\nall specified test nodes. (Declaring a term without a `NodeRefs` element has the\nsame effect). If `NodeRefs` has the value `master`, the operation is only\nperformed on the `Common Test` Master node (namely set the log directory or\ninstall an event handler).\n\nConsider the example in section\n[Test Specifications](run_test_chapter.md#test_specifications) in section\nRunning Tests and Analysing Results, now extended with node information and\nintended to be executed by `Common Test` Master:\n\n```erlang\n{define, 'Top', \"/home/test\"}.\n{define, 'T1', \"'Top'/t1\"}.\n{define, 'T2', \"'Top'/t2\"}.\n{define, 'T3', \"'Top'/t3\"}.\n{define, 'CfgFile', \"config.cfg\"}.\n{define, 'Node', ct_node}.\n\n{node, node1, 'Node@host_x'}.\n{node, node2, 'Node@host_y'}.\n\n{logdir, master, \"'Top'/master_logs\"}.\n{logdir, \"'Top'/logs\"}.\n\n{config, node1, \"'T1'/'CfgFile'\"}.\n{config, node2, \"'T2'/'CfgFile'\"}.\n{config, \"'T3'/'CfgFile'\"}.\n\n{suites, node1, 'T1', all}.\n{skip_suites, node1, 'T1', [t1B_SUITE,t1D_SUITE], \"Not implemented\"}.\n{skip_cases, node1, 'T1', t1A_SUITE, [test3,test4], \"Irrelevant\"}.\n{skip_cases, node1, 'T1', t1C_SUITE, [test1], \"Ignore\"}.\n\n{suites, node2, 'T2', [t2B_SUITE,t2C_SUITE]}.\n{cases, node2, 'T2', t2A_SUITE, [test4,test1,test7]}.\n\n{skip_suites, 'T3', all, \"Not implemented\"}.\n```\n\nThis example specifies the same tests as the original example. But now if\nstarted with a call to `ct_master:run(TestSpecName)`, test `t1` is executed on\nnode `ct_node@host_x` (`node1`), test `t2` on `ct_node@host_y` (`node2`) and\ntest `t3` on both `node1` and `node2`. Configuration file `t1` is only read on\n`node1` and configuration file `t2` only on `node2`, while the configuration\nfile `t3` is read on both `node1` and `node2`. Both test nodes write log files\nto the same directory. (However, the `Common Test` Master node uses a different\nlog directory than the test nodes.)\n\nIf the test session is instead started with a call to\n`ct_master:run(TestSpecName, [ct_node@host_z], [ct_node@host_x])`, the result is\nthat test `t1` does not run on `ct_node@host_x` (or any other node) while test\n`t3` runs on both `ct_node@host_y` and `ct_node@host_z`.\n\nA nice feature is that a test specification that includes node information can\nstill be used as input to the regular `Common Test` server (as described in\nsection [Test Specifications](run_test_chapter.md#test_specifications)). The\nresult is that any test specified to run on a node with the same name as the\n`Common Test` node in question (typically `ct@somehost` if started with the\n`ct_run` program), is performed. Tests without explicit node association are\nalways performed too, of course.","title":"Test Specifications - Using Common Test for Large-Scale Testing","ref":"ct_master_chapter.html#test-specifications"},{"type":"extras","doc":"[](){: #ct_slave }\n\nInitial actions can be started and performed automatically on test target nodes\nusing test specification term `init`.\n\nTwo subterms are supported, `node_start` and `eval`.\n\n_Example:_\n\n```erlang\n{node, node1, node1@host1}.\n{node, node2, node1@host2}.\n{node, node3, node2@host2}.\n{node, node4, node1@host3}.\n{init, node1, [{node_start, [{callback_module, my_slave_callback}]}]}.\n{init, [node2, node3], {node_start, [{username, \"ct_user\"}, {password, \"ct_password\"}]}}.\n{init, node4, {eval, {module, function, []}}}.\n```\n\nThis test specification declares that `node1@host1` is to be started using the\nuser callback function `callback_module:my_slave_callback/0`, and nodes\n`node1@host2` and `node2@host2` are to be started with the default callback\nmodule `ct_slave`. The specified username and password are used to log on to\nremote host `host2`. Also, function `module:function/0` is evaluated on\n`node1@host3`, and the result of this call is printed to the log.\n\nThe default callback module `m:ct_slave`, has the following features:\n\n- Starting Erlang target nodes on local or remote hosts (application `SSH` is\n used for communication).\n- Ability to start an Erlang emulator with more flags (any flags supported by\n `erl` are supported).\n- Supervision of a node being started using internal callback functions. Used to\n prevent hanging nodes. (Configurable.)\n- Monitoring of the master node by the slaves. A slave node can be stopped if\n the master node terminates. (Configurable.)\n- Execution of user functions after a slave node is started. Functions can be\n specified as a list of `{Module, Function, Arguments}` tuples.\n\n> #### Note {: .info }\n>\n> An `eval` term for the node and `startup_functions` in the `node_start`\n> options list can be specified. In this case, the node is started first, then\n> the `startup_functions` are executed, and finally functions specified with\n> `eval` are called.","title":"Automatic Startup of Test Target Nodes - Using Common Test for Large-Scale Testing","ref":"ct_master_chapter.html#automatic-startup-of-test-target-nodes"},{"type":"extras","doc":"\n# Event Handling\n\n[](){: #event_handling }","title":"Event Handling","ref":"event_handler_chapter.html"},{"type":"extras","doc":"The operator of a `Common Test` system can receive event notifications\ncontinuously during a test run. For example, `Common Test` reports when a test\ncase starts and stops, the current count of successful, failed, and skipped\ncases, and so on. This information can be used for different purposes such as\nlogging progress and results in another format than HTML, saving statistics to a\ndatabase for report generation, and test system supervision.\n\n`Common Test` has a framework for event handling based on the OTP event manager\nconcept and `gen_event` behavior. When the `Common Test` server starts, it\nspawns an event manager. During test execution the manager gets a notification\nfrom the server when something of potential interest happens. Any event handler\nplugged into the event manager can match on events of interest, take action, or\npass the information on. The event handlers are Erlang modules implemented by\nthe `Common Test` user according to the `gen_event` behavior (for details, see\nmodule `m:gen_event` and section [`gen_event Behaviour`](`e:system:events.md`)\nin OTP Design Principles in the System Documentation).\n\nA `Common Test` server always starts an event manager. The server also plugs in\na default event handler, which only purpose is to relay notifications to a\nglobally registered `Common Test` Master event manager (if a `Common Test`\nMaster server is running in the system). The `Common Test` Master also spawns an\nevent manager at startup. Event handlers plugged into this manager receives the\nevents from all the test nodes, plus information from the `Common Test` Master\nserver.\n\nUser-specific event handlers can be plugged into a `Common Test` event manager,\neither by telling `Common Test` to install them before the test run (described\nlater), or by adding the handlers dynamically during the test run using\n`gen_event:add_handler/3` or `gen_event:add_sup_handler/3`. In the latter\nscenario, the reference of the `Common Test` event manager is required. To get\nit, call `ct:get_event_mgr_ref/0` or (on the `Common Test` Master node)\n`ct_master:get_event_mgr_ref/0`.\n\n[](){: #usage }","title":"General - Event Handling","ref":"event_handler_chapter.html#general"},{"type":"extras","doc":"Event handlers can be installed by an `event_handler` start flag\n([`ct_run`](ct_run_cmd.md)) or option `ct:run_test/1`, where the argument\nspecifies the names of one or more event handler modules.\n\n_Example:_\n\n`$ ct_run -suite test/my_SUITE -event_handler handlers/my_evh1 handlers/my_evh2 -pa $PWD/handlers`\n\nTo pass start arguments to the event handler init function, use option\n`ct_run -event_handler_init` instead of `-event_handler`.\n\n> #### Note {: .info }\n>\n> All event handler modules must have `gen_event` behavior. These modules must\n> be precompiled and their locations must be added explicitly to the Erlang code\n> server search path (as in the previous example).\n\nAn event_handler tuple in argument `Opts` has the following definition (see\n`ct:run_test/1`):\n\n```erlang\n{event_handler,EventHandlers}\n\nEventHandlers = EH | [EH]\nEH = atom() | {atom(),InitArgs} | {[atom()],InitArgs}\nInitArgs = [term()]\n```\n\nIn the following example, two event handlers for the `my_SUITE` test are\ninstalled:\n\n```erlang\n1> ct:run_test([{suite,\"test/my_SUITE\"},{event_handler,[my_evh1,{my_evh2,[node()]}]}]).\n```\n\nEvent handler `my_evh1` is started with `[]` as argument to the init function.\nEvent handler `my_evh2` is started with the name of the current node in the init\nargument list.\n\nEvent handlers can also be plugged in using one of the following\n[test specification](run_test_chapter.md#test_specifications) terms:\n\n- `{event_handler, EventHandlers}`\n- `{event_handler, EventHandlers, InitArgs}`\n- `{event_handler, NodeRefs, EventHandlers}`\n- `{event_handler, NodeRefs, EventHandlers, InitArgs}`\n\n`EventHandlers` is a list of module names. Before a test session starts, the\ninit function of each plugged in event handler is called (with the `InitArgs`\nlist as argument or `[]` if no start arguments are specified).\n\nTo plug in a handler to the `Common Test` Master event manager, specify `master`\nas the node in `NodeRefs`.\n\nTo be able to match on events, the event handler module must include the header\nfile `ct_event.hrl`. An event is a record with the following definition:\n\n`#event{name, node, data}`\n\n- **`name`** - Label (type) of the event.\n\n- **`node`** - Name of the node that the event originated from (only relevant\n for `Common Test` Master event handlers).\n\n- **`data`** - Specific for the event.\n\n[](){: #events }","title":"Use - Event Handling","ref":"event_handler_chapter.html#use"},{"type":"extras","doc":"The general events are as follows:\n\n- **`#event{name = start_logging, data = LogDir}`** - `LogDir = string()`,\n top-level log directory for the test run.\n\n This event indicates that the logging process of `Common Test` has started\n successfully and is ready to receive I/O messages.\n\n- **`#event{name = stop_logging, data = []}`** - This event indicates that the\n logging process of `Common Test` was shut down at the end of the test run.\n\n- **`#event{name = test_start, data = {StartTime,LogDir}}`** -\n `StartTime = {date(),time()}`, test run start date and time.\n\n `LogDir = string()`, top-level log directory for the test run.\n\n This event indicates that `Common Test` has finished initial preparations and\n begins executing test cases.\n\n- **`#event{name = test_done, data = EndTime}`** - `EndTime = {date(),time()}`,\n date and time the test run finished.\n\n This event indicates that the last test case has been executed and\n `Common Test` is shutting down.\n\n- **`#event{name = start_info, data = {Tests,Suites,Cases}}`** -\n `Tests = integer()`, number of tests.\n\n `Suites = integer()`, total number of suites.\n\n `Cases = integer() | unknown`, total number of test cases.\n\n This event gives initial test run information that can be interpreted as:\n \"This test run will execute `Tests` separate tests, in total containing\n `Cases` number of test cases, in `Suites` number of suites\". However, if a\n test case group with a repeat property exists in any test, the total number of\n test cases cannot be calculated (unknown).\n\n- **`#event{name = tc_start, data = {Suite,FuncOrGroup}}`** - `Suite = atom()`,\n name of the test suite.\n\n `FuncOrGroup = Func | {Conf,GroupName,GroupProperties}`\n\n `Func = atom()`, name of test case or configuration function.\n\n `Conf = init_per_group | end_per_group`, group configuration function.\n\n `GroupName = atom()`, name of the group.\n\n `GroupProperties = list()`, list of execution properties for the group.\n\n This event informs about the start of a test case, or a group configuration\n function. The event is sent also for `init_per_suite` and `end_per_suite`, but\n not for `init_per_testcase` and `end_per_testcase`. If a group configuration\n function starts, the group name and execution properties are also specified.\n\n- **`#event{name = tc_logfile, data = {{Suite,Func},LogFileName}}`** -\n `Suite = atom()`, name of the test suite.\n\n `Func = atom()`, name of test case or configuration function.\n\n `LogFileName = string()`, full name of the test case log file.\n\n This event is sent at the start of each test case (and configuration function\n except `init/end_per_testcase`) and carries information about the full name\n (that is, the file name including the absolute directory path) of the current\n test case log file.\n\n- **`#event{name = tc_done, data = {Suite,FuncOrGroup,Result}}`** - [](){:\n #tc_done } `Suite = atom()`, name of the suite.\n\n `FuncOrGroup = Func | {Conf,GroupName,GroupProperties}`\n\n `Func = atom()`, name of test case or configuration function.\n\n `Conf = init_per_group | end_per_group`, group configuration function.\n\n `GroupName = unknown | atom()`, name of the group (unknown if init- or end\n function times out).\n\n `GroupProperties = list()`, list of execution properties for the group.\n\n `Result = ok | {auto_skipped,SkipReason} | {skipped,SkipReason} | {failed,FailReason}`,\n the result.\n\n [](){: #skipreason }\n `SkipReason = {require_failed,RequireInfo} | {require_failed_in_suite0,RequireInfo} | {failed,{Suite,init_per_testcase,FailInfo}} | UserTerm`,\n why the case was skipped.\n\n [](){: #failreason }\n `FailReason = {error,FailInfo} | {error,{RunTimeError,StackTrace}} | {timetrap_timeout,integer()} | {failed,{Suite,end_per_testcase,FailInfo}}`,\n reason for failure.\n\n `RequireInfo = {not_available,atom() | tuple()}`, why require failed.\n\n `FailInfo = {timetrap_timeout,integer()} | {RunTimeError,StackTrace} | UserTerm`,\n error details.\n\n `RunTimeError = term()`, a runtime error, for example, `badmatch` or `undef`.\n\n `StackTrace = list()`, list of function calls preceding a runtime error.\n\n `UserTerm = term()`, any data specified by user, or [`exit/1`](`exit/1`)\n information.\n\n This event informs about the end of a test case or a configuration function\n (see event `tc_start` for details on element `FuncOrGroup`). With this event\n comes the final result of the function in question. It is possible to\n determine on the top level of `Result` if the function was successful, skipped\n (by the user), or if it failed.\n\n It is also possible to dig deeper and, for example, perform pattern matching\n on the various reasons for skipped or failed. Notice that `{'EXIT',Reason}`\n tuples are translated into `{error,Reason}`. Notice also that if a\n `{failed,{Suite,end_per_testcase,FailInfo}` result is received, the test case\n was successful, but `end_per_testcase` for the case failed.\n\n- **`#event{name = tc_auto_skip, data = {Suite,TestName,Reason}}`** - [](){:\n #tc_auto_skip } `Suite = atom()`, the name of the suite.\n\n `TestName = init_per_suite | end_per_suite | {init_per_group,GroupName} | {end_per_group,GroupName} | {FuncName,GroupName} | FuncName`\n\n `FuncName = atom()`, the name of the test case or configuration function.\n\n `GroupName = atom()`, the name of the test case group.\n\n `Reason = {failed,FailReason} | {require_failed_in_suite0,RequireInfo}`,\n reason for auto-skipping `Func`.\n\n `FailReason = {Suite,ConfigFunc,FailInfo}} | {Suite,FailedCaseInSequence}`,\n reason for failure.\n\n `RequireInfo = {not_available,atom() | tuple()}`, why require failed.\n\n `ConfigFunc = init_per_suite | init_per_group`\n\n `FailInfo = {timetrap_timeout,integer()} | {RunTimeError,StackTrace} | bad_return | UserTerm`,\n error details.\n\n `FailedCaseInSequence = atom()`, the name of a case that failed in a sequence.\n\n `RunTimeError = term()`, a runtime error, for example `badmatch` or `undef`.\n\n `StackTrace = list()`, list of function calls preceding a runtime error.\n\n `UserTerm = term()`, any data specified by user, or [`exit/1`](`exit/1`)\n information.\n\n This event is sent for every test case or configuration function that\n `Common Test` has skipped automatically because of either a failed\n `init_per_suite` or `init_per_group`, a failed `require` in `suite/0`, or a\n failed test case in a sequence. Notice that this event is never received as a\n result of a test case getting skipped because of `init_per_testcase` failing,\n as that information is carried with event `tc_done`. If a failed test case\n belongs to a test case group, the second data element is a tuple\n `{FuncName,GroupName}`, otherwise only the function name.\n\n- **`#event{name = tc_user_skip, data = {Suite,TestName,Comment}}`** - [](){:\n #tc_user_skip } `Suite = atom()`, the name of the suite.\n\n `TestName = init_per_suite | end_per_suite | {init_per_group,GroupName} | {end_per_group,GroupName} | {FuncName,GroupName} | FuncName`\n\n `FuncName = atom()`, the name of the test case or configuration function.\n\n `GroupName = atom()`, the name of the test case group.\n\n `Comment = string()`, why the test case was skipped.\n\n This event specifies that a test case was skipped by the user. It is only\n received if the skip is declared in a test specification. Otherwise, user skip\n information is received as a `{skipped,SkipReason}` result in event `tc_done`\n for the test case. If a skipped test case belongs to a test case group, the\n second data element is a tuple `{FuncName,GroupName}`, otherwise only the\n function name.\n\n- **`#event{name = test_stats, data = {Ok,Failed,Skipped}}`** -\n `Ok = integer()`, current number of successful test cases.\n\n `Failed = integer()`, current number of failed test cases.\n\n `Skipped = {UserSkipped,AutoSkipped}`\n\n `UserSkipped = integer()`, current number of user-skipped test cases.\n\n `AutoSkipped = integer()`, current number of auto-skipped test cases.\n\n This is a statistics event with current count of successful, skipped, and\n failed test cases so far. This event is sent after the end of each test case,\n immediately following event `tc_done`.","title":"General Events - Event Handling","ref":"event_handler_chapter.html#general-events"},{"type":"extras","doc":"The internal events are as follows:\n\n- **`#event{name = start_make, data = Dir}`** - `Dir = string()`, running make\n in this directory.\n\n This internal event says that `Common Test` starts compiling modules in\n directory `Dir`.\n\n- **`#event{name = finished_make, data = Dir}`** - `Dir = string()`, finished\n running make in this directory.\n\n This internal event says that `Common Test` is finished compiling modules in\n directory `Dir`.\n\n- **`#event{name = start_write_file, data = FullNameFile}`** -\n `FullNameFile = string(), full name of the file.`\n\n This internal event is used by the `Common Test` Master process to synchronize\n particular file operations.\n\n- **`#event{name = finished_write_file, data = FullNameFile}`** -\n `FullNameFile = string(), full name of the file.`\n\n This internal event is used by the `Common Test` Master process to synchronize\n particular file operations.","title":"Internal Events - Event Handling","ref":"event_handler_chapter.html#internal-events"},{"type":"extras","doc":"The events are also documented in `ct_event.erl`. This module can serve as an\nexample of what an event handler for the `Common Test` event manager can look\nlike.\n\n> #### Note {: .info }\n>\n> To ensure that printouts to `stdout` (or printouts made with\n> [`ct:log/2,3`](`ct:log/2`) or [`ct:pal,2,3`](`ct:pal/2`)) get written to the\n> test case log file, and not to the `Common Test` framework log, you can\n> synchronize with the `Common Test` server by matching on events `tc_start` and\n> `tc_done`. In the period between these events, all I/O is directed to the test\n> case log file. These events are sent synchronously to avoid potential timing\n> problems (for example, that the test case log file is closed just before an\n> I/O message from an external process gets through). Knowing this, you need to\n> be careful that your `handle_event/2` callback function does not stall the\n> test execution, possibly causing unexpected behavior as a result.","title":"Notes - Event Handling","ref":"event_handler_chapter.html#notes"},{"type":"extras","doc":"\n# Dependencies between Test Cases and Suites","title":"Dependencies between Test Cases and Suites","ref":"dependencies_chapter.html"},{"type":"extras","doc":"When creating test suites, it is strongly recommended to not create dependencies\nbetween test cases, that is, letting test cases depend on the result of previous\ntest cases. There are various reasons for this, such as, the following:\n\n- It makes it impossible to run test cases individually.\n- It makes it impossible to run test cases in a different order.\n- It makes debugging difficult (as a fault can be the result of a problem in a\n different test case than the one failing).\n- There are no good and explicit ways to declare dependencies, so it can be\n difficult to see and understand these in test suite code and in test logs.\n- Extending, restructuring, and maintaining test suites with test case\n dependencies is difficult.\n\nThere are often sufficient means to work around the need for test case\ndependencies. Generally, the problem is related to the state of the System Under\nTest (SUT). The action of one test case can change the system state. For some\nother test case to run properly, this new state must be known.\n\nInstead of passing data between test cases, it is recommended that the test\ncases read the state from the SUT and perform assertions (that is, let the test\ncase run if the state is as expected, otherwise reset or fail). It is also\nrecommended to use the state to set variables necessary for the test case to\nexecute properly. Common actions can often be implemented as library functions\nfor test cases to call to set the SUT in a required state. (Such common actions\ncan also be separately tested, if necessary, to ensure that they work as\nexpected). It is sometimes also possible, but not always desirable, to group\ntests together in one test case, that is, let a test case perform a \"scenario\"\ntest (a test consisting of subtests).\n\nConsider, for example, a server application under test. The following\nfunctionality is to be tested:\n\n- Starting the server\n- Configuring the server\n- Connecting a client to the server\n- Disconnecting a client from the server\n- Stopping the server\n\nThere are obvious dependencies between the listed functions. The server cannot\nbe configured if it has not first been started, a client cannot be connected\nuntil the server is properly configured, and so on. If we want to have one test\ncase for each function, we might be tempted to try to always run the test cases\nin the stated order and carry possible data (identities, handles, and so on)\nbetween the cases and therefore introduce dependencies between them.\n\nTo avoid this, we can consider starting and stopping the server for every test.\nWe can thus implement the start and stop action as common functions to be called\nfrom [`init_per_testcase`](`c:ct_suite:init_per_testcase/2`) and\n[`end_per_testcase`](`c:ct_suite:end_per_testcase/2`). (Remember to test the\nstart and stop functionality separately.) The configuration can also be\nimplemented as a common function, maybe grouped with the start function.\nFinally, the testing of connecting and disconnecting a client can be grouped\ninto one test case. The resulting suite can look as follows:\n\n```erlang\n-module(my_server_SUITE).\n-compile(export_all).\n-include_lib(\"ct.hrl\").\n\n%%% init and end functions...\n\nsuite() -> [{require,my_server_cfg}].\n\ninit_per_testcase(start_and_stop, Config) ->\n Config;\n\ninit_per_testcase(config, Config) ->\n [{server_pid,start_server()} | Config];\n\ninit_per_testcase(_, Config) ->\n ServerPid = start_server(),\n configure_server(),\n [{server_pid,ServerPid} | Config].\n\nend_per_testcase(start_and_stop, _) ->\n ok;\n\nend_per_testcase(_, Config) ->\n ServerPid = proplists:get_value(server_pid, Config),\n stop_server(ServerPid).\n\n%%% test cases...\n\nall() -> [start_and_stop, config, connect_and_disconnect].\n\n%% test that starting and stopping works\nstart_and_stop(_) ->\n ServerPid = start_server(),\n stop_server(ServerPid).\n\n%% configuration test\nconfig(Config) ->\n ServerPid = proplists:get_value(server_pid, Config),\n configure_server(ServerPid).\n\n%% test connecting and disconnecting client\nconnect_and_disconnect(Config) ->\n ServerPid = proplists:get_value(server_pid, Config),\n {ok,SessionId} = my_server:connect(ServerPid),\n ok = my_server:disconnect(ServerPid, SessionId).\n\n%%% common functions...\n\nstart_server() ->\n {ok,ServerPid} = my_server:start(),\n ServerPid.\n\nstop_server(ServerPid) ->\n ok = my_server:stop(),\n ok.\n\nconfigure_server(ServerPid) ->\n ServerCfgData = ct:get_config(my_server_cfg),\n ok = my_server:configure(ServerPid, ServerCfgData),\n ok.\n```\n\n[](){: #save_config }","title":"General - Dependencies between Test Cases and Suites","ref":"dependencies_chapter.html#general"},{"type":"extras","doc":"Sometimes it is impossible, or infeasible, to implement independent test cases.\nMaybe it is not possible to read the SUT state. Maybe resetting the SUT is\nimpossible and it takes too long time to restart the system. In situations where\ntest case dependency is necessary, CT offers a structured way to carry data from\none test case to the next. The same mechanism can also be used to carry data\nfrom one test suite to the next.\n\nThe mechanism for passing data is called `save_config`. The idea is that one\ntest case (or suite) can save the current value of `Config`, or any list of\nkey-value tuples, so that the next executing test case (or test suite) can read\nit. The configuration data is not saved permanently but can only be passed from\none case (or suite) to the next.\n\nTo save `Config` data, return tuple `{save_config,ConfigList}` from\n`end_per_testcase` or from the main test case function.\n\nTo read data saved by a previous test case, use `proplists:get_value` with a\n`saved_config` key as follows:\n\n`{Saver,ConfigList} = proplists:get_value(saved_config, Config)`\n\n`Saver` (`t:atom/0`) is the name of the previous test case (where the data was\nsaved). The `proplists:get_value` function can be used to extract particular\ndata also from the recalled `ConfigList`. It is strongly recommended that\n`Saver` is always matched to the expected name of the saving test case. This\nway, problems because of restructuring of the test suite can be avoided. Also,\nit makes the dependency more explicit and the test suite easier to read and\nmaintain.\n\nTo pass data from one test suite to another, the same mechanism is used. The\ndata is to be saved by finction [`end_per_suite`](`c:ct_suite:end_per_suite/1`)\nand read by function [`init_per_suite`](`c:ct_suite:init_per_suite/1`) in the\nsuite that follows. When passing data between suites, `Saver` carries the name\nof the test suite.\n\n_Example:_\n\n```erlang\n-module(server_b_SUITE).\n-compile(export_all).\n-include_lib(\"ct.hrl\").\n\n%%% init and end functions...\n\ninit_per_suite(Config) ->\n %% read config saved by previous test suite\n {server_a_SUITE,OldConfig} = proplists:get_value(saved_config, Config),\n %% extract server identity (comes from server_a_SUITE)\n ServerId = proplists:get_value(server_id, OldConfig),\n SessionId = connect_to_server(ServerId),\n [{ids,{ServerId,SessionId}} | Config].\n\nend_per_suite(Config) ->\n %% save config for server_c_SUITE (session_id and server_id)\n {save_config,Config}\n\n%%% test cases...\n\nall() -> [allocate, deallocate].\n\nallocate(Config) ->\n {ServerId,SessionId} = proplists:get_value(ids, Config),\n {ok,Handle} = allocate_resource(ServerId, SessionId),\n %% save handle for deallocation test\n NewConfig = [{handle,Handle}],\n {save_config,NewConfig}.\n\ndeallocate(Config) ->\n {ServerId,SessionId} = proplists:get_value(ids, Config),\n {allocate,OldConfig} = proplists:get_value(saved_config, Config),\n Handle = proplists:get_value(handle, OldConfig),\n ok = deallocate_resource(ServerId, SessionId, Handle).\n```\n\nTo save `Config` data from a test case that is to be skipped, return tuple\n`{skip_and_save,Reason,ConfigList}`.\n\nThe result is that the test case is skipped with `Reason` printed to the log\nfile (as described earlier) and `ConfigList` is saved for the next test case.\n`ConfigList` can be read using `proplists:get_value(saved_config, Config)`, as\ndescribed earlier. `skip_and_save` can also be returned from `init_per_suite`.\nIn this case, the saved data can be read by `init_per_suite` in the suite that\nfollows.","title":"Saving Configuration Data - Dependencies between Test Cases and Suites","ref":"dependencies_chapter.html#saving-configuration-data"},{"type":"extras","doc":"Sometimes test cases depend on each other so that if one case fails, the\nfollowing tests are not to be executed. Typically, if the `save_config` facility\nis used and a test case that is expected to save data crashes, the following\ncase cannot run. `Common Test` offers a way to declare such dependencies, called\nsequences.\n\nA sequence of test cases is defined as a test case group with a `sequence`\nproperty. Test case groups are defined through function `groups/0` in the test\nsuite (for details, see section\n[Test Case Groups](write_test_chapter.md#test_case_groups).\n\nFor example, to ensure that if `allocate` in `server_b_SUITE` crashes,\n`deallocate` is skipped, the following sequence can be defined:\n\n```erlang\ngroups() -> [{alloc_and_dealloc, [sequence], [alloc,dealloc]}].\n```\n\nAssume that the suite contains the test case `get_resource_status` that is\nindependent of the other two cases, then function `all` can look as follows:\n\n```erlang\nall() -> [{group,alloc_and_dealloc}, get_resource_status].\n```\n\nIf `alloc` succeeds, `dealloc` is also executed. If `alloc` fails however,\n`dealloc` is not executed but marked as `SKIPPED` in the HTML log.\n`get_resource_status` runs no matter what happens to the `alloc_and_dealloc`\ncases.\n\nTest cases in a sequence are executed in order until all succeed or one fails.\nIf one fails, all following cases in the sequence are skipped. The cases in the\nsequence that have succeeded up to that point are reported as successful in the\nlog. Any number of sequences can be specified.\n\n_Example:_\n\n```erlang\ngroups() -> [{scenarioA, [sequence], [testA1, testA2]},\n {scenarioB, [sequence], [testB1, testB2, testB3]}].\n\nall() -> [test1,\n test2,\n {group,scenarioA},\n test3,\n {group,scenarioB},\n test4].\n```\n\nA sequence group can have subgroups. Such subgroups can have any property, that\nis, they are not required to also be sequences. If you want the status of the\nsubgroup to affect the sequence on the level above, return\n`{return_group_result,Status}` from\n[`end_per_group/2`](`c:ct_suite:end_per_group/2`), as described in section\n[Repeated Groups](write_test_chapter.md#repeated_groups) in Writing Test Suites.\nA failed subgroup (`Status == failed`) causes the execution of a sequence to\nfail in the same way a test case does.","title":"Sequences - Dependencies between Test Cases and Suites","ref":"dependencies_chapter.html#sequences"},{"type":"extras","doc":"\n# Common Test Hooks","title":"Common Test Hooks","ref":"ct_hooks_chapter.html"},{"type":"extras","doc":"The _Common Test Hook (CTH)_ framework allows extensions of the default behavior\nof `Common Test` using hooks before and after all test suite calls. CTHs allow\nadvanced `Common Test` users to abstract out behavior that is common to multiple\ntest suites without littering all test suites with library calls. This can be\nused for logging, starting, and monitoring external systems, building C files\nneeded by the tests, and so on.\n\nIn brief, CTH allows you to do the following:\n\n- Manipulate the runtime configuration before each suite configuration call.\n- Manipulate the return of all suite configuration calls, and in extension, the\n result of the tests themselves.\n\nThe following sections describe how to use CTHs, when they are run, and how to\nmanipulate the test results in a CTH.\n\n> #### Warning {: .warning }\n>\n> When executing within a CTH, all timetraps are shut off. So if your CTH never\n> returns, the entire test run is stalled.\n\n[](){: #installing }","title":"General - Common Test Hooks","ref":"ct_hooks_chapter.html#general"},{"type":"extras","doc":"A CTH can be installed in multiple ways in your test run. You can do it for all\ntests in a run, for specific test suites, and for specific groups within a test\nsuite. If you want a CTH to be present in all test suites within your test run,\nthere are three ways to accomplish that, as follows:\n\n- Add `-ct_hooks` as an argument to [ct_run](run_test_chapter.md#ct_run). To add\n multiple CTHs using this method, append them to each other using the keyword\n `and`, that is, `ct_run -ct_hooks cth1 [{debug,true}] and cth2 ...`.\n- Add tag `ct_hooks` to your\n [Test Specification](run_test_chapter.md#test_specifications).\n- Add tag `ct_hooks` to your call to `ct:run_test/1`.\n\nCTHs can also be added within a test suite. This is done by returning\n`{ct_hooks,[CTH]}` in the configuration list from\n[suite/0](`c:ct_suite:suite/0`),\n[init_per_suite/1](`c:ct_suite:init_per_suite/1`), or\n[init_per_group/2](`c:ct_suite:init_per_group/2`).\n\nIn this case, `CTH` can either be only the module name of the CTH or a tuple\nwith the module name and the initial arguments, and optionally the hook priority\nof the CTH. For example, one of the following:\n\n- `{ct_hooks,[my_cth_module]}`\n- `{ct_hooks,[{my_cth_module,[{debug,true}]}]}`\n- `{ct_hooks,[{my_cth_module,[{debug,true}],500}]}`\n\nNote that regardless of how you install a CTH, its BEAM file must be available\nin the code path when Common Test runs. `ct_run` accepts the `-pa` command line\noption.","title":"Installing a CTH - Common Test Hooks","ref":"ct_hooks_chapter.html#installing-a-cth"},{"type":"extras","doc":"By default, each installation of a CTH causes a new instance of it to be\nactivated. This can cause problems if you want to override CTHs in test\nspecifications while still having them in the suite information function. The\n[id/1](`c:ct_hooks:id/1`) callback exists to address this problem. By returning\nthe same `id` in both places, `Common Test` knows that this CTH is already\ninstalled and does not try to install it again.\n\n[](){: #cth_execution_order }","title":"Overriding CTHs - Common Test Hooks","ref":"ct_hooks_chapter.html#overriding-cths"},{"type":"extras","doc":"By default, each installed CTH is executed in the order in which they are\ninstalled for init calls, and then reversed for end calls. This order can be\nreferred to as test-centric, as the order is reversed after a testcase is\nexecuted and corresponds to the default value (`test`) of `ct_hooks_order`\noption.\n\nThe installation-based order is not always desired, so `Common Test` allows the\nuser to specify a priority for each hook. The priority can be specified in the\nCTH function [init/2](`c:ct_hooks:init/2`) or when installing the hook. The\npriority specified at installation overrides the priority returned by the CTH.\n\nIn some cases, the reversed order for all end calls is not desired, and instead,\nthe user might prefer the reversed order for post hook calls. Such behavior can\nbe enabled with `ct_hooks_order` option with `config` value. When this option is\nenabled, the execution order is configuration-centric, as the reversed order\nhappens after each configuration function and not in relation to testcase.\n\nNote that the `ct_hooks_order` option is considered as a global framework\nsetting. In case when option is configured multiple times framework with process\nonly the first value.\n\nThe `ct_hooks_order` option can be set as: `ct_run` argument, in test\nspecification or [suite/0](`c:ct_suite:suite/0`) return value.\n\n[](){: #scope }","title":"CTH Execution Order - Common Test Hooks","ref":"ct_hooks_chapter.html#cth-execution-order"},{"type":"extras","doc":"Once the CTH is installed into a certain test run it remains there until its\nscope is expired. The scope of a CTH depends on when it is installed, see the\nfollowing table. Function [init/2](`c:ct_hooks:init/2`) is called at the\nbeginning of the scope and function [terminate/1](`c:ct_hooks:terminate/1`) is\ncalled when the scope ends.\n\n| _CTH installed in_ | _CTH scope begins before_ | _CTH scope ends after_ |\n| ------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |\n| [ct_run](run_test_chapter.md#ct_run) | the first test suite is to be run | the last test suite has been run |\n| [ct:run_test](`ct:run_test/1`) | the first test suite is run | the last test suite has been run |\n| [Test Specification](run_test_chapter.md#test_specifications) | the first test suite is run | the last test suite has been run |\n| [suite/0](`c:ct_suite:suite/0`) | [pre_init_per_suite/3](`c:ct_hooks:pre_init_per_suite/3`) is called | [post_end_per_suite/4](`c:ct_hooks:post_end_per_suite/4`) has been called for that test suite |\n| [init_per_suite/1](`c:ct_suite:init_per_suite/1`) | [post_init_per_suite/4](`c:ct_hooks:post_init_per_suite/4`) is called | [post_end_per_suite/4](`c:ct_hooks:post_end_per_suite/4`) has been called for that test suite |\n| [init_per_group/2](`c:ct_suite:init_per_group/2`) | [post_init_per_group/5](`c:ct_hooks:post_init_per_group/5`) is called | [post_end_per_group/5](`c:ct_hooks:post_end_per_group/5`) has been called for that group |\n\n_Table: Scope of a CTH_","title":"CTH Scope - Common Test Hooks","ref":"ct_hooks_chapter.html#cth-scope"},{"type":"extras","doc":"CTHs are run with the same process scoping as normal test suites, that is, a\ndifferent process executes the `init_per_suite` hooks then the `init_per_group`\nor `per_testcase` hooks. So if you want to spawn a process in the CTH, you\ncannot link with the CTH process, as it exits after the post hook ends. Also, if\nyou for some reason need an ETS table with your CTH, you must spawn a process\nthat handles it.","title":"CTH Processes and Tables - Common Test Hooks","ref":"ct_hooks_chapter.html#cth-processes-and-tables"},{"type":"extras","doc":"Configuration data values in the CTH can be read by calling\n[`ct:get_config/1,2,3`](`ct:get_config/1`) (as explained in section\n[Requiring and Reading Configuration Data](config_file_chapter.md#require_config_data)).\nThe configuration variables in question must, as always, first have been\nrequired by a suite-, group-, or test case information function, or by function\n[`ct:require/1/2`](`ct:require/1`). The latter can also be used in CT hook\nfunctions.\n\nThe CT hook functions can call any logging function in the `ct` interface to\nprint information to the log files, or to add comments in the suite overview\npage.\n\n[](){: #manipulating }","title":"External Configuration Data and Logging - Common Test Hooks","ref":"ct_hooks_chapter.html#external-configuration-data-and-logging"},{"type":"extras","doc":"Through CTHs the results of tests and configuration functions can be\nmanipulated. The main purpose to do this with CTHs is to allow common patterns\nto be abstracted out from test suites and applied to multiple test suites\nwithout duplicating any code. All the callback functions for a CTH follow a\ncommon interface described hereafter.\n\n`Common Test` always calls all available hook functions, even pre- and post\nhooks for configuration functions that are not implemented in the suite. For\nexample, `pre_init_per_suite(x_SUITE, ...)` and\n`post_init_per_suite(x_SUITE, ...)` are called for test suite `x_SUITE`, even if\nit does not export `init_per_suite/1`. With this feature hooks can be used as\nconfiguration fallbacks, and all configuration functions can be replaced with\nhook functions.\n\n[](){: #pre }","title":"Manipulating Tests - Common Test Hooks","ref":"ct_hooks_chapter.html#manipulating-tests"},{"type":"extras","doc":"In a CTH, the behavior can be hooked in before the following functions:\n\n- [`init_per_suite`](`c:ct_suite:init_per_suite/1`)\n- [`init_per_group`](`c:ct_suite:init_per_group/2`)\n- [`init_per_testcase`](`c:ct_suite:init_per_testcase/2`)\n- [`end_per_testcase`](`c:ct_suite:end_per_testcase/2`)\n- [`end_per_group`](`c:ct_suite:end_per_group/2`)\n- [`end_per_suite`](`c:ct_suite:end_per_suite/1`)\n\nThis is done in the CTH functions called `pre_ `. These\nfunctions take the arguments `SuiteName`, `Name` (group or test case name, if\napplicable), `Config`, and `CTHState`. The return value of the CTH function is\nalways a combination of a result for the suite/group/test and an updated\n`CTHState`.\n\nTo let the test suite continue on executing, return the configuration list that\nyou want the test to use as the result.\n\nAll pre hooks, except `pre_end_per_testcase/4`, can skip or fail the test by\nreturning a tuple with `skip` or `fail`, and a reason as the result.\n\n_Example:_\n\n```erlang\npre_init_per_suite(SuiteName, Config, CTHState) ->\n case db:connect() of\n {error,_Reason} ->\n {{fail, \"Could not connect to DB\"}, CTHState};\n {ok, Handle} ->\n {[{db_handle, Handle} | Config], CTHState#state{ handle = Handle }}\n end.\n```\n\n> #### Note {: .info }\n>\n> If you use multiple CTHs, the first part of the return tuple is used as input\n> for the next CTH. So in the previous example the next CTH can get\n> `{fail,Reason}` as the second parameter. If you have many CTHs interacting, do\n> not let each CTH return `fail` or `skip`. Instead, return that an action is to\n> be taken through the `Config` list and implement a CTH that, at the end, takes\n> the correct action.\n\n[](){: #post }","title":"Pre Hooks - Common Test Hooks","ref":"ct_hooks_chapter.html#pre-hooks"},{"type":"extras","doc":"In a CTH, behavior can be hooked in after the following functions:\n\n- [`init_per_suite`](`c:ct_suite:init_per_suite/1`)\n- [`init_per_group`](`c:ct_suite:init_per_group/2`)\n- [`init_per_testcase`](`c:ct_suite:init_per_testcase/2`)\n- [`end_per_testcase`](`c:ct_suite:end_per_testcase/2`)\n- [`end_per_group`](`c:ct_suite:end_per_group/2`)\n- [`end_per_suite`](`c:ct_suite:end_per_suite/1`)\n\nThis is done in the CTH functions called `post_ `. These\nfunctions take the arguments `SuiteName`, `Name` (group or test case name, if\napplicable), `Config`, `Return`, and `CTHState`. `Config` in this case is the\nsame `Config` as the testcase is called with. `Return` is the value returned by\nthe testcase. If the testcase fails by crashing, `Return` is\n`{'EXIT',{{Error,Reason},Stacktrace}}`.\n\nThe return value of the CTH function is always a combination of a result for the\nsuite/group/test and an updated `CTHState`. If you do not want the callback to\naffect the outcome of the test, return the `Return` data as it is given to the\nCTH. You can also modify the test result. By returning the `Config` list with\nelement `tc_status` removed, you can recover from a test failure. As in all the\npre hooks, it is also possible to fail/skip the test case in the post hook.\n\n_Example:_\n\n```erlang\npost_end_per_testcase(_Suite, _TC, Config, {'EXIT',{_,_}}, CTHState) ->\n case db:check_consistency() of\n true ->\n %% DB is good, pass the test.\n {proplists:delete(tc_status, Config), CTHState};\n false ->\n %% DB is not good, mark as skipped instead of failing\n {{skip, \"DB is inconsistent!\"}, CTHState}\n end;\npost_end_per_testcase(_Suite, _TC, Config, Return, CTHState) ->\n %% Do nothing if tc does not crash.\n {Return, CTHState}.\n```\n\n> #### Note {: .info }\n>\n> Do recover from a testcase failure using CTHs only a last resort. If used\n> wrongly, it can be very difficult to determine which tests that pass or fail\n> in a test run.","title":"Post Hooks - Common Test Hooks","ref":"ct_hooks_chapter.html#post-hooks"},{"type":"extras","doc":"After any post hook has been executed for all installed CTHs,\n[on_tc_fail](`c:ct_hooks:on_tc_fail/4`) or\n[on_tc_skip](`c:ct_hooks:on_tc_skip/4`) is called if the testcase failed or was\nskipped, respectively. You cannot affect the outcome of the tests any further at\nthis point.\n\n[](){: #synchronizing }","title":"Skip and Fail Hooks - Common Test Hooks","ref":"ct_hooks_chapter.html#skip-and-fail-hooks"},{"type":"extras","doc":"CTHs can be used to synchronize test runs with external user applications. The\ninit function can, for example, start and/or communicate with an application\nthat has the purpose of preparing the SUT for an upcoming test run, or\ninitialize a database for saving test data to during the test run. The terminate\nfunction can similarly order such an application to reset the SUT after the test\nrun, and/or tell the application to finish active sessions and terminate. Any\nsystem error- or progress reports generated during the init- or termination\nstage are saved in the\n[Pre- and Post Test I/O Log](run_test_chapter.md#pre_post_test_io_log). (This is\nalso true for any printouts made with `ct:log/2` and `ct:pal/2`).\n\nTo ensure that `Common Test` does not start executing tests, or closes its log\nfiles and shuts down, before the external application is ready for it,\n`Common Test` can be synchronized with the application. During startup and\nshutdown, `Common Test` can be suspended, simply by having a CTH evaluate a\n`receive` expression in the init- or terminate function. The macros\n`?CT_HOOK_INIT_PROCESS` (the process executing the hook init function) and\n`?CT_HOOK_TERMINATE_PROCESS` (the process executing the hook terminate function)\neach specifies the name of the correct `Common Test` process to send a message\nto. This is done to return from the `receive`. These macros are defined in\n`ct.hrl`.\n\n[](){: #example }","title":"Synchronizing External User Applications with Common Test - Common Test Hooks","ref":"ct_hooks_chapter.html#synchronizing-external-user-applications-with-common-test"},{"type":"extras","doc":"The following CTH logs information about a test run into a format parseable by\n`file:consult/1` (in Kernel):\n\n```erlang\n%%% Common Test Example Common Test Hook module.\n%%%\n%%% To use this hook, on the command line:\n%%% ct_run -suite example_SUITE -pa . -ct_hooks example_cth\n%%%\n%%% Note `-pa .`: the hook beam file must be in the code path when installing.\n-module(example_cth).\n\n%% Mandatory Callbacks\n-export([init/2]).\n\n%% Optional Callbacks\n-export([id/1]).\n\n-export([pre_init_per_suite/3]).\n-export([post_end_per_suite/4]).\n\n-export([pre_init_per_testcase/4]).\n-export([post_end_per_testcase/5]).\n\n-export([on_tc_skip/4]).\n\n-export([terminate/1]).\n\n%% This hook state is threaded through all the callbacks.\n-record(state, {filename, total, suite_total, ts, tcs, data, skipped}).\n%% This example hook prints its results to a file, see terminate/1.\n-record(test_run, {total, skipped, suites}).\n\n%% Return a unique id for this CTH.\n%% Using the filename means the hook can be used with different\n%% log files to separate timing data within the same test run.\n%% See Installing a CTH for more information.\nid(Opts) ->\n %% the path is relative to the test run directory\n proplists:get_value(filename, Opts, \"example_cth.log\").\n\n%% Always called before any other callback function. Use this to initiate\n%% any common state.\ninit(Id, _Opts) ->\n {ok, #state{filename = Id, total = 0, data = []}}.\n\n%% Called before init_per_suite is called.\npre_init_per_suite(_Suite,Config,State) ->\n {Config, State#state{suite_total = 0, tcs = []}}.\n\n%% Called after end_per_suite.\npost_end_per_suite(Suite,_Config,Return,State) ->\n Data = {suites, Suite, State#state.suite_total,\n lists:reverse(State#state.tcs)},\n {Return, State#state{data = [Data | State#state.data],\n total = State#state.total + State#state.suite_total}}.\n\n%% Called before each init_per_testcase.\npre_init_per_testcase(_Suite,_TC,Config,State) ->\n Now = erlang:monotonic_time(microsecond),\n {Config, State#state{ts = Now, suite_total = State#state.suite_total + 1}}.\n\n%% Called after each end_per_testcase.\npost_end_per_testcase(Suite,TC,_Config,Return,State) ->\n Now = erlang:monotonic_time(microsecond),\n TCInfo = {testcase, Suite, TC, Return, Now - State#state.ts},\n {Return, State#state{ts = undefined, tcs = [TCInfo | State#state.tcs]}}.\n\n%% Called when a test case is skipped by either user action\n%% or due to an init function failing.\non_tc_skip(_Suite, _TC, _Reason, State) ->\n State#state{skipped = State#state.skipped + 1}.\n\n%% Called when the scope of the CTH is done.\nterminate(State) ->\n %% use append to avoid data loss if the path is reused\n {ok, File} = file:open(State#state.filename, [write, append]),\n io:format(File, \"~p.~n\", [results(State)]),\n file:close(File),\n ok.\n\nresults(State) ->\n #state{skipped = Skipped, data = Data, total = Total} = State,\n #test_run{total = Total, skipped = Skipped, suites = lists:reverse(Data)}.\n```\n\n[](){: #builtin_cths }","title":"Example CTH - Common Test Hooks","ref":"ct_hooks_chapter.html#example-cth"},{"type":"extras","doc":"`Common Test` is delivered with some general-purpose CTHs that can be enabled by\nthe user to provide generic testing functionality. Some of these CTHs are\nenabled by default when `common_test` is started to run. They can be disabled by\nsetting `enable_builtin_hooks` to `false` on the command line or in the test\nspecification. The following two CTHs are delivered with `Common Test`:\n\n- **`cth_log_redirect`** - Built-in\n\n Captures all log events that would normally be printed by the default logger\n handler, and prints them to the current test case log. If an event cannot be\n associated with a test case, it is printed in the `Common Test` framework log.\n This happens for test cases running in parallel and events occurring\n in-between test cases.\n\n The log events are handled using a [Logger](`m:logger`) handler called\n cth_log_redirect. The formatting and level is copied from the current\n `default` handler when the cth is started. If you want to use another level\n either change the `default` handler level before starting common_test, or use\n the `logger:set_handler_config/3` API.\n\n This hook supports the following options:\n\n - **`{mode, add}`** - Add `cth_log_redirect` to the default logging handler:\n Logs will be emitted to both standard output via the default handler, and\n into the Common Test HTML logs. This is the default behaviour.\n\n - **`{mode, replace}`** - Replace the `default` logging handler with\n `cth_log_redirect` instead of logging to both the default handler and this\n handler. This effectively silences any logger output which would normally be\n printed to standard output during test runs. To enable this mode, you can\n pass the following options to `ct_run`:\n\n `-enable_builtin_hooks false -ct_hooks cth_log_redirect [{mode,replace}]`\n\n- **`cth_surefire`** - Not built-in\n\n Captures all test results and outputs them as surefire XML into a file. The\n created file is by default called `junit_report.xml`. The file name can be\n changed by setting option `path` for this hook, for example:\n\n `-ct_hooks cth_surefire [{path,\"/tmp/report.xml\"}]`\n\n If option `url_base` is set, an extra attribute named `url` is added to each\n `testsuite` and `testcase` XML element. The value is constructed from\n `url_base` and a relative path to the test suite or test case log,\n respectively, for example:\n\n `-ct_hooks cth_surefire [{url_base, \"http://myserver.com/\"}]`\n\n gives an URL attribute value similar to\n\n `\"http://myserver.com/ct_run.ct@myhost.2012-12-12_11.19.39/ x86_64-unknown-linux-gnu.my_test.logs/run.2012-12-12_11.19.39/suite.log.html\"`\n\n Surefire XML can, for example, be used by Jenkins to display test results.","title":"Built-In CTHs - Common Test Hooks","ref":"ct_hooks_chapter.html#built-in-cths"},{"type":"extras","doc":"\n# Some Thoughts about Testing","title":"Some Thoughts about Testing","ref":"why_test_chapter.html"},{"type":"extras","doc":"It is not possible to prove that a program is correct by testing. On the\ncontrary, it has been formally proven that it is impossible to prove programs in\ngeneral by testing. Theoretical program proofs or plain examination of code can\nbe viable options for those wishing to certify that a program is correct. The\ntest server, as it is based on testing, cannot be used for certification. Its\nintended use is instead to (cost effectively) _find bugs_. A successful test\nsuite is one that reveals a bug. If a test suite results in OK, then we know\nvery little that we did not know before.","title":"Goals - Some Thoughts about Testing","ref":"why_test_chapter.html#goals"},{"type":"extras","doc":"There are many kinds of test suites. Some concentrate on calling every function\nor command (in the documented way) in a certain interface. Some others do the\nsame, but use all kinds of illegal parameters, and verify that the server stays\nalive and rejects the requests with reasonable error codes. Some test suites\nsimulate an application (typically consisting of a few modules of an\napplication), some try to do tricky requests in general, and some test suites\neven test internal functions with help of special Load Modules on target.\n\nAnother interesting category of test suites is the one checking that fixed bugs\ndo not reoccur. When a bugfix is introduced, a test case that checks for that\nspecific bug is written and submitted to the affected test suites.\n\nAim for finding bugs. Write whatever test that has the highest probability of\nfinding a bug, now or in the future. Concentrate more on the critical parts.\nBugs in critical subsystems are much more expensive than others.\n\nAim for functionality testing rather than implementation details. Implementation\ndetails change quite often, and the test suites are to be long lived.\nImplementation details often differ on different platforms and versions. If\nimplementation details must be tested, try to factor them out into separate test\ncases. These test cases can later be rewritten or skipped.\n\nAlso, aim for testing everything once, no less, no more. It is not effective\nhaving every test case fail only because one function in the interface changed.","title":"What to Test - Some Thoughts about Testing","ref":"why_test_chapter.html#what-to-test"},{"type":"extras","doc":"\n# Common Test's Property Testing Support: ct_property_test","title":"Common Test's Property Testing Support: ct_property_test","ref":"ct_property_test_chapter.html"},{"type":"extras","doc":"The _Common Test Property Testing Support (ct_property_test)_ is an aid to run\nproperty based testing tools in Common Test test suites.\n\nBasic knowledge of property based testing is assumed in the following. It is\nalso assumed that at least one of the following property based testing tools is\ninstalled and available in the library path:\n\n- [QuickCheck](http://www.quviq.com),\n- [PropEr](https://proper-testing.github.io) or\n- [Triq](https://github.com/krestenkrab/triq)\n\n[](){: #supported }","title":"General - Common Test's Property Testing Support: ct_property_test","ref":"ct_property_test_chapter.html#general"},{"type":"extras","doc":"The [ct_property_test](`m:ct_property_test#`) module does the following:\n\n- Compiles the files with property tests in the subdirectory `property_test`\n- Tests properties in those files using the first found Property Testing Tool.\n- Saves the results - that is the printouts - in the usual Common Test Log","title":"What Is Supported? - Common Test's Property Testing Support: ct_property_test","ref":"ct_property_test_chapter.html#what-is-supported"},{"type":"extras","doc":"Assume that we want to test the lists:sort/1 function.\n\nWe need a property to test the function. In normal way, we create\n`property_test/ct_prop.erl` module in the `test` directory in our application:\n\n```erlang\n-module(ct_prop).\n-export([prop_sort/0]).\n\n%%% This will include the .hrl file for the installed testing tool:\n-include_lib(\"common_test/include/ct_property_test.hrl\").\n\n%%% The property we want to check:\n%%% For all possibly unsorted lists,\n%%% the result of lists:sort/1 is sorted.\nprop_sort() ->\n ?FORALL(UnSorted, list(),\n is_sorted(lists:sort(UnSorted))\n ).\n\n%%% Function to check that a list is sorted:\nis_sorted([]) ->\n true;\nis_sorted([_]) ->\n true;\nis_sorted([H1,H2|SortedTail]) when H1 = \n is_sorted([H2|SortedTail]);\nis_sorted(_) ->\n false.\n```\n\nWe also need a CommonTest test suite:\n\n```erlang\n-module(ct_property_test_SUITE).\n-compile(export_all). % Only in tests!\n\n-include_lib(\"common_test/include/ct.hrl\").\n\nall() -> [prop_sort\n ].\n\n%%% First prepare Config and compile the property tests for the found tool:\ninit_per_suite(Config) ->\n ct_property_test:init_per_suite(Config).\n\nend_per_suite(Config) ->\n Config.\n\n%%%================================================================\n%%% Test suites\n%%%\nprop_sort(Config) ->\n ct_property_test:quickcheck(\n ct_prop:prop_sort(),\n Config\n ).\n```\n\nWe run it as usual, for example with ct_run in the OS shell:\n\n```text\n..../test$ ct_run -suite ct_property_test_SUITE\n.....\nCommon Test: Running make in test directories...\n\nTEST INFO: 1 test(s), 1 case(s) in 1 suite(s)\n\nTesting lib.common_test.ct_property_test_SUITE: Starting test, 1 test cases\n\n----------------------------------------------------\n2019-12-18 10:44:46.293\nFound property tester proper\nat \"/home/X/lib/proper/ebin/proper.beam\"\n\n\n----------------------------------------------------\n2019-12-18 10:44:46.294\nCompiling in \"/home/..../test/property_test\"\n Deleted: [\"ct_prop.beam\"]\n ErlFiles: [\"ct_prop.erl\"]\n MacroDefs: [{d,'PROPER'}]\n\nTesting lib.common_test.ct_property_test_SUITE: TEST COMPLETE, 1 ok, 0 failed of 1 test cases\n\n....\n```\n\n[](){: #stateful1 }","title":"Introductory Example - Common Test's Property Testing Support: ct_property_test","ref":"ct_property_test_chapter.html#introductory-example"},{"type":"extras","doc":"Assume a test that generates some parallel stateful commands, and runs 300\ntests:\n\n```erlang\nprop_parallel(Config) ->\n numtests(300,\n ?FORALL(Cmds, parallel_commands(?MODULE),\n begin\n RunResult = run_parallel_commands(?MODULE, Cmds),\n ct_property_test:present_result(?MODULE, Cmds, RunResult, Config)\n end)).\n```\n\nThe `ct_property_test:present_result/4` is a help function for printing some\nstatistics in the CommonTest log file.\n\nOur example test could for example be a simple test of an ftp server, where we\nperform get, put and delete requests, some of them in parallel. Per default, the\nresult has three sections:\n\n```text\n*** User 2019-12-11 13:28:17.504 ***\n\nDistribution sequential/parallel\n\n 57.7% sequential\n 28.0% parallel_2\n 14.3% parallel_1\n\n\n\n*** User 2019-12-11 13:28:17.505 ***\n\nFunction calls\n\n 44.4% get\n 39.3% put\n 16.3% delete\n\n\n\n*** User 2019-12-11 13:28:17.505 ***\n\nLength of command sequences\n\nRange : Number in range\n-------:----------------\n 0 - 4: 8 2.7% <-- min=3\n 5 - 9: 44 14.7%\n10 - 14: 74 24.7%\n15 - 19: 60 20.0% <-- mean=18.7 <-- median=16.0\n20 - 24: 38 12.7%\n25 - 29: 26 8.7%\n30 - 34: 19 6.3%\n35 - 39: 19 6.3%\n40 - 44: 8 2.7%\n45 - 49: 4 1.3% <-- max=47\n ------\n 300\n```\n\nThe first part - _Distribution sequential/parallel_ \\- shows the distribution in\nthe sequential and parallel part of the result of parallel_commands/1. See any\nproperty testing tool for an explanation of this function. The table shows that\nof all commands (get and put in our case), 57.7% are executed in the sequential\npart prior to the parallel part, 28.0% are executed in the first parallel list\nand the rest in the second parallel list.\n\nThe second part - _Function calls_ \\- shows the distribution of the three calls\nin the generated command lists. We see that all of the three calls are executed.\nIf it was so that we thought that we also generated a fourth call, a table like\nthis shows that we failed with that.\n\nThe third and final part - _Length of command sequences_ \\- show statistics of\nthe generated command sequences. We see that the shortest list has three\nelementes while the longest has 47 elements. The mean and median values are also\nshown. Further we could for example see that only 2.7% of the lists (that is\neight lists) only has three or four elements.","title":"A stateful testing example - Common Test's Property Testing Support: ct_property_test","ref":"ct_property_test_chapter.html#a-stateful-testing-example"},{"type":"extras","doc":"\n# ct_run\n\nProgram used for starting Common Test from the OS command line.","title":"ct_run","ref":"ct_run_cmd.html"},{"type":"extras","doc":"The `ct_run` program is automatically installed with Erlang/OTP and the\n`Common Test` application (for more information, see section\n[Installation](install_chapter.md) in the User's Guide). The program accepts\ndifferent start flags. Some flags trigger `ct_run` to start `Common Test` and\npass on data to it. Some flags start an Erlang node prepared for running\n`Common Test` in a particular mode.\n\nThe interface function `ct:run_test/1`, corresponding to the `ct_run` program,\nis used for starting `Common Test` from the Erlang shell (or an Erlang program).\nFor details, see the `m:ct` manual page.\n\n`ct_run` also accepts Erlang emulator flags. These are used when `ct_run` calls\n`erl` to start the Erlang node (this makes it possible to add directories to the\ncode server path, change the cookie on the node, start more applications, and so\non).\n\nWith the optional flag `-erl_args`, options on the `ct_run` command line can be\ndivided into two groups:\n\n- One group that `Common Test` is to process (those preceding `-erl_args`).\n- One group that `Common Test` is to ignore and pass on directly to the emulator\n (those following `-erl_args`).\n\nOptions preceding `-erl_args` that `Common Test` does not recognize are also\npassed on to the emulator untouched. By `-erl_args` the user can specify flags\nwith the same name, but with different destinations, on the `ct_run` command\nline.\n\nIf flags `-pa` or `-pz` are specified in the `Common Test` group of options\n(preceding `-erl_args`), relative directories are converted to absolute and\nreinserted into the code path by `Common Test`. This is to avoid problems\nloading user modules when `Common Test` changes working directory during test\nruns. However, `Common Test` ignores flags `-pa` and `-pz` following `-erl_args`\non the command line. These directories are added to the code path normally (that\nis, on specified form).\n\nExit status is set before the program ends. Value `0` indicates a successful\ntest result, `1` indicates one or more failed or auto-skipped test cases, and\n`2` indicates test execution failure.\n\nIf `ct_run` is called with option `-help`, it prints all valid start flags to\n`stdout`.\n\n[](){: #ct_run }","title":"Description - ct_run","ref":"ct_run_cmd.html#description"},{"type":"extras","doc":"```text\n ct_run -dir TestDir1 TestDir2 .. TestDirN |\n [-dir TestDir] -suite Suite1 Suite2 .. SuiteN\n [-group Groups1 Groups2 .. GroupsN] [-case Case1 Case2 .. CaseN]\n [-step [config | keep_inactive]]\n [-config ConfigFile1 ConfigFile2 .. ConfigFileN]\n [-userconfig CallbackModule1 ConfigString1 and CallbackModule2\n ConfigString2 and .. CallbackModuleN ConfigStringN]\n [-decrypt_key Key] | [-decrypt_file KeyFile]\n [-label Label]\n [-logdir LogDir]\n [-logopts LogOpts]\n [-verbosity GenVLevel | [Category1 VLevel1 and\n Category2 VLevel2 and .. CategoryN VLevelN]]\n [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]\n [-stylesheet CSSFile]\n [-cover CoverCfgFile]\n [-cover_stop Bool]\n [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] |\n [-event_handler_init EvHandler1 InitArg1 and\n EvHandler2 InitArg2 and .. EvHandlerN InitArgN]\n [-include InclDir1 InclDir2 .. InclDirN]\n [-no_auto_compile]\n [-abort_if_missing_suites]\n [-multiply_timetraps Multiplier]\n [-scale_timetraps]\n [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]\n [-repeat N] |\n [-duration HHMMSS [-force_stop [skip_rest]]] |\n [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]\n [-basic_html]\n [-no_esc_chars]\n [-keep_logs all | NLogs]\n [-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and ..\n CTHModuleN CTHOptsN]\n [-ct_hooks_order test | config]\n [-exit_status ignore_config]\n [-help]\n```","title":"Run Tests from Command Line - ct_run","ref":"ct_run_cmd.html#run-tests-from-command-line"},{"type":"extras","doc":"```text\n ct_run -spec TestSpec1 TestSpec2 .. TestSpecN\n [-join_specs]\n [-config ConfigFile1 ConfigFile2 .. ConfigFileN]\n [-userconfig CallbackModule1 ConfigString1 and CallbackModule2\n ConfigString2 and .. and CallbackModuleN ConfigStringN]\n [-decrypt_key Key] | [-decrypt_file KeyFile]\n [-label Label]\n [-logdir LogDir]\n [-logopts LogOpts]\n [-verbosity GenVLevel | [Category1 VLevel1 and\n Category2 VLevel2 and .. CategoryN VLevelN]]\n [-allow_user_terms]\n [-silent_connections [ConnType1 ConnType2 .. ConnTypeN]]\n [-stylesheet CSSFile]\n [-cover CoverCfgFile]\n [-cover_stop Bool]\n [-event_handler EvHandler1 EvHandler2 .. EvHandlerN] |\n [-event_handler_init EvHandler1 InitArg1 and\n EvHandler2 InitArg2 and .. EvHandlerN InitArgN]\n [-include InclDir1 InclDir2 .. InclDirN]\n [-no_auto_compile]\n [-abort_if_missing_suites]\n [-multiply_timetraps Multiplier]\n [-scale_timetraps]\n [-create_priv_dir auto_per_run | auto_per_tc | manual_per_tc]\n [-repeat N] |\n [-duration HHMMSS [-force_stop [skip_rest]]] |\n [-until [YYMoMoDD]HHMMSS [-force_stop [skip_rest]]]\n [-basic_html]\n [-no_esc_chars]\n [-keep_logs all | NLogs]\n [-ct_hooks CTHModule1 CTHOpts1 and CTHModule2 CTHOpts2 and ..\n CTHModuleN CTHOptsN]\n [-ct_hooks_order test | config]\n [-exit_status ignore_config]\n```","title":"Run Tests using Test Specification - ct_run","ref":"ct_run_cmd.html#run-tests-using-test-specification"},{"type":"extras","doc":"```text\n ct_run -refresh_logs [-logdir LogDir] [-basic_html]\n [-keep_logs all | NLogs]\n```","title":"Refresh HTML Index Files - ct_run","ref":"ct_run_cmd.html#refresh-html-index-files"},{"type":"extras","doc":"```erlang\n ct_run -shell\n [-config ConfigFile1 ConfigFile2 ... ConfigFileN]\n [-userconfig CallbackModule1 ConfigString1 and CallbackModule2\n ConfigString2 and .. and CallbackModuleN ConfigStringN]\n [-decrypt_key Key] | [-decrypt_file KeyFile]\n```","title":"Run Common Test in Interactive Mode - ct_run","ref":"ct_run_cmd.html#run-common-test-in-interactive-mode"},{"type":"extras","doc":"```text\n ct_run -ctmaster\n```","title":"Start a Common Test Master Node - ct_run","ref":"ct_run_cmd.html#start-a-common-test-master-node"},{"type":"extras","doc":"For information about the start flags, see section\n[Running Tests and Analyzing Results](run_test_chapter.md) in the User's Guide.","title":"See Also - ct_run","ref":"ct_run_cmd.html#see-also"}],"content_type":"text/plain","producer":{"name":"ex_doc","version":[48,46,51,52,46,49]}} \ No newline at end of file diff --git a/prs/8803/lib/common_test-1.27/doc/html/event_handler_chapter.html b/prs/8803/lib/common_test-1.27/doc/html/event_handler_chapter.html index 43793ff64dd33..0c55e1c340807 100644 --- a/prs/8803/lib/common_test-1.27/doc/html/event_handler_chapter.html +++ b/prs/8803/lib/common_test-1.27/doc/html/event_handler_chapter.html @@ -168,12 +168,12 @@

    ct_run -event_handler_init instead of -event_handler.

    Note

    All event handler modules must have gen_event behavior. These modules must be precompiled and their locations must be added explicitly to the Erlang code server search path (as in the previous example).

    An event_handler tuple in argument Opts has the following definition (see -ct:run_test/1):

    {event_handler,EventHandlers}
    +ct:run_test/1):

    {event_handler,EventHandlers}
     
    -EventHandlers = EH | [EH]
    -EH = atom() | {atom(),InitArgs} | {[atom()],InitArgs}
    -InitArgs = [term()]

    In the following example, two event handlers for the my_SUITE test are -installed:

    1> ct:run_test([{suite,"test/my_SUITE"},{event_handler,[my_evh1,{my_evh2,[node()]}]}]).

    Event handler my_evh1 is started with [] as argument to the init function. +EventHandlers = EH | [EH] +EH = atom() | {atom(),InitArgs} | {[atom()],InitArgs} +InitArgs = [term()]

    In the following example, two event handlers for the my_SUITE test are +installed:

    1> ct:run_test([{suite,"test/my_SUITE"},{event_handler,[my_evh1,{my_evh2,[node()]}]}]).

    Event handler my_evh1 is started with [] as argument to the init function. Event handler my_evh2 is started with the name of the current node in the init argument list.

    Event handlers can also be plugged in using one of the following test specification terms:

    • {event_handler, EventHandlers}
    • {event_handler, EventHandlers, InitArgs}
    • {event_handler, NodeRefs, EventHandlers}
    • {event_handler, NodeRefs, EventHandlers, InitArgs}

    EventHandlers is a list of module names. Before a test session starts, the diff --git a/prs/8803/lib/common_test-1.27/doc/html/example_chapter.html b/prs/8803/lib/common_test-1.27/doc/html/example_chapter.html index 33b57f7a2fd37..9ba9b94518921 100644 --- a/prs/8803/lib/common_test-1.27/doc/html/example_chapter.html +++ b/prs/8803/lib/common_test-1.27/doc/html/example_chapter.html @@ -131,19 +131,19 @@

    Test Suite Example

    -

    The following example test suite shows some tests of a database server:

    -module(db_data_type_SUITE).
    +

    The following example test suite shows some tests of a database server:

    -module(db_data_type_SUITE).
     
    --include_lib("common_test/include/ct.hrl").
    +-include_lib("common_test/include/ct.hrl").
     
     %% Test server callbacks
    --export([suite/0, all/0,
    +-export([suite/0, all/0,
              init_per_suite/1, end_per_suite/1,
    -         init_per_testcase/2, end_per_testcase/2]).
    +         init_per_testcase/2, end_per_testcase/2]).
     
     %% Test cases
    --export([string/1, integer/1]).
    +-export([string/1, integer/1]).
     
    --define(CONNECT_STR, "DSN=sqlserver;UID=alladin;PWD=sesame").
    +-define(CONNECT_STR, "DSN=sqlserver;UID=alladin;PWD=sesame").
     
     %%--------------------------------------------------------------------
     %% COMMON TEST CALLBACK FUNCTIONS
    @@ -158,8 +158,8 @@ 

    %% Description: Returns list of tuples to set default properties %% for the suite. %%-------------------------------------------------------------------- -suite() -> - [{timetrap,{minutes,1}}]. +suite() -> + [{timetrap,{minutes,1}}]. %%-------------------------------------------------------------------- %% Function: init_per_suite(Config0) -> Config1 @@ -169,10 +169,10 @@

    %% %% Description: Initialization before the suite. %%-------------------------------------------------------------------- -init_per_suite(Config) -> - {ok, Ref} = db:connect(?CONNECT_STR, []), - TableName = db_lib:unique_table_name(), - [{con_ref, Ref },{table_name, TableName}| Config]. +init_per_suite(Config) -> + {ok, Ref} = db:connect(?CONNECT_STR, []), + TableName = db_lib:unique_table_name(), + [{con_ref, Ref },{table_name, TableName}| Config]. %%-------------------------------------------------------------------- %% Function: end_per_suite(Config) -> term() @@ -182,9 +182,9 @@

    %% %% Description: Cleanup after the suite. %%-------------------------------------------------------------------- -end_per_suite(Config) -> - Ref = proplists:get_value(con_ref, Config), - db:disconnect(Ref), +end_per_suite(Config) -> + Ref = proplists:get_value(con_ref, Config), + db:disconnect(Ref), ok. %%-------------------------------------------------------------------- @@ -197,10 +197,10 @@

    %% %% Description: Initialization before each test case. %%-------------------------------------------------------------------- -init_per_testcase(Case, Config) -> - Ref = proplists:get_value(con_ref, Config), - TableName = proplists:get_value(table_name, Config), - ok = db:create_table(Ref, TableName, table_type(Case)), +init_per_testcase(Case, Config) -> + Ref = proplists:get_value(con_ref, Config), + TableName = proplists:get_value(table_name, Config), + ok = db:create_table(Ref, TableName, table_type(Case)), Config. %%-------------------------------------------------------------------- @@ -213,10 +213,10 @@

    %% %% Description: Cleanup after each test case. %%-------------------------------------------------------------------- -end_per_testcase(_Case, Config) -> - Ref = proplists:get_value(con_ref, Config), - TableName = proplists:get_value(table_name, Config), - ok = db:delete_table(Ref, TableName), +end_per_testcase(_Case, Config) -> + Ref = proplists:get_value(con_ref, Config), + TableName = proplists:get_value(table_name, Config), + ok = db:delete_table(Ref, TableName), ok. %%-------------------------------------------------------------------- @@ -231,28 +231,28 @@

    %% Description: Returns the list of groups and test cases that %% are to be executed. %%-------------------------------------------------------------------- -all() -> - [string, integer]. +all() -> + [string, integer]. %%-------------------------------------------------------------------- %% TEST CASES %%-------------------------------------------------------------------- -string(Config) -> - insert_and_lookup(dummy_key, "Dummy string", Config). +string(Config) -> + insert_and_lookup(dummy_key, "Dummy string", Config). -integer(Config) -> - insert_and_lookup(dummy_key, 42, Config). +integer(Config) -> + insert_and_lookup(dummy_key, 42, Config). -insert_and_lookup(Key, Value, Config) -> - Ref = proplists:get_value(con_ref, Config), - TableName = proplists:get_value(table_name, Config), - ok = db:insert(Ref, TableName, Key, Value), - [Value] = db:lookup(Ref, TableName, Key), - ok = db:delete(Ref, TableName, Key), - [] = db:lookup(Ref, TableName, Key), +insert_and_lookup(Key, Value, Config) -> + Ref = proplists:get_value(con_ref, Config), + TableName = proplists:get_value(table_name, Config), + ok = db:insert(Ref, TableName, Key, Value), + [Value] = db:lookup(Ref, TableName, Key), + ok = db:delete(Ref, TableName, Key), + [] = db:lookup(Ref, TableName, Key), ok.

    @@ -270,12 +270,12 @@

    %%% %%% Created : %%%------------------------------------------------------------------- --module(example_SUITE). +-module(example_SUITE). %% Note: This directive should only be used in test suites. --compile(export_all). +-compile(export_all). --include_lib("common_test/include/ct.hrl"). +-include_lib("common_test/include/ct.hrl"). %%-------------------------------------------------------------------- %% COMMON TEST CALLBACK FUNCTIONS @@ -293,8 +293,8 @@

    %% Note: The suite/0 function is only meant to be used to return %% default data values, not perform any other operations. %%-------------------------------------------------------------------- -suite() -> - [{timetrap,{minutes,10}}]. +suite() -> + [{timetrap,{minutes,10}}]. %%-------------------------------------------------------------------- %% Function: init_per_suite(Config0) -> @@ -310,7 +310,7 @@

    %% Note: This function is free to add any key/value pairs to the Config %% variable, but should NOT alter/remove any existing entries. %%-------------------------------------------------------------------- -init_per_suite(Config) -> +init_per_suite(Config) -> Config. %%-------------------------------------------------------------------- @@ -321,7 +321,7 @@

    %% %% Description: Cleanup after the suite. %%-------------------------------------------------------------------- -end_per_suite(_Config) -> +end_per_suite(_Config) -> ok. %%-------------------------------------------------------------------- @@ -337,7 +337,7 @@

    %% %% Description: Initialization before each test case group. %%-------------------------------------------------------------------- -init_per_group(_GroupName, Config) -> +init_per_group(_GroupName, Config) -> Config. %%-------------------------------------------------------------------- @@ -351,7 +351,7 @@

    %% %% Description: Cleanup after each test case group. %%-------------------------------------------------------------------- -end_per_group(_GroupName, _Config) -> +end_per_group(_GroupName, _Config) -> ok. %%-------------------------------------------------------------------- @@ -370,7 +370,7 @@

    %% Note: This function is free to add any key/value pairs to the Config %% variable, but should NOT alter/remove any existing entries. %%-------------------------------------------------------------------- -init_per_testcase(_TestCase, Config) -> +init_per_testcase(_TestCase, Config) -> Config. %%-------------------------------------------------------------------- @@ -386,7 +386,7 @@

    %% %% Description: Cleanup after each test case. %%-------------------------------------------------------------------- -end_per_testcase(_TestCase, _Config) -> +end_per_testcase(_TestCase, _Config) -> ok. %%-------------------------------------------------------------------- @@ -410,8 +410,8 @@

    %% %% Description: Returns a list of test case group definitions. %%-------------------------------------------------------------------- -groups() -> - []. +groups() -> + []. %%-------------------------------------------------------------------- %% Function: all() -> GroupsAndTestCases | {skip,Reason} @@ -427,8 +427,8 @@

    %% Description: Returns the list of groups and test cases that %% are to be executed. %%-------------------------------------------------------------------- -all() -> - [my_test_case]. +all() -> + [my_test_case]. %%-------------------------------------------------------------------- @@ -447,8 +447,8 @@

    %% Note: This function is only meant to be used to return a list of %% values, not perform any other operations. %%-------------------------------------------------------------------- -my_test_case() -> - []. +my_test_case() -> + []. %%-------------------------------------------------------------------- %% Function: TestCase(Config0) -> @@ -466,7 +466,7 @@

    %% the all/0 list or in a test case group for the test case %% to be executed). %%-------------------------------------------------------------------- -my_test_case(_Config) -> +my_test_case(_Config) -> ok.

    Small Common Test Suite

    %%%-------------------------------------------------------------------
     %%% File    : example_SUITE.erl
     %%% Author  :
    @@ -474,18 +474,18 @@ 

    %%% %%% Created : %%%------------------------------------------------------------------- --module(example_SUITE). +-module(example_SUITE). --compile(export_all). +-compile(export_all). --include_lib("common_test/include/ct.hrl"). +-include_lib("common_test/include/ct.hrl"). %%-------------------------------------------------------------------- %% Function: suite() -> Info %% Info = [tuple()] %%-------------------------------------------------------------------- -suite() -> - [{timetrap,{seconds,30}}]. +suite() -> + [{timetrap,{seconds,30}}]. %%-------------------------------------------------------------------- %% Function: init_per_suite(Config0) -> @@ -493,14 +493,14 @@

    %% Config0 = Config1 = [tuple()] %% Reason = term() %%-------------------------------------------------------------------- -init_per_suite(Config) -> +init_per_suite(Config) -> Config. %%-------------------------------------------------------------------- %% Function: end_per_suite(Config0) -> term() | {save_config,Config1} %% Config0 = Config1 = [tuple()] %%-------------------------------------------------------------------- -end_per_suite(_Config) -> +end_per_suite(_Config) -> ok. %%-------------------------------------------------------------------- @@ -510,7 +510,7 @@

    %% Config0 = Config1 = [tuple()] %% Reason = term() %%-------------------------------------------------------------------- -init_per_group(_GroupName, Config) -> +init_per_group(_GroupName, Config) -> Config. %%-------------------------------------------------------------------- @@ -519,7 +519,7 @@

    %% GroupName = atom() %% Config0 = Config1 = [tuple()] %%-------------------------------------------------------------------- -end_per_group(_GroupName, _Config) -> +end_per_group(_GroupName, _Config) -> ok. %%-------------------------------------------------------------------- @@ -529,7 +529,7 @@

    %% Config0 = Config1 = [tuple()] %% Reason = term() %%-------------------------------------------------------------------- -init_per_testcase(_TestCase, Config) -> +init_per_testcase(_TestCase, Config) -> Config. %%-------------------------------------------------------------------- @@ -539,7 +539,7 @@

    %% Config0 = Config1 = [tuple()] %% Reason = term() %%-------------------------------------------------------------------- -end_per_testcase(_TestCase, _Config) -> +end_per_testcase(_TestCase, _Config) -> ok. %%-------------------------------------------------------------------- @@ -554,8 +554,8 @@

    %% repeat_until_any_ok | repeat_until_any_fail %% N = integer() | forever %%-------------------------------------------------------------------- -groups() -> - []. +groups() -> + []. %%-------------------------------------------------------------------- %% Function: all() -> GroupsAndTestCases | {skip,Reason} @@ -564,15 +564,15 @@

    %% TestCase = atom() %% Reason = term() %%-------------------------------------------------------------------- -all() -> - [my_test_case]. +all() -> + [my_test_case]. %%-------------------------------------------------------------------- %% Function: TestCase() -> Info %% Info = [tuple()] %%-------------------------------------------------------------------- -my_test_case() -> - []. +my_test_case() -> + []. %%-------------------------------------------------------------------- %% Function: TestCase(Config0) -> @@ -582,7 +582,7 @@

    %% Reason = term() %% Comment = term() %%-------------------------------------------------------------------- -my_test_case(_Config) -> +my_test_case(_Config) -> ok.

    diff --git a/prs/8803/lib/common_test-1.27/doc/html/getting_started_chapter.html b/prs/8803/lib/common_test-1.27/doc/html/getting_started_chapter.html index d159fca0e91ee..32b2cd95f2307 100644 --- a/prs/8803/lib/common_test-1.27/doc/html/getting_started_chapter.html +++ b/prs/8803/lib/common_test-1.27/doc/html/getting_started_chapter.html @@ -169,14 +169,14 @@

    the test suite module implements callback functions (mandatory or optional) for various purposes, for example:

    • Init/end configuration function for the test suite
    • Init/end configuration function for a test case
    • Init/end configuration function for a test case group
    • Test cases

    The configuration functions are optional. The following example is a test suite without configuration functions, including one simple test case, to check that -module mymod exists (that is, can be successfully loaded by the code server):

    -module(my1st_SUITE).
    --compile(export_all).
    +module mymod exists (that is, can be successfully loaded by the code server):

    -module(my1st_SUITE).
    +-compile(export_all).
     
    -all() ->
    -    [mod_exists].
    +all() ->
    +    [mod_exists].
     
    -mod_exists(_) ->
    -    {module,mymod} = code:load_file(mymod).

    If the operation fails, a bad match error occurs that terminates the test case.

    +mod_exists(_) -> + {module,mymod} = code:load_file(mymod).

    If the operation fails, a bad match error occurs that terminates the test case.

    @@ -189,33 +189,33 @@

    through configuration functions on "lower level"). The data flow looks as follows:

    Configuration Data Flow in a Suite

    The following example shows a test suite that uses configuration functions to open and close a log file for the test cases (an operation that is unnecessary -and irrelevant to perform by each test case):

    -module(check_log_SUITE).
    --export([all/0, init_per_suite/1, end_per_suite/1]).
    --export([check_restart_result/1, check_no_errors/1]).
    +and irrelevant to perform by each test case):

    -module(check_log_SUITE).
    +-export([all/0, init_per_suite/1, end_per_suite/1]).
    +-export([check_restart_result/1, check_no_errors/1]).
     
    --define(value(Key,Config), proplists:get_value(Key,Config)).
    +-define(value(Key,Config), proplists:get_value(Key,Config)).
     
    -all() -> [check_restart_result, check_no_errors].
    +all() -> [check_restart_result, check_no_errors].
     
    -init_per_suite(InitConfigData) ->
    -    [{logref,open_log()} | InitConfigData].
    +init_per_suite(InitConfigData) ->
    +    [{logref,open_log()} | InitConfigData].
     
    -end_per_suite(ConfigData) ->
    -    close_log(?value(logref, ConfigData)).
    +end_per_suite(ConfigData) ->
    +    close_log(?value(logref, ConfigData)).
     
    -check_restart_result(ConfigData) ->
    -    TestData = read_log(restart, ?value(logref, ConfigData)),
    -    {match,_Line} = search_for("restart successful", TestData).
    +check_restart_result(ConfigData) ->
    +    TestData = read_log(restart, ?value(logref, ConfigData)),
    +    {match,_Line} = search_for("restart successful", TestData).
     
    -check_no_errors(ConfigData) ->
    -    TestData = read_log(all, ?value(logref, ConfigData)),
    -    case search_for("error", TestData) of
    -        {match,Line} -> ct:fail({error_found_in_log,Line});
    +check_no_errors(ConfigData) ->
    +    TestData = read_log(all, ?value(logref, ConfigData)),
    +    case search_for("error", TestData) of
    +        {match,Line} -> ct:fail({error_found_in_log,Line});
             nomatch -> ok
         end.

    The test cases verify, by parsing a log file, that our SUT has performed a successful restart and that no unexpected errors are printed.

    To execute the test cases in the recent test suite, type the following on the UNIX/Linux command line (assuming that the suite module is in the current -working directory):

    $ ct_run -dir .

    or:

    $ ct_run -suite check_log_SUITE

    To use the Erlang shell to run our test, you can evaluate the following call:

    1> ct:run_test([{dir, "."}]).

    or:

    1> ct:run_test([{suite, "check_log_SUITE"}]).

    The result from running the test is printed in log files in HTML format (stored +working directory):

    $ ct_run -dir .

    or:

    $ ct_run -suite check_log_SUITE

    To use the Erlang shell to run our test, you can evaluate the following call:

    1> ct:run_test([{dir, "."}]).

    or:

    1> ct:run_test([{suite, "check_log_SUITE"}]).

    The result from running the test is printed in log files in HTML format (stored in unique log directories on a different level). The following illustration shows the log file structure:

    HTML Log File Structure

    diff --git a/prs/8803/lib/common_test-1.27/doc/html/run_test_chapter.html b/prs/8803/lib/common_test-1.27/doc/html/run_test_chapter.html index c63d8a3dbdab9..68db6e8ef0729 100644 --- a/prs/8803/lib/common_test-1.27/doc/html/run_test_chapter.html +++ b/prs/8803/lib/common_test-1.27/doc/html/run_test_chapter.html @@ -279,7 +279,7 @@

    With the ct_run flag, or ct:run_test/1 option group, one or more test case groups can be specified, optionally in combination with specific test cases. The -syntax for specifying groups on the command line is as follows:

    $ ct_run -group <group_names_or_paths> [-case <cases>]

    The syntax in the Erlang shell is as follows:

    1> ct:run_test([{group,GroupsNamesOrPaths}, {case,Cases}]).

    Parameter group_names_or_paths specifies one or more group names and/or one or +syntax for specifying groups on the command line is as follows:

    $ ct_run -group <group_names_or_paths> [-case <cases>]

    The syntax in the Erlang shell is as follows:

    1> ct:run_test([{group,GroupsNamesOrPaths}, {case,Cases}]).

    Parameter group_names_or_paths specifies one or more group names and/or one or more group paths. At startup, Common Test searches for matching groups in the group definitions tree (that is, the list returned from Suite:groups/0; for details, see section Test Case Groups.

    Given a group name, say g, Common Test searches for all paths leading to @@ -311,30 +311,30 @@

    paths if an incomplete group path is specified.

    Note

    Group names and group paths can be combined with parameter group_names_or_paths. Each element is treated as an individual specification in combination with parameter cases. The following examples illustrates -this.

    Examples:

    -module(x_SUITE).
    +this.

    Examples:

    -module(x_SUITE).
     ...
     %% The group definitions:
    -groups() ->
    -  [{top1,[],[tc11,tc12,
    -             {sub11,[],[tc12,tc13]},
    -             {sub12,[],[tc14,tc15,
    -       		 {sub121,[],[tc12,tc16]}]}]},
    -
    -   {top2,[],[{group,sub21},{group,sub22}]},
    -   {sub21,[],[tc21,{group,sub2X2}]},
    -   {sub22,[],[{group,sub221},tc21,tc22,{group,sub2X2}]},
    -   {sub221,[],[tc21,tc23]},
    -   {sub2X2,[],[tc21,tc24]}].

    The following executes two tests, one for all cases and all subgroups under -top1, and one for all under top2:

    $ ct_run -suite "x_SUITE" -group all
    1> ct:run_test([{suite,"x_SUITE"}, {group,all}]).

    Using -group top1 top2, or {group,[top1,top2]} gives the same result.

    The following executes one test for all cases and subgroups under top1:

    $ ct_run -suite "x_SUITE" -group top1
    1> ct:run_test([{suite,"x_SUITE"}, {group,[top1]}]).

    The following runs a test executing tc12 in top1 and any subgroup under -top1 where it can be found (sub11 and sub121):

    $ ct_run -suite "x_SUITE" -group top1 -case tc12
    1> ct:run_test([{suite,"x_SUITE"}, {group,[top1]}, {testcase,[tc12]}]).

    The following executes tc12 only in group top1:

    $ ct_run -suite "x_SUITE" -group [top1] -case tc12
    1> ct:run_test([{suite,"x_SUITE"}, {group,[[top1]]}, {testcase,[tc12]}]).

    The following searches top1 and all its subgroups for tc16 resulting in that -this test case executes in group sub121:

    $ ct_run -suite "x_SUITE" -group top1 -case tc16
    1> ct:run_test([{suite,"x_SUITE"}, {group,[top1]}, {testcase,[tc16]}]).

    Using the specific path -group [sub121] or {group,[[sub121]]} gives the same +groups() -> + [{top1,[],[tc11,tc12, + {sub11,[],[tc12,tc13]}, + {sub12,[],[tc14,tc15, + {sub121,[],[tc12,tc16]}]}]}, + + {top2,[],[{group,sub21},{group,sub22}]}, + {sub21,[],[tc21,{group,sub2X2}]}, + {sub22,[],[{group,sub221},tc21,tc22,{group,sub2X2}]}, + {sub221,[],[tc21,tc23]}, + {sub2X2,[],[tc21,tc24]}].

    The following executes two tests, one for all cases and all subgroups under +top1, and one for all under top2:

    $ ct_run -suite "x_SUITE" -group all
    1> ct:run_test([{suite,"x_SUITE"}, {group,all}]).

    Using -group top1 top2, or {group,[top1,top2]} gives the same result.

    The following executes one test for all cases and subgroups under top1:

    $ ct_run -suite "x_SUITE" -group top1
    1> ct:run_test([{suite,"x_SUITE"}, {group,[top1]}]).

    The following runs a test executing tc12 in top1 and any subgroup under +top1 where it can be found (sub11 and sub121):

    $ ct_run -suite "x_SUITE" -group top1 -case tc12
    1> ct:run_test([{suite,"x_SUITE"}, {group,[top1]}, {testcase,[tc12]}]).

    The following executes tc12 only in group top1:

    $ ct_run -suite "x_SUITE" -group [top1] -case tc12
    1> ct:run_test([{suite,"x_SUITE"}, {group,[[top1]]}, {testcase,[tc12]}]).

    The following searches top1 and all its subgroups for tc16 resulting in that +this test case executes in group sub121:

    $ ct_run -suite "x_SUITE" -group top1 -case tc16
    1> ct:run_test([{suite,"x_SUITE"}, {group,[top1]}, {testcase,[tc16]}]).

    Using the specific path -group [sub121] or {group,[[sub121]]} gives the same result in this example.

    The following executes two tests, one including all cases and subgroups under -sub12, and one with only the test cases in sub12:

    $ ct_run -suite "x_SUITE" -group sub12 [sub12]
    1> ct:run_test([{suite,"x_SUITE"}, {group,[sub12,[sub12]]}]).

    In the following example, Common Test finds and executes two tests, one for +sub12, and one with only the test cases in sub12:

    $ ct_run -suite "x_SUITE" -group sub12 [sub12]
    1> ct:run_test([{suite,"x_SUITE"}, {group,[sub12,[sub12]]}]).

    In the following example, Common Test finds and executes two tests, one for the path from top2 to sub2X2 through sub21, and one from top2 to -sub2X2 through sub22:

    $ ct_run -suite "x_SUITE" -group sub2X2
    1> ct:run_test([{suite,"x_SUITE"}, {group,[sub2X2]}]).

    In the following example, by specifying the unique path +sub2X2 through sub22:

    $ ct_run -suite "x_SUITE" -group sub2X2
    1> ct:run_test([{suite,"x_SUITE"}, {group,[sub2X2]}]).

    In the following example, by specifying the unique path top2 -> sub21 -> sub2X2, only one test is executed. The second possible path, -from top2 to sub2X2 (from the former example) is discarded:

    $ ct_run -suite "x_SUITE" -group [sub21,sub2X2]
    1> ct:run_test([{suite,"x_SUITE"}, {group,[[sub21,sub2X2]]}]).

    The following executes only the test cases for sub22 and in reverse order -compared to the group definition:

    $ ct_run -suite "x_SUITE" -group [sub22] -case tc22 tc21
    1> ct:run_test([{suite,"x_SUITE"}, {group,[[sub22]]}, {testcase,[tc22,tc21]}]).

    If a test case belonging to a group (according to the group definition) is +from top2 to sub2X2 (from the former example) is discarded:

    $ ct_run -suite "x_SUITE" -group [sub21,sub2X2]
    1> ct:run_test([{suite,"x_SUITE"}, {group,[[sub21,sub2X2]]}]).

    The following executes only the test cases for sub22 and in reverse order +compared to the group definition:

    $ ct_run -suite "x_SUITE" -group [sub22] -case tc22 tc21
    1> ct:run_test([{suite,"x_SUITE"}, {group,[[sub22]]}, {testcase,[tc22,tc21]}]).

    If a test case belonging to a group (according to the group definition) is executed without a group specification, that is, simply by (using the command line):

    $ ct_run -suite "my_SUITE" -case my_tc

    or (using the Erlang shell):

    1> ct:run_test([{suite,"my_SUITE"}, {testcase,my_tc}]).

    then Common Test ignores the group definition and executes the test case in the scope of the test suite only (no group configuration functions are called).

    The group specification feature, as presented in this section, can also be used @@ -362,12 +362,12 @@

    configuration data with ct:require/1,2. This is equivalent to a require statement in the Test Suite Information Function or in the -Test Case Information Function.

    Example:

    1> ct:require(unix_telnet, unix).
    +Test Case Information Function.

    Example:

    1> ct:require(unix_telnet, unix).
     ok
    -2> ct_telnet:open(unix_telnet).
    -{ok,<0.105.0>}
    -4> ct_telnet:cmd(unix_telnet, "ls .").
    -{ok,["ls .","file1  ...",...]}

    Everything that Common Test normally prints in the test case logs, are in the +2> ct_telnet:open(unix_telnet). +{ok,<0.105.0>} +4> ct_telnet:cmd(unix_telnet, "ls ."). +{ok,["ls .","file1 ...",...]}

    Everything that Common Test normally prints in the test case logs, are in the interactive mode written to a log named ctlog.html in directory ct_run.<timestamp>. A link to this file is available in the file named last_interactive.html in the directory from which you execute ct_run. @@ -454,8 +454,8 @@

    included specification can either be joined with the source specification or used to produce a separate test run (as with start flag/option join_specs above).

    Example:

    %% In specification file "a.spec"
    -{specs, join, ["b.spec", "c.spec"]}.
    -{specs, separate, ["d.spec", "e.spec"]}.
    +{specs, join, ["b.spec", "c.spec"]}.
    +{specs, separate, ["d.spec", "e.spec"]}.
     %% Config and test terms follow
     ...

    In this example, the test terms defined in files "b.spec" and "c.spec" are joined with the terms in source specification "a.spec" (if any). The inclusion @@ -517,154 +517,154 @@

    available start flags (as most flags have a corresponding configuration term)
  • Logging (for terms verbosity, stylesheet, basic_html and esc_chars)
  • External Configuration Data (for terms config and userconfig)
  • Event Handling (for the -event_handler term)
  • Common Test Hooks (for term ct_hooks)
  • Configuration terms:

    {merge_tests, Bool}.
    +event_handler term)
  • Common Test Hooks (for term ct_hooks)
  • Configuration terms:

    {merge_tests, Bool}.
     
    -{define, Constant, Value}.
    +{define, Constant, Value}.
     
    -{specs, InclSpecsOption, TestSpecs}.
    +{specs, InclSpecsOption, TestSpecs}.
     
    -{node, NodeAlias, Node}.
    +{node, NodeAlias, Node}.
     
    -{init, InitOptions}.
    -{init, [NodeAlias], InitOptions}.
    +{init, InitOptions}.
    +{init, [NodeAlias], InitOptions}.
     
    -{label, Label}.
    -{label, NodeRefs, Label}.
    +{label, Label}.
    +{label, NodeRefs, Label}.
     
    -{verbosity, VerbosityLevels}.
    -{verbosity, NodeRefs, VerbosityLevels}.
    +{verbosity, VerbosityLevels}.
    +{verbosity, NodeRefs, VerbosityLevels}.
     
    -{stylesheet, CSSFile}.
    -{stylesheet, NodeRefs, CSSFile}.
    +{stylesheet, CSSFile}.
    +{stylesheet, NodeRefs, CSSFile}.
     
    -{silent_connections, ConnTypes}.
    -{silent_connections, NodeRefs, ConnTypes}.
    +{silent_connections, ConnTypes}.
    +{silent_connections, NodeRefs, ConnTypes}.
     
    -{multiply_timetraps, N}.
    -{multiply_timetraps, NodeRefs, N}.
    +{multiply_timetraps, N}.
    +{multiply_timetraps, NodeRefs, N}.
     
    -{scale_timetraps, Bool}.
    -{scale_timetraps, NodeRefs, Bool}.
    +{scale_timetraps, Bool}.
    +{scale_timetraps, NodeRefs, Bool}.
     
    -{cover, CoverSpecFile}.
    -{cover, NodeRefs, CoverSpecFile}.
    +{cover, CoverSpecFile}.
    +{cover, NodeRefs, CoverSpecFile}.
     
    -{cover_stop, Bool}.
    -{cover_stop, NodeRefs, Bool}.
    +{cover_stop, Bool}.
    +{cover_stop, NodeRefs, Bool}.
     
    -{include, IncludeDirs}.
    -{include, NodeRefs, IncludeDirs}.
    +{include, IncludeDirs}.
    +{include, NodeRefs, IncludeDirs}.
     
    -{auto_compile, Bool},
    -{auto_compile, NodeRefs, Bool},
    +{auto_compile, Bool},
    +{auto_compile, NodeRefs, Bool},
     
    -{abort_if_missing_suites, Bool},
    -{abort_if_missing_suites, NodeRefs, Bool},
    +{abort_if_missing_suites, Bool},
    +{abort_if_missing_suites, NodeRefs, Bool},
     
    -{config, ConfigFiles}.
    -{config, ConfigDir, ConfigBaseNames}.
    -{config, NodeRefs, ConfigFiles}.
    -{config, NodeRefs, ConfigDir, ConfigBaseNames}.
    +{config, ConfigFiles}.
    +{config, ConfigDir, ConfigBaseNames}.
    +{config, NodeRefs, ConfigFiles}.
    +{config, NodeRefs, ConfigDir, ConfigBaseNames}.
     
    -{userconfig, {CallbackModule, ConfigStrings}}.
    -{userconfig, NodeRefs, {CallbackModule, ConfigStrings}}.
    +{userconfig, {CallbackModule, ConfigStrings}}.
    +{userconfig, NodeRefs, {CallbackModule, ConfigStrings}}.
     
    -{logdir, LogDir}.
    -{logdir, NodeRefs, LogDir}.
    +{logdir, LogDir}.
    +{logdir, NodeRefs, LogDir}.
     
    -{logopts, LogOpts}.
    -{logopts, NodeRefs, LogOpts}.
    +{logopts, LogOpts}.
    +{logopts, NodeRefs, LogOpts}.
     
    -{create_priv_dir, PrivDirOption}.
    -{create_priv_dir, NodeRefs, PrivDirOption}.
    +{create_priv_dir, PrivDirOption}.
    +{create_priv_dir, NodeRefs, PrivDirOption}.
     
    -{event_handler, EventHandlers}.
    -{event_handler, NodeRefs, EventHandlers}.
    -{event_handler, EventHandlers, InitArgs}.
    -{event_handler, NodeRefs, EventHandlers, InitArgs}.
    +{event_handler, EventHandlers}.
    +{event_handler, NodeRefs, EventHandlers}.
    +{event_handler, EventHandlers, InitArgs}.
    +{event_handler, NodeRefs, EventHandlers, InitArgs}.
     
    -{ct_hooks, CTHModules}.
    -{ct_hooks, NodeRefs, CTHModules}.
    +{ct_hooks, CTHModules}.
    +{ct_hooks, NodeRefs, CTHModules}.
     
    -{ct_hooks_order, CTHOrder}.
    +{ct_hooks_order, CTHOrder}.
     
    -{enable_builtin_hooks, Bool}.
    +{enable_builtin_hooks, Bool}.
     
    -{basic_html, Bool}.
    -{basic_html, NodeRefs, Bool}.
    +{basic_html, Bool}.
    +{basic_html, NodeRefs, Bool}.
     
    -{esc_chars, Bool}.
    -{esc_chars, NodeRefs, Bool}.
    +{esc_chars, Bool}.
    +{esc_chars, NodeRefs, Bool}.
     
    -{release_shell, Bool}.

    Test terms:

    {suites, Dir, Suites}.
    -{suites, NodeRefs, Dir, Suites}.
    +{release_shell, Bool}.

    Test terms:

    {suites, Dir, Suites}.
    +{suites, NodeRefs, Dir, Suites}.
     
    -{groups, Dir, Suite, Groups}.
    -{groups, NodeRefs, Dir, Suite, Groups}.
    +{groups, Dir, Suite, Groups}.
    +{groups, NodeRefs, Dir, Suite, Groups}.
     
    -{groups, Dir, Suite, Groups, {cases,Cases}}.
    -{groups, NodeRefs, Dir, Suite, Groups, {cases,Cases}}.
    +{groups, Dir, Suite, Groups, {cases,Cases}}.
    +{groups, NodeRefs, Dir, Suite, Groups, {cases,Cases}}.
     
    -{cases, Dir, Suite, Cases}.
    -{cases, NodeRefs, Dir, Suite, Cases}.
    +{cases, Dir, Suite, Cases}.
    +{cases, NodeRefs, Dir, Suite, Cases}.
     
    -{skip_suites, Dir, Suites, Comment}.
    -{skip_suites, NodeRefs, Dir, Suites, Comment}.
    +{skip_suites, Dir, Suites, Comment}.
    +{skip_suites, NodeRefs, Dir, Suites, Comment}.
     
    -{skip_groups, Dir, Suite, GroupNames, Comment}.
    -{skip_groups, NodeRefs, Dir, Suite, GroupNames, Comment}.
    +{skip_groups, Dir, Suite, GroupNames, Comment}.
    +{skip_groups, NodeRefs, Dir, Suite, GroupNames, Comment}.
     
    -{skip_cases, Dir, Suite, Cases, Comment}.
    -{skip_cases, NodeRefs, Dir, Suite, Cases, Comment}.

    Types:

    Bool            = true | false
    -Constant        = atom()
    -Value           = term()
    +{skip_cases, Dir, Suite, Cases, Comment}.
    +{skip_cases, NodeRefs, Dir, Suite, Cases, Comment}.

    Types:

    Bool            = true | false
    +Constant        = atom()
    +Value           = term()
     InclSpecsOption = join | separate
    -TestSpecs       = string() | [string()]
    -NodeAlias       = atom()
    -Node            = node()
    +TestSpecs       = string() | [string()]
    +NodeAlias       = atom()
    +Node            = node()
     NodeRef         = NodeAlias | Node | master
    -NodeRefs        = all_nodes | [NodeRef] | NodeRef
    -InitOptions     = term()
    -Label           = atom() | string()
    -VerbosityLevels = integer() | [{Category,integer()}]
    -Category        = atom()
    -CSSFile         = string()
    -ConnTypes       = all | [atom()]
    -N               = integer()
    -CoverSpecFile   = string()
    -IncludeDirs     = string() | [string()]
    -ConfigFiles     = string() | [string()]
    -ConfigDir       = string()
    -ConfigBaseNames = string() | [string()]
    -CallbackModule  = atom()
    -ConfigStrings   = string() | [string()]
    -LogDir          = string()
    -LogOpts         = [term()]
    +NodeRefs        = all_nodes | [NodeRef] | NodeRef
    +InitOptions     = term()
    +Label           = atom() | string()
    +VerbosityLevels = integer() | [{Category,integer()}]
    +Category        = atom()
    +CSSFile         = string()
    +ConnTypes       = all | [atom()]
    +N               = integer()
    +CoverSpecFile   = string()
    +IncludeDirs     = string() | [string()]
    +ConfigFiles     = string() | [string()]
    +ConfigDir       = string()
    +ConfigBaseNames = string() | [string()]
    +CallbackModule  = atom()
    +ConfigStrings   = string() | [string()]
    +LogDir          = string()
    +LogOpts         = [term()]
     PrivDirOption   = auto_per_run | auto_per_tc | manual_per_tc
    -EventHandlers   = atom() | [atom()]
    -InitArgs        = [term()]
    -CTHModules      = [CTHModule |
    -       	    {CTHModule, CTHInitArgs} |
    -       	    {CTHModule, CTHInitArgs, CTHPriority}]
    -CTHModule       = atom()
    -CTHInitArgs     = term()
    +EventHandlers   = atom() | [atom()]
    +InitArgs        = [term()]
    +CTHModules      = [CTHModule |
    +       	    {CTHModule, CTHInitArgs} |
    +       	    {CTHModule, CTHInitArgs, CTHPriority}]
    +CTHModule       = atom()
    +CTHInitArgs     = term()
     CTHOrder        = test | config
    -Dir             = string()
    -Suites          = atom() | [atom()] | all
    -Suite           = atom()
    -Groups          = GroupPath | GroupSpec | [GroupSpec] | all
    -GroupPath       = [[GroupSpec]]
    -GroupSpec       = GroupName | {GroupName,Properties} | {GroupName,Properties,[GroupSpec]}
    -GroupName       = atom()
    -GroupNames      = GroupName | [GroupName]
    -Cases           = atom() | [atom()] | all
    -Comment         = string() | ""

    The difference between the config terms above is that with ConfigDir, +Dir = string() +Suites = atom() | [atom()] | all +Suite = atom() +Groups = GroupPath | GroupSpec | [GroupSpec] | all +GroupPath = [[GroupSpec]] +GroupSpec = GroupName | {GroupName,Properties} | {GroupName,Properties,[GroupSpec]} +GroupName = atom() +GroupNames = GroupName | [GroupName] +Cases = atom() | [atom()] | all +Comment = string() | ""

    The difference between the config terms above is that with ConfigDir, ConfigBaseNames is a list of base names, that is, without directory paths. ConfigFiles must be full names, including paths. For example, the following -two terms have the same meaning:

    {config, ["/home/testuser/tests/config/nodeA.cfg",
    -          "/home/testuser/tests/config/nodeB.cfg"]}.
    +two terms have the same meaning:

    {config, ["/home/testuser/tests/config/nodeA.cfg",
    +          "/home/testuser/tests/config/nodeB.cfg"]}.
     
    -{config, "/home/testuser/tests/config", ["nodeA.cfg","nodeB.cfg"]}.

    Note

    Any relative paths, specified in the test specification, are relative to the +{config, "/home/testuser/tests/config", ["nodeA.cfg","nodeB.cfg"]}.

    Note

    Any relative paths, specified in the test specification, are relative to the directory containing the test specification file if ct_run -spec TestSpecFile ... or ct:run:test([{spec,TestSpecFile},...]) executes the test.

    The path is relative to the top-level log directory if @@ -684,36 +684,36 @@

    an uppercase letter, or a $, ?, or _. This means that it must always be single quoted (as the constant name is an atom, not text).

    The main benefit of constants is that they can be used to reduce the size (and avoid repetition) of long strings, such as file paths.

    Examples:

    %% 1a. no constant
    -{config, "/home/testuser/tests/config", ["nodeA.cfg","nodeB.cfg"]}.
    -{suites, "/home/testuser/tests/suites", all}.
    +{config, "/home/testuser/tests/config", ["nodeA.cfg","nodeB.cfg"]}.
    +{suites, "/home/testuser/tests/suites", all}.
     
     %% 1b. with constant
    -{define, 'TESTDIR', "/home/testuser/tests"}.
    -{config, "'TESTDIR'/config", ["nodeA.cfg","nodeB.cfg"]}.
    -{suites, "'TESTDIR'/suites", all}.
    +{define, 'TESTDIR', "/home/testuser/tests"}.
    +{config, "'TESTDIR'/config", ["nodeA.cfg","nodeB.cfg"]}.
    +{suites, "'TESTDIR'/suites", all}.
     
     %% 2a. no constants
    -{config, [testnode@host1, testnode@host2], "../config", ["nodeA.cfg","nodeB.cfg"]}.
    -{suites, [testnode@host1, testnode@host2], "../suites", [x_SUITE, y_SUITE]}.
    +{config, [testnode@host1, testnode@host2], "../config", ["nodeA.cfg","nodeB.cfg"]}.
    +{suites, [testnode@host1, testnode@host2], "../suites", [x_SUITE, y_SUITE]}.
     
     %% 2b. with constants
    -{define, 'NODE', testnode}.
    -{define, 'NODES', ['NODE'@host1, 'NODE'@host2]}.
    -{config, 'NODES', "../config", ["nodeA.cfg","nodeB.cfg"]}.
    -{suites, 'NODES', "../suites", [x_SUITE, y_SUITE]}.

    Constants make the test specification term alias, in previous versions of +{define, 'NODE', testnode}. +{define, 'NODES', ['NODE'@host1, 'NODE'@host2]}. +{config, 'NODES', "../config", ["nodeA.cfg","nodeB.cfg"]}. +{suites, 'NODES', "../suites", [x_SUITE, y_SUITE]}.

    Constants make the test specification term alias, in previous versions of Common Test, redundant. This term is deprecated but remains supported in upcoming Common Test releases. Replacing alias terms with define is strongly recommended though. An example of such replacement follows:

    %% using the old alias term
    -{config, "/home/testuser/tests/config/nodeA.cfg"}.
    -{alias, suite_dir, "/home/testuser/tests/suites"}.
    -{groups, suite_dir, x_SUITE, group1}.
    +{config, "/home/testuser/tests/config/nodeA.cfg"}.
    +{alias, suite_dir, "/home/testuser/tests/suites"}.
    +{groups, suite_dir, x_SUITE, group1}.
     
     %% replacing with constants
    -{define, 'TestDir', "/home/testuser/tests"}.
    -{define, 'CfgDir', "'TestDir'/config"}.
    -{define, 'SuiteDir', "'TestDir'/suites"}.
    -{config, 'CfgDir', "nodeA.cfg"}.
    -{groups, 'SuiteDir', x_SUITE, group1}.

    Constants can well replace term node also, but this still has a declarative +{define, 'TestDir', "/home/testuser/tests"}. +{define, 'CfgDir', "'TestDir'/config"}. +{define, 'SuiteDir', "'TestDir'/suites"}. +{config, 'CfgDir', "nodeA.cfg"}. +{groups, 'SuiteDir', x_SUITE, group1}.

    Constants can well replace term node also, but this still has a declarative value, mainly when used in combination with NodeRefs == all_nodes (see Types).

    @@ -721,25 +721,25 @@

    Example

    -

    Here follows a simple test specification example:

    {define, 'Top', "/home/test"}.
    -{define, 'T1', "'Top'/t1"}.
    -{define, 'T2', "'Top'/t2"}.
    -{define, 'T3', "'Top'/t3"}.
    -{define, 'CfgFile', "config.cfg"}.
    +

    Here follows a simple test specification example:

    {define, 'Top', "/home/test"}.
    +{define, 'T1', "'Top'/t1"}.
    +{define, 'T2', "'Top'/t2"}.
    +{define, 'T3', "'Top'/t3"}.
    +{define, 'CfgFile', "config.cfg"}.
     
    -{logdir, "'Top'/logs"}.
    +{logdir, "'Top'/logs"}.
     
    -{config, ["'T1'/'CfgFile'", "'T2'/'CfgFile'", "'T3'/'CfgFile'"]}.
    +{config, ["'T1'/'CfgFile'", "'T2'/'CfgFile'", "'T3'/'CfgFile'"]}.
     
    -{suites, 'T1', all}.
    -{skip_suites, 'T1', [t1B_SUITE,t1D_SUITE], "Not implemented"}.
    -{skip_cases, 'T1', t1A_SUITE, [test3,test4], "Irrelevant"}.
    -{skip_cases, 'T1', t1C_SUITE, [test1], "Ignore"}.
    +{suites, 'T1', all}.
    +{skip_suites, 'T1', [t1B_SUITE,t1D_SUITE], "Not implemented"}.
    +{skip_cases, 'T1', t1A_SUITE, [test3,test4], "Irrelevant"}.
    +{skip_cases, 'T1', t1C_SUITE, [test1], "Ignore"}.
     
    -{suites, 'T2', [t2B_SUITE,t2C_SUITE]}.
    -{cases, 'T2', t2A_SUITE, [test4,test1,test7]}.
    +{suites, 'T2', [t2B_SUITE,t2C_SUITE]}.
    +{cases, 'T2', t2A_SUITE, [test4,test1,test7]}.
     
    -{skip_suites, 'T3', all, "Not implemented"}.

    The example specifies the following:

    • The specified logdir directory is used for storing the HTML log files (in +{skip_suites, 'T3', all, "Not implemented"}.

    The example specifies the following:

    For more information about require, see section +test case information list (the position in the list is irrelevant).

    Examples:

    testcase1() ->
    +    [{require, ftp},
    +     {default_config, ftp, [{ftp, "my_ftp_host"},
    +                            {username, "aladdin"},
    +                            {password, "sesame"}]}}].
    testcase2() ->
    +    [{require, unix_telnet, unix},
    +     {require, {unix, [telnet, username, password]}},
    +     {default_config, unix, [{telnet, "my_telnet_host"},
    +                             {username, "aladdin"},
    +                             {password, "sesame"}]}}].

    For more information about require, see section Requiring and Reading Configuration Data in section External Configuration Data and function ct:require/1/2.

    Note

    Specifying a default value for a required variable can result in a test case always getting executed. This might not be a desired behavior.

    If timetrap or require, or both, is not set specifically for a particular test case, default values specified by function -suite/0 are used.

    Tags other than the earlier mentioned are ignored by the test server.

    An example of a test case information function follows:

    reboot_node() ->
    -    [
    -     {timetrap,{seconds,60}},
    -     {require,interfaces},
    -     {userdata,
    -         [{description,"System Upgrade: RpuAddition Normal RebootNode"},
    -          {fts,"http://someserver.ericsson.se/test_doc4711.pdf"}]}
    -    ].

    +suite/0 are used.

    Tags other than the earlier mentioned are ignored by the test server.

    An example of a test case information function follows:

    reboot_node() ->
    +    [
    +     {timetrap,{seconds,60}},
    +     {require,interfaces},
    +     {userdata,
    +         [{description,"System Upgrade: RpuAddition Normal RebootNode"},
    +          {fts,"http://someserver.ericsson.se/test_doc4711.pdf"}]}
    +    ].

    @@ -302,14 +302,14 @@

    Test Case Information Function and Test Case Groups.

    The following options can also be specified with the suite information list:

    An example of the suite information function follows:

    suite() ->
    -    [
    -     {timetrap,{minutes,10}},
    -     {require,global_names},
    -     {userdata,[{info,"This suite tests database transactions."}]},
    -     {silent_connections,[telnet]},
    -     {stylesheet,"db_testing.css"}
    -    ].

    +Silent Connections

    An example of the suite information function follows:

    suite() ->
    +    [
    +     {timetrap,{minutes,10}},
    +     {require,global_names},
    +     {userdata,[{info,"This suite tests database transactions."}]},
    +     {silent_connections,[telnet]},
    +     {stylesheet,"db_testing.css"}
    +    ].

    @@ -331,20 +331,20 @@

    TCRepeatProps = [{repeat,N} | {repeat_until_ok,N} | {repeat_until_fail,N}]

    GroupName is the name of the group and must be unique within the test suite module. Groups can be nested, by including a group definition within the GroupsAndTestCases list of another group. Properties is the list of -execution properties for the group. The possible values are as follows:

    Properties = [parallel | sequence | Shuffle | {GroupRepeatType,N}]
    -Shuffle = shuffle | {shuffle,Seed}
    -Seed = {integer(),integer(),integer()}
    +execution properties for the group. The possible values are as follows:

    Properties = [parallel | sequence | Shuffle | {GroupRepeatType,N}]
    +Shuffle = shuffle | {shuffle,Seed}
    +Seed = {integer(),integer(),integer()}
     GroupRepeatType = repeat | repeat_until_all_ok | repeat_until_all_fail |
                       repeat_until_any_ok | repeat_until_any_fail
    -N = integer() | forever

    Explanations:

    • parallel - Common Test executes all test cases in the group in +N = integer() | forever

    Explanations:

    • parallel - Common Test executes all test cases in the group in parallel.

    • sequence - The cases are executed in a sequence as described in section Sequences in section Dependencies Between Test Cases and Suites.

    • shuffle - The cases in the group are executed in random order.

    • repeat, repeat_until_* - Orders Common Test to repeat execution of all the cases in the group a given number of times, or until any, or all, cases -fail or succeed.

    Example:

    groups() -> [{group1, [parallel], [test1a,test1b]},
    -             {group2, [shuffle,sequence], [test2a,test2b,test2c]}].

    To specify in which order groups are to be executed (also with respect to test +fail or succeed.

    Example:

    groups() -> [{group1, [parallel], [test1a,test1b]},
    +             {group2, [shuffle,sequence], [test2a,test2b,test2c]}].

    To specify in which order groups are to be executed (also with respect to test cases that are not part of any group), add tuples on the form -{group,GroupName} to the all/0 list.

    Example:

    all() -> [testcase1, {group,group1}, {testcase,testcase2,[{repeat,10}]}, {group,group2}].

    Execution properties with a group tuple in all/0: +{group,GroupName} to the all/0 list.

    Example:

    all() -> [testcase1, {group,group1}, {testcase,testcase2,[{repeat,10}]}, {group,group2}].

    Execution properties with a group tuple in all/0: {group,GroupName,Properties} can also be specified. These properties override those specified in the group definition (see groups/0 earlier). This way, the same set of tests can be run, but with different properties, without having to @@ -353,33 +353,33 @@

    SubGroups is a list of tuples, {GroupName,Properties} or {GroupName,Properties,SubGroups} representing the subgroups. Any subgroups defined in groups/0 for a group, that are not specified in the SubGroups -list, executes with their predefined properties.

    Example:

    groups() -> [{tests1, [], [{tests2, [], [t2a,t2b]},
    -                          {tests3, [], [t31,t3b]}]}].

    To execute group tests1 twice with different properties for tests2 each -time:

    all() ->
    -   [{group, tests1, default, [{tests2, [parallel]}]},
    -    {group, tests1, default, [{tests2, [shuffle,{repeat,10}]}]}].

    This is equivalent to the following specification:

    all() ->
    -   [{group, tests1, default, [{tests2, [parallel]},
    -                              {tests3, default}]},
    -    {group, tests1, default, [{tests2, [shuffle,{repeat,10}]},
    -                              {tests3, default}]}].

    Value default states that the predefined properties are to be used.

    The following example shows how to override properties in a scenario with deeply -nested groups:

    groups() ->
    -   [{tests1, [], [{group, tests2}]},
    -    {tests2, [], [{group, tests3}]},
    -    {tests3, [{repeat,2}], [t3a,t3b,t3c]}].
    -
    -all() ->
    -   [{group, tests1, default,
    -     [{tests2, default,
    -       [{tests3, [parallel,{repeat,100}]}]}]}].

    For ease of readability, all syntax definitions can be replaced by a function -call whose return value should match the expected syntax case.

    Example:

    all() ->
    -   [{group, tests1, default, test_cases()},
    -    {group, tests1, default, [shuffle_test(),
    -                              {tests3, default}]}].
    -test_cases() ->
    -   [{tests2, [parallel]}, {tests3, default}].
    -
    -shuffle_test() ->
    -   {tests2, [shuffle,{repeat,10}]}.

    The described syntax can also be used in test specifications to change group +list, executes with their predefined properties.

    Example:

    groups() -> [{tests1, [], [{tests2, [], [t2a,t2b]},
    +                          {tests3, [], [t31,t3b]}]}].

    To execute group tests1 twice with different properties for tests2 each +time:

    all() ->
    +   [{group, tests1, default, [{tests2, [parallel]}]},
    +    {group, tests1, default, [{tests2, [shuffle,{repeat,10}]}]}].

    This is equivalent to the following specification:

    all() ->
    +   [{group, tests1, default, [{tests2, [parallel]},
    +                              {tests3, default}]},
    +    {group, tests1, default, [{tests2, [shuffle,{repeat,10}]},
    +                              {tests3, default}]}].

    Value default states that the predefined properties are to be used.

    The following example shows how to override properties in a scenario with deeply +nested groups:

    groups() ->
    +   [{tests1, [], [{group, tests2}]},
    +    {tests2, [], [{group, tests3}]},
    +    {tests3, [{repeat,2}], [t3a,t3b,t3c]}].
    +
    +all() ->
    +   [{group, tests1, default,
    +     [{tests2, default,
    +       [{tests3, [parallel,{repeat,100}]}]}]}].

    For ease of readability, all syntax definitions can be replaced by a function +call whose return value should match the expected syntax case.

    Example:

    all() ->
    +   [{group, tests1, default, test_cases()},
    +    {group, tests1, default, [shuffle_test(),
    +                              {tests3, default}]}].
    +test_cases() ->
    +   [{tests2, [parallel]}, {tests3, default}].
    +
    +shuffle_test() ->
    +   {tests2, [shuffle,{repeat,10}]}.

    The described syntax can also be used in test specifications to change group properties at the time of execution, without having to edit the test suite. For more information, see section Test Specifications in section @@ -405,13 +405,13 @@

    bottom of the log for end_per_group/2.

    Test case groups can be nested so sets of groups can be configured with the same init_per_group/2 and end_per_group/2 functions. Nested groups can be defined by including a group definition, or a group name reference, in the test case -list of another group.

    Example:

    groups() -> [{group1, [shuffle], [test1a,
    -                                  {group2, [], [test2a,test2b]},
    -                                  test1b]},
    -             {group3, [], [{group,group4},
    -                           {group,group5}]},
    -             {group4, [parallel], [test4a,test4b]},
    -             {group5, [sequence], [test5a,test5b,test5c]}].

    In the previous example, if all/0 returns group name references in the order +list of another group.

    Example:

    groups() -> [{group1, [shuffle], [test1a,
    +                                  {group2, [], [test2a,test2b]},
    +                                  test1b]},
    +             {group3, [], [{group,group4},
    +                           {group,group5}]},
    +             {group4, [parallel], [test4a,test4b]},
    +             {group5, [sequence], [test5a,test5b,test5c]}].

    In the previous example, if all/0 returns group name references in the order [{group,group1},{group,group3}], the order of the configuration functions and test cases becomes the following (notice that init_per_testcase/2 and end_per_testcase/2: are also always called, but not included in this example @@ -484,25 +484,25 @@

    account by Common Test when evaluating if execution of a group is to be repeated or not (unless the basic repeat property is used).

    The value of tc_group_properties is a list of status tuples, each with the key ok, skipped, and failed. The value of a status tuple is a list with names -of test cases that have been executed with the corresponding status as result.

    The following is an example of how to return the status from a group:

    end_per_group(_Group, Config) ->
    -    Status = proplists:get_value(tc_group_result, Config),
    -    case proplists:get_value(failed, Status) of
    -        [] ->                                   % no failed cases
    -            {return_group_result,ok};
    +of test cases that have been executed with the corresponding status as result.

    The following is an example of how to return the status from a group:

    end_per_group(_Group, Config) ->
    +    Status = proplists:get_value(tc_group_result, Config),
    +    case proplists:get_value(failed, Status) of
    +        [] ->                                   % no failed cases
    +            {return_group_result,ok};
             _Failed ->                              % one or more failed
    -            {return_group_result,failed}
    +            {return_group_result,failed}
         end.

    It is also possible, in end_per_group/2, to check the status of a subgroup (maybe to determine what status the current group is to return). This is as simple as illustrated in the previous example, only the group name is stored in a tuple {group_result,GroupName}, which can be searched for in the status -lists.

    Example:

    end_per_group(group1, Config) ->
    -    Status = proplists:get_value(tc_group_result, Config),
    -    Failed = proplists:get_value(failed, Status),
    -    case lists:member({group_result,group2}, Failed) of
    +lists.

    Example:

    end_per_group(group1, Config) ->
    +    Status = proplists:get_value(tc_group_result, Config),
    +    Failed = proplists:get_value(failed, Status),
    +    case lists:member({group_result,group2}, Failed) of
               true ->
    -              {return_group_result,failed};
    +              {return_group_result,failed};
               false ->
    -              {return_group_result,ok}
    +              {return_group_result,ok}
         end;
     ...

    Note

    When a test case group is repeated, the configuration functions init_per_group/2 and end_per_group/2 are also always called with each @@ -534,9 +534,9 @@

    The test case group information function, group(GroupName), serves the same purpose as the suite- and test case information functions previously described. However, the scope for the group information function, is all test cases and -subgroups in the group in question (GroupName).

    Example:

    group(connection_tests) ->
    -   [{require,login_data},
    -    {timetrap,1000}].

    The group information properties override those set with the suite information +subgroups in the group in question (GroupName).

    Example:

    group(connection_tests) ->
    +   [{require,login_data},
    +    {timetrap,1000}].

    The group information properties override those set with the suite information function, and can in turn be overridden by test case information properties. For a list of valid information properties and more general information, see the Test Case Information Function.

    @@ -666,23 +666,23 @@

    (except from printouts made by Common Test itself).

    The general verbosity level is not associated with any particular category. This level sets the threshold for the standard I/O printouts, uncategorized ct:log/print/pal printouts, and printouts for categories with undefined -verbosity level.

    Examples:

    Some printouts during test case execution:

    io:format("1. Standard IO, importance = ~w~n", [?STD_IMPORTANCE]),
    -ct:log("2. Uncategorized, importance = ~w", [?STD_IMPORTANCE]),
    - ct:log(info, "3. Categorized info, importance = ~w", [?STD_IMPORTANCE]),
    - ct:log(info, ?LOW_IMPORTANCE, "4. Categorized info, importance = ~w", [?LOW_IMPORTANCE]),
    - ct:log(error, ?HI_IMPORTANCE, "5. Categorized error, importance = ~w", [?HI_IMPORTANCE]),
    - ct:log(error, ?MAX_IMPORTANCE, "6. Categorized error, importance = ~w", [?MAX_IMPORTANCE]),

    If starting the test with a general verbosity level of 50 (?STD_VERBOSITY):

    $ ct_run -verbosity 50

    the following is printed:

    1. Standard IO, importance = 50
    +verbosity level.

    Examples:

    Some printouts during test case execution:

    io:format("1. Standard IO, importance = ~w~n", [?STD_IMPORTANCE]),
    +ct:log("2. Uncategorized, importance = ~w", [?STD_IMPORTANCE]),
    + ct:log(info, "3. Categorized info, importance = ~w", [?STD_IMPORTANCE]),
    + ct:log(info, ?LOW_IMPORTANCE, "4. Categorized info, importance = ~w", [?LOW_IMPORTANCE]),
    + ct:log(error, ?HI_IMPORTANCE, "5. Categorized error, importance = ~w", [?HI_IMPORTANCE]),
    + ct:log(error, ?MAX_IMPORTANCE, "6. Categorized error, importance = ~w", [?MAX_IMPORTANCE]),

    If starting the test with a general verbosity level of 50 (?STD_VERBOSITY):

    $ ct_run -verbosity 50

    the following is printed:

    1. Standard IO, importance = 50
     2. Uncategorized, importance = 50
     3. Categorized info, importance = 50
     5. Categorized error, importance = 75
     6. Categorized error, importance = 99

    If starting the test with:

    $ ct_run -verbosity 1 and info 75

    the following is printed:

    3. Categorized info, importance = 50
     4. Categorized info, importance = 25
     6. Categorized error, importance = 99

    Note that the category argument is not required in order to only specify the -importance of a printout. Example:

    ct:pal(?LOW_IMPORTANCE, "Info report: ~p", [Info])

    Or perhaps in combination with constants:

    -define(INFO, ?LOW_IMPORTANCE).
    --define(ERROR, ?HI_IMPORTANCE).
    +importance of a printout. Example:

    ct:pal(?LOW_IMPORTANCE, "Info report: ~p", [Info])

    Or perhaps in combination with constants:

    -define(INFO, ?LOW_IMPORTANCE).
    +-define(ERROR, ?HI_IMPORTANCE).
     
    -ct:log(?INFO, "Info report: ~p", [Info])
    -ct:pal(?ERROR, "Error report: ~p", [Error])

    The functions ct:set_verbosity/2 and ct:get_verbosity/1 may be used to +ct:log(?INFO, "Info report: ~p", [Info]) +ct:pal(?ERROR, "Error report: ~p", [Error])

    The functions ct:set_verbosity/2 and ct:get_verbosity/1 may be used to modify and read verbosity levels during test execution.

    The arguments Format and FormatArgs in ct:log/print/pal are always passed on to the STDLIB function io:format/3 (For details, see the io manual page).

    ct:pal/4 and ct:log/5 add headers to strings being printed to the log file. diff --git a/prs/8803/lib/compiler-8.5.1/doc/html/beam_ssa.html b/prs/8803/lib/compiler-8.5.1/doc/html/beam_ssa.html index 0a647041a82f4..0d1b2e03e29a3 100644 --- a/prs/8803/lib/compiler-8.5.1/doc/html/beam_ssa.html +++ b/prs/8803/lib/compiler-8.5.1/doc/html/beam_ssa.html @@ -188,8 +188,8 @@

    br ^common_end_of_catch common_end_of_catch: - @tmp = phi { @catched_val, ^landing_pad_block }, - { @successful_result, ^protected_blockN } + @tmp = phi { @catched_val, ^landing_pad_block }, + { @successful_result, ^protected_blockN } @result_of_catch_expr = catch_end @tag, @tmp

    Just as for a try-catch expression all code that can cause an exception in one of the protected blocks must have explicit control flow edges to the landing pad block.

    @@ -234,7 +234,7 @@

    Variable Naming

    A variable name in BEAM SSA is either an atom or a non-negative -integer:

    atom() | non_neg_integer()

    In order to generate fresh unused variable names, all compiler +integer:

    atom() | non_neg_integer()

    In order to generate fresh unused variable names, all compiler transforms maintain a counter, the cnt-field in the b_function and opt_st records, which is incremented each time a new variable or label is created. In the following description the value of the diff --git a/prs/8803/lib/compiler-8.5.1/doc/html/compile.html b/prs/8803/lib/compiler-8.5.1/doc/html/compile.html index 29c40c36dcfa2..0de90f5c799a3 100644 --- a/prs/8803/lib/compiler-8.5.1/doc/html/compile.html +++ b/prs/8803/lib/compiler-8.5.1/doc/html/compile.html @@ -153,7 +153,7 @@

    Options given in the compile() attribute in the source code take precedence over options given to the compiler, which in turn take precedence over options given in the environment.

    A later compiler option takes precedence over an earlier one in the -option list. Example:

    compile:file(something, [nowarn_missing_spec,warn_missing_spec]).

    Warnings will be emitted for functions without specifications, unless +option list. Example:

    compile:file(something, [nowarn_missing_spec,warn_missing_spec]).

    Warnings will be emitted for functions without specifications, unless the source code for module something contains a compile(nowarn_missing_spec) attribute.

    Change

    In Erlang/OTP 26 and earlier, the option order was the opposite of what is described here.

    @@ -177,14 +177,14 @@

    which functions to inline, or {inline,[{Name,Arity},...]} to have the compiler inline all calls to the given functions. If the option is given inside a compile directive in an Erlang module, {Name,Arity} can be written as -Name/Arity.

    Example of explicit inlining:

    -compile({inline,[pi/0]}).
    +Name/Arity.

    Example of explicit inlining:

    -compile({inline,[pi/0]}).
     
    -pi() -> 3.1416.

    Example of implicit inlining:

    -compile(inline).

    The option {inline_size,Size} controls how large functions that are allowed to +pi() -> 3.1416.

    Example of implicit inlining:

    -compile(inline).

    The option {inline_size,Size} controls how large functions that are allowed to be inlined. Default is 24, which keeps the size of the inlined code roughly the same as the un-inlined version (only relatively small functions are inlined).

    Example:

    %% Aggressive inlining - will increase code size.
    --compile(inline).
    --compile({inline_size,100}).

    +-compile(inline). +-compile({inline_size,100}).

    @@ -932,10 +932,10 @@

    file(File, Options)

    function definitions. This is the preferred method of enabling and disabling features, since it is a local property of a module.

  • makedep - Produces a Makefile rule to track headers dependencies. No object file is produced.

    By default, this rule is written to <File>.Pbeam. However, if option -binary is set, nothing is written and the rule is returned in Binary.

    The output will be encoded in UTF-8.

    For example, if you have the following module:

    -module(module).
    +binary is set, nothing is written and the rule is returned in Binary.

    The output will be encoded in UTF-8.

    For example, if you have the following module:

    -module(module).
     
    --include_lib("eunit/include/eunit.hrl").
    --include("header.hrl").

    The Makefile rule generated by this option looks as follows:

    module.beam: module.erl \
    +-include_lib("eunit/include/eunit.hrl").
    +-include("header.hrl").

    The Makefile rule generated by this option looks as follows:

    module.beam: module.erl \
       /usr/local/lib/erlang/lib/eunit/include/eunit.hrl \
       header.hrl
  • makedep_side_effect - The dependencies are created as a side effect to the normal compilation process. This means that the object file will also be @@ -1001,7 +1001,7 @@

    file(File, Options)

    before Erlang/OTP R14A when calling a local function with the same name as an auto-imported BIF without module prefix.

    If the BIF is to be called, use the erlang module prefix in the call, not {no_auto_import,[{F,A}, ...]}.

    If this option is written in the source code, as a -compile directive, the -syntax F/A can be used instead of {F,A}. For example:

    -compile({no_auto_import,[error/1]}).
  • no_auto_import - Do not auto-import any functions from erlang module.

  • no_line_info - Omits line number information to produce a slightly +syntax F/A can be used instead of {F,A}. For example:

    -compile({no_auto_import,[error/1]}).
  • no_auto_import - Do not auto-import any functions from erlang module.

  • no_line_info - Omits line number information to produce a slightly smaller output file.

  • no_lint - Skips the pass that checks for errors and warnings. Only applicable together with the from_abstr option. This is mainly for implementations of other languages on top of Erlang, which have already done diff --git a/prs/8803/lib/compiler-8.5.1/doc/html/compiler.epub b/prs/8803/lib/compiler-8.5.1/doc/html/compiler.epub index e7a33b21c5531..fdc91f74119dc 100644 Binary files a/prs/8803/lib/compiler-8.5.1/doc/html/compiler.epub and b/prs/8803/lib/compiler-8.5.1/doc/html/compiler.epub differ diff --git a/prs/8803/lib/compiler-8.5.1/doc/html/notes.html b/prs/8803/lib/compiler-8.5.1/doc/html/notes.html index 43a5ee0bd0d15..139fdb7a110a9 100644 --- a/prs/8803/lib/compiler-8.5.1/doc/html/notes.html +++ b/prs/8803/lib/compiler-8.5.1/doc/html/notes.html @@ -149,13 +149,13 @@

    Fixed Bugs and Malfunctions

    -
    • Generators for binary comprehensions could be evaluated before it was known that they would be needed. That could result in a binary comprehensions failing if a generator that should not be evaluated until later failed.

      As an example, consider this module:

      -module(t).
      --export([f/0]).
      +
      • Generators for binary comprehensions could be evaluated before it was known that they would be needed. That could result in a binary comprehensions failing if a generator that should not be evaluated until later failed.

        As an example, consider this module:

        -module(t).
        +-export([f/0]).
         
        -f() ->
        -    <<0 || _ <- [], _ <- ok, false>>.

        In Erlang/OTP 26 it would fail like so:

        1> t:f().
        +f() ->
        +    <<0 || _ <- [], _ <- ok, false>>.

        In Erlang/OTP 26 it would fail like so:

        1> t:f().
         ** exception error: bad generator ok
        -     in function  t:f/0 (t.erl, line 6)

        In Erlang/OTP 27 it returns an empty binary:

        1> t:f().
        +     in function  t:f/0 (t.erl, line 6)

        In Erlang/OTP 27 it returns an empty binary:

        1> t:f().
         <<>>

        Own Id: OTP-18703 Aux Id: GH-7494, PR-7538

      • The documentation for the preprocessor now mentions that defined(Name) can be called in the condition for an -if or -elif directive to test whether Name is the name of a defined macro. (This feature was implemented in OTP 21.)

        If a function call in an -if or -elif with a name that is not the name of a guard BIF, there would not be a compilation error, but would instead cause the lines following the directive to be skipped. This has now been changed to be a compilation error.

        POTENTIAL INCOMPATIBILITY

        Own Id: OTP-18784 Aux Id: GH-7706, PR-7726

      @@ -163,39 +163,39 @@

      Improvements and New Features

      Own Id: OTP-18680 Aux Id: PR-7491, PR-8086, ERIERL-967

    • Improved the performance of the alias analysis pass.

      Own Id: OTP-18714 Aux Id: PR-7528, GH-7432

    • -spec attributes are now used for documentation.

      Own Id: OTP-18801 Aux Id: PR-7739

    • Native coverage support has been implemented in the JIT. It will automatically be used by the cover tool to reduce the execution overhead when running cover-compiled code.

      There are also new APIs to support native coverage without using the cover tool.

      To instrument code for native coverage it must be compiled with the line_coverage option.

      To enable native coverage in the runtime system, start it like so:

      $ erl +JPcover true

      There are also the following new functions for supporting native coverage:

      Own Id: OTP-18856 Aux Id: PR-7856

    • EEP-59 - Documentation Attributes has been implemented.

      Documentation attributes can be used to document functions, types, callbacks, and modules. The keyword -moduledoc "Documentation here". is used to document modules, while -doc "Documentation here". can be used on top of functions, types, and callbacks to document them, respectively.

      • Types, callbacks, and function documentation can be set to hidden either via -doc false or -doc hidden. When documentation attributes mark a type as hidden, they will not be part of the documentation.

      • The documentation from moduledoc and doc gets added by default to the binary beam file, following the format of EEP-48.

      • Using the compiler flag warn_missing_doc will raise a warning when -doc attributes are missing in exported functions, types, and callbacks.

      • Using the compiler flag warn_missing_spec_documented will raise a warning when -spec attributes are missing in documented functions, types, and callbacks.

      • moduledocs and docs may refer to external files to be embedded, such as -doc {file, "README.md"}., which refers to the file README.md found in the current working directory.

      • The compiler warns about exported functions whose specs refer to hidden types. Thus, there will be warnings when a hidden type (meaning, the type is not part of the documentation) gets used in an exported function.

      Own Id: OTP-18916 Aux Id: PR-7936

    • The documentation has been migrated to use Markdown and ExDoc.

      Own Id: OTP-18955 Aux Id: PR-8026

    • The order in which the compiler looks up options has changed.

      When there is a conflict in the compiler options given in the -compile() attribute and options given to the compiler, the options given in the -compile() attribute overrides the option given to the compiler, which in turn overrides options given in the ERL_COMPILER_OPTIONS environment variable.

      Example:

      If some_module.erl has the following attribute:

      -compile([nowarn_missing_spec]).

      and the compiler is invoked like so:

      % erlc +warn_missing_spec some_module.erl

      no warnings will be issued for functions that do not have any specs.

      POTENTIAL INCOMPATIBILITY

      Own Id: OTP-18968 Aux Id: GH-6979, PR-8093

    • Safe destructive update of tuples has been implemented in the compiler and runtime system. This allows the VM to update tuples in-place when it is safe to do so, thus improving performance by doing less copying but also by producing less garbage.

      Example:

      -record(rec, {a,b,c}).
      +spec attributes are missing in documented functions, types, and callbacks.

    • moduledocs and docs may refer to external files to be embedded, such as -doc {file, "README.md"}., which refers to the file README.md found in the current working directory.

    • The compiler warns about exported functions whose specs refer to hidden types. Thus, there will be warnings when a hidden type (meaning, the type is not part of the documentation) gets used in an exported function.

    Own Id: OTP-18916 Aux Id: PR-7936

  • The documentation has been migrated to use Markdown and ExDoc.

    Own Id: OTP-18955 Aux Id: PR-8026

  • The order in which the compiler looks up options has changed.

    When there is a conflict in the compiler options given in the -compile() attribute and options given to the compiler, the options given in the -compile() attribute overrides the option given to the compiler, which in turn overrides options given in the ERL_COMPILER_OPTIONS environment variable.

    Example:

    If some_module.erl has the following attribute:

    -compile([nowarn_missing_spec]).

    and the compiler is invoked like so:

    % erlc +warn_missing_spec some_module.erl

    no warnings will be issued for functions that do not have any specs.

    POTENTIAL INCOMPATIBILITY

    Own Id: OTP-18968 Aux Id: GH-6979, PR-8093

  • Safe destructive update of tuples has been implemented in the compiler and runtime system. This allows the VM to update tuples in-place when it is safe to do so, thus improving performance by doing less copying but also by producing less garbage.

    Example:

    -record(rec, {a,b,c}).
     
    -update(#rec{a=needs_update,b=N}=R0) ->
    -    R = R0#rec{a=up_to_date},
    +update(#rec{a=needs_update,b=N}=R0) ->
    +    R = R0#rec{a=up_to_date},
         if
             N < 0 ->
    -            R#rec{c=negative};
    +            R#rec{c=negative};
             N == 0 ->
    -            R#rec{c=zero};
    +            R#rec{c=zero};
             N > 0 ->
    -            R#rec{c=positive}
    +            R#rec{c=positive}
         end.

    The record updates in each of the three clauses of the if can safely be done in-place, because variable R is not used again.

    Own Id: OTP-18972 Aux Id: PR-8090

  • Improved the match context reuse optimization slightly, allowing match contexts to be passed as-is to bit_size/1 and byte_size/1.

    Own Id: OTP-18987

  • erl_lint (and by extension the compiler) will now warn for code using deprecated callbacks.

    The only callback currenly deprecated is format_status/2 in gen_server, gen_event and gen_statem.

    You can use nowarn_deprecated_callback to silence the warning.

    Own Id: OTP-19010 Aux Id: PR-8205

  • diff --git a/prs/8803/lib/compiler-8.5.1/doc/html/ssa_checks.html b/prs/8803/lib/compiler-8.5.1/doc/html/ssa_checks.html index 24d0cdc2a04bf..a3760e113a6e5 100644 --- a/prs/8803/lib/compiler-8.5.1/doc/html/ssa_checks.html +++ b/prs/8803/lib/compiler-8.5.1/doc/html/ssa_checks.html @@ -142,32 +142,32 @@

    SSA checks are embedded in the source code as comments starting with with one of %ssa%, %%ssa% or %%%ssa%. This is a short introduction the syntax, for the full syntax please refer to the -ssa_check_when_clause production in erl_parse.yrl.

    SSA checks can be placed inside any Erlang function, for example:

    t0() ->
    +ssa_check_when_clause production in erl_parse.yrl.

    SSA checks can be placed inside any Erlang function, for example:

    t0() ->
     %ssa% () when post_ssa_opt ->
     %ssa%   ret(#{}).
    -  #{}.

    will check that t0/0 returns the literal #{}. If we want to check -that a function returns its first formal parameter, we can write:

    t1(A, _B) ->
    +  #{}.

    will check that t0/0 returns the literal #{}. If we want to check +that a function returns its first formal parameter, we can write:

    t1(A, _B) ->
     %ssa% (X, _) when post_ssa_opt ->
     %ssa%   ret(X).
       A.

    Note how we match the first formal parameter using X. The reason for having our own formal parameters for the SSA check, is that we don't want to introduce new identifiers at the Erlang level to support SSA-level checks. Consider if t1/2 had been defined as t1([A|As], B) we would have had to introduce a new identifier for the aggregate -value [A|As].

    The full syntax for a SSA check clause is:

    <expected-result>? (<formals>) when <pipeline-location> -> <checks> '.'

    where <expected-result> can be one of pass (the check must +value [A|As].

    The full syntax for a SSA check clause is:

    <expected-result>? (<formals>) when <pipeline-location> -> <checks> '.'

    where <expected-result> can be one of pass (the check must succeed), fail and xfail (the check must fail). Omitting <expected-result> is parsed as an implicit pass.

    <formals> is a comma-separated list of variables.

    <pipeline-location> specifies when in the compiler pipeline to run the checks. For now the only supported value for <pipeline-location> is post_ssa_opt which runs the checks after the ssa_opt pass.

    <checks> is a comma-separated list of matches against the BEAM SSA -code. For non-flow-control operations the syntax is:

    <variable> = <operation> ( <arguments> ) <annotation>?

    where <operation> is the #b_set.op field from the internal SSA -representation. BIFs are written as bif:<atom>.

    <arguments> is a comma-separated list of variables or literals.

    For flow control operations and labels, the syntax is as follows:

    br(<bool>, <true-label>, <false-label>)
    +code. For non-flow-control operations the syntax is:

    <variable> = <operation> ( <arguments> ) <annotation>?

    where <operation> is the #b_set.op field from the internal SSA +representation. BIFs are written as bif:<atom>.

    <arguments> is a comma-separated list of variables or literals.

    For flow control operations and labels, the syntax is as follows:

    br(<bool>, <true-label>, <false-label>)
     
    -switch(<value>, <fail-label>, [{<label>,<value>},...])
    +switch(<value>, <fail-label>, [{<label>,<value>},...])
     
    -ret(<value>)
    +ret(<value>)
     
     label <value>

    where <value> is a literal or a variable.

    A check can also include an assertion on operation annotations. The assertion is written as a map-like pattern following the argument -list, for example:

    t0() ->
    +list, for example:

    t0() ->
     %ssa% () when post_ssa_opt ->
     %ssa% _ = call(fun return_int/0) { result_type => {t_integer,{17,17}},
     %ssa%                              location => {_,32} },
    @@ -175,9 +175,9 @@ 

    %ssa% result_type => {t_tuple,2,true,#{1 => {t_integer,{1,1}}, %ssa% 2 => {t_integer,{2,2}}}} %ssa% }. - X = return_int(), - Y = return_tuple(), - {X, Y}.

    + X = return_int(), + Y = return_tuple(), + {X, Y}.

    diff --git a/prs/8803/lib/crypto-5.5/doc/html/crypto.epub b/prs/8803/lib/crypto-5.5/doc/html/crypto.epub index 0867312d61900..b3db02a426bb4 100644 Binary files a/prs/8803/lib/crypto-5.5/doc/html/crypto.epub and b/prs/8803/lib/crypto-5.5/doc/html/crypto.epub differ diff --git a/prs/8803/lib/crypto-5.5/doc/html/crypto.html b/prs/8803/lib/crypto-5.5/doc/html/crypto.html index 98322ef8d27c1..0e6a96be5fcaf 100644 --- a/prs/8803/lib/crypto-5.5/doc/html/crypto.html +++ b/prs/8803/lib/crypto-5.5/doc/html/crypto.html @@ -595,7 +595,7 @@

    -
    rsa_public() = [E, N]
    rsa_private() = [E, N, D] | [E, N, D, P1, P2, E1, E2, C]

    Where E is the public exponent, N is public modulus and D is the private +

    rsa_public() = [E, N]
    rsa_private() = [E, N, D] | [E, N, D, P1, P2, E1, E2, C]

    Where E is the public exponent, N is public modulus and D is the private exponent. The longer key format contains redundant information that will make the calculation faster. P1 and P2 are first and second prime factors. E1 and E2 are first and second exponents. C is the CRT coefficient. The terminology is @@ -3131,7 +3131,7 @@

    rsa_params()

    -
    rsa_public() = [E, N]
    rsa_private() = [E, N, D] | [E, N, D, P1, P2, E1, E2, C]

    Where E is the public exponent, N is public modulus and D is the private +

    rsa_public() = [E, N]
    rsa_private() = [E, N, D] | [E, N, D, P1, P2, E1, E2, C]

    Where E is the public exponent, N is public modulus and D is the private exponent. The longer key format contains redundant information that will make the calculation faster. P1 and P2 are first and second prime factors. E1 and E2 are first and second exponents. C is the CRT coefficient. The terminology is @@ -5548,9 +5548,9 @@

    rand_seed()

    BN_rand_range).

    Saves the state in the process dictionary before returning it as well. See also rand:seed/1 and rand_seed_s/0.

    When using the state object from this function the rand functions using it may raise exception error:low_entropy in case the random generator failed due -to lack of secure "randomness".

    Example

    _ = crypto:rand_seed(),
    -_IntegerValue = rand:uniform(42), % [1; 42]
    -_FloatValue = rand:uniform().     % [0.0; 1.0[
    +to lack of secure "randomness".

    Example

    _ = crypto:rand_seed(),
    +_IntegerValue = rand:uniform(42), % [1; 42]
    +_FloatValue = rand:uniform().     % [0.0; 1.0[
    @@ -5616,9 +5616,9 @@

    rand_seed_alg(Alg)

    generate cryptographically strong random numbers.

    Saves the state in the process dictionary before returning it as well. See also rand:seed/1 and rand_seed_alg_s/1.

    When using the state object from this function the rand functions using it may raise exception error:low_entropy in case the random generator failed due -to lack of secure "randomness".

    Example

    _ = crypto:rand_seed_alg(crypto_cache),
    -_IntegerValue = rand:uniform(42), % [1; 42]
    -_FloatValue = rand:uniform().     % [0.0; 1.0[
    +to lack of secure "randomness".

    Example

    _ = crypto:rand_seed_alg(crypto_cache),
    +_IntegerValue = rand:uniform(42), % [1; 42]
    +_FloatValue = rand:uniform().     % [0.0; 1.0[
    @@ -5650,12 +5650,12 @@

    rand_seed_alg(Alg, Seed)

    Creates a state object for random number generation, in order to generate cryptographically unpredictable random numbers.

    Saves the state in the process dictionary before returning it as well. See also -rand_seed_alg_s/2.

    Example

    _ = crypto:rand_seed_alg(crypto_aes, "my seed"),
    -IntegerValue = rand:uniform(42), % [1; 42]
    -FloatValue = rand:uniform(),     % [0.0; 1.0[
    -_ = crypto:rand_seed_alg(crypto_aes, "my seed"),
    -IntegerValue = rand:uniform(42), % Same values
    -FloatValue = rand:uniform().     % again
    +rand_seed_alg_s/2.

    Example

    _ = crypto:rand_seed_alg(crypto_aes, "my seed"),
    +IntegerValue = rand:uniform(42), % [1; 42]
    +FloatValue = rand:uniform(),     % [0.0; 1.0[
    +_ = crypto:rand_seed_alg(crypto_aes, "my seed"),
    +IntegerValue = rand:uniform(42), % Same values
    +FloatValue = rand:uniform().     % again
    @@ -6120,12 +6120,12 @@

    info()

    -

    Get information about crypto and the OpenSSL backend.

    Returns a map with information about the compilation and linking of crypto.

    Example:

    1> crypto:info().
    -#{compile_type => normal,
    +

    Get information about crypto and the OpenSSL backend.

    Returns a map with information about the compilation and linking of crypto.

    Example:

    1> crypto:info().
    +#{compile_type => normal,
       cryptolib_version_compiled => "OpenSSL 3.0.0 7 sep 2021",
       cryptolib_version_linked => "OpenSSL 3.0.0 7 sep 2021",
       link_type => dynamic,
    -  otp_crypto_version => "5.0.2"}
    +  otp_crypto_version => "5.0.2"}
     2>

    More association types than documented may be present in the map.

    @@ -6193,8 +6193,8 @@

    info_lib()

    Get the name and version of the libraries used by crypto.

    Name is the name of the library. VerNum is the numeric version according to the library's own versioning scheme. VerStr contains a text variant of the -version.

    > info_lib().
    -[{<<"OpenSSL">>,269484095,<<"OpenSSL 1.1.0c  10 Nov 2016"">>}]

    Note

    From OTP R16 the numeric version represents the version of the OpenSSL +version.

    > info_lib().
    +[{<<"OpenSSL">>,269484095,<<"OpenSSL 1.1.0c  10 Nov 2016"">>}]

    Note

    From OTP R16 the numeric version represents the version of the OpenSSL header files (openssl/opensslv.h) used when crypto was compiled. The text variant represents the libcrypto library used at runtime. In earlier OTP versions both numeric and text was taken from the library.

    diff --git a/prs/8803/lib/crypto-5.5/doc/html/engine_keys.html b/prs/8803/lib/crypto-5.5/doc/html/engine_keys.html index d249037511256..0397cb3a9fc6d 100644 --- a/prs/8803/lib/crypto-5.5/doc/html/engine_keys.html +++ b/prs/8803/lib/crypto-5.5/doc/html/engine_keys.html @@ -161,13 +161,13 @@

    Sign with an engine stored private key

    This example shows how to construct a key reference that is used in a sign -operation. The actual key is stored in the engine that is loaded at prompt 1.

    1> {ok, EngineRef} = crypto:engine_load(....).
    +operation. The actual key is stored in the engine that is loaded at prompt 1.

    1> {ok, EngineRef} = crypto:engine_load(....).
     ...
    -{ok,#Ref<0.2399045421.3028942852.173962>}
    -2> PrivKey = #{engine => EngineRef,
    -               key_id => "id of the private key in Engine"}.
    +{ok,#Ref<0.2399045421.3028942852.173962>}
    +2> PrivKey = #{engine => EngineRef,
    +               key_id => "id of the private key in Engine"}.
     ...
    -3> Signature = crypto:sign(rsa, sha, <<"The message">>, PrivKey).
    +3> Signature = crypto:sign(rsa, sha, <<"The message">>, PrivKey).
     <<65,6,125,254,54,233,84,77,83,63,168,28,169,214,121,76,
       207,177,124,183,156,185,160,243,36,79,125,230,231,...>>

    @@ -177,10 +177,10 @@

    Here the signature and message in the last example is verifyed using the public key. The public key is stored in an engine, only to exemplify that it is -possible. The public key could of course be handled openly as usual.

    4> PublicKey = #{engine => EngineRef,
    -                 key_id => "id of the public key in Engine"}.
    +possible. The public key could of course be handled openly as usual.

    4> PublicKey = #{engine => EngineRef,
    +                 key_id => "id of the public key in Engine"}.
     ...
    -5> crypto:verify(rsa, sha, <<"The message">>, Signature, PublicKey).
    +5> crypto:verify(rsa, sha, <<"The message">>, Signature, PublicKey).
     true
     6>

    @@ -189,11 +189,11 @@

    Using a password protected private key

    The same example as the first sign example, except that a password protects the -key down in the Engine.

    6> PrivKeyPwd = #{engine => EngineRef,
    +key down in the Engine.

    6> PrivKeyPwd = #{engine => EngineRef,
                       key_id => "id of the pwd protected private key in Engine",
    -		  password => "password"}.
    +		  password => "password"}.
     ...
    -7> crypto:sign(rsa, sha, <<"The message">>, PrivKeyPwd).
    +7> crypto:sign(rsa, sha, <<"The message">>, PrivKeyPwd).
     <<140,80,168,101,234,211,146,183,231,190,160,82,85,163,
       175,106,77,241,141,120,72,149,181,181,194,154,175,76,
       223,...>>
    diff --git a/prs/8803/lib/crypto-5.5/doc/html/engine_load.html b/prs/8803/lib/crypto-5.5/doc/html/engine_load.html
    index 6fe2b6f81a82d..23a2a8beaa509 100644
    --- a/prs/8803/lib/crypto-5.5/doc/html/engine_load.html
    +++ b/prs/8803/lib/crypto-5.5/doc/html/engine_load.html
    @@ -152,35 +152,35 @@ 

    Dynamically load an engine from default directory

    If the engine is located in the OpenSSL/LibreSSL installation engines -directory.

    1> {ok, Engine} = crypto:engine_load(<<"otp_test_engine">>, [], []).
    - {ok, #Ref}

    +directory.

    1> {ok, Engine} = crypto:engine_load(<<"otp_test_engine">>, [], []).
    + {ok, #Ref}

    Load an engine with the dynamic engine

    Load an engine with the help of the dynamic engine by giving the path to the -library.

     2> {ok, Engine} = crypto:engine_load(<<"dynamic">>,
    -                                      [{<<"SO_PATH">>,
    -                                        <<"/some/path/otp_test_engine.so">>},
    -                                       {<<"ID">>, <<"MD5">>},
    -                                       <<"LOAD">>],
    -                                      []).
    - {ok, #Ref}

    +library.

     2> {ok, Engine} = crypto:engine_load(<<"dynamic">>,
    +                                      [{<<"SO_PATH">>,
    +                                        <<"/some/path/otp_test_engine.so">>},
    +                                       {<<"ID">>, <<"MD5">>},
    +                                       <<"LOAD">>],
    +                                      []).
    + {ok, #Ref}

    Load an engine and replace some methods

    Load an engine with the help of the dynamic engine and just replace some engine -methods.

     3> {ok, Engine} = crypto:engine_load(<<"dynamic">>,
    -                                      [{<<"SO_PATH">>,
    -                                        <<"/some/path/otp_test_engine.so">>},
    -                                       {<<"ID">>, <<"MD5">>},
    -                                       <<"LOAD">>],
    -                                      []).
    -{ok, #Ref}
    -4> ok = crypto:engine_register(Engine, [engine_method_digests]).
    +methods.

     3> {ok, Engine} = crypto:engine_load(<<"dynamic">>,
    +                                      [{<<"SO_PATH">>,
    +                                        <<"/some/path/otp_test_engine.so">>},
    +                                       {<<"ID">>, <<"MD5">>},
    +                                       <<"LOAD">>],
    +                                      []).
    +{ok, #Ref}
    +4> ok = crypto:engine_register(Engine, [engine_method_digests]).
     ok

    @@ -189,19 +189,19 @@

    5> {ok, Engine} = crypto:ensure_engine_loaded(<<"MD5">>, - <<"/some/path/otp_test_engine.so">>). - {ok, #Ref}

    To remove the tag from the OpenSSL engine list use crypto:engine_remove/1.

     6> crypto:engine_remove(Engine).
    +check if the ID is loaded and then just get a new reference to the engine.

     5> {ok, Engine} = crypto:ensure_engine_loaded(<<"MD5">>,
    +                                               <<"/some/path/otp_test_engine.so">>).
    + {ok, #Ref}

    To remove the tag from the OpenSSL engine list use crypto:engine_remove/1.

     6> crypto:engine_remove(Engine).
      ok

    To unload it use crypto:engine_unload/1 which removes the references to the -engine.

     6> crypto:engine_unload(Engine).
    +engine.

     6> crypto:engine_unload(Engine).
      ok

    List all engines currently loaded

    -
     8> crypto:engine_list().
    -[<<"dynamic">>, <<"MD5">>]
    +
     8> crypto:engine_list().
    +[<<"dynamic">>, <<"MD5">>]
    diff --git a/prs/8803/lib/crypto-5.5/doc/html/new_api.html b/prs/8803/lib/crypto-5.5/doc/html/new_api.html index 06513ca68f6e0..c60396d534f98 100644 --- a/prs/8803/lib/crypto-5.5/doc/html/new_api.html +++ b/prs/8803/lib/crypto-5.5/doc/html/new_api.html @@ -192,41 +192,41 @@

    initialises the crypto context. One or more calls crypto_update/2 does the actual encryption or decryption for each block.

    This example shows first the encryption of two blocks and then decryptions of the cipher text, but divided into three blocks just to show that it is possible -to divide the plain text and cipher text differently for some ciphers:

    	1> application:start(crypto).
    +to divide the plain text and cipher text differently for some ciphers:

    	1> application:start(crypto).
     	ok
     	2> Key = <<1:128>>.
     	<<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1>>
     	3> IV = <<0:128>>.
     	<<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>
    -	4> StateEnc = crypto:crypto_init(aes_128_ctr, Key, IV, true). % encrypt -> true
    +	4> StateEnc = crypto:crypto_init(aes_128_ctr, Key, IV, true). % encrypt -> true
     	#Ref<0.3768901617.1128660993.124047>
    -	5> crypto:crypto_update(StateEnc, <<"First bytes">>).
    +	5> crypto:crypto_update(StateEnc, <<"First bytes">>).
     	<<67,44,216,166,25,130,203,5,66,6,162>>
    -	6> crypto:crypto_update(StateEnc, <<"Second bytes">>).
    +	6> crypto:crypto_update(StateEnc, <<"Second bytes">>).
     	<<16,79,94,115,234,197,94,253,16,144,151,41>>
     	7>
    -	7> StateDec = crypto:crypto_init(aes_128_ctr, Key, IV, false). % decrypt -> false
    +	7> StateDec = crypto:crypto_init(aes_128_ctr, Key, IV, false). % decrypt -> false
     	#Ref<0.3768901617.1128660994.124255>
    -	8> crypto:crypto_update(StateDec, <<67,44,216,166,25,130,203>>).
    +	8> crypto:crypto_update(StateDec, <<67,44,216,166,25,130,203>>).
     	<<"First b">>
    -	9> crypto:crypto_update(StateDec, <<5,66,6,162,16,79,94,115,234,197,
    -        94,253,16,144,151>>).
    +	9> crypto:crypto_update(StateDec, <<5,66,6,162,16,79,94,115,234,197,
    +        94,253,16,144,151>>).
     	<<"ytesSecond byte">>
    -	10> crypto:crypto_update(StateDec, <<41>>).
    +	10> crypto:crypto_update(StateDec, <<41>>).
     	<<"s">>
     	11>

    Note that the internal data that the StateEnc and StateDec references are destructivly updated by the calls to crypto_update/2. This is to gain time in the calls of the nifs interfacing the cryptolib. In a loop where the state is saved in the loop's state, it also saves one update of the loop state per crypto operation.

    For example, a simple server receiving text parts to encrypt and send the result -back to the one who sent them (the Requester):

    	encode(Crypto, Key, IV) ->
    -	crypto_loop(crypto:crypto_init(Crypto, Key, IV, true)).
    +back to the one who sent them (the Requester):

    	encode(Crypto, Key, IV) ->
    +	crypto_loop(crypto:crypto_init(Crypto, Key, IV, true)).
     
    -	crypto_loop(State) ->
    +	crypto_loop(State) ->
     	receive
    -        {Text, Requester} ->
    -        Requester ! crypto:crypto_update(State, Text),
    -	loop(State)
    +        {Text, Requester} ->
    +        Requester ! crypto:crypto_update(State, Text),
    +	loop(State)
     	end.

    @@ -239,9 +239,9 @@

    <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1>> 2> IV = <<0:128>>. <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>> - 3> Txt = [<<"First bytes">>,<<"Second bytes">>]. - [<<"First bytes">>,<<"Second bytes">>] - 4> crypto:crypto_one_time(aes_128_ctr, Key, IV, Txt, true). + 3> Txt = [<<"First bytes">>,<<"Second bytes">>]. + [<<"First bytes">>,<<"Second bytes">>] + 4> crypto:crypto_one_time(aes_128_ctr, Key, IV, Txt, true). <<67,44,216,166,25,130,203,5,66,6,162,16,79,94,115,234, 197,94,253,16,144,151,41>> 5>

    The [<<"First bytes">>,<<"Second bytes">>] could of course have been one @@ -257,14 +257,14 @@

    <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1>> 2> IV = <<0:128>>. <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>> - 3> Txt = [<<"First bytes">>,<<"Second bytes">>]. - [<<"First bytes">>,<<"Second bytes">>] + 3> Txt = [<<"First bytes">>,<<"Second bytes">>]. + [<<"First bytes">>,<<"Second bytes">>] 4> AAD = <<"Some additional auth data">>. <<"Some additional auth data">> - 5> crypto:crypto_one_time_aead(aes_128_gcm, Key, IV, Txt, AAD, true). - {<<240,130,38,96,130,241,189,52,3,190,179,213,132,1,72, + 5> crypto:crypto_one_time_aead(aes_128_gcm, Key, IV, Txt, AAD, true). + {<<240,130,38,96,130,241,189,52,3,190,179,213,132,1,72, 192,103,176,90,104,15,71,158>>, - <<131,47,45,91,142,85,9,244,21,141,214,71,31,135,2,155>>} + <<131,47,45,91,142,85,9,244,21,141,214,71,31,135,2,155>>} 6>

    The [<<"First bytes">>,<<"Second bytes">>] could of course have been one single binary: <<"First bytesSecond bytes">>.

    @@ -274,21 +274,21 @@

    	1> Key = <<1:128>>.
     	<<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1>>
    -	2> StateMac = crypto:mac_init(cmac, aes_128_cbc, Key).
    +	2> StateMac = crypto:mac_init(cmac, aes_128_cbc, Key).
     	#Ref<0.2424664121.2781478916.232610>
    -	3> crypto:mac_update(StateMac, <<"First bytes">>).
    +	3> crypto:mac_update(StateMac, <<"First bytes">>).
     	#Ref<0.2424664121.2781478916.232610>
    -	4> crypto:mac_update(StateMac, " ").
    +	4> crypto:mac_update(StateMac, " ").
     	#Ref<0.2424664121.2781478916.232610>
    -	5> crypto:mac_update(StateMac, <<"last bytes">>).
    +	5> crypto:mac_update(StateMac, <<"last bytes">>).
     	#Ref<0.2424664121.2781478916.232610>
    -	6> crypto:mac_final(StateMac).
    +	6> crypto:mac_final(StateMac).
     	<<68,191,219,128,84,77,11,193,197,238,107,6,214,141,160,
     	249>>
    -	7>

    and compare the result with a single calculation just for this example:

    	7> crypto:mac(cmac, aes_128_cbc, Key, "First bytes last bytes").
    +	7>

    and compare the result with a single calculation just for this example:

    	7> crypto:mac(cmac, aes_128_cbc, Key, "First bytes last bytes").
     	<<68,191,219,128,84,77,11,193,197,238,107,6,214,141,160,
     	249>>
    -	8> v(7) == v(6).
    +	8> v(7) == v(6).
     	true
     	9>

    diff --git a/prs/8803/lib/debugger-5.4/doc/html/debugger.epub b/prs/8803/lib/debugger-5.4/doc/html/debugger.epub index 3c5a101067cdc..1d5917f794647 100644 Binary files a/prs/8803/lib/debugger-5.4/doc/html/debugger.epub and b/prs/8803/lib/debugger-5.4/doc/html/debugger.epub differ diff --git a/prs/8803/lib/debugger-5.4/doc/html/debugger_chapter.html b/prs/8803/lib/debugger-5.4/doc/html/debugger_chapter.html index 4b6106cf343cb..448d9c06512b2 100644 --- a/prs/8803/lib/debugger-5.4/doc/html/debugger_chapter.html +++ b/prs/8803/lib/debugger-5.4/doc/html/debugger_chapter.html @@ -164,12 +164,12 @@

    To have an effect, a breakpoint must be set at an executable line, which is a line of code containing an executable expression such as a matching or a function call. A blank line or a line containing a comment, function head, or -pattern in a case statement or receive statement is not executable.

    In the following example, lines 2, 4, 6, 8, and 11 are executable lines:

    1: is_loaded(Module,Compiled) ->
    -2:   case get_file(Module,Compiled) of
    -3:     {ok,File} ->
    -4:       case code:which(Module) of
    +pattern in a case statement or receive statement is not executable.

    In the following example, lines 2, 4, 6, 8, and 11 are executable lines:

    1: is_loaded(Module,Compiled) ->
    +2:   case get_file(Module,Compiled) of
    +3:     {ok,File} ->
    +4:       case code:which(Module) of
     5:         ?TAG ->
    -6:           {loaded,File};
    +6:           {loaded,File};
     7:         _ ->
     8:           unloaded
     9:       end;
    @@ -208,13 +208,13 @@ 

    returns unbound or {value,Value}.

    Conditional Break Dialog Window

    Right-click the Module entry to open a popup menu from which the appropriate module can be selected.

    Example:

    A conditional breakpoint calling c_test:c_break/1 is added at line 6 in module fact. Each time the breakpoint is reached, the function is called. When N is -equal to 3, the function returns true and the process stops.

    Extract from fact.erl:

    5. fac(0) -> 1;
    -6. fac(N) when N > 0, is_integer(N) -> N * fac(N-1).

    Definition of c_test:c_break/1:

    -module(c_test).
    --export([c_break/1]).
    +equal to 3, the function returns true and the process stops.

    Extract from fact.erl:

    5. fac(0) -> 1;
    +6. fac(N) when N > 0, is_integer(N) -> N * fac(N-1).

    Definition of c_test:c_break/1:

    -module(c_test).
    +-export([c_break/1]).
     
    -c_break(Bindings) ->
    -    case int:get_binding('N', Bindings) of
    -        {value, 3} ->
    +c_break(Bindings) ->
    +    case int:get_binding('N', Bindings) of
    +        {value, 3} ->
                 true;
             _ ->
                 false
    @@ -235,12 +235,12 @@ 

    The Erlang emulator keeps track of a stack trace, information about recent function calls. This information is used if an error occurs, for example:

    1> catch a+1.
    -{'EXIT',{badarith,[{erlang,'+',[a,1],[]},
    -                   {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,573}]},
    -                   {erl_eval,expr,5,[{file,"erl_eval.erl"},{line,357}]},
    -                   {shell,exprs,7,[{file,"shell.erl"},{line,674}]},
    -                   {shell,eval_exprs,7,[{file,"shell.erl"},{line,629}]},
    -                   {shell,eval_loop,3,[{file,"shell.erl"},{line,614}]}]}}

    For details about the stack trace, see section +{'EXIT',{badarith,[{erlang,'+',[a,1],[]}, + {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,573}]}, + {erl_eval,expr,5,[{file,"erl_eval.erl"},{line,357}]}, + {shell,exprs,7,[{file,"shell.erl"},{line,674}]}, + {shell,eval_exprs,7,[{file,"shell.erl"},{line,629}]}, + {shell,eval_loop,3,[{file,"shell.erl"},{line,614}]}]}}

    For details about the stack trace, see section Errors and Error Handling in the Erlang Reference Manual.

    Debugger emulates the stack trace by keeping track of recently called interpreted functions. (The real stack trace cannot be used, as it shows which diff --git a/prs/8803/lib/debugger-5.4/doc/html/i.html b/prs/8803/lib/debugger-5.4/doc/html/i.html index 8dcde90ff5239..33324e6c52152 100644 --- a/prs/8803/lib/debugger-5.4/doc/html/i.html +++ b/prs/8803/lib/debugger-5.4/doc/html/i.html @@ -134,9 +134,9 @@

    interpreted processes and break points.

    It is possible to attach to interpreted processes by only giving the corresponding process identity. By default, an attachment window is displayed. Processes at other Erlang nodes can be attached manually or automatically.

    The functions in this module are defined in the Erlang shell. That is, -they can be called without the i: prefix. For example:

    1> ii(t).
    -{module,t}
    -2> iaa([init]).
    +they can be called without the i: prefix. For example:

    1> ii(t).
    +{module,t}
    +2> iaa([init]).
     true
    diff --git a/prs/8803/lib/debugger-5.4/doc/html/int.html b/prs/8803/lib/debugger-5.4/doc/html/int.html index dbfbda9bbf3f7..effce50ce6e90 100644 --- a/prs/8803/lib/debugger-5.4/doc/html/int.html +++ b/prs/8803/lib/debugger-5.4/doc/html/int.html @@ -686,7 +686,7 @@

    auto_attach(Flags, Function)

    Sets when and how to attach automatically to a process executing code in interpreted modules.

    By default when the interpreter is started, automatic attach is disabled.

    If Flags is an empty list, automatic attach is disabled.

    Otherwise Flags should be a list containing at least one of the following flags:

    • init - Attach when a process for the first time calls an interpreted -function.
    • break - Attach whenever a process reaches a breakpoint.
    • exit - Attach when a process terminates.

    When the specified event occurs, the function Function is called as:

    spawn(Module, Name, [Pid | Args])

    Pid is the pid of the process executing interpreted code.

    +function.
  • break - Attach whenever a process reaches a breakpoint.
  • exit - Attach when a process terminates.
  • When the specified event occurs, the function Function is called as:

    spawn(Module, Name, [Pid | Args])

    Pid is the pid of the process executing interpreted code.

    diff --git a/prs/8803/lib/dialyzer-5.2/doc/html/dialyzer.epub b/prs/8803/lib/dialyzer-5.2/doc/html/dialyzer.epub index b0b01e6a546d2..0c1ccab954876 100644 Binary files a/prs/8803/lib/dialyzer-5.2/doc/html/dialyzer.epub and b/prs/8803/lib/dialyzer-5.2/doc/html/dialyzer.epub differ diff --git a/prs/8803/lib/dialyzer-5.2/doc/html/dialyzer.html b/prs/8803/lib/dialyzer-5.2/doc/html/dialyzer.html index cca0179f22cfa..e8d6933721a90 100644 --- a/prs/8803/lib/dialyzer-5.2/doc/html/dialyzer.html +++ b/prs/8803/lib/dialyzer-5.2/doc/html/dialyzer.html @@ -270,13 +270,13 @@

    repeating options which would otherwise need to be given explicitly to Dialyzer on every invocation.

    The location of the configuration file can be set via the DIALYZER_CONFIG environment variable, and defaults to within the user_config from -filename:basedir/3.

    An example configuration file's contents might be:

          {incremental,
    -        {default_apps,[stdlib,kernel,erts]},
    -        {default_warning_apps,[stdlib]}
    -      }.
    -      {warnings, [no_improper_lists]}.
    -      {add_pathsa,["/users/samwise/potatoes/ebin"]}.
    -      {add_pathsz,["/users/smeagol/fish/ebin"]}.

    +filename:basedir/3.

    An example configuration file's contents might be:

          {incremental,
    +        {default_apps,[stdlib,kernel,erts]},
    +        {default_warning_apps,[stdlib]}
    +      }.
    +      {warnings, [no_improper_lists]}.
    +      {add_pathsa,["/users/samwise/potatoes/ebin"]}.
    +      {add_pathsz,["/users/smeagol/fish/ebin"]}.

    @@ -284,13 +284,13 @@

    Attribute -dialyzer() can be used for turning off warnings in a module by specifying functions or warning options. For example, to turn off all warnings -for the function f/0, include the following line:

    -dialyzer({nowarn_function, f/0}).

    To turn off warnings for improper lists, add the following line to the source +for the function f/0, include the following line:

    -dialyzer({nowarn_function, f/0}).

    To turn off warnings for improper lists, add the following line to the source file:

    -dialyzer(no_improper_lists).

    Attribute -dialyzer() is allowed after function declarations. Lists of warning -options or functions are allowed:

    -dialyzer([{nowarn_function, [f/0]}, no_improper_lists]).

    Warning options can be restricted to functions:

    -dialyzer({no_improper_lists, g/0}).
    -dialyzer({[no_return, no_match], [g/0, h/0]}).

    The warning option for underspecified functions, -Wunderspecs, can result in +options or functions are allowed:

    -dialyzer([{nowarn_function, [f/0]}, no_improper_lists]).

    Warning options can be restricted to functions:

    -dialyzer({no_improper_lists, g/0}).
    -dialyzer({[no_return, no_match], [g/0, h/0]}).

    The warning option for underspecified functions, -Wunderspecs, can result in useful warnings, but often functions with specifications that are strictly more allowing than the success typing cannot easily be modified to be less allowing. To turn off the warning for underspecified function f/0, include the following -line:

    -dialyzer({no_underspecs, f/0}).

    For help on the warning options, use dialyzer -Whelp. The options are also +line:

    -dialyzer({no_underspecs, f/0}).

    For help on the warning options, use dialyzer -Whelp. The options are also enumerated, see type warn_option/0.

    Attribute -dialyzer() can also be used for turning on warnings. For example, if a module has been fixed regarding unmatched returns, adding the following line can help in assuring that no new unmatched return warnings are introduced:

    -dialyzer(unmatched_returns).
    diff --git a/prs/8803/lib/dialyzer-5.2/doc/html/dialyzer_chapter.html b/prs/8803/lib/dialyzer-5.2/doc/html/dialyzer_chapter.html index e45626182a8cf..130e3603d8303 100644 --- a/prs/8803/lib/dialyzer-5.2/doc/html/dialyzer_chapter.html +++ b/prs/8803/lib/dialyzer-5.2/doc/html/dialyzer_chapter.html @@ -209,29 +209,29 @@

    deduce). One implication of this is that if the user gives a spec for a function which overlaps with Dialyzer's inferred type, but is more restrictive, Dialyzer will trust those restrictions. This may then generate an error elsewhere that -follows from the erroneously restricted spec.

    Examples:

    Non-overlapping argument:

    -spec foo(boolean()) -> string().
    +follows from the erroneously restricted spec.

    Examples:

    Non-overlapping argument:

    -spec foo(boolean()) -> string().
     %% Dialyzer will infer: foo(integer()) -> string().
    -foo(N) ->
    -    integer_to_list(N).

    Since the type of the argument in the spec is different from the type that +foo(N) -> + integer_to_list(N).

    Since the type of the argument in the spec is different from the type that Dialyzer inferred, Dialyzer will generate the following warning:

    some_module.erl:7:2: Invalid type specification for function some_module:foo/1.
      The success typing is some_module:foo
    -          (integer()) -> string()
    +          (integer()) -> string()
      But the spec is some_module:foo
    -          (boolean()) -> string()
    - They do not overlap in the 1st argument

    Non-overlapping return:

    -spec bar(a | b) -> atom().
    +          (boolean()) -> string()
    + They do not overlap in the 1st argument

    Non-overlapping return:

    -spec bar(a | b) -> atom().
     %% Dialyzer will infer: bar(a | b) -> binary().
    -bar(a) -> <<"a">>;
    -bar(b) -> <<"b">>.

    Since the return value in the spec and the return value inferred by Dialyzer are +bar(a) -> <<"a">>; +bar(b) -> <<"b">>.

    Since the return value in the spec and the return value inferred by Dialyzer are different, Dialyzer will generate the following warning:

    some_module.erl:11:2: Invalid type specification for function some_module:bar/1.
      The success typing is some_module:bar
    -          ('a' | 'b') -> <<_:8>>
    +          ('a' | 'b') -> <<_:8>>
      But the spec is some_module:bar
    -          ('a' | 'b') -> atom()
    - The return types do not overlap

    Overlapping spec and inferred type:

    -spec baz(a | b) -> non_neg_integer().
    +          ('a' | 'b') -> atom()
    + The return types do not overlap

    Overlapping spec and inferred type:

    -spec baz(a | b) -> non_neg_integer().
     %% Dialyzer will infer: baz(b | c | d) -> -1 | 0 | 1.
    -baz(b) -> -1;
    -baz(c) -> 0;
    -baz(d) -> 1.

    Dialyzer will "trust" the spec and using the intersection of the spec and +baz(b) -> -1; +baz(c) -> 0; +baz(d) -> 1.

    Dialyzer will "trust" the spec and using the intersection of the spec and inferred type:

    baz(b) -> 0 | 1.

    Notice how the c and d from the argument to baz/1 and the -1 in the return from the inferred type were dropped once the spec and inferred type were intersected. This could result in warnings being emitted for later functions.

    For example, if baz/1 is called like this:

    call_baz1(A) ->
    diff --git a/prs/8803/lib/diameter-2.4/doc/html/diameter.epub b/prs/8803/lib/diameter-2.4/doc/html/diameter.epub
    index 66360c148f318..870f729d9fbe6 100644
    Binary files a/prs/8803/lib/diameter-2.4/doc/html/diameter.epub and b/prs/8803/lib/diameter-2.4/doc/html/diameter.epub differ
    diff --git a/prs/8803/lib/diameter-2.4/doc/html/diameter.html b/prs/8803/lib/diameter-2.4/doc/html/diameter.html
    index b4809bda67574..58de0773fef95 100644
    --- a/prs/8803/lib/diameter-2.4/doc/html/diameter.html
    +++ b/prs/8803/lib/diameter-2.4/doc/html/diameter.html
    @@ -229,14 +229,14 @@ 

    containing only 0 (NO_INBAND_SECURITY). If 1 (TLS) is specified then TLS is selected if the CER/CEA received from the peer offers it.

  • {'Acct-Application-Id', [Unsigned32()]}

  • {'Vendor-Specific-Application-Id', [Grouped()]}

  • {'Firmware-Revision',Unsigned32()}

  • Note that each tuple communicates one or more AVP values. It is an error to specify duplicate tuples.

  • eval() = {M,F,A} | fun() | [eval() | A] - An expression that can be -evaluated as a function in the following sense.

    eval([{M,F,A} | T]) ->
    -    apply(M, F, T ++ A);
    -eval([[F|A] | T]) ->
    -    eval([F | T ++ A]);
    -eval([F|A]) ->
    -    apply(F, A);
    -eval(F) ->
    -    eval([F]).

    Applying an eval() E to an argument list A is meant +evaluated as a function in the following sense.

    eval([{M,F,A} | T]) ->
    +    apply(M, F, T ++ A);
    +eval([[F|A] | T]) ->
    +    eval([F | T ++ A]);
    +eval([F|A]) ->
    +    apply(F, A);
    +eval(F) ->
    +    eval([F]).

    Applying an eval() E to an argument list A is meant in the sense of eval([E|A]).

    Warning

    Beware of using fun expressions of the form fun Name/Arity in situations in which the fun is not short-lived and code is to be upgraded at runtime since any processes retaining such a fun will have a reference to old code. @@ -279,10 +279,10 @@

    service_event() record. Can have one of the following types.

    • start

    • stop - The service is being started or stopped. No event precedes a start event. No event follows a stop event, and this event implies the -termination of all transport processes.

    • {up, Ref, Peer, Config, Pkt}

    • {up, Ref, Peer, Config}

    • {down, Ref, Peer, Config}

      Ref    = transport_ref()
      -Peer   = diameter_app:peer()
      -Config = {connect|listen, [transport_opt()]}
      -Pkt    = #diameter_packet{}

      The RFC 3539 watchdog state machine has transitioned into (up) or out of +termination of all transport processes.

    • {up, Ref, Peer, Config, Pkt}

    • {up, Ref, Peer, Config}

    • {down, Ref, Peer, Config}

      Ref    = transport_ref()
      +Peer   = diameter_app:peer()
      +Config = {connect|listen, [transport_opt()]}
      +Pkt    = #diameter_packet{}

      The RFC 3539 watchdog state machine has transitioned into (up) or out of (down) the OKAY state. If a #diameter_packet{} is present in an up event then there has been a capabilities exchange on a newly established transport connection and the record contains the received CER or CEA.

      Note that a single up or down event for a given peer corresponds to @@ -308,20 +308,20 @@

      Pkt = #diameter_packet{}

  • An incoming CER contained errors and has been answered with the indicated result code. Caps contains values for the local node only. Pkt contains the CER in question.

  • {'CER', timeout} - An expected CER was not received within -capx_timeout of connection establishment.

  • {'CEA', Result, Caps, Pkt}

    Result = ResultCode | atom() | {capabilities_cb, CB, ResultCode|discard}
    -Caps = #diameter_caps{}
    -Pkt  = #diameter_packet{}
    -ResultCode = integer()

    An incoming CEA has been rejected for the indicated reason. An +capx_timeout of connection establishment.

  • {'CEA', Result, Caps, Pkt}

    Result = ResultCode | atom() | {capabilities_cb, CB, ResultCode|discard}
    +Caps = #diameter_caps{}
    +Pkt  = #diameter_packet{}
    +ResultCode = integer()

    An incoming CEA has been rejected for the indicated reason. An integer-valued Result indicates the result code sent by the peer. Caps contains pairs of values for the local node and remote peer. Pkt contains the CEA in question. In the case of rejection by a capabilities callback, the tuple contains the rejecting callback.

  • {'CEA', Caps, Pkt}

    Caps = #diameter_caps{}
     Pkt  = #diameter_packet{}

    An incoming CEA contained errors and has been rejected. Caps contains only values for the local node. Pkt contains the CEA in question.

  • {'CEA', timeout} - An expected CEA was not received within -capx_timeout of connection establishment.

  • {watchdog, Ref, PeerRef, {From, To}, Config}

    Ref = transport_ref()
    -PeerRef = diameter_app:peer_ref()
    +capx_timeout of connection establishment.

  • {watchdog, Ref, PeerRef, {From, To}, Config}

    Ref = transport_ref()
    +PeerRef = diameter_app:peer_ref()
     From, To = initial | okay | suspect | down | reopen
    -Config = {connect|listen, [transport_opt()]}

    An RFC 3539 watchdog state machine has changed state.

  • any/0 - For forward compatibility, a subscriber should be prepared +Config = {connect|listen, [transport_opt()]}

  • An RFC 3539 watchdog state machine has changed state.

  • any/0 - For forward compatibility, a subscriber should be prepared to receive info fields of forms other than the above.

  • service_name() = term() - Name of a service as passed to start_service/2 and with which the service is identified. There can be at most one service with a given name on a given node. Note that @@ -569,10 +569,10 @@

    which a started transport process should be terminated if it has not yet established a connection. For example, the following options on a connecting transport request a connection with one peer over SCTP or another (typically -the same) over TCP.

    {transport_module, diameter_sctp}
    -{transport_config, SctpOpts, 5000}
    -{transport_module, diameter_tcp}
    -{transport_config, TcpOpts}

    To listen on both SCTP and TCP, define one transport for each.

  • {transport_module, atom()} - Module implementing +the same) over TCP.

    {transport_module, diameter_sctp}
    +{transport_config, SctpOpts, 5000}
    +{transport_module, diameter_tcp}
    +{transport_config, TcpOpts}

    To listen on both SCTP and TCP, define one transport for each.

  • {transport_module, atom()} - Module implementing a transport process as defined in diameter_transport. Defaults to diameter_tcp.

    Multiple transport_module and transport_config options are allowed. The @@ -2597,13 +2597,13 @@

    remove_transport(SvcName, Pred)

    Remove previously added transports.

    Pred determines which transports to remove. An arity-3-valued Pred removes all transports for which Pred(Ref, Type, Opts) returns true, where Type and Opts are as passed to add_transport/2 and Ref is as returned by it. -The remaining forms are equivalent to an arity-3 fun as follows.

    Pred = fun(transport_ref(), list()):  fun(Ref, _, Opts) -> Pred(Ref, Opts) end
    -Pred = fun(list()):                   fun(_, _, Opts) -> Pred(Opts) end
    -Pred = transport_ref():               fun(Ref, _, _)  -> Pred == Ref end
    -Pred = list():                        fun(_, _, Opts) -> [] == Pred -- Opts end
    -Pred = true:                          fun(_, _, _) -> true end
    -Pred = false:                         fun(_, _, _) -> false end
    -Pred = {M,F,A}:  fun(Ref, Type, Opts) -> apply(M, F, [Ref, Type, Opts | A]) end

    Removing a transport causes the corresponding transport processes to be +The remaining forms are equivalent to an arity-3 fun as follows.

    Pred = fun(transport_ref(), list()):  fun(Ref, _, Opts) -> Pred(Ref, Opts) end
    +Pred = fun(list()):                   fun(_, _, Opts) -> Pred(Opts) end
    +Pred = transport_ref():               fun(Ref, _, _)  -> Pred == Ref end
    +Pred = list():                        fun(_, _, Opts) -> [] == Pred -- Opts end
    +Pred = true:                          fun(_, _, _) -> true end
    +Pred = false:                         fun(_, _, _) -> false end
    +Pred = {M,F,A}:  fun(Ref, Type, Opts) -> apply(M, F, [Ref, Type, Opts | A]) end

    Removing a transport causes the corresponding transport processes to be terminated. Whether or not a DPR message is sent to a peer is controlled by value of disconnect_cb configured on the transport.

    @@ -2647,52 +2647,52 @@

    service_info(SvcName, Option)

    containing both configuration and information about established peer connections. An example return value with for a client service with Origin-Host "client.example.com" configured with a single transport connected -to "server.example.com" might look as follows.

    [[{ref,#Ref<0.0.0.93>},
    -  {type,connect},
    -  {options,[{transport_module,diameter_tcp},
    -            {transport_config,[{ip,{127,0,0,1}},
    -                               {raddr,{127,0,0,1}},
    -                               {rport,3868},
    -                               {reuseaddr,true}]}]},
    -  {watchdog,{<0.66.0>,-576460736368485571,okay}},
    -  {peer,{<0.67.0>,-576460736357885808}},
    -  {apps,[{0,common}]},
    -  {caps,[{origin_host,{"client.example.com","server.example.com"}},
    -         {origin_realm,{"example.com","example.com"}},
    -         {host_ip_address,{[{127,0,0,1}],[{127,0,0,1}]}},
    -         {vendor_id,{0,193}},
    -         {product_name,{"Client","Server"}},
    -         {origin_state_id,{[],[]}},
    -         {supported_vendor_id,{[],[]}},
    -         {auth_application_id,{[0],[0]}},
    -         {inband_security_id,{[],[0]}},
    -         {acct_application_id,{[],[]}},
    -         {vendor_specific_application_id,{[],[]}},
    -         {firmware_revision,{[],[]}},
    -         {avp,{[],[]}}]},
    -  {port,[{owner,<0.69.0>},
    -         {module,diameter_tcp},
    -         {socket,{{127,0,0,1},48758}},
    -         {peer,{{127,0,0,1},3868}},
    -         {statistics,[{recv_oct,656},
    -                      {recv_cnt,6},
    -                      {recv_max,148},
    -                      {recv_avg,109},
    -                      {recv_dvi,19},
    -                      {send_oct,836},
    -                      {send_cnt,6},
    -                      {send_max,184},
    -                      {send_avg,139},
    -                      {send_pend,0}]}]},
    -  {statistics,[{{{0,258,0},recv},3},
    -               {{{0,258,1},send},3},
    -               {{{0,258,0},recv,{'Result-Code',2001}},3},
    -               {{{0,257,0},recv},1},
    -               {{{0,257,1},send},1},
    -               {{{0,257,0},recv,{'Result-Code',2001}},1},
    -               {{{0,280,1},recv},2},
    -               {{{0,280,0},send},2},
    -               {{{0,280,0},send,{'Result-Code',2001}},2}]}]]

    Here ref is a transport_ref() and options +to "server.example.com" might look as follows.

    [[{ref,#Ref<0.0.0.93>},
    +  {type,connect},
    +  {options,[{transport_module,diameter_tcp},
    +            {transport_config,[{ip,{127,0,0,1}},
    +                               {raddr,{127,0,0,1}},
    +                               {rport,3868},
    +                               {reuseaddr,true}]}]},
    +  {watchdog,{<0.66.0>,-576460736368485571,okay}},
    +  {peer,{<0.67.0>,-576460736357885808}},
    +  {apps,[{0,common}]},
    +  {caps,[{origin_host,{"client.example.com","server.example.com"}},
    +         {origin_realm,{"example.com","example.com"}},
    +         {host_ip_address,{[{127,0,0,1}],[{127,0,0,1}]}},
    +         {vendor_id,{0,193}},
    +         {product_name,{"Client","Server"}},
    +         {origin_state_id,{[],[]}},
    +         {supported_vendor_id,{[],[]}},
    +         {auth_application_id,{[0],[0]}},
    +         {inband_security_id,{[],[0]}},
    +         {acct_application_id,{[],[]}},
    +         {vendor_specific_application_id,{[],[]}},
    +         {firmware_revision,{[],[]}},
    +         {avp,{[],[]}}]},
    +  {port,[{owner,<0.69.0>},
    +         {module,diameter_tcp},
    +         {socket,{{127,0,0,1},48758}},
    +         {peer,{{127,0,0,1},3868}},
    +         {statistics,[{recv_oct,656},
    +                      {recv_cnt,6},
    +                      {recv_max,148},
    +                      {recv_avg,109},
    +                      {recv_dvi,19},
    +                      {send_oct,836},
    +                      {send_cnt,6},
    +                      {send_max,184},
    +                      {send_avg,139},
    +                      {send_pend,0}]}]},
    +  {statistics,[{{{0,258,0},recv},3},
    +               {{{0,258,1},send},3},
    +               {{{0,258,0},recv,{'Result-Code',2001}},3},
    +               {{{0,257,0},recv},1},
    +               {{{0,257,1},send},1},
    +               {{{0,257,0},recv,{'Result-Code',2001}},1},
    +               {{{0,280,1},recv},2},
    +               {{{0,280,0},send},2},
    +               {{{0,280,0},send,{'Result-Code',2001}},2}]}]]

    Here ref is a transport_ref() and options the corresponding transport_opt() list passed to add_transport/2. The watchdog entry shows the state of a connection's RFC 3539 watchdog state machine. The peer entry identifies the @@ -2711,55 +2711,55 @@

    service_info(SvcName, Option)

    transport configuration.

    A listening transport presents its information slightly differently since there may be multiple accepted connections for the same transport_ref(). The transport info returned -by a server with a single client connection might look as follows.

    [[{ref,#Ref<0.0.0.61>},
    -  {type,listen},
    -  {options,[{transport_module,diameter_tcp},
    -            {transport_config,[{reuseaddr,true},
    -                               {ip,{127,0,0,1}},
    -                               {port,3868}]}]},
    -  {accept,[[{watchdog,{<0.56.0>,-576460739249514012,okay}},
    -            {peer,{<0.58.0>,-576460638229179167}},
    -            {apps,[{0,common}]},
    -            {caps,[{origin_host,{"server.example.com","client.example.com"}},
    -                   {origin_realm,{"example.com","example.com"}},
    -                   {host_ip_address,{[{127,0,0,1}],[{127,0,0,1}]}},
    -                   {vendor_id,{193,0}},
    -                   {product_name,{"Server","Client"}},
    -                   {origin_state_id,{[],[]}},
    -                   {supported_vendor_id,{[],[]}},
    -                   {auth_application_id,{[0],[0]}},
    -                   {inband_security_id,{[],[]}},
    -                   {acct_application_id,{[],[]}},
    -                   {vendor_specific_application_id,{[],[]}},
    -                   {firmware_revision,{[],[]}},
    -                   {avp,{[],[]}}]},
    -            {port,[{owner,<0.62.0>},
    -                   {module,diameter_tcp},
    -                   {socket,{{127,0,0,1},3868}},
    -                   {peer,{{127,0,0,1},48758}},
    -                   {statistics,[{recv_oct,1576},
    -                                {recv_cnt,16},
    -                                {recv_max,184},
    -                                {recv_avg,98},
    -                                {recv_dvi,26},
    -                                {send_oct,1396},
    -                                {send_cnt,16},
    -                                {send_max,148},
    -                                {send_avg,87},
    -                                {send_pend,0}]}]}],
    -           [{watchdog,{<0.72.0>,-576460638229717546,initial}}]]},
    -  {statistics,[{{{0,280,0},recv},7},
    -               {{{0,280,1},send},7},
    -               {{{0,280,0},recv,{'Result-Code',2001}},7},
    -               {{{0,258,1},recv},3},
    -               {{{0,258,0},send},3},
    -               {{{0,258,0},send,{'Result-Code',2001}},3},
    -               {{{0,280,1},recv},5},
    -               {{{0,280,0},send},5},
    -               {{{0,280,0},send,{'Result-Code',2001}},5},
    -               {{{0,257,1},recv},1},
    -               {{{0,257,0},send},1},
    -               {{{0,257,0},send,{'Result-Code',2001}},1}]}]]

    The information presented here is as in the connect case except that the +by a server with a single client connection might look as follows.

    [[{ref,#Ref<0.0.0.61>},
    +  {type,listen},
    +  {options,[{transport_module,diameter_tcp},
    +            {transport_config,[{reuseaddr,true},
    +                               {ip,{127,0,0,1}},
    +                               {port,3868}]}]},
    +  {accept,[[{watchdog,{<0.56.0>,-576460739249514012,okay}},
    +            {peer,{<0.58.0>,-576460638229179167}},
    +            {apps,[{0,common}]},
    +            {caps,[{origin_host,{"server.example.com","client.example.com"}},
    +                   {origin_realm,{"example.com","example.com"}},
    +                   {host_ip_address,{[{127,0,0,1}],[{127,0,0,1}]}},
    +                   {vendor_id,{193,0}},
    +                   {product_name,{"Server","Client"}},
    +                   {origin_state_id,{[],[]}},
    +                   {supported_vendor_id,{[],[]}},
    +                   {auth_application_id,{[0],[0]}},
    +                   {inband_security_id,{[],[]}},
    +                   {acct_application_id,{[],[]}},
    +                   {vendor_specific_application_id,{[],[]}},
    +                   {firmware_revision,{[],[]}},
    +                   {avp,{[],[]}}]},
    +            {port,[{owner,<0.62.0>},
    +                   {module,diameter_tcp},
    +                   {socket,{{127,0,0,1},3868}},
    +                   {peer,{{127,0,0,1},48758}},
    +                   {statistics,[{recv_oct,1576},
    +                                {recv_cnt,16},
    +                                {recv_max,184},
    +                                {recv_avg,98},
    +                                {recv_dvi,26},
    +                                {send_oct,1396},
    +                                {send_cnt,16},
    +                                {send_max,148},
    +                                {send_avg,87},
    +                                {send_pend,0}]}]}],
    +           [{watchdog,{<0.72.0>,-576460638229717546,initial}}]]},
    +  {statistics,[{{{0,280,0},recv},7},
    +               {{{0,280,1},send},7},
    +               {{{0,280,0},recv,{'Result-Code',2001}},7},
    +               {{{0,258,1},recv},3},
    +               {{{0,258,0},send},3},
    +               {{{0,258,0},send,{'Result-Code',2001}},3},
    +               {{{0,280,1},recv},5},
    +               {{{0,280,0},send},5},
    +               {{{0,280,0},send,{'Result-Code',2001}},5},
    +               {{{0,257,1},recv},1},
    +               {{{0,257,0},send},1},
    +               {{{0,257,0},send,{'Result-Code',2001}},1}]}]]

    The information presented here is as in the connect case except that the client connections are grouped under an accept tuple.

    Whether or not the transport_opt() pool_size has been configured affects the format of the listing in the case of a connecting transport, since a value greater than 1 implies multiple transport @@ -2770,54 +2770,54 @@

    service_info(SvcName, Option)

    This is a flat view of transport info which lists only active connections and for which Diameter-level statistics are accumulated only for the lifetime of the transport connection. A return value for the server above might look as -follows.

    [[{ref,#Ref<0.0.0.61>},
    -  {type,accept},
    -  {options,[{transport_module,diameter_tcp},
    -            {transport_config,[{reuseaddr,true},
    -                               {ip,{127,0,0,1}},
    -                               {port,3868}]}]},
    -  {watchdog,{<0.56.0>,-576460739249514012,okay}},
    -  {peer,{<0.58.0>,-576460638229179167}},
    -  {apps,[{0,common}]},
    -  {caps,[{origin_host,{"server.example.com","client.example.com"}},
    -         {origin_realm,{"example.com","example.com"}},
    -         {host_ip_address,{[{127,0,0,1}],[{127,0,0,1}]}},
    -         {vendor_id,{193,0}},
    -         {product_name,{"Server","Client"}},
    -         {origin_state_id,{[],[]}},
    -         {supported_vendor_id,{[],[]}},
    -         {auth_application_id,{[0],[0]}},
    -         {inband_security_id,{[],[]}},
    -         {acct_application_id,{[],[]}},
    -         {vendor_specific_application_id,{[],[]}},
    -         {firmware_revision,{[],[]}},
    -         {avp,{[],[]}}]},
    -  {port,[{owner,<0.62.0>},
    -         {module,diameter_tcp},
    -         {socket,{{127,0,0,1},3868}},
    -         {peer,{{127,0,0,1},48758}},
    -         {statistics,[{recv_oct,10124},
    -                      {recv_cnt,132},
    -                      {recv_max,184},
    -                      {recv_avg,76},
    -                      {recv_dvi,9},
    -                      {send_oct,10016},
    -                      {send_cnt,132},
    -                      {send_max,148},
    -                      {send_avg,75},
    -                      {send_pend,0}]}]},
    -  {statistics,[{{{0,280,0},recv},62},
    -               {{{0,280,1},send},62},
    -               {{{0,280,0},recv,{'Result-Code',2001}},62},
    -               {{{0,258,1},recv},3},
    -               {{{0,258,0},send},3},
    -               {{{0,258,0},send,{'Result-Code',2001}},3},
    -               {{{0,280,1},recv},66},
    -               {{{0,280,0},send},66},
    -               {{{0,280,0},send,{'Result-Code',2001}},66},
    -               {{{0,257,1},recv},1},
    -               {{{0,257,0},send},1},
    -               {{{0,257,0},send,{'Result-Code',2001}},1}]}]]

    Note that there may be multiple entries with the same ref, in contrast to +follows.

    [[{ref,#Ref<0.0.0.61>},
    +  {type,accept},
    +  {options,[{transport_module,diameter_tcp},
    +            {transport_config,[{reuseaddr,true},
    +                               {ip,{127,0,0,1}},
    +                               {port,3868}]}]},
    +  {watchdog,{<0.56.0>,-576460739249514012,okay}},
    +  {peer,{<0.58.0>,-576460638229179167}},
    +  {apps,[{0,common}]},
    +  {caps,[{origin_host,{"server.example.com","client.example.com"}},
    +         {origin_realm,{"example.com","example.com"}},
    +         {host_ip_address,{[{127,0,0,1}],[{127,0,0,1}]}},
    +         {vendor_id,{193,0}},
    +         {product_name,{"Server","Client"}},
    +         {origin_state_id,{[],[]}},
    +         {supported_vendor_id,{[],[]}},
    +         {auth_application_id,{[0],[0]}},
    +         {inband_security_id,{[],[]}},
    +         {acct_application_id,{[],[]}},
    +         {vendor_specific_application_id,{[],[]}},
    +         {firmware_revision,{[],[]}},
    +         {avp,{[],[]}}]},
    +  {port,[{owner,<0.62.0>},
    +         {module,diameter_tcp},
    +         {socket,{{127,0,0,1},3868}},
    +         {peer,{{127,0,0,1},48758}},
    +         {statistics,[{recv_oct,10124},
    +                      {recv_cnt,132},
    +                      {recv_max,184},
    +                      {recv_avg,76},
    +                      {recv_dvi,9},
    +                      {send_oct,10016},
    +                      {send_cnt,132},
    +                      {send_max,148},
    +                      {send_avg,75},
    +                      {send_pend,0}]}]},
    +  {statistics,[{{{0,280,0},recv},62},
    +               {{{0,280,1},send},62},
    +               {{{0,280,0},recv,{'Result-Code',2001}},62},
    +               {{{0,258,1},recv},3},
    +               {{{0,258,0},send},3},
    +               {{{0,258,0},send,{'Result-Code',2001}},3},
    +               {{{0,280,1},recv},66},
    +               {{{0,280,0},send},66},
    +               {{{0,280,0},send,{'Result-Code',2001}},66},
    +               {{{0,257,1},recv},1},
    +               {{{0,257,0},send},1},
    +               {{{0,257,0},send,{'Result-Code',2001}},1}]}]]

    Note that there may be multiple entries with the same ref, in contrast to transport info.

  • statistics - Return a {{Counter, Ref}, non_neg_integer()} list of counter values. Ref can be either a transport_ref() or a @@ -2829,12 +2829,12 @@

    service_info(SvcName, Option)

    configuration associated with a single peer, as passed to add_transport/2. The returned list is empty if the peer is unknown. Otherwise it contains the ref, type and options tuples as in transport and connections info -above. For example:

    [{ref,#Ref<0.0.0.61>},
    - {type,accept},
    - {options,[{transport_module,diameter_tcp},
    -           {transport_config,[{reuseaddr,true},
    -                              {ip,{127,0,0,1}},
    -                              {port,3868}]}]}]
  • +above. For example:

    [{ref,#Ref<0.0.0.61>},
    + {type,accept},
    + {options,[{transport_module,diameter_tcp},
    +           {transport_config,[{reuseaddr,true},
    +                              {ip,{127,0,0,1}},
    +                              {port,3868}]}]}]
    diff --git a/prs/8803/lib/diameter-2.4/doc/html/diameter_app.html b/prs/8803/lib/diameter-2.4/doc/html/diameter_app.html index c706374d337a8..8d192dfc2a4a8 100644 --- a/prs/8803/lib/diameter-2.4/doc/html/diameter_app.html +++ b/prs/8803/lib/diameter-2.4/doc/html/diameter_app.html @@ -719,12 +719,12 @@

    handle_request(Packet, SvcName, Peer)

    diameter:start_service/2) is determined by the Application Identifier in the header of the incoming request message, the selected module being the one whose corresponding dictionary declares itself as defining either the application in -question or the Relay application.

    The argument packet() has the following signature.

    #diameter_packet{header = #diameter_header{},
    -                 avps   = [#diameter_avp{}],
    -                 msg    = record() | undefined,
    -                 errors = [Unsigned32() | {Unsigned32(), #diameter_avp{}}],
    -                 bin    = binary(),
    -                 transport_data = term()}

    The msg field will be undefined in case the request has been received in the +question or the Relay application.

    The argument packet() has the following signature.

    #diameter_packet{header = #diameter_header{},
    +                 avps   = [#diameter_avp{}],
    +                 msg    = record() | undefined,
    +                 errors = [Unsigned32() | {Unsigned32(), #diameter_avp{}}],
    +                 bin    = binary(),
    +                 transport_data = term()}

    The msg field will be undefined in case the request has been received in the relay application. Otherwise it contains the record representing the request as outlined in diameter_dict(4).

    The errors field specifies any results codes identifying errors found while decoding the request. This is used to set Result-Code and/or Failed-AVP in a diff --git a/prs/8803/lib/diameter-2.4/doc/html/diameter_codec.html b/prs/8803/lib/diameter-2.4/doc/html/diameter_codec.html index 43ef5f01ae216..2a1beca9640b8 100644 --- a/prs/8803/lib/diameter-2.4/doc/html/diameter_codec.html +++ b/prs/8803/lib/diameter-2.4/doc/html/diameter_codec.html @@ -139,7 +139,7 @@

    results may differ from those returned by the functions documented here, depending on configuration.

    The header() and packet() records below are defined in diameter.hrl, -which can be included as follows.

    -include_lib("diameter/include/diameter.hrl").

    Application-specific records are defined in the hrl files resulting from +which can be included as follows.

    -include_lib("diameter/include/diameter.hrl").

    Application-specific records are defined in the hrl files resulting from dictionary file compilation.

    diff --git a/prs/8803/lib/diameter-2.4/doc/html/diameter_dict.html b/prs/8803/lib/diameter-2.4/doc/html/diameter_dict.html index 76c8eaadbe84b..ed430b3935047 100644 --- a/prs/8803/lib/diameter-2.4/doc/html/diameter_dict.html +++ b/prs/8803/lib/diameter-2.4/doc/html/diameter_dict.html @@ -309,14 +309,14 @@

    an incoming request.

    In cases in which there is a choice between string() and binary() types for OctetString() and derived types, the representation is determined by the value of diameter:service_opt() -string_decode.

    Basic AVP Data Formats

    OctetString() = string() | binary()
    -Integer32()   = -2147483647..2147483647
    -Integer64()   = -9223372036854775807..9223372036854775807
    -Unsigned32()  = 0..4294967295
    -Unsigned64()  = 0..18446744073709551615
    -Float32()     = '-infinity' | float() | infinity
    -Float64()     = '-infinity' | float() | infinity
    -Grouped()     = record()

    On encode, an OctetString() can be specified as an iolist(), excessively large +string_decode.

    Basic AVP Data Formats

    OctetString() = string() | binary()
    +Integer32()   = -2147483647..2147483647
    +Integer64()   = -9223372036854775807..9223372036854775807
    +Unsigned32()  = 0..4294967295
    +Unsigned64()  = 0..18446744073709551615
    +Float32()     = '-infinity' | float() | infinity
    +Float64()     = '-infinity' | float() | infinity
    +Grouped()     = record()

    On encode, an OctetString() can be specified as an iolist(), excessively large floats (in absolute value) are equivalent to infinity or '-infinity' and excessively large integers result in encode failure. The records for grouped AVPs are as discussed in the previous section.

    Derived AVP Data Formats

    Address() = OctetString()
    @@ -324,14 +324,14 @@ 

    while an IPv6 address is parsed in any of the formats specified by section 2.2 of RFC 2373, "Text Representation of Addresses". An IPv4 tuple() has length 4 and contains values of type 0..255. An IPv6 tuple() has length 8 and contains -values of type 0..65535. The tuple representation is used on decode.

    Time() = {date(), time()}
    +values of type 0..65535. The tuple representation is used on decode.

    Time() = {date(), time()}
     
     where
     
    -  date() = {Year, Month, Day}
    -  time() = {Hour, Minute, Second}
    +  date() = {Year, Month, Day}
    +  time() = {Hour, Minute, Second}
     
    -  Year   = integer()
    +  Year   = integer()
       Month  = 1..12
       Day    = 1..31
       Hour   = 0..23
    @@ -359,8 +359,8 @@ 

    diameter respectively. The grammar of an OctetString-valued DiameterURI() is as specified in section 4.3 of RFC 6733. The record representation is used on decode.

    Enumerated() = Integer32()

    On encode, values can be specified using the macros defined in a dictionary's -hrl file.

    IPFilterRule()  = OctetString()
    -QoSFilterRule() = OctetString()

    Values of these types are not currently parsed by diameter.

    +hrl file.

    IPFilterRule()  = OctetString()
    +QoSFilterRule() = OctetString()

    Values of these types are not currently parsed by diameter.

    diff --git a/prs/8803/lib/diameter-2.4/doc/html/diameterc_cmd.html b/prs/8803/lib/diameter-2.4/doc/html/diameterc_cmd.html index d1a3807666a2b..3a8f23d812352 100644 --- a/prs/8803/lib/diameter-2.4/doc/html/diameterc_cmd.html +++ b/prs/8803/lib/diameter-2.4/doc/html/diameterc_cmd.html @@ -131,7 +131,7 @@

    Synopsis

    -
    diameterc [<options>] <file>

    +
    diameterc [<options>] <file>

    diff --git a/prs/8803/lib/edoc-1.3.1/doc/html/edoc_doclet_markdown.html b/prs/8803/lib/edoc-1.3.1/doc/html/edoc_doclet_markdown.html index 82749c42b0c22..a43de1ae77ac2 100644 --- a/prs/8803/lib/edoc-1.3.1/doc/html/edoc_doclet_markdown.html +++ b/prs/8803/lib/edoc-1.3.1/doc/html/edoc_doclet_markdown.html @@ -128,8 +128,8 @@

    -

    Doclet converting an edoc application to use EEP-59 and Markdown.

    This doclet has to be used together with edoc_layout_chunks.

    Example:

     1> edoc:application(example, [{preprocess, true}, {doclet, edoc_doclet_markdown},
    -       {layout, edoc_layout_chunks}]).

    It will convert the overview to Markdown and any module documentation to use -doc attributes and Markdown. Any XHTML tags in the edoc documentation that are not part of the tags supported by Erlang Documentation Format will be added as HTML tags in the Markdown.

    It does not delete the old edoc documentation.

    See also: edoc_layout_chunks.

    +

    Doclet converting an edoc application to use EEP-59 and Markdown.

    This doclet has to be used together with edoc_layout_chunks.

    Example:

     1> edoc:application(example, [{preprocess, true}, {doclet, edoc_doclet_markdown},
    +       {layout, edoc_layout_chunks}]).

    It will convert the overview to Markdown and any module documentation to use -doc attributes and Markdown. Any XHTML tags in the edoc documentation that are not part of the tags supported by Erlang Documentation Format will be added as HTML tags in the Markdown.

    It does not delete the old edoc documentation.

    See also: edoc_layout_chunks.

    diff --git a/prs/8803/lib/eldap-1.2.13/doc/html/eldap.epub b/prs/8803/lib/eldap-1.2.13/doc/html/eldap.epub index fa5e55667bbfe..ee4b0e362c34d 100644 Binary files a/prs/8803/lib/eldap-1.2.13/doc/html/eldap.epub and b/prs/8803/lib/eldap-1.2.13/doc/html/eldap.epub differ diff --git a/prs/8803/lib/eldap-1.2.13/doc/html/eldap.html b/prs/8803/lib/eldap-1.2.13/doc/html/eldap.html index 21c0fa381e18c..091c715c9947d 100644 --- a/prs/8803/lib/eldap-1.2.13/doc/html/eldap.html +++ b/prs/8803/lib/eldap-1.2.13/doc/html/eldap.html @@ -977,13 +977,13 @@

    add(Handle, Dn, Attributes)

    -

    Add an entry. The entry must not exist.

      add(Handle,
    +

    Add an entry. The entry must not exist.

      add(Handle,
           "cn=Bill Valentine, ou=people, o=Example Org, dc=example, dc=com",
    -       [{"objectclass", ["person"]},
    -        {"cn", ["Bill Valentine"]},
    -        {"sn", ["Valentine"]},
    -        {"telephoneNumber", ["545 555 00"]}]
    -     )
    +
    [{"objectclass", ["person"]}, + {"cn", ["Bill Valentine"]}, + {"sn", ["Valentine"]}, + {"telephoneNumber", ["545 555 00"]}] + )
    @@ -1295,7 +1295,7 @@

    extensibleMatch(MatchValue, OptionalAttrs)< -

    Creates an extensible match filter. For example,

      eldap:extensibleMatch("Bar", [{type,"sn"}, {matchingRule,"caseExactMatch"}]))

    creates a filter which performs a caseExactMatch on the attribute sn and +

    Creates an extensible match filter. For example,

      eldap:extensibleMatch("Bar", [{type,"sn"}, {matchingRule,"caseExactMatch"}]))

    creates a filter which performs a caseExactMatch on the attribute sn and matches with the value "Bar". The default value of dnAttributes is false.

    @@ -1513,9 +1513,9 @@

    modify(Handle, Dn, ModifyOps)

    -

    Modify an entry.

      modify(Handle, "cn=Bill Valentine, ou=people, o=Example Org, dc=example, dc=com",
    -         [eldap:mod_replace("telephoneNumber", ["555 555 00"]),
    -	  eldap:mod_add("description", ["LDAP Hacker"]) ])
    +

    Modify an entry.

      modify(Handle, "cn=Bill Valentine, ou=people, o=Example Org, dc=example, dc=com",
    +         [eldap:mod_replace("telephoneNumber", ["555 555 00"]),
    +	  eldap:mod_add("description", ["LDAP Hacker"]) ])
    @@ -1836,8 +1836,8 @@

    paged_result_control(PageSize)

    paged_result_control(PageSize) -> {control, "1.2.840.113556.1.4.319", true, binary()}

    Paged results is an extension to the LDAP protocol specified by RFC2696

    This function creates a control with the specified page size for use in -search/3, for example:

    Control = eldap:paged_result_control(50),
    -{ok, SearchResults} = search(Handle, [{base, "dc=example, dc=com"}], [Control]),
    +search/3, for example:

    Control = eldap:paged_result_control(50),
    +{ok, SearchResults} = search(Handle, [{base, "dc=example, dc=com"}], [Control]),
    @@ -1871,12 +1871,12 @@

    paged_result_control(PageSize, Cookie)

    paged_result_control(PageSize, Cookie) -> {control, "1.2.840.113556.1.4.319", true, binary()}

    Paged results is an extension to the LDAP protocol specified by RFC2696

    This function creates a control with the specified page size and cookie for use in search/3 to retrieve the next results page.

    For example:

    PageSize = 50,
    -Control1 = eldap:paged_result_control(PageSize),
    -{ok, SearchResults1} = search(Handle, [{base, "dc=example, dc=com"}], [Control1]),
    +Control1 = eldap:paged_result_control(PageSize),
    +{ok, SearchResults1} = search(Handle, [{base, "dc=example, dc=com"}], [Control1]),
     %% retrieve the returned cookie from the search results
    -{ok, Cookie1} = eldap:paged_result_cookie(SearchResults1),
    -Control2 = eldap:paged_result_control(PageSize, Cookie1),
    -{ok, SearchResults2} = eldap:search(Handle, [{base, "dc=example,dc=com"}], [Control2]),
    +{ok, Cookie1} = eldap:paged_result_cookie(SearchResults1),
    +Control2 = eldap:paged_result_control(PageSize, Cookie1),
    +{ok, SearchResults2} = eldap:search(Handle, [{base, "dc=example,dc=com"}], [Control2]),
     %% etc
    @@ -1996,8 +1996,8 @@

    search(Handle, SearchOptions)

    Search the directory with the supplied the SearchOptions.

    The base and filter options must be supplied. Default values: scope is wholeSubtree/0, deref is -derefAlways/0, types_only is false and timeout is 0 (meaning infinity).

      Filter = eldap:substrings("cn", [{any,"V"}]),
    -  search(Handle, [{base, "dc=example, dc=com"}, {filter, Filter}, {attributes, ["cn"]}]),

    The timeout option in the SearchOptions is for the ldap server, while the +derefAlways/0, types_only is false and timeout is 0 (meaning infinity).

      Filter = eldap:substrings("cn", [{any,"V"}]),
    +  search(Handle, [{base, "dc=example, dc=com"}, {filter, Filter}, {attributes, ["cn"]}]),

    The timeout option in the SearchOptions is for the ldap server, while the timeout in eldap:open/2 is used for each individual request in the search operation.

    diff --git a/prs/8803/lib/erl_interface-5.5.2/doc/html/ei.html b/prs/8803/lib/erl_interface-5.5.2/doc/html/ei.html index 98d77adb039e5..8e1f0c2e10bf8 100644 --- a/prs/8803/lib/erl_interface-5.5.2/doc/html/ei.html +++ b/prs/8803/lib/erl_interface-5.5.2/doc/html/ei.html @@ -151,30 +151,30 @@

    Data Types

    -
    • ei_term

      typedef struct {
      +
      • ei_term

        typedef struct {
             char ei_type;
             int arity;
             int size;
        -    union {
        +    union {
           long i_val;
           double d_val;
        -  char atom_name[MAXATOMLEN_UTF8];
        +  char atom_name[MAXATOMLEN_UTF8];
           erlang_pid pid;
           erlang_port port;
           erlang_ref ref;
        -    } value;
        -} ei_term;

        Structure written by ei_decode_ei_term(). The + } value; +} ei_term;

      Structure written by ei_decode_ei_term(). The ei_type field is the type of the term which equals to what ei_get_type() sets *type to.

    • ei_x_buff - A dynamically resized buffer. It is a struct with two fields of interest for the user:

      • char *buff - Pointer to the dynamically allocated buffer.

      • int index - Offset to the next byte to write which also equals the amount of bytes currently written.

      An ei_x_buff is initialized by calling either ei_x_new() or ei_x_new_with_version(). The memory used by an initialized ei_x_buff is released by calling -ei_x_free().

    • erlang_char_encoding

      typedef enum {
      +ei_x_free().

    • erlang_char_encoding

      typedef enum {
           ERLANG_ASCII = 1,
           ERLANG_LATIN1 = 2,
           ERLANG_UTF8 = 4
      -} erlang_char_encoding;

      The character encodings used for atoms. ERLANG_ASCII represents 7-bit ASCII. +} erlang_char_encoding;

    The character encodings used for atoms. ERLANG_ASCII represents 7-bit ASCII. Latin-1 and UTF-8 are different extensions of 7-bit ASCII. All 7-bit ASCII characters are valid Latin-1 and UTF-8 characters. ASCII and Latin-1 both represent each character by one byte. An UTF-8 character can consist of 1-4 @@ -190,7 +190,7 @@

    ei_cmp_pids()

    -
    int ei_cmp_pids(erlang_pid *a, erlang_pid *b);

    Compare two process identifiers. The comparison is done the same way as Erlang +

    int ei_cmp_pids(erlang_pid *a, erlang_pid *b);

    Compare two process identifiers. The comparison is done the same way as Erlang does.

    Returns 0 if a and b are equal. Returns a value less than 0 if a compares as less than b. Returns a value larger than 0 if a compares as larger than b.

    Available since OTP 23.0

    @@ -199,7 +199,7 @@

    ei_cmp_ports()

    -
    int ei_cmp_ports(erlang_port *a, erlang_port *b);

    Compare two port identifiers. The comparison is done the same way as Erlang +

    int ei_cmp_ports(erlang_port *a, erlang_port *b);

    Compare two port identifiers. The comparison is done the same way as Erlang does.

    Returns 0 if a and b are equal. Returns a value less than 0 if a compares as less than b. Returns a value larger than 0 if a compares as larger than b.

    Available since OTP 23.0

    @@ -208,7 +208,7 @@

    ei_cmp_refs()

    -
    int ei_cmp_refs(erlang_ref *a, erlang_ref *b);

    Compare two references. The comparison is done the same way as Erlang does.

    Returns 0 if a and b are equal. Returns a value less than 0 if a +

    int ei_cmp_refs(erlang_ref *a, erlang_ref *b);

    Compare two references. The comparison is done the same way as Erlang does.

    Returns 0 if a and b are equal. Returns a value less than 0 if a compares as less than b. Returns a value larger than 0 if a compares as larger than b.

    Available since OTP 23.0

    @@ -216,15 +216,15 @@

    ei_decode_atom()

    -
    int ei_decode_atom(const char *buf, int *index, char *p);

    Decodes an atom from the binary format. The NULL-terminated name of the atom +

    int ei_decode_atom(const char *buf, int *index, char *p);

    Decodes an atom from the binary format. The NULL-terminated name of the atom is placed at p. At most MAXATOMLEN bytes can be placed in the buffer.

    ei_decode_atom_as()

    -
    int ei_decode_atom_as(const char *buf, int *index, char *p, int plen,
    -  erlang_char_encoding want, erlang_char_encoding* was, erlang_char_encoding* result);

    Decodes an atom from the binary format. The NULL-terminated name of the atom +

    int ei_decode_atom_as(const char *buf, int *index, char *p, int plen,
    +  erlang_char_encoding want, erlang_char_encoding* was, erlang_char_encoding* result);

    Decodes an atom from the binary format. The NULL-terminated name of the atom is placed in buffer at p of length plen bytes.

    The wanted string encoding is specified by want. The original encoding used in the binary format (Latin-1 or UTF-8) can be obtained from *was. The encoding of the resulting string (7-bit ASCII, @@ -239,7 +239,7 @@

    ei_decode_bignum()

    -
    int ei_decode_bignum(const char *buf, int *index, mpz_t obj);

    Decodes an integer in the binary format to a GMP mpz_t integer. To use this +

    int ei_decode_bignum(const char *buf, int *index, mpz_t obj);

    Decodes an integer in the binary format to a GMP mpz_t integer. To use this function, the ei library must be configured and compiled to use the GMP library.

    @@ -247,7 +247,7 @@

    ei_decode_binary()

    -
    int ei_decode_binary(const char *buf, int *index, void *p, long *len);

    Decodes a binary from the binary format. Parameter len is set to the actual +

    int ei_decode_binary(const char *buf, int *index, void *p, long *len);

    Decodes a binary from the binary format. Parameter len is set to the actual size of the binary. Notice that ei_decode_binary() assumes that there is enough room for the binary. The size required can be fetched by ei_get_type().

    @@ -256,8 +256,8 @@

    ei_decode_bitstring()

    -
    int ei_decode_bitstring(const char *buf, int *index, const char **pp,
    -  unsigned int *bitoffsp, size_t *nbitsp);

    Decodes a bit string from the binary format.

    • pp - Either NULL or *pp returns a pointer to the first byte of the +

      int ei_decode_bitstring(const char *buf, int *index, const char **pp,
      +  unsigned int *bitoffsp, size_t *nbitsp);

      Decodes a bit string from the binary format.

      • pp - Either NULL or *pp returns a pointer to the first byte of the bit string. The returned bit string is readable as long as the buffer pointed to by buf is readable and not written to.

      • bitoffsp - Either NULL or *bitoffsp returns the number of unused bits in the first byte pointed to by *pp. The value of *bitoffsp is @@ -273,14 +273,14 @@

        ei_decode_boolean()

        -
        int ei_decode_boolean(const char *buf, int *index, int *p);

        Decodes a boolean value from the binary format. A boolean is actually an atom, +

        int ei_decode_boolean(const char *buf, int *index, int *p);

        Decodes a boolean value from the binary format. A boolean is actually an atom, true decodes 1 and false decodes 0.

        ei_decode_char()

        -
        int ei_decode_char(const char *buf, int *index, char *p);

        Decodes a char (8-bit) integer between 0-255 from the binary format. For +

        int ei_decode_char(const char *buf, int *index, char *p);

        Decodes a char (8-bit) integer between 0-255 from the binary format. For historical reasons the returned integer is of type char. Your C code is to consider the returned value to be of type unsigned char even if the C compilers and system can define char to be signed.

        @@ -289,14 +289,14 @@

        ei_decode_double()

        -
        int ei_decode_double(const char *buf, int *index, double *p);

        Decodes a double-precision (64-bit) floating point number from the binary +

        int ei_decode_double(const char *buf, int *index, double *p);

        Decodes a double-precision (64-bit) floating point number from the binary format.

        ei_decode_ei_term()

        -
        int ei_decode_ei_term(const char* buf, int* index, ei_term* term);

        Decodes any term, or at least tries to. If the term pointed at by *index in +

        int ei_decode_ei_term(const char* buf, int* index, ei_term* term);

        Decodes any term, or at least tries to. If the term pointed at by *index in buf fits in the term union, it is decoded, and the appropriate field in term->value is set, and *index is incremented by the term size.

        The function returns 1 on successful decoding, -1 on error, and 0 if the term seems alright, but does not fit in the term structure. If 1 is @@ -314,7 +314,7 @@

        free_fun()

        -
        int ei_decode_fun(const char *buf, int *index, erlang_fun *p);
        void free_fun(erlang_fun* f);

        Decodes a fun from the binary format. Parameter p is to be NULL or point to +

        int ei_decode_fun(const char *buf, int *index, erlang_fun *p);
        void free_fun(erlang_fun* f);

        Decodes a fun from the binary format. Parameter p is to be NULL or point to an erlang_fun structure. This is the only decode function that allocates memory. When the erlang_fun is no longer needed, it is to be freed with free_fun. (This has to do with the arbitrary size of the environment for a @@ -324,7 +324,7 @@

        ei_decode_iodata()

        -
        int ei_decode_iodata(const char *buf, int *index, int *size, char *outbuf);

        Decodes a term of the type iodata(). +

        int ei_decode_iodata(const char *buf, int *index, int *size, char *outbuf);

        Decodes a term of the type iodata(). The iodata/0 term will be flattened an written into the buffer pointed to by the outbuf argument. The byte size of the iodata is written into the integer variable pointed to by the size argument. Both size and outbuf can be set @@ -345,7 +345,7 @@

        ei_decode_list_header()

        -
        int ei_decode_list_header(const char *buf, int *index, int *arity);

        Decodes a list header from the binary format. The number of elements is returned +

        int ei_decode_list_header(const char *buf, int *index, int *arity);

        Decodes a list header from the binary format. The number of elements is returned in arity. The arity+1 elements follow (the last one is the tail of the list, normally an empty list). If arity is 0, it is an empty list.

        Notice that lists are encoded as strings if they consist entirely of integers in the range 0..255. This function do not decode such strings, use @@ -355,21 +355,21 @@

        ei_decode_long()

        -
        int ei_decode_long(const char *buf, int *index, long *p);

        Decodes a long integer from the binary format. If the code is 64 bits, the +

        int ei_decode_long(const char *buf, int *index, long *p);

        Decodes a long integer from the binary format. If the code is 64 bits, the function ei_decode_long() is the same as ei_decode_longlong().

        ei_decode_longlong()

        -
        int ei_decode_longlong(const char *buf, int *index, long long *p);

        Decodes a GCC long long or Visual C++ __int64 (64-bit) integer from the +

        int ei_decode_longlong(const char *buf, int *index, long long *p);

        Decodes a GCC long long or Visual C++ __int64 (64-bit) integer from the binary format.

        ei_decode_map_header()

        -
        int ei_decode_map_header(const char *buf, int *index, int *arity);

        Decodes a map header from the binary format. The number of key-value pairs is +

        int ei_decode_map_header(const char *buf, int *index, int *arity);

        Decodes a map header from the binary format. The number of key-value pairs is returned in *arity. Keys and values follow in this order: K1, V1, K2, V2, ..., Kn, Vn. This makes a total of arity*2 terms. If arity is zero, it is an empty map. A correctly encoded map does not have duplicate @@ -379,25 +379,25 @@

        ei_decode_pid()

        -
        int ei_decode_pid(const char *buf, int *index, erlang_pid *p);

        Decodes a process identifier (pid) from the binary format.

        +
        int ei_decode_pid(const char *buf, int *index, erlang_pid *p);

        Decodes a process identifier (pid) from the binary format.

        ei_decode_port()

        -
        int ei_decode_port(const char *buf, int *index, erlang_port *p);

        Decodes a port identifier from the binary format.

        +
        int ei_decode_port(const char *buf, int *index, erlang_port *p);

        Decodes a port identifier from the binary format.

        ei_decode_ref()

        -
        int ei_decode_ref(const char *buf, int *index, erlang_ref *p);

        Decodes a reference from the binary format.

        +
        int ei_decode_ref(const char *buf, int *index, erlang_ref *p);

        Decodes a reference from the binary format.

        ei_decode_string()

        -
        int ei_decode_string(const char *buf, int *index, char *p);

        Decodes a string from the binary format. A string in Erlang is a list of +

        int ei_decode_string(const char *buf, int *index, char *p);

        Decodes a string from the binary format. A string in Erlang is a list of integers between 0 and 255. Notice that as the string is just a list, sometimes lists are encoded as strings by term_to_binary/1, even if it was not intended.

        The string is copied to p, and enough space must be allocated. The returned @@ -408,34 +408,34 @@

        ei_decode_trace()

        -
        int ei_decode_trace(const char *buf, int *index, erlang_trace *p);

        Decodes an Erlang trace token from the binary format.

        +
        int ei_decode_trace(const char *buf, int *index, erlang_trace *p);

        Decodes an Erlang trace token from the binary format.

        ei_decode_tuple_header()

        -
        int ei_decode_tuple_header(const char *buf, int *index, int *arity);

        Decodes a tuple header, the number of elements is returned in arity. The tuple +

        int ei_decode_tuple_header(const char *buf, int *index, int *arity);

        Decodes a tuple header, the number of elements is returned in arity. The tuple elements follow in order in the buffer.

        ei_decode_ulong()

        -
        int ei_decode_ulong(const char *buf, int *index, unsigned long *p);

        Decodes an unsigned long integer from the binary format. If the code is 64 bits, +

        int ei_decode_ulong(const char *buf, int *index, unsigned long *p);

        Decodes an unsigned long integer from the binary format. If the code is 64 bits, the function ei_decode_ulong() is the same as ei_decode_ulonglong().

        ei_decode_ulonglong()

        -
        int ei_decode_ulonglong(const char *buf, int *index, unsigned long long *p);

        Decodes a GCC unsigned long long or Visual C++ unsigned __int64 (64-bit) +

        int ei_decode_ulonglong(const char *buf, int *index, unsigned long long *p);

        Decodes a GCC unsigned long long or Visual C++ unsigned __int64 (64-bit) integer from the binary format.

        ei_decode_version()

        -
        int ei_decode_version(const char *buf, int *index, int *version);

        Decodes the version magic number for the Erlang binary term format. It must be +

        int ei_decode_version(const char *buf, int *index, int *version);

        Decodes the version magic number for the Erlang binary term format. It must be the first token in a binary term.

        @@ -460,7 +460,7 @@

        ei_x_encode_atom_len()

        -
        int ei_encode_atom(char *buf, int *index, const char *p);
        int ei_encode_atom_len(char *buf, int *index, const char *p, int len);
        int ei_x_encode_atom(ei_x_buff* x, const char *p);
        int ei_x_encode_atom_len(ei_x_buff* x, const char *p, int len);

        Encodes an atom in the binary format. Parameter p is the name of the atom in +

        int ei_encode_atom(char *buf, int *index, const char *p);
        int ei_encode_atom_len(char *buf, int *index, const char *p, int len);
        int ei_x_encode_atom(ei_x_buff* x, const char *p);
        int ei_x_encode_atom_len(ei_x_buff* x, const char *p, int len);

        Encodes an atom in the binary format. Parameter p is the name of the atom in Latin-1 encoding. Only up to MAXATOMLEN-1 bytes are encoded. The name is to be NULL-terminated, except for the ei_x_encode_atom_len() function.

        @@ -486,11 +486,11 @@

        ei_x_encode_atom_len_as()

        -
        int ei_encode_atom_as(char *buf, int *index, const char *p,
        -  erlang_char_encoding from_enc, erlang_char_encoding to_enc);
        int ei_encode_atom_len_as(char *buf, int *index, const char *p, int len,
        -  erlang_char_encoding from_enc, erlang_char_encoding to_enc);
        int ei_x_encode_atom_as(ei_x_buff* x, const char *p,
        -  erlang_char_encoding from_enc, erlang_char_encoding to_enc);
        int ei_x_encode_atom_len_as(ei_x_buff* x, const char *p, int len,
        -  erlang_char_encoding from_enc, erlang_char_encoding to_enc);

        Encodes an atom in the binary format. Parameter p is the name of the atom with +

        int ei_encode_atom_as(char *buf, int *index, const char *p,
        +  erlang_char_encoding from_enc, erlang_char_encoding to_enc);
        int ei_encode_atom_len_as(char *buf, int *index, const char *p, int len,
        +  erlang_char_encoding from_enc, erlang_char_encoding to_enc);
        int ei_x_encode_atom_as(ei_x_buff* x, const char *p,
        +  erlang_char_encoding from_enc, erlang_char_encoding to_enc);
        int ei_x_encode_atom_len_as(ei_x_buff* x, const char *p, int len,
        +  erlang_char_encoding from_enc, erlang_char_encoding to_enc);

        Encodes an atom in the binary format. Parameter p is the name of the atom with character encoding from_enc (ASCII, Latin-1, or UTF-8). The name must either be NULL-terminated or a function variant with a len parameter must be used.

        The encoding fails if p is not a valid string in encoding from_enc.

        Argument to_enc is ignored. As from Erlang/OTP 20 the encoding is always done @@ -506,7 +506,7 @@

        ei_x_encode_bignum()

        -
        int ei_encode_bignum(char *buf, int *index, mpz_t obj);
        int ei_x_encode_bignum(ei_x_buff *x, mpz_t obj);

        Encodes a GMP mpz_t integer to binary format. To use this function, the ei +

        int ei_encode_bignum(char *buf, int *index, mpz_t obj);
        int ei_x_encode_bignum(ei_x_buff *x, mpz_t obj);

        Encodes a GMP mpz_t integer to binary format. To use this function, the ei library must be configured and compiled to use the GMP library.

        @@ -519,7 +519,7 @@

        ei_x_encode_binary()

        -
        int ei_encode_binary(char *buf, int *index, const void *p, long len);
        int ei_x_encode_binary(ei_x_buff* x, const void *p, long len);

        Encodes a binary in the binary format. The data is at p, of len bytes +

        int ei_encode_binary(char *buf, int *index, const void *p, long len);
        int ei_x_encode_binary(ei_x_buff* x, const void *p, long len);

        Encodes a binary in the binary format. The data is at p, of len bytes length.

        @@ -532,7 +532,7 @@

        ei_x_encode_bitstring()

        -
        int ei_encode_bitstring(char *buf, int *index, const char *p, size_t bitoffs, size_t nbits);
        int ei_x_encode_bitstring(ei_x_buff* x, const char *p, size_t bitoffs, size_t nbits);

        Encodes a bit string in the binary format.

        The data is at p. The length of the bit string is nbits bits. The first +

        int ei_encode_bitstring(char *buf, int *index, const char *p, size_t bitoffs, size_t nbits);
        int ei_x_encode_bitstring(ei_x_buff* x, const char *p, size_t bitoffs, size_t nbits);

        Encodes a bit string in the binary format.

        The data is at p. The length of the bit string is nbits bits. The first bitoffs bits of the data at p are unused. The first byte which is part of the bit string is p[bitoffs/8]. The bitoffs%8 most significant bits of the first byte p[bitoffs/8] are unused.

        The number of bytes which is part of the bit string is @@ -550,7 +550,7 @@

        ei_x_encode_boolean()

        -
        int ei_encode_boolean(char *buf, int *index, int p);
        int ei_x_encode_boolean(ei_x_buff* x, int p);

        Encodes a boolean value as the atom true if p is not zero, or false if p +

        int ei_encode_boolean(char *buf, int *index, int p);
        int ei_x_encode_boolean(ei_x_buff* x, int p);

        Encodes a boolean value as the atom true if p is not zero, or false if p is zero.

        @@ -563,7 +563,7 @@

        ei_x_encode_char()

        -
        int ei_encode_char(char *buf, int *index, char p);
        int ei_x_encode_char(ei_x_buff* x, char p);

        Encodes a char (8-bit) as an integer between 0-255 in the binary format. For +

        int ei_encode_char(char *buf, int *index, char p);
        int ei_x_encode_char(ei_x_buff* x, char p);

        Encodes a char (8-bit) as an integer between 0-255 in the binary format. For historical reasons the integer argument is of type char. Your C code is to consider the specified argument to be of type unsigned char even if the C compilers and system may define char to be signed.

        @@ -578,7 +578,7 @@

        ei_x_encode_double()

        -
        int ei_encode_double(char *buf, int *index, double p);
        int ei_x_encode_double(ei_x_buff* x, double p);

        Encodes a double-precision (64-bit) floating point number in the binary format.

        Returns -1 if the floating point number is not finite.

        +
        int ei_encode_double(char *buf, int *index, double p);
        int ei_x_encode_double(ei_x_buff* x, double p);

        Encodes a double-precision (64-bit) floating point number in the binary format.

        Returns -1 if the floating point number is not finite.

        @@ -590,7 +590,7 @@

        ei_x_encode_empty_list()

        -
        int ei_encode_empty_list(char* buf, int* index);
        int ei_x_encode_empty_list(ei_x_buff* x);

        Encodes an empty list. It is often used at the tail of a list.

        +
        int ei_encode_empty_list(char* buf, int* index);
        int ei_x_encode_empty_list(ei_x_buff* x);

        Encodes an empty list. It is often used at the tail of a list.

        @@ -602,7 +602,7 @@

        ei_x_encode_fun()

        -
        int ei_encode_fun(char *buf, int *index, const erlang_fun *p);
        int ei_x_encode_fun(ei_x_buff* x, const erlang_fun* fun);

        Encodes a fun in the binary format. Parameter p points to an erlang_fun +

        int ei_encode_fun(char *buf, int *index, const erlang_fun *p);
        int ei_x_encode_fun(ei_x_buff* x, const erlang_fun* fun);

        Encodes a fun in the binary format. Parameter p points to an erlang_fun structure. The erlang_fun is not freed automatically, the free_fun is to be called if the fun is not needed after encoding.

        @@ -616,23 +616,23 @@

        ei_x_encode_list_header()

        -
        int ei_encode_list_header(char *buf, int *index, int arity);
        int ei_x_encode_list_header(ei_x_buff* x, int arity);

        Encodes a list header, with a specified arity. The next arity+1 terms are the +

        int ei_encode_list_header(char *buf, int *index, int arity);
        int ei_x_encode_list_header(ei_x_buff* x, int arity);

        Encodes a list header, with a specified arity. The next arity+1 terms are the elements (actually its arity cons cells) and the tail of the list. Lists and tuples are encoded recursively, so that a list can contain another list or -tuple.

        For example, to encode the list [c, d, [e | f]]:

        ei_encode_list_header(buf, &i, 3);
        -ei_encode_atom(buf, &i, "c");
        -ei_encode_atom(buf, &i, "d");
        -ei_encode_list_header(buf, &i, 1);
        -ei_encode_atom(buf, &i, "e");
        -ei_encode_atom(buf, &i, "f");
        -ei_encode_empty_list(buf, &i);

        Note

        It may seem that there is no way to create a list without knowing the number +tuple.

        For example, to encode the list [c, d, [e | f]]:

        ei_encode_list_header(buf, &i, 3);
        +ei_encode_atom(buf, &i, "c");
        +ei_encode_atom(buf, &i, "d");
        +ei_encode_list_header(buf, &i, 1);
        +ei_encode_atom(buf, &i, "e");
        +ei_encode_atom(buf, &i, "f");
        +ei_encode_empty_list(buf, &i);

        Note

        It may seem that there is no way to create a list without knowing the number of elements in advance. But indeed there is a way. Notice that the list [a, b, c] can be written as [a | [b | [c]]]. Using this, a list can be -written as conses.

        To encode a list, without knowing the arity in advance:

        while (something()) {
        -    ei_x_encode_list_header(&x, 1);
        -    ei_x_encode_ulong(&x, i); /* just an example */
        -}
        -ei_x_encode_empty_list(&x);

        +written as conses.

        To encode a list, without knowing the arity in advance:

        while (something()) {
        +    ei_x_encode_list_header(&x, 1);
        +    ei_x_encode_ulong(&x, i); /* just an example */
        +}
        +ei_x_encode_empty_list(&x);

        @@ -644,7 +644,7 @@

        ei_x_encode_long()

        -
        int ei_encode_long(char *buf, int *index, long p);
        int ei_x_encode_long(ei_x_buff* x, long p);

        Encodes a long integer in the binary format. If the code is 64 bits, the +

        int ei_encode_long(char *buf, int *index, long p);
        int ei_x_encode_long(ei_x_buff* x, long p);

        Encodes a long integer in the binary format. If the code is 64 bits, the function ei_encode_long() is the same as ei_encode_longlong().

        @@ -657,7 +657,7 @@

        ei_x_encode_longlong()

        -
        int ei_encode_longlong(char *buf, int *index, long long p);
        int ei_x_encode_longlong(ei_x_buff* x, long long p);

        Encodes a GCC long long or Visual C++ __int64 (64-bit) integer in the binary +

        int ei_encode_longlong(char *buf, int *index, long long p);
        int ei_x_encode_longlong(ei_x_buff* x, long long p);

        Encodes a GCC long long or Visual C++ __int64 (64-bit) integer in the binary format.

        @@ -670,13 +670,13 @@

        ei_x_encode_map_header()

        -
        int ei_encode_map_header(char *buf, int *index, int arity);
        int ei_x_encode_map_header(ei_x_buff* x, int arity);

        Encodes a map header, with a specified arity. The next arity*2 terms encoded +

        int ei_encode_map_header(char *buf, int *index, int arity);
        int ei_x_encode_map_header(ei_x_buff* x, int arity);

        Encodes a map header, with a specified arity. The next arity*2 terms encoded will be the keys and values of the map encoded in the following order: -K1, V1, K2, V2, ..., Kn, Vn.

        For example, to encode the map #{a => "Apple", b => "Banana"}:

        ei_x_encode_map_header(&x, 2);
        -ei_x_encode_atom(&x, "a");
        -ei_x_encode_string(&x, "Apple");
        -ei_x_encode_atom(&x, "b");
        -ei_x_encode_string(&x, "Banana");

        A correctly encoded map cannot have duplicate keys.

        Available since OTP 17.0

        +K1, V1, K2, V2, ..., Kn, Vn.

        For example, to encode the map #{a => "Apple", b => "Banana"}:

        ei_x_encode_map_header(&x, 2);
        +ei_x_encode_atom(&x, "a");
        +ei_x_encode_string(&x, "Apple");
        +ei_x_encode_atom(&x, "b");
        +ei_x_encode_string(&x, "Banana");

        A correctly encoded map cannot have duplicate keys.

        Available since OTP 17.0

        @@ -688,7 +688,7 @@

        ei_x_encode_pid()

        -
        int ei_encode_pid(char *buf, int *index, const erlang_pid *p);
        int ei_x_encode_pid(ei_x_buff* x, const erlang_pid *p);

        Encodes an Erlang process identifier (pid) in the binary format. Parameter p +

        int ei_encode_pid(char *buf, int *index, const erlang_pid *p);
        int ei_x_encode_pid(ei_x_buff* x, const erlang_pid *p);

        Encodes an Erlang process identifier (pid) in the binary format. Parameter p points to an erlang_pid structure which should either have been obtained earlier with ei_decode_pid(), ei_self() or created by @@ -704,7 +704,7 @@

        ei_x_encode_port()

        -
        int ei_encode_port(char *buf, int *index, const erlang_port *p);
        int ei_x_encode_port(ei_x_buff* x, const erlang_port *p);

        Encodes an Erlang port in the binary format. Parameter p points to an +

        int ei_encode_port(char *buf, int *index, const erlang_port *p);
        int ei_x_encode_port(ei_x_buff* x, const erlang_port *p);

        Encodes an Erlang port in the binary format. Parameter p points to an erlang_port structure which should have been obtained earlier with ei_decode_port(),

        @@ -718,7 +718,7 @@

        ei_x_encode_ref()

        -
        int ei_encode_ref(char *buf, int *index, const erlang_ref *p);
        int ei_x_encode_ref(ei_x_buff* x, const erlang_ref *p);

        Encodes an Erlang reference in the binary format. Parameter p points to an +

        int ei_encode_ref(char *buf, int *index, const erlang_ref *p);
        int ei_x_encode_ref(ei_x_buff* x, const erlang_ref *p);

        Encodes an Erlang reference in the binary format. Parameter p points to an erlang_ref structure which either should have been obtained earlier with ei_decode_ref(), or created by ei_make_ref().

        @@ -745,7 +745,7 @@

        ei_x_encode_string_len()

        -
        int ei_encode_string(char *buf, int *index, const char *p);
        int ei_encode_string_len(char *buf, int *index, const char *p, int len);
        int ei_x_encode_string(ei_x_buff* x, const char *p);
        int ei_x_encode_string_len(ei_x_buff* x, const char* s, int len);

        Encodes a string in the binary format. (A string in Erlang is a list, but is +

        int ei_encode_string(char *buf, int *index, const char *p);
        int ei_encode_string_len(char *buf, int *index, const char *p, int len);
        int ei_x_encode_string(ei_x_buff* x, const char *p);
        int ei_x_encode_string_len(ei_x_buff* x, const char* s, int len);

        Encodes a string in the binary format. (A string in Erlang is a list, but is encoded as a character array in the binary format.) The string is to be NULL-terminated, except for the ei_x_encode_string_len() function.

        @@ -759,7 +759,7 @@

        ei_x_encode_trace()

        -
        int ei_encode_trace(char *buf, int *index, const erlang_trace *p);
        int ei_x_encode_trace(ei_x_buff* x, const erlang_trace *p);

        Encodes an Erlang trace token in the binary format. Parameter p points to a +

        int ei_encode_trace(char *buf, int *index, const erlang_trace *p);
        int ei_x_encode_trace(ei_x_buff* x, const erlang_trace *p);

        Encodes an Erlang trace token in the binary format. Parameter p points to a erlang_trace structure which should have been obtained earlier with ei_decode_trace().

        @@ -773,13 +773,13 @@

        ei_x_encode_tuple_header()

        -
        int ei_encode_tuple_header(char *buf, int *index, int arity);
        int ei_x_encode_tuple_header(ei_x_buff* x, int arity);

        Encodes a tuple header, with a specified arity. The next arity terms encoded +

        int ei_encode_tuple_header(char *buf, int *index, int arity);
        int ei_x_encode_tuple_header(ei_x_buff* x, int arity);

        Encodes a tuple header, with a specified arity. The next arity terms encoded will be the elements of the tuple. Tuples and lists are encoded recursively, so -that a tuple can contain another tuple or list.

        For example, to encode the tuple {a, {b, {}}}:

        ei_encode_tuple_header(buf, &i, 2);
        -ei_encode_atom(buf, &i, "a");
        -ei_encode_tuple_header(buf, &i, 2);
        -ei_encode_atom(buf, &i, "b");
        -ei_encode_tuple_header(buf, &i, 0);

        +that a tuple can contain another tuple or list.

        For example, to encode the tuple {a, {b, {}}}:

        ei_encode_tuple_header(buf, &i, 2);
        +ei_encode_atom(buf, &i, "a");
        +ei_encode_tuple_header(buf, &i, 2);
        +ei_encode_atom(buf, &i, "b");
        +ei_encode_tuple_header(buf, &i, 0);

        @@ -791,7 +791,7 @@

        ei_x_encode_ulong()

        -
        int ei_encode_ulong(char *buf, int *index, unsigned long p);
        int ei_x_encode_ulong(ei_x_buff* x, unsigned long p);

        Encodes an unsigned long integer in the binary format. If the code is 64 bits, +

        int ei_encode_ulong(char *buf, int *index, unsigned long p);
        int ei_x_encode_ulong(ei_x_buff* x, unsigned long p);

        Encodes an unsigned long integer in the binary format. If the code is 64 bits, the function ei_encode_ulong() is the same as ei_encode_ulonglong().

        @@ -804,7 +804,7 @@

        ei_x_encode_ulonglong()

        -
        int ei_encode_ulonglong(char *buf, int *index, unsigned long long p);
        int ei_x_encode_ulonglong(ei_x_buff* x, unsigned long long p);

        Encodes a GCC unsigned long long or Visual C++ unsigned __int64 (64-bit) +

        int ei_encode_ulonglong(char *buf, int *index, unsigned long long p);
        int ei_x_encode_ulonglong(ei_x_buff* x, unsigned long long p);

        Encodes a GCC unsigned long long or Visual C++ unsigned __int64 (64-bit) integer in the binary format.

        @@ -817,14 +817,14 @@

        ei_x_encode_version()

        -
        int ei_encode_version(char *buf, int *index);
        int ei_x_encode_version(ei_x_buff* x);

        Encodes a version magic number for the binary format. Must be the first token in +

        int ei_encode_version(char *buf, int *index);
        int ei_x_encode_version(ei_x_buff* x);

        Encodes a version magic number for the binary format. Must be the first token in a binary term.

        ei_get_type()

        -
        int ei_get_type(const char *buf, const int *index, int *type, int *size);

        Returns the type in *type and size in *size of the encoded term. For strings +

        int ei_get_type(const char *buf, const int *index, int *type, int *size);

        Returns the type in *type and size in *size of the encoded term. For strings and atoms, size is the number of characters not including the terminating NULL. For binaries and bitstrings, *size is the number of bytes. For lists, tuples and maps, *size is the arity of the object. For bignum integers, @@ -857,7 +857,7 @@

        ei_init()

        -
        int ei_init(void);

        Initialize the ei library. This function should be called once (and only once) +

        int ei_init(void);

        Initialize the ei library. This function should be called once (and only once) before calling any other functionality in the ei library.

        On success zero is returned. On failure a posix error code is returned.

        Available since OTP 21.3

        @@ -870,7 +870,7 @@

        ei_s_print_term()

        -
        int ei_print_term(FILE* fp, const char* buf, int* index);
        int ei_s_print_term(char** s, const char* buf, int* index);

        Prints a term, in clear text, to the file specified by fp, or the buffer +

        int ei_print_term(FILE* fp, const char* buf, int* index);
        int ei_s_print_term(char** s, const char* buf, int* index);

        Prints a term, in clear text, to the file specified by fp, or the buffer pointed to by s. It tries to resemble the term printing in the Erlang shell.

        In ei_s_print_term(), parameter s is to point to a dynamically (malloc) allocated string of BUFSIZ bytes or a NULL pointer. The string can be reallocated (and *s can be updated) by this function if the result is more @@ -883,7 +883,7 @@

        ei_set_compat_rel()

        -
        void ei_set_compat_rel(unsigned release_number);

        In general, the ei library is guaranteed to be compatible with other +

        void ei_set_compat_rel(unsigned release_number);

        In general, the ei library is guaranteed to be compatible with other Erlang/OTP components that are 2 major releases older or newer than the ei library itself.

        Sometimes an exception to the above rule has to be made to make new features (or even bug fixes) possible. A call to ei_set_compat_rel(release_number) sets the @@ -908,7 +908,7 @@

        ei_skip_term()

        -
        int ei_skip_term(const char* buf, int* index);

        Skips a term in the specified buffer; recursively skips elements of lists and +

        int ei_skip_term(const char* buf, int* index);

        Skips a term in the specified buffer; recursively skips elements of lists and tuples, so that a full term is skipped. This is a way to get the size of an Erlang term.

        buf is the buffer.

        index is updated to point right after the term in the buffer.

        Note

        This can be useful when you want to hold arbitrary terms: skip them and copy the binary term data to some buffer.

        Returns 0 on success, otherwise -1.

        @@ -923,7 +923,7 @@

        ei_x_append_buf()

        -
        int ei_x_append(ei_x_buff* x, const ei_x_buff* x2);
        int ei_x_append_buf(ei_x_buff* x, const char* buf, int len);

        Appends data at the end of buffer x.

        +
        int ei_x_append(ei_x_buff* x, const ei_x_buff* x2);
        int ei_x_append_buf(ei_x_buff* x, const char* buf, int len);

        Appends data at the end of buffer x.

        @@ -935,7 +935,7 @@

        ei_x_format_wo_ver()

        -
        int ei_x_format(ei_x_buff* x, const char* fmt, ...);
        int ei_x_format_wo_ver(ei_x_buff* x, const char *fmt, ... );

        Formats a term, given as a string, to a buffer. Works like a sprintf for Erlang +

        int ei_x_format(ei_x_buff* x, const char* fmt, ...);
        int ei_x_format_wo_ver(ei_x_buff* x, const char *fmt, ... );

        Formats a term, given as a string, to a buffer. Works like a sprintf for Erlang terms. fmt contains a format string, with arguments like ~d, to insert terms from variables. The following formats are supported (with the C types given):

        ~a  An atom, char*
         ~c  A character, char
        @@ -945,14 +945,14 @@ 

        ~u A unsigned long integer, unsigned long int ~f A float, float ~d A double float, double float -~p An Erlang pid, erlang_pid*

        For example, to encode a tuple with some stuff:

        ei_x_format("{~a,~i,~d}", "numbers", 12, 3.14159)
        -encodes the tuple {numbers,12,3.14159}

        ei_x_format_wo_ver() formats into a buffer, without the initial version byte.

        Change

        Since OTP 26.2 maps can be encoded with syntax like "#{k1 => v1, k2 => v2}".

        +~p An Erlang pid, erlang_pid*

    For example, to encode a tuple with some stuff:

    ei_x_format("{~a,~i,~d}", "numbers", 12, 3.14159)
    +encodes the tuple {numbers,12,3.14159}

    ei_x_format_wo_ver() formats into a buffer, without the initial version byte.

    Change

    Since OTP 26.2 maps can be encoded with syntax like "#{k1 => v1, k2 => v2}".

    ei_x_free()

    -
    int ei_x_free(ei_x_buff* x);

    Deallocates the dynamically allocated content of the buffer referred by x. +

    int ei_x_free(ei_x_buff* x);

    Deallocates the dynamically allocated content of the buffer referred by x. After deallocation, the buff field is set to NULL.

    @@ -965,7 +965,7 @@

    ei_x_new_with_version()

    -
    int ei_x_new(ei_x_buff* x);
    int ei_x_new_with_version(ei_x_buff* x);

    Initialize the dynamically realizable buffer referred to by x. The fields of +

    int ei_x_new(ei_x_buff* x);
    int ei_x_new_with_version(ei_x_buff* x);

    Initialize the dynamically realizable buffer referred to by x. The fields of the structure pointed to by parameter x is filled in, and a default buffer is allocated. ei_x_new_with_version() also puts an initial version byte, which is used in the binary format (so that ei_x_encode_version() will not be needed.)

    diff --git a/prs/8803/lib/erl_interface-5.5.2/doc/html/ei_connect.html b/prs/8803/lib/erl_interface-5.5.2/doc/html/ei_connect.html index 285e44751a4e1..c9f124750794f 100644 --- a/prs/8803/lib/erl_interface-5.5.2/doc/html/ei_connect.html +++ b/prs/8803/lib/erl_interface-5.5.2/doc/html/ei_connect.html @@ -241,36 +241,36 @@

    • ei_cnode - Opaque data type representing a C-node. A ei_cnode structure is initialized by calling -ei_connect_init() or friends.

    • ei_socket_callbacks

      typedef struct {
      +ei_connect_init() or friends.

    • ei_socket_callbacks

      typedef struct {
           int flags;
      -    int (*socket)(void **ctx, void *setup_ctx);
      -    int   (*close)(void *ctx);
      -    int (*listen)(void *ctx, void *addr, int *len, int backlog);
      -    int (*accept)(void **ctx, void *addr, int *len, unsigned tmo);
      -    int (*connect)(void *ctx, void *addr, int len, unsigned tmo);
      -    int (*writev)(void *ctx, const void *iov, int iovcnt, ssize_t *len, unsigned tmo);
      -    int (*write)(void *ctx, const char *buf, ssize_t *len, unsigned tmo);
      -    int (*read)(void *ctx, char *buf, ssize_t *len, unsigned tmo);
      -    int (*handshake_packet_header_size)(void *ctx, int *sz);
      -    int (*connect_handshake_complete)(void *ctx);
      -    int (*accept_handshake_complete)(void *ctx);
      -    int (*get_fd)(void *ctx, int *fd);
      -} ei_socket_callbacks;

      Callbacks functions for a + int (*socket)(void **ctx, void *setup_ctx); + int (*close)(void *ctx); + int (*listen)(void *ctx, void *addr, int *len, int backlog); + int (*accept)(void **ctx, void *addr, int *len, unsigned tmo); + int (*connect)(void *ctx, void *addr, int len, unsigned tmo); + int (*writev)(void *ctx, const void *iov, int iovcnt, ssize_t *len, unsigned tmo); + int (*write)(void *ctx, const char *buf, ssize_t *len, unsigned tmo); + int (*read)(void *ctx, char *buf, ssize_t *len, unsigned tmo); + int (*handshake_packet_header_size)(void *ctx, int *sz); + int (*connect_handshake_complete)(void *ctx); + int (*accept_handshake_complete)(void *ctx); + int (*get_fd)(void *ctx, int *fd); +} ei_socket_callbacks;

    Callbacks functions for a User Supplied Socket Implementation. Documentation of each field can be -found in the User Supplied Socket Implementation section above.

  • ErlConnect

    typedef struct {
    -    char ipadr[4]; /* Ip v4 address in network byte order */
    -    char nodename[MAXNODELEN];
    -} ErlConnect;

    IP v4 address and nodename.

  • Erl_IpAddr

    typedef struct {
    +found in the User Supplied Socket Implementation section above.

  • ErlConnect

    typedef struct {
    +    char ipadr[4]; /* Ip v4 address in network byte order */
    +    char nodename[MAXNODELEN];
    +} ErlConnect;

    IP v4 address and nodename.

  • Erl_IpAddr

    typedef struct {
         unsigned s_addr; /* Ip v4 address in network byte order */
    -} Erl_IpAddr;

    IP v4 address.

  • erlang_msg

    typedef struct {
    +} Erl_IpAddr;

    IP v4 address.

  • erlang_msg

    typedef struct {
         long msgtype;
         erlang_pid from;
         erlang_pid to;
    -    char toname[MAXATOMLEN+1];
    -    char cookie[MAXATOMLEN+1];
    +    char toname[MAXATOMLEN+1];
    +    char cookie[MAXATOMLEN+1];
         erlang_trace token;
    -} erlang_msg;

    Information about a message received via +} erlang_msg;

  • Information about a message received via ei_receive_msg() or friends.

    @@ -295,15 +295,15 @@

    ei_gethostbyname_r()

    -
    struct hostent * ei_gethostbyaddr(const char *addr, int len, int type);
    struct hostent * ei_gethostbyaddr_r(const char *addr, int length,  int type,
    -  struct hostent *hostp, char *buffer,   int buflen,  int *h_errnop);
    struct hostent * ei_gethostbyname(const char *name);
    struct hostent * ei_gethostbyname_r(const char *name,  struct hostent *hostp,
    -  char *buffer,  int buflen,  int *h_errnop);

    Convenience functions for some common name lookup functions.

    +
    struct hostent * ei_gethostbyaddr(const char *addr, int len, int type);
    struct hostent * ei_gethostbyaddr_r(const char *addr, int length,  int type,
    +  struct hostent *hostp, char *buffer,   int buflen,  int *h_errnop);
    struct hostent * ei_gethostbyname(const char *name);
    struct hostent * ei_gethostbyname_r(const char *name,  struct hostent *hostp,
    +  char *buffer,  int buflen,  int *h_errnop);

    Convenience functions for some common name lookup functions.

    ei_accept()

    -
    int ei_accept(ei_cnode *ec, int listensock, ErlConnect *conp);

    Used by a server process to accept a connection from a client process.

    • ec is the C-node structure.
    • listensock is an open socket descriptor on which listen() has previously +
      int ei_accept(ei_cnode *ec, int listensock, ErlConnect *conp);

      Used by a server process to accept a connection from a client process.

      • ec is the C-node structure.
      • listensock is an open socket descriptor on which listen() has previously been called.
      • conp is a pointer to an ErlConnect struct.

      On success, conp is filled in with the address and node name of the connecting client and a file descriptor is returned. On failure, ERL_ERROR is returned and erl_errno is set to EIO.

      @@ -312,14 +312,14 @@

      ei_accept_tmo()

      -
      int ei_accept_tmo(ei_cnode *ec, int listensock, ErlConnect *conp, unsigned timeout_ms);

      Equivalent to ei_accept with an optional time-out argument, see the +

      int ei_accept_tmo(ei_cnode *ec, int listensock, ErlConnect *conp, unsigned timeout_ms);

      Equivalent to ei_accept with an optional time-out argument, see the description at the beginning of this manual page.

      ei_close_connection()

      -
      int ei_close_connection(int fd);

      Closes a previously opened connection or listen socket.

      Available since OTP 21.3

      +
      int ei_close_connection(int fd);

      Closes a previously opened connection or listen socket.

      Available since OTP 21.3

      @@ -343,7 +343,7 @@

      ei_xconnect_host_port()

      -
      int ei_connect(ei_cnode* ec, char *nodename);
      int ei_xconnect(ei_cnode* ec, Erl_IpAddr adr, char *alivename);
      int ei_connect_host_port(ei_cnode* ec, char *hostname, int port);
      int ei_xconnect_host_port(ei_cnode* ec, Erl_IpAddr adr, int port);

      Sets up a connection to an Erlang node.

      ei_xconnect() requires the IP address of the remote host and the alive name of +

      int ei_connect(ei_cnode* ec, char *nodename);
      int ei_xconnect(ei_cnode* ec, Erl_IpAddr adr, char *alivename);
      int ei_connect_host_port(ei_cnode* ec, char *hostname, int port);
      int ei_xconnect_host_port(ei_cnode* ec, Erl_IpAddr adr, int port);

      Sets up a connection to an Erlang node.

      ei_xconnect() requires the IP address of the remote host and the alive name of the remote node to be specified. ei_connect() provides an alternative interface and determines the information from the node name provided. The ei_xconnect_host_port() function provides yet another alternative that will @@ -359,12 +359,12 @@

      #define IP_ADDR "150.236.14.75" /*** Variant 1 ***/ -int fd = ei_connect(&ec, NODE); +int fd = ei_connect(&ec, NODE); /*** Variant 2 ***/ struct in_addr addr; -addr.s_addr = inet_addr(IP_ADDR); -fd = ei_xconnect(&ec, &addr, ALIVE);

    Available since OTP 23.0

    +addr.s_addr = inet_addr(IP_ADDR); +fd = ei_xconnect(&ec, &addr, ALIVE);

    Available since OTP 23.0

    @@ -388,11 +388,11 @@

    ei_connect_xinit_ussi()

    -
    int ei_connect_init(ei_cnode* ec, const char* this_node_name, const char *cookie, unsigned creation);
    int ei_connect_init_ussi(ei_cnode* ec, const char* this_node_name, const char *cookie,
    -  unsigned creation, ei_socket_callbacks *cbs, int cbs_sz, void *setup_context);
    int ei_connect_xinit(ei_cnode* ec, const char *thishostname, const char *thisalivename,
    -  const char *thisnodename, Erl_IpAddr thisipaddr, const char *cookie, unsigned creation);
    int ei_connect_xinit_ussi(ei_cnode* ec, const char *thishostname, const char *thisalivename,
    +
    int ei_connect_init(ei_cnode* ec, const char* this_node_name, const char *cookie, unsigned creation);
    int ei_connect_init_ussi(ei_cnode* ec, const char* this_node_name, const char *cookie,
    +  unsigned creation, ei_socket_callbacks *cbs, int cbs_sz, void *setup_context);
    int ei_connect_xinit(ei_cnode* ec, const char *thishostname, const char *thisalivename,
    +  const char *thisnodename, Erl_IpAddr thisipaddr, const char *cookie, unsigned creation);
    int ei_connect_xinit_ussi(ei_cnode* ec, const char *thishostname, const char *thisalivename,
       const char *thisnodename, Erl_IpAddr thisipaddr, const char *cookie, unsigned creation,
    -  ei_socket_callbacks *cbs, int cbs_sz, void *setup_context);

    Initializes the ec structure, to identify the node name and cookie of the + ei_socket_callbacks *cbs, int cbs_sz, void *setup_context);

    Initializes the ec structure, to identify the node name and cookie of the server. One of them must be called before other functions that works on the ei_cnode type or a file descriptor associated with a connection to another node is used.

    • ec is a structure containing information about the C-node. It is used in @@ -415,20 +415,20 @@

      see the relevant system documentation.

      These functions return a negative value indicating that an error occurred.

      Example 1:

      unsigned n = 0;
       struct in_addr addr;
       ei_cnode ec;
      -addr.s_addr = inet_addr("150.236.14.75");
      -if (ei_connect_xinit(&ec,
      +addr.s_addr = inet_addr("150.236.14.75");
      +if (ei_connect_xinit(&ec,
                            "chivas",
                            "madonna",
                            "madonna@chivas.du.etx.ericsson.se",
                            &addr;
                            "cookie...",
      -                     n++) < 0) {
      -    fprintf(stderr,"ERROR when initializing: %d",erl_errno);
      -    exit(-1);
      -}

      Example 2:

      if (ei_connect_init(&ec, "madonna", "cookie...", n++) < 0) {
      -    fprintf(stderr,"ERROR when initializing: %d",erl_errno);
      -    exit(-1);
      -}

      Available since OTP 21.3

      + n++) < 0) { + fprintf(stderr,"ERROR when initializing: %d",erl_errno); + exit(-1); +}

    Example 2:

    if (ei_connect_init(&ec, "madonna", "cookie...", n++) < 0) {
    +    fprintf(stderr,"ERROR when initializing: %d",erl_errno);
    +    exit(-1);
    +}

    Available since OTP 21.3

    @@ -452,7 +452,7 @@

    ei_xconnect_host_port_tmo()

    -
    int ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned timeout_ms);
    int ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr adr, char *alivename, unsigned timeout_ms);
    int ei_connect_host_port_tmo(ei_cnode* ec, char *hostname, int port, unsigned ms);
    int ei_xconnect_host_port_tmo(ei_cnode* ec, Erl_IpAddr adr, int port, unsigned ms);

    Equivalent to ei_connect, ei_xconnect, ei_connect_host_port and +

    int ei_connect_tmo(ei_cnode* ec, char *nodename, unsigned timeout_ms);
    int ei_xconnect_tmo(ei_cnode* ec, Erl_IpAddr adr, char *alivename, unsigned timeout_ms);
    int ei_connect_host_port_tmo(ei_cnode* ec, char *hostname, int port, unsigned ms);
    int ei_xconnect_host_port_tmo(ei_cnode* ec, Erl_IpAddr adr, int port, unsigned ms);

    Equivalent to ei_connect, ei_xconnect, ei_connect_host_port and ei_xconnect_host_port with an optional time-out argument, see the description at the beginning of this manual page.

    Available since OTP 23.0

    @@ -466,7 +466,7 @@

    ei_set_tracelevel()

    -
    int ei_get_tracelevel(void);
    void ei_set_tracelevel(int level);

    Used to set tracing on the distribution. The levels are different verbosity +

    int ei_get_tracelevel(void);
    void ei_set_tracelevel(int level);

    Used to set tracing on the distribution. The levels are different verbosity levels. A higher level means more information. See also section Debug Information.

    These functions are not thread safe.

    Available since OTP R13B04

    @@ -480,7 +480,7 @@

    ei_xlisten()

    -
    int ei_listen(ei_cnode *ec, int *port, int backlog);
    int ei_xlisten(ei_cnode *ec, Erl_IpAddr adr, int *port, int backlog);

    Used by a server process to setup a listen socket which later can be used for +

    int ei_listen(ei_cnode *ec, int *port, int backlog);
    int ei_xlisten(ei_cnode *ec, Erl_IpAddr adr, int *port, int backlog);

    Used by a server process to setup a listen socket which later can be used for accepting connections from client processes.

    • ec is the C-node structure.
    • adr is local interface to bind to.
    • port is a pointer to an integer containing the port number to bind to. If *port equals 0 when calling ei_listen(), the socket will be bound to an ephemeral port. On success, ei_listen() will update the value of *port to @@ -495,7 +495,7 @@

      ei_make_pid()

      -
      int ei_make_pid(ei_cnode *ec, erlang_pid *pid);

      Creates a new process identifier in the argument pid. This process identifier +

      int ei_make_pid(ei_cnode *ec, erlang_pid *pid);

      Creates a new process identifier in the argument pid. This process identifier refers to a conseptual process residing on the C-node identified by the argument ec. On success 0 is returned. On failure ERL_ERROR is returned and erl_errno is set.

      The C-node identified by ec must have been initialized and must have received @@ -508,7 +508,7 @@

      ei_make_ref()

      -
      int ei_make_ref(ei_cnode *ec, erlang_ref *ref);

      Creates a new reference in the argument ref. This reference originates from +

      int ei_make_ref(ei_cnode *ec, erlang_ref *ref);

      Creates a new reference in the argument ref. This reference originates from the C-node identified by the argument ec. On success 0 is returned. On failure ERL_ERROR is returned and erl_errno is set.

      The C-node identified by ec must have been initialized and must have received a name prior to the call to ei_make_ref(). Initialization of the C-node is @@ -520,7 +520,7 @@

      ei_publish()

      -
      int ei_publish(ei_cnode *ec, int port);

      Used by a server process to register with the local name server EPMD, thereby +

      int ei_publish(ei_cnode *ec, int port);

      Used by a server process to register with the local name server EPMD, thereby allowing other processes to send messages by using the registered name. Before calling either of these functions, the process should have called bind() and listen() on an open socket.

      • ec is the C-node structure.
      • port is the local name to register, and is to be the same as the port number @@ -533,14 +533,14 @@

        ei_publish_tmo()

        -
        int ei_publish_tmo(ei_cnode *ec, int port, unsigned timeout_ms);

        Equivalent to ei_publish with an optional time-out argument, see the +

        int ei_publish_tmo(ei_cnode *ec, int port, unsigned timeout_ms);

        Equivalent to ei_publish with an optional time-out argument, see the description at the beginning of this manual page.

        ei_receive()

        -
        int ei_receive(int fd, unsigned char* bufp, int bufsize);

        Receives a message consisting of a sequence of bytes in the Erlang external +

        int ei_receive(int fd, unsigned char* bufp, int bufsize);

        Receives a message consisting of a sequence of bytes in the Erlang external format.

        • fd is an open descriptor to an Erlang connection. It is obtained from a previous ei_connect or ei_accept.
        • bufp is a buffer large enough to hold the expected message.
        • bufsize indicates the size of bufp.

        If a tick occurs, that is, the Erlang node on the other end of the connection has polled this node to see if it is still alive, the function returns @@ -553,7 +553,7 @@

        ei_receive_encoded()

        -
        int ei_receive_encoded(int fd, char **mbufp, int *bufsz,  erlang_msg *msg, int *msglen);

        This function is retained for compatibility with code generated by the interface +

        int ei_receive_encoded(int fd, char **mbufp, int *bufsz,  erlang_msg *msg, int *msglen);

        This function is retained for compatibility with code generated by the interface compiler and with code following examples in the same application.

        In essence, the function performs the same operation as ei_xreceive_msg, but instead of using an ei_x_buff, the function expects a pointer to a character pointer (mbufp), where the character pointer is to point to a memory area @@ -569,8 +569,8 @@

        ei_receive_encoded_tmo()

        -
        int ei_receive_encoded_tmo(int fd, char **mbufp, int *bufsz,  erlang_msg *msg,
        -  int *msglen, unsigned timeout_ms);

        Equivalent to ei_receive_encoded with an optional time-out argument, see the +

        int ei_receive_encoded_tmo(int fd, char **mbufp, int *bufsz,  erlang_msg *msg,
        +  int *msglen, unsigned timeout_ms);

        Equivalent to ei_receive_encoded with an optional time-out argument, see the description at the beginning of this manual page.

        @@ -583,7 +583,7 @@

        ei_xreceive_msg()

        -
        int ei_receive_msg(int fd, erlang_msg* msg, ei_x_buff* x);
        int ei_xreceive_msg(int fd, erlang_msg* msg, ei_x_buff* x);

        Receives a message to the buffer in x. ei_xreceive_msg allows the buffer in +

        int ei_receive_msg(int fd, erlang_msg* msg, ei_x_buff* x);
        int ei_xreceive_msg(int fd, erlang_msg* msg, ei_x_buff* x);

        Receives a message to the buffer in x. ei_xreceive_msg allows the buffer in x to grow, but ei_receive_msg fails if the message is larger than the pre-allocated buffer in x.

        • fd is an open descriptor to an Erlang connection.
        • msg is a pointer to an erlang_msg structure and contains information on the message received.
        • x is buffer obtained from ei_x_new.

        On success, the functions return ERL_MSG and the @@ -603,33 +603,33 @@

        ei_xreceive_msg_tmo()

        -
        int ei_receive_msg_tmo(int fd, erlang_msg* msg, ei_x_buff* x, unsigned imeout_ms);
        int ei_xreceive_msg_tmo(int fd, erlang_msg* msg, ei_x_buff* x, unsigned timeout_ms);

        Equivalent to ei_receive_msg and ei_xreceive_msg with an optional time-out +

        int ei_receive_msg_tmo(int fd, erlang_msg* msg, ei_x_buff* x, unsigned imeout_ms);
        int ei_xreceive_msg_tmo(int fd, erlang_msg* msg, ei_x_buff* x, unsigned timeout_ms);

        Equivalent to ei_receive_msg and ei_xreceive_msg with an optional time-out argument, see the description at the beginning of this manual page.

        ei_receive_tmo()

        -
        int ei_receive_tmo(int fd, unsigned char* bufp, int bufsize, unsigned timeout_ms);

        Equivalent to ei_receive with an optional time-out argument, see the +

        int ei_receive_tmo(int fd, unsigned char* bufp, int bufsize, unsigned timeout_ms);

        Equivalent to ei_receive with an optional time-out argument, see the description at the beginning of this manual page.

        ei_reg_send()

        -
        int ei_reg_send(ei_cnode* ec, int fd, char* server_name, char* buf, int len);

        Sends an Erlang term to a registered process.

        • fd is an open descriptor to an Erlang connection.
        • server_name is the registered name of the intended recipient.
        • buf is the buffer containing the term in binary format.
        • len is the length of the message in bytes.

        Returns 0 if successful, otherwise -1. In the latter case it sets +

        int ei_reg_send(ei_cnode* ec, int fd, char* server_name, char* buf, int len);

        Sends an Erlang term to a registered process.

        • fd is an open descriptor to an Erlang connection.
        • server_name is the registered name of the intended recipient.
        • buf is the buffer containing the term in binary format.
        • len is the length of the message in bytes.

        Returns 0 if successful, otherwise -1. In the latter case it sets erl_errno to EIO.

        Example:

        Send the atom "ok" to the process "worker":

        ei_x_buff x;
        -ei_x_new_with_version(&x);
        -ei_x_encode_atom(&x, "ok");
        -if (ei_reg_send(&ec, fd, x.buff, x.index) < 0)
        -    handle_error();

        +ei_x_new_with_version(&x); +ei_x_encode_atom(&x, "ok"); +if (ei_reg_send(&ec, fd, x.buff, x.index) < 0) + handle_error();

    ei_reg_send_tmo()

    -
    int ei_reg_send_tmo(ei_cnode* ec, int fd, char* server_name, char* buf, int len,
    -  unsigned timeout_ms);

    Equivalent to ei_reg_send with an optional time-out argument, see the +

    int ei_reg_send_tmo(ei_cnode* ec, int fd, char* server_name, char* buf, int len,
    +  unsigned timeout_ms);

    Equivalent to ei_reg_send with an optional time-out argument, see the description at the beginning of this manual page.

    @@ -654,10 +654,10 @@

    ei_rpc_from()

    -
    int ei_rpc(ei_cnode *ec, int fd, char *mod, char *fun, const char *argbuf,
    -  int argbuflen, ei_x_buff *x);
    int ei_rpc_to(ei_cnode *ec, int fd, char *mod, char *fun, const char *argbuf,
    -  int argbuflen);
    int ei_xrpc_to(ei_cnode *ec, int fd, char *mod, char *fun, const char *argbuf,
    -  int argbuflen, int flags);
    int ei_rpc_from(ei_cnode *ec, int fd, int timeout, erlang_msg *msg, ei_x_buff *x);

    Supports calling Erlang functions on remote nodes. ei_rpc_to() sends an RPC +

    int ei_rpc(ei_cnode *ec, int fd, char *mod, char *fun, const char *argbuf,
    +  int argbuflen, ei_x_buff *x);
    int ei_rpc_to(ei_cnode *ec, int fd, char *mod, char *fun, const char *argbuf,
    +  int argbuflen);
    int ei_xrpc_to(ei_cnode *ec, int fd, char *mod, char *fun, const char *argbuf,
    +  int argbuflen, int flags);
    int ei_rpc_from(ei_cnode *ec, int fd, int timeout, erlang_msg *msg, ei_x_buff *x);

    Supports calling Erlang functions on remote nodes. ei_rpc_to() sends an RPC request to a remote node and ei_rpc_from() receives the results of such a call. ei_rpc() combines the functionality of these two functions by sending an RPC request and waiting for the results.

    The ei_xrpc_to() function is equivalent to ei_rpc_to() when its flags @@ -705,25 +705,25 @@

    functions set erl_errno to one of the following:

    • EIO - I/O error.

    • ETIMEDOUT - Time-out expired.

    • EAGAIN - Temporary error: Try again.

    Example:

    Check to see if an Erlang process is alive:

    int index = 0, is_alive;
     ei_x_buff args, result;
     
    -ei_x_new(&result);
    -ei_x_new(&args);
    -ei_x_encode_list_header(&args, 1);
    -ei_x_encode_pid(&args, &check_pid);
    -ei_x_encode_empty_list(&args);
    +ei_x_new(&result);
    +ei_x_new(&args);
    +ei_x_encode_list_header(&args, 1);
    +ei_x_encode_pid(&args, &check_pid);
    +ei_x_encode_empty_list(&args);
     
    -if (ei_rpc(&ec, fd, "erlang", "is_process_alive",
    -           args.buff, args.index, &result) < 0)
    -    handle_error();
    +if (ei_rpc(&ec, fd, "erlang", "is_process_alive",
    +           args.buff, args.index, &result) < 0)
    +    handle_error();
     
    -if (ei_decode_version(result.buff, &index) < 0
    -    || ei_decode_bool(result.buff, &index, &is_alive) < 0)
    -    handle_error();

    +if (ei_decode_version(result.buff, &index) < 0 + || ei_decode_bool(result.buff, &index, &is_alive) < 0) + handle_error();

    ei_self()

    -
    erlang_pid * ei_self(ei_cnode *ec);

    Retrieves a generic pid of the C-node. Every C-node has a (pseudo) pid used in +

    erlang_pid * ei_self(ei_cnode *ec);

    Retrieves a generic pid of the C-node. Every C-node has a (pseudo) pid used in ei_send_reg, ei_rpc(), and others. This is contained in a field in the ec structure. Do not modify this structure.

    On success a pointer to the process identifier is returned. On failure NULL is returned and erl_errno is set.

    The C-node identified by ec must have been initialized and must have received @@ -736,28 +736,28 @@

    ei_send()

    -
    int ei_send(int fd, erlang_pid* to, char* buf, int len);

    Sends an Erlang term to a process.

    • fd is an open descriptor to an Erlang connection.
    • to is the pid of the intended recipient of the message.
    • buf is the buffer containing the term in binary format.
    • len is the length of the message in bytes.

    Returns 0 if successful, otherwise -1. In the latter case it sets +

    int ei_send(int fd, erlang_pid* to, char* buf, int len);

    Sends an Erlang term to a process.

    • fd is an open descriptor to an Erlang connection.
    • to is the pid of the intended recipient of the message.
    • buf is the buffer containing the term in binary format.
    • len is the length of the message in bytes.

    Returns 0 if successful, otherwise -1. In the latter case it sets erl_errno to EIO.

    ei_send_encoded()

    -
    int ei_send_encoded(int fd, erlang_pid* to, char* buf, int len);

    Works exactly as ei_send, the alternative name is retained for backward +

    int ei_send_encoded(int fd, erlang_pid* to, char* buf, int len);

    Works exactly as ei_send, the alternative name is retained for backward compatibility. The function will not be removed without prior notice.

    ei_send_encoded_tmo()

    -
    int ei_send_encoded_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned timeout_ms);

    Equivalent to ei_send_encoded with an optional time-out argument, see the +

    int ei_send_encoded_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned timeout_ms);

    Equivalent to ei_send_encoded with an optional time-out argument, see the description at the beginning of this manual page.

    ei_send_reg_encoded()

    -
    int ei_send_reg_encoded(int fd, const erlang_pid *from, const char *to, const char *buf, int len);

    This function is retained for compatibility with code generated by the interface +

    int ei_send_reg_encoded(int fd, const erlang_pid *from, const char *to, const char *buf, int len);

    This function is retained for compatibility with code generated by the interface compiler and with code following examples in the same application.

    The function works as ei_reg_send with one exception. Instead of taking ei_cnode as first argument, it takes a second argument, an erlang_pid, which is to be the process identifier of the sending process (in the Erlang @@ -768,15 +768,15 @@

    ei_send_reg_encoded_tmo()

    -
    int ei_send_reg_encoded_tmo(int fd, const erlang_pid *from, const char *to, const char *buf,
    -  int len, unsigned timeout_ms);

    Equivalent to ei_send_reg_encoded with an optional time-out argument, see the +

    int ei_send_reg_encoded_tmo(int fd, const erlang_pid *from, const char *to, const char *buf,
    +  int len, unsigned timeout_ms);

    Equivalent to ei_send_reg_encoded with an optional time-out argument, see the description at the beginning of this manual page.

    ei_send_tmo()

    -
    int ei_send_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned timeout_ms);

    Equivalent to ei_send with an optional time-out argument, see the description +

    int ei_send_tmo(int fd, erlang_pid* to, char* buf, int len, unsigned timeout_ms);

    Equivalent to ei_send with an optional time-out argument, see the description at the beginning of this manual page.

    @@ -795,7 +795,7 @@

    ei_thisalivename()

    -
    const char * ei_thisnodename(ei_cnode *ec);
    const char * ei_thishostname(ei_cnode *ec);
    const char * ei_thisalivename(ei_cnode *ec);

    Can be used to retrieve information about the C-node. These values are initially +

    const char * ei_thisnodename(ei_cnode *ec);
    const char * ei_thishostname(ei_cnode *ec);
    const char * ei_thisalivename(ei_cnode *ec);

    Can be used to retrieve information about the C-node. These values are initially set with ei_connect_init() or ei_connect_xinit().

    These function simply fetch the appropriate field from the ec structure. Read the field directly will probably be safe for a long time, so these functions are not really needed.

    @@ -804,7 +804,7 @@

    ei_unpublish()

    -
    int ei_unpublish(ei_cnode *ec);

    Can be called by a process to unregister a specified node from EPMD on the local +

    int ei_unpublish(ei_cnode *ec);

    Can be called by a process to unregister a specified node from EPMD on the local host. This is, however, usually not allowed, unless EPMD was started with flag -relaxed_command_check, which it normally is not.

    To unregister a node you have published, you should close the descriptor that was returned by ei_publish().

    Warning

    This function is deprecated and will be removed in a future release.

    ec is the node structure of the node to unregister.

    If the node was successfully unregistered from EPMD, the function returns 0. @@ -814,7 +814,7 @@

    ei_unpublish_tmo()

    -
    int ei_unpublish_tmo(ei_cnode *ec, unsigned timeout_ms);

    Equivalent to ei_unpublish with an optional time-out argument, see the +

    int ei_unpublish_tmo(ei_cnode *ec, unsigned timeout_ms);

    Equivalent to ei_unpublish with an optional time-out argument, see the description at the beginning of this manual page.

    diff --git a/prs/8803/lib/erl_interface-5.5.2/doc/html/ei_global.html b/prs/8803/lib/erl_interface-5.5.2/doc/html/ei_global.html index 36c0d0b194f07..ee55ba750c1de 100644 --- a/prs/8803/lib/erl_interface-5.5.2/doc/html/ei_global.html +++ b/prs/8803/lib/erl_interface-5.5.2/doc/html/ei_global.html @@ -132,7 +132,7 @@

    ei_global_names()

    -
    char **ei_global_names(ei_cnode *ec, int fd, int *count);

    Retrieves a list of all known global names.

    • ec is the ei_cnode representing the current cnode.
    • fd is an open descriptor to an Erlang connection.
    • count is the address of an integer, or NULL. If count is not NULL, it +
      char **ei_global_names(ei_cnode *ec, int fd, int *count);

      Retrieves a list of all known global names.

      • ec is the ei_cnode representing the current cnode.
      • fd is an open descriptor to an Erlang connection.
      • count is the address of an integer, or NULL. If count is not NULL, it is set by the function to the number of names found.

      On success, the function returns an array of strings, each containing a single registered name, and sets count to the number of names found. The array is terminated by a single NULL pointer. On failure, the function returns NULL @@ -144,20 +144,20 @@

      ei_global_register()

      -
      int ei_global_register(int fd, const char *name, erlang_pid *self);

      Registers a name in global.

      • fd is an open descriptor to an Erlang connection.
      • name is the name to register in global.
      • pid is the pid that is to be associated with name. This value is returned +
        int ei_global_register(int fd, const char *name, erlang_pid *self);

        Registers a name in global.

        • fd is an open descriptor to an Erlang connection.
        • name is the name to register in global.
        • pid is the pid that is to be associated with name. This value is returned by global when processes request the location of name.

        Returns 0 on success, otherwise -1.

        Available since OTP 23.0

        ei_global_unregister()

        -
        int ei_global_unregister(ei_cnode *ec, int fd, const char *name);

        Unregisters a name from global.

        • ec is the ei_cnode representing the current cnode.
        • fd is an open descriptor to an Erlang connection.
        • name is the name to unregister from global.

        Returns 0 on success, otherwise -1.

        Available since OTP 23.0

        +
        int ei_global_unregister(ei_cnode *ec, int fd, const char *name);

        Unregisters a name from global.

        • ec is the ei_cnode representing the current cnode.
        • fd is an open descriptor to an Erlang connection.
        • name is the name to unregister from global.

        Returns 0 on success, otherwise -1.

        Available since OTP 23.0

        ei_global_whereis()

        -
        int ei_global_whereis(ei_cnode *ec, int fd, const char *name, erlang_pid* pid, char *node);

        Looks up a name in global.

        • ec is the ei_cnode representing the current cnode.
        • fd is an open descriptor to an Erlang connection.
        • name is the name that is to be looked up in global.

        The pid parameter is a pointer to a erlang_pid that the function will update +

        int ei_global_whereis(ei_cnode *ec, int fd, const char *name, erlang_pid* pid, char *node);

        Looks up a name in global.

        • ec is the ei_cnode representing the current cnode.
        • fd is an open descriptor to an Erlang connection.
        • name is the name that is to be looked up in global.

        The pid parameter is a pointer to a erlang_pid that the function will update with the pid associated with the global name, if successful.

        If node is not NULL, it is a pointer to a buffer where the function can fill in the name of the node where name is found. node can be passed directly to ei_connect() if necessary.

        On success, the function returns 0, updates the erlang_pid pointed to by the diff --git a/prs/8803/lib/erl_interface-5.5.2/doc/html/ei_users_guide.html b/prs/8803/lib/erl_interface-5.5.2/doc/html/ei_users_guide.html index ab52cfe9e5c83..ae03106a9bbed 100644 --- a/prs/8803/lib/erl_interface-5.5.2/doc/html/ei_users_guide.html +++ b/prs/8803/lib/erl_interface-5.5.2/doc/html/ei_users_guide.html @@ -180,11 +180,11 @@

        Erlang.

        The Erl_Interface library supports this activity. It has several C functions that create and manipulate Erlang data structures. The following example shows how to create and encode an Erlang tuple {tobbe,3928}:

        ei_x_buff buf;
        -ei_x_new(&buf);
        +ei_x_new(&buf);
         int i = 0;
        -ei_x_encode_tuple_header(&buf, 2);
        -ei_x_encode_atom(&buf, "tobbe");
        -ei_x_encode_long(&buf, 3928);

        For a complete description, see the ei module.

        +ei_x_encode_tuple_header(&buf, 2); +ei_x_encode_atom(&buf, "tobbe"); +ei_x_encode_long(&buf, 3928);

        For a complete description, see the ei module.

        @@ -193,18 +193,18 @@

        The previous example can be simplified by using the ei_x_format_wo_ver function to create an Erlang term:

        ei_x_buff buf;
        -ei_x_new(&buf);
        -ei_x_format_wo_ver(&buf, "{~a,~i}", "tobbe", 3928);

        For a complete description of the different format directives, see the the +ei_x_new(&buf); +ei_x_format_wo_ver(&buf, "{~a,~i}", "tobbe", 3928);

        For a complete description of the different format directives, see the the ei_x_format_wo_ver function.

        The following example is more complex:

        ei_x_buff buf;
         int i = 0;
        -ei_x_new(&buf);
        -ei_x_format_wo_ver(&buf,
        +ei_x_new(&buf);
        +ei_x_format_wo_ver(&buf,
                            "[{name,~a},{age,~i},{data,[{adr,~s,~i}]}]",
                            "madonna",
                            21,
        -                  "E-street", 42);
        -ei_print_term(stdout, buf.buff, &i);
        -ei_x_free(&buf);

        As in the previous examples, it is your responsibility to free the memory + "E-street", 42); +ei_print_term(stdout, buf.buff, &i); +ei_x_free(&buf);

        As in the previous examples, it is your responsibility to free the memory allocated for Erlang terms. In this example, ei_x_free() ensures that the data pointed to by buf is released.

        @@ -220,18 +220,18 @@

        char *cookie="a secret cookie string"; /* An example */ const char* node_name = "einode@durin"; const char *cookie = NULL; -short creation = time(NULL) + 1; +short creation = time(NULL) + 1; ei_cnode ec; -ei_connect_init(&ec, +ei_connect_init(&ec, node_name, cookie, - creation);

        For more information, see the ei_connect module.

        After initialization, you set up the connection to the Erlang node. To specify + creation);

        For more information, see the ei_connect module.

        After initialization, you set up the connection to the Erlang node. To specify the Erlang node you want to connect to, use the ei_connect_*() family of functions. The following example sets up the connection and is to result in a valid socket file descriptor:

        int sockfd;
         const char* node_name = "einode@durin"; /* An example */
        -if ((sockfd = ei_connect(&ec, nodename)) < 0)
        -  fprintf(stderr, "ERROR: ei_connect failed");

        +if ((sockfd = ei_connect(&ec, nodename)) < 0) + fprintf(stderr, "ERROR: ei_connect failed");

        @@ -246,7 +246,7 @@

        connection is first made to epmd and, if the node is known, a connection is then made to the Erlang node.

        C nodes can also register themselves with epmd if they want other nodes in the system to be able to find and connect to them.

        Before registering with epmd, you must first create a listen socket and bind -it to a port. Then:

        int pub = ei_publish(&ec, port);

        pub is a file descriptor now connected to epmd. epmd monitors the other +it to a port. Then:

        int pub = ei_publish(&ec, port);

        pub is a file descriptor now connected to epmd. epmd monitors the other end of the connection. If it detects that the connection has been closed, the node becomes unregistered. So, if you explicitly close the descriptor or if your node fails, it becomes unregistered from epmd.

        Notice that on some systems a failed node is not detected by this mechanism, as @@ -269,13 +269,13 @@

        In the following example, {Pid, hello_world} is sent to a registered process my_server:

        ei_x_buff buf;
        -ei_x_new_with_version(&buf);
        +ei_x_new_with_version(&buf);
         
        -ei_x_encode_tuple_header(&buf, 2);
        -ei_x_encode_pid(&buf, ei_self(ec));
        -ei_x_encode_atom(&buf, "Hello world");
        +ei_x_encode_tuple_header(&buf, 2);
        +ei_x_encode_pid(&buf, ei_self(ec));
        +ei_x_encode_atom(&buf, "Hello world");
         
        -ei_reg_send(&ec, fd, "my_server", buf.buff, buf.index);

        The first element of the tuple that is sent is your own pid. This enables +ei_reg_send(&ec, fd, "my_server", buf.buff, buf.index);

        The first element of the tuple that is sent is your own pid. This enables my_server to reply. For more information about the primitives, see the ei_connect module.

        @@ -289,24 +289,24 @@

        int arity = 0; erlang_pid pid; ei_x_buff buf; -ei_x_new(&buf); -for (;;) { - int got = ei_xreceive_msg(fd, &msg, &x); - if (got == ERL_TICK) +ei_x_new(&buf); +for (;;) { + int got = ei_xreceive_msg(fd, &msg, &x); + if (got == ERL_TICK) continue; - if (got == ERL_ERROR) { - fprintf(stderr, "ei_xreceive_msg, got==%d", got); - exit(1); - } + if (got == ERL_ERROR) { + fprintf(stderr, "ei_xreceive_msg, got==%d", got); + exit(1); + } break; -} -ei_decode_version(buf.buff, &index, &version); -ei_decode_tuple_header(buf.buff, &index, &arity); -if (arity != 2) { - fprintf(stderr, "got wrong message"); - exit(1); -} -ei_decode_pid(buf.buff, &index, &pid);

        To provide robustness, a distributed Erlang node occasionally polls all its +} +ei_decode_version(buf.buff, &index, &version); +ei_decode_tuple_header(buf.buff, &index, &arity); +if (arity != 2) { + fprintf(stderr, "got wrong message"); + exit(1); +} +ei_decode_pid(buf.buff, &index, &pid);

        To provide robustness, a distributed Erlang node occasionally polls all its connected neighbors in an attempt to detect failed nodes or communication links. A node that receives such a message is expected to respond immediately with an ERL_TICK message. This is done automatically by ei_xreceive_msg(). However, @@ -324,19 +324,19 @@

        a remote node and is called a remote procedure call.

        The following example checks if a specific Erlang process is alive:

        int index = 0, is_alive;
         ei_x_buff args, result;
         
        -ei_x_new(&result);
        -ei_x_new(&args);
        -ei_x_encode_list_header(&args, 1);
        -ei_x_encode_pid(&args, &check_pid);
        -ei_x_encode_empty_list(&args);
        +ei_x_new(&result);
        +ei_x_new(&args);
        +ei_x_encode_list_header(&args, 1);
        +ei_x_encode_pid(&args, &check_pid);
        +ei_x_encode_empty_list(&args);
         
        -if (ei_rpc(&ec, fd, "erlang", "is_process_alive",
        -           args.buff, args.index, &result) < 0)
        -    handle_error();
        +if (ei_rpc(&ec, fd, "erlang", "is_process_alive",
        +           args.buff, args.index, &result) < 0)
        +    handle_error();
         
        -if (ei_decode_version(result.buff, &index) < 0
        -    || ei_decode_bool(result.buff, &index, &is_alive) < 0)
        -    handle_error();

        For more information about ei_rpc() and its companions ei_rpc_to() and +if (ei_decode_version(result.buff, &index) < 0 + || ei_decode_bool(result.buff, &index, &is_alive) < 0) + handle_error();

        For more information about ei_rpc() and its companions ei_rpc_to() and ei_rpc_from(), see the ei_connect module.

        @@ -353,32 +353,32 @@

        int count; int i; -names = ei_global_names(&ec,fd,&count); +names = ei_global_names(&ec,fd,&count); -if (names) - for (i=0; i<count; i++) - printf("%s\n",names[i]); +if (names) + for (i=0; i<count; i++) + printf("%s\n",names[i]); -free(names);

        ei_global_names allocates and returns a buffer +free(names);

        ei_global_names allocates and returns a buffer containing all the names known to the global module in Kernel. count is initialized to indicate the number of names in the array. The array of strings in names is terminated by a NULL pointer, so it is not necessary to use count to determine when the last name is reached.

        It is the caller's responsibility to free the array. ei_global_names allocates the array and all the strings using a single call to malloc(), so free(names) is all that is necessary.

        To look up one of the names:

        ETERM *pid;
        -char node[256];
        +char node[256];
         erlang_pid the_pid;
         
        -if (ei_global_whereis(&ec,fd,"schedule",&the_pid,node) < 0)
        -   fprintf(stderr, "ei_global_whereis error\n");

        If "schedule" is known to the global module in Kernel, an Erlang pid is +if (ei_global_whereis(&ec,fd,"schedule",&the_pid,node) < 0) + fprintf(stderr, "ei_global_whereis error\n");

        If "schedule" is known to the global module in Kernel, an Erlang pid is written to the_pid. This pid that can be used to send messages to the schedule service. Also, node is initialized to contain the name of the node where the service is registered, so that you can make a connection to it by simply passing the variable to ei_connect.

        Before registering a name, you should already have registered your port number with epmd. This is not strictly necessary, but if you neglect to do so, then other nodes wishing to communicate with your service cannot find or connect to -your process.

        Create a name that Erlang processes can use to communicate with your service:

        ei_global_register(fd,servicename,ei_self(ec));

        After registering the name, use ei_accept to wait -for incoming connections.

        Note

        Remember to free pid later with ei_x_free.

        To unregister a name:

        ei_global_unregister(&ec,fd,servicename);
        +your process.

        Create a name that Erlang processes can use to communicate with your service:

        ei_global_register(fd,servicename,ei_self(ec));

        After registering the name, use ei_accept to wait +for incoming connections.

        Note

        Remember to free pid later with ei_x_free.

        To unregister a name:

        ei_global_unregister(&ec,fd,servicename);
        diff --git a/prs/8803/lib/erl_interface-5.5.2/doc/html/erl_call_cmd.html b/prs/8803/lib/erl_interface-5.5.2/doc/html/erl_call_cmd.html index 3f2899336d41a..b175e3b12955f 100644 --- a/prs/8803/lib/erl_interface-5.5.2/doc/html/erl_call_cmd.html +++ b/prs/8803/lib/erl_interface-5.5.2/doc/html/erl_call_cmd.html @@ -251,8 +251,8 @@

        {<madonna@chivas.du.etx.ericsson.se,38,0>, []}]

        To forward standard output without printing the result term (again, the input ends with EOF (Control-D)):

        erl_call -s -e -sname madonna -fetch_stdout -no_result_term
        -io:format("Number of schedulers: ~p~n", [erlang:system_info(schedulers)]),
        -io:format("Number of logical cores: ~p~n", [erlang:system_info(logical_processors_available)]).
        +io:format("Number of schedulers: ~p~n", [erlang:system_info(schedulers)]),
        +io:format("Number of logical cores: ~p~n", [erlang:system_info(logical_processors_available)]).
         ^D
         Number of schedulers: 8
         Number of logical cores: 8
        diff --git a/prs/8803/lib/erl_interface-5.5.2/doc/html/erl_interface.epub b/prs/8803/lib/erl_interface-5.5.2/doc/html/erl_interface.epub index 046705d178e32..938e7b1983dcf 100644 Binary files a/prs/8803/lib/erl_interface-5.5.2/doc/html/erl_interface.epub and b/prs/8803/lib/erl_interface-5.5.2/doc/html/erl_interface.epub differ diff --git a/prs/8803/lib/et-1.7.1/doc/html/et.epub b/prs/8803/lib/et-1.7.1/doc/html/et.epub index 55d6e2fb085da..8c1bfaf234de9 100644 Binary files a/prs/8803/lib/et-1.7.1/doc/html/et.epub and b/prs/8803/lib/et-1.7.1/doc/html/et.epub differ diff --git a/prs/8803/lib/et-1.7.1/doc/html/et_desc.html b/prs/8803/lib/et-1.7.1/doc/html/et_desc.html index 575d23c906a15..0510d0780f26a 100644 --- a/prs/8803/lib/et-1.7.1/doc/html/et_desc.html +++ b/prs/8803/lib/et-1.7.1/doc/html/et_desc.html @@ -138,33 +138,33 @@

        enable other types of Viewers. However in the following text we will focus on usage of the et_viewer.

        The main start function is et_viewer:start/1. By default it will start both an et_collector and an et_viewer:

        % erl -pa et/examples
        -Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
        +Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
         
        -Eshell V5.7.4  (abort with ^G)
        -1> {ok, Viewer} = et_viewer:start([]).
        -{ok,<0.40.0>}

        A Viewer gets trace Events from its Collector by polling it regularly for +Eshell V5.7.4 (abort with ^G) +1> {ok, Viewer} = et_viewer:start([]). +{ok,<0.40.0>}

        A Viewer gets trace Events from its Collector by polling it regularly for more Events to display. Events are for example reported to the Collector -with et_collector:report_event/6:

        2> Collector = et_viewer:get_collector_pid(Viewer).
        +with et_collector:report_event/6:

        2> Collector = et_viewer:get_collector_pid(Viewer).
         <0.39.0>
        -3> et_collector:report_event(Collector, 60, my_shell, mnesia_tm, start_outer,
        -3>                           "Start outer transaction"),
        -3> et_collector:report_event(Collector, 40, mnesia_tm, my_shell, new_tid,
        -3>                           "New transaction id is 4711"),
        -3> et_collector:report_event(Collector, 20, my_shell, mnesia_locker, try_write_lock,
        -3>                           "Acquire write lock for {my_tab, key}"),
        -3> et_collector:report_event(Collector, 10, mnesia_locker, my_shell, granted,
        -3>                           "You got the write lock for {my_tab, key}"),
        -3> et_collector:report_event(Collector, 60, my_shell, do_commit,
        -3>                           "Perform  transaction commit"),
        -3> et_collector:report_event(Collector, 40, my_shell, mnesia_locker, release_tid,
        -3>                           "Release all locks for transaction 4711"),
        -3> et_collector:report_event(Collector, 60, my_shell, mnesia_tm, delete_transaction,
        -3>                           "End of outer transaction"),
        -3> et_collector:report_event(Collector, 20, my_shell, end_outer,
        -3>                           "Transaction returned {atomic, ok}").
        -{ok,{table_handle,<0.39.0>,16402,trace_ts,
        -     #Fun<et_collector.0.62831470>}}

        This actually is a simulation of the process Events caused by a Mnesia -transaction that writes a record in a local table:

        mnesia:transaction(fun() -> mnesia:write({my_tab, key, val}) end).

        At this stage when we have a couple of Events, it is time to show how it looks +3> et_collector:report_event(Collector, 60, my_shell, mnesia_tm, start_outer, +3> "Start outer transaction"), +3> et_collector:report_event(Collector, 40, mnesia_tm, my_shell, new_tid, +3> "New transaction id is 4711"), +3> et_collector:report_event(Collector, 20, my_shell, mnesia_locker, try_write_lock, +3> "Acquire write lock for {my_tab, key}"), +3> et_collector:report_event(Collector, 10, mnesia_locker, my_shell, granted, +3> "You got the write lock for {my_tab, key}"), +3> et_collector:report_event(Collector, 60, my_shell, do_commit, +3> "Perform transaction commit"), +3> et_collector:report_event(Collector, 40, my_shell, mnesia_locker, release_tid, +3> "Release all locks for transaction 4711"), +3> et_collector:report_event(Collector, 60, my_shell, mnesia_tm, delete_transaction, +3> "End of outer transaction"), +3> et_collector:report_event(Collector, 20, my_shell, end_outer, +3> "Transaction returned {atomic, ok}"). +{ok,{table_handle,<0.39.0>,16402,trace_ts, + #Fun<et_collector.0.62831470>}}

        This actually is a simulation of the process Events caused by a Mnesia +transaction that writes a record in a local table:

        mnesia:transaction(fun() -> mnesia:write({my_tab, key, val}) end).

        At this stage when we have a couple of Events, it is time to show how it looks like in the graphical interface of et_viewer:

        A simulated Mnesia transaction which writes one record

        In the sequence chart, the actors (which symbolically has performed the Event) are shown as named vertical bars. The order of the actors may be altered by dragging (hold mouse button 1 pressed during the operation) the name tag of an @@ -181,11 +181,11 @@

        The Event Tracer (ET) uses named filters in various contexts. An Event Trace filter is an Erlang fun that takes some trace data as input and returns a -possibly modified version of it:

        filter(TraceData) -> false | true | {true, NewEvent}
        +possibly modified version of it:

        filter(TraceData) -> false | true | {true, NewEvent}
         
        -TraceData = Event | erlang_trace_data()
        -Event = #event{}
        -NewEvent = #event{}

        The interface of the filter function is the same as the the filter functions for +TraceData = Event | erlang_trace_data() +Event = #event{} +NewEvent = #event{}

        The interface of the filter function is the same as the the filter functions for the good old lists:filtermap/2. If the filter returns false it means that the trace data should silently be dropped. true means that the trace data data already is an Event Record and that it should be kept as it is. true means @@ -212,21 +212,21 @@

        in the viewer. The following filter in et/examples/et_demo.erl replaces the actor names mnesia_tm and mnesia_locker and leaves everything else in the record as it was:

        
        -mgr_actors(E) when is_record(E, event) ->
        -    Actor = fun(A) ->
        +mgr_actors(E) when is_record(E, event) ->
        +    Actor = fun(A) ->
                        case A of
                            mnesia_tm     -> trans_mgr;
                            mnesia_locker -> lock_mgr;
                            _             -> A
                        end
                     end,
        -    {true, E#event{from = Actor(E#event.from),
        -                   to = Actor(E#event.to),
        -                   contents = [{orig_from, E#event.from},
        -                               {orig_to,   E#event.to},
        -                               {orig_contents, E#event.contents}]}}.

        If we now add the filter to the running Collector:

        4> Fun = fun(E) -> et_demo:mgr_actors(E) end.
        +    {true, E#event{from = Actor(E#event.from),
        +                   to = Actor(E#event.to),
        +                   contents = [{orig_from, E#event.from},
        +                               {orig_to,   E#event.to},
        +                               {orig_contents, E#event.contents}]}}.

        If we now add the filter to the running Collector:

        4> Fun = fun(E) -> et_demo:mgr_actors(E) end.
         #Fun<erl_eval.6.13229925>
        -5> et_collector:dict_insert(Collector, {filter, mgr_actors}, Fun).
        +5> et_collector:dict_insert(Collector, {filter, mgr_actors}, Fun).
         ok

        you will see that the Filter menu in all viewers have got a new entry called mgr_actors. Select it, and a new Viewer window will pop up:

        The same trace data in a different view

        In order to see the nitty gritty details of an Event you may click on the Event in order to start a Contents Viewer for that Event. In the diff --git a/prs/8803/lib/et-1.7.1/doc/html/et_examples.html b/prs/8803/lib/et-1.7.1/doc/html/et_examples.html index df55e4ffb69a4..b8c09118509f0 100644 --- a/prs/8803/lib/et-1.7.1/doc/html/et_examples.html +++ b/prs/8803/lib/et-1.7.1/doc/html/et_examples.html @@ -133,52 +133,52 @@

        The Erlang code for running the simulated Mnesia transaction example in the previous chapter is included in the et/examples/et_demo.erl file:

        
        -sim_trans() ->
        -    sim_trans([]).
        -
        -sim_trans(ExtraOptions) ->
        -    Options = [{dict_insert, {filter, mgr_actors}, fun mgr_actors/1}],
        -    {ok, Viewer} = et_viewer:start_link(Options ++ ExtraOptions),
        -    Collector = et_viewer:get_collector_pid(Viewer),
        -    et_collector:report_event(Collector, 60, my_shell, mnesia_tm, start_outer,
        -                              "Start outer transaction"),
        -    et_collector:report_event(Collector, 40, mnesia_tm, my_shell, new_tid,
        -                              "New transaction id is 4711"),
        -    et_collector:report_event(Collector, 20, my_shell, mnesia_locker, try_write_lock,
        -                              "Acquire write lock for {my_tab, key}"),
        -    et_collector:report_event(Collector, 10, mnesia_locker, my_shell, granted,
        -                              "You got the write lock for {my_tab, key}"),
        -    et_collector:report_event(Collector, 60, my_shell, do_commit,
        -                              "Perform  transaction commit"),
        -    et_collector:report_event(Collector, 40, my_shell, mnesia_locker, release_tid,
        -                              "Release all locks for transaction 4711"),
        -    et_collector:report_event(Collector, 60, my_shell, mnesia_tm, delete_transaction,
        -                              "End of outer transaction"),
        -    et_collector:report_event(Collector, 20, my_shell, end_outer,
        -                              "Transaction returned {atomic, ok}"),
        -    {collector, Collector}.
        
        -mgr_actors(E) when is_record(E, event) ->
        -    Actor = fun(A) ->
        +sim_trans() ->
        +    sim_trans([]).
        +
        +sim_trans(ExtraOptions) ->
        +    Options = [{dict_insert, {filter, mgr_actors}, fun mgr_actors/1}],
        +    {ok, Viewer} = et_viewer:start_link(Options ++ ExtraOptions),
        +    Collector = et_viewer:get_collector_pid(Viewer),
        +    et_collector:report_event(Collector, 60, my_shell, mnesia_tm, start_outer,
        +                              "Start outer transaction"),
        +    et_collector:report_event(Collector, 40, mnesia_tm, my_shell, new_tid,
        +                              "New transaction id is 4711"),
        +    et_collector:report_event(Collector, 20, my_shell, mnesia_locker, try_write_lock,
        +                              "Acquire write lock for {my_tab, key}"),
        +    et_collector:report_event(Collector, 10, mnesia_locker, my_shell, granted,
        +                              "You got the write lock for {my_tab, key}"),
        +    et_collector:report_event(Collector, 60, my_shell, do_commit,
        +                              "Perform  transaction commit"),
        +    et_collector:report_event(Collector, 40, my_shell, mnesia_locker, release_tid,
        +                              "Release all locks for transaction 4711"),
        +    et_collector:report_event(Collector, 60, my_shell, mnesia_tm, delete_transaction,
        +                              "End of outer transaction"),
        +    et_collector:report_event(Collector, 20, my_shell, end_outer,
        +                              "Transaction returned {atomic, ok}"),
        +    {collector, Collector}.
        
        +mgr_actors(E) when is_record(E, event) ->
        +    Actor = fun(A) ->
                        case A of
                            mnesia_tm     -> trans_mgr;
                            mnesia_locker -> lock_mgr;
                            _             -> A
                        end
                     end,
        -    {true, E#event{from = Actor(E#event.from),
        -                   to = Actor(E#event.to),
        -                   contents = [{orig_from, E#event.from},
        -                               {orig_to,   E#event.to},
        -                               {orig_contents, E#event.contents}]}}.

        If you invoke the et_demo:sim_trans() function, a Viewer window will pop up + {true, E#event{from = Actor(E#event.from), + to = Actor(E#event.to), + contents = [{orig_from, E#event.from}, + {orig_to, E#event.to}, + {orig_contents, E#event.contents}]}}.

        If you invoke the et_demo:sim_trans() function, a Viewer window will pop up and the sequence trace will be almost the same as if the following Mnesia -transaction would have been run:

        mnesia:transaction(fun() -> mnesia:write({my_tab, key, val}) end).

        And the viewer window will look like:

        Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
        -
        -Eshell V5.7.4  (abort with ^G)
        -1> {ok, Viewer} = et_viewer:start([]).
        -{ok,<0.40.0>;}
        -2> et_demo:sim_trans().
        -{ok,{table_handle,<0.45.0>,24596,trace_ts,
        -     #Fun<et_collector.0.62831470>}}

        A simulated Mnesia transaction which writes one record

        +transaction would have been run:

        mnesia:transaction(fun() -> mnesia:write({my_tab, key, val}) end).

        And the viewer window will look like:

        Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
        +
        +Eshell V5.7.4  (abort with ^G)
        +1> {ok, Viewer} = et_viewer:start([]).
        +{ok,<0.40.0>;}
        +2> et_demo:sim_trans().
        +{ok,{table_handle,<0.45.0>,24596,trace_ts,
        +     #Fun<et_collector.0.62831470>}}

        A simulated Mnesia transaction which writes one record

        @@ -190,20 +190,20 @@

        caller to the callee. The [{message, {caller}}, {return_trace}] options to dbg:tpl/2 function will imply the necessary information in the Erlang traces. Here follows the module_as_actor filter:

        
        -module_as_actor(E) when is_record(E, event) ->
        -    case lists:keysearch(mfa, 1, E#event.contents) of
        -        {value, {mfa, {M, F, _A}}} ->
        -            case lists:keysearch(pam_result, 1, E#event.contents) of
        -                {value, {pam_result, {M2, _F2, _A2}}} ->
        -                    {true, E#event{label = F, from = M2, to = M}};
        +module_as_actor(E) when is_record(E, event) ->
        +    case lists:keysearch(mfa, 1, E#event.contents) of
        +        {value, {mfa, {M, F, _A}}} ->
        +            case lists:keysearch(pam_result, 1, E#event.contents) of
        +                {value, {pam_result, {M2, _F2, _A2}}} ->
        +                    {true, E#event{label = F, from = M2, to = M}};
                         _ ->
        -                    {true, E#event{label = F, from = M, to = M}}
        +                    {true, E#event{label = F, from = M, to = M}}
                     end;
                 _ ->
                     false
             end.

        The plain_process_info filter does not alter the Event Records. It merely ensures that the event not related to processes are skipped:

        
        -plain_process_info(E) when is_record(E, event) ->
        +plain_process_info(E) when is_record(E, event) ->
             case E#event.label of
                 send                          -> true;
                 send_to_non_existing_process  -> true;
        @@ -213,50 +213,50 @@ 

        link -> true; unlink -> true; getting_linked -> true; - {seq_send, _Label} -> true; - {seq_receive, _Label} -> true; - {seq_print, _Label} -> true; - {drop, _N} -> true; + {seq_send, _Label} -> true; + {seq_receive, _Label} -> true; + {seq_print, _Label} -> true; + {drop, _N} -> true; _ -> false end.

        The plain_process_info_nolink filter does not alter the Event Records. It do makes use of the plain_process_info , but do also ensure that the process info related to linking and unlinking is skipped:

        
        -plain_process_info_nolink(E) when is_record(E, event) ->
        -    (E#event.label /= link) and
        -    (E#event.label /= unlink) and
        -    (E#event.label /= getting_linked) and
        -    plain_process_info(E).

        In order to simplify the startup of an et_viewer process with the filters +plain_process_info_nolink(E) when is_record(E, event) -> + (E#event.label /= link) and + (E#event.label /= unlink) and + (E#event.label /= getting_linked) and + plain_process_info(E).

        In order to simplify the startup of an et_viewer process with the filters mentioned above, plus some others (that also are found in et/examples/et_demo.erl src/et_collector.erl the et_demo:start/0,1 functions can be used:

        
        -start() ->
        -    start([]).
        -
        -start(ExtraOptions) ->
        -    Options = [{trace_global, true},
        -               {parent_pid, undefined},
        -               {max_actors, infinity},
        -               {max_events, 1000},
        -               {active_filter, module_as_actor}],
        -    et_viewer:start_link(filters() ++ Options ++ ExtraOptions).

        A simple one-liner starts the tool:

                  erl -pa ../examples -s et_demo

        The filters are included by the following parameters:

        
        -filters() ->
        -    [{dict_insert, {filter, module_as_actor},
        -                   fun module_as_actor/1},
        -     {dict_insert, {filter, plain_process_info},
        -                   fun plain_process_info/1},
        -     {dict_insert, {filter, plain_process_info_nolink},
        -                   fun plain_process_info_nolink/1},
        -     {dict_insert, {filter, named_process_info},
        -                   fun named_process_info/1},
        -     {dict_insert, {filter, named_process_info_nolink},
        -                   fun named_process_info_nolink/1},
        -     {dict_insert, {filter, node_process_info},
        -                   fun node_process_info/1},
        -     {dict_insert, {filter, node_process_info_nolink},
        -                   fun node_process_info_nolink/1},
        -     {dict_insert, {filter, application_as_actor},
        -                   fun application_as_actor/1}
        -    ].

        +start() -> + start([]). + +start(ExtraOptions) -> + Options = [{trace_global, true}, + {parent_pid, undefined}, + {max_actors, infinity}, + {max_events, 1000}, + {active_filter, module_as_actor}], + et_viewer:start_link(filters() ++ Options ++ ExtraOptions).

        A simple one-liner starts the tool:

                  erl -pa ../examples -s et_demo

        The filters are included by the following parameters:

        
        +filters() ->
        +    [{dict_insert, {filter, module_as_actor},
        +                   fun module_as_actor/1},
        +     {dict_insert, {filter, plain_process_info},
        +                   fun plain_process_info/1},
        +     {dict_insert, {filter, plain_process_info_nolink},
        +                   fun plain_process_info_nolink/1},
        +     {dict_insert, {filter, named_process_info},
        +                   fun named_process_info/1},
        +     {dict_insert, {filter, named_process_info_nolink},
        +                   fun named_process_info_nolink/1},
        +     {dict_insert, {filter, node_process_info},
        +                   fun node_process_info/1},
        +     {dict_insert, {filter, node_process_info_nolink},
        +                   fun node_process_info_nolink/1},
        +     {dict_insert, {filter, application_as_actor},
        +                   fun application_as_actor/1}
        +    ].

        @@ -270,33 +270,33 @@

        processes plus the calling process (that is your shell). Please, observe that the whereis/1 call in the following code requires that both the traced Mnesia application and the et_viewer is running on the same node:

        
        -trace_mnesia() ->
        -    Modules = mnesia:ms(),
        -    Spec = [{message, {caller}}, {return_trace}],
        -    Flags = [send, 'receive', procs, timestamp],
        -    dbg:p(all, [call, timestamp]),
        -    [dbg:tpl(M, [{'_', [], Spec}]) || M <- Modules],
        -    LocallyRunningServers = [M || M <- Modules, whereis(M) /= undefined],
        -    [dbg:p(whereis(RS), Flags) || RS <- LocallyRunningServers],
        -    dbg:p(self(), Flags),
        +trace_mnesia() ->
        +    Modules = mnesia:ms(),
        +    Spec = [{message, {caller}}, {return_trace}],
        +    Flags = [send, 'receive', procs, timestamp],
        +    dbg:p(all, [call, timestamp]),
        +    [dbg:tpl(M, [{'_', [], Spec}]) || M <- Modules],
        +    LocallyRunningServers = [M || M <- Modules, whereis(M) /= undefined],
        +    [dbg:p(whereis(RS), Flags) || RS <- LocallyRunningServers],
        +    dbg:p(self(), Flags),
             LocallyRunningServers.

        The et_demo:live_trans/0 function starts the global Collector, starts a Viewer, starts Mnesia, creates a local table, activates tracing (as described above) and registers the shell process is as 'my_shell' for clarity. Finally a simple Mnesia transaction that writes a single record is run:

        
        -live_trans() ->
        -    live_trans([]).
        -
        -live_trans(ExtraOptions) ->
        -    Options = [{title, "Mnesia tracer"},
        -	       {hide_actions, true},
        -	       {active_filter, named_process_info_nolink}],
        -    et_demo:start(Options ++ ExtraOptions),
        -    mnesia:start(),
        -    mnesia:create_table(my_tab, [{ram_copies, [node()]}]),
        -    et_demo:trace_mnesia(),
        -    register(my_shell, self()),
        -
        -    mnesia:transaction(fun() -> mnesia:write({my_tab, key, val}) end).

        Now we run the et_demo:live_trans/0 function:

        erl -pa ../examples
        +live_trans() ->
        +    live_trans([]).
        +
        +live_trans(ExtraOptions) ->
        +    Options = [{title, "Mnesia tracer"},
        +	       {hide_actions, true},
        +	       {active_filter, named_process_info_nolink}],
        +    et_demo:start(Options ++ ExtraOptions),
        +    mnesia:start(),
        +    mnesia:create_table(my_tab, [{ram_copies, [node()]}]),
        +    et_demo:trace_mnesia(),
        +    register(my_shell, self()),
        +
        +    mnesia:transaction(fun() -> mnesia:write({my_tab, key, val}) end).

        Now we run the et_demo:live_trans/0 function:

        erl -pa ../examples
         Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4]
                                    [async-threads:0] [kernel-poll:false]
         
        @@ -316,113 +316,113 @@ 

        with calls to et:trace_me/5. For each call a detail level is given in order to enable dynamic control of the trace level in a simple manner.

        The megaco_filter module implements a customized filter for Megaco messages. It does also make use of trace_global combined with usage of the -trace_pattern:

        -module(megaco_filter).
        --export([start/0]).
        +trace_pattern:

        -module(megaco_filter).
        +-export([start/0]).
         
        -start() ->
        +start() ->
             Options =
        -        [{event_order, event_ts},
        -         {scale, 3},
        -         {max_actors, infinity},
        -         {trace_pattern, {megaco, max}},
        -         {trace_global, true},
        -         {dict_insert, {filter, megaco_filter}, fun filter/1},
        -         {active_filter, megaco_filter},
        -         {title, "Megaco tracer - Erlang/OTP"}],
        -    et_viewer:start(Options).

        First we start an Erlang node with a global Collector and its Viewer.

        erl -sname observer
        -Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
        -
        -Eshell V5.7.4  (abort with ^G)
        -(observer@falco)1> megaco_filter:start().
        -{ok,<0.48.0>}

        Secondly we start another Erlang node which we connect the observer node, before + [{event_order, event_ts}, + {scale, 3}, + {max_actors, infinity}, + {trace_pattern, {megaco, max}}, + {trace_global, true}, + {dict_insert, {filter, megaco_filter}, fun filter/1}, + {active_filter, megaco_filter}, + {title, "Megaco tracer - Erlang/OTP"}], + et_viewer:start(Options).

        First we start an Erlang node with a global Collector and its Viewer.

        erl -sname observer
        +Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
        +
        +Eshell V5.7.4  (abort with ^G)
        +(observer@falco)1> megaco_filter:start().
        +{ok,<0.48.0>}

        Secondly we start another Erlang node which we connect the observer node, before we start the application that we want to trace. In this case we start a Media Gateway Controller that listens for both TCP and UDP on the text and binary ports for Megaco:

        erl -sname mgc -pa ../../megaco/examples/simple
        -Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
        +Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
         
        -Eshell V5.7.4  (abort with ^G)
        -(mgc@falco)1> net:ping(observer@falco).
        +Eshell V5.7.4  (abort with ^G)
        +(mgc@falco)1> net:ping(observer@falco).
         pong
        -(mgc@falco)2> megaco:start().
        +(mgc@falco)2> megaco:start().
         ok
        -(mgc@falco)3> megaco_simple_mgc:start().
        -{ok,[{ok,2944,
        -         {megaco_receive_handle,{deviceName,"controller"},
        -                                megaco_pretty_text_encoder,[],megaco_tcp,dynamic}},
        -     {ok,2944,
        -         {megaco_receive_handle,{deviceName,"controller"},
        -                                megaco_pretty_text_encoder,[],megaco_udp,dynamic}},
        -     {ok,2945,
        -         {megaco_receive_handle,{deviceName,"controller"},
        -                                megaco_binary_encoder,[],megaco_tcp,dynamic}},
        -     {ok,2945,
        -         {megaco_receive_handle,{deviceName,"controller"},
        -                                megaco_binary_encoder,[],megaco_udp,dynamic}}]}

        And finally we start an Erlang node for the Media Gateways and connect to the +(mgc@falco)3> megaco_simple_mgc:start(). +{ok,[{ok,2944, + {megaco_receive_handle,{deviceName,"controller"}, + megaco_pretty_text_encoder,[],megaco_tcp,dynamic}}, + {ok,2944, + {megaco_receive_handle,{deviceName,"controller"}, + megaco_pretty_text_encoder,[],megaco_udp,dynamic}}, + {ok,2945, + {megaco_receive_handle,{deviceName,"controller"}, + megaco_binary_encoder,[],megaco_tcp,dynamic}}, + {ok,2945, + {megaco_receive_handle,{deviceName,"controller"}, + megaco_binary_encoder,[],megaco_udp,dynamic}}]}

        And finally we start an Erlang node for the Media Gateways and connect to the observer node. Each Media Gateway connects to the controller and sends an initial Service Change message. The controller accepts the gateways and sends a reply to each one using the same transport mechanism and message encoding according to the preference of each gateway. That is all combinations of TCP/IP -transport, UDP/IP transport, text encoding and ASN.1 BER encoding:

        Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
        +transport, UDP/IP transport, text encoding and ASN.1 BER encoding:

        Erlang R13B03 (erts-5.7.4) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
         
        -Eshell V5.7.4  (abort with ^G)
        -(mg@falco)1> net:ping(observer@falco).
        +Eshell V5.7.4  (abort with ^G)
        +(mg@falco)1> net:ping(observer@falco).
         pong
        -(mg@falco)2> megaco_simple_mg:start().
        -[{{deviceName,"gateway_tt"},
        -  {error,{start_user,megaco_not_started}}},
        - {{deviceName,"gateway_tb"},
        -  {error,{start_user,megaco_not_started}}},
        - {{deviceName,"gateway_ut"},
        -  {error,{start_user,megaco_not_started}}},
        - {{deviceName,"gateway_ub"},
        -  {error,{start_user,megaco_not_started}}}]
        -(mg@falco)3> megaco:start().
        +(mg@falco)2> megaco_simple_mg:start().
        +[{{deviceName,"gateway_tt"},
        +  {error,{start_user,megaco_not_started}}},
        + {{deviceName,"gateway_tb"},
        +  {error,{start_user,megaco_not_started}}},
        + {{deviceName,"gateway_ut"},
        +  {error,{start_user,megaco_not_started}}},
        + {{deviceName,"gateway_ub"},
        +  {error,{start_user,megaco_not_started}}}]
        +(mg@falco)3> megaco:start().
         ok
        -(mg@falco)4> megaco_simple_mg:start().
        -[{{deviceName,"gateway_tt"},
        -  {1,
        -   {ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
        -            [{serviceChangeReply,
        -                 {'ServiceChangeReply',
        -                     [{megaco_term_id,false,["root"]}],
        -                     {serviceChangeResParms,
        -                         {'ServiceChangeResParm',
        -                             {deviceName,"controller"},
        +(mg@falco)4> megaco_simple_mg:start().
        +[{{deviceName,"gateway_tt"},
        +  {1,
        +   {ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
        +            [{serviceChangeReply,
        +                 {'ServiceChangeReply',
        +                     [{megaco_term_id,false,["root"]}],
        +                     {serviceChangeResParms,
        +                         {'ServiceChangeResParm',
        +                             {deviceName,"controller"},
                                      asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
        -                             asn1_NOVALUE}}}}]}]}}},
        - {{deviceName,"gateway_tb"},
        -  {1,
        -   {ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
        -            [{serviceChangeReply,
        -                 {'ServiceChangeReply',
        -                     [{megaco_term_id,false,["root"]}],
        -                     {serviceChangeResParms,
        -                         {'ServiceChangeResParm',
        -                             {deviceName,"controller"},
        +                             asn1_NOVALUE}}}}]}]}}},
        + {{deviceName,"gateway_tb"},
        +  {1,
        +   {ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
        +            [{serviceChangeReply,
        +                 {'ServiceChangeReply',
        +                     [{megaco_term_id,false,["root"]}],
        +                     {serviceChangeResParms,
        +                         {'ServiceChangeResParm',
        +                             {deviceName,"controller"},
                                      asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
        -                             asn1_NOVALUE}}}}]}]}}},
        - {{deviceName,"gateway_ut"},
        -  {1,
        -   {ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
        -            [{serviceChangeReply,
        -                 {'ServiceChangeReply',
        -                     [{megaco_term_id,false,["root"]}],
        -                     {serviceChangeResParms,
        -                         {'ServiceChangeResParm',
        -                             {deviceName,"controller"},
        +                             asn1_NOVALUE}}}}]}]}}},
        + {{deviceName,"gateway_ut"},
        +  {1,
        +   {ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
        +            [{serviceChangeReply,
        +                 {'ServiceChangeReply',
        +                     [{megaco_term_id,false,["root"]}],
        +                     {serviceChangeResParms,
        +                         {'ServiceChangeResParm',
        +                             {deviceName,"controller"},
                                      asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
        -                             asn1_NOVALUE}}}}]}]}}},
        - {{deviceName,"gateway_ub"},
        -  {1,
        -   {ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
        -            [{serviceChangeReply,
        -                 {'ServiceChangeReply',
        -                     [{megaco_term_id,false,["root"]}],
        -                     {serviceChangeResParms,
        -                         {'ServiceChangeResParm',
        -                             {deviceName,"controller"},
        +                             asn1_NOVALUE}}}}]}]}}},
        + {{deviceName,"gateway_ub"},
        +  {1,
        +   {ok,[{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
        +            [{serviceChangeReply,
        +                 {'ServiceChangeReply',
        +                     [{megaco_term_id,false,["root"]}],
        +                     {serviceChangeResParms,
        +                         {'ServiceChangeResParm',
        +                             {deviceName,"controller"},
                                      asn1_NOVALUE,asn1_NOVALUE,
        -                             asn1_NOVALUE,...}}}}]}]}}}]

        The Megaco adopted viewer looks like this, when we have clicked on the + asn1_NOVALUE,...}}}}]}]}}}]

        The Megaco adopted viewer looks like this, when we have clicked on the [gateway_tt] actor name in order to only display the events regarding that actor:

        The viewer adopted for Megaco

        A pretty printed Megaco message looks like this:

        A textual Megaco message

        And the corresponding internal form for the same Megaco message looks like this:

        The internal form of a Megaco message

        diff --git a/prs/8803/lib/et-1.7.1/doc/html/et_tutorial.html b/prs/8803/lib/et-1.7.1/doc/html/et_tutorial.html index c4636536820b4..c54dc0c35ee9f 100644 --- a/prs/8803/lib/et-1.7.1/doc/html/et_tutorial.html +++ b/prs/8803/lib/et-1.7.1/doc/html/et_tutorial.html @@ -133,8 +133,8 @@

        The easiest way of using ET, is to just use it as a graphical tool for displaying message sequence charts. In order to do that you need to first start -a Viewer (which by default starts a Collector):

              {ok, ViewerPid} = et_viewer:start([{title,"Coffee Order"}]),
        -      CollectorPid = et_viewer:get_collector_pid(ViewerPid).

        Then you send events to the Collector with the function +a Viewer (which by default starts a Collector):

              {ok, ViewerPid} = et_viewer:start([{title,"Coffee Order"}]),
        +      CollectorPid = et_viewer:get_collector_pid(ViewerPid).

        Then you send events to the Collector with the function et_collector:report_event/6 like this:

              et_collector:report_event(CollectorPid,85,from,to,message,extra_stuff).

        The Viewer will automatically pull events from the Collector and display them on the screen.

        The number (in this case 85) is an integer from 1 to 100 that specifies the "detail level" of the message. The higher the number, the more important it is. @@ -144,30 +144,30 @@

        displayed next to the lifeline as an "action". The extra_stuffvalue is simply data that you can attach that will be displayed when someone actually clicks on the action or message in the Viewer window.

        The module et/examples/et_display_demo.erl illustrates how it can be used:

        
        --module(et_display_demo).
        +-module(et_display_demo).
         
        --export([test/0]).
        -
        -test() ->
        -    {ok, Viewer} = et_viewer:start([{title,"Coffee Order"}, {max_actors,10}]),
        -    Drink = {drink,iced_chai_latte},
        -    Size = {size,grande},
        -    Milk = {milk,whole},
        -    Flavor = {flavor,vanilla},
        -    C = et_viewer:get_collector_pid(Viewer),
        -    et_collector:report_event(C,99,customer,barrista1,place_order,[Drink,Size,Milk,Flavor]),
        -    et_collector:report_event(C,80,barrista1,register,enter_order,[Drink,Size,Flavor]),
        -    et_collector:report_event(C,80,register,barrista1,give_total,"$5"),
        -    et_collector:report_event(C,80,barrista1,barrista1,get_cup,[Drink,Size]),
        -    et_collector:report_event(C,80,barrista1,barrista2,give_cup,[]),
        -    et_collector:report_event(C,90,barrista1,customer,request_money,"$5"),
        -    et_collector:report_event(C,90,customer,barrista1,pay_money,"$5"),
        -    et_collector:report_event(C,80,barrista2,barrista2,get_chai_mix,[]),
        -    et_collector:report_event(C,80,barrista2,barrista2,add_flavor,[Flavor]),
        -    et_collector:report_event(C,80,barrista2,barrista2,add_milk,[Milk]),
        -    et_collector:report_event(C,80,barrista2,barrista2,add_ice,[]),
        -    et_collector:report_event(C,80,barrista2,barrista2,swirl,[]),
        -    et_collector:report_event(C,80,barrista2,customer,give_tasty_beverage,[Drink,Size]),
        +-export([test/0]).
        +
        +test() ->
        +    {ok, Viewer} = et_viewer:start([{title,"Coffee Order"}, {max_actors,10}]),
        +    Drink = {drink,iced_chai_latte},
        +    Size = {size,grande},
        +    Milk = {milk,whole},
        +    Flavor = {flavor,vanilla},
        +    C = et_viewer:get_collector_pid(Viewer),
        +    et_collector:report_event(C,99,customer,barrista1,place_order,[Drink,Size,Milk,Flavor]),
        +    et_collector:report_event(C,80,barrista1,register,enter_order,[Drink,Size,Flavor]),
        +    et_collector:report_event(C,80,register,barrista1,give_total,"$5"),
        +    et_collector:report_event(C,80,barrista1,barrista1,get_cup,[Drink,Size]),
        +    et_collector:report_event(C,80,barrista1,barrista2,give_cup,[]),
        +    et_collector:report_event(C,90,barrista1,customer,request_money,"$5"),
        +    et_collector:report_event(C,90,customer,barrista1,pay_money,"$5"),
        +    et_collector:report_event(C,80,barrista2,barrista2,get_chai_mix,[]),
        +    et_collector:report_event(C,80,barrista2,barrista2,add_flavor,[Flavor]),
        +    et_collector:report_event(C,80,barrista2,barrista2,add_milk,[Milk]),
        +    et_collector:report_event(C,80,barrista2,barrista2,add_ice,[]),
        +    et_collector:report_event(C,80,barrista2,barrista2,swirl,[]),
        +    et_collector:report_event(C,80,barrista2,customer,give_tasty_beverage,[Drink,Size]),
             ok.

        When you run the et_display_demo:test(). function in the example above, the Viewer window will look like this:

        Screenshot of the Viewer window

        @@ -199,7 +199,7 @@

        calls. The idea is that you should instrument your code with calls to et:trace_me/5 in strategic places where you have interesting information available in your program. Then you just start the Collector with global -tracing enabled:

              et_viewer:start([{trace_global, true}, {trace_pattern, {et,max}}]).

        This will start a Collector, a Viewer and also start the tracing of +tracing enabled:

              et_viewer:start([{trace_global, true}, {trace_pattern, {et,max}}]).

        This will start a Collector, a Viewer and also start the tracing of et:trace_me/5 function calls. The Raw Trace Data is collected by the Collector and a view of it is displayed on the screen by the Viewer. You can define your own "views" of the data by implementing your own Filter functions @@ -255,36 +255,36 @@

        all you have to do is enable them.

        For those people who want to do general tracing, consult the dbg module on how to trace whatever you're interested in and let it work its magic. If you just want et:trace_me/5 to work, do the following:

        1. Create a Collector
        2. Create a Viewer (this can do step #1 for you)
        3. Turn on and pare down debugging

        The module et/examples/et_trace_demo.erl achieves this.

        
        --module(et_trace_demo).
        +-module(et_trace_demo).
         
        --export([test/0]).
        -
        -test() ->
        -    et_viewer:start([
        -        {title,"Coffee Order"},
        -        {trace_global,true},
        -        {trace_pattern,{et,max}},
        -        {max_actors,10}
        -      ]),
        +-export([test/0]).
        +
        +test() ->
        +    et_viewer:start([
        +        {title,"Coffee Order"},
        +        {trace_global,true},
        +        {trace_pattern,{et,max}},
        +        {max_actors,10}
        +      ]),
               %% dbg:p(all,call),
               %% dbg:tpl(et, trace_me, 5, []),
        -      Drink = {drink,iced_chai_latte},
        -      Size = {size,grande},
        -      Milk = {milk,whole},
        -      Flavor = {flavor,vanilla},
        -      et:trace_me(99,customer,barrista1,place_order,[Drink,Size,Milk,Flavor]),
        -      et:trace_me(80,barrista1,register,enter_order,[Drink,Size,Flavor]),
        -      et:trace_me(80,register,barrista1,give_total,"$5"),
        -      et:trace_me(80,barrista1,barrista1,get_cup,[Drink,Size]),
        -      et:trace_me(80,barrista1,barrista2,give_cup,[]),
        -      et:trace_me(90,barrista1,customer,request_money,"$5"),
        -      et:trace_me(90,customer,barrista1,pay_money,"$5"),
        -      et:trace_me(80,barrista2,barrista2,get_chai_mix,[]),
        -      et:trace_me(80,barrista2,barrista2,add_flavor,[Flavor]),
        -      et:trace_me(80,barrista2,barrista2,add_milk,[Milk]),
        -      et:trace_me(80,barrista2,barrista2,add_ice,[]),
        -      et:trace_me(80,barrista2,barrista2,swirl,[]),
        -      et:trace_me(80,barrista2,customer,give_tasty_beverage,[Drink,Size]),
        +      Drink = {drink,iced_chai_latte},
        +      Size = {size,grande},
        +      Milk = {milk,whole},
        +      Flavor = {flavor,vanilla},
        +      et:trace_me(99,customer,barrista1,place_order,[Drink,Size,Milk,Flavor]),
        +      et:trace_me(80,barrista1,register,enter_order,[Drink,Size,Flavor]),
        +      et:trace_me(80,register,barrista1,give_total,"$5"),
        +      et:trace_me(80,barrista1,barrista1,get_cup,[Drink,Size]),
        +      et:trace_me(80,barrista1,barrista2,give_cup,[]),
        +      et:trace_me(90,barrista1,customer,request_money,"$5"),
        +      et:trace_me(90,customer,barrista1,pay_money,"$5"),
        +      et:trace_me(80,barrista2,barrista2,get_chai_mix,[]),
        +      et:trace_me(80,barrista2,barrista2,add_flavor,[Flavor]),
        +      et:trace_me(80,barrista2,barrista2,add_milk,[Milk]),
        +      et:trace_me(80,barrista2,barrista2,add_ice,[]),
        +      et:trace_me(80,barrista2,barrista2,swirl,[]),
        +      et:trace_me(80,barrista2,customer,give_tasty_beverage,[Drink,Size]),
               ok.

        Running through the above, the most important points are:

        • Turn on global tracing
        • Set a Trace Pattern
        • Tell dbg to trace function Calls
        • Tell it specifically to trace the et:trace_me/5 function

        When you run the et_trace_demo:test() function above, the Viewer window will look like this screenshot:

        Screenshot of the Viewer window

        diff --git a/prs/8803/lib/eunit-2.9.1/doc/html/.build b/prs/8803/lib/eunit-2.9.1/doc/html/.build index a46514cd0674e..df6fc6ccf2c4e 100644 --- a/prs/8803/lib/eunit-2.9.1/doc/html/.build +++ b/prs/8803/lib/eunit-2.9.1/doc/html/.build @@ -19,7 +19,7 @@ dist/lato-latin-ext-300-normal-VPGGJKJL.woff2 dist/lato-latin-ext-400-normal-N27NCBWW.woff2 dist/lato-latin-ext-700-normal-Q2L5DVMW.woff2 dist/remixicon-NKANDIL5.woff2 -dist/search_data-C541596B.js +dist/search_data-4CEF3D2D.js dist/sidebar_items-3A2D003A.js eunit.html eunit_surefire.html diff --git a/prs/8803/lib/eunit-2.9.1/doc/html/dist/search_data-4CEF3D2D.js b/prs/8803/lib/eunit-2.9.1/doc/html/dist/search_data-4CEF3D2D.js new file mode 100644 index 0000000000000..211e41773f5af --- /dev/null +++ b/prs/8803/lib/eunit-2.9.1/doc/html/dist/search_data-4CEF3D2D.js @@ -0,0 +1 @@ +searchData={"items":[{"type":"module","doc":"This module is the main EUnit user interface.","title":"eunit","ref":"eunit.html"},{"type":"function","doc":"Starts the EUnit server. Normally, you don't need to call this function; it is\nstarted automatically.","title":"eunit.start/0","ref":"eunit.html#start/0"},{"type":"function","doc":"Stops the EUnit server. Normally, you don't need to call this function.","title":"eunit.stop/0","ref":"eunit.html#stop/0"},{"type":"function","doc":"","title":"eunit.test/1","ref":"eunit.html#test/1"},{"type":"function","doc":"Runs a set of tests. The format of `Tests` is described in the section\n[EUnit test representation](chapter.md#EUnit_test_representation) of the\noverview.\n\nExample:\n\n```text\n eunit:test(fred)\n```\n\nruns all tests in the module `fred` and also any tests in the module\n`fred_tests`, if that module exists.\n\nOptions:\n\n- **`verbose`** - Displays more details about the running tests.\n\n- **`print_depth`** - Maximum depth to which terms are printed in case of error.\n\n- **`exact_execution`** - If this boolean flag is set to `true` framework will\n not automatically execute tests found in related module suffixed with\n \"\\_tests\". This behaviour might be unwanted if execution of modules found in a\n folder is ordered while it contains both source and test modules.\n\n- **`scale_timeouts`** - If this numeric value is set, timeouts will get scaled\n accordingly. It may be useful when running a set of tests on a slower host.\n Examples: `{scale_timeouts,10}` make the timeouts 10 times longer, while\n `{scale_timeouts,0.1}` would shorten them by a factor of 10.\n\nOptions in the environment variable EUNIT are also included last in the option\nlist, i.e., have lower precedence than those in `Options`.\n\n_See also: _`test/1`.","title":"eunit.test/2","ref":"eunit.html#test/2"},{"type":"module","doc":"Surefire reports for EUnit (Format used by Maven and Atlassian Bamboo for\nexample to integrate test results). Based on initial code from Paul Guyot.\n\nExample: Generate XML result file in the current directory:\n\n```text\n eunit:test([fib, eunit_examples],\n [{report,{eunit_surefire,[{dir,\".\"}]}}]).\n```\n\n_See also: _`m:eunit`.","title":"eunit_surefire","ref":"eunit_surefire.html"},{"type":"extras","doc":"\n# EUnit Release Notes\n\nThis document describes the changes made to the EUnit application.","title":"EUnit Release Notes","ref":"notes.html"},{"type":"extras","doc":"","title":"Eunit 2.9.1 - EUnit Release Notes","ref":"notes.html#eunit-2-9-1"},{"type":"extras","doc":"- The documentation has been migrated to use Markdown and ExDoc.\n\n Own Id: OTP-18955 Aux Id: [PR-8026]\n\n[PR-8026]: https://github.com/erlang/otp/pull/8026","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.9 - EUnit Release Notes","ref":"notes.html#eunit-2-9"},{"type":"extras","doc":"- With this change, EUnit timetraps can be scaled with the use of scale_timeouts\n option.\n\n Own Id: OTP-18771 Aux Id: PR-7635","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.8.2 - EUnit Release Notes","ref":"notes.html#eunit-2-8-2"},{"type":"extras","doc":"- Replace size/1 with either tuple_size/1 or byte_size/1\n\n The [`size/1`](`size/1`) BIF is not optimized by the JIT, and its use can\n result in worse types for Dialyzer.\n\n When one knows that the value being tested must be a tuple,\n [`tuple_size/1`](`tuple_size/1`) should always be preferred.\n\n When one knows that the value being tested must be a binary,\n [`byte_size/1`](`byte_size/1`) should be preferred. However,\n [`byte_size/1`](`byte_size/1`) also accepts a bitstring (rounding up size to a\n whole number of bytes), so one must make sure that the call to `byte_size/` is\n preceded by a call to [`is_binary/1`](`is_binary/1`) to ensure that bitstrings\n are rejected. Note that the compiler removes redundant calls to\n [`is_binary/1`](`is_binary/1`), so if one is not sure whether previous code\n had made sure that the argument is a binary, it does not harm to add an\n [`is_binary/1`](`is_binary/1`) test immediately before the call to\n [`byte_size/1`](`byte_size/1`).\n\n Own Id: OTP-18432 Aux Id:\n GH-6672,PR-6793,PR-6784,PR-6787,PR-6785,PR-6682,PR-6800,PR-6797,PR-6798,PR-6799,PR-6796,PR-6813,PR-6671,PR-6673,PR-6684,PR-6694,GH-6677,PR-6696,PR-6670,PR-6674","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.8.1 - EUnit Release Notes","ref":"notes.html#eunit-2-8-1"},{"type":"extras","doc":"- With this change, eunit exact_execution option works with application\n primitive.\n\n Own Id: OTP-18264 Aux Id: PR-6322, GH-6320","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.8 - EUnit Release Notes","ref":"notes.html#eunit-2-8"},{"type":"extras","doc":"- With this change, Eunit can optionally not try to execute related module with\n \"\\_tests\" suffix. This might be used for avoiding duplicated executions when\n source and test modules are located in the same folder.\n\n Own Id: OTP-18181 Aux Id: ERL-97, GH-3064, PR-5461","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.7.1 - EUnit Release Notes","ref":"notes.html#eunit-2-7-1"},{"type":"extras","doc":"- Minor internal improvements.\n\n Own Id: OTP-17884 Aux Id: GH-5617","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.7 - EUnit Release Notes","ref":"notes.html#eunit-2-7"},{"type":"extras","doc":"- In an eunit test, when a test case times out, include a stacktrace.\n\n Own Id: OTP-17613 Aux Id: PR-5185","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.6.1 - EUnit Release Notes","ref":"notes.html#eunit-2-6-1"},{"type":"extras","doc":"- The `m:eunit_surefire` report handler has been updated to automatically create\n the directories needed to store the surefire xml file.\n\n Own Id: OTP-17300 Aux Id: PR-4695","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.6 - EUnit Release Notes","ref":"notes.html#eunit-2-6"},{"type":"extras","doc":"- Fixed compiler warning.\n\n Own Id: OTP-16674","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.5 - EUnit Release Notes","ref":"notes.html#eunit-2-5"},{"type":"extras","doc":"- Let `eunit_surefire` skip invalid XML 1.0 characters.\n\n Own Id: OTP-15950 Aux Id: PR-2316, ERL-991\n\n- Add new macro ?capturedOutput for enabling to write test cases that verify\n data printed to standard out\n\n Own Id: OTP-16275 Aux Id: PR-2424\n\n- Add option to limit print depth of exceptions generated by eunit test suites.\n\n Own Id: OTP-16549 Aux Id: PR-2532","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.4.1 - EUnit Release Notes","ref":"notes.html#eunit-2-4-1"},{"type":"extras","doc":"- Backport of PR-2316: Strip control codes from eunit_surefire output to avoid\n generation of invalid xml\n\n Own Id: OTP-16380 Aux Id: ERL-991, PR-2316, PR-2487","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.4 - EUnit Release Notes","ref":"notes.html#eunit-2-4"},{"type":"extras","doc":"- Remove compiler warnings from eunit.\n\n Own Id: OTP-16313","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.3.8 - EUnit Release Notes","ref":"notes.html#eunit-2-3-8"},{"type":"extras","doc":"- Handle `get_until` request with explicit encoding in the implementation of the\n I/O protocol.\n\n Own Id: OTP-16000","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.3.7 - EUnit Release Notes","ref":"notes.html#eunit-2-3-7"},{"type":"extras","doc":"- Improved documentation.\n\n Own Id: OTP-15190","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.3.6 - EUnit Release Notes","ref":"notes.html#eunit-2-3-6"},{"type":"extras","doc":"- Calls to `erlang:get_stacktrace()` are removed.\n\n Own Id: OTP-14861","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.3.5 - EUnit Release Notes","ref":"notes.html#eunit-2-3-5"},{"type":"extras","doc":"- Removed all old unused files in the documentation.\n\n Own Id: OTP-14475 Aux Id: ERL-409, PR-1493","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.3.4 - EUnit Release Notes","ref":"notes.html#eunit-2-3-4"},{"type":"extras","doc":"- Tools are updated to show Unicode atoms correctly.\n\n Own Id: OTP-14464","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.3.3 - EUnit Release Notes","ref":"notes.html#eunit-2-3-3"},{"type":"extras","doc":"- The surefire reports from `eunit` will no longer have names with embedded\n double quotes.\n\n Own Id: OTP-14287","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.3.2 - EUnit Release Notes","ref":"notes.html#eunit-2-3-2"},{"type":"extras","doc":"- The address to the FSF in the license header has been updated.\n\n Own Id: OTP-14084","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.3.1 - EUnit Release Notes","ref":"notes.html#eunit-2-3-1"},{"type":"extras","doc":"- When asserts were moved out to a separate header file, the automatic enabling\n of asserts when testing is enabled stopped working.\n\n Own Id: OTP-13892","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.3 - EUnit Release Notes","ref":"notes.html#eunit-2-3"},{"type":"extras","doc":"- There is a new `debugVal/2` that gives control over the truncation depth.\n\n Own Id: OTP-13612","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.2.13 - EUnit Release Notes","ref":"notes.html#eunit-2-2-13"},{"type":"extras","doc":"- Suppress Dialyzer warnings.\n\n Own Id: OTP-12862","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.2.12 - EUnit Release Notes","ref":"notes.html#eunit-2-2-12"},{"type":"extras","doc":"- Small documentation fixes\n\n Own Id: OTP-13017","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.2.11 - EUnit Release Notes","ref":"notes.html#eunit-2-2-11"},{"type":"extras","doc":"- Improve success message when 2 tests have passed\n\n Own Id: OTP-12952","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.2.10 - EUnit Release Notes","ref":"notes.html#eunit-2-2-10"},{"type":"extras","doc":"- The `eunit` application is now unicode safe.\n\n Own Id: OTP-11660","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.2.9 - EUnit Release Notes","ref":"notes.html#eunit-2-2-9"},{"type":"extras","doc":"- Make sure to install .hrl files when needed\n\n Own Id: OTP-12197\n\n- Make sure the clean rule for ssh, ssl, eunit and otp_mibs actually removes\n generated files.\n\n Own Id: OTP-12200","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.2.8 - EUnit Release Notes","ref":"notes.html#eunit-2-2-8"},{"type":"extras","doc":"- Minor refactoring.\n\n Own Id: OTP-12051","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.2.7 - EUnit Release Notes","ref":"notes.html#eunit-2-2-7"},{"type":"extras","doc":"- Application upgrade (appup) files are corrected for the following\n applications:\n\n `asn1, common_test, compiler, crypto, debugger, dialyzer, edoc, eldap, erl_docgen, et, eunit, gs, hipe, inets, observer, odbc, os_mon, otp_mibs, parsetools, percept, public_key, reltool, runtime_tools, ssh, syntax_tools, test_server, tools, typer, webtool, wx, xmerl`\n\n A new test utility for testing appup files is added to test_server. This is\n now used by most applications in OTP.\n\n (Thanks to Tobias Schlager)\n\n Own Id: OTP-11744","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.2.6 - EUnit Release Notes","ref":"notes.html#eunit-2-2-6"},{"type":"extras","doc":"- Fix I/O-protocol error handling in eunit. Thanks to Yuki Ito.\n\n Own Id: OTP-11373\n\n- Do not attempt to detect lists of printable characters in format. Thanks to\n Roberto Aloi.\n\n Own Id: OTP-11467\n\n- Fix silent make rule (Thanks to Anthony Ramine )\n\n Own Id: OTP-11516","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.2.5 - EUnit Release Notes","ref":"notes.html#eunit-2-2-5"},{"type":"extras","doc":"- Wrap eunit macros into begin ... end blocks. Thanks to Anthony Ramine.\n\n Own Id: OTP-11217","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.2.4 - EUnit Release Notes","ref":"notes.html#eunit-2-2-4"},{"type":"extras","doc":"- Where necessary a comment stating encoding has been added to Erlang files. The\n comment is meant to be removed in Erlang/OTP R17B when UTF-8 becomes the\n default encoding.\n\n Own Id: OTP-10630","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.2.3 - EUnit Release Notes","ref":"notes.html#eunit-2-2-3"},{"type":"extras","doc":"- New option 'no_tty' to silent the default tty report.\n\n Recognize the new stacktrace format introduced in R15, adding location\n information. (Thanks to Klas Johansson.)\n\n Improve layout of error messages, printing the stack trace before the error\n term.\n\n Heuristically detect and report bad return values from generators and\n instantiators. E.g., \"ok\" will not be interpreted as a module name, and a\n warning will be printed.\n\n New test representation \\{test,M,F\\} for completeness along with\n \\{generator,M,F\\}. Tuples \\{M,F\\} are deprecated.\n\n Use UTF-8 as encoding in Surefire output files. (Thanks to Lukas Larsson.)\n\n Own Id: OTP-10173","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.2.2 - EUnit Release Notes","ref":"notes.html#eunit-2-2-2"},{"type":"extras","doc":"- Erlang/OTP can now be built using parallel make if you limit the number of\n jobs, for instance using '`make -j6`' or '`make -j10`'. '`make -j`' does not\n work at the moment because of some missing dependencies.\n\n Own Id: OTP-9451","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.2.1 - EUnit Release Notes","ref":"notes.html#eunit-2-2-1"},{"type":"extras","doc":"- Generate separate surefire XMLs for each test suite\n\n Previously the test cases of all test suites (=modules) were put in one and\n the same surefire report XML thereby breaking the principle of least\n astonishment and making post analysis harder. Assume the following layout:\n\n src/x.erl src/y.erl test/x_tests.erl test/y_tests.erl\n\n The results for both x_tests and y_tests were written to only one report\n grouped under either module x or y (seemingly randomly).\n\n Now two reports, one for module x and one for y are generated. (Thanks to Klas\n Johansson)\n\n Own Id: OTP-9465\n\n- Updated to EUnit version 2.2.0\n\n New macros assertNotMatch(Guard, Expr), assertNotEqual(Unexpected, Expr), and\n assertNotException(Class, Term, Expr).\n\n The debugMsg macro now also prints the pid of the current process.\n\n When testing all modules in a directory, tests in Module_tests.erl are no\n longer executed twice.\n\n The use of regexp internally has been replaced with re. (Thanks to Richard\n Carlsson)\n\n Own Id: OTP-9505\n\n- Removed some never-matching clauses reported by dialyzer Updated author\n e-mails and homepages Removed cvs keywords from files Removed files that\n should not be checked in (Thanks to Richard Carlsson)\n\n Own Id: OTP-9591","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.1.7 - EUnit Release Notes","ref":"notes.html#eunit-2-1-7"},{"type":"extras","doc":"- Increase depth of error messages in Eunit Surefire reports\n\n Currently, error messages in Eunit Surefire reports are shortened just like\n when written to a terminal. However, the space limitations that constrain\n terminal output do not apply here, so it's more useful to include more of the\n error message. The new depth of 100 should be enough for most cases, while\n protecting against runaway errors. (Thanks to Magnus Henoch)\n\n Own Id: OTP-9220\n\n- Don't let eunit_surefire report back to eunit when stopping\n\n When eunit is terminating, a stop message is sent to all listeners and eunit\n then waits for _one_ result message but previously both eunit_tty and\n eunit_surefire sent a response on error. Don't send a result message from\n eunit_surefire; let eunit_tty take care of all result reporting, both positive\n and negative to avoid race conditions and inconsistencies. (Thanks to Klas\n Johansson)\n\n Own Id: OTP-9269","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.1.6 - EUnit Release Notes","ref":"notes.html#eunit-2-1-6"},{"type":"extras","doc":"- Fix format_man_pages so it handles all man sections and remove warnings/errors\n in various man pages.\n\n Own Id: OTP-8600","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.1.5 - EUnit Release Notes","ref":"notes.html#eunit-2-1-5"},{"type":"extras","doc":"- The documentation is now possible to build in an open source environment after\n a number of bugs are fixed and some features are added in the documentation\n build process.\n\n \\- The arity calculation is updated.\n\n \\- The module prefix used in the function names for bif's are removed in the\n generated links so the links will look like\n \"http://www.erlang.org/doc/man/erlang.html#append_element-2\" instead of\n \"http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2\".\n\n \\- Enhanced the menu positioning in the html documentation when a new page is\n loaded.\n\n \\- A number of corrections in the generation of man pages (thanks to Sergei\n Golovan)\n\n \\- The legal notice is taken from the xml book file so OTP's build process can\n be used for non OTP applications.\n\n Own Id: OTP-8343","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.1.4 - EUnit Release Notes","ref":"notes.html#eunit-2-1-4"},{"type":"extras","doc":"- The documentation is now built with open source tools (xsltproc and fop) that\n exists on most platforms. One visible change is that the frames are removed.\n\n Own Id: OTP-8201","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.1.3 - EUnit Release Notes","ref":"notes.html#eunit-2-1-3"},{"type":"extras","doc":"- Miscellaneous updates.\n\n Own Id: OTP-8190","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.1.2 - EUnit Release Notes","ref":"notes.html#eunit-2-1-2"},{"type":"extras","doc":"- Miscellaneous updates.\n\n Own Id: OTP-8038","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Eunit 2.1.1 - EUnit Release Notes","ref":"notes.html#eunit-2-1-1"},{"type":"extras","doc":"- eunit was broken in R13B.\n\n Own Id: OTP-8018","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Eunit 2.1 - EUnit Release Notes","ref":"notes.html#eunit-2-1"},{"type":"extras","doc":"- Mostly internal changes, in particular to the event protocol; fixes problems\n with timeouts that could cause eunit to hang, and makes it much easier to\n write new reporting back-ends.\n\n New \"surefire\" report backend for Maven and Bamboo.\n\n The test representation is no longer traversed twice (the first pass was for\n enumeration only). This eliminates some strange restrictions on how generators\n can be written, but it also means that reports cannot be quite as complete as\n before in the event of skipped tests.\n\n Own Id: OTP-7964","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"EUnit 2.0.1 - EUnit Release Notes","ref":"notes.html#eunit-2-0-1"},{"type":"extras","doc":"- Corrected the documentation build.","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"EUnit 2.0 - EUnit Release Notes","ref":"notes.html#eunit-2-0"},{"type":"extras","doc":"- This is the first version of EUnit (for unit testing of Erlang modules) by\n Richard Carlsson released in OTP.","title":"Improvements and New Features - EUnit Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"\n# EUnit - a Lightweight Unit Testing Framework for Erlang\n\nEUnit is a unit testing framework for Erlang. It is very powerful and flexible,\nis easy to use, and has small syntactical overhead.\n\n- [Unit testing](chapter.md#Unit_testing)\n- [Terminology](chapter.md#terminology)\n- [Getting started](chapter.md#Getting_started)\n- [EUnit macros](chapter.md#EUnit_macros)\n- [EUnit test representation](chapter.md#EUnit_test_representation)\n\nEUnit builds on ideas from the family of unit testing frameworks for Object\nOriented languages that originated with JUnit by Beck and Gamma (and Beck's\nprevious framework SUnit for Smalltalk). However, EUnit uses techniques more\nadapted to functional and concurrent programming, and is typically less verbose\nthan its relatives.\n\nAlthough EUnit uses many preprocessor macros, they have been designed to be as\nnonintrusive as possible, and should not cause conflicts with existing code.\nAdding EUnit tests to a module should thus not normally require changing\nexisting code. Furthermore, tests that only exercise the exported functions of a\nmodule can always be placed in a completely separate module, avoiding any\nconflicts entirely.\n\n[](){: #Unit_testing }","title":"EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html"},{"type":"extras","doc":"Unit Testing is testing of individual program \"units\" in relative isolation.\nThere is no particular size requirement: a unit can be a function, a module, a\nprocess, or even a whole application, but the most typical testing units are\nindividual functions or modules. In order to test a unit, you specify a set of\nindividual tests, set up the smallest necessary environment for being able to\nrun those tests (often, you don't need to do any setup at all), you run the\ntests and collect the results, and finally you do any necessary cleanup so that\nthe test can be run again later. A Unit Testing Framework tries to help you in\neach stage of this process, so that it is easy to write tests, easy to run them,\nand easy to see which tests failed (so you can fix the bugs).\n\n[](){: #Advantages_of_unit_testing }","title":"Unit testing - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#unit-testing"},{"type":"extras","doc":"- **Reduces the risks of changing the program** - Most programs will be modified\n during their lifetime: bugs will be fixed, features will be added,\n optimizations may become necessary, or the code will need to be refactored or\n cleaned up in other ways to make it easier to work with. But every change to a\n working program is a risk of introducing new bugs - or reintroducing bugs that\n had previously been fixed. Having a set of unit tests that you can run with\n very little effort makes it easy to know that the code still works as it\n should (this use is called _regression testing_; see\n [Terminology](chapter.md#terminology)). This goes a long way to reduce the\n resistance to changing and refactoring code.\n\n- **Helps guide and speed up the development process** - By focusing on getting\n the code to pass the tests, the programmer can become more productive, not\n overspecify or get lost in premature optimizations, and create code that is\n correct from the very beginning (so-called _test-driven development_; see\n [Terminology](chapter.md#terminology)).\n\n- **Helps separate interface from implementation** - When writing tests, the\n programmer may discover dependencies (in order to get the tests to run) that\n ought not to be there, and which need to be abstracted away to get a cleaner\n design. This helps eliminate bad dependencies before they spread throughout\n the code.\n\n- **Makes component integration easier** - By testing in a bottom-up fashion,\n beginning with the smallest program units and creating a confidence in that\n they work as they should, it becomes easier to test that a higher-level\n component, consisting of several such units, also behaves according to\n specification (known as _integration testing_; see\n [Terminology](chapter.md#terminology)).\n\n- **Is self-documenting** - The tests can be read as documentation, typically\n showing both examples of correct and incorrect usage, along with the expected\n consequences.","title":"Advantages of unit testing - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#advantages-of-unit-testing"},{"type":"extras","doc":"- **Unit testing** - Testing that a program unit behaves as it is supposed to do\n (in itself), according to its specifications. Unit tests have an important\n function as regression tests, when the program later is modified for some\n reason, since they check that the program still behaves according to\n specification.\n\n- **Regression testing** - Running a set of tests after making changes to a\n program, to check that the program behaves as it did before the changes\n (except, of course, for any intentional changes in behaviour). Unit tests are\n important as regression tests, but regression testing can involve more than\n just unit testing, and may also test behaviour that might not be part of the\n normal specification (such as bug-for-bug-compatibility).\n\n- **Integration testing** - Testing that a number of individually developed\n program units (assumed to already have been separately unit tested) work\n together as expected. Depending on the system being developed, integration\n testing may be as simple as \"just another level of unit testing\", but might\n also involve other kinds of tests (compare _system testing_).\n\n- **System testing** - Testing that a complete system behaves according to its\n specification. Specifically, system testing should not require knowing any\n details about the implementation. It typically involves testing many different\n aspects of the system behaviour apart from the basic functionality, such as\n performance, usability, and reliability.\n\n- **Test-driven development** - A program development technique where you\n continuously write tests _before_ you implement the code that is supposed to\n pass those tests. This can help you focus on solving the right problems, and\n not make a more complicated implementation than necessary, by letting the unit\n tests determine when a program is \"done\": if it fulfils its specifications,\n there is no need to keep adding functionality.\n\n- **Mock object** - Sometimes, testing some unit `A` (e.g., a function) requires\n that it collaborates somehow with some other unit `B` (perhaps being passed as\n an argument, or by reference) - but `B` has not been implemented yet. A \"mock\n object\" - an object which, for the purposes of testing `A`, looks and behaves\n like a real `B` \\- might then be used instead. (This is of course only useful\n if it would be significantly more work to implement a real `B` than to create\n a mock object.)\n\n- **Test case** - A single, well-defined test, that somehow can be uniquely\n identified. When executed, the test case either _passes_ or _fails_; the test\n report should identify exactly which test cases failed.\n\n- **Test suite** - A collection of test cases, generally with a specific, common\n target for testing, such as a single function, module, or subsystem. A test\n suite may also be recursively composed by smaller test suites.\n\n[](){: #Getting_started }","title":"Terminology - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#terminology"},{"type":"extras","doc":"- [Including the EUnit header file](chapter.md#Including_the_EUnit_header_file)\n- [Writing simple test functions](chapter.md#Writing_simple_test_functions)\n- [Running EUnit](chapter.md#Running_EUnit)\n- [Writing test generating functions](chapter.md#Writing_test_generating_functions)\n- [An example](chapter.md#An_example)\n- [Disabling testing](chapter.md#Disabling_testing)\n- [Avoiding compile-time dependency on EUnit](chapter.md#Avoiding_compile-time_dependency_on_EUnit)\n\n[](){: #Including_the_EUnit_header_file }","title":"Getting started - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#getting-started"},{"type":"extras","doc":"The simplest way to use EUnit in an Erlang module is to add the following line\nat the beginning of the module (after the `-module` declaration, but before any\nfunction definitions):\n\n```text\n -include_lib(\"eunit/include/eunit.hrl\").\n```\n\nThis will have the following effect:\n\n- Creates an exported function `test()` (unless testing is turned off, and the\n module does not already contain a test() function), that can be used to run\n all the unit tests defined in the module\n- Causes all functions whose names match `..._test()` or `..._test_()` to be\n automatically exported from the module (unless testing is turned off, or the\n `EUNIT_NOAUTO` macro is defined)\n- Makes all the preprocessor macros of EUnit available, to help writing tests\n\n_Note:_ For `-include_lib(...)` to work, the Erlang module search path _must_\ncontain a directory whose name ends in `eunit/ebin` (pointing to the `ebin`\nsubdirectory of the EUnit installation directory). If EUnit is installed as\n`lib/eunit` under your Erlang/OTP system directory, its `ebin` subdirectory will\nbe automatically added to the search path when Erlang starts. Otherwise, you\nneed to add the directory explicitly, by passing a `-pa` flag to the `erl` or\n`erlc` command. For example, a Makefile could contain the following action for\ncompiling `.erl` files:\n\n```text\n erlc -pa \"path/to/eunit/ebin\" $(ERL_COMPILE_FLAGS) -o$(EBIN) $<\n```\n\nor if you want Eunit to always be available when you run Erlang interactively,\nyou can add a line like the following to your `$HOME/.erlang` file:\n\n```text\n code:add_path(\"/path/to/eunit/ebin\").\n```\n\n[](){: #Writing_simple_test_functions }","title":"Including the EUnit header file - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#including-the-eunit-header-file"},{"type":"extras","doc":"The EUnit framework makes it extremely easy to write unit tests in Erlang. There\nare a few different ways of writing them, though, so we start with the simplest:\n\nA function with a name ending in `..._test()` is recognized by EUnit as a simple\ntest function - it takes no arguments, and its execution either succeeds\n(returning some arbitrary value that EUnit will throw away), or fails by\nthrowing an exception of some kind (or by not terminating, in which case it will\nbe aborted after a while).\n\nAn example of a simple test function could be the following:\n\n```text\n reverse_test() -> lists:reverse([1,2,3]).\n```\n\nThis just tests that the function `lists:reverse(List)` does not crash when\n`List` is `[1,2,3]`. It is not a great test, but many people write simple\nfunctions like this one to test the basic functionality of their code, and those\ntests can be used directly by EUnit, without changes, as long as their function\nnames match.\n\n_Use exceptions to signal failure_{: #Use_exceptions_to_signal_failure } To\nwrite more interesting tests, we need to make them crash (throw an exception)\nwhen they don't get the result they expect. A simple way of doing this is to use\npattern matching with `=`, as in the following examples:\n\n```text\n reverse_nil_test() -> [] = lists:reverse([]).\n reverse_one_test() -> [1] = lists:reverse([1]).\n reverse_two_test() -> [2,1] = lists:reverse([1,2]).\n```\n\nIf there was some bug in `lists:reverse/1` that made it return something other\nthan `[2,1]` when it got `[1,2]` as input, then the last test above would throw\na `badmatch` error. The first two (we assume they do not get a `badmatch`) would\nsimply return `[]` and `[1]`, respectively, so both succeed. (Note that EUnit is\nnot psychic: if you write a test that returns a value, even if it is the wrong\nvalue, EUnit will consider it a success. You must make sure that the test is\nwritten so that it causes a crash if the result is not what it should be.)\n\n_Using assert macros_{: #Using_assert_macros } If you want to use Boolean\noperators for your tests, the `assert` macro comes in handy (see\n[EUnit macros](chapter.md#EUnit_macros) for details):\n\n```text\n length_test() -> ?assert(length([1,2,3]) =:= 3).\n```\n\nThe `?assert(Expression)` macro will evaluate `Expression`, and if that does not\nevaluate to `true`, it will throw an exception; otherwise it just returns `ok`.\nIn the above example, the test will thus fail if the call to `length` does not\nreturn 3.\n\n[](){: #Running_EUnit }","title":"Writing simple test functions - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#writing-simple-test-functions"},{"type":"extras","doc":"If you have added the declaration `-include_lib(\"eunit/include/eunit.hrl\")` to\nyour module, as described above, you only need to compile the module, and run\nthe automatically exported function `test()`. For example, if your module was\nnamed `m`, then calling `\\m:test()` will run EUnit on all the tests defined in\nthe module. You do not need to write `-export` declarations for the test\nfunctions. This is all done by magic.\n\nYou can also use the function `eunit:test/1` to run arbitrary tests, for example\nto try out some more advanced test descriptors (see\n[EUnit test representation](chapter.md#EUnit_test_representation)). For example,\nrunning `eunit:test(m)` does the same thing as the auto-generated function\n`\\m:test()`, while `eunit:test({inparallel, m})` runs the same test cases but\nexecutes them all in parallel.\n\n_Putting tests in separate modules_{: #Putting_tests_in_separate_modules }\n\nIf you want to separate your test code from your normal code (at least for\ntesting the exported functions), you can simply write the test functions in a\nmodule named `m_tests` (note: not `m_test`), if your module is named `m`. Then,\nwhenever you ask EUnit to test the module `m`, it will also look for the module\n`m_tests` and run those tests as well. See `ModuleName` in the section\n[Primitives](chapter.md#primitives) for details.\n\n_EUnit captures standard output_{: #EUnit_captures_standard_output }\n\nIf your test code writes to the standard output, you may be surprised to see\nthat the text does not appear on the console when the tests are running. This is\nbecause EUnit captures all standard output from test functions (this also\nincludes setup and cleanup functions, but not generator functions), so that it\ncan be included in the test report if errors occur. To bypass EUnit and print\ntext directly to the console while testing, you can write to the `user` output\nstream, as in `io:format(user, \"~w\", [Term])`. The recommended way of doing this\nis to use the EUnit [Debugging macros](chapter.md#Debugging_macros), which make\nit much simpler.\n\nFor checking the output produced by the unit under test, see\n[Macros for checking output](chapter.md#Macros_for_checking_output).\n\n[](){: #Writing_test_generating_functions }","title":"Running EUnit - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#running-eunit"},{"type":"extras","doc":"A drawback of simple test functions is that you must write a separate function\n(with a separate name) for each test case. A more compact way of writing tests\n(and much more flexible, as we shall see), is to write functions that _return_\ntests, instead of _being_ tests.\n\nA function with a name ending in `..._test_()` (note the final underscore) is\nrecognized by EUnit as a _test generator_ function. Test generators return a\n_representation_ of a _set of tests_ to be executed by EUnit.\n\n_Representing a test as data_{: #Representing_a_test_as_data } The most basic\nrepresentation of a test is a single fun-expression that takes no arguments. For\nexample, the following test generator:\n\n```text\n basic_test_() ->\n fun () -> ?assert(1 + 1 =:= 2) end.\n```\n\nwill have the same effect as the following simple test:\n\n```text\n simple_test() ->\n ?assert(1 + 1 =:= 2).\n```\n\n(in fact, EUnit will handle all simple tests just like it handles\nfun-expressions: it will put them in a list, and run them one by one).\n\n_Using macros to write tests_{: #Using_macros_to_write_tests } To make tests\nmore compact and readable, as well as automatically add information about the\nline number in the source code where a test occurred (and reduce the number of\ncharacters you have to type), you can use the `_test` macro (note the initial\nunderscore character), like this:\n\n```text\n basic_test_() ->\n ?_test(?assert(1 + 1 =:= 2)).\n```\n\nThe `_test` macro takes any expression (the \"body\") as argument, and places it\nwithin a fun-expression (along with some extra information). The body can be any\nkind of test expression, just like the body of a simple test function.\n\n_Underscore-prefixed macros create test objects_{:\n#Underscore-prefixed_macros_create_test_objects } But this example can be made\neven shorter\\! Most test macros, such as the family of `assert` macros, have a\ncorresponding form with an initial underscore character, which automatically\nadds a `?_test(...)` wrapper. The above example can then simply be written:\n\n```text\n basic_test_() ->\n ?_assert(1 + 1 =:= 2).\n```\n\nwhich has exactly the same meaning (note the `_assert` instead of `assert`). You\ncan think of the initial underscore as signalling _test object_.\n\n[](){: #An_example }","title":"Writing test generating functions - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#writing-test-generating-functions"},{"type":"extras","doc":"Sometimes, an example says more than a thousand words. The following small\nErlang module shows how EUnit can be used in practice.\n\n```text\n -module(fib).\n -export([fib/1]).\n -include_lib(\"eunit/include/eunit.hrl\").\n\n fib(0) -> 1;\n fib(1) -> 1;\n fib(N) when N > 1 -> fib(N-1) + fib(N-2).\n\n fib_test_() ->\n [?_assert(fib(0) =:= 1),\n\t?_assert(fib(1) =:= 1),\n\t?_assert(fib(2) =:= 2),\n\t?_assert(fib(3) =:= 3),\n\t?_assert(fib(4) =:= 5),\n\t?_assert(fib(5) =:= 8),\n\t?_assertException(error, function_clause, fib(-1)),\n\t?_assert(fib(31) =:= 2178309)\n ].\n```\n\n(Author's note: When I first wrote this example, I happened to write a `*`\ninstead of `+` in the `fib` function. Of course, this showed up immediately when\nI ran the tests.)\n\nSee [EUnit test representation](chapter.md#EUnit_test_representation) for a full\nlist of all the ways you can specify test sets in EUnit.\n\n[](){: #Disabling_testing }","title":"An example - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#an-example"},{"type":"extras","doc":"Testing can be turned off by defining the `NOTEST` macro when compiling, for\nexample as an option to `erlc`, as in:\n\n```text\n erlc -DNOTEST my_module.erl\n```\n\nor by adding a macro definition to the code, _before the EUnit header file is\nincluded_:\n\n```text\n -define(NOTEST, 1).\n```\n\n(the value is not important, but should typically be 1 or `true`). Note that\nunless the `EUNIT_NOAUTO` macro is defined, disabling testing will also\nautomatically strip all test functions from the code, except for any that are\nexplicitly declared as exported.\n\nFor instance, to use EUnit in your application, but with testing turned off by\ndefault, put the following lines in a header file:\n\n```text\n -define(NOTEST, true).\n -include_lib(\"eunit/include/eunit.hrl\").\n```\n\nand then make sure that every module of your application includes that header\nfile. This means that you have a single place to modify in order to change the\ndefault setting for testing. To override the `NOTEST` setting without modifying\nthe code, you can define `TEST` in a compiler option, like this:\n\n```text\n erlc -DTEST my_module.erl\n```\n\nSee [Compilation control macros](chapter.md#Compilation_control_macros) for\ndetails about these macros.\n\n[](){: #Avoiding_compile-time_dependency_on_EUnit }","title":"Disabling testing - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#disabling-testing"},{"type":"extras","doc":"If you are distributing the source code for your application for other people to\ncompile and run, you probably want to ensure that the code compiles even if\nEUnit is not available. Like the example in the previous section, you can put\nthe following lines in a common header file:\n\n```text\n -ifdef(TEST).\n -include_lib(\"eunit/include/eunit.hrl\").\n -endif.\n```\n\nand, of course, also make sure that you place all test code that uses EUnit\nmacros within `-ifdef(TEST)` or `-ifdef(EUNIT)` sections.\n\n[](){: #EUnit_macros }","title":"Avoiding compile-time dependency on EUnit - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#avoiding-compile-time-dependency-on-eunit"},{"type":"extras","doc":"Although all the functionality of EUnit is available even without the use of\npreprocessor macros, the EUnit header file defines a number of such macros in\norder to make it as easy as possible to write unit tests as compactly as\npossible and without getting too many details in the way.\n\nExcept where explicitly stated, using EUnit macros will never introduce run-time\ndependencies on the EUnit library code, regardless of whether your code is\ncompiled with testing enabled or disabled.\n\n- [Basic macros](chapter.md#Basic_macros)\n- [Compilation control macros](chapter.md#Compilation_control_macros)\n- [Utility macros](chapter.md#Utility_macros)\n- [Assert macros](chapter.md#Assert_macros)\n- [Macros for checking output](chapter.md#Macros_for_checking_output)\n- [Macros for running external commands](chapter.md#Macros_for_running_external_commands)\n- [Debugging macros](chapter.md#Debugging_macros)\n\n[](){: #Basic_macros }","title":"EUnit macros - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#eunit-macros"},{"type":"extras","doc":"- **`_test(Expr)`** - Turns `Expr` into a \"test object\", by wrapping it in a\n fun-expression and a source line number. Technically, this is the same as\n `{?LINE, fun () -> (Expr) end}`.\n\n[](){: #Compilation_control_macros }","title":"Basic macros - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#basic-macros"},{"type":"extras","doc":"- **`EUNIT`** - This macro is always defined to `true` whenever EUnit is enabled\n at compile time. This is typically used to place testing code within\n conditional compilation, as in:\n\n ```text\n -ifdef(EUNIT).\n % test code here\n ...\n -endif.\n ```\n\n e.g., to ensure that the code can be compiled without including the EUnit\n header file, when testing is disabled. See also the macros `TEST` and\n `NOTEST`.\n\n- **`EUNIT_NOAUTO`** - If this macro is defined, the automatic exporting or\n stripping of test functions will be disabled.\n\n- **`TEST`** - This macro is always defined (to `true`, unless previously\n defined by the user to have another value) whenever EUnit is enabled at\n compile time. This can be used to place testing code within conditional\n compilation; see also the macros `NOTEST` and `EUNIT`.\n\n For testing code that is strictly dependent on EUnit, it may be preferable to\n use the `EUNIT` macro for this purpose, while for code that uses more generic\n testing conventions, using the `TEST` macro may be preferred.\n\n The `TEST` macro can also be used to override the `NOTEST` macro. If `TEST` is\n defined _before_ the EUnit header file is included (even if `NOTEST` is also\n defined), then the code will be compiled with EUnit enabled.\n\n- **`NOTEST`** - This macro is always defined (to `true`, unless previously\n defined by the user to have another value) whenever EUnit is _disabled_ at\n compile time. (Compare the `TEST` macro.)\n\n This macro can also be used for conditional compilation, but is more typically\n used to disable testing: If `NOTEST` is defined _before_ the EUnit header file\n is included, and `TEST` is _not_ defined, then the code will be compiled with\n EUnit disabled. See also [Disabling testing](chapter.md#Disabling_testing).\n\n- **`NOASSERT`** - If this macro is defined, the assert macros will have no\n effect, when testing is also disabled. See\n [Assert macros](chapter.md#Assert_macros). When testing is enabled, the assert\n macros are always enabled automatically and cannot be disabled.\n\n- **`ASSERT`** - If this macro is defined, it overrides the NOASSERT macro,\n forcing the assert macros to always be enabled regardless of other settings.\n\n- **`NODEBUG`** - If this macro is defined, the debugging macros will have no\n effect. See [Debugging macros](chapter.md#Debugging_macros). `NODEBUG` also\n implies `NOASSERT`, unless testing is enabled.\n\n- **`DEBUG`** - If this macro is defined, it overrides the NODEBUG macro,\n forcing the debugging macros to be enabled.\n\n[](){: #Utility_macros }","title":"Compilation control macros - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#compilation-control-macros"},{"type":"extras","doc":"The following macros can make tests more compact and readable:\n\n- **`LET(Var,Arg,Expr)`** - Creates a local binding `Var = Arg` in `Expr`. (This\n is the same as `(fun(Var)->(Expr)end)(Arg)`.) Note that the binding is not\n exported outside of `Expr`, and that within `Expr`, this binding of `Var` will\n shadow any binding of `Var` in the surrounding scope.\n\n- **`IF(Cond,TrueCase,FalseCase)`** - Evaluates `TrueCase` if `Cond` evaluates\n to `true`, or otherwise evaluates `FalseCase` if `Cond` evaluates to `false`.\n (This is the same as\n `(case (Cond) of true->(TrueCase); false->(FalseCase) end)`.) Note that it is\n an error if `Cond` does not yield a boolean value.\n\n[](){: #Assert_macros }","title":"Utility macros - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#utility-macros"},{"type":"extras","doc":"(Note that these macros also have corresponding forms which start with an \"`_`\"\n(underscore) character, as in `?_assert(BoolExpr)`, that create a \"test object\"\ninstead of performing the test immediately. This is equivalent to writing\n`?_test(assert(BoolExpr))`, etc.)\n\nIf the macro `NOASSERT` is defined before the EUnit header file is included,\nthese macros have no effect when testing is also disabled; see\n[Compilation control macros](chapter.md#Compilation_control_macros) for details.\n\n- **`assert(BoolExpr)`** - Evaluates the expression `BoolExpr`, if testing is\n enabled. Unless the result is `true`, an informative exception will be\n generated. If there is no exception, the result of the macro expression is the\n atom `ok`, and the value of `BoolExpr` is discarded. If testing is disabled,\n the macro will not generate any code except the atom `ok`, and `BoolExpr` will\n not be evaluated.\n\n Typical usage:\n\n ```text\n ?assert(f(X, Y) =:= [])\n ```\n\n The `assert` macro can be used anywhere in a program, not just in unit tests,\n to check pre/postconditions and invariants. For example:\n\n ```text\n some_recursive_function(X, Y, Z) ->\n ?assert(X + Y > Z),\n ...\n ```\n\n- **`assertNot(BoolExpr)`** - Equivalent to `assert(not (BoolExpr))`.\n\n- **`assertMatch(GuardedPattern, Expr)`** - Evaluates `Expr` and matches the\n result against `GuardedPattern`, if testing is enabled. If the match fails, an\n informative exception will be generated; see the `assert` macro for further\n details. `GuardedPattern` can be anything that you can write on the left hand\n side of the `->` symbol in a case-clause, except that it cannot contain\n comma-separated guard tests.\n\n The main reason for using `assertMatch` also for simple matches, instead of\n matching with `=`, is that it produces more detailed error messages.\n\n Examples:\n\n ```text\n ?assertMatch({found, {fred, _}}, lookup(bloggs, Table))\n ```\n\n ```text\n ?assertMatch([X|_] when X > 0, binary_to_list(B))\n ```\n\n- **`assertNotMatch(GuardedPattern, Expr)`** - The inverse case of assertMatch,\n for convenience.\n\n- **`assertEqual(Expect, Expr)`** - Evaluates the expressions `Expect` and\n `Expr` and compares the results for equality, if testing is enabled. If the\n values are not equal, an informative exception will be generated; see the\n `assert` macro for further details.\n\n `assertEqual` is more suitable than `assertMatch` when the left-hand side is a\n computed value rather than a simple pattern, and gives more details than\n `?assert(Expect =:= Expr)`.\n\n Examples:\n\n ```text\n ?assertEqual(\"b\" ++ \"a\", lists:reverse(\"ab\"))\n ```\n\n ```text\n ?assertEqual(foo(X), bar(Y))\n ```\n\n- **`assertNotEqual(Unexpected, Expr)`** - The inverse case of assertEqual, for\n convenience.\n\n- **`assertException(ClassPattern, TermPattern, Expr)`**\n\n- **`assertError(TermPattern, Expr)`**\n\n- **`assertExit(TermPattern, Expr)`**\n\n- **`assertThrow(TermPattern, Expr)`** - Evaluates `Expr`, catching any\n exception and testing that it matches the expected `ClassPattern:TermPattern`.\n If the match fails, or if no exception is thrown by `Expr`, an informative\n exception will be generated; see the `assert` macro for further details. The\n `assertError`, `assertExit`, and `assertThrow` macros, are equivalent to using\n `assertException` with a `ClassPattern` of `error`, `exit`, or `throw`,\n respectively.\n\n Examples:\n\n ```text\n ?assertError(badarith, X/0)\n ```\n\n ```text\n ?assertExit(normal, exit(normal))\n ```\n\n ```text\n ?assertException(throw, {not_found,_}, throw({not_found,42}))\n ```\n\n[](){: #Macros_for_checking_output }","title":"Assert macros - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#assert-macros"},{"type":"extras","doc":"The following macro can be used within a test case to retrieve the output\nwritten to standard output.\n\n- **`capturedOutput`** - The output captured by EUnit in the current test case,\n as a string.\n\n Examples:\n\n ```text\n io:format(\"Hello~n\"),\n ?assertEqual(\"Hello\\n\", ?capturedOutput)\n ```\n\n[](){: #Macros_for_running_external_commands }","title":"Macros for checking output - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#macros-for-checking-output"},{"type":"extras","doc":"Keep in mind that external commands are highly dependent on the operating\nsystem. You can use the standard library function `os:type()` in test generator\nfunctions, to produce different sets of tests depending on the current operating\nsystem.\n\nNote: these macros introduce a run-time dependency on the EUnit library code, if\ncompiled with testing enabled.\n\n- **`assertCmd(CommandString)`** - Runs `CommandString` as an external command,\n if testing is enabled. Unless the returned status value is 0, an informative\n exception will be generated. If there is no exception, the result of the macro\n expression is the atom `ok`. If testing is disabled, the macro will not\n generate any code except the atom `ok`, and the command will not be executed.\n\n Typical usage:\n\n ```text\n ?assertCmd(\"mkdir foo\")\n ```\n\n- **`assertCmdStatus(N, CommandString)`** - Like the `assertCmd(CommandString)`\n macro, but generates an exception unless the returned status value is `N`.\n\n- **`assertCmdOutput(Text, CommandString)`** - Runs `CommandString` as an\n external command, if testing is enabled. Unless the output produced by the\n command exactly matches the specified string `Text`, an informative exception\n will be generated. (Note that the output is normalized to use a single LF\n character as line break on all platforms.) If there is no exception, the\n result of the macro expression is the atom `ok`. If testing is disabled, the\n macro will not generate any code except the atom `ok`, and the command will\n not be executed.\n\n- **`cmd(CommandString)`** - Runs `CommandString` as an external command. Unless\n the returned status value is 0 (indicating success), an informative exception\n will be generated; otherwise, the result of the macro expression is the output\n produced by the command, as a flat string. The output is normalized to use a\n single LF character as line break on all platforms.\n\n This macro is useful in the setup and cleanup sections of fixtures, e.g., for\n creating and deleting files or perform similar operating system specific\n tasks, to make sure that the test system is informed of any failures.\n\n A Unix-specific example:\n\n ```text\n {setup,\n fun () -> ?cmd(\"mktemp\") end,\n fun (FileName) -> ?cmd(\"rm \" ++ FileName) end,\n ...}\n ```\n\n[](){: #Debugging_macros }","title":"Macros for running external commands - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#macros-for-running-external-commands"},{"type":"extras","doc":"To help with debugging, EUnit defines several useful macros for printing\nmessages directly to the console (rather than to the standard output).\nFurthermore, these macros all use the same basic format, which includes the file\nand line number where they occur, making it possible in some development\nenvironments (e.g., when running Erlang in an Emacs buffer) to simply click on\nthe message and jump directly to the corresponding line in the code.\n\nIf the macro `NODEBUG` is defined before the EUnit header file is included,\nthese macros have no effect; see\n[Compilation control macros](chapter.md#Compilation_control_macros) for details.\n\n- **`debugHere`** - Just prints a marker showing the current file and line\n number. Note that this is an argument-less macro. The result is always `ok`.\n\n- **`debugMsg(Text)`** - Outputs the message `Text` (which can be a plain\n string, an IO-list, or just an atom). The result is always `ok`.\n\n- **`debugFmt(FmtString, Args)`** - This formats the text like\n `io:format(FmtString, Args)` and outputs it like `debugMsg`. The result is\n always `ok`.\n\n- **`debugVal(Expr)`** - Prints both the source code for `Expr` and its current\n value. E.g., `?debugVal(f(X))` might be displayed as \"`f(X) = 42`\". (Large\n terms are truncated to the depth given by the macro `EUNIT_DEBUG_VAL_DEPTH`,\n which defaults to 15 but can be overridden by the user.) The result is always\n the value of `Expr`, so this macro can be wrapped around any expression to\n display its value when the code is compiled with debugging enabled.\n\n- **`debugVal(Expr, Depth)`** - Like `debugVal(Expr)`, but prints terms\n truncated to the given depth.\n\n- **`debugTime(Text,Expr)`** - Prints `Text` and the wall clock time for\n evaluation of `Expr`. The result is always the value of `Expr`, so this macro\n can be wrapped around any expression to show its run time when the code is\n compiled with debugging enabled. For example,\n `List1 = ?debugTime(\"sorting\", lists:sort(List))` might show as\n \"`sorting: 0.015 s`\".\n\n[](){: #EUnit_test_representation }","title":"Debugging macros - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#debugging-macros"},{"type":"extras","doc":"The way EUnit represents tests and test sets as data is flexible, powerful, and\nconcise. This section describes the representation in detail.\n\n- [Simple test objects](chapter.md#Simple_test_objects)\n- [Test sets and deep lists](chapter.md#Test_sets_and_deep_lists)\n- [Titles](chapter.md#titles)\n- [Primitives](chapter.md#primitives)\n- [Control](chapter.md#control)\n- [Fixtures](chapter.md#fixtures)\n- [Lazy generators](chapter.md#Lazy_generators)\n\n[](){: #Simple_test_objects }","title":"EUnit test representation - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#eunit-test-representation"},{"type":"extras","doc":"A _simple test object_ is one of the following:\n\n- A nullary functional value (i.e., a fun that takes zero arguments). Examples:\n\n ```text\n fun () -> ... end\n ```\n\n ```text\n fun some_function/0\n ```\n\n ```text\n fun some_module:some_function/0\n ```\n\n- A tuple `{test, ModuleName, FunctionName}`, where `ModuleName` and\n `FunctionName` are atoms, referring to the function\n `ModuleName:FunctionName/0`\n- (Obsolete) A pair of atoms `{ModuleName, FunctionName}`, equivalent to\n `{test, ModuleName, FunctionName}` if nothing else matches first. This might\n be removed in a future version.\n- A pair `{LineNumber, SimpleTest}`, where `LineNumber` is a nonnegative integer\n and `SimpleTest` is another simple test object. `LineNumber` should indicate\n the source line of the test. Pairs like this are usually only created via\n `?_test(...)` macros; see [Basic macros](chapter.md#Basic_macros).\n\nIn brief, a simple test object consists of a single function that takes no\narguments (possibly annotated with some additional metadata, i.e., a line\nnumber). Evaluation of the function either _succeeds_, by returning some value\n(which is ignored), or _fails_, by throwing an exception.\n\n[](){: #Test_sets_and_deep_lists }","title":"Simple test objects - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#simple-test-objects"},{"type":"extras","doc":"A test set can be easily created by placing a sequence of test objects in a\nlist. If `T_1`, ..., `T_N` are individual test objects, then `[T_1, ..., T_N]`\nis a test set consisting of those objects (in that order).\n\nTest sets can be joined in the same way: if `S_1`, ..., `S_K` are test sets,\nthen `[S_1, ..., S_K]` is also a test set, where the tests of `S_i` are ordered\nbefore those of `S_(i+1)`, for each subset `S_i`.\n\nThus, the main representation of test sets is _deep lists_, and a simple test\nobject can be viewed as a test set containing only a single test; there is no\ndifference between `T` and `[T]`.\n\nA module can also be used to represent a test set; see `ModuleName` under\n[Primitives](chapter.md#primitives) below.","title":"Test sets and deep lists - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#test-sets-and-deep-lists"},{"type":"extras","doc":"Any test or test set `T` can be annotated with a title, by wrapping it in a pair\n`{Title, T}`, where `Title` is a string. For convenience, any test which is\nnormally represented using a tuple can simply be given a title string as the\nfirst element, i.e., writing `{\"The Title\", ...}` instead of adding an extra\ntuple wrapper as in `{\"The Title\", {...}}`.","title":"Titles - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#titles"},{"type":"extras","doc":"The following are primitives, which do not contain other test sets as arguments:\n\n- **`ModuleName::atom()`** - A single atom represents a module name, and is\n equivalent to `{module, ModuleName}`. This is often used as in the call\n `eunit:test(some_module)`.\n\n- **`{module, ModuleName::atom()}`** - This composes a test set from the\n exported test functions of the named module, i.e., those functions with arity\n zero whose names end with `_test` or `_test_`. Basically, the `..._test()`\n functions become simple tests, while the `..._test_()` functions become\n generators.\n\n In addition, EUnit will also look for another module whose name is\n `ModuleName` plus the suffix `_tests`, and if it exists, all the tests from\n that module will also be added. (If `ModuleName` already contains the suffix\n `_tests`, this is not done.) E.g., the specification `{module, mymodule}` will\n run all tests in the modules `mymodule` and `mymodule_tests`. Typically, the\n `_tests` module should only contain test cases that use the public interface\n of the main module (and no other code).\n\n- **`{application, AppName::atom(), Info::list()}`** - This is a normal\n Erlang/OTP application descriptor, as found in an `.app` file. The resulting\n test set consists of the modules listed in the `modules` entry in `Info`.\n\n- **`{application, AppName::atom()}`** - This creates a test set from all the\n modules belonging to the specified application, by consulting the\n application's `.app` file (see `{file, FileName}`), or if no such file exists,\n by testing all object files in the application's `ebin`\\-directory (see\n `{dir, Path}`); if that does not exist, the `code:lib_dir(AppName)` directory\n is used.\n\n- **`Path::string()`** - A single string represents the path of a file or\n directory, and is equivalent to `{file, Path}`, or `{dir, Path}`,\n respectively, depending on what `Path` refers to in the file system.\n\n- **`{file, FileName::string()}`** - If `FileName` has a suffix that indicates\n an object file (`.beam`), EUnit will try to reload the module from the\n specified file and test it. Otherwise, the file is assumed to be a text file\n containing test specifications, which will be read using the standard library\n function `file:path_consult/2`.\n\n Unless the file name is absolute, the file is first searched for relative to\n the current directory, and then using the normal search path\n (`code:get_path()`). This means that the names of typical \"app\" files can be\n used directly, without a path, e.g., `\"mnesia.app\"`.\n\n- **`{dir, Path::string()}`** - This tests all object files in the specified\n directory, as if they had been individually specified using\n `{file, FileName}`.\n\n- **`{generator, GenFun::(() -> Tests)}`** - The generator function `GenFun` is\n called to produce a test set.\n\n- **`{generator, ModuleName::atom(), FunctionName::atom()}`** - The function\n `ModuleName:FunctionName()` is called to produce a test set.\n\n- **`{with, X::any(), [AbstractTestFun::((any()) -> any())]}`** - Distributes\n the value `X` over the unary functions in the list, turning them into nullary\n test functions. An `AbstractTestFun` is like an ordinary test fun, but takes\n one argument instead of zero - it's basically missing some information before\n it can be a proper test. In practice, `{with, X, [F_1, ..., F_N]}` is\n equivalent to `[fun () -> F_1(X) end, ..., fun () -> F_N(X) end]`. This is\n particularly useful if your abstract test functions are already implemented as\n proper functions:\n `{with, FD, [fun filetest_a/1, fun filetest_b/1, fun filetest_c/1]}` is\n equivalent to\n `[fun () -> filetest_a(FD) end, fun () -> filetest_b(FD) end, fun () -> filetest_c(FD) end]`,\n but much more compact. See also [Fixtures](chapter.md#fixtures), below.","title":"Primitives - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#primitives"},{"type":"extras","doc":"The following representations control how and where tests are executed:\n\n- **`{spawn, Tests}`** - Runs the specified tests in a separate subprocess,\n while the current test process waits for it to finish. This is useful for\n tests that need a fresh, isolated process state. (Note that EUnit always\n starts at least one such a subprocess automatically; tests are never executed\n by the caller's own process.)\n\n- **`{spawn, Node::atom(), Tests}`** - Like `{spawn, Tests}`, but runs the\n specified tests on the given Erlang node.\n\n- **`{timeout, Time::number(), Tests}`** - Runs the specified tests under the\n given timeout. Time is in seconds; e.g., 60 means one minute and 0.1 means\n 1/10th of a second. If the timeout is exceeded, the unfinished tests will be\n forced to terminate. Note that if a timeout is set around a fixture, it\n includes the time for setup and cleanup, and if the timeout is triggered, the\n entire fixture is abruptly terminated (without running the cleanup). The\n default timeout for an individual test is 5 seconds.\n\n- **`{inorder, Tests}`** - Runs the specified tests in strict order. Also see\n `{inparallel, Tests}`. By default, tests are neither marked as `inorder` or\n `inparallel`, but may be executed as the test framework chooses.\n\n- **`{inparallel, Tests}`** - Runs the specified tests in parallel (if\n possible). Also see `{inorder, Tests}`.\n\n- **`{inparallel, N::integer(), Tests}`** - Like `{inparallel, Tests}`, but\n running no more than `N` subtests simultaneously.","title":"Control - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#control"},{"type":"extras","doc":"A \"fixture\" is some state that is necessary for a particular set of tests to\nrun. EUnit's support for fixtures makes it easy to set up such state locally for\na test set, and automatically tear it down again when the test set is finished,\nregardless of the outcome (success, failures, timeouts, etc.).\n\nTo make the descriptions simpler, we first list some definitions:\n\n| `Setup` | `() -> (R::any())` |\n| -------------- | ------------------------------- | ---------------------------------------------- | ---------------------- |\n| `SetupX` | `(X::any()) -> (R::any())` |\n| `Cleanup` | `(R::any()) -> any()` |\n| `CleanupX` | `(X::any(), R::any()) -> any()` |\n| `Instantiator` | `((R::any()) -> Tests) | {with, [AbstractTestFun::((any()) -> any())]}` |\n| `Where` | `local | spawn | {spawn, Node::atom()}` |\n\n(these are explained in more detail further below.)\n\nThe following representations specify fixture handling for test sets:\n\n- **`{setup, Setup, Tests | Instantiator}`**\n\n- **`{setup, Setup, Cleanup, Tests | Instantiator}`**\n\n- **`{setup, Where, Setup, Tests | Instantiator}`**\n\n- **`{setup, Where, Setup, Cleanup, Tests | Instantiator}`** - `setup` sets up a\n single fixture for running all of the specified tests, with optional teardown\n afterwards. The arguments are described in detail below.\n\n- **`{node, Node::atom(), Tests | Instantiator}`**\n\n- **`{node, Node::atom(), Args::string(), Tests | Instantiator}`** - `node` is\n like `setup`, but with a built-in behaviour: it starts a slave node for the\n duration of the tests. The atom `Node` should have the format\n `nodename@full.machine.name`, and `Args` are the optional arguments to the new\n node; see `slave:start_link/3` for details.\n\n- **`{foreach, Where, Setup, Cleanup, [Tests | Instantiator]}`**\n\n- **`{foreach, Setup, Cleanup, [Tests | Instantiator]}`**\n\n- **`{foreach, Where, Setup, [Tests | Instantiator]}`**\n\n- **`{foreach, Setup, [Tests | Instantiator]}`** - `foreach` is used to set up a\n fixture and optionally tear it down afterwards, repeated for each single one\n of the specified test sets.\n\n- **`{foreachx, Where, SetupX, CleanupX, Pairs::[{X::any(), ((X::any(), R::any()) -> Tests)}]}`**\n\n- **`{foreachx, SetupX, CleanupX, Pairs}`**\n\n- **`{foreachx, Where, SetupX, Pairs}`**\n\n- **`{foreachx, SetupX, Pairs}`** - `foreachx` is like `foreach`, but uses a\n list of pairs, each containing an extra argument `X` and an extended\n instantiator function.\n\nA `Setup` function is executed just before any of the specified tests are run,\nand a `Cleanup` function is executed when no more of the specified tests will be\nrun, regardless of the reason. A `Setup` function takes no argument, and returns\nsome value which will be passed as it is to the `Cleanup` function. A `Cleanup`\nfunction should do whatever necessary and return some arbitrary value, such as\nthe atom `ok`. (`SetupX` and `CleanupX` functions are similar, but receive one\nadditional argument: some value `X`, which depends on the context.) When no\n`Cleanup` function is specified, a dummy function is used which has no effect.\n\nAn `Instantiator` function receives the same value as the `Cleanup` function,\ni.e., the value returned by the `Setup` function. It should then behave much\nlike a generator (see [Primitives](chapter.md#primitives)), and return a test\nset whose tests have been _instantiated_ with the given value. A special case is\nthe syntax `{with, [AbstractTestFun]}` which represents an instantiator function\nthat distributes the value over a list of unary functions; see\n[Primitives](chapter.md#primitives): `{with, X, [...]}` for more details.\n\nA `Where` term controls how the specified tests are executed. The default is\n`spawn`, which means that the current process handles the setup and teardown,\nwhile the tests are executed in a subprocess. `{spawn, Node}` is like `spawn`,\nbut runs the subprocess on the specified node. `local` means that the current\nprocess will handle both setup/teardown and running the tests - the drawback is\nthat if a test times out so that the process is killed, the _cleanup will not be\nperformed_; hence, avoid this for persistent fixtures such as file operations.\nIn general, `local` should only be used when:\n\n- the setup/teardown needs to be executed by the process that will run the\n tests;\n- no further teardown needs to be done if the process is killed (i.e., no state\n outside the process was affected by the setup)\n\n[](){: #Lazy_generators }","title":"Fixtures - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#fixtures"},{"type":"extras","doc":"Sometimes, it can be convenient not to produce the whole set of test\ndescriptions before the testing begins; for example, if you want to generate a\nhuge amount of tests that would take up too much space to keep in memory all at\nonce.\n\nIt is fairly easy to write a generator which, each time it is called, either\nproduces an empty list if it is done, or otherwise produces a list containing a\nsingle test case plus a new generator which will produce the rest of the tests.\nThis demonstrates the basic pattern:\n\n```text\n lazy_test_() ->\n lazy_gen(10000).\n\n lazy_gen(N) ->\n {generator,\n fun () ->\n if N > 0 ->\n [?_test(...)\n | lazy_gen(N-1)];\n true ->\n []\n end\n end}.\n```\n\nWhen EUnit traverses the test representation in order to run the tests, the new\ngenerator will not be called to produce the next test until the previous test\nhas been executed.\n\nNote that it is easiest to write this kind of recursive generator using a help\nfunction, like the `lazy_gen/1` function above. It can also be written using a\nrecursive fun, if you prefer to not clutter your function namespace and are\ncomfortable with writing that kind of code.","title":"Lazy generators - EUnit - a Lightweight Unit Testing Framework for Erlang","ref":"chapter.html#lazy-generators"}],"content_type":"text/plain","producer":{"name":"ex_doc","version":[48,46,51,52,46,49]}} \ No newline at end of file diff --git a/prs/8803/lib/eunit-2.9.1/doc/html/dist/search_data-C541596B.js b/prs/8803/lib/eunit-2.9.1/doc/html/dist/search_data-C541596B.js deleted file mode 100644 index 5d1a8f5570d21..0000000000000 --- a/prs/8803/lib/eunit-2.9.1/doc/html/dist/search_data-C541596B.js +++ /dev/null @@ -1 +0,0 @@ -searchData={"items":[{"type":"module","title":"eunit","doc":"This module is the main EUnit user interface.","ref":"eunit.html"},{"type":"function","title":"eunit.start/0","doc":"Starts the EUnit server. Normally, you don't need to call this function; it is\nstarted automatically.","ref":"eunit.html#start/0"},{"type":"function","title":"eunit.stop/0","doc":"Stops the EUnit server. Normally, you don't need to call this function.","ref":"eunit.html#stop/0"},{"type":"function","title":"eunit.test/1","doc":"","ref":"eunit.html#test/1"},{"type":"function","title":"eunit.test/2","doc":"Runs a set of tests. The format of `Tests` is described in the section\n[EUnit test representation](chapter.md#EUnit_test_representation) of the\noverview.\n\nExample:\n\n```text\n eunit:test(fred)\n```\n\nruns all tests in the module `fred` and also any tests in the module\n`fred_tests`, if that module exists.\n\nOptions:\n\n- **`verbose`** - Displays more details about the running tests.\n\n- **`print_depth`** - Maximum depth to which terms are printed in case of error.\n\n- **`exact_execution`** - If this boolean flag is set to `true` framework will\n not automatically execute tests found in related module suffixed with\n \"\\_tests\". This behaviour might be unwanted if execution of modules found in a\n folder is ordered while it contains both source and test modules.\n\n- **`scale_timeouts`** - If this numeric value is set, timeouts will get scaled\n accordingly. It may be useful when running a set of tests on a slower host.\n Examples: `{scale_timeouts,10}` make the timeouts 10 times longer, while\n `{scale_timeouts,0.1}` would shorten them by a factor of 10.\n\nOptions in the environment variable EUNIT are also included last in the option\nlist, i.e., have lower precedence than those in `Options`.\n\n_See also: _`test/1`.","ref":"eunit.html#test/2"},{"type":"module","title":"eunit_surefire","doc":"Surefire reports for EUnit (Format used by Maven and Atlassian Bamboo for\nexample to integrate test results). Based on initial code from Paul Guyot.\n\nExample: Generate XML result file in the current directory:\n\n```text\n eunit:test([fib, eunit_examples],\n [{report,{eunit_surefire,[{dir,\".\"}]}}]).\n```\n\n_See also: _`m:eunit`.","ref":"eunit_surefire.html"},{"type":"extras","title":"EUnit Release Notes","doc":"\n# EUnit Release Notes\n\nThis document describes the changes made to the EUnit application.","ref":"notes.html"},{"type":"extras","title":"Eunit 2.9.1 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-9-1"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- The documentation has been migrated to use Markdown and ExDoc.\n\n Own Id: OTP-18955 Aux Id: [PR-8026]\n\n[PR-8026]: https://github.com/erlang/otp/pull/8026","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.9 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-9"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- With this change, EUnit timetraps can be scaled with the use of scale_timeouts\n option.\n\n Own Id: OTP-18771 Aux Id: PR-7635","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.8.2 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-8-2"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- Replace size/1 with either tuple_size/1 or byte_size/1\n\n The [`size/1`](`size/1`) BIF is not optimized by the JIT, and its use can\n result in worse types for Dialyzer.\n\n When one knows that the value being tested must be a tuple,\n [`tuple_size/1`](`tuple_size/1`) should always be preferred.\n\n When one knows that the value being tested must be a binary,\n [`byte_size/1`](`byte_size/1`) should be preferred. However,\n [`byte_size/1`](`byte_size/1`) also accepts a bitstring (rounding up size to a\n whole number of bytes), so one must make sure that the call to `byte_size/` is\n preceded by a call to [`is_binary/1`](`is_binary/1`) to ensure that bitstrings\n are rejected. Note that the compiler removes redundant calls to\n [`is_binary/1`](`is_binary/1`), so if one is not sure whether previous code\n had made sure that the argument is a binary, it does not harm to add an\n [`is_binary/1`](`is_binary/1`) test immediately before the call to\n [`byte_size/1`](`byte_size/1`).\n\n Own Id: OTP-18432 Aux Id:\n GH-6672,PR-6793,PR-6784,PR-6787,PR-6785,PR-6682,PR-6800,PR-6797,PR-6798,PR-6799,PR-6796,PR-6813,PR-6671,PR-6673,PR-6684,PR-6694,GH-6677,PR-6696,PR-6670,PR-6674","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.8.1 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-8-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- With this change, eunit exact_execution option works with application\n primitive.\n\n Own Id: OTP-18264 Aux Id: PR-6322, GH-6320","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.8 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-8"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- With this change, Eunit can optionally not try to execute related module with\n \"\\_tests\" suffix. This might be used for avoiding duplicated executions when\n source and test modules are located in the same folder.\n\n Own Id: OTP-18181 Aux Id: ERL-97, GH-3064, PR-5461","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.7.1 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-7-1"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- Minor internal improvements.\n\n Own Id: OTP-17884 Aux Id: GH-5617","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.7 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-7"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- In an eunit test, when a test case times out, include a stacktrace.\n\n Own Id: OTP-17613 Aux Id: PR-5185","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.6.1 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-6-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- The `m:eunit_surefire` report handler has been updated to automatically create\n the directories needed to store the surefire xml file.\n\n Own Id: OTP-17300 Aux Id: PR-4695","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.6 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-6"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- Fixed compiler warning.\n\n Own Id: OTP-16674","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.5 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-5"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- Let `eunit_surefire` skip invalid XML 1.0 characters.\n\n Own Id: OTP-15950 Aux Id: PR-2316, ERL-991\n\n- Add new macro ?capturedOutput for enabling to write test cases that verify\n data printed to standard out\n\n Own Id: OTP-16275 Aux Id: PR-2424\n\n- Add option to limit print depth of exceptions generated by eunit test suites.\n\n Own Id: OTP-16549 Aux Id: PR-2532","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.4.1 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-4-1"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- Backport of PR-2316: Strip control codes from eunit_surefire output to avoid\n generation of invalid xml\n\n Own Id: OTP-16380 Aux Id: ERL-991, PR-2316, PR-2487","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.4 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-4"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- Remove compiler warnings from eunit.\n\n Own Id: OTP-16313","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.3.8 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-3-8"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- Handle `get_until` request with explicit encoding in the implementation of the\n I/O protocol.\n\n Own Id: OTP-16000","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.3.7 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-3-7"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- Improved documentation.\n\n Own Id: OTP-15190","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.3.6 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-3-6"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- Calls to `erlang:get_stacktrace()` are removed.\n\n Own Id: OTP-14861","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.3.5 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-3-5"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- Removed all old unused files in the documentation.\n\n Own Id: OTP-14475 Aux Id: ERL-409, PR-1493","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.3.4 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-3-4"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- Tools are updated to show Unicode atoms correctly.\n\n Own Id: OTP-14464","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.3.3 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-3-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- The surefire reports from `eunit` will no longer have names with embedded\n double quotes.\n\n Own Id: OTP-14287","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.3.2 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-3-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- The address to the FSF in the license header has been updated.\n\n Own Id: OTP-14084","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.3.1 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-3-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- When asserts were moved out to a separate header file, the automatic enabling\n of asserts when testing is enabled stopped working.\n\n Own Id: OTP-13892","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.3 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-3"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- There is a new `debugVal/2` that gives control over the truncation depth.\n\n Own Id: OTP-13612","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.2.13 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-2-13"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- Suppress Dialyzer warnings.\n\n Own Id: OTP-12862","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.2.12 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-2-12"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- Small documentation fixes\n\n Own Id: OTP-13017","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.2.11 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-2-11"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- Improve success message when 2 tests have passed\n\n Own Id: OTP-12952","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.2.10 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-2-10"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- The `eunit` application is now unicode safe.\n\n Own Id: OTP-11660","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.2.9 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-2-9"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- Make sure to install .hrl files when needed\n\n Own Id: OTP-12197\n\n- Make sure the clean rule for ssh, ssl, eunit and otp_mibs actually removes\n generated files.\n\n Own Id: OTP-12200","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.2.8 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-2-8"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- Minor refactoring.\n\n Own Id: OTP-12051","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.2.7 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-2-7"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- Application upgrade (appup) files are corrected for the following\n applications:\n\n `asn1, common_test, compiler, crypto, debugger, dialyzer, edoc, eldap, erl_docgen, et, eunit, gs, hipe, inets, observer, odbc, os_mon, otp_mibs, parsetools, percept, public_key, reltool, runtime_tools, ssh, syntax_tools, test_server, tools, typer, webtool, wx, xmerl`\n\n A new test utility for testing appup files is added to test_server. This is\n now used by most applications in OTP.\n\n (Thanks to Tobias Schlager)\n\n Own Id: OTP-11744","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.2.6 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-2-6"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- Fix I/O-protocol error handling in eunit. Thanks to Yuki Ito.\n\n Own Id: OTP-11373\n\n- Do not attempt to detect lists of printable characters in format. Thanks to\n Roberto Aloi.\n\n Own Id: OTP-11467\n\n- Fix silent make rule (Thanks to Anthony Ramine )\n\n Own Id: OTP-11516","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.2.5 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-2-5"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- Wrap eunit macros into begin ... end blocks. Thanks to Anthony Ramine.\n\n Own Id: OTP-11217","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.2.4 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-2-4"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- Where necessary a comment stating encoding has been added to Erlang files. The\n comment is meant to be removed in Erlang/OTP R17B when UTF-8 becomes the\n default encoding.\n\n Own Id: OTP-10630","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.2.3 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-2-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- New option 'no_tty' to silent the default tty report.\n\n Recognize the new stacktrace format introduced in R15, adding location\n information. (Thanks to Klas Johansson.)\n\n Improve layout of error messages, printing the stack trace before the error\n term.\n\n Heuristically detect and report bad return values from generators and\n instantiators. E.g., \"ok\" will not be interpreted as a module name, and a\n warning will be printed.\n\n New test representation \\{test,M,F\\} for completeness along with\n \\{generator,M,F\\}. Tuples \\{M,F\\} are deprecated.\n\n Use UTF-8 as encoding in Surefire output files. (Thanks to Lukas Larsson.)\n\n Own Id: OTP-10173","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.2.2 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-2-2"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- Erlang/OTP can now be built using parallel make if you limit the number of\n jobs, for instance using '`make -j6`' or '`make -j10`'. '`make -j`' does not\n work at the moment because of some missing dependencies.\n\n Own Id: OTP-9451","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.2.1 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-2-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- Generate separate surefire XMLs for each test suite\n\n Previously the test cases of all test suites (=modules) were put in one and\n the same surefire report XML thereby breaking the principle of least\n astonishment and making post analysis harder. Assume the following layout:\n\n src/x.erl src/y.erl test/x_tests.erl test/y_tests.erl\n\n The results for both x_tests and y_tests were written to only one report\n grouped under either module x or y (seemingly randomly).\n\n Now two reports, one for module x and one for y are generated. (Thanks to Klas\n Johansson)\n\n Own Id: OTP-9465\n\n- Updated to EUnit version 2.2.0\n\n New macros assertNotMatch(Guard, Expr), assertNotEqual(Unexpected, Expr), and\n assertNotException(Class, Term, Expr).\n\n The debugMsg macro now also prints the pid of the current process.\n\n When testing all modules in a directory, tests in Module_tests.erl are no\n longer executed twice.\n\n The use of regexp internally has been replaced with re. (Thanks to Richard\n Carlsson)\n\n Own Id: OTP-9505\n\n- Removed some never-matching clauses reported by dialyzer Updated author\n e-mails and homepages Removed cvs keywords from files Removed files that\n should not be checked in (Thanks to Richard Carlsson)\n\n Own Id: OTP-9591","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.1.7 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-1-7"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- Increase depth of error messages in Eunit Surefire reports\n\n Currently, error messages in Eunit Surefire reports are shortened just like\n when written to a terminal. However, the space limitations that constrain\n terminal output do not apply here, so it's more useful to include more of the\n error message. The new depth of 100 should be enough for most cases, while\n protecting against runaway errors. (Thanks to Magnus Henoch)\n\n Own Id: OTP-9220\n\n- Don't let eunit_surefire report back to eunit when stopping\n\n When eunit is terminating, a stop message is sent to all listeners and eunit\n then waits for _one_ result message but previously both eunit_tty and\n eunit_surefire sent a response on error. Don't send a result message from\n eunit_surefire; let eunit_tty take care of all result reporting, both positive\n and negative to avoid race conditions and inconsistencies. (Thanks to Klas\n Johansson)\n\n Own Id: OTP-9269","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.1.6 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-1-6"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- Fix format_man_pages so it handles all man sections and remove warnings/errors\n in various man pages.\n\n Own Id: OTP-8600","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.1.5 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-1-5"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- The documentation is now possible to build in an open source environment after\n a number of bugs are fixed and some features are added in the documentation\n build process.\n\n \\- The arity calculation is updated.\n\n \\- The module prefix used in the function names for bif's are removed in the\n generated links so the links will look like\n \"http://www.erlang.org/doc/man/erlang.html#append_element-2\" instead of\n \"http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2\".\n\n \\- Enhanced the menu positioning in the html documentation when a new page is\n loaded.\n\n \\- A number of corrections in the generation of man pages (thanks to Sergei\n Golovan)\n\n \\- The legal notice is taken from the xml book file so OTP's build process can\n be used for non OTP applications.\n\n Own Id: OTP-8343","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.1.4 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-1-4"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- The documentation is now built with open source tools (xsltproc and fop) that\n exists on most platforms. One visible change is that the frames are removed.\n\n Own Id: OTP-8201","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.1.3 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-1-3"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- Miscellaneous updates.\n\n Own Id: OTP-8190","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.1.2 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-1-2"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- Miscellaneous updates.\n\n Own Id: OTP-8038","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Eunit 2.1.1 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-1-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - EUnit Release Notes","doc":"- eunit was broken in R13B.\n\n Own Id: OTP-8018","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Eunit 2.1 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-1"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- Mostly internal changes, in particular to the event protocol; fixes problems\n with timeouts that could cause eunit to hang, and makes it much easier to\n write new reporting back-ends.\n\n New \"surefire\" report backend for Maven and Bamboo.\n\n The test representation is no longer traversed twice (the first pass was for\n enumeration only). This eliminates some strange restrictions on how generators\n can be written, but it also means that reports cannot be quite as complete as\n before in the event of skipped tests.\n\n Own Id: OTP-7964","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"EUnit 2.0.1 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-0-1"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- Corrected the documentation build.","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"EUnit 2.0 - EUnit Release Notes","doc":"","ref":"notes.html#eunit-2-0"},{"type":"extras","title":"Improvements and New Features - EUnit Release Notes","doc":"- This is the first version of EUnit (for unit testing of Erlang modules) by\n Richard Carlsson released in OTP.","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"\n# EUnit - a Lightweight Unit Testing Framework for Erlang\n\nEUnit is a unit testing framework for Erlang. It is very powerful and flexible,\nis easy to use, and has small syntactical overhead.\n\n- [Unit testing](chapter.md#Unit_testing)\n- [Terminology](chapter.md#terminology)\n- [Getting started](chapter.md#Getting_started)\n- [EUnit macros](chapter.md#EUnit_macros)\n- [EUnit test representation](chapter.md#EUnit_test_representation)\n\nEUnit builds on ideas from the family of unit testing frameworks for Object\nOriented languages that originated with JUnit by Beck and Gamma (and Beck's\nprevious framework SUnit for Smalltalk). However, EUnit uses techniques more\nadapted to functional and concurrent programming, and is typically less verbose\nthan its relatives.\n\nAlthough EUnit uses many preprocessor macros, they have been designed to be as\nnonintrusive as possible, and should not cause conflicts with existing code.\nAdding EUnit tests to a module should thus not normally require changing\nexisting code. Furthermore, tests that only exercise the exported functions of a\nmodule can always be placed in a completely separate module, avoiding any\nconflicts entirely.\n\n[](){: #Unit_testing }","ref":"chapter.html"},{"type":"extras","title":"Unit testing - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"Unit Testing is testing of individual program \"units\" in relative isolation.\nThere is no particular size requirement: a unit can be a function, a module, a\nprocess, or even a whole application, but the most typical testing units are\nindividual functions or modules. In order to test a unit, you specify a set of\nindividual tests, set up the smallest necessary environment for being able to\nrun those tests (often, you don't need to do any setup at all), you run the\ntests and collect the results, and finally you do any necessary cleanup so that\nthe test can be run again later. A Unit Testing Framework tries to help you in\neach stage of this process, so that it is easy to write tests, easy to run them,\nand easy to see which tests failed (so you can fix the bugs).\n\n[](){: #Advantages_of_unit_testing }","ref":"chapter.html#unit-testing"},{"type":"extras","title":"Advantages of unit testing - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"- **Reduces the risks of changing the program** - Most programs will be modified\n during their lifetime: bugs will be fixed, features will be added,\n optimizations may become necessary, or the code will need to be refactored or\n cleaned up in other ways to make it easier to work with. But every change to a\n working program is a risk of introducing new bugs - or reintroducing bugs that\n had previously been fixed. Having a set of unit tests that you can run with\n very little effort makes it easy to know that the code still works as it\n should (this use is called _regression testing_; see\n [Terminology](chapter.md#terminology)). This goes a long way to reduce the\n resistance to changing and refactoring code.\n\n- **Helps guide and speed up the development process** - By focusing on getting\n the code to pass the tests, the programmer can become more productive, not\n overspecify or get lost in premature optimizations, and create code that is\n correct from the very beginning (so-called _test-driven development_; see\n [Terminology](chapter.md#terminology)).\n\n- **Helps separate interface from implementation** - When writing tests, the\n programmer may discover dependencies (in order to get the tests to run) that\n ought not to be there, and which need to be abstracted away to get a cleaner\n design. This helps eliminate bad dependencies before they spread throughout\n the code.\n\n- **Makes component integration easier** - By testing in a bottom-up fashion,\n beginning with the smallest program units and creating a confidence in that\n they work as they should, it becomes easier to test that a higher-level\n component, consisting of several such units, also behaves according to\n specification (known as _integration testing_; see\n [Terminology](chapter.md#terminology)).\n\n- **Is self-documenting** - The tests can be read as documentation, typically\n showing both examples of correct and incorrect usage, along with the expected\n consequences.","ref":"chapter.html#advantages-of-unit-testing"},{"type":"extras","title":"Terminology - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"- **Unit testing** - Testing that a program unit behaves as it is supposed to do\n (in itself), according to its specifications. Unit tests have an important\n function as regression tests, when the program later is modified for some\n reason, since they check that the program still behaves according to\n specification.\n\n- **Regression testing** - Running a set of tests after making changes to a\n program, to check that the program behaves as it did before the changes\n (except, of course, for any intentional changes in behaviour). Unit tests are\n important as regression tests, but regression testing can involve more than\n just unit testing, and may also test behaviour that might not be part of the\n normal specification (such as bug-for-bug-compatibility).\n\n- **Integration testing** - Testing that a number of individually developed\n program units (assumed to already have been separately unit tested) work\n together as expected. Depending on the system being developed, integration\n testing may be as simple as \"just another level of unit testing\", but might\n also involve other kinds of tests (compare _system testing_).\n\n- **System testing** - Testing that a complete system behaves according to its\n specification. Specifically, system testing should not require knowing any\n details about the implementation. It typically involves testing many different\n aspects of the system behaviour apart from the basic functionality, such as\n performance, usability, and reliability.\n\n- **Test-driven development** - A program development technique where you\n continuously write tests _before_ you implement the code that is supposed to\n pass those tests. This can help you focus on solving the right problems, and\n not make a more complicated implementation than necessary, by letting the unit\n tests determine when a program is \"done\": if it fulfils its specifications,\n there is no need to keep adding functionality.\n\n- **Mock object** - Sometimes, testing some unit `A` (e.g., a function) requires\n that it collaborates somehow with some other unit `B` (perhaps being passed as\n an argument, or by reference) - but `B` has not been implemented yet. A \"mock\n object\" - an object which, for the purposes of testing `A`, looks and behaves\n like a real `B` \\- might then be used instead. (This is of course only useful\n if it would be significantly more work to implement a real `B` than to create\n a mock object.)\n\n- **Test case** - A single, well-defined test, that somehow can be uniquely\n identified. When executed, the test case either _passes_ or _fails_; the test\n report should identify exactly which test cases failed.\n\n- **Test suite** - A collection of test cases, generally with a specific, common\n target for testing, such as a single function, module, or subsystem. A test\n suite may also be recursively composed by smaller test suites.\n\n[](){: #Getting_started }","ref":"chapter.html#terminology"},{"type":"extras","title":"Getting started - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"- [Including the EUnit header file](chapter.md#Including_the_EUnit_header_file)\n- [Writing simple test functions](chapter.md#Writing_simple_test_functions)\n- [Running EUnit](chapter.md#Running_EUnit)\n- [Writing test generating functions](chapter.md#Writing_test_generating_functions)\n- [An example](chapter.md#An_example)\n- [Disabling testing](chapter.md#Disabling_testing)\n- [Avoiding compile-time dependency on EUnit](chapter.md#Avoiding_compile-time_dependency_on_EUnit)\n\n[](){: #Including_the_EUnit_header_file }","ref":"chapter.html#getting-started"},{"type":"extras","title":"Including the EUnit header file - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"The simplest way to use EUnit in an Erlang module is to add the following line\nat the beginning of the module (after the `-module` declaration, but before any\nfunction definitions):\n\n```text\n -include_lib(\"eunit/include/eunit.hrl\").\n```\n\nThis will have the following effect:\n\n- Creates an exported function `test()` (unless testing is turned off, and the\n module does not already contain a test() function), that can be used to run\n all the unit tests defined in the module\n- Causes all functions whose names match `..._test()` or `..._test_()` to be\n automatically exported from the module (unless testing is turned off, or the\n `EUNIT_NOAUTO` macro is defined)\n- Makes all the preprocessor macros of EUnit available, to help writing tests\n\n_Note:_ For `-include_lib(...)` to work, the Erlang module search path _must_\ncontain a directory whose name ends in `eunit/ebin` (pointing to the `ebin`\nsubdirectory of the EUnit installation directory). If EUnit is installed as\n`lib/eunit` under your Erlang/OTP system directory, its `ebin` subdirectory will\nbe automatically added to the search path when Erlang starts. Otherwise, you\nneed to add the directory explicitly, by passing a `-pa` flag to the `erl` or\n`erlc` command. For example, a Makefile could contain the following action for\ncompiling `.erl` files:\n\n```text\n erlc -pa \"path/to/eunit/ebin\" $(ERL_COMPILE_FLAGS) -o$(EBIN) $<\n```\n\nor if you want Eunit to always be available when you run Erlang interactively,\nyou can add a line like the following to your `$HOME/.erlang` file:\n\n```text\n code:add_path(\"/path/to/eunit/ebin\").\n```\n\n[](){: #Writing_simple_test_functions }","ref":"chapter.html#including-the-eunit-header-file"},{"type":"extras","title":"Writing simple test functions - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"The EUnit framework makes it extremely easy to write unit tests in Erlang. There\nare a few different ways of writing them, though, so we start with the simplest:\n\nA function with a name ending in `..._test()` is recognized by EUnit as a simple\ntest function - it takes no arguments, and its execution either succeeds\n(returning some arbitrary value that EUnit will throw away), or fails by\nthrowing an exception of some kind (or by not terminating, in which case it will\nbe aborted after a while).\n\nAn example of a simple test function could be the following:\n\n```text\n reverse_test() -> lists:reverse([1,2,3]).\n```\n\nThis just tests that the function `lists:reverse(List)` does not crash when\n`List` is `[1,2,3]`. It is not a great test, but many people write simple\nfunctions like this one to test the basic functionality of their code, and those\ntests can be used directly by EUnit, without changes, as long as their function\nnames match.\n\n_Use exceptions to signal failure_{: #Use_exceptions_to_signal_failure } To\nwrite more interesting tests, we need to make them crash (throw an exception)\nwhen they don't get the result they expect. A simple way of doing this is to use\npattern matching with `=`, as in the following examples:\n\n```text\n reverse_nil_test() -> [] = lists:reverse([]).\n reverse_one_test() -> [1] = lists:reverse([1]).\n reverse_two_test() -> [2,1] = lists:reverse([1,2]).\n```\n\nIf there was some bug in `lists:reverse/1` that made it return something other\nthan `[2,1]` when it got `[1,2]` as input, then the last test above would throw\na `badmatch` error. The first two (we assume they do not get a `badmatch`) would\nsimply return `[]` and `[1]`, respectively, so both succeed. (Note that EUnit is\nnot psychic: if you write a test that returns a value, even if it is the wrong\nvalue, EUnit will consider it a success. You must make sure that the test is\nwritten so that it causes a crash if the result is not what it should be.)\n\n_Using assert macros_{: #Using_assert_macros } If you want to use Boolean\noperators for your tests, the `assert` macro comes in handy (see\n[EUnit macros](chapter.md#EUnit_macros) for details):\n\n```text\n length_test() -> ?assert(length([1,2,3]) =:= 3).\n```\n\nThe `?assert(Expression)` macro will evaluate `Expression`, and if that does not\nevaluate to `true`, it will throw an exception; otherwise it just returns `ok`.\nIn the above example, the test will thus fail if the call to `length` does not\nreturn 3.\n\n[](){: #Running_EUnit }","ref":"chapter.html#writing-simple-test-functions"},{"type":"extras","title":"Running EUnit - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"If you have added the declaration `-include_lib(\"eunit/include/eunit.hrl\")` to\nyour module, as described above, you only need to compile the module, and run\nthe automatically exported function `test()`. For example, if your module was\nnamed `m`, then calling `\\m:test()` will run EUnit on all the tests defined in\nthe module. You do not need to write `-export` declarations for the test\nfunctions. This is all done by magic.\n\nYou can also use the function `eunit:test/1` to run arbitrary tests, for example\nto try out some more advanced test descriptors (see\n[EUnit test representation](chapter.md#EUnit_test_representation)). For example,\nrunning `eunit:test(m)` does the same thing as the auto-generated function\n`\\m:test()`, while `eunit:test({inparallel, m})` runs the same test cases but\nexecutes them all in parallel.\n\n_Putting tests in separate modules_{: #Putting_tests_in_separate_modules }\n\nIf you want to separate your test code from your normal code (at least for\ntesting the exported functions), you can simply write the test functions in a\nmodule named `m_tests` (note: not `m_test`), if your module is named `m`. Then,\nwhenever you ask EUnit to test the module `m`, it will also look for the module\n`m_tests` and run those tests as well. See `ModuleName` in the section\n[Primitives](chapter.md#primitives) for details.\n\n_EUnit captures standard output_{: #EUnit_captures_standard_output }\n\nIf your test code writes to the standard output, you may be surprised to see\nthat the text does not appear on the console when the tests are running. This is\nbecause EUnit captures all standard output from test functions (this also\nincludes setup and cleanup functions, but not generator functions), so that it\ncan be included in the test report if errors occur. To bypass EUnit and print\ntext directly to the console while testing, you can write to the `user` output\nstream, as in `io:format(user, \"~w\", [Term])`. The recommended way of doing this\nis to use the EUnit [Debugging macros](chapter.md#Debugging_macros), which make\nit much simpler.\n\nFor checking the output produced by the unit under test, see\n[Macros for checking output](chapter.md#Macros_for_checking_output).\n\n[](){: #Writing_test_generating_functions }","ref":"chapter.html#running-eunit"},{"type":"extras","title":"Writing test generating functions - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"A drawback of simple test functions is that you must write a separate function\n(with a separate name) for each test case. A more compact way of writing tests\n(and much more flexible, as we shall see), is to write functions that _return_\ntests, instead of _being_ tests.\n\nA function with a name ending in `..._test_()` (note the final underscore) is\nrecognized by EUnit as a _test generator_ function. Test generators return a\n_representation_ of a _set of tests_ to be executed by EUnit.\n\n_Representing a test as data_{: #Representing_a_test_as_data } The most basic\nrepresentation of a test is a single fun-expression that takes no arguments. For\nexample, the following test generator:\n\n```text\n basic_test_() ->\n fun () -> ?assert(1 + 1 =:= 2) end.\n```\n\nwill have the same effect as the following simple test:\n\n```text\n simple_test() ->\n ?assert(1 + 1 =:= 2).\n```\n\n(in fact, EUnit will handle all simple tests just like it handles\nfun-expressions: it will put them in a list, and run them one by one).\n\n_Using macros to write tests_{: #Using_macros_to_write_tests } To make tests\nmore compact and readable, as well as automatically add information about the\nline number in the source code where a test occurred (and reduce the number of\ncharacters you have to type), you can use the `_test` macro (note the initial\nunderscore character), like this:\n\n```text\n basic_test_() ->\n ?_test(?assert(1 + 1 =:= 2)).\n```\n\nThe `_test` macro takes any expression (the \"body\") as argument, and places it\nwithin a fun-expression (along with some extra information). The body can be any\nkind of test expression, just like the body of a simple test function.\n\n_Underscore-prefixed macros create test objects_{:\n#Underscore-prefixed_macros_create_test_objects } But this example can be made\neven shorter\\! Most test macros, such as the family of `assert` macros, have a\ncorresponding form with an initial underscore character, which automatically\nadds a `?_test(...)` wrapper. The above example can then simply be written:\n\n```text\n basic_test_() ->\n ?_assert(1 + 1 =:= 2).\n```\n\nwhich has exactly the same meaning (note the `_assert` instead of `assert`). You\ncan think of the initial underscore as signalling _test object_.\n\n[](){: #An_example }","ref":"chapter.html#writing-test-generating-functions"},{"type":"extras","title":"An example - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"Sometimes, an example says more than a thousand words. The following small\nErlang module shows how EUnit can be used in practice.\n\n```text\n -module(fib).\n -export([fib/1]).\n -include_lib(\"eunit/include/eunit.hrl\").\n\n fib(0) -> 1;\n fib(1) -> 1;\n fib(N) when N > 1 -> fib(N-1) + fib(N-2).\n\n fib_test_() ->\n [?_assert(fib(0) =:= 1),\n\t?_assert(fib(1) =:= 1),\n\t?_assert(fib(2) =:= 2),\n\t?_assert(fib(3) =:= 3),\n\t?_assert(fib(4) =:= 5),\n\t?_assert(fib(5) =:= 8),\n\t?_assertException(error, function_clause, fib(-1)),\n\t?_assert(fib(31) =:= 2178309)\n ].\n```\n\n(Author's note: When I first wrote this example, I happened to write a `*`\ninstead of `+` in the `fib` function. Of course, this showed up immediately when\nI ran the tests.)\n\nSee [EUnit test representation](chapter.md#EUnit_test_representation) for a full\nlist of all the ways you can specify test sets in EUnit.\n\n[](){: #Disabling_testing }","ref":"chapter.html#an-example"},{"type":"extras","title":"Disabling testing - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"Testing can be turned off by defining the `NOTEST` macro when compiling, for\nexample as an option to `erlc`, as in:\n\n```text\n erlc -DNOTEST my_module.erl\n```\n\nor by adding a macro definition to the code, _before the EUnit header file is\nincluded_:\n\n```text\n -define(NOTEST, 1).\n```\n\n(the value is not important, but should typically be 1 or `true`). Note that\nunless the `EUNIT_NOAUTO` macro is defined, disabling testing will also\nautomatically strip all test functions from the code, except for any that are\nexplicitly declared as exported.\n\nFor instance, to use EUnit in your application, but with testing turned off by\ndefault, put the following lines in a header file:\n\n```text\n -define(NOTEST, true).\n -include_lib(\"eunit/include/eunit.hrl\").\n```\n\nand then make sure that every module of your application includes that header\nfile. This means that you have a single place to modify in order to change the\ndefault setting for testing. To override the `NOTEST` setting without modifying\nthe code, you can define `TEST` in a compiler option, like this:\n\n```text\n erlc -DTEST my_module.erl\n```\n\nSee [Compilation control macros](chapter.md#Compilation_control_macros) for\ndetails about these macros.\n\n[](){: #Avoiding_compile-time_dependency_on_EUnit }","ref":"chapter.html#disabling-testing"},{"type":"extras","title":"Avoiding compile-time dependency on EUnit - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"If you are distributing the source code for your application for other people to\ncompile and run, you probably want to ensure that the code compiles even if\nEUnit is not available. Like the example in the previous section, you can put\nthe following lines in a common header file:\n\n```text\n -ifdef(TEST).\n -include_lib(\"eunit/include/eunit.hrl\").\n -endif.\n```\n\nand, of course, also make sure that you place all test code that uses EUnit\nmacros within `-ifdef(TEST)` or `-ifdef(EUNIT)` sections.\n\n[](){: #EUnit_macros }","ref":"chapter.html#avoiding-compile-time-dependency-on-eunit"},{"type":"extras","title":"EUnit macros - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"Although all the functionality of EUnit is available even without the use of\npreprocessor macros, the EUnit header file defines a number of such macros in\norder to make it as easy as possible to write unit tests as compactly as\npossible and without getting too many details in the way.\n\nExcept where explicitly stated, using EUnit macros will never introduce run-time\ndependencies on the EUnit library code, regardless of whether your code is\ncompiled with testing enabled or disabled.\n\n- [Basic macros](chapter.md#Basic_macros)\n- [Compilation control macros](chapter.md#Compilation_control_macros)\n- [Utility macros](chapter.md#Utility_macros)\n- [Assert macros](chapter.md#Assert_macros)\n- [Macros for checking output](chapter.md#Macros_for_checking_output)\n- [Macros for running external commands](chapter.md#Macros_for_running_external_commands)\n- [Debugging macros](chapter.md#Debugging_macros)\n\n[](){: #Basic_macros }","ref":"chapter.html#eunit-macros"},{"type":"extras","title":"Basic macros - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"- **`_test(Expr)`** - Turns `Expr` into a \"test object\", by wrapping it in a\n fun-expression and a source line number. Technically, this is the same as\n `{?LINE, fun () -> (Expr) end}`.\n\n[](){: #Compilation_control_macros }","ref":"chapter.html#basic-macros"},{"type":"extras","title":"Compilation control macros - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"- **`EUNIT`** - This macro is always defined to `true` whenever EUnit is enabled\n at compile time. This is typically used to place testing code within\n conditional compilation, as in:\n\n ```text\n -ifdef(EUNIT).\n % test code here\n ...\n -endif.\n ```\n\n e.g., to ensure that the code can be compiled without including the EUnit\n header file, when testing is disabled. See also the macros `TEST` and\n `NOTEST`.\n\n- **`EUNIT_NOAUTO`** - If this macro is defined, the automatic exporting or\n stripping of test functions will be disabled.\n\n- **`TEST`** - This macro is always defined (to `true`, unless previously\n defined by the user to have another value) whenever EUnit is enabled at\n compile time. This can be used to place testing code within conditional\n compilation; see also the macros `NOTEST` and `EUNIT`.\n\n For testing code that is strictly dependent on EUnit, it may be preferable to\n use the `EUNIT` macro for this purpose, while for code that uses more generic\n testing conventions, using the `TEST` macro may be preferred.\n\n The `TEST` macro can also be used to override the `NOTEST` macro. If `TEST` is\n defined _before_ the EUnit header file is included (even if `NOTEST` is also\n defined), then the code will be compiled with EUnit enabled.\n\n- **`NOTEST`** - This macro is always defined (to `true`, unless previously\n defined by the user to have another value) whenever EUnit is _disabled_ at\n compile time. (Compare the `TEST` macro.)\n\n This macro can also be used for conditional compilation, but is more typically\n used to disable testing: If `NOTEST` is defined _before_ the EUnit header file\n is included, and `TEST` is _not_ defined, then the code will be compiled with\n EUnit disabled. See also [Disabling testing](chapter.md#Disabling_testing).\n\n- **`NOASSERT`** - If this macro is defined, the assert macros will have no\n effect, when testing is also disabled. See\n [Assert macros](chapter.md#Assert_macros). When testing is enabled, the assert\n macros are always enabled automatically and cannot be disabled.\n\n- **`ASSERT`** - If this macro is defined, it overrides the NOASSERT macro,\n forcing the assert macros to always be enabled regardless of other settings.\n\n- **`NODEBUG`** - If this macro is defined, the debugging macros will have no\n effect. See [Debugging macros](chapter.md#Debugging_macros). `NODEBUG` also\n implies `NOASSERT`, unless testing is enabled.\n\n- **`DEBUG`** - If this macro is defined, it overrides the NODEBUG macro,\n forcing the debugging macros to be enabled.\n\n[](){: #Utility_macros }","ref":"chapter.html#compilation-control-macros"},{"type":"extras","title":"Utility macros - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"The following macros can make tests more compact and readable:\n\n- **`LET(Var,Arg,Expr)`** - Creates a local binding `Var = Arg` in `Expr`. (This\n is the same as `(fun(Var)->(Expr)end)(Arg)`.) Note that the binding is not\n exported outside of `Expr`, and that within `Expr`, this binding of `Var` will\n shadow any binding of `Var` in the surrounding scope.\n\n- **`IF(Cond,TrueCase,FalseCase)`** - Evaluates `TrueCase` if `Cond` evaluates\n to `true`, or otherwise evaluates `FalseCase` if `Cond` evaluates to `false`.\n (This is the same as\n `(case (Cond) of true->(TrueCase); false->(FalseCase) end)`.) Note that it is\n an error if `Cond` does not yield a boolean value.\n\n[](){: #Assert_macros }","ref":"chapter.html#utility-macros"},{"type":"extras","title":"Assert macros - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"(Note that these macros also have corresponding forms which start with an \"`_`\"\n(underscore) character, as in `?_assert(BoolExpr)`, that create a \"test object\"\ninstead of performing the test immediately. This is equivalent to writing\n`?_test(assert(BoolExpr))`, etc.)\n\nIf the macro `NOASSERT` is defined before the EUnit header file is included,\nthese macros have no effect when testing is also disabled; see\n[Compilation control macros](chapter.md#Compilation_control_macros) for details.\n\n- **`assert(BoolExpr)`** - Evaluates the expression `BoolExpr`, if testing is\n enabled. Unless the result is `true`, an informative exception will be\n generated. If there is no exception, the result of the macro expression is the\n atom `ok`, and the value of `BoolExpr` is discarded. If testing is disabled,\n the macro will not generate any code except the atom `ok`, and `BoolExpr` will\n not be evaluated.\n\n Typical usage:\n\n ```text\n ?assert(f(X, Y) =:= [])\n ```\n\n The `assert` macro can be used anywhere in a program, not just in unit tests,\n to check pre/postconditions and invariants. For example:\n\n ```text\n some_recursive_function(X, Y, Z) ->\n ?assert(X + Y > Z),\n ...\n ```\n\n- **`assertNot(BoolExpr)`** - Equivalent to `assert(not (BoolExpr))`.\n\n- **`assertMatch(GuardedPattern, Expr)`** - Evaluates `Expr` and matches the\n result against `GuardedPattern`, if testing is enabled. If the match fails, an\n informative exception will be generated; see the `assert` macro for further\n details. `GuardedPattern` can be anything that you can write on the left hand\n side of the `->` symbol in a case-clause, except that it cannot contain\n comma-separated guard tests.\n\n The main reason for using `assertMatch` also for simple matches, instead of\n matching with `=`, is that it produces more detailed error messages.\n\n Examples:\n\n ```text\n ?assertMatch({found, {fred, _}}, lookup(bloggs, Table))\n ```\n\n ```text\n ?assertMatch([X|_] when X > 0, binary_to_list(B))\n ```\n\n- **`assertNotMatch(GuardedPattern, Expr)`** - The inverse case of assertMatch,\n for convenience.\n\n- **`assertEqual(Expect, Expr)`** - Evaluates the expressions `Expect` and\n `Expr` and compares the results for equality, if testing is enabled. If the\n values are not equal, an informative exception will be generated; see the\n `assert` macro for further details.\n\n `assertEqual` is more suitable than `assertMatch` when the left-hand side is a\n computed value rather than a simple pattern, and gives more details than\n `?assert(Expect =:= Expr)`.\n\n Examples:\n\n ```text\n ?assertEqual(\"b\" ++ \"a\", lists:reverse(\"ab\"))\n ```\n\n ```text\n ?assertEqual(foo(X), bar(Y))\n ```\n\n- **`assertNotEqual(Unexpected, Expr)`** - The inverse case of assertEqual, for\n convenience.\n\n- **`assertException(ClassPattern, TermPattern, Expr)`**\n\n- **`assertError(TermPattern, Expr)`**\n\n- **`assertExit(TermPattern, Expr)`**\n\n- **`assertThrow(TermPattern, Expr)`** - Evaluates `Expr`, catching any\n exception and testing that it matches the expected `ClassPattern:TermPattern`.\n If the match fails, or if no exception is thrown by `Expr`, an informative\n exception will be generated; see the `assert` macro for further details. The\n `assertError`, `assertExit`, and `assertThrow` macros, are equivalent to using\n `assertException` with a `ClassPattern` of `error`, `exit`, or `throw`,\n respectively.\n\n Examples:\n\n ```text\n ?assertError(badarith, X/0)\n ```\n\n ```text\n ?assertExit(normal, exit(normal))\n ```\n\n ```text\n ?assertException(throw, {not_found,_}, throw({not_found,42}))\n ```\n\n[](){: #Macros_for_checking_output }","ref":"chapter.html#assert-macros"},{"type":"extras","title":"Macros for checking output - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"The following macro can be used within a test case to retrieve the output\nwritten to standard output.\n\n- **`capturedOutput`** - The output captured by EUnit in the current test case,\n as a string.\n\n Examples:\n\n ```text\n io:format(\"Hello~n\"),\n ?assertEqual(\"Hello\\n\", ?capturedOutput)\n ```\n\n[](){: #Macros_for_running_external_commands }","ref":"chapter.html#macros-for-checking-output"},{"type":"extras","title":"Macros for running external commands - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"Keep in mind that external commands are highly dependent on the operating\nsystem. You can use the standard library function `os:type()` in test generator\nfunctions, to produce different sets of tests depending on the current operating\nsystem.\n\nNote: these macros introduce a run-time dependency on the EUnit library code, if\ncompiled with testing enabled.\n\n- **`assertCmd(CommandString)`** - Runs `CommandString` as an external command,\n if testing is enabled. Unless the returned status value is 0, an informative\n exception will be generated. If there is no exception, the result of the macro\n expression is the atom `ok`. If testing is disabled, the macro will not\n generate any code except the atom `ok`, and the command will not be executed.\n\n Typical usage:\n\n ```text\n ?assertCmd(\"mkdir foo\")\n ```\n\n- **`assertCmdStatus(N, CommandString)`** - Like the `assertCmd(CommandString)`\n macro, but generates an exception unless the returned status value is `N`.\n\n- **`assertCmdOutput(Text, CommandString)`** - Runs `CommandString` as an\n external command, if testing is enabled. Unless the output produced by the\n command exactly matches the specified string `Text`, an informative exception\n will be generated. (Note that the output is normalized to use a single LF\n character as line break on all platforms.) If there is no exception, the\n result of the macro expression is the atom `ok`. If testing is disabled, the\n macro will not generate any code except the atom `ok`, and the command will\n not be executed.\n\n- **`cmd(CommandString)`** - Runs `CommandString` as an external command. Unless\n the returned status value is 0 (indicating success), an informative exception\n will be generated; otherwise, the result of the macro expression is the output\n produced by the command, as a flat string. The output is normalized to use a\n single LF character as line break on all platforms.\n\n This macro is useful in the setup and cleanup sections of fixtures, e.g., for\n creating and deleting files or perform similar operating system specific\n tasks, to make sure that the test system is informed of any failures.\n\n A Unix-specific example:\n\n ```text\n {setup,\n fun () -> ?cmd(\"mktemp\") end,\n fun (FileName) -> ?cmd(\"rm \" ++ FileName) end,\n ...}\n ```\n\n[](){: #Debugging_macros }","ref":"chapter.html#macros-for-running-external-commands"},{"type":"extras","title":"Debugging macros - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"To help with debugging, EUnit defines several useful macros for printing\nmessages directly to the console (rather than to the standard output).\nFurthermore, these macros all use the same basic format, which includes the file\nand line number where they occur, making it possible in some development\nenvironments (e.g., when running Erlang in an Emacs buffer) to simply click on\nthe message and jump directly to the corresponding line in the code.\n\nIf the macro `NODEBUG` is defined before the EUnit header file is included,\nthese macros have no effect; see\n[Compilation control macros](chapter.md#Compilation_control_macros) for details.\n\n- **`debugHere`** - Just prints a marker showing the current file and line\n number. Note that this is an argument-less macro. The result is always `ok`.\n\n- **`debugMsg(Text)`** - Outputs the message `Text` (which can be a plain\n string, an IO-list, or just an atom). The result is always `ok`.\n\n- **`debugFmt(FmtString, Args)`** - This formats the text like\n `io:format(FmtString, Args)` and outputs it like `debugMsg`. The result is\n always `ok`.\n\n- **`debugVal(Expr)`** - Prints both the source code for `Expr` and its current\n value. E.g., `?debugVal(f(X))` might be displayed as \"`f(X) = 42`\". (Large\n terms are truncated to the depth given by the macro `EUNIT_DEBUG_VAL_DEPTH`,\n which defaults to 15 but can be overridden by the user.) The result is always\n the value of `Expr`, so this macro can be wrapped around any expression to\n display its value when the code is compiled with debugging enabled.\n\n- **`debugVal(Expr, Depth)`** - Like `debugVal(Expr)`, but prints terms\n truncated to the given depth.\n\n- **`debugTime(Text,Expr)`** - Prints `Text` and the wall clock time for\n evaluation of `Expr`. The result is always the value of `Expr`, so this macro\n can be wrapped around any expression to show its run time when the code is\n compiled with debugging enabled. For example,\n `List1 = ?debugTime(\"sorting\", lists:sort(List))` might show as\n \"`sorting: 0.015 s`\".\n\n[](){: #EUnit_test_representation }","ref":"chapter.html#debugging-macros"},{"type":"extras","title":"EUnit test representation - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"The way EUnit represents tests and test sets as data is flexible, powerful, and\nconcise. This section describes the representation in detail.\n\n- [Simple test objects](chapter.md#Simple_test_objects)\n- [Test sets and deep lists](chapter.md#Test_sets_and_deep_lists)\n- [Titles](chapter.md#titles)\n- [Primitives](chapter.md#primitives)\n- [Control](chapter.md#control)\n- [Fixtures](chapter.md#fixtures)\n- [Lazy generators](chapter.md#Lazy_generators)\n\n[](){: #Simple_test_objects }","ref":"chapter.html#eunit-test-representation"},{"type":"extras","title":"Simple test objects - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"A _simple test object_ is one of the following:\n\n- A nullary functional value (i.e., a fun that takes zero arguments). Examples:\n\n ```text\n fun () -> ... end\n ```\n\n ```text\n fun some_function/0\n ```\n\n ```text\n fun some_module:some_function/0\n ```\n\n- A tuple `{test, ModuleName, FunctionName}`, where `ModuleName` and\n `FunctionName` are atoms, referring to the function\n `ModuleName:FunctionName/0`\n- (Obsolete) A pair of atoms `{ModuleName, FunctionName}`, equivalent to\n `{test, ModuleName, FunctionName}` if nothing else matches first. This might\n be removed in a future version.\n- A pair `{LineNumber, SimpleTest}`, where `LineNumber` is a nonnegative integer\n and `SimpleTest` is another simple test object. `LineNumber` should indicate\n the source line of the test. Pairs like this are usually only created via\n `?_test(...)` macros; see [Basic macros](chapter.md#Basic_macros).\n\nIn brief, a simple test object consists of a single function that takes no\narguments (possibly annotated with some additional metadata, i.e., a line\nnumber). Evaluation of the function either _succeeds_, by returning some value\n(which is ignored), or _fails_, by throwing an exception.\n\n[](){: #Test_sets_and_deep_lists }","ref":"chapter.html#simple-test-objects"},{"type":"extras","title":"Test sets and deep lists - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"A test set can be easily created by placing a sequence of test objects in a\nlist. If `T_1`, ..., `T_N` are individual test objects, then `[T_1, ..., T_N]`\nis a test set consisting of those objects (in that order).\n\nTest sets can be joined in the same way: if `S_1`, ..., `S_K` are test sets,\nthen `[S_1, ..., S_K]` is also a test set, where the tests of `S_i` are ordered\nbefore those of `S_(i+1)`, for each subset `S_i`.\n\nThus, the main representation of test sets is _deep lists_, and a simple test\nobject can be viewed as a test set containing only a single test; there is no\ndifference between `T` and `[T]`.\n\nA module can also be used to represent a test set; see `ModuleName` under\n[Primitives](chapter.md#primitives) below.","ref":"chapter.html#test-sets-and-deep-lists"},{"type":"extras","title":"Titles - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"Any test or test set `T` can be annotated with a title, by wrapping it in a pair\n`{Title, T}`, where `Title` is a string. For convenience, any test which is\nnormally represented using a tuple can simply be given a title string as the\nfirst element, i.e., writing `{\"The Title\", ...}` instead of adding an extra\ntuple wrapper as in `{\"The Title\", {...}}`.","ref":"chapter.html#titles"},{"type":"extras","title":"Primitives - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"The following are primitives, which do not contain other test sets as arguments:\n\n- **`ModuleName::atom()`** - A single atom represents a module name, and is\n equivalent to `{module, ModuleName}`. This is often used as in the call\n `eunit:test(some_module)`.\n\n- **`{module, ModuleName::atom()}`** - This composes a test set from the\n exported test functions of the named module, i.e., those functions with arity\n zero whose names end with `_test` or `_test_`. Basically, the `..._test()`\n functions become simple tests, while the `..._test_()` functions become\n generators.\n\n In addition, EUnit will also look for another module whose name is\n `ModuleName` plus the suffix `_tests`, and if it exists, all the tests from\n that module will also be added. (If `ModuleName` already contains the suffix\n `_tests`, this is not done.) E.g., the specification `{module, mymodule}` will\n run all tests in the modules `mymodule` and `mymodule_tests`. Typically, the\n `_tests` module should only contain test cases that use the public interface\n of the main module (and no other code).\n\n- **`{application, AppName::atom(), Info::list()}`** - This is a normal\n Erlang/OTP application descriptor, as found in an `.app` file. The resulting\n test set consists of the modules listed in the `modules` entry in `Info`.\n\n- **`{application, AppName::atom()}`** - This creates a test set from all the\n modules belonging to the specified application, by consulting the\n application's `.app` file (see `{file, FileName}`), or if no such file exists,\n by testing all object files in the application's `ebin`\\-directory (see\n `{dir, Path}`); if that does not exist, the `code:lib_dir(AppName)` directory\n is used.\n\n- **`Path::string()`** - A single string represents the path of a file or\n directory, and is equivalent to `{file, Path}`, or `{dir, Path}`,\n respectively, depending on what `Path` refers to in the file system.\n\n- **`{file, FileName::string()}`** - If `FileName` has a suffix that indicates\n an object file (`.beam`), EUnit will try to reload the module from the\n specified file and test it. Otherwise, the file is assumed to be a text file\n containing test specifications, which will be read using the standard library\n function `file:path_consult/2`.\n\n Unless the file name is absolute, the file is first searched for relative to\n the current directory, and then using the normal search path\n (`code:get_path()`). This means that the names of typical \"app\" files can be\n used directly, without a path, e.g., `\"mnesia.app\"`.\n\n- **`{dir, Path::string()}`** - This tests all object files in the specified\n directory, as if they had been individually specified using\n `{file, FileName}`.\n\n- **`{generator, GenFun::(() -> Tests)}`** - The generator function `GenFun` is\n called to produce a test set.\n\n- **`{generator, ModuleName::atom(), FunctionName::atom()}`** - The function\n `ModuleName:FunctionName()` is called to produce a test set.\n\n- **`{with, X::any(), [AbstractTestFun::((any()) -> any())]}`** - Distributes\n the value `X` over the unary functions in the list, turning them into nullary\n test functions. An `AbstractTestFun` is like an ordinary test fun, but takes\n one argument instead of zero - it's basically missing some information before\n it can be a proper test. In practice, `{with, X, [F_1, ..., F_N]}` is\n equivalent to `[fun () -> F_1(X) end, ..., fun () -> F_N(X) end]`. This is\n particularly useful if your abstract test functions are already implemented as\n proper functions:\n `{with, FD, [fun filetest_a/1, fun filetest_b/1, fun filetest_c/1]}` is\n equivalent to\n `[fun () -> filetest_a(FD) end, fun () -> filetest_b(FD) end, fun () -> filetest_c(FD) end]`,\n but much more compact. See also [Fixtures](chapter.md#fixtures), below.","ref":"chapter.html#primitives"},{"type":"extras","title":"Control - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"The following representations control how and where tests are executed:\n\n- **`{spawn, Tests}`** - Runs the specified tests in a separate subprocess,\n while the current test process waits for it to finish. This is useful for\n tests that need a fresh, isolated process state. (Note that EUnit always\n starts at least one such a subprocess automatically; tests are never executed\n by the caller's own process.)\n\n- **`{spawn, Node::atom(), Tests}`** - Like `{spawn, Tests}`, but runs the\n specified tests on the given Erlang node.\n\n- **`{timeout, Time::number(), Tests}`** - Runs the specified tests under the\n given timeout. Time is in seconds; e.g., 60 means one minute and 0.1 means\n 1/10th of a second. If the timeout is exceeded, the unfinished tests will be\n forced to terminate. Note that if a timeout is set around a fixture, it\n includes the time for setup and cleanup, and if the timeout is triggered, the\n entire fixture is abruptly terminated (without running the cleanup). The\n default timeout for an individual test is 5 seconds.\n\n- **`{inorder, Tests}`** - Runs the specified tests in strict order. Also see\n `{inparallel, Tests}`. By default, tests are neither marked as `inorder` or\n `inparallel`, but may be executed as the test framework chooses.\n\n- **`{inparallel, Tests}`** - Runs the specified tests in parallel (if\n possible). Also see `{inorder, Tests}`.\n\n- **`{inparallel, N::integer(), Tests}`** - Like `{inparallel, Tests}`, but\n running no more than `N` subtests simultaneously.","ref":"chapter.html#control"},{"type":"extras","title":"Fixtures - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"A \"fixture\" is some state that is necessary for a particular set of tests to\nrun. EUnit's support for fixtures makes it easy to set up such state locally for\na test set, and automatically tear it down again when the test set is finished,\nregardless of the outcome (success, failures, timeouts, etc.).\n\nTo make the descriptions simpler, we first list some definitions:\n\n| `Setup` | `() -> (R::any())` |\n| -------------- | ------------------------------- | ---------------------------------------------- | ---------------------- |\n| `SetupX` | `(X::any()) -> (R::any())` |\n| `Cleanup` | `(R::any()) -> any()` |\n| `CleanupX` | `(X::any(), R::any()) -> any()` |\n| `Instantiator` | `((R::any()) -> Tests) | {with, [AbstractTestFun::((any()) -> any())]}` |\n| `Where` | `local | spawn | {spawn, Node::atom()}` |\n\n(these are explained in more detail further below.)\n\nThe following representations specify fixture handling for test sets:\n\n- **`{setup, Setup, Tests | Instantiator}`**\n\n- **`{setup, Setup, Cleanup, Tests | Instantiator}`**\n\n- **`{setup, Where, Setup, Tests | Instantiator}`**\n\n- **`{setup, Where, Setup, Cleanup, Tests | Instantiator}`** - `setup` sets up a\n single fixture for running all of the specified tests, with optional teardown\n afterwards. The arguments are described in detail below.\n\n- **`{node, Node::atom(), Tests | Instantiator}`**\n\n- **`{node, Node::atom(), Args::string(), Tests | Instantiator}`** - `node` is\n like `setup`, but with a built-in behaviour: it starts a slave node for the\n duration of the tests. The atom `Node` should have the format\n `nodename@full.machine.name`, and `Args` are the optional arguments to the new\n node; see `slave:start_link/3` for details.\n\n- **`{foreach, Where, Setup, Cleanup, [Tests | Instantiator]}`**\n\n- **`{foreach, Setup, Cleanup, [Tests | Instantiator]}`**\n\n- **`{foreach, Where, Setup, [Tests | Instantiator]}`**\n\n- **`{foreach, Setup, [Tests | Instantiator]}`** - `foreach` is used to set up a\n fixture and optionally tear it down afterwards, repeated for each single one\n of the specified test sets.\n\n- **`{foreachx, Where, SetupX, CleanupX, Pairs::[{X::any(), ((X::any(), R::any()) -> Tests)}]}`**\n\n- **`{foreachx, SetupX, CleanupX, Pairs}`**\n\n- **`{foreachx, Where, SetupX, Pairs}`**\n\n- **`{foreachx, SetupX, Pairs}`** - `foreachx` is like `foreach`, but uses a\n list of pairs, each containing an extra argument `X` and an extended\n instantiator function.\n\nA `Setup` function is executed just before any of the specified tests are run,\nand a `Cleanup` function is executed when no more of the specified tests will be\nrun, regardless of the reason. A `Setup` function takes no argument, and returns\nsome value which will be passed as it is to the `Cleanup` function. A `Cleanup`\nfunction should do whatever necessary and return some arbitrary value, such as\nthe atom `ok`. (`SetupX` and `CleanupX` functions are similar, but receive one\nadditional argument: some value `X`, which depends on the context.) When no\n`Cleanup` function is specified, a dummy function is used which has no effect.\n\nAn `Instantiator` function receives the same value as the `Cleanup` function,\ni.e., the value returned by the `Setup` function. It should then behave much\nlike a generator (see [Primitives](chapter.md#primitives)), and return a test\nset whose tests have been _instantiated_ with the given value. A special case is\nthe syntax `{with, [AbstractTestFun]}` which represents an instantiator function\nthat distributes the value over a list of unary functions; see\n[Primitives](chapter.md#primitives): `{with, X, [...]}` for more details.\n\nA `Where` term controls how the specified tests are executed. The default is\n`spawn`, which means that the current process handles the setup and teardown,\nwhile the tests are executed in a subprocess. `{spawn, Node}` is like `spawn`,\nbut runs the subprocess on the specified node. `local` means that the current\nprocess will handle both setup/teardown and running the tests - the drawback is\nthat if a test times out so that the process is killed, the _cleanup will not be\nperformed_; hence, avoid this for persistent fixtures such as file operations.\nIn general, `local` should only be used when:\n\n- the setup/teardown needs to be executed by the process that will run the\n tests;\n- no further teardown needs to be done if the process is killed (i.e., no state\n outside the process was affected by the setup)\n\n[](){: #Lazy_generators }","ref":"chapter.html#fixtures"},{"type":"extras","title":"Lazy generators - EUnit - a Lightweight Unit Testing Framework for Erlang","doc":"Sometimes, it can be convenient not to produce the whole set of test\ndescriptions before the testing begins; for example, if you want to generate a\nhuge amount of tests that would take up too much space to keep in memory all at\nonce.\n\nIt is fairly easy to write a generator which, each time it is called, either\nproduces an empty list if it is done, or otherwise produces a list containing a\nsingle test case plus a new generator which will produce the rest of the tests.\nThis demonstrates the basic pattern:\n\n```text\n lazy_test_() ->\n lazy_gen(10000).\n\n lazy_gen(N) ->\n {generator,\n fun () ->\n if N > 0 ->\n [?_test(...)\n | lazy_gen(N-1)];\n true ->\n []\n end\n end}.\n```\n\nWhen EUnit traverses the test representation in order to run the tests, the new\ngenerator will not be called to produce the next test until the previous test\nhas been executed.\n\nNote that it is easiest to write this kind of recursive generator using a help\nfunction, like the `lazy_gen/1` function above. It can also be written using a\nrecursive fun, if you prefer to not clutter your function namespace and are\ncomfortable with writing that kind of code.","ref":"chapter.html#lazy-generators"}],"content_type":"text/plain","producer":{"name":"ex_doc","version":[48,46,51,52,46,49]}} \ No newline at end of file diff --git a/prs/8803/lib/eunit-2.9.1/doc/html/eunit.epub b/prs/8803/lib/eunit-2.9.1/doc/html/eunit.epub index 29e12e126fb0b..8f8237ceb87c7 100644 Binary files a/prs/8803/lib/eunit-2.9.1/doc/html/eunit.epub and b/prs/8803/lib/eunit-2.9.1/doc/html/eunit.epub differ diff --git a/prs/8803/lib/eunit-2.9.1/doc/html/search.html b/prs/8803/lib/eunit-2.9.1/doc/html/search.html index 8354356e546cb..c13b3286384be 100644 --- a/prs/8803/lib/eunit-2.9.1/doc/html/search.html +++ b/prs/8803/lib/eunit-2.9.1/doc/html/search.html @@ -122,7 +122,7 @@

        - +

        diff --git a/prs/8803/lib/ftp-1.2.2/doc/html/ftp.epub b/prs/8803/lib/ftp-1.2.2/doc/html/ftp.epub index 68240831814d5..0690335ff8fb5 100644 Binary files a/prs/8803/lib/ftp-1.2.2/doc/html/ftp.epub and b/prs/8803/lib/ftp-1.2.2/doc/html/ftp.epub differ diff --git a/prs/8803/lib/ftp-1.2.2/doc/html/ftp_client.html b/prs/8803/lib/ftp-1.2.2/doc/html/ftp_client.html index 37f98f590195a..f843ec685ae69 100644 --- a/prs/8803/lib/ftp-1.2.2/doc/html/ftp_client.html +++ b/prs/8803/lib/ftp-1.2.2/doc/html/ftp_client.html @@ -126,25 +126,25 @@

        The following is a simple example of an FTP session, where the user guest with -password password logs on to the remote host erlang.org:

              1> ftp:start().
        +password password logs on to the remote host erlang.org:

              1> ftp:start().
               ok
        -      2> {ok, Pid} = ftp:open([{host, "erlang.org"}]).
        -      {ok,<0.22.0>}
        -      3> ftp:user(Pid, "guest", "password").
        +      2> {ok, Pid} = ftp:open([{host, "erlang.org"}]).
        +      {ok,<0.22.0>}
        +      3> ftp:user(Pid, "guest", "password").
               ok
        -      4> ftp:pwd(Pid).
        -      {ok, "/home/guest"}
        -      5> ftp:cd(Pid, "appl/examples").
        +      4> ftp:pwd(Pid).
        +      {ok, "/home/guest"}
        +      5> ftp:cd(Pid, "appl/examples").
               ok
        -      6> ftp:lpwd(Pid).
        -      {ok, "/home/fred"}.
        -      7> ftp:lcd(Pid, "/home/eproj/examples").
        +      6> ftp:lpwd(Pid).
        +      {ok, "/home/fred"}.
        +      7> ftp:lcd(Pid, "/home/eproj/examples").
               ok
        -      8> ftp:recv(Pid, "appl.erl").
        +      8> ftp:recv(Pid, "appl.erl").
               ok
        -      9> ftp:close(Pid).
        +      9> ftp:close(Pid).
               ok
        -      10> ftp:stop().
        +      10> ftp:stop().
               ok

        The file appl.erl is transferred from the remote to the local host. When the session is opened, the current directory at the remote host is /home/guest, and /home/fred at the local host. Before transferring the file, the current diff --git a/prs/8803/lib/inets-9.2/doc/html/http_client.html b/prs/8803/lib/inets-9.2/doc/html/http_client.html index 637ac1cc52863..afcbd0463be39 100644 --- a/prs/8803/lib/inets-9.2/doc/html/http_client.html +++ b/prs/8803/lib/inets-9.2/doc/html/http_client.html @@ -138,32 +138,32 @@

        handle each request, unless a persistent connection can be used with or without pipelining. The client adds a host header and an empty te header if there are no such headers present in the request.

        The client supports IPv6 as long as the underlying mechanisms also do so.

        The following is to be put in the Erlang node application configuration file to -start a profile at application startup:

        [{inets, [{services, [{httpc, PropertyList}]}]}]

        For valid properties, see httpc.

        +start a profile at application startup:

        [{inets, [{services, [{httpc, PropertyList}]}]}]

        For valid properties, see httpc.

        Getting Started

        -

        Start Inets:

        1> inets:start().
        +

        Start Inets:

        1> inets:start().
         ok

        The following calls use the default client profile. Use the proxy "www-proxy.mycompany.com:8000", except from requests to localhost. This -applies to all the following requests.

        Example:

        2> httpc:set_options([{proxy, {{"www-proxy.mycompany.com", 8000},
        -["localhost"]}}]).
        -ok

        The following is an ordinary synchronous request:

        3> {ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
        -.. httpc:request(get, {"http://www.erlang.org", []}, [], []).

        With all the default values presented, a get request can also be written as -follows:

        4> {ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
        -.. httpc:request("http://www.erlang.org").

        The following is a https request and with verification of the host:

        5> {ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
        -.. httpc:request(get, {"https://www.erlang.org", []}, [{ssl, httpc:ssl_verify_host_options(true)}], []).

        The following is an ordinary asynchronous request:

        6> {ok, RequestId} =
        -.. httpc:request(get, {"http://www.erlang.org", []}, [], [{sync, false}]).

        The result is sent to the calling process as {http, {ReqestId, Result}}.

        In this case, the calling process is the shell, so the following result is -received:

        7> receive {http, {RequestId, Result}} -> ok after 500 -> error end.
        -ok

        This sends a request with a specified connection header:

        8> {ok, {{NewVersion, 200, NewReasonPhrase}, NewHeaders, NewBody}} =
        -.. httpc:request(get, {"http://www.erlang.org", [{"connection", "close"}]},
        -.. [], []).

        This sends an HTTP request over a unix domain socket (experimental):

        9> httpc:set_options([{ipfamily, local}, {unix_socket,"/tmp/unix_socket/consul_http.sock"}]).
        -10> {ok, {{NewVersion, 200, NewReasonPhrase}, NewHeaders, NewBody}} =
        - .. httpc:request(put, {"http:///v1/kv/foo", [], [], "hello"}, [], []).

        Start an HTTP client profile:

        10> {ok, Pid} = inets:start(httpc, [{profile, foo}]).
        -{ok, <0.45.0>}

        The new profile has no proxy settings, so the connection is refused:

        11> httpc:request("http://www.erlang.org", foo).
        -{error, econnrefused}

        Stop the HTTP client profile:

        12> inets:stop(httpc, foo).
        -ok

        Alternative way to stop the HTTP client profile:

        13> inets:stop(httpc, Pid).
        +applies to all the following requests.

        Example:

        2> httpc:set_options([{proxy, {{"www-proxy.mycompany.com", 8000},
        +["localhost"]}}]).
        +ok

        The following is an ordinary synchronous request:

        3> {ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
        +.. httpc:request(get, {"http://www.erlang.org", []}, [], []).

        With all the default values presented, a get request can also be written as +follows:

        4> {ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
        +.. httpc:request("http://www.erlang.org").

        The following is a https request and with verification of the host:

        5> {ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
        +.. httpc:request(get, {"https://www.erlang.org", []}, [{ssl, httpc:ssl_verify_host_options(true)}], []).

        The following is an ordinary asynchronous request:

        6> {ok, RequestId} =
        +.. httpc:request(get, {"http://www.erlang.org", []}, [], [{sync, false}]).

        The result is sent to the calling process as {http, {ReqestId, Result}}.

        In this case, the calling process is the shell, so the following result is +received:

        7> receive {http, {RequestId, Result}} -> ok after 500 -> error end.
        +ok

        This sends a request with a specified connection header:

        8> {ok, {{NewVersion, 200, NewReasonPhrase}, NewHeaders, NewBody}} =
        +.. httpc:request(get, {"http://www.erlang.org", [{"connection", "close"}]},
        +.. [], []).

        This sends an HTTP request over a unix domain socket (experimental):

        9> httpc:set_options([{ipfamily, local}, {unix_socket,"/tmp/unix_socket/consul_http.sock"}]).
        +10> {ok, {{NewVersion, 200, NewReasonPhrase}, NewHeaders, NewBody}} =
        + .. httpc:request(put, {"http:///v1/kv/foo", [], [], "hello"}, [], []).

        Start an HTTP client profile:

        10> {ok, Pid} = inets:start(httpc, [{profile, foo}]).
        +{ok, <0.45.0>}

        The new profile has no proxy settings, so the connection is refused:

        11> httpc:request("http://www.erlang.org", foo).
        +{error, econnrefused}

        Stop the HTTP client profile:

        12> inets:stop(httpc, foo).
        +ok

        Alternative way to stop the HTTP client profile:

        13> inets:stop(httpc, Pid).
         ok
        diff --git a/prs/8803/lib/inets-9.2/doc/html/http_server.html b/prs/8803/lib/inets-9.2/doc/html/http_server.html index e08641b2d43dc..8ea3cd4b25745 100644 --- a/prs/8803/lib/inets-9.2/doc/html/http_server.html +++ b/prs/8803/lib/inets-9.2/doc/html/http_server.html @@ -141,20 +141,20 @@

        server API, which is described in the Erlang Web Server API. This API can be used to enhance the core server functionality, for example with custom logging and authentication.

        The following is to be put in the Erlang node application configuration file to -start an HTTP server at application startup:

        [{inets, [{services, [{httpd, [{proplist_file,
        -           "/var/tmp/server_root/conf/8888_props.conf"}]},
        -          {httpd, [{proplist_file,
        -           "/var/tmp/server_root/conf/8080_props.conf"}]}]}]}].

        The server is configured using an Erlang property list. For the available -properties, see httpd.

        The available configuration properties are as follows:

        httpd_service() -> {httpd, httpd()}
        -httpd()         -> [httpd_config()]
        -httpd_config()  -> {proplist_file, file()}
        -                   {debug, debug()} |
        -                   {accept_timeout, integer()}
        -debug()         -> disable | [debug_options()]
        -debug_options() -> {all_functions, modules()} |
        -                   {exported_functions, modules()} |
        -                   {disable, modules()}
        -modules()       -> [atom()]

        Here:

        In all of these cases, ReplyInfo has the following structure:

         {RequestId, saved_to_file}
        - {RequestId, {error, Reason}}
        - {RequestId, Result}
        - {RequestId, stream_start, Headers}
        - {RequestId, stream_start, Headers, HandlerPid}
        - {RequestId, stream, BinBodyPart}
        - {RequestId, stream_end, Headers}

        Default is the pid of the process calling the request function (self/0).

      • ipv6_host_with_brackets - Defines when parsing the Host-Port part of an +apply(Module, Function, [ReplyInfo | Args]).

      In all of these cases, ReplyInfo has the following structure:

       {RequestId, saved_to_file}
      + {RequestId, {error, Reason}}
      + {RequestId, Result}
      + {RequestId, stream_start, Headers}
      + {RequestId, stream_start, Headers, HandlerPid}
      + {RequestId, stream, BinBodyPart}
      + {RequestId, stream_end, Headers}

      Default is the pid of the process calling the request function (self/0).

    • ipv6_host_with_brackets - Defines when parsing the Host-Port part of an URI with an IPv6 address with brackets, if those brackets are to be retained (true) or stripped (false).

      Default is false.

    diff --git a/prs/8803/lib/inets-9.2/doc/html/httpd.html b/prs/8803/lib/inets-9.2/doc/html/httpd.html index eef281f0bff96..f3fc2ec20dd34 100644 --- a/prs/8803/lib/inets-9.2/doc/html/httpd.html +++ b/prs/8803/lib/inets-9.2/doc/html/httpd.html @@ -236,36 +236,36 @@

    level error under the hierarchical logger domain: [otp, inets, httpd, ServerID, error] The built in logger formatting function produces log entries from the error -reports:

    #{server_name => string()
    +reports:

    #{server_name => string()
       protocol => internal | 'TCP' | 'TLS' | 'HTTP',
       transport => "TCP" | "TLS", %% Present when protocol = 'HTTP'
    -  uri => string(), %% Present when protocol = 'HTTP' and URI is valid
    -  peer => inet:peername(),
    -  host => inet:hostname(),
    -  reason => term()
    -}

    An example of a log entry with only default settings of logger

    =ERROR REPORT==== 9-Oct-2019::09:33:27.350235 ===
    +  uri => string(), %% Present when protocol = 'HTTP' and URI is valid
    +  peer => inet:peername(),
    +  host => inet:hostname(),
    +  reason => term()
    +}

    An example of a log entry with only default settings of logger

    =ERROR REPORT==== 9-Oct-2019::09:33:27.350235 ===
        Server: My Server
      Protocol: HTTP
     Transport: TLS
           URI: /not_there
          Host: 127.0.1.1:80
          Peer: 127.0.0.1:45253
    -   Reason: [{statuscode,404},{description,"Object Not Found"}]

    Using this option makes mod_log and mod_disk_log error logs redundant.

    Add the filter

    {fun logger_filters:domain/2,
    -    {log,equal,[otp,inets, httpd, ServerID, error]}

    to appropriate logger handler to handle the events. For example to write the + Reason: [{statuscode,404},{description,"Object Not Found"}]

    Using this option makes mod_log and mod_disk_log error logs redundant.

    Add the filter

    {fun logger_filters:domain/2,
    +    {log,equal,[otp,inets, httpd, ServerID, error]}

    to appropriate logger handler to handle the events. For example to write the error log from an httpd server with a ServerID of my_server to a file -you can use the following sys.config:

    [{kernel,
    - [{logger,
    -  [{handler, http_error_test, logger_std_h,
    -    #{config => #{ file => "log/http_error.log" },
    -      filters => [{inets_httpd, {fun logger_filters:domain/2,
    -                                 {log, equal,
    -                                  [otp, inets, httpd, my_server, error]
    -                                 }}}],
    -      filter_default => stop }}]}]}].

    or if you want to add it to the default logger via an API:

    logger:add_handler_filter(default,
    +you can use the following sys.config:

    [{kernel,
    + [{logger,
    +  [{handler, http_error_test, logger_std_h,
    +    #{config => #{ file => "log/http_error.log" },
    +      filters => [{inets_httpd, {fun logger_filters:domain/2,
    +                                 {log, equal,
    +                                  [otp, inets, httpd, my_server, error]
    +                                 }}}],
    +      filter_default => stop }}]}]}].

    or if you want to add it to the default logger via an API:

    logger:add_handler_filter(default,
                               inets_httpd,
    -                          {fun logger_filters:domain/2,
    -                           {log, equal,
    -                            [otp, inets, httpd, my_server, error]}}).
  • {log_format, common | combined}
    Defines if access logs are to be written according to the common log format + {fun logger_filters:domain/2, + {log, equal, + [otp, inets, httpd, my_server, error]}}).

  • {log_format, common | combined}
    Defines if access logs are to be written according to the common log format or the extended common log format. The common format is one line looking like this: remotehost rfc931 authuser [date] "request" status bytes.

    Here:

    • remotehost - Remote.

    • rfc931 - The remote username of the client (RFC 931).

    • authuser - The username used for authentication.

    • [date] - Date and time of the request @@ -275,7 +275,7 @@

      remotehost rfc931 authuser [date] "request" status bytes "referer" "user_agent"

      In addition to the earlier:

      • "referer" - The URL the client was on before requesting the URL (if it could not be determined, a minus sign is placed in this field).

      • "user_agent" - The software the client claims to be using (if it could not be determined, a minus sign is placed in this field).

      This affects the access logs written by mod_log and mod_disk_log.

    • {error_log_format, pretty | compact}
      Default is pretty. If the error log is meant to be read directly by a human, -pretty is the best option.

      pretty has a format corresponding to:

      io:format("[~s] ~s, reason: ~n ~p ~n~n", [Date, Msg, Reason]).

      compact has a format corresponding to:

      io:format("[~s] ~s, reason: ~w ~n", [Date, Msg, Reason]).

      This affects the error logs written by mod_log and mod_disk_log.

    +pretty is the best option.

    pretty has a format corresponding to:

    io:format("[~s] ~s, reason: ~n ~p ~n~n", [Date, Msg, Reason]).

    compact has a format corresponding to:

    io:format("[~s] ~s, reason: ~w ~n", [Date, Msg, Reason]).

    This affects the error logs written by mod_log and mod_disk_log.

  • @@ -284,15 +284,15 @@

    • {alias, {Alias, RealName}}
      Alias = string() and RealName = string(). alias allows documents to be stored in the local file system instead of the document_root location. URLs with a path beginning with url-path is mapped to local files beginning with -directory-filename, for example:

      {alias, {"/image", "/ftp/pub/image"}}

      Access to http://your.server.org/image/foo.gif would refer to the file +directory-filename, for example:

      {alias, {"/image", "/ftp/pub/image"}}

      Access to http://your.server.org/image/foo.gif would refer to the file /ftp/pub/image/foo.gif.

    • {re_write, {Re, Replacement}}
      Re = string() and Replacement = string(). re_write allows documents to be stored in the local file system instead of the document_root location. URLs are rewritten by re:replace/3 to produce a path in the local -file-system, for example:

      {re_write, {"^/[~]([^/]+)(.*)$", "/home/\\1/public\\2"}}

      Access to http://your.server.org/~bob/foo.gif would refer to the file +file-system, for example:

      {re_write, {"^/[~]([^/]+)(.*)$", "/home/\\1/public\\2"}}

      Access to http://your.server.org/~bob/foo.gif would refer to the file /home/bob/public/foo.gif.

    • {directory_index, [string()]}
      directory_index specifies a list of resources to look for if a client requests a directory using a / at the end of the directory name. file depicts the name of a file in the directory. Several files can be given, in -which case the server returns the first it finds, for example:

      {directory_index, ["index.html", "welcome.html"]}

      Access to http://your.server.org/docs/ would return +which case the server returns the first it finds, for example:

      {directory_index, ["index.html", "welcome.html"]}

      Access to http://your.server.org/docs/ would return http://your.server.org/docs/index.html or http://your.server.org/docs/welcome.html if index.html does not exist.

    @@ -320,7 +320,7 @@

    method. The method is either GET or POST, as defined in RFC 1945. It propagates the URL and file path of the requested document using the standard CGI PATH_INFO and -PATH_TRANSLATED environment variables.

    Example:

    {script, {"PUT", "/cgi-bin/put"}}

    +PATH_TRANSLATED environment variables.

    Example:

    {script, {"PUT", "/cgi-bin/put"}}

    @@ -328,7 +328,7 @@

    • {erl_script_alias, {URLPath, [AllowedModule]}}
      URLPath = string() and AllowedModule = atom(). erl_script_alias marks all URLs matching url-path as erl scheme scripts. A matching URL is mapped -into a specific module and function, for example:

      {erl_script_alias, {"/cgi-bin/example", [httpd_example]}}

      A request to http://your.server.org/cgi-bin/example/httpd_example:yahoo would +into a specific module and function, for example:

      {erl_script_alias, {"/cgi-bin/example", [httpd_example]}}

      A request to http://your.server.org/cgi-bin/example/httpd_example:yahoo would refer to httpd_example:yahoo/3 or, if that does not exist, httpd_example:yahoo/2 and http://your.server.org/cgi-bin/example/other:yahoo would not be allowed to execute.

    • {erl_script_nocache, boolean()}
      If erl_script_nocache is set to true, the server adds HTTP header fields @@ -378,7 +378,7 @@

      Authentication Properties - Requires mod_auth

      -

      {directory, {path(), [{property(), term()}]}}

      The properties for directories are as follows:

      • {allow_from, all | [RegxpHostString]}
        Defines a set of hosts to be granted access to a given directory, for example:

        {allow_from, ["123.34.56.11", "150.100.23"]}

        The host 123.34.56.11 and all machines on the 150.100.23 subnet are +

        {directory, {path(), [{property(), term()}]}}

        The properties for directories are as follows:

        • {allow_from, all | [RegxpHostString]}
          Defines a set of hosts to be granted access to a given directory, for example:

          {allow_from, ["123.34.56.11", "150.100.23"]}

          The host 123.34.56.11 and all machines on the 150.100.23 subnet are allowed access.

        • {deny_from, all | [RegxpHostString]}
          Defines a set of hosts to be denied access to a given directory, for example:

          {deny_from, ["123.34.56.11", "150.100.23"]}

          The host 123.34.56.11 and all machines on the 150.100.23 subnet are not allowed access.

        • {auth_type, plain | dets | mnesia}
          Sets the type of authentication database that is used for the directory. The key difference between the different methods is that dynamic data can be saved @@ -413,7 +413,7 @@

          Security Properties - Requires mod_security

          -

          {security_directory, {path(), [{property(), term()}]}}

          The properties for the security directories are as follows:

          • {data_file, path()}
            Name of the security data file. The filename can either be absolute or +

            {security_directory, {path(), [{property(), term()}]}}

            The properties for the security directories are as follows:

            • {data_file, path()}
              Name of the security data file. The filename can either be absolute or relative to the server_root. This file is used to store persistent data for module mod_security.

            • {max_retries, integer()}
              Specifies the maximum number of attempts to authenticate a user before the user is blocked out. If a user successfully authenticates while blocked, the @@ -430,10 +430,10 @@

              Web server API data types

              -

              The Erlang web server API data types are as follows:

              ModData = #mod{}
              +

              The Erlang web server API data types are as follows:

              ModData = #mod{}
               
              --record(mod, {
              -    data = [],
              +-record(mod, {
              +    data = [],
                   socket_type = ip_comm,
                   socket,
                   config_db,
              @@ -442,10 +442,10 @@ 

              request_uri, http_version, request_line, - parsed_header = [], + parsed_header = [], entity_body, connection -}).

              To access the record in your callback-module use:

              -include_lib("inets/include/httpd.hrl").

              The fields of record mod have the following meaning:

              • data - Type [{InteractionKey,InteractionValue}] is used to propagate +}).

              To access the record in your callback-module use:

              -include_lib("inets/include/httpd.hrl").

              The fields of record mod have the following meaning:

              • data - Type [{InteractionKey,InteractionValue}] is used to propagate data between modules. Depicted interaction_data() in function type declarations.

              • socket_type - socket_type() indicates whether it is an IP socket or an ssl socket.

              • socket - The socket, in format ip_comm or ssl, depending on diff --git a/prs/8803/lib/inets-9.2/doc/html/inets.epub b/prs/8803/lib/inets-9.2/doc/html/inets.epub index 3f8ce45068105..575cecd08022e 100644 Binary files a/prs/8803/lib/inets-9.2/doc/html/inets.epub and b/prs/8803/lib/inets-9.2/doc/html/inets.epub differ diff --git a/prs/8803/lib/inets-9.2/doc/html/inets_services.html b/prs/8803/lib/inets-9.2/doc/html/inets_services.html index ac6b8f19e796d..3cae923e38fba 100644 --- a/prs/8803/lib/inets-9.2/doc/html/inets_services.html +++ b/prs/8803/lib/inets-9.2/doc/html/inets_services.html @@ -141,7 +141,7 @@

                unless the service is started with the standalone option. In this case the service is linked to the calling process and all OTP application features, such as soft upgrade, are lost.

                Services to be configured for startup at application startup are to be put into -the Erlang node configuration file on the following form:

                [{inets, [{services, ListofConfiguredServices}]}].

                For details of what to put in the list of configured services, see the +the Erlang node configuration file on the following form:

                [{inets, [{services, ListofConfiguredServices}]}].

                For details of what to put in the list of configured services, see the documentation for the services to be configured.

                diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/allclasses-index.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/allclasses-index.html index caa947853db61..57630f0d8109e 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/allclasses-index.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/allclasses-index.html @@ -2,10 +2,10 @@ - + All Classes (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/allclasses.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/allclasses.html index a7f37d4fa35f6..dc4e78f166418 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/allclasses.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/allclasses.html @@ -2,10 +2,10 @@ - + All Classes (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/allpackages-index.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/allpackages-index.html index 486f1241a1b09..cf54002603141 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/allpackages-index.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/allpackages-index.html @@ -2,10 +2,10 @@ - + All Packages (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/AbstractConnection.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/AbstractConnection.html index ce72d1dcae6fa..8f16720f315a1 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/AbstractConnection.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/AbstractConnection.html @@ -2,10 +2,10 @@ - + AbstractConnection (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/AbstractNode.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/AbstractNode.html index 7cc843db80b5e..d11027d9ce157 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/AbstractNode.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/AbstractNode.html @@ -2,10 +2,10 @@ - + AbstractNode (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/GenericQueue.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/GenericQueue.html index 4fc722da5cc7c..cff885326952d 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/GenericQueue.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/GenericQueue.html @@ -2,10 +2,10 @@ - + GenericQueue (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpAuthException.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpAuthException.html index 2b6b54b41435e..547362067cf06 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpAuthException.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpAuthException.html @@ -2,10 +2,10 @@ - + OtpAuthException (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpConnection.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpConnection.html index b3beceaf8526c..7f63790b36bc0 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpConnection.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpConnection.html @@ -2,10 +2,10 @@ - + OtpConnection (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpCookedConnection.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpCookedConnection.html index d748058f6c798..e50c8161ab25b 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpCookedConnection.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpCookedConnection.html @@ -2,10 +2,10 @@ - + OtpCookedConnection (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpEpmd.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpEpmd.html index 65d7286fd73fa..8eba3189ba649 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpEpmd.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpEpmd.html @@ -2,10 +2,10 @@ - + OtpEpmd (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangAtom.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangAtom.html index 1e4bdd8b02c8e..18bad556cf920 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangAtom.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangAtom.html @@ -2,10 +2,10 @@ - + OtpErlangAtom (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangBinary.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangBinary.html index a8f7e73b5a924..5df62c2660246 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangBinary.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangBinary.html @@ -2,10 +2,10 @@ - + OtpErlangBinary (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangBitstr.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangBitstr.html index 5a6fd9d1e70e9..9e19e0ea39f36 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangBitstr.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangBitstr.html @@ -2,10 +2,10 @@ - + OtpErlangBitstr (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangBoolean.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangBoolean.html index f8a2e34197e7c..424c6c9e47070 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangBoolean.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangBoolean.html @@ -2,10 +2,10 @@ - + OtpErlangBoolean (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangByte.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangByte.html index 641b7c68dca49..50c1eef659c66 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangByte.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangByte.html @@ -2,10 +2,10 @@ - + OtpErlangByte (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangChar.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangChar.html index 2b09dceb3bce0..53c3cfc8fc38d 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangChar.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangChar.html @@ -2,10 +2,10 @@ - + OtpErlangChar (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangDecodeException.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangDecodeException.html index d40b66c43081d..ea01673609866 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangDecodeException.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangDecodeException.html @@ -2,10 +2,10 @@ - + OtpErlangDecodeException (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangDouble.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangDouble.html index 6c929886bec8d..5c4a448517792 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangDouble.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangDouble.html @@ -2,10 +2,10 @@ - + OtpErlangDouble (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangException.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangException.html index 30a0dd3efcb94..9896436e2746f 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangException.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangException.html @@ -2,10 +2,10 @@ - + OtpErlangException (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangExit.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangExit.html index 0d3dcb13e515e..128ca3ab2b628 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangExit.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangExit.html @@ -2,10 +2,10 @@ - + OtpErlangExit (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangExternalFun.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangExternalFun.html index bcb45e9158e50..7295098d1eeb4 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangExternalFun.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangExternalFun.html @@ -2,10 +2,10 @@ - + OtpErlangExternalFun (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangFloat.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangFloat.html index 09fd1dd1a8910..8eddc6fc7fa91 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangFloat.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangFloat.html @@ -2,10 +2,10 @@ - + OtpErlangFloat (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangFun.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangFun.html index cfb03a63a1be2..7d4c852728fb9 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangFun.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangFun.html @@ -2,10 +2,10 @@ - + OtpErlangFun (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangInt.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangInt.html index 65b5467bf8553..7c8640ab812ec 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangInt.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangInt.html @@ -2,10 +2,10 @@ - + OtpErlangInt (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangList.SubList.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangList.SubList.html index 8eec7eae4a784..6908bff851e10 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangList.SubList.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangList.SubList.html @@ -2,10 +2,10 @@ - + OtpErlangList.SubList (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangList.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangList.html index dd534596f1e75..604c892885ee7 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangList.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangList.html @@ -2,10 +2,10 @@ - + OtpErlangList (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangLong.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangLong.html index f1f48b4d9f106..e2ed9fb63a3e1 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangLong.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangLong.html @@ -2,10 +2,10 @@ - + OtpErlangLong (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangMap.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangMap.html index 05909b627a13d..604e94a8e93fc 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangMap.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangMap.html @@ -2,10 +2,10 @@ - + OtpErlangMap (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangObject.Hash.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangObject.Hash.html index 4497f4bd650fa..a814de03fd5e4 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangObject.Hash.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangObject.Hash.html @@ -2,10 +2,10 @@ - + OtpErlangObject.Hash (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangObject.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangObject.html index a46f99f8810ec..a27c084386b5c 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangObject.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangObject.html @@ -2,10 +2,10 @@ - + OtpErlangObject (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangPid.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangPid.html index 69719bcef251c..8af40b79d1b32 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangPid.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangPid.html @@ -2,10 +2,10 @@ - + OtpErlangPid (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangPort.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangPort.html index b5cd19d7dda63..693ad0d2ab5e6 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangPort.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangPort.html @@ -2,10 +2,10 @@ - + OtpErlangPort (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangRangeException.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangRangeException.html index e35f26d6ef672..0e7165fb7384b 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangRangeException.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangRangeException.html @@ -2,10 +2,10 @@ - + OtpErlangRangeException (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangRef.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangRef.html index eae116f71814c..68ecd2d9da701 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangRef.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangRef.html @@ -2,10 +2,10 @@ - + OtpErlangRef (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangShort.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangShort.html index dc483ea2b9678..2f70bb820be39 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangShort.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangShort.html @@ -2,10 +2,10 @@ - + OtpErlangShort (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangString.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangString.html index 949bfd56341f6..20f7e8cc787dd 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangString.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangString.html @@ -2,10 +2,10 @@ - + OtpErlangString (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangTuple.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangTuple.html index 8a413cfe23909..fd9ee326c177a 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangTuple.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangTuple.html @@ -2,10 +2,10 @@ - + OtpErlangTuple (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangUInt.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangUInt.html index a214ef2f62445..83a9252a1b1fc 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangUInt.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangUInt.html @@ -2,10 +2,10 @@ - + OtpErlangUInt (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangUShort.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangUShort.html index 95438d5af0db0..7cd9aabfee8cb 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangUShort.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpErlangUShort.html @@ -2,10 +2,10 @@ - + OtpErlangUShort (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpException.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpException.html index c5af500678799..c8946ad4f1d7f 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpException.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpException.html @@ -2,10 +2,10 @@ - + OtpException (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpExternal.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpExternal.html index 3862f0608c27d..d762ffafa3201 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpExternal.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpExternal.html @@ -2,10 +2,10 @@ - + OtpExternal (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpGenericTransportFactory.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpGenericTransportFactory.html index f3952c804169b..b95371970ece3 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpGenericTransportFactory.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpGenericTransportFactory.html @@ -2,10 +2,10 @@ - + OtpGenericTransportFactory (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpInputStream.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpInputStream.html index 432f8da8f0858..1647b6f0053fc 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpInputStream.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpInputStream.html @@ -2,10 +2,10 @@ - + OtpInputStream (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpLocalNode.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpLocalNode.html index 4f41e54cb8cc7..ef279c410501c 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpLocalNode.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpLocalNode.html @@ -2,10 +2,10 @@ - + OtpLocalNode (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpMbox.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpMbox.html index b80dfdd808e70..642e9697980c9 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpMbox.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpMbox.html @@ -2,10 +2,10 @@ - + OtpMbox (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpMsg.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpMsg.html index 336be70e8e0c2..a3d248173ef99 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpMsg.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpMsg.html @@ -2,10 +2,10 @@ - + OtpMsg (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpNode.Acceptor.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpNode.Acceptor.html index 035b9d8ce189c..f6105ab399344 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpNode.Acceptor.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpNode.Acceptor.html @@ -2,10 +2,10 @@ - + OtpNode.Acceptor (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpNode.Mailboxes.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpNode.Mailboxes.html index 45406d9689245..7101a4afb8447 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpNode.Mailboxes.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpNode.Mailboxes.html @@ -2,10 +2,10 @@ - + OtpNode.Mailboxes (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpNode.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpNode.html index bb42669cb1eb8..3ae9a4696f633 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpNode.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpNode.html @@ -2,10 +2,10 @@ - + OtpNode (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpNodeStatus.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpNodeStatus.html index ea5223fc68418..9d8476c944ef7 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpNodeStatus.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpNodeStatus.html @@ -2,10 +2,10 @@ - + OtpNodeStatus (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpOutputStream.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpOutputStream.html index 4b740e9054c4e..613b21c040af5 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpOutputStream.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpOutputStream.html @@ -2,10 +2,10 @@ - + OtpOutputStream (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpPeer.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpPeer.html index 21d591ce779b0..50929daf31046 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpPeer.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpPeer.html @@ -2,10 +2,10 @@ - + OtpPeer (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpSelf.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpSelf.html index d94a83fdf33d6..a4515ba29de6a 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpSelf.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpSelf.html @@ -2,10 +2,10 @@ - + OtpSelf (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpServer.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpServer.html index 2bb713a38f7bc..88983865f9a42 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpServer.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpServer.html @@ -2,10 +2,10 @@ - + OtpServer (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpServerSocketTransport.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpServerSocketTransport.html index dc289e6b5246f..2f8945fab9013 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpServerSocketTransport.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpServerSocketTransport.html @@ -2,10 +2,10 @@ - + OtpServerSocketTransport (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpServerTransport.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpServerTransport.html index 4d5c5b14ada4e..75461131da3aa 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpServerTransport.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpServerTransport.html @@ -2,10 +2,10 @@ - + OtpServerTransport (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpSocketTransport.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpSocketTransport.html index 4826e887a9de2..0abd98278be74 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpSocketTransport.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpSocketTransport.html @@ -2,10 +2,10 @@ - + OtpSocketTransport (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpSocketTransportFactory.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpSocketTransportFactory.html index 241974926e67b..33ffdcb0a061b 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpSocketTransportFactory.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpSocketTransportFactory.html @@ -2,10 +2,10 @@ - + OtpSocketTransportFactory (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpTransport.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpTransport.html index 6dc3729937e64..13af12ccaf85f 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpTransport.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpTransport.html @@ -2,10 +2,10 @@ - + OtpTransport (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpTransportFactory.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpTransportFactory.html index c4cf5d964438a..e46dfb6d05179 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpTransportFactory.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/OtpTransportFactory.html @@ -2,10 +2,10 @@ - + OtpTransportFactory (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/package-summary.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/package-summary.html index cd1d795b1e8c0..5dba7123c06db 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/package-summary.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/package-summary.html @@ -2,10 +2,10 @@ - + com.ericsson.otp.erlang (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/package-tree.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/package-tree.html index ba405b5099b08..6cacec5a5f777 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/package-tree.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/com/ericsson/otp/erlang/package-tree.html @@ -2,10 +2,10 @@ - + com.ericsson.otp.erlang Class Hierarchy (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/constant-values.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/constant-values.html index 78376696308c0..4da6b325a619d 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/constant-values.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/constant-values.html @@ -2,10 +2,10 @@ - + Constant Field Values (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/deprecated-list.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/deprecated-list.html index ebae772849f18..8e0f7c2fb363f 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/deprecated-list.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/deprecated-list.html @@ -2,10 +2,10 @@ - + Deprecated List (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/help-doc.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/help-doc.html index e362562be9d70..ac904ca58056e 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/help-doc.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/help-doc.html @@ -2,10 +2,10 @@ - + API Help (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/index-all.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/index-all.html index be3852c672418..3a4164bc97f33 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/index-all.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/index-all.html @@ -2,10 +2,10 @@ - + Index (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/index.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/index.html index 932dc185ec16c..a37279f5110ca 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/index.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/index.html @@ -2,7 +2,7 @@ - + Java-Erlang Interface Library diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/member-search-index.zip b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/member-search-index.zip index 585a32bd71b94..ddbae3808dd4c 100644 Binary files a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/member-search-index.zip and b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/member-search-index.zip differ diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/overview-tree.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/overview-tree.html index e071dfd15b5f0..3584df301b295 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/overview-tree.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/overview-tree.html @@ -2,10 +2,10 @@ - + Class Hierarchy (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/package-search-index.zip b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/package-search-index.zip index 964eb68773967..9e0a8dd7715c1 100644 Binary files a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/package-search-index.zip and b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/package-search-index.zip differ diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/serialized-form.html b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/serialized-form.html index a6f199ff29af4..9d85f965c5472 100644 --- a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/serialized-form.html +++ b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/serialized-form.html @@ -2,10 +2,10 @@ - + Serialized Form (Java-Erlang Interface Library) - + diff --git a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/type-search-index.zip b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/type-search-index.zip index 5795609b4a87e..2bc4f10088c05 100644 Binary files a/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/type-search-index.zip and b/prs/8803/lib/jinterface-1.14.1/doc/html/assets/java/type-search-index.zip differ diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/app.html b/prs/8803/lib/kernel-10.0.1/doc/html/app.html index 724cc9ee6a713..4118e3404c4ab 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/app.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/app.html @@ -144,41 +144,41 @@

                The application resource file is to be called Application.app, where Application is the application name. The file is to be located in directory ebin for the application.

                The file must contain a single Erlang term, which is called an application -specification:

                {application, Application,
                -  [{description,  Description},
                -   {id,           Id},
                -   {vsn,          Vsn},
                -   {modules,      Modules},
                -   {maxP,         MaxP},
                -   {maxT,         MaxT},
                -   {registered,   Names},
                -   {included_applications, Apps},
                -   {optional_applications, Apps},
                -   {applications, Apps},
                -   {env,          Env},
                -   {mod,          Start},
                -   {start_phases, Phases},
                -   {runtime_dependencies, RTDeps}]}.
                +specification:

                {application, Application,
                +  [{description,  Description},
                +   {id,           Id},
                +   {vsn,          Vsn},
                +   {modules,      Modules},
                +   {maxP,         MaxP},
                +   {maxT,         MaxT},
                +   {registered,   Names},
                +   {included_applications, Apps},
                +   {optional_applications, Apps},
                +   {applications, Apps},
                +   {env,          Env},
                +   {mod,          Start},
                +   {start_phases, Phases},
                +   {runtime_dependencies, RTDeps}]}.
                 
                              Value                Default
                              -----                -------
                -Application  atom()               -
                -Description  string()             ""
                -Id           string()             ""
                -Vsn          string()             ""
                -Modules      [Module]             []
                -MaxP         int()                infinity
                -MaxT         int()                infinity
                -Names        [Name]               []
                -Apps         [App]                []
                -Env          [{Par,Val}]          []
                -Start        {Module,StartArgs}   []
                -Phases       [{Phase,PhaseArgs}]  undefined
                -RTDeps       [ApplicationVersion] []
                -
                -Module = Name = App = Par = Phase = atom()
                -Val = StartArgs = PhaseArgs = term()
                -ApplicationVersion = string()
                • Application - Application name.

                For the application controller, all keys are optional. The respective default +Application atom() - +Description string() "" +Id string() "" +Vsn string() "" +Modules [Module] [] +MaxP int() infinity +MaxT int() infinity +Names [Name] [] +Apps [App] [] +Env [{Par,Val}] [] +Start {Module,StartArgs} [] +Phases [{Phase,PhaseArgs}] undefined +RTDeps [ApplicationVersion] [] + +Module = Name = App = Par = Phase = atom() +Val = StartArgs = PhaseArgs = term() +ApplicationVersion = string()

                • Application - Application name.

                For the application controller, all keys are optional. The respective default values are used for any omitted keys.

                The functions in systools require more information. If they are used, the following keys are mandatory:

                • description
                • vsn
                • modules
                • registered
                • applications

                The other keys are ignored by systools.

                • description - A one-line description of the application.

                • id - Product identification, or similar.

                • vsn - Version of the application.

                • modules - All modules introduced by this application. systools uses this list when generating start scripts and tar files. A module can only be @@ -211,7 +211,7 @@

                  Module:start_phase(Phase,Type,PhaseArgs) for each start phase defined by key start_phases. Only after this extended start procedure, application:start(Application) returns.

                  Start phases can be used to synchronize startup of an application and its -included applications. In this case, key mod must be specified as follows:

                  {mod, {application_starter,[Module,StartArgs]}}

                  The application master then calls Module:start/2 for the primary +included applications. In this case, key mod must be specified as follows:

                  {mod, {application_starter,[Module,StartArgs]}}

                  The application master then calls Module:start/2 for the primary application, followed by calls to Module:start_phase/3 for each start phase (as defined for the primary application), both for the primary application and for each of its included applications, for which the start phase is defined.

                  This implies that for an included application, the set of start phases must be diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/application.html b/prs/8803/lib/kernel-10.0.1/doc/html/application.html index f5510577f8f6f..24f6cb811136a 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/application.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/application.html @@ -1653,7 +1653,7 @@

                  load(AppDescr, Distributed)

                  restart the application on another node. If Time is not specified, it defaults to 0 and the application is restarted immediately.

                  Nodes is a list of node names where the application can run, in priority from left to right. Node names can be grouped using tuples to indicate that they have -the same priority.

                  Example:

                  Nodes = [cp1@cave, {cp2@cave, cp3@cave}]

                  This means that the application is preferably to be started at cp1@cave. If +the same priority.

                  Example:

                  Nodes = [cp1@cave, {cp2@cave, cp3@cave}]

                  This means that the application is preferably to be started at cp1@cave. If cp1@cave is down, the application is to be started at cp2@cave or cp3@cave.

                  If Distributed == default, the value for the application in the Kernel configuration parameter distributed is used.

                  diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/code.html b/prs/8803/lib/kernel-10.0.1/doc/html/code.html index f88b65635eb37..4ca829336fdd4 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/code.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/code.html @@ -193,11 +193,11 @@

                  mnesia-4.4.7, the archive file must be named mnesia-4.4.7.ez and it must contain a top directory named mnesia-4.4.7. If the version part of the name is omitted, it must also be omitted in the archive. That is, a mnesia.ez archive -must contain a mnesia top directory.

                  An archive file for an application can, for example, be created like this:

                  zip:create("mnesia-4.4.7.ez",
                  -	["mnesia-4.4.7"],
                  -	[{cwd, code:lib_dir()},
                  -	 {compress, all},
                  -	 {uncompress,[".beam",".app"]}]).

                  Any file in the archive can be compressed, but to speed up the access of +must contain a mnesia top directory.

                  An archive file for an application can, for example, be created like this:

                  zip:create("mnesia-4.4.7.ez",
                  +	["mnesia-4.4.7"],
                  +	[{cwd, code:lib_dir()},
                  +	 {compress, all},
                  +	 {uncompress,[".beam",".app"]}]).

                  Any file in the archive can be compressed, but to speed up the access of frequently read files, it can be a good idea to store beam and app files uncompressed in the archive.

                  Normally the top directory of an application is located in library directory $OTPROOT/lib or in a directory referred to by environment variable ERL_LIBS. @@ -1875,10 +1875,10 @@

                  atomic_load(Modules)

                  the code already exists.

                • sticky_directory - The object code resides in a sticky directory.

                • pending_on_load - A previously loaded module contains an -on_load function that never finished.

                If it is important to minimize the time that an application is inactive while changing code, use prepare_loading/1 and finish_loading/1 instead of -atomic_load/1. Here is an example:

                {ok,Prepared} = code:prepare_loading(Modules),
                +atomic_load/1. Here is an example:

                {ok,Prepared} = code:prepare_loading(Modules),
                 %% Put the application into an inactive state or do any
                 %% other preparation needed before changing the code.
                -ok = code:finish_loading(Prepared),
                +ok = code:finish_loading(Prepared),
                 %% Resume the application.
                @@ -2431,8 +2431,8 @@

                get_object_code(Module)

                code for the module. This is useful if code is to be loaded on a remote node in a distributed system. For example, loading module Module on a node Node is done as follows:

                ...
                -{_Module, Binary, Filename} = code:get_object_code(Module),
                -erpc:call(Node, code, load_binary, [Module, Filename, Binary]),
                +{_Module, Binary, Filename} = code:get_object_code(Module),
                +erpc:call(Node, code, load_binary, [Module, Filename, Binary]),
                 ...
                @@ -2551,7 +2551,7 @@

                lib_dir()

                Returns the library directory, $OTPROOT/lib, where $OTPROOT is the root -directory of Erlang/OTP.

                Example:

                1> code:lib_dir().
                +directory of Erlang/OTP.

                Example:

                1> code:lib_dir().
                 "/usr/local/otp/lib"
                @@ -2590,7 +2590,7 @@

                lib_dir(Name)

                /usr/local/otp/lib/mnesia-4.2.2/ebin is returned. This means that the library directory for an application is the same, regardless if the application resides in an archive or not.

                Warning

                Archives are experimental. In a future release, they can be removed or -their behavior can change.

                Example:

                > code:lib_dir(mnesia).
                +their behavior can change.

                Example:

                > code:lib_dir(mnesia).
                 "/usr/local/otp/lib/mnesia-4.23"

                Returns {error, bad_name} if Name is not the name of an application under $OTPROOT/lib or on a directory referred to through environment variable ERL_LIBS. Fails with an exception if Name has the wrong type.

                Warning

                For backward compatibility, Name is also allowed to be a string. That will @@ -2633,7 +2633,7 @@

                lib_dir(Name, SubDir)

                situation is different. Some of the subdirectories can reside as regular directories while others reside in an archive file. It is not checked whether this directory exists.

                Instead of using this function, use code:lib_dir/1 -and filename:join/2.

                Example:

                1> filename:join(code:lib_dir(megaco), "priv").
                +and filename:join/2.

                Example:

                1> filename:join(code:lib_dir(megaco), "priv").
                 "/usr/local/otp/lib/megaco-3.9.1.1/priv"

                Fails with an exception if Name or SubDir has the wrong type.

                @@ -3092,7 +3092,7 @@

                root_dir()

                Returns the root directory of Erlang/OTP, which is the directory where it is -installed.

                Example:

                1> code:root_dir().
                +installed.

                Example:

                1> code:root_dir().
                 "/usr/local/otp"
                diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/config.html b/prs/8803/lib/kernel-10.0.1/doc/html/config.html index 2161b1c06a7a8..98e6369c869c1 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/config.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/config.html @@ -152,9 +152,9 @@

                File Syntax

                -

                The configuration file is to be called Name.config, where Name is any name.

                File .config contains a single Erlang term and has the following syntax:

                [{Application1, [{Par11, Val11}, ...]},
                +

                The configuration file is to be called Name.config, where Name is any name.

                File .config contains a single Erlang term and has the following syntax:

                [{Application1, [{Par11, Val11}, ...]},
                  ...
                - {ApplicationN, [{ParN1, ValN1}, ...]}].
                • Application = atom() - Application name.

                • Par = atom() - Name of a configuration parameter.

                • Val = term() - Value of a configuration parameter.

                + {ApplicationN, [{ParN1, ValN1}, ...]}].

                • Application = atom() - Application name.

                • Par = atom() - Name of a configuration parameter.

                • Val = term() - Value of a configuration parameter.

                diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/eep48_chapter.html b/prs/8803/lib/kernel-10.0.1/doc/html/eep48_chapter.html index 1533542b635bb..ea240625bae6a 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/eep48_chapter.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/eep48_chapter.html @@ -154,20 +154,20 @@

                In both storages, the documentation is written in the exactly same format: an Erlang term serialized to binary via term_to_binary/1. The term can be optionally -compressed when serialized. It must follow the type specification below:

                {docs_v1,
                - Anno :: erl_anno:anno(),
                - BeamLanguage :: atom(),
                - Format :: binary(),
                - ModuleDoc :: #{DocLanguage := DocValue} | none | hidden,
                - Metadata :: map(),
                +compressed when serialized. It must follow the type specification below:

                {docs_v1,
                + Anno :: erl_anno:anno(),
                + BeamLanguage :: atom(),
                + Format :: binary(),
                + ModuleDoc :: #{DocLanguage := DocValue} | none | hidden,
                + Metadata :: map(),
                  Docs ::
                -   [{{Kind, Name, Arity},
                -     Anno :: erl_anno:anno(),
                -     Signature :: [binary()],
                -     Doc :: #{DocLanguage := DocValue} | none | hidden,
                -     Metadata :: map()
                -    }]} when DocLanguage :: binary(),
                -             DocValue :: binary() | term()

                where in the root tuple we have:

                • Anno - annotation (line, column, file) of the definition itself (see + [{{Kind, Name, Arity}, + Anno :: erl_anno:anno(), + Signature :: [binary()], + Doc :: #{DocLanguage := DocValue} | none | hidden, + Metadata :: map() + }]} when DocLanguage :: binary(), + DocValue :: binary() | term()

                where in the root tuple we have:

                • Anno - annotation (line, column, file) of the definition itself (see erl_anno)

                • BeamLanguage - an atom representing the language, for example: erlang, elixir, lfe, alpaca, and so on

                • Format - the mime type of the documentation, such as <<"text/markdown">> or <<"application/erlang+html">>. For details of the format used by Erlang diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/erl_epmd.html b/prs/8803/lib/kernel-10.0.1/doc/html/erl_epmd.html index 09f258b8fec7e..892c481ff9637 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/erl_epmd.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/erl_epmd.html @@ -361,8 +361,8 @@

                  names(Host)

                  Called by net_adm:names/0. Host defaults to the localhost. Returns the names and associated port numbers of the Erlang nodes that epmd registered at the specified host. Returns {error, address} if epmd is not -operational.

                  Example:

                  (arne@dunn)1> erl_epmd:names(localhost).
                  -{ok,[{"arne",40262}]}
                  +operational.

                  Example:

                  (arne@dunn)1> erl_epmd:names(localhost).
                  +{ok,[{"arne",40262}]}
                  diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/erpc.html b/prs/8803/lib/kernel-10.0.1/doc/html/erpc.html index 189ba8e35a016..5d3f8b92697bf 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/erpc.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/erpc.html @@ -1221,20 +1221,20 @@

                  multicall(Nodes, Module, Function, Args, Ti selective receive optimization which removes the need to scan the message queue from the beginning in order to find a matching message. The send_request()/receive_response() combination can, however, not utilize this -optimization.

                  my_multicall(Nodes, Module, Function, Args) ->
                  -  ReqIds = lists:map(fun (Node) ->
                  -                       erpc:send_request(Node, Module, Function, Args)
                  +optimization.

                  my_multicall(Nodes, Module, Function, Args) ->
                  +  ReqIds = lists:map(fun (Node) ->
                  +                       erpc:send_request(Node, Module, Function, Args)
                                        end,
                  -                     Nodes),
                  -  lists:map(fun (ReqId) ->
                  +                     Nodes),
                  +  lists:map(fun (ReqId) ->
                                 try
                  -                {ok, erpc:receive_response(ReqId, infinity)}
                  +                {ok, erpc:receive_response(ReqId, infinity)}
                                 catch
                                   Class:Reason ->
                  -                  {Class, Reason}
                  +                  {Class, Reason}
                                 end
                               end,
                  -            ReqIds).

                  If an erpc operation fails, but it is unknown if the function is/will be + ReqIds).

                  If an erpc operation fails, but it is unknown if the function is/will be applied (that is, a timeout, connection loss, or an improper Nodes list), the caller will not receive any further information about the result if/when the applied function completes. If the applied function communicates with the @@ -1392,9 +1392,9 @@

                  receive_response(RequestId, Timeout)

                  performance. call() can utilize a selective receive optimization which removes the need to scan the message queue from the beginning in order to find a matching message. The send_request()/receive_response() combination can, -however, not utilize this optimization.

                  my_call(Node, Module, Function, Args, Timeout) ->
                  -  RequestId = erpc:send_request(Node, Module, Function, Args),
                  -  erpc:receive_response(RequestId, Timeout).

                  If the erpc operation fails, but it is unknown if the function is/will be +however, not utilize this optimization.

                  my_call(Node, Module, Function, Args, Timeout) ->
                  +  RequestId = erpc:send_request(Node, Module, Function, Args),
                  +  erpc:receive_response(RequestId, Timeout).

                  If the erpc operation fails, but it is unknown if the function is/will be applied (that is, a timeout, or a connection loss), the caller will not receive any further information about the result if/when the applied function completes. If the applied function explicitly communicates with the calling process, such @@ -1697,9 +1697,9 @@

                  send_request/4

                  performance. call() can utilize a selective receive optimization which removes the need to scan the message queue from the beginning in order to find a matching message. The send_request()/receive_response() combination can, -however, not utilize this optimization.

                  my_call(Node, Module, Function, Args, Timeout) ->
                  -  RequestId = erpc:send_request(Node, Module, Function, Args),
                  -  erpc:receive_response(RequestId, Timeout).

                  Fails with an {erpc, badarg} error exception if:

                  • Node is not an atom.
                  • Module is not an atom.
                  • Function is not an atom.
                  • Args is not a list. Note that the list is not verified to be a proper list +however, not utilize this optimization.

                    my_call(Node, Module, Function, Args, Timeout) ->
                    +  RequestId = erpc:send_request(Node, Module, Function, Args),
                    +  erpc:receive_response(RequestId, Timeout).

                    Fails with an {erpc, badarg} error exception if:

                    • Node is not an atom.
                    • Module is not an atom.
                    • Function is not an atom.
                    • Args is not a list. Note that the list is not verified to be a proper list at the client side.

                    Note

                    You cannot make any assumptions about the process that will perform the apply(). It may be a server, or a freshly spawned process.

                    Equivalent to erpc:send_request(Node, erlang, apply, [Fun,[]]), Label, RequestIdCollection).

                    Fails with an {erpc, badarg} error exception if:

                    • Node is not an atom.
                    • Fun is not a fun of zero arity.
                    • RequestIdCollection is detected not to be request identifier collection.

                    Note

                    You cannot make any assumptions about the process that will perform the diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/file.html b/prs/8803/lib/kernel-10.0.1/doc/html/file.html index 2f9890599bd60..c9a1824c8fc30 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/file.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/file.html @@ -180,31 +180,31 @@

                    improve performance for small reads and writes. However, the overhead won't disappear completely and it's best to keep the number of file operations to a minimum. As a contrived example, the following function writes 4MB in 2.5 -seconds when tested:

                    create_file_slow(Name) ->
                    -    {ok, Fd} = file:open(Name, [raw, write, delayed_write, binary]),
                    -    create_file_slow_1(Fd, 4 bsl 20),
                    -    file:close(Fd).
                    +seconds when tested:

                    create_file_slow(Name) ->
                    +    {ok, Fd} = file:open(Name, [raw, write, delayed_write, binary]),
                    +    create_file_slow_1(Fd, 4 bsl 20),
                    +    file:close(Fd).
                     
                    -create_file_slow_1(_Fd, 0) ->
                    +create_file_slow_1(_Fd, 0) ->
                         ok;
                    -create_file_slow_1(Fd, M) ->
                    -    ok = file:write(Fd, <<0>>),
                    -    create_file_slow_1(Fd, M - 1).

                    The following functionally equivalent code writes 128 bytes per call to +create_file_slow_1(Fd, M) -> + ok = file:write(Fd, <<0>>), + create_file_slow_1(Fd, M - 1).

                    The following functionally equivalent code writes 128 bytes per call to write/2 and so does the same work in 0.08 seconds, which is roughly 30 times -faster:

                    create_file(Name) ->
                    -    {ok, Fd} = file:open(Name, [raw, write, delayed_write, binary]),
                    -    create_file_1(Fd, 4 bsl 20),
                    -    file:close(Fd),
                    +faster:

                    create_file(Name) ->
                    +    {ok, Fd} = file:open(Name, [raw, write, delayed_write, binary]),
                    +    create_file_1(Fd, 4 bsl 20),
                    +    file:close(Fd),
                         ok.
                     
                    -create_file_1(_Fd, 0) ->
                    +create_file_1(_Fd, 0) ->
                         ok;
                    -create_file_1(Fd, M) when M >= 128 ->
                    -    ok = file:write(Fd, <<0:(128)/unit:8>>),
                    -    create_file_1(Fd, M - 128);
                    -create_file_1(Fd, M) ->
                    -    ok = file:write(Fd, <<0:(M)/unit:8>>),
                    -    create_file_1(Fd, M - 1).

                    When writing data it's generally more efficient to write a list of binaries +create_file_1(Fd, M) when M >= 128 -> + ok = file:write(Fd, <<0:(128)/unit:8>>), + create_file_1(Fd, M - 128); +create_file_1(Fd, M) -> + ok = file:write(Fd, <<0:(M)/unit:8>>), + create_file_1(Fd, M - 1).

                    When writing data it's generally more efficient to write a list of binaries rather than a list of integers. It is not needed to flatten a deep list before writing. On Unix hosts, scatter output, which writes a set of buffers in one operation, is used when possible. In this way @@ -1978,8 +1978,8 @@

                    consult(Filename)

                    For a list of typical error codes, see open/2.

                  • {error, {Line, Mod, Term}} - An error occurred when interpreting the Erlang terms in the file. To convert the three-element tuple to an English description of the error, use format_error/1.

                  Example:

                  f.txt:  {person, "kalle", 25}.
                  -        {person, "pelle", 30}.
                  1> file:consult("f.txt").
                  -{ok,[{person,"kalle",25},{person,"pelle",30}]}

                  The encoding of Filename can be set by a comment, as described in + {person, "pelle", 30}.

                1> file:consult("f.txt").
                +{ok,[{person,"kalle",25},{person,"pelle",30}]}

                The encoding of Filename can be set by a comment, as described in epp.

                @@ -3336,7 +3336,7 @@

                read_file_info(File, Opts)

                Retrieves information about a file. Returns {ok, FileInfo} if successful, otherwise {error, Reason}.

                FileInfo is a record file_info, defined in the Kernel include file file.hrl. -Include the following directive in the module from which the function is called:

                -include_lib("kernel/include/file.hrl").

                The time type returned in atime, mtime, and ctime is dependent on the time +Include the following directive in the module from which the function is called:

                -include_lib("kernel/include/file.hrl").

                The time type returned in atime, mtime, and ctime is dependent on the time type set in Opts :: {time, Type} as follows:

                • local - Returns local time.

                • universal - Returns universal time.

                • posix - Returns seconds since or before Unix time epoch, which is 1970-01-01 00:00 UTC.

                Default is {time, local}.

                If the option raw is set, the file server is not called and only information about local files is returned. Note that this will break this module's atomicity @@ -4026,7 +4026,7 @@

                write_file_info(Filename, FileInfo, Opts)Changes file information. Returns ok if successful, otherwise {error, Reason}.

                FileInfo is a record file_info, defined in the Kernel include file file.hrl. Include the following directive in the module from -which the function is called:

                -include_lib("kernel/include/file.hrl").

                The time type set in atime, mtime, and ctime depends on the time type set +which the function is called:

                -include_lib("kernel/include/file.hrl").

                The time type set in atime, mtime, and ctime depends on the time type set in Opts :: {time, Type} as follows:

                • local - Interprets the time set as local.

                • universal - Interprets it as universal time.

                • posix - Must be seconds since or before Unix time epoch, which is 1970-01-01 00:00 UTC.

                Default is {time, local}.

                If the option raw is set, the file server is not called and only information about local files is returned.

                The following fields are used from the record, if they are specified:

                • atime = date_time/0 | non_neg_integer/0 - The last time the file was diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/gen_sctp.html b/prs/8803/lib/kernel-10.0.1/doc/html/gen_sctp.html index 4bcd7ba32e700..6459da9e85ff2 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/gen_sctp.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/gen_sctp.html @@ -136,7 +136,7 @@

                  lksctp-tools-1.0.6

                • Briefly on Solaris 10
                • SUSE Linux Enterprise Server 10 Service Pack 1 (x86_64) kernel 2.6.16.54-0.2.3-smp with lksctp-tools-1.0.7
                • FreeBSD 8.2

                This module was written for one-to-many style sockets (type seqpacket). With the addition of peeloff/2, one-to-one style sockets (type stream) -were introduced.

                Record definitions for this module can be found using:

                -include_lib("kernel/include/inet_sctp.hrl").

                These record definitions use the "new" spelling 'adaptation', +were introduced.

                Record definitions for this module can be found using:

                -include_lib("kernel/include/inet_sctp.hrl").

                These record definitions use the "new" spelling 'adaptation', not the deprecated 'adaption', regardless of which spelling the underlying C API uses.

                @@ -181,31 +181,31 @@

                buffer for this socket. Sending errors would occur for datagrams larger than val(recbuf). Setting this option also adjusts the size of the driver buffer (see buffer above).

              • {sctp_module, module()} - Overrides which callback module is used. -Defaults to inet_sctp for IPv4 and inet6_sctp for IPv6.

              • {sctp_rtoinfo, #sctp_rtoinfo{}}

                #sctp_rtoinfo{
                -      assoc_id = assoc_id(),
                -      initial  = integer(),
                -      max      = integer(),
                -      min      = integer()
                -}

                Determines retransmission time-out parameters, in milliseconds, for the +Defaults to inet_sctp for IPv4 and inet6_sctp for IPv6.

              • {sctp_rtoinfo, #sctp_rtoinfo{}}

                #sctp_rtoinfo{
                +      assoc_id = assoc_id(),
                +      initial  = integer(),
                +      max      = integer(),
                +      min      = integer()
                +}

                Determines retransmission time-out parameters, in milliseconds, for the association(s) specified by assoc_id.

                assoc_id = 0 (default) indicates the whole endpoint. See RFC 2960 and Sockets API Extensions for SCTP -for the exact semantics of the field values.

              • {sctp_associnfo, #sctp_assocparams{}}

                #sctp_assocparams{
                -      assoc_id                 = assoc_id(),
                -      asocmaxrxt               = integer(),
                -      number_peer_destinations = integer(),
                -      peer_rwnd                = integer(),
                -      local_rwnd               = integer(),
                -      cookie_life              = integer()
                -}

                Determines association parameters for the association(s) specified by +for the exact semantics of the field values.

              • {sctp_associnfo, #sctp_assocparams{}}

                #sctp_assocparams{
                +      assoc_id                 = assoc_id(),
                +      asocmaxrxt               = integer(),
                +      number_peer_destinations = integer(),
                +      peer_rwnd                = integer(),
                +      local_rwnd               = integer(),
                +      cookie_life              = integer()
                +}

                Determines association parameters for the association(s) specified by assoc_id.

                assoc_id = 0 (default) indicates the whole endpoint. See Sockets API Extensions for SCTP -for the discussion of their semantics. Rarely used.

              • {sctp_initmsg, #sctp_initmsg{}}

                #sctp_initmsg{
                -     num_ostreams   = integer(),
                -     max_instreams  = integer(),
                -     max_attempts   = integer(),
                -     max_init_timeo = integer()
                -}

                Determines the default parameters that this socket tries to negotiate +for the discussion of their semantics. Rarely used.

              • {sctp_initmsg, #sctp_initmsg{}}

                #sctp_initmsg{
                +     num_ostreams   = integer(),
                +     max_instreams  = integer(),
                +     max_attempts   = integer(),
                +     max_init_timeo = integer()
                +}

                Determines the default parameters that this socket tries to negotiate with its peer while establishing an association with it. Is to be set after open/* but before the first connect/*. #sctp_initmsg{} can also be used as ancillary data with the first call of @@ -222,52 +222,52 @@

                performance reasons only.

              • {sctp_i_want_mapped_v4_addr, true|false} - Turns on|off automatic mapping of IPv4 addresses into IPv6 ones (if the socket address family is AF_INET6).

              • {sctp_maxseg, integer()} - Determines the maximum chunk size if message -fragmentation is used. If 0, the chunk size is limited by the Path MTU only.

              • {sctp_primary_addr, #sctp_prim{}}

                #sctp_prim{
                -      assoc_id = assoc_id(),
                -      addr     = {IP, Port}
                -}
                - IP = ip_address()
                - Port = port_number()

                For the association specified by assoc_id, {IP,Port} must be one of the +fragmentation is used. If 0, the chunk size is limited by the Path MTU only.

              • {sctp_primary_addr, #sctp_prim{}}

                #sctp_prim{
                +      assoc_id = assoc_id(),
                +      addr     = {IP, Port}
                +}
                + IP = ip_address()
                + Port = port_number()

                For the association specified by assoc_id, {IP,Port} must be one of the peer addresses. This option determines that the specified address is treated -by the local SCTP stack as the primary address of the peer.

              • {sctp_set_peer_primary_addr, #sctp_setpeerprim{}}

                #sctp_setpeerprim{
                -      assoc_id = assoc_id(),
                -      addr     = {IP, Port}
                -}
                - IP = ip_address()
                - Port = port_number()

                When set, informs the peer to use {IP, Port} as the primary address of the -local endpoint for the association specified by assoc_id.

              • {sctp_adaptation_layer, #sctp_setadaptation{}}

                #sctp_setadaptation{
                -      adaptation_ind = integer()
                -}

                When set, requests that the local endpoint uses the value specified by +by the local SCTP stack as the primary address of the peer.

              • {sctp_set_peer_primary_addr, #sctp_setpeerprim{}}

                #sctp_setpeerprim{
                +      assoc_id = assoc_id(),
                +      addr     = {IP, Port}
                +}
                + IP = ip_address()
                + Port = port_number()

                When set, informs the peer to use {IP, Port} as the primary address of the +local endpoint for the association specified by assoc_id.

              • {sctp_adaptation_layer, #sctp_setadaptation{}}

                #sctp_setadaptation{
                +      adaptation_ind = integer()
                +}

                When set, requests that the local endpoint uses the value specified by adaptation_ind as the Adaptation Indication parameter for establishing new associations. For details, see RFC 2960 and -Sockets API Extensions for SCTP.

              • {sctp_peer_addr_params, #sctp_paddrparams{}}

                #sctp_paddrparams{
                -      assoc_id   = assoc_id(),
                -      address    = {IP, Port},
                -      hbinterval = integer(),
                -      pathmaxrxt = integer(),
                -      pathmtu    = integer(),
                -      sackdelay  = integer(),
                -      flags      = list()
                -}
                -IP = ip_address()
                -Port = port_number()

                Determines various per-address parameters for the association specified by +Sockets API Extensions for SCTP.

              • {sctp_peer_addr_params, #sctp_paddrparams{}}

                #sctp_paddrparams{
                +      assoc_id   = assoc_id(),
                +      address    = {IP, Port},
                +      hbinterval = integer(),
                +      pathmaxrxt = integer(),
                +      pathmtu    = integer(),
                +      sackdelay  = integer(),
                +      flags      = list()
                +}
                +IP = ip_address()
                +Port = port_number()

                Determines various per-address parameters for the association specified by assoc_id and the peer address address (the SCTP protocol supports multi-homing, so more than one address can correspond to a specified association).

                • hbinterval - Heartbeat interval, in milliseconds

                • pathmaxrxt - Maximum number of retransmissions before this address is considered unreachable (and an alternative address is selected)

                • pathmtu - Fixed Path MTU, if automatic discovery is disabled (see flags below)

                • sackdelay - Delay, in milliseconds, for SAC messages (if the delay is -enabled, see flags below)

                • flags - The following flags are available:

                  • hb_enable - Enables heartbeat

                  • hb_disable - Disables heartbeat

                  • hb_demand - Initiates heartbeat immediately

                  • pmtud_enable - Enables automatic Path MTU discovery

                  • pmtud_disable - Disables automatic Path MTU discovery

                  • sackdelay_enable - Enables SAC delay

                  • sackdelay_disable - Disables SAC delay

              • {sctp_default_send_param, #sctp_sndrcvinfo{}}

                #sctp_sndrcvinfo{
                -      stream     = integer(),
                -      ssn        = integer(),
                -      flags      = list(),
                -      ppid       = integer(),
                -      context    = integer(),
                -      timetolive = integer(),
                -      tsn        = integer(),
                -      cumtsn     = integer(),
                -      assoc_id   = assoc_id()
                -}

                #sctp_sndrcvinfo{} is used both in this socket option, and as +enabled, see flags below)

              • flags - The following flags are available:

                • hb_enable - Enables heartbeat

                • hb_disable - Disables heartbeat

                • hb_demand - Initiates heartbeat immediately

                • pmtud_enable - Enables automatic Path MTU discovery

                • pmtud_disable - Disables automatic Path MTU discovery

                • sackdelay_enable - Enables SAC delay

                • sackdelay_disable - Disables SAC delay

            • {sctp_default_send_param, #sctp_sndrcvinfo{}}

              #sctp_sndrcvinfo{
              +      stream     = integer(),
              +      ssn        = integer(),
              +      flags      = list(),
              +      ppid       = integer(),
              +      context    = integer(),
              +      timetolive = integer(),
              +      tsn        = integer(),
              +      cumtsn     = integer(),
              +      assoc_id   = assoc_id()
              +}

              #sctp_sndrcvinfo{} is used both in this socket option, and as ancillary data while sending or receiving SCTP messages. When set as an option, it provides default values for subsequent send calls on the association specified by assoc_id.

              assoc_id = 0 (default) indicates the whole endpoint.

              The following fields typically must be specified by the sender:

              • sinfo_stream - Stream number (0-base) within the association to send @@ -276,7 +276,7 @@

                data

              • eof - Gracefully shuts down the current association, with flushing of unsent data

              Other fields are rarely used. For complete information, see RFC 2960 and -Sockets API Extensions for SCTP.

          • {sctp_events, #sctp_event_subscribe{}}

            #sctp_event_subscribe{
            +Sockets API Extensions for SCTP.

        • {sctp_events, #sctp_event_subscribe{}}

          #sctp_event_subscribe{
                   data_io_event          = true | false,
                   association_event      = true | false,
                   address_event          = true | false,
          @@ -285,42 +285,42 @@ 

          shutdown_event = true | false, partial_delivery_event = true | false, adaptation_layer_event = true | false -}

          This option determines which SCTP Events that are to be +}

          This option determines which SCTP Events that are to be received (through recv/*) along with the data. The only exception is data_io_event, which enables or disables receiving of #sctp_sndrcvinfo{} ancillary data, not events. By default, all flags except adaptation_layer_event are enabled, although sctp_data_io_event and association_event are used by the driver -itself and not exported to the user level.

        • {sctp_delayed_ack_time, #sctp_assoc_value{}}

          #sctp_assoc_value{
          -      assoc_id    = assoc_id(),
          -      assoc_value = integer()
          -}

          Rarely used. Determines the ACK time (specified by assoc_value, in +itself and not exported to the user level.

        • {sctp_delayed_ack_time, #sctp_assoc_value{}}

          #sctp_assoc_value{
          +      assoc_id    = assoc_id(),
          +      assoc_value = integer()
          +}

          Rarely used. Determines the ACK time (specified by assoc_value, in milliseconds) for the specified association or the whole endpoint if -assoc_value = 0 (default).

        • {sctp_status, #sctp_status{}}

          #sctp_status{
          -      assoc_id            = assoc_id(),
          -      state               = atom(),
          -      rwnd                = integer(),
          -      unackdata           = integer(),
          -      penddata            = integer(),
          -      instrms             = integer(),
          -      outstrms            = integer(),
          -      fragmentation_point = integer(),
          -      primary             = #sctp_paddrinfo{}
          -}

          This option is read-only. It determines the status of the SCTP association +assoc_value = 0 (default).

        • {sctp_status, #sctp_status{}}

          #sctp_status{
          +      assoc_id            = assoc_id(),
          +      state               = atom(),
          +      rwnd                = integer(),
          +      unackdata           = integer(),
          +      penddata            = integer(),
          +      instrms             = integer(),
          +      outstrms            = integer(),
          +      fragmentation_point = integer(),
          +      primary             = #sctp_paddrinfo{}
          +}

          This option is read-only. It determines the status of the SCTP association specified by assoc_id. The following are the possible values of state (the state designations are mostly self-explanatory):

          • sctp_state_empty - Default. Means that no other state is active.

          • sctp_state_closed

          • sctp_state_cookie_wait

          • sctp_state_cookie_echoed

          • sctp_state_established

          • sctp_state_shutdown_pending

          • sctp_state_shutdown_sent

          • sctp_state_shutdown_received

          • sctp_state_shutdown_ack_sent

          Semantics of the other fields:

          • sstat_rwnd - Current receiver window size of the association

          • sstat_unackdata - Number of unacked data chunks

          • sstat_penddata - Number of data chunks pending receipt

          • sstat_instrms - Number of inbound streams

          • sstat_outstrms - Number of outbound streams

          • sstat_fragmentation_point - Message size at which SCTP fragmentation occurs

          • sstat_primary - Information on the current primary peer address (see -below for the format of #sctp_paddrinfo{})

        • {sctp_get_peer_addr_info, #sctp_paddrinfo{}}

          #sctp_paddrinfo{
          -      assoc_id  = assoc_id(),
          -      address   = {IP, Port},
          +below for the format of #sctp_paddrinfo{})

      • {sctp_get_peer_addr_info, #sctp_paddrinfo{}}

        #sctp_paddrinfo{
        +      assoc_id  = assoc_id(),
        +      address   = {IP, Port},
               state     = inactive | active | unconfirmed,
        -      cwnd      = integer(),
        -      srtt      = integer(),
        -      rto       = integer(),
        -      mtu       = integer()
        -}
        -IP = ip_address()
        -Port = port_number()

        This option is read-only. It determines the parameters specific to + cwnd = integer(), + srtt = integer(), + rto = integer(), + mtu = integer() +} +IP = ip_address() +Port = port_number()

        This option is read-only. It determines the parameters specific to the peer address specified by address within the association specified by assoc_id. Field address fmust be set by the caller; all other fields are filled in on return. If assoc_id = 0 (default), the address @@ -334,119 +334,119 @@

        SCTP Examples

        Example of an Erlang SCTP server that receives SCTP messages -and prints them on the standard output:

        -module(sctp_server).
        +and prints them on the standard output:

        -module(sctp_server).
         
        --export([server/0,server/1,server/2]).
        --include_lib("kernel/include/inet.hrl").
        --include_lib("kernel/include/inet_sctp.hrl").
        -
        -server() ->
        -    server(any, 2006).
        -
        -server([Host,Port]) when is_list(Host), is_list(Port) ->
        -    {ok, #hostent{h_addr_list = [IP|_]}} = inet:gethostbyname(Host),
        -    io:format("~w -> ~w~n", [Host, IP]),
        -    server([IP, list_to_integer(Port)]).
        -
        -server(IP, Port) when is_tuple(IP) orelse IP == any orelse IP == loopback,
        -                      is_integer(Port) ->
        -    {ok,S} = gen_sctp:open(Port, [{recbuf,65536}, {ip,IP}]),
        -    io:format("Listening on ~w:~w. ~w~n", [IP,Port,S]),
        -    ok     = gen_sctp:listen(S, true),
        -    server_loop(S).
        -
        -server_loop(S) ->
        -    case gen_sctp:recv(S) of
        -    {error, Error} ->
        -        io:format("SCTP RECV ERROR: ~p~n", [Error]);
        +-export([server/0,server/1,server/2]).
        +-include_lib("kernel/include/inet.hrl").
        +-include_lib("kernel/include/inet_sctp.hrl").
        +
        +server() ->
        +    server(any, 2006).
        +
        +server([Host,Port]) when is_list(Host), is_list(Port) ->
        +    {ok, #hostent{h_addr_list = [IP|_]}} = inet:gethostbyname(Host),
        +    io:format("~w -> ~w~n", [Host, IP]),
        +    server([IP, list_to_integer(Port)]).
        +
        +server(IP, Port) when is_tuple(IP) orelse IP == any orelse IP == loopback,
        +                      is_integer(Port) ->
        +    {ok,S} = gen_sctp:open(Port, [{recbuf,65536}, {ip,IP}]),
        +    io:format("Listening on ~w:~w. ~w~n", [IP,Port,S]),
        +    ok     = gen_sctp:listen(S, true),
        +    server_loop(S).
        +
        +server_loop(S) ->
        +    case gen_sctp:recv(S) of
        +    {error, Error} ->
        +        io:format("SCTP RECV ERROR: ~p~n", [Error]);
             Data ->
        -        io:format("Received: ~p~n", [Data])
        +        io:format("Received: ~p~n", [Data])
             end,
        -    server_loop(S).

        Example of an Erlang SCTP client interacting with the above server. + server_loop(S).

        Example of an Erlang SCTP client interacting with the above server. Note that in this example the client creates an association with the server with 5 outbound streams. Therefore, sending of "Test 0" over stream 0 succeeds, but sending of "Test 5" over stream 5 fails. The client then aborts the association, which results in that -the corresponding event is received on the server side.

        -module(sctp_client).
        +the corresponding event is received on the server side.

        -module(sctp_client).
         
        --export([client/0, client/1, client/2]).
        --include_lib("kernel/include/inet.hrl").
        --include_lib("kernel/include/inet_sctp.hrl").
        -
        -client() ->
        -    client([localhost]).
        -
        -client([Host]) ->
        -    client(Host, 2006);
        -
        -client([Host, Port]) when is_list(Host), is_list(Port) ->
        -    client(Host,list_to_integer(Port)),
        -    init:stop().
        -
        -client(Host, Port) when is_integer(Port) ->
        -    {ok,S}     = gen_sctp:open(),
        -    {ok,Assoc} = gen_sctp:connect
        -        (S, Host, Port, [{sctp_initmsg,#sctp_initmsg{num_ostreams=5}}]),
        -    io:format("Connection Successful, Assoc=~p~n", [Assoc]),
        -
        -    io:write(gen_sctp:send(S, Assoc, 0, <<"Test 0">>)),
        -    io:nl(),
        -    timer:sleep(10000),
        -    io:write(gen_sctp:send(S, Assoc, 5, <<"Test 5">>)),
        -    io:nl(),
        -    timer:sleep(10000),
        -    io:write(gen_sctp:abort(S, Assoc)),
        -    io:nl(),
        -
        -    timer:sleep(1000),
        -    gen_sctp:close(S).

        A simple Erlang SCTP client that uses the connect_init API:

        -module(ex3).
        +-export([client/0, client/1, client/2]).
        +-include_lib("kernel/include/inet.hrl").
        +-include_lib("kernel/include/inet_sctp.hrl").
        +
        +client() ->
        +    client([localhost]).
        +
        +client([Host]) ->
        +    client(Host, 2006);
        +
        +client([Host, Port]) when is_list(Host), is_list(Port) ->
        +    client(Host,list_to_integer(Port)),
        +    init:stop().
        +
        +client(Host, Port) when is_integer(Port) ->
        +    {ok,S}     = gen_sctp:open(),
        +    {ok,Assoc} = gen_sctp:connect
        +        (S, Host, Port, [{sctp_initmsg,#sctp_initmsg{num_ostreams=5}}]),
        +    io:format("Connection Successful, Assoc=~p~n", [Assoc]),
        +
        +    io:write(gen_sctp:send(S, Assoc, 0, <<"Test 0">>)),
        +    io:nl(),
        +    timer:sleep(10000),
        +    io:write(gen_sctp:send(S, Assoc, 5, <<"Test 5">>)),
        +    io:nl(),
        +    timer:sleep(10000),
        +    io:write(gen_sctp:abort(S, Assoc)),
        +    io:nl(),
        +
        +    timer:sleep(1000),
        +    gen_sctp:close(S).

        A simple Erlang SCTP client that uses the connect_init API:

        -module(ex3).
         
        --export([client/4]).
        --include_lib("kernel/include/inet.hrl").
        --include_lib("kernel/include/inet_sctp.hrl").
        -
        -client(Peer1, Port1, Peer2, Port2)
        -  when is_tuple(Peer1), is_integer(Port1), is_tuple(Peer2), is_integer(Port2) ->
        -    {ok,S}     = gen_sctp:open(),
        -    SctpInitMsgOpt = {sctp_initmsg,#sctp_initmsg{num_ostreams=5}},
        -    ActiveOpt = {active, true},
        -    Opts = [SctpInitMsgOpt, ActiveOpt],
        -    ok = gen_sctp:connect(S, Peer1, Port1, Opts),
        -    ok = gen_sctp:connect(S, Peer2, Port2, Opts),
        -    io:format("Connections initiated~n", []),
        -    client_loop(S, Peer1, Port1, undefined, Peer2, Port2, undefined).
        -
        -client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2, AssocId2) ->
        +-export([client/4]).
        +-include_lib("kernel/include/inet.hrl").
        +-include_lib("kernel/include/inet_sctp.hrl").
        +
        +client(Peer1, Port1, Peer2, Port2)
        +  when is_tuple(Peer1), is_integer(Port1), is_tuple(Peer2), is_integer(Port2) ->
        +    {ok,S}     = gen_sctp:open(),
        +    SctpInitMsgOpt = {sctp_initmsg,#sctp_initmsg{num_ostreams=5}},
        +    ActiveOpt = {active, true},
        +    Opts = [SctpInitMsgOpt, ActiveOpt],
        +    ok = gen_sctp:connect(S, Peer1, Port1, Opts),
        +    ok = gen_sctp:connect(S, Peer2, Port2, Opts),
        +    io:format("Connections initiated~n", []),
        +    client_loop(S, Peer1, Port1, undefined, Peer2, Port2, undefined).
        +
        +client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2, AssocId2) ->
             receive
        -        {sctp, S, Peer1, Port1, {_Anc, SAC}}
        -          when is_record(SAC, sctp_assoc_change), AssocId1 == undefined ->
        -            io:format("Association 1 connect result: ~p. AssocId: ~p~n",
        -                      [SAC#sctp_assoc_change.state,
        -                       SAC#sctp_assoc_change.assoc_id]),
        -            client_loop(S, Peer1, Port1, SAC#sctp_assoc_change.assoc_id,
        -                        Peer2, Port2, AssocId2);
        -
        -        {sctp, S, Peer2, Port2, {_Anc, SAC}}
        -          when is_record(SAC, sctp_assoc_change), AssocId2 == undefined ->
        -            io:format("Association 2 connect result: ~p. AssocId: ~p~n",
        -                      [SAC#sctp_assoc_change.state, SAC#sctp_assoc_change.assoc_id]),
        -            client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2,
        -                       SAC#sctp_assoc_change.assoc_id);
        -
        -        {sctp, S, Peer1, Port1, Data} ->
        -            io:format("Association 1: received ~p~n", [Data]),
        -            client_loop(S, Peer1, Port1, AssocId1,
        -                        Peer2, Port2, AssocId2);
        -
        -        {sctp, S, Peer2, Port2, Data} ->
        -            io:format("Association 2: received ~p~n", [Data]),
        -            client_loop(S, Peer1, Port1, AssocId1,
        -                        Peer2, Port2, AssocId2);
        +        {sctp, S, Peer1, Port1, {_Anc, SAC}}
        +          when is_record(SAC, sctp_assoc_change), AssocId1 == undefined ->
        +            io:format("Association 1 connect result: ~p. AssocId: ~p~n",
        +                      [SAC#sctp_assoc_change.state,
        +                       SAC#sctp_assoc_change.assoc_id]),
        +            client_loop(S, Peer1, Port1, SAC#sctp_assoc_change.assoc_id,
        +                        Peer2, Port2, AssocId2);
        +
        +        {sctp, S, Peer2, Port2, {_Anc, SAC}}
        +          when is_record(SAC, sctp_assoc_change), AssocId2 == undefined ->
        +            io:format("Association 2 connect result: ~p. AssocId: ~p~n",
        +                      [SAC#sctp_assoc_change.state, SAC#sctp_assoc_change.assoc_id]),
        +            client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2,
        +                       SAC#sctp_assoc_change.assoc_id);
        +
        +        {sctp, S, Peer1, Port1, Data} ->
        +            io:format("Association 1: received ~p~n", [Data]),
        +            client_loop(S, Peer1, Port1, AssocId1,
        +                        Peer2, Port2, AssocId2);
        +
        +        {sctp, S, Peer2, Port2, Data} ->
        +            io:format("Association 2: received ~p~n", [Data]),
        +            client_loop(S, Peer1, Port1, AssocId1,
        +                        Peer2, Port2, AssocId2);
         
                 Other ->
        -            io:format("Other ~p~n", [Other]),
        -            client_loop(S, Peer1, Port1, AssocId1,
        -                        Peer2, Port2, AssocId2)
        +            io:format("Other ~p~n", [Other]),
        +            client_loop(S, Peer1, Port1, AssocId1,
        +                        Peer2, Port2, AssocId2)
         
             after 5000 ->
                     ok
        @@ -1445,16 +1445,16 @@ 

        connect(Socket, Addr, Port, Opts, Timeout)<

        The result of connect/* is an #sctp_assoc_change{} event that contains, in particular, the new Association ID: -l

        #sctp_assoc_change{
        -      state             = atom(),
        -      error             = integer(),
        -      outbound_streams  = integer(),
        -      inbound_streams   = integer(),
        -      assoc_id          = assoc_id()
        -}

        The number of outbound and inbound streams for the association -can be set by giving an sctp_initmsg option to connect as in:

        connect(Socket, Ip, Port>,
        -      [{sctp_initmsg,#sctp_initmsg{num_ostreams=OutStreams,
        -                                   max_instreams=MaxInStreams}}])

        All options Opt are set on the socket before the association is attempted. +l

        #sctp_assoc_change{
        +      state             = atom(),
        +      error             = integer(),
        +      outbound_streams  = integer(),
        +      inbound_streams   = integer(),
        +      assoc_id          = assoc_id()
        +}

        The number of outbound and inbound streams for the association +can be set by giving an sctp_initmsg option to connect as in:

        connect(Socket, Ip, Port>,
        +      [{sctp_initmsg,#sctp_initmsg{num_ostreams=OutStreams,
        +                                   max_instreams=MaxInStreams}}])

        All options Opt are set on the socket before the association is attempted. If an option record has undefined field values, the options record is first read from the socket for those values. In effect, Opt option records only need to define field values to change @@ -1938,7 +1938,7 @@

        open/1

        and with reasonably large kernel and driver buffers.

        When the socket is in passive mode, data can be received through the recv/1,2 calls.

        When the socket is in active mode, -data received data is delivered to the controlling process as messages:

        {sctp, Socket, FromIP, FromPort, {AncData, Data}}

        See recv/1,2 for a description of the message fields.

        Note

        This message format unfortunately differs slightly from the +data received data is delivered to the controlling process as messages:

        {sctp, Socket, FromIP, FromPort, {AncData, Data}}

        See recv/1,2 for a description of the message fields.

        Note

        This message format unfortunately differs slightly from the gen_udp message format with ancillary data, and from the recv/1,2 return tuple format.

        @@ -2200,39 +2200,39 @@

        recv(Socket, Timeout)

        Possible SCTP events

    -
    • #sctp_sndrcvinfo{}

    • #sctp_assoc_change{}

    • #sctp_paddr_change{
      -      addr      = {ip_address(),port()},
      -      state     = atom(),
      -      error     = integer(),
      -      assoc_id  = assoc_id()
      -}

      Indicates change of the status of the IP address of the peer specified by +

      • #sctp_sndrcvinfo{}

      • #sctp_assoc_change{}

      • #sctp_paddr_change{
        +      addr      = {ip_address(),port()},
        +      state     = atom(),
        +      error     = integer(),
        +      assoc_id  = assoc_id()
        +}

        Indicates change of the status of the IP address of the peer specified by addr within association assoc_id. Possible values of state (mostly self-explanatory) include:

        • addr_unreachable

        • addr_available

        • addr_removed

        • addr_added

        • addr_made_prim

        • addr_confirmed

        In case of an error (for example, addr_unreachable), the field error provides more diagnostics. In such cases, event #sctp_paddr_change{} is automatically converted into an error term returned by recv. The error field value can be converted -into a string using error_string/1.

      • #sctp_send_failed{
        +into a string using error_string/1.

      • #sctp_send_failed{
               flags     = true | false,
        -      error     = integer(),
        -      info      = #sctp_sndrcvinfo{},
        -      assoc_id  = assoc_id()
        -      data      = binary()
        -}

        The sender can receive this event if a send operation fails.

        • flags - A Boolean specifying if the data has been transmitted + error = integer(), + info = #sctp_sndrcvinfo{}, + assoc_id = assoc_id() + data = binary() +}

          The sender can receive this event if a send operation fails.

          • flags - A Boolean specifying if the data has been transmitted over the wire.

          • error - Provides extended diagnostics, use error_string/1.

          • info - The original #sctp_sndrcvinfo{} record used in the failed send/*.

          • data - The whole original data chunk attempted to be sent.

          In the current implementation of the Erlang/SCTP binding, this event is -internally converted into an error term returned by recv/*.

        • #sctp_adaptation_event{
          -      adaptation_ind = integer(),
          -      assoc_id       = assoc_id()
          -}

          Delivered when a peer sends an adaptation layer indication parameter +internally converted into an error term returned by recv/*.

        • #sctp_adaptation_event{
          +      adaptation_ind = integer(),
          +      assoc_id       = assoc_id()
          +}

          Delivered when a peer sends an adaptation layer indication parameter (configured through option sctp_adaptation_layer). Notie that with the current implementation of the Erlang/SCTP binding, -this event is disabled by default.

        • #sctp_pdapi_event{
          +this event is disabled by default.

        • #sctp_pdapi_event{
                 indication = sctp_partial_delivery_aborted,
          -      assoc_id   = assoc_id()
          -}

          A partial delivery failure. In the current implementation + assoc_id = assoc_id() +}

          A partial delivery failure. In the current implementation of the Erlang/SCTP binding, this event is internally converted into an error term returned by recv/*.

        diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/gen_tcp.html b/prs/8803/lib/kernel-10.0.1/doc/html/gen_tcp.html index 04e60e56b42e3..f7ea4889c66bb 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/gen_tcp.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/gen_tcp.html @@ -130,27 +130,27 @@

        Interface to TCP/IP sockets.

        This module provides functions for communicating over TCP/IP protocol sockets.

        The following code fragment is a simple example of a client connecting to a -server at port 5678, transferring a binary, and closing the connection:

        client() ->
        +server at port 5678, transferring a binary, and closing the connection:

        client() ->
             SomeHostInNet = "localhost", % to make it runnable on one machine
        -    {ok, Sock} = gen_tcp:connect(SomeHostInNet, 5678,
        -                                 [binary, {packet, 0}]),
        -    ok = gen_tcp:send(Sock, "Some Data"),
        -    ok = gen_tcp:close(Sock).

        At the other end, a server is listening on port 5678, accepts the connection, -and receives the binary:

        server() ->
        -    {ok, LSock} = gen_tcp:listen(5678, [binary, {packet, 0},
        -                                        {active, false}]),
        -    {ok, Sock} = gen_tcp:accept(LSock),
        -    {ok, Bin} = do_recv(Sock, []),
        -    ok = gen_tcp:close(Sock),
        -    ok = gen_tcp:close(LSock),
        +    {ok, Sock} = gen_tcp:connect(SomeHostInNet, 5678,
        +                                 [binary, {packet, 0}]),
        +    ok = gen_tcp:send(Sock, "Some Data"),
        +    ok = gen_tcp:close(Sock).

        At the other end, a server is listening on port 5678, accepts the connection, +and receives the binary:

        server() ->
        +    {ok, LSock} = gen_tcp:listen(5678, [binary, {packet, 0},
        +                                        {active, false}]),
        +    {ok, Sock} = gen_tcp:accept(LSock),
        +    {ok, Bin} = do_recv(Sock, []),
        +    ok = gen_tcp:close(Sock),
        +    ok = gen_tcp:close(LSock),
             Bin.
         
        -do_recv(Sock, Bs) ->
        -    case gen_tcp:recv(Sock, 0) of
        -        {ok, B} ->
        -            do_recv(Sock, [Bs, B]);
        -        {error, closed} ->
        -            {ok, list_to_binary(Bs)}
        +do_recv(Sock, Bs) ->
        +    case gen_tcp:recv(Sock, 0) of
        +        {ok, B} ->
        +            do_recv(Sock, [Bs, B]);
        +        {error, closed} ->
        +            {ok, list_to_binary(Bs)}
             end.

        For more examples, see section Examples.

        Note

        Functions that create sockets can take an optional option; {inet_backend, Backend} that, if specified, has to be the first option. This selects the implementation backend towards the platform's socket API.

        This is a temporary option that will be ignored in a future release.

        The default is Backend = inet that selects the traditional inet_drv.c @@ -189,48 +189,48 @@

        a single listening socket. Function start/2 takes the number of worker processes and the port number on which to listen for incoming connections. If LPort is specified as 0, an ephemeral port number is used, which is why the -start function returns the actual port number allocated:

        start(Num,LPort) ->
        -    case gen_tcp:listen(LPort,[{active, false},{packet,2}]) of
        -        {ok, ListenSock} ->
        -            start_servers(Num,ListenSock),
        -            {ok, Port} = inet:port(ListenSock),
        +start function returns the actual port number allocated:

        start(Num,LPort) ->
        +    case gen_tcp:listen(LPort,[{active, false},{packet,2}]) of
        +        {ok, ListenSock} ->
        +            start_servers(Num,ListenSock),
        +            {ok, Port} = inet:port(ListenSock),
                     Port;
        -        {error,Reason} ->
        -            {error,Reason}
        +        {error,Reason} ->
        +            {error,Reason}
             end.
         
        -start_servers(0,_) ->
        +start_servers(0,_) ->
             ok;
        -start_servers(Num,LS) ->
        -    spawn(?MODULE,server,[LS]),
        -    start_servers(Num-1,LS).
        -
        -server(LS) ->
        -    case gen_tcp:accept(LS) of
        -        {ok,S} ->
        -            loop(S),
        -            server(LS);
        +start_servers(Num,LS) ->
        +    spawn(?MODULE,server,[LS]),
        +    start_servers(Num-1,LS).
        +
        +server(LS) ->
        +    case gen_tcp:accept(LS) of
        +        {ok,S} ->
        +            loop(S),
        +            server(LS);
                 Other ->
        -            io:format("accept returned ~w - goodbye!~n",[Other]),
        +            io:format("accept returned ~w - goodbye!~n",[Other]),
                     ok
             end.
         
        -loop(S) ->
        -    inet:setopts(S,[{active,once}]),
        +loop(S) ->
        +    inet:setopts(S,[{active,once}]),
             receive
        -        {tcp,S,Data} ->
        -            Answer = process(Data), % Not implemented in this example
        -            gen_tcp:send(S,Answer),
        -            loop(S);
        -        {tcp_closed,S} ->
        -            io:format("Socket ~w closed [~w]~n",[S,self()]),
        +        {tcp,S,Data} ->
        +            Answer = process(Data), % Not implemented in this example
        +            gen_tcp:send(S,Answer),
        +            loop(S);
        +        {tcp_closed,S} ->
        +            io:format("Socket ~w closed [~w]~n",[S,self()]),
                     ok
        -    end.

        Example of a simple client:

        client(PortNo,Message) ->
        -    {ok,Sock} = gen_tcp:connect("localhost",PortNo,[{active,false},
        -                                                    {packet,2}]),
        -    gen_tcp:send(Sock,Message),
        -    A = gen_tcp:recv(Sock,0),
        -    gen_tcp:close(Sock),
        +    end.

        Example of a simple client:

        client(PortNo,Message) ->
        +    {ok,Sock} = gen_tcp:connect("localhost",PortNo,[{active,false},
        +                                                    {packet,2}]),
        +    gen_tcp:send(Sock,Message),
        +    A = gen_tcp:recv(Sock,0),
        +    gen_tcp:close(Sock),
             A.

        The send call does not accept a time-out option because time-outs on send is handled through socket option send_timeout. The behavior of a send operation with no receiver is mainly defined by the underlying TCP stack and the network @@ -240,32 +240,32 @@

        does not get any acknowledge for each message it sends, but has to rely on the send time-out option to detect that the other end is unresponsive. Option send_timeout can be used when connecting:

        ...
        -{ok,Sock} = gen_tcp:connect(HostAddress, Port,
        -                            [{active,false},
        -                             {send_timeout, 5000},
        -                             {packet,2}]),
        -                loop(Sock), % See below
        -...

        In the loop where requests are handled, send time-outs can now be detected:

        loop(Sock) ->
        +{ok,Sock} = gen_tcp:connect(HostAddress, Port,
        +                            [{active,false},
        +                             {send_timeout, 5000},
        +                             {packet,2}]),
        +                loop(Sock), % See below
        +...

        In the loop where requests are handled, send time-outs can now be detected:

        loop(Sock) ->
             receive
        -        {Client, send_data, Binary} ->
        -            case gen_tcp:send(Sock,[Binary]) of
        -                {error, timeout} ->
        -                    io:format("Send timeout, closing!~n",
        -                              []),
        -                    handle_send_timeout(), % Not implemented here
        -                    Client ! {self(),{error_sending, timeout}},
        +        {Client, send_data, Binary} ->
        +            case gen_tcp:send(Sock,[Binary]) of
        +                {error, timeout} ->
        +                    io:format("Send timeout, closing!~n",
        +                              []),
        +                    handle_send_timeout(), % Not implemented here
        +                    Client ! {self(),{error_sending, timeout}},
                             %% Usually, it's a good idea to give up in case of a
                             %% send timeout, as you never know how much actually
                             %% reached the server, maybe only a packet header?!
        -                    gen_tcp:close(Sock);
        -                {error, OtherSendError} ->
        -                    io:format("Some other error on socket (~p), closing",
        -                              [OtherSendError]),
        -                    Client ! {self(),{error_sending, OtherSendError}},
        -                    gen_tcp:close(Sock);
        +                    gen_tcp:close(Sock);
        +                {error, OtherSendError} ->
        +                    io:format("Some other error on socket (~p), closing",
        +                              [OtherSendError]),
        +                    Client ! {self(),{error_sending, OtherSendError}},
        +                    gen_tcp:close(Sock);
                         ok ->
        -                    Client ! {self(), data_sent},
        -                    loop(Sock)
        +                    Client ! {self(), data_sent},
        +                    loop(Sock)
                     end
             end.

        Usually it suffices to detect time-outs on receive, as most protocols include some sort of acknowledgment from the server, but if the protocol is strictly one diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/gen_udp.html b/prs/8803/lib/kernel-10.0.1/doc/html/gen_udp.html index ea2ed0e2f6a09..d570731496d77 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/gen_udp.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/gen_udp.html @@ -960,8 +960,8 @@

        open(Port, Opts)

        Leaves a multicast group.

      • option/0 - See inet:setopts/2.

      UDP packets are sent with this socket using send(Socket, ...). When UDP packets arrive to the Socket's UDP port, and the socket is in an active mode, the packets are delivered as messages to the -controlling process (socket owner):

      {udp, Socket, PeerIP, PeerPort, Packet} % Without ancillary data
      -{udp, Socket, PeerIP, PeerPort, AncData, Packet} % With ancillary data

      PeerIP and PeerPort are the address from which Packet was sent. +controlling process (socket owner):

      {udp, Socket, PeerIP, PeerPort, Packet} % Without ancillary data
      +{udp, Socket, PeerIP, PeerPort, AncData, Packet} % With ancillary data

      PeerIP and PeerPort are the address from which Packet was sent. Packet is a list of bytes ([byte/0] if option list is active and a binary/0 if option binaryis active (they are mutually exclusive).

      The message contains an AncData field only if any of the socket @@ -969,8 +969,8 @@

      open(Port, Opts)

      recvtclass or recvttl are active.

      When a socket in {active, N} mode (see inet:setopts/2 for details), transitions to passive ({active, false}) mode (N counts down to 0), -the controlling process is notified by a message on this form:

      {udp_passive, Socket}

      If the OS protocol stack reports an error for the socket, the following -message is sent to the controlling process:

      {udp_error, Socket, Reason}

      Reason is mostly a POSIX Error Code.

      If the socket is in passive mode (not in an active mode), received data +the controlling process is notified by a message on this form:

      {udp_passive, Socket}

      If the OS protocol stack reports an error for the socket, the following +message is sent to the controlling process:

      {udp_error, Socket, Reason}

      Reason is mostly a POSIX Error Code.

      If the socket is in passive mode (not in an active mode), received data can be retrieved with therecv/2,3](recv/2) calls. Note that incoming UDP packets that are longer than the receive buffer option specifies can be truncated without warning.

      The default value for the receive buffer option is {recbuf, 8192}.

      diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/global_group.html b/prs/8803/lib/kernel-10.0.1/doc/html/global_group.html index 462f048c0fe06..d03dcf1677663 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/global_group.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/global_group.html @@ -132,7 +132,7 @@

      groups. Each global group has its own global namespace, see global.

      The main advantage of dividing systems into global groups is that the background load decreases while the number of nodes to be updated is reduced when manipulating globally registered names.

      The Kernel configuration parameter global_groups -defines the global groups:

      {global_groups, [GroupTuple :: group_tuple()]}

      For the processes and nodes to run smoothly using the global group +defines the global groups:

      {global_groups, [GroupTuple :: group_tuple()]}

      For the processes and nodes to run smoothly using the global group functionality, the following criteria must be met:

      • An instance of the global group server, global_group, must be running on each node. The processes are automatically started and synchronized when a node is started.
      • All involved nodes must agree on the global group definition, otherwise the diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/inet.html b/prs/8803/lib/kernel-10.0.1/doc/html/inet.html index 7258f5aedf0db..6319cd0bbd1ef 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/inet.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/inet.html @@ -151,19 +151,19 @@

        or as a tuple {150, 236, 20, 73}.

        IPv4 address examples:

        Address          ip_address()
         -------          ------------
         127.0.0.1        {127,0,0,1}
        -192.168.42.2     {192,168,42,2}

        IPv6 address examples:

        Address          ip_address()
        +192.168.42.2     {192,168,42,2}

        IPv6 address examples:

        Address          ip_address()
         -------          ------------
        -::1             {0,0,0,0,0,0,0,1}
        -::192.168.42.2  {0,0,0,0,0,0,(192 bsl 8) bor 168,(42 bsl 8) bor 2}
        +::1             {0,0,0,0,0,0,0,1}
        +::192.168.42.2  {0,0,0,0,0,0,(192 bsl 8) bor 168,(42 bsl 8) bor 2}
         ::FFFF:192.168.42.2
        -                {0,0,0,0,0,16#FFFF,(192 bsl 8) bor 168,(42 bsl 8) bor 2}
        +                {0,0,0,0,0,16#FFFF,(192 bsl 8) bor 168,(42 bsl 8) bor 2}
         3ffe:b80:1f8d:2:204:acff:fe17:bf38
        -                {16#3ffe,16#b80,16#1f8d,16#2,16#204,16#acff,16#fe17,16#bf38}
        +                {16#3ffe,16#b80,16#1f8d,16#2,16#204,16#acff,16#fe17,16#bf38}
         fe80::204:acff:fe17:bf38
        -                {16#fe80,0,0,0,16#204,16#acff,16#fe17,16#bf38}

        Function parse_address/1 can be useful:

        1> inet:parse_address("192.168.42.2").
        -{ok,{192,168,42,2}}
        -2> inet:parse_address("::FFFF:192.168.42.2").
        -{ok,{0,0,0,0,0,65535,49320,10754}}

        + {16#fe80,0,0,0,16#204,16#acff,16#fe17,16#bf38}

        Function parse_address/1 can be useful:

        1> inet:parse_address("192.168.42.2").
        +{ok,{192,168,42,2}}
        +2> inet:parse_address("::FFFF:192.168.42.2").
        +{ok,{0,0,0,0,0,65535,49320,10754}}

        @@ -965,7 +965,7 @@

        hostent()

        A record describing a host; name and address.

        Corresponds to the C: struct hostent as returned by for example -gethostbyname(3).

        The record is defined in the Kernel include file "inet.hrl".

        Add the following directive to the module:

        -include_lib("kernel/include/inet.hrl").
        +gethostbyname(3).

        The record is defined in the Kernel include file "inet.hrl".

        Add the following directive to the module:

        -include_lib("kernel/include/inet.hrl").
        @@ -2132,8 +2132,8 @@

        getopts(Socket, Options)

        this information, you need to know the following:

        • The numeric value of protocol level IPPROTO_TCP
        • The numeric value of option TCP_INFO
        • The size of struct tcp_info
        • The size and offset of the specific field

        By inspecting the headers or writing a small C program, it is found that IPPROTO_TCP is 6, TCP_INFO is 11, the structure size is 92 (bytes), the offset of tcpi_sacked is 28 bytes, and the value is a 32-bit integer. The -following code can be used to retrieve the value:

        get_tcpi_sacked(Sock) ->
        -    {ok,[{raw,_,_,Info}]} = inet:getopts(Sock,[{raw,6,11,92}]),
        +following code can be used to retrieve the value:

        get_tcpi_sacked(Sock) ->
        +    {ok,[{raw,_,_,Info}]} = inet:getopts(Sock,[{raw,6,11,92}]),
             <<_:28/binary,TcpiSacked:32/native,_/binary>> = Info,
             TcpiSacked.

        Preferably, you would check the machine type, the operating system, and the Kernel version before executing anything similar to this code.

        @@ -2485,7 +2485,7 @@

        monitor(Socket)

        Start a socket monitor.

        If the Socket to monitor doesn't exist or when the monitor is triggered, -a 'DOWN' message is sent that has the following pattern:

        	    {'DOWN', MonitorRef, Type, Object, Info}
        • MonitorRef - The return value from this function.

        • Type - The type of socket, can be one of the following +a 'DOWN' message is sent that has the following pattern:

          	    {'DOWN', MonitorRef, Type, Object, Info}
          • MonitorRef - The return value from this function.

          • Type - The type of socket, can be one of the following atom/0s: port or socket.

          • Object - The monitored entity, the socket, which triggered the event.

          • Info - Either the termination reason of the socket or nosock (the Socket did not exist when this function was called).

          Making several calls to inet:monitor/1 for the same Socket is not an error; one monitor is created per call.

          The monitor is triggered when the socket is closed in any way such as diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/inet_res.html b/prs/8803/lib/kernel-10.0.1/doc/html/inet_res.html index 35db77ee5faf4..6ccf97cba0d9e 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/inet_res.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/inet_res.html @@ -179,15 +179,15 @@

          Example

          This access functions example shows how lookup/3 can be implemented using -resolve/3 from outside the module:

          example_lookup(Name, Class, Type) ->
          -    case inet_res:resolve(Name, Class, Type) of
          -        {ok,Msg} ->
          -            [inet_dns:rr(RR, data)
          -             || RR <- inet_dns:msg(Msg, anlist),
          -                 inet_dns:rr(RR, type) =:= Type,
          -                 inet_dns:rr(RR, class) =:= Class];
          -        {error,_} ->
          -            []
          +resolve/3 from outside the module:

          example_lookup(Name, Class, Type) ->
          +    case inet_res:resolve(Name, Class, Type) of
          +        {ok,Msg} ->
          +            [inet_dns:rr(RR, data)
          +             || RR <- inet_dns:msg(Msg, anlist),
          +                 inet_dns:rr(RR, type) =:= Type,
          +                 inet_dns:rr(RR, class) =:= Class];
          +        {error,_} ->
          +            []
                end.
        @@ -594,57 +594,57 @@

        dns_msg()

        A DNS message.

        This is the start of a hierarchy of opaque data structures that can be examined with access functions in inet_dns, which return lists of {Field,Value} tuples. The arity 2 functions return the value -for a specified field.

        dns_msg() = DnsMsg
        -    inet_dns:msg(DnsMsg) ->
        -        [ {header, dns_header()}
        -        | {qdlist, dns_query()}
        -        | {anlist, dns_rr()}
        -        | {nslist, dns_rr()}
        -        | {arlist, dns_rr()} ]
        -    inet_dns:msg(DnsMsg, header) -> dns_header() % for example
        -    inet_dns:msg(DnsMsg, Field) -> Value
        -
        -dns_header() = DnsHeader
        -    inet_dns:header(DnsHeader) ->
        -        [ {id, integer()}
        -        | {qr, boolean()}
        -        | {opcode, query | iquery | status | integer()}
        -        | {aa, boolean()}
        -        | {tc, boolean()}
        -        | {rd, boolean()}
        -        | {ra, boolean()}
        -        | {pr, boolean()}
        -        | {rcode, integer(0..16)} ]
        -    inet_dns:header(DnsHeader, Field) -> Value
        -
        -query_type() = axfr | mailb | maila | any | dns_rr_type()
        -
        -dns_query() = DnsQuery
        -    inet_dns:dns_query(DnsQuery) ->
        -        [ {domain, dns_name()}
        -        | {type, query_type()}
        -        | {class, dns_class()} ]
        -    inet_dns:dns_query(DnsQuery, Field) -> Value
        -
        -dns_rr() = DnsRr
        -    inet_dns:rr(DnsRr) -> DnsRrFields | DnsRrOptFields
        -    DnsRrFields = [ {domain, dns_name()}
        -                  | {type, dns_rr_type()}
        -                  | {class, dns_class()}
        -                  | {ttl, integer()}
        -                  | {data, dns_data()} ]
        -    DnsRrOptFields = [ {domain, dns_name()}
        -                     | {type, opt}
        -                     | {udp_payload_size, integer()}
        -                     | {ext_rcode, integer()}
        -                     | {version, integer()}
        -                     | {z, integer()}
        -                     | {data, dns_data()} ]
        -    inet_dns:rr(DnsRr, Field) -> Value

        There is an information function for the types above:

        inet_dns:record_type(dns_msg()) -> msg;
        -inet_dns:record_type(dns_header()) -> header;
        -inet_dns:record_type(dns_query()) -> dns_query;
        -inet_dns:record_type(dns_rr()) -> rr;
        -inet_dns:record_type(_) -> undefined.

        So, inet_dns:(inet_dns:record_type(X))(X) converts any of these data +for a specified field.

        dns_msg() = DnsMsg
        +    inet_dns:msg(DnsMsg) ->
        +        [ {header, dns_header()}
        +        | {qdlist, dns_query()}
        +        | {anlist, dns_rr()}
        +        | {nslist, dns_rr()}
        +        | {arlist, dns_rr()} ]
        +    inet_dns:msg(DnsMsg, header) -> dns_header() % for example
        +    inet_dns:msg(DnsMsg, Field) -> Value
        +
        +dns_header() = DnsHeader
        +    inet_dns:header(DnsHeader) ->
        +        [ {id, integer()}
        +        | {qr, boolean()}
        +        | {opcode, query | iquery | status | integer()}
        +        | {aa, boolean()}
        +        | {tc, boolean()}
        +        | {rd, boolean()}
        +        | {ra, boolean()}
        +        | {pr, boolean()}
        +        | {rcode, integer(0..16)} ]
        +    inet_dns:header(DnsHeader, Field) -> Value
        +
        +query_type() = axfr | mailb | maila | any | dns_rr_type()
        +
        +dns_query() = DnsQuery
        +    inet_dns:dns_query(DnsQuery) ->
        +        [ {domain, dns_name()}
        +        | {type, query_type()}
        +        | {class, dns_class()} ]
        +    inet_dns:dns_query(DnsQuery, Field) -> Value
        +
        +dns_rr() = DnsRr
        +    inet_dns:rr(DnsRr) -> DnsRrFields | DnsRrOptFields
        +    DnsRrFields = [ {domain, dns_name()}
        +                  | {type, dns_rr_type()}
        +                  | {class, dns_class()}
        +                  | {ttl, integer()}
        +                  | {data, dns_data()} ]
        +    DnsRrOptFields = [ {domain, dns_name()}
        +                     | {type, opt}
        +                     | {udp_payload_size, integer()}
        +                     | {ext_rcode, integer()}
        +                     | {version, integer()}
        +                     | {z, integer()}
        +                     | {data, dns_data()} ]
        +    inet_dns:rr(DnsRr, Field) -> Value

        There is an information function for the types above:

        inet_dns:record_type(dns_msg()) -> msg;
        +inet_dns:record_type(dns_header()) -> header;
        +inet_dns:record_type(dns_query()) -> dns_query;
        +inet_dns:record_type(dns_rr()) -> rr;
        +inet_dns:record_type(_) -> undefined.

        So, inet_dns:(inet_dns:record_type(X))(X) converts any of these data structures into a {Field,Value} list.

        diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/kernel.epub b/prs/8803/lib/kernel-10.0.1/doc/html/kernel.epub index 9ddfbf4f7037a..4bea0df81d680 100644 Binary files a/prs/8803/lib/kernel-10.0.1/doc/html/kernel.epub and b/prs/8803/lib/kernel-10.0.1/doc/html/kernel.epub differ diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/logger.html b/prs/8803/lib/kernel-10.0.1/doc/html/logger.html index c9429602f33b7..09f738f4f5611 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/logger.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/logger.html @@ -130,18 +130,18 @@

        API module for Logger, the standard logging facility in Erlang/OTP.

        This module implements the main API for logging in Erlang/OTP. To create a log event, use the API functions or the log -macros, for example:

        ?LOG_ERROR("error happened because: ~p", [Reason]).   % With macro
        -logger:error("error happened because: ~p", [Reason]). % Without macro

        To configure the Logger backend, use +macros, for example:

        ?LOG_ERROR("error happened because: ~p", [Reason]).   % With macro
        +logger:error("error happened because: ~p", [Reason]). % Without macro

        To configure the Logger backend, use Kernel configuration parameters or configuration functions in the Logger API.

        By default, the Kernel application installs one log handler at system start. This handler is named default. It receives and processes standard log events produced by the Erlang runtime system, standard behaviours and different Erlang/OTP applications. The log events are by default printed to the terminal.

        If you want your systems logs to be printed to a file instead, you must configure the default handler to do so. The simplest way is to include the -following in your sys.config:

        [{kernel,
        -  [{logger,
        -    [{handler, default, logger_std_h,
        -      #{config => #{file => "path/to/file.log"}}}]}]}].

        For more information about:

        @@ -2431,12 +2431,12 @@

        log(Level, FunOrFormat, Args, Metadata)

        %% A plain string with expensive metadata
        -1> logger:info(fun([]) -> {"Hello World", #{ meta => expensive() }} end,[]).
        +1> logger:info(fun([]) -> {"Hello World", #{ meta => expensive() }} end,[]).
         %% An expensive report
        -2> logger:debug(fun(What) -> #{ what => What, cause => expensive() } end,roof).
        +2> logger:debug(fun(What) -> #{ what => What, cause => expensive() } end,roof).
         %% A plain string with expensive metadata and normal metadata
        -3> logger:debug(fun([]) -> {"Hello World", #{ meta => expensive() }} end,[],
        -               #{ meta => data }).

        When metadata is given both as an argument and returned from the fun they are +3> logger:debug(fun([]) -> {"Hello World", #{ meta => expensive() }} end,[], + #{ meta => data }).

        When metadata is given both as an argument and returned from the fun they are merged. If equal keys exists the values are taken from the metadata returned by the fun.

        @@ -2759,26 +2759,26 @@

        add_handlers/1

        consistent no matter which handler the system uses. Normal usage is to add a call to logger:add_handlers/1 just after the processes that the handler needs are started, and pass the application's logger configuration as the argument. -For example:

        -behaviour(application).
        -start(_, []) ->
        -    case supervisor:start_link({local, my_sup}, my_sup, []) of
        -        {ok, Pid} ->
        -            ok = logger:add_handlers(my_app),
        -            {ok, Pid, []};
        +For example:

        -behaviour(application).
        +start(_, []) ->
        +    case supervisor:start_link({local, my_sup}, my_sup, []) of
        +        {ok, Pid} ->
        +            ok = logger:add_handlers(my_app),
        +            {ok, Pid, []};
                 Error -> Error
              end.

        This reads the logger configuration parameter from the my_app application and starts the configured handlers. The contents of the configuration use the same rules as the logger handler configuration.

        If the handler is meant to replace the default handler, the Kernel's default handler have to be disabled before the new handler is added. A sys.config file -that disables the Kernel handler and adds a custom handler could look like this:

        [{kernel,
        -  [{logger,
        +that disables the Kernel handler and adds a custom handler could look like this:

        [{kernel,
        +  [{logger,
             %% Disable the default Kernel handler
        -    [{handler, default, undefined}]}]},
        - {my_app,
        -  [{logger,
        +    [{handler, default, undefined}]}]},
        + {my_app,
        +  [{logger,
             %% Enable this handler as the default
        -    [{handler, default, my_handler, #{}}]}]}].
        +
        [{handler, default, my_handler, #{}}]}]}].
        @@ -3733,8 +3733,8 @@

        update_formatter_config(HandlerId, Formatte -

        Update the formatter configuration for the specified handler.

        The new configuration is merged with the existing formatter configuration.

        To overwrite the existing configuration without any merge, use

        set_handler_config(HandlerId, formatter,
        -	      {FormatterModule, FormatterConfig}).
        +

        Update the formatter configuration for the specified handler.

        The new configuration is merged with the existing formatter configuration.

        To overwrite the existing configuration without any merge, use

        set_handler_config(HandlerId, formatter,
        +	      {FormatterModule, FormatterConfig}).

        @@ -3797,8 +3797,8 @@

        update_handler_config(HandlerId, Config)

        Update configuration data for the specified handler. This function behaves as if -it was implemented as follows:

        {ok, {_, Old}} = logger:get_handler_config(HandlerId),
        -logger:set_handler_config(HandlerId, maps:merge(Old, Config)).

        To overwrite the existing configuration without any merge, use +it was implemented as follows:

        {ok, {_, Old}} = logger:get_handler_config(HandlerId),
        +logger:set_handler_config(HandlerId, maps:merge(Old, Config)).

        To overwrite the existing configuration without any merge, use set_handler_config/2 .

        @@ -3891,8 +3891,8 @@

        update_primary_config(Config)

        Update primary configuration data for Logger. This function behaves as if it was -implemented as follows:

        Old = logger:get_primary_config(),
        -logger:set_primary_config(maps:merge(Old, Config)).

        To overwrite the existing configuration without any merge, use +implemented as follows:

        Old = logger:get_primary_config(),
        +logger:set_primary_config(maps:merge(Old, Config)).

        To overwrite the existing configuration without any merge, use set_primary_config/1 .

        @@ -3924,7 +3924,7 @@

        update_process_metadata(Meta)

        Set or update metadata to use when logging from current process

        If process metadata exists for the current process, this function behaves as if -it was implemented as follows:

        logger:set_process_metadata(maps:merge(logger:get_process_metadata(), Meta)).

        If no process metadata exists, the function behaves as +it was implemented as follows:

        logger:set_process_metadata(maps:merge(logger:get_process_metadata(), Meta)).

        If no process metadata exists, the function behaves as set_process_metadata/1 .

        @@ -3956,8 +3956,8 @@

        update_proxy_config(Config)

        Update configuration data for the Logger proxy. This function behaves as if it -was implemented as follows:

        Old = logger:get_proxy_config(),
        -logger:set_proxy_config(maps:merge(Old, Config)).

        To overwrite the existing configuration without any merge, use +was implemented as follows:

        Old = logger:get_proxy_config(),
        +logger:set_proxy_config(maps:merge(Old, Config)).

        To overwrite the existing configuration without any merge, use set_proxy_config/1 .

        For more information about the proxy, see section Logger Proxy in the Kernel User's Guide.

        diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/logger_chapter.html b/prs/8803/lib/kernel-10.0.1/doc/html/logger_chapter.html index b383003b2af56..b4fe55b63a927 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/logger_chapter.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/logger_chapter.html @@ -190,7 +190,7 @@

        The API for logging consists of a set of macros, and a set of functions on the form logger:Level/1,2,3, which are all shortcuts for logger:log(Level,Arg1[,Arg2[,Arg3]]).

        The macros are defined in logger.hrl, which is included in a module with the -directive

        -include_lib("kernel/include/logger.hrl").

        The difference between using the macros and the exported functions is that +directive

        -include_lib("kernel/include/logger.hrl").

        The difference between using the macros and the exported functions is that macros add location (originator) information to the metadata, and performs lazy evaluation by wrapping the logger call in a case statement, so it is only evaluated if the log level of the event passes the primary log level check.

        @@ -212,23 +212,23 @@

        The log message contains the information to be logged. The message can consist of a format string and arguments (given as two separate parameters in the Logger -API), a string or a report.

        Example, format string and arguments:

        logger:error("The file does not exist: ~ts",[Filename])

        Example, string:

        logger:notice("Something strange happened!")

        A report, which is either a map or a key-value list, is the preferred way to log +API), a string or a report.

        Example, format string and arguments:

        logger:error("The file does not exist: ~ts",[Filename])

        Example, string:

        logger:notice("Something strange happened!")

        A report, which is either a map or a key-value list, is the preferred way to log using Logger as it makes it possible for different backends to filter and format -the log event as it needs to.

        Example, report:

        ?LOG_ERROR(#{ user => joe, filename => Filename, reason => enoent })

        Reports can be accompanied by a report callback specified in the log event's +the log event as it needs to.

        Example, report:

        ?LOG_ERROR(#{ user => joe, filename => Filename, reason => enoent })

        Reports can be accompanied by a report callback specified in the log event's metadata. The report callback is a convenience function that the formatter can use to convert the report to a format string and arguments, or directly to a string. The formatter can also use its own conversion function, if no callback is provided, or if a customized formatting is desired.

        The report callback must be a fun with one or two arguments. If it takes one argument, this is the report itself, and the fun returns a format string and -arguments:

        fun((logger:report()) -> {io:format(),[term()]})

        If it takes two arguments, the first is the report, and the second is a map -containing extra data that allows direct conversion to a string:

        fun((logger:report(),logger:report_cb_config()) -> unicode:chardata())

        The fun must obey the depth and chars_limit parameters provided in the +arguments:

        fun((logger:report()) -> {io:format(),[term()]})

        If it takes two arguments, the first is the report, and the second is a map +containing extra data that allows direct conversion to a string:

        fun((logger:report(),logger:report_cb_config()) -> unicode:chardata())

        The fun must obey the depth and chars_limit parameters provided in the second argument, as the formatter cannot do anything useful of these parameters with the returned string. The extra data also contains a field named single_line, indicating if the printed log message may contain line breaks or not. This variant is used when the formatting of the report depends on the size -or single line parameters.

        Example, report, and metadata with report callback:

        logger:debug(#{got => connection_request, id => Id, state => State},
        -             #{report_cb => fun(R) -> {"~p",[R]} end})

        The log message can also be provided through a fun for lazy evaluation. The fun +or single line parameters.

        Example, report, and metadata with report callback:

        logger:debug(#{got => connection_request, id => Id, state => State},
        +             #{report_cb => fun(R) -> {"~p",[R]} end})

        The log message can also be provided through a fun for lazy evaluation. The fun is only evaluated if the primary log level check passes, and is therefore recommended if it is expensive to generate the message. The lazy fun must return a string, a report, or a tuple with format string and arguments.

        @@ -416,14 +416,14 @@

        allows another application to add its own default handler.

        Only one entry of this type is allowed.

      • {handler, HandlerId, Module, HandlerConfig} - If HandlerId is default, then this entry modifies the default handler, equivalent to calling

                logger:remove_handler(default)
        -

        followed by

                logger:add_handler(default, Module, HandlerConfig)
        +

        followed by

                logger:add_handler(default, Module, HandlerConfig)
         

        For all other values of HandlerId, this entry adds a new handler, -equivalent to calling

                logger:add_handler(HandlerId, Module, HandlerConfig)
        +equivalent to calling

                logger:add_handler(HandlerId, Module, HandlerConfig)
         

        Multiple entries of this type are allowed.

      • {filters, FilterDefault, [Filter]} - Adds the specified primary -filters.

        • FilterDefault = log | stop

        • Filter = {FilterId, {FilterFun, FilterConfig}}

        Equivalent to calling

                logger:add_primary_filter(FilterId, {FilterFun, FilterConfig})
        +filters.

        • FilterDefault = log | stop

        • Filter = {FilterId, {FilterFun, FilterConfig}}

        Equivalent to calling

                logger:add_primary_filter(FilterId, {FilterFun, FilterConfig})
         

        for each Filter.

        FilterDefault specifies the behaviour if all primary filters return ignore, see section Filters.

        Only one entry of this type is allowed.

      • {module_level, Level, [Module]} - Sets module log level for the given -modules. Equivalent to calling

                logger:set_module_level(Module, Level)

        for each Module.

        Multiple entries of this type are allowed.

      • {proxy, ProxyConfig} - Sets the proxy configuration, equivalent to +modules. Equivalent to calling

                logger:set_module_level(Module, Level)

        for each Module.

        Multiple entries of this type are allowed.

      • {proxy, ProxyConfig} - Sets the proxy configuration, equivalent to calling

                logger:set_proxy_config(ProxyConfig)
         

        Only one entry of this type is allowed.

      See section Configuration Examples for examples using the logger parameter for system configuration.

    • logger_metadata = map() - Specifies the primary @@ -446,31 +446,31 @@

      file. See the config(4) manual page for more information about this file.

      Each of the following examples shows a simple system configuration file that configures Logger according to the description.

      Modify the default handler to print to a file instead of -standard_io:

      [{kernel,
      -  [{logger,
      -    [{handler, default, logger_std_h,  % {handler, HandlerId, Module,
      -      #{config => #{file => "log/erlang.log"}}}  % Config}
      -    ]}]}].

      Modify the default handler to print each log event as a single line:

      [{kernel,
      -  [{logger,
      -    [{handler, default, logger_std_h,
      -      #{formatter => {logger_formatter, #{single_line => true}}}}
      -    ]}]}].

      Modify the default handler to print the pid of the logging process for each log -event:

      [{kernel,
      -  [{logger,
      -    [{handler, default, logger_std_h,
      -      #{formatter => {logger_formatter,
      -                        #{template => [time," ",pid," ",msg,"\n"]}}}}
      -    ]}]}].

      Modify the default handler to only print errors and more severe log events to +standard_io:

      [{kernel,
      +  [{logger,
      +    [{handler, default, logger_std_h,  % {handler, HandlerId, Module,
      +      #{config => #{file => "log/erlang.log"}}}  % Config}
      +    ]}]}].

      Modify the default handler to print each log event as a single line:

      [{kernel,
      +  [{logger,
      +    [{handler, default, logger_std_h,
      +      #{formatter => {logger_formatter, #{single_line => true}}}}
      +    ]}]}].

      Modify the default handler to print the pid of the logging process for each log +event:

      [{kernel,
      +  [{logger,
      +    [{handler, default, logger_std_h,
      +      #{formatter => {logger_formatter,
      +                        #{template => [time," ",pid," ",msg,"\n"]}}}}
      +    ]}]}].

      Modify the default handler to only print errors and more severe log events to "log/erlang.log", and add another handler to print all log events to -"log/debug.log".

      [{kernel,
      -  [{logger,
      -    [{handler, default, logger_std_h,
      -      #{level => error,
      -        config => #{file => "log/erlang.log"}}},
      -     {handler, info, logger_std_h,
      -      #{level => debug,
      -        config => #{file => "log/debug.log"}}}
      -    ]}]}].

      +"log/debug.log".

      [{kernel,
      +  [{logger,
      +    [{handler, default, logger_std_h,
      +      #{level => error,
      +        config => #{file => "log/erlang.log"}}},
      +     {handler, info, logger_std_h,
      +      #{level => debug,
      +        config => #{file => "log/debug.log"}}}
      +    ]}]}].

      @@ -511,9 +511,9 @@

      This field can be used by filters to stop or allow the log events.

      See section SASL User's Guide for more information about the old SASL error logging functionality.

    • Legacy Event Handlers
      To use event handlers written for error_logger, just add your event handler with

      error_logger:add_report_handler/1,2.

      This automatically starts the error logger event manager, and adds -error_logger as a handler to Logger, with the following configuration:

      #{level => info,
      +error_logger as a handler to Logger, with the following configuration:

      #{level => info,
         filter_default => log,
      -  filters => []}.

      Note

      This handler ignores events that do not originate from the error_logger + filters => []}.

      Note

      This handler ignores events that do not originate from the error_logger API, or from within OTP. This means that if your code uses the Logger API for logging, then your log events will be discarded by this handler.

      The handler is not overload protected.

    @@ -539,19 +539,19 @@

    level notice or more severe, are logged to the terminal via the default handler. To also log info events, you can either change the primary log level to info:

    1> logger:set_primary_config(level, info).
    -ok

    or set the level for one or a few modules only:

    2> logger:set_module_level(mymodule, info).
    +ok

    or set the level for one or a few modules only:

    2> logger:set_module_level(mymodule, info).
     ok

    This allows info events to pass through to the default handler, and be printed to the terminal as well. If there are many info events, it can be useful to print these to a file instead.

    First, set the log level of the default handler to notice, preventing it from -printing info events to the terminal:

    3> logger:set_handler_config(default, level, notice).
    +printing info events to the terminal:

    3> logger:set_handler_config(default, level, notice).
     ok

    Then, add a new handler which prints to file. You can use the handler module -logger_std_h, and configure it to log to file:

    4> Config = #{config => #{file => "./info.log"}, level => info}.
    -#{config => #{file => "./info.log"},level => info}
    -5> logger:add_handler(myhandler, logger_std_h, Config).
    +logger_std_h, and configure it to log to file:

    4> Config = #{config => #{file => "./info.log"}, level => info}.
    +#{config => #{file => "./info.log"},level => info}
    +5> logger:add_handler(myhandler, logger_std_h, Config).
     ok

    Since filter_default defaults to log, this handler now receives all log events. If you want info events only in the file, you must add a filter to stop -all non-info events. The built-in filter logger_filters:level/2 can do this:

    6> logger:add_handler_filter(myhandler, stop_non_info,
    -                             {fun logger_filters:level/2, {stop, neq, info}}).
    +all non-info events. The built-in filter logger_filters:level/2 can do this:

    6> logger:add_handler_filter(myhandler, stop_non_info,
    +                             {fun logger_filters:level/2, {stop, neq, info}}).
     ok

    See section Filters for more information about the filters and the filter_default configuration parameter.

    @@ -576,48 +576,48 @@

    database.

    When logger:get_config/0 or logger:get_handler_config/0,1 is called, Logger calls HModule:filter_config(Config). This function must return the -handler configuration where internal data is removed.

    A simple handler that prints to the terminal can be implemented as follows:

    -module(myhandler1).
    --export([log/2]).
    +handler configuration where internal data is removed.

    A simple handler that prints to the terminal can be implemented as follows:

    -module(myhandler1).
    +-export([log/2]).
     
    -log(LogEvent, #{formatter := {FModule, FConfig}}) ->
    -    io:put_chars(FModule:format(LogEvent, FConfig)).

    Notice that the above handler does not have any overload protection, and all log +log(LogEvent, #{formatter := {FModule, FConfig}}) -> + io:put_chars(FModule:format(LogEvent, FConfig)).

    Notice that the above handler does not have any overload protection, and all log events are printed directly from the client process.

    For information and examples of overload protection, please refer to section Protecting the Handler from Overload, and the implementation of logger_std_h and logger_disk_log_h .

    The following is a simpler example of a handler which logs to a file through one -single process:

    -module(myhandler2).
    --export([adding_handler/1, removing_handler/1, log/2]).
    --export([init/1, handle_call/3, handle_cast/2, terminate/2]).
    +single process:

    -module(myhandler2).
    +-export([adding_handler/1, removing_handler/1, log/2]).
    +-export([init/1, handle_call/3, handle_cast/2, terminate/2]).
     
    -adding_handler(Config) ->
    -    MyConfig = maps:get(config,Config,#{file => "myhandler2.log"}),
    -    {ok, Pid} = gen_server:start(?MODULE, MyConfig, []),
    -    {ok, Config#{config => MyConfig#{pid => Pid}}}.
    +adding_handler(Config) ->
    +    MyConfig = maps:get(config,Config,#{file => "myhandler2.log"}),
    +    {ok, Pid} = gen_server:start(?MODULE, MyConfig, []),
    +    {ok, Config#{config => MyConfig#{pid => Pid}}}.
     
    -removing_handler(#{config := #{pid := Pid}}) ->
    -    gen_server:stop(Pid).
    +removing_handler(#{config := #{pid := Pid}}) ->
    +    gen_server:stop(Pid).
     
    -log(LogEvent,#{config := #{pid := Pid}} = Config) ->
    -    gen_server:cast(Pid, {log, LogEvent, Config}).
    +log(LogEvent,#{config := #{pid := Pid}} = Config) ->
    +    gen_server:cast(Pid, {log, LogEvent, Config}).
     
    -init(#{file := File}) ->
    -    {ok, Fd} = file:open(File, [append, {encoding, utf8}]),
    -    {ok, #{file => File, fd => Fd}}.
    +init(#{file := File}) ->
    +    {ok, Fd} = file:open(File, [append, {encoding, utf8}]),
    +    {ok, #{file => File, fd => Fd}}.
     
    -handle_call(_, _, State) ->
    -    {reply, {error, bad_request}, State}.
    +handle_call(_, _, State) ->
    +    {reply, {error, bad_request}, State}.
     
    -handle_cast({log, LogEvent, Config}, #{fd := Fd} = State) ->
    -    do_log(Fd, LogEvent, Config),
    -    {noreply, State}.
    +handle_cast({log, LogEvent, Config}, #{fd := Fd} = State) ->
    +    do_log(Fd, LogEvent, Config),
    +    {noreply, State}.
     
    -terminate(_Reason, #{fd := Fd}) ->
    -    _ = file:close(Fd),
    +terminate(_Reason, #{fd := Fd}) ->
    +    _ = file:close(Fd),
         ok.
     
    -do_log(Fd, LogEvent, #{formatter := {FModule, FConfig}}) ->
    -    String = FModule:format(LogEvent, FConfig),
    -    io:put_chars(Fd, String).

    +do_log(Fd, LogEvent, #{formatter := {FModule, FConfig}}) -> + String = FModule:format(LogEvent, FConfig), + io:put_chars(Fd, String).

    @@ -683,11 +683,11 @@

    performance reasons, the client processes must never be blocked by synchronous log requests. It is possible, perhaps, that dropping or flushing events is still acceptable, since it does not affect the performance of the client processes -sending the log events.

    A configuration example:

    logger:add_handler(my_standard_h, logger_std_h,
    -                   #{config => #{file => "./system_info.log",
    +sending the log events.

    A configuration example:

    logger:add_handler(my_standard_h, logger_std_h,
    +                   #{config => #{file => "./system_info.log",
                                      sync_mode_qlen => 100,
                                      drop_mode_qlen => 1000,
    -                                 flush_qlen => 2000}}).

    + flush_qlen => 2000}}).

    @@ -701,11 +701,11 @@

    disables it.

    Defaults to true.

  • burst_limit_max_count - This is the maximum number of events to handle within a burst_limit_window_time time frame. After the limit is reached, successive events are dropped until the end of the time frame.

    Defaults to 500 events.

  • burst_limit_window_time - See the previous description of -burst_limit_max_count.

    Defaults to 1000 milliseconds.

  • A configuration example:

    logger:add_handler(my_disk_log_h, logger_disk_log_h,
    -                   #{config => #{file => "./my_disk_log",
    +burst_limit_max_count.

    Defaults to 1000 milliseconds.

    A configuration example:

    logger:add_handler(my_disk_log_h, logger_disk_log_h,
    +                   #{config => #{file => "./my_disk_log",
                                      burst_limit_enable => true,
                                      burst_limit_max_count => 20,
    -                                 burst_limit_window_time => 500}}).

    + burst_limit_window_time => 500}}).

    @@ -741,11 +741,11 @@

    forwards the event to the proxy on the remote node.

    When receiving a log event, either from the emulator or from a remote node, the proxy calls the Logger API to log the event.

    The proxy process is overload protected in the same way as described in section Protecting the Handler from Overload, -but with the following default values:

        #{sync_mode_qlen => 500,
    +but with the following default values:

        #{sync_mode_qlen => 500,
           drop_mode_qlen => 1000,
           flush_qlen => 5000,
           burst_limit_enable => false,
    -      overload_kill_enable => false}

    For log events from the emulator, synchronous message passing mode is not + overload_kill_enable => false}

    For log events from the emulator, synchronous message passing mode is not applicable, since all messages are passed asynchronously by the emulator. Drop mode is achieved by setting the system_logger to undefined, forcing the emulator to drop events until it is set back to the proxy pid again.

    The proxy uses erlang:send_nosuspend/2 when sending log events to a remote diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/logger_cookbook.html b/prs/8803/lib/kernel-10.0.1/doc/html/logger_cookbook.html index c1b22de3fe131..502e4b3f14718 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/logger_cookbook.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/logger_cookbook.html @@ -144,19 +144,19 @@

    -
    1> logger:i(primary).
    +
    1> logger:i(primary).
     Primary configuration:
         Level: notice
         Filter Default: log
         Filters:
    -        (none)

    It is also possible to fetch the configuration using + (none)

    It is also possible to fetch the configuration using logger:get_primary_config().

    See also

    -
    2> logger:i(handlers).
    +
    2> logger:i(handlers).
     Handler configuration:
         Id: default
             Module: logger_std_h
    @@ -173,10 +173,10 @@ 

    @@ -233,17 +233,17 @@

    Since single line logging is the default of the built-in formatter you only have to provide the empty map as the configuration. The example below uses the sys.config to change the formatter configuration.

    $ cat sys.config
    -[{kernel,
    -  [{logger,
    -    [{handler, default, logger_std_h,
    -      #{ formatter => {logger_formatter, #{ }}}}]}]}].
    +[{kernel,
    +  [{logger,
    +    [{handler, default, logger_std_h,
    +      #{ formatter => {logger_formatter, #{ }}}}]}]}].
     $ erl -config sys
    -Eshell V10.5.1  (abort with ^G)
    -1> logger:error("Oh noes, an error").
    +Eshell V10.5.1  (abort with ^G)
    +1> logger:error("Oh noes, an error").
     1962-10-03T11:07:47.466763-04:00 error: Oh noes, an error

    However, if you just want to change it for the current session you can also do -that.

    1> logger:set_handler_config(default, formatter, {logger_formatter, #{}}).
    +that.

    1> logger:set_handler_config(default, formatter, {logger_formatter, #{}}).
     ok
    -2> logger:error("Oh noes, another error").
    +2> logger:error("Oh noes, another error").
     1962-10-04T15:34:02.648713-04:00 error: Oh noes, another error

    See also

    @@ -251,14 +251,14 @@

    Add file and line number to log entries

    You can change what is printed to the log by using the formatter template:

    $ cat sys.config
    -[{kernel,
    -  [{logger,
    -    [{handler, default, logger_std_h,
    -      #{ formatter => {logger_formatter,
    -        #{ template => [time," ", file,":",line," ",level,": ",msg,"\n"] }}}}]}]}].
    +[{kernel,
    +  [{logger,
    +    [{handler, default, logger_std_h,
    +      #{ formatter => {logger_formatter,
    +        #{ template => [time," ", file,":",line," ",level,": ",msg,"\n"] }}}}]}]}].
     $ erl -config sys
    -Eshell V10.5.1  (abort with ^G)
    -1> logger:error("Oh noes, more errors",#{ file => "shell.erl", line => 1 }).
    +Eshell V10.5.1  (abort with ^G)
    +1> logger:error("Oh noes, more errors",#{ file => "shell.erl", line => 1 }).
     1962-10-05T07:37:44.104241+02:00 shell.erl:1 error: Oh noes, more errors

    Note that file and line have to be added in the metadata by the caller of logger:log/3 as otherwise Logger will not know from where it was called. The file and line number are automatically added if you use the ?LOG_ERROR macros @@ -275,18 +275,18 @@

    Instead of printing the logs to stdout we print them to a rotating file log.

    $ cat sys.config
    -[{kernel,
    -  [{logger,
    -    [{handler, default, logger_std_h,
    -      #{ config => #{ file => "log/erlang.log",
    +[{kernel,
    +  [{logger,
    +    [{handler, default, logger_std_h,
    +      #{ config => #{ file => "log/erlang.log",
                           max_no_bytes => 4096,
    -                      max_no_files => 5},
    -         formatter => {logger_formatter, #{}}}}]}]}].
    +                      max_no_files => 5},
    +         formatter => {logger_formatter, #{}}}}]}]}].
     $ erl -config sys
    -Eshell V10.5.1  (abort with ^G)
    -1> logger:error("Oh noes, even more errors").
    +Eshell V10.5.1  (abort with ^G)
    +1> logger:error("Oh noes, even more errors").
     ok
    -2> erlang:halt().
    +2> erlang:halt().
     $ cat log/erlang.log
     2019-10-07T11:47:16.837958+02:00 error: Oh noes, even more errors

    See also

    @@ -296,24 +296,24 @@

    Add a handler that prints debug log events to a file, while the default handler prints only up to notice level events to standard out.

    $ cat sys.config
    -[{kernel,
    -  [{logger_level, all},
    -   {logger,
    -    [{handler, default, logger_std_h,
    -      #{ level => notice }},
    -     {handler, debug, logger_std_h,
    -      #{ filters => [{debug,{fun logger_filters:level/2, {stop, neq, debug}}}],
    -         config => #{ file => "log/debug.log" } }}
    -    ]}]}].
    +[{kernel,
    +  [{logger_level, all},
    +   {logger,
    +    [{handler, default, logger_std_h,
    +      #{ level => notice }},
    +     {handler, debug, logger_std_h,
    +      #{ filters => [{debug,{fun logger_filters:level/2, {stop, neq, debug}}}],
    +         config => #{ file => "log/debug.log" } }}
    +    ]}]}].
     $ erl -config sys
    -Eshell V10.5.1  (abort with ^G)
    -1> logger:error("Oh noes, even more errors").
    +Eshell V10.5.1  (abort with ^G)
    +1> logger:error("Oh noes, even more errors").
     =ERROR REPORT==== 9-Oct-2019::14:40:54.784162 ===
     Oh noes, even more errors
     ok
    -2> logger:debug("A debug event").
    +2> logger:debug("A debug event").
     ok
    -3> erlang:halt().
    +3> erlang:halt().
     $ cat log/debug.log
     2019-10-09T14:41:03.680541+02:00 debug: A debug event

    In the configuration above we first raise the primary log level to max in order for the debug log events to get to the handlers. Then we configure the default @@ -321,13 +321,13 @@

    See also

    @@ -343,7 +343,7 @@

    What to log and how

    The simplest way to log something is by using the Logger macros and give a -report to the macro. For example if you want to log an error:

    ?LOG_ERROR(#{ what => http_error, status => 418, src => ClientIP, dst => ServerIP }).

    This will print the following in the default log:

    =ERROR REPORT==== 10-Oct-2019::12:13:10.089073 ===
    +report to the macro. For example if you want to log an error:

    ?LOG_ERROR(#{ what => http_error, status => 418, src => ClientIP, dst => ServerIP }).

    This will print the following in the default log:

    =ERROR REPORT==== 10-Oct-2019::12:13:10.089073 ===
         dst: {8,8,4,4}
         src: {8,8,8,8}
         status: 418
    @@ -355,14 +355,14 @@ 

    If you want to do structured logging, but still want to have some control of how the final log message is formatted you can give a report_cb as part of the -metadata with your log event.

    ReportCB = fun(#{ what := What, status := Status, src := Src, dst := Dst }) ->
    -                   {ok, #hostent{ h_name = SrcName }} = inet:gethostbyaddr(Src),
    -                   {ok, #hostent{ h_name = DstName }} = inet:gethostbyaddr(Dst),
    -                   {"What: ~p~nStatus: ~p~nSrc: ~s (~s)~nDst: ~s (~s)~n",
    -                    [What, Status, inet:ntoa(Src), SrcName, inet:ntoa(Dst), DstName]}
    +metadata with your log event.

    ReportCB = fun(#{ what := What, status := Status, src := Src, dst := Dst }) ->
    +                   {ok, #hostent{ h_name = SrcName }} = inet:gethostbyaddr(Src),
    +                   {ok, #hostent{ h_name = DstName }} = inet:gethostbyaddr(Dst),
    +                   {"What: ~p~nStatus: ~p~nSrc: ~s (~s)~nDst: ~s (~s)~n",
    +                    [What, Status, inet:ntoa(Src), SrcName, inet:ntoa(Dst), DstName]}
                end,
    -?LOG_ERROR(#{ what => http_error, status => 418, src => ClientIP, dst => ServerIP },
    -           #{ report_cb => ReportCB }).

    This will print the following:

    =ERROR REPORT==== 10-Oct-2019::13:29:02.230863 ===
    +?LOG_ERROR(#{ what => http_error, status => 418, src => ClientIP, dst => ServerIP },
    +           #{ report_cb => ReportCB }).

    This will print the following:

    =ERROR REPORT==== 10-Oct-2019::13:29:02.230863 ===
     What: http_error
     Status: 418
     Src: 8.8.8.8 (dns.google)
    @@ -383,22 +383,22 @@ 

    If we only want debug messages from a specific process it is possible to do this with a filter like this:

    %% Initial setup to use a filter for the level filter instead of the primary level
    -PrimaryLevel = maps:get(level, logger:get_primary_config()),
    -ok = logger:add_primary_filter(primary_level,
    -    {fun logger_filters:level/2, {log, gteq, PrimaryLevel}}),
    -logger:set_primary_config(filter_default, stop),
    -logger:set_primary_config(level, all),
    +PrimaryLevel = maps:get(level, logger:get_primary_config()),
    +ok = logger:add_primary_filter(primary_level,
    +    {fun logger_filters:level/2, {log, gteq, PrimaryLevel}}),
    +logger:set_primary_config(filter_default, stop),
    +logger:set_primary_config(level, all),
     
     %% Test that things work as they should
    -logger:notice("Notice should be logged"),
    -logger:debug("Should not be logged"),
    +logger:notice("Notice should be logged"),
    +logger:debug("Should not be logged"),
     
     %% Add the filter to allow PidToLog to send debug events
    -PidToLog = self(),
    -PidFilter = fun(LogEvent, _) when PidToLog =:= self() -> LogEvent;
    -               (_LogEvent, _) -> ignore end,
    -ok = logger:add_primary_filter(pid, {PidFilter,[]}),
    -logger:debug("Debug should be logged").

    There is a bit of setup needed to allow filters to decide whether a specific +PidToLog = self(), +PidFilter = fun(LogEvent, _) when PidToLog =:= self() -> LogEvent; + (_LogEvent, _) -> ignore end, +ok = logger:add_primary_filter(pid, {PidFilter,[]}), +logger:debug("Debug should be logged").

    There is a bit of setup needed to allow filters to decide whether a specific process should be allowed to log. This is because the default primary log level is notice and it is enforced before the primary filters. So in order for the pid filter to be useful we have to raise the primary log level to all and then add @@ -415,11 +415,11 @@

    Domains are used to specify which subsystem a certain log event originates from. The default handler will by default only log events with the domain [otp] or without a domain. If you would like to include SSL log events into the default -handler log you could do this:

    1> logger:add_handler_filter(default,ssl_domain,
    -  {fun logger_filters:domain/2,{log,sub,[otp,ssl]}}).
    -2> application:ensure_all_started(ssl).
    -{ok,[crypto,asn1,public_key,ssl]}
    -3> ssl:connect("www.erlang.org",443,[{log_level,debug}]).
    +handler log you could do this:

    1> logger:add_handler_filter(default,ssl_domain,
    +  {fun logger_filters:domain/2,{log,sub,[otp,ssl]}}).
    +2> application:ensure_all_started(ssl).
    +{ok,[crypto,asn1,public_key,ssl]}
    +3> ssl:connect("www.erlang.org",443,[{log_level,debug}]).
     %% lots of text

    See also

    diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/logger_disk_log_h.html b/prs/8803/lib/kernel-10.0.1/doc/html/logger_disk_log_h.html index 3deba4fa5f096..527e8dc54998f 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/logger_disk_log_h.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/logger_disk_log_h.html @@ -164,12 +164,12 @@

    and the disk_log handler, and are documented in the User's Guide.

    Notice that when changing the configuration of the handler in runtime, the disk_log options (file, type, max_no_files, max_no_bytes) must not be -modified.

    Example of adding a disk_log handler:

    logger:add_handler(my_disk_log_h, logger_disk_log_h,
    -                   #{config => #{file => "./my_disk_log",
    +modified.

    Example of adding a disk_log handler:

    logger:add_handler(my_disk_log_h, logger_disk_log_h,
    +                   #{config => #{file => "./my_disk_log",
                                      type => wrap,
                                      max_no_files => 4,
                                      max_no_bytes => 10000,
    -                                 filesync_repeat_interval => 1000}}).

    To use the disk_log handler instead of the default standard handler when + filesync_repeat_interval => 1000}}).

    To use the disk_log handler instead of the default standard handler when starting an Erlang node, change the Kernel default logger to use logger_disk_log_h. Example:

    erl -kernel logger '[{handler,default,logger_disk_log_h,
                           #{config => #{file => "./system_disk_log"}}}]'

    diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/logger_filters.html b/prs/8803/lib/kernel-10.0.1/doc/html/logger_filters.html index bef210516450e..8e30acb6838db 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/logger_filters.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/logger_filters.html @@ -251,8 +251,8 @@

    domain(LogEvent, Extra)

    events from, for example, a specific functional area. This allows filtering or other specialized treatment in a Logger handler.

    A domain field must be a list of atoms, creating smaller and more specialized domains as the list grows longer. The greatest domain is [], which comprises -all possible domains.

    For example, consider the following domains:

    D1 = [otp]
    -D2 = [otp, sasl]

    D1 is the greatest of the two, and is said to be a super-domain of D2. D2 +all possible domains.

    For example, consider the following domains:

    D1 = [otp]
    +D2 = [otp, sasl]

    D1 is the greatest of the two, and is said to be a super-domain of D2. D2 is a sub-domain D1. Both D1 and D2 are sub-domains of [].

    The above domains are used for logs originating from Erlang/OTP. D1 specifies that the log event comes from Erlang/OTP in general, and D2 indicates that the log event is a so called SASL report.

    The Extra parameter to the domain/2 function is specified when @@ -267,11 +267,11 @@

    domain(LogEvent, Extra)

    filter matches and Action is stop, the log event is stopped.

    If the filter does not match, it returns ignore, meaning that other filters, or the value of the configuration parameter filter_default, decide if the event is allowed or not.

    Log events that do not contain any domain field, match only when Compare is -equal to undefined or not_equal.

    Example: stop all events with domain [otp, sasl | _]

    1> logger:set_handler_config(h1, filter_default, log). % this is the default
    +equal to undefined or not_equal.

    Example: stop all events with domain [otp, sasl | _]

    1> logger:set_handler_config(h1, filter_default, log). % this is the default
     ok
    -2> Filter = {fun logger_filters:domain/2, {stop, sub, [otp, sasl]}}.
    +2> Filter = {fun logger_filters:domain/2, {stop, sub, [otp, sasl]}}.
     ...
    -3> logger:add_handler_filter(h1, no_sasl, Filter).
    +3> logger:add_handler_filter(h1, no_sasl, Filter).
     ok
    @@ -316,9 +316,9 @@

    level(LogEvent, Extra)

    filter matches if the value of Operator is:

    • neq - and the compare function returns lt or gt.

    • eq - and the compare function returns eq.

    • lt - and the compare function returns lt.

    • gt - and the compare function returns gt.

    • lteq - and the compare function returns lt or eq.

    • gteq - and the compare function returns gt or eq.

    If the filter matches and Action is log, the log event is allowed. If the filter matches and Action is stop, the log event is stopped.

    If the filter does not match, it returns ignore, meaning that other filters, or the value of the configuration parameter filter_default, will decide if the -event is allowed or not.

    Example: only allow debug level log events

    logger:set_handler_config(h1, filter_default, stop).
    -Filter = {fun logger_filters:level/2, {log, eq, debug}}.
    -logger:add_handler_filter(h1, debug_only, Filter).
    +event is allowed or not.

    Example: only allow debug level log events

    logger:set_handler_config(h1, filter_default, stop).
    +Filter = {fun logger_filters:level/2, {log, eq, debug}}.
    +logger:add_handler_filter(h1, debug_only, Filter).
     ok
    diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/logger_std_h.html b/prs/8803/lib/kernel-10.0.1/doc/html/logger_std_h.html index c3d241f189a18..1d0646ced3011 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/logger_std_h.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/logger_std_h.html @@ -185,9 +185,9 @@

    protection behaviour. The same parameters are used both in the standard handler and the disk_log handler, and are documented in the User's Guide.

    Notice that if changing the configuration of the handler in runtime, the type, -file, or modes parameters must not be modified.

    Example of adding a standard handler:

    logger:add_handler(my_standard_h, logger_std_h,
    -                   #{config => #{file => "./system_info.log",
    -                                 filesync_repeat_interval => 1000}}).

    To set the default handler, that starts initially with the Kernel application, +file, or modes parameters must not be modified.

    Example of adding a standard handler:

    logger:add_handler(my_standard_h, logger_std_h,
    +                   #{config => #{file => "./system_info.log",
    +                                 filesync_repeat_interval => 1000}}).

    To set the default handler, that starts initially with the Kernel application, to log to file instead of standard_io, change the Kernel default logger configuration. Example:

    erl -kernel logger '[{handler,default,logger_std_h,
                           #{config => #{file => "./log.log"}}}]'

    An example of how to replace the standard handler with a disk_log handler at diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/net.html b/prs/8803/lib/kernel-10.0.1/doc/html/net.html index ae96899c4232c..7a8be8a3ab923 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/net.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/net.html @@ -565,13 +565,13 @@

    ifaddrs_filter_fun()

    Interface address filtering selector function/0.

    For each ifaddrs entry, return either true to keep the entry or false to discard the entry.

    For example, to get an interface list which only contains -non-loopback inet interfaces:

    net:getifaddrs(
    -    fun (#{ addr  := #{family := inet},
    -            flags := Flags}) ->
    -          not lists:member(loopback, Flags);
    -        (_) ->
    +non-loopback inet interfaces:

    net:getifaddrs(
    +    fun (#{ addr  := #{family := inet},
    +            flags := Flags}) ->
    +          not lists:member(loopback, Flags);
    +        (_) ->
               false
    -    end).
    +
    end).
    diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/net_adm.html b/prs/8803/lib/kernel-10.0.1/doc/html/net_adm.html index 2fb2c9b832f90..7c60f38e52c76 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/net_adm.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/net_adm.html @@ -491,8 +491,8 @@

    names(Host)

    Returns the names and associated port numbers of the Erlang nodes that epmd -registered at the specified host.

    Similar to epmd -names, see erts:epmd.

    Returns {error, address} if epmd is not operational.

    Example:

    (arne@dunn)1> net_adm:names().
    -{ok,[{"arne",40262}]}
    +registered at the specified host.

    Similar to epmd -names, see erts:epmd.

    Returns {error, address} if epmd is not operational.

    Example:

    (arne@dunn)1> net_adm:names().
    +{ok,[{"arne",40262}]}
    diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/net_kernel.html b/prs/8803/lib/kernel-10.0.1/doc/html/net_kernel.html index 2f91c5b70b77f..58c2d1a355c43 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/net_kernel.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/net_kernel.html @@ -132,9 +132,9 @@

    operational for distributed Erlang to work. The purpose of this process is to implement parts of the BIFs spawn/4 and spawn_link/4, and to provide monitoring of the network.

    An Erlang node is started using command-line flag -name or -sname:

    $ erl -sname foobar

    It is also possible to call net_kernel:start(foobar, #{}) -directly from the normal Erlang shell prompt:

    1> net_kernel:start(foobar, #{name_domain => shortnames}).
    -{ok,<0.64.0>}
    -(foobar@gringotts)2>

    If the node is started with command-line flag -sname, the node name is +directly from the normal Erlang shell prompt:

    1> net_kernel:start(foobar, #{name_domain => shortnames}).
    +{ok,<0.64.0>}
    +(foobar@gringotts)2>

    If the node is started with command-line flag -sname, the node name is foobar@Host, where Host is the short name of the host (not the fully qualified domain name). If started with flag -name, the node name is foobar@Host, where Host is the fully qualified domain name. For more @@ -668,13 +668,13 @@

    monitor_nodes(Flag, Options)

    delivered before a nodeup message due to a new connection to the same node. Prior to OTP 23.0, this was not guaranteed to be the case.

    The format of the node status change messages depends on Options. If Options is the empty list or if net_kernel:monitor_nodes/1 is called, the format is as -follows:

    {nodeup, Node} | {nodedown, Node}
    -  Node = node()

    When Options is the empty map or empty list, the caller will only subscribe +follows:

    {nodeup, Node} | {nodedown, Node}
    +  Node = node()

    When Options is the empty map or empty list, the caller will only subscribe for status change messages for visible nodes. That is, only nodes that appear in the result of erlang:nodes/0.

    If Options equals anything other than the empty list, the format of the status -change messages is as follows:

    {nodeup, Node, Info} | {nodedown, Node, Info}
    -  Node = node()
    -  Info = #{Tag => Val} | [{Tag, Val}]

    Info is either a map or a list of 2-tuples. Its content depends on Options. +change messages is as follows:

    {nodeup, Node, Info} | {nodedown, Node, Info}
    +  Node = node()
    +  Info = #{Tag => Val} | [{Tag, Val}]

    Info is either a map or a list of 2-tuples. Its content depends on Options. If Options is a map, Info will also be a map. If Options is a list, Info will also be a list.

    When Options is a map, currently the following associations are allowed:

    • connection_id => boolean() - If the value of the association equals true, a connection_id => ConnectionId association will be included in the @@ -708,23 +708,23 @@

      monitor_nodes(Flag, Options)

      {node_type, visible} tuple will be included in the Info list.

    • nodedown_reason - The tuple {nodedown_reason, Reason} will be included in the Info list for nodedown messages.

      See the documentation of the nodedown_reason => boolean() association -above for information about possible Reason values.

    Example:

    (a@localhost)1> net_kernel:monitor_nodes(true, #{connection_id=>true, node_type=>all, nodedown_reason=>true}).
    +above for information about possible Reason values.

    Example:

    (a@localhost)1> net_kernel:monitor_nodes(true, #{connection_id=>true, node_type=>all, nodedown_reason=>true}).
     ok
    -(a@localhost)2> flush().
    -Shell got {nodeup,b@localhost,
    -                  #{connection_id => 3067552,node_type => visible}}
    -Shell got {nodeup,c@localhost,
    -                  #{connection_id => 13892107,node_type => hidden}}
    -Shell got {nodedown,b@localhost,
    -                    #{connection_id => 3067552,node_type => visible,
    -                      nodedown_reason => connection_closed}}
    -Shell got {nodedown,c@localhost,
    -                    #{connection_id => 13892107,node_type => hidden,
    -                      nodedown_reason => net_tick_timeout}}
    -Shell got {nodeup,b@localhost,
    -                  #{connection_id => 3067553,node_type => visible}}
    +(a@localhost)2> flush().
    +Shell got {nodeup,b@localhost,
    +                  #{connection_id => 3067552,node_type => visible}}
    +Shell got {nodeup,c@localhost,
    +                  #{connection_id => 13892107,node_type => hidden}}
    +Shell got {nodedown,b@localhost,
    +                    #{connection_id => 3067552,node_type => visible,
    +                      nodedown_reason => connection_closed}}
    +Shell got {nodedown,c@localhost,
    +                    #{connection_id => 13892107,node_type => hidden,
    +                      nodedown_reason => net_tick_timeout}}
    +Shell got {nodeup,b@localhost,
    +                  #{connection_id => 3067553,node_type => visible}}
     ok
    -(a@localhost)3>
    +
    (a@localhost)3>
    diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/notes.html b/prs/8803/lib/kernel-10.0.1/doc/html/notes.html index b3c66f2607491..d6709678c7e8a 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/notes.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/notes.html @@ -3919,12 +3919,12 @@

    viewed as two operations performed atomically. Asynchronously send an unlink signal or a demonitor signal, and ignore any future results of the link or monitor.

    NOTE: This change can cause some obscure code to fail which previously did -not. For example, the following code might hang:

                Mon = erlang:monitor(process, Pid),
    +not. For example, the following code might hang:

                Mon = erlang:monitor(process, Pid),
                 %% ...
    -            exit(Pid, bang),
    -            erlang:demonitor(Mon),
    +            exit(Pid, bang),
    +            erlang:demonitor(Mon),
                 receive
    -                {'DOWN', Mon, process, Pid, _} -> ok
    +                {'DOWN', Mon, process, Pid, _} -> ok
                 %% We were previously guaranteed to get a down message
                 %% (since we exited the process ourself), so we could
                 %% in this case leave out:
    diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/os.html b/prs/8803/lib/kernel-10.0.1/doc/html/os.html
    index 2dc6de88822a4..8b50df2db374d 100644
    --- a/prs/8803/lib/kernel-10.0.1/doc/html/os.html
    +++ b/prs/8803/lib/kernel-10.0.1/doc/html/os.html
    @@ -656,13 +656,13 @@ 

    cmd(Command, Options)

    Executes Command in a command shell of the target OS, captures the standard -output and standard error of the command, and returns this result as a string.

    Examples:

    LsOut = os:cmd("ls"), % on unix platform
    -DirOut = os:cmd("dir"), % on Win32 platform

    Notice that in some cases, standard output of a command when called from another +output and standard error of the command, and returns this result as a string.

    Examples:

    LsOut = os:cmd("ls"), % on unix platform
    +DirOut = os:cmd("dir"), % on Win32 platform

    Notice that in some cases, standard output of a command when called from another program can differ, compared with the standard output of the command when called directly from an OS command shell.

    The possible options are:

    • max_size - The maximum size of the data returned by the os:cmd call. This option is a safety feature that should be used when the command executed -can return a very large, possibly infinite, result.

      > os:cmd("cat /dev/zero", #{ max_size => 20 }).
      -[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
    +can return a very large, possibly infinite, result.

    > os:cmd("cat /dev/zero", #{ max_size => 20 }).
    +[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

    @@ -952,7 +952,7 @@

    perf_counter(Unit)

    resolution timestamp.

    This counter is read directly from the hardware or operating system with the same guarantees. This means that two consecutive calls to the function are not guaranteed to be monotonic, though it most likely will be. The performance -counter will be converted to the resolution passed as an argument.

    1> T1 = os:perf_counter(1000),receive after 10000 -> ok end,T2 = os:perf_counter(1000).
    +counter will be converted to the resolution passed as an argument.

    1> T1 = os:perf_counter(1000),receive after 10000 -> ok end,T2 = os:perf_counter(1000).
     176525861
     2> T2 - T1.
     10004
    @@ -1123,16 +1123,16 @@

    timestamp()

    allows you to log time stamps in high resolution and consistent with the time in the rest of the OS.

    Example of code formatting a string in format "DD Mon YYYY HH:MM:SS.mmmmmm", where DD is the day of month, Mon is the textual month name, YYYY is the year, -HH:MM:SS is the time, and mmmmmm is the microseconds in six positions:

    -module(print_time).
    --export([format_utc_timestamp/0]).
    -format_utc_timestamp() ->
    -    TS = {_,_,Micro} = os:timestamp(),
    -    {{Year,Month,Day},{Hour,Minute,Second}} =
    -calendar:now_to_universal_time(TS),
    -    Mstr = element(Month,{"Jan","Feb","Mar","Apr","May","Jun","Jul",
    -    "Aug","Sep","Oct","Nov","Dec"}),
    -    io_lib:format("~2w ~s ~4w ~2w:~2..0w:~2..0w.~6..0w",
    -    [Day,Mstr,Year,Hour,Minute,Second,Micro]).

    This module can be used as follows:

    1> io:format("~s~n",[print_time:format_utc_timestamp()]).
    +HH:MM:SS is the time, and mmmmmm is the microseconds in six positions:

    -module(print_time).
    +-export([format_utc_timestamp/0]).
    +format_utc_timestamp() ->
    +    TS = {_,_,Micro} = os:timestamp(),
    +    {{Year,Month,Day},{Hour,Minute,Second}} =
    +calendar:now_to_universal_time(TS),
    +    Mstr = element(Month,{"Jan","Feb","Mar","Apr","May","Jun","Jul",
    +    "Aug","Sep","Oct","Nov","Dec"}),
    +    io_lib:format("~2w ~s ~4w ~2w:~2..0w:~2..0w.~6..0w",
    +    [Day,Mstr,Year,Hour,Minute,Second,Micro]).

    This module can be used as follows:

    1> io:format("~s~n",[print_time:format_utc_timestamp()]).
     29 Apr 2009  9:55:30.051711

    OS system time can also be retrieved by system_time/0 and system_time/1.

    diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/pg.html b/prs/8803/lib/kernel-10.0.1/doc/html/pg.html index 07059afbefc3c..3ef4019f3a9fb 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/pg.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/pg.html @@ -870,7 +870,7 @@

    monitor_scope(Scope)

    Subscribes the caller to updates from the specified scope.

    Returns content of the entire scope and a reference to match the upcoming notifications.

    Whenever any group membership changes, an update message is sent to the -subscriber:

    {Ref, join, Group, [JoinPid1, JoinPid2]}
    {Ref, leave, Group, [LeavePid1]}
    +subscriber:

    {Ref, join, Group, [JoinPid1, JoinPid2]}
    {Ref, leave, Group, [LeavePid1]}
    diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/rpc.html b/prs/8803/lib/kernel-10.0.1/doc/html/rpc.html index 1e3397167c49d..ca5a6e3ae45a1 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/rpc.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/rpc.html @@ -1079,10 +1079,10 @@

    multicall(Nodes, Module, Function, Args, Ti return values, or {badrpc, Reason} for failing calls. Timeout is a time (integer) in milliseconds, or infinity.

    The following example is useful when new object code is to be loaded on all nodes in the network, and indicates some side effects that RPCs can produce:

    %% Find object code for module Mod
    -{Mod, Bin, File} = code:get_object_code(Mod),
    +{Mod, Bin, File} = code:get_object_code(Mod),
     
     %% and load it on all nodes including this one
    -{ResL, _} = rpc:multicall(code, load_binary, [Mod, File, Bin]),
    +{ResL, _} = rpc:multicall(code, load_binary, [Mod, File, Bin]),
     
     %% and then maybe check the ResL list.

    Note

    If you want the ability to distinguish between results, you may want to consider using the erpc:multicall() function from the diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/seq_trace.html b/prs/8803/lib/kernel-10.0.1/doc/html/seq_trace.html index c98b5c29c08a4..6fe138ca44381 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/seq_trace.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/seq_trace.html @@ -141,9 +141,9 @@

    Trace Messages Sent to the System Tracer

    The format of the messages is one of the following, depending on if flag -timestamp of the trace token is set to true or false:

    {seq_trace, Label, SeqTraceInfo, TimeStamp}

    or

    {seq_trace, Label, SeqTraceInfo}

    Where:

    Label = int()
    -TimeStamp = {Seconds, Milliseconds, Microseconds}
    -  Seconds = Milliseconds = Microseconds = int()

    SeqTraceInfo can have the following formats:

    • {send, Serial, From, To, Message} - Used when a process From with its +timestamp of the trace token is set to true or false:

      {seq_trace, Label, SeqTraceInfo, TimeStamp}

      or

      {seq_trace, Label, SeqTraceInfo}

      Where:

      Label = int()
      +TimeStamp = {Seconds, Milliseconds, Microseconds}
      +  Seconds = Milliseconds = Microseconds = int()

      SeqTraceInfo can have the following formats:

      • {send, Serial, From, To, Message} - Used when a process From with its trace token flag send set to true has sent information. To may be a process identifier, a registered name on a node represented as {NameAtom, NodeAtom}, or a node name represented as an atom. From may be a @@ -287,68 +287,68 @@

        Example of Use

        This example gives a rough idea of how the new primitives can be used and what -kind of output it produces.

        Assume that you have an initiating process with Pid == <0.30.0> like this:

        -module(seqex).
        --compile(export_all).
        +kind of output it produces.

        Assume that you have an initiating process with Pid == <0.30.0> like this:

        -module(seqex).
        +-compile(export_all).
         
        -loop(Port) ->
        +loop(Port) ->
             receive
        -        {Port,Message} ->
        -            seq_trace:set_token(label,17),
        -            seq_trace:set_token('receive',true),
        -            seq_trace:set_token(print,true),
        -            seq_trace:print(17,"**** Trace Started ****"),
        -            call_server ! {self(),the_message};
        -        {ack,Ack} ->
        +        {Port,Message} ->
        +            seq_trace:set_token(label,17),
        +            seq_trace:set_token('receive',true),
        +            seq_trace:set_token(print,true),
        +            seq_trace:print(17,"**** Trace Started ****"),
        +            call_server ! {self(),the_message};
        +        {ack,Ack} ->
                     ok
             end,
        -    loop(Port).

        And a registered process call_server with Pid == <0.31.0> like this:

        loop() ->
        +    loop(Port).

        And a registered process call_server with Pid == <0.31.0> like this:

        loop() ->
             receive
        -        {PortController,Message} ->
        -            Ack = {received, Message},
        -            seq_trace:print(17,"We are here now"),
        -            PortController ! {ack,Ack}
        +        {PortController,Message} ->
        +            Ack = {received, Message},
        +            seq_trace:print(17,"We are here now"),
        +            PortController ! {ack,Ack}
             end,
        -    loop().

        A possible output from the system's sequential_tracer can be like this:

        17:<0.30.0> Info {0,1} WITH
        +    loop().

        A possible output from the system's sequential_tracer can be like this:

        17:<0.30.0> Info {0,1} WITH
         "**** Trace Started ****"
        -17:<0.31.0> Received {0,2} FROM <0.30.0> WITH
        -{<0.30.0>,the_message}
        -17:<0.31.0> Info {2,3} WITH
        +17:<0.31.0> Received {0,2} FROM <0.30.0> WITH
        +{<0.30.0>,the_message}
        +17:<0.31.0> Info {2,3} WITH
         "We are here now"
        -17:<0.30.0> Received {2,4} FROM <0.31.0> WITH
        -{ack,{received,the_message}}

        The implementation of a system tracer process that produces this printout can -look like this:

        tracer() ->
        +17:<0.30.0> Received {2,4} FROM <0.31.0> WITH
        +{ack,{received,the_message}}

        The implementation of a system tracer process that produces this printout can +look like this:

        tracer() ->
             receive
        -        {seq_trace,Label,TraceInfo} ->
        -           print_trace(Label,TraceInfo,false);
        -        {seq_trace,Label,TraceInfo,Ts} ->
        -           print_trace(Label,TraceInfo,Ts);
        +        {seq_trace,Label,TraceInfo} ->
        +           print_trace(Label,TraceInfo,false);
        +        {seq_trace,Label,TraceInfo,Ts} ->
        +           print_trace(Label,TraceInfo,Ts);
                 _Other -> ignore
             end,
        -    tracer().
        -
        -print_trace(Label,TraceInfo,false) ->
        -    io:format("~p:",[Label]),
        -    print_trace(TraceInfo);
        -print_trace(Label,TraceInfo,Ts) ->
        -    io:format("~p ~p:",[Label,Ts]),
        -    print_trace(TraceInfo).
        -
        -print_trace({print,Serial,From,_,Info}) ->
        -    io:format("~p Info ~p WITH~n~p~n", [From,Serial,Info]);
        -print_trace({'receive',Serial,From,To,Message}) ->
        -    io:format("~p Received ~p FROM ~p WITH~n~p~n",
        -              [To,Serial,From,Message]);
        -print_trace({send,Serial,From,To,Message}) ->
        -    io:format("~p Sent ~p TO ~p WITH~n~p~n",
        -              [From,Serial,To,Message]).

        The code that creates a process that runs this tracer function and sets that -process as the system tracer can look like this:

        start() ->
        -    Pid = spawn(?MODULE,tracer,[]),
        -    seq_trace:set_system_tracer(Pid), % set Pid as the system tracer
        -    ok.

        With a function like test/0, the whole example can be started:

        test() ->
        -    P = spawn(?MODULE, loop, [port]),
        -    register(call_server, spawn(?MODULE, loop, [])),
        -    start(),
        -    P ! {port,message}.
        +
        tracer(). + +print_trace(Label,TraceInfo,false) -> + io:format("~p:",[Label]), + print_trace(TraceInfo); +print_trace(Label,TraceInfo,Ts) -> + io:format("~p ~p:",[Label,Ts]), + print_trace(TraceInfo). + +print_trace({print,Serial,From,_,Info}) -> + io:format("~p Info ~p WITH~n~p~n", [From,Serial,Info]); +print_trace({'receive',Serial,From,To,Message}) -> + io:format("~p Received ~p FROM ~p WITH~n~p~n", + [To,Serial,From,Message]); +print_trace({send,Serial,From,To,Message}) -> + io:format("~p Sent ~p TO ~p WITH~n~p~n", + [From,Serial,To,Message]).

        The code that creates a process that runs this tracer function and sets that +process as the system tracer can look like this:

        start() ->
        +    Pid = spawn(?MODULE,tracer,[]),
        +    seq_trace:set_system_tracer(Pid), % set Pid as the system tracer
        +    ok.

        With a function like test/0, the whole example can be started:

        test() ->
        +    P = spawn(?MODULE, loop, [port]),
        +    register(call_server, spawn(?MODULE, loop, [])),
        +    start(),
        +    P ! {port,message}.

    @@ -937,11 +937,11 @@

    set_token(Token)

    tracing is disabled, otherwise Token should be an Erlang term returned from get_token/0 or set_token/1. set_token/1 can be used to temporarily exclude message passing from the trace by setting the -trace token to empty like this:

    OldToken = seq_trace:set_token([]), % set to empty and save
    +trace token to empty like this:

    OldToken = seq_trace:set_token([]), % set to empty and save
                                         % old value
     % do something that should not be part of the trace
    -io:format("Exclude the signalling caused by this~n"),
    -seq_trace:set_token(OldToken), % activate the trace token again
    +io:format("Exclude the signalling caused by this~n"),
    +seq_trace:set_token(OldToken), % activate the trace token again
     ...

    Returns the previous value of the trace token.

    diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/socket.html b/prs/8803/lib/kernel-10.0.1/doc/html/socket.html index 877840bbdecf1..1445877bbb0a3 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/socket.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/socket.html @@ -172,8 +172,8 @@

    completion_info/0 and the received completion message.

    The compiler may then optimize a following receive statement to only scan the messages that arrive after the reference/0 is created. If the message queue is large this is a big optimization.

    The reference/0 has to be unique for the call.

    Repeating an Operation on a select Systems

    Onselect systems, if a call would be repeated before the select -message has been received it replaces the call in progress:

        {select, {select_info, Handle}} = socket:accept(LSock, nowait),
    -    {error, timeout} = socket:accept(LSock, 500),
    +message has been received it replaces the call in progress:

        {select, {select_info, Handle}} = socket:accept(LSock, nowait),
    +    {error, timeout} = socket:accept(LSock, 500),
         :

    Above, Handle is no longer valid once the second accept/2, call has been made (the first call is automatically canceled). After the second accept/2 call returns {error, timeout}, @@ -206,28 +206,28 @@

    Examples

    -
    client(SAddr, SPort) ->
    -   {ok, Sock} = socket:open(inet, stream, tcp),
    -   ok = socket:connect(Sock, #{family => inet,
    +
    client(SAddr, SPort) ->
    +   {ok, Sock} = socket:open(inet, stream, tcp),
    +   ok = socket:connect(Sock, #{family => inet,
                                    addr   => SAddr,
    -                               port   => SPort}),
    +                               port   => SPort}),
        Msg = <<"hello">>,
    -   ok = socket:send(Sock, Msg),
    -   ok = socket:shutdown(Sock, write),
    -   {ok, Msg} = socket:recv(Sock),
    -   ok = socket:close(Sock).
    -
    -server(Addr, Port) ->
    -   {ok, LSock} = socket:open(inet, stream, tcp),
    -   ok = socket:bind(LSock, #{family => inet,
    +   ok = socket:send(Sock, Msg),
    +   ok = socket:shutdown(Sock, write),
    +   {ok, Msg} = socket:recv(Sock),
    +   ok = socket:close(Sock).
    +
    +server(Addr, Port) ->
    +   {ok, LSock} = socket:open(inet, stream, tcp),
    +   ok = socket:bind(LSock, #{family => inet,
                                  port   => Port,
    -                             addr   => Addr}),
    -   ok = socket:listen(LSock),
    -   {ok, Sock} = socket:accept(LSock),
    -   {ok, Msg} = socket:recv(Sock),
    -   ok = socket:send(Sock, Msg),
    -   ok = socket:close(Sock),
    -   ok = socket:close(LSock).
    +
    addr => Addr}), + ok = socket:listen(LSock), + {ok, Sock} = socket:accept(LSock), + {ok, Msg} = socket:recv(Sock), + ok = socket:send(Sock, Msg), + ok = socket:close(Sock), + ok = socket:close(LSock).
    @@ -4795,7 +4795,7 @@

    ioctl/2

    (since OTP 26.1).

    Result; a boolean/0.

  • tcp_info - Get miscellaneous TCP related information for a connected socket (since OTP 26.1).

    Result; a map/0 with information items as key-value pairs.

  • Note

    Not all requests are supported by all platforms. To see if a ioctl request is supported on the current platform:

          Request = nread,
    -      true = socket:is_supported(ioctl_requests, Request),
    +      true = socket:is_supported(ioctl_requests, Request),
           :
    @@ -4959,7 +4959,7 @@

    is_supported(Key1)

    Check if a socket feature is supported.

    Returns true if supports/0 has a {Key1, true} tuple or a {Key1, list()} tuple in its returned list, -otherwise false (also for unknown keys).

    Example:

    true = socket:is_supported(local),
    +otherwise false (also for unknown keys).

    Example:

    true = socket:is_supported(local),
    @@ -4990,7 +4990,7 @@

    is_supported(Key1, Key2)

    Check if a socket feature is supported.

    Returns true if supports(Key1) has a {Key2, true} tuple -in its returned list, otherwise false (also for unknown keys).

    Example:

    true = socket:is_supported(msg_flags, errqueue),
    +in its returned list, otherwise false (also for unknown keys).

    Example:

    true = socket:is_supported(msg_flags, errqueue),
    @@ -5088,7 +5088,7 @@

    monitor(Socket)

    Start a socket monitor.

    If the Socket doesn't exist or when later the monitor is triggered, a 'DOWN' message is sent to the process that called monitor/1 -with the following pattern:

    	    {'DOWN', MonitorRef, socket, Socket, Info}

    Info is the termination reason of the socket or nosock if +with the following pattern:

    	    {'DOWN', MonitorRef, socket, Socket, Info}

    Info is the termination reason of the socket or nosock if Socket did not exist when the monitor was started.

    Making several calls to socket:monitor/1 for the same Socket is not an error; each call creates an independent monitor instance.

    diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/socket_usage.html b/prs/8803/lib/kernel-10.0.1/doc/html/socket_usage.html index fe0d752abdb2e..0297c37e99fc0 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/socket_usage.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/socket_usage.html @@ -186,47 +186,47 @@

    Example

    This example is intended to show how to create a simple (echo) server -(and client).

    -module(example).
    +(and client).

    -module(example).
     
    --export([client/2, client/3]).
    --export([server/0, server/1, server/2]).
    +-export([client/2, client/3]).
    +-export([server/0, server/1, server/2]).
     
     
     %% ======================================================================
     
     %% === Client ===
     
    -client(#{family := Family} = ServerSockAddr, Msg)
    -  when is_list(Msg) orelse is_binary(Msg) ->
    -    {ok, Sock} = socket:open(Family, stream, default),
    -    ok         = maybe_bind(Sock, Family),
    -    ok         = socket:connect(Sock, ServerSockAddr),
    -    client_exchange(Sock, Msg);
    +client(#{family := Family} = ServerSockAddr, Msg)
    +  when is_list(Msg) orelse is_binary(Msg) ->
    +    {ok, Sock} = socket:open(Family, stream, default),
    +    ok         = maybe_bind(Sock, Family),
    +    ok         = socket:connect(Sock, ServerSockAddr),
    +    client_exchange(Sock, Msg);
     
    -client(ServerPort, Msg)
    -  when is_integer(ServerPort) andalso (ServerPort > 0) ->
    +client(ServerPort, Msg)
    +  when is_integer(ServerPort) andalso (ServerPort > 0) ->
         Family   = inet, % Default
    -    Addr     = get_local_addr(Family), % Pick an address
    -    SockAddr = #{family => Family,
    +    Addr     = get_local_addr(Family), % Pick an address
    +    SockAddr = #{family => Family,
     		 addr   => Addr,
    -		 port   => ServerPort},
    -    client(SockAddr, Msg).
    -
    -client(ServerPort, ServerAddr, Msg)
    -  when is_integer(ServerPort) andalso (ServerPort > 0) andalso
    -       is_tuple(ServerAddr) ->
    -    Family   = which_family(ServerAddr),
    -    SockAddr = #{family => Family,
    +		 port   => ServerPort},
    +    client(SockAddr, Msg).
    +
    +client(ServerPort, ServerAddr, Msg)
    +  when is_integer(ServerPort) andalso (ServerPort > 0) andalso
    +       is_tuple(ServerAddr) ->
    +    Family   = which_family(ServerAddr),
    +    SockAddr = #{family => Family,
     		 addr   => ServerAddr,
    -		 port   => ServerPort},
    -    client(SockAddr, Msg).
    +		 port   => ServerPort},
    +    client(SockAddr, Msg).
     
     %% Send the message to the (echo) server and wait for the echo to come back.
    -client_exchange(Sock, Msg) when is_list(Msg) ->
    -    client_exchange(Sock, list_to_binary(Msg));
    -client_exchange(Sock, Msg) when is_binary(Msg) ->
    -    ok = socket:send(Sock, Msg, infinity),
    -    {ok, Msg} = socket:recv(Sock, byte_size(Msg), infinity),
    +client_exchange(Sock, Msg) when is_list(Msg) ->
    +    client_exchange(Sock, list_to_binary(Msg));
    +client_exchange(Sock, Msg) when is_binary(Msg) ->
    +    ok = socket:send(Sock, Msg, infinity),
    +    {ok, Msg} = socket:recv(Sock, byte_size(Msg), infinity),
         ok.
     
     
    @@ -234,188 +234,188 @@ 

    %% === Server === -server() -> +server() -> %% Make system choose port (and address) - server(0). + server(0). %% This function return the port and address that it actually uses, %% in case server/0 or server/1 (with a port number) was used to start it. -server(#{family := Family, addr := Addr, port := _} = SockAddr) -> - {ok, Sock} = socket:open(Family, stream, tcp), - ok = socket:bind(Sock, SockAddr), - ok = socket:listen(Sock), - {ok, #{port := Port}} = socket:sockname(Sock), - Acceptor = start_acceptor(Sock), - {ok, {Port, Addr, Acceptor}}; +server(#{family := Family, addr := Addr, port := _} = SockAddr) -> + {ok, Sock} = socket:open(Family, stream, tcp), + ok = socket:bind(Sock, SockAddr), + ok = socket:listen(Sock), + {ok, #{port := Port}} = socket:sockname(Sock), + Acceptor = start_acceptor(Sock), + {ok, {Port, Addr, Acceptor}}; -server(Port) when is_integer(Port) -> +server(Port) when is_integer(Port) -> Family = inet, % Default - Addr = get_local_addr(Family), % Pick an address - SockAddr = #{family => Family, + Addr = get_local_addr(Family), % Pick an address + SockAddr = #{family => Family, addr => Addr, - port => Port}, - server(SockAddr). - -server(Port, Addr) - when is_integer(Port) andalso (Port >= 0) andalso - is_tuple(Addr) -> - Family = which_family(Addr), - SockAddr = #{family => Family, + port => Port}, + server(SockAddr). + +server(Port, Addr) + when is_integer(Port) andalso (Port >= 0) andalso + is_tuple(Addr) -> + Family = which_family(Addr), + SockAddr = #{family => Family, addr => Addr, - port => Port}, - server(SockAddr). + port => Port}, + server(SockAddr). %% --- Echo Server - Acceptor --- -start_acceptor(LSock) -> - Self = self(), - {Pid, MRef} = spawn_monitor(fun() -> acceptor_init(Self, LSock) end), +start_acceptor(LSock) -> + Self = self(), + {Pid, MRef} = spawn_monitor(fun() -> acceptor_init(Self, LSock) end), receive - {'DOWN', MRef, process, Pid, Info} -> - erlang:error({failed_starting_acceptor, Info}); - {Pid, started} -> + {'DOWN', MRef, process, Pid, Info} -> + erlang:error({failed_starting_acceptor, Info}); + {Pid, started} -> %% Transfer ownership - socket:setopt(LSock, otp, owner, Pid), - Pid ! {self(), continue}, - erlang:demonitor(MRef), + socket:setopt(LSock, otp, owner, Pid), + Pid ! {self(), continue}, + erlang:demonitor(MRef), Pid end. -acceptor_init(Parent, LSock) -> - Parent ! {self(), started}, +acceptor_init(Parent, LSock) -> + Parent ! {self(), started}, receive - {Parent, continue} -> + {Parent, continue} -> ok end, - acceptor_loop(LSock). - -acceptor_loop(LSock) -> - case socket:accept(LSock, infinity) of - {ok, ASock} -> - start_handler(ASock), - acceptor_loop(LSock); - {error, Reason} -> - erlang:error({accept_failed, Reason}) + acceptor_loop(LSock). + +acceptor_loop(LSock) -> + case socket:accept(LSock, infinity) of + {ok, ASock} -> + start_handler(ASock), + acceptor_loop(LSock); + {error, Reason} -> + erlang:error({accept_failed, Reason}) end. %% --- Echo Server - Handler --- -start_handler(Sock) -> - Self = self(), - {Pid, MRef} = spawn_monitor(fun() -> handler_init(Self, Sock) end), +start_handler(Sock) -> + Self = self(), + {Pid, MRef} = spawn_monitor(fun() -> handler_init(Self, Sock) end), receive - {'DOWN', MRef, process, Pid, Info} -> - erlang:error({failed_starting_handler, Info}); - {Pid, started} -> + {'DOWN', MRef, process, Pid, Info} -> + erlang:error({failed_starting_handler, Info}); + {Pid, started} -> %% Transfer ownership - socket:setopt(Sock, otp, owner, Pid), - Pid ! {self(), continue}, - erlang:demonitor(MRef), + socket:setopt(Sock, otp, owner, Pid), + Pid ! {self(), continue}, + erlang:demonitor(MRef), Pid end. -handler_init(Parent, Sock) -> - Parent ! {self(), started}, +handler_init(Parent, Sock) -> + Parent ! {self(), started}, receive - {Parent, continue} -> + {Parent, continue} -> ok end, - handler_loop(Sock, undefined). + handler_loop(Sock, undefined). %% No "ongoing" reads %% The use of 'nowait' here is clearly *overkill* for this use case, %% but is intended as an example of how to use it. -handler_loop(Sock, undefined) -> - case socket:recv(Sock, 0, nowait) of - {ok, Data} -> - echo(Sock, Data), - handler_loop(Sock, undefined); +handler_loop(Sock, undefined) -> + case socket:recv(Sock, 0, nowait) of + {ok, Data} -> + echo(Sock, Data), + handler_loop(Sock, undefined); - {select, SelectInfo} -> - handler_loop(Sock, SelectInfo); + {select, SelectInfo} -> + handler_loop(Sock, SelectInfo); - {completion, CompletionInfo} -> - handler_loop(Sock, CompletionInfo); + {completion, CompletionInfo} -> + handler_loop(Sock, CompletionInfo); - {error, Reason} -> - erlang:error({recv_failed, Reason}) + {error, Reason} -> + erlang:error({recv_failed, Reason}) end; %% This is the standard (asyncronous) behaviour. -handler_loop(Sock, {select_info, recv, SelectHandle}) -> +handler_loop(Sock, {select_info, recv, SelectHandle}) -> receive - {'$socket', Sock, select, SelectHandle} -> - case socket:recv(Sock, 0, nowait) of - {ok, Data} -> - echo(Sock, Data), - handler_loop(Sock, undefined); + {'$socket', Sock, select, SelectHandle} -> + case socket:recv(Sock, 0, nowait) of + {ok, Data} -> + echo(Sock, Data), + handler_loop(Sock, undefined); - {select, NewSelectInfo} -> - handler_loop(Sock, NewSelectInfo); + {select, NewSelectInfo} -> + handler_loop(Sock, NewSelectInfo); - {error, Reason} -> - erlang:error({recv_failed, Reason}) + {error, Reason} -> + erlang:error({recv_failed, Reason}) end end; %% This is the (asyncronous) behaviour on platforms that support 'completion', %% currently only Windows. -handler_loop(Sock, {completion_info, recv, CompletionHandle}) -> +handler_loop(Sock, {completion_info, recv, CompletionHandle}) -> receive - {'$socket', Sock, completion, {CompletionHandle, CompletionStatus}} -> + {'$socket', Sock, completion, {CompletionHandle, CompletionStatus}} -> case CompletionStatus of - {ok, Data} -> - echo(Sock, Data), - handler_loop(Sock, undefined); - {error, Reason} -> - erlang:error({recv_failed, Reason}) + {ok, Data} -> + echo(Sock, Data), + handler_loop(Sock, undefined); + {error, Reason} -> + erlang:error({recv_failed, Reason}) end end. -echo(Sock, Data) when is_binary(Data) -> - ok = socket:send(Sock, Data, infinity), - io:format("** ECHO **" - "~n~s~n", [binary_to_list(Data)]). +echo(Sock, Data) when is_binary(Data) -> + ok = socket:send(Sock, Data, infinity), + io:format("** ECHO **" + "~n~s~n", [binary_to_list(Data)]). %% ====================================================================== %% === Utility functions === -maybe_bind(Sock, Family) -> - maybe_bind(Sock, Family, os:type()). +maybe_bind(Sock, Family) -> + maybe_bind(Sock, Family, os:type()). -maybe_bind(Sock, Family, {win32, _}) -> - Addr = get_local_addr(Family), - SockAddr = #{family => Family, +maybe_bind(Sock, Family, {win32, _}) -> + Addr = get_local_addr(Family), + SockAddr = #{family => Family, addr => Addr, - port => 0}, - socket:bind(Sock, SockAddr); -maybe_bind(_Sock, _Family, _OS) -> + port => 0}, + socket:bind(Sock, SockAddr); +maybe_bind(_Sock, _Family, _OS) -> ok. %% The idea with this is extract a "usable" local address %% that can be used even from *another* host. And doing %% so using the net module. -get_local_addr(Family) -> +get_local_addr(Family) -> Filter = - fun(#{addr := #{family := Fam}, - flags := Flags}) -> - (Fam =:= Family) andalso (not lists:member(loopback, Flags)); - (_) -> + fun(#{addr := #{family := Fam}, + flags := Flags}) -> + (Fam =:= Family) andalso (not lists:member(loopback, Flags)); + (_) -> false end, - {ok, [SockAddr|_]} = net:getifaddrs(Filter), - #{addr := #{addr := Addr}} = SockAddr, + {ok, [SockAddr|_]} = net:getifaddrs(Filter), + #{addr := #{addr := Addr}} = SockAddr, Addr. -which_family(Addr) when is_tuple(Addr) andalso (tuple_size(Addr) =:= 4) -> +which_family(Addr) when is_tuple(Addr) andalso (tuple_size(Addr) =:= 4) -> inet; -which_family(Addr) when is_tuple(Addr) andalso (tuple_size(Addr) =:= 8) -> +which_family(Addr) when is_tuple(Addr) andalso (tuple_size(Addr) =:= 8) -> inet6.

    diff --git a/prs/8803/lib/kernel-10.0.1/doc/html/trace.html b/prs/8803/lib/kernel-10.0.1/doc/html/trace.html index d716d43b83b30..a76bbb53fd1ad 100644 --- a/prs/8803/lib/kernel-10.0.1/doc/html/trace.html +++ b/prs/8803/lib/kernel-10.0.1/doc/html/trace.html @@ -146,23 +146,23 @@

    messages. Several sessions can exist at the same time without interfering with each other. When a trace session is destroyed, all its trace settings are automatically cleaned up.

    Example:

    %% Create a tracer process that will receive the trace events
    -1> Tracer = spawn(fun F() -> receive M -> io:format("~p~n",[M]), F() end end).
    +1> Tracer = spawn(fun F() -> receive M -> io:format("~p~n",[M]), F() end end).
     <0.91.0>
     %% Create a session using the Tracer
    -2> Session = trace:session_create(my_session, Tracer, []).
    -{#Ref<0.1543805153.1548353537.92331>,{my_session, 0}}
    +2> Session = trace:session_create(my_session, Tracer, []).
    +{#Ref<0.1543805153.1548353537.92331>,{my_session, 0}}
     %% Setup call tracing on self()
    -3> trace:process(Session, self(), true, [call]).
    +3> trace:process(Session, self(), true, [call]).
     1
     %% Setup call tracing on lists:seq/2
    -4> trace:function(Session, {lists,seq,2}, [], []).
    +4> trace:function(Session, {lists,seq,2}, [], []).
     1
     %% Call the traced function
    -5> lists:seq(1, 10).
    -{trace,<0.89.0>,call,{lists,seq,[1,10]}} % The trace message
    -[1,2,3,4,5,6,7,8,9,10] % The return value
    +5> lists:seq(1, 10).
    +{trace,<0.89.0>,call,{lists,seq,[1,10]}} % The trace message
    +[1,2,3,4,5,6,7,8,9,10] % The return value
     %% Cleanup the trace session
    -6> trace:session_destroy(Session).
    +6> trace:session_destroy(Session).
     ok

    @@ -1322,9 +1322,9 @@

    recv(Session, MatchSpec, FlagList)

    Match Specifications in Erlang in the User's Guide for the ERTS application.

  • true - Enable tracing for all received messages (to 'receive' traced processes). Any match specification is removed. This is the default.

  • false - Disable tracing for all received messages. Any match -specification is removed.

  • Argument FlagList must be [] for receive tracing.

    The return value is always 1.

    Examples:

    Only trace messages from a specific process Pid:

    > trace:recv(Session, [{['_',Pid, '_'],[],[]}], []).
    -1

    Only trace messages matching {reply, _}:

    > trace:recv(Session, [{['_','_', {reply,'_'}],[],[]}], []).
    -1

    Only trace messages from other nodes:

    > trace:recv(Session, [{['$1', '_', '_'],[{'=/=','$1',{node}}],[]}], []).
    +specification is removed.

    Argument FlagList must be [] for receive tracing.

    The return value is always 1.

    Examples:

    Only trace messages from a specific process Pid:

    > trace:recv(Session, [{['_',Pid, '_'],[],[]}], []).
    +1

    Only trace messages matching {reply, _}:

    > trace:recv(Session, [{['_','_', {reply,'_'}],[],[]}], []).
    +1

    Only trace messages from other nodes:

    > trace:recv(Session, [{['$1', '_', '_'],[{'=/=','$1',{node}}],[]}], []).
     1

    Note

    A match specification for 'receive' trace can use all guard and body functions except caller, is_seq_trace, get_seq_token, set_seq_token, enable_trace, disable_trace, trace, silent, and process_dump.

    Fails by raising an error exception with an error reason of:

    • badarg - If an argument is invalid.

    • system_limit - If a match specification passed as argument has excessive @@ -1375,10 +1375,10 @@

      send(Session, MatchSpec, FlagList)

      Match Specifications in Erlang in the User's Guide for the ERTS application.

    • true - Enable tracing for all sent messages (from send traced processes). Any match specification is removed.

    • false - Disable tracing for all sent messages. Any match specification -is removed.

    Argument FlagList must be [].

    The return value is always 1.

    Examples:

    Only trace messages to a specific process Pid:

    > trace:send(Session, [{[Pid, '_'],[],[]}], []).
    -1

    Only trace messages matching {reply, _}:

    > trace:send(Session, [{['_', {reply,'_'}],[],[]}], []).
    -1

    Only trace messages sent to the sender itself:

    > trace:send(Session, [{['$1', '_'],[{'=:=','$1',{self}}],[]}], []).
    -1

    Only trace messages sent to other nodes:

    > trace:send(Session, [{['$1', '_'],[{'=/=',{node,'$1'},{node}}],[]}], []).
    +is removed.

    Argument FlagList must be [].

    The return value is always 1.

    Examples:

    Only trace messages to a specific process Pid:

    > trace:send(Session, [{[Pid, '_'],[],[]}], []).
    +1

    Only trace messages matching {reply, _}:

    > trace:send(Session, [{['_', {reply,'_'}],[],[]}], []).
    +1

    Only trace messages sent to the sender itself:

    > trace:send(Session, [{['$1', '_'],[{'=:=','$1',{self}}],[]}], []).
    +1

    Only trace messages sent to other nodes:

    > trace:send(Session, [{['$1', '_'],[{'=/=',{node,'$1'},{node}}],[]}], []).
     1

    Note

    A match specification for send trace can use all guard and body functions except caller.

    Fails by raising an error exception with an error reason of:

    • badarg - If an argument is invalid.

    • system_limit - If a match specification passed as argument has excessive nesting which causes scheduler stack exhaustion for the scheduler that the diff --git a/prs/8803/lib/megaco-4.6/doc/html/megaco.epub b/prs/8803/lib/megaco-4.6/doc/html/megaco.epub index 8e319c396a606..ce03aba1f6bca 100644 Binary files a/prs/8803/lib/megaco-4.6/doc/html/megaco.epub and b/prs/8803/lib/megaco-4.6/doc/html/megaco.epub differ diff --git a/prs/8803/lib/megaco-4.6/doc/html/megaco.html b/prs/8803/lib/megaco-4.6/doc/html/megaco.html index 089b1ee2a834c..d9749e2b2d7be 100644 --- a/prs/8803/lib/megaco-4.6/doc/html/megaco.html +++ b/prs/8803/lib/megaco-4.6/doc/html/megaco.html @@ -3205,7 +3205,7 @@

      print_version_info(Versions)

      Utility function to produce a formated printout of the versions info generated by the versions1 and versions2 functions.

      The function print_version_info/0 uses the result of function version1/0 as -VersionInfo.

      Example:

                 {ok, V} = megaco:versions1(), megaco:format_versions(V).

      +VersionInfo.

      Example:

                 {ok, V} = megaco:versions1(), megaco:format_versions(V).

      diff --git a/prs/8803/lib/megaco-4.6/doc/html/megaco_debug.html b/prs/8803/lib/megaco-4.6/doc/html/megaco_debug.html index 8dca0fd314c18..f2ef274498930 100644 --- a/prs/8803/lib/megaco-4.6/doc/html/megaco_debug.html +++ b/prs/8803/lib/megaco-4.6/doc/html/megaco_debug.html @@ -172,12 +172,12 @@

      can be expected by the different codecs provided by the megaco application.

      The measurement is done by iterating over the decode/encode function for approx 2 seconds per message and counting the number of decodes/encodes.

      Is best run by modifying the meas.sh.skel skeleton script provided by the tool.

      To run it manually do the following:

              % erl -pa <path-megaco-ebin-dir> -pa <path-to-meas-module-dir>
      -        Erlang (BEAM) emulator version 5.6 [source]
      +        Erlang (BEAM) emulator version 5.6 [source]
       
      -        Eshell V12.2  (abort with ^G)
      -        1> megaco_codec_meas:start().
      +        Eshell V12.2  (abort with ^G)
      +        1> megaco_codec_meas:start().
               ...
      -        2> halt().

      or to make it even easier, assuming a measure shall be done on all the codecs + 2> halt().

    or to make it even easier, assuming a measure shall be done on all the codecs (as above):

            % erl -noshell -pa <path-megaco-ebin-dir> \\
                   -pa <path-to-meas-module-dir> \\
                   -s megaco_codec_meas -s init stop

    When run as above (this will take some time), the measurement process is done @@ -199,10 +199,10 @@

    value.

    Both these tools use the message package (time_test.msgs) provided with the tool(s), although it can run on any message package as long as it has the same structure.

    Message package file

    This is simply an erlang compatible text-file with the following structure: -{codec_name(), messages_list()}.

    codec_name() = pretty | compact | ber | per | erlang      (how the messages are encoded)
    -messages_list() = [{message_name(), message()}]
    -message_name() = atom()
    -message() = binary()

    The codec name is the name of the codec with which all messages in the +{codec_name(), messages_list()}.

    codec_name() = pretty | compact | ber | per | erlang      (how the messages are encoded)
    +messages_list() = [{message_name(), message()}]
    +message_name() = atom()
    +message() = binary()

    The codec name is the name of the codec with which all messages in the message_list() has been encoded.

    This file can be exported to a file structure by calling the export_messages function. This can be usefull if a measurement shall be done with an external tool. Exporting the diff --git a/prs/8803/lib/megaco-4.6/doc/html/megaco_encode.html b/prs/8803/lib/megaco-4.6/doc/html/megaco_encode.html index 5367d1f2ac91b..35de3fa075e96 100644 --- a/prs/8803/lib/megaco-4.6/doc/html/megaco_encode.html +++ b/prs/8803/lib/megaco-4.6/doc/html/megaco_encode.html @@ -158,75 +158,75 @@

    format using long keywords and an indentation style like the text examples in the Megaco/H.248 specification).

    Here follows an example of a text message to give a feeling of the difference between the pretty and compact versions of text messages. First the pretty, well -indented version with long keywords:

       MEGACO/1 [124.124.124.222]
    -   Transaction = 9998 {
    -           Context = - {
    -                   ServiceChange = ROOT {
    -                           Services {
    +indented version with long keywords:

       MEGACO/1 [124.124.124.222]
    +   Transaction = 9998 {
    +           Context = - {
    +                   ServiceChange = ROOT {
    +                           Services {
                                        Method = Restart,
                                        ServiceChangeAddress = 55555,
                                        Profile = ResGW/1,
                                        Reason = "901 Cold Boot"
    -                           }
    -                   }
    -           }
    -   }

    Then the compact version without indentation and with short keywords:

    
    +                           }
    +                   }
    +           }
    +   }

    Then the compact version without indentation and with short keywords:

    
        !/1 [124.124.124.222]
        T=9998{C=-{SC=ROOT{SV{MT=RS,AD=55555,PF=ResGW/1,RE="901 Cold Boot"}}}}

    And the programmers view of the same message. First a list of ActionRequest records are constructed and then it is sent with one of the send functions in -the API:

      Prof = #'ServiceChangeProfile'{profileName = "resgw", version = 1},
    -  Parm = #'ServiceChangeParm'{serviceChangeMethod  = restart,
    -                              serviceChangeAddress = {portNumber, 55555},
    +the API:

      Prof = #'ServiceChangeProfile'{profileName = "resgw", version = 1},
    +  Parm = #'ServiceChangeParm'{serviceChangeMethod  = restart,
    +                              serviceChangeAddress = {portNumber, 55555},
                                   serviceChangeReason  = "901 Cold Boot",
    -                              serviceChangeProfile = Prof},
    -  Req = #'ServiceChangeRequest'{terminationID = [?megaco_root_termination_id],
    -                                serviceChangeParms = Parm},
    -  Actions = [#'ActionRequest'{contextId = ?megaco_null_context_id,
    -                              commandRequests = {serviceChangeReq, Req}}],
    -  megaco:call(ConnHandle, Actions, Config).

    And finally a print-out of the entire internal form:

      {'MegacoMessage',
    +                              serviceChangeProfile = Prof},
    +  Req = #'ServiceChangeRequest'{terminationID = [?megaco_root_termination_id],
    +                                serviceChangeParms = Parm},
    +  Actions = [#'ActionRequest'{contextId = ?megaco_null_context_id,
    +                              commandRequests = {serviceChangeReq, Req}}],
    +  megaco:call(ConnHandle, Actions, Config).

    And finally a print-out of the entire internal form:

      {'MegacoMessage',
        asn1_NOVALUE,
    -   {'Message',
    +   {'Message',
         1,
    -    {ip4Address,{'IP4Address', [124,124,124,222], asn1_NOVALUE}},
    -    {transactions,
    -     [
    -      {transactionRequest,
    -       {'TransactionRequest',
    +    {ip4Address,{'IP4Address', [124,124,124,222], asn1_NOVALUE}},
    +    {transactions,
    +     [
    +      {transactionRequest,
    +       {'TransactionRequest',
              9998,
    -         [{'ActionRequest',
    +         [{'ActionRequest',
                0,
                asn1_NOVALUE,
                asn1_NOVALUE,
    -           [
    -            {'CommandRequest',
    -             {serviceChangeReq,
    -              {'ServiceChangeRequest',
    -               [
    -                {megaco_term_id, false, ["root"]}],
    -                {'ServiceChangeParm',
    +           [
    +            {'CommandRequest',
    +             {serviceChangeReq,
    +              {'ServiceChangeRequest',
    +               [
    +                {megaco_term_id, false, ["root"]}],
    +                {'ServiceChangeParm',
                      restart,
    -                 {portNumber, 55555},
    +                 {portNumber, 55555},
                      asn1_NOVALUE,
    -                 {'ServiceChangeProfile', "resgw", version = 1},
    +                 {'ServiceChangeProfile', "resgw", version = 1},
                      "901 MG Cold Boot",
                      asn1_NOVALUE,
                      asn1_NOVALUE,
                      asn1_NOVALUE
    -                }
    -              }
    -             },
    +                }
    +              }
    +             },
                  asn1_NOVALUE,
                  asn1_NOVALUE
    -            }
    -           ]
    -          }
    -         ]
    -       }
    -      }
    -     ]
    -    }
    -   }
    -  }

    The following encoding modules are provided:

    • megaco_pretty_text_encoder - encodes messages into pretty text format, decodes + } + ] + } + ] + } + } + ] + } + } + }

    The following encoding modules are provided:

    • megaco_pretty_text_encoder - encodes messages into pretty text format, decodes both pretty as well as compact text.
    • megaco_compact_text_encoder - encodes messages into compact text format, decodes both pretty as well as compact text.
    • megaco_binary_encoder - encode/decode ASN.1 BER messages. This encoder implements the fastest of the BER encoders/decoders. Recommended binary codec.
    • megaco_ber_encoder - encode/decode ASN.1 BER messages.
    • megaco_per_encoder - encode/decode ASN.1 PER messages. N.B. that this format diff --git a/prs/8803/lib/megaco-4.6/doc/html/megaco_examples.html b/prs/8803/lib/megaco-4.6/doc/html/megaco_examples.html index 2f9a0f1ef785a..c4849746bba2a 100644 --- a/prs/8803/lib/megaco-4.6/doc/html/megaco_examples.html +++ b/prs/8803/lib/megaco-4.6/doc/html/megaco_examples.html @@ -159,10 +159,10 @@

      erl -pa ../../../megaco/ebin -s megaco_filter -s megaco megaco_simple_mg:start().

    or simply 'gmake mg'.

    If you "only" want to start a single MG which tries to connect an MG on a host named "baidarka", you may use one of these functions (instead of the -megaco_simple_mg:start/0 above):

          megaco_simple_mg:start_tcp_text("baidarka", []).
    -      megaco_simple_mg:start_tcp_binary("baidarka", []).
    -      megaco_simple_mg:start_udp_text("baidarka", []).
    -      megaco_simple_mg:start_udp_binary("baidarka", []).

    The -s megaco_filter option to erl implies, the event tracing mechanism to be +megaco_simple_mg:start/0 above):

          megaco_simple_mg:start_tcp_text("baidarka", []).
    +      megaco_simple_mg:start_tcp_binary("baidarka", []).
    +      megaco_simple_mg:start_udp_text("baidarka", []).
    +      megaco_simple_mg:start_udp_binary("baidarka", []).

    The -s megaco_filter option to erl implies, the event tracing mechanism to be enabled and an interactive sequence chart tool to be started. This may be quite useful in order to visualize how your MG interacts with the Megaco/H.248 protocol stack.

    The event traces may alternatively be directed to a file for later analyze. By diff --git a/prs/8803/lib/megaco-4.6/doc/html/megaco_performance.html b/prs/8803/lib/megaco-4.6/doc/html/megaco_performance.html index c1e8fda4776af..f5e6d8cfaf6ee 100644 --- a/prs/8803/lib/megaco-4.6/doc/html/megaco_performance.html +++ b/prs/8803/lib/megaco-4.6/doc/html/megaco_performance.html @@ -162,19 +162,19 @@

    built-in functions.

    The actual encoded messages have been collected in one directory per encoding type, containing one file per encoded message.

    Here follows an example of a text message to give a feeling of the difference between the pretty and compact versions of text messages. First the pretty -printed, well indented version with long keywords:

    MEGACO/1 [124.124.124.222]
    -  Transaction = 9998 {
    -    Context = - {
    -      ServiceChange = ROOT {
    -        Services {
    +printed, well indented version with long keywords:

    MEGACO/1 [124.124.124.222]
    +  Transaction = 9998 {
    +    Context = - {
    +      ServiceChange = ROOT {
    +        Services {
               Method = Restart,
               ServiceChangeAddress = 55555,
               Profile = ResGW/1,
               Reason = "901 MG Cold Boot"
    -        }
    -      }
    -    }
    -  }

    Then the compact text version without indentation and with short keywords:

    !/1 [124.124.124.222] T=9998{
    +        }
    +      }
    +    }
    +  }

    Then the compact text version without indentation and with short keywords:

    !/1 [124.124.124.222] T=9998{
       C=-{SC=ROOT{SV{MT=RS,AD=55555,PF=ResGW/1,RE="901 MG Cold Boot"}}}}

    diff --git a/prs/8803/lib/megaco-4.6/doc/html/megaco_user.html b/prs/8803/lib/megaco-4.6/doc/html/megaco_user.html index f2b584c223ea7..471e300d1a307 100644 --- a/prs/8803/lib/megaco-4.6/doc/html/megaco_user.html +++ b/prs/8803/lib/megaco-4.6/doc/html/megaco_user.html @@ -133,7 +133,7 @@

    list of the callback functions. For example, the handle_connect function takes by default two arguments:

            handle_connect(Handle, Version)

    but if the user_args parameter is set to a longer list, such as [SomePid,SomeTableRef], the callback function is expected to have these (in -this case two) extra arguments last in the argument list:

            handle_connect(Handle, Version, SomePid, SomeTableRef)

    Note

    Must of the functions below has an optional Extra argument (e.g. +this case two) extra arguments last in the argument list:

            handle_connect(Handle, Version, SomePid, SomeTableRef)

    Note

    Must of the functions below has an optional Extra argument (e.g. handle_unexpected_trans/4). The functions which takes this argument will be called if and only if one of the functions receive_message/5 or @@ -144,10 +144,10 @@

    DATA TYPES

    -
    action_request() = #'ActionRequest'{}
    -action_reply() = #'ActionReply'{}
    -error_desc() = #'ErrorDescriptor'{}
    -segment_no() = integer()
    conn_handle() = #megaco_conn_handle{}

    The record initially returned by megaco:connect/4,5. It identifies a "virtual" +

    action_request() = #'ActionRequest'{}
    +action_reply() = #'ActionReply'{}
    +error_desc() = #'ErrorDescriptor'{}
    +segment_no() = integer()
    conn_handle() = #megaco_conn_handle{}

    The record initially returned by megaco:connect/4,5. It identifies a "virtual" connection and may be reused after a reconnect (disconnect + connect).

    protocol_version() = integer()

    Is the actual protocol version. In most cases the protocol version is retrieved from the processed message, but there are exceptions:

    In these cases, the ProtocolVersion default version is obtained from the static diff --git a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia.epub b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia.epub index b2c77f7b63447..59f63360aa5a8 100644 Binary files a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia.epub and b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia.epub differ diff --git a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia.html b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia.html index afc332da9829e..118649e50be00 100644 --- a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia.html +++ b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia.html @@ -166,11 +166,11 @@

    specifies the types of the SNMP keys.

  • attributes. The names of the attributes for the records that are inserted in the table.

  • For information about the complete set of table properties and their details, see mnesia:create_table/2.

    This Reference Manual uses a table of persons to illustrate various examples. -The following record definition is assumed:

    -record(person, {name,
    +The following record definition is assumed:

    -record(person, {name,
                      age = 0,
                      address = unknown,
                      salary = 0,
    -                 children = []}),

    The first record attribute is the primary key, or key for short.

    The function descriptions are sorted in alphabetical order. It is recommended to + children = []}),

    The first record attribute is the primary key, or key for short.

    The function descriptions are sorted in alphabetical order. It is recommended to start to read about mnesia:create_table/2, mnesia:lock/2, and mnesia:activity/4 before you continue and learn about the rest.

    Writing or deleting in transaction-context creates a local copy of each modified record during the transaction. During iteration, that is, mnesia:foldl/4, @@ -2865,7 +2865,7 @@

    change_table_copy_type(Tab, Node, To)

    -

    Change the storage type of a table.

    For example:

    mnesia:change_table_copy_type(person, node(), disc_copies)

    Transforms the person table from a RAM table into a disc-based table at +

    Change the storage type of a table.

    For example:

    mnesia:change_table_copy_type(person, node(), disc_copies)

    Transforms the person table from a RAM table into a disc-based table at Node.

    This function can also be used to change the storage type of the table named schema. The schema table can only have ram_copies or disc_copies as the storage type. If the storage type of the schema is ram_copies, no other table @@ -3116,22 +3116,22 @@

    create_table(Name, Opts)

    back end storage. Backend can currently be ets or dets. Properties is a list of options sent to the back end storage during table creation. Properties cannot contain properties already used by Mnesia, such as type -or named_table.

    For example:

    mnesia:create_table(table, [{ram_copies, [node()]}, {disc_only_copies, nodes()},
    -       {storage_properties,
    -        [{ets, [compressed]}, {dets, [{auto_save, 5000}]} ]}])
  • {type, Type}, where Type must be either of the atoms set, ordered_set, +or named_table.

    For example:

    mnesia:create_table(table, [{ram_copies, [node()]}, {disc_only_copies, nodes()},
    +       {storage_properties,
    +        [{ets, [compressed]}, {dets, [{auto_save, 5000}]} ]}])
  • {type, Type}, where Type must be either of the atoms set, ordered_set, or bag. Default is set. In a set, all records have unique keys. In a bag, several records can have the same key, but the record content is unique. If a non-unique record is stored, the old conflicting records are overwritten.

    Notice that currently ordered_set is not supported for disc_only_copies.

  • {local_content, Bool}, where Bool is true or false. Default is false.

  • For example, the following call creates the person table (defined earlier) and -replicates it on two nodes:

    mnesia:create_table(person,
    -    [{ram_copies, [N1, N2]},
    -     {attributes, record_info(fields, person)}]).

    If it is required that Mnesia must build and maintain an extra index table on +replicates it on two nodes:

    mnesia:create_table(person,
    +    [{ram_copies, [N1, N2]},
    +     {attributes, record_info(fields, person)}]).

    If it is required that Mnesia must build and maintain an extra index table on attribute address of all the person records that are inserted in the table, -the following code would be issued:

    mnesia:create_table(person,
    -    [{ram_copies, [N1, N2]},
    -     {index, [address]},
    -     {attributes, record_info(fields, person)}]).

    The specification of index and attributes can be hard-coded as +the following code would be issued:

    mnesia:create_table(person,
    +    [{ram_copies, [N1, N2]},
    +     {index, [address]},
    +     {attributes, record_info(fields, person)}]).

    The specification of index and attributes can be hard-coded as {index, [2]} and {attributes, [name, age, address, salary, children]}, respectively.

    mnesia:create_table/2 writes records into the table schema. This function, and all other schema manipulation functions, are implemented with the normal @@ -5381,10 +5381,10 @@

    select(Tab, Spec, LockKind)

    argument. Default is read. The return value depends on MatchSpec.

    Notice that for best performance, select is to be used before any modifying operations are done on that table in the same transaction. That is, do not use write or delete before a select.

    In its simplest forms, the match_spec look as follows:

    • MatchSpec = [MatchFunction]
    • MatchFunction = {MatchHead, [Guard], [Result]}
    • MatchHead = tuple() | record()

    • Guard = {"Guardtest name", ...}
    • Result = "Term construct"

    For a complete description of select, see the ERTS -User's Guide and the ets manual page in STDLIB.

    For example, to find the names of all male persons older than 30 in table Tab:

    MatchHead = #person{name='$1', sex=male, age='$2', _='_'},
    -Guard = {'>', '$2', 30},
    +User's Guide and the ets manual page in STDLIB.

    For example, to find the names of all male persons older than 30 in table Tab:

    MatchHead = #person{name='$1', sex=male, age='$2', _='_'},
    +Guard = {'>', '$2', 30},
     Result = '$1',
    -mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),
    +
    mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),
    @@ -5679,9 +5679,9 @@

    snmp_open_table(Tab, Snmp)

    specified as a tuple of atoms describing the types. The only significant type is fix_string. This means that a string has a fixed size.

    For example, the following causes table person to be ordered as an SNMP table:

    mnesia:snmp_open_table(person, [{key, string}])

    Consider the following schema for a table of company employees. Each employee is identified by department number and name. The other table column stores the -telephone number:

    mnesia:create_table(employee,
    -    [{snmp, [{key, {integer, string}}]},
    -     {attributes, record_info(fields, employees)}]),

    The corresponding SNMP table would have three columns: department, name, and +telephone number:

    mnesia:create_table(employee,
    +    [{snmp, [{key, {integer, string}}]},
    +     {attributes, record_info(fields, employees)}]),

    The corresponding SNMP table would have three columns: department, name, and telno.

    An option is to have table columns that are not visible through the SNMP protocol. These columns must be the last columns of the table. In the previous example, the SNMP table could have columns department and name only. The @@ -6284,17 +6284,17 @@

    transaction(Fun, Args, Retries)

    transaction is terminated and the function transaction/1 returns the tuple {aborted, Reason}.

    If all is going well, {atomic, ResultOfFun} is returned, where ResultOfFun is the value of the last expression in Fun.

    A function that adds a family to the database can be written as follows if there -is a structure {family, Father, Mother, ChildrenList}:

    add_family({family, F, M, Children}) ->
    -    ChildOids = lists:map(fun oid/1, Children),
    -    Trans = fun() ->
    -        mnesia:write(F#person{children = ChildOids}),
    -        mnesia:write(M#person{children = ChildOids}),
    -        Write = fun(Child) -> mnesia:write(Child) end,
    -        lists:foreach(Write, Children)
    +is a structure {family, Father, Mother, ChildrenList}:

    add_family({family, F, M, Children}) ->
    +    ChildOids = lists:map(fun oid/1, Children),
    +    Trans = fun() ->
    +        mnesia:write(F#person{children = ChildOids}),
    +        mnesia:write(M#person{children = ChildOids}),
    +        Write = fun(Child) -> mnesia:write(Child) end,
    +        lists:foreach(Write, Children)
         end,
    -    mnesia:transaction(Trans).
    +    mnesia:transaction(Trans).
     
    -oid(Rec) -> {element(1, Rec), element(2, Rec)}.

    This code adds a set of people to the database. Running this code within one +oid(Rec) -> {element(1, Rec), element(2, Rec)}.

    This code adds a set of people to the database. Running this code within one transaction ensures that either the whole family is added to the database, or the whole transaction terminates. For example, if the last child is badly formatted, or the executing process terminates because of an 'EXIT' signal @@ -6302,17 +6302,17 @@

    transaction(Fun, Args, Retries)

    where half a family is added can never occur.

    It is also useful to update the database within a transaction if several processes concurrently update the same records. For example, the function raise(Name, Amount), which adds Amount to the salary field of a person, is -to be implemented as follows:

    raise(Name, Amount) ->
    -    mnesia:transaction(fun() ->
    -        case mnesia:wread({person, Name}) of
    -            [P] ->
    +to be implemented as follows:

    raise(Name, Amount) ->
    +    mnesia:transaction(fun() ->
    +        case mnesia:wread({person, Name}) of
    +            [P] ->
                     Salary = Amount + P#person.salary,
    -                P2 = P#person{salary = Salary},
    -                mnesia:write(P2);
    +                P2 = P#person{salary = Salary},
    +                mnesia:write(P2);
                 _ ->
    -                mnesia:abort("No such person")
    +                mnesia:abort("No such person")
             end
    -    end).

    When this function executes within a transaction, several processes running on + end).

    When this function executes within a transaction, several processes running on different nodes can concurrently execute the function raise/2 without interfering with each other.

    Since Mnesia detects deadlocks, a transaction can be restarted any number of times and therefore the Fun shall not have any side effects such as waiting diff --git a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_app_a.html b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_app_a.html index 57fbca3c456ea..2565b03cf7a78 100644 --- a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_app_a.html +++ b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_app_a.html @@ -159,11 +159,11 @@

    %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --module(mnesia_backup). +-module(mnesia_backup). --include_lib("kernel/include/file.hrl"). +-include_lib("kernel/include/file.hrl"). --export([ +-export([ %% Write access open_write/1, write/2, @@ -174,105 +174,105 @@

    open_read/1, read/1, close_read/1 - ]). + ]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Backup callback interface --record(backup, {tmp_file, file, file_desc}). +-record(backup, {tmp_file, file, file_desc}). %% Opens backup media for write %% %% Returns {ok, OpaqueData} or {error, Reason} -open_write(OpaqueData) -> +open_write(OpaqueData) -> File = OpaqueData, - Tmp = lists:concat([File,".BUPTMP"]), - file:delete(Tmp), - case disk_log:open([{name, make_ref()}, - {file, Tmp}, - {repair, false}, - {linkto, self()}]) of - {ok, Fd} -> - {ok, #backup{tmp_file = Tmp, file = File, file_desc = Fd}}; - {error, Reason} -> - {error, Reason} + Tmp = lists:concat([File,".BUPTMP"]), + file:delete(Tmp), + case disk_log:open([{name, make_ref()}, + {file, Tmp}, + {repair, false}, + {linkto, self()}]) of + {ok, Fd} -> + {ok, #backup{tmp_file = Tmp, file = File, file_desc = Fd}}; + {error, Reason} -> + {error, Reason} end. %% Writes BackupItems to the backup media %% %% Returns {ok, OpaqueData} or {error, Reason} -write(OpaqueData, BackupItems) -> +write(OpaqueData, BackupItems) -> B = OpaqueData, - case disk_log:log_terms(B#backup.file_desc, BackupItems) of + case disk_log:log_terms(B#backup.file_desc, BackupItems) of ok -> - {ok, B}; - {error, Reason} -> - abort_write(B), - {error, Reason} + {ok, B}; + {error, Reason} -> + abort_write(B), + {error, Reason} end. %% Closes the backup media after a successful backup %% %% Returns {ok, ReturnValueToUser} or {error, Reason} -commit_write(OpaqueData) -> +commit_write(OpaqueData) -> B = OpaqueData, - case disk_log:sync(B#backup.file_desc) of + case disk_log:sync(B#backup.file_desc) of ok -> - case disk_log:close(B#backup.file_desc) of + case disk_log:close(B#backup.file_desc) of ok -> - file:delete(B#backup.file), - case file:rename(B#backup.tmp_file, B#backup.file) of + file:delete(B#backup.file), + case file:rename(B#backup.tmp_file, B#backup.file) of ok -> - {ok, B#backup.file}; - {error, Reason} -> - {error, Reason} + {ok, B#backup.file}; + {error, Reason} -> + {error, Reason} end; - {error, Reason} -> - {error, Reason} + {error, Reason} -> + {error, Reason} end; - {error, Reason} -> - {error, Reason} + {error, Reason} -> + {error, Reason} end. %% Closes the backup media after an interrupted backup %% %% Returns {ok, ReturnValueToUser} or {error, Reason} -abort_write(BackupRef) -> - Res = disk_log:close(BackupRef#backup.file_desc), - file:delete(BackupRef#backup.tmp_file), +abort_write(BackupRef) -> + Res = disk_log:close(BackupRef#backup.file_desc), + file:delete(BackupRef#backup.tmp_file), case Res of ok -> - {ok, BackupRef#backup.file}; - {error, Reason} -> - {error, Reason} + {ok, BackupRef#backup.file}; + {error, Reason} -> + {error, Reason} end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Restore callback interface --record(restore, {file, file_desc, cont}). +-record(restore, {file, file_desc, cont}). %% Opens backup media for read %% %% Returns {ok, OpaqueData} or {error, Reason} -open_read(OpaqueData) -> +open_read(OpaqueData) -> File = OpaqueData, - case file:read_file_info(File) of - {error, Reason} -> - {error, Reason}; + case file:read_file_info(File) of + {error, Reason} -> + {error, Reason}; _FileInfo -> %% file exists - case disk_log:open([{file, File}, - {name, make_ref()}, - {repair, false}, - {mode, read_only}, - {linkto, self()}]) of - {ok, Fd} -> - {ok, #restore{file = File, file_desc = Fd, cont = start}}; - {repaired, Fd, _, {badbytes, 0}} -> - {ok, #restore{file = File, file_desc = Fd, cont = start}}; - {repaired, Fd, _, _} -> - {ok, #restore{file = File, file_desc = Fd, cont = start}}; - {error, Reason} -> - {error, Reason} + case disk_log:open([{file, File}, + {name, make_ref()}, + {repair, false}, + {mode, read_only}, + {linkto, self()}]) of + {ok, Fd} -> + {ok, #restore{file = File, file_desc = Fd, cont = start}}; + {repaired, Fd, _, {badbytes, 0}} -> + {ok, #restore{file = File, file_desc = Fd, cont = start}}; + {repaired, Fd, _, _} -> + {ok, #restore{file = File, file_desc = Fd, cont = start}}; + {error, Reason} -> + {error, Reason} end end. @@ -281,30 +281,30 @@

    %% Returns {ok, OpaqueData, BackupItems} or {error, Reason} %% %% BackupItems == [] is interpreted as eof -read(OpaqueData) -> +read(OpaqueData) -> R = OpaqueData, Fd = R#restore.file_desc, - case disk_log:chunk(Fd, R#restore.cont) of - {error, Reason} -> - {error, {"Possibly truncated", Reason}}; + case disk_log:chunk(Fd, R#restore.cont) of + {error, Reason} -> + {error, {"Possibly truncated", Reason}}; eof -> - {ok, R, []}; - {Cont, []} -> - read(R#restore{cont = Cont}); - {Cont, BackupItems, _BadBytes} -> - {ok, R#restore{cont = Cont}, BackupItems}; - {Cont, BackupItems} -> - {ok, R#restore{cont = Cont}, BackupItems} + {ok, R, []}; + {Cont, []} -> + read(R#restore{cont = Cont}); + {Cont, BackupItems, _BadBytes} -> + {ok, R#restore{cont = Cont}, BackupItems}; + {Cont, BackupItems} -> + {ok, R#restore{cont = Cont}, BackupItems} end. %% Closes the backup media after restore %% %% Returns {ok, ReturnValueToUser} or {error, Reason} -close_read(OpaqueData) -> +close_read(OpaqueData) -> R = OpaqueData, - case disk_log:close(R#restore.file_desc) of - ok -> {ok, R#restore.file}; - {error, Reason} -> {error, Reason} + case disk_log:close(R#restore.file_desc) of + ok -> {ok, R#restore.file}; + {error, Reason} -> {error, Reason} end.

    diff --git a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_app_b.html b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_app_b.html index 0f7094e3cfae8..10f567207d285 100644 --- a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_app_b.html +++ b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_app_b.html @@ -131,10 +131,10 @@

    mnesia_access Callback Behavior

    -
    -module(mnesia_frag).
    +
    -module(mnesia_frag).
     
     %% Callback functions when accessed within an activity
    --export([
    +-export([
     	 lock/4,
     	 write/5, delete/5, delete_object/5,
     	 read/5, match_object/5, all_keys/4,
    @@ -143,230 +143,230 @@ 

    foldl/6, foldr/6, table_info/4, first/3, next/4, prev/4, last/3, clear_table/4 - ]).

    %% Callback functions which provides transparent
    +       ]).
    %% Callback functions which provides transparent
     %% access of fragmented tables from any activity
     %% access context.
     
    -lock(ActivityId, Opaque, {table , Tab}, LockKind) ->
    -    case frag_names(Tab) of
    -	[Tab] ->
    -	    mnesia:lock(ActivityId, Opaque, {table, Tab}, LockKind);
    +lock(ActivityId, Opaque, {table , Tab}, LockKind) ->
    +    case frag_names(Tab) of
    +	[Tab] ->
    +	    mnesia:lock(ActivityId, Opaque, {table, Tab}, LockKind);
     	Frags ->
    -	    DeepNs = [mnesia:lock(ActivityId, Opaque, {table, F}, LockKind) ||
    -			 F <- Frags],
    -	    mnesia_lib:uniq(lists:append(DeepNs))
    +	    DeepNs = [mnesia:lock(ActivityId, Opaque, {table, F}, LockKind) ||
    +			 F <- Frags],
    +	    mnesia_lib:uniq(lists:append(DeepNs))
         end;
     
    -lock(ActivityId, Opaque, LockItem, LockKind) ->
    -    mnesia:lock(ActivityId, Opaque, LockItem, LockKind).
    +lock(ActivityId, Opaque, LockItem, LockKind) ->
    +    mnesia:lock(ActivityId, Opaque, LockItem, LockKind).
     
    -write(ActivityId, Opaque, Tab, Rec, LockKind) ->
    -    Frag = record_to_frag_name(Tab, Rec),
    -    mnesia:write(ActivityId, Opaque, Frag, Rec, LockKind).
    +write(ActivityId, Opaque, Tab, Rec, LockKind) ->
    +    Frag = record_to_frag_name(Tab, Rec),
    +    mnesia:write(ActivityId, Opaque, Frag, Rec, LockKind).
     
    -delete(ActivityId, Opaque, Tab, Key, LockKind) ->
    -    Frag = key_to_frag_name(Tab, Key),
    -    mnesia:delete(ActivityId, Opaque, Frag, Key, LockKind).
    +delete(ActivityId, Opaque, Tab, Key, LockKind) ->
    +    Frag = key_to_frag_name(Tab, Key),
    +    mnesia:delete(ActivityId, Opaque, Frag, Key, LockKind).
     
    -delete_object(ActivityId, Opaque, Tab, Rec, LockKind) ->
    -    Frag = record_to_frag_name(Tab, Rec),
    -    mnesia:delete_object(ActivityId, Opaque, Frag, Rec, LockKind).
    +delete_object(ActivityId, Opaque, Tab, Rec, LockKind) ->
    +    Frag = record_to_frag_name(Tab, Rec),
    +    mnesia:delete_object(ActivityId, Opaque, Frag, Rec, LockKind).
     
    -read(ActivityId, Opaque, Tab, Key, LockKind) ->
    -    Frag = key_to_frag_name(Tab, Key),
    -    mnesia:read(ActivityId, Opaque, Frag, Key, LockKind).
    +read(ActivityId, Opaque, Tab, Key, LockKind) ->
    +    Frag = key_to_frag_name(Tab, Key),
    +    mnesia:read(ActivityId, Opaque, Frag, Key, LockKind).
     
    -match_object(ActivityId, Opaque, Tab, HeadPat, LockKind) ->
    -    MatchSpec = [{HeadPat, [], ['$_']}],
    -    select(ActivityId, Opaque, Tab, MatchSpec, LockKind).
    +match_object(ActivityId, Opaque, Tab, HeadPat, LockKind) ->
    +    MatchSpec = [{HeadPat, [], ['$_']}],
    +    select(ActivityId, Opaque, Tab, MatchSpec, LockKind).
     
    -select(ActivityId, Opaque, Tab, MatchSpec, LockKind) ->
    -    do_select(ActivityId, Opaque, Tab, MatchSpec, LockKind).
    +select(ActivityId, Opaque, Tab, MatchSpec, LockKind) ->
    +    do_select(ActivityId, Opaque, Tab, MatchSpec, LockKind).
     
     
    -select(ActivityId, Opaque, Tab, MatchSpec, Limit, LockKind) ->
    -    init_select(ActivityId, Opaque, Tab, MatchSpec, Limit, LockKind).
    +select(ActivityId, Opaque, Tab, MatchSpec, Limit, LockKind) ->
    +    init_select(ActivityId, Opaque, Tab, MatchSpec, Limit, LockKind).
     
     
    -all_keys(ActivityId, Opaque, Tab, LockKind) ->
    -    Match = [mnesia:all_keys(ActivityId, Opaque, Frag, LockKind)
    -	     || Frag <- frag_names(Tab)],
    -    lists:append(Match).
    +all_keys(ActivityId, Opaque, Tab, LockKind) ->
    +    Match = [mnesia:all_keys(ActivityId, Opaque, Frag, LockKind)
    +	     || Frag <- frag_names(Tab)],
    +    lists:append(Match).
     
    -clear_table(ActivityId, Opaque, Tab, Obj) ->
    -    [mnesia:clear_table(ActivityId, Opaque, Frag, Obj)  || Frag <- frag_names(Tab)],
    +clear_table(ActivityId, Opaque, Tab, Obj) ->
    +    [mnesia:clear_table(ActivityId, Opaque, Frag, Obj)  || Frag <- frag_names(Tab)],
         ok.
     
    -index_match_object(ActivityId, Opaque, Tab, Pat, Attr, LockKind) ->
    +index_match_object(ActivityId, Opaque, Tab, Pat, Attr, LockKind) ->
         Match =
    -	[mnesia:index_match_object(ActivityId, Opaque, Frag, Pat, Attr, LockKind)
    -	 || Frag <- frag_names(Tab)],
    -    lists:append(Match).
    +	[mnesia:index_match_object(ActivityId, Opaque, Frag, Pat, Attr, LockKind)
    +	 || Frag <- frag_names(Tab)],
    +    lists:append(Match).
     
    -index_read(ActivityId, Opaque, Tab, Key, Attr, LockKind) ->
    +index_read(ActivityId, Opaque, Tab, Key, Attr, LockKind) ->
         Match =
    -	[mnesia:index_read(ActivityId, Opaque, Frag, Key, Attr, LockKind)
    -	     || Frag <- frag_names(Tab)],
    -    lists:append(Match).
    +	[mnesia:index_read(ActivityId, Opaque, Frag, Key, Attr, LockKind)
    +	     || Frag <- frag_names(Tab)],
    +    lists:append(Match).
     
    -foldl(ActivityId, Opaque, Fun, Acc, Tab, LockKind) ->
    -    Fun2 = fun(Frag, A) ->
    -		   mnesia:foldl(ActivityId, Opaque, Fun, A, Frag, LockKind)
    +foldl(ActivityId, Opaque, Fun, Acc, Tab, LockKind) ->
    +    Fun2 = fun(Frag, A) ->
    +		   mnesia:foldl(ActivityId, Opaque, Fun, A, Frag, LockKind)
     	   end,
    -    lists:foldl(Fun2, Acc, frag_names(Tab)).
    +    lists:foldl(Fun2, Acc, frag_names(Tab)).
     
    -foldr(ActivityId, Opaque, Fun, Acc, Tab, LockKind) ->
    -    Fun2 = fun(Frag, A) ->
    -		   mnesia:foldr(ActivityId, Opaque, Fun, A, Frag, LockKind)
    +foldr(ActivityId, Opaque, Fun, Acc, Tab, LockKind) ->
    +    Fun2 = fun(Frag, A) ->
    +		   mnesia:foldr(ActivityId, Opaque, Fun, A, Frag, LockKind)
     	   end,
    -    lists:foldr(Fun2, Acc, frag_names(Tab)).
    +    lists:foldr(Fun2, Acc, frag_names(Tab)).
     
    -table_info(ActivityId, Opaque, {Tab, Key}, Item) ->
    -    Frag = key_to_frag_name(Tab, Key),
    -    table_info2(ActivityId, Opaque, Tab, Frag, Item);
    -table_info(ActivityId, Opaque, Tab, Item) ->
    -    table_info2(ActivityId, Opaque, Tab, Tab, Item).
    +table_info(ActivityId, Opaque, {Tab, Key}, Item) ->
    +    Frag = key_to_frag_name(Tab, Key),
    +    table_info2(ActivityId, Opaque, Tab, Frag, Item);
    +table_info(ActivityId, Opaque, Tab, Item) ->
    +    table_info2(ActivityId, Opaque, Tab, Tab, Item).
     
    -table_info2(ActivityId, Opaque, Tab, Frag, Item) ->
    +table_info2(ActivityId, Opaque, Tab, Frag, Item) ->
         case Item of
     	size ->
    -	    SumFun = fun({_, Size}, Acc) -> Acc + Size end,
    -	    lists:foldl(SumFun, 0, frag_size(ActivityId, Opaque, Tab));
    +	    SumFun = fun({_, Size}, Acc) -> Acc + Size end,
    +	    lists:foldl(SumFun, 0, frag_size(ActivityId, Opaque, Tab));
     	memory ->
    -	    SumFun = fun({_, Size}, Acc) -> Acc + Size end,
    -	    lists:foldl(SumFun, 0, frag_memory(ActivityId, Opaque, Tab));
    +	    SumFun = fun({_, Size}, Acc) -> Acc + Size end,
    +	    lists:foldl(SumFun, 0, frag_memory(ActivityId, Opaque, Tab));
     	base_table ->
    -	    lookup_prop(Tab, base_table);
    +	    lookup_prop(Tab, base_table);
     	node_pool ->
    -	    lookup_prop(Tab, node_pool);
    +	    lookup_prop(Tab, node_pool);
     	n_fragments ->
    -	    FH = lookup_frag_hash(Tab),
    +	    FH = lookup_frag_hash(Tab),
     	    FH#frag_state.n_fragments;
     	foreign_key ->
    -	    FH = lookup_frag_hash(Tab),
    +	    FH = lookup_frag_hash(Tab),
     	    FH#frag_state.foreign_key;
     	foreigners ->
    -	    lookup_foreigners(Tab);
    +	    lookup_foreigners(Tab);
     	n_ram_copies ->
    -	    length(val({Tab, ram_copies}));
    +	    length(val({Tab, ram_copies}));
     	n_disc_copies ->
    -	    length(val({Tab, disc_copies}));
    +	    length(val({Tab, disc_copies}));
     	n_disc_only_copies ->
    -	    length(val({Tab, disc_only_copies}));
    +	    length(val({Tab, disc_only_copies}));
     	n_external_copies ->
    -	    length(val({Tab, external_copies}));
    +	    length(val({Tab, external_copies}));
     
     	frag_names ->
    -	    frag_names(Tab);
    +	    frag_names(Tab);
     	frag_dist ->
    -	    frag_dist(Tab);
    +	    frag_dist(Tab);
     	frag_size ->
    -	    frag_size(ActivityId, Opaque, Tab);
    +	    frag_size(ActivityId, Opaque, Tab);
     	frag_memory ->
    -	    frag_memory(ActivityId, Opaque, Tab);
    +	    frag_memory(ActivityId, Opaque, Tab);
     	_ ->
    -	    mnesia:table_info(ActivityId, Opaque, Frag, Item)
    +	    mnesia:table_info(ActivityId, Opaque, Frag, Item)
         end.
     
    -first(ActivityId, Opaque, Tab) ->
    -    case ?catch_val({Tab, frag_hash}) of
    -	{'EXIT', _} ->
    -	    mnesia:first(ActivityId, Opaque, Tab);
    +first(ActivityId, Opaque, Tab) ->
    +    case ?catch_val({Tab, frag_hash}) of
    +	{'EXIT', _} ->
    +	    mnesia:first(ActivityId, Opaque, Tab);
     	FH ->
     	    FirstFrag = Tab,
    -	    case mnesia:first(ActivityId, Opaque, FirstFrag) of
    +	    case mnesia:first(ActivityId, Opaque, FirstFrag) of
     		'$end_of_table' ->
    -		    search_first(ActivityId, Opaque, Tab, 1, FH);
    +		    search_first(ActivityId, Opaque, Tab, 1, FH);
     		Next ->
     		    Next
     	    end
         end.
     
    -search_first(ActivityId, Opaque, Tab, N, FH) when N < FH#frag_state.n_fragments ->
    +search_first(ActivityId, Opaque, Tab, N, FH) when N < FH#frag_state.n_fragments ->
         NextN = N + 1,
    -    NextFrag = n_to_frag_name(Tab, NextN),
    -    case mnesia:first(ActivityId, Opaque, NextFrag) of
    +    NextFrag = n_to_frag_name(Tab, NextN),
    +    case mnesia:first(ActivityId, Opaque, NextFrag) of
     	'$end_of_table' ->
    -	    search_first(ActivityId, Opaque, Tab, NextN, FH);
    +	    search_first(ActivityId, Opaque, Tab, NextN, FH);
     	Next ->
     	    Next
         end;
    -search_first(_ActivityId, _Opaque, _Tab, _N, _FH) ->
    +search_first(_ActivityId, _Opaque, _Tab, _N, _FH) ->
         '$end_of_table'.
     
    -last(ActivityId, Opaque, Tab) ->
    -    case ?catch_val({Tab, frag_hash}) of
    -	{'EXIT', _} ->
    -	    mnesia:last(ActivityId, Opaque, Tab);
    +last(ActivityId, Opaque, Tab) ->
    +    case ?catch_val({Tab, frag_hash}) of
    +	{'EXIT', _} ->
    +	    mnesia:last(ActivityId, Opaque, Tab);
     	FH ->
     	    LastN = FH#frag_state.n_fragments,
    -	    search_last(ActivityId, Opaque, Tab, LastN, FH)
    +	    search_last(ActivityId, Opaque, Tab, LastN, FH)
         end.
     
    -search_last(ActivityId, Opaque, Tab, N, FH) when N >= 1 ->
    -    Frag = n_to_frag_name(Tab, N),
    -    case mnesia:last(ActivityId, Opaque, Frag) of
    +search_last(ActivityId, Opaque, Tab, N, FH) when N >= 1 ->
    +    Frag = n_to_frag_name(Tab, N),
    +    case mnesia:last(ActivityId, Opaque, Frag) of
     	'$end_of_table' ->
     	    PrevN = N - 1,
    -	    search_last(ActivityId, Opaque, Tab, PrevN, FH);
    +	    search_last(ActivityId, Opaque, Tab, PrevN, FH);
     	Prev ->
     	    Prev
         end;
    -search_last(_ActivityId, _Opaque, _Tab, _N, _FH) ->
    +search_last(_ActivityId, _Opaque, _Tab, _N, _FH) ->
         '$end_of_table'.
     
    -prev(ActivityId, Opaque, Tab, Key) ->
    -    case ?catch_val({Tab, frag_hash}) of
    -	{'EXIT', _} ->
    -	    mnesia:prev(ActivityId, Opaque, Tab, Key);
    +prev(ActivityId, Opaque, Tab, Key) ->
    +    case ?catch_val({Tab, frag_hash}) of
    +	{'EXIT', _} ->
    +	    mnesia:prev(ActivityId, Opaque, Tab, Key);
     	FH ->
    -	    N = key_to_n(FH, Key),
    -	    Frag = n_to_frag_name(Tab, N),
    -	    case mnesia:prev(ActivityId, Opaque, Frag, Key) of
    +	    N = key_to_n(FH, Key),
    +	    Frag = n_to_frag_name(Tab, N),
    +	    case mnesia:prev(ActivityId, Opaque, Frag, Key) of
     		'$end_of_table' ->
    -		    search_prev(ActivityId, Opaque, Tab, N);
    +		    search_prev(ActivityId, Opaque, Tab, N);
     		Prev ->
     		    Prev
     	    end
         end.
     
    -search_prev(ActivityId, Opaque, Tab, N) when N > 1 ->
    +search_prev(ActivityId, Opaque, Tab, N) when N > 1 ->
         PrevN = N - 1,
    -    PrevFrag = n_to_frag_name(Tab, PrevN),
    -    case mnesia:last(ActivityId, Opaque, PrevFrag) of
    +    PrevFrag = n_to_frag_name(Tab, PrevN),
    +    case mnesia:last(ActivityId, Opaque, PrevFrag) of
     	'$end_of_table' ->
    -	    search_prev(ActivityId, Opaque, Tab, PrevN);
    +	    search_prev(ActivityId, Opaque, Tab, PrevN);
     	Prev ->
     	    Prev
         end;
    -search_prev(_ActivityId, _Opaque, _Tab, _N) ->
    +search_prev(_ActivityId, _Opaque, _Tab, _N) ->
         '$end_of_table'.
     
    -next(ActivityId, Opaque, Tab, Key) ->
    -    case ?catch_val({Tab, frag_hash}) of
    -	{'EXIT', _} ->
    -	    mnesia:next(ActivityId, Opaque, Tab, Key);
    +next(ActivityId, Opaque, Tab, Key) ->
    +    case ?catch_val({Tab, frag_hash}) of
    +	{'EXIT', _} ->
    +	    mnesia:next(ActivityId, Opaque, Tab, Key);
     	FH ->
    -	    N = key_to_n(FH, Key),
    -	    Frag = n_to_frag_name(Tab, N),
    -	    case mnesia:next(ActivityId, Opaque, Frag, Key) of
    +	    N = key_to_n(FH, Key),
    +	    Frag = n_to_frag_name(Tab, N),
    +	    case mnesia:next(ActivityId, Opaque, Frag, Key) of
     		'$end_of_table' ->
    -		    search_next(ActivityId, Opaque, Tab, N, FH);
    +		    search_next(ActivityId, Opaque, Tab, N, FH);
     		Prev ->
     		    Prev
     	    end
         end.
     
    -search_next(ActivityId, Opaque, Tab, N, FH) when N < FH#frag_state.n_fragments ->
    +search_next(ActivityId, Opaque, Tab, N, FH) when N < FH#frag_state.n_fragments ->
         NextN = N + 1,
    -    NextFrag = n_to_frag_name(Tab, NextN),
    -    case mnesia:first(ActivityId, Opaque, NextFrag) of
    +    NextFrag = n_to_frag_name(Tab, NextN),
    +    case mnesia:first(ActivityId, Opaque, NextFrag) of
     	'$end_of_table' ->
    -	    search_next(ActivityId, Opaque, Tab, NextN, FH);
    +	    search_next(ActivityId, Opaque, Tab, NextN, FH);
     	Next ->
     	    Next
         end;
    -search_next(_ActivityId, _Opaque, _Tab, _N, _FH) ->
    +search_next(_ActivityId, _Opaque, _Tab, _N, _FH) ->
         '$end_of_table'.
    diff --git a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_app_c.html b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_app_c.html index fd3c26d611de1..00a36fdd8dd75 100644 --- a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_app_c.html +++ b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_app_c.html @@ -131,136 +131,136 @@

    mnesia_frag_hash Callback Behavior

    -
    -module(mnesia_frag_hash).
    --compile([{nowarn_deprecated_function, [{erlang,phash,2}]}]).
    +
    -module(mnesia_frag_hash).
    +-compile([{nowarn_deprecated_function, [{erlang,phash,2}]}]).
     
     %% Fragmented Table Hashing callback functions
    --export([
    +-export([
     	 init_state/2,
     	 add_frag/1,
     	 del_frag/1,
     	 key_to_frag_number/2,
     	 match_spec_to_frag_numbers/2
    -	]).
    -record(hash_state,
    -	{n_fragments,
    +	]).
    -record(hash_state,
    +	{n_fragments,
     	 next_n_to_split,
     	 n_doubles,
    -	 function}).
    +	 function}).
     
     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    --spec init_state(Tab, State) -> NewState when
    -      Tab :: atom(),
    -      State :: term(),
    -      NewState :: term().
    -init_state(_Tab, State) when State == undefined ->
    -    #hash_state{n_fragments     = 1,
    +-spec init_state(Tab, State) -> NewState when
    +      Tab :: atom(),
    +      State :: term(),
    +      NewState :: term().
    +init_state(_Tab, State) when State == undefined ->
    +    #hash_state{n_fragments     = 1,
     		next_n_to_split = 1,
     		n_doubles       = 0,
    -		function        = phash2}.
    +		function        = phash2}.
     
    -convert_old_state({hash_state, N, P, L}) ->
    -    #hash_state{n_fragments     = N,
    +convert_old_state({hash_state, N, P, L}) ->
    +    #hash_state{n_fragments     = N,
     		next_n_to_split = P,
     		n_doubles       = L,
    -		function        = phash}.
    +		function        = phash}.
     
     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    --spec add_frag(State :: term()) -> {NewState, IterFrags, AdditionalLockFrags} when
    -      NewState :: term(),
    -      IterFrags :: [integer()],
    -      AdditionalLockFrags :: [integer()].
    -add_frag(#hash_state{next_n_to_split = SplitN, n_doubles = L, n_fragments = N} = State) ->
    +-spec add_frag(State :: term()) -> {NewState, IterFrags, AdditionalLockFrags} when
    +      NewState :: term(),
    +      IterFrags :: [integer()],
    +      AdditionalLockFrags :: [integer()].
    +add_frag(#hash_state{next_n_to_split = SplitN, n_doubles = L, n_fragments = N} = State) ->
         P = SplitN + 1,
         NewN = N + 1,
    -    State2 = case power2(L) + 1 of
    +    State2 = case power2(L) + 1 of
     		 P2 when P2 == P ->
    -		     State#hash_state{n_fragments      = NewN,
    +		     State#hash_state{n_fragments      = NewN,
     				      n_doubles        = L + 1,
    -				      next_n_to_split = 1};
    +				      next_n_to_split = 1};
     		 _ ->
    -		     State#hash_state{n_fragments     = NewN,
    -				      next_n_to_split = P}
    +		     State#hash_state{n_fragments     = NewN,
    +				      next_n_to_split = P}
     	     end,
    -    {State2, [SplitN], [NewN]};
    -add_frag(OldState) ->
    -    State = convert_old_state(OldState),
    -    add_frag(State).
    +    {State2, [SplitN], [NewN]};
    +add_frag(OldState) ->
    +    State = convert_old_state(OldState),
    +    add_frag(State).
     
     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    --spec del_frag(State :: term()) -> {NewState, IterFrags, AdditionalLockFrags} when
    -      NewState :: term(),
    -      IterFrags :: [integer()],
    -      AdditionalLockFrags :: [integer()].
    -del_frag(#hash_state{next_n_to_split = SplitN, n_doubles = L, n_fragments = N} = State) ->
    +-spec del_frag(State :: term()) -> {NewState, IterFrags, AdditionalLockFrags} when
    +      NewState :: term(),
    +      IterFrags :: [integer()],
    +      AdditionalLockFrags :: [integer()].
    +del_frag(#hash_state{next_n_to_split = SplitN, n_doubles = L, n_fragments = N} = State) ->
         P = SplitN - 1,
         if
     	P < 1 ->
     	    L2 = L - 1,
    -	    MergeN = power2(L2),
    -	    State2 = State#hash_state{n_fragments     = N - 1,
    +	    MergeN = power2(L2),
    +	    State2 = State#hash_state{n_fragments     = N - 1,
     				      next_n_to_split = MergeN,
    -				      n_doubles       = L2},
    -	    {State2, [N], [MergeN]};
    +				      n_doubles       = L2},
    +	    {State2, [N], [MergeN]};
     	true ->
     	    MergeN = P,
    -	    State2 = State#hash_state{n_fragments     = N - 1,
    -				      next_n_to_split = MergeN},
    -	    {State2, [N], [MergeN]}
    +	    State2 = State#hash_state{n_fragments     = N - 1,
    +				      next_n_to_split = MergeN},
    +	    {State2, [N], [MergeN]}
     	end;
    -del_frag(OldState) ->
    -    State = convert_old_state(OldState),
    -    del_frag(State).
    +del_frag(OldState) ->
    +    State = convert_old_state(OldState),
    +    del_frag(State).
     
     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    --spec key_to_frag_number(State, Key) -> Fragnum when
    -      State :: term(),
    -      Key :: term(),
    -      Fragnum :: integer().
    -key_to_frag_number(#hash_state{function = phash, n_fragments = N, n_doubles = L}, Key) ->
    -    A = erlang:phash(Key, power2(L + 1)),
    +-spec key_to_frag_number(State, Key) -> Fragnum when
    +      State :: term(),
    +      Key :: term(),
    +      Fragnum :: integer().
    +key_to_frag_number(#hash_state{function = phash, n_fragments = N, n_doubles = L}, Key) ->
    +    A = erlang:phash(Key, power2(L + 1)),
         if
     	A > N ->
    -	    A - power2(L);
    +	    A - power2(L);
     	true ->
     	    A
         end;
    -key_to_frag_number(#hash_state{function = phash2, n_fragments = N, n_doubles = L}, Key) ->
    -    A = erlang:phash2(Key, power2(L + 1)) + 1,
    +key_to_frag_number(#hash_state{function = phash2, n_fragments = N, n_doubles = L}, Key) ->
    +    A = erlang:phash2(Key, power2(L + 1)) + 1,
         if
     	A > N ->
    -	    A - power2(L);
    +	    A - power2(L);
     	true ->
     	    A
         end;
    -key_to_frag_number(OldState, Key) ->
    -    State = convert_old_state(OldState),
    -    key_to_frag_number(State, Key).
    +key_to_frag_number(OldState, Key) ->
    +    State = convert_old_state(OldState),
    +    key_to_frag_number(State, Key).
     
     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    --spec match_spec_to_frag_numbers(State, MatchSpec) -> Fragnums when
    -      State :: term(),
    -      MatchSpec :: ets:match_spec(),
    -      Fragnums :: [integer()].
    -match_spec_to_frag_numbers(#hash_state{n_fragments = N} = State, MatchSpec) ->
    +-spec match_spec_to_frag_numbers(State, MatchSpec) -> Fragnums when
    +      State :: term(),
    +      MatchSpec :: ets:match_spec(),
    +      Fragnums :: [integer()].
    +match_spec_to_frag_numbers(#hash_state{n_fragments = N} = State, MatchSpec) ->
         case MatchSpec of
    -	[{HeadPat, _, _}] when is_tuple(HeadPat), tuple_size(HeadPat) > 2 ->
    -	    KeyPat = element(2, HeadPat),
    -	    case has_var(KeyPat) of
    +	[{HeadPat, _, _}] when is_tuple(HeadPat), tuple_size(HeadPat) > 2 ->
    +	    KeyPat = element(2, HeadPat),
    +	    case has_var(KeyPat) of
     		false ->
    -		    [key_to_frag_number(State, KeyPat)];
    +		    [key_to_frag_number(State, KeyPat)];
     		true ->
    -		    lists:seq(1, N)
    +		    lists:seq(1, N)
     	    end;
     	_ ->
    -	    lists:seq(1, N)
    +	    lists:seq(1, N)
         end;
    -match_spec_to_frag_numbers(OldState, MatchSpec) ->
    -    State = convert_old_state(OldState),
    -    match_spec_to_frag_numbers(State, MatchSpec).
    +match_spec_to_frag_numbers(OldState, MatchSpec) ->
    +    State = convert_old_state(OldState),
    +    match_spec_to_frag_numbers(State, MatchSpec).
     
    -power2(Y) ->
    +power2(Y) ->
         1 bsl Y. % trunc(math:pow(2, Y)).
    diff --git a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap2.html b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap2.html index 53889bbd04605..d8ece202a5482 100644 --- a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap2.html +++ b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap2.html @@ -137,21 +137,21 @@

    This section provides a simplified demonstration of a Mnesia system startup. The dialogue from the Erlang shell is as follows:

    unix> erl -mnesia dir '"/tmp/funky"'
    -Erlang (BEAM) emulator version 4.9
    +Erlang (BEAM) emulator version 4.9
     
    -Eshell V4.9  (abort with ^G)
    +Eshell V4.9  (abort with ^G)
     1>
    -1> mnesia:create_schema([node()]).
    +1> mnesia:create_schema([node()]).
     ok
    -2> mnesia:start().
    +2> mnesia:start().
     ok
    -3> mnesia:create_table(funky, []).
    -{atomic,ok}
    -4> mnesia:info().
    +3> mnesia:create_table(funky, []).
    +{atomic,ok}
    +4> mnesia:info().
     ---> Processes holding locks <---
     ---> Processes waiting for locks <---
    ----> Pending (remote) transactions <---
    ----> Active (local) transactions <---
    +---> Pending (remote) transactions <---
    +---> Active (local) transactions <---
     ---> Uncertain transactions <---
     ---> Active tables <---
     funky          : with 0 records occupying 269 words of mem
    @@ -159,17 +159,17 @@ 

    ===> System info in version "1.0", debug level = none <=== opt_disc. Directory "/tmp/funky" is used. use fall-back at restart = false -running db nodes = [nonode@nohost] -stopped db nodes = [] -remote = [] -ram_copies = [funky] -disc_copies = [schema] -disc_only_copies = [] -[{nonode@nohost,disc_copies}] = [schema] -[{nonode@nohost,ram_copies}] = [funky] +running db nodes = [nonode@nohost] +stopped db nodes = [] +remote = [] +ram_copies = [funky] +disc_copies = [schema] +disc_only_copies = [] +[{nonode@nohost,disc_copies}] = [schema] +[{nonode@nohost,ram_copies}] = [funky] 1 transactions committed, 0 aborted, 0 restarted, 1 logged to disc 0 held locks, 0 in queue; 0 local transactions, 0 remote -0 transactions waits for other nodes: [] +0 transactions waits for other nodes: [] ok

    In this example, the following actions are performed:

    • Step 1: The Erlang system is started from the UNIX prompt with a flag -mnesia dir '"/tmp/funky"', which indicates in which directory to store the data.
    • Step 2: A new empty schema is initialized on the local node by evaluating @@ -229,28 +229,28 @@

      Defining Structure and Content

      First the record definitions are entered into a text file named company.hrl. -This file defines the following structure for the example database:

      -record(employee, {emp_no,
      +This file defines the following structure for the example database:

      -record(employee, {emp_no,
                          name,
                          salary,
                          sex,
                          phone,
      -                   room_no}).
      +                   room_no}).
       
      --record(dept, {id,
      -               name}).
      +-record(dept, {id,
      +               name}).
       
      --record(project, {name,
      -                  number}).
      +-record(project, {name,
      +                  number}).
       
       
      --record(manager, {emp,
      -                  dept}).
      +-record(manager, {emp,
      +                  dept}).
       
      --record(at_dep, {emp,
      -                 dept_id}).
      +-record(at_dep, {emp,
      +                 dept_id}).
       
      --record(in_proj, {emp,
      -                  proj_name}).

      The structure defines six tables in the database. In Mnesia, the function +-record(in_proj, {emp, + proj_name}).

      The structure defines six tables in the database. In Mnesia, the function mnesia:create_table(Name, ArgList) creates tables. Name is the table name.

      Note

      The current version of Mnesia does not require that the name of the table is the same as the record name, see @@ -267,28 +267,28 @@

      The following shell interaction starts Mnesia and initializes the schema for the Company database:

      % erl -mnesia dir '"/ldisc/scratch/Mnesia.Company"'
      -Erlang (BEAM) emulator version 4.9
      +Erlang (BEAM) emulator version 4.9
       
      -Eshell V4.9  (abort with ^G)
      -1> mnesia:create_schema([node()]).
      +Eshell V4.9  (abort with ^G)
      +1> mnesia:create_schema([node()]).
       ok
      -2> mnesia:start().
      -ok

      The following program module creates and populates previously defined tables:

      -include_lib("stdlib/include/qlc.hrl").
      --include("company.hrl").
      -
      -init() ->
      -    mnesia:create_table(employee,
      -                        [{attributes, record_info(fields, employee)}]),
      -    mnesia:create_table(dept,
      -                        [{attributes, record_info(fields, dept)}]),
      -    mnesia:create_table(project,
      -                        [{attributes, record_info(fields, project)}]),
      -    mnesia:create_table(manager, [{type, bag},
      -                                  {attributes, record_info(fields, manager)}]),
      -    mnesia:create_table(at_dep,
      -                         [{attributes, record_info(fields, at_dep)}]),
      -    mnesia:create_table(in_proj, [{type, bag},
      -                                  {attributes, record_info(fields, in_proj)}]).

      +2> mnesia:start(). +ok

    The following program module creates and populates previously defined tables:

    -include_lib("stdlib/include/qlc.hrl").
    +-include("company.hrl").
    +
    +init() ->
    +    mnesia:create_table(employee,
    +                        [{attributes, record_info(fields, employee)}]),
    +    mnesia:create_table(dept,
    +                        [{attributes, record_info(fields, dept)}]),
    +    mnesia:create_table(project,
    +                        [{attributes, record_info(fields, project)}]),
    +    mnesia:create_table(manager, [{type, bag},
    +                                  {attributes, record_info(fields, manager)}]),
    +    mnesia:create_table(at_dep,
    +                         [{attributes, record_info(fields, at_dep)}]),
    +    mnesia:create_table(in_proj, [{type, bag},
    +                                  {attributes, record_info(fields, in_proj)}]).

    @@ -302,13 +302,13 @@

    the format mnesia:create_schema(DiscNodeList) and initiates a new schema. In this example, a non-distributed system using only one node is created. Schemas are fully explained in Define a Schema.
  • mnesia:start(). This function starts Mnesia and is fully -explained in Start Mnesia.
  • Continuing the dialogue with the Erlang shell produces the following:

    3> company:init().
    -{atomic,ok}
    -4> mnesia:info().
    +explained in Start Mnesia.

    Continuing the dialogue with the Erlang shell produces the following:

    3> company:init().
    +{atomic,ok}
    +4> mnesia:info().
     ---> Processes holding locks <---
     ---> Processes waiting for locks <---
    ----> Pending (remote) transactions <---
    ----> Active (local) transactions <---
    +---> Pending (remote) transactions <---
    +---> Active (local) transactions <---
     ---> Uncertain transactions <---
     ---> Active tables <---
     in_proj        : with 0 records occuping 269 words of mem
    @@ -321,19 +321,19 @@ 

    ===> System info in version "1.0", debug level = none <=== opt_disc. Directory "/ldisc/scratch/Mnesia.Company" is used. use fall-back at restart = false -running db nodes = [nonode@nohost] -stopped db nodes = [] -remote = [] +running db nodes = [nonode@nohost] +stopped db nodes = [] +remote = [] ram_copies = - [at_dep,dept,employee,in_proj,manager,project] -disc_copies = [schema] -disc_only_copies = [] -[{nonode@nohost,disc_copies}] = [schema] -[{nonode@nohost,ram_copies}] = - [employee,dept,project,manager,at_dep,in_proj] + [at_dep,dept,employee,in_proj,manager,project] +disc_copies = [schema] +disc_only_copies = [] +[{nonode@nohost,disc_copies}] = [schema] +[{nonode@nohost,ram_copies}] = + [employee,dept,project,manager,at_dep,in_proj] 6 transactions committed, 0 aborted, 0 restarted, 6 logged to disc 0 held locks, 0 in queue; 0 local transactions, 0 remote -0 transactions waits for other nodes: [] +0 transactions waits for other nodes: [] ok

    A set of tables is created. The function mnesia:create_table(Name, ArgList) creates the required database tables. The options available with ArgList are explained in @@ -347,32 +347,32 @@

    transactions have been committed, as six successful transactions were run when creating the tables.

    To write a function that inserts an employee record into the database, there must be an at_dep record and a set of in_proj records inserted. Examine the -following code used to complete this action:

    insert_emp(Emp, DeptId, ProjNames) ->
    +following code used to complete this action:

    insert_emp(Emp, DeptId, ProjNames) ->
         Ename = Emp#employee.name,
    -    Fun = fun() ->
    -                  mnesia:write(Emp),
    -                  AtDep = #at_dep{emp = Ename, dept_id = DeptId},
    -                  mnesia:write(AtDep),
    -                  mk_projs(Ename, ProjNames)
    +    Fun = fun() ->
    +                  mnesia:write(Emp),
    +                  AtDep = #at_dep{emp = Ename, dept_id = DeptId},
    +                  mnesia:write(AtDep),
    +                  mk_projs(Ename, ProjNames)
               end,
    -    mnesia:transaction(Fun).
    +    mnesia:transaction(Fun).
     
     
    -mk_projs(Ename, [ProjName|Tail]) ->
    -    mnesia:write(#in_proj{emp = Ename, proj_name = ProjName}),
    -    mk_projs(Ename, Tail);
    -mk_projs(_, []) -> ok.
    • The insert_emp/3 arguments are as follows:
      1. Emp is an employee record.
      2. DeptId is the identity of the department where the employee works.
      3. ProjNames is a list of the names of the projects where the employee +mk_projs(Ename, [ProjName|Tail]) -> + mnesia:write(#in_proj{emp = Ename, proj_name = ProjName}), + mk_projs(Ename, Tail); +mk_projs(_, []) -> ok.
    • The insert_emp/3 arguments are as follows:
      1. Emp is an employee record.
      2. DeptId is the identity of the department where the employee works.
      3. ProjNames is a list of the names of the projects where the employee works.

    The function insert_emp/3 creates a Functional Object (Fun). Fun is passed as a single argument to the function mnesia:transaction(Fun). This means that Fun is run as a transaction with the following properties:

    • A Fun either succeeds or fails.
    • Code that manipulates the same data records can be run concurrently without -the different processes interfering with each other.

    The function can be used as follows:

    Emp = #employee{emp_no = 104732,
    +the different processes interfering with each other.

    The function can be used as follows:

    Emp = #employee{emp_no = 104732,
                     name = klacke,
                     salary = 7,
                     sex = male,
                     phone = 98108,
    -                room_no = {221, 015}},
    -insert_emp(Emp, 'B/SFR', [Erlang, mnesia, otp]).

    Note

    For information about Funs, see "Fun Expressions" in section + room_no = {221, 015}}, +insert_emp(Emp, 'B/SFR', [Erlang, mnesia, otp]).

    Note

    For information about Funs, see "Fun Expressions" in section Erlang Reference Manual in System Documentation..

    @@ -400,48 +400,48 @@

    Adding Records and Relationships to Database

    After adding more records to the Company database, the result can be the -following records:

    employees:

    {employee, 104465, "Johnson Torbjorn",   1, male,  99184, {242,038}}.
    -{employee, 107912, "Carlsson Tuula",     2, female,94556, {242,056}}.
    -{employee, 114872, "Dacker Bjarne",      3, male,  99415, {221,035}}.
    -{employee, 104531, "Nilsson Hans",       3, male,  99495, {222,026}}.
    -{employee, 104659, "Tornkvist Torbjorn", 2, male,  99514, {222,022}}.
    -{employee, 104732, "Wikstrom Claes",     2, male,  99586, {221,015}}.
    -{employee, 117716, "Fedoriw Anna",       1, female,99143, {221,031}}.
    -{employee, 115018, "Mattsson Hakan",     3, male,  99251, {203,348}}.

    dept:

    {dept, 'B/SF',  "Open Telecom Platform"}.
    -{dept, 'B/SFP', "OTP - Product Development"}.
    -{dept, 'B/SFR', "Computer Science Laboratory"}.

    projects:

    %% projects
    -{project, erlang, 1}.
    -{project, otp, 2}.
    -{project, beam, 3}.
    -{project, mnesia, 5}.
    -{project, wolf, 6}.
    -{project, documentation, 7}.
    -{project, www, 8}.

    These three tables, employees, dept, and projects, are made up of real +following records:

    employees:

    {employee, 104465, "Johnson Torbjorn",   1, male,  99184, {242,038}}.
    +{employee, 107912, "Carlsson Tuula",     2, female,94556, {242,056}}.
    +{employee, 114872, "Dacker Bjarne",      3, male,  99415, {221,035}}.
    +{employee, 104531, "Nilsson Hans",       3, male,  99495, {222,026}}.
    +{employee, 104659, "Tornkvist Torbjorn", 2, male,  99514, {222,022}}.
    +{employee, 104732, "Wikstrom Claes",     2, male,  99586, {221,015}}.
    +{employee, 117716, "Fedoriw Anna",       1, female,99143, {221,031}}.
    +{employee, 115018, "Mattsson Hakan",     3, male,  99251, {203,348}}.

    dept:

    {dept, 'B/SF',  "Open Telecom Platform"}.
    +{dept, 'B/SFP', "OTP - Product Development"}.
    +{dept, 'B/SFR', "Computer Science Laboratory"}.

    projects:

    %% projects
    +{project, erlang, 1}.
    +{project, otp, 2}.
    +{project, beam, 3}.
    +{project, mnesia, 5}.
    +{project, wolf, 6}.
    +{project, documentation, 7}.
    +{project, www, 8}.

    These three tables, employees, dept, and projects, are made up of real records. The following database content is stored in the tables and is built on -relationships. These tables are manager, at_dep, and in_proj.

    manager:

    {manager, 104465, 'B/SF'}.
    -{manager, 104465, 'B/SFP'}.
    -{manager, 114872, 'B/SFR'}.

    at_dep:

    {at_dep, 104465, 'B/SF'}.
    -{at_dep, 107912, 'B/SF'}.
    -{at_dep, 114872, 'B/SFR'}.
    -{at_dep, 104531, 'B/SFR'}.
    -{at_dep, 104659, 'B/SFR'}.
    -{at_dep, 104732, 'B/SFR'}.
    -{at_dep, 117716, 'B/SFP'}.
    -{at_dep, 115018, 'B/SFP'}.

    in_proj:

    {in_proj, 104465, otp}.
    -{in_proj, 107912, otp}.
    -{in_proj, 114872, otp}.
    -{in_proj, 104531, otp}.
    -{in_proj, 104531, mnesia}.
    -{in_proj, 104545, wolf}.
    -{in_proj, 104659, otp}.
    -{in_proj, 104659, wolf}.
    -{in_proj, 104732, otp}.
    -{in_proj, 104732, mnesia}.
    -{in_proj, 104732, erlang}.
    -{in_proj, 117716, otp}.
    -{in_proj, 117716, documentation}.
    -{in_proj, 115018, otp}.
    -{in_proj, 115018, mnesia}.

    The room number is an attribute of the employee record. This is a structured +relationships. These tables are manager, at_dep, and in_proj.

    manager:

    {manager, 104465, 'B/SF'}.
    +{manager, 104465, 'B/SFP'}.
    +{manager, 114872, 'B/SFR'}.

    at_dep:

    {at_dep, 104465, 'B/SF'}.
    +{at_dep, 107912, 'B/SF'}.
    +{at_dep, 114872, 'B/SFR'}.
    +{at_dep, 104531, 'B/SFR'}.
    +{at_dep, 104659, 'B/SFR'}.
    +{at_dep, 104732, 'B/SFR'}.
    +{at_dep, 117716, 'B/SFP'}.
    +{at_dep, 115018, 'B/SFP'}.

    in_proj:

    {in_proj, 104465, otp}.
    +{in_proj, 107912, otp}.
    +{in_proj, 114872, otp}.
    +{in_proj, 104531, otp}.
    +{in_proj, 104531, mnesia}.
    +{in_proj, 104545, wolf}.
    +{in_proj, 104659, otp}.
    +{in_proj, 104659, wolf}.
    +{in_proj, 104732, otp}.
    +{in_proj, 104732, mnesia}.
    +{in_proj, 104732, erlang}.
    +{in_proj, 117716, otp}.
    +{in_proj, 117716, documentation}.
    +{in_proj, 115018, otp}.
    +{in_proj, 115018, mnesia}.

    The room number is an attribute of the employee record. This is a structured attribute that consists of a tuple. The first element of the tuple identifies a corridor, and the second element identifies the room in that corridor. An alternative is to represent this as a record -record(room, {corr, no}). @@ -453,67 +453,67 @@

    Retrieving data from DBMS is usually to be done with the functions mnesia:read/3 or mnesia:read/1. The following function -raises the salary:

    raise(Eno, Raise) ->
    -    F = fun() ->
    -                [E] = mnesia:read(employee, Eno, write),
    +raises the salary:

    raise(Eno, Raise) ->
    +    F = fun() ->
    +                [E] = mnesia:read(employee, Eno, write),
                     Salary = E#employee.salary + Raise,
    -                New = E#employee{salary = Salary},
    -                mnesia:write(New)
    +                New = E#employee{salary = Salary},
    +                mnesia:write(New)
             end,
    -    mnesia:transaction(F).

    Since it is desired to update the record using the function mnesia:write/1 + mnesia:transaction(F).

    Since it is desired to update the record using the function mnesia:write/1 after the salary has been increased, a write lock (third argument to read) is acquired when the record from the table is read.

    To read the values from the table directly is not always possible. It can be needed to search one or more tables to get the wanted data, and this is done by writing database queries. Queries are always more expensive operations than direct lookups done with mnesia:read/1. Therefore, avoid queries in performance-critical code.

    Two methods are available for writing database queries:

    • Mnesia functions
    • QLC

    Using Mnesia Functions

    The following function extracts the names of the female employees stored in the -database:

    mnesia:select(employee, [{#employee{sex = female, name = '$1', _ = '_'},[], ['$1']}]).

    select must always run within an activity, such as a transaction. The -following function can be constructed to call from the shell:

    all_females() ->
    -    F = fun() ->
    -		Female = #employee{sex = female, name = '$1', _ = '_'},
    -		mnesia:select(employee, [{Female, [], ['$1']}])
    +database:

    mnesia:select(employee, [{#employee{sex = female, name = '$1', _ = '_'},[], ['$1']}]).

    select must always run within an activity, such as a transaction. The +following function can be constructed to call from the shell:

    all_females() ->
    +    F = fun() ->
    +		Female = #employee{sex = female, name = '$1', _ = '_'},
    +		mnesia:select(employee, [{Female, [], ['$1']}])
             end,
    -    mnesia:transaction(F).

    The select expression matches all entries in table employee with the field -sex set to female.

    This function can be called from the shell as follows:

    (klacke@gin)1> company:all_females().
    -{atomic, ["Carlsson Tuula", "Fedoriw Anna"]}

    For a description of select and its syntax, see + mnesia:transaction(F).

    The select expression matches all entries in table employee with the field +sex set to female.

    This function can be called from the shell as follows:

    (klacke@gin)1> company:all_females().
    +{atomic, ["Carlsson Tuula", "Fedoriw Anna"]}

    For a description of select and its syntax, see Pattern Matching.

    Using QLC

    This section contains simple introductory examples only. For a full description of the QLC query language, see the qlc manual page in STDLIB.

    Using QLC can be more expensive than using Mnesia functions directly but -offers a nice syntax.

    The following function extracts a list of female employees from the database:

    Q = qlc:q([E#employee.name || E <- mnesia:table(employee),
    -                              E#employee.sex == female]),
    -qlc:e(Q),

    Accessing Mnesia tables from a QLC list comprehension must always be done -within a transaction. Consider the following function:

    females() ->
    -    F = fun() ->
    -		Q = qlc:q([E#employee.name || E <- mnesia:table(employee),
    -					      E#employee.sex == female]),
    -		qlc:e(Q)
    +offers a nice syntax.

    The following function extracts a list of female employees from the database:

    Q = qlc:q([E#employee.name || E <- mnesia:table(employee),
    +                              E#employee.sex == female]),
    +qlc:e(Q),

    Accessing Mnesia tables from a QLC list comprehension must always be done +within a transaction. Consider the following function:

    females() ->
    +    F = fun() ->
    +		Q = qlc:q([E#employee.name || E <- mnesia:table(employee),
    +					      E#employee.sex == female]),
    +		qlc:e(Q)
     	end,
    -    mnesia:transaction(F).

    This function can be called from the shell as follows:

    (klacke@gin)1> company:females().
    -{atomic, ["Carlsson Tuula", "Fedoriw Anna"]}

    In traditional relational database terminology, this operation is called a + mnesia:transaction(F).

    This function can be called from the shell as follows:

    (klacke@gin)1> company:females().
    +{atomic, ["Carlsson Tuula", "Fedoriw Anna"]}

    In traditional relational database terminology, this operation is called a selection, followed by a projection.

    The previous list comprehension expression contains a number of syntactical elements:

    • The first [ bracket is read as "build the list".
    • The || "such that" and the arrow <- is read as "taken from".

    Hence, the previous list comprehension demonstrates the formation of the list E#employee.name such that E is taken from the table of employees, and attribute sex of each record is equal to the atom female.

    The whole list comprehension must be given to the function qlc:q/1.

    List comprehensions with low-level Mnesia functions can be combined in the same transaction. To raise the salary of all female employees, execute the -following:

    raise_females(Amount) ->
    -    F = fun() ->
    -                Q = qlc:q([E || E <- mnesia:table(employee),
    -                                E#employee.sex == female]),
    -		Fs = qlc:e(Q),
    -                over_write(Fs, Amount)
    +following:

    raise_females(Amount) ->
    +    F = fun() ->
    +                Q = qlc:q([E || E <- mnesia:table(employee),
    +                                E#employee.sex == female]),
    +		Fs = qlc:e(Q),
    +                over_write(Fs, Amount)
             end,
    -    mnesia:transaction(F).
    +    mnesia:transaction(F).
     
    -over_write([E|Tail], Amount) ->
    +over_write([E|Tail], Amount) ->
         Salary = E#employee.salary + Amount,
    -    New = E#employee{salary = Salary},
    -    mnesia:write(New),
    -    1 + over_write(Tail, Amount);
    -over_write([], _) ->
    +    New = E#employee{salary = Salary},
    +    mnesia:write(New),
    +    1 + over_write(Tail, Amount);
    +over_write([], _) ->
         0.

    The function raise_females/1 returns the tuple {atomic, Number}, where Number is the number of female employees who received a salary increase. If an error occurs, the value {aborted, Reason} is returned, and Mnesia guarantees -that the salary is not raised for any employee.

    Example:

    33> company:raise_females(33).
    -{atomic,2}
    +that the salary is not raised for any employee.

    Example:

    33> company:raise_females(33).
    +{atomic,2}
    diff --git a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap3.html b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap3.html index ba21e378d748a..ae1c02398a0f0 100644 --- a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap3.html +++ b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap3.html @@ -175,18 +175,18 @@

    changes the format on all records in table Tab. It applies argument Fun to all records in the table. Fun must be a function that takes a record of the old type, and returns the record of the new type. The table key must not be -changed.

    Example:

    -record(old, {key, val}).
    --record(new, {key, val, extra}).
    +changed.

    Example:

    -record(old, {key, val}).
    +-record(new, {key, val, extra}).
     
     Transformer =
    -   fun(X) when record(X, old) ->
    -      #new{key = X#old.key,
    +   fun(X) when record(X, old) ->
    +      #new{key = X#old.key,
                val = X#old.val,
    -           extra = 42}
    +           extra = 42}
        end,
    -{atomic, ok} = mnesia:transform_table(foo, Transformer,
    -                                      record_info(fields, new),
    -                                      new),

    Argument Fun can also be the atom ignore, which indicates that only the +{atomic, ok} = mnesia:transform_table(foo, Transformer, + record_info(fields, new), + new),

    Argument Fun can also be the atom ignore, which indicates that only the metadata about the table is updated. Use of ignore is not recommended (as it creates inconsistencies between the metadata and the actual data) but it is included as a possibility for the user do to an own (offline) transform.

  • mnesia:change_table_copy_type(Tab, Node, ToType) @@ -238,29 +238,29 @@

    when starting the Erlang shell or in the application script. Previously, the following example was used to create the directory for the Company database:

    % erl -mnesia dir '"/ldisc/scratch/Mnesia.Company"'

  • If no command-line flag is entered, the Mnesia directory becomes the current working directory on the node where the Erlang shell is started.

  • To start the Company database and get it running on the two specified nodes, -enter the following commands:

    1. On the node a@gin:
     gin % erl -sname a  -mnesia dir '"/ldisc/scratch/Mnesia.company"'
    1. On the node b@skeppet:
    skeppet % erl -sname b -mnesia dir '"/ldisc/scratch/Mnesia.company"'
    1. On one of the two nodes:
    (a@gin)1> mnesia:create_schema([a@gin, b@skeppet]).
    1. The function mnesia:start() is called on both nodes.
    2. To initialize the database, execute the following code on one of the two -nodes:
    dist_init() ->
    -    mnesia:create_table(employee,
    -                         [{ram_copies, [a@gin, b@skeppet]},
    -                          {attributes, record_info(fields,
    -						   employee)}]),
    -    mnesia:create_table(dept,
    -                         [{ram_copies, [a@gin, b@skeppet]},
    -                          {attributes, record_info(fields, dept)}]),
    -    mnesia:create_table(project,
    -                         [{ram_copies, [a@gin, b@skeppet]},
    -                          {attributes, record_info(fields, project)}]),
    -    mnesia:create_table(manager, [{type, bag},
    -                                  {ram_copies, [a@gin, b@skeppet]},
    -                                  {attributes, record_info(fields,
    -							   manager)}]),
    -    mnesia:create_table(at_dep,
    -                         [{ram_copies, [a@gin, b@skeppet]},
    -                          {attributes, record_info(fields, at_dep)}]),
    -    mnesia:create_table(in_proj,
    -                        [{type, bag},
    -                         {ram_copies, [a@gin, b@skeppet]},
    -                         {attributes, record_info(fields, in_proj)}]).

    As illustrated, the two directories reside on different nodes, because +enter the following commands:

    1. On the node a@gin:
     gin % erl -sname a  -mnesia dir '"/ldisc/scratch/Mnesia.company"'
    1. On the node b@skeppet:
    skeppet % erl -sname b -mnesia dir '"/ldisc/scratch/Mnesia.company"'
    1. On one of the two nodes:
    (a@gin)1> mnesia:create_schema([a@gin, b@skeppet]).
    1. The function mnesia:start() is called on both nodes.
    2. To initialize the database, execute the following code on one of the two +nodes:
    dist_init() ->
    +    mnesia:create_table(employee,
    +                         [{ram_copies, [a@gin, b@skeppet]},
    +                          {attributes, record_info(fields,
    +						   employee)}]),
    +    mnesia:create_table(dept,
    +                         [{ram_copies, [a@gin, b@skeppet]},
    +                          {attributes, record_info(fields, dept)}]),
    +    mnesia:create_table(project,
    +                         [{ram_copies, [a@gin, b@skeppet]},
    +                          {attributes, record_info(fields, project)}]),
    +    mnesia:create_table(manager, [{type, bag},
    +                                  {ram_copies, [a@gin, b@skeppet]},
    +                                  {attributes, record_info(fields,
    +							   manager)}]),
    +    mnesia:create_table(at_dep,
    +                         [{ram_copies, [a@gin, b@skeppet]},
    +                          {attributes, record_info(fields, at_dep)}]),
    +    mnesia:create_table(in_proj,
    +                        [{type, bag},
    +                         {ram_copies, [a@gin, b@skeppet]},
    +                         {attributes, record_info(fields, in_proj)}]).

    As illustrated, the two directories reside on different nodes, because /ldisc/scratch (the "local" disc) exists on the two different nodes.

    By executing these commands, two Erlang nodes are configured to run the Company database, and therefore, initialize the database. This is required only once when setting up. The next time the system is started, @@ -277,7 +277,7 @@

    Startup Procedure

    -

    Start Mnesia by calling the following function:

    mnesia:start().

    This function initiates the DBMS locally.

    The choice of configuration alters the location and load order of the tables. +

    Start Mnesia by calling the following function:

    mnesia:start().

    This function initiates the DBMS locally.

    The choice of configuration alters the location and load order of the tables. The alternatives are as follows:

    1. Tables that are only stored locally are initialized from the local Mnesia directory.
    2. Replicated tables that reside locally as well as somewhere else are either initiated from disc or by copying the entire table from the other node, @@ -300,9 +300,9 @@

      from disc at a faster rate. The function forces tables to be loaded from disc regardless of the network situation.

      Thus, it can be assumed that if an application wants to use tables a and b, the application must perform some action similar to following before it can use -the tables:

      case mnesia:wait_for_tables([a, b], 20000) of
      -  {timeout, RemainingTabs} ->
      -    panic(RemainingTabs);
      +the tables:

      case mnesia:wait_for_tables([a, b], 20000) of
      +  {timeout, RemainingTabs} ->
      +    panic(RemainingTabs);
         ok ->
           synced
       end.

      Warning

      When tables are forcefully loaded from the local disc, all operations that @@ -328,13 +328,13 @@

      key, whereas a table of type bag can have an arbitrary number of records per key. The key for each record is always the first attribute of the record.

      The following example illustrates the difference between type set and -bag:

       f() ->
      -    F = fun() ->
      -          mnesia:write({foo, 1, 2}),
      -          mnesia:write({foo, 1, 3}),
      -          mnesia:read({foo, 1})
      +bag:

       f() ->
      +    F = fun() ->
      +          mnesia:write({foo, 1, 2}),
      +          mnesia:write({foo, 1, 3}),
      +          mnesia:read({foo, 1})
               end,
      -    mnesia:transaction(F).

      This transaction returns the list [{foo,1,3}] if table foo is of type + mnesia:transaction(F).

      This transaction returns the list [{foo,1,3}] if table foo is of type set. However, the list [{foo,1,2}, {foo,1,3}] is returned if the table is of type bag.

      Mnesia tables can never contain duplicates of the same record in the same table. Duplicate records have attributes with the same contents and key.

    3. {disc_copies, NodeList}, where NodeList is a list of the nodes where @@ -378,11 +378,11 @@

      table. All records stored in the table must have this name as their first element. record_name defaults to the name of the table. For more information, see -Record Names versus Table Names.

    4. As an example, consider the following record definition:

      -record(funky, {x, y}).

      The following call would create a table that is replicated on two nodes, has an -extra index on attribute y, and is of type bag.

      mnesia:create_table(funky, [{disc_copies, [N1, N2]}, {index, [y]},
      -                            {type, bag}, {attributes, record_info(fields, funky)}]).

      Whereas a call to the following default code values would return a table with a +Record Names versus Table Names.

      As an example, consider the following record definition:

      -record(funky, {x, y}).

      The following call would create a table that is replicated on two nodes, has an +extra index on attribute y, and is of type bag.

      mnesia:create_table(funky, [{disc_copies, [N1, N2]}, {index, [y]},
      +                            {type, bag}, {attributes, record_info(fields, funky)}]).

      Whereas a call to the following default code values would return a table with a RAM copy on the local node, no extra indexes, and the attributes defaulted to -the list [key,val].

      mnesia:create_table(stuff, [])
      +the list [key,val].

      mnesia:create_table(stuff, [])
    diff --git a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap4.html b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap4.html index 652f6c039c4db..5cd3931df476d 100644 --- a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap4.html +++ b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap4.html @@ -145,14 +145,14 @@

    and delete Mnesia records. The Fun is evaluated as a transaction that either commits or terminates. If a transaction succeeds in executing the Fun, it replicates the action on all nodes involved, or terminates if an error occurs.

    The following example shows a transaction that raises the salary of certain -employee numbers:

    raise(Eno, Raise) ->
    -    F = fun() ->
    -                [E] = mnesia:read(employee, Eno, write),
    +employee numbers:

    raise(Eno, Raise) ->
    +    F = fun() ->
    +                [E] = mnesia:read(employee, Eno, write),
                     Salary = E#employee.salary + Raise,
    -                New = E#employee{salary = Salary},
    -                mnesia:write(New)
    +                New = E#employee{salary = Salary},
    +                mnesia:write(New)
             end,
    -    mnesia:transaction(F).

    The function raise/2 contains a Fun made up of four code lines. This Fun is + mnesia:transaction(F).

    The function raise/2 contains a Fun made up of four code lines. This Fun is called by the statement mnesia:transaction(F) and returns a value.

    The Mnesia transaction system facilitates the construction of reliable, distributed systems by providing the following important properties:

    • The transaction handler ensures that a Fun, which is placed inside a transaction, does not interfere with operations embedded in other transactions @@ -246,15 +246,15 @@

      The Fun in the transaction is evaluated once more.

      It is therefore important that the code inside the Fun given to mnesia:transaction/1 is pure. Some strange results can occur if, for example, messages are sent by the transaction Fun. The following example illustrates this -situation:

      bad_raise(Eno, Raise) ->
      -    F = fun() ->
      -                [E] = mnesia:read({employee, Eno}),
      +situation:

      bad_raise(Eno, Raise) ->
      +    F = fun() ->
      +                [E] = mnesia:read({employee, Eno}),
                       Salary = E#employee.salary + Raise,
      -                New = E#employee{salary = Salary},
      -                io:format("Trying to write ... ~n", []),
      -                mnesia:write(New)
      +                New = E#employee{salary = Salary},
      +                io:format("Trying to write ... ~n", []),
      +                mnesia:write(New)
               end,
      -    mnesia:transaction(F).

      This transaction can write the text "Trying to write ... " 1000 times to the + mnesia:transaction(F).

      This transaction can write the text "Trying to write ... " 1000 times to the terminal. However, Mnesia guarantees that each transaction will eventually run. As a result, Mnesia is not only deadlock free, but also livelock free.

      The Mnesia programmer cannot prioritize one particular transaction to execute before other transactions that are waiting to execute. As a result, the Mnesia @@ -301,13 +301,13 @@

      fails. Such applications can benefit from using sticky locks instead of the normal locking scheme.

      A sticky lock is a lock that stays in place at a node, after the transaction that first acquired the lock has terminated. To illustrate this, assume that the -following transaction is executed:

      F = fun() ->
      -      mnesia:write(#foo{a = kalle})
      +following transaction is executed:

      F = fun() ->
      +      mnesia:write(#foo{a = kalle})
           end,
      -mnesia:transaction(F).

      The foo table is replicated on the two nodes N1 and N2.

      Normal locking requires the following:

      • One network RPC (two messages) to acquire the write lock
      • Three network messages to execute the two-phase commit protocol

      If sticky locks are used, the code must first be changed as follows:

      F = fun() ->
      -      mnesia:s_write(#foo{a = kalle})
      +mnesia:transaction(F).

      The foo table is replicated on the two nodes N1 and N2.

      Normal locking requires the following:

      • One network RPC (two messages) to acquire the write lock
      • Three network messages to execute the two-phase commit protocol

      If sticky locks are used, the code must first be changed as follows:

      F = fun() ->
      +      mnesia:s_write(#foo{a = kalle})
           end,
      -mnesia:transaction(F).

      This code uses the function s_write/1 instead of the +mnesia:transaction(F).

      This code uses the function s_write/1 instead of the function write/1 The function s_write/1 sets a sticky lock instead of a normal lock. If the table is not replicated, sticky locks have no special effect. If the table is replicated, and a sticky lock is set on node @@ -333,8 +333,8 @@

      following two functions are used to set explicit table locks for read and write operations:

      Alternative syntax for acquisition of table locks is as follows:

      mnesia:lock({table, Tab}, read)
      -mnesia:lock({table, Tab}, write)

      The matching operations in Mnesia can either lock the entire table or only a +on table Tab.

    Alternative syntax for acquisition of table locks is as follows:

    mnesia:lock({table, Tab}, read)
    +mnesia:lock({table, Tab}, write)

    The matching operations in Mnesia can either lock the entire table or only a single record (when the key is bound in the pattern).

    @@ -425,78 +425,78 @@

    necessarily have to be the same as the table name, although this is the case in most of the examples in this User's Guide. If a table is created without property record_name, the following code ensures that all records in the -tables have the same name as the table:

    mnesia:create_table(subscriber, [])

    However, if the table is created with an explicit record name as argument, as +tables have the same name as the table:

    mnesia:create_table(subscriber, [])

    However, if the table is created with an explicit record name as argument, as shown in the following example, subscriber records can be stored in both of the -tables regardless of the table names:

    TabDef = [{record_name, subscriber}],
    -mnesia:create_table(my_subscriber, TabDef),
    -mnesia:create_table(your_subscriber, TabDef).

    To access such tables, simplified access functions (as described earlier) cannot +tables regardless of the table names:

    TabDef = [{record_name, subscriber}],
    +mnesia:create_table(my_subscriber, TabDef),
    +mnesia:create_table(your_subscriber, TabDef).

    To access such tables, simplified access functions (as described earlier) cannot be used. For example, writing a subscriber record into a table requires the function mnesia:write/3 instead of the simplified functions mnesia:write/1 -and mnesia:s_write/1:

    mnesia:write(subscriber, #subscriber{}, write)
    -mnesia:write(my_subscriber, #subscriber{}, sticky_write)
    -mnesia:write(your_subscriber, #subscriber{}, write)

    The following simple code illustrates the relationship between the simplified +and mnesia:s_write/1:

    mnesia:write(subscriber, #subscriber{}, write)
    +mnesia:write(my_subscriber, #subscriber{}, sticky_write)
    +mnesia:write(your_subscriber, #subscriber{}, write)

    The following simple code illustrates the relationship between the simplified access functions used in most of the examples and their more flexible -counterparts:

    mnesia:dirty_write(Record) ->
    -  Tab = element(1, Record),
    -  mnesia:dirty_write(Tab, Record).
    +counterparts:

    mnesia:dirty_write(Record) ->
    +  Tab = element(1, Record),
    +  mnesia:dirty_write(Tab, Record).
     
    -mnesia:dirty_delete({Tab, Key}) ->
    -  mnesia:dirty_delete(Tab, Key).
    +mnesia:dirty_delete({Tab, Key}) ->
    +  mnesia:dirty_delete(Tab, Key).
     
    -mnesia:dirty_delete_object(Record) ->
    -  Tab = element(1, Record),
    -  mnesia:dirty_delete_object(Tab, Record)
    +mnesia:dirty_delete_object(Record) ->
    +  Tab = element(1, Record),
    +  mnesia:dirty_delete_object(Tab, Record)
     
    -mnesia:dirty_update_counter({Tab, Key}, Incr) ->
    -  mnesia:dirty_update_counter(Tab, Key, Incr).
    +mnesia:dirty_update_counter({Tab, Key}, Incr) ->
    +  mnesia:dirty_update_counter(Tab, Key, Incr).
     
    -mnesia:dirty_read({Tab, Key}) ->
    -  Tab = element(1, Record),
    -  mnesia:dirty_read(Tab, Key).
    +mnesia:dirty_read({Tab, Key}) ->
    +  Tab = element(1, Record),
    +  mnesia:dirty_read(Tab, Key).
     
    -mnesia:dirty_match_object(Pattern) ->
    -  Tab = element(1, Pattern),
    -  mnesia:dirty_match_object(Tab, Pattern).
    +mnesia:dirty_match_object(Pattern) ->
    +  Tab = element(1, Pattern),
    +  mnesia:dirty_match_object(Tab, Pattern).
     
    -mnesia:dirty_index_match_object(Pattern, Attr)
    -  Tab = element(1, Pattern),
    -  mnesia:dirty_index_match_object(Tab, Pattern, Attr).
    +mnesia:dirty_index_match_object(Pattern, Attr)
    +  Tab = element(1, Pattern),
    +  mnesia:dirty_index_match_object(Tab, Pattern, Attr).
     
    -mnesia:write(Record) ->
    -  Tab = element(1, Record),
    -  mnesia:write(Tab, Record, write).
    +mnesia:write(Record) ->
    +  Tab = element(1, Record),
    +  mnesia:write(Tab, Record, write).
     
    -mnesia:s_write(Record) ->
    -  Tab = element(1, Record),
    -  mnesia:write(Tab, Record, sticky_write).
    +mnesia:s_write(Record) ->
    +  Tab = element(1, Record),
    +  mnesia:write(Tab, Record, sticky_write).
     
    -mnesia:delete({Tab, Key}) ->
    -  mnesia:delete(Tab, Key, write).
    +mnesia:delete({Tab, Key}) ->
    +  mnesia:delete(Tab, Key, write).
     
    -mnesia:s_delete({Tab, Key}) ->
    -  mnesia:delete(Tab, Key, sticky_write).
    +mnesia:s_delete({Tab, Key}) ->
    +  mnesia:delete(Tab, Key, sticky_write).
     
    -mnesia:delete_object(Record) ->
    -  Tab = element(1, Record),
    -  mnesia:delete_object(Tab, Record, write).
    +mnesia:delete_object(Record) ->
    +  Tab = element(1, Record),
    +  mnesia:delete_object(Tab, Record, write).
     
    -mnesia:s_delete_object(Record) ->
    -  Tab = element(1, Record),
    -  mnesia:delete_object(Tab, Record, sticky_write).
    +mnesia:s_delete_object(Record) ->
    +  Tab = element(1, Record),
    +  mnesia:delete_object(Tab, Record, sticky_write).
     
    -mnesia:read({Tab, Key}) ->
    -  mnesia:read(Tab, Key, read).
    +mnesia:read({Tab, Key}) ->
    +  mnesia:read(Tab, Key, read).
     
    -mnesia:wread({Tab, Key}) ->
    -  mnesia:read(Tab, Key, write).
    +mnesia:wread({Tab, Key}) ->
    +  mnesia:read(Tab, Key, write).
     
    -mnesia:match_object(Pattern) ->
    -  Tab = element(1, Pattern),
    -  mnesia:match_object(Tab, Pattern, read).
    +mnesia:match_object(Pattern) ->
    +  Tab = element(1, Pattern),
    +  mnesia:match_object(Tab, Pattern, read).
     
    -mnesia:index_match_object(Pattern, Attr) ->
    -  Tab = element(1, Pattern),
    -  mnesia:index_match_object(Tab, Pattern, Attr, read).

    +mnesia:index_match_object(Pattern, Attr) -> + Tab = element(1, Pattern), + mnesia:index_match_object(Tab, Pattern, Attr, read).

    @@ -577,28 +577,28 @@

    terminates. So, although a nested transaction returns {atomic, Val}, if the enclosing parent transaction terminates, the entire nested operation terminates.

    The ability to have nested transaction with identical semantics as top-level transaction makes it easier to write library functions that manipulate Mnesia -tables.

    Consider a function that adds a subscriber to a telephony system:

    add_subscriber(S) ->
    -    mnesia:transaction(fun() ->
    -        case mnesia:read( ..........

    This function needs to be called as a transaction. Assume that you wish to write +tables.

    Consider a function that adds a subscriber to a telephony system:

    add_subscriber(S) ->
    +    mnesia:transaction(fun() ->
    +        case mnesia:read( ..........

    This function needs to be called as a transaction. Assume that you wish to write a function that both calls the function add_subscriber/1 and is in itself protected by the context of a transaction. By calling add_subscriber/1 from within another transaction, a nested transaction is created.

    Also, different activity access contexts can be mixed while nesting. However, the dirty ones (async_dirty, sync_dirty, and ets) inherit the transaction semantics if they are called inside a transaction and thus grab locks and use -two or three phase commit.

    Example:

    add_subscriber(S) ->
    -    mnesia:transaction(fun() ->
    +two or three phase commit.

    Example:

    add_subscriber(S) ->
    +    mnesia:transaction(fun() ->
            %% Transaction context
    -       mnesia:read({some_tab, some_data}),
    -       mnesia:sync_dirty(fun() ->
    +       mnesia:read({some_tab, some_data}),
    +       mnesia:sync_dirty(fun() ->
                %% Still in a transaction context.
    -           case mnesia:read( ..) ..end), end).
    -add_subscriber2(S) ->
    -    mnesia:sync_dirty(fun() ->
    +           case mnesia:read( ..) ..end), end).
    +add_subscriber2(S) ->
    +    mnesia:sync_dirty(fun() ->
            %% In dirty context
    -       mnesia:read({some_tab, some_data}),
    -       mnesia:transaction(fun() ->
    +       mnesia:read({some_tab, some_data}),
    +       mnesia:transaction(fun() ->
                %% In a transaction context.
    -           case mnesia:read( ..) ..end), end).

    + case mnesia:read( ..) ..end), end).

    @@ -606,13 +606,13 @@

    When the function mnesia:read/3 cannot be used, Mnesia provides the programmer with several functions for matching records against a pattern. The -most useful ones are the following:

    mnesia:select(Tab, MatchSpecification, LockKind) ->
    -    transaction abort | [ObjectList]
    -mnesia:select(Tab, MatchSpecification, NObjects, Lock) ->
    -    transaction abort | {[Object],Continuation} | '$end_of_table'
    -mnesia:select(Cont) ->
    -    transaction abort | {[Object],Continuation} | '$end_of_table'
    -mnesia:match_object(Tab, Pattern, LockKind) ->
    +most useful ones are the following:

    mnesia:select(Tab, MatchSpecification, LockKind) ->
    +    transaction abort | [ObjectList]
    +mnesia:select(Tab, MatchSpecification, NObjects, Lock) ->
    +    transaction abort | {[Object],Continuation} | '$end_of_table'
    +mnesia:select(Cont) ->
    +    transaction abort | {[Object],Continuation} | '$end_of_table'
    +mnesia:match_object(Tab, Pattern, LockKind) ->
         transaction abort | RecordList

    These functions match a Pattern against all records in table Tab. In a mnesia:select call, Pattern is a part of MatchSpecification described in the following. It is not necessarily performed @@ -627,22 +627,22 @@

    occurrences of that variable against the bound value.

    Use function mnesia:table_info(Tab, wild_pattern) to obtain a basic pattern, which matches all records in a table, or use the default value in record creation. Do not make the pattern hard-coded, as this makes the -code more vulnerable to future changes of the record definition.

    Example:

    Wildpattern = mnesia:table_info(employee, wild_pattern),
    +code more vulnerable to future changes of the record definition.

    Example:

    Wildpattern = mnesia:table_info(employee, wild_pattern),
     %% Or use
    -Wildpattern = #employee{_ = '_'},

    For the employee table, the wild pattern looks as follows:

    {employee, '_', '_', '_', '_', '_',' _'}.

    To constrain the match, it is needed to replace some of the '_' elements. The -code for matching out all female employees looks as follows:

    Pat = #employee{sex = female, _ = '_'},
    -F = fun() -> mnesia:match_object(Pat) end,
    -Females = mnesia:transaction(F).

    The match function can also be used to check the equality of different +Wildpattern = #employee{_ = '_'},

    For the employee table, the wild pattern looks as follows:

    {employee, '_', '_', '_', '_', '_',' _'}.

    To constrain the match, it is needed to replace some of the '_' elements. The +code for matching out all female employees looks as follows:

    Pat = #employee{sex = female, _ = '_'},
    +F = fun() -> mnesia:match_object(Pat) end,
    +Females = mnesia:transaction(F).

    The match function can also be used to check the equality of different attributes. For example, to find all employees with an employee number equal to -their room number:

    Pat = #employee{emp_no = '$1', room_no = '$1', _ = '_'},
    -F = fun() -> mnesia:match_object(Pat) end,
    -Odd = mnesia:transaction(F).

    The function mnesia:match_object/3 lacks some important features that +their room number:

    Pat = #employee{emp_no = '$1', room_no = '$1', _ = '_'},
    +F = fun() -> mnesia:match_object(Pat) end,
    +Odd = mnesia:transaction(F).

    The function mnesia:match_object/3 lacks some important features that mnesia:select/3 have. For example, mnesia:match_object/3 can only return the matching records, and it cannot express constraints other -than equality. To find the names of the male employees on the second floor:

    MatchHead = #employee{name='$1', sex=male, room_no={'$2', '_'}, _='_'},
    -Guard = [{'>=', '$2', 220},{'<', '$2', 230}],
    +than equality. To find the names of the male employees on the second floor:

    MatchHead = #employee{name='$1', sex=male, room_no={'$2', '_'}, _='_'},
    +Guard = [{'>=', '$2', 220},{'<', '$2', 230}],
     Result = '$1',
    -mnesia:select(employee,[{MatchHead, Guard, [Result]}])

    The function select can be used to add more constraints and create output that +mnesia:select(employee,[{MatchHead, Guard, [Result]}])

    The function select can be used to add more constraints and create output that cannot be done with mnesia:match_object/3.

    The second argument to select is a MatchSpecification. A MatchSpecification is a list of MatchFunctions, where each MatchFunction consists of a tuple containing {MatchHead, MatchCondition, MatchBody}:

    • MatchHead is the same pattern as used in mnesia:match_object/3 described @@ -672,8 +672,8 @@

      {traverse, {select, MatchSpecification}} as an option to mnesia:table/2 the user can specify its own view of the table.

    If no options are specified, a read lock is acquired, 100 results are returned -in each chunk, and select is used to traverse the table, that is:

    mnesia:table(Tab) ->
    -    mnesia:table(Tab, [{n_objects, 100},{lock, read}, {traverse, select}]).

    The function mnesia:all_keys(Tab) returns all keys in a +in each chunk, and select is used to traverse the table, that is:

    mnesia:table(Tab) ->
    +    mnesia:table(Tab, [{n_objects, 100},{lock, read}, {traverse, select}]).

    The function mnesia:all_keys(Tab) returns all keys in a table.

    @@ -681,10 +681,10 @@

    Iteration

    Mnesia provides the following functions that iterate over all the records in a -table:

    mnesia:foldl(Fun, Acc0, Tab) -> NewAcc | transaction abort
    -mnesia:foldr(Fun, Acc0, Tab) -> NewAcc | transaction abort
    -mnesia:foldl(Fun, Acc0, Tab, LockType) -> NewAcc | transaction abort
    -mnesia:foldr(Fun, Acc0, Tab, LockType) -> NewAcc | transaction abort

    These functions iterate over the Mnesia table Tab and apply the function +table:

    mnesia:foldl(Fun, Acc0, Tab) -> NewAcc | transaction abort
    +mnesia:foldr(Fun, Acc0, Tab) -> NewAcc | transaction abort
    +mnesia:foldl(Fun, Acc0, Tab, LockType) -> NewAcc | transaction abort
    +mnesia:foldr(Fun, Acc0, Tab, LockType) -> NewAcc | transaction abort

    These functions iterate over the Mnesia table Tab and apply the function Fun to each record. Fun takes two arguments, the first is a record from the table, and the second is the accumulator. Fun returns a new accumulator.

    The first time Fun is applied, Acc0 is the second argument. The next time Fun is called, the return value from the previous call is used as the second @@ -695,35 +695,35 @@

    write lock is to be acquired.

    These functions can be used to find records in a table when it is impossible to write constraints for the function mnesia:match_object/3, or when you want to perform some action on certain records.

    For example, finding all the employees who have a salary less than 10 can look -as follows:

    find_low_salaries() ->
    +as follows:

    find_low_salaries() ->
       Constraint =
    -       fun(Emp, Acc) when Emp#employee.salary < 10 ->
    -              [Emp | Acc];
    -          (_, Acc) ->
    +       fun(Emp, Acc) when Emp#employee.salary < 10 ->
    +              [Emp | Acc];
    +          (_, Acc) ->
                   Acc
            end,
    -  Find = fun() -> mnesia:foldl(Constraint, [], employee) end,
    -  mnesia:transaction(Find).

    To raise the salary to 10 for everyone with a salary less than 10 and return the -sum of all raises:

    increase_low_salaries() ->
    +  Find = fun() -> mnesia:foldl(Constraint, [], employee) end,
    +  mnesia:transaction(Find).

    To raise the salary to 10 for everyone with a salary less than 10 and return the +sum of all raises:

    increase_low_salaries() ->
        Increase =
    -       fun(Emp, Acc) when Emp#employee.salary < 10 ->
    +       fun(Emp, Acc) when Emp#employee.salary < 10 ->
                   OldS = Emp#employee.salary,
    -              ok = mnesia:write(Emp#employee{salary = 10}),
    +              ok = mnesia:write(Emp#employee{salary = 10}),
                   Acc + 10 - OldS;
    -          (_, Acc) ->
    +          (_, Acc) ->
                   Acc
            end,
    -  IncLow = fun() -> mnesia:foldl(Increase, 0, employee, write) end,
    -  mnesia:transaction(IncLow).

    Many nice things can be done with the iterator functions but take some caution + IncLow = fun() -> mnesia:foldl(Increase, 0, employee, write) end, + mnesia:transaction(IncLow).

    Many nice things can be done with the iterator functions but take some caution about performance and memory use for large tables.

    Call these iteration functions on nodes that contain a replica of the table. Each call to the function Fun access the table and if the table resides on another node it generates much unnecessary network traffic.

    Mnesia also provides some functions that make it possible for the user to iterate over the table. The order of the iteration is unspecified if the table -is not of type ordered_set:

    mnesia:first(Tab) ->  Key | transaction abort
    -mnesia:last(Tab)  ->  Key | transaction abort
    -mnesia:next(Tab,Key)  ->  Key | transaction abort
    -mnesia:prev(Tab,Key)  ->  Key | transaction abort
    -mnesia:snmp_get_next_index(Tab,Index) -> {ok, NextIndex} | endOfTable

    The order of first/last and next/prev is only valid for ordered_set +is not of type ordered_set:

    mnesia:first(Tab) ->  Key | transaction abort
    +mnesia:last(Tab)  ->  Key | transaction abort
    +mnesia:next(Tab,Key)  ->  Key | transaction abort
    +mnesia:prev(Tab,Key)  ->  Key | transaction abort
    +mnesia:snmp_get_next_index(Tab,Index) -> {ok, NextIndex} | endOfTable

    The order of first/last and next/prev is only valid for ordered_set tables, they are synonyms for other tables. When the end of the table is reached, the special key '$end_of_table' is returned.

    If records are written and deleted during the traversal, use the function mnesia:foldl/3 or mnesia:foldr/3 with a write lock. Or the function diff --git a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap5.html b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap5.html index 684504e3db617..6db58aefb294b 100644 --- a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap5.html +++ b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap5.html @@ -167,9 +167,9 @@

    whether the data resides on the local node or on a remote node.

    Notice that the program runs slower if the data is located on a remote node.

  • The database can be reconfigured, and tables can be moved between nodes. These operations do not affect the user programs.

  • It has previously been shown that each table has a number of system attributes, such as index and type.

    Table attributes are specified when the table is created. For example, the -following function creates a table with two RAM replicas:

    mnesia:create_table(foo,
    -                    [{ram_copies, [N1, N2]},
    -                     {attributes, record_info(fields, foo)}]).

    Tables can also have the following properties, where each attribute has a list +following function creates a table with two RAM replicas:

    mnesia:create_table(foo,
    +                    [{ram_copies, [N1, N2]},
    +                     {attributes, record_info(fields, foo)}]).

    Tables can also have the following properties, where each attribute has a list of Erlang nodes as its value:

    • ram_copies. The value of the node list is a list of Erlang nodes, and a RAM replica of the table resides on each node in the list.

      Notice that no disc operations are performed when a program executes write operations to these replicas. However, if permanent RAM replicas are required, @@ -222,52 +222,52 @@

      searched for matching records.

      Notice that in ordered_set tables, the records are ordered per fragment, and the order is undefined in results returned by select and match_object, as well as first, next, prev and last.

      The following code illustrates how a Mnesia table is converted to be a -fragmented table and how more fragments are added later:

      Eshell V4.7.3.3  (abort with ^G)
      -(a@sam)1> mnesia:start().
      +fragmented table and how more fragments are added later:

      Eshell V4.7.3.3  (abort with ^G)
      +(a@sam)1> mnesia:start().
       ok
      -(a@sam)2> mnesia:system_info(running_db_nodes).
      -[b@sam,c@sam,a@sam]
      +(a@sam)2> mnesia:system_info(running_db_nodes).
      +[b@sam,c@sam,a@sam]
       (a@sam)3> Tab = dictionary.
       dictionary
      -(a@sam)4> mnesia:create_table(Tab, [{ram_copies, [a@sam, b@sam]}]).
      -{atomic,ok}
      -(a@sam)5> Write = fun(Keys) -> [mnesia:write({Tab,K,-K}) || K <- Keys], ok end.
      +(a@sam)4> mnesia:create_table(Tab, [{ram_copies, [a@sam, b@sam]}]).
      +{atomic,ok}
      +(a@sam)5> Write = fun(Keys) -> [mnesia:write({Tab,K,-K}) || K <- Keys], ok end.
       #Fun<erl_eval>
      -(a@sam)6> mnesia:activity(sync_dirty, Write, [lists:seq(1, 256)], mnesia_frag).
      +(a@sam)6> mnesia:activity(sync_dirty, Write, [lists:seq(1, 256)], mnesia_frag).
       ok
      -(a@sam)7> mnesia:change_table_frag(Tab, {activate, []}).
      -{atomic,ok}
      -(a@sam)8> mnesia:table_info(Tab, frag_properties).
      -[{base_table,dictionary},
      - {foreign_key,undefined},
      - {n_doubles,0},
      - {n_fragments,1},
      - {next_n_to_split,1},
      - {node_pool,[a@sam,b@sam,c@sam]}]
      -(a@sam)9> Info = fun(Item) -> mnesia:table_info(Tab, Item) end.
      +(a@sam)7> mnesia:change_table_frag(Tab, {activate, []}).
      +{atomic,ok}
      +(a@sam)8> mnesia:table_info(Tab, frag_properties).
      +[{base_table,dictionary},
      + {foreign_key,undefined},
      + {n_doubles,0},
      + {n_fragments,1},
      + {next_n_to_split,1},
      + {node_pool,[a@sam,b@sam,c@sam]}]
      +(a@sam)9> Info = fun(Item) -> mnesia:table_info(Tab, Item) end.
       #Fun<erl_eval>
      -(a@sam)10> Dist = mnesia:activity(sync_dirty, Info, [frag_dist], mnesia_frag).
      -[{c@sam,0},{a@sam,1},{b@sam,1}]
      -(a@sam)11> mnesia:change_table_frag(Tab, {add_frag, Dist}).
      -{atomic,ok}
      -(a@sam)12> Dist2 = mnesia:activity(sync_dirty, Info, [frag_dist], mnesia_frag).
      -[{b@sam,1},{c@sam,1},{a@sam,2}]
      -(a@sam)13> mnesia:change_table_frag(Tab, {add_frag, Dist2}).
      -{atomic,ok}
      -(a@sam)14> Dist3 = mnesia:activity(sync_dirty, Info, [frag_dist], mnesia_frag).
      -[{a@sam,2},{b@sam,2},{c@sam,2}]
      -(a@sam)15> mnesia:change_table_frag(Tab, {add_frag, Dist3}).
      -{atomic,ok}
      -(a@sam)16> Read = fun(Key) -> mnesia:read({Tab, Key}) end.
      +(a@sam)10> Dist = mnesia:activity(sync_dirty, Info, [frag_dist], mnesia_frag).
      +[{c@sam,0},{a@sam,1},{b@sam,1}]
      +(a@sam)11> mnesia:change_table_frag(Tab, {add_frag, Dist}).
      +{atomic,ok}
      +(a@sam)12> Dist2 = mnesia:activity(sync_dirty, Info, [frag_dist], mnesia_frag).
      +[{b@sam,1},{c@sam,1},{a@sam,2}]
      +(a@sam)13> mnesia:change_table_frag(Tab, {add_frag, Dist2}).
      +{atomic,ok}
      +(a@sam)14> Dist3 = mnesia:activity(sync_dirty, Info, [frag_dist], mnesia_frag).
      +[{a@sam,2},{b@sam,2},{c@sam,2}]
      +(a@sam)15> mnesia:change_table_frag(Tab, {add_frag, Dist3}).
      +{atomic,ok}
      +(a@sam)16> Read = fun(Key) -> mnesia:read({Tab, Key}) end.
       #Fun<erl_eval>
      -(a@sam)17> mnesia:activity(transaction, Read, [12], mnesia_frag).
      -[{dictionary,12,-12}]
      -(a@sam)18> mnesia:activity(sync_dirty, Info, [frag_size], mnesia_frag).
      -[{dictionary,64},
      - {dictionary_frag2,64},
      - {dictionary_frag3,64},
      - {dictionary_frag4,64}]
      -(a@sam)19>

      +(a@sam)17> mnesia:activity(transaction, Read, [12], mnesia_frag). +[{dictionary,12,-12}] +(a@sam)18> mnesia:activity(sync_dirty, Info, [frag_size], mnesia_frag). +[{dictionary,64}, + {dictionary_frag2,64}, + {dictionary_frag3,64}, + {dictionary_frag4,64}] +(a@sam)19>

      @@ -309,64 +309,64 @@

      This property can explicitly be set at table creation. Default is mnesia_frag_hash.

    • {hash_state, Term} - Enables a table-specific parameterization of a generic hash module. This property can explicitly be set at table creation. -Default is undefined.

      Eshell V4.7.3.3  (abort with ^G)
      -(a@sam)1> mnesia:start().
      +Default is undefined.

      Eshell V4.7.3.3  (abort with ^G)
      +(a@sam)1> mnesia:start().
       ok
      -(a@sam)2> PrimProps = [{n_fragments, 7}, {node_pool, [node()]}].
      -[{n_fragments,7},{node_pool,[a@sam]}]
      -(a@sam)3> mnesia:create_table(prim_dict,
      -                              [{frag_properties, PrimProps},
      -                               {attributes,[prim_key,prim_val]}]).
      -{atomic,ok}
      -(a@sam)4> SecProps = [{foreign_key, {prim_dict, sec_val}}].
      -[{foreign_key,{prim_dict,sec_val}}]
      -(a@sam)5> mnesia:create_table(sec_dict,
      -                              [{frag_properties, SecProps},
      -(a@sam)5>                      {attributes, [sec_key, sec_val]}]).
      -{atomic,ok}
      -(a@sam)6> Write = fun(Rec) -> mnesia:write(Rec) end.
      +(a@sam)2> PrimProps = [{n_fragments, 7}, {node_pool, [node()]}].
      +[{n_fragments,7},{node_pool,[a@sam]}]
      +(a@sam)3> mnesia:create_table(prim_dict,
      +                              [{frag_properties, PrimProps},
      +                               {attributes,[prim_key,prim_val]}]).
      +{atomic,ok}
      +(a@sam)4> SecProps = [{foreign_key, {prim_dict, sec_val}}].
      +[{foreign_key,{prim_dict,sec_val}}]
      +(a@sam)5> mnesia:create_table(sec_dict,
      +                              [{frag_properties, SecProps},
      +(a@sam)5>                      {attributes, [sec_key, sec_val]}]).
      +{atomic,ok}
      +(a@sam)6> Write = fun(Rec) -> mnesia:write(Rec) end.
       #Fun<erl_eval>
       (a@sam)7> PrimKey = 11.
       11
       (a@sam)8> SecKey = 42.
       42
      -(a@sam)9> mnesia:activity(sync_dirty, Write,
      -                          [{prim_dict, PrimKey, -11}], mnesia_frag).
      +(a@sam)9> mnesia:activity(sync_dirty, Write,
      +                          [{prim_dict, PrimKey, -11}], mnesia_frag).
       ok
      -(a@sam)10> mnesia:activity(sync_dirty, Write,
      -                           [{sec_dict, SecKey, PrimKey}], mnesia_frag).
      +(a@sam)10> mnesia:activity(sync_dirty, Write,
      +                           [{sec_dict, SecKey, PrimKey}], mnesia_frag).
       ok
      -(a@sam)11> mnesia:change_table_frag(prim_dict, {add_frag, [node()]}).
      -{atomic,ok}
      -(a@sam)12> SecRead = fun(PrimKey, SecKey) ->
      -               mnesia:read({sec_dict, PrimKey}, SecKey, read) end.
      +(a@sam)11> mnesia:change_table_frag(prim_dict, {add_frag, [node()]}).
      +{atomic,ok}
      +(a@sam)12> SecRead = fun(PrimKey, SecKey) ->
      +               mnesia:read({sec_dict, PrimKey}, SecKey, read) end.
       #Fun<erl_eval>
      -(a@sam)13> mnesia:activity(transaction, SecRead,
      -                           [PrimKey, SecKey], mnesia_frag).
      -[{sec_dict,42,11}]
      -(a@sam)14> Info = fun(Tab, Item) -> mnesia:table_info(Tab, Item) end.
      +(a@sam)13> mnesia:activity(transaction, SecRead,
      +                           [PrimKey, SecKey], mnesia_frag).
      +[{sec_dict,42,11}]
      +(a@sam)14> Info = fun(Tab, Item) -> mnesia:table_info(Tab, Item) end.
       #Fun<erl_eval>
      -(a@sam)15> mnesia:activity(sync_dirty, Info,
      -                           [prim_dict, frag_size], mnesia_frag).
      -[{prim_dict,0},
      - {prim_dict_frag2,0},
      - {prim_dict_frag3,0},
      - {prim_dict_frag4,1},
      - {prim_dict_frag5,0},
      - {prim_dict_frag6,0},
      - {prim_dict_frag7,0},
      - {prim_dict_frag8,0}]
      -(a@sam)16> mnesia:activity(sync_dirty, Info,
      -                           [sec_dict, frag_size], mnesia_frag).
      -[{sec_dict,0},
      - {sec_dict_frag2,0},
      - {sec_dict_frag3,0},
      - {sec_dict_frag4,1},
      - {sec_dict_frag5,0},
      - {sec_dict_frag6,0},
      - {sec_dict_frag7,0},
      - {sec_dict_frag8,0}]
      -(a@sam)17>

    +(a@sam)15> mnesia:activity(sync_dirty, Info, + [prim_dict, frag_size], mnesia_frag). +[{prim_dict,0}, + {prim_dict_frag2,0}, + {prim_dict_frag3,0}, + {prim_dict_frag4,1}, + {prim_dict_frag5,0}, + {prim_dict_frag6,0}, + {prim_dict_frag7,0}, + {prim_dict_frag8,0}] +(a@sam)16> mnesia:activity(sync_dirty, Info, + [sec_dict, frag_size], mnesia_frag). +[{sec_dict,0}, + {sec_dict_frag2,0}, + {sec_dict_frag3,0}, + {sec_dict_frag4,1}, + {sec_dict_frag5,0}, + {sec_dict_frag6,0}, + {sec_dict_frag7,0}, + {sec_dict_frag8,0}] +(a@sam)17>

    @@ -496,10 +496,10 @@

    table is ram_copies). The default for the application parameter is opt_disc.

    When schema_location is set to opt_disc, the function mnesia:change_table_copy_type/3 can be used to change the storage type of the -schema. This is illustrated as follows:

    1> mnesia:start().
    +schema. This is illustrated as follows:

    1> mnesia:start().
     ok
    -2> mnesia:change_table_copy_type(schema, node(), disc_copies).
    -{atomic, ok}

    Assuming that the call to mnesia:start/0 does not find any schema to read on +2> mnesia:change_table_copy_type(schema, node(), disc_copies). +{atomic, ok}

    Assuming that the call to mnesia:start/0 does not find any schema to read on the disc, Mnesia starts as a disc-less node, and then change it to a node that use the disc to store the schema locally.

    @@ -723,34 +723,34 @@

    a normal text editor) and later reloaded.

    These functions are much slower than the ordinary store and load functions of Mnesia. However, this is mainly intended for minor experiments and initial prototyping. The major advantage of these functions is that they are easy to -use.

    The format of the text file is as follows:

    {tables, [{Typename, [Options]},
    -{Typename2 ......}]}.
    +use.

    The format of the text file is as follows:

    {tables, [{Typename, [Options]},
    +{Typename2 ......}]}.
     
    -{Typename, Attribute1, Attribute2 ....}.
    -{Typename, Attribute1, Attribute2 ....}.

    Options is a list of {Key,Value} tuples conforming to the options that you +{Typename, Attribute1, Attribute2 ....}. +{Typename, Attribute1, Attribute2 ....}.

    Options is a list of {Key,Value} tuples conforming to the options that you can give to mnesia:create_table/2.

    For example, to start playing with a small database for healthy foods, enter the -following data into file FRUITS:

    {tables,
    - [{fruit, [{attributes, [name, color, taste]}]},
    -  {vegetable, [{attributes, [name, color, taste, price]}]}]}.
    +following data into file FRUITS:

    {tables,
    + [{fruit, [{attributes, [name, color, taste]}]},
    +  {vegetable, [{attributes, [name, color, taste, price]}]}]}.
     
     
    -{fruit, orange, orange, sweet}.
    -{fruit, apple, green, sweet}.
    -{vegetable, carrot, orange, carrotish, 2.55}.
    -{vegetable, potato, yellow, none, 0.45}.

    The following session with the Erlang shell shows how to load the FRUITS +{fruit, orange, orange, sweet}. +{fruit, apple, green, sweet}. +{vegetable, carrot, orange, carrotish, 2.55}. +{vegetable, potato, yellow, none, 0.45}.

    The following session with the Erlang shell shows how to load the FRUITS database:

    % erl
    -Erlang (BEAM) emulator version 4.9
    +Erlang (BEAM) emulator version 4.9
     
    -Eshell V4.9  (abort with ^G)
    -1> mnesia:load_textfile("FRUITS").
    +Eshell V4.9  (abort with ^G)
    +1> mnesia:load_textfile("FRUITS").
     New table fruit
     New table vegetable
    -{atomic,ok}
    -2> mnesia:info().
    +{atomic,ok}
    +2> mnesia:info().
     ---> Processes holding locks <---
     ---> Processes waiting for locks <---
    ----> Pending (remote) transactions <---
    ----> Active (local) transactions <---
    +---> Pending (remote) transactions <---
    +---> Active (local) transactions <---
     ---> Uncertain transactions <---
     ---> Active tables <---
     vegetable      : with 2 records occuping 299 words of mem
    @@ -759,17 +759,17 @@ 

    ===> System info in version "1.1", debug level = none <=== opt_disc. Directory "/var/tmp/Mnesia.nonode@nohost" is used. use fallback at restart = false -running db nodes = [nonode@nohost] -stopped db nodes = [] -remote = [] -ram_copies = [fruit,vegetable] -disc_copies = [schema] -disc_only_copies = [] -[{nonode@nohost,disc_copies}] = [schema] -[{nonode@nohost,ram_copies}] = [fruit,vegetable] +running db nodes = [nonode@nohost] +stopped db nodes = [] +remote = [] +ram_copies = [fruit,vegetable] +disc_copies = [schema] +disc_only_copies = [] +[{nonode@nohost,disc_copies}] = [schema] +[{nonode@nohost,ram_copies}] = [fruit,vegetable] 3 transactions committed, 0 aborted, 0 restarted, 2 logged to disc 0 held locks, 0 in queue; 0 local transactions, 0 remote -0 transactions waits for other nodes: [] +0 transactions waits for other nodes: [] ok 3>

    It can be seen that the DBMS was initiated from a regular text file.

    @@ -783,20 +783,20 @@

    relationships (manager, at_dep, in_proj). This is a normalized data model, which has some advantages over a non-normalized data model.

    It is more efficient to do a generalized search in a normalized database. Some operations are also easier to perform on a normalized data model. For example, -one project can easily be removed, as the following example illustrates:

    remove_proj(ProjName) ->
    -    F = fun() ->
    -                Ip = qlc:e(qlc:q([X || X <- mnesia:table(in_proj),
    -				       X#in_proj.proj_name == ProjName]
    -				)),
    -                mnesia:delete({project, ProjName}),
    -                del_in_projs(Ip)
    +one project can easily be removed, as the following example illustrates:

    remove_proj(ProjName) ->
    +    F = fun() ->
    +                Ip = qlc:e(qlc:q([X || X <- mnesia:table(in_proj),
    +				       X#in_proj.proj_name == ProjName]
    +				)),
    +                mnesia:delete({project, ProjName}),
    +                del_in_projs(Ip)
             end,
    -    mnesia:transaction(F).
    +    mnesia:transaction(F).
     
    -del_in_projs([Ip|Tail]) ->
    -    mnesia:delete_object(Ip),
    -    del_in_projs(Tail);
    -del_in_projs([]) ->
    +del_in_projs([Ip|Tail]) ->
    +    mnesia:delete_object(Ip),
    +    del_in_projs(Tail);
    +del_in_projs([]) ->
         done.

    In reality, data models are seldom fully normalized. A realistic alternative to a normalized database model would be a data model that is not even in first normal form. Mnesia is suitable for applications such as telecommunications, @@ -811,7 +811,7 @@

    this is the case, a drastically different data model without direct relationships can be chosen. You would then have only the records themselves, and different records could contain either direct references to other records, -or contain other records that are not part of the Mnesia schema.

    The following record definitions can be created:

    -record(employee, {emp_no,
    +or contain other records that are not part of the Mnesia schema.

    The following record definitions can be created:

    -record(employee, {emp_no,
     		   name,
     		   salary,
     		   sex,
    @@ -819,23 +819,23 @@ 

    room_no, dept, projects, - manager}). + manager}). --record(dept, {id, - name}). +-record(dept, {id, + name}). --record(project, {name, +-record(project, {name, number, - location}).

    A record that describes an employee can look as follows:

    Me = #employee{emp_no = 104732,
    +                  location}).

    A record that describes an employee can look as follows:

    Me = #employee{emp_no = 104732,
                    name = klacke,
                    salary = 7,
                    sex = male,
                    phone = 99586,
    -               room_no = {221, 015},
    +               room_no = {221, 015},
                    dept = 'B/SFR',
    -               projects = [erlang, mnesia, otp],
    -               manager = 114872},

    This model has only three different tables, and the employee records contain + projects = [erlang, mnesia, otp], + manager = 114872},

    This model has only three different tables, and the employee records contain references to other records. The record has the following references:

    • 'B/SFR' refers to a dept record.
    • [erlang, mnesia, otp] is a list of three direct references to three different projects records.
    • 114872 refers to another employee record.

    The Mnesia record identifiers ({Tab, Key}) can also be used as references. In this case, attribute dept would be set to value {dept, 'B/SFR'} instead @@ -845,14 +845,14 @@

    difficult to ensure that records do not contain dangling pointers to other non-existent, or deleted, records.

    The following code exemplifies a search with a non-normalized data model. To find all employees at department Dep with a salary higher than Salary, use -the following code:

    get_emps(Salary, Dep) ->
    -    Q = qlc:q(
    -          [E || E <- mnesia:table(employee),
    +the following code:

    get_emps(Salary, Dep) ->
    +    Q = qlc:q(
    +          [E || E <- mnesia:table(employee),
                     E#employee.salary > Salary,
    -                E#employee.dept == Dep]
    -	 ),
    -    F = fun() -> qlc:e(Q) end,
    -    transaction(F).

    This code is easier to write and to understand, and it also executes much + E#employee.dept == Dep] + ), + F = fun() -> qlc:e(Q) end, + transaction(F).

    This code is easier to write and to understand, and it also executes much faster.

    It is easy to show examples of code that executes faster if a non-normalized data model is used, instead of a normalized model. The main reason is that fewer tables are required. Therefore, data from different tables can more easily be diff --git a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap7.html b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap7.html index 574b2fc89c632..91150c51dd1cc 100644 --- a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap7.html +++ b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_chap7.html @@ -233,26 +233,26 @@

    for starting Mnesia:

    The following example shows how these tasks are performed:

    Step 1: Start an Erlang session and specify a Mnesia directory for the -database:

    % erl -sname klacke -mnesia dir '"/ldisc/scratch/klacke"'
    Erlang (BEAM) emulator version 4.9
    +database:

    % erl -sname klacke -mnesia dir '"/ldisc/scratch/klacke"'
    Erlang (BEAM) emulator version 4.9
     
    -Eshell V4.9  (abort with ^G)
    -(klacke@gin)1> mnesia:create_schema([node()]).
    +Eshell V4.9  (abort with ^G)
    +(klacke@gin)1> mnesia:create_schema([node()]).
     ok
    -(klacke@gin)2>
    +(klacke@gin)2>
     ^Z
     Suspended

    Step 2: You can inspect the Mnesia directory to see what files have been created:

    % ls -l /ldisc/scratch/klacke
     -rw-rw-r--   1 klacke   staff       247 Aug 12 15:06 FALLBACK.BUP

    The response shows that the file FALLBACK.BUP has been created. This is called a backup file, and it contains an initial schema. If more than one node in the function mnesia:create_schema/1 had been specified, identical backup files -would have been created on all nodes.

    Step 3: Start Mnesia:

    (klacke@gin)3>mnesia:start( ).
    +would have been created on all nodes.

    Step 3: Start Mnesia:

    (klacke@gin)3>mnesia:start( ).
     ok

    Step 4: You can see the following listing in the Mnesia directory:

    -rw-rw-r--   1 klacke   staff         86 May 26 19:03 LATEST.LOG
     -rw-rw-r--   1 klacke   staff      34507 May 26 19:03 schema.DAT

    The schema in the backup file FALLBACK.BUP has been used to generate the file schema.DAT. Since there are no other disc resident tables than the schema, no other data files were created. The file FALLBACK.BUP was removed after the successful "restoration". You also see some files that are for internal use by -Mnesia.

    Step 5: Create a table:

    (klacke@gin)4> mnesia:create_table(foo,[{disc_copies, [node()]}]).
    -{atomic,ok}

    Step 6: You can see the following listing in the Mnesia directory:

    % ls -l /ldisc/scratch/klacke
    +Mnesia.

    Step 5: Create a table:

    (klacke@gin)4> mnesia:create_table(foo,[{disc_copies, [node()]}]).
    +{atomic,ok}

    Step 6: You can see the following listing in the Mnesia directory:

    % ls -l /ldisc/scratch/klacke
     -rw-rw-r-- 1 klacke staff    86 May 26 19:07 LATEST.LOG
     -rw-rw-r-- 1 klacke staff    94 May 26 19:07 foo.DCD
     -rw-rw-r-- 1 klacke staff  6679 May 26 19:07 schema.DAT

    The file foo.DCD has been created. This file will eventually store all data @@ -296,11 +296,11 @@

    the Mnesia data files. For example, dets contains the function dets:traverse/2, which can be used to view the contents of a Mnesia DAT file. However, this can only be done when Mnesia is not running. So, to view -the schema file, do as follows;

    {ok, N} = dets:open_file(schema, [{file, "./schema.DAT"},{repair,false},
    -{keypos, 2}]),
    -F = fun(X) -> io:format("~p~n", [X]), continue end,
    -dets:traverse(N, F),
    -dets:close(N).

    Warning

    The DAT files must always be opened with option {repair, false}. This +the schema file, do as follows;

    {ok, N} = dets:open_file(schema, [{file, "./schema.DAT"},{repair,false},
    +{keypos, 2}]),
    +F = fun(X) -> io:format("~p~n", [X]), continue end,
    +dets:traverse(N, F),
    +dets:close(N).

    Warning

    The DAT files must always be opened with option {repair, false}. This ensures that these files are not automatically repaired. Without this option, the database can become inconsistent, because Mnesia can believe that the files were properly closed. For information about configuration parameter @@ -534,40 +534,40 @@

    located first in the backup.

    The schema itself is a table and is possibly included in the backup. Each node where the schema table resides is regarded as a db_node.

    The following example shows how mnesia:traverse_backup can be used to rename a -db_node in a backup file:

    change_node_name(Mod, From, To, Source, Target) ->
    +db_node in a backup file:

    change_node_name(Mod, From, To, Source, Target) ->
         Switch =
    -        fun(Node) when Node == From -> To;
    -           (Node) when Node == To -> throw({error, already_exists});
    -           (Node) -> Node
    +        fun(Node) when Node == From -> To;
    +           (Node) when Node == To -> throw({error, already_exists});
    +           (Node) -> Node
             end,
         Convert =
    -        fun({schema, db_nodes, Nodes}, Acc) ->
    -                {[{schema, db_nodes, lists:map(Switch,Nodes)}], Acc};
    -           ({schema, version, Version}, Acc) ->
    -                {[{schema, version, Version}], Acc};
    -           ({schema, cookie, Cookie}, Acc) ->
    -                {[{schema, cookie, Cookie}], Acc};
    -           ({schema, Tab, CreateList}, Acc) ->
    -                Keys = [ram_copies, disc_copies, disc_only_copies],
    +        fun({schema, db_nodes, Nodes}, Acc) ->
    +                {[{schema, db_nodes, lists:map(Switch,Nodes)}], Acc};
    +           ({schema, version, Version}, Acc) ->
    +                {[{schema, version, Version}], Acc};
    +           ({schema, cookie, Cookie}, Acc) ->
    +                {[{schema, cookie, Cookie}], Acc};
    +           ({schema, Tab, CreateList}, Acc) ->
    +                Keys = [ram_copies, disc_copies, disc_only_copies],
                     OptSwitch =
    -                    fun({Key, Val}) ->
    -                            case lists:member(Key, Keys) of
    -                                true -> {Key, lists:map(Switch, Val)};
    -                                false-> {Key, Val}
    +                    fun({Key, Val}) ->
    +                            case lists:member(Key, Keys) of
    +                                true -> {Key, lists:map(Switch, Val)};
    +                                false-> {Key, Val}
                                 end
                         end,
    -                {[{schema, Tab, lists:map(OptSwitch, CreateList)}], Acc};
    -           (Other, Acc) ->
    -                {[Other], Acc}
    +                {[{schema, Tab, lists:map(OptSwitch, CreateList)}], Acc};
    +           (Other, Acc) ->
    +                {[Other], Acc}
             end,
    -    mnesia:traverse_backup(Source, Mod, Target, Mod, Convert, switched).
    +    mnesia:traverse_backup(Source, Mod, Target, Mod, Convert, switched).
     
    -view(Source, Mod) ->
    -    View = fun(Item, Acc) ->
    -                   io:format("~p.~n",[Item]),
    -                   {[Item], Acc + 1}
    +view(Source, Mod) ->
    +    View = fun(Item, Acc) ->
    +                   io:format("~p.~n",[Item]),
    +                   {[Item], Acc + 1}
                end,
    -    mnesia:traverse_backup(Source, Mod, dummy, read_only, View, 0).

    + mnesia:traverse_backup(Source, Mod, dummy, read_only, View, 0).

    diff --git a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_registry.html b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_registry.html index 3b13368697448..9925800caf436 100644 --- a/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_registry.html +++ b/prs/8803/lib/mnesia-4.23.2/doc/html/mnesia_registry.html @@ -258,8 +258,8 @@

    create_table(Tab, Opt)

    Warning

    This function is deprecated. Do not use it.

    A wrapper function for mnesia:create_table/2, which creates a table (if there is no existing table) with an appropriate set of attributes. The attributes and TabDef are forwarded to mnesia:create_table/2. For example, if the table -is to reside as disc_only_copies on all nodes, a call looks as follows:

              TabDef = [{{disc_only_copies, node()|nodes()]}],
    -          mnesia_registry:create_table(my_reg, TabDef)
    +is to reside as disc_only_copies on all nodes, a call looks as follows:

              TabDef = [{{disc_only_copies, node()|nodes()]}],
    +          mnesia_registry:create_table(my_reg, TabDef)
    diff --git a/prs/8803/lib/observer-2.16/doc/html/observer.epub b/prs/8803/lib/observer-2.16/doc/html/observer.epub index 4d1d32a53f617..8c7a0923c4c7b 100644 Binary files a/prs/8803/lib/observer-2.16/doc/html/observer.epub and b/prs/8803/lib/observer-2.16/doc/html/observer.epub differ diff --git a/prs/8803/lib/observer-2.16/doc/html/ttb.html b/prs/8803/lib/observer-2.16/doc/html/ttb.html index a48052ee5be25..2f107caaa4afd 100644 --- a/prs/8803/lib/observer-2.16/doc/html/ttb.html +++ b/prs/8803/lib/observer-2.16/doc/html/ttb.html @@ -1908,13 +1908,13 @@

    seq_trigger_ms(Flags)

    is "contaminated" with token seq_trace.

    If Flags = all, all possible flags are set.

    The possible values for SeqTraceFlag are available in seq_trace.

    For a description of the match_spec() syntax, see section Match Specifications in Erlang in ERTS, which explains the general match specification "language".

    Note

    The system tracer for sequential tracing is automatically initiated by ttb -when a trace port is started with ttb:tracer/0,1,2.

    An example of how to use function seq_trigger_ms/0,1 follows:

    (tiger@durin)5> ttb:tracer().
    -{ok,[tiger@durin]}
    -(tiger@durin)6> ttb:p(all,call).
    -{ok,{[all],[call]}}
    -(tiger@durin)7> ttb:tp(mod,func,ttb:seq_trigger_ms()).
    -{ok,[{matched,1},{saved,1}]}
    -(tiger@durin)8>

    Whenever mod:func(...) is called after this, token seq_trace is set on the +when a trace port is started with ttb:tracer/0,1,2.

    An example of how to use function seq_trigger_ms/0,1 follows:

    (tiger@durin)5> ttb:tracer().
    +{ok,[tiger@durin]}
    +(tiger@durin)6> ttb:p(all,call).
    +{ok,{[all],[call]}}
    +(tiger@durin)7> ttb:tp(mod,func,ttb:seq_trigger_ms()).
    +{ok,[{matched,1},{saved,1}]}
    +(tiger@durin)8>

    Whenever mod:func(...) is called after this, token seq_trace is set on the executing process.

    @@ -1953,14 +1953,14 @@

    start_trace(Nodes, Patterns, FlagSpec, Trac

    start_trace(Nodes, Patterns, FlagSpec, Opts) -> Result

    This function is a shortcut allowing to start a trace with one command. Each tuple in Patterns is converted to a list, which in turn is passed to -ttb:tpl/2,3,4.

    The call:

    > ttb:start_trace([Node, OtherNode],
    -                  [{mod, foo, []}, {mod, bar, 2}],
    -                  {all, call},
    -                  [{file, File}, {handler,{fun myhandler/4, S}}]).

    is equivalent to:

    > ttb:start_trace([Node, OtherNode],
    -                  [{file, File}, {handler,{fun myhandler/4, S}}]),
    -ttb:tpl(mod, foo, []),
    -ttb:tpl(mod, bar, 2, []),
    -ttb:p(all, call).
    +ttb:tpl/2,3,4.

    The call:

    > ttb:start_trace([Node, OtherNode],
    +                  [{mod, foo, []}, {mod, bar, 2}],
    +                  {all, call},
    +                  [{file, File}, {handler,{fun myhandler/4, S}}]).

    is equivalent to:

    > ttb:start_trace([Node, OtherNode],
    +                  [{file, File}, {handler,{fun myhandler/4, S}}]),
    +ttb:tpl(mod, foo, []),
    +ttb:tpl(mod, bar, 2, []),
    +ttb:p(all, call).
    diff --git a/prs/8803/lib/observer-2.16/doc/html/ttb_ug.html b/prs/8803/lib/observer-2.16/doc/html/ttb_ug.html index 4a6df2319bb2a..adedd50cf9f41 100644 --- a/prs/8803/lib/observer-2.16/doc/html/ttb_ug.html +++ b/prs/8803/lib/observer-2.16/doc/html/ttb_ug.html @@ -172,56 +172,56 @@

    Tracing Local Node from Erlang Shell

    -

    The following small module is used in the subsequent example:

    -module(m).
    --export([f/0]).
    -f() ->
    +

    The following small module is used in the subsequent example:

    -module(m).
    +-export([f/0]).
    +f() ->
        receive
    -      From when is_pid(From) ->
    -         Now = erlang:now(),
    -         From ! {self(),Now}
    +      From when is_pid(From) ->
    +         Now = erlang:now(),
    +         From ! {self(),Now}
        end.

    The following example shows the basic use of ttb from the Erlang shell. Default options are used both for starting the tracer and for formatting (the custom fetch directory is however provided). This gives a trace log named Node-ttb in the newly created directory, where Node is the node name. The default handler prints the formatted trace messages in the shell:

    (tiger@durin)47> %% First I spawn a process running my test function
    -(tiger@durin)47> Pid = spawn(m,f,[]).
    +(tiger@durin)47> Pid = spawn(m,f,[]).
     <0.125.0>
    -(tiger@durin)48>
    +(tiger@durin)48>
     (tiger@durin)48> %% Then I start a tracer...
    -(tiger@durin)48> ttb:tracer().
    -{ok,[tiger@durin]}
    -(tiger@durin)49>
    +(tiger@durin)48> ttb:tracer().
    +{ok,[tiger@durin]}
    +(tiger@durin)49>
     (tiger@durin)49> %% and activate the new process for tracing
     (tiger@durin)49> %% function calls and sent messages.
    -(tiger@durin)49> ttb:p(Pid,[call,send]).
    -{ok,[{<0.125.0>,[{matched,tiger@durin,1}]}]}
    -(tiger@durin)50>
    +(tiger@durin)49> ttb:p(Pid,[call,send]).
    +{ok,[{<0.125.0>,[{matched,tiger@durin,1}]}]}
    +(tiger@durin)50>
     (tiger@durin)50> %% Here I set a trace pattern on erlang:now/0
     (tiger@durin)50> %% The trace pattern is a simple match spec
     (tiger@durin)50> %% indicating that the return value should be
     (tiger@durin)50> %% traced. Refer to the reference_manual for
     (tiger@durin)50> %% the full list of match spec shortcuts
     (tiger@durin)50> %% available.
    -(tiger@durin)51> ttb:tp(erlang,now,return).
    -{ok,[{matched,tiger@durin,1},{saved,1}]}
    -(tiger@durin)52>
    +(tiger@durin)51> ttb:tp(erlang,now,return).
    +{ok,[{matched,tiger@durin,1},{saved,1}]}
    +(tiger@durin)52>
     (tiger@durin)52> %% I run my test (i.e. send a message to
     (tiger@durin)52> %% my new process)
    -(tiger@durin)52> Pid ! self().
    +(tiger@durin)52> Pid ! self().
     <0.72.0>
    -(tiger@durin)53>
    +(tiger@durin)53>
     (tiger@durin)53> %% And then I have to stop ttb in order to flush
     (tiger@durin)53> %% the trace port buffer
    -(tiger@durin)53> ttb:stop([return, {fetch_dir, "fetch"}]).
    -{stopped, "fetch"}
    -(tiger@durin)54>
    +(tiger@durin)53> ttb:stop([return, {fetch_dir, "fetch"}]).
    +{stopped, "fetch"}
    +(tiger@durin)54>
     (tiger@durin)54> %% Finally I format my trace log
    -(tiger@durin)54> ttb:format("fetch").
    -({<0.125.0>,{m,f,0},tiger@durin}) call erlang:now()
    -({<0.125.0>,{m,f,0},tiger@durin}) returned from erlang:now/0 ->
    -{1031,133451,667611}
    -({<0.125.0>,{m,f,0},tiger@durin}) <0.72.0> !
    -{<0.125.0>,{1031,133451,667611}}
    +(tiger@durin)54> ttb:format("fetch").
    +({<0.125.0>,{m,f,0},tiger@durin}) call erlang:now()
    +({<0.125.0>,{m,f,0},tiger@durin}) returned from erlang:now/0 ->
    +{1031,133451,667611}
    +({<0.125.0>,{m,f,0},tiger@durin}) <0.72.0> !
    +{<0.125.0>,{1031,133451,667611}}
     ok

    @@ -229,65 +229,65 @@

    Build Your Own Tool

    The following example shows a simple tool for "debug tracing", that is, tracing -of function calls with return values:

    -module(mydebug).
    --export([start/0,trc/1,stop/0,format/1]).
    --export([print/4]).
    +of function calls with return values:

    -module(mydebug).
    +-export([start/0,trc/1,stop/0,format/1]).
    +-export([print/4]).
     %% Include ms_transform.hrl so that I can use dbg:fun2ms/2 to
     %% generate match specifications.
    --include_lib("stdlib/include/ms_transform.hrl").
    +-include_lib("stdlib/include/ms_transform.hrl").
     %%% -------------Tool API-------------
     %%% ----------------------------------
     %%% Star the "mydebug" tool
    -start() ->
    +start() ->
         %% The options specify that the binary log shall be named
         %% <Node>-debug_log and that the print/4 function in this
         %% module shall be used as format handler
    -    ttb:tracer(all,[{file,"debug_log"},{handler,{{?MODULE,print},0}}]),
    +    ttb:tracer(all,[{file,"debug_log"},{handler,{{?MODULE,print},0}}]),
         %% All processes (existing and new) shall trace function calls
         %% We want trace messages to be sorted upon format, which requires
         %% timestamp flag. The flag is however enabled by default in ttb.
    -    ttb:p(all,call).
    +    ttb:p(all,call).
     
     %%% Set trace pattern on function(s)
    -trc(M) when is_atom(M) ->
    -    trc({M,'_','_'});
    -trc({M,F}) when is_atom(M), is_atom(F) ->
    -    trc({M,F,'_'});
    -trc({M,F,_A}=MFA) when is_atom(M), is_atom(F) ->
    +trc(M) when is_atom(M) ->
    +    trc({M,'_','_'});
    +trc({M,F}) when is_atom(M), is_atom(F) ->
    +    trc({M,F,'_'});
    +trc({M,F,_A}=MFA) when is_atom(M), is_atom(F) ->
         %% This match spec shortcut specifies that return values shall
         %% be traced.
    -    MatchSpec = dbg:fun2ms(fun(_) -> return_trace() end),
    -    ttb:tpl(MFA,MatchSpec).
    +    MatchSpec = dbg:fun2ms(fun(_) -> return_trace() end),
    +    ttb:tpl(MFA,MatchSpec).
     
     %%% Format a binary trace log
    -format(Dir) ->
    -    ttb:format(Dir).
    +format(Dir) ->
    +    ttb:format(Dir).
     
     %%% Stop the "mydebug" tool
    -stop() ->
    -    ttb:stop(return).
    +stop() ->
    +    ttb:stop(return).
     
     %%% --------Internal functions--------
     %%% ----------------------------------
     %%% Format handler
    -print(_Out,end_of_trace,_TI,N) ->
    +print(_Out,end_of_trace,_TI,N) ->
         N;
    -print(Out,Trace,_TI,N) ->
    -    do_print(Out,Trace,N),
    +print(Out,Trace,_TI,N) ->
    +    do_print(Out,Trace,N),
         N+1.
     
    -do_print(Out,{trace_ts,P,call,{M,F,A},Ts},N) ->
    -    io:format(Out,
    +do_print(Out,{trace_ts,P,call,{M,F,A},Ts},N) ->
    +    io:format(Out,
                   "~w: ~w, ~w:~n"
                   "Call      : ~w:~w/~w~n"
                   "Arguments :~p~n~n",
    -              [N,Ts,P,M,F,length(A),A]);
    -do_print(Out,{trace_ts,P,return_from,{M,F,A},R,Ts},N) ->
    -    io:format(Out,
    +              [N,Ts,P,M,F,length(A),A]);
    +do_print(Out,{trace_ts,P,return_from,{M,F,A},R,Ts},N) ->
    +    io:format(Out,
                   "~w: ~w, ~w:~n"
                   "Return from  : ~w:~w/~w~n"
                   "Return value :~p~n~n",
    -              [N,Ts,P,M,F,A,R]).

    To distinguish trace logs produced with this tool from other logs, option file + [N,Ts,P,M,F,A,R]).

    To distinguish trace logs produced with this tool from other logs, option file is used in tracer/2. The logs are therefore fetched to a directory named ttb_upload_debug_log-YYYYMMDD-HHMMSS

    By using option handler when starting the tracer, the information about how to format the file is stored in the trace information file (.ti). This is not @@ -319,9 +319,9 @@

    If the traced node is diskless, ttb must be started from a trace control node with disk access, and option file must be specified to function tracer/2 -with value {local, File}, for example:

    (trace_control@durin)1> ttb:tracer(mynode@diskless,
    -                                   {file,{local,{wrap,"mytrace"}}}).
    -{ok,[mynode@diskless]}

    +with value {local, File}, for example:

    (trace_control@durin)1> ttb:tracer(mynode@diskless,
    +                                   {file,{local,{wrap,"mytrace"}}}).
    +{ok,[mynode@diskless]}

    @@ -341,10 +341,10 @@

    Opts as argument.

    The timer is started with ttb:p/2, so any trace patterns must be set up in advance. ttb:start_trace/4 always sets up all patterns before invoking ttb:p/2.

    The following example shows how to set up a trace that is automatically stopped -and formatted after 5 seconds:

    (tiger@durin)1> ttb:start_trace([node()],
    -                                [{erlang, now,[]}],
    -                                {all, call},
    -                                [{timer, {5000, format}}]).

    Note

    Because of network and processing delays, the period of tracing is +and formatted after 5 seconds:

    (tiger@durin)1> ttb:start_trace([node()],
    +                                [{erlang, now,[]}],
    +                                {all, call},
    +                                [{timer, {5000, format}}]).

    Note

    Because of network and processing delays, the period of tracing is approximate.

    @@ -361,22 +361,22 @@

    once overload protection is activated in one of the traced nodes. This is to avoid trace setup being inconsistent between nodes.

    Module:Function provided with option overload must handle three calls: init, check, and stop. init and stop allow some setup and teardown -required by the check. An overload check module can look as follows:

    -module(overload).
    --export([check/1]).
    -
    -check(init) ->
    -    Pid = sophisticated_module:start(),
    -    put(pid, Pid);
    -check(check) ->
    -    get(pid) ! is_overloaded,
    +required by the check. An overload check module can look as follows:

    -module(overload).
    +-export([check/1]).
    +
    +check(init) ->
    +    Pid = sophisticated_module:start(),
    +    put(pid, Pid);
    +check(check) ->
    +    get(pid) ! is_overloaded,
         receive
             Reply ->
                 Reply
         after 5000 ->
                 true
         end;
    -check(stop) ->
    -    get(pid) ! stop.

    Note

    check is always called by the same process, so put and get are possible.

    +check(stop) -> + get(pid) ! stop.

    Note

    check is always called by the same process, so put and get are possible.

    @@ -397,24 +397,24 @@

    behaviour (that is, on diskless nodes) by specifying their own module to handle autostart data storage and retrieval (ttb_autostart_module environment variable of runtime_tools). For information about the API, see module ttb. -The following example shows the default handler:

    -module(ttb_autostart).
    --export([read_config/0,
    +The following example shows the default handler:

    -module(ttb_autostart).
    +-export([read_config/0,
              write_config/1,
    -         delete_config/0]).
    +         delete_config/0]).
     
    --define(AUTOSTART_FILENAME, "ttb_autostart.bin").
    +-define(AUTOSTART_FILENAME, "ttb_autostart.bin").
     
    -delete_config() ->
    -    file:delete(?AUTOSTART_FILENAME).
    +delete_config() ->
    +    file:delete(?AUTOSTART_FILENAME).
     
    -read_config() ->
    -    case file:read_file(?AUTOSTART_FILENAME) of
    -        {ok, Data} -> {ok, binary_to_term(Data)};
    +read_config() ->
    +    case file:read_file(?AUTOSTART_FILENAME) of
    +        {ok, Data} -> {ok, binary_to_term(Data)};
             Error      -> Error
         end.
     
    -write_config(Data) ->
    -    file:write_file(?AUTOSTART_FILENAME, term_to_binary(Data)).

    Note

    Remember that file trace ports buffer the data by default. If the node +write_config(Data) -> + file:write_file(?AUTOSTART_FILENAME, term_to_binary(Data)).

    Note

    Remember that file trace ports buffer the data by default. If the node crashes, trace messages are not flushed to the binary log. If the risk of failure is high, it can be a good idea to flush the buffers every now and then automatically. Passing {flush, MSec} as an option of ttb:tracer/2 flushes @@ -483,22 +483,22 @@

    default handler is used, which prints each trace message as a text line.

  • disable_sort - Indicates that the logs are not to be merged according to time-stamp, but processed one file after another (this can be a bit faster).

  • A format handler is a fun taking four arguments. This fun is called for each trace message in the binary log(s). A simple example that only prints each trace -message can be as follows:

    fun(Fd, Trace, _TraceInfo, State) ->
    -   io:format(Fd, "Trace: ~p~n", [Trace]),
    +message can be as follows:

    fun(Fd, Trace, _TraceInfo, State) ->
    +   io:format(Fd, "Trace: ~p~n", [Trace]),
        State
     end.

    Here, Fd is the file descriptor for the destination file, or the atom standard_io. _TraceInfo contains information from the trace information file (see section Trace Information and File .ti). State is a state variable for the format handler fun. The initial value of variable -State is specified with the handler option, for example:

    ttb:format("tiger@durin-ttb", [{handler, {{Mod,Fun}, initial_state}}])
    +State is specified with the handler option, for example:

    ttb:format("tiger@durin-ttb", [{handler, {{Mod,Fun}, initial_state}}])
                                                          ^^^^^^^^^^^^^

    Another format handler can be used to calculate the time spent by the garbage -collector:

    fun(_Fd,{trace_ts,P,gc_start,_Info,StartTs},_TraceInfo,State) ->
    -      [{P,StartTs}|State];
    -   (Fd,{trace_ts,P,gc_end,_Info,EndTs},_TraceInfo,State) ->
    -      {value,{P,StartTs}} = lists:keysearch(P,1,State),
    -      Time = diff(StartTs,EndTs),
    -      io:format("GC in process ~w: ~w milliseconds~n", [P,Time]),
    -      State -- [{P,StartTs}]
    +collector:

    fun(_Fd,{trace_ts,P,gc_start,_Info,StartTs},_TraceInfo,State) ->
    +      [{P,StartTs}|State];
    +   (Fd,{trace_ts,P,gc_end,_Info,EndTs},_TraceInfo,State) ->
    +      {value,{P,StartTs}} = lists:keysearch(P,1,State),
    +      Time = diff(StartTs,EndTs),
    +      io:format("GC in process ~w: ~w milliseconds~n", [P,Time]),
    +      State -- [{P,StartTs}]
     end

    A more refined version of this format handler is function handle_gc/4 in module multitrace.erl included in directory src of the Observer application.

    The trace message is passed as the second argument (Trace). The possible values of Trace are the following:

    • All trace messages described in erlang:trace/3
    • {drop, N} if IP tracer is used (see dbg:trace_port/2)
    • end_of_trace received once when all trace messages are processed

    By giving the format handler ttb:get_et_handler(), @@ -508,19 +508,19 @@

    directory, but analyze single files instead. To do so, a single file (or list of files) must be passed as the first argument to format/1,2.

    Wrap logs can be formatted one by one or all at once. To format one of the wrap logs in a set, specify the exact file name. To format the whole set of wrap -logs, specify the name with * instead of the wrap count.

    Example:

    Start tracing:

    (tiger@durin)1> ttb:tracer(node(),{file,{wrap,"trace"}}).
    -{ok,[tiger@durin]}
    -(tiger@durin)2> ttb:p(...)
    +logs, specify the name with * instead of the wrap count.

    Example:

    Start tracing:

    (tiger@durin)1> ttb:tracer(node(),{file,{wrap,"trace"}}).
    +{ok,[tiger@durin]}
    +(tiger@durin)2> ttb:p(...)
     ...

    This gives a set of binary logs, for example:

    tiger@durin-trace.0.wrp
     tiger@durin-trace.1.wrp
     tiger@durin-trace.2.wrp
    -...

    Format the whole set of logs:

    1> ttb:format("tiger@durin-trace.*.wrp").
    +...

    Format the whole set of logs:

    1> ttb:format("tiger@durin-trace.*.wrp").
     ....
     ok
    -2>

    Format only the first log:

    1> ttb:format("tiger@durin-trace.0.wrp").
    +2>

    Format only the first log:

    1> ttb:format("tiger@durin-trace.0.wrp").
     ....
     ok
    -2>

    To merge all wrap logs from two nodes:

    1> ttb:format(["tiger@durin-trace.*.wrp","lion@durin-trace.*.wrp"]).
    +2>

    To merge all wrap logs from two nodes:

    1> ttb:format(["tiger@durin-trace.*.wrp","lion@durin-trace.*.wrp"]).
     ....
     ok
     2>

    @@ -547,8 +547,8 @@

    obtained using both the call and return_to flags when tracing. Notice that flag return_to only works with local call trace, that is, when trace patterns are set with ttb:tpl.

    The same result can be obtained by using the flag call only and setting a -match specification on local or global function calls as follows:

    1> dbg:fun2ms(fun(_) -> return_trace(),message(caller()) end).
    -[{'_',[],[{return_trace},{message,{caller}}]}]

    This must however be done with care, as function {return_trace} in the match +match specification on local or global function calls as follows:

    1> dbg:fun2ms(fun(_) -> return_trace(),message(caller()) end).
    +[{'_',[],[{return_trace},{message,{caller}}]}]

    This must however be done with care, as function {return_trace} in the match specification destroys tail recursiveness.

    The modules filter shows each module as a vertical line in the sequence diagram. External function calls/returns are shown as interactions between modules, and internal function calls/returns are shown as activities within a @@ -556,42 +556,42 @@

    diagram. A function calling itself is shown as an activity within a function, and all other function calls are shown as interactions between functions.

    The mods_and_procs and funcs_and_procs filters are equivalent to the modules and functions filters respectively, except that each module or -function can have many vertical lines, one for each process it resides on.

    In the following example, modules foo and bar are used:

    -module(foo).
    --export([start/0,go/0]).
    +function can have many vertical lines, one for each process it resides on.

    In the following example, modules foo and bar are used:

    -module(foo).
    +-export([start/0,go/0]).
     
    -start() ->
    -    spawn(?MODULE, go, []).
    +start() ->
    +    spawn(?MODULE, go, []).
     
    -go() ->
    +go() ->
         receive
             stop ->
                 ok;
             go ->
    -            bar:f1(),
    -            go()
    -    end.
    -module(bar).
    --export([f1/0,f3/0]).
    -f1() ->
    -    f2(),
    +            bar:f1(),
    +            go()
    +    end.
    -module(bar).
    +-export([f1/0,f3/0]).
    +f1() ->
    +    f2(),
         ok.
    -f2() ->
    -    spawn(?MODULE,f3,[]).
    -f3() ->
    +f2() ->
    +    spawn(?MODULE,f3,[]).
    +f3() ->
         ok.

    Setting up the trace:

    (tiger@durin)1> %%First we retrieve the Pid to limit traced processes set
    -(tiger@durin)1> Pid = foo:start().
    +(tiger@durin)1> Pid = foo:start().
     (tiger@durin)2> %%Now we set up tracing
    -(tiger@durin)2> ttb:tracer().
    -(tiger@durin)3> ttb:p(Pid, [call, return_to, procs, set_on_spawn]).
    -(tiger@durin)4> ttb:tpl(bar, []).
    +(tiger@durin)2> ttb:tracer().
    +(tiger@durin)3> ttb:p(Pid, [call, return_to, procs, set_on_spawn]).
    +(tiger@durin)4> ttb:tpl(bar, []).
     (tiger@durin)5> %%Invoke our test function and see output with et viewer
     (tiger@durin)5> Pid ! go.
    -(tiger@durin)6> ttb:stop({format, {handler, ttb:get_et_handler()}}).

    This renders a result similar to the following:

    Filter: "processes"

    Filter: "mods_and_procs"

    Notice that function ttb:start_trace/4 can be used as help as follows:

    (tiger@durin)1> Pid = foo:start().
    -(tiger@durin)2> ttb:start_trace([node()],
    -                                [{bar,[]}],
    -                                {Pid, [call, return_to, procs, set_on_spawn]}
    -                                {handler, ttb:get_et_handler()}).
    +(tiger@durin)6> ttb:stop({format, {handler, ttb:get_et_handler()}}).

    This renders a result similar to the following:

    Filter: "processes"

    Filter: "mods_and_procs"

    Notice that function ttb:start_trace/4 can be used as help as follows:

    (tiger@durin)1> Pid = foo:start().
    +(tiger@durin)2> ttb:start_trace([node()],
    +                                [{bar,[]}],
    +                                {Pid, [call, return_to, procs, set_on_spawn]}
    +                                {handler, ttb:get_et_handler()}).
     (tiger@durin)3> Pid ! go.
    -(tiger@durin)4> ttb:stop(format).

    +(tiger@durin)4> ttb:stop(format).

    @@ -632,76 +632,76 @@

    of {Module,Function,Args}.

    Any existing file ConfigFile is deleted and a new file is created when write_config/2 is called. Option append can be used to add something at the end of an existing configuration file, for example, -ttb:write_config(ConfigFile,What,[append]).

    Example:

    See the content of the history buffer:

    (tiger@durin)191> ttb:tracer().
    -{ok,[tiger@durin]}
    -(tiger@durin)192> ttb:p(self(),[garbage_collection,call]).
    -{ok,{[<0.1244.0>],[garbage_collection,call]}}
    -(tiger@durin)193> ttb:tp(ets,new,2,[]).
    -{ok,[{matched,1}]}
    -(tiger@durin)194> ttb:list_history().
    -[{1,{ttb,tracer,[tiger@durin,[]]}},
    - {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
    - {3,{ttb,tp,[ets,new,2,[]]}}]

    Execute an entry from the history buffer:

    (tiger@durin)195> ttb:ctp(ets,new,2).
    -{ok,[{matched,1}]}
    -(tiger@durin)196> ttb:list_history().
    -[{1,{ttb,tracer,[tiger@durin,[]]}},
    - {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
    - {3,{ttb,tp,[ets,new,2,[]]}},
    - {4,{ttb,ctp,[ets,new,2]}}]
    -(tiger@durin)197> ttb:run_history(3).
    -ttb:tp(ets,new,2,[]) ->
    -{ok,[{matched,1}]}

    Write the content of the history buffer to a configuration file:

    (tiger@durin)198> ttb:write_config("myconfig",all).
    +ttb:write_config(ConfigFile,What,[append]).

    Example:

    See the content of the history buffer:

    (tiger@durin)191> ttb:tracer().
    +{ok,[tiger@durin]}
    +(tiger@durin)192> ttb:p(self(),[garbage_collection,call]).
    +{ok,{[<0.1244.0>],[garbage_collection,call]}}
    +(tiger@durin)193> ttb:tp(ets,new,2,[]).
    +{ok,[{matched,1}]}
    +(tiger@durin)194> ttb:list_history().
    +[{1,{ttb,tracer,[tiger@durin,[]]}},
    + {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
    + {3,{ttb,tp,[ets,new,2,[]]}}]

    Execute an entry from the history buffer:

    (tiger@durin)195> ttb:ctp(ets,new,2).
    +{ok,[{matched,1}]}
    +(tiger@durin)196> ttb:list_history().
    +[{1,{ttb,tracer,[tiger@durin,[]]}},
    + {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
    + {3,{ttb,tp,[ets,new,2,[]]}},
    + {4,{ttb,ctp,[ets,new,2]}}]
    +(tiger@durin)197> ttb:run_history(3).
    +ttb:tp(ets,new,2,[]) ->
    +{ok,[{matched,1}]}

    Write the content of the history buffer to a configuration file:

    (tiger@durin)198> ttb:write_config("myconfig",all).
     ok
    -(tiger@durin)199> ttb:list_config("myconfig").
    -[{1,{ttb,tracer,[tiger@durin,[]]}},
    - {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
    - {3,{ttb,tp,[ets,new,2,[]]}},
    - {4,{ttb,ctp,[ets,new,2]}},
    - {5,{ttb,tp,[ets,new,2,[]]}}]

    Extend an existing configuration:

    (tiger@durin)200> ttb:write_config("myconfig",[{ttb,tp,[ets,delete,1,[]]}],
    -[append]).
    +(tiger@durin)199> ttb:list_config("myconfig").
    +[{1,{ttb,tracer,[tiger@durin,[]]}},
    + {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
    + {3,{ttb,tp,[ets,new,2,[]]}},
    + {4,{ttb,ctp,[ets,new,2]}},
    + {5,{ttb,tp,[ets,new,2,[]]}}]

    Extend an existing configuration:

    (tiger@durin)200> ttb:write_config("myconfig",[{ttb,tp,[ets,delete,1,[]]}],
    +[append]).
     ok
    -(tiger@durin)201> ttb:list_config("myconfig").
    -[{1,{ttb,tracer,[tiger@durin,[]]}},
    - {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
    - {3,{ttb,tp,[ets,new,2,[]]}},
    - {4,{ttb,ctp,[ets,new,2]}},
    - {5,{ttb,tp,[ets,new,2,[]]}},
    - {6,{ttb,tp,[ets,delete,1,[]]}}]

    Go back to a previous configuration after stopping Trace Tool Builder:

    (tiger@durin)202> ttb:stop().
    +(tiger@durin)201> ttb:list_config("myconfig").
    +[{1,{ttb,tracer,[tiger@durin,[]]}},
    + {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
    + {3,{ttb,tp,[ets,new,2,[]]}},
    + {4,{ttb,ctp,[ets,new,2]}},
    + {5,{ttb,tp,[ets,new,2,[]]}},
    + {6,{ttb,tp,[ets,delete,1,[]]}}]

    Go back to a previous configuration after stopping Trace Tool Builder:

    (tiger@durin)202> ttb:stop().
     ok
    -(tiger@durin)203> ttb:run_config("myconfig").
    -ttb:tracer(tiger@durin,[]) ->
    -{ok,[tiger@durin]}
    +(tiger@durin)203> ttb:run_config("myconfig").
    +ttb:tracer(tiger@durin,[]) ->
    +{ok,[tiger@durin]}
     
    -ttb:p(<0.1244.0>,[garbage_collection,call]) ->
    -{ok,{[<0.1244.0>],[garbage_collection,call]}}
    +ttb:p(<0.1244.0>,[garbage_collection,call]) ->
    +{ok,{[<0.1244.0>],[garbage_collection,call]}}
     
    -ttb:tp(ets,new,2,[]) ->
    -{ok,[{matched,1}]}
    +ttb:tp(ets,new,2,[]) ->
    +{ok,[{matched,1}]}
     
    -ttb:ctp(ets,new,2) ->
    -{ok,[{matched,1}]}
    +ttb:ctp(ets,new,2) ->
    +{ok,[{matched,1}]}
     
    -ttb:tp(ets,new,2,[]) ->
    -{ok,[{matched,1}]}
    +ttb:tp(ets,new,2,[]) ->
    +{ok,[{matched,1}]}
     
    -ttb:tp(ets,delete,1,[]) ->
    -{ok,[{matched,1}]}
    +ttb:tp(ets,delete,1,[]) ->
    +{ok,[{matched,1}]}
     
    -ok

    Write selected entries from the history buffer to a configuration file:

    (tiger@durin)204> ttb:list_history().
    -[{1,{ttb,tracer,[tiger@durin,[]]}},
    - {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
    - {3,{ttb,tp,[ets,new,2,[]]}},
    - {4,{ttb,ctp,[ets,new,2]}},
    - {5,{ttb,tp,[ets,new,2,[]]}},
    - {6,{ttb,tp,[ets,delete,1,[]]}}]
    -(tiger@durin)205> ttb:write_config("myconfig",[1,2,3,6]).
    +ok

    Write selected entries from the history buffer to a configuration file:

    (tiger@durin)204> ttb:list_history().
    +[{1,{ttb,tracer,[tiger@durin,[]]}},
    + {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
    + {3,{ttb,tp,[ets,new,2,[]]}},
    + {4,{ttb,ctp,[ets,new,2]}},
    + {5,{ttb,tp,[ets,new,2,[]]}},
    + {6,{ttb,tp,[ets,delete,1,[]]}}]
    +(tiger@durin)205> ttb:write_config("myconfig",[1,2,3,6]).
     ok
    -(tiger@durin)206> ttb:list_config("myconfig").
    -[{1,{ttb,tracer,[tiger@durin,[]]}},
    - {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}},
    - {3,{ttb,tp,[ets,new,2,[]]}},
    - {4,{ttb,tp,[ets,delete,1,[]]}}]
    -(tiger@durin)207>

    +(tiger@durin)206> ttb:list_config("myconfig"). +[{1,{ttb,tracer,[tiger@durin,[]]}}, + {2,{ttb,p,[<0.1244.0>,[garbage_collection,call]]}}, + {3,{ttb,tp,[ets,new,2,[]]}}, + {4,{ttb,tp,[ets,delete,1,[]]}}] +(tiger@durin)207>

    @@ -714,40 +714,40 @@

    ttb:tracer/0,1,2. Sequential tracing can then be started in either of the following ways:

    Example 1:

    In the following example, function dbg:get_tracer/0 is used as trigger for -sequential tracing:

    (tiger@durin)110> ttb:tracer().
    -{ok,[tiger@durin]}
    -(tiger@durin)111> ttb:p(self(),call).
    -{ok,{[<0.158.0>],[call]}}
    -(tiger@durin)112> ttb:tp(dbg,get_tracer,0,ttb:seq_trigger_ms(send)).
    -{ok,[{matched,1},{saved,1}]}
    -(tiger@durin)113> dbg:get_tracer(), seq_trace:reset_trace().
    +sequential tracing:

    (tiger@durin)110> ttb:tracer().
    +{ok,[tiger@durin]}
    +(tiger@durin)111> ttb:p(self(),call).
    +{ok,{[<0.158.0>],[call]}}
    +(tiger@durin)112> ttb:tp(dbg,get_tracer,0,ttb:seq_trigger_ms(send)).
    +{ok,[{matched,1},{saved,1}]}
    +(tiger@durin)113> dbg:get_tracer(), seq_trace:reset_trace().
     true
    -(tiger@durin)114> ttb:stop(format).
    -({<0.158.0>,{shell,evaluator,3},tiger@durin}) call dbg:get_tracer()
    -SeqTrace [0]: ({<0.158.0>,{shell,evaluator,3},tiger@durin})
    -{<0.237.0>,dbg,tiger@durin} ! {<0.158.0>,{get_tracer,tiger@durin}}
    -[Serial: {0,1}]
    -SeqTrace [0]: ({<0.237.0>,dbg,tiger@durin})
    -{<0.158.0>,{shell,evaluator,3},tiger@durin} ! {dbg,{ok,#Port<0.222>}}
    -[Serial: {1,2}]
    +(tiger@durin)114> ttb:stop(format).
    +({<0.158.0>,{shell,evaluator,3},tiger@durin}) call dbg:get_tracer()
    +SeqTrace [0]: ({<0.158.0>,{shell,evaluator,3},tiger@durin})
    +{<0.237.0>,dbg,tiger@durin} ! {<0.158.0>,{get_tracer,tiger@durin}}
    +[Serial: {0,1}]
    +SeqTrace [0]: ({<0.237.0>,dbg,tiger@durin})
    +{<0.158.0>,{shell,evaluator,3},tiger@durin} ! {dbg,{ok,#Port<0.222>}}
    +[Serial: {1,2}]
     ok
    -(tiger@durin)116>

    Example 2:

    Starting sequential tracing with a trigger is more useful if the trigger +(tiger@durin)116>

    Example 2:

    Starting sequential tracing with a trigger is more useful if the trigger function is not called directly from the shell, but rather implicitly within a larger system. When calling a function from the shell, it is simpler to start -sequential tracing directly, for example, as follows:

    (tiger@durin)116> ttb:tracer().
    -{ok,[tiger@durin]}
    -(tiger@durin)117> seq_trace:set_token(send,true), dbg:get_tracer(),
    -seq_trace:reset_trace().
    +sequential tracing directly, for example, as follows:

    (tiger@durin)116> ttb:tracer().
    +{ok,[tiger@durin]}
    +(tiger@durin)117> seq_trace:set_token(send,true), dbg:get_tracer(),
    +seq_trace:reset_trace().
     true
    -(tiger@durin)118> ttb:stop(format).
    -SeqTrace [0]: ({<0.158.0>,{shell,evaluator,3},tiger@durin})
    -{<0.246.0>,dbg,tiger@durin} ! {<0.158.0>,{get_tracer,tiger@durin}}
    -[Serial: {0,1}]
    -SeqTrace [0]: ({<0.246.0>,dbg,tiger@durin})
    -{<0.158.0>,{shell,evaluator,3},tiger@durin} ! {dbg,{ok,#Port<0.229>}}
    -[Serial: {1,2}]
    +(tiger@durin)118> ttb:stop(format).
    +SeqTrace [0]: ({<0.158.0>,{shell,evaluator,3},tiger@durin})
    +{<0.246.0>,dbg,tiger@durin} ! {<0.158.0>,{get_tracer,tiger@durin}}
    +[Serial: {0,1}]
    +SeqTrace [0]: ({<0.246.0>,dbg,tiger@durin})
    +{<0.158.0>,{shell,evaluator,3},tiger@durin} ! {dbg,{ok,#Port<0.229>}}
    +[Serial: {1,2}]
     ok
    -(tiger@durin)120>

    In both previous examples, seq_trace:reset_trace/0 resets the trace token +(tiger@durin)120>

    In both previous examples, seq_trace:reset_trace/0 resets the trace token immediately after the traced function to avoid many trace messages because of the printouts in the Erlang shell.

    All functions in module seq_trace, except set_system_tracer/1, can be used after the trace port is started with ttb:tracer/0,1,2.

    diff --git a/prs/8803/lib/odbc-2.14.3/doc/html/getting_started.html b/prs/8803/lib/odbc-2.14.3/doc/html/getting_started.html index 6d3da67fc39fc..13b20ce197daa 100644 --- a/prs/8803/lib/odbc-2.14.3/doc/html/getting_started.html +++ b/prs/8803/lib/odbc-2.14.3/doc/html/getting_started.html @@ -157,77 +157,77 @@

    relevance to anything that exist in reality, it is just a simple example. The example was created using sqlserver 7.0 with servicepack 1 as database and the ODBC driver for sqlserver with version 2000.80.194.00.

     1 > odbc:start().
    -      ok

    Connect to the database

     2 > {ok, Ref} = odbc:connect("DSN=sql-server;UID=aladdin;PWD=sesame", []).
    -      {ok,<0.342.0>}

    Create a table

     3 > odbc:sql_query(Ref, "CREATE TABLE EMPLOYEE (NR integer,
    +      ok

    Connect to the database

     2 > {ok, Ref} = odbc:connect("DSN=sql-server;UID=aladdin;PWD=sesame", []).
    +      {ok,<0.342.0>}

    Create a table

     3 > odbc:sql_query(Ref, "CREATE TABLE EMPLOYEE (NR integer,
           FIRSTNAME  char varying(20), LASTNAME  char varying(20), GENDER char(1),
           PRIMARY KEY(NR))").
           {updated,undefined}

    Insert some data

     4 > odbc:sql_query(Ref, "INSERT INTO EMPLOYEE VALUES(1, 'Jane', 'Doe', 'F')").
           {updated,1}

    Check what data types the database assigned for the columns. Hopefully this is not a surprise, some times it can be! These are the data types that you should -use if you want to do a parameterized query.

     5 > odbc:describe_table(Ref, "EMPLOYEE").
    -      {ok, [{"NR", sql_integer},
    -            {"FIRSTNAME", {sql_varchar, 20}},
    -            {"LASTNAME", {sql_varchar, 20}}
    -            {"GENDER", {sql_char, 1}}]}

    Use a parameterized query to insert many rows in one go.

     6 > odbc:param_query(Ref,"INSERT INTO EMPLOYEE (NR, FIRSTNAME, "
    +use if you want to do a parameterized query.

     5 > odbc:describe_table(Ref, "EMPLOYEE").
    +      {ok, [{"NR", sql_integer},
    +            {"FIRSTNAME", {sql_varchar, 20}},
    +            {"LASTNAME", {sql_varchar, 20}}
    +            {"GENDER", {sql_char, 1}}]}

    Use a parameterized query to insert many rows in one go.

     6 > odbc:param_query(Ref,"INSERT INTO EMPLOYEE (NR, FIRSTNAME, "
                       "LASTNAME, GENDER) VALUES(?, ?, ?, ?)",
    -                   [{sql_integer,[2,3,4,5,6,7,8]},
    -                    {{sql_varchar, 20},
    -                             ["John", "Monica", "Ross", "Rachel",
    -                             "Piper", "Prue", "Louise"]},
    -                   {{sql_varchar, 20},
    -                             ["Doe","Geller","Geller", "Green",
    -                              "Halliwell", "Halliwell", "Lane"]},
    -                   {{sql_char, 1}, ["M","F","M","F","F","F","F"]}]).
    -      {updated, 7}

    Fetch all data in the table employee

     7> odbc:sql_query(Ref, "SELECT * FROM EMPLOYEE").
    -    {selected,["NR","FIRSTNAME","LASTNAME","GENDER"],
    -          [{1,"Jane","Doe","F"},
    -           {2,"John","Doe","M"},
    -           {3,"Monica","Geller","F"},
    -           {4,"Ross","Geller","M"},
    -           {5,"Rachel","Green","F"},
    -           {6,"Piper","Halliwell","F"},
    -           {7,"Prue","Halliwell","F"},
    -           {8,"Louise","Lane","F"}]]}

    Associate a result set containing the whole table EMPLOYEE to the connection. -The number of rows in the result set is returned.

     8 > odbc:select_count(Ref, "SELECT * FROM EMPLOYEE").
    -      {ok,8}

    You can always traverse the result set sequential by using next

     9 > odbc:next(Ref).
    -      {selected,["NR","FIRSTNAME","LASTNAME","GENDER"],[{1,"Jane","Doe","F"}]}
     10 > odbc:next(Ref).
    -      {selected,["NR","FIRSTNAME","LASTNAME","GENDER"],[{2,"John","Doe","M"}]}

    If your driver supports scrollable cursors you have a little more freedom, and -can do things like this.

     11 > odbc:last(Ref).
    -      {selected,["NR","FIRSTNAME","LASTNAME","GENDER"],[{8,"Louise","Lane","F"}]}
     12 > odbc:prev(Ref).
    -      {selected,["NR","FIRSTNAME","LASTNAME","GENDER"],[{7,"Prue","Halliwell","F"}]}
     13 > odbc:first(Ref).
    -      {selected,["NR","FIRSTNAME","LASTNAME","GENDER"],[{1,"Jane","Doe","F"}]}
     14 > odbc:next(Ref).
    -      {selected,["NR","FIRSTNAME","LASTNAME","GENDER"],[{2,"John","Doe","M"}]}

    Fetch the fields FIRSTNAMEand NRfor all female employees

     15 > odbc:sql_query(Ref, "SELECT FIRSTNAME, NR FROM EMPLOYEE WHERE GENDER = 'F'").
    -     {selected,["FIRSTNAME","NR"],
    -          [{"Jane",1},
    -           {"Monica",3},
    -           {"Rachel",5},
    -           {"Piper",6},
    -           {"Prue",7},
    -           {"Louise",8}]}

    Fetch the fields FIRSTNAMEand NRfor all female employees and sort them on -the field FIRSTNAME.

     16 > odbc:sql_query(Ref, "SELECT FIRSTNAME, NR FROM EMPLOYEE WHERE GENDER = 'F'
    -      ORDER BY FIRSTNAME").
    -    {selected,["FIRSTNAME","NR"],
    -          [{"Jane",1},
    -           {"Louise",8},
    -           {"Monica",3},
    -           {"Piper",6},
    -           {"Prue",7},
    -           {"Rachel",5}]}

    Associate a result set that contains the fields FIRSTNAME and NRfor all + [{sql_integer,[2,3,4,5,6,7,8]}, + {{sql_varchar, 20}, + ["John", "Monica", "Ross", "Rachel", + "Piper", "Prue", "Louise"]}, + {{sql_varchar, 20}, + ["Doe","Geller","Geller", "Green", + "Halliwell", "Halliwell", "Lane"]}, + {{sql_char, 1}, ["M","F","M","F","F","F","F"]}]). + {updated, 7}

    Fetch all data in the table employee

     7> odbc:sql_query(Ref, "SELECT * FROM EMPLOYEE").
    +    {selected,["NR","FIRSTNAME","LASTNAME","GENDER"],
    +          [{1,"Jane","Doe","F"},
    +           {2,"John","Doe","M"},
    +           {3,"Monica","Geller","F"},
    +           {4,"Ross","Geller","M"},
    +           {5,"Rachel","Green","F"},
    +           {6,"Piper","Halliwell","F"},
    +           {7,"Prue","Halliwell","F"},
    +           {8,"Louise","Lane","F"}]]}

    Associate a result set containing the whole table EMPLOYEE to the connection. +The number of rows in the result set is returned.

     8 > odbc:select_count(Ref, "SELECT * FROM EMPLOYEE").
    +      {ok,8}

    You can always traverse the result set sequential by using next

     9 > odbc:next(Ref).
    +      {selected,["NR","FIRSTNAME","LASTNAME","GENDER"],[{1,"Jane","Doe","F"}]}
     10 > odbc:next(Ref).
    +      {selected,["NR","FIRSTNAME","LASTNAME","GENDER"],[{2,"John","Doe","M"}]}

    If your driver supports scrollable cursors you have a little more freedom, and +can do things like this.

     11 > odbc:last(Ref).
    +      {selected,["NR","FIRSTNAME","LASTNAME","GENDER"],[{8,"Louise","Lane","F"}]}
     12 > odbc:prev(Ref).
    +      {selected,["NR","FIRSTNAME","LASTNAME","GENDER"],[{7,"Prue","Halliwell","F"}]}
     13 > odbc:first(Ref).
    +      {selected,["NR","FIRSTNAME","LASTNAME","GENDER"],[{1,"Jane","Doe","F"}]}
     14 > odbc:next(Ref).
    +      {selected,["NR","FIRSTNAME","LASTNAME","GENDER"],[{2,"John","Doe","M"}]}

    Fetch the fields FIRSTNAMEand NRfor all female employees

     15 > odbc:sql_query(Ref, "SELECT FIRSTNAME, NR FROM EMPLOYEE WHERE GENDER = 'F'").
    +     {selected,["FIRSTNAME","NR"],
    +          [{"Jane",1},
    +           {"Monica",3},
    +           {"Rachel",5},
    +           {"Piper",6},
    +           {"Prue",7},
    +           {"Louise",8}]}

    Fetch the fields FIRSTNAMEand NRfor all female employees and sort them on +the field FIRSTNAME.

     16 > odbc:sql_query(Ref, "SELECT FIRSTNAME, NR FROM EMPLOYEE WHERE GENDER = 'F'
    +      ORDER BY FIRSTNAME").
    +    {selected,["FIRSTNAME","NR"],
    +          [{"Jane",1},
    +           {"Louise",8},
    +           {"Monica",3},
    +           {"Piper",6},
    +           {"Prue",7},
    +           {"Rachel",5}]}

    Associate a result set that contains the fields FIRSTNAME and NRfor all female employees to the connection. The number of rows in the result set is -returned.

     17 > odbc:select_count(Ref, "SELECT FIRSTNAME, NR FROM EMPLOYEE WHERE GENDER = 'F'").
    -      {ok,6}

    A few more ways of retrieving parts of the result set when the driver supports +returned.

     17 > odbc:select_count(Ref, "SELECT FIRSTNAME, NR FROM EMPLOYEE WHERE GENDER = 'F'").
    +      {ok,6}

    A few more ways of retrieving parts of the result set when the driver supports scrollable cursors. Note that next will work even without support for scrollable -cursors.

     18 > odbc:select(Ref, {relative, 2}, 3).
    -    {selected,["FIRSTNAME","NR"],[{"Monica",3},{"Rachel",5},{"Piper",6}]}
     19 > odbc:select(Ref, next, 2).
    -      {selected,["FIRSTNAME","NR"],[{"Prue",7},{"Louise",8}]}
     20 > odbc:select(Ref, {absolute, 1}, 2).
    -      {selected,["FIRSTNAME","NR"],[{"Jane",1},{"Monica",3}]}
     21 > odbc:select(Ref, next, 2).
    -    {selected,["FIRSTNAME","NR"],[{"Rachel",5},{"Piper",6}]}
     22 > odbc:select(Ref, {absolute, 1}, 4).
    -      {selected,["FIRSTNAME","NR"],
    -                [{"Jane",1},{"Monica",3},{"Rachel",5},{"Piper",6}]}

    Select, using a parameterized query.

     23 > odbc:param_query(Ref, "SELECT * FROM EMPLOYEE WHERE GENDER=?",
    -      [{{sql_char, 1}, ["M"]}]).
    -      {selected,["NR","FIRSTNAME","LASTNAME","GENDER"],
    -                [{2,"John", "Doe", "M"},{4,"Ross","Geller","M"}]}

    Delete the table EMPLOYEE.

     24 > odbc:sql_query(Ref, "DROP TABLE EMPLOYEE").
    -      {updated,undefined}

    Shut down the connection.

     25 > odbc:disconnect(Ref).
    +cursors.

     18 > odbc:select(Ref, {relative, 2}, 3).
    +    {selected,["FIRSTNAME","NR"],[{"Monica",3},{"Rachel",5},{"Piper",6}]}
     19 > odbc:select(Ref, next, 2).
    +      {selected,["FIRSTNAME","NR"],[{"Prue",7},{"Louise",8}]}
     20 > odbc:select(Ref, {absolute, 1}, 2).
    +      {selected,["FIRSTNAME","NR"],[{"Jane",1},{"Monica",3}]}
     21 > odbc:select(Ref, next, 2).
    +    {selected,["FIRSTNAME","NR"],[{"Rachel",5},{"Piper",6}]}
     22 > odbc:select(Ref, {absolute, 1}, 4).
    +      {selected,["FIRSTNAME","NR"],
    +                [{"Jane",1},{"Monica",3},{"Rachel",5},{"Piper",6}]}

    Select, using a parameterized query.

     23 > odbc:param_query(Ref, "SELECT * FROM EMPLOYEE WHERE GENDER=?",
    +      [{{sql_char, 1}, ["M"]}]).
    +      {selected,["NR","FIRSTNAME","LASTNAME","GENDER"],
    +                [{2,"John", "Doe", "M"},{4,"Ross","Geller","M"}]}

    Delete the table EMPLOYEE.

     24 > odbc:sql_query(Ref, "DROP TABLE EMPLOYEE").
    +      {updated,undefined}

    Shut down the connection.

     25 > odbc:disconnect(Ref).
           ok

    Shut down the application.

     26 > odbc:stop().
         =INFO REPORT==== 7-Jan-2004::17:00:59 ===
         application: odbc
    diff --git a/prs/8803/lib/odbc-2.14.3/doc/html/odbc.epub b/prs/8803/lib/odbc-2.14.3/doc/html/odbc.epub
    index b63c81a46f5cb..c54dbf5629a61 100644
    Binary files a/prs/8803/lib/odbc-2.14.3/doc/html/odbc.epub and b/prs/8803/lib/odbc-2.14.3/doc/html/odbc.epub differ
    diff --git a/prs/8803/lib/os_mon-2.10/doc/html/os_mon.epub b/prs/8803/lib/os_mon-2.10/doc/html/os_mon.epub
    index 68979c0619d5e..a78d39599fd9a 100644
    Binary files a/prs/8803/lib/os_mon-2.10/doc/html/os_mon.epub and b/prs/8803/lib/os_mon-2.10/doc/html/os_mon.epub differ
    diff --git a/prs/8803/lib/parsetools-2.6/doc/html/leex.html b/prs/8803/lib/parsetools-2.6/doc/html/leex.html
    index 126d9b7fae421..40866eb62023f 100644
    --- a/prs/8803/lib/parsetools-2.6/doc/html/leex.html
    +++ b/prs/8803/lib/parsetools-2.6/doc/html/leex.html
    @@ -173,13 +173,13 @@ 

    next token. Note that pushing back a newline will mean the line numbering will no longer be correct.

    Note

    Pushing back characters gives you unexpected possibilities to cause the scanner to loop!

    The following example would match a simple Erlang integer or float and return a -token which could be sent to the Erlang parser:

    D = [0-9]
    +token which could be sent to the Erlang parser:

    D = [0-9]
     
    -{D}+ :
    -  {token,{integer,TokenLine,list_to_integer(TokenChars)}}.
    +{D}+ :
    +  {token,{integer,TokenLine,list_to_integer(TokenChars)}}.
     
    -{D}+\.{D}+((E|e)(\+|\-)?{D}+)? :
    -  {token,{float,TokenLine,list_to_float(TokenChars)}}.

    The Erlang code in the Erlang code. section is written into the output file +{D}+\.{D}+((E|e)(\+|\-)?{D}+)? : + {token,{float,TokenLine,list_to_float(TokenChars)}}.

    The Erlang code in the Erlang code. section is written into the output file directly after the module declaration and predefined exports declaration, making it possible to add extra exports, define imports, and other attributes, which are visible in the whole file.

    @@ -731,7 +731,7 @@

    token(Cont, Chars, StartLoc)

    the token. This is continued until a token has been scanned. Cont is initially [].

    It is not designed to be called directly by an application, but is used through the I/O system where it can typically be called in an -application by:

    io:request(InFile, {get_until,unicode,Prompt,Module,token,[Loc]})
    +application by:

    io:request(InFile, {get_until,unicode,Prompt,Module,token,[Loc]})
       -> TokenRet

    @@ -820,7 +820,7 @@

    tokens(Cont, Chars, StartLoc)

    like Erlang where there is an explicit end token, '.'. If no end token is found then the whole file will be scanned and returned. If an error occurs then all tokens up to and including the next end token will be skipped.

    It is not designed to be called directly by an application, but used through the -I/O system where it can typically be called in an application by:

    io:request(InFile, {get_until,unicode,Prompt,Module,tokens,[Loc]})
    +I/O system where it can typically be called in an application by:

    io:request(InFile, {get_until,unicode,Prompt,Module,tokens,[Loc]})
       -> TokensRet
    diff --git a/prs/8803/lib/parsetools-2.6/doc/html/parsetools.epub b/prs/8803/lib/parsetools-2.6/doc/html/parsetools.epub index 4bffcfa6646c1..5b215fcb9f5b8 100644 Binary files a/prs/8803/lib/parsetools-2.6/doc/html/parsetools.epub and b/prs/8803/lib/parsetools-2.6/doc/html/parsetools.epub differ diff --git a/prs/8803/lib/parsetools-2.6/doc/html/yecc.html b/prs/8803/lib/parsetools-2.6/doc/html/yecc.html index 0a2c63e5f8bef..2a3db6e3edec0 100644 --- a/prs/8803/lib/parsetools-2.6/doc/html/yecc.html +++ b/prs/8803/lib/parsetools-2.6/doc/html/yecc.html @@ -162,8 +162,8 @@

    distinguished from all the terminal and non-terminal categories of the syntax rules. The Endsymbol can be declared in the grammar file.

    The simplest case is to segment the input string into a list of identifiers (atoms) and use those atoms both as categories and values of the tokens. For -example, the input string aaa bbb 777, X may be scanned (tokenized) as:

    [{aaa, 1}, {bbb, 1}, {777, 1}, {',' , 1}, {'X', 1},
    - {'$end', 1}].

    This assumes that this is the first line of the input text, and that '$end' is +example, the input string aaa bbb 777, X may be scanned (tokenized) as:

    [{aaa, 1}, {bbb, 1}, {777, 1}, {',' , 1}, {'X', 1},
    + {'$end', 1}].

    This assumes that this is the first line of the input text, and that '$end' is the distinguished end_of_input symbol.

    The Erlang scanner in the io module can be used as a starting point when writing a new scanner. Study yeccscan.erl in order to see how a filter can be added on top of io:scan_erl_form/3 to provide a scanner for Yecc that @@ -233,8 +233,8 @@

    element -> atom. element -> list.

    This grammar can be used to generate a parser which parses list expressions, such as (), (a), (peter charles), (a (b c) d (())), ... provided that your -scanner tokenizes, for example, the input (peter charles) as follows:

    [{'(', 1} , {atom, 1, peter}, {atom, 1, charles}, {')', 1},
    - {'$end', 1}]

    When a grammar rule is used by the parser to parse (part of) the input string as +scanner tokenizes, for example, the input (peter charles) as follows:

    [{'(', 1} , {atom, 1, peter}, {atom, 1, charles}, {')', 1},
    + {'$end', 1}]

    When a grammar rule is used by the parser to parse (part of) the input string as a grammatical phrase, the associated code is evaluated, and the value of the last expression becomes the value of the parsed phrase. This value may be used by the parser later to build structures that are values of higher phrases of @@ -246,8 +246,8 @@

    element -> atom : '$1'. element -> list : '$1'.

    With this code added to the grammar rules, the parser produces the following value (structure) when parsing the input string (a b c).. This still assumes -that this was the first input line that the scanner tokenized:

    {cons, {atom, 1, a}, {cons, {atom, 1, b},
    -                            {cons, {atom, 1, c}, nil}}}

    The associated code contains pseudo variables '$1', '$2', +that this was the first input line that the scanner tokenized:

    {cons, {atom, 1, a}, {cons, {atom, 1, b},
    +                            {cons, {atom, 1, c}, nil}}}

    The associated code contains pseudo variables '$1', '$2', '$3', and so on. which refer to (are bound to) the values associated previously by the parser with the symbols of the right-hand side of the rule. When these symbols are terminal categories, the @@ -270,12 +270,12 @@

    Generating a Parser

    -

    To call the parser generator, use the following command:

    yecc:file(Grammarfile).

    An error message from Yecc will be shown if the grammar is not of the LALR type +

    To call the parser generator, use the following command:

    yecc:file(Grammarfile).

    An error message from Yecc will be shown if the grammar is not of the LALR type (for example too ambiguous). Shift/reduce conflicts are resolved in favor of shifting if there are no operator precedence declarations. Refer to the yacc documentation on the use of operator precedence.

    The output file contains Erlang source code for a parser module with module name equal to the Parserfile parameter. After compilation, the parser can be called -as follows (the module name is assumed to be myparser):

    myparser:parse(myscanner:scan(Inport))

    The call format can be different if a customized prologue file has been included +as follows (the module name is assumed to be myparser):

    myparser:parse(myscanner:scan(Inport))

    The call format can be different if a customized prologue file has been included when generating the parser instead of the default file lib/parsetools/include/yeccpre.hrl.

    With the standard prologue, this call will return either {ok, Result}, where Result is a structure that the Erlang code of the grammar file has built, or @@ -284,15 +284,15 @@

    the screen. The user will have to do this either by printing the returned error messages, or by inserting tests and print instructions in the Erlang code associated with the syntax rules of the grammar file.

    It is also possible to make the parser ask for more input tokens when needed if -the following call format is used:

    myparser:parse_and_scan({Function, Args})
    -myparser:parse_and_scan({Mod, Tokenizer, Args})

    The tokenizer Function is either a fun or a tuple {Mod, Tokenizer}. The call +the following call format is used:

    myparser:parse_and_scan({Function, Args})
    +myparser:parse_and_scan({Mod, Tokenizer, Args})

    The tokenizer Function is either a fun or a tuple {Mod, Tokenizer}. The call apply(Function, Args) or apply({Mod, Tokenizer}, Args) is executed whenever a new token is needed. This, for example, makes it possible to parse from a file, token by token.

    The tokenizer used above has to be implemented so as to return one of the -following:

    {ok, Tokens, EndPosition}
    -{eof, EndPosition}
    -{error, Error_description, EndPosition}

    This conforms to the format used by the scanner in the Erlang io library +following:

    {ok, Tokens, EndPosition}
    +{eof, EndPosition}
    +{error, Error_description, EndPosition}

    This conforms to the format used by the scanner in the Erlang io library module.

    If {eof, EndPosition} is returned immediately, the call to parse_and_scan/1 returns {ok, eof}. If {eof, EndPosition} is returned before the parser expects end of input, parse_and_scan/1 will, of course, return an error @@ -342,36 +342,36 @@

    Endsymbol '$end'. grammar -> declaration : '$1'. grammar -> rule : '$1'. -declaration -> symbol symbols dot: {'$1', '$2'}. -rule -> head '->' symbols attached_code dot: {rule, ['$1' | '$3'], - '$4'}. +declaration -> symbol symbols dot: {'$1', '$2'}. +rule -> head '->' symbols attached_code dot: {rule, ['$1' | '$3'], + '$4'}. head -> symbol : '$1'. -symbols -> symbol : ['$1']. -symbols -> symbol symbols : ['$1' | '$2']. -attached_code -> ':' tokens : {erlang_code, '$2'}. -attached_code -> '$empty' : {erlang_code, - [{atom, 0, '$undefined'}]}. -tokens -> token : ['$1']. -tokens -> token tokens : ['$1' | '$2']. -symbol -> var : value_of('$1'). -symbol -> atom : value_of('$1'). -symbol -> integer : value_of('$1'). -symbol -> reserved_word : value_of('$1'). +symbols -> symbol : ['$1']. +symbols -> symbol symbols : ['$1' | '$2']. +attached_code -> ':' tokens : {erlang_code, '$2'}. +attached_code -> '$empty' : {erlang_code, + [{atom, 0, '$undefined'}]}. +tokens -> token : ['$1']. +tokens -> token tokens : ['$1' | '$2']. +symbol -> var : value_of('$1'). +symbol -> atom : value_of('$1'). +symbol -> integer : value_of('$1'). +symbol -> reserved_word : value_of('$1'). token -> var : '$1'. token -> atom : '$1'. token -> float : '$1'. token -> integer : '$1'. token -> string : '$1'. token -> char : '$1'. -token -> reserved_symbol : {value_of('$1'), line_of('$1')}. -token -> reserved_word : {value_of('$1'), line_of('$1')}. -token -> '->' : {'->', line_of('$1')}. -token -> ':' : {':', line_of('$1')}. +token -> reserved_symbol : {value_of('$1'), line_of('$1')}. +token -> reserved_word : {value_of('$1'), line_of('$1')}. +token -> '->' : {'->', line_of('$1')}. +token -> ':' : {':', line_of('$1')}. Erlang code. -value_of(Token) -> - element(3, Token). -line_of(Token) -> - element(2, Token).

    Note

    The symbols '->', and ':' have to be treated in a special way, as they are +value_of(Token) -> + element(3, Token). +line_of(Token) -> + element(2, Token).

    Note

    The symbols '->', and ':' have to be treated in a special way, as they are meta symbols of the grammar notation, as well as terminal symbols of the Yecc grammar.

    5. The file erl_parse.yrl in the lib/stdlib/src directory contains the grammar for Erlang.

    Note

    Syntactic tests are used in the code associated with some rules, and an error diff --git a/prs/8803/lib/public_key-1.16.1/doc/html/public_key.epub b/prs/8803/lib/public_key-1.16.1/doc/html/public_key.epub index 386c9cfe139bf..c773ccccadda7 100644 Binary files a/prs/8803/lib/public_key-1.16.1/doc/html/public_key.epub and b/prs/8803/lib/public_key-1.16.1/doc/html/public_key.epub differ diff --git a/prs/8803/lib/public_key-1.16.1/doc/html/public_key.html b/prs/8803/lib/public_key-1.16.1/doc/html/public_key.html index d1135eec9313f..1c480d5bcabef 100644 --- a/prs/8803/lib/public_key-1.16.1/doc/html/public_key.html +++ b/prs/8803/lib/public_key-1.16.1/doc/html/public_key.html @@ -3307,22 +3307,22 @@

    pkix_path_validation(Cert, CertChain, Optio or also by the user when the option policy_set is provided to this function. The qualifiers convey information about the valid policy and is intended as information to end users.

    Available options:

    • {verify_fun, {fun(), UserState::term()} - The fun must be -defined as:

      fun(OtpCert :: #'OTPCertificate'{},
      -    Event :: {bad_cert, Reason :: atom() | {revoked, atom()}} |
      -             {extension, #'Extension'{}},
      -    UserState :: term()) ->
      -  {valid, UserState :: term()} |
      -  {valid_peer, UserState :: term()} |
      -  {fail, Reason :: term()} |
      -  {unknown, UserState :: term()}.

      or as:

      fun(OtpCert :: #'OTPCertificate'{},
      -    DerCert :: der_encoded(),
      -    Event :: {bad_cert, Reason :: atom() | {revoked, atom()}} |
      -             {extension, #'Extension'{}},
      -    UserState :: term()) ->
      -  {valid, UserState :: term()} |
      -  {valid_peer, UserState :: term()} |
      -  {fail, Reason :: term()} |
      -  {unknown, UserState :: term()}.

      The verify callback can have 3 or 4 arguments in case the DER encoded +defined as:

      fun(OtpCert :: #'OTPCertificate'{},
      +    Event :: {bad_cert, Reason :: atom() | {revoked, atom()}} |
      +             {extension, #'Extension'{}},
      +    UserState :: term()) ->
      +  {valid, UserState :: term()} |
      +  {valid_peer, UserState :: term()} |
      +  {fail, Reason :: term()} |
      +  {unknown, UserState :: term()}.

      or as:

      fun(OtpCert :: #'OTPCertificate'{},
      +    DerCert :: der_encoded(),
      +    Event :: {bad_cert, Reason :: atom() | {revoked, atom()}} |
      +             {extension, #'Extension'{}},
      +    UserState :: term()) ->
      +  {valid, UserState :: term()} |
      +  {valid_peer, UserState :: term()} |
      +  {fail, Reason :: term()} |
      +  {unknown, UserState :: term()}.

      The verify callback can have 3 or 4 arguments in case the DER encoded version is needed by the callback.

      If the verify callback fun returns {fail, Reason}, the verification process is immediately stopped. If the verify callback fun returns {valid, UserState}, the verification process is continued. This can be used @@ -3494,9 +3494,9 @@

      pkix_verify_hostname(Cert, ReferenceIDs, Op about hostname verification. The User's Guide and code examples describes this -function more detailed.

      The option funs are described here:

      • match_fun

        fun(ReferenceId::ReferenceId() | FQDN::string(),
        -    PresentedId::{dNSName,string()} | {uniformResourceIdentifier,string() |
        -                 {iPAddress,list(byte())} | {OtherId::atom()|oid(),term()}})

        This function replaces the default host name matching rules. The fun should +function more detailed.

        The option funs are described here:

        • match_fun

          fun(ReferenceId::ReferenceId() | FQDN::string(),
          +    PresentedId::{dNSName,string()} | {uniformResourceIdentifier,string() |
          +                 {iPAddress,list(byte())} | {OtherId::atom()|oid(),term()}})

          This function replaces the default host name matching rules. The fun should return a boolean to tell if the Reference ID and Presented ID matches or not. The match fun can also return a third value, value, the atom default, if the default matching rules shall apply. This makes it possible to augment the @@ -3696,14 +3696,14 @@

          pkix_crls_validate(OTPcertificate, DPandCRL

    Performs CRL validation. It is intended to be called from the verify fun of -pkix_path_validation/3 .

    Available options:

    • {update_crl, fun()} - The fun has the following type specification:

       fun(#'DistributionPoint'{}, #'CertificateList'{}) ->
      -        #'CertificateList'{}

      The fun uses the information in the distribution point to access the latest +pkix_path_validation/3 .

      Available options:

      • {update_crl, fun()} - The fun has the following type specification:

         fun(#'DistributionPoint'{}, #'CertificateList'{}) ->
        +        #'CertificateList'{}

        The fun uses the information in the distribution point to access the latest possible version of the CRL. If this fun is not specified, Public Key uses the default implementation:

         fun(_DP, CRL) -> CRL end
      • {issuer_fun, {fun(), UserState::term()}} - The fun has the following type -specification:

        fun(#'DistributionPoint'{}, #'CertificateList'{},
        -    {rdnSequence,[#'AttributeTypeAndValue'{}]}, UserState::term()) ->
        -  {ok, #'OTPCertificate'{}, [der_encoded]}

        The fun returns the root certificate and certificate chain that has signed the -CRL.

         fun(DP, CRL, Issuer, UserState) -> {ok, RootCert, CertChain}
      • {undetermined_details, boolean()} - Defaults to false. When revocation +specification:

        fun(#'DistributionPoint'{}, #'CertificateList'{},
        +    {rdnSequence,[#'AttributeTypeAndValue'{}]}, UserState::term()) ->
        +  {ok, #'OTPCertificate'{}, [der_encoded]}

        The fun returns the root certificate and certificate chain that has signed the +CRL.

         fun(DP, CRL, Issuer, UserState) -> {ok, RootCert, CertChain}
      • {undetermined_details, boolean()} - Defaults to false. When revocation status cannot be determined, and this option is set to true, details of why no CRLs where accepted are included in the return value.

      @@ -4051,18 +4051,18 @@

      pkix_test_data(ChainConf)

      generating an ECDSA key. Note this could fail if Erlang/OTP is compiled with a very old cryptolib.

    • {validity, {From::erlang:timestamp(), To::erlang:timestamp()}} - The validity period of the certificate.

    • {extensions, [#'Extension'{}]} - Extensions to include in the -certificate.

      Default extensions included in CA certificates if not otherwise specified are:

      [#'Extension'{extnID = ?'id-ce-keyUsage',
      -              extnValue = [keyCertSign, cRLSign],
      -              critical = false},
      -#'Extension'{extnID = ?'id-ce-basicConstraints',
      -             extnValue = #'BasicConstraints'{cA = true},
      -             critical = true}]

      Default extensions included in the server peer cert if not otherwise specified -are:

      [#'Extension'{extnID = ?'id-ce-keyUsage',
      -              extnValue = [digitalSignature, keyAgreement],
      -              critical = false},
      -#'Extension'{extnID = ?'id-ce-subjectAltName',
      -             extnValue = [{dNSName, Hostname}],
      -             critical = false}]

      Hostname is the result of calling net_adm:localhost() in the Erlang node where +certificate.

      Default extensions included in CA certificates if not otherwise specified are:

      [#'Extension'{extnID = ?'id-ce-keyUsage',
      +              extnValue = [keyCertSign, cRLSign],
      +              critical = false},
      +#'Extension'{extnID = ?'id-ce-basicConstraints',
      +             extnValue = #'BasicConstraints'{cA = true},
      +             critical = true}]

      Default extensions included in the server peer cert if not otherwise specified +are:

      [#'Extension'{extnID = ?'id-ce-keyUsage',
      +              extnValue = [digitalSignature, keyAgreement],
      +              critical = false},
      +#'Extension'{extnID = ?'id-ce-subjectAltName',
      +             extnValue = [{dNSName, Hostname}],
      +             critical = false}]

      Hostname is the result of calling net_adm:localhost() in the Erlang node where this function is called.

    Note

    Note that the generated certificates and keys does not provide a formally correct PKIX-trust-chain and they cannot be used to achieve real security. This function is provided for testing purposes only.

    diff --git a/prs/8803/lib/public_key-1.16.1/doc/html/public_key_records.html b/prs/8803/lib/public_key-1.16.1/doc/html/public_key_records.html index 52a0156159800..e640a12560d2e 100644 --- a/prs/8803/lib/public_key-1.16.1/doc/html/public_key_records.html +++ b/prs/8803/lib/public_key-1.16.1/doc/html/public_key_records.html @@ -129,7 +129,7 @@

    used to handle public key infrastructure. The scope is to describe the data types of each component, not the semantics. For information on the semantics, refer to the relevant standards and RFCs linked in the sections below.

    Use the following include directive to get access to the records and constant -macros described in the following sections:

     -include_lib("public_key/include/public_key.hrl").

    +macros described in the following sections:

     -include_lib("public_key/include/public_key.hrl").

    @@ -137,48 +137,48 @@

    Common non-standard Erlang data types used to describe the record fields in the following sections and which are not defined in the Public Key -Reference Manual follows here:

    time() = utc_time() | general_time()
    +Reference Manual follows here:

    time() = utc_time() | general_time()
     
    -utc_time()  = {utcTime, "YYMMDDHHMMSSZ"}
    +utc_time()  = {utcTime, "YYMMDDHHMMSSZ"}
     
    -general_time() = {generalTime, "YYYYMMDDHHMMSSZ"}
    +general_time() = {generalTime, "YYYYMMDDHHMMSSZ"}
     
    -general_name() = {rfc822Name, string()} |
    +general_name() = {rfc822Name, string()} |
     
    -                 {dNSName, string()} |
    +                 {dNSName, string()} |
     
    -                 {x400Address, string() |
    +                 {x400Address, string() |
     
    -                 {directoryName, {rdnSequence, [#'AttributeTypeAndValue'{}]}} |
    +                 {directoryName, {rdnSequence, [#'AttributeTypeAndValue'{}]}} |
     
    -                 {ediPartyName, special_string()} |
    +                 {ediPartyName, special_string()} |
     
    -                 {ediPartyName, special_string(), special_string()} |
    +                 {ediPartyName, special_string(), special_string()} |
     
    -                 {uniformResourceIdentifier, string()} |
    +                 {uniformResourceIdentifier, string()} |
     
    -                 {iPAddress, string()} |
    +                 {iPAddress, string()} |
     
    -                 {registeredId, oid()} |
    +                 {registeredId, oid()} |
     
    -                 {otherName, term()}
    +                 {otherName, term()}
     
    -special_string() = {teletexString, string()} |
    +special_string() = {teletexString, string()} |
      
    -                   {printableString, string()} |
    +                   {printableString, string()} |
     
    -                   {universalString, string()} |
    +                   {universalString, string()} |
     
    -                   {utf8String, binary()} |
    +                   {utf8String, binary()} |
     
    -                   {bmpString, string()}
    +                   {bmpString, string()}
     
    -dist_reason() = unused | keyCompromise | cACompromise | affiliationChanged |
    +dist_reason() = unused | keyCompromise | cACompromise | affiliationChanged |
                     cessationOfOperation | certificateHold | privilegeWithdrawn | aACompromise
     
    -OID_macro() = ?OID_name()
    +OID_macro() = ?OID_name()
     
    -OID_name() = atom()

    +OID_name() = atom()

    @@ -186,12 +186,12 @@

    Erlang representation of Rivest-Shamir-Adleman cryptosystem (RSA) -keys follows:

    #'RSAPublicKey'{
    +keys follows:

    #'RSAPublicKey'{
        modulus,       % pos_integer()
        publicExponent % pos_integer()
    -  }.
    +  }.
     
    -#'RSAPrivateKey'{
    +#'RSAPrivateKey'{
        version,         % two-prime | multi
        modulus,         % pos_integer()
        publicExponent,  % pos_integer()
    @@ -202,50 +202,50 @@ 

    exponent2, % pos_integer() coefficient, % pos_integer() otherPrimeInfos % [#OtherPrimeInfo{}] | asn1_NOVALUE - }. + }. -#'OtherPrimeInfo'{ +#'OtherPrimeInfo'{ prime, % pos_integer() exponent, % pos_integer() coefficient % pos_integer() - }. + }. -#'RSASSA-PSS-params'{ +#'RSASSA-PSS-params'{ hashAlgorithm, % #'HashAlgorithm'{}}, maskGenAlgorithm, % #'MaskGenAlgorithm'{}}, saltLength, % pos_integer(), trailerField, % pos_integer() - }. + }. -#'HashAlgorithm'{ +#'HashAlgorithm'{ algorithm, % oid() parameters % defaults to asn1_NOVALUE - }. + }. -#'MaskGenAlgorithm'{ +#'MaskGenAlgorithm'{ algorithm, % oid() parameters, % defaults to asn1_NOVALUE - }.

    + }.

    DSA

    Erlang representation of -Digital Signature Algorithm (DSA) keys

    #'DSAPrivateKey'{
    +Digital Signature Algorithm (DSA) keys

    #'DSAPrivateKey'{
        version,      % pos_integer()
        p,            % pos_integer()
        q,            % pos_integer()
        g,            % pos_integer()
        y,            % pos_integer()
        x             % pos_integer()
    -  }.
    +  }.
     
    -#'Dss-Parms'{
    +#'Dss-Parms'{
        p,         % pos_integer()
        q,         % pos_integer()
        g          % pos_integer()
    -  }.

    + }.

    @@ -256,38 +256,38 @@

    and Edwards-Curve Digital Signature Algorithm (EDDSA) where parameters in the private key will be -{namedCurve, ?'id-Ed25519' | ?'id-Ed448'}.

    #'ECPrivateKey'{
    +{namedCurve, ?'id-Ed25519' | ?'id-Ed448'}.

    #'ECPrivateKey'{
        version,       % pos_integer()
        privateKey,    % binary()
        parameters,    % {ecParameters, #'ECParameters'{}} |
                       % {namedCurve, Oid::tuple()} |
                       % {implicitlyCA, 'NULL'}
        publicKey      % bitstring()
    -  }.
    +  }.
     
    -#'ECParameters'{
    +#'ECParameters'{
        version,    % pos_integer()
        fieldID,    % #'FieldID'{}
        curve,      % #'Curve'{}
        base,       % binary()
        order,      % pos_integer()
        cofactor    % pos_integer()
    -  }.
    +  }.
     
    -#'Curve'{
    +#'Curve'{
        a,        % binary()
        b,        % binary()
        seed      % bitstring() - optional
    -  }.
    +  }.
     
    -#'FieldID'{
    +#'FieldID'{
        fieldType,    % oid()
        parameters    % Depending on fieldType
    -  }.
    +  }.
     
    -#'ECPoint'{
    +#'ECPoint'{
        point %  binary() - the public key
    -  }.

    + }.

    @@ -295,13 +295,13 @@

    Erlang representation of PKIX certificates derived from ASN.1 specifications see also X509 certificates (RFC 5280), also -referred to as plain type, are as follows:

    #'Certificate'{
    +referred to as plain type, are as follows:

    #'Certificate'{
        tbsCertificate,        % #'TBSCertificate'{}
        signatureAlgorithm,    % #'AlgorithmIdentifier'{}
        signature              % bitstring()
    -  }.
    +  }.
     
    -#'TBSCertificate'{
    +#'TBSCertificate'{
        version,              % v1 | v2 | v3
        serialNumber,         % pos_integer()
        signature,            % #'AlgorithmIdentifier'{}
    @@ -312,19 +312,19 @@ 

    issuerUniqueID, % binary() | asn1_novalue subjectUniqueID, % binary() | asn1_novalue extensions % [#'Extension'{}] - }. + }. -#'AlgorithmIdentifier'{ +#'AlgorithmIdentifier'{ algorithm, % oid() parameters % der_encoded() - }.

    Erlang alternate representation of PKIX certificate, also referred to as otp -type

    #'OTPCertificate'{
    +  }.

    Erlang alternate representation of PKIX certificate, also referred to as otp +type

    #'OTPCertificate'{
        tbsCertificate,        % #'OTPTBSCertificate'{}
        signatureAlgorithm,    % #'SignatureAlgorithm'
        signature              % bitstring()
    -  }.
    +  }.
     
    -#'OTPTBSCertificate'{
    +#'OTPTBSCertificate'{
        version,              % v1 | v2 | v3
        serialNumber,         % pos_integer()
        signature,            % #'SignatureAlgorithm'
    @@ -335,35 +335,35 @@ 

    issuerUniqueID, % binary() | asn1_novalue subjectUniqueID, % binary() | asn1_novalue extensions % [#'Extension'{}] - }. + }. -#'SignatureAlgorithm'{ +#'SignatureAlgorithm'{ algorithm, % id_signature_algorithm() parameters % asn1_novalue | #'Dss-Parms'{} - }.

    id_signature_algorithm() = OID_macro()

    The available OID names are as follows:

    OID Name
    id-dsa-with-sha1
    id-dsaWithSHA1 (ISO or OID to above)
    md2WithRSAEncryption
    md5WithRSAEncryption
    sha1WithRSAEncryption
    sha-1WithRSAEncryption (ISO or OID to above)
    sha224WithRSAEncryption
    sha256WithRSAEncryption
    sha512WithRSAEncryption
    ecdsa-with-SHA1

    Table: Signature Algorithm OIDs

    The data type 'AttributeTypeAndValue', is represented as the following erlang -record:

    #'AttributeTypeAndValue'{
    +  }.

    id_signature_algorithm() = OID_macro()

    The available OID names are as follows:

    OID Name
    id-dsa-with-sha1
    id-dsaWithSHA1 (ISO or OID to above)
    md2WithRSAEncryption
    md5WithRSAEncryption
    sha1WithRSAEncryption
    sha-1WithRSAEncryption (ISO or OID to above)
    sha224WithRSAEncryption
    sha256WithRSAEncryption
    sha512WithRSAEncryption
    ecdsa-with-SHA1

    Table: Signature Algorithm OIDs

    The data type 'AttributeTypeAndValue', is represented as the following erlang +record:

    #'AttributeTypeAndValue'{
        type,   % id_attributes()
        value   % term()
    -  }.

    The attribute OID name atoms and their corresponding value types are as follows:

    OID NameValue Type
    id-at-namespecial_string()
    id-at-surnamespecial_string()
    id-at-givenNamespecial_string()
    id-at-initialsspecial_string()
    id-at-generationQualifierspecial_string()
    id-at-commonNamespecial_string()
    id-at-localityNamespecial_string()
    id-at-stateOrProvinceNamespecial_string()
    id-at-organizationNamespecial_string()
    id-at-titlespecial_string()
    id-at-dnQualifier{printableString, string()}
    id-at-countryName{printableString, string()}
    id-at-serialNumber{printableString, string()}
    id-at-pseudonymspecial_string()

    Table: Attribute OIDs

    The data types 'Validity', 'SubjectPublicKeyInfo', and + }.

    The attribute OID name atoms and their corresponding value types are as follows:

    OID NameValue Type
    id-at-namespecial_string()
    id-at-surnamespecial_string()
    id-at-givenNamespecial_string()
    id-at-initialsspecial_string()
    id-at-generationQualifierspecial_string()
    id-at-commonNamespecial_string()
    id-at-localityNamespecial_string()
    id-at-stateOrProvinceNamespecial_string()
    id-at-organizationNamespecial_string()
    id-at-titlespecial_string()
    id-at-dnQualifier{printableString, string()}
    id-at-countryName{printableString, string()}
    id-at-serialNumber{printableString, string()}
    id-at-pseudonymspecial_string()

    Table: Attribute OIDs

    The data types 'Validity', 'SubjectPublicKeyInfo', and 'SubjectPublicKeyInfoAlgorithm' are represented as the following Erlang -records:

    #'Validity'{
    +records:

    #'Validity'{
        notBefore, % time()
        notAfter   % time()
    -  }.
    +  }.
     
    -#'SubjectPublicKeyInfo'{
    +#'SubjectPublicKeyInfo'{
        algorithm,       % #AlgorithmIdentifier{}
        subjectPublicKey % binary()
    -  }.
    +  }.
     
    -#'SubjectPublicKeyInfoAlgorithm'{
    +#'SubjectPublicKeyInfoAlgorithm'{
        algorithm,  % id_public_key_algorithm()
        parameters  % public_key_params()
    -  }.

    The public-key algorithm OID name atoms are as follows:

    OID Name
    rsaEncryption
    id-dsa
    dhpublicnumber
    id-keyExchangeAlgorithm
    id-ecPublicKey

    Table: Public-Key Algorithm OIDs

    #'Extension'{
    +  }.

    The public-key algorithm OID name atoms are as follows:

    OID Name
    rsaEncryption
    id-dsa
    dhpublicnumber
    id-keyExchangeAlgorithm
    id-ecPublicKey

    Table: Public-Key Algorithm OIDs

    #'Extension'{
        extnID,    % id_extensions() | oid()
        critical,  % boolean()
        extnValue  % der_encoded()
    -  }.

    id_extensions() + }.

    id_extensions() Standard Certificate Extensions, Private Internet Extensions, CRL Extensions and @@ -374,98 +374,98 @@

    Standard Certificate Extensions

    The standard certificate extensions OID name atoms and their corresponding value -types are as follows:

    OID NameValue Type
    id-ce-authorityKeyIdentifier#'AuthorityKeyIdentifier'{}
    id-ce-subjectKeyIdentifieroid()
    id-ce-keyUsage[key_usage()]
    id-ce-privateKeyUsagePeriod#'PrivateKeyUsagePeriod'{}
    id-ce-certificatePolicies#'PolicyInformation'{}
    id-ce-policyMappings#'PolicyMappings_SEQOF'{}
    id-ce-subjectAltNamegeneral_name()
    id-ce-issuerAltNamegeneral_name()
    id-ce-subjectDirectoryAttributes[#'Attribute'{}]
    id-ce-basicConstraints#'BasicConstraints'{}
    id-ce-nameConstraints#'NameConstraints'{}
    id-ce-policyConstraints#'PolicyConstraints'{}
    id-ce-extKeyUsage[id_key_purpose()]
    id-ce-cRLDistributionPoints[#'DistributionPoint'{}]
    id-ce-inhibitAnyPolicypos_integer()
    id-ce-freshestCRL[#'DistributionPoint'{}]

    Table: Standard Certificate Extensions

    Here:

    key_usage() = digitalSignature | nonRepudiation | keyEncipherment
    +types are as follows:

    OID NameValue Type
    id-ce-authorityKeyIdentifier#'AuthorityKeyIdentifier'{}
    id-ce-subjectKeyIdentifieroid()
    id-ce-keyUsage[key_usage()]
    id-ce-privateKeyUsagePeriod#'PrivateKeyUsagePeriod'{}
    id-ce-certificatePolicies#'PolicyInformation'{}
    id-ce-policyMappings#'PolicyMappings_SEQOF'{}
    id-ce-subjectAltNamegeneral_name()
    id-ce-issuerAltNamegeneral_name()
    id-ce-subjectDirectoryAttributes[#'Attribute'{}]
    id-ce-basicConstraints#'BasicConstraints'{}
    id-ce-nameConstraints#'NameConstraints'{}
    id-ce-policyConstraints#'PolicyConstraints'{}
    id-ce-extKeyUsage[id_key_purpose()]
    id-ce-cRLDistributionPoints[#'DistributionPoint'{}]
    id-ce-inhibitAnyPolicypos_integer()
    id-ce-freshestCRL[#'DistributionPoint'{}]

    Table: Standard Certificate Extensions

    Here:

    key_usage() = digitalSignature | nonRepudiation | keyEncipherment
                 | dataEncipherment | keyAgreement | keyCertSign
    -            | cRLSign | encipherOnly | decipherOnly

    And for id_key_purpose():

    OID Name
    id-kp-serverAuth
    id-kp-clientAuth
    id-kp-codeSigning
    id-kp-emailProtection
    id-kp-timeStamping
    id-kp-OCSPSigning

    Table: Key Purpose OIDs

    #'AuthorityKeyIdentifier'{
    +            | cRLSign | encipherOnly | decipherOnly

    And for id_key_purpose():

    OID Name
    id-kp-serverAuth
    id-kp-clientAuth
    id-kp-codeSigning
    id-kp-emailProtection
    id-kp-timeStamping
    id-kp-OCSPSigning

    Table: Key Purpose OIDs

    #'AuthorityKeyIdentifier'{
        keyIdentifier,            % oid()
        authorityCertIssuer,      % general_name()
        authorityCertSerialNumber % pos_integer()
    -  }.
    +  }.
     
    -#'PrivateKeyUsagePeriod'{
    +#'PrivateKeyUsagePeriod'{
        notBefore,   % general_time()
        notAfter     % general_time()
    -  }.
    +  }.
     
    -#'PolicyInformation'{
    +#'PolicyInformation'{
        policyIdentifier,  % oid()
        policyQualifiers   % [#PolicyQualifierInfo{}]
    -  }.
    +  }.
     
    -#'PolicyQualifierInfo'{
    +#'PolicyQualifierInfo'{
        policyQualifierId,   % oid()
        qualifier            % string() | #'UserNotice'{}
    -  }.
    +  }.
     
    -#'UserNotice'{
    +#'UserNotice'{
        noticeRef,   % #'NoticeReference'{}
        explicitText % string()
    -  }.
    +  }.
     
    -#'NoticeReference'{
    +#'NoticeReference'{
        organization,    % string()
        noticeNumbers    % [pos_integer()]
    -  }.
    +  }.
     
    -#'PolicyMappings_SEQOF'{
    +#'PolicyMappings_SEQOF'{
        issuerDomainPolicy,  % oid()
        subjectDomainPolicy  % oid()
    -  }.
    +  }.
     
    -#'Attribute'{
    +#'Attribute'{
        type,  % oid()
        values % [der_encoded()]
    -  }).
    +  }).
     
    -#'BasicConstraints'{
    +#'BasicConstraints'{
        cA,               % boolean()
        pathLenConstraint % pos_integer()
    -  }).
    +  }).
     
    -#'NameConstraints'{
    +#'NameConstraints'{
        permittedSubtrees, % [#'GeneralSubtree'{}]
        excludedSubtrees   % [#'GeneralSubtree'{}]
    -  }).
    +  }).
     
    -#'GeneralSubtree'{
    +#'GeneralSubtree'{
        base,    % general_name()
        minimum, % pos_integer()
        maximum  % pos_integer()
    -  }).
    +  }).
     
    -#'PolicyConstraints'{
    +#'PolicyConstraints'{
        requireExplicitPolicy, % pos_integer()
        inhibitPolicyMapping   % pos_integer()
    -  }).
    +  }).
     
    -#'DistributionPoint'{
    +#'DistributionPoint'{
        distributionPoint, % {fullName, [general_name()]} | {nameRelativeToCRLIssuer,[#AttributeTypeAndValue{}]}
        reasons,           % [dist_reason()]
        cRLIssuer          % [general_name()]
    -  }).

    + }).

    Private Internet Extensions

    The private internet extensions OID name atoms and their corresponding value -types are as follows:

    OID NameValue Type
    id-pe-authorityInfoAccess[#'AccessDescription'{}]
    id-pe-subjectInfoAccess[#'AccessDescription'{}]

    Table: Private Internet Extensions

    #'AccessDescription'{
    +types are as follows:

    OID NameValue Type
    id-pe-authorityInfoAccess[#'AccessDescription'{}]
    id-pe-subjectInfoAccess[#'AccessDescription'{}]

    Table: Private Internet Extensions

    #'AccessDescription'{
        accessMethod,    % oid()
        accessLocation   % general_name()
    -  }).

    + }).

    CRL and CRL Extensions Profile

    Erlang representation of CRL and CRL extensions profile derived from ASN.1 -specifications and RFC 5280 are as follows:

    #'CertificateList'{
    +specifications and RFC 5280 are as follows:

    #'CertificateList'{
        tbsCertList,        % #'TBSCertList{}
        signatureAlgorithm, % #'AlgorithmIdentifier'{}
        signature           % bitstring()
    -  }).
    +  }).
     
    -#'TBSCertList'{
    +#'TBSCertList'{
        version,             % v2 (if defined)
        signature,           % #AlgorithmIdentifier{}
        issuer,              % {rdnSequence, [#AttributeTypeAndValue'{}]}
    @@ -473,13 +473,13 @@ 

    nextUpdate, % time() revokedCertificates, % [#'TBSCertList_revokedCertificates_SEQOF'{}] crlExtensions % [#'Extension'{}] - }). + }). -#'TBSCertList_revokedCertificates_SEQOF'{ +#'TBSCertList_revokedCertificates_SEQOF'{ userCertificate, % pos_integer() revocationDate, % timer() crlEntryExtensions % [#'Extension'{}] - }).

    + }).

    @@ -487,21 +487,21 @@

    The CRL extensions OID name atoms and their corresponding value types are as follows:

    OID NameValue Type
    id-ce-authorityKeyIdentifier#'AuthorityKeyIdentifier{}
    id-ce-issuerAltName{rdnSequence, [#AttributeTypeAndValue'{}]}
    id-ce-cRLNumberpos_integer()
    id-ce-deltaCRLIndicatorpos_integer()
    id-ce-issuingDistributionPoint#'IssuingDistributionPoint'{}
    id-ce-freshestCRL[#'Distributionpoint'{}]

    Table: CRL Extensions

    Here, the data type 'IssuingDistributionPoint' is represented as the following -Erlang record:

    #'IssuingDistributionPoint'{
    +Erlang record:

    #'IssuingDistributionPoint'{
        distributionPoint,         % {fullName, [general_name()]} | {nameRelativeToCRLIssuer, [#'AttributeTypeAndValue'{}]}
        onlyContainsUserCerts,     % boolean()
        onlyContainsCACerts,       % boolean()
        onlySomeReasons,           % [dist_reason()]
        indirectCRL,               % boolean()
        onlyContainsAttributeCerts % boolean()
    -  }).

    + }).

    CRL Entry Extensions

    The CRL entry extensions OID name atoms and their corresponding value types are -as follows:

    OID NameValue Type
    id-ce-cRLReasoncrl_reason()
    id-ce-holdInstructionCodeoid()
    id-ce-invalidityDategeneral_time()
    id-ce-certificateIssuergeneral_name()

    Table: CRL Entry Extensions

    Here:

        crl_reason() = unspecified | keyCompromise | cACompromise
    +as follows:

    OID NameValue Type
    id-ce-cRLReasoncrl_reason()
    id-ce-holdInstructionCodeoid()
    id-ce-invalidityDategeneral_time()
    id-ce-certificateIssuergeneral_name()

    Table: CRL Entry Extensions

    Here:

        crl_reason() = unspecified | keyCompromise | cACompromise
                      | affiliationChanged | superseded | cessationOfOperation
                      | certificateHold | removeFromCRL
                      | privilegeWithdrawn | aACompromise

    @@ -511,38 +511,38 @@

    PKCS#10 Certification Request

    Erlang representation of a PKCS#10 certification request derived from ASN.1 -specifications and RFC 5280 are as follows:

    #'CertificationRequest'{
    +specifications and RFC 5280 are as follows:

    #'CertificationRequest'{
        certificationRequestInfo, % #'CertificationRequestInfo'{},
        signatureAlgorithm,       % #'CertificationRequest_signatureAlgorithm'{}}.
        signature                 % bitstring()
    -  }.
    +  }.
     
    -#'CertificationRequestInfo'{
    +#'CertificationRequestInfo'{
        version,       % atom(),
        subject,       % {rdnSequence, [#AttributeTypeAndValue'{}]} ,
        subjectPKInfo, % #'CertificationRequestInfo_subjectPKInfo'{},
        attributes     % [#'AttributePKCS-10' {}]
    -  }.
    +  }.
     
    -#'CertificationRequestInfo_subjectPKInfo'{
    +#'CertificationRequestInfo_subjectPKInfo'{
        algorithm,        % #'CertificationRequestInfo_subjectPKInfo_algorithm'{}
        subjectPublicKey  %  bitstring()
    -  }.
    +  }.
     
    -#'CertificationRequestInfo_subjectPKInfo_algorithm'{
    +#'CertificationRequestInfo_subjectPKInfo_algorithm'{
        algorithm,  % oid(),
        parameters  % der_encoded()
    -  }.
    +  }.
     
    -#'CertificationRequest_signatureAlgorithm'{
    +#'CertificationRequest_signatureAlgorithm'{
        algorithm,  % oid(),
        parameters  % der_encoded()
    -  }.
    +  }.
     
    -#'AttributePKCS-10'{
    +#'AttributePKCS-10'{
        type,   % oid(),
        values  % [der_encoded()]
    -  }.

    +
    }.

    diff --git a/prs/8803/lib/public_key-1.16.1/doc/html/using_public_key.html b/prs/8803/lib/public_key-1.16.1/doc/html/using_public_key.html index 98980cd46a248..bace6bedb63fb 100644 --- a/prs/8803/lib/public_key-1.16.1/doc/html/using_public_key.html +++ b/prs/8803/lib/public_key-1.16.1/doc/html/using_public_key.html @@ -148,30 +148,30 @@

    DSA Private Key

    -

    A DSA private key can look as follows:

    Note

    File handling is not done by the Public Key application.

    1> {ok, PemBin} = file:read_file("dsa.pem").
    -{ok,<<"-----BEGIN DSA PRIVATE KEY-----\nMIIBuw"...>>}

    The following PEM file has only one entry, a private DSA key:

    2>[DSAEntry] =  public_key:pem_decode(PemBin).
    -[{'DSAPrivateKey',<<48,130,1,187,2,1,0,2,129,129,0,183,
    +

    A DSA private key can look as follows:

    Note

    File handling is not done by the Public Key application.

    1> {ok, PemBin} = file:read_file("dsa.pem").
    +{ok,<<"-----BEGIN DSA PRIVATE KEY-----\nMIIBuw"...>>}

    The following PEM file has only one entry, a private DSA key:

    2>[DSAEntry] =  public_key:pem_decode(PemBin).
    +[{'DSAPrivateKey',<<48,130,1,187,2,1,0,2,129,129,0,183,
                         179,230,217,37,99,144,157,21,228,204,
                         162,207,61,246,...>>,
    -                    not_encrypted}]
    3> Key = public_key:pem_entry_decode(DSAEntry).
    -#'DSAPrivateKey'{version = 0,
    +                    not_encrypted}]
    3> Key = public_key:pem_entry_decode(DSAEntry).
    +#'DSAPrivateKey'{version = 0,
                      p = 12900045185019966618...6593,
                      q = 1216700114794736143432235288305776850295620488937,
                      g = 10442040227452349332...47213,
                      y = 87256807980030509074...403143,
    -                 x = 510968529856012146351317363807366575075645839654}

    + x = 510968529856012146351317363807366575075645839654}

    RSA Private Key with Password

    -

    An RSA private key encrypted with a password can look as follows:

    1> {ok, PemBin} = file:read_file("rsa.pem").
    -{ok,<<"Bag Attribute"...>>}

    The following PEM file has only one entry, a private RSA key:

    2>[RSAEntry] = public_key:pem_decode(PemBin).
    -[{'RSAPrivateKey',<<224,108,117,203,152,40,15,77,128,126,
    +

    An RSA private key encrypted with a password can look as follows:

    1> {ok, PemBin} = file:read_file("rsa.pem").
    +{ok,<<"Bag Attribute"...>>}

    The following PEM file has only one entry, a private RSA key:

    2>[RSAEntry] = public_key:pem_decode(PemBin).
    +[{'RSAPrivateKey',<<224,108,117,203,152,40,15,77,128,126,
                         221,195,154,249,85,208,202,251,109,
                         119,120,57,29,89,19,9,...>>,
    -                  {"DES-EDE3-CBC",<<"kÙeø¼pµL">>}}]

    In this following example, the password is "abcd1234":

    3> Key = public_key:pem_entry_decode(RSAEntry, "abcd1234").
    -#'RSAPrivateKey'{version = 'two-prime',
    +                  {"DES-EDE3-CBC",<<"kÙeø¼pµL">>}}]

    In this following example, the password is "abcd1234":

    3> Key = public_key:pem_entry_decode(RSAEntry, "abcd1234").
    +#'RSAPrivateKey'{version = 'two-prime',
                      modulus = 1112355156729921663373...2737107,
                      publicExponent = 65537,
                      privateExponent = 58064406231183...2239766033,
    @@ -180,201 +180,201 @@ 

    exponent1 = 77928819327425934607...22152984217, exponent2 = 36287623121853605733...20588523793, coefficient = 924840412626098444...41820968343, - otherPrimeInfos = asn1_NOVALUE}

    + otherPrimeInfos = asn1_NOVALUE}

    X509 Certificates

    -

    The following is an example of X509 certificates:

    1> {ok, PemBin} = file:read_file("cacerts.pem").
    -{ok,<<"-----BEGIN CERTIFICATE-----\nMIIC7jCCAl"...>>}

    The following file includes two certificates:

    2> [CertEntry1, CertEntry2] = public_key:pem_decode(PemBin).
    -[{'Certificate',<<48,130,2,238,48,130,2,87,160,3,2,1,2,2,
    +

    The following is an example of X509 certificates:

    1> {ok, PemBin} = file:read_file("cacerts.pem").
    +{ok,<<"-----BEGIN CERTIFICATE-----\nMIIC7jCCAl"...>>}

    The following file includes two certificates:

    2> [CertEntry1, CertEntry2] = public_key:pem_decode(PemBin).
    +[{'Certificate',<<48,130,2,238,48,130,2,87,160,3,2,1,2,2,
                       9,0,230,145,97,214,191,2,120,150,48,13,
                       ...>>,
    -                not_encrypted},
    - {'Certificate',<<48,130,3,200,48,130,3,49,160,3,2,1,2,2,1,
    +                not_encrypted},
    + {'Certificate',<<48,130,3,200,48,130,3,49,160,3,2,1,2,2,1,
                       1,48,13,6,9,42,134,72,134,247,...>>,
    -                not_encrypted}]

    Certificates can be decoded as usual:

    2> Cert = public_key:pem_entry_decode(CertEntry1).
    -#'Certificate'{
    +                not_encrypted}]

    Certificates can be decoded as usual:

    2> Cert = public_key:pem_entry_decode(CertEntry1).
    +#'Certificate'{
         tbsCertificate =
    -        #'TBSCertificate'{
    +        #'TBSCertificate'{
                 version = v3,serialNumber = 16614168075301976214,
                 signature =
    -                #'AlgorithmIdentifier'{
    -                    algorithm = {1,2,840,113549,1,1,5},
    -                    parameters = <<5,0>>},
    +                #'AlgorithmIdentifier'{
    +                    algorithm = {1,2,840,113549,1,1,5},
    +                    parameters = <<5,0>>},
                 issuer =
    -                {rdnSequence,
    -                    [[#'AttributeTypeAndValue'{
    -                          type = {2,5,4,3},
    -                          value = <<19,8,101,114,108,97,110,103,67,65>>}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {2,5,4,11},
    -                          value = <<19,10,69,114,108,97,110,103,32,79,84,80>>}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {2,5,4,10},
    -                          value = <<19,11,69,114,105,99,115,115,111,110,32,65,66>>}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {2,5,4,7},
    -                          value = <<19,9,83,116,111,99,107,104,111,108,109>>}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {2,5,4,6},
    -                          value = <<19,2,83,69>>}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {1,2,840,113549,1,9,1},
    -                          value = <<22,22,112,101,116,101,114,64,101,114,...>>}]]},
    +                {rdnSequence,
    +                    [[#'AttributeTypeAndValue'{
    +                          type = {2,5,4,3},
    +                          value = <<19,8,101,114,108,97,110,103,67,65>>}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {2,5,4,11},
    +                          value = <<19,10,69,114,108,97,110,103,32,79,84,80>>}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {2,5,4,10},
    +                          value = <<19,11,69,114,105,99,115,115,111,110,32,65,66>>}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {2,5,4,7},
    +                          value = <<19,9,83,116,111,99,107,104,111,108,109>>}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {2,5,4,6},
    +                          value = <<19,2,83,69>>}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {1,2,840,113549,1,9,1},
    +                          value = <<22,22,112,101,116,101,114,64,101,114,...>>}]]},
                 validity =
    -                #'Validity'{
    -                    notBefore = {utcTime,"080109082929Z"},
    -                    notAfter = {utcTime,"080208082929Z"}},
    +                #'Validity'{
    +                    notBefore = {utcTime,"080109082929Z"},
    +                    notAfter = {utcTime,"080208082929Z"}},
                 subject =
    -                {rdnSequence,
    -                    [[#'AttributeTypeAndValue'{
    -                          type = {2,5,4,3},
    -                          value = <<19,8,101,114,108,97,110,103,67,65>>}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {2,5,4,11},
    -                          value = <<19,10,69,114,108,97,110,103,32,79,84,80>>}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {2,5,4,10},
    -                          value = <<19,11,69,114,105,99,115,115,111,110,32,...>>}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {2,5,4,7},
    -                          value = <<19,9,83,116,111,99,107,104,111,108,...>>}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {2,5,4,6},
    -                          value = <<19,2,83,69>>}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {1,2,840,113549,1,9,1},
    -                          value = <<22,22,112,101,116,101,114,64,...>>}]]},
    +                {rdnSequence,
    +                    [[#'AttributeTypeAndValue'{
    +                          type = {2,5,4,3},
    +                          value = <<19,8,101,114,108,97,110,103,67,65>>}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {2,5,4,11},
    +                          value = <<19,10,69,114,108,97,110,103,32,79,84,80>>}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {2,5,4,10},
    +                          value = <<19,11,69,114,105,99,115,115,111,110,32,...>>}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {2,5,4,7},
    +                          value = <<19,9,83,116,111,99,107,104,111,108,...>>}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {2,5,4,6},
    +                          value = <<19,2,83,69>>}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {1,2,840,113549,1,9,1},
    +                          value = <<22,22,112,101,116,101,114,64,...>>}]]},
                 subjectPublicKeyInfo =
    -                #'SubjectPublicKeyInfo'{
    +                #'SubjectPublicKeyInfo'{
                         algorithm =
    -                        #'AlgorithmIdentifier'{
    -                            algorithm = {1,2,840,113549,1,1,1},
    -                            parameters = <<5,0>>},
    +                        #'AlgorithmIdentifier'{
    +                            algorithm = {1,2,840,113549,1,1,1},
    +                            parameters = <<5,0>>},
                         subjectPublicKey =
    -                        {0,<<48,129,137,2,129,129,0,203,209,187,77,73,231,90,...>>}},
    +                        {0,<<48,129,137,2,129,129,0,203,209,187,77,73,231,90,...>>}},
                 issuerUniqueID = asn1_NOVALUE,
                 subjectUniqueID = asn1_NOVALUE,
                 extensions =
    -                [#'Extension'{
    -                     extnID = {2,5,29,19},
    +                [#'Extension'{
    +                     extnID = {2,5,29,19},
                          critical = true,
    -                     extnValue = [48,3,1,1,255]},
    -                 #'Extension'{
    -                     extnID = {2,5,29,15},
    +                     extnValue = [48,3,1,1,255]},
    +                 #'Extension'{
    +                     extnID = {2,5,29,15},
                          critical = false,
    -                     extnValue = [3,2,1,6]},
    -                 #'Extension'{
    -                     extnID = {2,5,29,14},
    +                     extnValue = [3,2,1,6]},
    +                 #'Extension'{
    +                     extnID = {2,5,29,14},
                          critical = false,
    -                     extnValue = [4,20,27,217,65,152,6,30,142|...]},
    -                 #'Extension'{
    -                     extnID = {2,5,29,17},
    +                     extnValue = [4,20,27,217,65,152,6,30,142|...]},
    +                 #'Extension'{
    +                     extnID = {2,5,29,17},
                          critical = false,
    -                     extnValue = [48,24,129,22,112,101,116,101|...]}]},
    +                     extnValue = [48,24,129,22,112,101,116,101|...]}]},
         signatureAlgorithm =
    -        #'AlgorithmIdentifier'{
    -            algorithm = {1,2,840,113549,1,1,5},
    -            parameters = <<5,0>>},
    +        #'AlgorithmIdentifier'{
    +            algorithm = {1,2,840,113549,1,1,5},
    +            parameters = <<5,0>>},
         signature =
         <<163,186,7,163,216,152,63,47,154,234,139,73,154,96,120,
    -    165,2,52,196,195,109,167,192,...>>}

    Parts of certificates can be decoded with public_key:der_decode/2, using the + 165,2,52,196,195,109,167,192,...>>}

    Parts of certificates can be decoded with public_key:der_decode/2, using the ASN.1 type of that part. However, an application-specific certificate extension requires application-specific ASN.1 decode/encode-functions. In the recent example, the first value of rdnSequence is of ASN.1 type -'X520CommonName'. ({2,5,4,3} = ?id-at-commonName):

    public_key:der_decode('X520CommonName', <<19,8,101,114,108,97,110,103,67,65>>).
    -{printableString,"erlangCA"}

    However, certificates can also be decoded using pkix_decode_cert/2, which can -customize and recursively decode standard parts of a certificate:

    3> {_, DerCert, _} = CertEntry1.
    4> public_key:pkix_decode_cert(DerCert, otp).
    -#'OTPCertificate'{
    +'X520CommonName'. ({2,5,4,3} = ?id-at-commonName):

    public_key:der_decode('X520CommonName', <<19,8,101,114,108,97,110,103,67,65>>).
    +{printableString,"erlangCA"}

    However, certificates can also be decoded using pkix_decode_cert/2, which can +customize and recursively decode standard parts of a certificate:

    3> {_, DerCert, _} = CertEntry1.
    4> public_key:pkix_decode_cert(DerCert, otp).
    +#'OTPCertificate'{
         tbsCertificate =
    -        #'OTPTBSCertificate'{
    +        #'OTPTBSCertificate'{
                 version = v3,serialNumber = 16614168075301976214,
                 signature =
    -                #'SignatureAlgorithm'{
    -                    algorithm = {1,2,840,113549,1,1,5},
    -                    parameters = 'NULL'},
    +                #'SignatureAlgorithm'{
    +                    algorithm = {1,2,840,113549,1,1,5},
    +                    parameters = 'NULL'},
                 issuer =
    -                {rdnSequence,
    -                    [[#'AttributeTypeAndValue'{
    -                          type = {2,5,4,3},
    -                          value = {printableString,"erlangCA"}}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {2,5,4,11},
    -                          value = {printableString,"Erlang OTP"}}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {2,5,4,10},
    -                          value = {printableString,"Ericsson AB"}}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {2,5,4,7},
    -                          value = {printableString,"Stockholm"}}],
    -                     [#'AttributeTypeAndValue'{type = {2,5,4,6},value = "SE"}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {1,2,840,113549,1,9,1},
    -                          value = "peter@erix.ericsson.se"}]]},
    +                {rdnSequence,
    +                    [[#'AttributeTypeAndValue'{
    +                          type = {2,5,4,3},
    +                          value = {printableString,"erlangCA"}}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {2,5,4,11},
    +                          value = {printableString,"Erlang OTP"}}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {2,5,4,10},
    +                          value = {printableString,"Ericsson AB"}}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {2,5,4,7},
    +                          value = {printableString,"Stockholm"}}],
    +                     [#'AttributeTypeAndValue'{type = {2,5,4,6},value = "SE"}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {1,2,840,113549,1,9,1},
    +                          value = "peter@erix.ericsson.se"}]]},
                 validity =
    -                #'Validity'{
    -                    notBefore = {utcTime,"080109082929Z"},
    -                    notAfter = {utcTime,"080208082929Z"}},
    +                #'Validity'{
    +                    notBefore = {utcTime,"080109082929Z"},
    +                    notAfter = {utcTime,"080208082929Z"}},
                 subject =
    -                {rdnSequence,
    -                    [[#'AttributeTypeAndValue'{
    -                          type = {2,5,4,3},
    -                          value = {printableString,"erlangCA"}}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {2,5,4,11},
    -                          value = {printableString,"Erlang OTP"}}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {2,5,4,10},
    -                          value = {printableString,"Ericsson AB"}}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {2,5,4,7},
    -                          value = {printableString,"Stockholm"}}],
    -                     [#'AttributeTypeAndValue'{type = {2,5,4,6},value = "SE"}],
    -                     [#'AttributeTypeAndValue'{
    -                          type = {1,2,840,113549,1,9,1},
    -                          value = "peter@erix.ericsson.se"}]]},
    +                {rdnSequence,
    +                    [[#'AttributeTypeAndValue'{
    +                          type = {2,5,4,3},
    +                          value = {printableString,"erlangCA"}}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {2,5,4,11},
    +                          value = {printableString,"Erlang OTP"}}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {2,5,4,10},
    +                          value = {printableString,"Ericsson AB"}}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {2,5,4,7},
    +                          value = {printableString,"Stockholm"}}],
    +                     [#'AttributeTypeAndValue'{type = {2,5,4,6},value = "SE"}],
    +                     [#'AttributeTypeAndValue'{
    +                          type = {1,2,840,113549,1,9,1},
    +                          value = "peter@erix.ericsson.se"}]]},
                 subjectPublicKeyInfo =
    -                #'OTPSubjectPublicKeyInfo'{
    +                #'OTPSubjectPublicKeyInfo'{
                         algorithm =
    -                        #'PublicKeyAlgorithm'{
    -                            algorithm = {1,2,840,113549,1,1,1},
    -                            parameters = 'NULL'},
    +                        #'PublicKeyAlgorithm'{
    +                            algorithm = {1,2,840,113549,1,1,1},
    +                            parameters = 'NULL'},
                         subjectPublicKey =
    -                        #'RSAPublicKey'{
    +                        #'RSAPublicKey'{
                                 modulus =
                                     1431267547247997...37419,
    -                            publicExponent = 65537}},
    +                            publicExponent = 65537}},
                 issuerUniqueID = asn1_NOVALUE,
                 subjectUniqueID = asn1_NOVALUE,
                 extensions =
    -                [#'Extension'{
    -                     extnID = {2,5,29,19},
    +                [#'Extension'{
    +                     extnID = {2,5,29,19},
                          critical = true,
                          extnValue =
    -                         #'BasicConstraints'{
    -                             cA = true,pathLenConstraint = asn1_NOVALUE}},
    -                 #'Extension'{
    -                     extnID = {2,5,29,15},
    +                         #'BasicConstraints'{
    +                             cA = true,pathLenConstraint = asn1_NOVALUE}},
    +                 #'Extension'{
    +                     extnID = {2,5,29,15},
                          critical = false,
    -                     extnValue = [keyCertSign,cRLSign]},
    -                 #'Extension'{
    -                     extnID = {2,5,29,14},
    +                     extnValue = [keyCertSign,cRLSign]},
    +                 #'Extension'{
    +                     extnID = {2,5,29,14},
                          critical = false,
    -                     extnValue = [27,217,65,152,6,30,142,132,245|...]},
    -                 #'Extension'{
    -                     extnID = {2,5,29,17},
    +                     extnValue = [27,217,65,152,6,30,142,132,245|...]},
    +                 #'Extension'{
    +                     extnID = {2,5,29,17},
                          critical = false,
    -                     extnValue = [{rfc822Name,"peter@erix.ericsson.se"}]}]},
    +                     extnValue = [{rfc822Name,"peter@erix.ericsson.se"}]}]},
         signatureAlgorithm =
    -        #'SignatureAlgorithm'{
    -            algorithm = {1,2,840,113549,1,1,5},
    -            parameters = 'NULL'},
    +        #'SignatureAlgorithm'{
    +            algorithm = {1,2,840,113549,1,1,5},
    +            parameters = 'NULL'},
         signature =
              <<163,186,7,163,216,152,63,47,154,234,139,73,154,96,120,
    -           165,2,52,196,195,109,167,192,...>>}

    This call is equivalent to public_key:pem_entry_decode(CertEntry1):

    5> public_key:pkix_decode_cert(DerCert, plain).
    -#'Certificate'{ ...}

    + 165,2,52,196,195,109,167,192,...>>}

    This call is equivalent to public_key:pem_entry_decode(CertEntry1):

    5> public_key:pkix_decode_cert(DerCert, plain).
    +#'Certificate'{ ...}

    @@ -385,17 +385,17 @@

    the result to a file. For example, assume that you have PubKey = 'RSAPublicKey'{}. Then you can create a PEM-"RSA PUBLIC KEY" file (ASN.1 type 'RSAPublicKey') or a PEM-"PUBLIC KEY" file -('SubjectPublicKeyInfo' ASN.1 type).

    The second element of the PEM-entry is the ASN.1 DER encoded key data:

    1> PemEntry = public_key:pem_entry_encode('RSAPublicKey', RSAPubKey).
    -{'RSAPublicKey', <<48,72,...>>, not_encrypted}
    +('SubjectPublicKeyInfo' ASN.1 type).

    The second element of the PEM-entry is the ASN.1 DER encoded key data:

    1> PemEntry = public_key:pem_entry_encode('RSAPublicKey', RSAPubKey).
    +{'RSAPublicKey', <<48,72,...>>, not_encrypted}
     
    -2> PemBin = public_key:pem_encode([PemEntry]).
    +2> PemBin = public_key:pem_encode([PemEntry]).
     <<"-----BEGIN RSA PUBLIC KEY-----\nMEgC...>>
     
     3> file:write_file("rsa_pub_key.pem", PemBin).
    -ok

    or:

    1> PemEntry = public_key:pem_entry_encode('SubjectPublicKeyInfo', RSAPubKey).
    -{'SubjectPublicKeyInfo', <<48,92...>>, not_encrypted}
    +ok

    or:

    1> PemEntry = public_key:pem_entry_encode('SubjectPublicKeyInfo', RSAPubKey).
    +{'SubjectPublicKeyInfo', <<48,92...>>, not_encrypted}
     
    -2> PemBin = public_key:pem_encode([PemEntry]).
    +2> PemBin = public_key:pem_encode([PemEntry]).
     <<"-----BEGIN PUBLIC KEY-----\nMFw...>>
     
     3> file:write_file("pub_key.pem", PemBin).
    @@ -405,9 +405,9 @@ 

    RSA Public-Key Cryptography

    -

    Suppose you have the following private key and a corresponding public key:

    • PrivateKey = #'RSAPrivateKey{}' and the plaintext Msg = binary()
    • PublicKey = #'RSAPublicKey'{}

    Then you can proceed as follows:

    Encrypt with the private key:

    RsaEncrypted = public_key:encrypt_private(Msg, PrivateKey),
    -Msg = public_key:decrypt_public(RsaEncrypted, PublicKey),

    Encrypt with the public key:

    RsaEncrypted = public_key:encrypt_public(Msg, PublicKey),
    -Msg = public_key:decrypt_private(RsaEncrypted, PrivateKey),

    Note

    You normally do only one of the encrypt or decrypt operations, and the peer +

    Suppose you have the following private key and a corresponding public key:

    • PrivateKey = #'RSAPrivateKey{}' and the plaintext Msg = binary()
    • PublicKey = #'RSAPublicKey'{}

    Then you can proceed as follows:

    Encrypt with the private key:

    RsaEncrypted = public_key:encrypt_private(Msg, PrivateKey),
    +Msg = public_key:decrypt_public(RsaEncrypted, PublicKey),

    Encrypt with the public key:

    RsaEncrypted = public_key:encrypt_public(Msg, PublicKey),
    +Msg = public_key:decrypt_private(RsaEncrypted, PrivateKey),

    Note

    You normally do only one of the encrypt or decrypt operations, and the peer does the other. This normally used in legacy applications as a primitive digital signature.

    Warning

    This legacy algorithm is broken although there exists a software prevention when using appropriate OpenSSL cryptolib with Erlang/OTP it is hard to @@ -418,12 +418,12 @@

    Digital Signatures

    Suppose you have the following private key and a corresponding public key:

    • PrivateKey = #'RSAPrivateKey{}' or #'DSAPrivateKey'{} and the plaintext -Msg = binary()
    • PublicKey = #'RSAPublicKey'{} or {integer(), #'DssParams'{}}

    Then you can proceed as follows:

    Signature = public_key:sign(Msg, sha, PrivateKey),
    -true = public_key:verify(Msg, sha, Signature, PublicKey),

    Note

    You normally do only one of the sign or verify operations, and the peer does +Msg = binary()

  • PublicKey = #'RSAPublicKey'{} or {integer(), #'DssParams'{}}
  • Then you can proceed as follows:

    Signature = public_key:sign(Msg, sha, PrivateKey),
    +true = public_key:verify(Msg, sha, Signature, PublicKey),

    Note

    You normally do only one of the sign or verify operations, and the peer does the other.

    It can be appropriate to calculate the message digest before calling sign or -verify, and then use none as second argument:

    Digest = crypto:sha(Msg),
    -Signature = public_key:sign(Digest, none, PrivateKey),
    -true = public_key:verify(Digest, none, Signature, PublicKey),

    +verify, and then use none as second argument:

    Digest = crypto:sha(Msg),
    +Signature = public_key:sign(Digest, none, PrivateKey),
    +true = public_key:verify(Digest, none, Signature, PublicKey),

    @@ -514,9 +514,9 @@

    Note

    Other applications like ssl/tls or https might have options that are passed down to the public_key:pkix_verify_hostname. You will probably not have to call it directly

    Suppose our client expects to connect to the web server https://www.example.net. -This URI is therefore the Reference IDs of the client. The call will be:

     public_key:pkix_verify_hostname(CertFromHost,
    -                                 [{uri_id, "https://www.example.net"}
    -                                 ]).

    The call will return true or false depending on the check. The caller do not +This URI is therefore the Reference IDs of the client. The call will be:

     public_key:pkix_verify_hostname(CertFromHost,
    +                                 [{uri_id, "https://www.example.net"}
    +                                 ]).

    The call will return true or false depending on the check. The caller do not need to handle the matching rules in the rfc. The matching will proceed as:

    • If there is a Subject Alternate Name field, the {uri_id,string()} in the function call will be compared to any {uniformResourceIdentifier,string()} in the Certificate field. If the two strings() are equal (case insensitive), @@ -539,25 +539,25 @@

      either a string/0 to be matched to each CN-name or the atom default which will invoke the default fqdn extraction function. The return value undefined removes the current URI from the fqdn extraction.

       ...
      - Extract = fun({uri_id, "myspecial://"++HostName}) -> HostName;
      -              (_Else) -> default
      + Extract = fun({uri_id, "myspecial://"++HostName}) -> HostName;
      +              (_Else) -> default
                  end,
        ...
      - public_key:pkix_verify_hostname(CertFromHost, RefIDs,
      -                                 [{fqdn_fun, Extract}])
      + public_key:pkix_verify_hostname(CertFromHost, RefIDs,
      +                                 [{fqdn_fun, Extract}])
        ...

      Re-defining the match operation

      The default matching handles dns_id and uri_id. In an uri_id the value is tested for equality with a value from the Subject Alternate Name. If some other kind of matching is needed, use the match_fun option.

      The match_fun takes two arguments and returns either true, false or default. The value default will invoke the default match function.

       ...
      - Match = fun({uri_id,"myspecial://"++A},
      -             {uniformResourceIdentifier,"myspecial://"++B}) ->
      -                                                    my_match(A,B);
      -            (_RefID, _PresentedID) ->
      + Match = fun({uri_id,"myspecial://"++A},
      +             {uniformResourceIdentifier,"myspecial://"++B}) ->
      +                                                    my_match(A,B);
      +            (_RefID, _PresentedID) ->
                                       default
                end,
        ...
      - public_key:pkix_verify_hostname(CertFromHost, RefIDs,
      -                                 [{match_fun, Match}]),
      + public_key:pkix_verify_hostname(CertFromHost, RefIDs,
      +                                 [{match_fun, Match}]),
        ...

      In case of a match operation between a ReferenceID and a CN value from the Subject field, the first argument to the fun is the extracted hostname from the ReferenceID, and the second argument is the tuple {cn, string()} taken @@ -578,19 +578,19 @@

      identifier. ..."

    The purpose is to have a mechanism for a human to accept an otherwise faulty Certificate. In for example a web browser, you could get a question like

    Warning: you wanted to visit the site www.example.com, but the certificate is for shop.example.com. Accept anyway (yes/no)?"

    This could be accomplished with the option fail_callback which will be called -if the hostname verification fails:

     -include_lib("public_key/include/public_key.hrl"). % Record def
    +if the hostname verification fails:

     -include_lib("public_key/include/public_key.hrl"). % Record def
      ...
    - Fail = fun(#'OTPCertificate'{}=C) ->
    -              case in_my_cache(C) orelse my_accept(C) of
    + Fail = fun(#'OTPCertificate'{}=C) ->
    +              case in_my_cache(C) orelse my_accept(C) of
                       true ->
    -                       enter_my_cache(C),
    +                       enter_my_cache(C),
                            true;
                       false ->
                            false
              end,
      ...
    - public_key:pkix_verify_hostname(CertFromHost, RefIDs,
    -                                 [{fail_callback, Fail}]),
    + public_key:pkix_verify_hostname(CertFromHost, RefIDs,
    +                                 [{fail_callback, Fail}]),
      ...

    diff --git a/prs/8803/lib/reltool-1.0.1/doc/html/reltool.epub b/prs/8803/lib/reltool-1.0.1/doc/html/reltool.epub index 3671921682460..bf420d1201697 100644 Binary files a/prs/8803/lib/reltool-1.0.1/doc/html/reltool.epub and b/prs/8803/lib/reltool-1.0.1/doc/html/reltool.epub differ diff --git a/prs/8803/lib/reltool-1.0.1/doc/html/reltool_examples.html b/prs/8803/lib/reltool-1.0.1/doc/html/reltool_examples.html index 35ea120ec64fb..0e3f9faa2d3d1 100644 --- a/prs/8803/lib/reltool-1.0.1/doc/html/reltool_examples.html +++ b/prs/8803/lib/reltool-1.0.1/doc/html/reltool_examples.html @@ -135,500 +135,500 @@

    via the GUI frontend process. When the GUI is started, a server process will automatically be started. The GUI process is started with reltool:start/0, reltool:start/1 or reltool:start_link/1. The pid of its server can be -obtained with reltool:get_server/1

    Erlang/OTP 20 [erts-9.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
    -[hipe] [kernel-poll:false]
    -Eshell V9.0  (abort with ^G)
    +obtained with reltool:get_server/1

    Erlang/OTP 20 [erts-9.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
    +[hipe] [kernel-poll:false]
    +Eshell V9.0  (abort with ^G)
     1>
    -1> {ok, Win} = reltool:start([]).
    -{ok,<0.36.01>}
    -2> {ok, Server} = reltool:get_server(Win).
    -{ok,<0.37.01>}
    -3> reltool:get_config(Server).
    -{ok,{sys,[]}}
    +1> {ok, Win} = reltool:start([]).
    +{ok,<0.36.01>}
    +2> {ok, Server} = reltool:get_server(Win).
    +{ok,<0.37.01>}
    +3> reltool:get_config(Server).
    +{ok,{sys,[]}}
     4>
    -4> {ok, Server2} = reltool:start_server([]).
    -{ok,<0.6535.01>}
    -5> reltool:get_config(Server2).
    -{ok,{sys,[]}}
    -6> reltool:stop(Server2).
    +4> {ok, Server2} = reltool:start_server([]).
    +{ok,<0.6535.01>}
    +5> reltool:get_config(Server2).
    +{ok,{sys,[]}}
    +6> reltool:stop(Server2).
     ok

    Inspecting the configuration

    -
    Erlang/OTP 20 [erts-9.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
    -[hipe] [kernel-poll:false]
    -Eshell V9.0  (abort with ^G)
    +
    Erlang/OTP 20 [erts-9.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
    +[hipe] [kernel-poll:false]
    +Eshell V9.0  (abort with ^G)
     1>
    -1> Config = {sys, [{escript, "examples/display_args", [{incl_cond, include}]},
    -		   {app, inets, [{incl_cond, include}]},
    -		   {app, mnesia, [{incl_cond, exclude}]},
    -		   {app, ssl, [{incl_cond, exclude}]},
    -		   {app, runtime_tools, [{incl_cond, exclude}]},
    -		   {app, syntax_tools, [{incl_cond, exclude}]}]}.
    -{sys,[{escript,"examples/display_args",[{incl_cond,include}]},
    -      {app,inets,[{incl_cond,include}]},
    -      {app,mnesia,[{incl_cond,exclude}]},
    -      {app,ssl,[{incl_cond,exclude}]},
    -      {app,runtime_tools,[{incl_cond,exclude}]},
    -      {app,syntax_tools,[{incl_cond,exclude}]}]}
    +1> Config = {sys, [{escript, "examples/display_args", [{incl_cond, include}]},
    +		   {app, inets, [{incl_cond, include}]},
    +		   {app, mnesia, [{incl_cond, exclude}]},
    +		   {app, ssl, [{incl_cond, exclude}]},
    +		   {app, runtime_tools, [{incl_cond, exclude}]},
    +		   {app, syntax_tools, [{incl_cond, exclude}]}]}.
    +{sys,[{escript,"examples/display_args",[{incl_cond,include}]},
    +      {app,inets,[{incl_cond,include}]},
    +      {app,mnesia,[{incl_cond,exclude}]},
    +      {app,ssl,[{incl_cond,exclude}]},
    +      {app,runtime_tools,[{incl_cond,exclude}]},
    +      {app,syntax_tools,[{incl_cond,exclude}]}]}
     2>
    -2> {ok, Server} = reltool:start_server([Config]).
    -{ok,<0.66.0>}
    +2> {ok, Server} = reltool:start_server([Config]).
    +{ok,<0.66.0>}
     3>
    -3> reltool:get_config(Server).
    -{ok,{sys,[{escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args",
    -                   [{incl_cond,include}]},
    -          {app,inets,[{incl_cond,include}]},
    -          {app,mnesia,[{incl_cond,exclude}]},
    -          {app,runtime_tools,[{incl_cond,exclude}]},
    -          {app,ssl,[{incl_cond,exclude}]},
    -          {app,syntax_tools,[{incl_cond,exclude}]}]}}
    +3> reltool:get_config(Server).
    +{ok,{sys,[{escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args",
    +                   [{incl_cond,include}]},
    +          {app,inets,[{incl_cond,include}]},
    +          {app,mnesia,[{incl_cond,exclude}]},
    +          {app,runtime_tools,[{incl_cond,exclude}]},
    +          {app,ssl,[{incl_cond,exclude}]},
    +          {app,syntax_tools,[{incl_cond,exclude}]}]}}
     4>
    -4> reltool:get_config(Server, false, false).
    -{ok,{sys,[{escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args",
    -                   [{incl_cond,include}]},
    -          {app,inets,[{incl_cond,include}]},
    -          {app,mnesia,[{incl_cond,exclude}]},
    -          {app,runtime_tools,[{incl_cond,exclude}]},
    -          {app,ssl,[{incl_cond,exclude}]},
    -          {app,syntax_tools,[{incl_cond,exclude}]}]}}
    +4> reltool:get_config(Server, false, false).
    +{ok,{sys,[{escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args",
    +                   [{incl_cond,include}]},
    +          {app,inets,[{incl_cond,include}]},
    +          {app,mnesia,[{incl_cond,exclude}]},
    +          {app,runtime_tools,[{incl_cond,exclude}]},
    +          {app,ssl,[{incl_cond,exclude}]},
    +          {app,syntax_tools,[{incl_cond,exclude}]}]}}
     5>
    -5> reltool:get_config(Server, true, false).
    -{ok,{sys,[{root_dir,"/usr/local/lib/erlang"},
    -          {lib_dirs,[]},
    -          {escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args",
    -                   [{incl_cond,include}]},
    -          {mod_cond,all},
    -          {incl_cond,derived},
    -          {app,inets,
    -               [{incl_cond,include},{vsn,undefined},{lib_dir,undefined}]},
    -          {app,mnesia,[{incl_cond,exclude}]},
    -          {app,runtime_tools,[{incl_cond,exclude}]},
    -          {app,ssl,[{incl_cond,exclude}]},
    -          {app,syntax_tools,[{incl_cond,exclude}]},
    -          {boot_rel,"start_clean"},
    -          {rel,"start_clean","1.0",[]},
    -          {rel,"start_sasl","1.0",[sasl]},
    -          {emu_name,"beam"},
    -          {relocatable,true},
    -          {profile,development},
    -          {incl_sys_filters,[".*"]},
    -          {excl_sys_filters,[]},
    -          {incl_app_filters,[".*"]},
    -          {excl_app_filters,[]},
    -          {rel_app_type,...},
    -          {...}|...]}}
    +5> reltool:get_config(Server, true, false).
    +{ok,{sys,[{root_dir,"/usr/local/lib/erlang"},
    +          {lib_dirs,[]},
    +          {escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args",
    +                   [{incl_cond,include}]},
    +          {mod_cond,all},
    +          {incl_cond,derived},
    +          {app,inets,
    +               [{incl_cond,include},{vsn,undefined},{lib_dir,undefined}]},
    +          {app,mnesia,[{incl_cond,exclude}]},
    +          {app,runtime_tools,[{incl_cond,exclude}]},
    +          {app,ssl,[{incl_cond,exclude}]},
    +          {app,syntax_tools,[{incl_cond,exclude}]},
    +          {boot_rel,"start_clean"},
    +          {rel,"start_clean","1.0",[]},
    +          {rel,"start_sasl","1.0",[sasl]},
    +          {emu_name,"beam"},
    +          {relocatable,true},
    +          {profile,development},
    +          {incl_sys_filters,[".*"]},
    +          {excl_sys_filters,[]},
    +          {incl_app_filters,[".*"]},
    +          {excl_app_filters,[]},
    +          {rel_app_type,...},
    +          {...}|...]}}
     6>
    -6> reltool:get_config(Server, true, true).
    -{ok,{sys,[{root_dir,"/usr/local/lib/erlang"},
    -          {lib_dirs,[]},
    -          {escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args",
    -                   [{incl_cond,include}]},
    -          {mod_cond,all},
    -          {incl_cond,derived},
    -          {erts,[{app,erts,
    -                      [{vsn,"10.0"},
    -                       {lib_dir,"/usr/local/lib/erlang/lib/erts-10.0"},
    -                       {mod,erl_prim_loader,[]},
    -                       {mod,erl_tracer,[]},
    -                       {mod,erlang,[]},
    -                       {mod,erts_code_purger,[]},
    -                       {mod,erts_dirty_process_signal_handler,[]},
    -                       {mod,erts_internal,[]},
    -                       {mod,erts_literal_area_collector,[]},
    -                       {mod,init,[]},
    -                       {mod,erl_init,...},
    -                       {mod,...},
    -                       {...}|...]}]},
    -          {app,compiler,
    -               [{vsn,"7.0.4"},
    -                {lib_dir,"/usr/local/lib/erlang/lib/compiler-7.0.4"},
    -                {mod,beam_a,[]},
    -                {mod,beam_asm,[]},
    -                {mod,beam_block,[]},
    -                {mod,beam_bs,[]},
    -                {mod,beam_bsm,[]},
    -                {mod,beam_clean,[]},
    -                {mod,beam_dead,[]},
    -                {mod,beam_dict,[]},
    -                {mod,beam_disasm,[]},
    -                {mod,beam_except,[]},
    -                {mod,beam_flatten,...},
    -                {mod,...},
    -                {...}|...]},
    -          {app,crypto,
    -               [{vsn,"3.7.4"},
    -                {lib_dir,"/usr/local/lib/erlang/lib/crypto-3.7.4"},
    -                {mod,crypto,[]},
    -                {mod,crypto_ec_curves,[]}]},
    -          {app,hipe,
    -               [{vsn,"3.15.4"},
    -                {lib_dir,"/usr/local/lib/erlang/lib/hipe-3.15.4"},
    -                {mod,cerl_cconv,[]},
    -                {mod,cerl_closurean,[]},
    -                {mod,cerl_hipeify,[]},
    -                {mod,cerl_lib,[]},
    -                {mod,cerl_messagean,[]},
    -                {mod,cerl_pmatch,[]},
    -                {mod,cerl_prettypr,[]},
    -                {mod,cerl_to_icode,[]},
    -                {mod,cerl_typean,...},
    -                {mod,...},
    -                {...}|...]},
    -          {app,inets,
    -               [{incl_cond,include},
    -                {vsn,"6.3.9"},
    -                {lib_dir,"/usr/local/lib/erlang/lib/inets-6.3.9"},
    -                {mod,ftp,[]},
    -                {mod,ftp_progress,[]},
    -                {mod,ftp_response,[]},
    -                {mod,ftp_sup,[]},
    -                {mod,http_chunk,[]},
    -                {mod,http_request,[]},
    -                {mod,http_response,...},
    -                {mod,...},
    -                {...}|...]},
    -          {app,kernel,
    -               [{vsn,"5.2"},
    -                {lib_dir,"/usr/local/lib/erlang/lib/kernel-5.2"},
    -                {mod,application,[]},
    -                {mod,application_controller,[]},
    -                {mod,application_master,[]},
    -                {mod,application_starter,[]},
    -                {mod,auth,[]},
    -                {mod,code,[]},
    -                {mod,code_server,...},
    -                {mod,...},
    -                {...}|...]},
    -          {app,mnesia,[{incl_cond,exclude}]},
    -          {app,runtime_tools,[{incl_cond,exclude}]},
    -          {app,sasl,
    -               [{vsn,"3.0.3"},
    -                {lib_dir,"/usr/local/lib/erlang/lib/sasl-3.0.3"},
    -                {mod,alarm_handler,[]},
    -                {mod,erlsrv,[]},
    -                {mod,format_lib_supp,[]},
    -                {mod,misc_supp,...},
    -                {mod,...},
    -                {...}|...]},
    -          {app,ssl,[{incl_cond,exclude}]},
    -          {app,stdlib,
    -               [{vsn,"3.3"},
    -                {lib_dir,"/usr/local/lib/erlang/lib/stdlib-3.3"},
    -                {mod,array,[]},
    -                {mod,base64,...},
    -                {mod,...},
    -                {...}|...]},
    -          {app,syntax_tools,[{incl_cond,exclude}]},
    -          {app,tools,
    -               [{vsn,"2.9.1"},{lib_dir,[...]},{mod,...},{...}|...]},
    -          {boot_rel,"start_clean"},
    -          {rel,"start_clean","1.0",[]},
    -          {rel,"start_sasl","1.0",[...]},
    -          {emu_name,"beam"},
    -          {relocatable,true},
    -          {profile,...},
    -          {...}|...]}}
    +6> reltool:get_config(Server, true, true).
    +{ok,{sys,[{root_dir,"/usr/local/lib/erlang"},
    +          {lib_dirs,[]},
    +          {escript,"/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args",
    +                   [{incl_cond,include}]},
    +          {mod_cond,all},
    +          {incl_cond,derived},
    +          {erts,[{app,erts,
    +                      [{vsn,"10.0"},
    +                       {lib_dir,"/usr/local/lib/erlang/lib/erts-10.0"},
    +                       {mod,erl_prim_loader,[]},
    +                       {mod,erl_tracer,[]},
    +                       {mod,erlang,[]},
    +                       {mod,erts_code_purger,[]},
    +                       {mod,erts_dirty_process_signal_handler,[]},
    +                       {mod,erts_internal,[]},
    +                       {mod,erts_literal_area_collector,[]},
    +                       {mod,init,[]},
    +                       {mod,erl_init,...},
    +                       {mod,...},
    +                       {...}|...]}]},
    +          {app,compiler,
    +               [{vsn,"7.0.4"},
    +                {lib_dir,"/usr/local/lib/erlang/lib/compiler-7.0.4"},
    +                {mod,beam_a,[]},
    +                {mod,beam_asm,[]},
    +                {mod,beam_block,[]},
    +                {mod,beam_bs,[]},
    +                {mod,beam_bsm,[]},
    +                {mod,beam_clean,[]},
    +                {mod,beam_dead,[]},
    +                {mod,beam_dict,[]},
    +                {mod,beam_disasm,[]},
    +                {mod,beam_except,[]},
    +                {mod,beam_flatten,...},
    +                {mod,...},
    +                {...}|...]},
    +          {app,crypto,
    +               [{vsn,"3.7.4"},
    +                {lib_dir,"/usr/local/lib/erlang/lib/crypto-3.7.4"},
    +                {mod,crypto,[]},
    +                {mod,crypto_ec_curves,[]}]},
    +          {app,hipe,
    +               [{vsn,"3.15.4"},
    +                {lib_dir,"/usr/local/lib/erlang/lib/hipe-3.15.4"},
    +                {mod,cerl_cconv,[]},
    +                {mod,cerl_closurean,[]},
    +                {mod,cerl_hipeify,[]},
    +                {mod,cerl_lib,[]},
    +                {mod,cerl_messagean,[]},
    +                {mod,cerl_pmatch,[]},
    +                {mod,cerl_prettypr,[]},
    +                {mod,cerl_to_icode,[]},
    +                {mod,cerl_typean,...},
    +                {mod,...},
    +                {...}|...]},
    +          {app,inets,
    +               [{incl_cond,include},
    +                {vsn,"6.3.9"},
    +                {lib_dir,"/usr/local/lib/erlang/lib/inets-6.3.9"},
    +                {mod,ftp,[]},
    +                {mod,ftp_progress,[]},
    +                {mod,ftp_response,[]},
    +                {mod,ftp_sup,[]},
    +                {mod,http_chunk,[]},
    +                {mod,http_request,[]},
    +                {mod,http_response,...},
    +                {mod,...},
    +                {...}|...]},
    +          {app,kernel,
    +               [{vsn,"5.2"},
    +                {lib_dir,"/usr/local/lib/erlang/lib/kernel-5.2"},
    +                {mod,application,[]},
    +                {mod,application_controller,[]},
    +                {mod,application_master,[]},
    +                {mod,application_starter,[]},
    +                {mod,auth,[]},
    +                {mod,code,[]},
    +                {mod,code_server,...},
    +                {mod,...},
    +                {...}|...]},
    +          {app,mnesia,[{incl_cond,exclude}]},
    +          {app,runtime_tools,[{incl_cond,exclude}]},
    +          {app,sasl,
    +               [{vsn,"3.0.3"},
    +                {lib_dir,"/usr/local/lib/erlang/lib/sasl-3.0.3"},
    +                {mod,alarm_handler,[]},
    +                {mod,erlsrv,[]},
    +                {mod,format_lib_supp,[]},
    +                {mod,misc_supp,...},
    +                {mod,...},
    +                {...}|...]},
    +          {app,ssl,[{incl_cond,exclude}]},
    +          {app,stdlib,
    +               [{vsn,"3.3"},
    +                {lib_dir,"/usr/local/lib/erlang/lib/stdlib-3.3"},
    +                {mod,array,[]},
    +                {mod,base64,...},
    +                {mod,...},
    +                {...}|...]},
    +          {app,syntax_tools,[{incl_cond,exclude}]},
    +          {app,tools,
    +               [{vsn,"2.9.1"},{lib_dir,[...]},{mod,...},{...}|...]},
    +          {boot_rel,"start_clean"},
    +          {rel,"start_clean","1.0",[]},
    +          {rel,"start_sasl","1.0",[...]},
    +          {emu_name,"beam"},
    +          {relocatable,true},
    +          {profile,...},
    +          {...}|...]}}
     7>
    -7> reltool:get_config([{sys, [{profile, embedded}]}], true, false).
    -{ok,{sys,[{root_dir,"/usr/local/lib/erlang"},
    -          {lib_dirs,[]},
    -          {mod_cond,all},
    -          {incl_cond,derived},
    -          {boot_rel,"start_clean"},
    -          {rel,"start_clean","1.0",[]},
    -          {rel,"start_sasl","1.0",[sasl]},
    -          {emu_name,"beam"},
    -          {relocatable,true},
    -          {profile,embedded},
    -          {incl_sys_filters,["^bin","^erts","^lib","^releases"]},
    -          {excl_sys_filters,["^bin/(erlc|dialyzer|typer)(|\\.exe)$",
    +7> reltool:get_config([{sys, [{profile, embedded}]}], true, false).
    +{ok,{sys,[{root_dir,"/usr/local/lib/erlang"},
    +          {lib_dirs,[]},
    +          {mod_cond,all},
    +          {incl_cond,derived},
    +          {boot_rel,"start_clean"},
    +          {rel,"start_clean","1.0",[]},
    +          {rel,"start_sasl","1.0",[sasl]},
    +          {emu_name,"beam"},
    +          {relocatable,true},
    +          {profile,embedded},
    +          {incl_sys_filters,["^bin","^erts","^lib","^releases"]},
    +          {excl_sys_filters,["^bin/(erlc|dialyzer|typer)(|\\.exe)$",
                                  "^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)$",
    -                             "^erts.*/bin/.*(debug|pdb)"]},
    -          {incl_app_filters,["^ebin","^include","^priv"]},
    -          {excl_app_filters,[]},
    -          {rel_app_type,permanent},
    -          {embedded_app_type,load},
    -          {app_file,keep},
    -          {debug_info,keep}]}}
    +                             "^erts.*/bin/.*(debug|pdb)"]},
    +          {incl_app_filters,["^ebin","^include","^priv"]},
    +          {excl_app_filters,[]},
    +          {rel_app_type,permanent},
    +          {embedded_app_type,load},
    +          {app_file,keep},
    +          {debug_info,keep}]}}
     8>
    -8> reltool:get_config([{sys, [{profile, standalone}]}], true, false).
    -{ok,{sys,[{root_dir,"/usr/local/lib/erlang"},
    -          {lib_dirs,[]},
    -          {mod_cond,all},
    -          {incl_cond,derived},
    -          {boot_rel,"start_clean"},
    -          {rel,"start_clean","1.0",[]},
    -          {rel,"start_sasl","1.0",[sasl]},
    -          {emu_name,"beam"},
    -          {relocatable,true},
    -          {profile,standalone},
    -          {incl_sys_filters,["^bin/(erl|epmd)(|\\.exe|\\.ini)$",
    -                             "^bin/start(|_clean).boot$","^erts.*/bin","^lib$"]},
    -          {excl_sys_filters,["^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)$",
    +8> reltool:get_config([{sys, [{profile, standalone}]}], true, false).
    +{ok,{sys,[{root_dir,"/usr/local/lib/erlang"},
    +          {lib_dirs,[]},
    +          {mod_cond,all},
    +          {incl_cond,derived},
    +          {boot_rel,"start_clean"},
    +          {rel,"start_clean","1.0",[]},
    +          {rel,"start_sasl","1.0",[sasl]},
    +          {emu_name,"beam"},
    +          {relocatable,true},
    +          {profile,standalone},
    +          {incl_sys_filters,["^bin/(erl|epmd)(|\\.exe|\\.ini)$",
    +                             "^bin/start(|_clean).boot$","^erts.*/bin","^lib$"]},
    +          {excl_sys_filters,["^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)$",
                                  "^erts.*/bin/(start|escript|to_erl|run_erl)(|\\.exe)$",
    -                             "^erts.*/bin/.*(debug|pdb)"]},
    -          {incl_app_filters,["^ebin","^priv"]},
    -          {excl_app_filters,["^ebin/.*\\.appup$"]},
    -          {rel_app_type,permanent},
    -          {app_file,keep},
    -          {debug_info,keep}]}}

    + "^erts.*/bin/.*(debug|pdb)"]}, + {incl_app_filters,["^ebin","^priv"]}, + {excl_app_filters,["^ebin/.*\\.appup$"]}, + {rel_app_type,permanent}, + {app_file,keep}, + {debug_info,keep}]}}

    Generate release and script files

    -
    Erlang/OTP 20 [erts-10.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
    -[hipe] [kernel-poll:false]
    -Eshell V10.0  (abort with ^G)
    +
    Erlang/OTP 20 [erts-10.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
    +[hipe] [kernel-poll:false]
    +Eshell V10.0  (abort with ^G)
     1>
    -1> {ok, Server} = reltool:start_server([{config,
    -                                         {sys,
    -                                          [{boot_rel, "NAME"},
    -                                           {rel, "NAME", "VSN",
    -                                            [sasl],
    -                                            [{load_dot_erlang, false}]}]}}]).
    -{ok,<0.1288.0>}
    +1> {ok, Server} = reltool:start_server([{config,
    +                                         {sys,
    +                                          [{boot_rel, "NAME"},
    +                                           {rel, "NAME", "VSN",
    +                                            [sasl],
    +                                            [{load_dot_erlang, false}]}]}}]).
    +{ok,<0.1288.0>}
     2>
    -2> reltool:get_config(Server).
    -{ok,{sys,[{boot_rel,"NAME"},
    -          {rel,"NAME","VSN",[sasl]}]}}
    +2> reltool:get_config(Server).
    +{ok,{sys,[{boot_rel,"NAME"},
    +          {rel,"NAME","VSN",[sasl]}]}}
     3>
    -3> reltool:get_rel(Server, "NAME").
    -{ok,{release,{"NAME","VSN"},
    -             {erts,"10.0"},
    -             [{kernel,"5.2"},{stdlib,"3.3"},{sasl,"3.0.3"}]}}
    +3> reltool:get_rel(Server, "NAME").
    +{ok,{release,{"NAME","VSN"},
    +             {erts,"10.0"},
    +             [{kernel,"5.2"},{stdlib,"3.3"},{sasl,"3.0.3"}]}}
     4>
    -4> reltool:get_script(Server, "NAME").
    -{ok,{script,{"NAME","VSN"},
    -            [{preLoaded,[erl_prim_loader,erl_tracer,erlang,
    +4> reltool:get_script(Server, "NAME").
    +{ok,{script,{"NAME","VSN"},
    +            [{preLoaded,[erl_prim_loader,erl_tracer,erlang,
                              erts_code_purger,erts_dirty_process_signal_handler,
                              erts_internal,erts_literal_area_collector,init,erl_init,
    -                         prim_eval,prim_file,prim_inet,prim_zip,zlib]},
    -             {progress,preloaded},
    -             {path,["$ROOT/lib/kernel-5.2/ebin",
    -                    "$ROOT/lib/stdlib-3.3/ebin"]},
    -             {primLoad,[error_handler]},
    -             {kernel_load_completed},
    -             {progress,kernel_load_completed},
    -             {path,["$ROOT/lib/kernel-5.2/ebin"]},
    -             {primLoad,[application,application_controller,
    +                         prim_eval,prim_file,prim_inet,prim_zip,zlib]},
    +             {progress,preloaded},
    +             {path,["$ROOT/lib/kernel-5.2/ebin",
    +                    "$ROOT/lib/stdlib-3.3/ebin"]},
    +             {primLoad,[error_handler]},
    +             {kernel_load_completed},
    +             {progress,kernel_load_completed},
    +             {path,["$ROOT/lib/kernel-5.2/ebin"]},
    +             {primLoad,[application,application_controller,
                             application_master,application_starter,auth,code,
                             code_server,disk_log,disk_log_1,disk_log_server,
    -                        disk_log_sup,dist_ac,dist_util,erl_boot_server|...]},
    -             {path,["$ROOT/lib/stdlib-3.3/ebin"]},
    -             {primLoad,[array,base64,beam_lib,binary,c,calendar,dets,
    -                        dets_server,dets_sup,dets_utils,dets_v9,dict|...]},
    -             {path,["$ROOT/lib/sasl-3.0.3/ebin"]},
    -             {primLoad,[alarm_handler,erlsrv,format_lib_supp,misc_supp,
    +                        disk_log_sup,dist_ac,dist_util,erl_boot_server|...]},
    +             {path,["$ROOT/lib/stdlib-3.3/ebin"]},
    +             {primLoad,[array,base64,beam_lib,binary,c,calendar,dets,
    +                        dets_server,dets_sup,dets_utils,dets_v9,dict|...]},
    +             {path,["$ROOT/lib/sasl-3.0.3/ebin"]},
    +             {primLoad,[alarm_handler,erlsrv,format_lib_supp,misc_supp,
                             rb,rb_format_supp,release_handler,release_handler_1,sasl,
    -                        sasl_report|...]},
    -             {progress,modules_loaded},
    -             {path,["$ROOT/lib/kernel-5.2/ebin",
    -                    "$ROOT/lib/stdlib-3.3/ebin","$ROOT/lib/sasl-3.0.3/ebin"]},
    -             {kernelProcess,heart,{heart,start,[]}},
    -             {kernelProcess,error_logger,{error_logger,start_link,[]}},
    -             {kernelProcess,application_controller,
    -                            {application_controller,start,[{...}]}},
    -             {progress,init_kernel_started},
    -             {apply,{application,load,[...]}},
    -             {apply,{application,load,...}},
    -             {progress,applications_loaded},
    -             {apply,{...}},
    -             {apply,...},
    -             {...}|...]}}
    +                        sasl_report|...]},
    +             {progress,modules_loaded},
    +             {path,["$ROOT/lib/kernel-5.2/ebin",
    +                    "$ROOT/lib/stdlib-3.3/ebin","$ROOT/lib/sasl-3.0.3/ebin"]},
    +             {kernelProcess,heart,{heart,start,[]}},
    +             {kernelProcess,error_logger,{error_logger,start_link,[]}},
    +             {kernelProcess,application_controller,
    +                            {application_controller,start,[{...}]}},
    +             {progress,init_kernel_started},
    +             {apply,{application,load,[...]}},
    +             {apply,{application,load,...}},
    +             {progress,applications_loaded},
    +             {apply,{...}},
    +             {apply,...},
    +             {...}|...]}}
     5>
    -5> reltool:stop(Server).
    +5> reltool:stop(Server).
     ok

    Create a target system

    -
    Erlang/OTP 20 [erts-10.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
    -[hipe] [kernel-poll:false]
    -Eshell V10.0  (abort with ^G)
    +
    Erlang/OTP 20 [erts-10.0] [source-c13b302] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10]
    +[hipe] [kernel-poll:false]
    +Eshell V10.0  (abort with ^G)
     1>
    -1> Config = {sys, [{escript, "examples/display_args", [{incl_cond, include}]},
    -		   {app, inets, [{incl_cond, include}]},
    -		   {app, mnesia, [{incl_cond, exclude}]},
    -		   {app, ssl, [{incl_cond, exclude}]},
    -		   {app, runtime_tools, [{incl_cond, exclude}]},
    -		   {app, syntax_tools, [{incl_cond, exclude}]}]}.
    -{sys,[{escript,"examples/display_args",[{incl_cond,include}]},
    -      {app,inets,[{incl_cond,include}]},
    -      {app,mnesia,[{incl_cond,exclude}]},
    -      {app,ssl,[{incl_cond,exclude}]},
    -      {app,runtime_tools,[{incl_cond,exclude}]},
    -      {app,syntax_tools,[{incl_cond,exclude}]}]}
    +1> Config = {sys, [{escript, "examples/display_args", [{incl_cond, include}]},
    +		   {app, inets, [{incl_cond, include}]},
    +		   {app, mnesia, [{incl_cond, exclude}]},
    +		   {app, ssl, [{incl_cond, exclude}]},
    +		   {app, runtime_tools, [{incl_cond, exclude}]},
    +		   {app, syntax_tools, [{incl_cond, exclude}]}]}.
    +{sys,[{escript,"examples/display_args",[{incl_cond,include}]},
    +      {app,inets,[{incl_cond,include}]},
    +      {app,mnesia,[{incl_cond,exclude}]},
    +      {app,ssl,[{incl_cond,exclude}]},
    +      {app,runtime_tools,[{incl_cond,exclude}]},
    +      {app,syntax_tools,[{incl_cond,exclude}]}]}
     2>
    -2> {ok, Spec} = reltool:get_target_spec([Config]).
    -{ok,[{create_dir,"releases",
    -         [{write_file,"start_erl.data","10.0 1.0\n"},
    -          {create_dir,"1.0",
    -              [{write_file,"start_clean.rel",
    -                   [37,37,32,114,101,108,32,103,101,110,101,114,97,116|...]},
    -               {write_file,"start_clean.script",
    -                   [37,37,32,115,99,114,105,112,116,32,103,101,110|...]},
    -               {write_file,"start_clean.boot",
    -                   <<131,104,3,119,6,115,99,114,105,112,116,104,...>>},
    -               {write_file,"start_sasl.rel",
    -                   [37,37,32,114,101,108,32,103,101,110,101|...]},
    -               {write_file,"start_sasl.script",
    -                   [37,37,32,115,99,114,105,112,116,32|...]},
    -               {write_file,"start_sasl.boot",
    -                   <<131,104,3,119,6,115,99,114,105,...>>}]}]},
    -     {create_dir,"bin",
    -         [{copy_file,"display_args.escript",
    -              "/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args"},
    -          {copy_file,"display_args","erts-10.0/bin/escript"},
    -          {copy_file,"start","erts-10.0/bin/start"},
    -          {copy_file,"ct_run","erts-10.0/bin/ct_run"},
    -          {copy_file,"dialyzer","erts-10.0/bin/dialyzer"},
    -          {copy_file,"run_erl","erts-10.0/bin/run_erl"},
    -          {copy_file,"erl","erts-10.0/bin/dyn_erl"},
    -          {copy_file,"to_erl","erts-10.0/bin/to_erl"},
    -          {copy_file,"epmd","erts-10.0/bin/epmd"},
    -          {copy_file,"erlc","erts-10.0/bin/erlc"},
    -          {copy_file,"typer","erts-10.0/bin/typer"},
    -          {copy_file,"escript","erts-10.0/bin/escript"},
    -          {write_file,"start_clean.boot",<<131,104,3,119,6,115,...>>},
    -          {write_file,"start_sasl.boot",<<131,104,3,119,6,...>>},
    -          {write_file,"start.boot",<<131,104,3,119,...>>}]},
    -     {copy_file,"Install"},
    -     {create_dir,"misc",
    -         [{copy_file,"format_man_pages"}]},
    -     {create_dir,"usr",
    -         [{create_dir,"lib",
    -              [{copy_file,"liberl_interface_st.a"},
    -               {copy_file,"libic.a"},
    -               {copy_file,"liberl_interface.a"},
    -               {copy_file,"libei_st.a"},
    -               {copy_file,"libei.a"}]},
    -          {create_dir,"include",
    -              [{copy_file,"driver_int.h"},
    -               {copy_file,"ei_connect.h"},
    -               {copy_file,"ei.h"},
    -               {copy_file,"erl_nif_api_funcs.h"},
    -               {copy_file,"erl_fixed_size_int_types.h"},
    -               {copy_file,"erl_int_sizes_config.h"},
    -               {copy_file,"erl_interface.h"},
    -               {copy_file,"eicode.h"},
    -               {copy_file,"erl_driver.h"},
    -               {copy_file,"erlang.idl"},
    -               {copy_file,[...]},
    -               {copy_file,...},
    -               {...}]}]},
    -     {create_dir,"erts-10.0",
    -         [{create_dir,"bin",
    -              [{copy_file,"start"},
    -               {copy_file,"ct_run"},
    -               {copy_file,"erlexec"},
    -               {copy_file,"dialyzer"},
    -               {copy_file,"beam.smp"},
    -               {copy_file,"run_erl"},
    -               {copy_file,"erl","erts-10.0/bin/dyn_erl"},
    -               {copy_file,"to_erl"},
    -               {copy_file,"epmd"},
    -               {copy_file,"erl_child_setup"},
    -               {copy_file,"heart"},
    -               {copy_file,[...]},
    -               {copy_file,...},
    -               {...}|...]},
    -          {create_dir,"lib",
    -              [{create_dir,"internal",
    -                   [{copy_file,"liberts_internal.a"},
    -                    {copy_file,"liberts_internal_r.a"},
    -                    {copy_file,"libethread.a"},
    -                    {copy_file,"README"}]},
    -               ]},
    -          {create_dir,"src",[{copy_file,"setuid_socket_wrap.c"}]},
    -          {create_dir,"doc",[]},
    -          {create_dir,"man",[]},
    -          {create_dir,"include",
    -              [{create_dir,"internal",
    -                   [{create_dir,"i386",[{...}|...]},
    -                    {copy_file,"erl_errno.h"},
    -                    {copy_file,[...]},
    -                    {copy_file,...},
    -                    {...}|...]},
    -               {copy_file,"driver_int.h"},
    -               {copy_file,"erl_nif_api_funcs.h"},
    -               {copy_file,"erl_fixed_size_int_types.h"},
    -               {copy_file,"erl_int_sizes_config.h"},
    -               {copy_file,[...]},
    -               {copy_file,...},
    -               {...}]}]},
    -     {create_dir,"lib",
    -         [{create_dir,"compiler-7.0.4",
    -              [{create_dir,"src",
    -                   [{copy_file,"beam_flatten.erl"},
    -                    {copy_file,[...]},
    -                    {copy_file,...},
    -                    {...}|...]},
    -               {create_dir,"ebin",
    -                   [{copy_file,[...]},{copy_file,...},{...}|...]}]},
    -          {create_dir,"crypto-3.7.4",
    -              [{create_dir,"src",[{copy_file,[...]},{copy_file,...}]},
    -               {create_dir,"ebin",[{copy_file,...},{...}|...]}]},
    -          {create_dir,"crypto-3.7.4",
    -              [{create_dir,"priv",
    -                   [{create_dir,"lib",[{copy_file,[...]},{copy_file,...}]},
    -                    {create_dir,"obj",[{copy_file,...},{...}|...]}]}]},
    -          {create_dir,"erts-10.0",
    -              [{create_dir,"src",[{...}|...]},
    -               {create_dir,"ebin",[...]}]},
    -          {create_dir,"hipe-3.15.4",
    -              [{create_dir,"flow",[...]},
    -               {copy_file,[...]},
    -               {create_dir,...},
    -               {...}|...]},
    -          {create_dir,"inets-6.3.9",
    -              [{create_dir,[...],...},{create_dir,...},{...}]},
    -          {create_dir,"inets-6.3.9",
    -              [{create_dir,"priv",[{create_dir,[...],...}]},
    -               {create_dir,"include",[{copy_file,...},{...}]}]},
    -          {create_dir,"kernel-5.2",[{...}|...]},
    -          {create_dir,"kernel-5.2",
    -              [{create_dir,"include",[{...}|...]}]},
    -          {create_dir,[...],...},
    -          {create_dir,...},
    -          {create_dir,"stdlib-3.3",[{create_dir,...}]},
    -          ...]}]}
    +2> {ok, Spec} = reltool:get_target_spec([Config]).
    +{ok,[{create_dir,"releases",
    +         [{write_file,"start_erl.data","10.0 1.0\n"},
    +          {create_dir,"1.0",
    +              [{write_file,"start_clean.rel",
    +                   [37,37,32,114,101,108,32,103,101,110,101,114,97,116|...]},
    +               {write_file,"start_clean.script",
    +                   [37,37,32,115,99,114,105,112,116,32,103,101,110|...]},
    +               {write_file,"start_clean.boot",
    +                   <<131,104,3,119,6,115,99,114,105,112,116,104,...>>},
    +               {write_file,"start_sasl.rel",
    +                   [37,37,32,114,101,108,32,103,101,110,101|...]},
    +               {write_file,"start_sasl.script",
    +                   [37,37,32,115,99,114,105,112,116,32|...]},
    +               {write_file,"start_sasl.boot",
    +                   <<131,104,3,119,6,115,99,114,105,...>>}]}]},
    +     {create_dir,"bin",
    +         [{copy_file,"display_args.escript",
    +              "/usr/local/lib/erlang/lib/reltool-0.7.3/examples/display_args"},
    +          {copy_file,"display_args","erts-10.0/bin/escript"},
    +          {copy_file,"start","erts-10.0/bin/start"},
    +          {copy_file,"ct_run","erts-10.0/bin/ct_run"},
    +          {copy_file,"dialyzer","erts-10.0/bin/dialyzer"},
    +          {copy_file,"run_erl","erts-10.0/bin/run_erl"},
    +          {copy_file,"erl","erts-10.0/bin/dyn_erl"},
    +          {copy_file,"to_erl","erts-10.0/bin/to_erl"},
    +          {copy_file,"epmd","erts-10.0/bin/epmd"},
    +          {copy_file,"erlc","erts-10.0/bin/erlc"},
    +          {copy_file,"typer","erts-10.0/bin/typer"},
    +          {copy_file,"escript","erts-10.0/bin/escript"},
    +          {write_file,"start_clean.boot",<<131,104,3,119,6,115,...>>},
    +          {write_file,"start_sasl.boot",<<131,104,3,119,6,...>>},
    +          {write_file,"start.boot",<<131,104,3,119,...>>}]},
    +     {copy_file,"Install"},
    +     {create_dir,"misc",
    +         [{copy_file,"format_man_pages"}]},
    +     {create_dir,"usr",
    +         [{create_dir,"lib",
    +              [{copy_file,"liberl_interface_st.a"},
    +               {copy_file,"libic.a"},
    +               {copy_file,"liberl_interface.a"},
    +               {copy_file,"libei_st.a"},
    +               {copy_file,"libei.a"}]},
    +          {create_dir,"include",
    +              [{copy_file,"driver_int.h"},
    +               {copy_file,"ei_connect.h"},
    +               {copy_file,"ei.h"},
    +               {copy_file,"erl_nif_api_funcs.h"},
    +               {copy_file,"erl_fixed_size_int_types.h"},
    +               {copy_file,"erl_int_sizes_config.h"},
    +               {copy_file,"erl_interface.h"},
    +               {copy_file,"eicode.h"},
    +               {copy_file,"erl_driver.h"},
    +               {copy_file,"erlang.idl"},
    +               {copy_file,[...]},
    +               {copy_file,...},
    +               {...}]}]},
    +     {create_dir,"erts-10.0",
    +         [{create_dir,"bin",
    +              [{copy_file,"start"},
    +               {copy_file,"ct_run"},
    +               {copy_file,"erlexec"},
    +               {copy_file,"dialyzer"},
    +               {copy_file,"beam.smp"},
    +               {copy_file,"run_erl"},
    +               {copy_file,"erl","erts-10.0/bin/dyn_erl"},
    +               {copy_file,"to_erl"},
    +               {copy_file,"epmd"},
    +               {copy_file,"erl_child_setup"},
    +               {copy_file,"heart"},
    +               {copy_file,[...]},
    +               {copy_file,...},
    +               {...}|...]},
    +          {create_dir,"lib",
    +              [{create_dir,"internal",
    +                   [{copy_file,"liberts_internal.a"},
    +                    {copy_file,"liberts_internal_r.a"},
    +                    {copy_file,"libethread.a"},
    +                    {copy_file,"README"}]},
    +               ]},
    +          {create_dir,"src",[{copy_file,"setuid_socket_wrap.c"}]},
    +          {create_dir,"doc",[]},
    +          {create_dir,"man",[]},
    +          {create_dir,"include",
    +              [{create_dir,"internal",
    +                   [{create_dir,"i386",[{...}|...]},
    +                    {copy_file,"erl_errno.h"},
    +                    {copy_file,[...]},
    +                    {copy_file,...},
    +                    {...}|...]},
    +               {copy_file,"driver_int.h"},
    +               {copy_file,"erl_nif_api_funcs.h"},
    +               {copy_file,"erl_fixed_size_int_types.h"},
    +               {copy_file,"erl_int_sizes_config.h"},
    +               {copy_file,[...]},
    +               {copy_file,...},
    +               {...}]}]},
    +     {create_dir,"lib",
    +         [{create_dir,"compiler-7.0.4",
    +              [{create_dir,"src",
    +                   [{copy_file,"beam_flatten.erl"},
    +                    {copy_file,[...]},
    +                    {copy_file,...},
    +                    {...}|...]},
    +               {create_dir,"ebin",
    +                   [{copy_file,[...]},{copy_file,...},{...}|...]}]},
    +          {create_dir,"crypto-3.7.4",
    +              [{create_dir,"src",[{copy_file,[...]},{copy_file,...}]},
    +               {create_dir,"ebin",[{copy_file,...},{...}|...]}]},
    +          {create_dir,"crypto-3.7.4",
    +              [{create_dir,"priv",
    +                   [{create_dir,"lib",[{copy_file,[...]},{copy_file,...}]},
    +                    {create_dir,"obj",[{copy_file,...},{...}|...]}]}]},
    +          {create_dir,"erts-10.0",
    +              [{create_dir,"src",[{...}|...]},
    +               {create_dir,"ebin",[...]}]},
    +          {create_dir,"hipe-3.15.4",
    +              [{create_dir,"flow",[...]},
    +               {copy_file,[...]},
    +               {create_dir,...},
    +               {...}|...]},
    +          {create_dir,"inets-6.3.9",
    +              [{create_dir,[...],...},{create_dir,...},{...}]},
    +          {create_dir,"inets-6.3.9",
    +              [{create_dir,"priv",[{create_dir,[...],...}]},
    +               {create_dir,"include",[{copy_file,...},{...}]}]},
    +          {create_dir,"kernel-5.2",[{...}|...]},
    +          {create_dir,"kernel-5.2",
    +              [{create_dir,"include",[{...}|...]}]},
    +          {create_dir,[...],...},
    +          {create_dir,...},
    +          {create_dir,"stdlib-3.3",[{create_dir,...}]},
    +          ...]}]}
     3>
     3> TargetDir = "/tmp/my_target_dir".
     "/tmp/my_target_dir"
     4>
    -4> reltool:eval_target_spec(Spec, code:root_dir(), TargetDir).
    -{error,"/tmp/my_target_dir: no such file or directory"}
    +4> reltool:eval_target_spec(Spec, code:root_dir(), TargetDir).
    +{error,"/tmp/my_target_dir: no such file or directory"}
     5>
    -5> file:make_dir(TargetDir).
    +5> file:make_dir(TargetDir).
     ok
     6>
    -6> reltool:eval_target_spec(Spec, code:root_dir(), TargetDir).
    +6> reltool:eval_target_spec(Spec, code:root_dir(), TargetDir).
     ok
     7>
    -7> file:list_dir(TargetDir).
    -{ok,["bin","Install","lib","misc","usr","erts-10.0",
    -     "releases"]}
    +7> file:list_dir(TargetDir).
    +{ok,["bin","Install","lib","misc","usr","erts-10.0",
    +     "releases"]}
     8>
    -8> file:list_dir(filename:join([TargetDir,"lib"])).
    -{ok,["tools-2.9.1","inets-6.3.9",
    +8> file:list_dir(filename:join([TargetDir,"lib"])).
    +{ok,["tools-2.9.1","inets-6.3.9",
          "kernel-5.2","sasl-3.0.3",
          "crypto-3.7.4","erts-10.0",
    -     "stdlib-3.3","compiler-7.0.4"]}
    +     "stdlib-3.3","compiler-7.0.4"]}
     9>
    -9> file:make_dir("/tmp/yet_another_target_dir").
    +9> file:make_dir("/tmp/yet_another_target_dir").
     ok
     10>
    -10> reltool:create_target([Config], "/tmp/yet_another_target_dir").
    +10> reltool:create_target([Config], "/tmp/yet_another_target_dir").
     ok
     11>
    -11> file:list_dir("/tmp/yet_another_target_dir").
    -{ok,["bin","Install","lib","misc","usr","erts-10.0",
    -     "releases"]}
    +11>
    file:list_dir("/tmp/yet_another_target_dir"). +{ok,["bin","Install","lib","misc","usr","erts-10.0", + "releases"]}
    diff --git a/prs/8803/lib/runtime_tools-2.1/doc/html/dbg.html b/prs/8803/lib/runtime_tools-2.1/doc/html/dbg.html index b67e7582d8751..09052f2c4e208 100644 --- a/prs/8803/lib/runtime_tools-2.1/doc/html/dbg.html +++ b/prs/8803/lib/runtime_tools-2.1/doc/html/dbg.html @@ -131,16 +131,16 @@

    The Text Based Trace Facility

    This module implements a text based interface to the trace:process/4, trace:port/4, and trace:function/4 BIFs, simplifying tracing of functions, processes, ports, and messages.

    To quickly get started on tracing function calls you can use the -following code in the Erlang shell:

    1> dbg:tracer().  % Start the default trace message receiver
    -{ok,<0.90.0>}
    -2> dbg:p(all, c). % Set upp call tracing on all processes
    -{ok,[{matched,nonode@nohost,49}]}
    -3> dbg:tp(lists, seq, cx). %  Set up call and exception tracing on lists:seq/2,3
    -{ok,[{matched,nonode@nohost,2},{saved,cx}]}
    -4> lists:seq(1, 10).
    -(<0.88.0>) call lists:seq(1,10) ({erl_eval,do_apply,7,{"erl_eval.erl",904}})
    -[1,2,3,4,5,6,7,8,9,10]
    -(<0.88.0>) returned from lists:seq/2 -> [1,2,3,4,5,6,7,8,9,10]

    The utilities are also suitable to use in system testing on large systems, where +following code in the Erlang shell:

    1> dbg:tracer().  % Start the default trace message receiver
    +{ok,<0.90.0>}
    +2> dbg:p(all, c). % Set upp call tracing on all processes
    +{ok,[{matched,nonode@nohost,49}]}
    +3> dbg:tp(lists, seq, cx). %  Set up call and exception tracing on lists:seq/2,3
    +{ok,[{matched,nonode@nohost,2},{saved,cx}]}
    +4> lists:seq(1, 10).
    +(<0.88.0>) call lists:seq(1,10) ({erl_eval,do_apply,7,{"erl_eval.erl",904}})
    +[1,2,3,4,5,6,7,8,9,10]
    +(<0.88.0>) returned from lists:seq/2 -> [1,2,3,4,5,6,7,8,9,10]

    The utilities are also suitable to use in system testing on large systems, where other tools have too severe impact on the system performance. Some primitive support for sequential tracing is also included; see the advanced topics section.

    @@ -152,36 +152,36 @@

    To trace a call to a function with minimal fuss, call dbg:c(Module, Name, Arguments). dbg:c/3 starts a temporary trace receiver, enables all trace flags, and calls the designated function from a temporary process. For example, here is how to trace a call -to application:which_applications/0:

    1> dbg:c(application, which_applications, []).
    -(<0.92.0>) <0.45.0> ! {'$gen_call',{<0.92.0>,
    -                                    [alias|
    -                                     #Ref<0.0.11779.270031856.1478295555.230456>]},
    -                                   which_applications} (Timestamp: {1710,
    +to application:which_applications/0:

    1> dbg:c(application, which_applications, []).
    +(<0.92.0>) <0.45.0> ! {'$gen_call',{<0.92.0>,
    +                                    [alias|
    +                                     #Ref<0.0.11779.270031856.1478295555.230456>]},
    +                                   which_applications} (Timestamp: {1710,
                                                                         847802,
    -                                                                    479222})
    -(<0.92.0>) out {gen,do_call,4} (Timestamp: {1710,847802,479231})
    -(<0.92.0>) in {gen,do_call,4} (Timestamp: {1710,847802,479271})
    -(<0.92.0>) << {[alias|#Ref<0.0.11779.270031856.1478295555.230456>],
    -               [{stdlib,"ERTS  CXC 138 10","5.2.1"},
    -                {kernel,"ERTS  CXC 138 10","9.2.2"}]} (Timestamp: {1710,
    +                                                                    479222})
    +(<0.92.0>) out {gen,do_call,4} (Timestamp: {1710,847802,479231})
    +(<0.92.0>) in {gen,do_call,4} (Timestamp: {1710,847802,479271})
    +(<0.92.0>) << {[alias|#Ref<0.0.11779.270031856.1478295555.230456>],
    +               [{stdlib,"ERTS  CXC 138 10","5.2.1"},
    +                {kernel,"ERTS  CXC 138 10","9.2.2"}]} (Timestamp: {1710,
                                                                        847802,
    -                                                                   479274})
    -[{stdlib,"ERTS  CXC 138 10","5.2.1"},
    - {kernel,"ERTS  CXC 138 10","9.2.2"}]

    Four trace events are generated:

    • A send event (!) for the sending of a request from the current process + 479274}) +[{stdlib,"ERTS CXC 138 10","5.2.1"}, + {kernel,"ERTS CXC 138 10","9.2.2"}]

    Four trace events are generated:

    • A send event (!) for the sending of a request from the current process to the application_controller process.
    • A schedule-out event (out) when the current process schedules out while waiting in a receive for the reply to arrive.
    • A schedule-in event (in) when the current process is scheduled in when reply has arrived.
    • A receive event (<<) when the current process retrieves the reply from the application_controller process.

    The dbg:c/4 function has a fourth argument for specifying the trace flags. -Here is how to only show message sending and receiving:

    2> dbg:c(application, which_applications, [], m).
    -(<0.96.0>) <0.45.0> ! {'$gen_call',{<0.96.0>,
    -                                    [alias|
    -                                     #Ref<0.0.12291.270031856.1478295555.230496>]},
    -                                   which_applications}
    -(<0.96.0>) << {[alias|#Ref<0.0.12291.270031856.1478295555.230496>],
    -               [{stdlib,"ERTS  CXC 138 10","5.2.1"},
    -                {kernel,"ERTS  CXC 138 10","9.2.2"}]}
    -[{stdlib,"ERTS  CXC 138 10","5.2.1"},
    - {kernel,"ERTS  CXC 138 10","9.2.2"}]

    +Here is how to only show message sending and receiving:

    2> dbg:c(application, which_applications, [], m).
    +(<0.96.0>) <0.45.0> ! {'$gen_call',{<0.96.0>,
    +                                    [alias|
    +                                     #Ref<0.0.12291.270031856.1478295555.230496>]},
    +                                   which_applications}
    +(<0.96.0>) << {[alias|#Ref<0.0.12291.270031856.1478295555.230496>],
    +               [{stdlib,"ERTS  CXC 138 10","5.2.1"},
    +                {kernel,"ERTS  CXC 138 10","9.2.2"}]}
    +[{stdlib,"ERTS  CXC 138 10","5.2.1"},
    + {kernel,"ERTS  CXC 138 10","9.2.2"}]

    @@ -189,35 +189,35 @@

    Another way of tracing from the shell is to explicitly start a tracer and set the trace flags of your choice on the processes you want to trace. -For example, here is how to trace messages and process events:

    1> Pid = spawn(fun() -> receive {From,Msg} -> From ! Msg end end).
    +For example, here is how to trace messages and process events:

    1> Pid = spawn(fun() -> receive {From,Msg} -> From ! Msg end end).
     <0.90.0>
    -2> dbg:tracer().
    -{ok,<0.92.0>}
    -3> dbg:p(Pid, [m,procs]).
    -{ok,[{matched,nonode@nohost,1}]}
    -4> Pid ! {self(),hello}.
    -(<0.90.0>) << {<0.88.0>,hello}
    -{<0.88.0>,hello}
    -(<0.90.0>) <0.88.0> ! hello
    -(<0.90.0>) exit normal
    -5> flush().
    +2> dbg:tracer().
    +{ok,<0.92.0>}
    +3> dbg:p(Pid, [m,procs]).
    +{ok,[{matched,nonode@nohost,1}]}
    +4> Pid ! {self(),hello}.
    +(<0.90.0>) << {<0.88.0>,hello}
    +{<0.88.0>,hello}
    +(<0.90.0>) <0.88.0> ! hello
    +(<0.90.0>) exit normal
    +5> flush().
     Shell got hello
     ok

    In order to trace functions call, in addition to enabling the call trace flag for the process, it is also necessary to set a trace pattern for the functions -to trace.

    Example:

    1> dbg:tracer().
    -{ok,<0.90.0>}
    -2> dbg:p(all, call).
    -{ok,[{matched,nonode@nohost,49}]}
    -3> dbg:tp(lists, last, 1, []).
    -{ok,[{matched,nonode@nohost,1}]}
    -4> lists:last([a,b,c,d,e]).
    -(<0.88.0>) call lists:last([a,b,c,d,e])
    +to trace.

    Example:

    1> dbg:tracer().
    +{ok,<0.90.0>}
    +2> dbg:p(all, call).
    +{ok,[{matched,nonode@nohost,49}]}
    +3> dbg:tp(lists, last, 1, []).
    +{ok,[{matched,nonode@nohost,1}]}
    +4> lists:last([a,b,c,d,e]).
    +(<0.88.0>) call lists:last([a,b,c,d,e])
     e
    -5> dbg:tp(lists, last, 1, [{'_',[],[{return_trace}]}]).
    -{ok,[{matched,nonode@nohost,1},{saved,1}]}
    -6> lists:last([a,b,c,d,e]).
    -(<0.88.0>) call lists:last([a,b,c,d,e])
    -(<0.88.0>) returned from lists:last/1 -> e
    +5> dbg:tp(lists, last, 1, [{'_',[],[{return_trace}]}]).
    +{ok,[{matched,nonode@nohost,1},{saved,1}]}
    +6> lists:last([a,b,c,d,e]).
    +(<0.88.0>) call lists:last([a,b,c,d,e])
    +(<0.88.0>) returned from lists:last/1 -> e
     e

    @@ -231,21 +231,21 @@

    seq_trace and the same tracer function for both types of tracing can be used. The seq_trace messages can also be sent to a trace port for further analysis.

    As a match specification can turn on sequential tracing, the combination of dbg and seq_trace can be powerful. This brief example shows a session -where sequential tracing is used to trace the dbg module and the trace itself:

    1> dbg:tracer().
    -{ok,<0.30.0>}
    -2> {ok, Tracer} = dbg:get_tracer().
    -{ok,<0.31.0>}
    -3> seq_trace:set_system_tracer(Tracer).
    +where sequential tracing is used to trace the dbg module and the trace itself:

    1> dbg:tracer().
    +{ok,<0.30.0>}
    +2> {ok, Tracer} = dbg:get_tracer().
    +{ok,<0.31.0>}
    +3> seq_trace:set_system_tracer(Tracer).
     false
    -4> dbg:tp(dbg, get_tracer, 0, [{[],[],[{set_seq_token, send, true}]}]).
    -{ok,[{matched,nonode@nohost,1},{saved,1}]}
    -5> dbg:p(all,call).
    -{ok,[{matched,nonode@nohost,22}]}
    -6> dbg:get_tracer(), seq_trace:set_token([]).
    -(<0.25.0>) call dbg:get_tracer()
    -SeqTrace [0]: (<0.25.0>) <0.30.0> ! {<0.25.0>,get_tracer} [Serial: {2,4}]
    -SeqTrace [0]: (<0.30.0>) <0.25.0> ! {dbg,{ok,<0.31.0>}} [Serial: {4,5}]
    -{1,0,5,<0.30.0>,4}

    This session sets the system_tracer to the same process as the +4> dbg:tp(dbg, get_tracer, 0, [{[],[],[{set_seq_token, send, true}]}]). +{ok,[{matched,nonode@nohost,1},{saved,1}]} +5> dbg:p(all,call). +{ok,[{matched,nonode@nohost,22}]} +6> dbg:get_tracer(), seq_trace:set_token([]). +(<0.25.0>) call dbg:get_tracer() +SeqTrace [0]: (<0.25.0>) <0.30.0> ! {<0.25.0>,get_tracer} [Serial: {2,4}] +SeqTrace [0]: (<0.30.0>) <0.25.0> ! {dbg,{ok,<0.31.0>}} [Serial: {4,5}] +{1,0,5,<0.30.0>,4}

    This session sets the system_tracer to the same process as the ordinary tracer process (i. e. <0.31.0>) and sets the trace pattern for the function dbg:get_tracer to one that has the action of setting a sequential token. When the function is called by a traced @@ -267,20 +267,20 @@

    trace handler prints to the tty using an io function such as format/2. Note that when dbg:p(all, call) is called, IO processes are also traced. Here is an example:

    %% Using a default line editing shell
    -1> dbg:tracer(process, {fun(Msg,_) -> io:format("~p~n", [Msg]), 0 end, 0}).
    -{ok,<0.37.0>}
    -2> dbg:p(all, [call]).
    -{ok,[{matched,nonode@nohost,25}]}
    -3> dbg:tp(mymod,[{'_',[],[]}]).
    -{ok,[{matched,nonode@nohost,0},{saved,1}]}
    +1> dbg:tracer(process, {fun(Msg,_) -> io:format("~p~n", [Msg]), 0 end, 0}).
    +{ok,<0.37.0>}
    +2> dbg:p(all, [call]).
    +{ok,[{matched,nonode@nohost,25}]}
    +3> dbg:tp(mymod,[{'_',[],[]}]).
    +{ok,[{matched,nonode@nohost,0},{saved,1}]}
     4> mymod: % TAB pressed here
     %% -- Deadlock --

    Here is another example:

    %% Using a shell without line editing (oldshell)
    -1> dbg:tracer(process).
    -{ok,<0.31.0>}
    -2> dbg:p(all, [call]).
    -{ok,[{matched,nonode@nohost,25}]}
    -3> dbg:tp(lists,[{'_',[],[]}]).
    -{ok,[{matched,nonode@nohost,0},{saved,1}]}
    +1> dbg:tracer(process).
    +{ok,<0.31.0>}
    +2> dbg:p(all, [call]).
    +{ok,[{matched,nonode@nohost,25}]}
    +3> dbg:tp(lists,[{'_',[],[]}]).
    +{ok,[{matched,nonode@nohost,0},{saved,1}]}
     % -- Deadlock --

    The reason we get a deadlock in the first example is because when TAB is pressed to expand the function name, the group leader (which handles character input) calls mymod:module_info(). This generates a trace message which, in turn, @@ -2095,40 +2095,40 @@

    fun2ms(LiteralFun)

    as the argument of the function call; it cannot be held in a variable which in turn is passed to the function. Furthermore, the parse transform module ms_transform must be enabled. The easiest way to -enable it is by adding the following line to the source file:

    -include_lib("stdlib/include/ms_transform.hrl").

    Failing to include ms_transform.hrl in the source will result in a runtime +enable it is by adding the following line to the source file:

    -include_lib("stdlib/include/ms_transform.hrl").

    Failing to include ms_transform.hrl in the source will result in a runtime error, not a compile-time error.

    This function can also be invoked directly from the Erlang shell, as shown in the examples that follow.

    The head of the fun must be a single pattern that matches a list. That pattern -will be used to match the arguments for the call:

    Examples:

    1> dbg:fun2ms(fun([_,_]) -> true end).
    -[{['_','_'],[],[true]}]
    -2> dbg:fun2ms(fun(Args) when length(Args) > 6 -> true end).
    -[{'$1',[{'>',{length,'$1'},6}],[true]}]

    The first match specification matches when a function having two +will be used to match the arguments for the call:

    Examples:

    1> dbg:fun2ms(fun([_,_]) -> true end).
    +[{['_','_'],[],[true]}]
    +2> dbg:fun2ms(fun(Args) when length(Args) > 6 -> true end).
    +[{'$1',[{'>',{length,'$1'},6}],[true]}]

    The first match specification matches when a function having two arguments is called. The second matches when a function with more than -6 arguments is called.

    Examples:

    1> dbg:fun2ms(fun(42) -> true end).
    +6 arguments is called.

    Examples:

    1> dbg:fun2ms(fun(42) -> true end).
     Error: dbg:fun2ms requires fun with single variable or list parameter
    -{error,transform_error}
    -2> dbg:fun2ms(fun([<<H,T/binary>>]) -> true end).
    +{error,transform_error}
    +2> dbg:fun2ms(fun([<<H,T/binary>>]) -> true end).
     Error: fun head contains bit syntax matching of variable 'H', which cannot be translated into match_spec
    -{error,transform_error}

    The preceding two examples show what happens when a fun cannot be +{error,transform_error}

    The preceding two examples show what happens when a fun cannot be translated into a match specification. In the first example, the fun head connot possibly match a list. In the second example, an attempt is made to take apart a binary using the bit syntax, which is currently not -supported in match specifications.

    However, note that literal binaries can be matched:

    1> dbg:fun2ms(fun([<<"abc">>]) -> true end).
    -[{[<<"abc">>],[],[true]}]

    Match specifications support a large subset of the +supported in match specifications.

    However, note that literal binaries can be matched:

    1> dbg:fun2ms(fun([<<"abc">>]) -> true end).
    +[{[<<"abc">>],[],[true]}]

    Match specifications support a large subset of the guard expressions supported -by Erlang, but not all. For example, updating a map is currently not supported:

    1> dbg:fun2ms(fun([M]) when map_size(M#{a => b}) > 2 -> true end).
    -Error: the language element map (in guard) cannot be translated into match_spec
    -{error,transform_error}

    However, creating a map in a guard is allowed:

    1> dbg:fun2ms(fun([M]) when map_size(#{a => b}) > 2 -> true end).
    -[{['$1'],[{'>',{map_size,#{a => b}},2}],[true]}]

    Variables from the environment can be imported, so this works:

    1> X = 3.
    +by Erlang, but not all. For example, updating a map is currently not supported:

    1> dbg:fun2ms(fun([M]) when map_size(M#{a => b}) > 2 -> true end).
    +Error: the language element map (in guard) cannot be translated into match_spec
    +{error,transform_error}

    However, creating a map in a guard is allowed:

    1> dbg:fun2ms(fun([M]) when map_size(#{a => b}) > 2 -> true end).
    +[{['$1'],[{'>',{map_size,#{a => b}},2}],[true]}]

    Variables from the environment can be imported, so this works:

    1> X = 3.
     3
    -2> dbg:fun2ms(fun([M,N]) when N > X  -> return_trace() end).
    -[{['$1','$2'],[{'>','$2',{const,3}}],[{return_trace}]}]

    The imported variables will be replaced by const expressions, which +2> dbg:fun2ms(fun([M,N]) when N > X -> return_trace() end). +[{['$1','$2'],[{'>','$2',{const,3}}],[{return_trace}]}]

    The imported variables will be replaced by const expressions, which is consistent with the static scoping for Erlang funs.

    In the body of the fun, only guard expressions and calls to the special functions for tracing -are allowed.

    Examples:

    1> dbg:fun2ms(fun([A]) when is_atom(A) -> return_trace() end).
    -[{['$1'],[{is_atom,'$1'}],[{return_trace}]}]
    -2> dbg:fun2ms(fun(_) -> erlang:garbage_collect() end).
    -Error: fun containing the remote function call 'erlang:garbage_collect/0' (called in body) cannot be translated into match_spec
    -{error,transform_error}

    Warning

    If the parse transform is not applied to a module which calls dbg:fun2ms/1, +are allowed.

    Examples:

    1> dbg:fun2ms(fun([A]) when is_atom(A) -> return_trace() end).
    +[{['$1'],[{is_atom,'$1'}],[{return_trace}]}]
    +2> dbg:fun2ms(fun(_) -> erlang:garbage_collect() end).
    +Error: fun containing the remote function call 'erlang:garbage_collect/0' (called in body) cannot be translated into match_spec
    +{error,transform_error}

    Warning

    If the parse transform is not applied to a module which calls dbg:fun2ms/1, the call will fail in runtime with a badarg exception.

    More information is available in the documentation for module ms_transform in STDLIB.

    @@ -2336,16 +2336,16 @@

    ltp()

    names, parameters, return values, and exceptions raised from functions

  • caller_trace, c - sets a trace that displays function names, parameters, and information about which function called it

  • caller_exception_trace, cx - combines exception_trace and -caller_trace

  • Here is an example that shows how to use a built-in match specification:

    1> dbg:tracer().
    -{ok,<0.90.0>}
    -2> dbg:tp(lists, seq, 2, cx).
    -{ok,[{matched,nonode@nohost,1},{saved,cx}]}
    -3> dbg:p(self(), call).
    -{ok,[{matched,nonode@nohost,1}]}
    -4> lists:seq(1, 5).
    -(<0.88.0>) call lists:seq(1,5) ({erl_eval,do_apply,7,{"erl_eval.erl",904}})
    -[1,2,3,4,5]
    -(<0.88.0>) returned from lists:seq/2 -> [1,2,3,4,5]
    +caller_trace

    Here is an example that shows how to use a built-in match specification:

    1> dbg:tracer().
    +{ok,<0.90.0>}
    +2> dbg:tp(lists, seq, 2, cx).
    +{ok,[{matched,nonode@nohost,1},{saved,cx}]}
    +3> dbg:p(self(), call).
    +{ok,[{matched,nonode@nohost,1}]}
    +4> lists:seq(1, 5).
    +(<0.88.0>) call lists:seq(1,5) ({erl_eval,do_apply,7,{"erl_eval.erl",904}})
    +[1,2,3,4,5]
    +(<0.88.0>) returned from lists:seq/2 -> [1,2,3,4,5]
    @@ -2543,37 +2543,37 @@

    session(Session, Fun)

    is provided.

    Any dbg function that is called with in the provided fun will use the session/0 provided instead of the default dbg session. This means that the tracing will be isolated -from other tracing users on the system.

    The function returns the term that the fun returns.

    Example:

    1> S = dbg:session_create(my_session).
    +from other tracing users on the system.

    The function returns the term that the fun returns.

    Example:

    1> S = dbg:session_create(my_session).
     <0.91.0>
    -2> dbg:session(S, fun() -> dbg:tracer(), dbg:p(all,c), dbg:tp(lists,seq,x) end).
    -{ok,[{matched,nonode@nohost,2},{saved,x}]}
    -3> lists:seq(1, 10).
    -(<0.89.0>) call lists:seq(1,10)
    -(<0.89.0>) returned from lists:seq/2 -> [1,2,3,4,5,6,7,8,9,10]
    -[1,2,3,4,5,6,7,8,9,10]
    -4> dbg:session_destroy(S).
    +2> dbg:session(S, fun() -> dbg:tracer(), dbg:p(all,c), dbg:tp(lists,seq,x) end).
    +{ok,[{matched,nonode@nohost,2},{saved,x}]}
    +3> lists:seq(1, 10).
    +(<0.89.0>) call lists:seq(1,10)
    +(<0.89.0>) returned from lists:seq/2 -> [1,2,3,4,5,6,7,8,9,10]
    +[1,2,3,4,5,6,7,8,9,10]
    +4> dbg:session_destroy(S).
     ok

    The state of the session/0 is preserved in between session/2 calls, so -you can call session/2 multiple when debugging you application.

    Example:

    1> S = dbg:session_create(my_session).
    +you can call session/2 multiple when debugging you application.

    Example:

    1> S = dbg:session_create(my_session).
     <0.91.0>
     %% Setup the initial traces
    -2> dbg:session(S, fun() -> dbg:tracer(), dbg:p(self(),c), dbg:tp(lists,seq,x) end).
    -{ok,[{matched,nonode@nohost,2},{saved,x}]}
    -3> lists:seq(1, 3).
    -(<0.89.0>) call lists:seq(1,3)
    -(<0.89.0>) returned from lists:seq/2 -> [1,2,3]
    -[1,2,3]
    +2> dbg:session(S, fun() -> dbg:tracer(), dbg:p(self(),c), dbg:tp(lists,seq,x) end).
    +{ok,[{matched,nonode@nohost,2},{saved,x}]}
    +3> lists:seq(1, 3).
    +(<0.89.0>) call lists:seq(1,3)
    +(<0.89.0>) returned from lists:seq/2 -> [1,2,3]
    +[1,2,3]
     %% Add an additional trace pattern
    -4> dbg:session(S, fun() -> dbg:tpl(lists,seq_loop,x) end).
    +4> dbg:session(S, fun() -> dbg:tpl(lists,seq_loop,x) end).
     ok
    -5> lists:seq(1, 3).
    -(<0.89.0>) call lists:seq(1,3)
    -(<0.89.0>) call lists:seq_loop(3,3,[])
    -(<0.89.0>) call lists:seq_loop(1,1,[2,3])
    -(<0.89.0>) returned from lists:seq_loop/3 -> [1,2,3]
    -(<0.89.0>) returned from lists:seq_loop/3 -> [1,2,3]
    -(<0.89.0>) returned from lists:seq/2 -> [1,2,3]
    -[1,2,3]
    -6> dbg:session_destroy(S).
    +5> lists:seq(1, 3).
    +(<0.89.0>) call lists:seq(1,3)
    +(<0.89.0>) call lists:seq_loop(3,3,[])
    +(<0.89.0>) call lists:seq_loop(1,1,[2,3])
    +(<0.89.0>) returned from lists:seq_loop/3 -> [1,2,3]
    +(<0.89.0>) returned from lists:seq_loop/3 -> [1,2,3]
    +(<0.89.0>) returned from lists:seq/2 -> [1,2,3]
    +[1,2,3]
    +6> dbg:session_destroy(S).
     ok

    Note

    The session functionality is experimental in Erlang/OTP 27 and may change in future releases without notice.

    @@ -2747,11 +2747,11 @@

    tp(ModuleOrMFA, MatchSpec)

    and will stand as an "alias" for the given expression.

    If the match specification is invalid, an {error, Errors} tuple is returned. Errors is as a list of tuples {error, string()}, where the string is a textual explanation of the compilation error. For -example:

    1> dbg:tp({dbg,ltp,0},[{[],[],[{message, two, arguments}, {noexist}]}]).
    -{error,
    - [{error,"Special form 'message' called with wrong number of
    -          arguments in {message,two,arguments}."},
    -  {error,"Function noexist/1 does_not_exist."}]}
    +example:

    1> dbg:tp({dbg,ltp,0},[{[],[],[{message, two, arguments}, {noexist}]}]).
    +{error,
    + [{error,"Special form 'message' called with wrong number of
    +          arguments in {message,two,arguments}."},
    +  {error,"Function noexist/1 does_not_exist."}]}
    @@ -3002,17 +3002,17 @@

    trace_client(Type, Parameters)

    host Hostname, from where it reads trace messages until the TCP/IP connection is closed. If no Hostname is specified, the local host is assumed.

    As an example, one can let trace messages be sent over the network to another Erlang node (preferably not distributed), where the formatting occurs.

    On the node stack there exists an Erlang node ant@stack. In the -shell, type the following:

    ant@stack> dbg:tracer(port, dbg:trace_port(ip, 4711)).
    +shell, type the following:

    ant@stack> dbg:tracer(port, dbg:trace_port(ip, 4711)).
     <0.17.0>
    -ant@stack> dbg:p(self(), send).
    -{ok,1}

    All trace messages are now sent to the trace port driver, which in turn listens +ant@stack> dbg:p(self(), send). +{ok,1}

    All trace messages are now sent to the trace port driver, which in turn listens for connections on the TCP/IP port 4711. If we want to see the messages on -another node, preferably on another host, we do like this:

    1> dbg:trace_client(ip, {"stack", 4711}).
    +another node, preferably on another host, we do like this:

    1> dbg:trace_client(ip, {"stack", 4711}).
     <0.42.0>

    If we now send a message from the shell on the node ant@stack, where all sends -from the shell are traced:

    ant@stack> self() ! hello.
    +from the shell are traced:

    ant@stack> self() ! hello.
     hello

    The following will appear at the console on the node that started the trace -client:

    (<0.23.0>) <0.23.0> ! hello
    -(<0.23.0>) <0.22.0> ! {shell_rep,<0.23.0>,{value,hello,[],[]}}

    The last line is generated due to internal message passing in the Erlang shell. +client:

    (<0.23.0>) <0.23.0> ! hello
    +(<0.23.0>) <0.22.0> ! {shell_rep,<0.23.0>,{value,hello,[],[]}}

    The last line is generated due to internal message passing in the Erlang shell. The pids will vary.

    @@ -3096,7 +3096,7 @@

    trace_port(Type, Parameters)

    Creates a trace-port-generating fun that is suitable as the -second argument to tracer/2.

    Example:

    dbg:tracer(port, dbg:trace_port(ip, 4711)).

    A trace port is an Erlang port to a dynamically linked-in driver that +second argument to tracer/2.

    Example:

    dbg:tracer(port, dbg:trace_port(ip, 4711)).

    A trace port is an Erlang port to a dynamically linked-in driver that handles trace messages directly, without the overhead of sending them as messages to an Erlang process. Using a trace port significantly lowers the overhead imposed by tracing.

    Two trace drivers are currently implemented: the file and the ip diff --git a/prs/8803/lib/runtime_tools-2.1/doc/html/dyntrace.html b/prs/8803/lib/runtime_tools-2.1/doc/html/dyntrace.html index 83b2cff187d9e..1c6462612f5e3 100644 --- a/prs/8803/lib/runtime_tools-2.1/doc/html/dyntrace.html +++ b/prs/8803/lib/runtime_tools-2.1/doc/html/dyntrace.html @@ -857,14 +857,14 @@

    restore_tag(TagData)

    Restores the previous state of user tags and their spreading as it was before a call to spread_tag/1.

    Note that the restoring is not limited to the same process; one can utilize this to turn off spreding in one process and restore it in a -newly created process that is is actually going to send messages:

    f() ->
    -    TagData = dyntrace:spread_tag(false),
    -    spawn(fun() ->
    -             dyntrace:restore_tag(TagData),
    -             do_something()
    -          end),
    -    do_something_else(),
    -    dyntrace:restore_tag(TagData).

    Correctly handling user tags and their spreading might take some effort, as +newly created process that is is actually going to send messages:

    f() ->
    +    TagData = dyntrace:spread_tag(false),
    +    spawn(fun() ->
    +             dyntrace:restore_tag(TagData),
    +             do_something()
    +          end),
    +    do_something_else(),
    +    dyntrace:restore_tag(TagData).

    Correctly handling user tags and their spreading might take some effort, as Erlang programs tend to send and receive messages so that sometimes the user tag gets lost due to various things, like double receives or communication with a port (ports do not handle user tags, in the same way as they do not handle @@ -911,12 +911,12 @@

    spread_tag(boolean())

    later call to restore_tag/1.

    The file module already spreads tags, so there is no need to manually call this function to get user tags spread to the efile driver through that module.

    The most use of this function would be if one, for example, uses the io module to communicate with an I/O-server for a regular file, such as in the following -example:

    f() ->
    -   {ok, F} = file:open("test.tst", [write]),
    -   Saved = dyntrace:spread_tag(true),
    -   io:format(F, "Hello world!", []),
    -   dyntrace:restore_tag(Saved),
    -   file:close(F).

    In this example, any user tag set in the calling process will be spread to the +example:

    f() ->
    +   {ok, F} = file:open("test.tst", [write]),
    +   Saved = dyntrace:spread_tag(true),
    +   io:format(F, "Hello world!", []),
    +   dyntrace:restore_tag(Saved),
    +   file:close(F).

    In this example, any user tag set in the calling process will be spread to the I/O-server when the io:format/3 call is done.

    diff --git a/prs/8803/lib/runtime_tools-2.1/doc/html/instrument.html b/prs/8803/lib/runtime_tools-2.1/doc/html/instrument.html index dddddf41f5aa4..37a4399d9d04a 100644 --- a/prs/8803/lib/runtime_tools-2.1/doc/html/instrument.html +++ b/prs/8803/lib/runtime_tools-2.1/doc/html/instrument.html @@ -355,8 +355,8 @@

    block_histogram()

    the one before it.

    The upper bound of the first interval is provided by the function that returned the histogram, and the last interval has no upper bound.

    For example, the histogram below has 40 (message) blocks between 128-256 bytes in size, 78 blocks between 256-512 bytes,2 blocks between 512-1024 bytes, and 2 -blocks between 1-2KB.

    > instrument:allocations(#{ histogram_start => 128, histogram_width => 15 }).
    -{ok, {128, 0, #{ message => {0,40,78,2,2,0,0,0,0,0,0,0,0,0,0}, ... } }}
    +blocks between 1-2KB.

    > instrument:allocations(#{ histogram_start => 128, histogram_width => 15 }).
    +{ok, {128, 0, #{ message => {0,40,78,2,2,0,0,0,0,0,0,0,0,0,0}, ... } }}
    @@ -496,30 +496,30 @@

    allocations(Options)

    block size histograms. Defaults to 128.

  • histogram_width - The number of intervals in the allocated block size histograms. Defaults to 18.

  • flags - Controls how to group the output, for example showing allocations on a per-process basis (when possible) rather than only a -NIF/driver-basis. Defaults to [].

  • Example:

    > instrument:allocations(#{ histogram_start => 128, histogram_width => 15 }).
    -{ok,{128,0,
    -     #{udp_inet =>
    -           #{driver_event_state => {0,0,0,0,0,0,0,0,0,1,0,0,0,0,0}},
    +NIF/driver-basis. Defaults to [].

    Example:

    > instrument:allocations(#{ histogram_start => 128, histogram_width => 15 }).
    +{ok,{128,0,
    +     #{udp_inet =>
    +           #{driver_event_state => {0,0,0,0,0,0,0,0,0,1,0,0,0,0,0}},
            system =>
    -           #{heap => {0,0,0,0,20,4,2,2,2,3,0,1,0,0,1},
    -             db_term => {271,3,1,52,80,1,0,0,0,0,0,0,0,0,0},
    -             code => {0,0,0,5,3,6,11,22,19,20,10,2,1,0,0},
    -             binary => {18,0,0,0,7,0,0,1,0,0,0,0,0,0,0},
    -             message => {0,40,78,2,2,0,0,0,0,0,0,0,0,0,0},
    -             ... }
    +           #{heap => {0,0,0,0,20,4,2,2,2,3,0,1,0,0,1},
    +             db_term => {271,3,1,52,80,1,0,0,0,0,0,0,0,0,0},
    +             code => {0,0,0,5,3,6,11,22,19,20,10,2,1,0,0},
    +             binary => {18,0,0,0,7,0,0,1,0,0,0,0,0,0,0},
    +             message => {0,40,78,2,2,0,0,0,0,0,0,0,0,0,0},
    +             ... }
            spawn_forker =>
    -           #{driver_select_data_state =>
    -                 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
    -       ram_file_drv => #{drv_binary => {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}},
    +           #{driver_select_data_state =>
    +                 {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
    +       ram_file_drv => #{drv_binary => {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}},
            prim_file =>
    -           #{process_specific_data => {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    -             nif_trap_export_entry => {0,4,0,0,0,0,0,0,0,0,0,0,0,0,0},
    -             monitor_extended => {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
    -             drv_binary => {0,0,0,0,0,0,1,0,3,5,0,0,0,1,0},
    -             binary => {0,4,0,0,0,0,0,0,0,0,0,0,0,0,0}},
    +           #{process_specific_data => {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    +             nif_trap_export_entry => {0,4,0,0,0,0,0,0,0,0,0,0,0,0,0},
    +             monitor_extended => {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
    +             drv_binary => {0,0,0,0,0,0,1,0,3,5,0,0,0,1,0},
    +             binary => {0,4,0,0,0,0,0,0,0,0,0,0,0,0,0}},
            prim_buffer =>
    -           #{nif_internal => {0,4,0,0,0,0,0,0,0,0,0,0,0,0,0},
    -             binary => {0,4,0,0,0,0,0,0,0,0,0,0,0,0,0}}}}}
    +
    #{nif_internal => {0,4,0,0,0,0,0,0,0,0,0,0,0,0,0}, + binary => {0,4,0,0,0,0,0,0,0,0,0,0,0,0,0}}}}}
    @@ -596,15 +596,15 @@

    carriers(Options)

    tied to any particular scheduler. Defaults to all schedulers and the global instance.

  • histogram_start - The upper bound of the first interval in the free block size histograms. Defaults to 512.

  • histogram_width - The number of intervals in the free block size -histograms. Defaults to 14.

  • Example:

    > instrument:carriers(#{ histogram_start => 512, histogram_width => 8 }).
    -{ok,{512,
    -     [{driver_alloc,false,262144,0,
    -                    [{driver_alloc,1,32784}],
    -                    {0,0,0,0,0,0,0,1}},
    -      {binary_alloc,false,32768,0,
    -                    [{binary_alloc,15,4304}],
    -                    {3,0,0,0,1,0,0,0}},
    -      {...}|...]}}
    +histograms. Defaults to 14.

    Example:

    > instrument:carriers(#{ histogram_start => 512, histogram_width => 8 }).
    +{ok,{512,
    +     [{driver_alloc,false,262144,0,
    +                    [{driver_alloc,1,32784}],
    +                    {0,0,0,0,0,0,0,1}},
    +      {binary_alloc,false,32768,0,
    +                    [{binary_alloc,15,4304}],
    +                    {3,0,0,0,1,0,0,0}},
    +      {...}|...]}}
    diff --git a/prs/8803/lib/runtime_tools-2.1/doc/html/lttng.html b/prs/8803/lib/runtime_tools-2.1/doc/html/lttng.html index ab24cbd6c85e3..2571af4407bfb 100644 --- a/prs/8803/lib/runtime_tools-2.1/doc/html/lttng.html +++ b/prs/8803/lib/runtime_tools-2.1/doc/html/lttng.html @@ -150,42 +150,42 @@

    Dyntrace Tracepoints

    All tracepoints are in the domain of org_erlang_dyntrace

    All Erlang types are the string equivalent in LTTng.

    process_spawn

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • parent : string :: Process ID. Ex. "<0.131.0>"
    • entry : string :: Code Location. Ex. "lists:sort/1"

    Available through erlang:trace/3 with trace flag procs and -{tracer,dyntrace,[]} as tracer module.

    Example:

    process_spawn: { cpu_id = 3 }, { pid = "<0.131.0>", parent = "<0.130.0>", entry = "erlang:apply/2" }

    process_link

    • to : string :: Process ID or Port ID. Ex. "<0.131.0>"
    • from : string :: Process ID or Port ID. Ex. "<0.131.0>"
    • type : string :: "link" | "unlink"

    Available through erlang:trace/3 with trace flag procs and +{tracer,dyntrace,[]} as tracer module.

    Example:

    process_spawn: { cpu_id = 3 }, { pid = "<0.131.0>", parent = "<0.130.0>", entry = "erlang:apply/2" }

    process_link

    • to : string :: Process ID or Port ID. Ex. "<0.131.0>"
    • from : string :: Process ID or Port ID. Ex. "<0.131.0>"
    • type : string :: "link" | "unlink"

    Available through erlang:trace/3 with trace flag procs and {tracer,dyntrace,[]} as tracer module.

    Example:

    process_link: { cpu_id = 3 }, { from = "<0.130.0>", to = "<0.131.0>", type = "link" }

    process_exit

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • reason : string :: Exit reason. Ex. "normal"

    Available through erlang:trace/3 with trace flag procs and -{tracer,dyntrace,[]} as tracer module.

    Example:

    process_exit: { cpu_id = 3 }, { pid = "<0.130.0>", reason = "normal" }

    process_register

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • name : string :: Registered name. Ex. "logger"
    • type : string :: "register" | "unregister"

    Example:

    process_register: { cpu_id = 0 }, { pid = "<0.128.0>", name = "dyntrace_lttng_SUITE" type = "register" }

    process_scheduled

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • entry : string :: Code Location. Ex. "lists:sort/1"
    • type : string :: +{tracer,dyntrace,[]} as tracer module.

      Example:

      process_exit: { cpu_id = 3 }, { pid = "<0.130.0>", reason = "normal" }

      process_register

      • pid : string :: Process ID. Ex. "<0.131.0>"
      • name : string :: Registered name. Ex. "logger"
      • type : string :: "register" | "unregister"

      Example:

      process_register: { cpu_id = 0 }, { pid = "<0.128.0>", name = "dyntrace_lttng_SUITE" type = "register" }

      process_scheduled

      • pid : string :: Process ID. Ex. "<0.131.0>"
      • entry : string :: Code Location. Ex. "lists:sort/1"
      • type : string :: "in" | "out" | "in_exiting" | "out_exiting" | "out_exited"

      Available through erlang:trace/3 with trace flag running and -{tracer,dyntrace,[]} as tracer module.

      Example:

      process_scheduled: { cpu_id = 0 }, { pid = "<0.136.0>", entry = "erlang:apply/2", type = "in" }

      port_open

      • pid : string :: Process ID. Ex. "<0.131.0>"
      • driver : string :: Driver name. Ex. "tcp_inet"
      • port : string :: Port ID. Ex. "#Port<0.1031>"

      Available through erlang:trace/3 with trace flag ports and +{tracer,dyntrace,[]} as tracer module.

      Example:

      process_scheduled: { cpu_id = 0 }, { pid = "<0.136.0>", entry = "erlang:apply/2", type = "in" }

      port_open

      • pid : string :: Process ID. Ex. "<0.131.0>"
      • driver : string :: Driver name. Ex. "tcp_inet"
      • port : string :: Port ID. Ex. "#Port<0.1031>"

      Available through erlang:trace/3 with trace flag ports and {tracer,dyntrace,[]} as tracer module.

      Example:

      port_open: { cpu_id = 5 }, { pid = "<0.131.0>", driver = "'/bin/sh -s unix:cmd'", port = "#Port<0.1887>" }

      port_exit

      • port : string :: Port ID. Ex. "#Port<0.1031>"
      • reason : string :: Exit reason. Ex. "normal"

      Available through erlang:trace/3 with trace flag ports and {tracer,dyntrace,[]} as tracer module.

      Example:

      port_exit: { cpu_id = 5 }, { port = "#Port<0.1887>", reason = "normal" }

      port_link

      • to : string :: Process ID. Ex. "<0.131.0>"
      • from : string :: Process ID. Ex. "<0.131.0>"
      • type : string :: "link" | "unlink"

      Available through erlang:trace/3 with trace flag ports and -{tracer,dyntrace,[]} as tracer module.

      Example:

      port_link: { cpu_id = 5 }, { from = "#Port<0.1887>", to = "<0.131.0>", type = "unlink" }

      port_scheduled

      Available through erlang:trace/3 with trace flag running and +{tracer,dyntrace,[]} as tracer module.

      Example:

      port_link: { cpu_id = 5 }, { from = "#Port<0.1887>", to = "<0.131.0>", type = "unlink" }

      port_scheduled

      Available through erlang:trace/3 with trace flag running and {tracer,dyntrace,[]} as tracer module.

      • port : string :: Port ID. Ex. "#Port<0.1031>"
      • entry : string :: Callback. Ex. "open"
      • type : string :: -"in" | "out" | "in_exiting" | "out_exiting" | "out_exited"

      Example:

      port_scheduled: { cpu_id = 5 }, { pid = "#Port<0.1905>", entry = "close", type = "out" }

      Available through erlang:trace/3 with trace flag running and +"in" | "out" | "in_exiting" | "out_exiting" | "out_exited"

    Example:

    port_scheduled: { cpu_id = 5 }, { pid = "#Port<0.1905>", entry = "close", type = "out" }

    Available through erlang:trace/3 with trace flag running and {tracer,dyntrace,[]} as tracer module.

    function_call

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • entry : string :: Code Location. Ex. "lists:sort/1"
    • depth : integer :: Stack depth. Ex. 0

    Available through erlang:trace/3 with trace flag call and -{tracer,dyntrace,[]} as tracer module.

    Example:

    function_call: { cpu_id = 5 }, { pid = "<0.145.0>", entry = "dyntrace_lttng_SUITE:'-t_call/1-fun-1-'/0", depth = 0 }

    function_return

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • entry : string :: Code Location. Ex. "lists:sort/1"
    • depth : integer :: Stack depth. Ex. 0

    Available through erlang:trace/3 with trace flag call or return_to and -{tracer,dyntrace,[]} as tracer module.

    Example:

    function_return: { cpu_id = 5 }, { pid = "<0.145.0>", entry = "dyntrace_lttng_SUITE:waiter/0", depth = 0 }

    function_exception

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • entry : string :: Code Location. Ex. "lists:sort/1"
    • class : string :: Error reason. Ex. "error"

    Available through erlang:trace/3 with trace flag call and -{tracer,dyntrace,[]} as tracer module.

    Example:

    function_exception: { cpu_id = 5 }, { pid = "<0.144.0>", entry = "t:call_exc/1", class = "error" }

    message_send

    • from : string :: Process ID or Port ID. Ex. "<0.131.0>"
    • to : string :: Process ID or Port ID. Ex. "<0.131.0>"
    • message : string :: Message sent. Ex. "{<0.162.0>,ok}"

    Available through erlang:trace/3 with trace flag send and +{tracer,dyntrace,[]} as tracer module.

    Example:

    function_call: { cpu_id = 5 }, { pid = "<0.145.0>", entry = "dyntrace_lttng_SUITE:'-t_call/1-fun-1-'/0", depth = 0 }

    function_return

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • entry : string :: Code Location. Ex. "lists:sort/1"
    • depth : integer :: Stack depth. Ex. 0

    Available through erlang:trace/3 with trace flag call or return_to and +{tracer,dyntrace,[]} as tracer module.

    Example:

    function_return: { cpu_id = 5 }, { pid = "<0.145.0>", entry = "dyntrace_lttng_SUITE:waiter/0", depth = 0 }

    function_exception

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • entry : string :: Code Location. Ex. "lists:sort/1"
    • class : string :: Error reason. Ex. "error"

    Available through erlang:trace/3 with trace flag call and +{tracer,dyntrace,[]} as tracer module.

    Example:

    function_exception: { cpu_id = 5 }, { pid = "<0.144.0>", entry = "t:call_exc/1", class = "error" }

    message_send

    • from : string :: Process ID or Port ID. Ex. "<0.131.0>"
    • to : string :: Process ID or Port ID. Ex. "<0.131.0>"
    • message : string :: Message sent. Ex. "{<0.162.0>,ok}"

    Available through erlang:trace/3 with trace flag send and {tracer,dyntrace,[]} as tracer module.

    Example:

    message_send: { cpu_id = 3 }, { from = "#Port<0.1938>", to = "<0.160.0>", message = "{#Port<0.1938>,eof}" }

    message_receive

    • to : string :: Process ID or Port ID. Ex. "<0.131.0>"
    • message : string :: Message received. Ex. "{<0.162.0>,ok}"

    Available through erlang:trace/3 with trace flag 'receive' and {tracer,dyntrace,[]} as tracer module.

    Example:

    message_receive: { cpu_id = 7 }, { to = "<0.167.0>", message = "{<0.165.0>,ok}" }

    gc_minor_start

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • need : integer :: Heap need. Ex. 2
    • heap : integer :: Young heap word size. Ex. 233
    • old_heap : integer :: Old heap word size. Ex. 233

    Available through erlang:trace/3 with trace flag garbage_collection and -{tracer,dyntrace,[]} as tracer module.

    Example:

    gc_minor_start: { cpu_id = 0 }, { pid = "<0.172.0>", need = 0, heap = 610, old_heap = 0 }

    gc_minor_end

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • reclaimed : integer :: Heap reclaimed. Ex. 2
    • heap : integer :: Young heap word size. Ex. 233
    • old_heap : integer :: Old heap word size. Ex. 233

    Available through erlang:trace/3 with trace flag garbage_collection and -{tracer,dyntrace,[]} as tracer module.

    Example:

    gc_minor_end: { cpu_id = 0 }, { pid = "<0.172.0>", reclaimed = 120, heap = 1598, old_heap = 1598 }

    gc_major_start

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • need : integer :: Heap need. Ex. 2
    • heap : integer :: Young heap word size. Ex. 233
    • old_heap : integer :: Old heap word size. Ex. 233

    Available through erlang:trace/3 with trace flag garbage_collection and -{tracer,dyntrace,[]} as tracer module.

    Example:

    gc_major_start: { cpu_id = 0 }, { pid = "<0.172.0>", need = 8, heap = 2586, old_heap = 1598 }

    gc_major_end

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • reclaimed : integer :: Heap reclaimed. Ex. 2
    • heap : integer :: Young heap word size. Ex. 233
    • old_heap : integer :: Old heap word size. Ex. 233

    Available through erlang:trace/3 with trace flag garbage_collection and +{tracer,dyntrace,[]} as tracer module.

    Example:

    gc_minor_start: { cpu_id = 0 }, { pid = "<0.172.0>", need = 0, heap = 610, old_heap = 0 }

    gc_minor_end

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • reclaimed : integer :: Heap reclaimed. Ex. 2
    • heap : integer :: Young heap word size. Ex. 233
    • old_heap : integer :: Old heap word size. Ex. 233

    Available through erlang:trace/3 with trace flag garbage_collection and +{tracer,dyntrace,[]} as tracer module.

    Example:

    gc_minor_end: { cpu_id = 0 }, { pid = "<0.172.0>", reclaimed = 120, heap = 1598, old_heap = 1598 }

    gc_major_start

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • need : integer :: Heap need. Ex. 2
    • heap : integer :: Young heap word size. Ex. 233
    • old_heap : integer :: Old heap word size. Ex. 233

    Available through erlang:trace/3 with trace flag garbage_collection and +{tracer,dyntrace,[]} as tracer module.

    Example:

    gc_major_start: { cpu_id = 0 }, { pid = "<0.172.0>", need = 8, heap = 2586, old_heap = 1598 }

    gc_major_end

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • reclaimed : integer :: Heap reclaimed. Ex. 2
    • heap : integer :: Young heap word size. Ex. 233
    • old_heap : integer :: Old heap word size. Ex. 233

    Available through erlang:trace/3 with trace flag garbage_collection and {tracer,dyntrace,[]} as tracer module.

    Example:

    gc_major_end: { cpu_id = 0 }, { pid = "<0.172.0>", reclaimed = 240, heap = 4185, old_heap = 0 }

    BEAM Tracepoints

    -

    All tracepoints are in the domain of org_erlang_otp

    All Erlang types are the string equivalent in LTTng.

    driver_init

    • driver : string :: Driver name. Ex. "tcp_inet"
    • major : integer :: Major version. Ex. 3
    • minor : integer :: Minor version. Ex. 1
    • flags : integer :: Flags. Ex. 1

    Example:

    driver_init: { cpu_id = 2 }, { driver = "caller_drv", major = 3, minor = 3, flags = 1 }

    driver_start

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • driver : string :: Driver name. Ex. "tcp_inet"
    • port : string :: Port ID. Ex. "#Port<0.1031>"

    Example:

    driver_start: { cpu_id = 2 }, { pid = "<0.198.0>", driver = "caller_drv", port = "#Port<0.3676>" }

    driver_output

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • port : string :: Port ID. Ex. "#Port<0.1031>"
    • driver : string :: Driver name. Ex. "tcp_inet"
    • bytes : integer :: Size of data returned. Ex. 82

    Example:

    driver_output: { cpu_id = 2 }, { pid = "<0.198.0>", port = "#Port<0.3677>", driver = "/bin/sh -s unix:cmd", bytes = 36 }

    driver_outputv

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • port : string :: Port ID. Ex. "#Port<0.1031>"
    • driver : string :: Driver name. Ex. "tcp_inet"
    • bytes : integer :: Size of data returned. Ex. 82

    Example:

    driver_outputv: { cpu_id = 5 }, { pid = "<0.194.0>", port = "#Port<0.3663>", driver = "tcp_inet", bytes = 3 }

    driver_ready_input

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • port : string :: Port ID. Ex. "#Port<0.1031>"
    • driver : string :: Driver name. Ex. "tcp_inet"

    Example:

    driver_ready_input: { cpu_id = 5 }, { pid = "<0.189.0>", port = "#Port<0.3637>", driver = "inet_gethost 4 " }

    driver_ready_output

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • port : string :: Port ID. Ex. "#Port<0.1031>"
    • driver : string :: Driver name. Ex. "tcp_inet"

    Example:

    driver_ready_output: { cpu_id = 5 }, { pid = "<0.194.0>", port = "#Port<0.3663>", driver = "tcp_inet" }

    driver_timeout

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • port : string :: Port ID. Ex. "#Port<0.1031>"
    • driver : string :: Driver name. Ex. "tcp_inet"

    Example:

    driver_timeout: { cpu_id = 5 }, { pid = "<0.196.0>", port = "#Port<0.3664>", driver = "tcp_inet" }

    driver_stop_select

    • driver : string :: Driver name. Ex. "tcp_inet"

    Example:

    driver_stop_select: { cpu_id = 5 }, { driver = "unknown" }

    driver_flush

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • port : string :: Port ID. Ex. "#Port<0.1031>"
    • driver : string :: Driver name. Ex. "tcp_inet"

    Example:

    driver_flush: { cpu_id = 7 }, { pid = "<0.204.0>", port = "#Port<0.3686>", driver = "tcp_inet" }

    driver_stop

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • port : string :: Port ID. Ex. "#Port<0.1031>"
    • driver : string :: Driver name. Ex. "tcp_inet"

    Example:

    driver_stop: { cpu_id = 5 }, { pid = "[]", port = "#Port<0.3673>", driver = "tcp_inet" }

    driver_process_exit

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • port : string :: Port ID. Ex. "#Port<0.1031>"
    • driver : string :: Driver name. Ex. "tcp_inet"

    driver_ready_async

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • port : string :: Port ID. Ex. "#Port<0.1031>"
    • driver : string :: Driver name. Ex. "tcp_inet"

    Example:

    driver_ready_async: { cpu_id = 3 }, { pid = "<0.181.0>", port = "#Port<0.3622>", driver = "tcp_inet" }

    driver_call

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • port : string :: Port ID. Ex. "#Port<0.1031>"
    • driver : string :: Driver name. Ex. "tcp_inet"
    • command : integer :: Command integer. Ex. 1
    • bytes : integer :: Size of data returned. Ex. 82

    Example:

    driver_call: { cpu_id = 2 }, { pid = "<0.202.0>", port = "#Port<0.3676>", driver = "caller_drv", command = 0, bytes = 2 }

    driver_control

    • pid : string :: Process ID. Ex. "<0.131.0>"
    • port : string :: Port ID. Ex. "#Port<0.1031>"
    • driver : string :: Driver name. Ex. "tcp_inet"
    • command : integer :: Command integer. Ex. 1
    • bytes : integer :: Size of data returned. Ex. 82

    Example:

    driver_control: { cpu_id = 3 }, { pid = "<0.32767.8191>", port = "#Port<0.0>", driver = "forker", command = 83, bytes = 32 }

    carrier_create

    • type : string :: Carrier type. Ex. "ets_alloc"
    • instance : integer :: Allocator instance. Ex. 1
    • size : integer :: Carrier size. Ex. 262144
    • mbc_carriers : integer :: Number of multiblock carriers in instance. Ex. 3
    • mbc_carriers_size : integer :: Total size of multiblock blocks carriers in +

      All tracepoints are in the domain of org_erlang_otp

      All Erlang types are the string equivalent in LTTng.

      driver_init

      • driver : string :: Driver name. Ex. "tcp_inet"
      • major : integer :: Major version. Ex. 3
      • minor : integer :: Minor version. Ex. 1
      • flags : integer :: Flags. Ex. 1

      Example:

      driver_init: { cpu_id = 2 }, { driver = "caller_drv", major = 3, minor = 3, flags = 1 }

      driver_start

      • pid : string :: Process ID. Ex. "<0.131.0>"
      • driver : string :: Driver name. Ex. "tcp_inet"
      • port : string :: Port ID. Ex. "#Port<0.1031>"

      Example:

      driver_start: { cpu_id = 2 }, { pid = "<0.198.0>", driver = "caller_drv", port = "#Port<0.3676>" }

      driver_output

      • pid : string :: Process ID. Ex. "<0.131.0>"
      • port : string :: Port ID. Ex. "#Port<0.1031>"
      • driver : string :: Driver name. Ex. "tcp_inet"
      • bytes : integer :: Size of data returned. Ex. 82

      Example:

      driver_output: { cpu_id = 2 }, { pid = "<0.198.0>", port = "#Port<0.3677>", driver = "/bin/sh -s unix:cmd", bytes = 36 }

      driver_outputv

      • pid : string :: Process ID. Ex. "<0.131.0>"
      • port : string :: Port ID. Ex. "#Port<0.1031>"
      • driver : string :: Driver name. Ex. "tcp_inet"
      • bytes : integer :: Size of data returned. Ex. 82

      Example:

      driver_outputv: { cpu_id = 5 }, { pid = "<0.194.0>", port = "#Port<0.3663>", driver = "tcp_inet", bytes = 3 }

      driver_ready_input

      • pid : string :: Process ID. Ex. "<0.131.0>"
      • port : string :: Port ID. Ex. "#Port<0.1031>"
      • driver : string :: Driver name. Ex. "tcp_inet"

      Example:

      driver_ready_input: { cpu_id = 5 }, { pid = "<0.189.0>", port = "#Port<0.3637>", driver = "inet_gethost 4 " }

      driver_ready_output

      • pid : string :: Process ID. Ex. "<0.131.0>"
      • port : string :: Port ID. Ex. "#Port<0.1031>"
      • driver : string :: Driver name. Ex. "tcp_inet"

      Example:

      driver_ready_output: { cpu_id = 5 }, { pid = "<0.194.0>", port = "#Port<0.3663>", driver = "tcp_inet" }

      driver_timeout

      • pid : string :: Process ID. Ex. "<0.131.0>"
      • port : string :: Port ID. Ex. "#Port<0.1031>"
      • driver : string :: Driver name. Ex. "tcp_inet"

      Example:

      driver_timeout: { cpu_id = 5 }, { pid = "<0.196.0>", port = "#Port<0.3664>", driver = "tcp_inet" }

      driver_stop_select

      • driver : string :: Driver name. Ex. "tcp_inet"

      Example:

      driver_stop_select: { cpu_id = 5 }, { driver = "unknown" }

      driver_flush

      • pid : string :: Process ID. Ex. "<0.131.0>"
      • port : string :: Port ID. Ex. "#Port<0.1031>"
      • driver : string :: Driver name. Ex. "tcp_inet"

      Example:

      driver_flush: { cpu_id = 7 }, { pid = "<0.204.0>", port = "#Port<0.3686>", driver = "tcp_inet" }

      driver_stop

      • pid : string :: Process ID. Ex. "<0.131.0>"
      • port : string :: Port ID. Ex. "#Port<0.1031>"
      • driver : string :: Driver name. Ex. "tcp_inet"

      Example:

      driver_stop: { cpu_id = 5 }, { pid = "[]", port = "#Port<0.3673>", driver = "tcp_inet" }

      driver_process_exit

      • pid : string :: Process ID. Ex. "<0.131.0>"
      • port : string :: Port ID. Ex. "#Port<0.1031>"
      • driver : string :: Driver name. Ex. "tcp_inet"

      driver_ready_async

      • pid : string :: Process ID. Ex. "<0.131.0>"
      • port : string :: Port ID. Ex. "#Port<0.1031>"
      • driver : string :: Driver name. Ex. "tcp_inet"

      Example:

      driver_ready_async: { cpu_id = 3 }, { pid = "<0.181.0>", port = "#Port<0.3622>", driver = "tcp_inet" }

      driver_call

      • pid : string :: Process ID. Ex. "<0.131.0>"
      • port : string :: Port ID. Ex. "#Port<0.1031>"
      • driver : string :: Driver name. Ex. "tcp_inet"
      • command : integer :: Command integer. Ex. 1
      • bytes : integer :: Size of data returned. Ex. 82

      Example:

      driver_call: { cpu_id = 2 }, { pid = "<0.202.0>", port = "#Port<0.3676>", driver = "caller_drv", command = 0, bytes = 2 }

      driver_control

      • pid : string :: Process ID. Ex. "<0.131.0>"
      • port : string :: Port ID. Ex. "#Port<0.1031>"
      • driver : string :: Driver name. Ex. "tcp_inet"
      • command : integer :: Command integer. Ex. 1
      • bytes : integer :: Size of data returned. Ex. 82

      Example:

      driver_control: { cpu_id = 3 }, { pid = "<0.32767.8191>", port = "#Port<0.0>", driver = "forker", command = 83, bytes = 32 }

      carrier_create

      • type : string :: Carrier type. Ex. "ets_alloc"
      • instance : integer :: Allocator instance. Ex. 1
      • size : integer :: Carrier size. Ex. 262144
      • mbc_carriers : integer :: Number of multiblock carriers in instance. Ex. 3
      • mbc_carriers_size : integer :: Total size of multiblock blocks carriers in instance. Ex. 1343488
      • mbc_blocks : integer :: Number of multiblock blocks in instance. Ex. 122
      • mbc_blocks_size : integer :: Total size of all multiblock blocks in instance. Ex. 285296
      • sbc_carriers : integer :: Number of singleblock carriers in instance. Ex. 1
      • sbc_carriers_size : integer :: Total size of singleblock blocks carriers in instance. Ex. 1343488
      • sbc_blocks : integer :: Number of singleblocks in instance. Ex. 1
      • sbc_blocks_size : integer :: Total size of all singleblock blocks in -instance. Ex. 285296

      Example:

      carrier_create: { cpu_id = 2 }, { type = "ets_alloc", instance = 7, size = 2097152, mbc_carriers = 4, mbc_carriers_size = 3440640, mbc_blocks = 526, mbc_blocks_size = 1278576, sbc_carriers = 0, sbc_carriers_size = 0, sbc_blocks = 0, sbc_blocks_size = 0 }

      carrier_destroy

      • type : string :: Carrier type. Ex. "ets_alloc"
      • instance : integer :: Allocator instance. Ex. 1
      • size : integer :: Carrier size. Ex. 262144
      • mbc_carriers : integer :: Number of multiblock carriers in instance. Ex. 3
      • mbc_carriers_size : integer :: Total size of multiblock blocks carriers in +instance. Ex. 285296

      Example:

      carrier_create: { cpu_id = 2 }, { type = "ets_alloc", instance = 7, size = 2097152, mbc_carriers = 4, mbc_carriers_size = 3440640, mbc_blocks = 526, mbc_blocks_size = 1278576, sbc_carriers = 0, sbc_carriers_size = 0, sbc_blocks = 0, sbc_blocks_size = 0 }

      carrier_destroy

      • type : string :: Carrier type. Ex. "ets_alloc"
      • instance : integer :: Allocator instance. Ex. 1
      • size : integer :: Carrier size. Ex. 262144
      • mbc_carriers : integer :: Number of multiblock carriers in instance. Ex. 3
      • mbc_carriers_size : integer :: Total size of multiblock blocks carriers in instance. Ex. 1343488
      • mbc_blocks : integer :: Number of multiblock blocks in instance. Ex. 122
      • mbc_blocks_size : integer :: Total size of all multiblock blocks in instance. Ex. 285296
      • sbc_carriers : integer :: Number of singleblock carriers in instance. Ex. 1
      • sbc_carriers_size : integer :: Total size of singleblock blocks carriers in instance. Ex. 1343488
      • sbc_blocks : integer :: Number of singleblocks in instance. Ex. 1
      • sbc_blocks_size : integer :: Total size of all singleblock blocks in -instance. Ex. 285296

      Example:

      carrier_destroy: { cpu_id = 6 }, { type = "ets_alloc", instance = 7, size = 262144, mbc_carriers = 3, mbc_carriers_size = 3178496, mbc_blocks = 925, mbc_blocks_size = 2305336, sbc_carriers = 0, sbc_carriers_size = 0, sbc_blocks = 0, sbc_blocks_size = 0 }

      carrier_pool_put

      • type : string :: Carrier type. Ex. "ets_alloc"
      • instance : integer :: Allocator instance. Ex. 1
      • size : integer :: Carrier size. Ex. 262144

      Example:

      carrier_pool_put: { cpu_id = 3 }, { type = "ets_alloc", instance = 5, size = 1048576 }

      carrier_pool_get

      • type : string :: Carrier type. Ex. "ets_alloc"
      • instance : integer :: Allocator instance. Ex. 1
      • size : integer :: Carrier size. Ex. 262144

      Example:

      carrier_pool_get: { cpu_id = 7 }, { type = "ets_alloc", instance = 4, size = 3208 }

      +instance. Ex. 285296

    Example:

    carrier_destroy: { cpu_id = 6 }, { type = "ets_alloc", instance = 7, size = 262144, mbc_carriers = 3, mbc_carriers_size = 3178496, mbc_blocks = 925, mbc_blocks_size = 2305336, sbc_carriers = 0, sbc_carriers_size = 0, sbc_blocks = 0, sbc_blocks_size = 0 }

    carrier_pool_put

    • type : string :: Carrier type. Ex. "ets_alloc"
    • instance : integer :: Allocator instance. Ex. 1
    • size : integer :: Carrier size. Ex. 262144

    Example:

    carrier_pool_put: { cpu_id = 3 }, { type = "ets_alloc", instance = 5, size = 1048576 }

    carrier_pool_get

    • type : string :: Carrier type. Ex. "ets_alloc"
    • instance : integer :: Allocator instance. Ex. 1
    • size : integer :: Carrier size. Ex. 262144

    Example:

    carrier_pool_get: { cpu_id = 7 }, { type = "ets_alloc", instance = 4, size = 3208 }

    @@ -198,10 +198,10 @@

    Erlang/OTP 19 [erts-8.0] [source-4d7b24d] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [lttng] Eshell V8.0 (abort with ^G) -1>

    Load the dyntrace module.

    1> l(dyntrace).
    -{module,dyntrace}

    All tracepoints via dyntrace are now visible and can be listed through +1>

    Load the dyntrace module.

    1> l(dyntrace).
    +{module,dyntrace}

    All tracepoints via dyntrace are now visible and can be listed through lttng list -u.

    Enable the process_register LTTng tracepoint for Erlang.

    $ lttng enable-event -u org_erlang_dyntrace:process_register
    -UST event org_erlang_dyntrace:process_register created in channel channel0

    Enable process tracing for new processes and use dyntrace as tracer backend.

    2> erlang:trace(new,true,[procs,{tracer,dyntrace,[]}]).
    +UST event org_erlang_dyntrace:process_register created in channel channel0

    Enable process tracing for new processes and use dyntrace as tracer backend.

    2> erlang:trace(new,true,[procs,{tracer,dyntrace,[]}]).
     0

    Start LTTng tracing.

    $ lttng start
     Tracing started for session erlang-demo

    Start the os_mon application in Erlang.

    3> application:ensure_all_started(os_mon).
     {ok,[sasl,os_mon]}

    Stop LTTng tracing and view the result.

    $ lttng stop
    diff --git a/prs/8803/lib/runtime_tools-2.1/doc/html/msacc.html b/prs/8803/lib/runtime_tools-2.1/doc/html/msacc.html
    index e0d525e10f642..054fc70070831 100644
    --- a/prs/8803/lib/runtime_tools-2.1/doc/html/msacc.html
    +++ b/prs/8803/lib/runtime_tools-2.1/doc/html/msacc.html
    @@ -131,9 +131,9 @@ 

    Convenience functions for microstate accounting

    This module implements some convenience functions for analyzing microstate accounting data. For details about how to use the basic API and what the different states represent, see -erlang:statistics(microstate_accounting).

    Basic Scenario

    1> msacc:start(1000).
    +erlang:statistics(microstate_accounting).

    Basic Scenario

    1> msacc:start(1000).
     ok
    -2> msacc:print().
    +2> msacc:print().
     Average thread real-time    : 1000513 us
     Accumulated system run-time :    2213 us
     Average scheduler run-time  :    1076 us
    @@ -141,11 +141,11 @@ 

    Thread aux check_io emulator gc other port sleep Stats per thread: - async( 0) 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 100.00% - async( 1) 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 100.00% - aux( 1) 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 99.99% - scheduler( 1) 0.00% 0.03% 0.13% 0.00% 0.01% 0.00% 99.82% - scheduler( 2) 0.00% 0.00% 0.00% 0.00% 0.03% 0.00% 99.97% + async( 0) 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 100.00% + async( 1) 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 100.00% + aux( 1) 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 99.99% + scheduler( 1) 0.00% 0.03% 0.13% 0.00% 0.01% 0.00% 99.82% + scheduler( 2) 0.00% 0.00% 0.00% 0.00% 0.03% 0.00% 99.97% Stats per type: async 0.00% 0.00% 0.00% 0.00% 0.00% 0.00% 100.00% @@ -945,7 +945,7 @@

    print(DataOrStats, Options)

    this can be verbose. See the top of this reference manual for a brief description of what the fields mean.

    It is possible to print more specific types of statistics by first manipulating the DataOrStats using stats/2. For instance if you want to print the -percentage of run-time for each thread you can do:

    msacc:print(msacc:stats(runtime, msacc:stats())).

    If you want to only print run-time per thread type you can do:

    msacc:print(msacc:stats(type, msacc:stats(runtime, msacc:stats()))).

    Options

    • system - Print percentage of time spent in each state out of system time +percentage of run-time for each thread you can do:

      msacc:print(msacc:stats(runtime, msacc:stats())).

      If you want to only print run-time per thread type you can do:

      msacc:print(msacc:stats(type, msacc:stats(runtime, msacc:stats()))).

      Options

      • system - Print percentage of time spent in each state out of system time as well as thread time. Default: false.
      diff --git a/prs/8803/lib/runtime_tools-2.1/doc/html/runtime_tools.epub b/prs/8803/lib/runtime_tools-2.1/doc/html/runtime_tools.epub index ecc1c28016019..c27a839993bdd 100644 Binary files a/prs/8803/lib/runtime_tools-2.1/doc/html/runtime_tools.epub and b/prs/8803/lib/runtime_tools-2.1/doc/html/runtime_tools.epub differ diff --git a/prs/8803/lib/runtime_tools-2.1/doc/html/scheduler.html b/prs/8803/lib/runtime_tools-2.1/doc/html/scheduler.html index b096a2815d0a4..f403867a58be9 100644 --- a/prs/8803/lib/runtime_tools-2.1/doc/html/scheduler.html +++ b/prs/8803/lib/runtime_tools-2.1/doc/html/scheduler.html @@ -613,7 +613,7 @@

      utilization/1

      scheduler_wall_time.

      Calculate scheduler utilizations for the time interval from when Sample was taken and "now". The same as calling scheduler:utilization(Sample, scheduler:sample_all()).

      Note

      This function is not recommended as it's so easy to get invalid results -without noticing. In particular do not do this:

      scheduler:utilization(scheduler:sample()). % DO NOT DO THIS!

      The above example takes two samples in rapid succession and calculates the +without noticing. In particular do not do this:

      scheduler:utilization(scheduler:sample()). % DO NOT DO THIS!

      The above example takes two samples in rapid succession and calculates the scheduler utilization between them. The resulting values will probably be more misleading than informative.

      Instead use scheduler:utilization/2 and call get_sample/0 to get samples with some time in between.

      diff --git a/prs/8803/lib/sasl-4.2.2/doc/html/appup.html b/prs/8803/lib/sasl-4.2.2/doc/html/appup.html index 3abafecfcc598..a97d8ef15c530 100644 --- a/prs/8803/lib/sasl-4.2.2/doc/html/appup.html +++ b/prs/8803/lib/sasl-4.2.2/doc/html/appup.html @@ -143,9 +143,9 @@

      Application is the application name. The file is to be located in the ebin directory for the application.

      The .appup file contains one single Erlang term, which defines the instructions used to upgrade or downgrade the application. The file has the -following syntax:

      {Vsn,
      -  [{UpFromVsn, Instructions}, ...],
      -  [{DownToVsn, Instructions}, ...]}.
      • Vsn = string() - Current application version.

      • UpFromVsn = string() | binary() - An earlier application version to +following syntax:

        {Vsn,
        +  [{UpFromVsn, Instructions}, ...],
        +  [{DownToVsn, Instructions}, ...]}.
        • Vsn = string() - Current application version.

        • UpFromVsn = string() | binary() - An earlier application version to upgrade from. If it is a string, it is interpreted as a specific version number. If it is a binary, it is interpreted as a regular expression that can match multiple version numbers.

        • DownToVsn = string() | binary() - An earlier application version to @@ -221,21 +221,21 @@

          version. For static modules, the new version is loaded before the process is asked to change code, both in the case of upgrading and downgrading. Callback modules are dynamic.

        update with argument supervisor is used when changing the start -specification of a supervisor.

        {load_module, Mod}
        -{load_module, Mod, DepMods}
        -{load_module, Mod, PrePurge, PostPurge, DepMods}
        -  Mod = atom()
        +specification of a supervisor.

        {load_module, Mod}
        +{load_module, Mod, DepMods}
        +{load_module, Mod, PrePurge, PostPurge, DepMods}
        +  Mod = atom()
           PrePurge = PostPurge = soft_purge | brutal_purge
        -  DepMods = [Mod]

        Simple code replacement of the module Mod.

        For a description of PrePurge and PostPurge, see update above.

        DepMods defaults to [] and defines which other modules Mod is dependent + DepMods = [Mod]

        Simple code replacement of the module Mod.

        For a description of PrePurge and PostPurge, see update above.

        DepMods defaults to [] and defines which other modules Mod is dependent on. In the relup file, instructions for loading these modules come before the -instruction for loading Mod when upgrading, and conversely when downgrading.

        {add_module, Mod}
        -{add_module, Mod, DepMods}
        -  Mod = atom()
        -  DepMods = [Mod]

        Loads a new module Mod.

        DepMods defaults to [] and defines which other modules Mod is dependent +instruction for loading Mod when upgrading, and conversely when downgrading.

        {add_module, Mod}
        +{add_module, Mod, DepMods}
        +  Mod = atom()
        +  DepMods = [Mod]

        Loads a new module Mod.

        DepMods defaults to [] and defines which other modules Mod is dependent on. In the relup file, instructions related to these modules come before the -instruction for loading Mod when upgrading, and conversely when downgrading.

        {delete_module, Mod}
        -{delete_module, Mod, DepMods}
        -  Mod = atom()

        Deletes a module Mod using the low-level instructions remove and purge.

        DepMods defaults to [] and defines which other modules Mod is dependent +instruction for loading Mod when upgrading, and conversely when downgrading.

        {delete_module, Mod}
        +{delete_module, Mod, DepMods}
        +  Mod = atom()

        Deletes a module Mod using the low-level instructions remove and purge.

        DepMods defaults to [] and defines which other modules Mod is dependent on. In the relup file, instructions related to these modules come before the instruction for removing Mod when upgrading, and conversely when downgrading.

        {add_application, Application}
         {add_application, Application, Type}
        @@ -262,9 +262,9 @@ 

        Low-Level Instructions

        -
        {load_object_code, {App, Vsn, [Mod]}}
        -  App = Mod = atom()
        -  Vsn = string()

        Reads each Mod from directory App-Vsn/ebin as a binary. It does not load the +

        {load_object_code, {App, Vsn, [Mod]}}
        +  App = Mod = atom()
        +  Vsn = string()

        Reads each Mod from directory App-Vsn/ebin as a binary. It does not load the modules. The instruction is to be placed first in the script to read all new code from the file to make the suspend-load-resume cycle less time-consuming.

        point_of_no_return

        If a crash occurs after this instruction, the system cannot recover and is restarted from the old release version. The instruction must only occur once in @@ -278,38 +278,38 @@

        PrePurge = PostPurge = soft_purge | brutal_purge

        Makes the current version of Mod old. PrePurge is ignored. For a description of PostPurge, see the high-level instruction update earlier.

        {purge, [Mod]}
           Mod = atom()

        Purges each module Mod, that is, removes the old code. Notice that any process -executing purged code is killed.

        {suspend, [Mod | {Mod, Timeout}]}
        -  Mod = atom()
        -  Timeout = int()>0 | default | infinity

        Tries to suspend all processes using a module Mod. If a process does not +executing purged code is killed.

        {suspend, [Mod | {Mod, Timeout}]}
        +  Mod = atom()
        +  Timeout = int()>0 | default | infinity

        Tries to suspend all processes using a module Mod. If a process does not respond, it is ignored. This can cause the process to die, either because it crashes when it spontaneously switches to new code, or as a result of a purge operation. If no Timeout is specified or default is specified, the default value for sys:suspend is used.

        {resume, [Mod]}
        -  Mod = atom()

        Resumes all suspended processes using a module Mod.

        {code_change, [{Mod, Extra}]}
        -{code_change, Mode, [{Mod, Extra}]}
        -  Mod = atom()
        +  Mod = atom()

        Resumes all suspended processes using a module Mod.

        {code_change, [{Mod, Extra}]}
        +{code_change, Mode, [{Mod, Extra}]}
        +  Mod = atom()
           Mode = up | down
        -  Extra = term()

        Mode defaults to up and specifies if it is an upgrade or downgrade. This + Extra = term()

    Mode defaults to up and specifies if it is an upgrade or downgrade. This instruction sends a code_change system message to all processes using a module Mod by calling function sys:change_code, passing term Extra as argument.

    {stop, [Mod]}
       Mod = atom()

    Stops all processes using a module Mod by calling supervisor:terminate_child/2. This instruction is useful when the simplest way -to change code is to stop and restart the processes that run the code.

    {start, [Mod]}
    -  Mod = atom()

    Starts all stopped processes using a module Mod by calling -supervisor:restart_child/2.

    {sync_nodes, Id, [Node]}
    -{sync_nodes, Id, {M, F, A}}
    -  Id = term()
    -  Node = node()
    -  M = F = atom()
    -  A = [term()]

    apply(M, F, A) must return a list of nodes.

    This instruction synchronizes the release installation with other nodes. Each +to change code is to stop and restart the processes that run the code.

    {start, [Mod]}
    +  Mod = atom()

    Starts all stopped processes using a module Mod by calling +supervisor:restart_child/2.

    {sync_nodes, Id, [Node]}
    +{sync_nodes, Id, {M, F, A}}
    +  Id = term()
    +  Node = node()
    +  M = F = atom()
    +  A = [term()]

    apply(M, F, A) must return a list of nodes.

    This instruction synchronizes the release installation with other nodes. Each Node must evaluate this command with the same Id. The local node waits for all other nodes to evaluate the instruction before execution continues. If a node goes down, it is considered to be an unrecoverable error, and the local node is restarted from the old release. There is no time-out for this -instruction, which means that it can hang forever.

    {apply, {M, F, A}}
    -  M = F = atom()
    -  A = [term()]

    Evaluates apply(M, F, A).

    If the instruction appears before instruction point_of_no_return, a failure is +instruction, which means that it can hang forever.

    {apply, {M, F, A}}
    +  M = F = atom()
    +  A = [term()]

    Evaluates apply(M, F, A).

    If the instruction appears before instruction point_of_no_return, a failure is caught. release_handler:install_release/1 then returns {error,{'EXIT',Reason}}, unless {error,Error} is thrown or returned. Then it returns {error,Error}.

    If the instruction appears after instruction point_of_no_return and the diff --git a/prs/8803/lib/sasl-4.2.2/doc/html/error_logging.html b/prs/8803/lib/sasl-4.2.2/doc/html/error_logging.html index 49bf5dd396bd5..153ba016b6649 100644 --- a/prs/8803/lib/sasl-4.2.2/doc/html/error_logging.html +++ b/prs/8803/lib/sasl-4.2.2/doc/html/error_logging.html @@ -308,42 +308,42 @@

    Show Reports

    Use function rb:show(Number) to show details of a specific -report:

    7> rb:show(4).
    +report:

    7> rb:show(4).
     
     PROGRESS REPORT  <0.20.0>                                   1996-10-16 16:16:36
     ===============================================================================
    -supervisor                                                     {local,sasl_sup}
    +supervisor                                                     {local,sasl_sup}
     started
    -[{pid,<0.24.0>},
    -{name,release_handler},
    -{mfa,{release_handler,start_link,[]}},
    -{restart_type,permanent},
    -{shutdown,2000},
    -{child_type,worker}]
    +[{pid,<0.24.0>},
    +{name,release_handler},
    +{mfa,{release_handler,start_link,[]}},
    +{restart_type,permanent},
    +{shutdown,2000},
    +{child_type,worker}]
     
     ok
    -8> rb:show(9).
    +8> rb:show(9).
     
     CRASH REPORT  <0.24.0>                                      1996-10-16 16:16:21
     ===============================================================================
     Crashing process
     pid                                                                 <0.24.0>
     registered_name                                              release_handler
    -error_info                             {undef,{release_handler,mbj_func,[]}}
    +error_info                             {undef,{release_handler,mbj_func,[]}}
     initial_call
    -{gen,init_it,
    -[gen_server,
    +{gen,init_it,
    +[gen_server,
     <0.20.0>,
     <0.20.0>,
    -{erlang,register},
    +{erlang,register},
     release_handler,
     release_handler,
    -[],
    -[]]}
    -ancestors                                                [sasl_sup,<0.18.0>]
    -messages                                                                  []
    -links                                                    [<0.23.0>,<0.20.0>]
    -dictionary                                                                []
    +[],
    +[]]}
    +ancestors                                                [sasl_sup,<0.18.0>]
    +messages                                                                  []
    +links                                                    [<0.23.0>,<0.20.0>]
    +dictionary                                                                []
     trap_exit                                                              false
     status                                                               running
     heap_size                                                                610
    diff --git a/prs/8803/lib/sasl-4.2.2/doc/html/rel.html b/prs/8803/lib/sasl-4.2.2/doc/html/rel.html
    index 124a733cd1252..7105baa5bf3e4 100644
    --- a/prs/8803/lib/sasl-4.2.2/doc/html/rel.html
    +++ b/prs/8803/lib/sasl-4.2.2/doc/html/rel.html
    @@ -140,11 +140,11 @@ 

    File Syntax

    The release resource file is to be called Name.rel.

    The .rel file contains one single Erlang term, which is called a release -specification. The file has the following syntax:

    {release, {RelName,Vsn}, {erts, EVsn},
    -  [{Application, AppVsn} |
    -   {Application, AppVsn, Type} |
    -   {Application, AppVsn, IncApps} |
    -   {Application, AppVsn, Type, IncApps}]}.
    • RelName = string() - Release name.

    • Vsn = string() - Release version.

    • EVsn = string() - ERTS version the release is intended for.

    • Application = atom() - Name of an application included in the release.

    • AppVsn = string() - Version of an application included in the release.

    • Type = permanent | transient | temporary | load | none - Start type of +specification. The file has the following syntax:

      {release, {RelName,Vsn}, {erts, EVsn},
      +  [{Application, AppVsn} |
      +   {Application, AppVsn, Type} |
      +   {Application, AppVsn, IncApps} |
      +   {Application, AppVsn, Type, IncApps}]}.
      • RelName = string() - Release name.

      • Vsn = string() - Release version.

      • EVsn = string() - ERTS version the release is intended for.

      • Application = atom() - Name of an application included in the release.

      • AppVsn = string() - Version of an application included in the release.

      • Type = permanent | transient | temporary | load | none - Start type of an application included in the release.

        If Type = permanent | transient | temporary, the application is loaded and started in the corresponding way, see application.

        If Type = load, the application is only loaded.

        If Type = none, the application is not loaded and not started, although the code for its modules is loaded.

        Defaults to permanent

      • IncApps = [atom()] - A list of applications that are included by an diff --git a/prs/8803/lib/sasl-4.2.2/doc/html/release_handler.html b/prs/8803/lib/sasl-4.2.2/doc/html/release_handler.html index ec9a726af2f47..214a997363e85 100644 --- a/prs/8803/lib/sasl-4.2.2/doc/html/release_handler.html +++ b/prs/8803/lib/sasl-4.2.2/doc/html/release_handler.html @@ -1084,8 +1084,8 @@

        install_release(Vsn, [Opt])

        create_RELEASES/4 or set_unpacked/2.

        Example:

        In the current version CurVsn of a release, the application directory of myapp is $ROOT/lib/myapp-1.0. A new version NewVsn is unpacked outside the release handler and the release handler is informed about this with a call -as follows:

        release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]).
        -=> {ok,NewVsn}

        If NewVsn is installed with option {update_paths,true}, then +as follows:

        release_handler:set_unpacked(RelFile, [{myapp,"1.0","/home/user"},...]).
        +=> {ok,NewVsn}

        If NewVsn is installed with option {update_paths,true}, then code:lib_dir(myapp) returns /home/user/myapp-1.0.

      Note

      Installing a new release can be time consuming if there are many processes in the system. The reason is that each process must be checked for references to old code before a module can be purged. This check can lead to garbage diff --git a/prs/8803/lib/sasl-4.2.2/doc/html/relup.html b/prs/8803/lib/sasl-4.2.2/doc/html/relup.html index 10759e768770d..6fcd989d902b4 100644 --- a/prs/8803/lib/sasl-4.2.2/doc/html/relup.html +++ b/prs/8803/lib/sasl-4.2.2/doc/html/relup.html @@ -143,9 +143,9 @@

      In a target system, the release upgrade file is to be located in directory $ROOT/releases/Vsn.

      The relup file contains one single Erlang term, which defines the instructions -used to upgrade the release. The file has the following syntax:

      {Vsn,
      -  [{UpFromVsn, Descr, Instructions}, ...],
      -  [{DownToVsn, Descr, Instructions}, ...]}.
      • Vsn = string() - Current release version.

      • UpFromVsn = string() - Earlier version of the release to upgrade from.

      • Descr = term() - A user-defined parameter passed from the function +used to upgrade the release. The file has the following syntax:

        {Vsn,
        +  [{UpFromVsn, Descr, Instructions}, ...],
        +  [{DownToVsn, Descr, Instructions}, ...]}.
        • Vsn = string() - Current release version.

        • UpFromVsn = string() - Earlier version of the release to upgrade from.

        • Descr = term() - A user-defined parameter passed from the function systools:make_relup/3,4. It is used in the return value of release_handler:install_release/1,2.

        • Instructions - A list of low-level release upgrade instructions, see diff --git a/prs/8803/lib/sasl-4.2.2/doc/html/sasl.epub b/prs/8803/lib/sasl-4.2.2/doc/html/sasl.epub index 086c54a5ac687..2b3f306a9c073 100644 Binary files a/prs/8803/lib/sasl-4.2.2/doc/html/sasl.epub and b/prs/8803/lib/sasl-4.2.2/doc/html/sasl.epub differ diff --git a/prs/8803/lib/sasl-4.2.2/doc/html/script.html b/prs/8803/lib/sasl-4.2.2/doc/html/script.html index b3f094ebcecc0..27d4712136b23 100644 --- a/prs/8803/lib/sasl-4.2.2/doc/html/script.html +++ b/prs/8803/lib/sasl-4.2.2/doc/html/script.html @@ -142,20 +142,20 @@

          File Syntax

          The boot script is stored in a file with extension .script. The file has the -following syntax:

          {script, {Name, Vsn},
          - [
          -  {progress, loading},
          -  {preLoaded, [Mod1, Mod2, ...]},
          -  {path, [Dir1,"$ROOT/Dir",...]}.
          -  {primLoad, [Mod1, Mod2, ...]},
          +following syntax:

          {script, {Name, Vsn},
          + [
          +  {progress, loading},
          +  {preLoaded, [Mod1, Mod2, ...]},
          +  {path, [Dir1,"$ROOT/Dir",...]}.
          +  {primLoad, [Mod1, Mod2, ...]},
             ...
          -  {kernel_load_completed},
          -  {progress, loaded},
          -  {kernelProcess, Name, {Mod, Func, Args}},
          +  {kernel_load_completed},
          +  {progress, loaded},
          +  {kernelProcess, Name, {Mod, Func, Args}},
             ...
          -  {apply, {Mod, Func, Args}},
          +  {apply, {Mod, Func, Args}},
             ...
          -  {progress, started}]}.
          • Name = string() - Defines the system name.

          • Vsn = string() - Defines the system version.

          • {progress, Term} - Sets the "progress" of the initialization program. + {progress, started}]}.

          • Name = string() - Defines the system name.

          • Vsn = string() - Defines the system version.

          • {progress, Term} - Sets the "progress" of the initialization program. The init:get_status/0 function returns the current value of the progress, which is {InternalStatus,Term}.

          • {path, [Dir]} - Dir is a string. This argument sets the load path of the system to [Dir]. The load path used to load modules is obtained from the diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmp.epub b/prs/8803/lib/snmp-5.16/doc/html/snmp.epub index 645f717526aca..faeb2c9e74719 100644 Binary files a/prs/8803/lib/snmp-5.16/doc/html/snmp.epub and b/prs/8803/lib/snmp-5.16/doc/html/snmp.epub differ diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmp.html b/prs/8803/lib/snmp-5.16/doc/html/snmp.html index 46670c0568fcc..82836f53822d7 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmp.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmp.html @@ -3343,8 +3343,8 @@

            print_version_info(Prefix)

            Utility function(s) to produce a formatted printout of the versions info -generated by the versions1 function

            This is the same as doing, e.g.:

                       {ok, V} = snmp:versions1(),
            -           snmp:print_versions(V).
            +generated by the versions1 function

            This is the same as doing, e.g.:

                       {ok, V} = snmp:versions1(),
            +           snmp:print_versions(V).
            @@ -3542,17 +3542,17 @@

            set_trace(Targets, TraceOpts)

            This function is used to set up trace on function(s) for the given module or modules.

            The example below sets up trace on the exported functions (default) of module snmp_generic and all functions of module snmp_generic_mnesia. With return -values (which is default) and timestamps in both cases (which is also default):

            	  snmp:enable_trace(),
            -	  snmp:set_trace([snmp_generic,
            -                          {snmp_generic_mnesia, [{scope, all_functions}]}]),
            +values (which is default) and timestamps in both cases (which is also default):

            	  snmp:enable_trace(),
            +	  snmp:set_trace([snmp_generic,
            +                          {snmp_generic_mnesia, [{scope, all_functions}]}]),
             	  .
             	  .
             	  .
            -          snmp:set_trace(snmp_generic, disable),
            +          snmp:set_trace(snmp_generic, disable),
             	  .
             	  .
             	  .
            -	  snmp:disable_trace(),
            +
            snmp:disable_trace(),
            diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmp_advanced_agent.html b/prs/8803/lib/snmp-5.16/doc/html/snmp_advanced_agent.html index bc383c07a391e..24e8e04436181 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmp_advanced_agent.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmp_advanced_agent.html @@ -329,16 +329,16 @@

            empName DisplayString, empTelNo DisplayString, empStatus RowStatus - }

    The corresponding Mnesia table is specified as follows:

    mnesia:create_table([{name, employees},
    -                     {snmp, [{key, {integer, string}}]},
    -                     {attributes, [key, telno, row_status]}]).

    Note

    In the Mnesia tables, the two key columns are stored as a tuple with two + }

    The corresponding Mnesia table is specified as follows:

    mnesia:create_table([{name, employees},
    +                     {snmp, [{key, {integer, string}}]},
    +                     {attributes, [key, telno, row_status]}]).

    Note

    In the Mnesia tables, the two key columns are stored as a tuple with two elements. Therefore, the arity of the table is 3.

    Instrumentation Functions

    -

    The MIB table shown in the previous section can be compiled as follows:

    1> snmpc:compile("EmpMIB", [{db, mnesia}]).

    This is all that has to be done! Now the manager can read, add, and modify +

    The MIB table shown in the previous section can be compiled as follows:

    1> snmpc:compile("EmpMIB", [{db, mnesia}]).

    This is all that has to be done! Now the manager can read, add, and modify rows. Also, you can use the ordinary Mnesia API to access the table from your programs. The only explicit action is to create the Mnesia table, an action the user has to perform in order to create the required table schemas.

    @@ -350,11 +350,11 @@

    It is often necessary to take some specific action when a table is modified. This is accomplished with an instrumentation function. It executes some specific code when the table is set, and passes all other requests down to the -pre-defined function.

    The following example illustrates this idea:

    emp_table(set, RowIndex, Cols) ->
    -    notify_internal_resources(RowIndex, Cols),
    -    snmp_generic:table_func(set, RowIndex, Cols, {empTable, mnesia});
    -emp_table(Op, RowIndex, Cols) ->
    -    snmp_generic:table_func(Op, RowIndex, Cols, {empTable, mnesia}).

    The default instrumentation functions are defined in the module snmp_generic. +pre-defined function.

    The following example illustrates this idea:

    emp_table(set, RowIndex, Cols) ->
    +    notify_internal_resources(RowIndex, Cols),
    +    snmp_generic:table_func(set, RowIndex, Cols, {empTable, mnesia});
    +emp_table(Op, RowIndex, Cols) ->
    +    snmp_generic:table_func(Op, RowIndex, Cols, {empTable, mnesia}).

    The default instrumentation functions are defined in the module snmp_generic. Refer to the Reference Manual, section SNMP, module snmp_generic for details.

    @@ -367,28 +367,28 @@

    that the agent does not know about. This situation is handled by adding values for the internal columns in the set function.

    To illustrate this, suppose we extend our Mnesia empTable with one internal column. We create it as before, but with an arity of 4, by adding another -attribute.

    mnesia:create_table([{name, employees},
    -                     {snmp, [{key, {integer, string}}]},
    -                     {attributes, {key, telno, row_status, internal_col}}]).

    The last column is the internal column. When performing a set operation, which +attribute.

    mnesia:create_table([{name, employees},
    +                     {snmp, [{key, {integer, string}}]},
    +                     {attributes, {key, telno, row_status, internal_col}}]).

    The last column is the internal column. When performing a set operation, which creates a row, we must give a value to the internal column. The instrumentation -functions will now look as follows:

    -define(createAndGo, 4).
    --define(createAndWait, 5).
    +functions will now look as follows:

    -define(createAndGo, 4).
    +-define(createAndWait, 5).
     
    -emp_table(set, RowIndex, Cols) ->
    -  notify_internal_resources(RowIndex, Cols),
    +emp_table(set, RowIndex, Cols) ->
    +  notify_internal_resources(RowIndex, Cols),
       NewCols =
    -    case is_row_created(empTable, Cols) of
    -      true -> Cols ++ [{4, "internal"}]; % add internal column
    +    case is_row_created(empTable, Cols) of
    +      true -> Cols ++ [{4, "internal"}]; % add internal column
           false -> Cols                      % keep original cols
       end,
    -  snmp_generic:table_func(set, RowIndex, NewCols, {empTable, mnesia});
    -emp_table(Op, RowIndex, Cols) ->
    -  snmp_generic:table_func(Op, RowIndex, Cols, {empTable, mnesia}).
    -
    -is_row_created(Name, Cols) ->
    -  case snmp_generic:get_status_col(Name, Cols) of
    -    {ok, ?createAndGo} -> true;
    -    {ok, ?createAndWait} -> true;
    +  snmp_generic:table_func(set, RowIndex, NewCols, {empTable, mnesia});
    +emp_table(Op, RowIndex, Cols) ->
    +  snmp_generic:table_func(Op, RowIndex, Cols, {empTable, mnesia}).
    +
    +is_row_created(Name, Cols) ->
    +  case snmp_generic:get_status_col(Name, Cols) of
    +    {ok, ?createAndGo} -> true;
    +    {ok, ?createAndWait} -> true;
         _ -> false
       end.

    If a row is created, we always set the internal column to "internal".

    diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmp_agent_config_files.html b/prs/8803/lib/snmp-5.16/doc/html/snmp_agent_config_files.html index 24547f3974c82..b435dbcb16b52 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmp_agent_config_files.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmp_agent_config_files.html @@ -150,19 +150,19 @@

    The agent information should be stored in a file called agent.conf.

    Each entry is a tuple of size two:

    {AgentVariable, Value}.

    • AgentVariable is one of the variables in SNMP-FRAMEWORK-MIB or one of the internal variables intAgentUDPPort, which defines which UDP port the agent listens to, or intAgentTransports, which defines the transport domains and -addresses of the agent.
    • Value is the value for the variable.

    The following example shows an agent.conf file:

    {intAgentUDPPort, 4000}.
    -{intAgentTransports,
    - [{transportDomainUdpIpv4, {141,213,11,24}},
    -  {transportDomainUdpIpv6, {0,0,0,0,0,0,0,1}}]}.
    -{snmpEngineID, "mbj's engine"}.
    -{snmpEngineMaxMessageSize, 484}.

    These are the supported entries and their value types:

          {snmpEngine,               string()}.                     % Mandatory
    -      {snmpEngineMaxMessageSize, snmp_framework_mib:max_message_size()}.  % Mandatory
    -      {intAgentUDPPort,          inet:port_number()}.                      % Optional
    -      {intAgentTransports,       [snmpa_conf:intAgentTransport()]}.   % Mandatory

    If a "traditional" transport is specified (without explicit Kind, handling +addresses of the agent.

  • Value is the value for the variable.
  • The following example shows an agent.conf file:

    {intAgentUDPPort, 4000}.
    +{intAgentTransports,
    + [{transportDomainUdpIpv4, {141,213,11,24}},
    +  {transportDomainUdpIpv6, {0,0,0,0,0,0,0,1}}]}.
    +{snmpEngineID, "mbj's engine"}.
    +{snmpEngineMaxMessageSize, 484}.

    These are the supported entries and their value types:

          {snmpEngine,               string()}.                     % Mandatory
    +      {snmpEngineMaxMessageSize, snmp_framework_mib:max_message_size()}.  % Mandatory
    +      {intAgentUDPPort,          inet:port_number()}.                      % Optional
    +      {intAgentTransports,       [snmpa_conf:intAgentTransport()]}.   % Mandatory

    If a "traditional" transport is specified (without explicit Kind, handling both requests and traps) for a transport domain, its not possible to also specify a transport (for that domain) with a specific Kind. This is for -example, not allowed:

     [{transportDomainUdpIpv4, {{141,213,11,24}, 4000}},
    -  {transportDomainUdpIpv4, {{141,213,11,24}, 4001}, trap_sender}].

    Note that only one transport per kind for each transport domain can be +example, not allowed:

     [{transportDomainUdpIpv4, {{141,213,11,24}, 4000}},
    +  {transportDomainUdpIpv4, {{141,213,11,24}, 4001}, trap_sender}].

    Note that only one transport per kind for each transport domain can be configured.

    PortInfo system is used to indicate that the 'system' should choose (the way port number '0' (zero) is normally used). Port info '0' (zero) cannot be used for this, since it is (internally) used to represent the 'default' port number.

    In the traditional transport entries, when the Addr value does not contain a @@ -188,12 +188,12 @@

    System Information

    The system information should be stored in a file called standard.conf.

    Each entry is a tuple of size two:

    {SystemVariable, Value}.

    • SystemVariable is one of the variables in the system group, or -snmpEnableAuthenTraps.
    • Value is the value for the variable.

    The following example shows a valid standard.conf file:

    {sysDescr, "Erlang SNMP agent"}.
    -{sysObjectID, [1,2,3]}.
    -{sysContact, "(mbj,eklas)@erlang.ericsson.se"}.
    -{sysName, "test"}.
    -{sysServices, 72}.
    -{snmpEnableAuthenTraps, enabled}.

    A value must be provided for all variables, which lack default values in the +snmpEnableAuthenTraps.

  • Value is the value for the variable.
  • The following example shows a valid standard.conf file:

    {sysDescr, "Erlang SNMP agent"}.
    +{sysObjectID, [1,2,3]}.
    +{sysContact, "(mbj,eklas)@erlang.ericsson.se"}.
    +{sysName, "test"}.
    +{sysServices, 72}.
    +{snmpEnableAuthenTraps, enabled}.

    A value must be provided for all variables, which lack default values in the MIB.

    diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmp_agent_funct_descr.html b/prs/8803/lib/snmp-5.16/doc/html/snmp_agent_funct_descr.html index da0676c8e91ad..6e07372dd8f6c 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmp_agent_funct_descr.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmp_agent_funct_descr.html @@ -308,7 +308,7 @@

    MIBs are always available in all contexts.

    The ASN.1 code, the Erlang source code, and the generated .hrl files for them are provided in the distribution and are placed in the directories mibs, src, and include, respectively, in the snmp application.

    The .hrl files are generated with snmpc:mib_to_hrl/1. Include these files in -your code as in the following example:

    -include_lib("snmp/include/SNMPv2-MIB.hrl").

    The initial values for the managed objects defined in these tables, are read at +your code as in the following example:

    -include_lib("snmp/include/SNMPv2-MIB.hrl").

    The initial values for the managed objects defined in these tables, are read at start-up from a set of configuration files. These are described in Configuration Files.

    @@ -469,9 +469,9 @@

    Notifications are defined in SMIv1 with the TRAP-TYPE macro in the definition of an MIB (see RFC1215). The corresponding macro in SMIv2 is NOTIFICATION-TYPE. When an application decides to send a notification, it calls one of the -following functions:

    snmpa:send_notification(Agent, Notification, Receiver
    -                       [, NotifyName, ContextName, Varbinds])
    -snmpa:send_trap(Agent, Notification, Community [, Receiver, Varbinds])

    providing the registered name or process identifier of the agent where the MIB, +following functions:

    snmpa:send_notification(Agent, Notification, Receiver
    +                       [, NotifyName, ContextName, Varbinds])
    +snmpa:send_trap(Agent, Notification, Community [, Receiver, Varbinds])

    providing the registered name or process identifier of the agent where the MIB, which defines the notification is loaded and the symbolic name of the notification.

    If the send_notification/3,4 function is used, all management targets are selected, as defined in RFC2273. The Receiver parameter defines where the diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmp_app.html b/prs/8803/lib/snmp-5.16/doc/html/snmp_app.html index 2217a0be6b09a..8d966d3a97d79 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmp_app.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmp_app.html @@ -140,51 +140,51 @@

    The following configuration parameters are defined for the SNMP application. Refer to application(3) for more information about configuration parameters.

    The snmp part of the config file specifying the configuration parameters is -basically the following tuple:

          {snmp, snmp_components_config()}

    A minimal config file for starting a node with both a manager and an agent:

          [{snmp,
    -        [{agent, [{db_dir, "/tmp/snmp/agent/db"},
    -                  {config, [{dir, "/tmp/snmp/agent/conf"}]}]},
    -         {manager, [{config, [{dir, "/tmp/snmp/manager/conf"},
    -                              {db_dir, "/tmp/snmp/manager/db"}]}]}]}
    -        ]
    +basically the following tuple:

          {snmp, snmp_components_config()}

    A minimal config file for starting a node with both a manager and an agent:

          [{snmp,
    +        [{agent, [{db_dir, "/tmp/snmp/agent/db"},
    +                  {config, [{dir, "/tmp/snmp/agent/conf"}]}]},
    +         {manager, [{config, [{dir, "/tmp/snmp/manager/conf"},
    +                              {db_dir, "/tmp/snmp/manager/db"}]}]}]}
    +        ]
            }
           ].

    Each snmp component has its own set of configuration parameters, even though -some of the types are common to both components.

          snmp_components_config() -> [snmp_component_config()]
    -      snmp_component_config() -> {agent, agent_options()} | {manager, manager_options()}
    -      agent_options() = [agent_option()]
    -      agent_option() = {restart_type,     restart_type()}     |
    -                       {agent_type,       agent_type()}       |
    -                       {agent_verbosity,  verbosity()}        |
    -                       {discovery,        agent_discovery()}  |
    -                       {versions,         versions()}         |
    -                       {gb_max_vbs,       gb_max_vbs()}       |
    -                       {priority,         priority()}         |
    -                       {multi_threaded,   multi_threaded()}   |
    -                       {db_dir,           db_dir()}           |
    -                       {db_init_error,    db_init_error()}    |
    -                       {local_db,         local_db()}         |
    -                       {net_if,           agent_net_if()}     |
    -                       {mibs,             mibs()}             |
    -                       {mib_storage,      mib_storage()}      |
    -                       {mib_server,       mib_server()}       |
    -                       {audit_trail_log,  audit_trail_log()}  |
    -                       {error_report_mod, error_report_mod()} |
    -                       {note_store,       note_store()}       |
    -                       {symbolic_store,   symbolic_store()}   |
    -                       {target_cache,     target_cache()}     |
    -                       {config,           agent_config()}
    -      manager_options() = [manager_option()]
    -      manager_option() = {restart_type,             restart_type()}    |
    -                         {net_if,                   manager_net_if()}  |
    -                         {server,                   server()}          |
    -                         {note_store,               note_store()}      |
    -                         {config,                   manager_config()}  |
    -                         {inform_request_behaviour, manager_irb()}     |
    -                         {mibs,                     manager_mibs()}    |
    -                         {priority,                 priority()}        |
    -                         {audit_trail_log,          audit_trail_log()} |
    -                         {versions,                 versions()}        |
    -                         {def_user_mod,             def_user_module()  |
    -                         {def_user_data,            def_user_data()}

    Agent specific config options and types:

    • agent_type() = master | sub <optional> - If master, +some of the types are common to both components.

            snmp_components_config() -> [snmp_component_config()]
      +      snmp_component_config() -> {agent, agent_options()} | {manager, manager_options()}
      +      agent_options() = [agent_option()]
      +      agent_option() = {restart_type,     restart_type()}     |
      +                       {agent_type,       agent_type()}       |
      +                       {agent_verbosity,  verbosity()}        |
      +                       {discovery,        agent_discovery()}  |
      +                       {versions,         versions()}         |
      +                       {gb_max_vbs,       gb_max_vbs()}       |
      +                       {priority,         priority()}         |
      +                       {multi_threaded,   multi_threaded()}   |
      +                       {db_dir,           db_dir()}           |
      +                       {db_init_error,    db_init_error()}    |
      +                       {local_db,         local_db()}         |
      +                       {net_if,           agent_net_if()}     |
      +                       {mibs,             mibs()}             |
      +                       {mib_storage,      mib_storage()}      |
      +                       {mib_server,       mib_server()}       |
      +                       {audit_trail_log,  audit_trail_log()}  |
      +                       {error_report_mod, error_report_mod()} |
      +                       {note_store,       note_store()}       |
      +                       {symbolic_store,   symbolic_store()}   |
      +                       {target_cache,     target_cache()}     |
      +                       {config,           agent_config()}
      +      manager_options() = [manager_option()]
      +      manager_option() = {restart_type,             restart_type()}    |
      +                         {net_if,                   manager_net_if()}  |
      +                         {server,                   server()}          |
      +                         {note_store,               note_store()}      |
      +                         {config,                   manager_config()}  |
      +                         {inform_request_behaviour, manager_irb()}     |
      +                         {mibs,                     manager_mibs()}    |
      +                         {priority,                 priority()}        |
      +                         {audit_trail_log,          audit_trail_log()} |
      +                         {versions,                 versions()}        |
      +                         {def_user_mod,             def_user_module()  |
      +                         {def_user_data,            def_user_data()}

      Agent specific config options and types:

      • agent_type() = master | sub <optional> - If master, one master agent is started. Otherwise, no agents are started.

        Default is master.

      • agent_discovery() = [agent_discovery_opt()] <optional> - agent_discovery_opt() = {terminating, agent_terminating_discovery_opts()} | {originating, agent_originating_discovery_opts()}

        The terminating options effects discovery initiated by a manager.

        The originating options effects discovery initiated by this agent.

        For defaults see the options in agent_discovery_opt().

      • agent_terminating_discovery_opts() = [agent_terminating_discovery_opt()] <optional> - agent_terminating_discovery_opt() = {enable, boolean()} | {stage2, discovery | plain} | {trigger_username, string()}

        These are options effecting discovery terminating in this agent (i.e. diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmp_app_b.html b/prs/8803/lib/snmp-5.16/doc/html/snmp_app_b.html index 244cc5814049f..cd3c5f24a1ddb 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmp_app_b.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmp_app_b.html @@ -586,23 +586,23 @@

        immediately removed." - SYNTAX INTEGER { + SYNTAX INTEGER { -- the following two values are states: -- these values may be read or written - active(1), - notInService(2), + active(1), + notInService(2), -- the following value is a state: -- this value may be read, but not written - notReady(3), + notReady(3), -- the following three values are -- actions: these values may be written, -- but are never read - createAndGo(4), - createAndWait(5), - destroy(6) - }

    + createAndGo(4), + createAndWait(5), + destroy(6) + }

    diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmp_config.html b/prs/8803/lib/snmp-5.16/doc/html/snmp_config.html index 8721109165e74..755b205c10127 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmp_config.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmp_config.html @@ -145,41 +145,41 @@

    more information).
  • the database directory stores the internal database files.
  • The agent and manager uses (application) configuration parameters to find out where these directories are located. The parameters should be defined in an Erlang system configuration file. The following configuration parameters are -defined for the SNMP application:

          agent_options() = [agent_option()]
    -      agent_option() = {restart_type,     restart_type()}     |
    -                       {agent_type,       agent_type()}       |
    -                       {agent_verbosity,  verbosity()}        |
    -                       {versions,         versions()}         |
    -                       {discovery,        agent_discovery()}  |
    -                       {gb_max_vbs,       gb_max_vbs()}       |
    -                       {priority,         priority()}         |
    -                       {multi_threaded,   multi_threaded()}   |
    -                       {db_dir,           db_dir()}           |
    -                       {db_init_error,    db_init_error()}    |
    -                       {local_db,         local_db()}         |
    -                       {net_if,           agent_net_if()}     |
    -                       {mibs,             mibs()}             |
    -                       {mib_storage,      mib_storage()}      |
    -                       {mib_server,       mib_server()}       |
    -                       {audit_trail_log,  audit_trail_log()}  |
    -                       {error_report_mod, error_report_mod()} |
    -                       {note_store,       note_store()}       |
    -                       {symbolic_store,   symbolic_store()}   |
    -                       {target_cache,     target_cache()}     |
    -                       {config,           agent_config()}
    -      manager_options() = [manager_option()]
    -      manager_option() = {restart_type,             restart_type()}    |
    -                         {net_if,                   manager_net_if()}  |
    -                         {server,                   server()}          |
    -                         {note_store,               note_store()}      |
    -                         {config,                   manager_config()}  |
    -                         {inform_request_behaviour, manager_irb()}     |
    -                         {mibs,                     manager_mibs()}    |
    -                         {priority,                 priority()}        |
    -                         {audit_trail_log,          audit_trail_log()} |
    -                         {versions,                 versions()}        |
    -                         {def_user_mod,             def_user_module()  |
    -                         {def_user_data,            def_user_data()}

    Agent specific config options and types:

    • agent_type() = master | sub <optional> - If master, +defined for the SNMP application:

            agent_options() = [agent_option()]
      +      agent_option() = {restart_type,     restart_type()}     |
      +                       {agent_type,       agent_type()}       |
      +                       {agent_verbosity,  verbosity()}        |
      +                       {versions,         versions()}         |
      +                       {discovery,        agent_discovery()}  |
      +                       {gb_max_vbs,       gb_max_vbs()}       |
      +                       {priority,         priority()}         |
      +                       {multi_threaded,   multi_threaded()}   |
      +                       {db_dir,           db_dir()}           |
      +                       {db_init_error,    db_init_error()}    |
      +                       {local_db,         local_db()}         |
      +                       {net_if,           agent_net_if()}     |
      +                       {mibs,             mibs()}             |
      +                       {mib_storage,      mib_storage()}      |
      +                       {mib_server,       mib_server()}       |
      +                       {audit_trail_log,  audit_trail_log()}  |
      +                       {error_report_mod, error_report_mod()} |
      +                       {note_store,       note_store()}       |
      +                       {symbolic_store,   symbolic_store()}   |
      +                       {target_cache,     target_cache()}     |
      +                       {config,           agent_config()}
      +      manager_options() = [manager_option()]
      +      manager_option() = {restart_type,             restart_type()}    |
      +                         {net_if,                   manager_net_if()}  |
      +                         {server,                   server()}          |
      +                         {note_store,               note_store()}      |
      +                         {config,                   manager_config()}  |
      +                         {inform_request_behaviour, manager_irb()}     |
      +                         {mibs,                     manager_mibs()}    |
      +                         {priority,                 priority()}        |
      +                         {audit_trail_log,          audit_trail_log()} |
      +                         {versions,                 versions()}        |
      +                         {def_user_mod,             def_user_module()  |
      +                         {def_user_data,            def_user_data()}

      Agent specific config options and types:

      • agent_type() = master | sub <optional> - If master, one master agent is started. Otherwise, no agents are started.

        Default is master.

      • agent_discovery() = [agent_discovery_opt()] <optional> - agent_discovery_opt() = {terminating, agent_terminating_discovery_opts()} | {originating, agent_originating_discovery_opts()}

        The terminating options effects discovery initiated by a manager.

        The originating options effects discovery initiated by this agent.

        For defaults see the options in agent_discovery_opt().

      • agent_terminating_discovery_opts() = [agent_terminating_discovery_opt()] <optional> - agent_terminating_discovery_opt() = {enable, boolean()} | {stage2, discovery | plain} | {trigger_username, string()}

        These are options effecting discovery terminating in this agent (i.e. @@ -556,34 +556,34 @@

        configuration parameters. The verbosity itself has several _levels: silence | info | log | debug | trace. For the lowest verbosity silence, nothing is printed. The higher the verbosity, the -more is printed. Default value is always silence.

        3> snmpa:verbosity(master_agent, log).
        +more is printed. Default value is always silence.

        3> snmpa:verbosity(master_agent, log).
         ok
        -5> snmpa:verbosity(net_if, log).
        +5> snmpa:verbosity(net_if, log).
         ok
         6>
         %% Example of output from the agent when a get-next-request arrives:
         ** SNMP NET-IF LOG:
        -   got packet from {147,12,12,12}:5000
        +   got packet from {147,12,12,12}:5000
         
         ** SNMP NET-IF MPD LOG:
            v1, community: all-rights
         
         ** SNMP NET-IF LOG:
        -   got pdu from {147,12,12,12}:5000 {pdu, 'get-next-request',
        +   got pdu from {147,12,12,12}:5000 {pdu, 'get-next-request',
                                                   62612569,noError,0,
        -                                          [{varbind,[1,1],'NULL','NULL',1}]}
        +                                          [{varbind,[1,1],'NULL','NULL',1}]}
         
         ** SNMP MASTER-AGENT LOG:
        -   apply: snmp_generic,variable_func,[get,{sysDescr,persistent}]
        +   apply: snmp_generic,variable_func,[get,{sysDescr,persistent}]
         
         ** SNMP MASTER-AGENT LOG:
        -   returned: {value,"Erlang SNMP agent"}
        +   returned: {value,"Erlang SNMP agent"}
         
         ** SNMP NET-IF LOG:
        -   reply pdu: {pdu,'get-response',62612569,noError,0,
        -                   [{varbind,[1,3,6,1,2,1,1,1,0],
        +   reply pdu: {pdu,'get-response',62612569,noError,0,
        +                   [{varbind,[1,3,6,1,2,1,1,1,0],
                                      'OCTET STRING',
        -                             "Erlang SNMP agent",1}]}
        +                             "Erlang SNMP agent",1}]}
         
         ** SNMP NET-IF INFO: time in agent: 19711 mysec

        Other useful function(s) for debugging the agent are:

        • snmpa:info/0,1 - info is used to retrieve a list of miscellaneous agent information.

        • snmpa:which_aliasnames/0 - diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmp_generic.html b/prs/8803/lib/snmp-5.16/doc/html/snmp_generic.html index dcbaa68fdfa3b..8e2e534939c6c 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmp_generic.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmp_generic.html @@ -140,9 +140,9 @@

          | MIB | +---------------+ | - Association file (associates a MIB object with + Association file (associates a MIB object with | snmp_generic:table_funct - | snmp_generic:variable_func) + | snmp_generic:variable_func) +--------------------------------------+ | snmp_generic | Support for get-next, | | RowStatus operations @@ -150,7 +150,7 @@

          | snmpa_local_db | Mnesia | Database +--------------+-------+---------------+ | dets | ets | -| (persistent) | | +| (persistent) | | +--------------+-------+

        Each function takes the argument NameDb, which is a tuple {Name, Db}, to identify which database the functions should use. Name is the symbolic name of the managed object as defined in the MIB, and Db is either volatile, @@ -162,41 +162,41 @@

        this. Specifically, if variables are stored in Mnesia, the table snmp_variables must be created by the programmer. The record definition for this table is defined in the file snmp/include/snmp_types.hrl.

        If an instrumentation function in the association file for a variable myVar -does not have a name when compiling an MIB, the compiler generates an entry.

        {myVar, {snmp_generic, variable_func, [{myVar, Db]}}.

        And for a table:

        {myTable, {snmp_generic, table_func, [{myTable, Db]}}.

        +does not have a name when compiling an MIB, the compiler generates an entry.

        {myVar, {snmp_generic, variable_func, [{myVar, Db]}}.

        And for a table:

        {myTable, {snmp_generic, table_func, [{myTable, Db]}}.

        Example

        The following example shows an implementation of a table which is stored in -Mnesia, but with some checks performed at set-request operations.

        myTable_func(new, NameDb) ->   % pass unchanged
        -  snmp_generic:table_func(new, NameDb).
        +Mnesia, but with some checks performed at set-request operations.

        myTable_func(new, NameDb) ->   % pass unchanged
        +  snmp_generic:table_func(new, NameDb).
         
        -myTable_func(delete, NameDb) ->   % pass unchanged
        -  snmp_generic:table_func(delete, NameDb).
        +myTable_func(delete, NameDb) ->   % pass unchanged
        +  snmp_generic:table_func(delete, NameDb).
         
         %% change row
        -myTable_func(is_set_ok, RowIndex, Cols, NameDb) ->
        -  case snmp_generic:table_func(is_set_ok, RowIndex,
        -                               Cols, NameDb) of
        -    {noError, 0} ->
        -      myApplication:is_set_ok(RowIndex, Cols);
        +myTable_func(is_set_ok, RowIndex, Cols, NameDb) ->
        +  case snmp_generic:table_func(is_set_ok, RowIndex,
        +                               Cols, NameDb) of
        +    {noError, 0} ->
        +      myApplication:is_set_ok(RowIndex, Cols);
             Err ->
               Err
           end;
         
        -myTable_func(set, RowIndex, Cols, NameDb) ->
        -  case snmp_generic:table_func(set, RowIndex, Cols,
        -                               NameDb),
        -    {noError, 0} ->
        +myTable_func(set, RowIndex, Cols, NameDb) ->
        +  case snmp_generic:table_func(set, RowIndex, Cols,
        +                               NameDb),
        +    {noError, 0} ->
               % Now the row is updated, tell the application
        -      myApplication:update(RowIndex, Cols);
        +      myApplication:update(RowIndex, Cols);
             Err ->
               Err
           end;
         
        -myTable_func(Op, RowIndex, Cols, NameDb) ->   % pass unchanged
        -  snmp_generic:table_func(Op, RowIndex, Cols, NameDb).

        The .funcs file would look like:

        {myTable, {myModule, myTable_func, [{myTable, mnesia}]}}.
        +
        myTable_func(Op, RowIndex, Cols, NameDb) -> % pass unchanged + snmp_generic:table_func(Op, RowIndex, Cols, NameDb).

        The .funcs file would look like:

        {myTable, {myModule, myTable_func, [{myTable, mnesia}]}}.

    diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmp_impl_example_agent.html b/prs/8803/lib/snmp-5.16/doc/html/snmp_impl_example_agent.html index 556bdc35a91b4..24ffa94377e71 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmp_impl_example_agent.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmp_impl_example_agent.html @@ -230,54 +230,54 @@

    the default implementation of it. Recall that MIBs imported by "EX1-MIB.mib" must be present and compiled in the current directory ("./STANDARD-MIB.bin","./RFC1213-MIB.bin") when compiling.

    unix> erl -config ./sys
    -1> application:start(snmp).
    +1> application:start(snmp).
     ok
    -2> snmpc:compile("EX1-MIB").
    +2> snmpc:compile("EX1-MIB").
     No accessfunction for 'friendsTable', using default.
     No accessfunction for 'myName', using default.
    -{ok, "EX1-MIB.bin"}
    -3> snmpa:load_mibs(snmp_master_agent, ["EX1-MIB"]).
    +{ok, "EX1-MIB.bin"}
    +3> snmpa:load_mibs(snmp_master_agent, ["EX1-MIB"]).
     ok

    This MIB is now loaded into the agent, and a manager can ask questions. As an example of this, we start another Erlang system and the simple Erlang manager in -the toolkit:

    1> snmp_test_mgr:start_link([{agent,"dront.ericsson.se"},{community,"all-rights"},
    +the toolkit:

    1> snmp_test_mgr:start_link([{agent,"dront.ericsson.se"},{community,"all-rights"},
      %% making it understand symbolic names: {mibs,["EX1-MIB","STANDARD-MIB"]}]).
    -{ok, <0.89.0>}
    +{ok, <0.89.0>}
     %% a get-next request with one OID.
    -2> snmp_test_mgr:gn([[1,3,6,1,3,7]]).
    +2> snmp_test_mgr:gn([[1,3,6,1,3,7]]).
     ok
     * Got PDU:
    -[myName,0] = []
    +[myName,0] = []
     %% A set-request (now using symbolic names for convenience)
    -3> snmp_test_mgr:s([{[myName,0], "Martin"}]).
    +3> snmp_test_mgr:s([{[myName,0], "Martin"}]).
     ok
     * Got PDU:
    -[myName,0] = "Martin"
    +[myName,0] = "Martin"
     %% Try the same get-next request again
    -4> snmp_test_mgr:gn([[1,3,6,1,3,7]]).
    +4> snmp_test_mgr:gn([[1,3,6,1,3,7]]).
     ok
     * Got PDU:
    -[myName,0] = "Martin"
    +[myName,0] = "Martin"
     %% ... and we got the new value.
     %% you can event do row operations. How to add a row:
    -5> snmp_test_mgr:s([{[fName,0], "Martin"}, {[fAddress,0],"home"}, {[fStatus,0],4}]).
    +5> snmp_test_mgr:s([{[fName,0], "Martin"}, {[fAddress,0],"home"}, {[fStatus,0],4}]).
      %% createAndGo
     ok
     * Got PDU:
    -[fName,0] = "Martin"
    -[fAddress,0] = "home"
    -[fStatus,0] = 4
    -6> snmp_test_mgr:gn([[myName,0]]).
    +[fName,0] = "Martin"
    +[fAddress,0] = "home"
    +[fStatus,0] = 4
    +6> snmp_test_mgr:gn([[myName,0]]).
     ok
     * Got PDU:
    -[fName,0] = "Martin"
    -7> snmp_test_mgr:gn().
    +[fName,0] = "Martin"
    +7> snmp_test_mgr:gn().
     ok
     * Got PDU:
    -[fAddress,0] = "home"
    -8> snmp_test_mgr:gn().
    +[fAddress,0] = "home"
    +8> snmp_test_mgr:gn().
     ok
     * Got PDU:
    -[fStatus,0] = 1
    +[fStatus,0] = 1
     9>

    @@ -295,55 +295,55 @@

    Code

    -
    -module(ex1).
    --author('dummy@flop.org').
    +
    -module(ex1).
    +-author('dummy@flop.org').
     %% External exports
    --export([start/0, my_name/1, my_name/2, friends_table/3]).
    +-export([start/0, my_name/1, my_name/2, friends_table/3]).
     %% Internal exports
    --export([init/0]).
    --define(status_col, 4).
    --define(active, 1).
    --define(notInService, 2).
    --define(notReady, 3).
    --define(createAndGo, 4).   % Action; written, not read
    --define(createAndWait, 5). % Action; written, not read
    --define(destroy, 6).       % Action; written, not read
    -start() ->
    -    spawn(ex1, init, []).
    +-export([init/0]).
    +-define(status_col, 4).
    +-define(active, 1).
    +-define(notInService, 2).
    +-define(notReady, 3).
    +-define(createAndGo, 4).   % Action; written, not read
    +-define(createAndWait, 5). % Action; written, not read
    +-define(destroy, 6).       % Action; written, not read
    +start() ->
    +    spawn(ex1, init, []).
     %%----------------------------------------------------------------
     %% Instrumentation function for variable myName.
     %% Returns: (get) {value, Name}
     %%          (set) noError
     %%----------------------------------------------------------------
    -my_name(get) ->
    -    ex1_server ! {self(), get_my_name},
    -    Name = wait_answer(),
    -    {value, Name}.
    -my_name(set, NewName) ->
    -    ex1_server ! {self(), {set_my_name, NewName}},
    +my_name(get) ->
    +    ex1_server ! {self(), get_my_name},
    +    Name = wait_answer(),
    +    {value, Name}.
    +my_name(set, NewName) ->
    +    ex1_server ! {self(), {set_my_name, NewName}},
         noError.
     %%----------------------------------------------------------------
     %% Instrumentation function for table friendsTable.
     %%----------------------------------------------------------------
    -friends_table(get, RowIndex, Cols) ->
    -    case get_row(RowIndex) of
    -   {ok, Row} ->
    -        get_cols(Cols, Row);
    +friends_table(get, RowIndex, Cols) ->
    +    case get_row(RowIndex) of
    +   {ok, Row} ->
    +        get_cols(Cols, Row);
        _  ->
    -        {noValue, noSuchInstance}
    +        {noValue, noSuchInstance}
         end;
    -friends_table(get_next, RowIndex, Cols) ->
    -    case get_next_row(RowIndex) of
    -   {ok, Row} ->
    -        get_next_cols(Cols, Row);
    +friends_table(get_next, RowIndex, Cols) ->
    +    case get_next_row(RowIndex) of
    +   {ok, Row} ->
    +        get_next_cols(Cols, Row);
        _  ->
    -       case get_next_row([]) of
    -     {ok, Row} ->
    +       case get_next_row([]) of
    +     {ok, Row} ->
              % Get next cols from first row.
    -         NewCols = add_one_to_cols(Cols),
    -         get_next_cols(NewCols, Row);
    +         NewCols = add_one_to_cols(Cols),
    +         get_next_cols(NewCols, Row);
          _  ->
    -        end_of_table(Cols)
    +        end_of_table(Cols)
             end
         end;
     %%----------------------------------------------------------------
    @@ -354,158 +354,158 @@ 

    %% *) Otherwise, error (for simplicity). %% Otherwise, row is modified; check that row exists. %%---------------------------------------------------------------- -friends_table(is_set_ok, RowIndex, Cols) -> +friends_table(is_set_ok, RowIndex, Cols) -> RowExists = - case get_row(RowIndex) of - {ok, _Row} -> true; + case get_row(RowIndex) of + {ok, _Row} -> true; _ -> false end, - case is_row_status_col_changed(Cols) of - {true, ?destroy} when RowExists == true -> - {noError, 0}; - {true, ?createAndGo} when RowExists == false, - length(Cols) == 3 -> - {noError, 0}; - {true, _} -> - {inconsistentValue, ?status_col}; + case is_row_status_col_changed(Cols) of + {true, ?destroy} when RowExists == true -> + {noError, 0}; + {true, ?createAndGo} when RowExists == false, + length(Cols) == 3 -> + {noError, 0}; + {true, _} -> + {inconsistentValue, ?status_col}; false when RowExists == true -> - {noError, 0}; + {noError, 0}; _ -> - [{Col, _NewVal} | _Cols] = Cols, - {inconsistentName, Col} + [{Col, _NewVal} | _Cols] = Cols, + {inconsistentName, Col} end; -friends_table(set, RowIndex, Cols) -> - case is_row_status_col_changed(Cols) of - {true, ?destroy} -> - ex1_server ! {self(), {delete_row, RowIndex}}; - {true, ?createAndGo} -> - NewRow = make_row(RowIndex, Cols), - ex1_server ! {self(), {add_row, NewRow}}; +friends_table(set, RowIndex, Cols) -> + case is_row_status_col_changed(Cols) of + {true, ?destroy} -> + ex1_server ! {self(), {delete_row, RowIndex}}; + {true, ?createAndGo} -> + NewRow = make_row(RowIndex, Cols), + ex1_server ! {self(), {add_row, NewRow}}; false -> - {ok, Row} = get_row(RowIndex), - NewRow = merge_rows(Row, Cols), - ex1_server ! {self(), {delete_row, RowIndex}}, - ex1_server ! {self(), {add_row, NewRow}} + {ok, Row} = get_row(RowIndex), + NewRow = merge_rows(Row, Cols), + ex1_server ! {self(), {delete_row, RowIndex}}, + ex1_server ! {self(), {add_row, NewRow}} end, - {noError, 0}. + {noError, 0}. %%---------------------------------------------------------------- %% Make a list of {value, Val} of the Row and Cols list. %%---------------------------------------------------------------- -get_cols([Col | Cols], Row) -> - [{value, element(Col, Row)} | get_cols(Cols, Row)]; -get_cols([], _Row) -> - []. +get_cols([Col | Cols], Row) -> + [{value, element(Col, Row)} | get_cols(Cols, Row)]; +get_cols([], _Row) -> + []. %%---------------------------------------------------------------- %% As get_cols, but the Cols list may contain invalid column %% numbers. If it does, we must find the next valid column, %% or return endOfTable. %%---------------------------------------------------------------- -get_next_cols([Col | Cols], Row) when Col < 2 -> - [{[2, element(1, Row)], element(2, Row)} | - get_next_cols(Cols, Row)]; -get_next_cols([Col | Cols], Row) when Col > 4 -> - [endOfTable | - get_next_cols(Cols, Row)]; -get_next_cols([Col | Cols], Row) -> - [{[Col, element(1, Row)], element(Col, Row)} | - get_next_cols(Cols, Row)]; -get_next_cols([], _Row) -> - []. +get_next_cols([Col | Cols], Row) when Col < 2 -> + [{[2, element(1, Row)], element(2, Row)} | + get_next_cols(Cols, Row)]; +get_next_cols([Col | Cols], Row) when Col > 4 -> + [endOfTable | + get_next_cols(Cols, Row)]; +get_next_cols([Col | Cols], Row) -> + [{[Col, element(1, Row)], element(Col, Row)} | + get_next_cols(Cols, Row)]; +get_next_cols([], _Row) -> + []. %%---------------------------------------------------------------- %% Make a list of endOfTable with as many elems as Cols list. %%---------------------------------------------------------------- -end_of_table([Col | Cols]) -> - [endOfTable | end_of_table(Cols)]; -end_of_table([]) -> - []. -add_one_to_cols([Col | Cols]) -> - [Col + 1 | add_one_to_cols(Cols)]; -add_one_to_cols([]) -> - []. -is_row_status_col_changed(Cols) -> - case lists:keysearch(?status_col, 1, Cols) of - {value, {?status_col, StatusVal}} -> - {true, StatusVal}; +end_of_table([Col | Cols]) -> + [endOfTable | end_of_table(Cols)]; +end_of_table([]) -> + []. +add_one_to_cols([Col | Cols]) -> + [Col + 1 | add_one_to_cols(Cols)]; +add_one_to_cols([]) -> + []. +is_row_status_col_changed(Cols) -> + case lists:keysearch(?status_col, 1, Cols) of + {value, {?status_col, StatusVal}} -> + {true, StatusVal}; _ -> false end. -get_row(RowIndex) -> - ex1_server ! {self(), {get_row, RowIndex}}, - wait_answer(). -get_next_row(RowIndex) -> - ex1_server ! {self(), {get_next_row, RowIndex}}, - wait_answer(). -wait_answer() -> +get_row(RowIndex) -> + ex1_server ! {self(), {get_row, RowIndex}}, + wait_answer(). +get_next_row(RowIndex) -> + ex1_server ! {self(), {get_next_row, RowIndex}}, + wait_answer(). +wait_answer() -> receive - {ex1_server, Answer} -> + {ex1_server, Answer} -> Answer end. %%%--------------------------------------------------------------- %%% Server code follows %%%--------------------------------------------------------------- -init() -> - register(ex1_server, self()), - loop("", []). +init() -> + register(ex1_server, self()), + loop("", []). -loop(MyName, Table) -> +loop(MyName, Table) -> receive - {From, get_my_name} -> - From ! {ex1_server, MyName}, - loop(MyName, Table); - {From, {set_my_name, NewName}} -> - loop(NewName, Table); - {From, {get_row, RowIndex}} -> - Res = table_get_row(Table, RowIndex), - From ! {ex1_server, Res}, - loop(MyName, Table); - {From, {get_next_row, RowIndex}} -> - Res = table_get_next_row(Table, RowIndex), - From ! {ex1_server, Res}, - loop(MyName, Table); - {From, {delete_row, RowIndex}} -> - NewTable = table_delete_row(Table, RowIndex), - loop(MyName, NewTable); - {From, {add_row, NewRow}} -> - NewTable = table_add_row(Table, NewRow), - loop(MyName, NewTable) + {From, get_my_name} -> + From ! {ex1_server, MyName}, + loop(MyName, Table); + {From, {set_my_name, NewName}} -> + loop(NewName, Table); + {From, {get_row, RowIndex}} -> + Res = table_get_row(Table, RowIndex), + From ! {ex1_server, Res}, + loop(MyName, Table); + {From, {get_next_row, RowIndex}} -> + Res = table_get_next_row(Table, RowIndex), + From ! {ex1_server, Res}, + loop(MyName, Table); + {From, {delete_row, RowIndex}} -> + NewTable = table_delete_row(Table, RowIndex), + loop(MyName, NewTable); + {From, {add_row, NewRow}} -> + NewTable = table_add_row(Table, NewRow), + loop(MyName, NewTable) end. %%%--------------------------------------------------------------- %%% Functions for table operations. The table is represented as %%% a list of rows. %%%--------------------------------------------------------------- -table_get_row([{Index, Name, Address, Status} | _], [Index]) -> - {ok, {Index, Name, Address, Status}}; -table_get_row([H | T], RowIndex) -> - table_get_row(T, RowIndex); -table_get_row([], _RowIndex) -> +table_get_row([{Index, Name, Address, Status} | _], [Index]) -> + {ok, {Index, Name, Address, Status}}; +table_get_row([H | T], RowIndex) -> + table_get_row(T, RowIndex); +table_get_row([], _RowIndex) -> no_such_row. -table_get_next_row([Row | T], []) -> - {ok, Row}; -table_get_next_row([Row | T], [Index | _]) -when element(1, Row) > Index -> - {ok, Row}; -table_get_next_row([Row | T], RowIndex) -> - table_get_next_row(T, RowIndex); -table_get_next_row([], RowIndex) -> +table_get_next_row([Row | T], []) -> + {ok, Row}; +table_get_next_row([Row | T], [Index | _]) +when element(1, Row) > Index -> + {ok, Row}; +table_get_next_row([Row | T], RowIndex) -> + table_get_next_row(T, RowIndex); +table_get_next_row([], RowIndex) -> endOfTable. -table_delete_row([{Index, _, _, _} | T], [Index]) -> +table_delete_row([{Index, _, _, _} | T], [Index]) -> T; -table_delete_row([H | T], RowIndex) -> - [H | table_delete_row(T, RowIndex)]; -table_delete_row([], _RowIndex) -> - []. -table_add_row([Row | T], NewRow) - when element(1, Row) > element(1, NewRow) -> - [NewRow, Row | T]; -table_add_row([H | T], NewRow) -> - [H | table_add_row(T, NewRow)]; -table_add_row([], NewRow) -> - [NewRow]. -make_row([Index], [{2, Name}, {3, Address} | _]) -> - {Index, Name, Address, ?active}. -merge_rows(Row, [{Col, NewVal} | T]) -> - merge_rows(setelement(Col, Row, NewVal), T); -merge_rows(Row, []) -> +table_delete_row([H | T], RowIndex) -> + [H | table_delete_row(T, RowIndex)]; +table_delete_row([], _RowIndex) -> + []. +table_add_row([Row | T], NewRow) + when element(1, Row) > element(1, NewRow) -> + [NewRow, Row | T]; +table_add_row([H | T], NewRow) -> + [H | table_add_row(T, NewRow)]; +table_add_row([], NewRow) -> + [NewRow]. +make_row([Index], [{2, Name}, {3, Address} | _]) -> + {Index, Name, Address, ?active}. +merge_rows(Row, [{Col, NewVal} | T]) -> + merge_rows(setelement(Col, Row, NewVal), T); +merge_rows(Row, []) -> Row.

    @@ -513,21 +513,21 @@

    Association File

    The association file EX1-MIB.funcs for the real implementation looks as -follows:

    {myName, {ex1, my_name, []}}.
    -{friendsTable, {ex1, friends_table, []}}.

    +follows:

    {myName, {ex1, my_name, []}}.
    +{friendsTable, {ex1, friends_table, []}}.

    Transcript

    To use the real implementation, we must recompile the MIB and load it into the -agent.

    1> application:start(snmp).
    +agent.

    1> application:start(snmp).
     ok
    -2> snmpc:compile("EX1-MIB").
    -{ok,"EX1-MIB.bin"}
    -3> snmpa:load_mibs(snmp_master_agent, ["EX1-MIB"]).
    +2> snmpc:compile("EX1-MIB").
    +{ok,"EX1-MIB.bin"}
    +3> snmpa:load_mibs(snmp_master_agent, ["EX1-MIB"]).
     ok
    -4> ex1:start().
    +4> ex1:start().
     <0.115.0>
     %% Now all requests operates on this "real" implementation.
     %% The output from the manager requests will *look* exactly the
    @@ -543,35 +543,35 @@ 

    trap, myName and fIndex. fIndex is a table column, so we must provide its value and the index for the row in the call to snmpa:send_notification2/3. In the example below, we assume that the row in question is indexed by 2 (the row with -fIndex 2).

    we use a simple Erlang SNMP manager, which can receive traps.

    [MANAGER]
    -1> snmp_test_mgr:start_link([{agent,"dront.ericsson.se"},{community,"public"}
    +fIndex 2).

    we use a simple Erlang SNMP manager, which can receive traps.

    [MANAGER]
    +1> snmp_test_mgr:start_link([{agent,"dront.ericsson.se"},{community,"public"}
      %% does not have write-access
    -1>{mibs,["EX1-MIB","STANDARD-MIB"]}]).
    -{ok, <0.100.0>}
    -2> snmp_test_mgr:s([{[myName,0], "Klas"}]).
    +1>{mibs,["EX1-MIB","STANDARD-MIB"]}]).
    +{ok, <0.100.0>}
    +2> snmp_test_mgr:s([{[myName,0], "Klas"}]).
     ok
     * Got PDU:
     Received a trap:
           Generic: 4       %% authenticationFailure
    -   Enterprise: [iso,2,3]
    +   Enterprise: [iso,2,3]
          Specific: 0
    -   Agent addr: [123,12,12,21]
    +   Agent addr: [123,12,12,21]
         TimeStamp: 42993
     2>
    -[AGENT]
    -3> SendOpts = [{receiver, no_receiver}, {varbinds, [{fIndex,[2],2}]}, {name, "standard trap"}, {context, ""}],
    -4> snmpa:send_notification2(snmp_master_agent, fTrap, SendOpts).
    -[MANAGER]
    +[AGENT]
    +3> SendOpts = [{receiver, no_receiver}, {varbinds, [{fIndex,[2],2}]}, {name, "standard trap"}, {context, ""}],
    +4> snmpa:send_notification2(snmp_master_agent, fTrap, SendOpts).
    +[MANAGER]
     2>
     * Got PDU:
     Received a trap:
           Generic: 6
    -   Enterprise: [example1]
    +   Enterprise: [example1]
          Specific: 1
    -   Agent addr: [123,12,12,21]
    +   Agent addr: [123,12,12,21]
         TimeStamp: 69649
    -[myName,0] = "Martin"
    -[fIndex,2] = 2
    +[myName,0] = "Martin"
    +[fIndex,2] = 2
     2>
    diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmp_index.html b/prs/8803/lib/snmp-5.16/doc/html/snmp_index.html index 0bf6a399fd346..e6aea65752090 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmp_index.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmp_index.html @@ -135,13 +135,13 @@

    actual implementation of the table. The SNMP ordering, that is implementation of GET NEXT, is implemented in this module.

    For example, suppose there is an SNMP table, which is best implemented in Erlang as one process per SNMP table row. Suppose further that the INDEX in the SNMP -table is an OCTET STRING. The index structure would be created as follows:

    snmp_index:new(string)

    For each new process we create, we insert an item in an snmp_index structure:

    new_process(Name, SnmpIndex) ->
    -  Pid = start_process(),
    +table is an OCTET STRING. The index structure would be created as follows:

    snmp_index:new(string)

    For each new process we create, we insert an item in an snmp_index structure:

    new_process(Name, SnmpIndex) ->
    +  Pid = start_process(),
       NewSnmpIndex =
    -    snmp_index:insert(SnmpIndex, Name, Pid),
    +    snmp_index:insert(SnmpIndex, Name, Pid),
       <...>

    With this structure, we can now map an OBJECT IDENTIFIER in e.g. a GET NEXT -request, to the correct process:

    get_next_pid(Oid, SnmpIndex) ->
    -  {ok, {_, Pid}} = snmp_index:get_next(SnmpIndex, Oid),
    +request, to the correct process:

    get_next_pid(Oid, SnmpIndex) ->
    +  {ok, {_, Pid}} = snmp_index:get_next(SnmpIndex, Oid),
       Pid.

    diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmp_instr_functions.html b/prs/8803/lib/snmp-5.16/doc/html/snmp_instr_functions.html index e9e3bcf4c172a..ca60f2c23fc4d 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmp_instr_functions.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmp_instr_functions.html @@ -153,8 +153,8 @@

    New / Delete Operations

    -

    For scalar variables:

    variable_access(new [, ExtraArg1, ...])
    -variable_access(delete [, ExtraArg1, ...])

    For tables:

    table_access(new [, ExtraArg1, ...])
    +

    For scalar variables:

    variable_access(new [, ExtraArg1, ...])
    +variable_access(delete [, ExtraArg1, ...])

    For tables:

    table_access(new [, ExtraArg1, ...])
     table_access(delete [, ExtraArg1, ...])

    These functions are called for each object in an MIB when the MIB is unloaded or loaded, respectively.

    @@ -214,9 +214,9 @@

    value 1, and [3, 5] is the list of requested columns. The function should now return the lexicographically next elements:

    [{[3, 1, 2], d}, {[5, 1, 2], f}]

    This is illustrated in the following table:

    GetNext from [3,1,1] and [5,1,1].

    The manager now issues the following getNext request:

    getNext{ myTable.myTableEntry.3.2.1,
              myTable.myTableEntry.5.2.1 }

    This is transformed into one call to my_table:

    my_table(get_next, [2, 1], [3, 5])

    The function should now return:

    [{[4, 1, 1], b}, endOfTable]

    This is illustrated in the following table:

    GetNext from [3,2,1] and [5,2,1].

    The manager now issues the following getNext request:

    getNext{ myTable.myTableEntry.3.1.2,
    -         myTable.myTableEntry.4.1.2 }

    This will be transform into one call to my_table:

    my_table(get_next, [1, 2], [3, 4])

    The function should now return:

    [{[3, 2, 1], g}, {[5, 1, 1], c}]

    This is illustrated in the following table:

    GetNext from [3,1,2] and [4,1,2].

    The manager now issues the following getNext request:

    getNext{ myTable.myTableEntry,
    -         myTable.myTableEntry.1.3.2 }

    This will be transform into two calls to my_table:

    my_table(get_next, [], [0]) and
    -my_table(get_next, [3, 2], [1])

    The function should now return:

    [{[3, 1, 1], a}] and
    +         myTable.myTableEntry.4.1.2 }

    This will be transform into one call to my_table:

    my_table(get_next, [1, 2], [3, 4])

    The function should now return:

    [{[3, 2, 1], g}, {[5, 1, 1], c}]

    This is illustrated in the following table:

    GetNext from [3,1,2] and [4,1,2].

    The manager now issues the following getNext request:

    getNext{ myTable.myTableEntry,
    +         myTable.myTableEntry.1.3.2 }

    This will be transform into two calls to my_table:

    my_table(get_next, [], [0]) and
    +my_table(get_next, [3, 2], [1])

    The function should now return:

    [{[3, 1, 1], a}] and
     [{[3, 1, 1], a}]

    In both cases, the first accessible element in the table should be returned. As the key columns are not accessible, this means that the third column is the first row.

    Note

    Normally, the functions described above behave exactly as shown, but they are @@ -233,17 +233,17 @@

    variables for a device, ipAdr and name with object identifiers 1.1.23.4 and 1.1.7 respectively. To access these variables, one could implement the two Erlang functions ip_access and name_access, which will be in the MIB. The -functions could be specified in a text file as follows:

    {ipAdr, {my_module, ip_access, []}}.
    +functions could be specified in a text file as follows:

    {ipAdr, {my_module, ip_access, []}}.
     % Or using the oid syntax for 'name'
    -{[1,1,7], {my_module, name_access, []}}.

    The ExtraArgument parameter is the empty list. For example, when the agent +{[1,1,7], {my_module, name_access, []}}.

    The ExtraArgument parameter is the empty list. For example, when the agent receives a get-request for the ipAdr variable, a call will be made to ip_access(get). The value returned by this function is the answer to the get-request.

    If ip_access and name_access are implemented similarly, we could write a -generic_access function using the ListOfExtraArguments:

    {ipAdr, {my_module, generic_access, ['IPADR']}}.
    +generic_access function using the ListOfExtraArguments:

    {ipAdr, {my_module, generic_access, ['IPADR']}}.
     % The mnemonic 'name' is more convenient than 1.1.7
    -{name, {my_module, generic_access, ['NAME']}}.

    When the agent receives the same get-request as above, a call will be made to -generic_access(get,'IPADR').

    Yet another possibility, closer to the hardware, could be:

    {ipAdr, {my_module, generic_access, [16#2543]}}.
    -{name, {my_module, generic_access, [16#A2B3]}}.

    +{name, {my_module, generic_access, ['NAME']}}.

    When the agent receives the same get-request as above, a call will be made to +generic_access(get,'IPADR').

    Yet another possibility, closer to the hardware, could be:

    {ipAdr, {my_module, generic_access, [16#2543]}}.
    +{name, {my_module, generic_access, [16#A2B3]}}.

    diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmp_manager_config_files.html b/prs/8803/lib/snmp-5.16/doc/html/snmp_manager_config_files.html index f86ca317d09c3..64dd023f8496a 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmp_manager_config_files.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmp_manager_config_files.html @@ -149,10 +149,10 @@

    every transport.

  • engine_id - The SnmpEngineID as defined in SNMP-FRAMEWORK-MIB. Mandatory.

  • max_message_size - The snmpEngineMaxMessageSize as defined in SNMP-FRAMEWORK-MIB. Mandatory.

  • Value is the value for the variable.

  • The legacy and intermediate variables address and domain are still supported -so old configurations will work.

    The following example shows a manager.conf file:

    {transports,       [{transportDomainUdpIpv4, {{141,213,11,24}, 5000}},
    -                    {transportDomainUdpIpv6, {{0,0,0,0,0,0,0,1}, 5000}}]}.
    -{engine_id,        "mgrEngine"}.
    -{max_message_size, 484}.

    The value of engine_id is a string, which should have a very specific +so old configurations will work.

    The following example shows a manager.conf file:

    {transports,       [{transportDomainUdpIpv4, {{141,213,11,24}, 5000}},
    +                    {transportDomainUdpIpv6, {{0,0,0,0,0,0,0,1}, 5000}}]}.
    +{engine_id,        "mgrEngine"}.
    +{max_message_size, 484}.

    The value of engine_id is a string, which should have a very specific structure. See RFC 2271/2571 for details.

    diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmp_mib_compiler.html b/prs/8803/lib/snmp-5.16/doc/html/snmp_mib_compiler.html index 79cb51aa40c1f..7906139043188 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmp_mib_compiler.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmp_mib_compiler.html @@ -141,7 +141,7 @@

    association file, it gives a warning message and uses default instrumentation functions. (See Default Instrumentation for more details).

    The MIB compiler is started with a call to snmpc:compile(<mibname>). For -example:

    snmpc:compile("RFC1213-MIB").

    The output is a new file which is called <mibname>.bin.

    The MIB compiler understands both SMIv1 and SMIv2 MIBs. It uses the +example:

    snmpc:compile("RFC1213-MIB").

    The output is a new file which is called <mibname>.bin.

    The MIB compiler understands both SMIv1 and SMIv2 MIBs. It uses the MODULE-IDENTITY statement to determinate if the MIB is written in SMI version 1 or 2.

    @@ -153,10 +153,10 @@

    compiled file and not the ASN.1 (source) file. A MIB must be recompiled to make changes visible to other MIBs importing it.

    The compiled files of the imported MIBs must be present in the current directory, or a directory in the current path. The path is supplied with the -{i, Path} option, for example:

    snmpc:compile("MY-MIB",
    -       [{i, ["friend_mibs/", "../standard_mibs/"]}]).

    It is also possible to import MIBs from OTP applications in an "include_lib" -like fashion with the il option. Example:

    snmpc:compile("MY-MIB",
    -       [{il, ["snmp/priv/mibs/", "myapp/priv/mibs/"]}]).

    finds the latest version of the snmp and myapp applications in the OTP +{i, Path} option, for example:

    snmpc:compile("MY-MIB",
    +       [{i, ["friend_mibs/", "../standard_mibs/"]}]).

    It is also possible to import MIBs from OTP applications in an "include_lib" +like fashion with the il option. Example:

    snmpc:compile("MY-MIB",
    +       [{il, ["snmp/priv/mibs/", "myapp/priv/mibs/"]}]).

    finds the latest version of the snmp and myapp applications in the OTP system and uses the expanded paths as include paths.

    Note that an SMIv2 MIB can import an SMIv1 MIB and vice versa.

    The following MIBs are built-ins of the Erlang SNMP compiler: SNMPv2-SMI, RFC-1215, RFC-1212, SNMPv2-TC, SNMPv2-CONF, and RFC1155-SMI. They cannot therefore be compiled separately.

    diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmp_pdus.html b/prs/8803/lib/snmp-5.16/doc/html/snmp_pdus.html index b813f41df33d6..43c6c700acd7d 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmp_pdus.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmp_pdus.html @@ -134,8 +134,8 @@

    Erlang record representations and vice versa. The record definitions can be found in the file snmp/include/snmp_types.hrl. If snmpv3 is used, the module that includes snmp_types.hrl must define the constant SNMP_USE_V3 before the -header file is included. Example:

    -define(SNMP_USE_V3, true).
    --include_lib("snmp/include/snmp_types.hrl").

    Encoding and decoding must be done explicitly when writing your own Net if +header file is included. Example:

    -define(SNMP_USE_V3, true).
    +-include_lib("snmp/include/snmp_types.hrl").

    Encoding and decoding must be done explicitly when writing your own Net if process.

    diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmpa.html b/prs/8803/lib/snmp-5.16/doc/html/snmpa.html index 83ac36ca5bd47..0de51afcdfd40 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmpa.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmpa.html @@ -3336,8 +3336,8 @@

    load_mib(Agent, Mib)

    Load a single Mib into an agent. The MibName is the name of the Mib, -including the path to where the compiled mib is found. For example:

              Dir = code:priv_dir(my_app) ++ "/mibs/",
    -          snmpa:load_mib(snmp_master_agent, Dir ++ "MY-MIB").
    +including the path to where the compiled mib is found. For example:

              Dir = code:priv_dir(my_app) ++ "/mibs/",
    +          snmpa:load_mib(snmp_master_agent, Dir ++ "MY-MIB").
    @@ -3453,8 +3453,8 @@

    load_mibs(Agent, Mibs, Force)

    Load Mibs into an agent. If the agent cannot load all MIBs (the default value of the Force argument is false), it will indicate where loading was aborted. The MibName is the name of the Mib, including the path to where the compiled -mib is found. For example,

              Dir = code:priv_dir(my_app) ++ "/mibs/",
    -          snmpa:load_mibs(snmp_master_agent, [Dir ++ "MY-MIB"]).

    If Force = true then the agent will continue attempting to load each mib even +mib is found. For example,

              Dir = code:priv_dir(my_app) ++ "/mibs/",
    +          snmpa:load_mibs(snmp_master_agent, [Dir ++ "MY-MIB"]).

    If Force = true then the agent will continue attempting to load each mib even after failing to load a previous mib. Use with care.

    @@ -4565,8 +4565,8 @@

    register_subagent(Agent, SubTree, SubAgent)

    Registers a sub-agent under a sub-tree of another agent.

    It is easy to make mistakes when registering sub-agents and this activity should be done carefully. For example, a strange behaviour would result from the -following configuration:

    snmp_agent:register_subagent(MAPid,[1,2,3,4],SA1),
    -snmp_agent:register_subagent(SA1,[1,2,3], SA2).

    SA2 will not get requests starting with object identifier [1,2,3] since +following configuration:

    snmp_agent:register_subagent(MAPid,[1,2,3,4],SA1),
    +snmp_agent:register_subagent(SA1,[1,2,3], SA2).

    SA2 will not get requests starting with object identifier [1,2,3] since SA1 does not.

    @@ -5011,20 +5011,20 @@

    send_notification(Agent, Notification, Rece Addresses and if there are no targets for which an Inform-Request is sent, Addresses is the empty list [].

    The receiver will first be sent the snmp_targets message, and then for each address in Addresses list, one of the two snmp_notification messages.

  • {Mod, Func, Args} - The info will be delivered via the function call:

    Mod:Func([Msg | Args])

    where Msg has the same content and purpose as the messages descrived above.

  • Address is a management target address and Addresses is a list of management -target addresses. They are defined as followes:

            Addresses  = [address()]
    -        Address    = address()
    -        address()  = v1_address() | v3_address()
    -        v1_address() = {TDomain, TAddress}
    -        v3_address() = {{TDomain, TAddress}, V3MsgData}
    -        TDomain    = tdoamin()
    -        TAddress   = taddress()
    -        tdomain()  = The oid of snmpUDPDomain
    +target addresses. They are defined as followes:

            Addresses  = [address()]
    +        Address    = address()
    +        address()  = v1_address() | v3_address()
    +        v1_address() = {TDomain, TAddress}
    +        v3_address() = {{TDomain, TAddress}, V3MsgData}
    +        TDomain    = tdoamin()
    +        TAddress   = taddress()
    +        tdomain()  = The oid of snmpUDPDomain
                          This is the only supported transport domain.
    -        taddress() = [A1, A2, A3, A4, P1, P3]
    +        taddress() = [A1, A2, A3, A4, P1, P3]
                          The 4 first bytes makes up the IP-address and the last 2,
                          the UDP-port number.
    -        V3MsgData  = v3_msg_data()
    -        v3_msg_data() = term()

    If Receiver is a notification_delivery_info/0 record, then the information + V3MsgData = v3_msg_data() + v3_msg_data() = term()

    If Receiver is a notification_delivery_info/0 record, then the information about the notification delivery will be delivered to the receiver via the callback functions defined by the snmpa_notification_delivery_info_receiver behaviour according to the content of the notification_delivery_info/0 diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmpc_cmd.html b/prs/8803/lib/snmp-5.16/doc/html/snmpc_cmd.html index 8b7ad6badb2eb..e38f5bb0efb8a 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmpc_cmd.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmpc_cmd.html @@ -131,7 +131,7 @@

    Synopsis

    -
    snmpc [options] file.mib | file.bin

    +
    snmpc [options] file.mib | file.bin

    diff --git a/prs/8803/lib/snmp-5.16/doc/html/snmpm.html b/prs/8803/lib/snmp-5.16/doc/html/snmpm.html index b2e35447f45aa..2032fa464b396 100644 --- a/prs/8803/lib/snmp-5.16/doc/html/snmpm.html +++ b/prs/8803/lib/snmp-5.16/doc/html/snmpm.html @@ -2008,8 +2008,8 @@

    load_mib(MibName)

    Load a Mib into the manager. The MibName is the name of the Mib, including -the path to where the compiled mib is found. For example,

              Dir = code:priv_dir(my_app) ++ "/mibs/",
    -          snmpm:load_mib(Dir ++ "MY-MIB").
    +the path to where the compiled mib is found. For example,

              Dir = code:priv_dir(my_app) ++ "/mibs/",
    +          snmpm:load_mib(Dir ++ "MY-MIB").
    @@ -3588,8 +3588,8 @@

    unload_mib(MibName)

    Unload a Mib from the manager. The MibName is the name of the Mib, including -the path to where the compiled mib is found. For example,

              Dir = code:priv_dir(my_app) ++ "/mibs/",
    -          snmpm:unload_mib(Dir ++ "MY-MIB").
    +the path to where the compiled mib is found. For example,

              Dir = code:priv_dir(my_app) ++ "/mibs/",
    +          snmpm:unload_mib(Dir ++ "MY-MIB").
    diff --git a/prs/8803/lib/ssh-5.2.1/doc/html/configurations.html b/prs/8803/lib/ssh-5.2.1/doc/html/configurations.html index 02fbe8fb0a048..7f071d879c240 100644 --- a/prs/8803/lib/ssh-5.2.1/doc/html/configurations.html +++ b/prs/8803/lib/ssh-5.2.1/doc/html/configurations.html @@ -142,23 +142,23 @@

    Options configuration

    There are from OTP-23.0 two main ways to set an option:

    • Like before, in the Options parameter in the Erlang code in a call to for -example ssh:daemon/3 or ssh:connect/3 or any of their variants. Example:

      ssh:connect(22, [{user,"foo"}])
    • In OTP Configuration Parameters:

      • In the erl command line:

        erl -ssh user \"foo\"
      • In the ssh.app file, in the env part

        {application, ssh,
        - [{description, "SSH-2 for Erlang/OTP"},
        -  {vsn, "4.9"},
        -  {modules, [ssh,
        +example ssh:daemon/3 or ssh:connect/3 or any of their variants. Example:

        ssh:connect(22, [{user,"foo"}])
      • In OTP Configuration Parameters:

        • In the erl command line:

          erl -ssh user \"foo\"
        • In the ssh.app file, in the env part

          {application, ssh,
          + [{description, "SSH-2 for Erlang/OTP"},
          +  {vsn, "4.9"},
          +  {modules, [ssh,
                   ...
          -         ssh_xfer]},
          -  {registered, []},
          -  {applications, [kernel, stdlib, crypto, public_key]},
          -  {env, [{user, "bar"]}, % <<<<<<<<<<<<<<<<<<<<<<<<<<<<<< HERE
          -  {mod, {ssh_app, []}},
          -       ...
        • In a .config file:

          erl -config ex1

          where ex1.config contains:

          [
          -{ssh, [{user, "foo"}]}
          -].

        If the option is intended only for a server or for a client, it may be set in -this way:

        [
        -{ssh, [{server_options,[{user, "foo"}]},
        -       {client_options,[{user, "bar"}]}
        -].

        A server (daemon) will use the user name foo, and a client will use the name + ssh_xfer]}, + {registered, []}, + {applications, [kernel, stdlib, crypto, public_key]}, + {env, [{user, "bar"]}, % <<<<<<<<<<<<<<<<<<<<<<<<<<<<<< HERE + {mod, {ssh_app, []}}, + ...

  • In a .config file:

    erl -config ex1

    where ex1.config contains:

    [
    +{ssh, [{user, "foo"}]}
    +].
  • If the option is intended only for a server or for a client, it may be set in +this way:

    [
    +{ssh, [{server_options,[{user, "foo"}]},
    +       {client_options,[{user, "bar"}]}
    +].

    A server (daemon) will use the user name foo, and a client will use the name bar.

    @@ -229,17 +229,17 @@

    'hmac-sha1']}]}, {compression,[{client2server,[none,'zlib@openssh.com',zlib]}, {server2client,[none,'zlib@openssh.com',zlib]}]}]

    Note that the algorithms in the file ex2.config is not yet applied. They will -be when we start ssh:

    2> ssh:start().
    +be when we start ssh:

    2> ssh:start().
     ok
    -3> ssh:default_algorithms().
    -[{kex,['ecdh-sha2-nistp384']},
    - {public_key,['ssh-rsa']},
    - {cipher,[{client2server,['aes192-ctr']},
    -          {server2client,['aes192-ctr']}]},
    - {mac,[{client2server,['hmac-sha1']},
    -       {server2client,['hmac-sha1']}]},
    - {compression,[{client2server,[none,'zlib@openssh.com',zlib]},
    -               {server2client,[none,'zlib@openssh.com',zlib]}]}]
    +3> ssh:default_algorithms().
    +[{kex,['ecdh-sha2-nistp384']},
    + {public_key,['ssh-rsa']},
    + {cipher,[{client2server,['aes192-ctr']},
    +          {server2client,['aes192-ctr']}]},
    + {mac,[{client2server,['hmac-sha1']},
    +       {server2client,['hmac-sha1']}]},
    + {compression,[{client2server,[none,'zlib@openssh.com',zlib]},
    +               {server2client,[none,'zlib@openssh.com',zlib]}]}]
     4>

    We see that the algorithm set is changed to the one in the ex2.config. Since compression is not specified in the file, the hard-coded default is still used for that entry.

    Establishing a connection (ssh:connect et al) or starting a daemon (ssh:daemon)

    Both when the client establishes a connection with ssh:connect or other @@ -252,65 +252,65 @@

    modify_algorithms on all levels in order starting with level 0 are applied.

    We continue the example above by connecting to a server and modifying the kex algorithm set. We remove the only one ('ecdh-sha2-nistp384') and add -'curve25519-sha256@libssh.org' by appending it to the now empty list:

    4> {ok,C} = ssh:connect(loopback, 22,
    -                        [{modify_algorithms,
    -                                 [{rm,
    -                                     [ {kex,['ecdh-sha2-nistp384']} ]
    -				  },
    -                                  {append,
    -			             [ {kex,['curve25519-sha256@libssh.org']} ]
    -				  }
    -				 ]
    -	                 }
    -                        ]).
    -{ok,>0.118.0>}

    We check which algorithms are negotiated by the client and the server, and note -that the (only) kex algorithm 'curve25519-sha256@libssh.org' was selected:

    5> ssh:connection_info(C, algorithms).
    -{algorithms,[{kex,'curve25519-sha256@libssh.org'},
    -             {hkey,'ssh-rsa'},
    -             {send_mac,'hmac-sha1'},
    -             {recv_mac,'hmac-sha1'},
    -             {encrypt,'aes192-ctr'},
    -             {decrypt,'aes192-ctr'},
    -             {compress,none},
    -             {decompress,none},
    -             {send_ext_info,false},
    -             {recv_ext_info,true}]}

    Example of modify_algorithms handling

    We will now check if the +'curve25519-sha256@libssh.org' by appending it to the now empty list:

    4> {ok,C} = ssh:connect(loopback, 22,
    +                        [{modify_algorithms,
    +                                 [{rm,
    +                                     [ {kex,['ecdh-sha2-nistp384']} ]
    +				  },
    +                                  {append,
    +			             [ {kex,['curve25519-sha256@libssh.org']} ]
    +				  }
    +				 ]
    +	                 }
    +                        ]).
    +{ok,>0.118.0>}

    We check which algorithms are negotiated by the client and the server, and note +that the (only) kex algorithm 'curve25519-sha256@libssh.org' was selected:

    5> ssh:connection_info(C, algorithms).
    +{algorithms,[{kex,'curve25519-sha256@libssh.org'},
    +             {hkey,'ssh-rsa'},
    +             {send_mac,'hmac-sha1'},
    +             {recv_mac,'hmac-sha1'},
    +             {encrypt,'aes192-ctr'},
    +             {decrypt,'aes192-ctr'},
    +             {compress,none},
    +             {decompress,none},
    +             {send_ext_info,false},
    +             {recv_ext_info,true}]}

    Example of modify_algorithms handling

    We will now check if the modify_algorithms on a lower level is applied to a preferred_algorithms on a higher level. We will do that by enabling the ssh-dss algorithm that is supported, -but not in the default set.

    The config file ex3.config has the contents:

    [
    - {ssh, [{modify_algorithms,
    -         [ {prepend, [{public_key, ['ssh-dss']}]} ]
    -        }]}
    -].

    A newly started erlang shell shows that no 'ssh-dss' is present in the -public_key entry:

    1> proplists:get_value(public_key, ssh:default_algorithms()).
    -['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
    +but not in the default set.

    The config file ex3.config has the contents:

    [
    + {ssh, [{modify_algorithms,
    +         [ {prepend, [{public_key, ['ssh-dss']}]} ]
    +        }]}
    +].

    A newly started erlang shell shows that no 'ssh-dss' is present in the +public_key entry:

    1> proplists:get_value(public_key, ssh:default_algorithms()).
    +['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
      'ecdsa-sha2-nistp256','ssh-ed25519','ssh-ed448',
    - 'rsa-sha2-256','rsa-sha2-512','ssh-rsa']
    -2>

    A call to ssh:connect/3 removes all algorithms but one of each type:

    2> ssh:start().
    + 'rsa-sha2-256','rsa-sha2-512','ssh-rsa']
    +2>

    A call to ssh:connect/3 removes all algorithms but one of each type:

    2> ssh:start().
     ok
    -3> {ok,C} = ssh:connect(loopback, 22,
    -                        [{preferred_algorithms,
    -                         [{public_key, ['ecdsa-sha2-nistp256']},
    -			  {kex, ['ecdh-sha2-nistp256']},
    -		          {cipher, ['chacha20-poly1305@openssh.com']},
    -			  {mac, ['hmac-sha2-256']},
    -			  {compression, [none]}
    -			  ]}
    -			 ]).
    -{ok,<0.101.0>}
    -4> ssh:connection_info(C,algorithms).
    -{algorithms,[{kex,'ecdh-sha2-nistp256'},
    -             {hkey,'ssh-dss'},
    -             {send_mac,'chacha20-poly1305@openssh.com'},
    -             {recv_mac,'chacha20-poly1305@openssh.com'},
    -             {encrypt,'chacha20-poly1305@openssh.com'},
    -             {decrypt,'chacha20-poly1305@openssh.com'},
    -             {compress,none},
    -             {decompress,none},
    -             {send_ext_info,false},
    -             {recv_ext_info,true}]}
    +3> {ok,C} = ssh:connect(loopback, 22,
    +                        [{preferred_algorithms,
    +                         [{public_key, ['ecdsa-sha2-nistp256']},
    +			  {kex, ['ecdh-sha2-nistp256']},
    +		          {cipher, ['chacha20-poly1305@openssh.com']},
    +			  {mac, ['hmac-sha2-256']},
    +			  {compression, [none]}
    +			  ]}
    +			 ]).
    +{ok,<0.101.0>}
    +4> ssh:connection_info(C,algorithms).
    +{algorithms,[{kex,'ecdh-sha2-nistp256'},
    +             {hkey,'ssh-dss'},
    +             {send_mac,'chacha20-poly1305@openssh.com'},
    +             {recv_mac,'chacha20-poly1305@openssh.com'},
    +             {encrypt,'chacha20-poly1305@openssh.com'},
    +             {decrypt,'chacha20-poly1305@openssh.com'},
    +             {compress,none},
    +             {decompress,none},
    +             {send_ext_info,false},
    +             {recv_ext_info,true}]}
     5>

    But 'ssh-dss' is selected although the call inserted only 'ecdsa-sha2-nistp256' as acceptable.

    This example showed that we could augment the set of algorithms with a config-file without the need to change the actual call.

    For demonstration purposes we used prepend instead of append. This forces diff --git a/prs/8803/lib/ssh-5.2.1/doc/html/configure_algos.html b/prs/8803/lib/ssh-5.2.1/doc/html/configure_algos.html index 2829e146dc9ff..5ca5a4ae8fbf2 100644 --- a/prs/8803/lib/ssh-5.2.1/doc/html/configure_algos.html +++ b/prs/8803/lib/ssh-5.2.1/doc/html/configure_algos.html @@ -170,29 +170,29 @@

    supported by the:

    • crypto app,
    • The cryptolib OTP is linked with, usually the one the OS uses, probably OpenSSL,
    • and finally what the SSH app implements

    Due to this, it impossible to list in documentation what algorithms that are available in a certain installation.

    There is an important command to list the actual algorithms and their ordering: -ssh:default_algorithms/0.

    0> ssh:default_algorithms().
    -[{kex,['ecdh-sha2-nistp384','ecdh-sha2-nistp521',
    +ssh:default_algorithms/0.

    0> ssh:default_algorithms().
    +[{kex,['ecdh-sha2-nistp384','ecdh-sha2-nistp521',
            'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256',
            'diffie-hellman-group16-sha512',
            'diffie-hellman-group18-sha512',
            'diffie-hellman-group14-sha256',
            'diffie-hellman-group14-sha1',
    -       'diffie-hellman-group-exchange-sha1']},
    - {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
    +       'diffie-hellman-group-exchange-sha1']},
    + {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
                   'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256',
    -              'rsa-sha2-512','ssh-dss']},
    - {cipher,[{client2server,['aes256-gcm@openssh.com',
    +              'rsa-sha2-512','ssh-dss']},
    + {cipher,[{client2server,['aes256-gcm@openssh.com',
                               'aes256-ctr','aes192-ctr','aes128-gcm@openssh.com',
    -                          'aes128-ctr','aes128-cbc','3des-cbc']},
    -          {server2client,['aes256-gcm@openssh.com','aes256-ctr',
    +                          'aes128-ctr','aes128-cbc','3des-cbc']},
    +          {server2client,['aes256-gcm@openssh.com','aes256-ctr',
                               'aes192-ctr','aes128-gcm@openssh.com','aes128-ctr',
    -                          'aes128-cbc','3des-cbc']}]},
    - {mac,[{client2server,['hmac-sha2-256','hmac-sha2-512',
    -                       'hmac-sha1']},
    -       {server2client,['hmac-sha2-256','hmac-sha2-512',
    -                       'hmac-sha1']}]},
    - {compression,[{client2server,[none,'zlib@openssh.com',zlib]},
    -               {server2client,[none,'zlib@openssh.com',zlib]}]}]

    To change the algorithm list, there are two options which can be used in + 'aes128-cbc','3des-cbc']}]}, + {mac,[{client2server,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}, + {server2client,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}]}, + {compression,[{client2server,[none,'zlib@openssh.com',zlib]}, + {server2client,[none,'zlib@openssh.com',zlib]}]}]

    To change the algorithm list, there are two options which can be used in ssh:connect/2,3,4 and ssh:daemon/2,3. The options could of course be used in all other functions that initiates connections.

    The options are @@ -215,28 +215,28 @@

    Example 1

    Replace the kex algorithms list with the single algorithm -'diffie-hellman-group14-sha256':

    1> ssh:chk_algos_opts(
    -               [{preferred_algorithms,
    -                     [{kex, ['diffie-hellman-group14-sha256']}
    -                     ]
    -                }
    -              ]).
    -[{kex,['diffie-hellman-group14-sha256']},
    - {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
    +'diffie-hellman-group14-sha256':

    1> ssh:chk_algos_opts(
    +               [{preferred_algorithms,
    +                     [{kex, ['diffie-hellman-group14-sha256']}
    +                     ]
    +                }
    +              ]).
    +[{kex,['diffie-hellman-group14-sha256']},
    + {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
                   'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256',
    -              'rsa-sha2-512','ssh-dss']},
    - {cipher,[{client2server,['aes256-gcm@openssh.com',
    +              'rsa-sha2-512','ssh-dss']},
    + {cipher,[{client2server,['aes256-gcm@openssh.com',
                               'aes256-ctr','aes192-ctr','aes128-gcm@openssh.com',
    -                          'aes128-ctr','aes128-cbc','3des-cbc']},
    -          {server2client,['aes256-gcm@openssh.com','aes256-ctr',
    +                          'aes128-ctr','aes128-cbc','3des-cbc']},
    +          {server2client,['aes256-gcm@openssh.com','aes256-ctr',
                               'aes192-ctr','aes128-gcm@openssh.com','aes128-ctr',
    -                          'aes128-cbc','3des-cbc']}]},
    - {mac,[{client2server,['hmac-sha2-256','hmac-sha2-512',
    -                       'hmac-sha1']},
    -       {server2client,['hmac-sha2-256','hmac-sha2-512',
    -                       'hmac-sha1']}]},
    - {compression,[{client2server,[none,'zlib@openssh.com',zlib]},
    -               {server2client,[none,'zlib@openssh.com',zlib]}]}]

    Note that the unmentioned lists (public_key, cipher, mac and + 'aes128-cbc','3des-cbc']}]}, + {mac,[{client2server,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}, + {server2client,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}]}, + {compression,[{client2server,[none,'zlib@openssh.com',zlib]}, + {server2client,[none,'zlib@openssh.com',zlib]}]}]

    Note that the unmentioned lists (public_key, cipher, mac and compression) are unchanged.

    @@ -244,30 +244,30 @@

    Example 2

    In the lists that are divided in two for the two directions (for example cipher) it is -possible to change both directions at once:

    2> ssh:chk_algos_opts(
    -               [{preferred_algorithms,
    -                     [{cipher,['aes128-ctr']}
    -                     ]
    -                }
    -              ]).
    -[{kex,['ecdh-sha2-nistp384','ecdh-sha2-nistp521',
    +possible to change both directions at once:

    2> ssh:chk_algos_opts(
    +               [{preferred_algorithms,
    +                     [{cipher,['aes128-ctr']}
    +                     ]
    +                }
    +              ]).
    +[{kex,['ecdh-sha2-nistp384','ecdh-sha2-nistp521',
            'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256',
            'diffie-hellman-group16-sha512',
            'diffie-hellman-group18-sha512',
            'diffie-hellman-group14-sha256',
            'diffie-hellman-group14-sha1',
    -       'diffie-hellman-group-exchange-sha1']},
    - {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
    +       'diffie-hellman-group-exchange-sha1']},
    + {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
                   'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256',
    -              'rsa-sha2-512','ssh-dss']},
    - {cipher,[{client2server,['aes128-ctr']},
    -          {server2client,['aes128-ctr']}]},
    - {mac,[{client2server,['hmac-sha2-256','hmac-sha2-512',
    -                       'hmac-sha1']},
    -       {server2client,['hmac-sha2-256','hmac-sha2-512',
    -                       'hmac-sha1']}]},
    - {compression,[{client2server,[none,'zlib@openssh.com',zlib]},
    -               {server2client,[none,'zlib@openssh.com',zlib]}]}]

    Note that both lists in cipher has been changed to the provided value + 'rsa-sha2-512','ssh-dss']}, + {cipher,[{client2server,['aes128-ctr']}, + {server2client,['aes128-ctr']}]}, + {mac,[{client2server,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}, + {server2client,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}]}, + {compression,[{client2server,[none,'zlib@openssh.com',zlib]}, + {server2client,[none,'zlib@openssh.com',zlib]}]}]

    Note that both lists in cipher has been changed to the provided value ('aes128-ctr').

    @@ -275,56 +275,56 @@

    Example 3

    In the lists that are divided in two for the two directions (for example cipher) it is -possible to change only one of the directions:

    3> ssh:chk_algos_opts(
    -               [{preferred_algorithms,
    -                     [{cipher,[{client2server,['aes128-ctr']}]}
    -                     ]
    -                }
    -              ]).
    -[{kex,['ecdh-sha2-nistp384','ecdh-sha2-nistp521',
    +possible to change only one of the directions:

    3> ssh:chk_algos_opts(
    +               [{preferred_algorithms,
    +                     [{cipher,[{client2server,['aes128-ctr']}]}
    +                     ]
    +                }
    +              ]).
    +[{kex,['ecdh-sha2-nistp384','ecdh-sha2-nistp521',
            'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256',
            'diffie-hellman-group16-sha512',
            'diffie-hellman-group18-sha512',
            'diffie-hellman-group14-sha256',
            'diffie-hellman-group14-sha1',
    -       'diffie-hellman-group-exchange-sha1']},
    - {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
    +       'diffie-hellman-group-exchange-sha1']},
    + {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
                   'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256',
    -              'rsa-sha2-512','ssh-dss']},
    - {cipher,[{client2server,['aes128-ctr']},
    -          {server2client,['aes256-gcm@openssh.com','aes256-ctr',
    +              'rsa-sha2-512','ssh-dss']},
    + {cipher,[{client2server,['aes128-ctr']},
    +          {server2client,['aes256-gcm@openssh.com','aes256-ctr',
                               'aes192-ctr','aes128-gcm@openssh.com','aes128-ctr',
    -                          'aes128-cbc','3des-cbc']}]},
    - {mac,[{client2server,['hmac-sha2-256','hmac-sha2-512',
    -                       'hmac-sha1']},
    -       {server2client,['hmac-sha2-256','hmac-sha2-512',
    -                       'hmac-sha1']}]},
    - {compression,[{client2server,[none,'zlib@openssh.com',zlib]},
    -               {server2client,[none,'zlib@openssh.com',zlib]}]}]

    + 'aes128-cbc','3des-cbc']}]}, + {mac,[{client2server,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}, + {server2client,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}]}, + {compression,[{client2server,[none,'zlib@openssh.com',zlib]}, + {server2client,[none,'zlib@openssh.com',zlib]}]}]

    Example 4

    -

    It is of course possible to change more than one list:

    4> ssh:chk_algos_opts(
    -               [{preferred_algorithms,
    -                     [{cipher,['aes128-ctr']},
    -		      {mac,['hmac-sha2-256']},
    -                      {kex,['ecdh-sha2-nistp384']},
    -		      {public_key,['ssh-rsa']},
    -		      {compression,[{server2client,[none]},
    -		                    {client2server,[zlib]}]}
    -                     ]
    -                }
    -              ]).
    -[{kex,['ecdh-sha2-nistp384']},
    - {public_key,['ssh-rsa']},
    - {cipher,[{client2server,['aes128-ctr']},
    -          {server2client,['aes128-ctr']}]},
    - {mac,[{client2server,['hmac-sha2-256']},
    -       {server2client,['hmac-sha2-256']}]},
    - {compression,[{client2server,[zlib]},
    -               {server2client,[none]}]}]

    Note that the order of the tuples in the lists does not matter.

    +

    It is of course possible to change more than one list:

    4> ssh:chk_algos_opts(
    +               [{preferred_algorithms,
    +                     [{cipher,['aes128-ctr']},
    +		      {mac,['hmac-sha2-256']},
    +                      {kex,['ecdh-sha2-nistp384']},
    +		      {public_key,['ssh-rsa']},
    +		      {compression,[{server2client,[none]},
    +		                    {client2server,[zlib]}]}
    +                     ]
    +                }
    +              ]).
    +[{kex,['ecdh-sha2-nistp384']},
    + {public_key,['ssh-rsa']},
    + {cipher,[{client2server,['aes128-ctr']},
    +          {server2client,['aes128-ctr']}]},
    + {mac,[{client2server,['hmac-sha2-256']},
    +       {server2client,['hmac-sha2-256']}]},
    + {compression,[{client2server,[zlib]},
    +               {server2client,[none]}]}]

    Note that the order of the tuples in the lists does not matter.

    @@ -338,10 +338,10 @@

    ssh:default_algorithms() and then do changes in the lists.

    To facilitate addition or removal of algorithms the option modify_algorithms is available. See the Reference Manual for details.

    The option takes a list with instructions to append, prepend or remove -algorithms:

    {modify_algorithms, [{append,  ...},
    -                     {prepend, ...},
    -		     {rm,      ...}
    -		    ]}

    Each of the ... can be a algs_list() as the argument to the +algorithms:

    {modify_algorithms, [{append,  ...},
    +                     {prepend, ...},
    +		     {rm,      ...}
    +		    ]}

    Each of the ... can be a algs_list() as the argument to the preferred_algorithms option.

    @@ -349,37 +349,37 @@

    Example 5

    As an example let's add the Diffie-Hellman Group1 first in the kex list. It is -supported according to Supported algorithms.

    5> ssh:chk_algos_opts(
    -         [{modify_algorithms,
    -	       [{prepend,
    -	           [{kex,['diffie-hellman-group1-sha1']}]
    -		   }
    -	       ]
    -          }
    -        ]).
    -[{kex,['diffie-hellman-group1-sha1','ecdh-sha2-nistp384',
    +supported according to Supported algorithms.

    5> ssh:chk_algos_opts(
    +         [{modify_algorithms,
    +	       [{prepend,
    +	           [{kex,['diffie-hellman-group1-sha1']}]
    +		   }
    +	       ]
    +          }
    +        ]).
    +[{kex,['diffie-hellman-group1-sha1','ecdh-sha2-nistp384',
            'ecdh-sha2-nistp521','ecdh-sha2-nistp256',
            'diffie-hellman-group-exchange-sha256',
            'diffie-hellman-group16-sha512',
            'diffie-hellman-group18-sha512',
            'diffie-hellman-group14-sha256',
            'diffie-hellman-group14-sha1',
    -       'diffie-hellman-group-exchange-sha1']},
    - {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
    +       'diffie-hellman-group-exchange-sha1']},
    + {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
                   'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256',
    -              'rsa-sha2-512','ssh-dss']},
    - {cipher,[{client2server,['aes256-gcm@openssh.com',
    +              'rsa-sha2-512','ssh-dss']},
    + {cipher,[{client2server,['aes256-gcm@openssh.com',
                               'aes256-ctr','aes192-ctr','aes128-gcm@openssh.com',
    -                          'aes128-ctr','aes128-cbc','3des-cbc']},
    -          {server2client,['aes256-gcm@openssh.com','aes256-ctr',
    +                          'aes128-ctr','aes128-cbc','3des-cbc']},
    +          {server2client,['aes256-gcm@openssh.com','aes256-ctr',
                               'aes192-ctr','aes128-gcm@openssh.com','aes128-ctr',
    -                          'aes128-cbc','3des-cbc']}]},
    - {mac,[{client2server,['hmac-sha2-256','hmac-sha2-512',
    -                       'hmac-sha1']},
    -       {server2client,['hmac-sha2-256','hmac-sha2-512',
    -                       'hmac-sha1']}]},
    - {compression,[{client2server,[none,'zlib@openssh.com',zlib]},
    -               {server2client,[none,'zlib@openssh.com',zlib]}]}]

    And the result shows that the Diffie-Hellman Group1 is added at the head of the + 'aes128-cbc','3des-cbc']}]}, + {mac,[{client2server,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}, + {server2client,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}]}, + {compression,[{client2server,[none,'zlib@openssh.com',zlib]}, + {server2client,[none,'zlib@openssh.com',zlib]}]}]

    And the result shows that the Diffie-Hellman Group1 is added at the head of the kex list

    @@ -387,27 +387,27 @@

    Example 6

    In this example, we in put the 'diffie-hellman-group1-sha1' first and also move -the 'ecdh-sha2-nistp521' to the end in the kex list, that is, append it.

    6> ssh:chk_algos_opts(
    -         [{modify_algorithms,
    -	       [{prepend,
    -	           [{kex, ['diffie-hellman-group1-sha1']}
    -		   ]},
    -		{append,
    -                   [{kex, ['ecdh-sha2-nistp521']}
    -                   ]}
    -	       ]
    -          }
    -        ]).
    -[{kex,['diffie-hellman-group1-sha1','ecdh-sha2-nistp384',
    +the 'ecdh-sha2-nistp521' to the end in the kex list, that is, append it.

    6> ssh:chk_algos_opts(
    +         [{modify_algorithms,
    +	       [{prepend,
    +	           [{kex, ['diffie-hellman-group1-sha1']}
    +		   ]},
    +		{append,
    +                   [{kex, ['ecdh-sha2-nistp521']}
    +                   ]}
    +	       ]
    +          }
    +        ]).
    +[{kex,['diffie-hellman-group1-sha1','ecdh-sha2-nistp384',
            'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256',
            'diffie-hellman-group16-sha512',
            'diffie-hellman-group18-sha512',
            'diffie-hellman-group14-sha256',
            'diffie-hellman-group14-sha1',
    -       'diffie-hellman-group-exchange-sha1','ecdh-sha2-nistp521']},
    - {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
    +       'diffie-hellman-group-exchange-sha1','ecdh-sha2-nistp521']},
    + {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
        .....
    -]

    Note that the appended algorithm is removed from its original place and then +]

    Note that the appended algorithm is removed from its original place and then appended to the same list.

    @@ -416,34 +416,34 @@

    In this example, we use both options (preferred_algorithms and modify_algorithms) and also try to prepend an unsupported algorithm. Any -unsupported algorithm is quietly removed.

    7> ssh:chk_algos_opts(
    -         [{preferred_algorithms,
    -               [{cipher,['aes128-ctr']},
    -	        {mac,['hmac-sha2-256']},
    -                {kex,['ecdh-sha2-nistp384']},
    -		{public_key,['ssh-rsa']},
    -		{compression,[{server2client,[none]},
    -		              {client2server,[zlib]}]}
    -               ]
    -           },
    -          {modify_algorithms,
    -	       [{prepend,
    -	           [{kex, ['some unsupported algorithm']}
    -		   ]},
    -		{append,
    -                   [{kex, ['diffie-hellman-group1-sha1']}
    -                   ]}
    -	       ]
    -          }
    -        ]).
    -[{kex,['ecdh-sha2-nistp384','diffie-hellman-group1-sha1']},
    - {public_key,['ssh-rsa']},
    - {cipher,[{client2server,['aes128-ctr']},
    -          {server2client,['aes128-ctr']}]},
    - {mac,[{client2server,['hmac-sha2-256']},
    -       {server2client,['hmac-sha2-256']}]},
    - {compression,[{client2server,[zlib]},
    -               {server2client,[none]}]}]

    It is of course questionable why anyone would like to use the both these options +unsupported algorithm is quietly removed.

    7> ssh:chk_algos_opts(
    +         [{preferred_algorithms,
    +               [{cipher,['aes128-ctr']},
    +	        {mac,['hmac-sha2-256']},
    +                {kex,['ecdh-sha2-nistp384']},
    +		{public_key,['ssh-rsa']},
    +		{compression,[{server2client,[none]},
    +		              {client2server,[zlib]}]}
    +               ]
    +           },
    +          {modify_algorithms,
    +	       [{prepend,
    +	           [{kex, ['some unsupported algorithm']}
    +		   ]},
    +		{append,
    +                   [{kex, ['diffie-hellman-group1-sha1']}
    +                   ]}
    +	       ]
    +          }
    +        ]).
    +[{kex,['ecdh-sha2-nistp384','diffie-hellman-group1-sha1']},
    + {public_key,['ssh-rsa']},
    + {cipher,[{client2server,['aes128-ctr']},
    +          {server2client,['aes128-ctr']}]},
    + {mac,[{client2server,['hmac-sha2-256']},
    +       {server2client,['hmac-sha2-256']}]},
    + {compression,[{client2server,[zlib]},
    +               {server2client,[none]}]}]

    It is of course questionable why anyone would like to use the both these options together, but it is possible if an unforeseen need should arise.

    @@ -452,7 +452,7 @@

    In this example, we need to use a diffie-hellman-group1-sha1 key exchange algorithm although it is unsafe and disabled by default.

    We use the modify_algorithms -option, because we want to keep all other algorithm definitions.

    We add the option:

      {modify_algorithms, [{append, [{kex,['diffie-hellman-group1-sha1']}]}]}

    either to the Options list in a function call, in the ssh.app file or in a +option, because we want to keep all other algorithm definitions.

    We add the option:

      {modify_algorithms, [{append, [{kex,['diffie-hellman-group1-sha1']}]}]}

    either to the Options list in a function call, in the ssh.app file or in a .config file for the erl command. See the chapter Configuration in SSH in the SSH User's Guide.

    @@ -464,7 +464,7 @@

    either as a user's key, a host's key or both.

    To do that, we enable the 'ssh-dss' algorithm that is disabled by default by security reasons. We use the modify_algorithms option, because -we want to keep all other algorithm definitions.

    We add the option:

      {modify_algorithms, [{append, [{public_key,['ssh-dss']}]}]}

    either to the Options list in a function call, in the ssh.app file or in a +we want to keep all other algorithm definitions.

    We add the option:

      {modify_algorithms, [{append, [{public_key,['ssh-dss']}]}]}

    either to the Options list in a function call, in the ssh.app file or in a .config file for the erl command. See the chapter Configuration in SSH in the SSH User's Guide.

    diff --git a/prs/8803/lib/ssh-5.2.1/doc/html/hardening.html b/prs/8803/lib/ssh-5.2.1/doc/html/hardening.html index ed4047002cd47..c96467047c522 100644 --- a/prs/8803/lib/ssh-5.2.1/doc/html/hardening.html +++ b/prs/8803/lib/ssh-5.2.1/doc/html/hardening.html @@ -214,16 +214,16 @@

    could be replaced with a pwdfun plugin. The arity four variant (pwdfun_4()) can also be used for introducing delays after failed password checking attempts. Here is a simple -example of such a pwdfun:

    fun(User, Password, _PeerAddress, State) ->
    -        case lists:member({User,Password}, my_user_pwds()) of
    +example of such a pwdfun:

    fun(User, Password, _PeerAddress, State) ->
    +        case lists:member({User,Password}, my_user_pwds()) of
                 true ->
    -                {true, undefined}; % Reset delay time
    +                {true, undefined}; % Reset delay time
                 false when State == undefined ->
    -                timer:sleep(1000),
    -                {false, 2000}; % Next delay is 2000 ms
    -            false when is_integer(State) ->
    -                timer:sleep(State),
    -                {false, 2*State} % Double the delay for each failure
    +                timer:sleep(1000),
    +                {false, 2000}; % Next delay is 2000 ms
    +            false when is_integer(State) ->
    +                timer:sleep(State),
    +                {false, 2*State} % Double the delay for each failure
             end
     end.

    If a public key is used for logging in, there is normally no checking of the user name. It could be enabled by setting the option @@ -292,7 +292,7 @@

    exploiting known faults or peculiarities learned by reading the public code.

    Each SSH client or daemon presents themselves to each other with brand and version. This may look like

    SSH-2.0-Erlang/4.10

    or

    SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3

    This brand and version may be changed with the option id_string. We start a daemon with that -option:

    	ssh:daemon(1234, [{id_string,"hi there"}, ... ]).

    and the daemon will present itself as:

    SSH-2.0-hi there

    It is possible to replace the string with one randomly generated for each +option:

    	ssh:daemon(1234, [{id_string,"hi there"}, ... ]).

    and the daemon will present itself as:

    SSH-2.0-hi there

    It is possible to replace the string with one randomly generated for each connection attempt. See the reference manual for id_string.

    diff --git a/prs/8803/lib/ssh-5.2.1/doc/html/ssh.epub b/prs/8803/lib/ssh-5.2.1/doc/html/ssh.epub index 0b25bd1c5ac8c..9912ccb8a23a9 100644 Binary files a/prs/8803/lib/ssh-5.2.1/doc/html/ssh.epub and b/prs/8803/lib/ssh-5.2.1/doc/html/ssh.epub differ diff --git a/prs/8803/lib/ssh-5.2.1/doc/html/ssh.html b/prs/8803/lib/ssh-5.2.1/doc/html/ssh.html index 9dfc5e706cd29..0732049c129a9 100644 --- a/prs/8803/lib/ssh-5.2.1/doc/html/ssh.html +++ b/prs/8803/lib/ssh-5.2.1/doc/html/ssh.html @@ -3655,14 +3655,14 @@

    double_algs(AlgType)

    List of algorithms to use in the algorithm negotiation. The default algs_list/0 can be obtained from default_algorithms/0.

    If an alg_entry() is missing in the algs_list(), the default value is used for -that entry.

    Here is an example of this option:

    	  {preferred_algorithms,
    -	  [{public_key,['ssh-rsa','ssh-dss']},
    -	  {cipher,[{client2server,['aes128-ctr']},
    -          {server2client,['aes128-cbc','3des-cbc']}]},
    -	  {mac,['hmac-sha2-256','hmac-sha1']},
    -	  {compression,[none,zlib]}
    -	  ]
    -	  }

    The example specifies different algorithms in the two directions (client2server +that entry.

    Here is an example of this option:

    	  {preferred_algorithms,
    +	  [{public_key,['ssh-rsa','ssh-dss']},
    +	  {cipher,[{client2server,['aes128-ctr']},
    +          {server2client,['aes128-cbc','3des-cbc']}]},
    +	  {mac,['hmac-sha2-256','hmac-sha1']},
    +	  {compression,[none,zlib]}
    +	  ]
    +	  }

    The example specifies different algorithms in the two directions (client2server and server2client), for cipher but specifies the same algorithms for mac and compression in both directions. The kex (key exchange) is implicit but public_key is set explicitly.

    For background and more examples see the @@ -5559,21 +5559,21 @@

    hostkey_fingerprint(TypeOrTypes, Key)

    hostkey_fingerprint([DigestType], HostKey) -> [string()]hostkey_fingerprint(DigestType, HostKey) -> string()

    Calculates a ssh fingerprint from a public host key as openssh does.

    The algorithm in hostkey_fingerprint/1 is md5 to be compatible with older ssh-keygen commands. The string from the second variant is -prepended by the algorithm name in uppercase as in newer ssh-keygen commands.

    Examples:

     2> ssh:hostkey_fingerprint(Key).
    +prepended by the algorithm name in uppercase as in newer ssh-keygen commands.

    Examples:

     2> ssh:hostkey_fingerprint(Key).
      "f5:64:a6:c1:5a:cb:9f:0a:10:46:a2:5c:3e:2f:57:84"
     
    - 3> ssh:hostkey_fingerprint(md5,Key).
    + 3> ssh:hostkey_fingerprint(md5,Key).
      "MD5:f5:64:a6:c1:5a:cb:9f:0a:10:46:a2:5c:3e:2f:57:84"
     
    - 4> ssh:hostkey_fingerprint(sha,Key).
    + 4> ssh:hostkey_fingerprint(sha,Key).
      "SHA1:bSLY/C4QXLDL/Iwmhyg0PGW9UbY"
     
    - 5> ssh:hostkey_fingerprint(sha256,Key).
    + 5> ssh:hostkey_fingerprint(sha256,Key).
      "SHA256:aZGXhabfbf4oxglxltItWeHU7ub3Dc31NcNw2cMJePQ"
     
    - 6> ssh:hostkey_fingerprint([sha,sha256],Key).
    - ["SHA1:bSLY/C4QXLDL/Iwmhyg0PGW9UbY",
    -  "SHA256:aZGXhabfbf4oxglxltItWeHU7ub3Dc31NcNw2cMJePQ"]
    +
    6> ssh:hostkey_fingerprint([sha,sha256],Key). + ["SHA1:bSLY/C4QXLDL/Iwmhyg0PGW9UbY", + "SHA256:aZGXhabfbf4oxglxltItWeHU7ub3Dc31NcNw2cMJePQ"]
    diff --git a/prs/8803/lib/ssh-5.2.1/doc/html/ssh_agent.html b/prs/8803/lib/ssh-5.2.1/doc/html/ssh_agent.html index 9bdfd0dd0c497..6ceee40492d96 100644 --- a/prs/8803/lib/ssh-5.2.1/doc/html/ssh_agent.html +++ b/prs/8803/lib/ssh-5.2.1/doc/html/ssh_agent.html @@ -135,11 +135,11 @@

    authentication.

    Ssh_agent implements the ssh_client_key_api, to allow it to be used by setting the option key_cb when starting a client (with for example ssh:connect, -ssh:shell ).

          {key_cb, {ssh_agent, []}}

    The agent communication is established through a UNIX domain socket. By default, +ssh:shell ).

          {key_cb, {ssh_agent, []}}

    The agent communication is established through a UNIX domain socket. By default, the socket path will be fetched from the SSH_AUTH_SOCK environment variable, which is the default socket path in the agent implementation of OpenSSH.

    In order to set a different socket path the socket_path -option can be set.

          {key_cb, {ssh_agent, [{socket_path, SocketPath}]}}

    Note

    The functions are Callbacks for the SSH app. They are not intended to be +option can be set.

          {key_cb, {ssh_agent, [{socket_path, SocketPath}]}}

    Note

    The functions are Callbacks for the SSH app. They are not intended to be called from the user's code!

    diff --git a/prs/8803/lib/ssh-5.2.1/doc/html/using_ssh.html b/prs/8803/lib/ssh-5.2.1/doc/html/using_ssh.html index a5977e020dca5..87ff3152e23a7 100644 --- a/prs/8803/lib/ssh-5.2.1/doc/html/using_ssh.html +++ b/prs/8803/lib/ssh-5.2.1/doc/html/using_ssh.html @@ -140,9 +140,9 @@

    Using the Erlang ssh Terminal Client

    The user otptest, which has bash as default shell, uses the ssh:shell/1 -client to connect to the OpenSSH daemon running on a host called ssh.example.com:

    1> ssh:start().
    +client to connect to the OpenSSH daemon running on a host called ssh.example.com:

    1> ssh:start().
     ok
    -2> {ok, S} = ssh:shell("ssh.example.com").
    +2> {ok, S} = ssh:shell("ssh.example.com").
     otptest@ssh.example.com:> pwd
     /home/otptest
     otptest@ssh.example.com:> exit
    @@ -161,11 +161,11 @@ 

    [...] $bash> ssh-keygen -t rsa -f /tmp/otptest_user/.ssh/id_rsa [...]

    Step 2. Create the file /tmp/otptest_user/.ssh/authorized_keys and add the -content of /tmp/otptest_user/.ssh/id_rsa.pub.

    Step 3. Start the Erlang ssh daemon:

    1> ssh:start().
    +content of /tmp/otptest_user/.ssh/id_rsa.pub.

    Step 3. Start the Erlang ssh daemon:

    1> ssh:start().
     ok
    -2> {ok, Sshd} = ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
    -                                  {user_dir, "/tmp/otptest_user/.ssh"}]).
    -{ok,<0.54.0>}
    +2> {ok, Sshd} = ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
    +                                  {user_dir, "/tmp/otptest_user/.ssh"}]).
    +{ok,<0.54.0>}
     3>

    Step 4. Use the OpenSSH client from a shell to connect to the Erlang ssh daemon:

    $bash> ssh ssh.example.com -p 8989  -i /tmp/otptest_user/.ssh/id_rsa \
                       -o UserKnownHostsFile=/tmp/otptest_user/.ssh/known_hosts
    @@ -176,10 +176,10 @@ 

    Eshell V5.10 (abort with ^G) 1>

    There are two ways of shutting down an ssh daemon, see Step 5a and Step 5b.

    Step 5a. Shut down the Erlang ssh daemon so that it stops the listener but -leaves existing connections, started by the listener, operational:

    3> ssh:stop_listener(Sshd).
    +leaves existing connections, started by the listener, operational:

    3> ssh:stop_listener(Sshd).
     ok
     4>

    Step 5b. Shut down the Erlang ssh daemon so that it stops the listener and -all connections started by the listener:

    3> ssh:stop_daemon(Sshd).
    +all connections started by the listener:

    3> ssh:stop_daemon(Sshd).
     ok
     4>

    @@ -195,35 +195,35 @@

    In the following example, the Erlang shell is the client process that receives the channel replies as Erlang messages.

    Do an one-time execution of a remote OS command ("pwd") over ssh to the ssh -server of the OS at the host "ssh.example.com":

    1> ssh:start().
    +server of the OS at the host "ssh.example.com":

    1> ssh:start().
     ok
    -2> {ok, ConnectionRef} = ssh:connect("ssh.example.com", 22, []).
    -{ok,<0.57.0>}
    -3> {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity).
    -{ok,0}
    -4> success = ssh_connection:exec(ConnectionRef, ChannelId, "pwd", infinity).
    -5> flush(). % Get all pending messages. NOTE: ordering may vary!
    -Shell got {ssh_cm,<0.57.0>,{data,0,0,<<"/home/otptest\n">>}}
    -Shell got {ssh_cm,<0.57.0>,{eof,0}}
    -Shell got {ssh_cm,<0.57.0>,{exit_status,0,0}}
    -Shell got {ssh_cm,<0.57.0>,{closed,0}}
    +2> {ok, ConnectionRef} = ssh:connect("ssh.example.com", 22, []).
    +{ok,<0.57.0>}
    +3> {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity).
    +{ok,0}
    +4> success = ssh_connection:exec(ConnectionRef, ChannelId, "pwd", infinity).
    +5> flush(). % Get all pending messages. NOTE: ordering may vary!
    +Shell got {ssh_cm,<0.57.0>,{data,0,0,<<"/home/otptest\n">>}}
    +Shell got {ssh_cm,<0.57.0>,{eof,0}}
    +Shell got {ssh_cm,<0.57.0>,{exit_status,0,0}}
    +Shell got {ssh_cm,<0.57.0>,{closed,0}}
     ok
    -6> ssh:connection_info(ConnectionRef, channels).
    -{channels,[]}
    +6> ssh:connection_info(ConnectionRef, channels).
    +{channels,[]}
     7>

    See ssh_connection and ssh_connection:exec/4 for finding documentation of the channel messages.

    To collect the channel messages in a program, use receive...end instead of flush/1:

    5> receive
    -5>     {ssh_cm, ConnectionRef, {data, ChannelId, Type, Result}} when Type == 0 ->
    -5>         {ok,Result}
    -5>     {ssh_cm, ConnectionRef, {data, ChannelId, Type, Result}} when Type == 1 ->
    -5>         {error,Result}
    +5>     {ssh_cm, ConnectionRef, {data, ChannelId, Type, Result}} when Type == 0 ->
    +5>         {ok,Result}
    +5>     {ssh_cm, ConnectionRef, {data, ChannelId, Type, Result}} when Type == 1 ->
    +5>         {error,Result}
     5> end.
    -{ok,<<"/home/otptest\n">>}
    +{ok,<<"/home/otptest\n">>}
     6>

    Note that only the exec channel is closed after the one-time execution. The connection is still up and can handle previously opened channels. It is also possible to open a new channel:

    % try to open a new channel to check if the ConnectionRef is still open
    -7> {ok, NewChannelId} = ssh_connection:session_channel(ConnectionRef, infinity).
    -{ok,1}
    +7> {ok, NewChannelId} = ssh_connection:session_channel(ConnectionRef, infinity).
    +{ok,1}
     8>

    To close the connection, call the function ssh:close(ConnectionRef). As an alternative, set the option {idle_time, 1} when opening the @@ -238,23 +238,23 @@

    "command" must be as if entered into the erlang shell, that is a sequence of Erlang expressions ended by a period (.). Variables bound in that sequence will keep their bindings throughout the expression -sequence. The bindings are disposed when the result is returned.

    Here is an example of a suitable expression sequence:

    A=1, B=2, 3 == (A + B).

    It evaluates to true if submitted to the Erlang daemon started in +sequence. The bindings are disposed when the result is returned.

    Here is an example of a suitable expression sequence:

    A=1, B=2, 3 == (A + B).

    It evaluates to true if submitted to the Erlang daemon started in Step 3 above:

    $bash> ssh ssh.example.com -p 8989 "A=1, B=2, 3 == (A + B)."
     true
     $bash>

    The same example but now using the Erlang ssh client to contact the Erlang -server:

    1> {ok, ConnectionRef} = ssh:connect("ssh.example.com", 8989, []).
    -{ok,<0.216.0>}
    -2> {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity).
    -{ok,0}
    -3> success = ssh_connection:exec(ConnectionRef, ChannelId,
    +server:

    1> {ok, ConnectionRef} = ssh:connect("ssh.example.com", 8989, []).
    +{ok,<0.216.0>}
    +2> {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity).
    +{ok,0}
    +3> success = ssh_connection:exec(ConnectionRef, ChannelId,
                                      "A=1, B=2, 3 == (A + B).",
    -                                 infinity).
    +                                 infinity).
     success
    -4> flush().
    -Shell got {ssh_cm,<0.216.0>,{data,0,0,<<"true">>}}
    -Shell got {ssh_cm,<0.216.0>,{exit_status,0,0}}
    -Shell got {ssh_cm,<0.216.0>,{eof,0}}
    -Shell got {ssh_cm,<0.216.0>,{closed,0}}
    +4> flush().
    +Shell got {ssh_cm,<0.216.0>,{data,0,0,<<"true">>}}
    +Shell got {ssh_cm,<0.216.0>,{exit_status,0,0}}
    +Shell got {ssh_cm,<0.216.0>,{eof,0}}
    +Shell got {ssh_cm,<0.216.0>,{closed,0}}
     ok
     5>

    Note that Erlang shell specific functions and control sequences like for example h(). are not supported.

    @@ -275,36 +275,36 @@

    write something: [a,b,c]. {ok,[a,b,c]} $bash>

    The same example but using the Erlang ssh client:

    
    -Eshell V10.5.2  (abort with ^G)
    -1> ssh:start().
    +Eshell V10.5.2  (abort with ^G)
    +1> ssh:start().
     ok
    -2> {ok, ConnectionRef} = ssh:connect(loopback, 8989, []).
    -{ok,<0.92.0>}
    -3> {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity).
    -{ok,0}
    -4> success = ssh_connection:exec(ConnectionRef, ChannelId,
    +2> {ok, ConnectionRef} = ssh:connect(loopback, 8989, []).
    +{ok,<0.92.0>}
    +3> {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity).
    +{ok,0}
    +4> success = ssh_connection:exec(ConnectionRef, ChannelId,
                                      "io:read(\"write something: \").",
    -                                 infinity).
    +                                 infinity).
     success
    -5> flush().
    -Shell got {ssh_cm,<0.92.0>,{data,0,0,<<"write something: ">>}}
    +5> flush().
    +Shell got {ssh_cm,<0.92.0>,{data,0,0,<<"write something: ">>}}
     ok
     % All data is sent as binaries with string contents:
    -6> ok = ssh_connection:send(ConnectionRef, ChannelId, <<"[a,b,c].">>).
    +6> ok = ssh_connection:send(ConnectionRef, ChannelId, <<"[a,b,c].">>).
     ok
    -7> flush().
    +7> flush().
     ok
     %% Nothing is received, because the io:read/1
     %% requires the input line to end with a newline.
     
     %% Send a newline (it could have been included in the last send):
    -8> ssh_connection:send(ConnectionRef, ChannelId, <<"\n">>).
    +8> ssh_connection:send(ConnectionRef, ChannelId, <<"\n">>).
     ok
    -9> flush().
    -Shell got {ssh_cm,<0.92.0>,{data,0,0,<<"{ok,[a,b,c]}">>}}
    -Shell got {ssh_cm,<0.92.0>,{exit_status,0,0}}
    -Shell got {ssh_cm,<0.92.0>,{eof,0}}
    -Shell got {ssh_cm,<0.92.0>,{closed,0}}
    +9> flush().
    +Shell got {ssh_cm,<0.92.0>,{data,0,0,<<"{ok,[a,b,c]}">>}}
    +Shell got {ssh_cm,<0.92.0>,{exit_status,0,0}}
    +Shell got {ssh_cm,<0.92.0>,{eof,0}}
    +Shell got {ssh_cm,<0.92.0>,{closed,0}}
     ok
     10>

    @@ -321,44 +321,44 @@

    ssh:daemon/2,3 and exec_daemon_option() for details.

    Examples of the two ways to configure the exec evaluator:

    1. Disable one-time execution.
      To modify the daemon start example above to reject one-time execution requests, we change Step 3 by adding the -option {exec, disabled} to:
    1> ssh:start().
    +option {exec, disabled} to:
    1> ssh:start().
     ok
    -2> {ok, Sshd} = ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
    -                                  {user_dir, "/tmp/otptest_user/.ssh"},
    -                                  {exec, disabled}
    -                                 ]).
    -{ok,<0.54.0>}
    +2> {ok, Sshd} = ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
    +                                  {user_dir, "/tmp/otptest_user/.ssh"},
    +                                  {exec, disabled}
    +                                 ]).
    +{ok,<0.54.0>}
     3>

    A call to that daemon will return the text "Prohibited." on stderr (depending on the client and OS), and the exit status 255:

    $bash> ssh ssh.example.com -p 8989 "test."
     Prohibited.
     $bash> echo $?
     255
     $bash>

    And the Erlang client library also returns the text "Prohibited." on data type 1 -instead of the normal 0 and exit status 255:

    2> {ok, ConnectionRef} = ssh:connect(loopback, 8989, []).
    -{ok,<0.92.0>}
    -3> {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity).
    -{ok,0}
    -4> success = ssh_connection:exec(ConnectionRef, ChannelId, "test."
    +instead of the normal 0 and exit status 255:

    2> {ok, ConnectionRef} = ssh:connect(loopback, 8989, []).
    +{ok,<0.92.0>}
    +3> {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity).
    +{ok,0}
    +4> success = ssh_connection:exec(ConnectionRef, ChannelId, "test."
     success
    -5> flush().
    -Shell got {ssh_cm,<0.106.0>,{data,0,1,<<"Prohibited.">>}}
    -Shell got {ssh_cm,<0.106.0>,{exit_status,0,255}}
    -Shell got {ssh_cm,<0.106.0>,{eof,0}}
    -Shell got {ssh_cm,<0.106.0>,{closed,0}}
    +5> flush().
    +Shell got {ssh_cm,<0.106.0>,{data,0,1,<<"Prohibited.">>}}
    +Shell got {ssh_cm,<0.106.0>,{exit_status,0,255}}
    +Shell got {ssh_cm,<0.106.0>,{eof,0}}
    +Shell got {ssh_cm,<0.106.0>,{closed,0}}
     ok
    -6>
    1. Install an alternative evaluator.
      Start the damon with a reference to a fun() that handles the evaluation:
    1> ssh:start().
    +6>
    1. Install an alternative evaluator.
      Start the damon with a reference to a fun() that handles the evaluation:
    1> ssh:start().
     ok
    -2> MyEvaluator = fun("1") -> {ok, some_value};
    -                    ("2") -> {ok, some_other_value};
    -                    ("3") -> {ok, V} = io:read("input erlang term>> "),
    -                             {ok, V};
    -                    (Err) -> {error,{bad_input,Err}}
    +2> MyEvaluator = fun("1") -> {ok, some_value};
    +                    ("2") -> {ok, some_other_value};
    +                    ("3") -> {ok, V} = io:read("input erlang term>> "),
    +                             {ok, V};
    +                    (Err) -> {error,{bad_input,Err}}
                      end.
    -3> {ok, Sshd} = ssh:daemon(1234, [{system_dir, "/tmp/ssh_daemon"},
    -                                  {user_dir, "/tmp/otptest_user/.ssh"},
    -                                  {exec, {direct,MyEvaluator}}
    -                                 ]).
    -{ok,<0.275.0>}
    +3> {ok, Sshd} = ssh:daemon(1234, [{system_dir, "/tmp/ssh_daemon"},
    +                                  {user_dir, "/tmp/otptest_user/.ssh"},
    +                                  {exec, {direct,MyEvaluator}}
    +                                 ]).
    +{ok,<0.275.0>}
     4>

    and call it:

    $bash> ssh localhost -p 1234 1
     some_value
     $bash> ssh localhost -p 1234 2
    @@ -372,17 +372,17 @@ 

    **Error** {bad_input,"1+ 2."} $bash>

    Note that spaces are preserved and that no point (.) is needed at the end - that was required by the default evaluator.

    The error return in the Erlang client (The text as data type 1 and exit_status -255):

    2> {ok, ConnectionRef} = ssh:connect(loopback, 1234, []).
    -{ok,<0.92.0>}
    -3> {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity).
    -{ok,0}
    -4> success = ssh_connection:exec(ConnectionRef, ChannelId, "1+ 2.").
    +255):

    2> {ok, ConnectionRef} = ssh:connect(loopback, 1234, []).
    +{ok,<0.92.0>}
    +3> {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity).
    +{ok,0}
    +4> success = ssh_connection:exec(ConnectionRef, ChannelId, "1+ 2.").
     success
    -5> flush().
    -Shell got {ssh_cm,<0.106.0>,{data,0,1,<<"**Error** {bad_input,\"1+ 2.\"}">>}}
    -Shell got {ssh_cm,<0.106.0>,{exit_status,0,255}}
    -Shell got {ssh_cm,<0.106.0>,{eof,0}}
    -Shell got {ssh_cm,<0.106.0>,{closed,0}}
    +5> flush().
    +Shell got {ssh_cm,<0.106.0>,{data,0,1,<<"**Error** {bad_input,\"1+ 2.\"}">>}}
    +Shell got {ssh_cm,<0.106.0>,{exit_status,0,255}}
    +Shell got {ssh_cm,<0.106.0>,{eof,0}}
    +Shell got {ssh_cm,<0.106.0>,{closed,0}}
     ok
     6>

    The fun() in the exec option could take up to three arguments (Cmd, User and ClientAddress). See the @@ -394,14 +394,14 @@

    SFTP Server

    -

    Start the Erlang ssh daemon with the SFTP subsystem:

    1> ssh:start().
    +

    Start the Erlang ssh daemon with the SFTP subsystem:

    1> ssh:start().
     ok
    -2> ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
    -                     {user_dir, "/tmp/otptest_user/.ssh"},
    -                     {subsystems, [ssh_sftpd:subsystem_spec(
    -                                            [{cwd, "/tmp/sftp/example"}])
    -                                  ]}]).
    -{ok,<0.54.0>}
    +2> ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
    +                     {user_dir, "/tmp/otptest_user/.ssh"},
    +                     {subsystems, [ssh_sftpd:subsystem_spec(
    +                                            [{cwd, "/tmp/sftp/example"}])
    +                                  ]}]).
    +{ok,<0.54.0>}
     3>

    Run the OpenSSH SFTP client:

    $bash> sftp -oPort=8989 -o IdentityFile=/tmp/otptest_user/.ssh/id_rsa \
                 -o UserKnownHostsFile=/tmp/otptest_user/.ssh/known_hosts ssh.example.com
     Connecting to ssh.example.com...
    @@ -413,12 +413,12 @@ 

    SFTP Client

    -

    Fetch a file with the Erlang SFTP client:

    1> ssh:start().
    +

    Fetch a file with the Erlang SFTP client:

    1> ssh:start().
     ok
    -2> {ok, ChannelPid, Connection} = ssh_sftp:start_channel("ssh.example.com", []).
    -{ok,<0.57.0>,<0.51.0>}
    -3> ssh_sftp:read_file(ChannelPid, "/home/otptest/test.txt").
    -{ok,<<"This is a test file\n">>}

    +2> {ok, ChannelPid, Connection} = ssh_sftp:start_channel("ssh.example.com", []). +{ok,<0.57.0>,<0.51.0>} +3> ssh_sftp:read_file(ChannelPid, "/home/otptest/test.txt"). +{ok,<<"This is a test file\n">>}

    @@ -430,17 +430,17 @@

    Basic example

    -

    This is an example of writing and then reading a tar file:

    {ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write]),
    -ok = erl_tar:add(HandleWrite, .... ),
    -ok = erl_tar:add(HandleWrite, .... ),
    +

    This is an example of writing and then reading a tar file:

    {ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write]),
    +ok = erl_tar:add(HandleWrite, .... ),
    +ok = erl_tar:add(HandleWrite, .... ),
     ...
    -ok = erl_tar:add(HandleWrite, .... ),
    -ok = erl_tar:close(HandleWrite),
    +ok = erl_tar:add(HandleWrite, .... ),
    +ok = erl_tar:close(HandleWrite),
     
     %% And for reading
    -{ok,HandleRead} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [read]),
    -{ok,NameValueList} = erl_tar:extract(HandleRead,[memory]),
    -ok = erl_tar:close(HandleRead),

    +{ok,HandleRead} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [read]), +{ok,NameValueList} = erl_tar:extract(HandleRead,[memory]), +ok = erl_tar:close(HandleRead),

    @@ -449,123 +449,123 @@

    The previous Basic example can be extended with encryption and decryption as follows:

    %% First three parameters depending on which crypto type we select:
     Key = <<"This is a 256 bit key. abcdefghi">>,
    -Ivec0 = crypto:strong_rand_bytes(16),
    +Ivec0 = crypto:strong_rand_bytes(16),
     DataSize = 1024,  % DataSize rem 16 = 0 for aes_cbc
     
     %% Initialization of the CryptoState, in this case it is the Ivector.
    -InitFun = fun() -> {ok, Ivec0, DataSize} end,
    +InitFun = fun() -> {ok, Ivec0, DataSize} end,
     
     %% How to encrypt:
     EncryptFun =
    -    fun(PlainBin,Ivec) ->
    -        EncryptedBin = crypto:block_encrypt(aes_cbc256, Key, Ivec, PlainBin),
    -        {ok, EncryptedBin, crypto:next_iv(aes_cbc,EncryptedBin)}
    +    fun(PlainBin,Ivec) ->
    +        EncryptedBin = crypto:block_encrypt(aes_cbc256, Key, Ivec, PlainBin),
    +        {ok, EncryptedBin, crypto:next_iv(aes_cbc,EncryptedBin)}
         end,
     
     %% What to do with the very last block:
     CloseFun =
    -    fun(PlainBin, Ivec) ->
    -        EncryptedBin = crypto:block_encrypt(aes_cbc256, Key, Ivec,
    -                                            pad(16,PlainBin) %% Last chunk
    -                                           ),
    -       {ok, EncryptedBin}
    +    fun(PlainBin, Ivec) ->
    +        EncryptedBin = crypto:block_encrypt(aes_cbc256, Key, Ivec,
    +                                            pad(16,PlainBin) %% Last chunk
    +                                           ),
    +       {ok, EncryptedBin}
         end,
     
    -Cw = {InitFun,EncryptFun,CloseFun},
    -{ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write,{crypto,Cw}]),
    -ok = erl_tar:add(HandleWrite, .... ),
    -ok = erl_tar:add(HandleWrite, .... ),
    +Cw = {InitFun,EncryptFun,CloseFun},
    +{ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write,{crypto,Cw}]),
    +ok = erl_tar:add(HandleWrite, .... ),
    +ok = erl_tar:add(HandleWrite, .... ),
     ...
    -ok = erl_tar:add(HandleWrite, .... ),
    -ok = erl_tar:close(HandleWrite),
    +ok = erl_tar:add(HandleWrite, .... ),
    +ok = erl_tar:close(HandleWrite),
     
     %% And for decryption (in this crypto example we could use the same InitFun
     %% as for encryption):
     DecryptFun =
    -    fun(EncryptedBin,Ivec) ->
    -        PlainBin = crypto:block_decrypt(aes_cbc256, Key, Ivec, EncryptedBin),
    -       {ok, PlainBin, crypto:next_iv(aes_cbc,EncryptedBin)}
    +    fun(EncryptedBin,Ivec) ->
    +        PlainBin = crypto:block_decrypt(aes_cbc256, Key, Ivec, EncryptedBin),
    +       {ok, PlainBin, crypto:next_iv(aes_cbc,EncryptedBin)}
         end,
     
    -Cr = {InitFun,DecryptFun},
    -{ok,HandleRead} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [read,{crypto,Cw}]),
    -{ok,NameValueList} = erl_tar:extract(HandleRead,[memory]),
    -ok = erl_tar:close(HandleRead),

    +Cr = {InitFun,DecryptFun}, +{ok,HandleRead} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [read,{crypto,Cw}]), +{ok,NameValueList} = erl_tar:extract(HandleRead,[memory]), +ok = erl_tar:close(HandleRead),

    Creating a Subsystem

    A small ssh subsystem that echoes N bytes can be implemented as shown in the -following example:

    -module(ssh_echo_server).
    --behaviour(ssh_server_channel). % replaces ssh_daemon_channel
    --record(state, {
    +following example:

    -module(ssh_echo_server).
    +-behaviour(ssh_server_channel). % replaces ssh_daemon_channel
    +-record(state, {
     	  n,
     	  id,
     	  cm
    -	 }).
    --export([init/1, handle_msg/2, handle_ssh_msg/2, terminate/2]).
    +	 }).
    +-export([init/1, handle_msg/2, handle_ssh_msg/2, terminate/2]).
     
    -init([N]) ->
    -    {ok, #state{n = N}}.
    +init([N]) ->
    +    {ok, #state{n = N}}.
     
    -handle_msg({ssh_channel_up, ChannelId, ConnectionManager}, State) ->
    -    {ok, State#state{id = ChannelId,
    -		     cm = ConnectionManager}}.
    +handle_msg({ssh_channel_up, ChannelId, ConnectionManager}, State) ->
    +    {ok, State#state{id = ChannelId,
    +		     cm = ConnectionManager}}.
     
    -handle_ssh_msg({ssh_cm, CM, {data, ChannelId, 0, Data}}, #state{n = N} = State) ->
    -    M = N - size(Data),
    +handle_ssh_msg({ssh_cm, CM, {data, ChannelId, 0, Data}}, #state{n = N} = State) ->
    +    M = N - size(Data),
         case M > 0 of
     	true ->
    -	   ssh_connection:send(CM, ChannelId, Data),
    -	   {ok, State#state{n = M}};
    +	   ssh_connection:send(CM, ChannelId, Data),
    +	   {ok, State#state{n = M}};
     	false ->
     	   <<SendData:N/binary, _/binary>> = Data,
    -           ssh_connection:send(CM, ChannelId, SendData),
    -           ssh_connection:send_eof(CM, ChannelId),
    -	   {stop, ChannelId, State}
    +           ssh_connection:send(CM, ChannelId, SendData),
    +           ssh_connection:send_eof(CM, ChannelId),
    +	   {stop, ChannelId, State}
         end;
    -handle_ssh_msg({ssh_cm, _ConnectionManager,
    -		{data, _ChannelId, 1, Data}}, State) ->
    -    error_logger:format(standard_error, " ~p~n", [binary_to_list(Data)]),
    -    {ok, State};
    +handle_ssh_msg({ssh_cm, _ConnectionManager,
    +		{data, _ChannelId, 1, Data}}, State) ->
    +    error_logger:format(standard_error, " ~p~n", [binary_to_list(Data)]),
    +    {ok, State};
     
    -handle_ssh_msg({ssh_cm, _ConnectionManager, {eof, _ChannelId}}, State) ->
    -    {ok, State};
    +handle_ssh_msg({ssh_cm, _ConnectionManager, {eof, _ChannelId}}, State) ->
    +    {ok, State};
     
    -handle_ssh_msg({ssh_cm, _, {signal, _, _}}, State) ->
    +handle_ssh_msg({ssh_cm, _, {signal, _, _}}, State) ->
         %% Ignore signals according to RFC 4254 section 6.9.
    -    {ok, State};
    +    {ok, State};
     
    -handle_ssh_msg({ssh_cm, _, {exit_signal, ChannelId, _, _Error, _}},
    -	       State) ->
    -    {stop, ChannelId,  State};
    +handle_ssh_msg({ssh_cm, _, {exit_signal, ChannelId, _, _Error, _}},
    +	       State) ->
    +    {stop, ChannelId,  State};
     
    -handle_ssh_msg({ssh_cm, _, {exit_status, ChannelId, _Status}}, State) ->
    -    {stop, ChannelId, State}.
    +handle_ssh_msg({ssh_cm, _, {exit_status, ChannelId, _Status}}, State) ->
    +    {stop, ChannelId, State}.
     
    -terminate(_Reason, _State) ->
    +terminate(_Reason, _State) ->
         ok.

    The subsystem can be run on the host ssh.example.com with the generated keys, as described in Section -Running an Erlang ssh Daemon:

    1> ssh:start().
    +Running an Erlang ssh Daemon:

    1> ssh:start().
     ok
    -2> ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
    -                     {user_dir, "/tmp/otptest_user/.ssh"}
    -                     {subsystems, [{"echo_n", {ssh_echo_server, [10]}}]}]).
    -{ok,<0.54.0>}
    -3>
    1> ssh:start().
    +2> ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
    +                     {user_dir, "/tmp/otptest_user/.ssh"}
    +                     {subsystems, [{"echo_n", {ssh_echo_server, [10]}}]}]).
    +{ok,<0.54.0>}
    +3>
    1> ssh:start().
     ok
    -2> {ok, ConnectionRef} = ssh:connect("ssh.example.com", 8989,
    -                                    [{user_dir, "/tmp/otptest_user/.ssh"}]).
    - {ok,<0.57.0>}
    -3> {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity).
    -4> success = ssh_connection:subsystem(ConnectionRef, ChannelId, "echo_n", infinity).
    -5> ok = ssh_connection:send(ConnectionRef, ChannelId, "0123456789", infinity).
    -6> flush().
    -{ssh_msg, <0.57.0>, {data, 0, 1, "0123456789"}}
    -{ssh_msg, <0.57.0>, {eof, 0}}
    -{ssh_msg, <0.57.0>, {closed, 0}}
    -7> {error, closed} = ssh_connection:send(ConnectionRef, ChannelId, "10", infinity).

    See also ssh_client_channel (replaces ssh_channel(3)).

    +2>
    {ok, ConnectionRef} = ssh:connect("ssh.example.com", 8989, + [{user_dir, "/tmp/otptest_user/.ssh"}]). + {ok,<0.57.0>} +3> {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity). +4> success = ssh_connection:subsystem(ConnectionRef, ChannelId, "echo_n", infinity). +5> ok = ssh_connection:send(ConnectionRef, ChannelId, "0123456789", infinity). +6> flush(). +{ssh_msg, <0.57.0>, {data, 0, 1, "0123456789"}} +{ssh_msg, <0.57.0>, {eof, 0}} +{ssh_msg, <0.57.0>, {closed, 0}} +7> {error, closed} = ssh_connection:send(ConnectionRef, ChannelId, "10", infinity).

    See also ssh_client_channel (replaces ssh_channel(3)).

    diff --git a/prs/8803/lib/ssl-11.2.1/doc/html/.build b/prs/8803/lib/ssl-11.2.1/doc/html/.build index 749d5a9c1de34..9e4a34816e8db 100644 --- a/prs/8803/lib/ssl-11.2.1/doc/html/.build +++ b/prs/8803/lib/ssl-11.2.1/doc/html/.build @@ -18,7 +18,7 @@ dist/lato-latin-ext-300-normal-VPGGJKJL.woff2 dist/lato-latin-ext-400-normal-N27NCBWW.woff2 dist/lato-latin-ext-700-normal-Q2L5DVMW.woff2 dist/remixicon-NKANDIL5.woff2 -dist/search_data-6435E30D.js +dist/search_data-731AC49D.js dist/sidebar_items-7FA2259C.js index.html notes.html diff --git a/prs/8803/lib/ssl-11.2.1/doc/html/dist/search_data-6435E30D.js b/prs/8803/lib/ssl-11.2.1/doc/html/dist/search_data-6435E30D.js deleted file mode 100644 index 29727fa6b58a2..0000000000000 --- a/prs/8803/lib/ssl-11.2.1/doc/html/dist/search_data-6435E30D.js +++ /dev/null @@ -1 +0,0 @@ -searchData={"items":[{"type":"module","doc":"Interface functions for TLS (Transport Layer Security)\nand DTLS (Datagram Transport Layer Security).\n\n> #### Note {: .info }\nThe application's name is still SSL because the first versions of the\nTLS protocol were named SSL (Secure Socket Layer). However, no version\nof the old SSL protocol is supported by this application.\n\nExample:\n```erlang\n1> ssl:start(), ssl:connect(\"google.com\", 443, [{verify, verify_peer},\n {cacerts, public_key:cacerts_get()}]).\n{ok,{sslsocket, [...]}}\n```\n\nSee [Examples](using_ssl.md) for detailed usage and more examples of\nthis API.\n\nSpecial Erlang node configuration for the application can be found in\n[SSL Application](ssl_app.md).","title":"ssl","ref":"ssl.html"},{"type":"function","doc":"Make `Deferred` suites become the least preferred suites.\n\nThe `Deferred` suites will be put at the end of the cipher suite list\n`Suites` after removing them from `Suites` if present. `Deferred` can\nbe a list of cipher suites or a list of filters in which case the\nfilters are used on `Suites` to extract the deferred cipher list.","title":"ssl.append_cipher_suites/2","ref":"ssl.html#append_cipher_suites/2"},{"type":"function","doc":"Lists all available cipher suites corresponding to `Description`.\n\nThe `exclusive` and `exclusive_anonymous` option will exclusively\nlist cipher suites first supported in `Version`, whereas the other options are\ninclusive from the lowest possible version to `Version`. The `all` option\nincludes all suites except anonymous suites. No anonymous suites are supported\nby default.\n\n> #### Note {: .info }\n>\n> TLS-1.3 has no overlapping cipher suites with previous TLS versions, meaning that\n> the result of [`cipher_suites(all, 'tlsv1.3')`](`cipher_suites/2`) contains a separate\n> set of suites that can be used with TLS-1.3 and another set that can be used if a lower\n> version is negotiated. The so-called `PSK` and `SRP` suites (prior to TLS-1.3)\n> need extra configuration to work; namely the option `user_lookup_function`. No\n> anonymous suites are supported by TLS-1.3.\n>\n> Also note that the cipher suites returned by this function are the cipher\n> suites that the OTP SSL application can support provided that they are\n> supported by the crypto library linked with the OTP Crypto application. Use\n> [`ssl:filter_cipher_suites(Suites, [])`](`filter_cipher_suites/2`) to filter\n> the list for the current crypto library. Note that cipher suites may be filtered\n> out because they are too old or too new depending on the crypto library.","title":"ssl.cipher_suites/2","ref":"ssl.html#cipher_suites/2"},{"type":"function","doc":"Equivalent to `cipher_suites/2`, but lists RFC or OpenSSL string names instead of\n[`erl_cipher_suite()`](`t:erl_cipher_suite/0`).","title":"ssl.cipher_suites/3","ref":"ssl.html#cipher_suites/3"},{"type":"function","doc":"Clears the PEM cache.\n\nPEM files, used by SSL API-functions, are cached for performance\nreasons. The cache is automatically checked at regular intervals to\ndetermine whether any cache entries should be invalidated.\n\nThis function provides a way to unconditionally clear the entire cache, thereby\nforcing a reload of previously cached PEM files.","title":"ssl.clear_pem_cache/0","ref":"ssl.html#clear_pem_cache/0"},{"type":"function","doc":"Closes a TLS/DTLS connection.","title":"ssl.close/1","ref":"ssl.html#close/1"},{"type":"function","doc":"Closes or downgrades a TLS connection.\n\nIn the latter case the transport connection will be handed over to the\n`NewController` process after receiving the TLS close alert from the\npeer. The returned transport socket will have the following options\nset: `[{active, false}, {packet, 0}, {mode, binary}]`.\n\nIn case of downgrade, the close function might return some binary data that\nshould be treated by the user as the first bytes received on the downgraded\nconnection.","title":"ssl.close/2","ref":"ssl.html#close/2"},{"type":"function","doc":"","title":"ssl.connect/2","ref":"ssl.html#connect/2"},{"type":"function","doc":"Opens a TLS/DTLS connection.\n\n```erlang\nconnect(TCPSocket, TLSOptions, Timeout).\n```\n\nUpgrades a `gen_tcp` (or equivalent) connected socket to a TLS socket by\nperforming the client-side TLS handshake.\n\n\n```erlang\nconnect(Host, Port, TLSOptions).\n```\n\nOpens a TLS/DTLS connection to `Host`, `Port`. This call is equivalent to:\n\n```erlang\nconnect(Host, Port, TLSOptions, infinity).\n```","title":"ssl.connect/3","ref":"ssl.html#connect/3"},{"type":"function","doc":"Opens a TLS/DTLS connection to `Host`, `Port`.\n\nWhen the `verify` option is set to `verify_peer`, the\n`public_key:pkix_verify_hostname/2` check will be performed in addition to the usual\nX.509-path validation checks. If the check fails, the error `{bad_cert,\nhostname_check_failed}` will be propagated to the path validation fun,\nwhere it is possible to do customized checks\nby using the full possibilities of the `public_key:pkix_verify_hostname/3` API.\nWhen the `server_name_indication` option is provided, its value (the DNS name)\nwill be used as `ReferenceID` to `public_key:pkix_verify_hostname/2`. When no\n`server_name_indication` option is given, the `Host` argument will be used as\nServer Name Indication extension. The `Host` argument will also be used for the\n`public_key:pkix_verify_hostname/2` check. If the `Host` argument is an\n[`inet:ip_address()`](`t:inet:ip_address/0`) the `ReferenceID` used for the\ncheck will be `{ip, Host}`; otherwise `dns_id` will be assumed with a fallback to\n`ip` if that fails.\n\n> #### Note {: .info }\n>\n> According to good practices, certificates should not use IP addresses as\n> \"server names\", especially outside a closed network.\n\nIf the `{handshake, hello}` option is used, the handshake is paused after\nreceiving the server hello message and the success response is\n`{ok, SslSocket, Ext}` instead of `{ok, SslSocket}`. Thereafter the handshake is\ncontinued or canceled by calling `handshake_continue/3` or `handshake_cancel/1`.\n\nIf the `active` option is set to `once`, `true`, or an integer value, the process\nowning the SSL socket will receive messages of type\n[`active_msgs()`](`t:active_msgs/0`).","title":"ssl.connect/4","ref":"ssl.html#connect/4"},{"type":"function","doc":"Returns the most relevant information about the connection.\n\nSome items that are undefined will be filtered out. No values\nthat affect the security of the connection will be returned.\n\n> #### Note {: .info }\n>\n> The legacy `cipher_suite` item was removed in OTP 23. Previously it returned\n> the cipher suite in its (undocumented) legacy format. It is replaced by\n> `selected_cipher_suite`.","title":"ssl.connection_information/1","ref":"ssl.html#connection_information/1"},{"type":"function","doc":"Returns the requested information items about the connection if they are\ndefined.\n\nNote that the values for `client_random`, `server_random`, `master_secret`, and `keylog`\naffect the security of connection.\n\nIn order to retrieve `keylog` and other secret information from a TLS 1.3\nconnection, the `keep_secrets` option must be configured in advance and\nset to `true`.\n\n> #### Note {: .info }\n>\n> If only undefined options are requested the resulting list can be empty.","title":"ssl.connection_information/2","ref":"ssl.html#connection_information/2"},{"type":"function","doc":"Assigns a new controlling process to the SSL socket.\n\nA controlling process is the owner of an SSL socket and receives all\nmessages from the socket.","title":"ssl.controlling_process/2","ref":"ssl.html#controlling_process/2"},{"type":"function","doc":"Returns a list of all supported elliptic curves, including legacy\ncurves, for all TLS/DTLS versions prior to TLS-1.3.","title":"ssl.eccs/0","ref":"ssl.html#eccs/0"},{"type":"function","doc":"Returns the elliptic curves supported by default for `Version`.\n\nThis is a subset of what `eccs/0` returns.","title":"ssl.eccs/1","ref":"ssl.html#eccs/1"},{"type":"function","doc":"","title":"ssl.export_key_materials/4","ref":"ssl.html#export_key_materials/4"},{"type":"function","doc":"Uses a Pseudo-Random Function (PRF prior to TLS-1.3) or a Key\nDerivation Function (HKDF in TLS-1.3) for a TLS connection to\ngenerate and export keying materials.\n\nIn TLS-1.3, using `no_context` is equivalent to specifying an empty\ncontext (an empty binary). Prior to TLS-1.3, `no_context` and an empty\ncontext will produce different results.\n\nThe `ConsumeSecret` argument is relevant only in TLS-1.3, causing the\nTLS-1.3 `exporter_master_secret` to be consumed, thereby making it\nunavailable and increasing security. Further attempts to call this\nfunction will fail.","title":"ssl.export_key_materials/5","ref":"ssl.html#export_key_materials/5"},{"type":"function","doc":"Removes cipher suites if any of the filter functions returns `false` for any part\nof the cipher suite.\n\nIf no filter function is supplied for some part, the default behavior\ntreats it as a filter function that returns `true`. For\nexamples, see [Customizing cipher suites\n](using_ssl.md#customizing-cipher-suites). Additionally, this function\nalso filters the cipher suites to exclude cipher suites not supported\nby the crypto library used by the OTP Crypto application, meaning that\n[`ssl:filter_cipher_suites(Suites, [])`](`filter_cipher_suites/2`)\nis equivalent to applying only the filters for crypto library support.","title":"ssl.filter_cipher_suites/2","ref":"ssl.html#filter_cipher_suites/2"},{"type":"function","doc":"Presents the error returned by an SSL function as a printable string.","title":"ssl.format_error/1","ref":"ssl.html#format_error/1"},{"type":"function","doc":"Gets the values of the specified socket options.","title":"ssl.getopts/2","ref":"ssl.html#getopts/2"},{"type":"function","doc":"Get statistics for the underlying socket.","title":"ssl.getstat/1","ref":"ssl.html#getstat/1"},{"type":"function","doc":"Get one or more statistic values for the underlying socket.\n\nSee `inet:getstat/2` for further details.","title":"ssl.getstat/2","ref":"ssl.html#getstat/2"},{"type":"function","doc":"Returns all supported groups in TLS 1.3.\n\nExisted since OTP 22.0; documented as of OTP 27.","title":"ssl.groups/0","ref":"ssl.html#groups/0"},{"type":"function","doc":"Returns default supported groups in TLS 1.3.\n\nExisted since OTP 22.0; documented as of OTP 27.","title":"ssl.groups/1","ref":"ssl.html#groups/1"},{"type":"function","doc":"","title":"ssl.handshake/1","ref":"ssl.html#handshake/1"},{"type":"function","doc":"Performs the TLS/DTLS server-side handshake.\n\nIf the second argument is a timeout value:\n\n```erlang\nhandshake(HsSocket, Timeout).\n```\n\nthis call is equivalent to:\n\n```erlang\nhandshake(HsSocket, [], Timeout).\n```\n\nOtherwise, if the second argument is a list of options:\n\n\n```erlang\nhandshake(HsSocket, Options).\n```\nthis call is equivalent to:\n\n```erlang\nhandshake(HsSocket, Options, infinity).\n```","title":"ssl.handshake/2","ref":"ssl.html#handshake/2"},{"type":"function","doc":"Performs the TLS/DTLS server-side handshake.\n\nReturns a new TLS/DTLS socket if the handshake is successful.\n\nIf `Socket` is a ordinary [`socket()`](`t:socket/0`), upgrades a\n`gen_tcp` or equivalent socket to an SSL socket by performing the\nTLS server-side handshake and returning a TLS socket.\n\n> #### Note {: .info }\nThe ordinary `Socket` must be in passive mode (`{active, false}`)\nbefore calling this function and before the client tries to connect\nwith TLS; otherwise, the behavior of this function is undefined. The\nbest way to ensure this is to create the ordinary listen socket in\npassive mode.\n\nIf `Socket` is an [`sslsocket()`](`t:sslsocket/0`), provides extra\nTLS/DTLS options to those specified in `listen/2` and then performs\nthe TLS/DTLS handshake. Returns a new TLS/DTLS socket if the handshake\nis successful.\n\n> #### Warning {: .warning }\nNot setting the timeout makes the server more vulnerable to Denial of\nService (DoS) attacks.\n\nIf option `{handshake, hello}` is specified the handshake is paused after\nreceiving the client hello message and the success response is\n`{ok, SslSocket, Ext}` instead of `{ok, SslSocket}`. Thereafter the handshake is\ncontinued or canceled by calling `handshake_continue/3` or `handshake_cancel/1`.\n\nIf option `active` is set to `once`, `true`, or an integer value, the process\nowning the [`sslsocket()`](`t:sslsocket/0`) will receive messages of type\n[`active_msgs()`](`t:active_msgs/0`).","title":"ssl.handshake/3","ref":"ssl.html#handshake/3"},{"type":"function","doc":"Cancel the handshake with a fatal `USER_CANCELED` alert.","title":"ssl.handshake_cancel/1","ref":"ssl.html#handshake_cancel/1"},{"type":"function","doc":"","title":"ssl.handshake_continue/2","ref":"ssl.html#handshake_continue/2"},{"type":"function","doc":"Continue the TLS handshake, possibly with new, additional, or changed options.","title":"ssl.handshake_continue/3","ref":"ssl.html#handshake_continue/3"},{"type":"function","doc":"Creates an SSL listen socket.","title":"ssl.listen/2","ref":"ssl.html#listen/2"},{"type":"function","doc":"Returns the protocol negotiated through ALPN or NPN extensions.","title":"ssl.negotiated_protocol/1","ref":"ssl.html#negotiated_protocol/1"},{"type":"function","doc":"The peer certificate is returned as a DER-encoded binary.\n\nThe certificate can be\ndecoded with `public_key:pkix_decode_cert/2`. Suggested further reading about\ncertificates is [Public_Key User's Guide](`e:public_key:public_key_records.md`)\nand [SSL User's Guide](standards_compliance.md).","title":"ssl.peercert/1","ref":"ssl.html#peercert/1"},{"type":"function","doc":"Returns the address and port number of the peer.","title":"ssl.peername/1","ref":"ssl.html#peername/1"},{"type":"function","doc":"Make `Preferred` suites become the most preferred suites.\n\nThe `Preferred` suites will be put at the head of the cipher suite\nlist `Suites` after removing them from `Suites` if\npresent. `Preferred` can be a list of cipher suites or a list of\nfilters in which case the filters are used on `Suites` to extract the\npreferred cipher list.","title":"ssl.prepend_cipher_suites/2","ref":"ssl.html#prepend_cipher_suites/2"},{"type":"function","doc":"Uses the Pseudo-Random Function (PRF) of a TLS session to generate extra key\nmaterial.\n\nIt either takes user-generated values for `Secret` and `Seed` or atoms\ndirecting it to use a specific value from the session security parameters.\n\n> #### Note {: .info }\n\nThis function is replaced by `export_key_materials/4`, the officially\ndocumented API function since OTP 27, which is equivalent to\n[`prf(TLSSocket, master_secret, Label, [client_random, server_random,\nContext], WantedLength)`](`prf/5`). Other ways of calling this\nfunction were for testing purposes only and has no use case. When\ncalled in a TLS-1.3 context it will now behave as\n[`export_key_materials(TLSSocket, [Label], [Context],\n[WantedLength])`](`export_key_materials/4`).","title":"ssl.prf/5","ref":"ssl.html#prf/5"},{"type":"function","doc":"","title":"ssl.recv/2","ref":"ssl.html#recv/2"},{"type":"function","doc":"Receives a packet from a socket in passive mode.\n\nA closed socket is indicated by return value `{error, closed}`.\nArgument `Length` is meaningful only when the socket is in mode `raw`\nand denotes the number of bytes to read. If `Length` is zero, all\navailable bytes are returned. If `Length` is greater than zero,\nexactly `Length` bytes are returned, or an error; possibly discarding\nless than `Length` bytes of data when the socket gets closed from\nthe other side.\n\nOptional argument `Timeout` specifies a time-out in milliseconds. The default\nvalue is `infinity`.","title":"ssl.recv/3","ref":"ssl.html#recv/3"},{"type":"function","doc":"Initiates a new handshake.\n\nA notable return value is `{error, renegotiation_rejected}` indicating\nthat the peer refused to go through with the renegotiation, but the\nconnection is still active using the previously negotiated session.\n\nTLS-1.3 has removed the renegotiation feature from earlier TLS\nversions and instead adds a new feature called key update, which\nreplaces the most important part of renegotiation: the refreshing of\nsession keys. This is triggered automatically after reaching a\nplaintext limit and can be configured using the `key_update_at` option\nin `t:common_option_tls13/0`.","title":"ssl.renegotiate/1","ref":"ssl.html#renegotiate/1"},{"type":"function","doc":"Writes `Data` to `SslSocket`.\n\nA notable return value is `{error, closed}` indicating that the socket is\nclosed.","title":"ssl.send/2","ref":"ssl.html#send/2"},{"type":"function","doc":"Sets options according to `Options` for socket `SslSocket`.","title":"ssl.setopts/2","ref":"ssl.html#setopts/2"},{"type":"function","doc":"Immediately closes a socket in one or two directions.\n\n`How == write` means closing the socket for writing, but reading from\nit is still possible.\n\nTo handle siutations where the peer has performed a shutdown on the\nwrite side, option `{exit_on_close, false}` is useful.","title":"ssl.shutdown/2","ref":"ssl.html#shutdown/2"},{"type":"function","doc":"Lists all available signature algorithms corresponding to `Description`.\n\nThe `exclusive` option will exclusively list algorithms or algorithm schemes for\nthat protocol version, whereas the `default` and `all` options lists the\ncombined list to support the range of protocols from (D)TLS-1.2, the first\nversion to support configuration of the signature algorithms, to `Version`.\n\nExample:\n\n```erlang\n1> ssl:signature_algs(default, 'tlsv1.3').\n[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,\necdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,\nrsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,\nrsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,\nrsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256,\n{sha512,ecdsa},\n{sha384,ecdsa},\n{sha256,ecdsa}]\n\n2> ssl:signature_algs(all, 'tlsv1.3').\n[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,\necdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,\nrsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,\nrsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,\nrsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256,\n{sha512,ecdsa},\n{sha384,ecdsa},\n{sha256,ecdsa},\n{sha224,ecdsa},\n{sha224,rsa},\n{sha,rsa},\n{sha,dsa}]\n\n3> ssl:signature_algs(exclusive, 'tlsv1.3').\n[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,\necdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,\nrsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,\nrsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256]\n```\n\n> #### Note {: .info }\n>\n> Some TLS-1-3 scheme names overlap with TLS-1.2 algorithm-tuple-pair-names and\n> then TLS-1.3 names will be used, for example `rsa_pkcs1_sha256` instead of\n> `{sha256, rsa}`. These are legacy algorithms in TLS-1.3 that apply only to\n> certificate signatures in this version of the protocol.","title":"ssl.signature_algs/2","ref":"ssl.html#signature_algs/2"},{"type":"function","doc":"Returns the local address and port number of socket `SslSocket`.","title":"ssl.sockname/1","ref":"ssl.html#sockname/1"},{"type":"function","doc":"","title":"ssl.start/0","ref":"ssl.html#start/0"},{"type":"function","doc":"Starts the SSL application.","title":"ssl.start/1","ref":"ssl.html#start/1"},{"type":"function","doc":"Stops the SSL application.","title":"ssl.stop/0","ref":"ssl.html#stop/0"},{"type":"function","doc":"Converts an RFC or OpenSSL name string to an `t:erl_cipher_suite/0`\n\nReturns an error if the cipher suite is not supported or the name is\nnot a valid cipher suite name.","title":"ssl.str_to_suite/1","ref":"ssl.html#str_to_suite/1"},{"type":"function","doc":"Converts an [`erl_cipher_suite()`](`t:erl_cipher_suite/0`) value to\nan OpenSSL name string.\n\nPRE TLS-1.3 these names differ for RFC names","title":"ssl.suite_to_openssl_str/1","ref":"ssl.html#suite_to_openssl_str/1"},{"type":"function","doc":"Converts an [`erl_cipher_suite()`](`t:erl_cipher_suite/0`) value to an RFC\nname string.","title":"ssl.suite_to_str/1","ref":"ssl.html#suite_to_str/1"},{"type":"function","doc":"","title":"ssl.transport_accept/1","ref":"ssl.html#transport_accept/1"},{"type":"function","doc":"Accepts an incoming connection request on a listen socket.\n\n`ListenSocket` must be a socket returned from `listen/2`. The socket\nreturned is to be passed to [`handshake/1,2,3`](`handshake/3`) to\ncomplete the handshake and establish the TLS/DTLS connection.\n\n> #### Warning {: .warning }\n>\n> Most API functions require that the TLS/DTLS connection is established to work\n> as expected.\n\nThe accepted socket inherits the options set for `ListenSocket` in `listen/2`.\n\nThe default value for `Timeout` is `infinity`. If `Timeout` is specified and no\nconnection is accepted within the given time, `{error, timeout}` is returned.","title":"ssl.transport_accept/2","ref":"ssl.html#transport_accept/2"},{"type":"function","doc":"Create new session keys.\n\nThere are cryptographic limits on the amount of plaintext which can be safely\nencrypted under a given set of keys. If the amount of data surpasses those\nlimits, a key update is triggered and a new set of keys are installed. See also\nthe `key_update_at` option in `t:common_option_tls13/0`.\n\nThis function can be used to explicitly start a key update on a TLS-1.3\nconnection. There are two types of key updates: if `Type` is `write`,\nonly the writing key is updated; if `Type` is `read_write`, both the\nreading and writing keys are updated.","title":"ssl.update_keys/2","ref":"ssl.html#update_keys/2"},{"type":"function","doc":"Lists information, mainly concerning TLS/DTLS versions, in runtime for debugging\nand testing purposes.\n\n- **`app_vsn`** - The application version of the SSL application.\n\n- **`supported`** - TLS versions supported with current application environment\n and crypto library configuration. Overridden by a version option on\n [`connect/2,3,4`](`connect/2`), `listen/2`, and\n [`handshake/2,3`](`handshake/2`). For the negotiated TLS version, see\n [`connection_information/1`](`connection_information/1`).\n\n- **`supported_dtls`** - DTLS versions supported with current application\n environment and crypto library configuration. Overridden by a version option\n on [`connect/2,3,4`](`connect/2`), `listen/2`, and\n [`handshake/2,3`](`handshake/2`). For the negotiated DTLS version, see\n [`connection_information/1`](`connection_information/1`).\n\n- **`available`** - All TLS versions supported with the linked crypto library.\n\n- **`available_dtls`** - All DTLS versions supported with the linked crypto\n library.\n\n- **`implemented`** - All TLS versions supported by the SSL application if\n linked with a crypto library with the necessary support.\n\n- **`implemented_dtls`** - All DTLS versions supported by the SSL application if\n linked with a crypto library with the necessary support.","title":"ssl.versions/0","ref":"ssl.html#versions/0"},{"type":"type","doc":"The type for the messages that are delivered to the owner of a\nTLS/DTLS socket in active mode.\n\nThe `ssl_passive` message is sent only when the socket is in `{active, N}` mode\nand the counter has dropped to 0. It indicates that the socket has transitioned\nto passive (`{active, false}`) mode.","title":"ssl.active_msgs/0","ref":"ssl.html#t:active_msgs/0"},{"type":"type","doc":"Claim an intermediate CA in the chain as trusted.\n\n```erlang\nfun(Chain::[public_key:der_encoded()]) ->\n {trusted_ca, DerCert::public_key:der_encoded()} | unknown_ca.\n```\n\nTLS then uses `public_key:pkix_path_validation/3` with the selected CA\nas the trusted anchor and verifies the rest of the chain.","title":"ssl.anchor_fun/0","ref":"ssl.html#t:anchor_fun/0"},{"type":"type","doc":"Configuration of the entity certificate and its corresponding key.\n\nA certificate (or possibly a list including the certificate and its\nchain certificates, where the entity certificate must be the first\nelement in the list or the first entry in the file) and its associated\nkey. For the PEM file format, there can also be a password associated\nwith the file containing the key.\n\nFor maximum interoperability, the certificates in the chain should be\nin the correct order, as the chain will be sent as-is to the peer. If\nchain certificates are not provided, certificates from the configured\ntrusted CA certificates will be used to construct the chain. See\n[`client_option_cert()`](`t:client_option_cert/0`) and\n[`server_option_cert()`](`t:server_option_cert/0`) for more\ninformation.","title":"ssl.cert_key_conf/0","ref":"ssl.html#t:cert_key_conf/0"},{"type":"type","doc":"Cipher algorithms that can be used for payload encryption.","title":"ssl.cipher/0","ref":"ssl.html#t:cipher/0"},{"type":"type","doc":"Filter that allows you to customize cipher suite list.","title":"ssl.cipher_filters/0","ref":"ssl.html#t:cipher_filters/0"},{"type":"type","doc":"A list of cipher suites that should be supported.\n\nFunction [ssl:cipher_suites/2 ](`cipher_suites/2`) can be used to find all\ncipher suites that are supported by default and all cipher suites that can be\nconfigured.\n\nIf you compose your own `t:cipher_suites/0` make sure they are\nfiltered for crypto library support using [ssl:filter_cipher_suites/2\n](`filter_cipher_suites/2`).\n\nThe following function can help creating customized cipher suite lists:\n\n- [ssl:append_cipher_suites/2 ](`append_cipher_suites/2`)\n- [ssl:prepend_cipher_suites/2](`prepend_cipher_suites/2`)\n- [ssl:suite_to_str/1](`suite_to_str/1`)\n- [ssl:str_to_suite/1](`str_to_suite/1`)\n- [ssl:suite_to_openssl_str/1](`suite_to_openssl_str/1`)\n\n> #### Note {: .info }\nNote that TLS-1.3 and TLS-1.2 use different sets of cipher suites. To\nsupport both versions, cipher suites from both sets need to be\nincluded. If the supplied list does not comply with the configured\nversions or crypto library, that is, resulting in an empty list, the option\nwill fall back to its appropriate default value for the configured\nversions.\n\nNon-default cipher suites, including anonymous cipher suites (prior to\nTLS 1.3), are supported for interoperability and testing\npurposes. These can be used by adding them to your cipher suite\nlist. Note that they also need to be supported and enabled by the peer\nto be actually used, and they may require additional configuration;\nsee [`srp_param_type()`](`t:srp_param_type/0`).","title":"ssl.cipher_suites/0","ref":"ssl.html#t:cipher_suites/0"},{"type":"type","doc":"Cipher suite formats.\n\nFor backwards compatibility, cipher suites can be configured as a\ncolon-separated string of cipher suite RFC names (or even old OpenSSL\nnames). However, a more flexible approach is to use utility functions\ntogether with [`cipher_filters()`](`t:cipher_filters/0`) if a customized\ncipher suite option is needed.","title":"ssl.ciphers/0","ref":"ssl.html#t:ciphers/0"},{"type":"type","doc":"The following options are specific to the client side, or have\ndifferent semantics for the client and server:\n\n- **`{alpn_advertised_protocols, AppProtocols}`** - Application layer protocol\n\n The list of protocols supported by the client to be sent to the server to be\n used for an Application-Layer Protocol Negotiation (ALPN). If the server\n supports ALPN, it will choose a protocol from this list; otherwise it will\n fail the connection with a `no_application_protocol` alert. A server that does\n not support ALPN will ignore this value. The list of protocols must not contain\n an empty binary.\n\n- **`{max_fragment_length, MaxLen}`** - Max fragment length extension\n\n Specifies the maximum fragment length the client is prepared to accept from the\n server. See [RFC 6066](http://www.ietf.org/rfc/rfc6066.txt).","title":"ssl.client_option/0","ref":"ssl.html#t:client_option/0"},{"type":"type","doc":"Certificate-related options specific to the client side, or with\ndifferent semantics for the client and server.\n\n- **`{verify, Verify}`** - Verification of certificates\n\n This option specifies whether certificates are to be verified.\n\n If `Verify` is `verify_peer`, which is the default, it is required\n to also provide one of the options `cacerts` or `cacertfile` in\n order for the certificate verification to succeed. For example, an\n HTTPS client can use option `{cacerts, public_key:cacerts_get()}` to\n use the trusted CA certificates provided by the operating system.\n\n If `Verify` is `verify_none`, all X.509-certificate path\n validation errors will be ignored.\n\n > #### Change {: .info }\n >\n > The default for `Verify` was changed to `verify_peer` in\n > Erlang/OTP 26.\n\n- **`{cacerts, CACerts}`** - Trusted certificates\n\n The DER-encoded trusted certificates. If this option is supplied it overrides\n option `cacertfile`.\n\n Function `public_key:cacerts_get/0` can be used to retrieve to the\n trusted CA certificates provided by the operating system.\n\n- **`{cacertfile, CertFile}`** - End entity certificate\n\n Path to a file containing PEM-encoded CA certificates. The CA certificates are\n used during server authentication and when building the client certificate\n chain.\n\n > #### Note {: .info }\n >\n > When PEM caching is enabled, files provided with this option will be checked\n > for updates at fixed time intervals specified by the\n > [ssl_pem_cache_clean](ssl_app.md#configuration) environment parameter.\n\n\n- **`{server_name_indication, SNI}`** - Server Name Indication extension\n\n Specify the hostname to be used in TLS Server Name Indication extension. If not\n specified it will default to the `Host` argument of\n [connect/3,4](`connect/3`) unless it is of type [`inet:ip_address()`](`t:inet:ip_address/0`).\n The hostname will also be used in the hostname verification of the peer\n certificate using `public_key:pkix_verify_hostname/2`.\n The special value `disable` prevents the Server Name Indication extension from\n being sent and disables the hostname verification check.\n\n- **`{customize_hostname_check, HostNameCheckOpts}`** - Customization option\n\n Customizes the hostname verification of the peer certificate, as various\n protocols that use TLS, such as HTTP or LDAP, may require different approaches. For\n example, here is how to use standard hostname checking for HTTPS implemented in\n [Public_Key](`e:public_key:public_key_app.md`):\n\n ```erlang\n {customize_hostname_check, [{match_fun, public_key:pkix_verify_hostname_match_fun(https)}]}\n ```\n\n For futher description of the customize options, see\n `public_key:pkix_verify_hostname/3`.\n\n- **`{client_certificate_authorities, UseCertAuth}`** - Inter-op hint option\n\n If `UseCertAuth` is set to `true`, sends the certificate authorities\n extension in the TLS-1.3 client hello. The default is `false`. Note\n that setting `UseCertAuth` to `true` can result in a significant\n overhead if there exists many trusted CA certificates. (Since\n Erlang/OTP 24.3.)\n\n- **`{stapling, Stapling}`** - Certificate revocation check option\n\n If `Stapling` is atom `staple` or a map, OCSP stapling will be\n enabled, meaning that an extension of type \"status_request\" will be\n included in the client hello to indicate the desire to receive\n certificate status information.\n\n If `Stapling` is set to `no_staple` (the default), OCSP stapling will be disabled.\n\n > #### Note {: .info }\n >\n > Even if requested by the client, the OCSP response might not be\n > provided by the server. In such event, SSL will proceed with\n > the handshake and generate a `{missing, stapling_response}` logger\n > event.\n\n When `Stapling` is given as a map, boolean `ocsp_nonce` key can\n indicate whether an OCSP nonce should be requested by the client\n (default is `false`).\n\n > #### Note {: .info }\n >\n > The OCSP response can be provided without a nonce value — even if it was requested\n > by the client. In such cases SSL will proceed with the handshake and generate\n > a `{missing, ocsp_nonce}` logger event.","title":"ssl.client_option_cert/0","ref":"ssl.html#t:client_option_cert/0"},{"type":"type","doc":"Legacy client options.\n\n- **`{client_preferred_next_protocols, NextAppProtocols}`** - Next Protocol Negotiation\n\n ALPN (Application-Layer Protocol Negotiation)\n deprecates NPN (Next Protocol Negotiation) and this option.\n\n Indicates that the client wants to perform Next Protocol Negotiation.\n\n If `Precedence` is `server`, the negotiated protocol is the first protocol to be\n shown on the server advertised list that is also on the client preference\n list.\n\n If `Precedence` is `client`, the negotiated protocol is the first protocol to be\n shown on the client preference list that is also on the server advertised\n list.\n\n If the client does not support any of the server advertised protocols or the\n server does not advertise any protocols, the client falls back to the first\n protocol in its list or to the default protocol (if a default is supplied). If\n the server does not support Next Protocol Negotiation, the connection terminates\n if no default protocol is supplied.","title":"ssl.client_option_legacy/0","ref":"ssl.html#t:client_option_legacy/0"},{"type":"type","doc":"Options only relevant to TLS versions prior to TLS-1.3.\n\n- **`{reuse_session, SessionRef}`** - Explicit session reuse\n\n Reuses a specific session.\n\n Since Erlang/OTP 21.3, if the session was saved earlier using option\n `{reuse_sessions, save}`, the session can be referred by its session ID.\n\n Since Erlang/OTP 22.3, the session can be explicitly specified by\n its session ID and associated data.\n\n See also\n [SSL User's Guide, Session Reuse pre TLS 1.3.](using_ssl.md#session-reuse-prior-to-tls-1-3)\n\n- **`{reuse_sessions, Reuse}`** - Enables later session reuse\n\n When `Reuse` is set to `save`, a new connection will be negotiated and saved for later\n reuse. The session ID can be fetched with `connection_information/2` and used\n with the client option `reuse_session`.\n\n When `Reuse` is set to `true`, automated session reuse will be\n performed, if possible. If a new session is created, and is unique in regard to previous\n stored sessions, it will be saved for possible later reuse.\n\n Since: OTP 21.3.\n\n- **`{psk_identity, PskID}`** - Option for use with PSK cipher suites\n\n Specifies the identity the client presents to the server. The matching secret is\n found by the fun given in the `user_lookup_fun` option.\n\n- **`{srp_identity, SrpID}`** - Option for use SRP cipher suites\n\n Specifies the username and password to use to authenticate to the server.\n\n- **`{fallback, LegacyFallback}`** - Inter-op legacy client option\n\n Send special cipher suite TLS_FALLBACK_SCSV to avoid an undesired TLS version\n downgrade. Defaults to `false`.\n\n > #### Warning {: .warning }\n >\n > This option is not needed in normal TLS usage and must not be used to\n > implement new clients. However, legacy clients that retries connections in the\n > following manner:\n >\n > `ssl:connect(Host, Port, [...{versions, ['tlsv2', 'tlsv1.1', 'tlsv1']}])`\n >\n > `ssl:connect(Host, Port, [...{versions, [tlsv1.1', 'tlsv1']}, {fallback, true}])`\n >\n > `ssl:connect(Host, Port, [...{versions, ['tlsv1']}, {fallback, true}])`\n >\n > can use it to avoid undesired TLS version downgrade. Note that\n > TLS_FALLBACK_SCSV must also be supported by the server for the prevention to\n > work.","title":"ssl.client_option_pre_tls13/0","ref":"ssl.html#t:client_option_pre_tls13/0"},{"type":"type","doc":"Options only relevant for TLS-1.3.\n\n- **`{session_tickets, SessionTickets}`** - Use of session tickets\n\n Configures the session ticket functionality. Allowed values are `disabled`,\n `manual`, and `auto`. If it is set to `manual` the client will send the ticket\n information to user process in a 3-tuple:\n\n ```erlang\n {ssl, session_ticket, {SNI, TicketData}}\n ```\n\n where `SNI` is the ServerNameIndication and `TicketData` is the extended ticket\n data that can be used in subsequent session resumptions.\n\n If it is set to `auto`, the client automatically handles received tickets and\n tries to use them when making new TLS connections (session resumption with\n pre-shared keys).\n\n Ticket lifetime, the number of tickets sent by the server, and the\n maximum number of tickets stored by the server in stateful mode are configured\n by [application variables](ssl_app.md#configuration).\n\n See also\n [SSL User's Guide, Session Tickets and Session Resumption in TLS 1.3](using_ssl.md#session-tickets-and-session-resumption-in-tls-1-3).\n\n- **`{use_ticket, Tickets}`**\n\n Configures the session tickets to be used for session resumption. It is a\n mandatory option in `manual` mode (`{session_tickets, manual}`).\n\n > #### Note {: .info }\n >\n > Session tickets are only sent to the user if option `session_tickets` is set to\n > `manual`\n >\n > This option is supported by TLS-1.3. See also\n > [SSL User's Guide, Session Tickets and Session Resumption in TLS 1.3](using_ssl.md#session-tickets-and-session-resumption-in-tls-1-3).\n\n- **`{early_data, EarlyData}`**\n\n Configures the early data to be sent by the client.\n\n To verify that the server has the intention to process the early\n data, the following tuple is sent to the user process:\n\n ```erlang\n {ssl, SslSocket, {early_data, Result}}\n ```\n\n where `Result` is either `accepted` or `rejected`.\n\n > #### Warning {: .warning }\n >\n > It is the responsibility of the user to handle rejected `EarlyData` and to\n > resend when appropriate.\n\n- **`{middlebox_comp_mode, MiddleBoxMode}`**\n\n Configures the middlebox compatibility mode for a TLS-1.3 connection.\n\n A significant number of middleboxes misbehave when a TLS-1.3\n connection is negotiated. Implementations can increase the chance of\n making connections through those middleboxes by adapting the TLS-1.3\n handshake to resemble that of a TLS-1.2 handshake.\n\n The middlebox compatibility mode is enabled (`true`) by default.","title":"ssl.client_option_tls13/0","ref":"ssl.html#t:client_option_tls13/0"},{"type":"type","doc":"Options common to both client and server side.\n\n- **`{protocol, Protocol}`** - Choose TLS or DTLS protocol for the transport layer security.\n\n Defaults to `tls`.\n\n- **`{handshake_completion, Completion}`** - Possibly pause handshake at hello stage.\n\n Defaults to `full`. If `hello` is specified the handshake will pause\n after the hello message, allowing the user to make decisions based\n on hello extensions before continuing or aborting the handshake by\n calling `handshake_continue/3` or `handshake_cancel/1`.\n\n- **`{keep_secrets, KeepSecrets}`** - Configures a TLS 1.3 connection for keylogging.\n\n In order to retrieve keylog information on a TLS 1.3 connection, it must be\n configured in advance to keep `client_random` and various handshake secrets.\n\n The `keep_secrets` functionality is disabled (`false`) by default.\n\n Added in OTP 23.2.\n\n- **`{handshake_size, HandshakeSize}`** - Limit the acceptable handshake packet size.\n\n Used to limit the size of valid TLS handshake packets to avoid DoS\n attacks.\n\n Integer (24 bits, unsigned). Defaults to `256*1024`.\n\n- **`{hibernate_after, HibernateTimeout}`** - Hibernate inactive connection processes.\n\n When an integer-value is specified, the TLS/DTLS connection goes into hibernation\n after the specified number of milliseconds of inactivity, thus reducing its\n memory footprint. When not specified the process never goes into hibernation.\n\n- **`{log_level, Level}`** - Specifies the log level for a TLS/DTLS connection.\n\n Alerts are logged on `notice`\n level, which is the default level. The level `debug` triggers verbose logging of\n TLS/DTLS protocol messages. See also [SSL Application](ssl_app.md)\n\n- **`{receiver|sender_spawn_opts, SpawnOpts}`** - Configure erlang spawn opts.\n\n Configures spawn options of TLS sender and receiver processes.\n\n Setting up garbage collection options can be helpful for trade-offs between CPU\n usage and memory usage. See `erlang:spawn_opt/2`.\n\n For connections using Erlang distribution, the default sender option\n is `[...{priority, max}]`; this priority option cannot be changed. For all\n connections, `...link` is added to receiver and cannot be changed.","title":"ssl.common_option/0","ref":"ssl.html#t:common_option/0"},{"type":"type","doc":"Common certificate related options to both client and server.\n\n- **`{certs_keys, CertsKeys}`** - At least one certificate and key pair.\n\n A list of a certificate (or possible a certificate and its chain)\n and the associated key of the certificate that can be used to\n authenticate the client or the server. The certificate key pair that\n is considered best and matches negotiated parameters for the\n connection will be selected.\n\n The different signature algorithms are prioritized in the following\n order: `eddsa`, `ecdsa`, `rsa_pss_pss`, `rsa`, and `dsa`. If more\n than one key is supplied for the same signature algorithm, they will\n be prioritized by strength (except for _engine keys_; see the next\n paragraph). This offers flexibility to, for instance, configure a\n newer certificate that is expected to be used in most cases, and an\n older but acceptable certificate that will only be used to\n communicate with legacy systems. Note that there is a trade off\n between the induced overhead and the flexibility; thus, alternatives\n should be chosen for good reasons.\n\n _Engine keys_ will be favored over other keys. As engine keys cannot\n be inspected, supplying more than one engine key makes no sense.\n\n When this option is specified it overrides all single certificate\n and key options. For examples, see the [User's Guide](using_ssl.md).\n\n > #### Note {: .info }\n >\n > `eddsa` certificates are only supported by TLS-1.3 implementations that do not support `dsa`\n > certificates. `rsa_pss_pss` (RSA certificates using Probabilistic Signature\n > Scheme) are supported in TLS-1.2 and TLS-1.3, but some TLS-1.2 implementations\n > do not support `rsa_pss_pss`.\n\n- **`{depth, AllowedCertChainLen}`** - Limits the accepted number of certificates in the certificate chain.\n\n Maximum number of non-self-issued intermediate certificates that can follow the\n peer certificate in a valid certification path. So, if depth is 0 the PEER must\n be signed by the trusted ROOT-CA directly; if 1 the path can be PEER, CA,\n ROOT-CA; if 2 the path can be PEER, CA, CA, ROOT-CA, and so on. The default\n value is 10. Used to mitigate DoS attack possibilities.\n\n- **`{verify_fun, Verify}`** - Customize certificate path validation\n\n The verification fun is to be defined as follows:\n\n ```erlang\n fun(OtpCert :: #'OTPCertificate'{},\n Event, InitialUserState :: term()) ->\n\t{valid, UserState :: term()} |\n\t{fail, Reason :: term()} | {unknown, UserState :: term()}.\n\n fun(OtpCert :: #'OTPCertificate'{}, DerCert :: public_key:der_encoded(),\n Event, InitialUserState :: term()) ->\n\t{valid, UserState :: term()} |\n\t{fail, Reason :: term()} | {unknown, UserState :: term()}.\n\n Types:\n Event = {bad_cert, Reason :: atom() |\n {revoked, atom()}} |\n\t\t{extension, #'Extension'{}} |\n valid |\n valid_peer\n ```\n\n The verification fun is called during the X.509-path validation when\n an error occurs or an extension unknown to the SSL application is\n encountered. It is also called when a certificate is considered\n valid by the path validation to allow access to each certificate in\n the path to the user application. It differentiates between the peer\n certificate and the CA certificates by using `valid_peer` or `valid`\n as `Event` argument to the verification fun. See the [Public_Key\n User's Guide](`e:public_key:public_key_records.md`) for definition\n of `#'OTPCertificate'{}` and `#'Extension'{}`.\n\n - If the verify callback fun returns `{fail, Reason}`, the verification process\n is immediately stopped, an alert is sent to the peer, and the TLS/DTLS\n handshake terminates.\n - If the verify callback fun returns `{valid, UserState}`, the verification\n process continues.\n - If the verify callback fun always returns `{valid, UserState}`, the TLS/DTLS\n handshake does not terminate regardless of verification failures, and the\n connection is established.\n - If called with an extension unknown to the user application, the fun is to\n return `{unknown, UserState}`.\n\n Note that if the fun returns `unknown` for an extension marked as critical,\n validation will fail.\n\n Default option `verify_fun` in `verify_peer mode`:\n\n ```erlang\n {fun(_, _, {bad_cert, _} = Reason, _) ->\n\t {fail, Reason};\n (_, _, {extension, _}, UserState) ->\n\t {unknown, UserState};\n (_, _, valid, UserState) ->\n\t {valid, UserState};\n (_, _, valid_peer, UserState) ->\n {valid, UserState}\n end, []}\n ```\n\n Default option `verify_fun` in mode `verify_none`:\n\n ```erlang\n {fun(_, _, {bad_cert, _}, UserState) ->\n\t {valid, UserState};\n (_, _, {extension, #'Extension'{critical = true}}, UserState) ->\n\t {valid, UserState};\n (_, _, {extension, _}, UserState) ->\n\t {unknown, UserState};\n (_, _, valid, UserState) ->\n\t {valid, UserState};\n (_, _, valid_peer, UserState) ->\n {valid, UserState}\n end, []}\n ```\n\n The possible path validation errors are given in the form `{bad_cert, Reason}`,\n where `Reason` is:\n\n - **`unknown_ca`**\n\n No trusted CA was found in the trusted store. The trusted\n CA is normally a so-called ROOT CA, which is a self-signed certificate. Trust\n can be claimed for an intermediate CA (the trusted anchor does not have to be\n self-signed according to X-509) by using option `partial_chain`.\n\n - **`selfsigned_peer`**\n\n The chain consisted only of one self-signed certificate.\n\n - **`PKIX X-509-path validation error`**\n\n For possible reasons, see `public_key:pkix_path_validation/3`.\n\n- **`{cert_policy_opts, PolicyOpts}`** - Handle certificate policies.\n\n Configure X.509 certificate policy handling for the certificate path validation process;\n see [public_key:pkix_path_validation/3](`public_key:pkix_path_validation/3`) for\n more details.\n\n- **`{cerl_check, Check}`** - Handle certificate revocation lists.\n\n Perform CRL (Certificate Revocation List) verification\n [(public_key:pkix_crls_validate/3)](`public_key:pkix_crls_validate/3`) on all\n the certificates during the path validation\n [(public_key:pkix_path_validation/3) ](`public_key:pkix_path_validation/3`)of\n the certificate chain. `Check` defaults to `false`.\n\n The meaning of `Check` is as follows:\n\n - **`false`**\n\n No checks are performed.\n\n - **`peer`**\n\n Check is only performed on the peer certificate.\n\n - **`best_effort`**\n\n If certificate revocation status cannot be determined it will be accepted as valid.\n\n The CA certificates specified for the connection will be used to construct the\n certificate chain validating the CRLs.\n\n The CRLs will be fetched from a local or external cache. See\n `m:ssl_crl_cache_api`.","title":"ssl.common_option_cert/0","ref":"ssl.html#t:common_option_cert/0"},{"type":"type","doc":"Common options to client and server only valid for DTLS.\n\n- **`{use_srtp, UseSrtp}`** - Configures the `use_srtp` DTLS hello extension.\n\n In order to negotiate the use of SRTP data protection, clients include an\n extension of type \"use_srtp\" in the DTLS extended client hello. This extension\n MUST only be used when the data being transported is RTP or RTCP.\n\n The value is a map with a mandatory `protection_profiles` parameter\n and an optional `mki` parameter.\n\n `protection_profiles` configures the list of the client's acceptable SRTP\n Protection Profiles. Each profile is a 2-byte binary. Example:\n `#{protection_profiles => [<<0,2>>, <<0,5>>]}`\n\n `mki` configures the SRTP Master Key Identifier chosen by the client.\n\n The `srtp_mki` field contains the value of the SRTP MKI which is associated with\n the SRTP master keys derived from this handshake. Each SRTP session MUST have\n exactly one master key that is used to protect packets at any given time. The\n client MUST choose the MKI value so that it is distinct from the last MKI value\n that was used, and it SHOULD make these values unique for the duration of the\n TLS session.\n\n > #### Note {: .info }\n >\n > OTP does not handle SRTP, so an external implementations of SRTP\n > encoder/decoder and a packet demultiplexer are needed to make use of the\n > `use_srtp` extension. See also option [transport_option](`t:transport_option/0`).\n\n Servers that receive an extended hello containing a \"use_srtp\" extension can\n agree to use SRTP by including an extension of type \"use_srtp\", with the chosen\n protection profile in the extended server hello. This extension MUST only be\n used when the data being transported is RTP or RTCP.","title":"ssl.common_option_dtls/0","ref":"ssl.html#t:common_option_dtls/0"},{"type":"type","doc":"Legacy options considered deprecated in favor of other options,\ninsecure to use, or plainly not relevant anymore.\n\n- **`{cert, Certs}`**\n\n Use option `certs_keys` instead.\n\n- **`{certfile, CertPem}`**\n\n Use option `certs_keys` instead.\n\n- **`{keyfile, KeyPem}`**\n\n Use option `certs_keys` instead.\n\n- **`{password, KeyPemPasswd}`**\n\n Use option `certs_keys` instead.\n\n- **`{log_alert, LogAlert}`**\n\n If `LogAlert` is `false`, TLS/DTLS Alert reports are not displayed. Deprecated in OTP\n 22; use `{log_level, Level}` instead.\n\n- **`{padding_check, PaddingCheck}`** - Inter-op trade-off option\n\n Affects TLS-1.0 connections only. If set to `false`, it disables the block\n cipher padding check to be able to interoperate with legacy software.\n\n > #### Warning {: .warning }\n >\n > Using `{padding_check, false}` makes TLS vulnerable to the Poodle attack.\n\n- **`{beast_mitigation, BeastMitigation}`** - Inter-op trade-off option\n\n Affects TLS-1.0 connections only. Used to change the BEAST mitigation strategy\n to interoperate with legacy software. Defaults to `one_n_minus_one`.\n\n `one_n_minus_one` - Perform `1/n-1` BEAST mitigation.\n\n `zero_n` - Perform `0/n` BEAST mitigation.\n\n `disabled` - Disable BEAST mitigation.\n\n > #### Warning {: .warning }\n >\n > Using `{beast_mitigation, disabled}` makes TLS-1.0 vulnerable to the BEAST\n > attack.\n\n- **`{ssl_imp, Imp}`**\n\n Deprecated since OTP 17; has no effect.","title":"ssl.common_option_legacy/0","ref":"ssl.html#t:common_option_legacy/0"},{"type":"type","doc":"Options common to client and server side prior to TLS-1.3.\n\n- **`{eccs, NamedCurves}`** - Named Elliptic Curves\n\n Elliptic curves that can be used in pre TLS-1.3 key exchange.\n\n- **`{secure_renegotiate, SecureRenegotiate}`** - Inter-operate trade-off option\n\n Specifies whether to reject renegotiation attempt that does not live\n up to [RFC 5746](http://www.ietf.org/rfc/rfc5746.txt). By default,\n `SecureRenegotiate` is `true`, meaning that secure renegotiation is\n enforced. If `SecureRenegotiate` is `false` secure renegotiation\n will still be used if possible, but it falls back to insecure\n renegotiation if the peer does not support if [RFC\n 5746](http://www.ietf.org/rfc/rfc5746.txt).\n\n- **`{user_lookup_fun, {LookupFun, UserState}}`** - PSK/SRP cipher suite option\n\n The lookup fun is to be defined as follows:\n\n ```erlang\n fun(psk, PSKIdentity :: binary(), UserState :: term()) ->\n\t{ok, SharedSecret :: binary()} | error;\n fun(srp, Username :: binary(), UserState :: term()) ->\n\t{ok, {SRPParams :: srp_param_type(), Salt :: binary(),\n\t DerivedKey :: binary()}} | error.\n ```\n\n For Pre-Shared Key (PSK) cipher suites, the lookup fun is called by the client\n and server to determine the shared secret. When called by the client,\n `PSKIdentity` is the hint presented by the server or `undefined`. When\n called by the server, `PSKIdentity` is the identity presented by the client.\n\n For Secure Remote Password (SRP), the fun is only used by the server to obtain\n parameters that it uses to generate its session keys. `DerivedKey` is to be\n derived according to [RFC 2945](http://tools.ietf.org/html/rfc2945#section/3)\n and [RFC 5054](http://tools.ietf.org/html/rfc5054#section-2.4):\n `crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])])`","title":"ssl.common_option_pre_tls13/0","ref":"ssl.html#t:common_option_pre_tls13/0"},{"type":"type","doc":"Common options to both client and server for TLS-1.3.\n\n- **`{supported_groups, Groups}`** - Key exchange option\n\n TLS 1.3 introduces the \"supported_groups\" extension, which is used for negotiating\n the Diffie-Hellman parameters in a TLS 1.3 handshake. Both client and server can\n specify a list of parameters that they are willing to use.\n\n If not specified it will use a default list (`[x25519, x448, secp256r1,\n secp384r1]`) that is filtered based on the installed crypto library version.\n\n- **`{key_update_at, KeyUpdateAt}`** - Session key renewal\n\n Configures the maximum amount of bytes that can be sent on a TLS 1.3 connection\n before an automatic key update is performed.\n\n There are cryptographic limits on the amount of plaintext which can be safely\n encrypted under a given set of keys. The current default ensures that data\n integrity will not be breached with probability greater than `1/2^57`. For more\n information see\n [Limits on Authenticated Encryption Use in TLS](https://eprint.iacr.org/2024/051.pdf).","title":"ssl.common_option_tls13/0","ref":"ssl.html#t:common_option_tls13/0"},{"type":"type","doc":"Key value list convening some information about the established connection.","title":"ssl.connection_info/0","ref":"ssl.html#t:connection_info/0"},{"type":"type","doc":"TLS connection keys for which information can be retrieved.","title":"ssl.connection_info_keys/0","ref":"ssl.html#t:connection_info_keys/0"},{"type":"type","doc":"TLS connection information relevant prior to TLS-1.3.","title":"ssl.connection_info_pre_tls13/0","ref":"ssl.html#t:connection_info_pre_tls13/0"},{"type":"type","doc":"Options for using built-in CRL cache support.\n\nSpecify how to perform lookup and caching of certificate revocation\nlists (CRLs). `Module` defaults to `m:ssl_crl_cache` with `DbHandle`\nbeing `internal`, and `Args` being `[]`.\n\nThere are two implementations available:\n\n- **`ssl_crl_cache`** - Implementation 1\n\n This module maintains a cache of CRLs. CRLs can be added to the\n cache using `ssl_crl_cache:insert/1`, and can optionally be\n automatically fetched through HTTP if the following argument is\n specified:\n\n - **`{http, timeout()}`**\n\n Enables fetching of CRLs specified as http URIs in [X.509 certificate\n extensions](`e:public_key:public_key_records.md`). Requires the\n [Inets](`e:inets:introduction.md`) application.\n\n- **`ssl_crl_hash_dir`** - Implementation 2\n\n This module makes use of a directory where CRLs are\n stored in files named by the hash of the issuer name.\n\n The file names consist of eight hexadecimal digits followed by `.rN`, where\n `N` is an integer, for example `1a2b3c4d.r0`. For the first version of the CRL, `N`\n starts at zero, and for each new version, `N` is incremented by one. The\n OpenSSL utility `c_rehash` creates symlinks according to this pattern.\n\n For a given hash value, this module finds all consecutive `.r*`\n files starting from zero, and those files taken together make up the\n revocation list. CRL files with `nextUpdate` fields in the past or\n issued by a different CA that happens to have the same name hash\n are excluded.\n\n The following argument is required:\n\n - **`{dir, string()}`**\n\n Specifies the directory in which the CRLs can be found.","title":"ssl.crl_cache_opts/0","ref":"ssl.html#t:crl_cache_opts/0"},{"type":"type","doc":"A DTLS protocol version that are no longer supported by default for security reasons.","title":"ssl.dtls_legacy_version/0","ref":"ssl.html#t:dtls_legacy_version/0"},{"type":"type","doc":"DTLS protocol version.","title":"ssl.dtls_version/0","ref":"ssl.html#t:dtls_version/0"},{"type":"type","doc":"Erlang cipher suite representation\n\n> #### Warning {: .warning }\nEnabling cipher suites using RSA as a key exchange algorithm is\nstrongly discouraged (only available prior to TLS-1.3). For some\nconfigurations software preventions may exist, and can make them\nusable if they work, but relying on them to work is risky. There\nexists more reliable cipher suites that can be used instead.","title":"ssl.erl_cipher_suite/0","ref":"ssl.html#t:erl_cipher_suite/0"},{"type":"type","doc":"If a TLS connection fails a TLS protocol ALERT will be sent/received.\n\nAn atom reflecting the raised alert, according to the TLS protocol, and a description string\nwith some further details will be returned.","title":"ssl.error_alert/0","ref":"ssl.html#t:error_alert/0"},{"type":"type","doc":"TLS-1.3 key exchange configuration.","title":"ssl.group/0","ref":"ssl.html#t:group/0"},{"type":"type","doc":"Hash algorithms used together with signing and encryption functions.","title":"ssl.hash/0","ref":"ssl.html#t:hash/0"},{"type":"type","doc":"A name or address to a host.","title":"ssl.host/0","ref":"ssl.html#t:host/0"},{"type":"type","doc":"Cipher Suite Key Exchange Algorithm will be `any`\nin TLS-1.3 as key exchange is no longer part of cipher suite\nconfiguration in TLS-1.3.","title":"ssl.kex_algo/0","ref":"ssl.html#t:kex_algo/0"},{"type":"type","doc":"The user's private key.\n\nThe key can be provided either directly as a DER-encoded entity,\nindirectly using a crypto engine/provider (with key reference\ninformation), or as an Erlang fun (with possible custom options).\nThe latter two options can be used for customized signing with\nhardware security modules (HSM) or trusted platform modules (TPM).\n\n- A DER encoded key will need to specify the ASN-1 type used to create the\n encoding.\n- An engine/provider needs to specify specific information to support this\n concept and can optionally be password protected; see also\n [crypto:engine_load/3 ](`crypto:engine_load/3`) and\n [Crypto User's Guide](`e:crypto:engine_load.md`).\n- A fun option should include a fun that mimics `public_key:sign/4` and possibly\n [public_key:private_encrypt/4](`public_key:encrypt_private/3`) if legacy\n versions TLS-1.0 and TLS-1.1 must be supported.","title":"ssl.key/0","ref":"ssl.html#t:key/0"},{"type":"type","doc":"Cipher algorithms that are no longer supported by default for security reasons.","title":"ssl.legacy_cipher/0","ref":"ssl.html#t:legacy_cipher/0"},{"type":"type","doc":"Hash algorithms that are no longer supported by default for security reasons.","title":"ssl.legacy_hash/0","ref":"ssl.html#t:legacy_hash/0"},{"type":"type","doc":"Key exchange configuration prior to TLS-1.3.\n\nThese curves have been deprecated by RFC 8422.","title":"ssl.legacy_named_curve/0","ref":"ssl.html#t:legacy_named_curve/0"},{"type":"type","doc":"Signature algorithms that are no longer supported by default for security reasons.","title":"ssl.legacy_sign_algo/0","ref":"ssl.html#t:legacy_sign_algo/0"},{"type":"type","doc":"This is only used for certificate signatures if TLS-1.2 is negotiated,\nmeaning that the peer only supports TLS-1.2, but we also support\nTLS-1.3.","title":"ssl.legacy_sign_scheme/0","ref":"ssl.html#t:legacy_sign_scheme/0"},{"type":"type","doc":"Key exchange configuration prior to TLS-1.3.","title":"ssl.named_curve/0","ref":"ssl.html#t:named_curve/0"},{"type":"type","doc":"For backwards compatibility only; do not use.","title":"ssl.old_cipher_suite/0","ref":"ssl.html#t:old_cipher_suite/0"},{"type":"type","doc":"","title":"ssl.prf_random/0","ref":"ssl.html#t:prf_random/0"},{"type":"type","doc":"Client hello extensions.","title":"ssl.protocol_extensions/0","ref":"ssl.html#t:protocol_extensions/0"},{"type":"type","doc":"TLS or DTLS protocol version.","title":"ssl.protocol_version/0","ref":"ssl.html#t:protocol_version/0"},{"type":"type","doc":"Error reason for debug purposes.\n\nNot to be matched.","title":"ssl.reason/0","ref":"ssl.html#t:reason/0"},{"type":"type","doc":"Supported in TLS-1.3 and TLS-1.2.","title":"ssl.rsassa_pss_scheme/0","ref":"ssl.html#t:rsassa_pss_scheme/0"},{"type":"type","doc":"TLS connection information that can be used for NSS key logging.","title":"ssl.security_info/0","ref":"ssl.html#t:security_info/0"},{"type":"type","doc":"Options specific to the server side, or with different semantics for the client and server.\n\n- **`{alpn_preferred_protocols, AppProtocols}`** - Application Layer Protocol Negotiation\n\n Indicates that the server will try to perform Application-Layer\n Protocol Negotiation (ALPN).\n\n The list of protocols is in order of preference. The protocol negotiated will be\n the first in the list that matches one of the protocols advertised by the\n client. If no protocol matches, the server will fail the connection with a\n `no_application_protocol` alert.\n\n The negotiated protocol can be retrieved using the\n [`negotiated_protocol/1`](`negotiated_protocol/1`) function.\n\n- **`{sni_fun, SNIFun}`**\n\n If the server receives a SNI (Server Name Indication) from the\n client, the given fun `SNIFun` will be called to retrieve\n [`server_option()`](`t:server_option/0`) for the indicated\n hosts. These options will override previously specified options for\n that host.\n\n > #### Note {: .info }\n The options `sni_fun` and `sni_hosts` are mutually exclusive.\n\n- **`{sni_hosts, SNIHosts}`**\n\n If the server receives a SNI (Server Name Indication) from the client matching a\n host listed in the `sni_hosts` option, the specific options for that host will\n override previously specified options.\n\n > #### Note {: .info }\n The options `sni_fun` and `sni_hosts` are mutually exclusive.","title":"ssl.server_option/0","ref":"ssl.html#t:server_option/0"},{"type":"type","doc":"Certificate related options for a server.\n\n- **`{cacerts, CACerts}`** - Trusted certificates.\n\n The DER-encoded trusted certificates. If this option is supplied, it overrides\n the `cacertfile` option.\n\n- **`{verify, Verify}`** - Verify certificates.\n\n Client certificates are an optional part of the TLS protocol. A server performs\n X.509 certificate path validation only in `verify_peer` mode. By default the server\n is in `verify_none` mode and, hence, will not send an certificate request to the\n client. When using `verify_peer` you may also want to specify the options\n `fail_if_no_peer_cert` and `certificate_authorities`.\n\n- **`{fail_if_no_peer_cert, FailNoPeerCert}`** - Legacy trade-off option\n\n Used together with `{verify, verify_peer}` by an TLS/DTLS server. If set to\n `true`, the server fails if the client does not have a certificate to send, that\n is, sends an empty certificate. If set to `false`, it fails only if the client\n sends an invalid certificate (an empty certificate is considered valid).\n Defaults to `false`.\n\n- **`{certificate_authorities, ServerCertAuth}`** - Inter-operate hint option\n\n Determines whether a TLS-1.3 server should include the authorities extension in its\n certificate request message that is sent when the option `verify` is set to\n `verify_peer`. Defaults to `true`.\n\n A reason to exclude the extension would be if the server wants to communicate\n with clients incapable of sending complete certificate chains that adhere to the\n extension, but the server still has the capability to recreate a chain that it\n can verify.","title":"ssl.server_option_cert/0","ref":"ssl.html#t:server_option_cert/0"},{"type":"type","doc":"Legacy server options.\n\n- **`{next_protocols_advertised, NextAppProtocols}`**\n\n ALPN (Application-Layer Protocol Negotiation)\n deprecates NPN (Next Protocol Negotiation) described here.\n\n List of protocols to send to the client if the client indicates that it supports\n the Next Protocol extension. The client can select a protocol that is not on\n this list. The list of protocols must not contain an empty binary. If the server\n negotiates a Next Protocol, it can be accessed using the\n `negotiated_protocol/1` method.","title":"ssl.server_option_legacy/0","ref":"ssl.html#t:server_option_legacy/0"},{"type":"type","doc":"Options only relevant to TLS versions prior to TLS-1.3.\n\n- **`{client_renegotiation, ClientRengotiation}`** - DoS attack avoidance option\n\n In protocols that support client-initiated renegotiation, the resource cost\n of such an operation is higher for the server than the client. This can act as a\n vector for denial-of-service (DoS) attacks. The SSL application already takes measures\n to counter-act such attempts, but client-initiated renegotiation can be completely\n disabled by setting this option to `false`. The default value is `true`. Note\n that disabling renegotiation can result in long-lived connections becoming\n unusable due to limits on the number of messages the underlying cipher suite can\n encipher.\n\n- **`{reuse_sessions, ReuseSessions}`** - Enable session reuse\n\n The boolean value `true` specifies that the server will agree to reuse sessions.\n Setting it to `false` will result in an empty session table, meaning that no sessions\n will be reused.\n\n- **`{reuse_session, ReuseSession}`** - Local server reuse policy\n\n Enables the TLS/DTLS server to have a local policy for deciding whether a session\n is to be reused. Meaningful only if `reuse_sessions` is set to `true`.\n\n `ReuseSession` should be a fun:\n\n `fun(SuggestedSessionId, PeerCert, Compression, CipherSuite)`\n\n `SuggestedSessionId` is a [`binary()`](`t:binary/0`),\n `PeerCert` is a DER-encoded certificate,\n `Compression` is an enumeration integer, and `CipherSuite` is of type\n [`erl_cipher_suite()`](`t:erl_cipher_suite/0`).\n\n- **`{psk_identity, PSKHint}`** - Inter-operate hint option\n\n Specifies the server identity hint that the server presents to the client.\n\n- **`{honor_cipher_order, HonorServerCipherOrder}`** - Trade-off option alters protocol defined behavior\n\n If `true`, use the server's preference for ECC curve selection. If `false` (the\n default), use the client's preference.\n\n- **`{honor_ecc_order, HonorServerECCOrder}`** - Trade-off option alters protocol defined behavior\n\n If `true`, use the server's preference for ECC curve selection. If `false` (the\n default), use the client's preference.\n\n- **`{dh, DHder}`** - Affects DH key exchange cipher suites\n\n The DER-encoded Diffie-Hellman parameters. If specified, it overrides option\n `dhfile`.\n\n- **`{dh_file, DHfile}`** - Affects DH key exchange cipher suites\n\n Path to a file containing PEM-encoded Diffie Hellman parameters to be used by\n the server if a cipher suite using Diffie Hellman key exchange is negotiated. If\n not specified, default parameters are used.","title":"ssl.server_option_pre_tls13/0","ref":"ssl.html#t:server_option_pre_tls13/0"},{"type":"type","doc":"Options only relevant for TLS-1.3.\n\n- **`{session_tickets, SessionTickets}`**\n\n Configures the session ticket functionality. Allowed values for `SessionTickets` are:\n\n * `disabled`\n * `stateful`\n * `stateless`\n * `stateful_with_cert`\n * `stateless_with_cert`\n\n If `SessionTickets` is not set to `disabled`, session resumption with pre-shared\n keys is enabled and the server will send stateful or stateless session tickets to the\n client after successful connections.\n\n > #### Note {: .info }\n In pre-shared key session ticket resumption, there is no certificate\n exchange involved. Therefore, `ssl:peercert/1` will not return the\n peer certificate, as it is only communicated during the initial\n handshake. To associate the client certificate from the original\n handshake with the tickets it issues, the server options\n `stateful_with_cert` or `stateless_with_cert` can be used.\n\n A stateful session ticket is a database reference to internal state information.\n A stateless session ticket is a self-encrypted binary that contains both\n cryptographic keying material and state data.\n\n > #### Warning {: .warning }\n When `SessionTickets` is set to `stateful_with_cert`, the client\n certificate is stored along with the internal state information,\n leading to increased memory consumption. Conversely, when it is set\n to `stateless_with_cert`, the client certificate is encoded in the\n self-encrypted binary sent to the client, resulting in an increase\n in payload size.\n\n See also [SSL User's Guide, Session Tickets and Session Resumption in TLS 1.3](using_ssl.md#session-tickets-and-session-resumption-in-tls-1-3).\n\n- **`{stateless_tickets_seed, TicketSeed}`** - Option for statless tickets\n\n Configures the seed used for the encryption of stateless session tickets.\n Allowed values are any randomly generated `t:binary/0`. If this option is not\n configured, an encryption seed will be randomly generated.\n\n > #### Warning {: .warning }\n >\n > Reusing the ticket encryption seed between multiple server instances enables\n > stateless session tickets to work across multiple server instances, but it\n > breaks anti-replay protection across instances.\n >\n > Inaccurate time synchronization between server instances can also affect\n > session ticket freshness checks, potentially causing false negatives as well\n > as false positives.\n\n- **`{anti_replay, AntiReplay}`** - Option for statless tickets\n\n Configures the server's built-in anti replay feature based on Bloom filters.\n\n Allowed values for `AntiReplay` are the pre-defined `'10k'`,\n `'100k'`, or a custom 3-tuple that defines the properties of the\n bloom filters:\n `{WindowSize, HashFunctions, Bits}`. `WindowSize` is the number of seconds after\n the current Bloom filter is rotated and also the window size used for freshness\n checks of ClientHello. `HashFunctions` is the number hash functions and `Bits`\n is the number of bits in the bit vector. `'10k'` and `'100k'` are simple\n defaults with the following properties:\n\n - `'10k'`: Bloom filters can hold 10000 elements with 3% probability of false\n positives. `WindowSize`: 10, `HashFunctions`: 5, `Bits:` 72985 (8.91 KiB).\n - `'100k'`: Bloom filters can hold 100000 elements with 3% probability of false\n positives. `WindowSize`: 10, `HashFunctions`: 5, `Bits`: 729845 (89.09 KiB).\n\n See also [SSL User's Guide, Anti-Replay Protection in TLS\n 1.3](using_ssl.md#anti-replay-protection-in-tls-1-3).\n\n- **`{cookie, Cookie}`** - Option for `HelloRetryRequest` behavior\n\n If `Cookie` is `true`, which is the default, the server sends a\n cookie extension in its `HelloRetryRequest` messages.\n\n The cookie extension has two main purposes. It allows the server to force the\n client to demonstrate reachability at their apparent network address (thus\n providing a measure of DoS protection). This is primarily useful for\n non-connection-oriented transports. It also allows offloading the server's\n state to the client. The cookie extension is enabled by default as it is a\n mandatory extension in RFC8446.\n\n- **`{early_data, EarlyData}`** - Option for accepting or rejecting Early Data\n\n Configures if the server accepts (`enabled`) or rejects (`disabled`) early data\n sent by a client. The default value is `disabled`.","title":"ssl.server_option_tls13/0","ref":"ssl.html#t:server_option_tls13/0"},{"type":"type","doc":"Identifies a TLS session prior to TLS-1.3.","title":"ssl.session_id/0","ref":"ssl.html#t:session_id/0"},{"type":"type","doc":"SHA2 hash algorithms.","title":"ssl.sha2/0","ref":"ssl.html#t:sha2/0"},{"type":"type","doc":"Signature algorithms.","title":"ssl.sign_algo/0","ref":"ssl.html#t:sign_algo/0"},{"type":"type","doc":"Signature schemes, defined by TLS-1.3, and replacing signature algorithms from TLS-1.2.\n\nExplicitly list acceptable signature schemes in the preferred\norder.\n\nOverrides the algorithms supplied in\n[`signature_algs`](`t:signature_algs/0`) option for certificates.\nIn addition to the `signature_algorithms` extension from TLS 1.2,\n[TLS 1.3 (RFC 5246 Section 4.2.3)](http://www.ietf.org/rfc/rfc8446.txt#section-4.2.3)\nadds the `signature_algorithms_cert` extension which enables having special\nrequirements on the signatures used in the certificates that differs from the\nrequirements on digital signatures as a whole. If this is not required this\nextension is not needed.\n\nThe client will send a `signature_algorithms_cert` extension (in the\nclient hello message), if TLS version 1.2 (back-ported to TLS 1.2 in\n24.1) or later is used, and the signature_algs_cert option is\nexplicitly specified. By default, only the\n[signature_algs](`t:signature_algs/0`) extension is sent with the\nexception of when signature_algs option is not explicitly specified,\nin which case it will append the rsa_pkcs1_sha1 algorithm to the\ndefault value of signature_algs and use it as value for\nsignature_algs_cert to allow certificates to have this signature but\nstill disallow sha1 use in the TLS protocol, since 27.0.1 and 26.2.5.2.\n\n> #### Note {: .info }\n>\n> Note that supported signature schemes for TLS-1.2 are\n[`legacy_sign_scheme()`](`t:legacy_sign_scheme/0`)\n> and [`rsassa_pss_scheme()`](`t:rsassa_pss_scheme/0`).","title":"ssl.sign_scheme/0","ref":"ssl.html#t:sign_scheme/0"},{"type":"type","doc":"Explicitly list acceptable signature algorithms for certificates and handshake\nmessages in the preferred order.\n\nThe client will send its list as the client hello\n`signature_algorithm` extension introduced in TLS-1.2; see [Section\n7.4.1.4.1 in RFC 5246](http://www.ietf.org/rfc/rfc5246.txt). Before\nTLS-1.2, these algorithms where implicitly chosen and partly derived\nfrom the cipher suite.\n\nIn TLS-1.2 a somewhat more explicit negotiation is made possible using a list of\n`{HashAlgo, SignAlgo}` tuples.\n\nIn TLS-1.3, these algorithm pairs are replaced by [signature\nschemes](`t:sign_scheme/0`) that are completely decoupled from the\ncipher suite.\n\nSignature algorithms used for certificates can be overridden by the\n[signature schemes](`t:sign_scheme/0`) supplied by the\n`signature_algs_cert` option.\n\nThe TLS-1.2 default is `Default_TLS_12_Alg_Pairs` interleaved with\n`rsa_pss_schemes` since ssl-11.0 (Erlang/OTP 25). `pss_pss` is\npreferred over `pss_rsae`, which in turn is preferred over `rsa`.\n\nThe list for `Default_TLS_12_Alg_Pairs` is defined as follows:\n\n```erlang\n[\n{sha512, ecdsa},\n{sha512, rsa},\n{sha384, ecdsa},\n{sha384, rsa},\n{sha256, ecdsa},\n{sha256, rsa}\n]\n```\n\n> #### Change {: .info }\n>\n> - Support for `{md5, rsa}` was removed from the TLS-1.2 default in\n> ssl-8.0 (Erlang/OTP 22).\n> - Support for `{sha, _}` (SHA1) and `{sha224, _}` was removed\n> from the TLS-1.2 default in ssl-11.0 (Erlang/OTP 26).\n\nThe list for `rsa_pss_schemes` is defined as follows:\n\n\n```erlang\n[rsa_pss_pss_sha512,\nrsa_pss_pss_sha384,\nrsa_pss_pss_sha256,\nrsa_pss_rsae_sha512,\nrsa_pss_rsae_sha384,\nrsa_pss_rsae_sha256]\n```\n\nThe list of `TLS_13_Legacy_Schemes` is defined as follows:\n\n```erlang\n[\n%% Legacy algorithms only applicable to certificate signatures\nrsa_pkcs1_sha512, %% Corresponds to {sha512, rsa}\nrsa_pkcs1_sha384, %% Corresponds to {sha384, rsa}\nrsa_pkcs1_sha256, %% Corresponds to {sha256, rsa}\n]\n```\n\nThe list of `Default_TLS_13_Schemes` is defined as follows:\n\n```text\n[\n%% EDDSA\neddsa_ed25519,\neddsa_ed448\n\n%% ECDSA\necdsa_secp521r1_sha512,\necdsa_secp384r1_sha384,\necdsa_secp256r1_sha256] ++\n\n%% RSASSA-PSS\nrsa_pss_schemes()\n```\n\n> #### Change {: .info }\n>\n> EDDSA was made highest priority in ssl-10.8 (Erlang/OTP 25).\n\nThe TLS-1.3 default is `Default_TLS_13_Schemes`.\n\nIf both TLS-1.3 and TLS-1.2 are supported the default is:\n\n```erlang\nDefault_TLS_13_Schemes ++ TLS_13_Legacy_Schemes ++\nDefault_TLS_12_Alg_Pairs %% not represented in TLS_13_Legacy_Schemes\n```\n\nto ensure that appropriate algorithms can be chosen for the negotiated\nversion.\n\n> #### Note {: .info }\nTLS-1.2 algorithms will not be negotiated for TLS-1.3, but the TLS-1.3\nRSASSA-PSS ([`rsassa_pss_scheme()`](`t:rsassa_pss_scheme/0`))\nsignature schemes can be negotiated also for TLS-1.2 from Erlang/OTP\n24.1 (fully working from Erlang/OTP 24.1.3). However, if both TLS 1.3\nand TLS 1.2 are supported using defaults, and TLS 1.3 is negotiated,\nthe corresponding TLS 1.2 algorithms for TLS 1.3 legacy signature\nschemes will be treated as legacy schemes and applied only to\ncertificate signatures.","title":"ssl.signature_algs/0","ref":"ssl.html#t:signature_algs/0"},{"type":"type","doc":"A socket that can be used to perform a so-called \"START-TLS\", which\nmeans using an already connected socket previously used for plain TCP\ntraffic and upgrading it to use TLS.\n\nBoth sides needs to agree on the upgrade.","title":"ssl.socket/0","ref":"ssl.html#t:socket/0"},{"type":"type","doc":"Options for the transport socket.\n\nThe default socket options are\n`[{mode, list}, {packet, 0}, {header, 0}, {active, true}]`.\n\nFor valid options, see `m:inet`, `m:gen_tcp`, and `m:gen_udp`\nin Kernel. Note that stream-oriented options such as `packet` are\nonly relevant for TLS and not DTLS.","title":"ssl.socket_option/0","ref":"ssl.html#t:socket_option/0"},{"type":"type","doc":"SRP cipher suite configuration prior to TLS-1.3.","title":"ssl.srp_param_type/0","ref":"ssl.html#t:srp_param_type/0"},{"type":"type","doc":"An opaque reference to the TLS/DTLS connection.\n\nNote that despite being opaque, matching `sslsocket()` instances is allowed.","title":"ssl.sslsocket/0","ref":"ssl.html#t:sslsocket/0"},{"type":"type","doc":"TLS Alert Protocol reasons.","title":"ssl.tls_alert/0","ref":"ssl.html#t:tls_alert/0"},{"type":"type","doc":"An option that can be supplied to a TLS client.","title":"ssl.tls_client_option/0","ref":"ssl.html#t:tls_client_option/0"},{"type":"type","doc":"A TLS protocol version that are no longer supported by default for security reasons.","title":"ssl.tls_legacy_version/0","ref":"ssl.html#t:tls_legacy_version/0"},{"type":"type","doc":"An option related to the TLS/DTLS protocol.","title":"ssl.tls_option/0","ref":"ssl.html#t:tls_option/0"},{"type":"type","doc":"An option that can be supplied to a TLS server.","title":"ssl.tls_server_option/0","ref":"ssl.html#t:tls_server_option/0"},{"type":"type","doc":"TLS protocol version.","title":"ssl.tls_version/0","ref":"ssl.html#t:tls_version/0"},{"type":"type","doc":"Transport option defines a callback module and message tags to handle the underlying transport socket.\n\nCan be used to customize the transport layer. The tag\nvalues should be the values used by the underlying transport in its active mode\nmessages.\n\nDefaults to `{gen_tcp, tcp, tcp_closed, tcp_error, tcp_passive}` for TLS.\n\n> #### Note {: .info }\nFor backward compatibility a tuple of size four will be converted to a\ntuple of size five, where `PassiveTag` is the `DataTag` element with\n`_passive` appended.\n\nFor TLS the callback module must implement a reliable transport\nprotocol, behave as `m:gen_tcp`, and have functions corresponding to\n`inet:setopts/2`, `inet:getopts/2`, `inet:peername/1`, `inet:sockname/1`, and\n`inet:port/1`. The callback `m:gen_tcp` is treated specially and calls `m:inet`\ndirectly. For DTLS this feature is considered experimental.","title":"ssl.transport_option/0","ref":"ssl.html#t:transport_option/0"},{"type":"module","doc":"CRL cache\n\nImplements an internal CRL (Certificate Revocation List) cache. In addition to\nimplementing the `m:ssl_crl_cache_api` behaviour the following functions are\navailable.","title":"ssl_crl_cache","ref":"ssl_crl_cache.html"},{"type":"function","doc":"Delete CRLs from the ssl applications local cache.","title":"ssl_crl_cache.delete/1","ref":"ssl_crl_cache.html#delete/1"},{"type":"function","doc":"","title":"ssl_crl_cache.insert/1","ref":"ssl_crl_cache.html#insert/1"},{"type":"function","doc":"Insert CRLs into the ssl applications local cache, with or without a\ndistribution point reference URI","title":"ssl_crl_cache.insert/2","ref":"ssl_crl_cache.html#insert/2"},{"type":"type","doc":"A source to input CRLs","title":"ssl_crl_cache.crl_src/0","ref":"ssl_crl_cache.html#t:crl_src/0"},{"type":"behaviour","doc":"API for a TLS CRL (Certificate Revocation List) cache.\n\nWhen TLS performs certificate path validation according to\n[RFC 5280 ](http://www.ietf.org/rfc/rfc5280.txt)it should also perform CRL\nvalidation checks. To enable the CRL checks the application needs access to\nCRLs. A database of CRLs can be set up in many different ways. This module\nprovides the behavior of the API needed to integrate an arbitrary CRL cache with\nthe erlang ssl application. It is also used by the application itself to provide\na simple default implementation of a CRL cache.","title":"ssl_crl_cache_api","ref":"ssl_crl_cache_api.html"},{"type":"callback","doc":"`fun fresh_crl/2` will be used as input option `update_crl` to\n`public_key:pkix_crls_validate/3`.\n\nIt is possible to return logger info, since OTP 22.2, that will be used by the TLS connection to\nproduce log events.","title":"ssl_crl_cache_api.fresh_crl/2","ref":"ssl_crl_cache_api.html#c:fresh_crl/2"},{"type":"callback","doc":"Backwards compatibility, replaced by lookup/3","title":"ssl_crl_cache_api.lookup/2","ref":"ssl_crl_cache_api.html#c:lookup/2"},{"type":"callback","doc":"Lookup the CRLs belonging to the distribution point `Distributionpoint`. This\nfunction may choose to only look in the cache or to follow distribution point\nlinks depending on how the cache is administrated.\n\nThe `Issuer` argument contains the issuer name of the certificate to\nbe checked. Normally the returned CRL should be issued by this\nissuer, except if the `cRLIssuer` field of `DistributionPoint` has a\nvalue, in which case that value should be used instead.\n\nIn an earlier version of this API, the `lookup` function received two\narguments, omitting `Issuer`. For compatibility, this is still\nsupported: if there is no [`lookup/3`](`c:lookup/3`) function in the\ncallback module,[`lookup/2`](`c:lookup/2`) is called instead.\n\nIt is possible to return logger info, since OTP 22.2, that will be used by the TLS connection to\nproduce log events.","title":"ssl_crl_cache_api.lookup/3","ref":"ssl_crl_cache_api.html#c:lookup/3"},{"type":"callback","doc":"Select the CRLs in the cache that are issued by `Issuer` unless the value is a\nlist of so called general names, see\n[X509 certificates records](`e:public_key:public_key_records.md`), originating\nform `#'DistributionPoint'.cRLissuer` and representing different mechanism to\nobtain the CRLs. The cache callback needs to use the appropriate entry to\nretrieve the CRLs or return an empty list if it does not exist.\n\nIt is possible to return logger info, since OTP 22.2, that will be used by the TLS connection to\nproduce log events.","title":"ssl_crl_cache_api.select/2","ref":"ssl_crl_cache_api.html#c:select/2"},{"type":"type","doc":"Reference to the CRL cache.","title":"ssl_crl_cache_api.crl_cache_ref/0","ref":"ssl_crl_cache_api.html#t:crl_cache_ref/0"},{"type":"type","doc":"For description see\n[X509 certificates records](`e:public_key:public_key_records.md`)","title":"ssl_crl_cache_api.dist_point/0","ref":"ssl_crl_cache_api.html#t:dist_point/0"},{"type":"type","doc":"Information for ssl applications use of [Logger(3)](`m:logger`)","title":"ssl_crl_cache_api.logger_info/0","ref":"ssl_crl_cache_api.html#t:logger_info/0"},{"type":"behaviour","doc":"TLS session cache API\n\nDefines the API for the TLS session cache (pre TLS-1.3) so that the data storage\nscheme can be replaced by defining a new callback module implementing this API.","title":"ssl_session_cache_api","ref":"ssl_session_cache_api.html"},{"type":"callback","doc":"Deletes a cache entry.\n\nIs only called from the cache handling process.","title":"ssl_session_cache_api.delete/2","ref":"ssl_session_cache_api.html#c:delete/2"},{"type":"callback","doc":"Calls `Fun(Elem, AccIn)` on successive elements of the cache, starting with\n `AccIn == Acc0`.\n\n`Fun/2` must return a new accumulator, which is passed to the\nnext call. The function returns the final value of the accumulator. `Acc0` is\nreturned if the cache is empty.\n\n> #### Note {: .info }\n>\n> Since OTP-23.3 this functions is only used on the client side and does not\n> need to implemented for a server cache.","title":"ssl_session_cache_api.foldl/3","ref":"ssl_session_cache_api.html#c:foldl/3"},{"type":"callback","doc":"Performs possible initializations of the cache and returns a reference to it\nthat is used as parameter to the other API functions. \n\nIs called by the cache handling processes `init` function, hence\nputting the same requirements on it as a normal process `init`\nfunction. This function is called twice when starting the SSL\napplication, once with the role client and once with the role server,\nas the SSL application must be prepared to take on both roles.\n\nIncludes property `{role, client | server}` in init argument list. \nCurrently this is the only predefined property, there can also be\nuser-defined properties. See also application environment variable\n[session_cb_init_args](ssl_app.md).","title":"ssl_session_cache_api.init/1","ref":"ssl_session_cache_api.html#c:init/1"},{"type":"callback","doc":"Looks up a cache entry. Is to be callable from any process.","title":"ssl_session_cache_api.lookup/2","ref":"ssl_session_cache_api.html#c:lookup/2"},{"type":"callback","doc":"Selects sessions that can be reused, that is sessions that include `PartialKey`\nin its key. Is to be callable from any process.\n\n> #### Note {: .info }\n>\n> Since OTP-23.3 This functions is only used on the client side and does not\n> need to implemented for a server cache.","title":"ssl_session_cache_api.select_session/2","ref":"ssl_session_cache_api.html#c:select_session/2"},{"type":"callback","doc":"Returns the number of sessions in the cache.\n\nIf size exceeds the maximum number of sessions, the current cache\nentries will be invalidated regardless of their remaining lifetime. Is\nto be callable from any process.","title":"ssl_session_cache_api.size/1","ref":"ssl_session_cache_api.html#c:size/1"},{"type":"callback","doc":"Takes care of possible cleanup that is needed when the cache handling process\nterminates.","title":"ssl_session_cache_api.terminate/1","ref":"ssl_session_cache_api.html#c:terminate/1"},{"type":"callback","doc":"Caches a new session or updates an already cached one.\n\nIs only called from the cache handling process.","title":"ssl_session_cache_api.update/3","ref":"ssl_session_cache_api.html#c:update/3"},{"type":"opaque","doc":"The opaque part of the key. Does not need to be handled by the callback.","title":"ssl_session_cache_api.partial_key/0","ref":"ssl_session_cache_api.html#t:partial_key/0"},{"type":"opaque","doc":"The session data that is stored for each session.","title":"ssl_session_cache_api.session/0","ref":"ssl_session_cache_api.html#t:session/0"},{"type":"type","doc":"A key to an entry in the session cache.","title":"ssl_session_cache_api.session_cache_key/0","ref":"ssl_session_cache_api.html#t:session_cache_key/0"},{"type":"type","doc":"A term that can be used to reference the cache.","title":"ssl_session_cache_api.session_cache_ref/0","ref":"ssl_session_cache_api.html#t:session_cache_ref/0"},{"type":"extras","doc":"\n# SSL Application\n\nThe ssl application provides secure communication over sockets.","title":"SSL Application","ref":"ssl_app.html"},{"type":"extras","doc":"The ssl application is an implementation of the TLS (previously known as SSL) and DTLS protocols in\nErlang.\n\nFor current statement of standards compliance see the\n[User's Guide](standards_compliance.md).","title":"Description - SSL Application","ref":"ssl_app.html#description"},{"type":"extras","doc":"The SSL application uses the `Public_Key`, `Asn1` and `Crypto` application to\nhandle public keys and encryption, hence these applications must be loaded for\nthe SSL application to work. In an embedded environment this means they must be\nstarted with `application:start/1,2` before the SSL application is started.","title":"Dependencies - SSL Application","ref":"ssl_app.html#dependencies"},{"type":"extras","doc":"The application environment configuration parameters in this section are defined\nfor the SSL application. For more information about configuration parameters,\nsee the `m:application` manual page in Kernel.\n\n> #### Note {: .info }\nAll parameters including the wording 'session_ticket' are TLS-1.3 only configuration\nand other session parameters are prior to TLS-1.3 only configuration. DTLS versions\nare based on TLS versions see [standard compliance](standards_compliance.md) for mapping.\n\nThe environment parameters can be set on the command line, for example:\n\n`erl -ssl protocol_version \"['tlsv1.2', 'tlsv1.1']\"`\n\n- **`protocol_version = ``t:ssl:tls_version/0` | [`t:ssl:tls_version/0`]\n ` `** - Protocol supported by started clients and servers. If this\n option is not set, it defaults to all TLS protocols currently supported, more\n might be configurable, by the SSL application. This option can be overridden\n by the version option to `ssl:connect/2,3` and `ssl:listen/2`.\n\n- **`dtls_protocol_version = ``t:ssl:dtls_version/0` | [`t:ssl:dtls_version/0`]\n ` `** - Protocol supported by started clients and servers. If this\n option is not set, it defaults to all DTLS protocols currently supported, more\n might be configurable, by the SSL application. This option can be overridden\n by the version option to `ssl:connect/2,3` and `ssl:listen/2`.\n\n- **`session_lifetime = integer() `** - Maximum lifetime of the\n session data in seconds. Defaults to 24 hours which is the maximum recommended\n lifetime by [RFC 5246](http://www.ietf.org/rfc/5246rfc.txt). However sessions\n may be invalidated earlier due to the maximum limitation of the session cache\n table.\n\n- **`session_cb = atom() `** - Deprecated Since OTP-23.3 replaced by\n `client_session_cb` and `server_session_cb`\n\n- **`client_session_cb = atom() `** - Since OTP-23.3 Name client of\n the session cache callback module that implements the `ssl_session_cache_api`\n behavior. Defaults to `ssl_client_session_cache_db`.\n\n- **`server_session_cb = atom() `** - Since OTP-23.3 Name of the\n server session cache callback module that implements the\n `ssl_session_cache_api` behavior. Defaults to `ssl_server_session_cache_db`.\n\n- **`session_cb_init_args = proplist:proplist() `** - Deprecated Since\n OTP-23.3 replaced by `client_session_cb_init_args` and\n `server_session_cb_init_args`\n\n- **`client_session_cb_init_args = proplist:proplist() `** - List of\n extra user-defined arguments to the `init` function in the session cache\n callback module. Defaults to `[]`.\n\n- **`server_session_cb_init_args = proplist:proplist() `** - List of\n extra user-defined arguments to the `init` function in the session cache\n callback module. Defaults to `[]`.\n\n- **`session_cache_client_max = integer() ` \n ** \n Limits the growth of the clients session cache, that is how many sessions\n towards servers that are cached to be used by new client connections. If the\n maximum number of sessions is reached, the current cache entries will be\n invalidated regardless of their remaining lifetime. Defaults to 1000.\n Recommended ssl-8.2.1 or later for this option to work as intended.\n\n- **`session_cache_server_max = integer() `** - Limits the growth of\n the servers session cache, that is how many client sessions are cached by the\n server. If the maximum number of sessions is reached, the current cache\n entries will be invalidated regardless of their remaining lifetime. Defaults\n to 1000. Recommended ssl-8.2.1 or later for this option to work as intended.\n\n- **`ssl_pem_cache_clean = integer() `** - Number of milliseconds\n between PEM cache validations. Defaults to 2 minutes.\n\n Note: The cache can be reloaded by calling `ssl:clear_pem_cache/0`.\n\n- **`bypass_pem_cache = boolean() `** - Introduced in ssl-8.0.2.\n Disables the PEM-cache. Can be used as a workaround for the PEM-cache\n bottleneck before ssl-8.1.1. Defaults to false.\n\n- **`alert_timeout = integer() `** - Number of milliseconds between\n sending of a fatal alert and closing the connection. Waiting a little while\n improves the peers chances to properly receiving the alert so it may shutdown\n gracefully. Defaults to 5000 milliseconds.\n\n- **`internal_active_n = integer() `** - For TLS connections this\n value is used to handle the internal socket. As the implementation was changed\n from an active once to an active N behavior (N = 100), for performance\n reasons, this option exist for possible tweaking or restoring of the old\n behavior (internal_active_n = 1) in unforeseen scenarios. The option will not\n affect erlang distribution over TLS that will always run in active N mode.\n Added in ssl-9.1 (OTP-21.2).\n\n- **`server_session_tickets_amount = integer() `** - Number of session\n tickets sent by the server. It must be greater than 0. Defaults to 3.\n\n- **`server_session_ticket_lifetime = integer() `** - Lifetime of\n session tickets sent by the server. Servers must not use any value greater\n than 604800 seconds (7 days). Expired tickets are automatically removed.\n Defaults to 7200 seconds (2 hours).\n\n- **`server_session_ticket_store_size = integer() `** - Sets the\n maximum size of the server session ticket store (stateful tickets). Defaults\n to 1000. Size limit is enforced by dropping old tickets.\n\n- **`server_session_ticket_max_early_data = integer() `** - Sets the\n maximum size of the early data that the server accepts and also configures its\n NewSessionTicket messages to include this same size limit in their\n early_data_indication extension. Defaults to 16384. Size limit is enforced by\n both client and server.\n\n- **`client_session_ticket_lifetime = integer() `** - Lifetime of\n session tickets in the client ticket store. Expired tickets are automatically\n removed. Defaults to 7200 seconds (2 hours).\n\n- **`client_session_ticket_store_size = integer() `** - Sets the\n maximum size of the client session ticket store. Defaults to 1000. Size limit\n is enforced by dropping old tickets.","title":"Configuration - SSL Application","ref":"ssl_app.html#configuration"},{"type":"extras","doc":"The SSL application uses [OTP logger](`m:logger`). TLS/DTLS alerts are logged on\nnotice level. Unexpected errors are logged on error level. These log entries\nwill by default end up in the default Erlang log. The option `log_level` may be\nused to in run-time to set the log level of a specific TLS connection, which is\nhandy when you want to use level debug to inspect the TLS handshake setup.","title":"Error Logger and Event Handlers - SSL Application","ref":"ssl_app.html#error-logger-and-event-handlers"},{"type":"extras","doc":"`m:application`","title":"See Also - SSL Application","ref":"ssl_app.html#see-also"},{"type":"extras","doc":"\n# SSL Release Notes\n\nThis document describes the changes made to the SSL application.","title":"SSL Release Notes","ref":"notes.html"},{"type":"extras","doc":"","title":"SSL 11.2.1 - SSL Release Notes","ref":"notes.html#ssl-11-2-1"},{"type":"extras","doc":"- Check for TLS-1.3 support should check minimum requirements.\n\n Own Id: OTP-19094 Aux Id: [GH-8489]\n\n- If both TLS-1.3 and TLS-1.2 is supported\n and TLS-1.2 negotiated convert TLS-1.3 ECDSA schemes to TLS-1.2 hash and signature pairs for increased interoperability.\n\n Own Id: OTP-19107 Aux Id: [GH-8376]\n\n- TLS-1.3 negotiation now uses SNI based options correctly instead of ignoring them.\n\n Own Id: OTP-19140\n\n[GH-8489]: https://github.com/erlang/otp/issues/8489\n[GH-8376]: https://github.com/erlang/otp/issues/8376","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Make it easier to distinguish between a invalid signature and unsupported signature.\n\n Own Id: OTP-19091\n\n- Enhance ALERT logs to help understand what causes the alert.\n\n Own Id: OTP-19092 Aux Id: [GH-8482]\n\n- When the default value for signature_algs is used, default the signature_algs_cert to the default value + rsa_pkcs1_sha1 to allow this algorithms for certificates but not for the TLS protocol. This is for better interoperability. If signature_algs is set explicitly signature_algs_cert must also be set explicitly if they should be different.\n\n Own Id: OTP-19152 Aux Id: [GH-8588]\n\n[GH-8482]: https://github.com/erlang/otp/issues/8482\n[GH-8588]: https://github.com/erlang/otp/issues/8588","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.2 - SSL Release Notes","ref":"notes.html#ssl-11-2"},{"type":"extras","doc":"- Starting a TLS server without sufficient credentials (certificate or anonymous cipher) would work, but it was impossible to connect to it.\n \n This has been corrected to return an error instead of starting the server.\n\n Own Id: OTP-18887 Aux Id: [GH-7493], [PR-7918]\n\n- ASN.1 decoding errors are handled in more places to ensure that errors are returned instead of cause a crash.\n\n Own Id: OTP-18969 Aux Id: [GH-8058], [PR-8256]\n\n- Improved error checking on the API functions.\n\n Own Id: OTP-18992 Aux Id: [GH-8066] [PR-8156]\n\n[GH-7493]: https://github.com/erlang/otp/issues/7493\n[PR-7918]: https://github.com/erlang/otp/pull/7918\n[GH-8058]: https://github.com/erlang/otp/issues/8058\n[PR-8256]: https://github.com/erlang/otp/pull/8256\n[GH-8066]: https://github.com/erlang/otp/issues/8066\n[PR-8156]: https://github.com/erlang/otp/pull/8156","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The `ssl` client can negotiate and handle certificate status request (OCSP stapling support on the client side).\n \n Thanks to voltone for interop testing and related discussions.\n\n Own Id: OTP-18606 Aux Id: OTP-16875,OTP-16448\n\n- Memory consumption has been reduced and performance increased by refactoring internal data structures and their usage.\n\n Own Id: OTP-18665 Aux Id: [PR-7447]\n\n- Added `c:ssl_crl_cache_api:lookup/2` as an optional `-callback` attribute.\n\n Own Id: OTP-18788 Aux Id: [PR-7700]\n\n- Key customization support has been extended to allow flexibility for implementers of for instance hardware security modules (HSM) or trusted platform modules (TPM).\n\n Own Id: OTP-18876 Aux Id: [PR-7898], [PR-7475]\n\n- The `proc_lib:set_label/1` function is now used to increase observability of `ssl` processes.\n\n Own Id: OTP-18879\n\n- Brainpool elliptic curves are now supported in TLS-1.3.\n\n Own Id: OTP-18884 Aux Id: [PR-8056]\n\n- The documentation has been migrated to use Markdown and ExDoc.\n\n Own Id: OTP-18955 Aux Id: [PR-8026]\n\n- For security reasons, the CBC ciphers are now longer included in the list of default ciphers for TLS-1.2.\n\n *** POTENTIAL INCOMPATIBILITY ***\n\n Own Id: OTP-19025 Aux Id: [PR-8250]\n\n- There is a new `cert_policy_opts` option to configure certificate policy options for the certificate path validation.\n\n Own Id: OTP-19027 Aux Id: [PR-8255]\n\n[PR-7447]: https://github.com/erlang/otp/pull/7447\n[PR-7700]: https://github.com/erlang/otp/pull/7700\n[PR-7898]: https://github.com/erlang/otp/pull/7898\n[PR-7475]: https://github.com/erlang/otp/pull/7475\n[PR-8056]: https://github.com/erlang/otp/pull/8056\n[PR-8026]: https://github.com/erlang/otp/pull/8026\n[PR-8250]: https://github.com/erlang/otp/pull/8250\n[PR-8255]: https://github.com/erlang/otp/pull/8255","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.1.4.3 - SSL Release Notes","ref":"notes.html#ssl-11-1-4-3"},{"type":"extras","doc":"* A race in the kTLS flavour of SSL distribution has been fixed so inet_drv.c doesn't read ahead too much data which could cause the kTLS encryption to be activated too late when some encrypted data had already been read into the inet_drv.c buffer as unencrypted.\n\n Own Id: OTP-19175 Aux Id: GH-8561, PR-8690","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"* Make sure all TLS-1.3 terminations are graceful (previous TLS version terminations already are).\n\n Own Id: OTP-17848\n* Include more information in logging of SNI (Server Name Indication) mismatch error.\n\n Own Id: OTP-19187","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.1.4.2 - SSL Release Notes","ref":"notes.html#ssl-11-1-4-2"},{"type":"extras","doc":"* When the default value for signature_algs is used, default the signature_algs_cert to the default value + rsa_pkcs1_sha1 to allow this algorithms for certificates but not for the TLS protocol. This is for better interoperability. If signature_algs is set explicitly signature_algs_cert must also be set explicitly if they should be different.\n\n Own Id: OTP-19152 Aux Id: GH-8588","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.1.4.1 - SSL Release Notes","ref":"notes.html#ssl-11-1-4-1"},{"type":"extras","doc":"* Check for TLS-1.3 support should check minimum requirements.\n\n Own Id: OTP-19094 Aux Id: GH-8489\n* If both TLS-1.3 and TLS-1.2 is supported and TLS-1.2 negotiated convert TLS-1.3 ECDSA schemes to TLS-1.2 hash and signature pairs for increased interoperability.\n\n Own Id: OTP-19107 Aux Id: GH-8376\n* TLS-1.3 negotiation now uses SNI based options correctly instead of ignoring them.\n\n Own Id: OTP-19140","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"* Make it easier to distinguish between a invalid signature and unsupported signature.\n\n Own Id: OTP-19091\n* Enhance ALERT logs to help understand what causes the alert.\n\n Own Id: OTP-19092 Aux Id: GH-8482","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.1.4 - SSL Release Notes","ref":"notes.html#ssl-11-1-4"},{"type":"extras","doc":"* Fix certificate authorities check so that CA closest to peer is not lost. It could manifest itself in a failed connection as the client failed to realize it had a valid certificate chain to send to the server.\n\n Own Id: OTP-19065 Aux Id: GH-8356, PR-8367\n* ssl:signature_algs/2 did not list some legacy algorithm schemes correctly when listing all algorithms available.\n\n Own Id: OTP-19067 Aux Id: PR-8379","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 11.1.3 - SSL Release Notes","ref":"notes.html#ssl-11-1-3"},{"type":"extras","doc":"* Cleanup and close all connections in DTLS when the listen socket owner dies.\n\n Improved IPv6 handling in DTLS.\n\n Own Id: OTP-19037 Aux Id: GH-7951 GH-7955\n* Fixed a crash in dtls accept.\n\n Own Id: OTP-19059 Aux Id: GH-8338","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 11.1.2 - SSL Release Notes","ref":"notes.html#ssl-11-1-2"},{"type":"extras","doc":"* ssl:prf/5, will start working instead of hanging in a TLS-1.3 context if called appropriately. Note that the implementation has changed and in OTP-27 a more adequate API will be documented.\n\n Own Id: OTP-18890 Aux Id: GH-7911\n* Server name verification didn't work if a connection was made with IP-address as a string.\n\n Own Id: OTP-18909 Aux Id: GH-7968\n* The fallback after \"dh\" ssl option was undefined was to get \"dh\" from ssl options again. This is clearly wrong and now changed to the documented fallback \"dhfile\" ssl option.\n\n Own Id: OTP-18919 Aux Id: PR-7984\n* Correct default value selection for DTLS. Will only affect users linked with really old version of cryptolib library.\n\n Own Id: OTP-18962 Aux Id: GH-8079\n* Adhere elliptic curves with RFC 8422 pre TLS-1.3, that is Edwards curves are added to curves that can be used for key exchange, and documentation and implementation of eccs/0,1 are aligned.\n\n Own Id: OTP-18991","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"* Improve alert reason when ecdhe_rsa key_exchange does not have any common curves to use\n\n Own Id: OTP-18985","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.1.1 - SSL Release Notes","ref":"notes.html#ssl-11-1-1"},{"type":"extras","doc":"* Legacy name handling could cause interop problems between TLS-1.3/1.2 client and TLS-1.2 server.\n\n Own Id: OTP-18917 Aux Id: GH-7978","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 11.1 - SSL Release Notes","ref":"notes.html#ssl-11-1"},{"type":"extras","doc":"- ssl application will validate id-kp-serverAuth and id-kp-clientAuth extended\n key usage only in end entity certificates. public_key application will\n disallow \"anyExtendedKeyUsage\" for CA certificates that includes the extended\n key usage extension and marks it critical.\n\n Own Id: OTP-18739\n\n- Replaced unintentional Erlang Public License 1.1 headers in some files with\n the intended Apache License 2.0 header.\n\n Own Id: OTP-18815 Aux Id: PR-7780\n\n- Correct handling of TLS-1.3 legacy scheme names, could cause interop failures\n for TLS-1.2 clients.\n\n Own Id: OTP-18817\n\n- Add missing export for connection_info() API type.\n\n Own Id: OTP-18886","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Fixed `server name indication` which was not handled properly.\n\n Own Id: OTP-18836 Aux Id: GH-7795\n\n- Align documentation and implementation\n\n Own Id: OTP-18853 Aux Id: PR-7841\n\n- Improve connection setup by optimizing certificate lookup.\n\n Own Id: OTP-18893 Aux Id: PR-7920 PR-7921","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.0.3 - SSL Release Notes","ref":"notes.html#ssl-11-0-3"},{"type":"extras","doc":"- Avoid function clause error in ssl:getopts/2 by handling that inet:getopts may\n return an empty list during some circumstances, such as the socket being in a\n closing state.\n\n Own Id: OTP-18697 Aux Id: GH-7506\n\n- The API function \\`ssl:recv/3\\` has been tightened to disallow negative\n length, which has never been documented to work, but was passed through and\n caused strange errors.\n\n Own Id: OTP-18700 Aux Id: GH-7507\n\n- When a client initiated renegotiation was rejected and the client socket was\n in active mode the expected error message to the controlling process was not\n sent.\n\n Own Id: OTP-18712 Aux Id: GH-7431","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add some guidance for signature algorithms configuration in ssl applications\n users guide.\n\n Own Id: OTP-18631","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.0.2 - SSL Release Notes","ref":"notes.html#ssl-11-0-2"},{"type":"extras","doc":"- Added keylog information to all protocol versions in\n `ssl:connection_information/2`.\n\n Own Id: OTP-18643 Aux Id: ERIERL-932","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add RFC-6083 considerations for DTLS to enable gen_sctp based callback for the\n transport.\n\n Own Id: OTP-18618 Aux Id: ERIERL-932","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.0.1 - SSL Release Notes","ref":"notes.html#ssl-11-0-1"},{"type":"extras","doc":"- Make sure that selection of client certificates handle both TLS-1.3 and\n TLS-1.2 names correctly. Could cause valid client certificate to not be\n selected, and an empty client certificate message to be sent to server.\n\n Own Id: OTP-18588 Aux Id: GH-7264, PR-7277\n\n- Improved `ssl:format_error/1` to handle more error tuples.\n\n Own Id: OTP-18596 Aux Id: GH-7247\n\n- Fixed hanging `ssl:connect` when ssl application is not started.\n\n Own Id: OTP-18603 Aux Id: GH-7297\n\n- Correct handling of retransmission timers, current behavior could cause\n unwanted delays.\n\n Own Id: OTP-18632 Aux Id: PR-7300, GH-7301","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 11.0 - SSL Release Notes","ref":"notes.html#ssl-11-0"},{"type":"extras","doc":"- Remove less that 256 bit ECC from default supported ECC pre TLS-1.3\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-14771\n\n- Improved error checking and handling of ssl options.\n\n Own Id: OTP-15903\n\n- With this change, stateless tickets generated by server with anti_replay\n option enabled can be used for creating ClientHello throughout ticket\n lifetime. Without this change, usability was limited to WindowSize number of\n seconds configured for anti_replay option.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-18168 Aux Id: PR-6019, GH-6014\n\n- Support for Kernel TLS (kTLS), has been added to the SSL application, for TLS\n distribution (`-proto_dist inet_tls`), the SSL option `{ktls, true}`. Using\n this for general SSL sockets is uncomfortable, undocumented and not\n recommended since it requires very platform dependent raw options.\n\n This, for now, only works for some not too old Linux distributions. Roughly, a\n kernel 5.2.0 or later with support for UserLand Protocols and the kernel\n module `tls` is required.\n\n Own Id: OTP-18235 Aux Id: PR-6104, PR-5840\n\n- With this change, TLS 1.3 server can be configured to include client\n certificate in session ticket.\n\n Own Id: OTP-18253\n\n- With this change, it is possible to configure encryption seed to be used with\n TLS1.3 stateless tickets. This enables using tickets on different server\n instances.\n\n Own Id: OTP-18254 Aux Id: PR-5982\n\n- Debugging enhancements.\n\n Own Id: OTP-18312\n\n- With this change, maybe keyword atom is not used as function name in ssl code.\n\n Own Id: OTP-18335\n\n- Replace size/1 with either tuple_size/1 or byte_size/1\n\n The [`size/1`](`size/1`) BIF is not optimized by the JIT, and its use can\n result in worse types for Dialyzer.\n\n When one knows that the value being tested must be a tuple,\n [`tuple_size/1`](`tuple_size/1`) should always be preferred.\n\n When one knows that the value being tested must be a binary,\n [`byte_size/1`](`byte_size/1`) should be preferred. However,\n [`byte_size/1`](`byte_size/1`) also accepts a bitstring (rounding up size to a\n whole number of bytes), so one must make sure that the call to `byte_size/` is\n preceded by a call to [`is_binary/1`](`is_binary/1`) to ensure that bitstrings\n are rejected. Note that the compiler removes redundant calls to\n [`is_binary/1`](`is_binary/1`), so if one is not sure whether previous code\n had made sure that the argument is a binary, it does not harm to add an\n [`is_binary/1`](`is_binary/1`) test immediately before the call to\n [`byte_size/1`](`byte_size/1`).\n\n Own Id: OTP-18405 Aux Id:\n GH-6672,PR-6702,PR-6768,PR-6700,PR-6769,PR-6812,PR-6814\n\n- For security reasons remove support for SHA1 and DSA algorithms from default\n values.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-18438 Aux Id: GH-6679\n\n- Mitigate memory usage from large certificate chains by lowering the maximum\n handshake size. This should not effect the common cases, if needed it can be\n configured to a higher value.\n\n Own Id: OTP-18453\n\n- Change the client default verify option to verify_peer. Note that this makes\n it mandatory to also supply trusted CA certificates or explicitly set verify\n to verify_none. This also applies when using the so called anonymous test\n cipher suites defined in TLS versions pre TLS-1.3.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-18455 Aux Id: GH-5899\n\n- Erlang distribution code in Kernel and SSL has been refactored a bit to\n facilitate debugging and re-usability, which shouldn't have any noticeable\n effects on behaviour or performance.\n\n Own Id: OTP-18456\n\n- Add encoding and decoding of use_srtp hello extension to facilitate for DTLS\n users to implement SRTP functionality.\n\n Own Id: OTP-18459\n\n- Refactors the (`ssl` application to use macros for TLS and DTLS versions\n instead of hard-coded tuple numbers. This change improves the maintainability\n of `ssl`\n\n Own Id: OTP-18465 Aux Id: GH-7065\n\n- If the function ssl:renegotiate/1 is called on connection that is running\n TLS-1.3 return an error instead of hanging or timing out.\n\n Own Id: OTP-18507\n\n- If a user cancel alert with level warning is received during handshake make it\n be handled the same regardless of TLS version. If it is received in connection\n in TLS-1.3 regard it as an error as it is inappropriate.\n\n In TLS-1.3 all error alerts are considered FATAL regardless of legacy alert\n type. But make sure legacy type is printed in logs to not confuse users that\n are expecting the same legacy type as sent by peer.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-18531\n\n- Make `fail_if_no_peer_cert` default true if verify_peer is set on the server,\n otherwise the server will accept the connection if verify_peer is set and the\n user have forgot to set the fail_if_no_peer_cert and the client did not send a\n certificate.\n\n Own Id: OTP-18567\n\n- To make it easier to configure signature algorithms with algorithms that are\n moved from the default add the API function signature_algs/2 that lists\n possible values. Also make sha224 a non default value.\n\n Own Id: OTP-18572","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.9.1.5 - SSL Release Notes","ref":"notes.html#ssl-10-9-1-5"},{"type":"extras","doc":"* TLS-1.3 negotiation now uses SNI based options correctly instead of ignoring them.\n\n Own Id: OTP-19140","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.9.1.4 - SSL Release Notes","ref":"notes.html#ssl-10-9-1-4"},{"type":"extras","doc":"* Fix certificate authorities check so that CA closest to peer is not lost. It could manifest itself in a failed connection as the client failed to realize it had a valid certificate chain to send to the server.\n\n Own Id: OTP-19065 Aux Id: GH-8356, PR-8367","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.9.1.3 - SSL Release Notes","ref":"notes.html#ssl-10-9-1-3"},{"type":"extras","doc":"- ssl application will validate id-kp-serverAuth and id-kp-clientAuth extended\n key usage only in end entity certificates. public_key application will\n disallow \"anyExtendedKeyUsage\" for CA certificates that includes the extended\n key usage extension and marks it critical.\n\n Own Id: OTP-18739\n\n- Add missing export for connection_info() API type.\n\n Own Id: OTP-18886","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.9.1.2 - SSL Release Notes","ref":"notes.html#ssl-10-9-1-2"},{"type":"extras","doc":"- The API function \\`ssl:recv/3\\` has been tightened to disallow negative\n length, which has never been documented to work, but was passed through and\n caused strange errors.\n\n Own Id: OTP-18700 Aux Id: GH-7507\n\n- When a client initiated renegotiation was rejected and the client socket was\n in active mode the expected error message to the controlling process was not\n sent.\n\n Own Id: OTP-18712 Aux Id: GH-7431","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.9.1.1 - SSL Release Notes","ref":"notes.html#ssl-10-9-1-1"},{"type":"extras","doc":"- Added keylog information to all protocol versions in\n `ssl:connection_information/2`.\n\n Own Id: OTP-18643 Aux Id: ERIERL-932","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add RFC-6083 considerations for DTLS to enable gen_sctp based callback for the\n transport.\n\n Own Id: OTP-18618 Aux Id: ERIERL-932","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.9.1 - SSL Release Notes","ref":"notes.html#ssl-10-9-1"},{"type":"extras","doc":"- With this change, ssl:connection_information/2 returns correct keylog data\n after TLS1.3 key update.\n\n Own Id: OTP-18489\n\n- Client signature algorithm list input order is now honored again , it was\n accidently reversed by a previous fix.\n\n Own Id: OTP-18550","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.9 - SSL Release Notes","ref":"notes.html#ssl-10-9"},{"type":"extras","doc":"- Fixed that new `dtls` connections from the same client ip port combination\n works. If there is a process waiting for accept the new connection will\n connect to that, otherwise it will try to re-connect to the old server\n connection.\n\n Own Id: OTP-18371 Aux Id: GH-6160\n\n- When shutting down a node that uses SSL distribution (`-proto_dist inet_tls`),\n a confusing error message about an unexpected process exit was printed. This\n particular message is no longer generated.\n\n Own Id: OTP-18443 Aux Id: PR-6810","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- fixes the type spec for ssl:format_error/1\n\n Own Id: OTP-18366 Aux Id: PR-6565, GH-6506\n\n- Replace size/1 with either tuple_size/1 or byte_size/1\n\n The [`size/1`](`size/1`) BIF is not optimized by the JIT, and its use can\n result in worse types for Dialyzer.\n\n When one knows that the value being tested must be a tuple,\n [`tuple_size/1`](`tuple_size/1`) should always be preferred.\n\n When one knows that the value being tested must be a binary,\n [`byte_size/1`](`byte_size/1`) should be preferred. However,\n [`byte_size/1`](`byte_size/1`) also accepts a bitstring (rounding up size to a\n whole number of bytes), so one must make sure that the call to `byte_size/` is\n preceded by a call to [`is_binary/1`](`is_binary/1`) to ensure that bitstrings\n are rejected. Note that the compiler removes redundant calls to\n [`is_binary/1`](`is_binary/1`), so if one is not sure whether previous code\n had made sure that the argument is a binary, it does not harm to add an\n [`is_binary/1`](`is_binary/1`) test immediately before the call to\n [`byte_size/1`](`byte_size/1`).\n\n Own Id: OTP-18432 Aux Id:\n GH-6672,PR-6793,PR-6784,PR-6787,PR-6785,PR-6682,PR-6800,PR-6797,PR-6798,PR-6799,PR-6796,PR-6813,PR-6671,PR-6673,PR-6684,PR-6694,GH-6677,PR-6696,PR-6670,PR-6674","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.8.7 - SSL Release Notes","ref":"notes.html#ssl-10-8-7"},{"type":"extras","doc":"- Maximize compatibility by ignoring change_cipher_spec during handshake even if\n middle_box_mode is not negotiated (mandated by client)\n\n Own Id: OTP-18433 Aux Id: GH-6772\n\n- Move assert of middlebox message after an hello_retry_request to maximize\n interoperability. Does not changes semantics of the protocol only allows\n unexpected message delay from server.\n\n Own Id: OTP-18467 Aux Id: GH-6807","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.8.6 - SSL Release Notes","ref":"notes.html#ssl-10-8-6"},{"type":"extras","doc":"- With this change, tls_sender process is hibernated after sufficient\n inactivity.\n\n Own Id: OTP-18314 Aux Id: GH-6373\n\n- Correct handling of legacy schemes so that ECDSA certs using sha1 may be used\n for some TLS-1.3 configurations.\n\n Own Id: OTP-18332 Aux Id: GH-6435, PR-6435, ERL-6435\n\n- With this change, tls_sender does not cause logger crash upon key update.\n\n Own Id: OTP-18349","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Enhance warning message\n\n Own Id: OTP-18257 Aux Id: GH-6307\n\n- Provide server option to make certificate_authorities extension in the TLS-1.3\n servers certificate request optional. This will allow clients to send\n incomplete chains that may be reconstructable and thereby verifiable by the\n server, but that would not adhere to the certificate_authorities extension.\n\n Own Id: OTP-18267 Aux Id: PR-6228, GH-6106\n\n- If the `verify_fun` handles four arguments the DER cert will be supplied as\n one of the arguments.\n\n Own Id: OTP-18302 Aux Id: ERIERL-867","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.8.5 - SSL Release Notes","ref":"notes.html#ssl-10-8-5"},{"type":"extras","doc":"- Fixes handling of symlinks in cacertfile option.\n\n Own Id: OTP-18266 Aux Id: GH-6328","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.8.4 - SSL Release Notes","ref":"notes.html#ssl-10-8-4"},{"type":"extras","doc":"- Reject unexpected application data in all relevant places for all TLS\n versions. Also, handle TLS-1.3 middlebox compatibility with more care. This\n will make malicious connections fail early and further, mitigate possible DoS\n attacks, that would be caught by the handshake timeout.\n\n Thanks to Aina Toky Rasoamanana and Olivier Levillain from Télécom SudParis\n for alerting us of the issues in our implementation.\n\n Own Id: OTP-18044\n\n- With this change, value of cacertfile option will be adjusted before loading\n certs from the file. Adjustments include converting relative paths to absolute\n and converting symlinks to actual file path.\n\n Thanks to Marcus Johansson\n\n Own Id: OTP-18099 Aux Id: PR-6287\n\n- In TLS-1.3, if chain certs are missing (so server auth domain adherence can\n not be determined) send peer cert and hope the server is able to recreate a\n chain in its auth domain.\n\n Own Id: OTP-18191 Aux Id: GH-6105\n\n- Make sure periodical refresh of CA certificate files repopulates cache\n properly.\n\n Own Id: OTP-18195\n\n- Correct internal CRL cache functions to use internal format consistently.\n\n Own Id: OTP-18203 Aux Id: PR-5996\n\n- Incorrect handling of client middlebox negotiation for TLS-1.3 could result in\n that a TLS-1.3 server would not use middlebox mode although the client was\n expecting it too and failing the negotiation with unexpected message.\n\n Own Id: OTP-18219 Aux Id: GH-6241, PR-6249\n\n- If the \"User\" process, the process starting the TLS connection, gets killed in\n the middle of spawning the dynamic connection tree make sure we do not leave\n any processes behind.\n\n Own Id: OTP-18233 Aux Id: GH-6244, PR-6270","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- A vulnerability has been discovered and corrected. It is registered as\n CVE-2022-37026 \"Client Authentication Bypass\". Corrections have been released\n on the supported tracks with patches 23.3.4.15, 24.3.4.2, and 25.0.2. The\n vulnerability might also exist in older OTP versions. We recommend that\n impacted users upgrade to one of these versions or later on the respective\n tracks. OTP 25.1 would be an even better choice. Impacted are those who are\n running an ssl/tls/dtls server using the ssl application either directly or\n indirectly via other applications. For example via inets (httpd), cowboy, etc.\n Note that the vulnerability only affects servers that request client\n certification, that is sets the option \\{verify, verify_peer\\}.\n\n Own Id: OTP-18241","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.8.3 - SSL Release Notes","ref":"notes.html#ssl-10-8-3"},{"type":"extras","doc":"- The link to crypto:engine_load refered the function with wrong arity.\n\n Own Id: OTP-18173","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.8.2 - SSL Release Notes","ref":"notes.html#ssl-10-8-2"},{"type":"extras","doc":"- Improved handling of unexpected messages during the handshake, taking the\n right action for unexpected messages.\n\n Own Id: OTP-18145","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.8.1 - SSL Release Notes","ref":"notes.html#ssl-10-8-1"},{"type":"extras","doc":"- When a TLS-1.3 enabled client tried to talk to a TLS-1.2 server that coalesces\n TLS-1.2 handshake message over one TLS record, the connection could fail due\n to some message being handled in the wrong state, this has been fixed.\n\n Own Id: OTP-18087 Aux Id: GH-5961\n\n- Correctly handles supported protocol version change from default to something\n else by sni_fun supplied to ssl:handshake/\\[2,3] together with a TCP-socket\n (so called upgrade).\n\n Own Id: OTP-18100 Aux Id: GH-5985\n\n- Also, TLS-1.3 should respond with a protocol version alert if previous\n versions, that are supported but not configured, are attempted.\n\n Own Id: OTP-18129 Aux Id: GH-5950","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.8 - SSL Release Notes","ref":"notes.html#ssl-10-8"},{"type":"extras","doc":"- When a TLS-1.3 enabled client tried to talk to a TLS-1.2 server that coalesces\n TLS-1.2 handshake message over one TLS record, the connection could fail due\n to some message being handled in the wrong state, this has been fixed.\n\n Own Id: OTP-18087 Aux Id: GH-5961\n\n- Fixed tls-1.3 session ticket lifetime which was discarded to quickly before.\n\n Own Id: OTP-18092 Aux Id: PR-5959","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- With this change, it is possible to provide several certificates. Most\n appropriate will be selected based on negotiated properties.\n\n Own Id: OTP-15993 Aux Id: GH-4143\n\n- Add options for users to be able to set spawn_opts for TLS processes (sender\n and receiver) this may be useful for tuning trade-offs between CPU and Memory\n usage.\n\n Own Id: OTP-17855 Aux Id: PR-5328\n\n- Allow key file passwords to be input as a single binary, that is we change the\n data type to be the more for the purpose logical data type iodata() instead of\n string().\n\n Own Id: OTP-17890\n\n- Logging enhancement, add location information to the warning log message.\n\n Own Id: OTP-18000 Aux Id: PR-5790\n\n- Now also accepts the signature_algs_cert option in TLS-1.2 configuration.\n\n Own Id: OTP-18014\n\n- Handle certificate selection correctly for server fallback and certificate\n authorities considerations.\n\n Own Id: OTP-18045 Aux Id: ERIERL-792, OTP-15993\n\n- Enhance handling of handshake decoding errors, especially for certificate\n authorities extension to ensure graceful termination.\n\n Own Id: OTP-18085","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.7.3.9 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-9"},{"type":"extras","doc":"- When a client initiated renegotiation was rejected and the client socket was\n in active mode the expected error message to the controlling process was not\n sent.\n\n Own Id: OTP-18712 Aux Id: GH-7431","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7.3.8 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-8"},{"type":"extras","doc":"- Added keylog information to all protocol versions in\n `ssl:connection_information/2`.\n\n Own Id: OTP-18643 Aux Id: ERIERL-932","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add RFC-6083 considerations for DTLS to enable gen_sctp based callback for the\n transport.\n\n Own Id: OTP-18618 Aux Id: ERIERL-932","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.7.3.7 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-7"},{"type":"extras","doc":"- Client signature algorithm list input order is now honored again , it was\n accidently reversed by a previous fix.\n\n Own Id: OTP-18550","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7.3.6 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-6"},{"type":"extras","doc":"- Maximize compatibility by ignoring change_cipher_spec during handshake even if\n middle_box_mode is not negotiated (mandated by client)\n\n Own Id: OTP-18433 Aux Id: GH-6772\n\n- Move assert of middlebox message after an hello_retry_request to maximize\n interoperability. Does not changes semantics of the protocol only allows\n unexpected message delay from server.\n\n Own Id: OTP-18467 Aux Id: GH-6807","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.7.3.5 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-5"},{"type":"extras","doc":"- Fixes handling of symlinks in cacertfile option.\n\n Own Id: OTP-18266 Aux Id: GH-6328","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7.3.4 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-4"},{"type":"extras","doc":"- With this change, value of cacertfile option will be adjusted before loading\n certs from the file. Adjustments include converting relative paths to absolute\n and converting symlinks to actual file path.\n\n Thanks to Marcus Johansson\n\n Own Id: OTP-18099 Aux Id: PR-6287\n\n- Incorrect handling of client middlebox negotiation for TLS-1.3 could result in\n that a TLS-1.3 server would not use middlebox mode although the client was\n expecting it too and failing the negotiation with unexpected message.\n\n Own Id: OTP-18219 Aux Id: GH-6241, PR-6249\n\n- If the \"User\" process, the process starting the TLS connection, gets killed in\n the middle of spawning the dynamic connection tree make sure we do not leave\n any processes behind.\n\n Own Id: OTP-18233 Aux Id: GH-6244, PR-6270","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7.3.3 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-3"},{"type":"extras","doc":"- Reject unexpected application data in all relevant places for all TLS\n versions. Also, handle TLS-1.3 middlebox compatibility with more care. This\n will make malicious connections fail early and further, mitigate possible DoS\n attacks, that would be caught by the handshake timeout.\n\n Thanks to Aina Toky Rasoamanana and Olivier Levillain from Télécom SudParis\n for alerting us of the issues in our implementation.\n\n Own Id: OTP-18044\n\n- The link to crypto:engine_load refered the function with wrong arity.\n\n Own Id: OTP-18173\n\n- Make sure periodical refresh of CA certificate files repopulates cache\n properly.\n\n Own Id: OTP-18195","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7.3.2 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-2"},{"type":"extras","doc":"- Improved handling of unexpected messages during the handshake, taking the\n right action for unexpected messages.\n\n Own Id: OTP-18145","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7.3.1 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-1"},{"type":"extras","doc":"- When a TLS-1.3 enabled client tried to talk to a TLS-1.2 server that coalesces\n TLS-1.2 handshake message over one TLS record, the connection could fail due\n to some message being handled in the wrong state, this has been fixed.\n\n Own Id: OTP-18087 Aux Id: GH-5961\n\n- Fixed tls-1.3 session ticket lifetime which was discarded to quickly before.\n\n Own Id: OTP-18092 Aux Id: PR-5959\n\n- Correctly handles supported protocol version change from default to something\n else by sni_fun supplied to ssl:handshake/\\[2,3] together with a TCP-socket\n (so called upgrade).\n\n Own Id: OTP-18100 Aux Id: GH-5985\n\n- Also, TLS-1.3 should respond with a protocol version alert if previous\n versions, that are supported but not configured, are attempted.\n\n Own Id: OTP-18129 Aux Id: GH-5950","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Enhance handling of handshake decoding errors, especially for certificate\n authorities extension to ensure graceful termination.\n\n Own Id: OTP-18085","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.7.3 - SSL Release Notes","ref":"notes.html#ssl-10-7-3"},{"type":"extras","doc":"- Client certification could fail if TLS-1.3 enabled client negotiated TLS-1.2\n connection with the server, this is due to the wrong version being used when\n decoding the certificate request message from the server.\n\n Own Id: OTP-18028 Aux Id: GH-5835\n\n- socket option packet_size was not handled in ssl:setops/2 and ssl:getotps/2\n\n Own Id: OTP-18062 Aux Id: GH-5898\n\n- Remove legacy code to fix interoperability with new socket inet_backend.\n\n Own Id: OTP-18071 Aux Id: GH-5930","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7.2 - SSL Release Notes","ref":"notes.html#ssl-10-7-2"},{"type":"extras","doc":"- With this change, potential hanging of pre TLS1.3 client receiving OSCP staple\n message is avoided.\n\n Own Id: OTP-17994","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7.1 - SSL Release Notes","ref":"notes.html#ssl-10-7-1"},{"type":"extras","doc":"- Client certification could fail for TLS-1.3 servers that did not include the\n certificate_authorities extension in its certificate request message.\n\n Own Id: OTP-17971 Aux Id: GH-5783","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7 - SSL Release Notes","ref":"notes.html#ssl-10-7"},{"type":"extras","doc":"- Improved error handling.\n\n Own Id: OTP-17759 Aux Id: GH-5367\n\n- Before this change, net_kernel used with TLS distribution might be leaking\n processes in case of connectivity issues.\n\n Own Id: OTP-17815 Aux Id: GH-5332\n\n- Fix makefile dependency bugs.\n\n Own Id: OTP-17847 Aux Id: PR-5574 GH-5548\n\n- Make sure the TLS sender process handles explicit calls to\n erlang:disconnect_node properly, avoiding potential hanging problems in\n net_kernel.\n\n Own Id: OTP-17929 Aux Id: GH-5708","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add support for TLS-1.3 certificate_authorities extension. And process\n certificate_authorities field in pre-TLS-1.3 certificate requests.\n\n Own Id: OTP-15719\n\n- Support password fun for protected keyfiles in ssl:connect function.\n\n Own Id: OTP-17816 Aux Id: PR-5607\n\n- Add in some cases earlier detection of possible DoS attacks by malicious\n clients sending unexpected TLS messages instead of the client hello. Note that\n such attacks are already mitigated by providing a timeout for the TLS\n handshake.\n\n Own Id: OTP-17903","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.6.1 - SSL Release Notes","ref":"notes.html#ssl-10-6-1"},{"type":"extras","doc":"- Improve SNI (server name indication) handling so that protocol version can be\n selected with regards to SNI. Also, make sure that\n ssl:connection_information/1 returns the correct SNI value.\n\n Own Id: OTP-17794 Aux Id: GH-5341, GH-4450\n\n- Fixed cipher suite listing functions so that the listing of all cipher suites\n will be complete. Another fix for cipher suite handling in OTP-24.1\n accidentally excludes a few cipher suites from the listing of all cipher\n suites.\n\n Own Id: OTP-17829 Aux Id: ERIERL-708\n\n- Reenable legacy cipher suite TLS_RSA_WITH_3DES_EDE_CBC_SHA for explicit\n configuration in TLS-1.2, not supported by default.\n\n Own Id: OTP-17879 Aux Id: GH-5624","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Avoid unnecessary logs by better adjusting the tls_sender process to the new\n supervisor structure in OTP-24.2\n\n Own Id: OTP-17831","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.6 - SSL Release Notes","ref":"notes.html#ssl-10-6"},{"type":"extras","doc":"- Allow re-connect on DTLS sockets\n\n Can happen when a computer reboots and connects from the same client port\n without the server noticing should be allowed according to RFC.\n\n Own Id: OTP-17411 Aux Id: ERL-1203, GH-4393\n\n- Fix tls and non-tls distribution to use erl_epmd:address_please to figure out\n if IPv4 or IPv6 addresses should be used when connecting to the remote node.\n\n Before this fix, a dns lookup of the remote node hostname determined which IP\n version was to be used which meant that the hostname had to resolve to a valid\n ip address.\n\n Own Id: OTP-17809 Aux Id: PR-5337 GH-5334","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Use supervisor significant child to manage tls connection process and tls\n sender process dependency.\n\n Own Id: OTP-17417\n\n- Random generation adjustment for TLS1.3\n\n Own Id: OTP-17699\n\n- Allow any \\{03,XX\\} TLS record version in the client hello for maximum\n interoperability\n\n Own Id: OTP-17761 Aux Id: GH-5380","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.5.3 - SSL Release Notes","ref":"notes.html#ssl-10-5-3"},{"type":"extras","doc":"- Correct typo of ECC curve name in signature algorithm handling. Will make the\n signature algorithm ecdsa_secp521r1_sha512 succeed.\n\n Own Id: OTP-17756 Aux Id: GH-5383, PR-5397\n\n- Suppress authenticity warning when option verify_none is explicitly supplied.\n\n Own Id: OTP-17757 Aux Id: GH-5352, PR-5395","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.5.2 - SSL Release Notes","ref":"notes.html#ssl-10-5-2"},{"type":"extras","doc":"- Fix TLS-1.2 RSA-PSS negotiation and also fix broken certificate request\n message for pre-TLS-1.3 servers.\n\n Own Id: OTP-17688 Aux Id: GH-5255\n\n- Fix CRL issuer verification that under some circumstances could fail with a\n function_clause error.\n\n Own Id: OTP-17723 Aux Id: GH-5300","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.5.1 - SSL Release Notes","ref":"notes.html#ssl-10-5-1"},{"type":"extras","doc":"- Before that change, TLS downgrade could occasionally fail when data intended\n for downgraded socket were delivered together with CLOSE_NOTIFY alert to ssl\n app.\n\n Own Id: OTP-17393\n\n- Avoid re-encoding of decoded certificates. This could cause unexpected\n failures as some subtle encoding errors can be tolerated when decoding but\n hence creating another sequence of bytes if the decoded value is re-encoded.\n\n Own Id: OTP-17657\n\n- Fix possible process leak when the process doing ssl:transport_accept dies\n before initiating the TLS handshake.\n\n Own Id: OTP-17666 Aux Id: GH-5239\n\n- Fix dtls memory leak, the replay window code was broken.\n\n Own Id: OTP-17670 Aux Id: GH-5224","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.5 - SSL Release Notes","ref":"notes.html#ssl-10-5"},{"type":"extras","doc":"- Fix Makefile dependency generation to work no matter what the `ERL_TOP` folder\n is called.\n\n Own Id: OTP-17423 Aux Id: GH-4823 PR-4829\n\n- If trying to downgrade a TLS-1.3 connection to a plain TCP connection,\n possible TLS-1.3 session ticket messages will be ignored in the \"downgrade\"\n state while waiting for the close notify alert.\n\n Own Id: OTP-17517 Aux Id: GH-5009\n\n- Corrected error handling to correctly generate an insufficient security alert\n when there are no suitable groups that can be negotiated in TLS-1.3 instead of\n crashing resulting in an internal error alert.\n\n Own Id: OTP-17521\n\n- Properly handle default session data storage.\n\n When a client tries to reuse an expired session the default server storage\n handling would crash losing other session data. This would cause a error\n report and possible loss of abbreviated handshakes.\n\n Own Id: OTP-17635 Aux Id: GH-5192","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add support for RSA-PSS-PSS signatures and signature_algorithms_cert in\n TLS-1.2. This is a TLS-1.3 RFC requirement to backport this functionality.\n\n Own Id: OTP-16590 Aux Id: ERL-625, GH-5029\n\n- Use inet:monitor/1 to monitor listen-sockets so that we are compatible with\n the new socket backend for gen_tcp.\n\n Own Id: OTP-17392 Aux Id: PR-5050\n\n- Enhance ssl:prf/4 handling and testing\n\n Own Id: OTP-17464\n\n- Enhanced cipher suite filtering functionality, making sure TLS-1.3 and TLS-1.2\n cipher suites can be supported correctly together even when TLS-1.2 anonymous\n ciphers are included.\n\n Own Id: OTP-17501 Aux Id: GH-4978\n\n- Enhance gracefulness especially in TLS-1.3\n\n Own Id: OTP-17530","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.4.2 - SSL Release Notes","ref":"notes.html#ssl-10-4-2"},{"type":"extras","doc":"- Handle cross-signed root certificates when old root expired as reported in\n GH-4877.\n\n Own Id: OTP-17475 Aux Id: GH-4877\n\n- The signature selection algorithm has been changed to also verify if the\n client supports signatures using the elliptic curve of the server's\n public/private key pair. This change fixes #4958.\n\n Own Id: OTP-17529 Aux Id: PR-4979, GH-4958","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Slight optimization of certificate decoding.\n\n Own Id: OTP-17150 Aux Id: GH-4877","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.4.1 - SSL Release Notes","ref":"notes.html#ssl-10-4-1"},{"type":"extras","doc":"- Fix cache invalidation problem for CA certs provided by the cacertfile option.\n\n Own Id: OTP-17435 Aux Id: ERIERL-653","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.4 - SSL Release Notes","ref":"notes.html#ssl-10-4"},{"type":"extras","doc":"- Missing runtime dependencies has been added to this application.\n\n Own Id: OTP-17243 Aux Id: PR-4557\n\n- TLS handshake should fail if OCSP staple is requested but missing. Note that\n OCSP support is still considered experimental and only partially implemented.\n\n Own Id: OTP-17343","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Removed ssl:ssl_accept/1,2,3 and ssl:cipher:suites/0,1 use ssl:handshake/1,2,3\n and ssl:cipher_suites/2,3 instead.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-16974\n\n- Make TLS handshakes in Erlang distribution concurrent.\n\n Own Id: OTP-17044 Aux Id: PR-2654\n\n- Randomize internal `{active,n}` optimization when running Erlang distribution\n over TLS to spread RAM/CPU spike that may occur when starting up a big\n cluster.\n\n Own Id: OTP-17117 Aux Id: PR-2933\n\n- TLS connections now support EdDSA certificates.\n\n Own Id: OTP-17142 Aux Id: PR-4756, GH-4637, GH-4650\n\n- Enhance documentation and logging of certificate handling.\n\n Own Id: OTP-17384 Aux Id: GH-4800","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.3.1.5 - SSL Release Notes","ref":"notes.html#ssl-10-3-1-5"},{"type":"extras","doc":"- Correct corner case of unexpected message handling for pre TLS-1.3 versions,\n could cause \"late failure\" and make the server dependent on its handshake\n timeout to prevent possible DoS attacks.\n\n Own Id: OTP-18224","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.3.1.4 - SSL Release Notes","ref":"notes.html#ssl-10-3-1-4"},{"type":"extras","doc":"- The link to crypto:engine_load refered the function with wrong arity.\n\n Own Id: OTP-18173","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.3.1.3 - SSL Release Notes","ref":"notes.html#ssl-10-3-1-3"},{"type":"extras","doc":"- Improved handling of unexpected messages during the handshake, taking the\n right action for unexpected messages.\n\n Own Id: OTP-18145","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.3.1.2 - SSL Release Notes","ref":"notes.html#ssl-10-3-1-2"},{"type":"extras","doc":"- Handle cross-signed root certificates when old root expired as reported in\n GH-4877.\n\n Own Id: OTP-17475 Aux Id: GH-4877\n\n- The signature selection algorithm has been changed to also verify if the\n client supports signatures using the elliptic curve of the server's\n public/private key pair. This change fixes #4958.\n\n Own Id: OTP-17529 Aux Id: PR-4979, GH-4958","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Slight optimization of certificate decoding.\n\n Own Id: OTP-17150 Aux Id: GH-4877","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.3.1.1 - SSL Release Notes","ref":"notes.html#ssl-10-3-1-1"},{"type":"extras","doc":"- Fix cache invalidation problem for CA certs provided by the cacertfile option.\n\n Own Id: OTP-17435 Aux Id: ERIERL-653","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.3.1 - SSL Release Notes","ref":"notes.html#ssl-10-3-1"},{"type":"extras","doc":"- Retain backwards compatible behavior of verify_fun when handling incomplete\n chains that are not verifiable.\n\n Own Id: OTP-17296 Aux Id: GH-4682\n\n- Avoid server session handler crash, this will increase session ruse\n opportunities.\n\n Own Id: OTP-17348 Aux Id: ERIERL-641","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.3 - SSL Release Notes","ref":"notes.html#ssl-10-3"},{"type":"extras","doc":"- Fix CRL handling that previously could fail to find the issuer cert under some\n circumstances.\n\n Own Id: OTP-17261 Aux Id: GH-4589\n\n- TLS-1.3 client could, under some circumstances, select an incorrect algorithm\n to sign the certificate verification message causing a TLS Decrypt Alert being\n issued by the server.\n\n Own Id: OTP-17281 Aux Id: GH-4620\n\n- Correct handling of default values for emulated socket options and retain the\n order of the ssl options list to ensure backwards compatible behavior if\n options should be set more than once.\n\n Own Id: OTP-17282","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Enhance pre TLS-1.3 session handling so the client and server side handling is\n completely separated and client disregards oldest session when reaching max\n limit of the session table.\n\n Own Id: OTP-16876\n\n- This change implements the early data feature for TLS 1.3 clients.\n\n TLS 1.3 allows clients to send data in the first flight using a Pre-Shared Key\n to authenticate the server and to encrypt the early data.\n\n Own Id: OTP-16985\n\n- This change implements the early data feature for TLS 1.3 servers.\n\n Own Id: OTP-17042","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.2.4.4 - SSL Release Notes","ref":"notes.html#ssl-10-2-4-4"},{"type":"extras","doc":"- Improved handling of unexpected messages during the handshake, taking the\n right action for unexpected messages.\n\n Own Id: OTP-18145","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.2.4.3 - SSL Release Notes","ref":"notes.html#ssl-10-2-4-3"},{"type":"extras","doc":"- Fix cache invalidation problem for CA certs provided by the cacertfile option.\n\n Own Id: OTP-17435 Aux Id: ERIERL-653","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.2.4.2 - SSL Release Notes","ref":"notes.html#ssl-10-2-4-2"},{"type":"extras","doc":"- Fix handling of emulated socket options, the previous patch was incomplete,\n\n Own Id: OTP-17305","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.2.4.1 - SSL Release Notes","ref":"notes.html#ssl-10-2-4-1"},{"type":"extras","doc":"- Backport of OTP-17282\n\n Correct handling of default values for emulated socket options and retain the\n order of the ssl options list to ensure backwards compatible behavior if\n options should be set more than once.\n\n Own Id: OTP-17289 Aux Id: GH-4585","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.2.4 - SSL Release Notes","ref":"notes.html#ssl-10-2-4"},{"type":"extras","doc":"- Enhance logging option log_level to support none and all, also restore\n backwards compatibility for log_alert option.\n\n Own Id: OTP-17228 Aux Id: ERIERL-614","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.2.3 - SSL Release Notes","ref":"notes.html#ssl-10-2-3"},{"type":"extras","doc":"- Avoid race when the first two upgrade server handshakes (that is servers that\n use a gen_tcp socket as input to ssl:handshake/2,3) start close to each other.\n Could lead to that one of the handshakes would fail.\n\n Own Id: OTP-17190 Aux Id: ERIERL-606","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.2.2 - SSL Release Notes","ref":"notes.html#ssl-10-2-2"},{"type":"extras","doc":"- Avoid that upgrade (from TCP to TLS) servers starts multiple session cache\n handlers for the same server. This applies to Erlang distribution over TLS\n servers.\n\n Own Id: OTP-17139 Aux Id: ERL-1458, OTP-16239\n\n- Legacy cipher suites defined before TLS-1.2 (but still supported) should be\n possible to use in TLS-1.2. They where accidentally excluded for available\n cipher suites for TLS-1.2 in OTP-23.2.2.\n\n Own Id: OTP-17174 Aux Id: ERIERL-597","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Enable Erlang distribution over TLS to run TLS-1.3, although TLS-1.2 will\n still be default.\n\n Own Id: OTP-16239 Aux Id: ERL-1458, OTP-17139","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.2.1 - SSL Release Notes","ref":"notes.html#ssl-10-2-1"},{"type":"extras","doc":"- Fix CVE-2020-35733 this only affects ssl-10.2 (OTP-23.2). This vulnerability\n could enable a man in the middle attack using a fake chain to a known trusted\n ROOT. Also limits alternative chain handling, for handling of possibly\n extraneous certs, to improve memory management.\n\n Own Id: OTP-17098","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add support for AES CCM based cipher suites defined in RFC 7251\n\n Also Correct cipher suite name conversion to OpenSSL names. A few names where\n corrected earlier in OTP-16267 For backwards compatible reasons we support\n usage of openSSL names for cipher suites. Mostly anonymous suites names where\n incorrect, but also some legacy suites.\n\n Own Id: OTP-17100","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.2 - SSL Release Notes","ref":"notes.html#ssl-10-2"},{"type":"extras","doc":"- SSL's Erlang Distribution Protocol modules inet_tls_dist and inet6_tls_dist\n lacked a callback function, so the start flag \"-dist_listen false\" did not\n work, which has now been fixed.\n\n Own Id: OTP-15126 Aux Id: ERL-1375\n\n- Correct OpenSSL names for newer cipher suites using DHE in their name that\n accidentally got the wrong value when fixing other older names using EDH\n instead.\n\n Own Id: OTP-16267 Aux Id: ERIERL-571, ERIERL-477\n\n- This change improves the handling of DTLS listening dockets, making it\n possible to open multiple listeners on the same port with different IP\n addresses.\n\n Own Id: OTP-16849 Aux Id: ERL-1339\n\n- Fix a bug that causes cross-build failure.\n\n This change excludes the ssl.d dependency file from the source tarballs.\n\n Own Id: OTP-16921\n\n- This change fixes ssl:peername/1 when called on a DTLS client socket.\n\n Own Id: OTP-16923 Aux Id: ERL-1341, PR-2786\n\n- Retain emulation of active once on a closed socket to behave as before 23.1\n\n Own Id: OTP-17018 Aux Id: ERL-1409\n\n- Corrected server session cache entry deletion pre TLS-1.3. May increase\n session reuse.\n\n Own Id: OTP-17019 Aux Id: ERL-1412","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Handle extraneous certs in certificate chains as well as chains that are\n incomplete but can be reconstructed or unordered chains. The cert and certfile\n options will now accept a list of certificates so that the user may specify\n the chain explicitly.\n\n Also, the default value of the depth option has been increased to allow longer\n chains by default.\n\n Own Id: OTP-16277\n\n- This change implements optional NSS-style keylog in\n ssl:connection_information/2 for debugging purposes.\n\n The keylog contains various TLS secrets that can be loaded in Wireshark to\n decrypt TLS packets.\n\n Own Id: OTP-16445 Aux Id: PR-2823\n\n- Use new gen_statem feature of changing callback mode to improve code\n maintainability.\n\n Own Id: OTP-16529\n\n- The handling of Service Name Indication has been aligned with RFC8446.\n\n Own Id: OTP-16762\n\n- Add explicit session reuse option to TLS clients for pre TLS-1.3 sessions.\n Also, add documentation to Users Guide for such sessions.\n\n Own Id: OTP-16893","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.1 - SSL Release Notes","ref":"notes.html#ssl-10-1"},{"type":"extras","doc":"- If a passive socket is created, ssl:recv/2,3 is never called and then the peer\n closes the socket the controlling process will no longer receive an active\n close message.\n\n Own Id: OTP-16697 Aux Id: ERIERL-496\n\n- Data deliver with ssl:recv/2,3 could fail for when using packet mode. This has\n been fixed by correcting the flow control handling of passive sockets when\n packet mode is used.\n\n Own Id: OTP-16764\n\n- This change fixes a potential man-in-the-middle vulnerability when the ssl\n client is configured to automatically handle session tickets\n (\\{session_tickets, auto\\}).\n\n Own Id: OTP-16765\n\n- Fix the internal handling of options 'verify' and 'verify_fun'.\n\n This change fixes a vulnerability when setting the ssl option 'verify' to\n verify_peer in a continued handshake won't take any effect resulting in the\n acceptance of expired peer certificates.\n\n Own Id: OTP-16767 Aux Id: ERIERL-512\n\n- This change fixes the handling of stateless session tickets when anti-replay\n is enabled.\n\n Own Id: OTP-16776 Aux Id: ERL-1316\n\n- Fix a crash due to the faulty handling of stateful session tickets received by\n servers expecting stateless session tickets.\n\n This change also improves the handling of faulty/invalid tickets.\n\n Own Id: OTP-16777 Aux Id: ERL-1317\n\n- Correct flow ctrl checks from OTP-16764 to work as intended. Probably will not\n have a noticeable affect but will make connections more well behaved under\n some circumstances.\n\n Own Id: OTP-16837 Aux Id: ERL-1319, OTP-16764\n\n- Distribution over TLS could exhibit livelock-like behaviour when there is a\n constant stream of distribution messages. Distribution data is now chunked\n every 16 Mb to avoid that.\n\n Own Id: OTP-16851 Aux Id: PR-2703","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Implement the cookie extension for TLS 1.3.\n\n Own Id: OTP-15855\n\n- Experimental OCSP client support.\n\n Own Id: OTP-16448\n\n- TLS 1.0 -TLS-1.2 sessions tables now have a absolute max value instead of\n using a shrinking mechanism when reaching the limit. To avoid out of memory\n problems under heavy load situations. Note that this change infers that\n implementations of ssl_session_cache_api needs to implement the size function\n (introduce in OTP 19) for session reuse to be optimally utilized.\n\n Own Id: OTP-16802 Aux Id: ERIERL-516","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.0 - SSL Release Notes","ref":"notes.html#ssl-10-0"},{"type":"extras","doc":"- Fix a bug that causes cross-build failure.\n\n This change excludes the ssl.d dependency file from the source tar balls.\n\n Own Id: OTP-16562 Aux Id: ERL-1168\n\n- Correct translation of OpenSSL legacy names for two legacy cipher suites\n\n Own Id: OTP-16573 Aux Id: ERIERL-477\n\n- Correct documentation for PSK identity and SRP username.\n\n Own Id: OTP-16585\n\n- Make sure client hostname check is run when client uses its own verify_fun\n\n Own Id: OTP-16626 Aux Id: ERL-1232\n\n- Improved signature selection mechanism in TLS 1.3 for increased\n interoperability.\n\n Own Id: OTP-16638 Aux Id: ERL-1206","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Drop support for SSL-3.0. Support for this legacy TLS version has not been\n enabled by default since OTP 19. Now all code to support it has been removed,\n that is SSL-3.0 protocol version can not be used and is considered invalid.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-14790\n\n- Added support for RSA-PSS signature schemes\n\n Own Id: OTP-15247\n\n- Improve interoperability by implementing the middlebox compatibility mode.\n\n The middlebox compatibility mode makes the TLS 1.3 handshake look more like a\n TLS 1.2 handshake and increases the chance of successfully establishing TLS\n 1.3 connections through legacy middleboxes.\n\n Own Id: OTP-15589\n\n- Utilize new properties of\n [`erlang:dist_ctrl_get_data()`](`erlang:dist_ctrl_get_data/1`) for performance\n improvement of Erlang distribution over TLS.\n\n Own Id: OTP-16127 Aux Id: OTP-15618\n\n- Calls of deprecated functions in the\n [Old Crypto API](`e:crypto:new_api.md#the-old-api`) are replaced by calls of\n their [substitutions](`e:crypto:new_api.md#the-new-api`).\n\n Own Id: OTP-16346\n\n- Implement cipher suite TLS_AES_128_CCM_8_SHA256.\n\n Own Id: OTP-16391\n\n- This change adds TLS-1.3 to the list of default supported versions. That is,\n TLS-1.3 and TLS-1.2 are configured when ssl option 'versions' is not\n explicitly set.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-16400\n\n- Refactored the internal handling of deprecated and removed functions.\n\n Own Id: OTP-16469\n\n- Extended ssl:versions so that it lists supported, available and implemented\n TLS/DTLS versions.\n\n Own Id: OTP-16519\n\n- Added new option exclusive for ssl:cipher_suites/2,3\n\n Own Id: OTP-16532\n\n- Avoid DoS attack against stateful session_tickets by making session ticket ids\n unpredictable.\n\n Own Id: OTP-16533\n\n- Add support for the max_fragment_length extension (RFC 6066).\n\n Own Id: OTP-16547 Aux Id: PR-2547\n\n- Add srp_username in ssl:connection_info, update the document with types of\n this function.\n\n Own Id: OTP-16584","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.6.2.3 - SSL Release Notes","ref":"notes.html#ssl-9-6-2-3"},{"type":"extras","doc":"- Correct flow ctrl checks from OTP-16764 to work as intended. Probably will not\n have a noticeable affect but will make connections more well behaved under\n some circumstances.\n\n Own Id: OTP-16837 Aux Id: ERL-1319, OTP-16764\n\n- Fix a bug that causes cross-build failure.\n\n This change excludes the ssl.d dependency file from the source tar balls.\n\n Own Id: OTP-16921","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.6.2.2 - SSL Release Notes","ref":"notes.html#ssl-9-6-2-2"},{"type":"extras","doc":"- Data deliver with ssl:recv/2,3 could fail for when using packet mode. This has\n been fixed by correcting the flow control handling of passive sockets when\n packet mode is used.\n\n Own Id: OTP-16764\n\n- Fix the internal handling of options 'verify' and 'verify_fun'.\n\n This change fixes a vulnerability when setting the ssl option 'verify' to\n verify_peer in a continued handshake won't take any effect resulting in the\n acceptance of expired peer certificates.\n\n Own Id: OTP-16767 Aux Id: ERIERL-512","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.6.2.1 - SSL Release Notes","ref":"notes.html#ssl-9-6-2-1"},{"type":"extras","doc":"- If a passive socket is created, ssl:recv/2,3 is never called and then the peer\n closes the socket the controlling process will no longer receive an active\n close message.\n\n Own Id: OTP-16697 Aux Id: ERIERL-496","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.6.2 - SSL Release Notes","ref":"notes.html#ssl-9-6-2"},{"type":"extras","doc":"- Fix timing bug that could cause ssl sockets to become unresponsive after an\n ssl:recv/3 call timed out\n\n Own Id: OTP-16619 Aux Id: ERL-1213","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.6.1 - SSL Release Notes","ref":"notes.html#ssl-9-6-1"},{"type":"extras","doc":"- Correct error handling when the partial_chain fun claims a certificate to be\n the trusted cert that is not part of the chain. This bug would hide the\n appropriate alert generating an \"INTERNAL_ERROR\" alert instead.\n\n Own Id: OTP-16567 Aux Id: ERIERL-481","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.6 - SSL Release Notes","ref":"notes.html#ssl-9-6"},{"type":"extras","doc":"- Correct handling of TLS record limit in TLS-1.3. The max value differs from\n previous versions. Also the payload data max record check was broken, that is\n record overflow problems could occur if user sent large amounts of data.\n\n Own Id: OTP-16258\n\n- Correct close handling for DTLS\n\n Own Id: OTP-16348 Aux Id: ERL-1110\n\n- Fix ssl:getstat/1-2 to also work for DTLS sockets\n\n Own Id: OTP-16352 Aux Id: ERL-1099\n\n- Correct internal handling och socket active mode to avoid reviving TCP data\n aimed for a downgraded TLS socket.\n\n Own Id: OTP-16425\n\n- When using the host name as fallback for SNI (server name indication) strip a\n possible trailing dot that is allowed in a host name but not in the SNI. Also\n if the server receives a SNI with a trailing dot send an UNRECOGNIZED_NAME\n alert.\n\n Own Id: OTP-16437 Aux Id: ERL-1135\n\n- Immediately remove session entries if handshake is abruptly closed at\n transport level.\n\n Own Id: OTP-16479","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Implementation of the key and initialization vector update feature, and\n general hardening of TLS 1.3.\n\n There are cryptographic limits on the amount of plaintext which can be safely\n encrypted under a given set of keys.\n\n This change enforces those limits by triggering automatic key updates on TLS\n 1.3 connections.\n\n Own Id: OTP-15856\n\n- Add support for TLS 1.3 Session Tickets (stateful and stateless). This allows\n session resumption using keying material from a previous successful handshake.\n\n Own Id: OTP-16253\n\n- Add support for key exchange with Edward curves and PSS-RSA padding in\n signature verification.\n\n Own Id: OTP-16528","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.5.3 - SSL Release Notes","ref":"notes.html#ssl-9-5-3"},{"type":"extras","doc":"- Enhance error handling, all ALERTS shall be handled gracefully and not cause a\n crash.\n\n Own Id: OTP-16413 Aux Id: ERL-1136\n\n- Enhance alert logging, in some places the role indication of the alert origin\n was missing. So the log would say undefined instead of client or server.\n\n Own Id: OTP-16424\n\n- Two different optimizations did not work together and resulted in the possible\n breakage of connections using stream ciphers (that is RC4). Reworked the\n implementation to avoid this.\n\n Own Id: OTP-16426 Aux Id: ERL-1136","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.5.2 - SSL Release Notes","ref":"notes.html#ssl-9-5-2"},{"type":"extras","doc":"- Fix the handling of GREASE values sent by web browsers when establishing TLS\n 1.3 connections. This change improves handling of GREASE values in various\n protocol elements sent in a TLS 1.3 ClientHello.\n\n Own Id: OTP-16388 Aux Id: ERL-1130\n\n- Correct DTLS listen emulation, could cause problems with opening a new DTLS\n listen socket for a port previously used by a now closed DTLS listen socket.\n\n Own Id: OTP-16396 Aux Id: ERL-1118","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.5.1 - SSL Release Notes","ref":"notes.html#ssl-9-5-1"},{"type":"extras","doc":"- Add missing alert handling clause for TLS record handling. Could sometimes\n cause confusing error behaviors of TLS connections.\n\n Own Id: OTP-16357 Aux Id: ERL-1166\n\n- Fix handling of ssl:recv that happens during a renegotiation. Using the\n passive receive function ssl:recv/\\[2,3] during a renegotiation would fail the\n connection with unexpected msg.\n\n Own Id: OTP-16361","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.5 - SSL Release Notes","ref":"notes.html#ssl-9-5"},{"type":"extras","doc":"- Corrected CRL handling which could cause CRL verification to fail. This could\n happen when the CRL distribution point explicitly specifies the CRL issuer,\n that is not using the fallback.\n\n Own Id: OTP-16156 Aux Id: ERL-1030\n\n- Correct handling of unordered chains so that it works as expected\n\n Own Id: OTP-16293\n\n- Fix bug causing ssl application to crash when handshake is paused and\n ClientHello contains extensions for session resumption\n (psk_key_exchange_modes, pre_shared_key).\n\n Own Id: OTP-16295 Aux Id: ERL-1095\n\n- Fix connectivity problems with legacy servers when client is configured to\n support a range of protocol versions including TLS 1.3.\n\n Own Id: OTP-16303","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Improve session handling for TLS-1.3 compatibility mode and cleaner internal\n handling so that removal of old session data can be more efficient, hopefully\n mitigating problems with big session tables during heavy load.\n\n Own Id: OTP-15524 Aux Id: OTP-15352\n\n- Correct handling of DTLS listen socket emulation. Could cause failure to\n create new listen socket after process that owned previous listen socket died.\n\n Own Id: OTP-15809 Aux Id: ERL-917\n\n- Add detailed info in ALERT description when client does not send a requested\n cert.\n\n Own Id: OTP-16266","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.4 - SSL Release Notes","ref":"notes.html#ssl-9-4"},{"type":"extras","doc":"- Handling of zero size fragments in TLS could cause an infinite loop. This has\n now been corrected.\n\n Own Id: OTP-15328 Aux Id: ERIERL-379\n\n- DTLS record check needs to consider that a resent hello message can have a\n different version than the negotiated.\n\n Own Id: OTP-15807 Aux Id: ERL-920","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Basic support for TLS 1.3 Client for experimental use. For more information\n see the Standards Compliance chapter of the User's Guide.\n\n Own Id: OTP-15431\n\n- Correct solution for retaining tcp flow control OTP-15802 (ERL-934) as to not\n break ssl:recv as reported in (ERL-938)\n\n Own Id: OTP-15823 Aux Id: ERL-934, ERL-938\n\n- Enhance dialyzer specs to reflect implementation better and avoid dialyzer\n warnings for the user that wants to use TLS with unix domain sockets.\n\n Own Id: OTP-15851 Aux Id: PR-2235\n\n- Add support for ECDSA signature algorithms in TLS 1.3.\n\n Own Id: OTP-15854\n\n- Correct error handling of TLS downgrade, possible return values form\n ssl:close/2 when downgrading is \\{ok, Port\\} or \\{error, Reason\\}, it could\n happen that only ok was returned instead of \\{error, closed\\} when downgrade\n failed due to that the peer closed the TCP connection.\n\n Own Id: OTP-16027","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.3.5 - SSL Release Notes","ref":"notes.html#ssl-9-3-5"},{"type":"extras","doc":"- Enhance error handling for erroneous alerts from the peer.\n\n Own Id: OTP-15943","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.3.4 - SSL Release Notes","ref":"notes.html#ssl-9-3-4"},{"type":"extras","doc":"- Fix handling of certificate decoding problems in TLS 1.3 similarly as in TLS\n 1.2.\n\n Own Id: OTP-15900\n\n- Hibernation now works as expected in all cases, was accidentally broken by\n optimization efforts.\n\n Own Id: OTP-15910\n\n- Fix interoperability problems with openssl when the TLS 1.3 server is\n configured with the option signature_algs_cert.\n\n Own Id: OTP-15913","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.3.3 - SSL Release Notes","ref":"notes.html#ssl-9-3-3"},{"type":"extras","doc":"- Correct handshake handling, might cause strange symptoms such as ASN.1\n certificate decoding issues.\n\n Own Id: OTP-15879 Aux Id: ERL-968\n\n- Fix handling of the signature_algorithms_cert extension in the ClientHello\n handshake message.\n\n Own Id: OTP-15887 Aux Id: ERL-973\n\n- Handle new ClientHello extensions when handshake is paused by the \\{handshake,\n hello\\} ssl option.\n\n Own Id: OTP-15888 Aux Id: ERL-975","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.3.2 - SSL Release Notes","ref":"notes.html#ssl-9-3-2"},{"type":"extras","doc":"- Returned \"alert error string\" is now same as logged alert string\n\n Own Id: OTP-15844\n\n- Fix returned extension map fields to follow the documentation.\n\n Own Id: OTP-15862 Aux Id: ERL-951\n\n- Avoid DTLS crash due to missing gen_server return value in DTLS packet demux\n process.\n\n Own Id: OTP-15864 Aux Id: ERL-962","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.3.1 - SSL Release Notes","ref":"notes.html#ssl-9-3-1"},{"type":"extras","doc":"- Missing check of size of user_data_buffer made internal socket behave as an\n active socket instead of active N. This could cause memory problems.\n\n Own Id: OTP-15825 Aux Id: ERL-934, OTP-15823","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.3 - SSL Release Notes","ref":"notes.html#ssl-9-3"},{"type":"extras","doc":"- The distribution handshake with TLS distribution (`inet_tls_dist`) does now\n utilize the socket option `{nodelay, true}`, which decreases the distribution\n setup time significantly.\n\n Own Id: OTP-14792\n\n- Correct shutdown reason to avoid an incorrect crash report\n\n Own Id: OTP-15710 Aux Id: ERL-893\n\n- Enhance documentation and type specifications.\n\n Own Id: OTP-15746 Aux Id: ERIERL-333","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- TLS-1.0, TLS-1.1 and DTLS-1.0 are now considered legacy and not supported by\n default\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-14865\n\n- Use new logger API in ssl. Introduce log levels and verbose debug logging for\n SSL.\n\n Own Id: OTP-15055\n\n- Add new API function str_to_suite/1, cipher_suites/3 (list cipher suites as\n rfc or OpenSSL name strings) and suite_to_openssl_str/1\n\n Own Id: OTP-15483 Aux Id: ERL-924\n\n- Basic support for TLS 1.3 Server for experimental use. The client is not yet\n functional, for more information see the Standards Compliance chapter of the\n User's Guide.\n\n Own Id: OTP-15591\n\n- Add support for PSK CCM ciphers from RFC 6655\n\n Own Id: OTP-15626","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.2.3.7 - SSL Release Notes","ref":"notes.html#ssl-9-2-3-7"},{"type":"extras","doc":"- Data deliver with ssl:recv/2,3 could fail for when using packet mode. This has\n been fixed by correcting the flow control handling of passive sockets when\n packet mode is used.\n\n Own Id: OTP-16764","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2.3.6 - SSL Release Notes","ref":"notes.html#ssl-9-2-3-6"},{"type":"extras","doc":"- Fix timing bug that could cause ssl sockets to become unresponsive after an\n ssl:recv/3 call timed out\n\n Own Id: OTP-16619 Aux Id: ERL-1213","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2.3.5 - SSL Release Notes","ref":"notes.html#ssl-9-2-3-5"},{"type":"extras","doc":"- Handling of zero size fragments in TLS could cause an infinite loop. This has\n now been corrected.\n\n Own Id: OTP-15328 Aux Id: ERIERL-379","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2.3.4 - SSL Release Notes","ref":"notes.html#ssl-9-2-3-4"},{"type":"extras","doc":"- Hibernation now works as expected in all cases, was accidentally broken by\n optimization efforts.\n\n Own Id: OTP-15910","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2.3.3 - SSL Release Notes","ref":"notes.html#ssl-9-2-3-3"},{"type":"extras","doc":"- Correct handshake handling, might cause strange symptoms such as ASN.1\n certificate decoding issues.\n\n Own Id: OTP-15879 Aux Id: ERL-968","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2.3.2 - SSL Release Notes","ref":"notes.html#ssl-9-2-3-2"},{"type":"extras","doc":"- Returned \"alert error string\" is now same as logged alert string\n\n Own Id: OTP-15844","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2.3.1 - SSL Release Notes","ref":"notes.html#ssl-9-2-3-1"},{"type":"extras","doc":"- Correct solution for retaining tcp flow control OTP-15802 (ERL-934) as to not\n break ssl:recv as reported in (ERL-938)\n\n Own Id: OTP-15823 Aux Id: ERL-934, ERL-938","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2.3 - SSL Release Notes","ref":"notes.html#ssl-9-2-3"},{"type":"extras","doc":"- Missing check of size of user_data_buffer made internal socket behave as an\n active socket instead of active N. This could cause memory problems.\n\n Own Id: OTP-15802 Aux Id: ERL-934","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Back port of bug fix ERL-893 from OTP-22 and document enhancements that will\n solve dialyzer warnings for users of the ssl application.\n\n This change also affects public_key, eldap (and inet doc).\n\n Own Id: OTP-15785 Aux Id: ERL-929, ERL-893, PR-2215","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.2.2 - SSL Release Notes","ref":"notes.html#ssl-9-2-2"},{"type":"extras","doc":"- With the default BEAST Mitigation strategy for TLS 1.0 an empty TLS fragment\n could be sent after a one-byte fragment. This glitch has been fixed.\n\n Own Id: OTP-15054 Aux Id: ERIERL-346","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2.1 - SSL Release Notes","ref":"notes.html#ssl-9-2-1"},{"type":"extras","doc":"- The timeout for a passive receive was sometimes not cancelled and later caused\n a server crash. This bug has now been corrected.\n\n Own Id: OTP-14701 Aux Id: ERL-883, ERL-884\n\n- Add tag for passive message (active N) in cb_info to retain transport\n transparency.\n\n Own Id: OTP-15679 Aux Id: ERL-861","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2 - SSL Release Notes","ref":"notes.html#ssl-9-2"},{"type":"extras","doc":"- Fix bug that an incorrect return value for gen_statem could be created when\n alert was a result of handling renegotiation info extension\n\n Own Id: OTP-15502\n\n- Correct check for 3des_ede_cbc, could cause ssl to claim to support\n 3des_ede_cbc when cryptolib does not.\n\n Own Id: OTP-15539\n\n- Improved DTLS error handling, avoids unexpected connection failure in rare\n cases.\n\n Own Id: OTP-15561\n\n- Corrected active once emulation bug that could cause the ssl_closed meassage\n to not be sent. Bug introduced by OTP-15449\n\n Own Id: OTP-15666 Aux Id: ERIERL-316,","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add client option \\{reuse_session, SessionID::binary()\\} that can be used\n together with new option value \\{reuse_sessions, save\\}. This makes it\n possible to reuse a session from a specific connection establishment.\n\n Own Id: OTP-15369\n\n- The Reason part of of the error return from the functions connect and\n handshake has a better and documented format. This will sometimes differ from\n previous returned reasons, however those where only documented as term() and\n should for that reason not be relied on.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-15423\n\n- Refactor of state handling to improve TLS application data throughput and\n reduce CPU overhead\n\n Own Id: OTP-15445\n\n- The SSL code has been optimized in many small ways to reduce CPU load for\n encryption/decryption, especially for Erlang's distribution protocol over TLS.\n\n Own Id: OTP-15529\n\n- Add support for active N\n\n Own Id: OTP-15665 Aux Id: ERL-811, PR-2072","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.1.2 - SSL Release Notes","ref":"notes.html#ssl-9-1-2"},{"type":"extras","doc":"- Fix encoding of the SRP extension length field in ssl. The old encoding of the\n SRP extension length could cause interoperability problems with third party\n SSL implementations when SRP was used.\n\n Own Id: OTP-15477 Aux Id: ERL-790\n\n- Guarantee active once data delivery, handling TCP stream properly.\n\n Own Id: OTP-15504 Aux Id: ERL-371\n\n- Correct gen_statem returns for some error cases\n\n Own Id: OTP-15505","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.1.1 - SSL Release Notes","ref":"notes.html#ssl-9-1-1"},{"type":"extras","doc":"- Fixed renegotiation bug. Client did not handle server initiated renegotiation\n correctly after rewrite to two connection processes, due to ERL-622 commit\n d87ac1c55188f5ba5cdf72384125d94d42118c18. This could manifest it self as a \"\n bad_record_mac\" alert.\n\n Also included are some optimizations\n\n Own Id: OTP-15489 Aux Id: ERL-308","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.1 - SSL Release Notes","ref":"notes.html#ssl-9-1"},{"type":"extras","doc":"- PEM cache was not evicting expired entries due to due to timezone confusion.\n\n Own Id: OTP-15368\n\n- Make sure an error is returned if a \"transport_accept socket\" is used in some\n other call than ssl:handshake\\* or ssl:controlling_process\n\n Own Id: OTP-15384 Aux Id: ERL-756\n\n- Fix timestamp handling in the PEM-cache could cause entries to not be\n invalidated at the correct time.\n\n Own Id: OTP-15402\n\n- Extend check for undelivered data at closing, could under some circumstances\n fail to deliver all data that was actually received.\n\n Own Id: OTP-15412 Aux Id: ERL-731\n\n- Correct signature check for TLS-1.2 that allows different algorithms for\n signature of peer cert and peer cert key. Not all allowed combinations where\n accepted.\n\n Own Id: OTP-15415 Aux Id: ERL-763\n\n- Correct gen_statem return value, could cause renegotiation to fail.\n\n Own Id: OTP-15418 Aux Id: ERL-770","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add engine support for RSA key exchange\n\n Own Id: OTP-15420 Aux Id: ERIERL-268\n\n- ssl now uses active n internally to boost performance. Old active once\n behavior can be restored by setting application variable see manual page for\n ssl application (man 6).\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-15449","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.0.3 - SSL Release Notes","ref":"notes.html#ssl-9-0-3"},{"type":"extras","doc":"- Correct alert handling with new TLS sender process, from ssl-9.0.2. CLOSE\n ALERTS could under some circumstances be encoded using an incorrect cipher\n state. This would cause the peer to regard them as unknown messages.\n\n Own Id: OTP-15337 Aux Id: ERL-738\n\n- Correct handling of socket packet option with new TLS sender process, from\n ssl-9.0.2. When changing the socket option \\{packet, 1|2|3|4\\} with\n ssl:setopts/2 the option must internally be propagated to the sender process\n as well as the reader process as this particular option also affects the data\n to be sent.\n\n Own Id: OTP-15348 Aux Id: ERL-747","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.0.2 - SSL Release Notes","ref":"notes.html#ssl-9-0-2"},{"type":"extras","doc":"- Use separate processes for sending and receiving application data for TLS\n connections to avoid potential deadlock that was most likely to occur when\n using TLS for Erlang distribution. Note does not change the API.\n\n Own Id: OTP-15122\n\n- Correct handling of empty server SNI extension\n\n Own Id: OTP-15168\n\n- Correct PSK cipher suite handling and add selected_cipher_suite to connection\n information\n\n Own Id: OTP-15172\n\n- Adopt to the fact that cipher suite sign restriction are relaxed in TLS-1.2\n\n Own Id: OTP-15173\n\n- Enhance error handling of non existing PEM files\n\n Own Id: OTP-15174\n\n- Correct close handling of transport accepted sockets in the error state\n\n Own Id: OTP-15216\n\n- Correct PEM cache to not add references to empty entries when PEM file does\n not exist.\n\n Own Id: OTP-15224\n\n- Correct handling of all PSK cipher suites\n\n Before only some PSK suites would be correctly negotiated and most PSK ciphers\n suites would fail the connection.\n\n Own Id: OTP-15285","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- TLS will now try to order certificate chains if they appear to be unordered.\n That is prior to TLS 1.3, “certificate_list” ordering was required to be\n strict, however some implementations already allowed for some flexibility. For\n maximum compatibility, all implementations SHOULD be prepared to handle\n potentially extraneous certificates and arbitrary orderings from any TLS\n version.\n\n Own Id: OTP-12983\n\n- TLS will now try to reconstructed an incomplete certificate chains from its\n local CA-database and use that data for the certificate path validation. This\n especially makes sense for partial chains as then the peer might not send an\n intermediate CA as it is considered the trusted root in that case.\n\n Own Id: OTP-15060\n\n- Option keyfile defaults to certfile and should be trumped with key. This\n failed for engine keys.\n\n Own Id: OTP-15193\n\n- Error message improvement when own certificate has decoding issues, see also\n issue ERL-668.\n\n Own Id: OTP-15234\n\n- Correct dialyzer spec for key option\n\n Own Id: OTP-15281","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.0.1 - SSL Release Notes","ref":"notes.html#ssl-9-0-1"},{"type":"extras","doc":"- Correct cipher suite handling for ECDHE\\_\\*, the incorrect handling could\n cause an incorrrect suite to be selected and most likely fail the handshake.\n\n Own Id: OTP-15203","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.0 - SSL Release Notes","ref":"notes.html#ssl-9-0"},{"type":"extras","doc":"- Correct handling of ECDH suites.\n\n Own Id: OTP-14974\n\n- Proper handling of clients that choose to send an empty answer to a\n certificate request\n\n Own Id: OTP-15050","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Distribution over SSL (inet_tls) has, to improve performance, been rewritten\n to not use intermediate processes and ports.\n\n Own Id: OTP-14465\n\n- Add support for ECDHE_PSK cipher suites\n\n Own Id: OTP-14547\n\n- For security reasons no longer support 3-DES cipher suites by default\n\n \\*** INCOMPATIBILITY with possibly \\***\n\n Own Id: OTP-14768\n\n- For security reasons RSA-key exchange cipher suites are no longer supported by\n default\n\n \\*** INCOMPATIBILITY with possible \\***\n\n Own Id: OTP-14769\n\n- The interoperability option to fallback to insecure renegotiation now has to\n be explicitly turned on.\n\n \\*** INCOMPATIBILITY with possibly \\***\n\n Own Id: OTP-14789\n\n- Drop support for SSLv2 enabled clients. SSLv2 has been broken for decades and\n never supported by the Erlang SSL/TLS implementation. This option was by\n default disabled and enabling it has proved to sometimes break connections not\n using SSLv2 enabled clients.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-14824\n\n- Remove CHACHA20_POLY1305 ciphers form default for now. We have discovered\n interoperability problems, ERL-538, that we believe needs to be solved in\n crypto.\n\n \\*** INCOMPATIBILITY with possibly \\***\n\n Own Id: OTP-14882\n\n- Generalize DTLS packet multiplexing to make it easier to add future DTLS\n features and uses.\n\n Own Id: OTP-14888\n\n- Use uri_string module instead of http_uri.\n\n Own Id: OTP-14902\n\n- The SSL distribution protocol `-proto inet_tls` has stopped setting the SSL\n option `server_name_indication`. New verify funs for client and server in\n `inet_tls_dist` has been added, not documented yet, that checks node name if\n present in peer certificate. Usage is still also yet to be documented.\n\n Own Id: OTP-14969 Aux Id: OTP-14465, ERL-598\n\n- Deprecate ssl:ssl_accept/\\[1,2,3] in favour of ssl:handshake/\\[1,2,3]\n\n Own Id: OTP-15056\n\n- Customizes the hostname verification of the peer certificate, as different\n protocols that use TLS such as HTTP or LDAP may want to do it differently\n\n Own Id: OTP-15102 Aux Id: ERL-542, OTP-14962\n\n- Add utility function for converting erlang cipher suites to a string\n representation (ERL-600).\n\n Own Id: OTP-15106\n\n- First version with support for DTLS\n\n Own Id: OTP-15142","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.2.6.4 - SSL Release Notes","ref":"notes.html#ssl-8-2-6-4"},{"type":"extras","doc":"- Add engine support for RSA key exchange\n\n Own Id: OTP-15420","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.2.6.3 - SSL Release Notes","ref":"notes.html#ssl-8-2-6-3"},{"type":"extras","doc":"- Extend check for undelivered data at closing, could under some circumstances\n fail to deliverd all data that was acctualy recivied.\n\n Own Id: OTP-15412","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.2.6.2 - SSL Release Notes","ref":"notes.html#ssl-8-2-6-2"},{"type":"extras","doc":"- Correct handling of empty server SNI extension\n\n Own Id: OTP-15168\n\n- Correct cipher suite handling for ECDHE\\_\\*, the incorrect handling could\n cause an incorrrect suite to be selected and most likely fail the handshake.\n\n Own Id: OTP-15203","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.2.6.1 - SSL Release Notes","ref":"notes.html#ssl-8-2-6-1"},{"type":"extras","doc":"- Improve cipher suite handling correcting ECC and TLS-1.2 requierments.\n Backport of solution for ERL-641\n\n Own Id: OTP-15178","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Option keyfile defaults to certfile and should be trumped with key. This\n failed for engine keys.\n\n Own Id: OTP-15193","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.2.6 - SSL Release Notes","ref":"notes.html#ssl-8-2-6"},{"type":"extras","doc":"- Proper handling of clients that choose to send an empty answer to a\n certificate request\n\n Own Id: OTP-15050","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.2.5 - SSL Release Notes","ref":"notes.html#ssl-8-2-5"},{"type":"extras","doc":"- Fix filter function to not incorrectly exclude AEAD cipher suites\n\n Own Id: OTP-14981","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.2.4 - SSL Release Notes","ref":"notes.html#ssl-8-2-4"},{"type":"extras","doc":"- Optimization of bad merge conflict resolution causing dubble decode\n\n Own Id: OTP-14843\n\n- Restore error propagation to OTP-19.3 behaviour, in OTP-20.2 implementation\n adjustments to gen_statem needed some further adjustments to avoid a race\n condition. This could cause a TLS server to not always report file path errors\n correctly.\n\n Own Id: OTP-14852\n\n- Corrected RC4 suites listing function to regard TLS version\n\n Own Id: OTP-14871\n\n- Fix alert handling so that unexpected messages are logged and alerted\n correctly\n\n Own Id: OTP-14919\n\n- Correct handling of anonymous cipher suites\n\n Own Id: OTP-14952","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Added new API functions to facilitate cipher suite handling\n\n Own Id: OTP-14760\n\n- Correct TLS_FALLBACK_SCSV handling so that this special flag suite is always\n placed last in the cipher suite list in accordance with the specs. Also make\n sure this functionality is used in DTLS.\n\n Own Id: OTP-14828\n\n- Add TLS record version sanity check for early as possible error detection and\n consistency in ALERT codes generated\n\n Own Id: OTP-14892","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.2.3 - SSL Release Notes","ref":"notes.html#ssl-8-2-3"},{"type":"extras","doc":"- Packet options cannot be supported for unreliable transports, that is, packet\n option for DTLS over udp will not be supported.\n\n Own Id: OTP-14664\n\n- Ensure data delivery before close if possible. This fix is related to fix in\n PR-1479.\n\n Own Id: OTP-14794","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The crypto API is extended to use private/public keys stored in an Engine for\n sign/verify or encrypt/decrypt operations.\n\n The ssl application provides an API to use this new engine concept in TLS.\n\n Own Id: OTP-14448\n\n- Implemented renegotiation for DTLS\n\n Own Id: OTP-14563\n\n- A new command line option `-ssl_dist_optfile` has been added to facilitate\n specifying the many options needed when using SSL as the distribution\n protocol.\n\n Own Id: OTP-14657","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.2.2 - SSL Release Notes","ref":"notes.html#ssl-8-2-2"},{"type":"extras","doc":"- TLS sessions must be registered with SNI if provided, so that sessions where\n client hostname verification would fail cannot connect reusing a session\n created when the server name verification succeeded.\n\n Own Id: OTP-14632\n\n- An erlang TLS server configured with cipher suites using rsa key exchange, may\n be vulnerable to an Adaptive Chosen Ciphertext attack (AKA Bleichenbacher\n attack) against RSA, which when exploited, may result in plaintext recovery of\n encrypted messages and/or a Man-in-the-middle (MiTM) attack, despite the\n attacker not having gained access to the server’s private key itself.\n [CVE-2017-1000385](https://nvd.nist.gov/vuln/detail/CVE-2017-1000385)\n\n Exploiting this vulnerability to perform plaintext recovery of encrypted\n messages will, in most practical cases, allow an attacker to read the\n plaintext only after the session has completed. Only TLS sessions established\n using RSA key exchange are vulnerable to this attack.\n\n Exploiting this vulnerability to conduct a MiTM attack requires the attacker\n to complete the initial attack, which may require thousands of server\n requests, during the handshake phase of the targeted session within the window\n of the configured handshake timeout. This attack may be conducted against any\n TLS session using RSA signatures, but only if cipher suites using RSA key\n exchange are also enabled on the server. The limited window of opportunity,\n limitations in bandwidth, and latency make this attack significantly more\n difficult to execute.\n\n RSA key exchange is enabled by default although least prioritized if server\n order is honored. For such a cipher suite to be chosen it must also be\n supported by the client and probably the only shared cipher suite.\n\n Captured TLS sessions encrypted with ephemeral cipher suites (DHE or ECDHE)\n are not at risk for subsequent decryption due to this vulnerability.\n\n As a workaround if default cipher suite configuration was used you can\n configure the server to not use vulnerable suites with the ciphers option like\n this:\n\n `{ciphers, [Suite || Suite <- ssl:cipher_suites(), element(1,Suite) =/= rsa]}`\n\n that is your code will look somethingh like this:\n\n `ssl:listen(Port, [{ciphers, [Suite || Suite <- ssl:cipher_suites(), element(1,S) =/= rsa]} | Options]).`\n\n Thanks to Hanno Böck, Juraj Somorovsky and Craig Young for reporting this\n vulnerability.\n\n Own Id: OTP-14748","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- If no SNI is available and the hostname is an IP-address also check for\n IP-address match. This check is not as good as a DNS hostname check and\n certificates using IP-address are not recommended.\n\n Own Id: OTP-14655","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.2.1 - SSL Release Notes","ref":"notes.html#ssl-8-2-1"},{"type":"extras","doc":"- Max session table works correctly again\n\n Own Id: OTP-14556","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Customize alert handling for DTLS over UDP to mitigate DoS attacks\n\n Own Id: OTP-14078\n\n- Improved error propagation and reports\n\n Own Id: OTP-14236","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.2 - SSL Release Notes","ref":"notes.html#ssl-8-2"},{"type":"extras","doc":"- ECDH-ECDSA key exchange supported, was accidentally dismissed in earlier\n versions.\n\n Own Id: OTP-14421\n\n- Correct close semantics for active once connections. This was a timing\n dependent bug the resulted in the close message not always reaching the ssl\n user process.\n\n Own Id: OTP-14443","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- TLS-1.2 clients will now always send hello messages on its own format, as\n opposed to earlier versions that will send the hello on the lowest supported\n version, this is a change supported by the latest RFC.\n\n This will make interoperability with some newer servers smoother. Potentially,\n but unlikely, this could cause a problem with older servers if they do not\n adhere to the RFC and ignore unknown extensions.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-13820\n\n- Allow Erlang/OTP to use OpenSSL in FIPS-140 mode, in order to satisfy specific\n security requirements (mostly by different parts of the US federal\n government).\n\n See the new crypto users guide \"FIPS mode\" chapter about building and using\n the FIPS support which is disabled by default.\n\n (Thanks to dszoboszlay and legoscia)\n\n Own Id: OTP-13921 Aux Id: PR-1180\n\n- Implemented DTLS cookie generation, required by spec, instead of using a\n hardcoded value.\n\n Own Id: OTP-14076\n\n- Implement sliding window replay protection of DTLS records.\n\n Own Id: OTP-14077\n\n- TLS client processes will by default call public_key:pkix_verify_hostname/2 to\n verify the hostname of the connection with the server certificates specified\n hostname during certificate path validation. The user may explicitly disables\n it. Also if the hostname cannot be derived from the first argument to connect\n or is not supplied by the server name indication option, the check will not be\n performed.\n\n Own Id: OTP-14197\n\n- Extend connection_information/\\[1,2] . The values session_id, master_secret,\n client_random and server_random can no be accessed by\n connection_information/2. Note only session_id will be added to\n connection_information/1. The rational is that values concerning the\n connection security should have to be explicitly requested.\n\n Own Id: OTP-14291\n\n- Chacha cipher suites are currently not tested enough to be most preferred ones\n\n Own Id: OTP-14382\n\n- Basic support for DTLS that been tested together with OpenSSL.\n\n Test by providing the option \\{protocol, dtls\\} to the ssl API functions\n connect and listen.\n\n Own Id: OTP-14388","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.1.3.1.1 - SSL Release Notes","ref":"notes.html#ssl-8-1-3-1-1"},{"type":"extras","doc":"- Fix alert handling so that unexpected messages are logged and alerted\n correctly\n\n Own Id: OTP-14929","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.1.3.1 - SSL Release Notes","ref":"notes.html#ssl-8-1-3-1"},{"type":"extras","doc":"- An erlang TLS server configured with cipher suites using rsa key exchange, may\n be vulnerable to an Adaptive Chosen Ciphertext attack (AKA Bleichenbacher\n attack) against RSA, which when exploited, may result in plaintext recovery of\n encrypted messages and/or a Man-in-the-middle (MiTM) attack, despite the\n attacker not having gained access to the server’s private key itself.\n [CVE-2017-1000385](https://nvd.nist.gov/vuln/detail/CVE-2017-1000385)\n\n Exploiting this vulnerability to perform plaintext recovery of encrypted\n messages will, in most practical cases, allow an attacker to read the\n plaintext only after the session has completed. Only TLS sessions established\n using RSA key exchange are vulnerable to this attack.\n\n Exploiting this vulnerability to conduct a MiTM attack requires the attacker\n to complete the initial attack, which may require thousands of server\n requests, during the handshake phase of the targeted session within the window\n of the configured handshake timeout. This attack may be conducted against any\n TLS session using RSA signatures, but only if cipher suites using RSA key\n exchange are also enabled on the server. The limited window of opportunity,\n limitations in bandwidth, and latency make this attack significantly more\n difficult to execute.\n\n RSA key exchange is enabled by default although least prioritized if server\n order is honored. For such a cipher suite to be chosen it must also be\n supported by the client and probably the only shared cipher suite.\n\n Captured TLS sessions encrypted with ephemeral cipher suites (DHE or ECDHE)\n are not at risk for subsequent decryption due to this vulnerability.\n\n As a workaround if default cipher suite configuration was used you can\n configure the server to not use vulnerable suites with the ciphers option like\n this:\n\n `{ciphers, [Suite || Suite <- ssl:cipher_suites(), element(1,Suite) =/= rsa]}`\n\n that is your code will look somethingh like this:\n\n `ssl:listen(Port, [{ciphers, [Suite || Suite <- ssl:cipher_suites(), element(1,S) =/= rsa]} | Options]).`\n\n Thanks to Hanno Böck, Juraj Somorovsky and Craig Young for reporting this\n vulnerability.\n\n Own Id: OTP-14748","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.1.3 - SSL Release Notes","ref":"notes.html#ssl-8-1-3"},{"type":"extras","doc":"- Remove debug printout\n\n Own Id: OTP-14396","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.1.2 - SSL Release Notes","ref":"notes.html#ssl-8-1-2"},{"type":"extras","doc":"- Correct active once emulation, for TLS. Now all data received by the\n connection process will be delivered through active once, even when the active\n once arrives after that the gen_tcp socket is closed by the peer.\n\n Own Id: OTP-14300","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.1.1 - SSL Release Notes","ref":"notes.html#ssl-8-1-1"},{"type":"extras","doc":"- Corrected termination behavior, that caused a PEM cache bug and sometimes\n resulted in connection failures.\n\n Own Id: OTP-14100\n\n- Fix bug that could hang ssl connection processes when failing to require more\n data for very large handshake packages. Add option max_handshake_size to\n mitigate DoS attacks.\n\n Own Id: OTP-14138\n\n- Improved support for CRL handling that could fail to work as intended when an\n id-ce-extKeyUsage was present in the certificate. Also improvements where\n needed to distributionpoint handling so that all revocations actually are\n found and not deemed to be not determinable.\n\n Own Id: OTP-14141\n\n- A TLS handshake might accidentally match old sslv2 format and ssl application\n would incorrectly aborted TLS handshake with ssl_v2_client_hello_no_supported.\n Parsing was altered to avoid this problem.\n\n Own Id: OTP-14222\n\n- Correct default cipher list to prefer AES 128 before 3DES\n\n Own Id: OTP-14235","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Move PEM cache to a dedicated process, to avoid making the SSL manager process\n a bottleneck. This improves scalability of TLS connections.\n\n Own Id: OTP-13874","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.1 - SSL Release Notes","ref":"notes.html#ssl-8-1"},{"type":"extras","doc":"- List of possible anonymous suites, never supported by default, where incorrect\n for some TLS versions.\n\n Own Id: OTP-13926","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Experimental version of DTLS. It is runnable but not complete and cannot be\n considered reliable for production usage.\n\n Own Id: OTP-12982\n\n- Add API options to handle ECC curve selection.\n\n Own Id: OTP-13959","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.0.3 - SSL Release Notes","ref":"notes.html#ssl-8-0-3"},{"type":"extras","doc":"- A timing related bug in event handling could cause interoperability problems\n between an erlang TLS server and some TLS clients, especially noticed with\n Firefox as TLS client.\n\n Own Id: OTP-13917\n\n- Correct ECC curve selection, the error could cause the default to always be\n selected.\n\n Own Id: OTP-13918","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.0.2 - SSL Release Notes","ref":"notes.html#ssl-8-0-2"},{"type":"extras","doc":"- Correctly formed handshake messages received out of order will now correctly\n fail the connection with unexpected message.\n\n Own Id: OTP-13853\n\n- Correct handling of signature algorithm selection\n\n Own Id: OTP-13711","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- ssl application now behaves gracefully also on partially incorrect input from\n peer.\n\n Own Id: OTP-13834\n\n- Add application environment configuration bypass_pem_cache. This can be used\n as a workaround for the current implementation of the PEM-cache that has\n proven to be a bottleneck.\n\n Own Id: OTP-13883","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.0.1 - SSL Release Notes","ref":"notes.html#ssl-8-0-1"},{"type":"extras","doc":"- The TLS/SSL protocol version selection for the SSL server has been corrected\n to follow RFC 5246 Appendix E.1 especially in case where the list of supported\n versions has gaps. Now the server selects the highest protocol version it\n supports that is not higher than what the client supports.\n\n Own Id: OTP-13753 Aux Id: seq13150","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.0 - SSL Release Notes","ref":"notes.html#ssl-8-0"},{"type":"extras","doc":"- Server now rejects, a not requested client cert, as an incorrect handshake\n message and ends the connection.\n\n Own Id: OTP-13651","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Remove default support for DES cipher suites\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-13195\n\n- Deprecate the function `crypto:rand_bytes` and make sure that\n `crypto:strong_rand_bytes` is used in all places that are cryptographically\n significant.\n\n Own Id: OTP-13214\n\n- Better error handling of user error during TLS upgrade. ERL-69 is solved by\n gen_statem rewrite of ssl application.\n\n Own Id: OTP-13255\n\n- Provide user friendly error message when crypto rejects a key\n\n Own Id: OTP-13256\n\n- Add ssl:getstat/1 and ssl:getstat/2\n\n Own Id: OTP-13415\n\n- TLS distribution connections now allow specifying the options `verify_fun`,\n `crl_check` and `crl_cache`. See the documentation. GitHub pull req #956\n contributed by Magnus Henoch.\n\n Own Id: OTP-13429 Aux Id: Pull#956\n\n- Remove confusing error message when closing a distributed erlang node running\n over TLS\n\n Own Id: OTP-13431\n\n- Remove default support for use of md5 in TLS 1.2 signature algorithms\n\n Own Id: OTP-13463\n\n- ssl now uses gen_statem instead of gen_fsm to implement the ssl connection\n process, this solves some timing issues in addition to making the code more\n intuitive as the behaviour can be used cleanly instead of having a lot of\n workaround for shortcomings of the behaviour.\n\n Own Id: OTP-13464\n\n- Phase out interoperability with clients that offer SSLv2. By default they are\n no longer supported, but an option to provide interoperability is offered.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-13465\n\n- OpenSSL has functions to generate short (eight hex digits) hashes of issuers\n of certificates and CRLs. These hashes are used by the \"c_rehash\" script to\n populate directories of CA certificates and CRLs, e.g. in the Apache web\n server. Add functionality to let an Erlang program find the right CRL for a\n given certificate in such a directory.\n\n Own Id: OTP-13530\n\n- Some legacy TLS 1.0 software does not tolerate the 1/n-1 content split BEAST\n mitigation technique. Add a beast_mitigation SSL option (defaulting to\n one_n_minus_one) to select or disable the BEAST mitigation technique.\n\n Own Id: OTP-13629\n\n- Enhance error log messages to facilitate for users to understand the error\n\n Own Id: OTP-13632\n\n- Increased default DH params to 2048-bit\n\n Own Id: OTP-13636\n\n- Propagate CRL unknown CA error so that public_key validation process continues\n correctly and determines what should happen.\n\n Own Id: OTP-13656\n\n- Introduce a flight concept for handshake packages. This is a preparation for\n enabling DTLS, however it can also have a positive effects for TLS on slow and\n unreliable networks.\n\n Own Id: OTP-13678","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 7.3.3.2 - SSL Release Notes","ref":"notes.html#ssl-7-3-3-2"},{"type":"extras","doc":"- An erlang TLS server configured with cipher suites using rsa key exchange, may\n be vulnerable to an Adaptive Chosen Ciphertext attack (AKA Bleichenbacher\n attack) against RSA, which when exploited, may result in plaintext recovery of\n encrypted messages and/or a Man-in-the-middle (MiTM) attack, despite the\n attacker not having gained access to the server’s private key itself.\n [CVE-2017-1000385](https://nvd.nist.gov/vuln/detail/CVE-2017-1000385)\n\n Exploiting this vulnerability to perform plaintext recovery of encrypted\n messages will, in most practical cases, allow an attacker to read the\n plaintext only after the session has completed. Only TLS sessions established\n using RSA key exchange are vulnerable to this attack.\n\n Exploiting this vulnerability to conduct a MiTM attack requires the attacker\n to complete the initial attack, which may require thousands of server\n requests, during the handshake phase of the targeted session within the window\n of the configured handshake timeout. This attack may be conducted against any\n TLS session using RSA signatures, but only if cipher suites using RSA key\n exchange are also enabled on the server. The limited window of opportunity,\n limitations in bandwidth, and latency make this attack significantly more\n difficult to execute.\n\n RSA key exchange is enabled by default although least prioritized if server\n order is honored. For such a cipher suite to be chosen it must also be\n supported by the client and probably the only shared cipher suite.\n\n Captured TLS sessions encrypted with ephemeral cipher suites (DHE or ECDHE)\n are not at risk for subsequent decryption due to this vulnerability.\n\n As a workaround if default cipher suite configuration was used you can\n configure the server to not use vulnerable suites with the ciphers option like\n this:\n\n `{ciphers, [Suite || Suite <- ssl:cipher_suites(), element(1,Suite) =/= rsa]}`\n\n that is your code will look somethingh like this:\n\n `ssl:listen(Port, [{ciphers, [Suite || Suite <- ssl:cipher_suites(), element(1,S) =/= rsa]} | Options]).`\n\n Thanks to Hanno Böck, Juraj Somorovsky and Craig Young for reporting this\n vulnerability.\n\n Own Id: OTP-14748","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 7.3.3 - SSL Release Notes","ref":"notes.html#ssl-7-3-3"},{"type":"extras","doc":"- Correct ssl:prf/5 to use the negotiated cipher suite's prf function in\n ssl:prf/5 instead of the default prf.\n\n Own Id: OTP-13546\n\n- Timeouts may have the value 0, guards have been corrected to allow this\n\n Own Id: OTP-13635\n\n- Change of internal handling of hash sign pairs as the used one enforced to\n much restrictions making some valid combinations unavailable.\n\n Own Id: OTP-13670","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 7.3.3.0.1 - SSL Release Notes","ref":"notes.html#ssl-7-3-3-0-1"},{"type":"extras","doc":"- An erlang TLS server configured with cipher suites using rsa key exchange, may\n be vulnerable to an Adaptive Chosen Ciphertext attack (AKA Bleichenbacher\n attack) against RSA, which when exploited, may result in plaintext recovery of\n encrypted messages and/or a Man-in-the-middle (MiTM) attack, despite the\n attacker not having gained access to the server’s private key itself.\n [CVE-2017-1000385](https://nvd.nist.gov/vuln/detail/CVE-2017-1000385)\n\n Exploiting this vulnerability to perform plaintext recovery of encrypted\n messages will, in most practical cases, allow an attacker to read the\n plaintext only after the session has completed. Only TLS sessions established\n using RSA key exchange are vulnerable to this attack.\n\n Exploiting this vulnerability to conduct a MiTM attack requires the attacker\n to complete the initial attack, which may require thousands of server\n requests, during the handshake phase of the targeted session within the window\n of the configured handshake timeout. This attack may be conducted against any\n TLS session using RSA signatures, but only if cipher suites using RSA key\n exchange are also enabled on the server. The limited window of opportunity,\n limitations in bandwidth, and latency make this attack significantly more\n difficult to execute.\n\n RSA key exchange is enabled by default although least prioritized if server\n order is honored. For such a cipher suite to be chosen it must also be\n supported by the client and probably the only shared cipher suite.\n\n Captured TLS sessions encrypted with ephemeral cipher suites (DHE or ECDHE)\n are not at risk for subsequent decryption due to this vulnerability.\n\n As a workaround if default cipher suite configuration was used you can\n configure the server to not use vulnerable suites with the ciphers option like\n this:\n\n `{ciphers, [Suite || Suite <- ssl:cipher_suites(), element(1,Suite) =/= rsa]}`\n\n that is your code will look somethingh like this:\n\n `ssl:listen(Port, [{ciphers, [Suite || Suite <- ssl:cipher_suites(), element(1,S) =/= rsa]} | Options]).`\n\n Thanks to Hanno Böck, Juraj Somorovsky and Craig Young for reporting this\n vulnerability.\n\n Own Id: OTP-14748","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Create a little randomness in sending of session invalidation messages, to\n mitigate load when whole table is invalidated.\n\n Own Id: OTP-13490","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 7.3.2 - SSL Release Notes","ref":"notes.html#ssl-7-3-2"},{"type":"extras","doc":"- Correct cipher suites conversion and guard expression. Caused problems with\n GCM cipher suites and client side option to set signature_algorithms extension\n values.\n\n Own Id: OTP-13525","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 7.3.1 - SSL Release Notes","ref":"notes.html#ssl-7-3-1"},{"type":"extras","doc":"- Corrections to cipher suite handling using the 3 and 4 tuple format in\n addition to commit 89d7e21cf4ae988c57c8ef047bfe85127875c70c\n\n Own Id: OTP-13511","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Make values for the TLS-1.2 signature_algorithms extension configurable\n\n Own Id: OTP-13261","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 7.3 - SSL Release Notes","ref":"notes.html#ssl-7-3"},{"type":"extras","doc":"- Make sure there is only one poller validator at a time for validating the\n session cache.\n\n Own Id: OTP-13185\n\n- A timing related issue could cause ssl to hang, especially happened with newer\n versions of OpenSSL in combination with ECC ciphers.\n\n Own Id: OTP-13253\n\n- Work around a race condition in the TLS distribution start.\n\n Own Id: OTP-13268\n\n- Big handshake messages are now correctly fragmented in the TLS record layer.\n\n Own Id: OTP-13306\n\n- Improve portability of ECC tests in Crypto and SSL for \"exotic\" OpenSSL\n versions.\n\n Own Id: OTP-13311\n\n- Certificate extensions marked as critical are ignored when using verify_none\n\n Own Id: OTP-13377\n\n- If a certificate doesn't contain a CRL Distribution Points extension, and the\n relevant CRL is not in the cache, and the `crl_check` option is not set to\n `best_effort` , the revocation check should fail.\n\n Own Id: OTP-13378\n\n- Enable TLS distribution over IPv6\n\n Own Id: OTP-13391","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Improve error reporting for TLS distribution\n\n Own Id: OTP-13219\n\n- Include options from connect, listen and accept in\n `connection_information/1,2`\n\n Own Id: OTP-13232\n\n- Allow adding extra options for outgoing TLS distribution connections, as\n supported for plain TCP connections.\n\n Own Id: OTP-13285\n\n- Use loopback as server option in TLS-distribution module\n\n Own Id: OTP-13300\n\n- Verify certificate signature against original certificate binary.\n\n This avoids bugs due to encoding errors when re-encoding a decode certificate.\n As there exists several decode step and using of different ASN.1 specification\n this is a risk worth avoiding.\n\n Own Id: OTP-13334\n\n- Use `application:ensure_all_started/2` instead of hard-coding dependencies\n\n Own Id: OTP-13363","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 7.2 - SSL Release Notes","ref":"notes.html#ssl-7-2"},{"type":"extras","doc":"- Honor distribution port range options\n\n Own Id: OTP-12838\n\n- Correct supervisor specification in TLS distribution.\n\n Own Id: OTP-13134\n\n- Correct cache timeout\n\n Own Id: OTP-13141\n\n- Avoid crash and restart of ssl process when key file does not exist.\n\n Own Id: OTP-13144\n\n- Enable passing of raw socket options on the format \\{raw,_,_,\\_\\} to the\n underlying socket.\n\n Own Id: OTP-13166\n\n- Hibernation with small or a zero timeout will now work as expected\n\n Own Id: OTP-13189","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add upper limit for session cache, configurable on ssl application level.\n\n If upper limit is reached, invalidate the current cache entries, e.i the\n session lifetime is the max time a session will be kept, but it may be\n invalidated earlier if the max limit for the table is reached. This will keep\n the ssl manager process well behaved, not exhusting memory. Invalidating the\n entries will incrementally empty the cache to make room for fresh sessions\n entries.\n\n Own Id: OTP-12392\n\n- Use new time functions to measure passed time.\n\n Own Id: OTP-12457\n\n- Improved error handling in TLS distribution\n\n Own Id: OTP-13142\n\n- Distribution over TLS now honors the nodelay distribution flag\n\n Own Id: OTP-13143","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 7.1 - SSL Release Notes","ref":"notes.html#ssl-7-1"},{"type":"extras","doc":"- Add DER encoded ECPrivateKey as valid input format for key option.\n\n Own Id: OTP-12974\n\n- Correct return value of default session callback module\n\n This error had the symptom that the client check for unique session would\n always fail, potentially making the client session table grow a lot and\n causing long setup times.\n\n Own Id: OTP-12980","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add possibility to downgrade an SSL/TLS connection to a tcp connection, and\n give back the socket control to a user process.\n\n This also adds the possibility to specify a timeout to the ssl:close function.\n\n Own Id: OTP-11397\n\n- Add application setting to be able to change fatal alert shutdown timeout,\n also shorten the default timeout. The fatal alert timeout is the number of\n milliseconds between sending of a fatal alert and closing the connection.\n Waiting a little while improves the peers chances to properly receiving the\n alert so it may shutdown gracefully.\n\n Own Id: OTP-12832","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 7.0 - SSL Release Notes","ref":"notes.html#ssl-7-0"},{"type":"extras","doc":"- Ignore signature_algorithm (TLS 1.2 extension) sent to TLS 1.0 or TLS 1.1\n server\n\n Own Id: OTP-12670\n\n- Improve error handling in TLS distribution module to avoid lingering sockets.\n\n Own Id: OTP-12799 Aux Id: Tom Briden\n\n- Add option \\{client_renegotiation, boolean()\\} option to the server-side of\n the SSL application.\n\n Own Id: OTP-12815","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add new API functions to handle CRL-verification\n\n Own Id: OTP-10362 Aux Id: kunagi-215 \\[126]\n\n- Remove default support for SSL-3.0, due to Poodle vunrability in protocol\n specification.\n\n Add padding check for TLS-1.0 to remove Poodle vunrability from TLS 1.0, also\n add the option padding_check. This option only affects TLS-1.0 connections and\n if set to false it disables the block cipher padding check to be able to\n interoperate with legacy software.\n\n Remove default support for RC4 cipher suites, as they are consider too weak.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-12390\n\n- Add support for TLS ALPN (Application-Layer Protocol Negotiation) extension.\n\n Own Id: OTP-12580\n\n- Add SNI (Server Name Indication) support for the server side.\n\n Own Id: OTP-12736","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 6.0.1.1 - SSL Release Notes","ref":"notes.html#ssl-6-0-1-1"},{"type":"extras","doc":"- Gracefully ignore proprietary hash_sign algorithms\n\n Own Id: OTP-12829","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 6.0.1 - SSL Release Notes","ref":"notes.html#ssl-6-0-1"},{"type":"extras","doc":"- Terminate gracefully when receiving bad input to premaster secret calculation\n\n Own Id: OTP-12783","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 6.0 - SSL Release Notes","ref":"notes.html#ssl-6-0"},{"type":"extras","doc":"- Exclude self-signed trusted anchor certificates from certificate prospective\n certification path according to RFC 3280.\n\n This will avoid some unnecessary certificate processing.\n\n Own Id: OTP-12449","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Separate client and server session cache internally.\n\n Avoid session table growth when client starts many connections in such a\n manner that many connections are started before session reuse is possible.\n Only save a new session in client if there is no equivalent session already\n stored.\n\n Own Id: OTP-11365\n\n- The PEM cache is now validated by a background process, instead of always\n keeping it if it is small enough and clearing it otherwise. That strategy\n required that small caches where cleared by API function if a file changes on\n disk.\n\n However export the API function to clear the cache as it may still be useful.\n\n Own Id: OTP-12391\n\n- Add padding check for TLS-1.0 to remove Poodle vulnerability from TLS 1.0,\n also add the option padding_check. This option only affects TLS-1.0\n connections and if set to false it disables the block cipher padding check to\n be able to interoperate with legacy software.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-12420\n\n- Add support for TLS_FALLBACK_SCSV used to prevent undesired TLS version\n downgrades. If used by a client that is vulnerable to the POODLE attack, and\n the server also supports TLS_FALLBACK_SCSV, the attack can be prevented.\n\n Own Id: OTP-12458","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.3.8 - SSL Release Notes","ref":"notes.html#ssl-5-3-8"},{"type":"extras","doc":"- Make sure the clean rule for ssh, ssl, eunit and otp_mibs actually removes\n generated files.\n\n Own Id: OTP-12200","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Change code to reflect that state data may be secret to avoid breaking\n dialyzer contracts.\n\n Own Id: OTP-12341","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.3.7 - SSL Release Notes","ref":"notes.html#ssl-5-3-7"},{"type":"extras","doc":"- Handle the fact that servers may send an empty SNI extension to the client.\n\n Own Id: OTP-12198","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 5.3.6 - SSL Release Notes","ref":"notes.html#ssl-5-3-6"},{"type":"extras","doc":"- Corrected handling of ECC certificates, there where several small issues with\n the handling of such certificates in the ssl and public_key application. Now\n ECC signed ECC certificates shall work and not only RSA signed ECC\n certificates.\n\n Own Id: OTP-12026\n\n- Check that the certificate chain ends with a trusted ROOT CA e.i. a\n self-signed certificate, but provide an option partial_chain to enable the\n application to define an intermediat CA as trusted.\n\n Own Id: OTP-12149","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add decode functions for SNI (Server Name Indication)\n\n Own Id: OTP-12048","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.3.5 - SSL Release Notes","ref":"notes.html#ssl-5-3-5"},{"type":"extras","doc":"- ssl:recv now returns \\{error, einval\\} if applied to a non passive socket, the\n same as gen_tcp:recv.\n\n Thanks to Danil Zagoskin for reporting this issue\n\n Own Id: OTP-11878\n\n- Corrected handling of default values for signature_algorithms extension in\n TLS-1.2 and corresponding values used in previous versions that does not\n support this extension.\n\n Thanks to Danil Zagoskin\n\n Own Id: OTP-11886\n\n- Handle socket option inheritance when pooling of accept sockets is used\n\n Own Id: OTP-11897\n\n- Make sure that the list of versions, possibly supplied in the versions option,\n is not order dependent.\n\n Thanks to Ransom Richardson for reporting this issue\n\n Own Id: OTP-11912\n\n- Reject connection if the next_protocol message is sent twice.\n\n Own Id: OTP-11926\n\n- Correct options handling when ssl:ssl_accept/3 is called with new ssl options\n after calling ssl:listen/2\n\n Own Id: OTP-11950","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Gracefully handle unknown alerts\n\n Thanks to Atul Atri for reporting this issue\n\n Own Id: OTP-11874\n\n- Gracefully ignore cipher suites sent by client not supported by the SSL/TLS\n version that the client has negotiated.\n\n Thanks to Danil Zagoskin for reporting this issue\n\n Own Id: OTP-11875\n\n- Gracefully handle structured garbage, i.e a client sends some garbage in a ssl\n record instead of a valid fragment.\n\n Thanks to Danil Zagoskin\n\n Own Id: OTP-11880\n\n- Gracefully handle invalid alerts\n\n Own Id: OTP-11890\n\n- Generalize handling of default ciphers\n\n Thanks to Andreas Schultz\n\n Own Id: OTP-11966\n\n- Make sure change cipher spec is correctly handled\n\n Own Id: OTP-11975","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.3.4 - SSL Release Notes","ref":"notes.html#ssl-5-3-4"},{"type":"extras","doc":"- Fix incorrect dialyzer spec and types, also enhance documentation.\n\n Thanks to Ayaz Tuncer.\n\n Own Id: OTP-11627\n\n- Fix possible mismatch between SSL/TLS version and default ciphers. Could\n happen when you specified SSL/TLS-version in optionlist to listen or accept.\n\n Own Id: OTP-11712\n\n- Application upgrade (appup) files are corrected for the following\n applications:\n\n `asn1, common_test, compiler, crypto, debugger, dialyzer, edoc, eldap, erl_docgen, et, eunit, gs, hipe, inets, observer, odbc, os_mon, otp_mibs, parsetools, percept, public_key, reltool, runtime_tools, ssh, syntax_tools, test_server, tools, typer, webtool, wx, xmerl`\n\n A new test utility for testing appup files is added to test_server. This is\n now used by most applications in OTP.\n\n (Thanks to Tobias Schlager)\n\n Own Id: OTP-11744","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Moved elliptic curve definition from the crypto NIF/OpenSSL into Erlang code,\n adds the RFC-5639 brainpool curves and makes TLS use them (RFC-7027).\n\n Thanks to Andreas Schultz\n\n Own Id: OTP-11578\n\n- Unicode adaptations\n\n Own Id: OTP-11620\n\n- Added option honor_cipher_order. This instructs the server to prefer its own\n cipher ordering rather than the client's and can help protect against things\n like BEAST while maintaining compatibility with clients which only support\n older ciphers.\n\n Thanks to Andrew Thompson for the implementation, and Andreas Schultz for the\n test cases.\n\n Own Id: OTP-11621\n\n- Replace boolean checking in validate_option with is_boolean guard.\n\n Thanks to Andreas Schultz.\n\n Own Id: OTP-11634\n\n- Some function specs are corrected or moved and some edoc comments are\n corrected in order to allow use of edoc. (Thanks to Pierre Fenoll)\n\n Own Id: OTP-11702\n\n- Correct clean up of certificate database when certs are inputted in pure DER\n format.The incorrect code could cause a memory leek when certs where inputted\n in DER. Thanks to Bernard Duggan for reporting this.\n\n Own Id: OTP-11733\n\n- Improved documentation of the cacertfile option\n\n Own Id: OTP-11759 Aux Id: seq12535\n\n- Avoid next protocol negotiation failure due to incorrect option format.\n\n Own Id: OTP-11760\n\n- Handle v1 CRLs, with no extensions and fixes issues with IDP (Issuing\n Distribution Point) comparison during CRL validation.\n\n Thanks to Andrew Thompson\n\n Own Id: OTP-11761\n\n- Server now ignores client ECC curves that it does not support instead of\n crashing.\n\n Thanks to Danil Zagoskin for reporting the issue and suggesting a solution.\n\n Own Id: OTP-11780\n\n- Handle SNI (Server Name Indication) alert unrecognized_name and gracefully\n deal with unexpected alerts.\n\n Thanks to Masatake Daimon for reporting this.\n\n Own Id: OTP-11815\n\n- Add possibility to specify ssl options when calling ssl:ssl_accept\n\n Own Id: OTP-11837","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.3.3 - SSL Release Notes","ref":"notes.html#ssl-5-3-3"},{"type":"extras","doc":"- Add missing validation of the server_name_indication option and test for its\n explicit use. It was not possible to set or disable the default\n server_name_indication as the validation of the option was missing.\n\n Own Id: OTP-11567\n\n- Elliptic curve selection in server mode now properly selects a curve suggested\n by the client, if possible, and the fallback alternative is changed to a more\n widely supported curve.\n\n Own Id: OTP-11575\n\n- Bug in the TLS hello extension handling caused the server to behave as it did\n not understand secure renegotiation.\n\n Own Id: OTP-11595","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 5.3.2 - SSL Release Notes","ref":"notes.html#ssl-5-3-2"},{"type":"extras","doc":"- Honors the clients advertised support of elliptic curves and no longer sends\n incorrect elliptic curve extension in server hello.\n\n Own Id: OTP-11370\n\n- Fix initialization of DTLS fragment reassembler, in previously contributed\n code, for future support of DTLS . Thanks to Andreas Schultz.\n\n Own Id: OTP-11376\n\n- Corrected type error in client_preferred_next_protocols documentation. Thanks\n to Julien Barbot.\n\n Own Id: OTP-11457","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- TLS code has been refactored to prepare for future DTLS support. Also some\n DTLS code is in place but not yet runnable, some of it contributed by Andreas\n Schultz and some of it written by the OTP team. Thanks to to Andreas for his\n participation.\n\n Own Id: OTP-11292\n\n- Remove extraneous dev debug code left in the close function. Thanks to Ken\n Key.\n\n Own Id: OTP-11447\n\n- Add SSL Server Name Indication (SNI) client support. Thanks to Julien Barbot.\n\n Own Id: OTP-11460","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.3.1 - SSL Release Notes","ref":"notes.html#ssl-5-3-1"},{"type":"extras","doc":"- Setopts during renegotiation caused the renegotiation to be unsuccessful.\n\n If calling setopts during a renegotiation the FSM state might change during\n the handling of the setopts messages, this is now handled correctly.\n\n Own Id: OTP-11228\n\n- Now handles signature_algorithm field in digitally_signed properly with proper\n defaults. Prior to this change some elliptic curve cipher suites could fail\n reporting the error \"bad certificate\".\n\n Own Id: OTP-11229\n\n- The code emulating the inet header option was changed in the belief that it\n made it inet compatible. However the testing is a bit hairy as the inet option\n is actually broken, now the tests are corrected and the header option should\n work in the same broken way as inet again, preferably use the bitsyntax\n instead.\n\n Own Id: OTP-11230","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Make the ssl manager name for erlang distribution over SSL/TLS relative to the\n module name of the ssl_manager.\n\n This can be beneficial when making tools that rename modules for internal\n processing in the tool.\n\n Own Id: OTP-11255\n\n- Add documentation regarding log_alert option.\n\n Own Id: OTP-11271","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.3 - SSL Release Notes","ref":"notes.html#ssl-5-3"},{"type":"extras","doc":"- Honor the versions option to ssl:connect and ssl:listen.\n\n Own Id: OTP-10905\n\n- Next protocol negotiation with reused sessions will now succeed\n\n Own Id: OTP-10909","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add support for PSK (Pre Shared Key) and SRP (Secure Remote Password) cipher\n suites, thanks to Andreas Schultz.\n\n Own Id: OTP-10450 Aux Id: kunagi-269 \\[180]\n\n- Fix SSL Next Protocol Negotiation documentation. Thanks to Julien Barbot.\n\n Own Id: OTP-10955\n\n- Fix ssl_connection to support reading proxy/chain certificates. Thanks to\n Valentin Kuznetsov.\n\n Own Id: OTP-10980\n\n- Integrate elliptic curve contribution from Andreas Schultz\n\n In order to be able to support elliptic curve cipher suites in SSL/TLS,\n additions to handle elliptic curve infrastructure has been added to public_key\n and crypto.\n\n This also has resulted in a rewrite of the crypto API to gain consistency and\n remove unnecessary overhead. All OTP applications using crypto has been\n updated to use the new API.\n\n Impact: Elliptic curve cryptography (ECC) offers equivalent security with\n smaller key sizes than other public key algorithms. Smaller key sizes result\n in savings for power, memory, bandwidth, and computational cost that make ECC\n especially attractive for constrained environments.\n\n Own Id: OTP-11009","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.2.1 - SSL Release Notes","ref":"notes.html#ssl-5-2-1"},{"type":"extras","doc":"- Transport callback handling is changed so that gen_tcp is treated as a special\n case where inet will be called directly for functions such as setopts, as\n gen_tcp does not have its own setopts. This will enable users to use the\n transport callback for other customizations such as websockets.\n\n Own Id: OTP-10847\n\n- Follow up to OTP-10451 solved in ssl-5.2 R16A. Make sure format_error return\n good strings. Replace confusing legacy atoms with more descriptive atoms.\n\n Own Id: OTP-10864","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.1.2.1 - SSL Release Notes","ref":"notes.html#ssl-5-1-2-1"},{"type":"extras","doc":"- Make log_alert configurable as option in ssl, SSLLogLevel added as option to\n inets conf file\n\n Own Id: OTP-11259","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.2 - SSL Release Notes","ref":"notes.html#ssl-5-2"},{"type":"extras","doc":"- SSL: TLS 1.2, advertise sha224 support, thanks to Andreas Schultz.\n\n Own Id: OTP-10586\n\n- If an ssl server is restarted with new options and a client tries to reuse a\n session the server must make sure that it complies to the new options before\n agreeing to reuse it.\n\n Own Id: OTP-10595\n\n- Now handles cleaning of CA-certificate database correctly so that there will\n be no memory leek, bug was introduced in ssl- 5.1 when changing implementation\n to increase parallel execution.\n\n Impact: Improved memory usage, especially if you have many different\n certificates and upgrade tcp-connections to TLS-connections.\n\n Own Id: OTP-10710","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Support Next Protocol Negotiation in TLS, thanks to Ben Murphy for the\n contribution.\n\n Impact: Could give performance benefit if used as it saves a round trip.\n\n Own Id: OTP-10361 Aux Id: kunagi-214 \\[125]\n\n- TLS 1.2 will now be the default TLS version if sufficient crypto support is\n available otherwise TLS 1.1 will be default.\n\n Impact: A default TLS connection will have higher security and hence it may be\n perceived as slower then before.\n\n Own Id: OTP-10425 Aux Id: kunagi-275 \\[186]\n\n- It is now possible to call controlling_process on a listen socket, same as in\n gen_tcp.\n\n Own Id: OTP-10447\n\n- Remove filter mechanisms that made error messages backwards compatible with\n old ssl but hid information about what actually happened.\n\n This does not break the documented API however other reason terms may be\n returned, so code that matches on the reason part of \\{error, Reason\\} may\n fail.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-10451 Aux Id: kunagi-270 \\[181]\n\n- Added missing dependencies to Makefile\n\n Own Id: OTP-10594\n\n- Removed deprecated function ssl:pid/0, it has been pointless since R14 but has\n been keep for backwards compatibility.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-10613 Aux Id: kunagi-331 \\[242]\n\n- Refactor to simplify addition of key exchange methods, thanks to Andreas\n Schultz.\n\n Own Id: OTP-10709","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.1.2 - SSL Release Notes","ref":"notes.html#ssl-5-1-2"},{"type":"extras","doc":"- ssl:ssl_accept/2 timeout is no longer ignored\n\n Own Id: OTP-10600","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 5.1.1 - SSL Release Notes","ref":"notes.html#ssl-5-1-1"},{"type":"extras","doc":"- ssl:recv/3 could \"loose\" data when the timeout occurs. If the timeout in\n ssl:connect or ssl:ssl_accept expired the ssl connection process was not\n terminated as it should, this due to gen_fsm:send_all_state_event timeout is a\n client side time out. These timouts are now handled by the gen_fsm-procss\n instead.\n\n Own Id: OTP-10569","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Better termination handling that avoids hanging.\n\n Own Id: OTP-10574","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.1 - SSL Release Notes","ref":"notes.html#ssl-5-1"},{"type":"extras","doc":"- Sometimes the client process could receive an extra \\{error, closed\\} message\n after ssl:recv had returned \\{error, closed\\}.\n\n Own Id: OTP-10118\n\n- ssl v3 alert number 41 (no_certificate_RESERVED) is now recognized\n\n Own Id: OTP-10196","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Experimental support for TLS 1.1 is now available, will be officially\n supported from OTP-R16. Thanks to Andreas Schultz for implementing the first\n version.\n\n Own Id: OTP-8871\n\n- Experimental support for TLS 1.2 is now available, will be officially\n supported from OTP-R16. Thanks to Andreas Schultz for implementing the first\n version.\n\n Own Id: OTP-8872\n\n- Removed some bottlenecks increasing the applications parallelism especially\n for the client side.\n\n Own Id: OTP-10113\n\n- Workaround for handling certificates that wrongly encode X509countryname in\n utf-8 when the actual value is a valid ASCCI value of length 2. Such\n certificates are accepted by many browsers such as Chrome and Fierfox so for\n interoperability reasons we will too.\n\n Own Id: OTP-10222","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.0.1 - SSL Release Notes","ref":"notes.html#ssl-5-0-1"},{"type":"extras","doc":"- Robustness and improvement to distribution over SSL\n\n Fix a bug where ssl_tls_dist_proxy would crash at caller timeout. Fix a bug\n where a timeout from the SSL layer would block the distribution indefinitely.\n Run the proxy exclusively on the loopback interface. (Thanks to Paul Guyot)\n\n Own Id: OTP-9915\n\n- Fix setup loop of SSL TLS dist proxy\n\n Fix potential leak of processes waiting indefinitely for data from closed\n sockets during socket setup phase. (Thanks to Paul Guyot)\n\n Own Id: OTP-9916\n\n- Correct spelling of registered (Thanks to Richard Carlsson)\n\n Own Id: OTP-9925\n\n- Added TLS PRF function to the SSL API for generation of additional key\n material from a TLS session. (Thanks to Andreas Schultz)\n\n Own Id: OTP-10024","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 5.0 - SSL Release Notes","ref":"notes.html#ssl-5-0"},{"type":"extras","doc":"- Invalidation handling of sessions could cause the time_stamp field in the\n session record to be set to undefined crashing the session clean up process.\n This did not affect the connections but would result in that the session table\n would grow.\n\n Own Id: OTP-9696 Aux Id: seq11947\n\n- Changed code to use ets:foldl and throw instead of ets:next traversal,\n avoiding the need to explicitly call ets:safe_fixtable. It was possible to get\n a badarg-crash under special circumstances.\n\n Own Id: OTP-9703 Aux Id: seq11947\n\n- Send ssl_closed notification to active ssl user when a tcp error occurs.\n\n Own Id: OTP-9734 Aux Id: seq11946\n\n- If a passive receive was ongoing during a renegotiation the process evaluating\n ssl:recv could be left hanging for ever.\n\n Own Id: OTP-9744","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Support for the old ssl implementation is dropped and the code is removed.\n\n Own Id: OTP-7048\n\n- The erlang distribution can now be run over the new ssl implementation. All\n options can currently not be set but it is enough to replace to old ssl\n implementation.\n\n Own Id: OTP-7053\n\n- public_key, ssl and crypto now supports PKCS-8\n\n Own Id: OTP-9312\n\n- Implements a CBC timing attack counter measure. Thanks to Andreas Schultz for\n providing the patch.\n\n Own Id: OTP-9683\n\n- Mitigates an SSL/TLS Computational DoS attack by disallowing the client to\n renegotiate many times in a row in a short time interval, thanks to Tuncer\n Ayaz for alerting us about this.\n\n Own Id: OTP-9739\n\n- Implements the 1/n-1 splitting countermeasure to the Rizzo Duong BEAST attack,\n affects SSL 3.0 and TLS 1.0. Thanks to Tuncer Ayaz for alerting us about this.\n\n Own Id: OTP-9750","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 4.1.6 - SSL Release Notes","ref":"notes.html#ssl-4-1-6"},{"type":"extras","doc":"- replace \"a ssl\" with \"an ssl\" reindent pkix_path_validation/3 Trivial\n documentation fixes (Thanks to Christian von Roques )\n\n Own Id: OTP-9464","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Adds function clause to avoid denial of service attack. Thanks to Vinod for\n reporting this vulnerability.\n\n Own Id: OTP-9364\n\n- Error handling code now takes care of inet:getopts/2 and inets:setopts/2\n crashes. Thanks to Richard Jones for reporting this.\n\n Own Id: OTP-9382\n\n- Support explicit use of packet option httph and httph_bin\n\n Own Id: OTP-9461\n\n- Decoding of hello extensions could fail to come to the correct conclusion due\n to an error in a binary match pattern. Thanks to Ben Murphy.\n\n Own Id: OTP-9589","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 4.1.5 - SSL Release Notes","ref":"notes.html#ssl-4-1-5"},{"type":"extras","doc":"- Calling gen_tcp:connect with option \\{ip, \\{127,0,0,1\\}\\} results in an exit\n with reason badarg. Neither SSL nor INETS This was not caught, resulting in\n crashes with incomprehensible reasons.\n\n Own Id: OTP-9289 Aux Id: seq11845","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 4.1.3 - SSL Release Notes","ref":"notes.html#ssl-4-1-3"},{"type":"extras","doc":"- Fixed error in cache-handling fix from ssl-4.1.2\n\n Own Id: OTP-9018 Aux Id: seq11739\n\n- Verification of a critical extended_key_usage-extension corrected\n\n Own Id: OTP-9029 Aux Id: seq11541","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 4.1.2 - SSL Release Notes","ref":"notes.html#ssl-4-1-2"},{"type":"extras","doc":"- The ssl application caches certificate files, it will now invalidate cache\n entries if the diskfile is changed.\n\n Own Id: OTP-8965 Aux Id: seq11739\n\n- Now runs the terminate function before returning from the call made by\n ssl:close/1, as before the caller of ssl:close/1 could get problems with the\n reuseaddr option.\n\n Own Id: OTP-8992","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 4.1.1 - SSL Release Notes","ref":"notes.html#ssl-4-1-1"},{"type":"extras","doc":"- Correct handling of client certificate verify message When checking the client\n certificate verify message the server used the wrong algorithm identifier to\n determine the signing algorithm, causing a function clause error in the\n public_key application when the key-exchange algorithm and the public key\n algorithm of the client certificate happen to differ.\n\n Own Id: OTP-8897","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- For testing purposes ssl now also support some anonymous cipher suites when\n explicitly configured to do so.\n\n Own Id: OTP-8870\n\n- Sends an error alert instead of crashing if a crypto function for the selected\n cipher suite fails.\n\n Own Id: OTP-8930 Aux Id: seq11720","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 4.1 - SSL Release Notes","ref":"notes.html#ssl-4-1"},{"type":"extras","doc":"- Updated ssl to ignore CA certs that violate the asn1-spec for a certificate,\n and updated public key asn1 spec to handle inherited DSS-params.\n\n Own Id: OTP-7884\n\n- Changed ssl implementation to retain backwards compatibility for old option\n \\{verify, 0\\} that shall be equivalent to \\{verify, verify_none\\}, also\n separate the cases unknown ca and selfsigned peer cert, and restored return\n value of deprecated function public_key:pem_to_der/1.\n\n Own Id: OTP-8858\n\n- Changed the verify fun so that it differentiate between the peer certificate\n and CA certificates by using valid_peer or valid as the second argument to the\n verify fun. It may not always be trivial or even possible to know when the\n peer certificate is reached otherwise.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-8873","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 4.0.1 - SSL Release Notes","ref":"notes.html#ssl-4-0-1"},{"type":"extras","doc":"- The server now verifies the client certificate verify message correctly,\n instead of causing a case-clause.\n\n Own Id: OTP-8721\n\n- The client hello message now always include ALL available cipher suites (or\n those specified by the ciphers option). Previous implementation would filter\n them based on the client certificate key usage extension (such filtering only\n makes sense for the server certificate).\n\n Own Id: OTP-8772\n\n- Fixed handling of the option \\{mode, list\\} that was broken for some packet\n types for instance line.\n\n Own Id: OTP-8785\n\n- Empty packets were not delivered to the client.\n\n Own Id: OTP-8790\n\n- Building in a source tree without prebuilt platform independent build results\n failed on the SSL examples when:\n\n - cross building. This has been solved by not building the SSL examples during\n a cross build.\n - building on Windows.\n\n Own Id: OTP-8791\n\n- Fixed a handshake error which occurred on some ssl implementations.\n\n Own Id: OTP-8793","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Revise the public_key API - Cleaned up and documented the public_key API to\n make it useful for general use, also changed ssl to use the new API.\n\n Own Id: OTP-8722\n\n- Added support for inputing certificates and keys directly in DER format these\n options will override the pem-file options if specified.\n\n Own Id: OTP-8723\n\n- To gain interoperability ssl will not check for padding errors when using TLS\n 1.0. It is first in TLS 1.1 that checking the padding is an requirement.\n\n Own Id: OTP-8740\n\n- Changed the semantics of the verify_fun option in the ssl-application so that\n it takes care of both application handling of path validation errors and\n verification of application specific extensions. This means that it is now\n possible for the server application in verify_peer mode to handle path\n validation errors. This change moved some functionality earlier in ssl to the\n public_key application.\n\n Own Id: OTP-8770\n\n- Added the functionality so that the verification fun will be called when a\n certificate is considered valid by the path validation to allow access to each\n certificate in the path to the user application. Also try to verify\n subject-AltName, if unable to verify it let the application verify it.\n\n Own Id: OTP-8825","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 4.0 - SSL Release Notes","ref":"notes.html#ssl-4-0"},{"type":"extras","doc":"- New ssl now support client/server-certificates signed by dsa keys.\n\n Own Id: OTP-8587\n\n- Ssl has now switched default implementation and removed deprecated certificate\n handling. All certificate handling is done by the public_key application.\n\n Own Id: OTP-8695","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"\n\n# TLS/DTLS Protocol Overview","title":"TLS/DTLS Protocol Overview","ref":"ssl_protocol.html"},{"type":"extras","doc":"Transport Layer Security (TLS) and its predecessor, the Secure Sockets Layer\n(SSL), are cryptographic protocols designed to provide communications security\nover a computer network. The protocols use X.509 certificates and hence public\nkey (asymmetric) cryptography to authenticate the counterpart with whom they\ncommunicate, and to exchange a symmetric key for payload encryption. The\nprotocol provides data/message confidentiality (encryption), integrity (through\nmessage authentication code checks) and host verification (through certificate\npath validation). DTLS (Datagram Transport Layer Security) that is based on TLS\nbut datagram oriented instead of stream oriented.\n\n# Erlang Support\n\nThe Erlang SSL application implements the TLS/DTLS protocol for the currently\nsupported versions, see the `m:ssl` manual page.\n\nBy default TLS is run over the TCP/IP protocol even though you can plug in any\nother reliable transport protocol with the same Application Programming\nInterface (API) as the `gen_tcp` module in Kernel. DTLS is by default run over\nUDP/IP, which means that application data has no delivery guarantees. Other\ntransports, such as SCTP, may be supported in future releases.\n\nIf a client and a server wants to use an upgrade mechanism, such as defined by\nRFC 2817, to upgrade a regular TCP/IP connection to a TLS connection, this is\nsupported by the Erlang SSL application API. This can be useful for, for\nexample, supporting HTTP and HTTPS on the same port and implementing virtual\nhosting. Note this is a TLS feature only.","title":"Purpose - TLS/DTLS Protocol Overview","ref":"ssl_protocol.html#purpose"},{"type":"extras","doc":"To achieve authentication and privacy, the client and server perform a TLS/DTLS\nhandshake procedure before transmitting or receiving any data. During the\nhandshake, they agree on a protocol version and cryptographic algorithms,\ngenerate shared secrets using public key cryptographies, and optionally\nauthenticate each other with digital certificates.","title":"Security Overview - TLS/DTLS Protocol Overview","ref":"ssl_protocol.html#security-overview"},{"type":"extras","doc":"A _symmetric key_ algorithm has one key only. The key is used for both\nencryption and decryption. These algorithms are fast, compared to public key\nalgorithms (using two keys, one public and one private) and are therefore\ntypically used for encrypting bulk data.\n\nThe keys for the symmetric encryption are generated uniquely for each connection\nand are based on a secret negotiated in the TLS/DTLS handshake.\n\nThe TLS/DTLS handshake protocol and data transfer is run on top of the TLS/DTLS\nRecord Protocol, which uses a keyed-hash Message Authenticity Code (MAC), or a\nHash-based MAC (HMAC), to protect the message data integrity. From the TLS RFC:\n\"A Message Authentication Code is a one-way hash computed from a message and\nsome secret data. It is difficult to forge without knowing the secret data. Its\npurpose is to detect if the message has been altered.\"","title":"Data Privacy and Integrity - TLS/DTLS Protocol Overview","ref":"ssl_protocol.html#data-privacy-and-integrity"},{"type":"extras","doc":"A certificate is similar to a driver's license, or a passport. The holder of the\ncertificate is called the _subject_. The certificate is signed with the private\nkey of the issuer of the certificate. A chain of trust is built by having the\nissuer in its turn being certified by another certificate, and so on, until you\nreach the so called root certificate, which is self-signed, that is, issued by\nitself.\n\nCertificates are issued by Certification Authorities (CAs) only. A handful of\ntop CAs in the world issue root certificates. You can examine several of these\ncertificates by clicking through the menus of your web browser.","title":"Digital Certificates - TLS/DTLS Protocol Overview","ref":"ssl_protocol.html#digital-certificates"},{"type":"extras","doc":"Authentication of the peer is done by public key path validation as defined in\nRFC 3280. This means basically the following:\n\n- Each certificate in the certificate chain is issued by the previous one.\n- The certificates attributes are valid.\n- The root certificate is a trusted certificate that is present in the trusted\n certificate database kept by the peer.\n\nThe server always sends a certificate chain as part of the TLS handshake, but\nthe client only sends one if requested by the server. If the client does not\nhave an appropriate certificate, it can send an \"empty\" certificate to the\nserver.\n\nThe client can choose to accept some path evaluation errors, for example, a web\nbrowser can ask the user whether to accept an unknown CA root certificate. The\nserver, if it requests a certificate, does however not accept any path\nvalidation errors. It is configurable if the server is to accept or reject an\n\"empty\" certificate as response to a certificate request.","title":"Peer Authentication - TLS/DTLS Protocol Overview","ref":"ssl_protocol.html#peer-authentication"},{"type":"extras","doc":"From the TLS RFC: \"A TLS session is an association between a client and a\nserver. Sessions are created by the handshake protocol. Sessions define a set of\ncryptographic security parameters, which can be shared among multiple\nconnections. Sessions are used to avoid the expensive negotiation of new\nsecurity parameters for each connection.\"\n\nSession data is by default kept by the SSL application in a memory storage,\nhence session data is lost at application restart or takeover. Users can define\ntheir own callback module to handle session data storage if persistent data\nstorage is required. Session data is also invalidated when session database\nexceeds its limit or 24 hours after being saved (RFC max lifetime\nrecommendation). The amount of time the session data is to be saved can be\nconfigured.\n\nBy default the TLS/DTLS clients try to reuse an available session and by default\nthe TLS/DTLS servers agree to reuse sessions when clients ask for it. See also\n[Session Reuse Prior to TLS-1.3](using_ssl.md#session-reuse-prior-to-tls-1-3)","title":"TLS Sessions - Prior to TLS-1.3 - TLS/DTLS Protocol Overview","ref":"ssl_protocol.html#tls-sessions-prior-to-tls-1-3"},{"type":"extras","doc":"In TLS 1.3 the session reuse is replaced by a new session tickets mechanism\nbased on the prior to shared key concept. This mechanism also obsoletes the session\ntickets from RFC5077, not implemented by this application. See also\n[Session Tickets and Session Resumption in TLS-1.3](using_ssl.md#session-tickets-and-session-resumption-in-tls-1-3)","title":"TLS-1.3 session tickets - TLS/DTLS Protocol Overview","ref":"ssl_protocol.html#tls-1-3-session-tickets"},{"type":"extras","doc":"\n# Examples\n\nTo see relevant version information for ssl, call `ssl:versions/0` .\n\nTo see all supported cipher suites, call\n[`ssl:cipher_suites(all, 'tlsv1.3')` ](`ssl:cipher_suites/2`). The available\ncipher suites for a connection depend on the TLS version and prior to TLS-1.3 also on\nthe certificate. To see the default cipher suite list change `all` to `default`.\nNote that TLS 1.3 and previous versions do not have any cipher suites in common,\nfor listing cipher suites for a specific version use\n[`ssl:cipher_suites(exclusive, 'tlsv1.3')` ](`ssl:cipher_suites/2`). Specific\ncipher suites that you want your connection to use can also be specified.\nDefault is to use the strongest available.\n\n\n> #### Warning {: .warning }\n>Enabling cipher suites using RSA as a key exchange algorithm is\n>strongly discouraged (only available prior to TLS-1.3). For some\n>configurations software preventions may exist, and can make them usable if they work,\n>but relying on them to work is risky and there are many more reliable\n>cipher suites that can be used instead.\n\nThe following sections shows small examples of how to set up client/server\nconnections using the Erlang shell. The returned value of the `sslsocket` is\nabbreviated with `[...]` as it can be fairly large and is opaque to the user\nexcept for the purpose of pattern matching.\n\n> #### Note {: .info }\n>\n> Note that client certificate verification is optional for the server and needs\n> additional conguration on both sides to work. The Certificate and keys, in the\n> examples, are provided using the `t:ssl:cert_key_conf/0` supplied in the `certs_keys`\n> introduced in OTP 25.","title":"Examples","ref":"using_ssl.html"},{"type":"extras","doc":"```erlang\n 1 > ssl:start(), ssl:connect(\"google.com\", 443, [{verify, verify_peer},\n {cacerts, public_key:cacerts_get()}]).\n {ok,{sslsocket, [...]}}\n```","title":"Basic Client - Examples","ref":"using_ssl.html#basic-client"},{"type":"extras","doc":"_Step 1:_ Start the server side:\n\n```erlang\n1 server> ssl:start().\nok\n```\n\n_Step 2:_ with alternative certificates, in this example the EDDSA certificate\nwill be preferred if TLS-1.3 is negotiated and the RSA certificate will always\nbe used for TLS-1.2 as it does not support the EDDSA algorithm:\n\n```erlang\n2 server> {ok, ListenSocket} =\nssl:listen(9999, [{certs_keys, [#{certfile => \"eddsacert.pem\",\n keyfile => \"eddsakey.pem\"},\n #{certfile => \"rsacert.pem\",\n keyfile => \"rsakey.pem\",\n password => \"foobar\"}\n ]},{reuseaddr, true}]).\n{ok,{sslsocket, [...]}}\n```\n\n_Step 3:_ Do a transport accept on the TLS listen socket:\n\n```erlang\n3 server> {ok, TLSTransportSocket} = ssl:transport_accept(ListenSocket).\n{ok,{sslsocket, [...]}}\n```\n\n> #### Note {: .info }\n>\n> ssl:transport_accept/1 and ssl:handshake/2 are separate functions so that the\n> handshake part can be called in a new erlang process dedicated to handling the\n> connection\n\n_Step 4:_ Start the client side:\n\n```erlang\n1 client> ssl:start().\nok\n```\n\nBe sure to configure trusted certificates to use for server certificate\nverification.\n\n```erlang\n2 client> {ok, Socket} = ssl:connect(\"localhost\", 9999,\n [{verify, verify_peer},\n {cacertfile, \"cacerts.pem\"}, {active, once}], infinity).\n{ok,{sslsocket, [...]}}\n```\n\n_Step 5:_ Do the TLS handshake:\n\n```erlang\n4 server> {ok, Socket} = ssl:handshake(TLSTransportSocket).\n{ok,{sslsocket, [...]}}\n```\n\n> #### Note {: .info }\n>\n> A real server should use ssl:handshake/2 that has a timeout to avoid DoS\n> attacks. In the example the timeout defaults to infinty.\n\n_Step 6:_ Send a message over TLS:\n\n```erlang\n5 server> ssl:send(Socket, \"foo\").\nok\n```\n\n_Step 7:_ Flush the shell message queue to see that the message sent on the\nserver side is recived by the client side:\n\n```erlang\n3 client> flush().\nShell got {ssl,{sslsocket,[...]},\"foo\"}\nok\n```","title":"Basic Connection - Examples","ref":"using_ssl.html#basic-connection"},{"type":"extras","doc":"Upgrading a a TCP/IP connection to a TLS connections is mostly used when there\nis a desire have unencrypted communication first and then later secure the\ncommunication channel by using TLS. Note that the client and server need to\nagree to do the upgrade in the protocol doing the communication. This is concept\nis often referenced as `STARTLS` and used in many protocols such as `SMTP`,\n`FTPS` and `HTTPS` via a proxy.\n\n> #### Warning {: .warning }\n>\n> Maximum security recommendations are however moving away from such solutions.\n\nTo upgrade to a TLS connection:\n\n_Step 1:_ Start the server side:\n\n```erlang\n1 server> ssl:start().\n ok\n```\n\n_Step 2:_ Create a normal TCP listen socket and ensure `active` is set to\n`false` and not set to any active mode otherwise TLS handshake messages can be\ndelivered to the wrong process.\n\n```erlang\n2 server> {ok, ListenSocket} = gen_tcp:listen(9999, [{reuseaddr, true},\n {active, false}]).\n {ok, #Port<0.475>}\n```\n\n_Step 3:_ Accept client connection:\n\n```erlang\n3 server> {ok, Socket} = gen_tcp:accept(ListenSocket).\n {ok, #Port<0.476>}\n```\n\n_Step 4:_ Start the client side:\n\n```erlang\n1 client> ssl:start().\n ok\n```\n\n```erlang\n2 client> {ok, Socket} = gen_tcp:connect(\"localhost\", 9999, [], infinity).\n```\n\n_Step 5:_ Do the TLS handshake:\n\n```erlang\n4 server> {ok, TLSSocket} = ssl:handshake(Socket, [{verify, verify_peer},\n {fail_if_no_peer_cert, true},\n {cacertfile, \"cacerts.pem\"},\n {certs_keys, [#{certfile => \"cert.pem\", keyfile => \"key.pem\"}]}]).\n {ok,{sslsocket,[...]}}\n```\n\n_Step 6:_ Upgrade to a TLS connection. The client and server must agree upon the\nupgrade. The server must be prepared to be a TLS server before the client can do\na successful connect.\n\n```erlang\n3 client>{ok, TLSSocket} = ssl:connect(Socket, [{verify, verify_peer},\n {cacertfile, \"cacerts.pem\"},\n {certs_keys, [#{certfile => \"cert.pem\", keyfile => \"key.pem\"}]}], infinity).\n{ok,{sslsocket,[...]}}\n```\n\n_Step 7:_ Send a message over TLS:\n\n```erlang\n4 client> ssl:send(TLSSocket, \"foo\").\n ok\n```\n\n_Step 8:_ Set `active once` on the TLS socket:\n\n```erlang\n5 server> ssl:setopts(TLSSocket, [{active, once}]).\n ok\n```\n\n_Step 9:_ Flush the shell message queue to see that the message sent on the\nclient side is recived by the server side:\n\n```erlang\n5 server> flush().\n Shell got {ssl,{sslsocket,[...]},\"foo\"}\n ok\n```","title":"Upgrade Example - TLS only - Examples","ref":"using_ssl.html#upgrade-example-tls-only"},{"type":"extras","doc":"Fetch default cipher suite list for a TLS/DTLS version. Change default to all to\nget all possible cipher suites.\n\n```erlang\n1> Default = ssl:cipher_suites(default, 'tlsv1.2').\n [#{cipher => aes_256_gcm,key_exchange => ecdhe_ecdsa,\n mac => aead,prf => sha384}, ....]\n```\n\nIn OTP 20 it is desirable to remove all cipher suites that uses rsa key exchange\n(removed from default in 21)\n\n```erlang\n2> NoRSA =\n ssl:filter_cipher_suites(Default,\n [{key_exchange, fun(rsa) -> false;\n (_) -> true\n end}]).\n [...]\n```\n\nPick just a few suites\n\n```erlang\n 3> Suites =\n ssl:filter_cipher_suites(Default,\n [{key_exchange, fun(ecdh_ecdsa) -> true;\n (_) -> false\n end},\n {cipher, fun(aes_128_cbc) -> true;\n (_) ->false\n end}]).\n\n[#{cipher => aes_128_cbc,key_exchange => ecdh_ecdsa,\n mac => sha256,prf => sha256},\n #{cipher => aes_128_cbc,key_exchange => ecdh_ecdsa,mac => sha,\n prf => default_prf}]\n```\n\nMake some particular suites the most preferred, or least preferred by changing\nprepend to append.\n\n```erlang\n 4>ssl:prepend_cipher_suites(Suites, Default).\n [#{cipher => aes_128_cbc,key_exchange => ecdh_ecdsa,\n mac => sha256,prf => sha256},\n #{cipher => aes_128_cbc,key_exchange => ecdh_ecdsa,mac => sha,\n prf => default_prf},\n #{cipher => aes_256_cbc,key_exchange => ecdhe_ecdsa,\n mac => sha384,prf => sha384}, ...]\n```","title":"Customizing cipher suites - Examples","ref":"using_ssl.html#customizing-cipher-suites"},{"type":"extras","doc":"Starting from TLS-1.2 signature algorithms (called signature schemes in TLS-1.3)\nis something that can be negotiated and hence also configured. These\nalgorithms/schemes will be used for digital signatures in protocol messages and\nin certificates.\n\n> #### Note {: .info }\n>\n> TLS-1.3 schemes have atom names whereas TLS-1.2 configuration is two element\n> tuples composed by one hash algorithm and one signature algorithm. When both\n> versions are supported the configuration can be a mix of these as both\n> versions might be negotiated. All `rsa_pss` based schemes are back ported to\n> TLS-1.2 and can be used also in a TLS-1.2 configuration. In TLS-1.2 the\n> signature algorithms chosen by the server will also be affected by the chiper\n> suite that is chosen, which is not the case in TLS-1.3.\n\nUsing the function `ssl:signature_algs/2` will let you inspect different aspects\nof possible configurations for your system. For example if TLS-1.3 and TLS-1.2\nis supported the default signature_algorithm list in OTP-26 and cryptolib from\nOpenSSL 3.0.2 would look like:\n\n```erlang\n 1> ssl:signature_algs(default, 'tlsv1.3').\n %% TLS-1.3 schemes\n [eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,\n ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,\n rsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,\n rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,\n %% Legacy schemes only valid for certificate signatures in TLS-1.3\n %% (would have a tuple name in TLS-1.2 only configuration)\n rsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256\n %% TLS 1.2 algorithms\n {sha512,ecdsa},\n {sha384,ecdsa},\n {sha256,ecdsa}]\n```\n\nIf you want to add support for non default supported algorithms you should\nappend them to the default list as the configuration is in prefered order,\nsomething like this:\n\n```erlang\n MySignatureAlgs = ssl:signature_algs(default, 'tlsv1.3') ++ [{sha, rsa}, {sha, dsa}],\n ssl:connect(Host,Port,[{signature_algs, MySignatureAlgs,...]}),\n ...\n```\n\nSee also `ssl:signature_algs/2` and [sign_algo()](`t:ssl:signature_algs/0`)","title":"Customizing signature algorithms(TLS-1.2)/schemes(TLS-1.3) - Examples","ref":"using_ssl.html#customizing-signature-algorithms-tls-1-2-schemes-tls-1-3"},{"type":"extras","doc":"Erlang ssl application is able to use private keys provided by OpenSSL engines\nusing the following mechanism:\n\n```erlang\n1> ssl:start().\nok\n```\n\nLoad a crypto engine, should be done once per engine used. For example\ndynamically load the engine called `MyEngine`:\n\n```erlang\n2> {ok, EngineRef} =\ncrypto:engine_load(<<\"dynamic\">>,\n[{<<\"SO_PATH\">>, \"/tmp/user/engines/MyEngine\"},<<\"LOAD\">>],\n[]).\n{ok,#Ref<0.2399045421.3028942852.173962>}\n```\n\nCreate a map with the engine information and the algorithm used by the engine:\n\n```erlang\n3> PrivKey =\n #{algorithm => rsa,\n engine => EngineRef,\n key_id => \"id of the private key in Engine\"}.\n```\n\nUse the map in the ssl key option:\n\n```erlang\n4> {ok, SSLSocket} =\n ssl:connect(\"localhost\", 9999,\n [{cacertfile, \"cacerts.pem\"},\n {certs_keys, [#{certfile => \"cert.pem\", key => PrivKey}]}\n ], infinity).\n\n```\n\nSee also [crypto documentation](`e:crypto:engine_load.md#engine_load`)","title":"Using an Engine Stored Key - Examples","ref":"using_ssl.html#using-an-engine-stored-key"},{"type":"extras","doc":"The NSS keylog debug feature can be used by authorized users to for instance\nenable wireshark to decrypt TLS packets.\n\n_Server (with NSS key logging)_\n\n```erlang\n server() ->\n application:load(ssl),\n {ok, _} = application:ensure_all_started(ssl),\n Port = 11029,\n LOpts = [{certs_keys, [#{certfile => \"cert.pem\", keyfile => \"key.pem\"}]},\n {reuseaddr, true},\n {versions, ['tlsv1.2','tlsv1.3']},\n {keep_secrets, true} %% Enable NSS key log (debug option)\n ],\n {ok, LSock} = ssl:listen(Port, LOpts),\n {ok, ASock} = ssl:transport_accept(LSock),\n {ok, CSock} = ssl:handshake(ASock).\n```\n\n_Exporting the secrets_\n\n```erlang\n {ok, [{keylog, KeylogItems}]} = ssl:connection_information(CSock, [keylog]).\n file:write_file(\"key.log\", [[KeylogItem,$\\n] || KeylogItem <- KeylogItems]).\n```","title":"NSS keylog - Examples","ref":"using_ssl.html#nss-keylog"},{"type":"extras","doc":"Clients can request to reuse a session established by a previous full handshake\nbetween that client and server by sending the id of the session in the initial\nhandshake message. The server may or may not agree to reuse it. If agreed the\nserver will send back the id and if not it will send a new id. The ssl\napplication has several options for handling session reuse.\n\nOn the client side the ssl application will save session data to try to automate\nsession reuse on behalf of the client processes on the Erlang node. Note that\nonly verified sessions will be saved for security reasons, that is session\nresumption relies on the certificate validation to have been run in the original\nhandshake. To minimize memory consumption only unique sessions will be saved\nunless the special `save` value is specified for the following option\n`{reuse_sessions, boolean() | save}` in which case a full handshake will be\nperformed and that specific session will have been saved before the handshake\nreturns. The session id and even an opaque binary containing the session data\ncan be retrieved using `ssl:connection_information/1` function. A saved session\n(guaranteed by the save option) can be explicitly reused using\n`{reuse_session, SessionId}`. Also it is possible for the client to reuse a\nsession that is not saved by the ssl application using\n`{reuse_session, {SessionId, SessionData}}`.\n\n> #### Note {: .info }\n>\n> When using explicit session reuse, it is up to the client to make sure that\n> the session being reused is for the correct server and has been verified.\n\nHere follows a client side example, divide into several steps for readability.\n\nStep 1 - Automated Session Reuse\n\n```erlang\n1> ssl:start().\nok\n\n2>{ok, C1} = ssl:connect(\"localhost\", 9999, [{verify, verify_peer},\n {versions, ['tlsv1.2']},\n {cacertfile, \"cacerts.pem\"}]).\n{ok,{sslsocket,{gen_tcp,#Port<0.7>,tls_connection,undefined}, ...}}\n\n3> ssl:connection_information(C1, [session_id]).\n{ok,[{session_id,<<95,32,43,22,35,63,249,22,26,36,106,\n 152,49,52,124,56,130,192,137,161,\n 146,145,164,232,...>>}]}\n\n%% Reuse session if possible, note that if C2 is really fast the session\n%% data might not be available for reuse.\n4>{ok, C2} = ssl:connect(\"localhost\", 9999, [{verify, verify_peer},\n {versions, ['tlsv1.2']},\n {cacertfile, \"cacerts.pem\"},\n {reuse_sessions, true}]).\n{ok,{sslsocket,{gen_tcp,#Port<0.8>,tls_connection,undefined}, ...]}}\n\n%% C2 got same session ID as client one, session was automatically reused.\n5> ssl:connection_information(C2, [session_id]).\n{ok,[{session_id,<<95,32,43,22,35,63,249,22,26,36,106,\n 152,49,52,124,56,130,192,137,161,\n 146,145,164,232,...>>}]}\n```\n\nStep 2- Using `save` Option\n\n```erlang\n%% We want save this particular session for\n%% reuse although it has the same basis as C1\n6> {ok, C3} = ssl:connect(\"localhost\", 9999, [{verify, verify_peer},\n {versions, ['tlsv1.2']},\n {cacertfile, \"cacerts.pem\"},\n {reuse_sessions, save}]).\n\n{ok,{sslsocket,{gen_tcp,#Port<0.9>,tls_connection,undefined}, ...]}}\n\n%% A full handshake is performed and we get a new session ID\n7> {ok, [{session_id, ID}]} = ssl:connection_information(C3, [session_id]).\n{ok,[{session_id,<<91,84,27,151,183,39,84,90,143,141,\n 121,190,66,192,10,1,27,192,33,95,78,\n 8,34,180,...>>}]}\n\n%% Use automatic session reuse\n8> {ok, C4} = ssl:connect(\"localhost\", 9999, [{verify, verify_peer},\n {versions, ['tlsv1.2']},\n {cacertfile, \"cacerts.pem\"},\n {reuse_sessions, true}]).\n\n{ok,{sslsocket,{gen_tcp,#Port<0.10>,tls_connection,\n undefined}, ...]}}\n\n%% The \"saved\" one happened to be selected, but this is not a guarantee\n9> ssl:connection_information(C4, [session_id]).\n{ok,[{session_id,<<91,84,27,151,183,39,84,90,143,141,\n 121,190,66,192,10,1,27,192,33,95,78,\n 8,34,180,...>>}]}\n\n%% Make sure to reuse the \"saved\" session\n10> {ok, C5} = ssl:connect(\"localhost\", 9999, [{verify, verify_peer},\n {versions, ['tlsv1.2']},\n {cacertfile, \"cacerts.pem\"},\n {reuse_session, ID}]).\n{ok,{sslsocket,{gen_tcp,#Port<0.11>,tls_connection,\n undefined}, ...]}}\n\n11> ssl:connection_information(C5, [session_id]).\n{ok,[{session_id,<<91,84,27,151,183,39,84,90,143,141,\n 121,190,66,192,10,1,27,192,33,95,78,\n 8,34,180,...>>}]}\n```\n\nStep 3 - Explicit Session Reuse\n\n```erlang\n%% Perform a full handshake and the session will not be saved for reuse\n12> {ok, C9} =\nssl:connect(\"localhost\", 9999, [{verify, verify_peer},\n {versions, ['tlsv1.2']},\n {cacertfile, \"cacerts.pem\"},\n {reuse_sessions, false},\n {server_name_indication, disable}]).\n{ok,{sslsocket,{gen_tcp,#Port<0.14>,tls_connection, ...}}\n\n%% Fetch session ID and data for C9 connection\n12> {ok, [{session_id, ID1}, {session_data, SessData}]} =\n ssl:connection_information(C9, [session_id, session_data]).\n{ok,[{session_id,<<9,233,4,54,170,88,170,180,17,96,202,\n 85,85,99,119,47,9,68,195,50,120,52,\n 130,239,...>>},\n {session_data,<<131,104,13,100,0,7,115,101,115,115,105,\n 111,110,109,0,0,0,32,9,233,4,54,170,...>>}]}\n\n%% Explicitly reuse the session from C9\n13> {ok, C10} = ssl:connect(\"localhost\", 9999, [{verify, verify_peer},\n {versions, ['tlsv1.2']},\n {cacertfile, \"cacerts.pem\"},\n {reuse_session, {ID1, SessData}}]).\n{ok,{sslsocket,{gen_tcp,#Port<0.15>,tls_connection,\n undefined}, ...}}\n\n14> ssl:connection_information(C10, [session_id]).\n{ok,[{session_id,<<9,233,4,54,170,88,170,180,17,96,202,\n 85,85,99,119,47,9,68,195,50,120,52,\n 130,239,...>>}]}\n```\n\nStep 4 - Not Possible to Reuse Explicit Session by ID Only\n\n```erlang\n%% Try to reuse the session from C9 using only the id\n15> {ok, E} = ssl:connect(\"localhost\", 9999, [{verify, verify_peer},\n {versions, ['tlsv1.2']},\n {cacertfile, \"cacerts.pem\"},\n {reuse_session, ID1}]).\n{ok,{sslsocket,{gen_tcp,#Port<0.18>,tls_connection,\n undefined}, ...}}\n\n%% This will fail (as it is not saved for reuse)\n%% and a full handshake will be performed, we get a new id.\n16> ssl:connection_information(E, [session_id]).\n{ok,[{session_id,<<87,46,43,126,175,68,160,153,37,29,\n 196,240,65,160,254,88,65,224,18,63,\n 18,17,174,39,...>>}]}\n```\n\nOn the server side the the `{reuse_sessions, boolean()}` option determines if\nthe server will save session data and allow session reuse or not. This can be\nfurther customized by the option `{reuse_session, fun()}` that may introduce a\nlocal policy for session reuse.","title":"Session Reuse Prior to TLS 1.3 - Examples","ref":"using_ssl.html#session-reuse-prior-to-tls-1-3"},{"type":"extras","doc":"TLS 1.3 introduces a new secure way of resuming sessions by using session\ntickets. A session ticket is an opaque data structure that is sent in the\npre_shared_key extension of a ClientHello, when a client attempts to resume a\nsession with keying material from a previous successful handshake.\n\nSession tickets can be stateful or stateless. A stateful session ticket is a\ndatabase reference (session ticket store) and used with stateful servers, while\na stateless ticket is a self-encrypted and self-authenticated data structure\nwith cryptographic keying material and state data, enabling session resumption\nwith stateless servers.\n\nThe choice between stateful or stateless depends on the server requirements as\nthe session tickets are opaque for the clients. Generally, stateful tickets are\nsmaller and the server can guarantee that tickets are only used once. Stateless\ntickets contain additional data, require less storage on the server side, but\nthey offer different guarantees against anti-replay. See also\n[Anti-Replay Protection in TLS 1.3](using_ssl.md#anti-replay-protection-in-tls-1-3)\n\nSession tickets are sent by servers on newly established TLS connections. The\nnumber of tickets sent and their lifetime are configurable by application\nvariables. See also [SSL's configuration](ssl_app.md#configuration).\n\nSession tickets are protected by application traffic keys, and in stateless\ntickets, the opaque data structure itself is self-encrypted.\n\nAn example with automatic and manual session resumption:\n\n```erlang\n {ok, _} = application:ensure_all_started(ssl).\n LOpts = [{certs_keys, [#{certfile => \"cert.pem\",\n keyfile => \"key.pem\"}]},\n {versions, ['tlsv1.2','tlsv1.3']},\n {session_tickets, stateless}].\n {ok, LSock} = ssl:listen(8001, LOpts).\n {ok, ASock} = ssl:transport_accept(LSock).\n```\n\n_Step 2 (client):_ Start the client and connect to server:\n\n```erlang\n {ok, _} = application:ensure_all_started(ssl).\n COpts = [{cacertfile, \"cert.pem\"},\n {versions, ['tlsv1.2','tlsv1.3']},\n {log_level, debug},\n {session_tickets, auto}].\n ssl:connect(\"localhost\", 8001, COpts).\n```\n\n_Step 3 (server):_ Start the TLS handshake:\n\n```erlang\n {ok, CSocket} = ssl:handshake(ASock).\n```\n\nA connection is established using a full handshake. Below is a summary of the\nexchanged messages:\n\n```erlang\n >>> TLS 1.3 Handshake, ClientHello ...\n << >> Handshake, Finished ...\n << >> TLS 1.3 Handshake, ClientHello ...\n << >> Handshake, Finished ...\n << TicketData end.\n```\n\n_Step 11 (server):_ Accept a new connection on the server:\n\n```erlang\n {ok, ASock4} = ssl:transport_accept(LSock).\n```\n\n_Step 12 (client):_ Initiate a new connection to the server with the session\nticket received in Step 10:\n\n```erlang\n {ok, _} = application:ensure_all_started(ssl).\n COpts2 = [{cacertfile, \"cert.pem\"},\n {versions, ['tlsv1.2','tlsv1.3']},\n {log_level, debug},\n {session_tickets, manual},\n {use_ticket, [Ticket]}].\n ssl:connect(\"localhost\", 8001, COpts).\n```\n\n_Step 13 (server):_ Start the handshake:\n\n```erlang\n {ok, CSock4} = ssl:handshake(ASock4).\n```","title":"Session Tickets and Session Resumption in TLS 1.3 - Examples","ref":"using_ssl.html#session-tickets-and-session-resumption-in-tls-1-3"},{"type":"extras","doc":"TLS 1.3 allows clients to send data on the first flight if the endpoints have a\nshared crypographic secret (pre-shared key). This means that clients can send\nearly data if they have a valid session ticket received in a previous successful\nhandshake. For more information about session resumption see\n[Session Tickets and Session Resumption in TLS 1.3](using_ssl.md#session-tickets-and-session-resumption-in-tls-1-3).\n\nThe security properties of Early Data are weaker than other kinds of TLS data.\nThis data is not forward secret, and it is vulnerable to replay attacks. For\navailable mitigation strategies see\n[Anti-Replay Protection in TLS 1.3](using_ssl.md#anti-replay-protection-in-tls-1-3).\n\nIn normal operation, clients will not know which, if any, of the available\nmitigation strategies servers actually implement, and hence must only send early\ndata which they deem safe to be replayed. For example, idempotent HTTP\noperations, such as HEAD and GET, can usually be regarded as safe but even they\ncan be exploited by a large number of replays causing resource limit exhaustion\nand other similar problems.\n\nAn example of sending early data with automatic and manual session ticket\nhandling:\n\n_Server_\n\n```erlang\nearly_data_server() ->\n application:load(ssl),\n {ok, _} = application:ensure_all_started(ssl),\n Port = 11029,\n LOpts = [{certs_keys, [#{certfile => \"cert.pem\", keyfile => \"key.pem\"}]},\n {reuseaddr, true},\n {versions, ['tlsv1.2','tlsv1.3']},\n {session_tickets, stateless},\n {early_data, enabled},\n ],\n {ok, LSock} = ssl:listen(Port, LOpts),\n %% Accept first connection\n {ok, ASock0} = ssl:transport_accept(LSock),\n {ok, CSock0} = ssl:handshake(ASock0),\n %% Accept second connection\n {ok, ASock1} = ssl:transport_accept(LSock),\n {ok, CSock1} = ssl:handshake(ASock1),\n Sock.\n```\n\n_Client (automatic ticket handling):_\n\n```erlang\nearly_data_auto() ->\n %% First handshake 1-RTT - get session tickets\n application:load(ssl),\n {ok, _} = application:ensure_all_started(ssl),\n Port = 11029,\n Data = <<\"HEAD / HTTP/1.1\\r\\nHost: \\r\\nConnection: close\\r\\n\">>,\n COpts0 = [{cacertfile, \"cacerts.pem\"},\n {versions, ['tlsv1.2', 'tlsv1.3']},\n {session_tickets, auto}],\n {ok, Sock0} = ssl:connect(\"localhost\", Port, COpts0),\n\n %% Wait for session tickets\n timer:sleep(500),\n %% Close socket if server cannot handle multiple\n %% connections e.g. openssl s_server\n ssl:close(Sock0),\n\n %% Second handshake 0-RTT\n COpts1 = [{cacertfile, \"cacerts.pem\"},\n {versions, ['tlsv1.2', 'tlsv1.3']},\n {session_tickets, auto},\n {early_data, Data}],\n {ok, Sock} = ssl:connect(\"localhost\", Port, COpts1),\n Sock.\n\n```\n\n_Client (manual ticket handling):_\n\n```erlang\nearly_data_manual() ->\n %% First handshake 1-RTT - get session tickets\n application:load(ssl),\n {ok, _} = application:ensure_all_started(ssl),\n Port = 11029,\n Data = <<\"HEAD / HTTP/1.1\\r\\nHost: \\r\\nConnection: close\\r\\n\">>,\n COpts0 = [{cacertfile, \"cacerts.pem\"},\n {versions, ['tlsv1.2', 'tlsv1.3']},\n {session_tickets, manual}],\n {ok, Sock0} = ssl:connect(\"localhost\", Port, COpts0),\n\n %% Wait for session tickets\n Ticket =\n receive\n {ssl, session_ticket, Ticket0} ->\n Ticket0\n end,\n\n %% Close socket if server cannot handle multiple connections\n %% e.g. openssl s_server\n ssl:close(Sock0),\n\n %% Second handshake 0-RTT\n COpts1 = [{cacertfile, \"cacerts.pem\"},\n {versions, ['tlsv1.2', 'tlsv1.3']},\n {session_tickets, manual},\n {use_ticket, [Ticket]},\n {early_data, Data}],\n {ok, Sock} = ssl:connect(\"localhost\", Port, COpts1),\n Sock.\n```","title":"Early Data in TLS-1.3 - Examples","ref":"using_ssl.html#early-data-in-tls-1-3"},{"type":"extras","doc":"The TLS 1.3 protocol does not provide inherent protection for replay of 0-RTT\ndata but describes mechanisms that SHOULD be implemented by compliant server\nimplementations. The implementation of TLS 1.3 in the SSL application employs\nall standard methods to prevent potential threats.\n\n_Single-use tickets_\n\nThis mechanism is available with stateful session tickets. Session tickets can\nonly be used once, subsequent use of the same ticket results in a full\nhandshake. Stateful servers enforce this rule by maintaining a database of\noutstanding valid tickets.\n\n_Client Hello Recording_\n\nThis mechanism is available with stateless session tickets. The server records a\nunique value derived from the ClientHello (PSK binder) in a given time window.\nThe ticket's age is verified by using both the \"obsfuscated_ticket_age\" and an\nadditional timestamp encrypted in the ticket data. As the used datastore allows\nfalse positives, apparent replays will be answered by doing a full 1-RTT\nhandshake.\n\n_Freshness Checks_\n\nThis mechanism is available with the stateless session tickets. As the ticket\ndata has an embedded timestamp, the server can determine if a ClientHello was\nsent reasonably recently and accept the 0-RTT handshake, otherwise if falls back\nto a full 1-RTT handshake. This mechanism is tightly coupled with the previous\none, it prevents storing an unlimited number of ClientHellos.\n\nThe current implementation uses a pair of Bloom filters to implement the last\ntwo mechanisms. Bloom filters are fast, memory-efficient, probabilistic data\nstructures that can tell if an element may be in a set or if it is definitely\nnot in the set.\n\nIf the option `anti_replay` is defined in the server, a\npair of Bloom filters (_current_ and _old_) are used to record incoming\nClientHello messages (it is the unique binder value that is actually stored).\nThe _current_ Bloom filter is used for `WindowSize` seconds to store new\nelements. At the end of the time window the Bloom filters are rotated (the\n_current_ Bloom filter becomes the _old_ and an empty Bloom filter is set as\n_current_.\n\nThe Anti-Replay protection feature in stateless servers executes in the\nfollowing steps when a new ClientHello is received:\n\n- Reported ticket age (obfuscated ticket age) shall be less than ticket\n lifetime.\n- Actual ticket age shall be less than the ticket lifetime (stateless session\n tickets contain the servers timestamp when the ticket was issued).\n- ClientHello created with the ticket shall be sent relatively recently\n (freshness checks).\n- If all above checks passed both _current_ and _old_ Bloom filters are checked\n to detect if binder was already seen. Being a probabilistic data structure,\n false positives can occur and they trigger a full handshake.\n- If the binder is not seen, the binder is validated. If the binder is valid,\n the server proceeds with the 0-RTT handshake.","title":"Anti-Replay Protection in TLS 1.3 - Examples","ref":"using_ssl.html#anti-replay-protection-in-tls-1-3"},{"type":"extras","doc":"Using DTLS has basically the same API as TLS. You need to add the option\n\\{protocol, dtls\\} to the connect and listen functions. For example\n\n```erlang\n client>{ok, Socket} = ssl:connect(\"localhost\", 9999, [{protocol, dtls},\n {verify, verify_peer},\n {cacertfile, \"cacerts.pem\"}],\n infinity).\n{ok,{sslsocket, [...]}}\n\n```","title":"Using DTLS - Examples","ref":"using_ssl.html#using-dtls"},{"type":"extras","doc":"\n# Erlang Distribution over TLS\n\nThis section describes how the Erlang distribution can use TLS to get extra\nverification and security.\n\nThe Erlang distribution can in theory use almost any connection-based protocol\nas bearer. However, a module that implements the protocol-specific parts of the\nconnection setup is needed. The default distribution module is `inet_tcp_dist`\nin the Kernel application. When starting an Erlang node distributed,\n`net_kernel` uses this module to set up listen ports and connections.\n\nIn the SSL application, an extra distribution module, `inet_tls_dist`, can be\nused as an alternative. All distribution connections will use TLS and all\nparticipating Erlang nodes in a distributed system must use this distribution\nmodule.\n\nThe security level depends on the parameters provided to the TLS connection\nsetup. Erlang node cookies are however always used, as they can be used to\ndifferentiate between two different Erlang networks.\n\nTo set up Erlang distribution over TLS:\n\n- _Step 1:_ Build boot scripts including the SSL application.\n- _Step 2:_ Specify the distribution module for `net_kernel`.\n- _Step 3:_ Specify the security options and other SSL options.\n- _Step 4:_ Set up the environment to always use TLS.\n\nThe following sections describe these steps.","title":"Erlang Distribution over TLS","ref":"ssl_distribution.html"},{"type":"extras","doc":"Boot scripts are built using the `systools` utility in the SASL application. For\nmore information on `systools`, see the SASL documentation. This is only an\nexample of what can be done.\n\nThe simplest boot script possible includes only the Kernel and STDLIB\napplications. Such a script is located in the `bin` directory of the Erlang\ndistribution. The source for the script is found under the Erlang installation\ntop directory under `releases/ /start_clean.rel`.\n\nDo the following:\n\n- Copy that script to another location (and preferably another name).\n- Add the applications Crypto, Public Key, and SSL with their current version\n numbers after the STDLIB application.\n\nThe following shows an example `.rel` file with TLS added:\n\n```erlang\n {release, {\"OTP APN 181 01\",\"R15A\"}, {erts, \"5.9\"},\n [{kernel,\"2.15\"},\n {stdlib,\"1.18\"},\n {crypto, \"2.0.3\"},\n {public_key, \"0.12\"},\n {asn1, \"4.0\"},\n {ssl, \"5.0\"}\n ]}.\n```\n\nThe version numbers differ in your system. Whenever one of the applications\nincluded in the script is upgraded, change the script.\n\nDo the following:\n\n- Build the boot script.\n\n Assuming the `.rel file` is stored in a file `start_ssl.rel` in the current\n directory, a boot script can be built as follows:\n\n```text\n 1> systools:make_script(\"start_ssl\",[]).\n```\n\nThere is now a `start_ssl.boot` file in the current directory.\n\nDo the following:\n\n- Test the boot script. To do this, start Erlang with the `-boot` command-line\n parameter specifying this boot script (with its full path, but without the\n `.boot` suffix). In UNIX it can look as follows:\n\n```text\n$ erl -boot /home/me/ssl/start_ssl\nErlang (BEAM) emulator version 5.0\n\nEshell V5.0 (abort with ^G)\n1> whereis(ssl_manager).\n<0.41.0>\n```\n\nThe `whereis` function-call verifies that the SSL application is started.\n\nAs an alternative to building a bootscript, you can explicitly add the path to\nthe SSL `ebin` directory on the command line. This is done with command-line\noption `-pa`. This works as the SSL application does not need to be started for\nthe distribution to come up, as a clone of the SSL application is hooked into\nthe Kernel application. So, as long as the SSL application code can be reached,\nthe distribution starts. The `-pa` method is only recommended for testing\npurposes.\n\n> #### Note {: .info }\n>\n> The clone of the SSL application must enable the use of the SSL code in such\n> an early bootstage as needed to set up the distribution. However, this makes\n> it impossible to soft upgrade the SSL application.","title":"Building Boot Scripts Including the SSL Application - Erlang Distribution over TLS","ref":"ssl_distribution.html#building-boot-scripts-including-the-ssl-application"},{"type":"extras","doc":"The distribution module for TLS is named `inet_tls_dist` and is specified on the\ncommand line with option `-proto_dist`. The argument to `-proto_dist` is to be\nthe module name without suffix `_dist`. So, this distribution module is\nspecified with `-proto_dist inet_tls` on the command line.\n\nExtending the command line gives the following:\n\n```text\n$ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls\n```\n\nFor the distribution to be started, give the emulator a name as well:\n\n```text\n$ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls -sname ssl_test\nErlang (BEAM) emulator version 5.0 [source]\n\nEshell V5.0 (abort with ^G)\n(ssl_test@myhost)1>\n```\n\nHowever, a node started in this way refuses to talk to other nodes, as no TLS\nparameters are supplied (see the next section).","title":"Specifying Distribution Module for net_kernel - Erlang Distribution over TLS","ref":"ssl_distribution.html#specifying-distribution-module-for-net_kernel"},{"type":"extras","doc":"The TLS distribution options can be written into a file that is consulted when\nthe node is started. This file name is then specified with the command line\nargument `-ssl_dist_optfile`.\n\nAny available TLS option can be specified in an options file.\n\n> #### Note {: .info }\nOptions that take a `fun()` has to use the syntax `fun Mod:Func/Arity` since a\nfunction body cannot be compiled when consulting a file. Also the encoding\nof the file can be specified as defined by module `m:epp`.\n\n> #### Warning {: .warning }\nDo not tamper with the socket options `list`, `binary`, `active`, `packet`,\n`nodelay` and `deliver` since they are used by the distribution protocol handler\nitself. Other raw socket options such as `packet_size` may interfere severely,\nso beware\\!\n\nFor TLS to work, at least a public key and a certificate must be specified for\nthe server side and the client needs to specify CAs that it trusts (client certification\nis optional and requires more configuration).\n\nIn the following example (to keep it simple), the PEM file `\"/home/me/ssl/erlserver.pem\"`\ncontains both the server certificate and its private key .\n\nCreate a file named for example `\"/home/me/ssl/ssl_test@myhost.conf\"`:\n\n```erlang\n[{server,\n [{certfile, \"/home/me/ssl/erlserver.pem\"}]},\n {client,\n [{cacertfile, \"/home/me/ssl/client_trusted.pem\"}]}].\n```\n\nAnd then start the node like this (line breaks in the command are for\nreadability, and shall not be there when typed):\n\n```text\n$ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls\n -ssl_dist_optfile \"/home/me/ssl/ssl_test@myhost.conf\"\n -sname ssl_test\n```\n\nThe options in the `{server, Opts}` tuple are used when calling\n`ssl:handshake/3`, and the options in the `{client, Opts}` tuple are used when\ncalling `ssl:connect/4`.\n\nFor the client, the option `{server_name_indication, atom_to_list(TargetNode)}`\nis added when connecting. This makes it possible to use the client option\n`{verify, verify_peer}`, and the client will verify that the certificate matches\nthe node name you are connecting to. This only works if the the server\ncertificate is issued to the name\n[`atom_to_list(TargetNode)`](`atom_to_list/1`).\n\nFor the server it is also possible to use the option `{verify, verify_peer}` and\nthe server will only accept client connections with certificates that are\ntrusted by a root certificate that the server knows. A client that presents an\nuntrusted certificate will be rejected. This option is preferably combined with\n`{fail_if_no_peer_cert, true}` or a client will still be accepted if it does not\npresent any certificate.\n\nA node started in this way is fully functional, using TLS as the distribution\nprotocol.","title":"Specifying TLS Options - Erlang Distribution over TLS","ref":"ssl_distribution.html#specifying-tls-options"},{"type":"extras","doc":"It is possible to use TLS distribution over IPv6 instead of IPv4. To do this,\npass the option `-proto_dist inet6_tls` instead of `-proto_dist inet_tls` when\nstarting Erlang, either on the command line or in the `ERL_FLAGS` environment\nvariable.\n\nAn example command line with this option would look like this:\n\n```text\n$ erl -boot /home/me/ssl/start_ssl -proto_dist inet6_tls\n -ssl_dist_optfile \"/home/me/ssl/ssl_test@myhost.conf\"\n -sname ssl_test\n```\n\nA node started in this way will only be able to communicate with other nodes\nusing TLS distribution over IPv6.","title":"Using TLS distribution over IPv6 - Erlang Distribution over TLS","ref":"ssl_distribution.html#using-tls-distribution-over-ipv6"},{"type":"extras","doc":"> #### Note {: .info }\n> The following section describes TLS Option handling prior to OTP 20.2\n> and can only handle a small subset of the actual available options.\n> It is here only for the sake of backwards compatibility .\n\nAs in the previous section the PEM file `\"/home/me/ssl/erlserver.pem\"` contains\nboth the server certificate and its private key.\n\nOn the `erl` command line you can specify options that the TLS distribution adds\nwhen creating a socket.\n\nThe simplest TLS options in the following list can be specified by adding the\nprefix `server_` or `client_` to the option name:\n\n- `certfile`\n- `keyfile`\n- `password`\n- `cacertfile`\n- `verify`\n- `verify_fun` (write as `{Module, Function, InitialUserState}`)\n- `crl_check`\n- `crl_cache` (write as Erlang term)\n- `reuse_sessions`\n- `secure_renegotiate`\n- `depth`\n- `hibernate_after`\n- `ciphers` (use old string format)\n\nNote that `verify_fun` needs to be written in a different form than the\ncorresponding TLS option, since funs are not accepted on the command line.\n\nThe server can also take the options `dhfile` and `fail_if_no_peer_cert` (also\nprefixed).\n\n`client_`\\-prefixed options are used when the distribution initiates a\nconnection to another node. `server_`\\-prefixed options are used when accepting\na connection from a remote node.\n\nRaw socket options, such as `packet` and `size` must not be specified on the\ncommand line.\n\nThe command-line argument for specifying the TLS options is named\n`-ssl_dist_opt` and is to be followed by pairs of SSL options and their values.\nArgument `-ssl_dist_opt` can be repeated any number of times.\n\nAn example command line doing the same as the example in the previous section\ncan now look as follows (line breaks in the command are for readability, and\nshall not be there when typed):\n\n```text\n$ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls\n -ssl_dist_opt server_certfile \"/home/me/ssl/erlserver.pem\"\n -ssl_dist_opt server_secure_renegotiate true client_secure_renegotiate true\n -sname ssl_test\nErlang (BEAM) emulator version 5.0 [source]\n\nEshell V5.0 (abort with ^G)\n(ssl_test@myhost)1>\n```","title":"Specifying TLS Options (Legacy) - Erlang Distribution over TLS","ref":"ssl_distribution.html#specifying-tls-options-legacy"},{"type":"extras","doc":"A convenient way to specify arguments to Erlang is to use environment variable\n`ERL_FLAGS`. All the flags needed to use the TLS distribution can be specified\nin that variable and are then interpreted as command-line arguments for all\nsubsequent invocations of Erlang.\n\nIn a Unix (Bourne) shell, it can look as follows (line breaks are for\nreadability, they are not to be there when typed):\n\n```erlang\n$ ERL_FLAGS=\"-boot /home/me/ssl/start_ssl -proto_dist inet_tls\n -ssl_dist_opt server_certfile /home/me/ssl/erlserver.pem\n -ssl_dist_opt server_secure_renegotiate true client_secure_renegotiate true\"\n$ export ERL_FLAGS\n$ erl -sname ssl_test\nErlang (BEAM) emulator version 5.0 [source]\n\nEshell V5.0 (abort with ^G)\n(ssl_test@myhost)1> init:get_arguments().\n[{root,[\"/usr/local/erlang\"]},\n {progname,[\"erl \"]},\n {sname,[\"ssl_test\"]},\n {boot,[\"/home/me/ssl/start_ssl\"]},\n {proto_dist,[\"inet_tls\"]},\n {ssl_dist_opt,[\"server_certfile\",\"/home/me/ssl/erlserver.pem\"]},\n {ssl_dist_opt,[\"server_secure_renegotiate\",\"true\",\n \"client_secure_renegotiate\",\"true\"]\n {home,[\"/home/me\"]}]\n```\n\nThe `init:get_arguments()` call verifies that the correct arguments are supplied\nto the emulator.","title":"Setting up Environment to Always Use TLS - Erlang Distribution over TLS","ref":"ssl_distribution.html#setting-up-environment-to-always-use-tls"},{"type":"extras","doc":"\n# Standards Compliance","title":"Standards Compliance","ref":"standards_compliance.html"},{"type":"extras","doc":"This section describes the current state of standards compliance of the ssl\napplication.","title":"Purpose - Standards Compliance","ref":"standards_compliance.html#purpose"},{"type":"extras","doc":"- For security reasons RSA key exchange cipher suites are no longer supported by\n default, but can be configured. (OTP 21)\n- For security reasons DES cipher suites are no longer supported by default, but\n can be configured. (OTP 20)\n- For security reasons 3DES cipher suites are no longer supported by default,\n but can be configured. (OTP 21)\n- Renegotiation Indication Extension\n [RFC 5746](http://www.ietf.org/rfc/rfc5746.txt) is supported\n- Ephemeral Diffie-Hellman cipher suites are supported, but not Diffie Hellman\n Certificates cipher suites.\n- Elliptic Curve cipher suites are supported if the Crypto application supports\n it and named curves are used.\n- Export cipher suites are not supported as the U.S. lifted its export\n restrictions in early 2000.\n- IDEA cipher suites are not supported as they have become deprecated by the TLS\n 1.2 specification so it is not motivated to implement them.\n- Compression is not supported.\n- It is possible to use Pre-Shared Key (PSK) and Secure Remote Password (SRP)\n cipher suites, but they are not enabled by default and need addition configuration.","title":"Common (prior to TLS 1.3) - Standards Compliance","ref":"standards_compliance.html#common-prior-to-tls-1-3"},{"type":"extras","doc":"- CRL validation is supported.\n- Policy certificate extensions are supported. (OTP 27)\n- 'Server Name Indication' extension\n ([RFC 6066](http://www.ietf.org/rfc/rfc6066.txt)) is supported.\n- Application Layer Protocol Negotiation (ALPN) and its successor Next Protocol\n Negotiation (NPN) are supported.","title":"Common - Standards Compliance","ref":"standards_compliance.html#common"},{"type":"extras","doc":"For security reasons SSL-2.0 is not supported. Interoperability with SSL-2.0\nenabled clients dropped. (OTP 21)","title":"SSL 2.0 - Standards Compliance","ref":"standards_compliance.html#ssl-2-0"},{"type":"extras","doc":"For security reasons SSL-3.0 is no longer supported at all. (OTP 23)\n\nFor security reasons SSL-3.0 is no longer supported by default, but can be\nconfigured. (OTP 19)","title":"SSL 3.0 - Standards Compliance","ref":"standards_compliance.html#ssl-3-0"},{"type":"extras","doc":"For security reasons TLS-1.0 is no longer supported by default, but can be\nconfigured. (OTP 22)","title":"TLS 1.0 - Standards Compliance","ref":"standards_compliance.html#tls-1-0"},{"type":"extras","doc":"For security reasons TLS-1.1 is no longer supported by default, but can be\nconfigured. (OTP 22)","title":"TLS 1.1 - Standards Compliance","ref":"standards_compliance.html#tls-1-1"},{"type":"extras","doc":"Supported","title":"TLS 1.2 - Standards Compliance","ref":"standards_compliance.html#tls-1-2"},{"type":"extras","doc":"For security reasons DTLS-1.0 (based on TLS 1.1) is no longer supported by\ndefault, but can be configured. (OTP 22)","title":"DTLS 1.0 - Standards Compliance","ref":"standards_compliance.html#dtls-1-0"},{"type":"extras","doc":"Supported (based on TLS 1.2)","title":"DTLS 1.2 - Standards Compliance","ref":"standards_compliance.html#dtls-1-2"},{"type":"extras","doc":"Not yet supported","title":"DTLS 1.3 - Standards Compliance","ref":"standards_compliance.html#dtls-1-3"},{"type":"extras","doc":"OTP-22 introduces support for TLS 1.3. The current implementation supports a\nselective set of cryptographic algorithms:\n\n- Key Exchange: ECDHE groups supported by default\n- Groups: all standard groups supported for the Diffie-Hellman key exchange\n- Groups: Support brainpool groups from RFC 8734\n- Ciphers: all mandatory cipher suites are supported\n- Signature Algorithms: All algorithms form RFC 8446\n- Certificates: RSA, ECDSA and EDDSA keys\n\nOther notable features:\n\n- PSK and session resumption is supported (stateful and stateless tickets)\n- Anti-replay protection using Bloom-filters with stateless tickets\n- Early data and 0-RTT is supported\n- Key and Initialization Vector Update is supported\n\nFor more detailed information see the\n[Standards Compliance](standards_compliance.md#soc_table) below.\n\nThe following table describes the current state of standards compliance for TLS\n1.3.\n\n(_C_ = Compliant, _NC_ = Non-Compliant, _PC_ = Partially-Compliant, _NA_ = Not\nApplicable)\n\n[](){: #soc_table }\n\n| _Section_ | _Feature_ | _State_ | _Since_ |\n| --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------- |\n| [1\\.3. Updates Affecting TLS 1.2](https://tools.ietf.org/html/rfc8446#section-1.2) | | _C_ | _24\\.1_ |\n| | Version downgrade protection mechanism | _C_ | _22_ |\n| | RSASSA-PSS signature schemes | _C_ | _24\\.1_ |\n| | supported_versions (ClientHello) extension | _C_ | _22_ |\n| | signature_algorithms_cert extension | _C_ | _24\\.1_ |\n| [2\\. Protocol Overview](https://tools.ietf.org/html/rfc8446#section/2) | | _PC_ | _22_ |\n| | (EC)DHE | _C_ | _22_ |\n| | PSK-only | _NC_ | |\n| | PSK with (EC)DHE | _C_ | _22\\.2_ |\n| [2\\.1. Incorrect DHE share](https://tools.ietf.org/html/rfc8446#section-2.1) | HelloRetryRequest | _C_ | _22_ |\n| [2\\.2. Resumption and Pre-Shared Key (PSK)](https://tools.ietf.org/html/rfc8446#section-2.2) | | _C_ | _22\\.2_ |\n| [2\\.3. 0-RTT Data](https://tools.ietf.org/html/rfc8446#section-2.3) | | _PC_ | _23\\.3_ |\n| [4\\.1.1. Cryptographic Negotiation](https://tools.ietf.org/html/rfc8446#section-4.1.1) | | _C_ | _22\\.2_ |\n| | supported_groups extension | _C_ | _22_ |\n| | signature_algorithms extension | _C_ | _22_ |\n| | pre_shared_key extension | _C_ | _22\\.2_ |\n| [4\\.1.2. Client Hello](https://tools.ietf.org/html/rfc8446#section-4.1.2) | _Client_ | _PC_ | _22\\.1_ |\n| | server_name (RFC6066) | _C_ | _23\\.2_ |\n| | max_fragment_length (RFC6066) | _C_ | _23\\.0_ |\n| | status_request (RFC6066) | _C_ | _27\\.0_ |\n| | supported_groups (RFC7919) | _C_ | _22\\.1_ |\n| | signature_algorithms (RFC8446) | _C_ | _22\\.1_ |\n| | use_srtp (RFC5764) | _C_ | 26\\.0 |\n| | heartbeat (RFC6520) | _NC_ | |\n| | application_layer_protocol_negotiation (RFC7301) | _C_ | _22\\.1_ |\n| | signed_certificate_timestamp (RFC6962) | _NC_ | |\n| | client_certificate_type (RFC7250) | _NC_ | |\n| | server_certificate_type (RFC7250) | _NC_ | |\n| | padding (RFC7685) | _NC_ | |\n| | key_share (RFC8446) | _C_ | _22\\.1_ |\n| | pre_shared_key (RFC8446) | _C_ | _22\\.2_ |\n| | psk_key_exchange_modes (RFC8446) | _C_ | _22\\.2_ |\n| | early_data (RFC8446) | _C_ | _23\\.3_ |\n| | cookie (RFC8446) | _C_ | _23\\.1_ |\n| | supported_versions (RFC8446) | _C_ | _22\\.1_ |\n| | certificate_authorities (RFC8446) | _C_ | 24\\.3 |\n| | oid_filters (RFC8446) | _NC_ | |\n| | post_handshake_auth (RFC8446) | _NC_ | |\n| | signature_algorithms_cert (RFC8446) | _C_ | _22\\.1_ |\n| | _Server_ | _PC_ | _22_ |\n| | server_name (RFC6066) | _C_ | _23\\.2_ |\n| | max_fragment_length (RFC6066) | _C_ | _23\\.0_ |\n| | status_request (RFC6066) | _NC_ | |\n| | supported_groups (RFC7919) | _C_ | _22_ |\n| | signature_algorithms (RFC8446) | _C_ | _22_ |\n| | use_srtp (RFC5764) | _C_ | 26\\.0 |\n| | heartbeat (RFC6520) | _NC_ | |\n| | application_layer_protocol_negotiation (RFC7301) | _C_ | _22\\.1_ |\n| | signed_certificate_timestamp (RFC6962) | _NC_ | |\n| | client_certificate_type (RFC7250) | _NC_ | |\n| | server_certificate_type (RFC7250) | _NC_ | |\n| | padding (RFC7685) | _NC_ | |\n| | key_share (RFC8446) | _C_ | _22_ |\n| | pre_shared_key (RFC8446) | _C_ | _22\\.2_ |\n| | psk_key_exchange_modes (RFC8446) | _C_ | _22\\.2_ |\n| | early_data (RFC8446) | _C_ | _23\\.3_ |\n| | cookie (RFC8446) | _C_ | _23\\.1_ |\n| | supported_versions (RFC8446) | _C_ | _22_ |\n| | oid_filters (RFC8446) | _NC_ | |\n| | post_handshake_auth (RFC8446) | _NC_ | |\n| | signature_algorithms_cert (RFC8446) | _C_ | _22_ |\n| [4\\.1.3. Server Hello](https://tools.ietf.org/html/rfc8446#section-4.1.3) | _Client_ | _C_ | _22\\.2_ |\n| | Version downgrade protection | _C_ | _22\\.1_ |\n| | key_share (RFC8446) | _C_ | _22\\.1_ |\n| | pre_shared_key (RFC8446) | _C_ | _22\\.2_ |\n| | supported_versions (RFC8446) | _C_ | _22\\.1_ |\n| | use_srtp (RFC5764) | _C_ | 26\\.0 |\n| | _Server_ | _C_ | _22\\.2_ |\n| | Version downgrade protection | _C_ | _22_ |\n| | key_share (RFC8446) | _C_ | _22_ |\n| | pre_shared_key (RFC8446) | _C_ | _22\\.2_ |\n| | supported_versions (RFC8446) | _C_ | _22_ |\n| | use_srtp (RFC5764) | _C_ | 26\\.0 |\n| [4\\.1.4. Hello Retry Request](https://tools.ietf.org/html/rfc8446#section-4.1.4) | _Server_ | _C_ | _22_ |\n| | key_share (RFC8446) | _C_ | _22_ |\n| | cookie (RFC8446) | _C_ | _23\\.1_ |\n| | supported_versions (RFC8446) | _C_ | _22_ |\n| [4\\.2.1. Supported Versions](https://tools.ietf.org/html/rfc8446#section-4.2.1) | _Client_ | _C_ | _22\\.1_ |\n| | _Server_ | _C_ | _22_ |\n| [4\\.2.2. Cookie](https://tools.ietf.org/html/rfc8446#section-4.2.2) | _Client_ | _C_ | _23\\.1_ |\n| | _Server_ | _C_ | _23\\.1_ |\n| [4\\.2.3. Signature Algorithms](https://tools.ietf.org/html/rfc8446#section-4.2.3) | _Client_ | _C_ | _24_ |\n| | rsa_pkcs1_sha256 | _C_ | _22\\.1_ |\n| | rsa_pkcs1_sha384 | _C_ | _22\\.1_ |\n| | rsa_pkcs1_sha512 | _C_ | _22\\.1_ |\n| | ecdsa_secp256r1_sha256 | _C_ | _22\\.1_ |\n| | ecdsa_secp384r1_sha384 | _C_ | _22\\.1_ |\n| | ecdsa_secp521r1_sha512 | _C_ | _22\\.1_ |\n| | rsa_pss_rsae_sha256 | _C_ | _22\\.1_ |\n| | rsa_pss_rsae_sha384 | _C_ | _22\\.1_ |\n| | rsa_pss_rsae_sha512 | _C_ | _22\\.1_ |\n| | ed25519 | _C_ | _24_ |\n| | ed448 | _C_ | _24_ |\n| | rsa_pss_pss_sha256 | _C_ | _23_ |\n| | rsa_pss_pss_sha384 | _C_ | _23_ |\n| | rsa_pss_pss_sha512 | _C_ | _23_ |\n| | rsa_pkcs1_sha1 | _C_ | _22\\.1_ |\n| | ecdsa_sha1 | _C_ | _22\\.1_ |\n| | _Server_ | _C_ | _24_ |\n| | rsa_pkcs1_sha256 | _C_ | _22_ |\n| | rsa_pkcs1_sha384 | _C_ | _22_ |\n| | rsa_pkcs1_sha512 | _C_ | _22_ |\n| | ecdsa_secp256r1_sha256 | _C_ | _22\\.1_ |\n| | ecdsa_secp384r1_sha384 | _C_ | _22\\.1_ |\n| | ecdsa_secp521r1_sha512 | _C_ | _22\\.1_ |\n| | rsa_pss_rsae_sha256 | _C_ | _22_ |\n| | rsa_pss_rsae_sha384 | _C_ | _22_ |\n| | rsa_pss_rsae_sha512 | _C_ | _22_ |\n| | ed25519 | _C_ | _24_ |\n| | ed448 | _C_ | _24_ |\n| | rsa_pss_pss_sha256 | _C_ | _23_ |\n| | rsa_pss_pss_sha384 | _C_ | _23_ |\n| | rsa_pss_pss_sha512 | _C_ | _23_ |\n| | rsa_pkcs1_sha1 | _C_ | _22_ |\n| | ecdsa_sha1 | _C_ | _22_ |\n| [4\\.2.4. Certificate Authorities](https://tools.ietf.org/html/rfc8446#section-4.2.4) | _Client_ | _C_ | 24\\.3 |\n| | _Server_ | _C_ | _24\\.3_ |\n| [4\\.2.5. OID Filters](https://tools.ietf.org/html/rfc8446#section-4.2.5) | _Client_ | _NC_ | |\n| | _Server_ | _NC_ | |\n| [4\\.2.6. Post-Handshake Client Authentication](https://tools.ietf.org/html/rfc8446#section-4.2.6) | _Client_ | _NC_ | |\n| | _Server_ | _NC_ | |\n| [4\\.2.7. Supported Groups](https://tools.ietf.org/html/rfc8446#section-4.2.7) | _Client_ | _C_ | _22\\.1_ |\n| | secp256r1 | _C_ | _22\\.1_ |\n| | secp384r1 | _C_ | _22\\.1_ |\n| | secp521r1 | _C_ | _22\\.1_ |\n| | x25519 | _C_ | _22\\.1_ |\n| | x448 | _C_ | _22\\.1_ |\n| | ffdhe2048 | _C_ | _22\\.1_ |\n| | ffdhe3072 | _C_ | _22\\.1_ |\n| | ffdhe4096 | _C_ | _22\\.1_ |\n| | ffdhe6144 | _C_ | _22\\.1_ |\n| | ffdhe8192 | _C_ | _22\\.1_ |\n| | _Server_ | _C_ | _22_ |\n| | secp256r1 | _C_ | _22_ |\n| | secp384r1 | _C_ | _22_ |\n| | secp521r1 | _C_ | _22_ |\n| | x25519 | _C_ | _22_ |\n| | x448 | _C_ | _22_ |\n| | ffdhe2048 | _C_ | _22_ |\n| | ffdhe3072 | _C_ | _22_ |\n| | ffdhe4096 | _C_ | _22_ |\n| | ffdhe6144 | _C_ | _22_ |\n| | ffdhe8192 | _C_ | _22_ |\n| [4\\.2.8. Key Share](https://tools.ietf.org/html/rfc8446#section-4.2.8) | _Client_ | _C_ | _22\\.1_ |\n| | _Server_ | _C_ | _22_ |\n| [4\\.2.9. Pre-Shared Key Exchange Modes](https://tools.ietf.org/html/rfc8446#section-4.2.9) | _Client_ | _C_ | _22\\.2_ |\n| | _Server_ | _C_ | _22\\.2_ |\n| [4\\.2.10. Early Data Indication](https://tools.ietf.org/html/rfc8446#section-4.2.10) | _Client_ | _C_ | _23\\.3_ |\n| | _Server_ | _C_ | _23\\.3_ |\n| [4\\.2.11. Pre-Shared Key Extension](https://tools.ietf.org/html/rfc8446#section-4.2.11) | _Client_ | _C_ | _22\\.2_ |\n| | _Server_ | _C_ | _22\\.2_ |\n| [4\\.2.11.1. Ticket Age](https://tools.ietf.org/html/rfc8446#section-4.2.11.1) | _Client_ | _C_ | _22\\.2_ |\n| | _Server_ | _C_ | _22\\.2_ |\n| [4\\.2.11.2. PSK Binder](https://tools.ietf.org/html/rfc8446#section-4.2.11.2) | _Client_ | _C_ | _22\\.2_ |\n| | _Server_ | _C_ | _22\\.2_ |\n| [4\\.2.11.3. Processing Order](https://tools.ietf.org/html/rfc8446#section-4.2.11.3) | _Client_ | _NC_ | |\n| | _Server_ | _NC_ | |\n| [4\\.3.1. Encrypted Extensions](https://tools.ietf.org/html/rfc8446#section-4.3.1) | _Client_ | _PC_ | _22\\.1_ |\n| | server_name (RFC6066) | _C_ | _23\\.2_ |\n| | max_fragment_length (RFC6066) | _C_ | _23\\.0_ |\n| | supported_groups (RFC7919) | _NC_ | |\n| | use_srtp (RFC5764) | _NC_ | |\n| | heartbeat (RFC6520) | _NC_ | |\n| | application_layer_protocol_negotiation (RFC7301) | _C_ | 23\\.0 |\n| | client_certificate_type (RFC7250) | _NC_ | |\n| | server_certificate_type (RFC7250) | _NC_ | |\n| | early_data (RFC8446) | _C_ | _23\\.3_ |\n| | _Server_ | _PC_ | _22_ |\n| | server_name (RFC6066) | _C_ | _23\\.2_ |\n| | max_fragment_length (RFC6066) | _C_ | _23\\.0_ |\n| | supported_groups (RFC7919) | _NC_ | |\n| | use_srtp (RFC5764) | _NC_ | |\n| | heartbeat (RFC6520) | _NC_ | |\n| | application_layer_protocol_negotiation (RFC7301) | _C_ | 23\\.0 |\n| | client_certificate_type (RFC7250) | _NC_ | |\n| | server_certificate_type (RFC7250) | _NC_ | |\n| | early_data (RFC8446) | _C_ | _23\\.3_ |\n| [4\\.3.2. Certificate Request](https://tools.ietf.org/html/rfc8446#section-4.3.2) | _Client_ | _PC_ | _22\\.1_ |\n| | status_request (RFC6066) | _NC_ | |\n| | signature_algorithms (RFC8446) | _C_ | _22\\.1_ |\n| | signed_certificate_timestamp (RFC6962) | _NC_ | |\n| | certificate_authorities (RFC8446) | _C_ | 24\\.3 |\n| | oid_filters (RFC8446) | _NC_ | |\n| | signature_algorithms_cert (RFC8446) | _C_ | _22\\.1_ |\n| | _Server_ | _PC_ | _22_ |\n| | status_request (RFC6066) | _NC_ | |\n| | signature_algorithms (RFC8446) | _C_ | _22_ |\n| | signed_certificate_timestamp (RFC6962) | _NC_ | |\n| | certificate_authorities (RFC8446) | _C_ | 24\\.3 |\n| | oid_filters (RFC8446) | _NC_ | |\n| | signature_algorithms_cert (RFC8446) | _C_ | _22_ |\n| [4\\.4.1. The Transcript Hash](https://tools.ietf.org/html/rfc8446#section-4.4.1) | | _C_ | _22_ |\n| [4\\.4.2. Certificate](https://tools.ietf.org/html/rfc8446#section-4.4.2) | _Client_ | _PC_ | _22\\.1_ |\n| | Arbitrary certificate chain orderings | _C_ | _22\\.2_ |\n| | Extraneous certificates in chain | _C_ | _23\\.2_ |\n| | status_request (RFC6066) | _C_ | 27\\.0 |\n| | signed_certificate_timestamp (RFC6962) | _NC_ | |\n| | _Server_ | _PC_ | _22_ |\n| | status_request (RFC6066) | _NC_ | |\n| | signed_certificate_timestamp (RFC6962) | _NC_ | |\n| [4\\.4.2.1. OCSP Status and SCT Extensions](https://tools.ietf.org/html/rfc8446#section-4.4.2.1) | _Client_ | _PC_ | _27\\.0_ |\n| | _Server_ | _NC_ | |\n| [4\\.4.2.2. Server Certificate Selection](https://tools.ietf.org/html/rfc8446#section-4.4.2.2) | | _C_ | _24\\.3_ |\n| | The certificate type MUST be X.509v3, unless explicitly negotiated otherwise | _C_ | _22_ |\n| | The server's end-entity certificate's public key (and associated restrictions) MUST be compatible with the selected authentication algorithm from the client's \"signature_algorithms\" extension (currently RSA, ECDSA, or EdDSA). | _C_ | _22_ |\n| | The certificate MUST allow the key to be used for signing with a signature scheme indicated in the client's \"signature_algorithms\"/\"signature_algorithms_cert\" extensions | _C_ | _22_ |\n| | The \"server_name\" and \"certificate_authorities\" extensions are used to guide certificate selection. As servers MAY require the presence of the \"server_name\" extension, clients SHOULD send this extension, when applicable. | _C_ | _24\\.3_ |\n| [4\\.4.2.3. Client Certificate Selection](https://tools.ietf.org/html/rfc8446#section-4.4.2.3) | | _PC_ | _22\\.1_ |\n| | The certificate type MUST be X.509v3, unless explicitly negotiated otherwise | _C_ | _22\\.1_ |\n| | If the \"certificate_authorities\" extension in the CertificateRequest message was present, at least one of the certificates in the certificate chain SHOULD be issued by one of the listed CAs. | _C_ | _24\\.3_ |\n| | The certificates MUST be signed using an acceptable signature algorithm | _C_ | _22\\.1_ |\n| | If the CertificateRequest message contained a non-empty \"oid_filters\" extension, the end-entity certificate MUST match the extension OIDs that are recognized by the client | _NC_ | |\n| [4\\.4.2.4. Receiving a Certificate Message](https://tools.ietf.org/html/rfc8446#section-4.4.2.4) | _Client_ | _C_ | _22\\.1_ |\n| | _Server_ | _C_ | _22_ |\n| [4\\.4.3. Certificate Verify](https://tools.ietf.org/html/rfc8446#section-4.4.3) | _Client_ | _C_ | _22\\.1_ |\n| | _Server_ | _C_ | _22_ |\n| [4\\.4.4. Finished](https://tools.ietf.org/html/rfc8446#section-4.4.4) | _Client_ | _C_ | _22\\.1_ |\n| | _Server_ | _C_ | _22_ |\n| [4\\.5. End of Early Data](https://tools.ietf.org/html/rfc8446#section-4.5) | _Client_ | _C_ | _23\\.3_ |\n| | _Server_ | _C_ | _23\\.3_ |\n| [4\\.6.1. New Session Ticket Message](https://tools.ietf.org/html/rfc8446#section-4.6.1) | _Client_ | _C_ | _23\\.3_ |\n| | early_data (RFC8446) | _C_ | _23\\.3_ |\n| | _Server_ | _C_ | _23\\.3_ |\n| | early_data (RFC8446) | _C_ | _23\\.3_ |\n| [4\\.6.2. Post-Handshake Authentication](https://tools.ietf.org/html/rfc8446#section-4.6.2) | _Client_ | _NC_ | |\n| | _Server_ | _NC_ | |\n| [4\\.6.3. Key and Initialization Vector Update](https://tools.ietf.org/html/rfc8446#section-4.6.3) | _Client_ | _C_ | _22\\.3_ |\n| | _Server_ | _C_ | _22\\.3_ |\n| [5\\.1. Record Layer](https://tools.ietf.org/html/rfc8446#section-5.1) | | _C_ | _22_ |\n| | MUST NOT be interleaved with other record types | _C_ | _22_ |\n| | MUST NOT span key changes | _C_ | _22_ |\n| | MUST NOT send zero-length fragments | _C_ | _22_ |\n| | Alert messages MUST NOT be fragmented | _C_ | _22_ |\n| [5\\.2. Record Payload Protection](https://tools.ietf.org/html/rfc8446#section-5.2) | | _C_ | _22_ |\n| [5\\.3. Per-Record Nonce](https://tools.ietf.org/html/rfc8446#section-5.3) | | _C_ | _22_ |\n| [5\\.4. Record Padding](https://tools.ietf.org/html/rfc8446#section-5.4) | | _PC_ | _22_ |\n| | MAY choose to pad | _NC_ | |\n| | MUST NOT send Handshake and Alert records that have a zero-length TLSInnerPlaintext.content | _NC_ | |\n| | The padding sent is automatically verified | _C_ | _22_ |\n| [5\\.5. Limits on Key Usage](https://tools.ietf.org/html/rfc8446#section-5.5) | | _C_ | _22\\.3_ |\n| [6\\.1. Closure Alerts](https://tools.ietf.org/html/rfc8446#section-6.1) | | _22_ | |\n| | close_notify | _C_ | _22_ | |\n| | user_cancelled | _C_ | _22_ | |\n| [6\\.2. Error Alerts](https://tools.ietf.org/html/rfc8446#section-6.2) | | _PC_ | _22_ |\n| [7\\.1. Key Schedule](https://tools.ietf.org/html/rfc8446#section-7.1) | | _C_ | _22_ |\n| [7\\.2. Updating Traffic Secrets](https://tools.ietf.org/html/rfc8446#section-7.2) | | _C_ | _22_ |\n| [7\\.3. Traffic Key Calculation](https://tools.ietf.org/html/rfc8446#section-7.3) | | _C_ | _22_ |\n| [7\\.5. Exporters](https://tools.ietf.org/html/rfc8446#section-7.5) | | _PC_ | _26\\.3_ |\n| [8\\. 0-RTT and Anti-Replay](https://tools.ietf.org/html/rfc8446#section/8) | | _C_ | _22\\.2_ |\n| [8\\.1. Single-Use Tickets](https://tools.ietf.org/html/rfc8446#section-8.1) | | _C_ | _22\\.2_ |\n| [8\\.2. Client Hello Recording](https://tools.ietf.org/html/rfc8446#section-8.2) | | _C_ | _22\\.2_ |\n| [8\\.3. Freshness Checks](https://tools.ietf.org/html/rfc8446#section-8.3) | | _C_ | _22\\.2_ |\n| [9\\.1. Mandatory-to-Implement Cipher Suites](https://tools.ietf.org/html/rfc8446#section-9.1) | | _C_ | _22\\.1_ |\n| | MUST implement the TLS_AES_128_GCM_SHA256 | _C_ | _22_ |\n| | SHOULD implement the TLS_AES_256_GCM_SHA384 | _C_ | _22_ |\n| | SHOULD implement the TLS_CHACHA20_POLY1305_SHA256 | _C_ | _22_ |\n| | _Digital signatures_ | _C_ | _22\\.1_ |\n| | MUST support rsa_pkcs1_sha256 (for certificates) | _C_ | _22_ |\n| | MUST support rsa_pss_rsae_sha256 (for CertificateVerify and certificates) | _C_ | _22_ |\n| | MUST support ecdsa_secp256r1_sha256 | _C_ | _22\\.1_ |\n| | _Key Exchange_ | _C_ | _22_ |\n| | MUST support key exchange with secp256r1 | _C_ | _22_ |\n| | SHOULD support key exchange with X25519 | _C_ | _22_ |\n| [9\\.2. Mandatory-to-Implement Extensions](https://tools.ietf.org/html/rfc8446#section-9.2) | | _C_ | _23\\.2_ |\n| | Supported Versions | _C_ | _22_ |\n| | Cookie | _C_ | _23\\.1_ |\n| | Signature Algorithms | _C_ | _22_ |\n| | Signature Algorithms Certificate | _C_ | _22_ |\n| | Negotiated Groups | _C_ | _22_ |\n| | Key Share | _C_ | _22_ |\n| | Server Name Indication | _C_ | _23\\.2_ |\n| | _MUST send and use these extensions_ | _C_ | _22\\.2_ |\n| | \"supported_versions\" is REQUIRED for ClientHello, ServerHello and HelloRetryRequest | _C_ | _22\\.1_ |\n| | \"signature_algorithms\" is REQUIRED for certificate authentication | _C_ | _22_ |\n| | \"supported_groups\" is REQUIRED for ClientHello messages using (EC)DHE key exchange | _C_ | _22_ |\n| | \"key_share\" is REQUIRED for (EC)DHE key exchange | _C_ | _22_ |\n| | \"pre_shared_key\" is REQUIRED for PSK key agreement | _C_ | _22\\.2_ |\n| | \"psk_key_exchange_modes\" is REQUIRED for PSK key agreement | _C_ | _22\\.2_ |\n| | _TLS 1.3 ClientHello_ | _C_ | _22\\.1_ |\n| | If not containing a \"pre_shared_key\" extension, it MUST contain both a \"signature_algorithms\" extension and a \"supported_groups\" extension. | _C_ | _22\\.1_ |\n| | If containing a \"supported_groups\" extension, it MUST also contain a \"key_share\" extension, and vice versa. An empty KeyShare.client_shares vector is permitted. | _C_ | _22\\.1_ |\n| | _TLS 1.3 ServerHello_ | _C_ | _23\\.2_ |\n| | MUST support the use of the \"server_name\" extension | _C_ | _23\\.2_ |\n| [9\\.3. Protocol Invariants](https://tools.ietf.org/html/rfc8446#section-9.3) | | _C_ | _22\\.1_ |\n| | _MUST correctly handle extensible fields_ | _C_ | _22\\.1_ |\n| | A client sending a ClientHello MUST support all parameters advertised in it. Otherwise, the server may fail to interoperate by selecting one of those parameters. | _C_ | _22\\.1_ |\n| | A server receiving a ClientHello MUST correctly ignore all unrecognized cipher suites, extensions, and other parameters. Otherwise, it may fail to interoperate with newer clients. In TLS 1.3, a client receiving a CertificateRequest or NewSessionTicket MUST also ignore all unrecognized extensions. | _C_ | _22\\.1_ |\n| | A middlebox which terminates a TLS connection MUST behave as a compliant TLS server | _NA_ | |\n| | A middlebox which forwards ClientHello parameters it does not understand MUST NOT process any messages beyond that ClientHello. It MUST forward all subsequent traffic unmodified. Otherwise, it may fail to interoperate with newer clients and servers. | _NA_ | |\n| [B.4. Cipher Suites](https://tools.ietf.org/html/rfc8446#section-B.4) | | _C_ | _23_ |\n| | TLS_AES_128_GCM_SHA256 | _C_ | _22_ |\n| | TLS_AES_256_GCM_SHA384 | _C_ | _22_ |\n| | TLS_CHACHA20_POLY1305_SHA256 | _C_ | _22_ |\n| | TLS_AES_128_CCM_SHA256 | _C_ | _22_ |\n| | TLS_AES_128_CCM_8_SHA256 | _C_ | _23_ |\n| [C.1. Random Number Generation and Seeding](https://tools.ietf.org/html/rfc8446#section-C.1) | | _C_ | _22_ |\n| [C.2. Certificates and Authentication](https://tools.ietf.org/html/rfc8446#section-C.2) | | _C_ | _22_ |\n| [C.3. Implementation Pitfalls](https://tools.ietf.org/html/rfc8446#section-C.3) | | _PC_ | _22_ |\n| [C.4. Client Tracking Prevention](https://tools.ietf.org/html/rfc8446#section-C.4) | | _C_ | _22\\.2_ |\n| [C.5. Unauthenticated Operation](https://tools.ietf.org/html/rfc8446#section-C.5) | | _C_ | _22_ |\n| [D.1. Negotiating with an Older Server](https://tools.ietf.org/html/rfc8446#section-D.1) | | _C_ | _22\\.2_ |\n| [D.2. Negotiating with an Older Client](https://tools.ietf.org/html/rfc8446#section-D.2) | | _C_ | _22_ |\n| [D.3. 0-RTT Backward Compatibility](https://tools.ietf.org/html/rfc8446#section-D.3) | | _NC_ | |\n| [D.4. Middlebox Compatibility Mode](https://tools.ietf.org/html/rfc8446#section-D.4) | | _C_ | _23_ |\n| [D.5. Security Restrictions Related to Backward Compatibility](https://tools.ietf.org/html/rfc8446#section-D.5) | | _C_ | _22_ |\n\n_Table: Standards Compliance_","title":"TLS 1.3 - Standards Compliance","ref":"standards_compliance.html#tls-1-3"}],"content_type":"text/plain","producer":{"name":"ex_doc","version":[48,46,51,52,46,49]}} \ No newline at end of file diff --git a/prs/8803/lib/ssl-11.2.1/doc/html/dist/search_data-731AC49D.js b/prs/8803/lib/ssl-11.2.1/doc/html/dist/search_data-731AC49D.js new file mode 100644 index 0000000000000..a659c8c2a5812 --- /dev/null +++ b/prs/8803/lib/ssl-11.2.1/doc/html/dist/search_data-731AC49D.js @@ -0,0 +1 @@ +searchData={"items":[{"type":"module","doc":"Interface functions for TLS (Transport Layer Security)\nand DTLS (Datagram Transport Layer Security).\n\n> #### Note {: .info }\nThe application's name is still SSL because the first versions of the\nTLS protocol were named SSL (Secure Socket Layer). However, no version\nof the old SSL protocol is supported by this application.\n\nExample:\n```erlang\n1> ssl:start(), ssl:connect(\"google.com\", 443, [{verify, verify_peer},\n {cacerts, public_key:cacerts_get()}]).\n{ok,{sslsocket, [...]}}\n```\n\nSee [Examples](using_ssl.md) for detailed usage and more examples of\nthis API.\n\nSpecial Erlang node configuration for the application can be found in\n[SSL Application](ssl_app.md).","title":"ssl","ref":"ssl.html"},{"type":"function","doc":"Make `Deferred` suites become the least preferred suites.\n\nThe `Deferred` suites will be put at the end of the cipher suite list\n`Suites` after removing them from `Suites` if present. `Deferred` can\nbe a list of cipher suites or a list of filters in which case the\nfilters are used on `Suites` to extract the deferred cipher list.","title":"ssl.append_cipher_suites/2","ref":"ssl.html#append_cipher_suites/2"},{"type":"function","doc":"Lists all available cipher suites corresponding to `Description`.\n\nThe `exclusive` and `exclusive_anonymous` option will exclusively\nlist cipher suites first supported in `Version`, whereas the other options are\ninclusive from the lowest possible version to `Version`. The `all` option\nincludes all suites except anonymous suites. No anonymous suites are supported\nby default.\n\n> #### Note {: .info }\n>\n> TLS-1.3 has no overlapping cipher suites with previous TLS versions, meaning that\n> the result of [`cipher_suites(all, 'tlsv1.3')`](`cipher_suites/2`) contains a separate\n> set of suites that can be used with TLS-1.3 and another set that can be used if a lower\n> version is negotiated. The so-called `PSK` and `SRP` suites (prior to TLS-1.3)\n> need extra configuration to work; namely the option `user_lookup_function`. No\n> anonymous suites are supported by TLS-1.3.\n>\n> Also note that the cipher suites returned by this function are the cipher\n> suites that the OTP SSL application can support provided that they are\n> supported by the crypto library linked with the OTP Crypto application. Use\n> [`ssl:filter_cipher_suites(Suites, [])`](`filter_cipher_suites/2`) to filter\n> the list for the current crypto library. Note that cipher suites may be filtered\n> out because they are too old or too new depending on the crypto library.","title":"ssl.cipher_suites/2","ref":"ssl.html#cipher_suites/2"},{"type":"function","doc":"Equivalent to `cipher_suites/2`, but lists RFC or OpenSSL string names instead of\n[`erl_cipher_suite()`](`t:erl_cipher_suite/0`).","title":"ssl.cipher_suites/3","ref":"ssl.html#cipher_suites/3"},{"type":"function","doc":"Clears the PEM cache.\n\nPEM files, used by SSL API-functions, are cached for performance\nreasons. The cache is automatically checked at regular intervals to\ndetermine whether any cache entries should be invalidated.\n\nThis function provides a way to unconditionally clear the entire cache, thereby\nforcing a reload of previously cached PEM files.","title":"ssl.clear_pem_cache/0","ref":"ssl.html#clear_pem_cache/0"},{"type":"function","doc":"Closes a TLS/DTLS connection.","title":"ssl.close/1","ref":"ssl.html#close/1"},{"type":"function","doc":"Closes or downgrades a TLS connection.\n\nIn the latter case the transport connection will be handed over to the\n`NewController` process after receiving the TLS close alert from the\npeer. The returned transport socket will have the following options\nset: `[{active, false}, {packet, 0}, {mode, binary}]`.\n\nIn case of downgrade, the close function might return some binary data that\nshould be treated by the user as the first bytes received on the downgraded\nconnection.","title":"ssl.close/2","ref":"ssl.html#close/2"},{"type":"function","doc":"","title":"ssl.connect/2","ref":"ssl.html#connect/2"},{"type":"function","doc":"Opens a TLS/DTLS connection.\n\n```erlang\nconnect(TCPSocket, TLSOptions, Timeout).\n```\n\nUpgrades a `gen_tcp` (or equivalent) connected socket to a TLS socket by\nperforming the client-side TLS handshake.\n\n\n```erlang\nconnect(Host, Port, TLSOptions).\n```\n\nOpens a TLS/DTLS connection to `Host`, `Port`. This call is equivalent to:\n\n```erlang\nconnect(Host, Port, TLSOptions, infinity).\n```","title":"ssl.connect/3","ref":"ssl.html#connect/3"},{"type":"function","doc":"Opens a TLS/DTLS connection to `Host`, `Port`.\n\nWhen the `verify` option is set to `verify_peer`, the\n`public_key:pkix_verify_hostname/2` check will be performed in addition to the usual\nX.509-path validation checks. If the check fails, the error `{bad_cert,\nhostname_check_failed}` will be propagated to the path validation fun,\nwhere it is possible to do customized checks\nby using the full possibilities of the `public_key:pkix_verify_hostname/3` API.\nWhen the `server_name_indication` option is provided, its value (the DNS name)\nwill be used as `ReferenceID` to `public_key:pkix_verify_hostname/2`. When no\n`server_name_indication` option is given, the `Host` argument will be used as\nServer Name Indication extension. The `Host` argument will also be used for the\n`public_key:pkix_verify_hostname/2` check. If the `Host` argument is an\n[`inet:ip_address()`](`t:inet:ip_address/0`) the `ReferenceID` used for the\ncheck will be `{ip, Host}`; otherwise `dns_id` will be assumed with a fallback to\n`ip` if that fails.\n\n> #### Note {: .info }\n>\n> According to good practices, certificates should not use IP addresses as\n> \"server names\", especially outside a closed network.\n\nIf the `{handshake, hello}` option is used, the handshake is paused after\nreceiving the server hello message and the success response is\n`{ok, SslSocket, Ext}` instead of `{ok, SslSocket}`. Thereafter the handshake is\ncontinued or canceled by calling `handshake_continue/3` or `handshake_cancel/1`.\n\nIf the `active` option is set to `once`, `true`, or an integer value, the process\nowning the SSL socket will receive messages of type\n[`active_msgs()`](`t:active_msgs/0`).","title":"ssl.connect/4","ref":"ssl.html#connect/4"},{"type":"function","doc":"Returns the most relevant information about the connection.\n\nSome items that are undefined will be filtered out. No values\nthat affect the security of the connection will be returned.\n\n> #### Note {: .info }\n>\n> The legacy `cipher_suite` item was removed in OTP 23. Previously it returned\n> the cipher suite in its (undocumented) legacy format. It is replaced by\n> `selected_cipher_suite`.","title":"ssl.connection_information/1","ref":"ssl.html#connection_information/1"},{"type":"function","doc":"Returns the requested information items about the connection if they are\ndefined.\n\nNote that the values for `client_random`, `server_random`, `master_secret`, and `keylog`\naffect the security of connection.\n\nIn order to retrieve `keylog` and other secret information from a TLS 1.3\nconnection, the `keep_secrets` option must be configured in advance and\nset to `true`.\n\n> #### Note {: .info }\n>\n> If only undefined options are requested the resulting list can be empty.","title":"ssl.connection_information/2","ref":"ssl.html#connection_information/2"},{"type":"function","doc":"Assigns a new controlling process to the SSL socket.\n\nA controlling process is the owner of an SSL socket and receives all\nmessages from the socket.","title":"ssl.controlling_process/2","ref":"ssl.html#controlling_process/2"},{"type":"function","doc":"Returns a list of all supported elliptic curves, including legacy\ncurves, for all TLS/DTLS versions prior to TLS-1.3.","title":"ssl.eccs/0","ref":"ssl.html#eccs/0"},{"type":"function","doc":"Returns the elliptic curves supported by default for `Version`.\n\nThis is a subset of what `eccs/0` returns.","title":"ssl.eccs/1","ref":"ssl.html#eccs/1"},{"type":"function","doc":"","title":"ssl.export_key_materials/4","ref":"ssl.html#export_key_materials/4"},{"type":"function","doc":"Uses a Pseudo-Random Function (PRF prior to TLS-1.3) or a Key\nDerivation Function (HKDF in TLS-1.3) for a TLS connection to\ngenerate and export keying materials.\n\nIn TLS-1.3, using `no_context` is equivalent to specifying an empty\ncontext (an empty binary). Prior to TLS-1.3, `no_context` and an empty\ncontext will produce different results.\n\nThe `ConsumeSecret` argument is relevant only in TLS-1.3, causing the\nTLS-1.3 `exporter_master_secret` to be consumed, thereby making it\nunavailable and increasing security. Further attempts to call this\nfunction will fail.","title":"ssl.export_key_materials/5","ref":"ssl.html#export_key_materials/5"},{"type":"function","doc":"Removes cipher suites if any of the filter functions returns `false` for any part\nof the cipher suite.\n\nIf no filter function is supplied for some part, the default behavior\ntreats it as a filter function that returns `true`. For\nexamples, see [Customizing cipher suites\n](using_ssl.md#customizing-cipher-suites). Additionally, this function\nalso filters the cipher suites to exclude cipher suites not supported\nby the crypto library used by the OTP Crypto application, meaning that\n[`ssl:filter_cipher_suites(Suites, [])`](`filter_cipher_suites/2`)\nis equivalent to applying only the filters for crypto library support.","title":"ssl.filter_cipher_suites/2","ref":"ssl.html#filter_cipher_suites/2"},{"type":"function","doc":"Presents the error returned by an SSL function as a printable string.","title":"ssl.format_error/1","ref":"ssl.html#format_error/1"},{"type":"function","doc":"Gets the values of the specified socket options.","title":"ssl.getopts/2","ref":"ssl.html#getopts/2"},{"type":"function","doc":"Get statistics for the underlying socket.","title":"ssl.getstat/1","ref":"ssl.html#getstat/1"},{"type":"function","doc":"Get one or more statistic values for the underlying socket.\n\nSee `inet:getstat/2` for further details.","title":"ssl.getstat/2","ref":"ssl.html#getstat/2"},{"type":"function","doc":"Returns all supported groups in TLS 1.3.\n\nExisted since OTP 22.0; documented as of OTP 27.","title":"ssl.groups/0","ref":"ssl.html#groups/0"},{"type":"function","doc":"Returns default supported groups in TLS 1.3.\n\nExisted since OTP 22.0; documented as of OTP 27.","title":"ssl.groups/1","ref":"ssl.html#groups/1"},{"type":"function","doc":"","title":"ssl.handshake/1","ref":"ssl.html#handshake/1"},{"type":"function","doc":"Performs the TLS/DTLS server-side handshake.\n\nIf the second argument is a timeout value:\n\n```erlang\nhandshake(HsSocket, Timeout).\n```\n\nthis call is equivalent to:\n\n```erlang\nhandshake(HsSocket, [], Timeout).\n```\n\nOtherwise, if the second argument is a list of options:\n\n\n```erlang\nhandshake(HsSocket, Options).\n```\nthis call is equivalent to:\n\n```erlang\nhandshake(HsSocket, Options, infinity).\n```","title":"ssl.handshake/2","ref":"ssl.html#handshake/2"},{"type":"function","doc":"Performs the TLS/DTLS server-side handshake.\n\nReturns a new TLS/DTLS socket if the handshake is successful.\n\nIf `Socket` is a ordinary [`socket()`](`t:socket/0`), upgrades a\n`gen_tcp` or equivalent socket to an SSL socket by performing the\nTLS server-side handshake and returning a TLS socket.\n\n> #### Note {: .info }\nThe ordinary `Socket` must be in passive mode (`{active, false}`)\nbefore calling this function and before the client tries to connect\nwith TLS; otherwise, the behavior of this function is undefined. The\nbest way to ensure this is to create the ordinary listen socket in\npassive mode.\n\nIf `Socket` is an [`sslsocket()`](`t:sslsocket/0`), provides extra\nTLS/DTLS options to those specified in `listen/2` and then performs\nthe TLS/DTLS handshake. Returns a new TLS/DTLS socket if the handshake\nis successful.\n\n> #### Warning {: .warning }\nNot setting the timeout makes the server more vulnerable to Denial of\nService (DoS) attacks.\n\nIf option `{handshake, hello}` is specified the handshake is paused after\nreceiving the client hello message and the success response is\n`{ok, SslSocket, Ext}` instead of `{ok, SslSocket}`. Thereafter the handshake is\ncontinued or canceled by calling `handshake_continue/3` or `handshake_cancel/1`.\n\nIf option `active` is set to `once`, `true`, or an integer value, the process\nowning the [`sslsocket()`](`t:sslsocket/0`) will receive messages of type\n[`active_msgs()`](`t:active_msgs/0`).","title":"ssl.handshake/3","ref":"ssl.html#handshake/3"},{"type":"function","doc":"Cancel the handshake with a fatal `USER_CANCELED` alert.","title":"ssl.handshake_cancel/1","ref":"ssl.html#handshake_cancel/1"},{"type":"function","doc":"","title":"ssl.handshake_continue/2","ref":"ssl.html#handshake_continue/2"},{"type":"function","doc":"Continue the TLS handshake, possibly with new, additional, or changed options.","title":"ssl.handshake_continue/3","ref":"ssl.html#handshake_continue/3"},{"type":"function","doc":"Creates an SSL listen socket.","title":"ssl.listen/2","ref":"ssl.html#listen/2"},{"type":"function","doc":"Returns the protocol negotiated through ALPN or NPN extensions.","title":"ssl.negotiated_protocol/1","ref":"ssl.html#negotiated_protocol/1"},{"type":"function","doc":"The peer certificate is returned as a DER-encoded binary.\n\nThe certificate can be\ndecoded with `public_key:pkix_decode_cert/2`. Suggested further reading about\ncertificates is [Public_Key User's Guide](`e:public_key:public_key_records.md`)\nand [SSL User's Guide](standards_compliance.md).","title":"ssl.peercert/1","ref":"ssl.html#peercert/1"},{"type":"function","doc":"Returns the address and port number of the peer.","title":"ssl.peername/1","ref":"ssl.html#peername/1"},{"type":"function","doc":"Make `Preferred` suites become the most preferred suites.\n\nThe `Preferred` suites will be put at the head of the cipher suite\nlist `Suites` after removing them from `Suites` if\npresent. `Preferred` can be a list of cipher suites or a list of\nfilters in which case the filters are used on `Suites` to extract the\npreferred cipher list.","title":"ssl.prepend_cipher_suites/2","ref":"ssl.html#prepend_cipher_suites/2"},{"type":"function","doc":"Uses the Pseudo-Random Function (PRF) of a TLS session to generate extra key\nmaterial.\n\nIt either takes user-generated values for `Secret` and `Seed` or atoms\ndirecting it to use a specific value from the session security parameters.\n\n> #### Note {: .info }\n\nThis function is replaced by `export_key_materials/4`, the officially\ndocumented API function since OTP 27, which is equivalent to\n[`prf(TLSSocket, master_secret, Label, [client_random, server_random,\nContext], WantedLength)`](`prf/5`). Other ways of calling this\nfunction were for testing purposes only and has no use case. When\ncalled in a TLS-1.3 context it will now behave as\n[`export_key_materials(TLSSocket, [Label], [Context],\n[WantedLength])`](`export_key_materials/4`).","title":"ssl.prf/5","ref":"ssl.html#prf/5"},{"type":"function","doc":"","title":"ssl.recv/2","ref":"ssl.html#recv/2"},{"type":"function","doc":"Receives a packet from a socket in passive mode.\n\nA closed socket is indicated by return value `{error, closed}`.\nArgument `Length` is meaningful only when the socket is in mode `raw`\nand denotes the number of bytes to read. If `Length` is zero, all\navailable bytes are returned. If `Length` is greater than zero,\nexactly `Length` bytes are returned, or an error; possibly discarding\nless than `Length` bytes of data when the socket gets closed from\nthe other side.\n\nOptional argument `Timeout` specifies a time-out in milliseconds. The default\nvalue is `infinity`.","title":"ssl.recv/3","ref":"ssl.html#recv/3"},{"type":"function","doc":"Initiates a new handshake.\n\nA notable return value is `{error, renegotiation_rejected}` indicating\nthat the peer refused to go through with the renegotiation, but the\nconnection is still active using the previously negotiated session.\n\nTLS-1.3 has removed the renegotiation feature from earlier TLS\nversions and instead adds a new feature called key update, which\nreplaces the most important part of renegotiation: the refreshing of\nsession keys. This is triggered automatically after reaching a\nplaintext limit and can be configured using the `key_update_at` option\nin `t:common_option_tls13/0`.","title":"ssl.renegotiate/1","ref":"ssl.html#renegotiate/1"},{"type":"function","doc":"Writes `Data` to `SslSocket`.\n\nA notable return value is `{error, closed}` indicating that the socket is\nclosed.","title":"ssl.send/2","ref":"ssl.html#send/2"},{"type":"function","doc":"Sets options according to `Options` for socket `SslSocket`.","title":"ssl.setopts/2","ref":"ssl.html#setopts/2"},{"type":"function","doc":"Immediately closes a socket in one or two directions.\n\n`How == write` means closing the socket for writing, but reading from\nit is still possible.\n\nTo handle siutations where the peer has performed a shutdown on the\nwrite side, option `{exit_on_close, false}` is useful.","title":"ssl.shutdown/2","ref":"ssl.html#shutdown/2"},{"type":"function","doc":"Lists all available signature algorithms corresponding to `Description`.\n\nThe `exclusive` option will exclusively list algorithms or algorithm schemes for\nthat protocol version, whereas the `default` and `all` options lists the\ncombined list to support the range of protocols from (D)TLS-1.2, the first\nversion to support configuration of the signature algorithms, to `Version`.\n\nExample:\n\n```erlang\n1> ssl:signature_algs(default, 'tlsv1.3').\n[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,\necdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,\nrsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,\nrsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,\nrsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256,\n{sha512,ecdsa},\n{sha384,ecdsa},\n{sha256,ecdsa}]\n\n2> ssl:signature_algs(all, 'tlsv1.3').\n[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,\necdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,\nrsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,\nrsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,\nrsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256,\n{sha512,ecdsa},\n{sha384,ecdsa},\n{sha256,ecdsa},\n{sha224,ecdsa},\n{sha224,rsa},\n{sha,rsa},\n{sha,dsa}]\n\n3> ssl:signature_algs(exclusive, 'tlsv1.3').\n[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,\necdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,\nrsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,\nrsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256]\n```\n\n> #### Note {: .info }\n>\n> Some TLS-1-3 scheme names overlap with TLS-1.2 algorithm-tuple-pair-names and\n> then TLS-1.3 names will be used, for example `rsa_pkcs1_sha256` instead of\n> `{sha256, rsa}`. These are legacy algorithms in TLS-1.3 that apply only to\n> certificate signatures in this version of the protocol.","title":"ssl.signature_algs/2","ref":"ssl.html#signature_algs/2"},{"type":"function","doc":"Returns the local address and port number of socket `SslSocket`.","title":"ssl.sockname/1","ref":"ssl.html#sockname/1"},{"type":"function","doc":"","title":"ssl.start/0","ref":"ssl.html#start/0"},{"type":"function","doc":"Starts the SSL application.","title":"ssl.start/1","ref":"ssl.html#start/1"},{"type":"function","doc":"Stops the SSL application.","title":"ssl.stop/0","ref":"ssl.html#stop/0"},{"type":"function","doc":"Converts an RFC or OpenSSL name string to an `t:erl_cipher_suite/0`\n\nReturns an error if the cipher suite is not supported or the name is\nnot a valid cipher suite name.","title":"ssl.str_to_suite/1","ref":"ssl.html#str_to_suite/1"},{"type":"function","doc":"Converts an [`erl_cipher_suite()`](`t:erl_cipher_suite/0`) value to\nan OpenSSL name string.\n\nPRE TLS-1.3 these names differ for RFC names","title":"ssl.suite_to_openssl_str/1","ref":"ssl.html#suite_to_openssl_str/1"},{"type":"function","doc":"Converts an [`erl_cipher_suite()`](`t:erl_cipher_suite/0`) value to an RFC\nname string.","title":"ssl.suite_to_str/1","ref":"ssl.html#suite_to_str/1"},{"type":"function","doc":"","title":"ssl.transport_accept/1","ref":"ssl.html#transport_accept/1"},{"type":"function","doc":"Accepts an incoming connection request on a listen socket.\n\n`ListenSocket` must be a socket returned from `listen/2`. The socket\nreturned is to be passed to [`handshake/1,2,3`](`handshake/3`) to\ncomplete the handshake and establish the TLS/DTLS connection.\n\n> #### Warning {: .warning }\n>\n> Most API functions require that the TLS/DTLS connection is established to work\n> as expected.\n\nThe accepted socket inherits the options set for `ListenSocket` in `listen/2`.\n\nThe default value for `Timeout` is `infinity`. If `Timeout` is specified and no\nconnection is accepted within the given time, `{error, timeout}` is returned.","title":"ssl.transport_accept/2","ref":"ssl.html#transport_accept/2"},{"type":"function","doc":"Create new session keys.\n\nThere are cryptographic limits on the amount of plaintext which can be safely\nencrypted under a given set of keys. If the amount of data surpasses those\nlimits, a key update is triggered and a new set of keys are installed. See also\nthe `key_update_at` option in `t:common_option_tls13/0`.\n\nThis function can be used to explicitly start a key update on a TLS-1.3\nconnection. There are two types of key updates: if `Type` is `write`,\nonly the writing key is updated; if `Type` is `read_write`, both the\nreading and writing keys are updated.","title":"ssl.update_keys/2","ref":"ssl.html#update_keys/2"},{"type":"function","doc":"Lists information, mainly concerning TLS/DTLS versions, in runtime for debugging\nand testing purposes.\n\n- **`app_vsn`** - The application version of the SSL application.\n\n- **`supported`** - TLS versions supported with current application environment\n and crypto library configuration. Overridden by a version option on\n [`connect/2,3,4`](`connect/2`), `listen/2`, and\n [`handshake/2,3`](`handshake/2`). For the negotiated TLS version, see\n [`connection_information/1`](`connection_information/1`).\n\n- **`supported_dtls`** - DTLS versions supported with current application\n environment and crypto library configuration. Overridden by a version option\n on [`connect/2,3,4`](`connect/2`), `listen/2`, and\n [`handshake/2,3`](`handshake/2`). For the negotiated DTLS version, see\n [`connection_information/1`](`connection_information/1`).\n\n- **`available`** - All TLS versions supported with the linked crypto library.\n\n- **`available_dtls`** - All DTLS versions supported with the linked crypto\n library.\n\n- **`implemented`** - All TLS versions supported by the SSL application if\n linked with a crypto library with the necessary support.\n\n- **`implemented_dtls`** - All DTLS versions supported by the SSL application if\n linked with a crypto library with the necessary support.","title":"ssl.versions/0","ref":"ssl.html#versions/0"},{"type":"type","doc":"The type for the messages that are delivered to the owner of a\nTLS/DTLS socket in active mode.\n\nThe `ssl_passive` message is sent only when the socket is in `{active, N}` mode\nand the counter has dropped to 0. It indicates that the socket has transitioned\nto passive (`{active, false}`) mode.","title":"ssl.active_msgs/0","ref":"ssl.html#t:active_msgs/0"},{"type":"type","doc":"Claim an intermediate CA in the chain as trusted.\n\n```erlang\nfun(Chain::[public_key:der_encoded()]) ->\n {trusted_ca, DerCert::public_key:der_encoded()} | unknown_ca.\n```\n\nTLS then uses `public_key:pkix_path_validation/3` with the selected CA\nas the trusted anchor and verifies the rest of the chain.","title":"ssl.anchor_fun/0","ref":"ssl.html#t:anchor_fun/0"},{"type":"type","doc":"Configuration of the entity certificate and its corresponding key.\n\nA certificate (or possibly a list including the certificate and its\nchain certificates, where the entity certificate must be the first\nelement in the list or the first entry in the file) and its associated\nkey. For the PEM file format, there can also be a password associated\nwith the file containing the key.\n\nFor maximum interoperability, the certificates in the chain should be\nin the correct order, as the chain will be sent as-is to the peer. If\nchain certificates are not provided, certificates from the configured\ntrusted CA certificates will be used to construct the chain. See\n[`client_option_cert()`](`t:client_option_cert/0`) and\n[`server_option_cert()`](`t:server_option_cert/0`) for more\ninformation.","title":"ssl.cert_key_conf/0","ref":"ssl.html#t:cert_key_conf/0"},{"type":"type","doc":"Cipher algorithms that can be used for payload encryption.","title":"ssl.cipher/0","ref":"ssl.html#t:cipher/0"},{"type":"type","doc":"Filter that allows you to customize cipher suite list.","title":"ssl.cipher_filters/0","ref":"ssl.html#t:cipher_filters/0"},{"type":"type","doc":"A list of cipher suites that should be supported.\n\nFunction [ssl:cipher_suites/2 ](`cipher_suites/2`) can be used to find all\ncipher suites that are supported by default and all cipher suites that can be\nconfigured.\n\nIf you compose your own `t:cipher_suites/0` make sure they are\nfiltered for crypto library support using [ssl:filter_cipher_suites/2\n](`filter_cipher_suites/2`).\n\nThe following function can help creating customized cipher suite lists:\n\n- [ssl:append_cipher_suites/2 ](`append_cipher_suites/2`)\n- [ssl:prepend_cipher_suites/2](`prepend_cipher_suites/2`)\n- [ssl:suite_to_str/1](`suite_to_str/1`)\n- [ssl:str_to_suite/1](`str_to_suite/1`)\n- [ssl:suite_to_openssl_str/1](`suite_to_openssl_str/1`)\n\n> #### Note {: .info }\nNote that TLS-1.3 and TLS-1.2 use different sets of cipher suites. To\nsupport both versions, cipher suites from both sets need to be\nincluded. If the supplied list does not comply with the configured\nversions or crypto library, that is, resulting in an empty list, the option\nwill fall back to its appropriate default value for the configured\nversions.\n\nNon-default cipher suites, including anonymous cipher suites (prior to\nTLS 1.3), are supported for interoperability and testing\npurposes. These can be used by adding them to your cipher suite\nlist. Note that they also need to be supported and enabled by the peer\nto be actually used, and they may require additional configuration;\nsee [`srp_param_type()`](`t:srp_param_type/0`).","title":"ssl.cipher_suites/0","ref":"ssl.html#t:cipher_suites/0"},{"type":"type","doc":"Cipher suite formats.\n\nFor backwards compatibility, cipher suites can be configured as a\ncolon-separated string of cipher suite RFC names (or even old OpenSSL\nnames). However, a more flexible approach is to use utility functions\ntogether with [`cipher_filters()`](`t:cipher_filters/0`) if a customized\ncipher suite option is needed.","title":"ssl.ciphers/0","ref":"ssl.html#t:ciphers/0"},{"type":"type","doc":"The following options are specific to the client side, or have\ndifferent semantics for the client and server:\n\n- **`{alpn_advertised_protocols, AppProtocols}`** - Application layer protocol\n\n The list of protocols supported by the client to be sent to the server to be\n used for an Application-Layer Protocol Negotiation (ALPN). If the server\n supports ALPN, it will choose a protocol from this list; otherwise it will\n fail the connection with a `no_application_protocol` alert. A server that does\n not support ALPN will ignore this value. The list of protocols must not contain\n an empty binary.\n\n- **`{max_fragment_length, MaxLen}`** - Max fragment length extension\n\n Specifies the maximum fragment length the client is prepared to accept from the\n server. See [RFC 6066](http://www.ietf.org/rfc/rfc6066.txt).","title":"ssl.client_option/0","ref":"ssl.html#t:client_option/0"},{"type":"type","doc":"Certificate-related options specific to the client side, or with\ndifferent semantics for the client and server.\n\n- **`{verify, Verify}`** - Verification of certificates\n\n This option specifies whether certificates are to be verified.\n\n If `Verify` is `verify_peer`, which is the default, it is required\n to also provide one of the options `cacerts` or `cacertfile` in\n order for the certificate verification to succeed. For example, an\n HTTPS client can use option `{cacerts, public_key:cacerts_get()}` to\n use the trusted CA certificates provided by the operating system.\n\n If `Verify` is `verify_none`, all X.509-certificate path\n validation errors will be ignored.\n\n > #### Change {: .info }\n >\n > The default for `Verify` was changed to `verify_peer` in\n > Erlang/OTP 26.\n\n- **`{cacerts, CACerts}`** - Trusted certificates\n\n The DER-encoded trusted certificates. If this option is supplied it overrides\n option `cacertfile`.\n\n Function `public_key:cacerts_get/0` can be used to retrieve to the\n trusted CA certificates provided by the operating system.\n\n- **`{cacertfile, CertFile}`** - End entity certificate\n\n Path to a file containing PEM-encoded CA certificates. The CA certificates are\n used during server authentication and when building the client certificate\n chain.\n\n > #### Note {: .info }\n >\n > When PEM caching is enabled, files provided with this option will be checked\n > for updates at fixed time intervals specified by the\n > [ssl_pem_cache_clean](ssl_app.md#configuration) environment parameter.\n\n\n- **`{server_name_indication, SNI}`** - Server Name Indication extension\n\n Specify the hostname to be used in TLS Server Name Indication extension. If not\n specified it will default to the `Host` argument of\n [connect/3,4](`connect/3`) unless it is of type [`inet:ip_address()`](`t:inet:ip_address/0`).\n The hostname will also be used in the hostname verification of the peer\n certificate using `public_key:pkix_verify_hostname/2`.\n The special value `disable` prevents the Server Name Indication extension from\n being sent and disables the hostname verification check.\n\n- **`{customize_hostname_check, HostNameCheckOpts}`** - Customization option\n\n Customizes the hostname verification of the peer certificate, as various\n protocols that use TLS, such as HTTP or LDAP, may require different approaches. For\n example, here is how to use standard hostname checking for HTTPS implemented in\n [Public_Key](`e:public_key:public_key_app.md`):\n\n ```erlang\n {customize_hostname_check, [{match_fun, public_key:pkix_verify_hostname_match_fun(https)}]}\n ```\n\n For futher description of the customize options, see\n `public_key:pkix_verify_hostname/3`.\n\n- **`{client_certificate_authorities, UseCertAuth}`** - Inter-op hint option\n\n If `UseCertAuth` is set to `true`, sends the certificate authorities\n extension in the TLS-1.3 client hello. The default is `false`. Note\n that setting `UseCertAuth` to `true` can result in a significant\n overhead if there exists many trusted CA certificates. (Since\n Erlang/OTP 24.3.)\n\n- **`{stapling, Stapling}`** - Certificate revocation check option\n\n If `Stapling` is atom `staple` or a map, OCSP stapling will be\n enabled, meaning that an extension of type \"status_request\" will be\n included in the client hello to indicate the desire to receive\n certificate status information.\n\n If `Stapling` is set to `no_staple` (the default), OCSP stapling will be disabled.\n\n > #### Note {: .info }\n >\n > Even if requested by the client, the OCSP response might not be\n > provided by the server. In such event, SSL will proceed with\n > the handshake and generate a `{missing, stapling_response}` logger\n > event.\n\n When `Stapling` is given as a map, boolean `ocsp_nonce` key can\n indicate whether an OCSP nonce should be requested by the client\n (default is `false`).\n\n > #### Note {: .info }\n >\n > The OCSP response can be provided without a nonce value — even if it was requested\n > by the client. In such cases SSL will proceed with the handshake and generate\n > a `{missing, ocsp_nonce}` logger event.","title":"ssl.client_option_cert/0","ref":"ssl.html#t:client_option_cert/0"},{"type":"type","doc":"Legacy client options.\n\n- **`{client_preferred_next_protocols, NextAppProtocols}`** - Next Protocol Negotiation\n\n ALPN (Application-Layer Protocol Negotiation)\n deprecates NPN (Next Protocol Negotiation) and this option.\n\n Indicates that the client wants to perform Next Protocol Negotiation.\n\n If `Precedence` is `server`, the negotiated protocol is the first protocol to be\n shown on the server advertised list that is also on the client preference\n list.\n\n If `Precedence` is `client`, the negotiated protocol is the first protocol to be\n shown on the client preference list that is also on the server advertised\n list.\n\n If the client does not support any of the server advertised protocols or the\n server does not advertise any protocols, the client falls back to the first\n protocol in its list or to the default protocol (if a default is supplied). If\n the server does not support Next Protocol Negotiation, the connection terminates\n if no default protocol is supplied.","title":"ssl.client_option_legacy/0","ref":"ssl.html#t:client_option_legacy/0"},{"type":"type","doc":"Options only relevant to TLS versions prior to TLS-1.3.\n\n- **`{reuse_session, SessionRef}`** - Explicit session reuse\n\n Reuses a specific session.\n\n Since Erlang/OTP 21.3, if the session was saved earlier using option\n `{reuse_sessions, save}`, the session can be referred by its session ID.\n\n Since Erlang/OTP 22.3, the session can be explicitly specified by\n its session ID and associated data.\n\n See also\n [SSL User's Guide, Session Reuse pre TLS 1.3.](using_ssl.md#session-reuse-prior-to-tls-1-3)\n\n- **`{reuse_sessions, Reuse}`** - Enables later session reuse\n\n When `Reuse` is set to `save`, a new connection will be negotiated and saved for later\n reuse. The session ID can be fetched with `connection_information/2` and used\n with the client option `reuse_session`.\n\n When `Reuse` is set to `true`, automated session reuse will be\n performed, if possible. If a new session is created, and is unique in regard to previous\n stored sessions, it will be saved for possible later reuse.\n\n Since: OTP 21.3.\n\n- **`{psk_identity, PskID}`** - Option for use with PSK cipher suites\n\n Specifies the identity the client presents to the server. The matching secret is\n found by the fun given in the `user_lookup_fun` option.\n\n- **`{srp_identity, SrpID}`** - Option for use SRP cipher suites\n\n Specifies the username and password to use to authenticate to the server.\n\n- **`{fallback, LegacyFallback}`** - Inter-op legacy client option\n\n Send special cipher suite TLS_FALLBACK_SCSV to avoid an undesired TLS version\n downgrade. Defaults to `false`.\n\n > #### Warning {: .warning }\n >\n > This option is not needed in normal TLS usage and must not be used to\n > implement new clients. However, legacy clients that retries connections in the\n > following manner:\n >\n > `ssl:connect(Host, Port, [...{versions, ['tlsv2', 'tlsv1.1', 'tlsv1']}])`\n >\n > `ssl:connect(Host, Port, [...{versions, [tlsv1.1', 'tlsv1']}, {fallback, true}])`\n >\n > `ssl:connect(Host, Port, [...{versions, ['tlsv1']}, {fallback, true}])`\n >\n > can use it to avoid undesired TLS version downgrade. Note that\n > TLS_FALLBACK_SCSV must also be supported by the server for the prevention to\n > work.","title":"ssl.client_option_pre_tls13/0","ref":"ssl.html#t:client_option_pre_tls13/0"},{"type":"type","doc":"Options only relevant for TLS-1.3.\n\n- **`{session_tickets, SessionTickets}`** - Use of session tickets\n\n Configures the session ticket functionality. Allowed values are `disabled`,\n `manual`, and `auto`. If it is set to `manual` the client will send the ticket\n information to user process in a 3-tuple:\n\n ```erlang\n {ssl, session_ticket, {SNI, TicketData}}\n ```\n\n where `SNI` is the ServerNameIndication and `TicketData` is the extended ticket\n data that can be used in subsequent session resumptions.\n\n If it is set to `auto`, the client automatically handles received tickets and\n tries to use them when making new TLS connections (session resumption with\n pre-shared keys).\n\n Ticket lifetime, the number of tickets sent by the server, and the\n maximum number of tickets stored by the server in stateful mode are configured\n by [application variables](ssl_app.md#configuration).\n\n See also\n [SSL User's Guide, Session Tickets and Session Resumption in TLS 1.3](using_ssl.md#session-tickets-and-session-resumption-in-tls-1-3).\n\n- **`{use_ticket, Tickets}`**\n\n Configures the session tickets to be used for session resumption. It is a\n mandatory option in `manual` mode (`{session_tickets, manual}`).\n\n > #### Note {: .info }\n >\n > Session tickets are only sent to the user if option `session_tickets` is set to\n > `manual`\n >\n > This option is supported by TLS-1.3. See also\n > [SSL User's Guide, Session Tickets and Session Resumption in TLS 1.3](using_ssl.md#session-tickets-and-session-resumption-in-tls-1-3).\n\n- **`{early_data, EarlyData}`**\n\n Configures the early data to be sent by the client.\n\n To verify that the server has the intention to process the early\n data, the following tuple is sent to the user process:\n\n ```erlang\n {ssl, SslSocket, {early_data, Result}}\n ```\n\n where `Result` is either `accepted` or `rejected`.\n\n > #### Warning {: .warning }\n >\n > It is the responsibility of the user to handle rejected `EarlyData` and to\n > resend when appropriate.\n\n- **`{middlebox_comp_mode, MiddleBoxMode}`**\n\n Configures the middlebox compatibility mode for a TLS-1.3 connection.\n\n A significant number of middleboxes misbehave when a TLS-1.3\n connection is negotiated. Implementations can increase the chance of\n making connections through those middleboxes by adapting the TLS-1.3\n handshake to resemble that of a TLS-1.2 handshake.\n\n The middlebox compatibility mode is enabled (`true`) by default.","title":"ssl.client_option_tls13/0","ref":"ssl.html#t:client_option_tls13/0"},{"type":"type","doc":"Options common to both client and server side.\n\n- **`{protocol, Protocol}`** - Choose TLS or DTLS protocol for the transport layer security.\n\n Defaults to `tls`.\n\n- **`{handshake, Completion}`** - Possibly pause handshake at hello stage.\n\n Defaults to `full`. If `hello` is specified the handshake will pause\n after the hello message, allowing the user to make decisions based\n on hello extensions before continuing or aborting the handshake by\n calling `handshake_continue/3` or `handshake_cancel/1`.\n\n- **`{keep_secrets, KeepSecrets}`** - Configures a TLS 1.3 connection for keylogging.\n\n In order to retrieve keylog information on a TLS 1.3 connection, it must be\n configured in advance to keep `client_random` and various handshake secrets.\n\n The `keep_secrets` functionality is disabled (`false`) by default.\n\n Added in OTP 23.2.\n\n- **`{max_handshake_size, HandshakeSize}`** - Limit the acceptable handshake packet size.\n\n Used to limit the size of valid TLS handshake packets to avoid DoS\n attacks.\n\n Integer (24 bits, unsigned). Defaults to `256*1024`.\n\n- **`{hibernate_after, HibernateTimeout}`** - Hibernate inactive connection processes.\n\n When an integer-value is specified, the TLS/DTLS connection goes into hibernation\n after the specified number of milliseconds of inactivity, thus reducing its\n memory footprint. When not specified the process never goes into hibernation.\n\n- **`{log_level, Level}`** - Specifies the log level for a TLS/DTLS connection.\n\n Alerts are logged on `notice`\n level, which is the default level. The level `debug` triggers verbose logging of\n TLS/DTLS protocol messages. See also [SSL Application](ssl_app.md)\n\n- **`{receiver|sender_spawn_opts, SpawnOpts}`** - Configure erlang spawn opts.\n\n Configures spawn options of TLS sender and receiver processes.\n\n Setting up garbage collection options can be helpful for trade-offs between CPU\n usage and memory usage. See `erlang:spawn_opt/2`.\n\n For connections using Erlang distribution, the default sender option\n is `[...{priority, max}]`; this priority option cannot be changed. For all\n connections, `...link` is added to receiver and cannot be changed.","title":"ssl.common_option/0","ref":"ssl.html#t:common_option/0"},{"type":"type","doc":"Common certificate related options to both client and server.\n\n- **`{certs_keys, CertsKeys}`** - At least one certificate and key pair.\n\n A list of a certificate (or possible a certificate and its chain)\n and the associated key of the certificate that can be used to\n authenticate the client or the server. The certificate key pair that\n is considered best and matches negotiated parameters for the\n connection will be selected.\n\n The different signature algorithms are prioritized in the following\n order: `eddsa`, `ecdsa`, `rsa_pss_pss`, `rsa`, and `dsa`. If more\n than one key is supplied for the same signature algorithm, they will\n be prioritized by strength (except for _engine keys_; see the next\n paragraph). This offers flexibility to, for instance, configure a\n newer certificate that is expected to be used in most cases, and an\n older but acceptable certificate that will only be used to\n communicate with legacy systems. Note that there is a trade off\n between the induced overhead and the flexibility; thus, alternatives\n should be chosen for good reasons.\n\n _Engine keys_ will be favored over other keys. As engine keys cannot\n be inspected, supplying more than one engine key makes no sense.\n\n When this option is specified it overrides all single certificate\n and key options. For examples, see the [User's Guide](using_ssl.md).\n\n > #### Note {: .info }\n >\n > `eddsa` certificates are only supported by TLS-1.3 implementations that do not support `dsa`\n > certificates. `rsa_pss_pss` (RSA certificates using Probabilistic Signature\n > Scheme) are supported in TLS-1.2 and TLS-1.3, but some TLS-1.2 implementations\n > do not support `rsa_pss_pss`.\n\n- **`{depth, AllowedCertChainLen}`** - Limits the accepted number of certificates in the certificate chain.\n\n Maximum number of non-self-issued intermediate certificates that can follow the\n peer certificate in a valid certification path. So, if depth is 0 the PEER must\n be signed by the trusted ROOT-CA directly; if 1 the path can be PEER, CA,\n ROOT-CA; if 2 the path can be PEER, CA, CA, ROOT-CA, and so on. The default\n value is 10. Used to mitigate DoS attack possibilities.\n\n- **`{verify_fun, Verify}`** - Customize certificate path validation\n\n The verification fun is to be defined as follows:\n\n ```erlang\n fun(OtpCert :: #'OTPCertificate'{},\n Event, InitialUserState :: term()) ->\n\t{valid, UserState :: term()} |\n\t{fail, Reason :: term()} | {unknown, UserState :: term()}.\n\n fun(OtpCert :: #'OTPCertificate'{}, DerCert :: public_key:der_encoded(),\n Event, InitialUserState :: term()) ->\n\t{valid, UserState :: term()} |\n\t{fail, Reason :: term()} | {unknown, UserState :: term()}.\n\n Types:\n Event = {bad_cert, Reason :: atom() |\n {revoked, atom()}} |\n\t\t{extension, #'Extension'{}} |\n valid |\n valid_peer\n ```\n\n The verification fun is called during the X.509-path validation when\n an error occurs or an extension unknown to the SSL application is\n encountered. It is also called when a certificate is considered\n valid by the path validation to allow access to each certificate in\n the path to the user application. It differentiates between the peer\n certificate and the CA certificates by using `valid_peer` or `valid`\n as `Event` argument to the verification fun. See the [Public_Key\n User's Guide](`e:public_key:public_key_records.md`) for definition\n of `#'OTPCertificate'{}` and `#'Extension'{}`.\n\n - If the verify callback fun returns `{fail, Reason}`, the verification process\n is immediately stopped, an alert is sent to the peer, and the TLS/DTLS\n handshake terminates.\n - If the verify callback fun returns `{valid, UserState}`, the verification\n process continues.\n - If the verify callback fun always returns `{valid, UserState}`, the TLS/DTLS\n handshake does not terminate regardless of verification failures, and the\n connection is established.\n - If called with an extension unknown to the user application, the fun is to\n return `{unknown, UserState}`.\n\n Note that if the fun returns `unknown` for an extension marked as critical,\n validation will fail.\n\n Default option `verify_fun` in `verify_peer mode`:\n\n ```erlang\n {fun(_, _, {bad_cert, _} = Reason, _) ->\n\t {fail, Reason};\n (_, _, {extension, _}, UserState) ->\n\t {unknown, UserState};\n (_, _, valid, UserState) ->\n\t {valid, UserState};\n (_, _, valid_peer, UserState) ->\n {valid, UserState}\n end, []}\n ```\n\n Default option `verify_fun` in mode `verify_none`:\n\n ```erlang\n {fun(_, _, {bad_cert, _}, UserState) ->\n\t {valid, UserState};\n (_, _, {extension, #'Extension'{critical = true}}, UserState) ->\n\t {valid, UserState};\n (_, _, {extension, _}, UserState) ->\n\t {unknown, UserState};\n (_, _, valid, UserState) ->\n\t {valid, UserState};\n (_, _, valid_peer, UserState) ->\n {valid, UserState}\n end, []}\n ```\n\n The possible path validation errors are given in the form `{bad_cert, Reason}`,\n where `Reason` is:\n\n - **`unknown_ca`**\n\n No trusted CA was found in the trusted store. The trusted\n CA is normally a so-called ROOT CA, which is a self-signed certificate. Trust\n can be claimed for an intermediate CA (the trusted anchor does not have to be\n self-signed according to X-509) by using option `partial_chain`.\n\n - **`selfsigned_peer`**\n\n The chain consisted only of one self-signed certificate.\n\n - **`PKIX X-509-path validation error`**\n\n For possible reasons, see `public_key:pkix_path_validation/3`.\n\n- **`{cert_policy_opts, PolicyOpts}`** - Handle certificate policies.\n\n Configure X.509 certificate policy handling for the certificate path validation process;\n see [public_key:pkix_path_validation/3](`public_key:pkix_path_validation/3`) for\n more details.\n\n- **`{cerl_check, Check}`** - Handle certificate revocation lists.\n\n Perform CRL (Certificate Revocation List) verification\n [(public_key:pkix_crls_validate/3)](`public_key:pkix_crls_validate/3`) on all\n the certificates during the path validation\n [(public_key:pkix_path_validation/3) ](`public_key:pkix_path_validation/3`)of\n the certificate chain. `Check` defaults to `false`.\n\n The meaning of `Check` is as follows:\n\n - **`false`**\n\n No checks are performed.\n\n - **`peer`**\n\n Check is only performed on the peer certificate.\n\n - **`best_effort`**\n\n If certificate revocation status cannot be determined it will be accepted as valid.\n\n The CA certificates specified for the connection will be used to construct the\n certificate chain validating the CRLs.\n\n The CRLs will be fetched from a local or external cache. See\n `m:ssl_crl_cache_api`.","title":"ssl.common_option_cert/0","ref":"ssl.html#t:common_option_cert/0"},{"type":"type","doc":"Common options to client and server only valid for DTLS.\n\n- **`{use_srtp, UseSrtp}`** - Configures the `use_srtp` DTLS hello extension.\n\n In order to negotiate the use of SRTP data protection, clients include an\n extension of type \"use_srtp\" in the DTLS extended client hello. This extension\n MUST only be used when the data being transported is RTP or RTCP.\n\n The value is a map with a mandatory `protection_profiles` parameter\n and an optional `mki` parameter.\n\n `protection_profiles` configures the list of the client's acceptable SRTP\n Protection Profiles. Each profile is a 2-byte binary. Example:\n `#{protection_profiles => [<<0,2>>, <<0,5>>]}`\n\n `mki` configures the SRTP Master Key Identifier chosen by the client.\n\n The `srtp_mki` field contains the value of the SRTP MKI which is associated with\n the SRTP master keys derived from this handshake. Each SRTP session MUST have\n exactly one master key that is used to protect packets at any given time. The\n client MUST choose the MKI value so that it is distinct from the last MKI value\n that was used, and it SHOULD make these values unique for the duration of the\n TLS session.\n\n > #### Note {: .info }\n >\n > OTP does not handle SRTP, so an external implementations of SRTP\n > encoder/decoder and a packet demultiplexer are needed to make use of the\n > `use_srtp` extension. See also option [transport_option](`t:transport_option/0`).\n\n Servers that receive an extended hello containing a \"use_srtp\" extension can\n agree to use SRTP by including an extension of type \"use_srtp\", with the chosen\n protection profile in the extended server hello. This extension MUST only be\n used when the data being transported is RTP or RTCP.","title":"ssl.common_option_dtls/0","ref":"ssl.html#t:common_option_dtls/0"},{"type":"type","doc":"Legacy options considered deprecated in favor of other options,\ninsecure to use, or plainly not relevant anymore.\n\n- **`{cert, Certs}`**\n\n Use option `certs_keys` instead.\n\n- **`{certfile, CertPem}`**\n\n Use option `certs_keys` instead.\n\n- **`{keyfile, KeyPem}`**\n\n Use option `certs_keys` instead.\n\n- **`{password, KeyPemPasswd}`**\n\n Use option `certs_keys` instead.\n\n- **`{log_alert, LogAlert}`**\n\n If `LogAlert` is `false`, TLS/DTLS Alert reports are not displayed. Deprecated in OTP\n 22; use `{log_level, Level}` instead.\n\n- **`{padding_check, PaddingCheck}`** - Inter-op trade-off option\n\n Affects TLS-1.0 connections only. If set to `false`, it disables the block\n cipher padding check to be able to interoperate with legacy software.\n\n > #### Warning {: .warning }\n >\n > Using `{padding_check, false}` makes TLS vulnerable to the Poodle attack.\n\n- **`{beast_mitigation, BeastMitigation}`** - Inter-op trade-off option\n\n Affects TLS-1.0 connections only. Used to change the BEAST mitigation strategy\n to interoperate with legacy software. Defaults to `one_n_minus_one`.\n\n `one_n_minus_one` - Perform `1/n-1` BEAST mitigation.\n\n `zero_n` - Perform `0/n` BEAST mitigation.\n\n `disabled` - Disable BEAST mitigation.\n\n > #### Warning {: .warning }\n >\n > Using `{beast_mitigation, disabled}` makes TLS-1.0 vulnerable to the BEAST\n > attack.\n\n- **`{ssl_imp, Imp}`**\n\n Deprecated since OTP 17; has no effect.","title":"ssl.common_option_legacy/0","ref":"ssl.html#t:common_option_legacy/0"},{"type":"type","doc":"Options common to client and server side prior to TLS-1.3.\n\n- **`{eccs, NamedCurves}`** - Named Elliptic Curves\n\n Elliptic curves that can be used in pre TLS-1.3 key exchange.\n\n- **`{secure_renegotiate, SecureRenegotiate}`** - Inter-operate trade-off option\n\n Specifies whether to reject renegotiation attempt that does not live\n up to [RFC 5746](http://www.ietf.org/rfc/rfc5746.txt). By default,\n `SecureRenegotiate` is `true`, meaning that secure renegotiation is\n enforced. If `SecureRenegotiate` is `false` secure renegotiation\n will still be used if possible, but it falls back to insecure\n renegotiation if the peer does not support if [RFC\n 5746](http://www.ietf.org/rfc/rfc5746.txt).\n\n- **`{user_lookup_fun, {LookupFun, UserState}}`** - PSK/SRP cipher suite option\n\n The lookup fun is to be defined as follows:\n\n ```erlang\n fun(psk, PSKIdentity :: binary(), UserState :: term()) ->\n\t{ok, SharedSecret :: binary()} | error;\n fun(srp, Username :: binary(), UserState :: term()) ->\n\t{ok, {SRPParams :: srp_param_type(), Salt :: binary(),\n\t DerivedKey :: binary()}} | error.\n ```\n\n For Pre-Shared Key (PSK) cipher suites, the lookup fun is called by the client\n and server to determine the shared secret. When called by the client,\n `PSKIdentity` is the hint presented by the server or `undefined`. When\n called by the server, `PSKIdentity` is the identity presented by the client.\n\n For Secure Remote Password (SRP), the fun is only used by the server to obtain\n parameters that it uses to generate its session keys. `DerivedKey` is to be\n derived according to [RFC 2945](http://tools.ietf.org/html/rfc2945#section/3)\n and [RFC 5054](http://tools.ietf.org/html/rfc5054#section-2.4):\n `crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])])`","title":"ssl.common_option_pre_tls13/0","ref":"ssl.html#t:common_option_pre_tls13/0"},{"type":"type","doc":"Common options to both client and server for TLS-1.3.\n\n- **`{supported_groups, Groups}`** - Key exchange option\n\n TLS 1.3 introduces the \"supported_groups\" extension, which is used for negotiating\n the Diffie-Hellman parameters in a TLS 1.3 handshake. Both client and server can\n specify a list of parameters that they are willing to use.\n\n If not specified it will use a default list (`[x25519, x448, secp256r1,\n secp384r1]`) that is filtered based on the installed crypto library version.\n\n- **`{key_update_at, KeyUpdateAt}`** - Session key renewal\n\n Configures the maximum amount of bytes that can be sent on a TLS 1.3 connection\n before an automatic key update is performed.\n\n There are cryptographic limits on the amount of plaintext which can be safely\n encrypted under a given set of keys. The current default ensures that data\n integrity will not be breached with probability greater than `1/2^57`. For more\n information see\n [Limits on Authenticated Encryption Use in TLS](https://eprint.iacr.org/2024/051.pdf).","title":"ssl.common_option_tls13/0","ref":"ssl.html#t:common_option_tls13/0"},{"type":"type","doc":"Key value list convening some information about the established connection.","title":"ssl.connection_info/0","ref":"ssl.html#t:connection_info/0"},{"type":"type","doc":"TLS connection keys for which information can be retrieved.","title":"ssl.connection_info_keys/0","ref":"ssl.html#t:connection_info_keys/0"},{"type":"type","doc":"TLS connection information relevant prior to TLS-1.3.","title":"ssl.connection_info_pre_tls13/0","ref":"ssl.html#t:connection_info_pre_tls13/0"},{"type":"type","doc":"Options for using built-in CRL cache support.\n\nSpecify how to perform lookup and caching of certificate revocation\nlists (CRLs). `Module` defaults to `m:ssl_crl_cache` with `DbHandle`\nbeing `internal`, and `Args` being `[]`.\n\nThere are two implementations available:\n\n- **`ssl_crl_cache`** - Implementation 1\n\n This module maintains a cache of CRLs. CRLs can be added to the\n cache using `ssl_crl_cache:insert/1`, and can optionally be\n automatically fetched through HTTP if the following argument is\n specified:\n\n - **`{http, timeout()}`**\n\n Enables fetching of CRLs specified as http URIs in [X.509 certificate\n extensions](`e:public_key:public_key_records.md`). Requires the\n [Inets](`e:inets:introduction.md`) application.\n\n- **`ssl_crl_hash_dir`** - Implementation 2\n\n This module makes use of a directory where CRLs are\n stored in files named by the hash of the issuer name.\n\n The file names consist of eight hexadecimal digits followed by `.rN`, where\n `N` is an integer, for example `1a2b3c4d.r0`. For the first version of the CRL, `N`\n starts at zero, and for each new version, `N` is incremented by one. The\n OpenSSL utility `c_rehash` creates symlinks according to this pattern.\n\n For a given hash value, this module finds all consecutive `.r*`\n files starting from zero, and those files taken together make up the\n revocation list. CRL files with `nextUpdate` fields in the past or\n issued by a different CA that happens to have the same name hash\n are excluded.\n\n The following argument is required:\n\n - **`{dir, string()}`**\n\n Specifies the directory in which the CRLs can be found.","title":"ssl.crl_cache_opts/0","ref":"ssl.html#t:crl_cache_opts/0"},{"type":"type","doc":"A DTLS protocol version that are no longer supported by default for security reasons.","title":"ssl.dtls_legacy_version/0","ref":"ssl.html#t:dtls_legacy_version/0"},{"type":"type","doc":"DTLS protocol version.","title":"ssl.dtls_version/0","ref":"ssl.html#t:dtls_version/0"},{"type":"type","doc":"Erlang cipher suite representation\n\n> #### Warning {: .warning }\nEnabling cipher suites using RSA as a key exchange algorithm is\nstrongly discouraged (only available prior to TLS-1.3). For some\nconfigurations software preventions may exist, and can make them\nusable if they work, but relying on them to work is risky. There\nexists more reliable cipher suites that can be used instead.","title":"ssl.erl_cipher_suite/0","ref":"ssl.html#t:erl_cipher_suite/0"},{"type":"type","doc":"If a TLS connection fails a TLS protocol ALERT will be sent/received.\n\nAn atom reflecting the raised alert, according to the TLS protocol, and a description string\nwith some further details will be returned.","title":"ssl.error_alert/0","ref":"ssl.html#t:error_alert/0"},{"type":"type","doc":"TLS-1.3 key exchange configuration.","title":"ssl.group/0","ref":"ssl.html#t:group/0"},{"type":"type","doc":"Hash algorithms used together with signing and encryption functions.","title":"ssl.hash/0","ref":"ssl.html#t:hash/0"},{"type":"type","doc":"A name or address to a host.","title":"ssl.host/0","ref":"ssl.html#t:host/0"},{"type":"type","doc":"Cipher Suite Key Exchange Algorithm will be `any`\nin TLS-1.3 as key exchange is no longer part of cipher suite\nconfiguration in TLS-1.3.","title":"ssl.kex_algo/0","ref":"ssl.html#t:kex_algo/0"},{"type":"type","doc":"The user's private key.\n\nThe key can be provided either directly as a DER-encoded entity,\nindirectly using a crypto engine/provider (with key reference\ninformation), or as an Erlang fun (with possible custom options).\nThe latter two options can be used for customized signing with\nhardware security modules (HSM) or trusted platform modules (TPM).\n\n- A DER encoded key will need to specify the ASN-1 type used to create the\n encoding.\n- An engine/provider needs to specify specific information to support this\n concept and can optionally be password protected; see also\n [crypto:engine_load/3 ](`crypto:engine_load/3`) and\n [Crypto User's Guide](`e:crypto:engine_load.md`).\n- A fun option should include a fun that mimics `public_key:sign/4` and possibly\n [public_key:private_encrypt/4](`public_key:encrypt_private/3`) if legacy\n versions TLS-1.0 and TLS-1.1 must be supported.","title":"ssl.key/0","ref":"ssl.html#t:key/0"},{"type":"type","doc":"Cipher algorithms that are no longer supported by default for security reasons.","title":"ssl.legacy_cipher/0","ref":"ssl.html#t:legacy_cipher/0"},{"type":"type","doc":"Hash algorithms that are no longer supported by default for security reasons.","title":"ssl.legacy_hash/0","ref":"ssl.html#t:legacy_hash/0"},{"type":"type","doc":"Key exchange configuration prior to TLS-1.3.\n\nThese curves have been deprecated by RFC 8422.","title":"ssl.legacy_named_curve/0","ref":"ssl.html#t:legacy_named_curve/0"},{"type":"type","doc":"Signature algorithms that are no longer supported by default for security reasons.","title":"ssl.legacy_sign_algo/0","ref":"ssl.html#t:legacy_sign_algo/0"},{"type":"type","doc":"This is only used for certificate signatures if TLS-1.2 is negotiated,\nmeaning that the peer only supports TLS-1.2, but we also support\nTLS-1.3.","title":"ssl.legacy_sign_scheme/0","ref":"ssl.html#t:legacy_sign_scheme/0"},{"type":"type","doc":"Key exchange configuration prior to TLS-1.3.","title":"ssl.named_curve/0","ref":"ssl.html#t:named_curve/0"},{"type":"type","doc":"For backwards compatibility only; do not use.","title":"ssl.old_cipher_suite/0","ref":"ssl.html#t:old_cipher_suite/0"},{"type":"type","doc":"","title":"ssl.prf_random/0","ref":"ssl.html#t:prf_random/0"},{"type":"type","doc":"Client hello extensions.","title":"ssl.protocol_extensions/0","ref":"ssl.html#t:protocol_extensions/0"},{"type":"type","doc":"TLS or DTLS protocol version.","title":"ssl.protocol_version/0","ref":"ssl.html#t:protocol_version/0"},{"type":"type","doc":"Error reason for debug purposes.\n\nNot to be matched.","title":"ssl.reason/0","ref":"ssl.html#t:reason/0"},{"type":"type","doc":"Supported in TLS-1.3 and TLS-1.2.","title":"ssl.rsassa_pss_scheme/0","ref":"ssl.html#t:rsassa_pss_scheme/0"},{"type":"type","doc":"TLS connection information that can be used for NSS key logging.","title":"ssl.security_info/0","ref":"ssl.html#t:security_info/0"},{"type":"type","doc":"Options specific to the server side, or with different semantics for the client and server.\n\n- **`{alpn_preferred_protocols, AppProtocols}`** - Application Layer Protocol Negotiation\n\n Indicates that the server will try to perform Application-Layer\n Protocol Negotiation (ALPN).\n\n The list of protocols is in order of preference. The protocol negotiated will be\n the first in the list that matches one of the protocols advertised by the\n client. If no protocol matches, the server will fail the connection with a\n `no_application_protocol` alert.\n\n The negotiated protocol can be retrieved using the\n [`negotiated_protocol/1`](`negotiated_protocol/1`) function.\n\n- **`{sni_fun, SNIFun}`**\n\n If the server receives a SNI (Server Name Indication) from the\n client, the given fun `SNIFun` will be called to retrieve\n [`server_option()`](`t:server_option/0`) for the indicated\n hosts. These options will override previously specified options for\n that host.\n\n > #### Note {: .info }\n The options `sni_fun` and `sni_hosts` are mutually exclusive.\n\n- **`{sni_hosts, SNIHosts}`**\n\n If the server receives a SNI (Server Name Indication) from the client matching a\n host listed in the `sni_hosts` option, the specific options for that host will\n override previously specified options.\n\n > #### Note {: .info }\n The options `sni_fun` and `sni_hosts` are mutually exclusive.","title":"ssl.server_option/0","ref":"ssl.html#t:server_option/0"},{"type":"type","doc":"Certificate related options for a server.\n\n- **`{cacerts, CACerts}`** - Trusted certificates.\n\n The DER-encoded trusted certificates. If this option is supplied, it overrides\n the `cacertfile` option.\n\n- **`{verify, Verify}`** - Verify certificates.\n\n Client certificates are an optional part of the TLS protocol. A server performs\n X.509 certificate path validation only in `verify_peer` mode. By default the server\n is in `verify_none` mode and, hence, will not send an certificate request to the\n client. When using `verify_peer` you may also want to specify the options\n `fail_if_no_peer_cert` and `certificate_authorities`.\n\n- **`{fail_if_no_peer_cert, FailNoPeerCert}`** - Legacy trade-off option\n\n Used together with `{verify, verify_peer}` by an TLS/DTLS server. If set to\n `true`, the server fails if the client does not have a certificate to send, that\n is, sends an empty certificate. If set to `false`, it fails only if the client\n sends an invalid certificate (an empty certificate is considered valid).\n Defaults to `false`.\n\n- **`{certificate_authorities, ServerCertAuth}`** - Inter-operate hint option\n\n Determines whether a TLS-1.3 server should include the authorities extension in its\n certificate request message that is sent when the option `verify` is set to\n `verify_peer`. Defaults to `true`.\n\n A reason to exclude the extension would be if the server wants to communicate\n with clients incapable of sending complete certificate chains that adhere to the\n extension, but the server still has the capability to recreate a chain that it\n can verify.","title":"ssl.server_option_cert/0","ref":"ssl.html#t:server_option_cert/0"},{"type":"type","doc":"Legacy server options.\n\n- **`{next_protocols_advertised, NextAppProtocols}`**\n\n ALPN (Application-Layer Protocol Negotiation)\n deprecates NPN (Next Protocol Negotiation) described here.\n\n List of protocols to send to the client if the client indicates that it supports\n the Next Protocol extension. The client can select a protocol that is not on\n this list. The list of protocols must not contain an empty binary. If the server\n negotiates a Next Protocol, it can be accessed using the\n `negotiated_protocol/1` method.","title":"ssl.server_option_legacy/0","ref":"ssl.html#t:server_option_legacy/0"},{"type":"type","doc":"Options only relevant to TLS versions prior to TLS-1.3.\n\n- **`{client_renegotiation, ClientRengotiation}`** - DoS attack avoidance option\n\n In protocols that support client-initiated renegotiation, the resource cost\n of such an operation is higher for the server than the client. This can act as a\n vector for denial-of-service (DoS) attacks. The SSL application already takes measures\n to counter-act such attempts, but client-initiated renegotiation can be completely\n disabled by setting this option to `false`. The default value is `true`. Note\n that disabling renegotiation can result in long-lived connections becoming\n unusable due to limits on the number of messages the underlying cipher suite can\n encipher.\n\n- **`{reuse_sessions, ReuseSessions}`** - Enable session reuse\n\n The boolean value `true` specifies that the server will agree to reuse sessions.\n Setting it to `false` will result in an empty session table, meaning that no sessions\n will be reused.\n\n- **`{reuse_session, ReuseSession}`** - Local server reuse policy\n\n Enables the TLS/DTLS server to have a local policy for deciding whether a session\n is to be reused. Meaningful only if `reuse_sessions` is set to `true`.\n\n `ReuseSession` should be a fun:\n\n `fun(SuggestedSessionId, PeerCert, Compression, CipherSuite)`\n\n `SuggestedSessionId` is a [`binary()`](`t:binary/0`),\n `PeerCert` is a DER-encoded certificate,\n `Compression` is an enumeration integer, and `CipherSuite` is of type\n [`erl_cipher_suite()`](`t:erl_cipher_suite/0`).\n\n- **`{psk_identity, PSKHint}`** - Inter-operate hint option\n\n Specifies the server identity hint that the server presents to the client.\n\n- **`{honor_cipher_order, HonorServerCipherOrder}`** - Trade-off option alters protocol defined behavior\n\n If `true`, use the server's preference for ECC curve selection. If `false` (the\n default), use the client's preference.\n\n- **`{honor_ecc_order, HonorServerECCOrder}`** - Trade-off option alters protocol defined behavior\n\n If `true`, use the server's preference for ECC curve selection. If `false` (the\n default), use the client's preference.\n\n- **`{dh, DHder}`** - Affects DH key exchange cipher suites\n\n The DER-encoded Diffie-Hellman parameters. If specified, it overrides option\n `dhfile`.\n\n- **`{dh_file, DHfile}`** - Affects DH key exchange cipher suites\n\n Path to a file containing PEM-encoded Diffie Hellman parameters to be used by\n the server if a cipher suite using Diffie Hellman key exchange is negotiated. If\n not specified, default parameters are used.","title":"ssl.server_option_pre_tls13/0","ref":"ssl.html#t:server_option_pre_tls13/0"},{"type":"type","doc":"Options only relevant for TLS-1.3.\n\n- **`{session_tickets, SessionTickets}`**\n\n Configures the session ticket functionality. Allowed values for `SessionTickets` are:\n\n * `disabled`\n * `stateful`\n * `stateless`\n * `stateful_with_cert`\n * `stateless_with_cert`\n\n If `SessionTickets` is not set to `disabled`, session resumption with pre-shared\n keys is enabled and the server will send stateful or stateless session tickets to the\n client after successful connections.\n\n > #### Note {: .info }\n In pre-shared key session ticket resumption, there is no certificate\n exchange involved. Therefore, `ssl:peercert/1` will not return the\n peer certificate, as it is only communicated during the initial\n handshake. To associate the client certificate from the original\n handshake with the tickets it issues, the server options\n `stateful_with_cert` or `stateless_with_cert` can be used.\n\n A stateful session ticket is a database reference to internal state information.\n A stateless session ticket is a self-encrypted binary that contains both\n cryptographic keying material and state data.\n\n > #### Warning {: .warning }\n When `SessionTickets` is set to `stateful_with_cert`, the client\n certificate is stored along with the internal state information,\n leading to increased memory consumption. Conversely, when it is set\n to `stateless_with_cert`, the client certificate is encoded in the\n self-encrypted binary sent to the client, resulting in an increase\n in payload size.\n\n See also [SSL User's Guide, Session Tickets and Session Resumption in TLS 1.3](using_ssl.md#session-tickets-and-session-resumption-in-tls-1-3).\n\n- **`{stateless_tickets_seed, TicketSeed}`** - Option for statless tickets\n\n Configures the seed used for the encryption of stateless session tickets.\n Allowed values are any randomly generated `t:binary/0`. If this option is not\n configured, an encryption seed will be randomly generated.\n\n > #### Warning {: .warning }\n >\n > Reusing the ticket encryption seed between multiple server instances enables\n > stateless session tickets to work across multiple server instances, but it\n > breaks anti-replay protection across instances.\n >\n > Inaccurate time synchronization between server instances can also affect\n > session ticket freshness checks, potentially causing false negatives as well\n > as false positives.\n\n- **`{anti_replay, AntiReplay}`** - Option for statless tickets\n\n Configures the server's built-in anti replay feature based on Bloom filters.\n\n Allowed values for `AntiReplay` are the pre-defined `'10k'`,\n `'100k'`, or a custom 3-tuple that defines the properties of the\n bloom filters:\n `{WindowSize, HashFunctions, Bits}`. `WindowSize` is the number of seconds after\n the current Bloom filter is rotated and also the window size used for freshness\n checks of ClientHello. `HashFunctions` is the number hash functions and `Bits`\n is the number of bits in the bit vector. `'10k'` and `'100k'` are simple\n defaults with the following properties:\n\n - `'10k'`: Bloom filters can hold 10000 elements with 3% probability of false\n positives. `WindowSize`: 10, `HashFunctions`: 5, `Bits:` 72985 (8.91 KiB).\n - `'100k'`: Bloom filters can hold 100000 elements with 3% probability of false\n positives. `WindowSize`: 10, `HashFunctions`: 5, `Bits`: 729845 (89.09 KiB).\n\n See also [SSL User's Guide, Anti-Replay Protection in TLS\n 1.3](using_ssl.md#anti-replay-protection-in-tls-1-3).\n\n- **`{cookie, Cookie}`** - Option for `HelloRetryRequest` behavior\n\n If `Cookie` is `true`, which is the default, the server sends a\n cookie extension in its `HelloRetryRequest` messages.\n\n The cookie extension has two main purposes. It allows the server to force the\n client to demonstrate reachability at their apparent network address (thus\n providing a measure of DoS protection). This is primarily useful for\n non-connection-oriented transports. It also allows offloading the server's\n state to the client. The cookie extension is enabled by default as it is a\n mandatory extension in RFC8446.\n\n- **`{early_data, EarlyData}`** - Option for accepting or rejecting Early Data\n\n Configures if the server accepts (`enabled`) or rejects (`disabled`) early data\n sent by a client. The default value is `disabled`.","title":"ssl.server_option_tls13/0","ref":"ssl.html#t:server_option_tls13/0"},{"type":"type","doc":"Identifies a TLS session prior to TLS-1.3.","title":"ssl.session_id/0","ref":"ssl.html#t:session_id/0"},{"type":"type","doc":"SHA2 hash algorithms.","title":"ssl.sha2/0","ref":"ssl.html#t:sha2/0"},{"type":"type","doc":"Signature algorithms.","title":"ssl.sign_algo/0","ref":"ssl.html#t:sign_algo/0"},{"type":"type","doc":"Signature schemes, defined by TLS-1.3, and replacing signature algorithms from TLS-1.2.\n\nExplicitly list acceptable signature schemes in the preferred\norder.\n\nOverrides the algorithms supplied in\n[`signature_algs`](`t:signature_algs/0`) option for certificates.\nIn addition to the `signature_algorithms` extension from TLS 1.2,\n[TLS 1.3 (RFC 5246 Section 4.2.3)](http://www.ietf.org/rfc/rfc8446.txt#section-4.2.3)\nadds the `signature_algorithms_cert` extension which enables having special\nrequirements on the signatures used in the certificates that differs from the\nrequirements on digital signatures as a whole. If this is not required this\nextension is not needed.\n\nThe client will send a `signature_algorithms_cert` extension (in the\nclient hello message), if TLS version 1.2 (back-ported to TLS 1.2 in\n24.1) or later is used, and the signature_algs_cert option is\nexplicitly specified. By default, only the\n[signature_algs](`t:signature_algs/0`) extension is sent with the\nexception of when signature_algs option is not explicitly specified,\nin which case it will append the rsa_pkcs1_sha1 algorithm to the\ndefault value of signature_algs and use it as value for\nsignature_algs_cert to allow certificates to have this signature but\nstill disallow sha1 use in the TLS protocol, since 27.0.1 and 26.2.5.2.\n\n> #### Note {: .info }\n>\n> Note that supported signature schemes for TLS-1.2 are\n[`legacy_sign_scheme()`](`t:legacy_sign_scheme/0`)\n> and [`rsassa_pss_scheme()`](`t:rsassa_pss_scheme/0`).","title":"ssl.sign_scheme/0","ref":"ssl.html#t:sign_scheme/0"},{"type":"type","doc":"Explicitly list acceptable signature algorithms for certificates and handshake\nmessages in the preferred order.\n\nThe client will send its list as the client hello\n`signature_algorithm` extension introduced in TLS-1.2; see [Section\n7.4.1.4.1 in RFC 5246](http://www.ietf.org/rfc/rfc5246.txt). Before\nTLS-1.2, these algorithms where implicitly chosen and partly derived\nfrom the cipher suite.\n\nIn TLS-1.2 a somewhat more explicit negotiation is made possible using a list of\n`{HashAlgo, SignAlgo}` tuples.\n\nIn TLS-1.3, these algorithm pairs are replaced by [signature\nschemes](`t:sign_scheme/0`) that are completely decoupled from the\ncipher suite.\n\nSignature algorithms used for certificates can be overridden by the\n[signature schemes](`t:sign_scheme/0`) supplied by the\n`signature_algs_cert` option.\n\nThe TLS-1.2 default is `Default_TLS_12_Alg_Pairs` interleaved with\n`rsa_pss_schemes` since ssl-11.0 (Erlang/OTP 25). `pss_pss` is\npreferred over `pss_rsae`, which in turn is preferred over `rsa`.\n\nThe list for `Default_TLS_12_Alg_Pairs` is defined as follows:\n\n```erlang\n[\n{sha512, ecdsa},\n{sha512, rsa},\n{sha384, ecdsa},\n{sha384, rsa},\n{sha256, ecdsa},\n{sha256, rsa}\n]\n```\n\n> #### Change {: .info }\n>\n> - Support for `{md5, rsa}` was removed from the TLS-1.2 default in\n> ssl-8.0 (Erlang/OTP 22).\n> - Support for `{sha, _}` (SHA1) and `{sha224, _}` was removed\n> from the TLS-1.2 default in ssl-11.0 (Erlang/OTP 26).\n\nThe list for `rsa_pss_schemes` is defined as follows:\n\n\n```erlang\n[rsa_pss_pss_sha512,\nrsa_pss_pss_sha384,\nrsa_pss_pss_sha256,\nrsa_pss_rsae_sha512,\nrsa_pss_rsae_sha384,\nrsa_pss_rsae_sha256]\n```\n\nThe list of `TLS_13_Legacy_Schemes` is defined as follows:\n\n```erlang\n[\n%% Legacy algorithms only applicable to certificate signatures\nrsa_pkcs1_sha512, %% Corresponds to {sha512, rsa}\nrsa_pkcs1_sha384, %% Corresponds to {sha384, rsa}\nrsa_pkcs1_sha256, %% Corresponds to {sha256, rsa}\n]\n```\n\nThe list of `Default_TLS_13_Schemes` is defined as follows:\n\n```text\n[\n%% EDDSA\neddsa_ed25519,\neddsa_ed448\n\n%% ECDSA\necdsa_secp521r1_sha512,\necdsa_secp384r1_sha384,\necdsa_secp256r1_sha256] ++\n\n%% RSASSA-PSS\nrsa_pss_schemes()\n```\n\n> #### Change {: .info }\n>\n> EDDSA was made highest priority in ssl-10.8 (Erlang/OTP 25).\n\nThe TLS-1.3 default is `Default_TLS_13_Schemes`.\n\nIf both TLS-1.3 and TLS-1.2 are supported the default is:\n\n```erlang\nDefault_TLS_13_Schemes ++ TLS_13_Legacy_Schemes ++\nDefault_TLS_12_Alg_Pairs %% not represented in TLS_13_Legacy_Schemes\n```\n\nto ensure that appropriate algorithms can be chosen for the negotiated\nversion.\n\n> #### Note {: .info }\nTLS-1.2 algorithms will not be negotiated for TLS-1.3, but the TLS-1.3\nRSASSA-PSS ([`rsassa_pss_scheme()`](`t:rsassa_pss_scheme/0`))\nsignature schemes can be negotiated also for TLS-1.2 from Erlang/OTP\n24.1 (fully working from Erlang/OTP 24.1.3). However, if both TLS 1.3\nand TLS 1.2 are supported using defaults, and TLS 1.3 is negotiated,\nthe corresponding TLS 1.2 algorithms for TLS 1.3 legacy signature\nschemes will be treated as legacy schemes and applied only to\ncertificate signatures.","title":"ssl.signature_algs/0","ref":"ssl.html#t:signature_algs/0"},{"type":"type","doc":"A socket that can be used to perform a so-called \"START-TLS\", which\nmeans using an already connected socket previously used for plain TCP\ntraffic and upgrading it to use TLS.\n\nBoth sides needs to agree on the upgrade.","title":"ssl.socket/0","ref":"ssl.html#t:socket/0"},{"type":"type","doc":"Options for the transport socket.\n\nThe default socket options are\n`[{mode, list}, {packet, 0}, {header, 0}, {active, true}]`.\n\nFor valid options, see `m:inet`, `m:gen_tcp`, and `m:gen_udp`\nin Kernel. Note that stream-oriented options such as `packet` are\nonly relevant for TLS and not DTLS.","title":"ssl.socket_option/0","ref":"ssl.html#t:socket_option/0"},{"type":"type","doc":"SRP cipher suite configuration prior to TLS-1.3.","title":"ssl.srp_param_type/0","ref":"ssl.html#t:srp_param_type/0"},{"type":"type","doc":"An opaque reference to the TLS/DTLS connection.\n\nNote that despite being opaque, matching `sslsocket()` instances is allowed.","title":"ssl.sslsocket/0","ref":"ssl.html#t:sslsocket/0"},{"type":"type","doc":"TLS Alert Protocol reasons.","title":"ssl.tls_alert/0","ref":"ssl.html#t:tls_alert/0"},{"type":"type","doc":"An option that can be supplied to a TLS client.","title":"ssl.tls_client_option/0","ref":"ssl.html#t:tls_client_option/0"},{"type":"type","doc":"A TLS protocol version that are no longer supported by default for security reasons.","title":"ssl.tls_legacy_version/0","ref":"ssl.html#t:tls_legacy_version/0"},{"type":"type","doc":"An option related to the TLS/DTLS protocol.","title":"ssl.tls_option/0","ref":"ssl.html#t:tls_option/0"},{"type":"type","doc":"An option that can be supplied to a TLS server.","title":"ssl.tls_server_option/0","ref":"ssl.html#t:tls_server_option/0"},{"type":"type","doc":"TLS protocol version.","title":"ssl.tls_version/0","ref":"ssl.html#t:tls_version/0"},{"type":"type","doc":"Transport option defines a callback module and message tags to handle the underlying transport socket.\n\nCan be used to customize the transport layer. The tag\nvalues should be the values used by the underlying transport in its active mode\nmessages.\n\nDefaults to `{gen_tcp, tcp, tcp_closed, tcp_error, tcp_passive}` for TLS.\n\n> #### Note {: .info }\nFor backward compatibility a tuple of size four will be converted to a\ntuple of size five, where `PassiveTag` is the `DataTag` element with\n`_passive` appended.\n\nFor TLS the callback module must implement a reliable transport\nprotocol, behave as `m:gen_tcp`, and have functions corresponding to\n`inet:setopts/2`, `inet:getopts/2`, `inet:peername/1`, `inet:sockname/1`, and\n`inet:port/1`. The callback `m:gen_tcp` is treated specially and calls `m:inet`\ndirectly. For DTLS this feature is considered experimental.","title":"ssl.transport_option/0","ref":"ssl.html#t:transport_option/0"},{"type":"module","doc":"CRL cache\n\nImplements an internal CRL (Certificate Revocation List) cache. In addition to\nimplementing the `m:ssl_crl_cache_api` behaviour the following functions are\navailable.","title":"ssl_crl_cache","ref":"ssl_crl_cache.html"},{"type":"function","doc":"Delete CRLs from the ssl applications local cache.","title":"ssl_crl_cache.delete/1","ref":"ssl_crl_cache.html#delete/1"},{"type":"function","doc":"","title":"ssl_crl_cache.insert/1","ref":"ssl_crl_cache.html#insert/1"},{"type":"function","doc":"Insert CRLs into the ssl applications local cache, with or without a\ndistribution point reference URI","title":"ssl_crl_cache.insert/2","ref":"ssl_crl_cache.html#insert/2"},{"type":"type","doc":"A source to input CRLs","title":"ssl_crl_cache.crl_src/0","ref":"ssl_crl_cache.html#t:crl_src/0"},{"type":"behaviour","doc":"API for a TLS CRL (Certificate Revocation List) cache.\n\nWhen TLS performs certificate path validation according to\n[RFC 5280 ](http://www.ietf.org/rfc/rfc5280.txt)it should also perform CRL\nvalidation checks. To enable the CRL checks the application needs access to\nCRLs. A database of CRLs can be set up in many different ways. This module\nprovides the behavior of the API needed to integrate an arbitrary CRL cache with\nthe erlang ssl application. It is also used by the application itself to provide\na simple default implementation of a CRL cache.","title":"ssl_crl_cache_api","ref":"ssl_crl_cache_api.html"},{"type":"callback","doc":"`fun fresh_crl/2` will be used as input option `update_crl` to\n`public_key:pkix_crls_validate/3`.\n\nIt is possible to return logger info, since OTP 22.2, that will be used by the TLS connection to\nproduce log events.","title":"ssl_crl_cache_api.fresh_crl/2","ref":"ssl_crl_cache_api.html#c:fresh_crl/2"},{"type":"callback","doc":"Backwards compatibility, replaced by lookup/3","title":"ssl_crl_cache_api.lookup/2","ref":"ssl_crl_cache_api.html#c:lookup/2"},{"type":"callback","doc":"Lookup the CRLs belonging to the distribution point `Distributionpoint`. This\nfunction may choose to only look in the cache or to follow distribution point\nlinks depending on how the cache is administrated.\n\nThe `Issuer` argument contains the issuer name of the certificate to\nbe checked. Normally the returned CRL should be issued by this\nissuer, except if the `cRLIssuer` field of `DistributionPoint` has a\nvalue, in which case that value should be used instead.\n\nIn an earlier version of this API, the `lookup` function received two\narguments, omitting `Issuer`. For compatibility, this is still\nsupported: if there is no [`lookup/3`](`c:lookup/3`) function in the\ncallback module,[`lookup/2`](`c:lookup/2`) is called instead.\n\nIt is possible to return logger info, since OTP 22.2, that will be used by the TLS connection to\nproduce log events.","title":"ssl_crl_cache_api.lookup/3","ref":"ssl_crl_cache_api.html#c:lookup/3"},{"type":"callback","doc":"Select the CRLs in the cache that are issued by `Issuer` unless the value is a\nlist of so called general names, see\n[X509 certificates records](`e:public_key:public_key_records.md`), originating\nform `#'DistributionPoint'.cRLissuer` and representing different mechanism to\nobtain the CRLs. The cache callback needs to use the appropriate entry to\nretrieve the CRLs or return an empty list if it does not exist.\n\nIt is possible to return logger info, since OTP 22.2, that will be used by the TLS connection to\nproduce log events.","title":"ssl_crl_cache_api.select/2","ref":"ssl_crl_cache_api.html#c:select/2"},{"type":"type","doc":"Reference to the CRL cache.","title":"ssl_crl_cache_api.crl_cache_ref/0","ref":"ssl_crl_cache_api.html#t:crl_cache_ref/0"},{"type":"type","doc":"For description see\n[X509 certificates records](`e:public_key:public_key_records.md`)","title":"ssl_crl_cache_api.dist_point/0","ref":"ssl_crl_cache_api.html#t:dist_point/0"},{"type":"type","doc":"Information for ssl applications use of [Logger(3)](`m:logger`)","title":"ssl_crl_cache_api.logger_info/0","ref":"ssl_crl_cache_api.html#t:logger_info/0"},{"type":"behaviour","doc":"TLS session cache API\n\nDefines the API for the TLS session cache (pre TLS-1.3) so that the data storage\nscheme can be replaced by defining a new callback module implementing this API.","title":"ssl_session_cache_api","ref":"ssl_session_cache_api.html"},{"type":"callback","doc":"Deletes a cache entry.\n\nIs only called from the cache handling process.","title":"ssl_session_cache_api.delete/2","ref":"ssl_session_cache_api.html#c:delete/2"},{"type":"callback","doc":"Calls `Fun(Elem, AccIn)` on successive elements of the cache, starting with\n `AccIn == Acc0`.\n\n`Fun/2` must return a new accumulator, which is passed to the\nnext call. The function returns the final value of the accumulator. `Acc0` is\nreturned if the cache is empty.\n\n> #### Note {: .info }\n>\n> Since OTP-23.3 this functions is only used on the client side and does not\n> need to implemented for a server cache.","title":"ssl_session_cache_api.foldl/3","ref":"ssl_session_cache_api.html#c:foldl/3"},{"type":"callback","doc":"Performs possible initializations of the cache and returns a reference to it\nthat is used as parameter to the other API functions. \n\nIs called by the cache handling processes `init` function, hence\nputting the same requirements on it as a normal process `init`\nfunction. This function is called twice when starting the SSL\napplication, once with the role client and once with the role server,\nas the SSL application must be prepared to take on both roles.\n\nIncludes property `{role, client | server}` in init argument list. \nCurrently this is the only predefined property, there can also be\nuser-defined properties. See also application environment variable\n[session_cb_init_args](ssl_app.md).","title":"ssl_session_cache_api.init/1","ref":"ssl_session_cache_api.html#c:init/1"},{"type":"callback","doc":"Looks up a cache entry. Is to be callable from any process.","title":"ssl_session_cache_api.lookup/2","ref":"ssl_session_cache_api.html#c:lookup/2"},{"type":"callback","doc":"Selects sessions that can be reused, that is sessions that include `PartialKey`\nin its key. Is to be callable from any process.\n\n> #### Note {: .info }\n>\n> Since OTP-23.3 This functions is only used on the client side and does not\n> need to implemented for a server cache.","title":"ssl_session_cache_api.select_session/2","ref":"ssl_session_cache_api.html#c:select_session/2"},{"type":"callback","doc":"Returns the number of sessions in the cache.\n\nIf size exceeds the maximum number of sessions, the current cache\nentries will be invalidated regardless of their remaining lifetime. Is\nto be callable from any process.","title":"ssl_session_cache_api.size/1","ref":"ssl_session_cache_api.html#c:size/1"},{"type":"callback","doc":"Takes care of possible cleanup that is needed when the cache handling process\nterminates.","title":"ssl_session_cache_api.terminate/1","ref":"ssl_session_cache_api.html#c:terminate/1"},{"type":"callback","doc":"Caches a new session or updates an already cached one.\n\nIs only called from the cache handling process.","title":"ssl_session_cache_api.update/3","ref":"ssl_session_cache_api.html#c:update/3"},{"type":"opaque","doc":"The opaque part of the key. Does not need to be handled by the callback.","title":"ssl_session_cache_api.partial_key/0","ref":"ssl_session_cache_api.html#t:partial_key/0"},{"type":"opaque","doc":"The session data that is stored for each session.","title":"ssl_session_cache_api.session/0","ref":"ssl_session_cache_api.html#t:session/0"},{"type":"type","doc":"A key to an entry in the session cache.","title":"ssl_session_cache_api.session_cache_key/0","ref":"ssl_session_cache_api.html#t:session_cache_key/0"},{"type":"type","doc":"A term that can be used to reference the cache.","title":"ssl_session_cache_api.session_cache_ref/0","ref":"ssl_session_cache_api.html#t:session_cache_ref/0"},{"type":"extras","doc":"\n# SSL Application\n\nThe ssl application provides secure communication over sockets.","title":"SSL Application","ref":"ssl_app.html"},{"type":"extras","doc":"The ssl application is an implementation of the TLS (previously known as SSL) and DTLS protocols in\nErlang.\n\nFor current statement of standards compliance see the\n[User's Guide](standards_compliance.md).","title":"Description - SSL Application","ref":"ssl_app.html#description"},{"type":"extras","doc":"The SSL application uses the `Public_Key`, `Asn1` and `Crypto` application to\nhandle public keys and encryption, hence these applications must be loaded for\nthe SSL application to work. In an embedded environment this means they must be\nstarted with `application:start/1,2` before the SSL application is started.","title":"Dependencies - SSL Application","ref":"ssl_app.html#dependencies"},{"type":"extras","doc":"The application environment configuration parameters in this section are defined\nfor the SSL application. For more information about configuration parameters,\nsee the `m:application` manual page in Kernel.\n\n> #### Note {: .info }\nAll parameters including the wording 'session_ticket' are TLS-1.3 only configuration\nand other session parameters are prior to TLS-1.3 only configuration. DTLS versions\nare based on TLS versions see [standard compliance](standards_compliance.md) for mapping.\n\nThe environment parameters can be set on the command line, for example:\n\n`erl -ssl protocol_version \"['tlsv1.2', 'tlsv1.1']\"`\n\n- **`protocol_version = ``t:ssl:tls_version/0` | [`t:ssl:tls_version/0`]\n ` `** - Protocol supported by started clients and servers. If this\n option is not set, it defaults to all TLS protocols currently supported, more\n might be configurable, by the SSL application. This option can be overridden\n by the version option to `ssl:connect/2,3` and `ssl:listen/2`.\n\n- **`dtls_protocol_version = ``t:ssl:dtls_version/0` | [`t:ssl:dtls_version/0`]\n ` `** - Protocol supported by started clients and servers. If this\n option is not set, it defaults to all DTLS protocols currently supported, more\n might be configurable, by the SSL application. This option can be overridden\n by the version option to `ssl:connect/2,3` and `ssl:listen/2`.\n\n- **`session_lifetime = integer() `** - Maximum lifetime of the\n session data in seconds. Defaults to 24 hours which is the maximum recommended\n lifetime by [RFC 5246](http://www.ietf.org/rfc/5246rfc.txt). However sessions\n may be invalidated earlier due to the maximum limitation of the session cache\n table.\n\n- **`session_cb = atom() `** - Deprecated Since OTP-23.3 replaced by\n `client_session_cb` and `server_session_cb`\n\n- **`client_session_cb = atom() `** - Since OTP-23.3 Name client of\n the session cache callback module that implements the `ssl_session_cache_api`\n behavior. Defaults to `ssl_client_session_cache_db`.\n\n- **`server_session_cb = atom() `** - Since OTP-23.3 Name of the\n server session cache callback module that implements the\n `ssl_session_cache_api` behavior. Defaults to `ssl_server_session_cache_db`.\n\n- **`session_cb_init_args = proplist:proplist() `** - Deprecated Since\n OTP-23.3 replaced by `client_session_cb_init_args` and\n `server_session_cb_init_args`\n\n- **`client_session_cb_init_args = proplist:proplist() `** - List of\n extra user-defined arguments to the `init` function in the session cache\n callback module. Defaults to `[]`.\n\n- **`server_session_cb_init_args = proplist:proplist() `** - List of\n extra user-defined arguments to the `init` function in the session cache\n callback module. Defaults to `[]`.\n\n- **`session_cache_client_max = integer() ` \n ** \n Limits the growth of the clients session cache, that is how many sessions\n towards servers that are cached to be used by new client connections. If the\n maximum number of sessions is reached, the current cache entries will be\n invalidated regardless of their remaining lifetime. Defaults to 1000.\n Recommended ssl-8.2.1 or later for this option to work as intended.\n\n- **`session_cache_server_max = integer() `** - Limits the growth of\n the servers session cache, that is how many client sessions are cached by the\n server. If the maximum number of sessions is reached, the current cache\n entries will be invalidated regardless of their remaining lifetime. Defaults\n to 1000. Recommended ssl-8.2.1 or later for this option to work as intended.\n\n- **`ssl_pem_cache_clean = integer() `** - Number of milliseconds\n between PEM cache validations. Defaults to 2 minutes.\n\n Note: The cache can be reloaded by calling `ssl:clear_pem_cache/0`.\n\n- **`bypass_pem_cache = boolean() `** - Introduced in ssl-8.0.2.\n Disables the PEM-cache. Can be used as a workaround for the PEM-cache\n bottleneck before ssl-8.1.1. Defaults to false.\n\n- **`alert_timeout = integer() `** - Number of milliseconds between\n sending of a fatal alert and closing the connection. Waiting a little while\n improves the peers chances to properly receiving the alert so it may shutdown\n gracefully. Defaults to 5000 milliseconds.\n\n- **`internal_active_n = integer() `** - For TLS connections this\n value is used to handle the internal socket. As the implementation was changed\n from an active once to an active N behavior (N = 100), for performance\n reasons, this option exist for possible tweaking or restoring of the old\n behavior (internal_active_n = 1) in unforeseen scenarios. The option will not\n affect erlang distribution over TLS that will always run in active N mode.\n Added in ssl-9.1 (OTP-21.2).\n\n- **`server_session_tickets_amount = integer() `** - Number of session\n tickets sent by the server. It must be greater than 0. Defaults to 3.\n\n- **`server_session_ticket_lifetime = integer() `** - Lifetime of\n session tickets sent by the server. Servers must not use any value greater\n than 604800 seconds (7 days). Expired tickets are automatically removed.\n Defaults to 7200 seconds (2 hours).\n\n- **`server_session_ticket_store_size = integer() `** - Sets the\n maximum size of the server session ticket store (stateful tickets). Defaults\n to 1000. Size limit is enforced by dropping old tickets.\n\n- **`server_session_ticket_max_early_data = integer() `** - Sets the\n maximum size of the early data that the server accepts and also configures its\n NewSessionTicket messages to include this same size limit in their\n early_data_indication extension. Defaults to 16384. Size limit is enforced by\n both client and server.\n\n- **`client_session_ticket_lifetime = integer() `** - Lifetime of\n session tickets in the client ticket store. Expired tickets are automatically\n removed. Defaults to 7200 seconds (2 hours).\n\n- **`client_session_ticket_store_size = integer() `** - Sets the\n maximum size of the client session ticket store. Defaults to 1000. Size limit\n is enforced by dropping old tickets.","title":"Configuration - SSL Application","ref":"ssl_app.html#configuration"},{"type":"extras","doc":"The SSL application uses [OTP logger](`m:logger`). TLS/DTLS alerts are logged on\nnotice level. Unexpected errors are logged on error level. These log entries\nwill by default end up in the default Erlang log. The option `log_level` may be\nused to in run-time to set the log level of a specific TLS connection, which is\nhandy when you want to use level debug to inspect the TLS handshake setup.","title":"Error Logger and Event Handlers - SSL Application","ref":"ssl_app.html#error-logger-and-event-handlers"},{"type":"extras","doc":"`m:application`","title":"See Also - SSL Application","ref":"ssl_app.html#see-also"},{"type":"extras","doc":"\n# SSL Release Notes\n\nThis document describes the changes made to the SSL application.","title":"SSL Release Notes","ref":"notes.html"},{"type":"extras","doc":"","title":"SSL 11.2.1 - SSL Release Notes","ref":"notes.html#ssl-11-2-1"},{"type":"extras","doc":"- Check for TLS-1.3 support should check minimum requirements.\n\n Own Id: OTP-19094 Aux Id: [GH-8489]\n\n- If both TLS-1.3 and TLS-1.2 is supported\n and TLS-1.2 negotiated convert TLS-1.3 ECDSA schemes to TLS-1.2 hash and signature pairs for increased interoperability.\n\n Own Id: OTP-19107 Aux Id: [GH-8376]\n\n- TLS-1.3 negotiation now uses SNI based options correctly instead of ignoring them.\n\n Own Id: OTP-19140\n\n[GH-8489]: https://github.com/erlang/otp/issues/8489\n[GH-8376]: https://github.com/erlang/otp/issues/8376","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Make it easier to distinguish between a invalid signature and unsupported signature.\n\n Own Id: OTP-19091\n\n- Enhance ALERT logs to help understand what causes the alert.\n\n Own Id: OTP-19092 Aux Id: [GH-8482]\n\n- When the default value for signature_algs is used, default the signature_algs_cert to the default value + rsa_pkcs1_sha1 to allow this algorithms for certificates but not for the TLS protocol. This is for better interoperability. If signature_algs is set explicitly signature_algs_cert must also be set explicitly if they should be different.\n\n Own Id: OTP-19152 Aux Id: [GH-8588]\n\n[GH-8482]: https://github.com/erlang/otp/issues/8482\n[GH-8588]: https://github.com/erlang/otp/issues/8588","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.2 - SSL Release Notes","ref":"notes.html#ssl-11-2"},{"type":"extras","doc":"- Starting a TLS server without sufficient credentials (certificate or anonymous cipher) would work, but it was impossible to connect to it.\n \n This has been corrected to return an error instead of starting the server.\n\n Own Id: OTP-18887 Aux Id: [GH-7493], [PR-7918]\n\n- ASN.1 decoding errors are handled in more places to ensure that errors are returned instead of cause a crash.\n\n Own Id: OTP-18969 Aux Id: [GH-8058], [PR-8256]\n\n- Improved error checking on the API functions.\n\n Own Id: OTP-18992 Aux Id: [GH-8066] [PR-8156]\n\n[GH-7493]: https://github.com/erlang/otp/issues/7493\n[PR-7918]: https://github.com/erlang/otp/pull/7918\n[GH-8058]: https://github.com/erlang/otp/issues/8058\n[PR-8256]: https://github.com/erlang/otp/pull/8256\n[GH-8066]: https://github.com/erlang/otp/issues/8066\n[PR-8156]: https://github.com/erlang/otp/pull/8156","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The `ssl` client can negotiate and handle certificate status request (OCSP stapling support on the client side).\n \n Thanks to voltone for interop testing and related discussions.\n\n Own Id: OTP-18606 Aux Id: OTP-16875,OTP-16448\n\n- Memory consumption has been reduced and performance increased by refactoring internal data structures and their usage.\n\n Own Id: OTP-18665 Aux Id: [PR-7447]\n\n- Added `c:ssl_crl_cache_api:lookup/2` as an optional `-callback` attribute.\n\n Own Id: OTP-18788 Aux Id: [PR-7700]\n\n- Key customization support has been extended to allow flexibility for implementers of for instance hardware security modules (HSM) or trusted platform modules (TPM).\n\n Own Id: OTP-18876 Aux Id: [PR-7898], [PR-7475]\n\n- The `proc_lib:set_label/1` function is now used to increase observability of `ssl` processes.\n\n Own Id: OTP-18879\n\n- Brainpool elliptic curves are now supported in TLS-1.3.\n\n Own Id: OTP-18884 Aux Id: [PR-8056]\n\n- The documentation has been migrated to use Markdown and ExDoc.\n\n Own Id: OTP-18955 Aux Id: [PR-8026]\n\n- For security reasons, the CBC ciphers are now longer included in the list of default ciphers for TLS-1.2.\n\n *** POTENTIAL INCOMPATIBILITY ***\n\n Own Id: OTP-19025 Aux Id: [PR-8250]\n\n- There is a new `cert_policy_opts` option to configure certificate policy options for the certificate path validation.\n\n Own Id: OTP-19027 Aux Id: [PR-8255]\n\n[PR-7447]: https://github.com/erlang/otp/pull/7447\n[PR-7700]: https://github.com/erlang/otp/pull/7700\n[PR-7898]: https://github.com/erlang/otp/pull/7898\n[PR-7475]: https://github.com/erlang/otp/pull/7475\n[PR-8056]: https://github.com/erlang/otp/pull/8056\n[PR-8026]: https://github.com/erlang/otp/pull/8026\n[PR-8250]: https://github.com/erlang/otp/pull/8250\n[PR-8255]: https://github.com/erlang/otp/pull/8255","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.1.4.3 - SSL Release Notes","ref":"notes.html#ssl-11-1-4-3"},{"type":"extras","doc":"* A race in the kTLS flavour of SSL distribution has been fixed so inet_drv.c doesn't read ahead too much data which could cause the kTLS encryption to be activated too late when some encrypted data had already been read into the inet_drv.c buffer as unencrypted.\n\n Own Id: OTP-19175 Aux Id: GH-8561, PR-8690","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"* Make sure all TLS-1.3 terminations are graceful (previous TLS version terminations already are).\n\n Own Id: OTP-17848\n* Include more information in logging of SNI (Server Name Indication) mismatch error.\n\n Own Id: OTP-19187","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.1.4.2 - SSL Release Notes","ref":"notes.html#ssl-11-1-4-2"},{"type":"extras","doc":"* When the default value for signature_algs is used, default the signature_algs_cert to the default value + rsa_pkcs1_sha1 to allow this algorithms for certificates but not for the TLS protocol. This is for better interoperability. If signature_algs is set explicitly signature_algs_cert must also be set explicitly if they should be different.\n\n Own Id: OTP-19152 Aux Id: GH-8588","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.1.4.1 - SSL Release Notes","ref":"notes.html#ssl-11-1-4-1"},{"type":"extras","doc":"* Check for TLS-1.3 support should check minimum requirements.\n\n Own Id: OTP-19094 Aux Id: GH-8489\n* If both TLS-1.3 and TLS-1.2 is supported and TLS-1.2 negotiated convert TLS-1.3 ECDSA schemes to TLS-1.2 hash and signature pairs for increased interoperability.\n\n Own Id: OTP-19107 Aux Id: GH-8376\n* TLS-1.3 negotiation now uses SNI based options correctly instead of ignoring them.\n\n Own Id: OTP-19140","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"* Make it easier to distinguish between a invalid signature and unsupported signature.\n\n Own Id: OTP-19091\n* Enhance ALERT logs to help understand what causes the alert.\n\n Own Id: OTP-19092 Aux Id: GH-8482","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.1.4 - SSL Release Notes","ref":"notes.html#ssl-11-1-4"},{"type":"extras","doc":"* Fix certificate authorities check so that CA closest to peer is not lost. It could manifest itself in a failed connection as the client failed to realize it had a valid certificate chain to send to the server.\n\n Own Id: OTP-19065 Aux Id: GH-8356, PR-8367\n* ssl:signature_algs/2 did not list some legacy algorithm schemes correctly when listing all algorithms available.\n\n Own Id: OTP-19067 Aux Id: PR-8379","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 11.1.3 - SSL Release Notes","ref":"notes.html#ssl-11-1-3"},{"type":"extras","doc":"* Cleanup and close all connections in DTLS when the listen socket owner dies.\n\n Improved IPv6 handling in DTLS.\n\n Own Id: OTP-19037 Aux Id: GH-7951 GH-7955\n* Fixed a crash in dtls accept.\n\n Own Id: OTP-19059 Aux Id: GH-8338","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 11.1.2 - SSL Release Notes","ref":"notes.html#ssl-11-1-2"},{"type":"extras","doc":"* ssl:prf/5, will start working instead of hanging in a TLS-1.3 context if called appropriately. Note that the implementation has changed and in OTP-27 a more adequate API will be documented.\n\n Own Id: OTP-18890 Aux Id: GH-7911\n* Server name verification didn't work if a connection was made with IP-address as a string.\n\n Own Id: OTP-18909 Aux Id: GH-7968\n* The fallback after \"dh\" ssl option was undefined was to get \"dh\" from ssl options again. This is clearly wrong and now changed to the documented fallback \"dhfile\" ssl option.\n\n Own Id: OTP-18919 Aux Id: PR-7984\n* Correct default value selection for DTLS. Will only affect users linked with really old version of cryptolib library.\n\n Own Id: OTP-18962 Aux Id: GH-8079\n* Adhere elliptic curves with RFC 8422 pre TLS-1.3, that is Edwards curves are added to curves that can be used for key exchange, and documentation and implementation of eccs/0,1 are aligned.\n\n Own Id: OTP-18991","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"* Improve alert reason when ecdhe_rsa key_exchange does not have any common curves to use\n\n Own Id: OTP-18985","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.1.1 - SSL Release Notes","ref":"notes.html#ssl-11-1-1"},{"type":"extras","doc":"* Legacy name handling could cause interop problems between TLS-1.3/1.2 client and TLS-1.2 server.\n\n Own Id: OTP-18917 Aux Id: GH-7978","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 11.1 - SSL Release Notes","ref":"notes.html#ssl-11-1"},{"type":"extras","doc":"- ssl application will validate id-kp-serverAuth and id-kp-clientAuth extended\n key usage only in end entity certificates. public_key application will\n disallow \"anyExtendedKeyUsage\" for CA certificates that includes the extended\n key usage extension and marks it critical.\n\n Own Id: OTP-18739\n\n- Replaced unintentional Erlang Public License 1.1 headers in some files with\n the intended Apache License 2.0 header.\n\n Own Id: OTP-18815 Aux Id: PR-7780\n\n- Correct handling of TLS-1.3 legacy scheme names, could cause interop failures\n for TLS-1.2 clients.\n\n Own Id: OTP-18817\n\n- Add missing export for connection_info() API type.\n\n Own Id: OTP-18886","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Fixed `server name indication` which was not handled properly.\n\n Own Id: OTP-18836 Aux Id: GH-7795\n\n- Align documentation and implementation\n\n Own Id: OTP-18853 Aux Id: PR-7841\n\n- Improve connection setup by optimizing certificate lookup.\n\n Own Id: OTP-18893 Aux Id: PR-7920 PR-7921","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.0.3 - SSL Release Notes","ref":"notes.html#ssl-11-0-3"},{"type":"extras","doc":"- Avoid function clause error in ssl:getopts/2 by handling that inet:getopts may\n return an empty list during some circumstances, such as the socket being in a\n closing state.\n\n Own Id: OTP-18697 Aux Id: GH-7506\n\n- The API function \\`ssl:recv/3\\` has been tightened to disallow negative\n length, which has never been documented to work, but was passed through and\n caused strange errors.\n\n Own Id: OTP-18700 Aux Id: GH-7507\n\n- When a client initiated renegotiation was rejected and the client socket was\n in active mode the expected error message to the controlling process was not\n sent.\n\n Own Id: OTP-18712 Aux Id: GH-7431","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add some guidance for signature algorithms configuration in ssl applications\n users guide.\n\n Own Id: OTP-18631","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.0.2 - SSL Release Notes","ref":"notes.html#ssl-11-0-2"},{"type":"extras","doc":"- Added keylog information to all protocol versions in\n `ssl:connection_information/2`.\n\n Own Id: OTP-18643 Aux Id: ERIERL-932","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add RFC-6083 considerations for DTLS to enable gen_sctp based callback for the\n transport.\n\n Own Id: OTP-18618 Aux Id: ERIERL-932","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 11.0.1 - SSL Release Notes","ref":"notes.html#ssl-11-0-1"},{"type":"extras","doc":"- Make sure that selection of client certificates handle both TLS-1.3 and\n TLS-1.2 names correctly. Could cause valid client certificate to not be\n selected, and an empty client certificate message to be sent to server.\n\n Own Id: OTP-18588 Aux Id: GH-7264, PR-7277\n\n- Improved `ssl:format_error/1` to handle more error tuples.\n\n Own Id: OTP-18596 Aux Id: GH-7247\n\n- Fixed hanging `ssl:connect` when ssl application is not started.\n\n Own Id: OTP-18603 Aux Id: GH-7297\n\n- Correct handling of retransmission timers, current behavior could cause\n unwanted delays.\n\n Own Id: OTP-18632 Aux Id: PR-7300, GH-7301","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 11.0 - SSL Release Notes","ref":"notes.html#ssl-11-0"},{"type":"extras","doc":"- Remove less that 256 bit ECC from default supported ECC pre TLS-1.3\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-14771\n\n- Improved error checking and handling of ssl options.\n\n Own Id: OTP-15903\n\n- With this change, stateless tickets generated by server with anti_replay\n option enabled can be used for creating ClientHello throughout ticket\n lifetime. Without this change, usability was limited to WindowSize number of\n seconds configured for anti_replay option.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-18168 Aux Id: PR-6019, GH-6014\n\n- Support for Kernel TLS (kTLS), has been added to the SSL application, for TLS\n distribution (`-proto_dist inet_tls`), the SSL option `{ktls, true}`. Using\n this for general SSL sockets is uncomfortable, undocumented and not\n recommended since it requires very platform dependent raw options.\n\n This, for now, only works for some not too old Linux distributions. Roughly, a\n kernel 5.2.0 or later with support for UserLand Protocols and the kernel\n module `tls` is required.\n\n Own Id: OTP-18235 Aux Id: PR-6104, PR-5840\n\n- With this change, TLS 1.3 server can be configured to include client\n certificate in session ticket.\n\n Own Id: OTP-18253\n\n- With this change, it is possible to configure encryption seed to be used with\n TLS1.3 stateless tickets. This enables using tickets on different server\n instances.\n\n Own Id: OTP-18254 Aux Id: PR-5982\n\n- Debugging enhancements.\n\n Own Id: OTP-18312\n\n- With this change, maybe keyword atom is not used as function name in ssl code.\n\n Own Id: OTP-18335\n\n- Replace size/1 with either tuple_size/1 or byte_size/1\n\n The [`size/1`](`size/1`) BIF is not optimized by the JIT, and its use can\n result in worse types for Dialyzer.\n\n When one knows that the value being tested must be a tuple,\n [`tuple_size/1`](`tuple_size/1`) should always be preferred.\n\n When one knows that the value being tested must be a binary,\n [`byte_size/1`](`byte_size/1`) should be preferred. However,\n [`byte_size/1`](`byte_size/1`) also accepts a bitstring (rounding up size to a\n whole number of bytes), so one must make sure that the call to `byte_size/` is\n preceded by a call to [`is_binary/1`](`is_binary/1`) to ensure that bitstrings\n are rejected. Note that the compiler removes redundant calls to\n [`is_binary/1`](`is_binary/1`), so if one is not sure whether previous code\n had made sure that the argument is a binary, it does not harm to add an\n [`is_binary/1`](`is_binary/1`) test immediately before the call to\n [`byte_size/1`](`byte_size/1`).\n\n Own Id: OTP-18405 Aux Id:\n GH-6672,PR-6702,PR-6768,PR-6700,PR-6769,PR-6812,PR-6814\n\n- For security reasons remove support for SHA1 and DSA algorithms from default\n values.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-18438 Aux Id: GH-6679\n\n- Mitigate memory usage from large certificate chains by lowering the maximum\n handshake size. This should not effect the common cases, if needed it can be\n configured to a higher value.\n\n Own Id: OTP-18453\n\n- Change the client default verify option to verify_peer. Note that this makes\n it mandatory to also supply trusted CA certificates or explicitly set verify\n to verify_none. This also applies when using the so called anonymous test\n cipher suites defined in TLS versions pre TLS-1.3.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-18455 Aux Id: GH-5899\n\n- Erlang distribution code in Kernel and SSL has been refactored a bit to\n facilitate debugging and re-usability, which shouldn't have any noticeable\n effects on behaviour or performance.\n\n Own Id: OTP-18456\n\n- Add encoding and decoding of use_srtp hello extension to facilitate for DTLS\n users to implement SRTP functionality.\n\n Own Id: OTP-18459\n\n- Refactors the (`ssl` application to use macros for TLS and DTLS versions\n instead of hard-coded tuple numbers. This change improves the maintainability\n of `ssl`\n\n Own Id: OTP-18465 Aux Id: GH-7065\n\n- If the function ssl:renegotiate/1 is called on connection that is running\n TLS-1.3 return an error instead of hanging or timing out.\n\n Own Id: OTP-18507\n\n- If a user cancel alert with level warning is received during handshake make it\n be handled the same regardless of TLS version. If it is received in connection\n in TLS-1.3 regard it as an error as it is inappropriate.\n\n In TLS-1.3 all error alerts are considered FATAL regardless of legacy alert\n type. But make sure legacy type is printed in logs to not confuse users that\n are expecting the same legacy type as sent by peer.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-18531\n\n- Make `fail_if_no_peer_cert` default true if verify_peer is set on the server,\n otherwise the server will accept the connection if verify_peer is set and the\n user have forgot to set the fail_if_no_peer_cert and the client did not send a\n certificate.\n\n Own Id: OTP-18567\n\n- To make it easier to configure signature algorithms with algorithms that are\n moved from the default add the API function signature_algs/2 that lists\n possible values. Also make sha224 a non default value.\n\n Own Id: OTP-18572","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.9.1.5 - SSL Release Notes","ref":"notes.html#ssl-10-9-1-5"},{"type":"extras","doc":"* TLS-1.3 negotiation now uses SNI based options correctly instead of ignoring them.\n\n Own Id: OTP-19140","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.9.1.4 - SSL Release Notes","ref":"notes.html#ssl-10-9-1-4"},{"type":"extras","doc":"* Fix certificate authorities check so that CA closest to peer is not lost. It could manifest itself in a failed connection as the client failed to realize it had a valid certificate chain to send to the server.\n\n Own Id: OTP-19065 Aux Id: GH-8356, PR-8367","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.9.1.3 - SSL Release Notes","ref":"notes.html#ssl-10-9-1-3"},{"type":"extras","doc":"- ssl application will validate id-kp-serverAuth and id-kp-clientAuth extended\n key usage only in end entity certificates. public_key application will\n disallow \"anyExtendedKeyUsage\" for CA certificates that includes the extended\n key usage extension and marks it critical.\n\n Own Id: OTP-18739\n\n- Add missing export for connection_info() API type.\n\n Own Id: OTP-18886","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.9.1.2 - SSL Release Notes","ref":"notes.html#ssl-10-9-1-2"},{"type":"extras","doc":"- The API function \\`ssl:recv/3\\` has been tightened to disallow negative\n length, which has never been documented to work, but was passed through and\n caused strange errors.\n\n Own Id: OTP-18700 Aux Id: GH-7507\n\n- When a client initiated renegotiation was rejected and the client socket was\n in active mode the expected error message to the controlling process was not\n sent.\n\n Own Id: OTP-18712 Aux Id: GH-7431","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.9.1.1 - SSL Release Notes","ref":"notes.html#ssl-10-9-1-1"},{"type":"extras","doc":"- Added keylog information to all protocol versions in\n `ssl:connection_information/2`.\n\n Own Id: OTP-18643 Aux Id: ERIERL-932","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add RFC-6083 considerations for DTLS to enable gen_sctp based callback for the\n transport.\n\n Own Id: OTP-18618 Aux Id: ERIERL-932","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.9.1 - SSL Release Notes","ref":"notes.html#ssl-10-9-1"},{"type":"extras","doc":"- With this change, ssl:connection_information/2 returns correct keylog data\n after TLS1.3 key update.\n\n Own Id: OTP-18489\n\n- Client signature algorithm list input order is now honored again , it was\n accidently reversed by a previous fix.\n\n Own Id: OTP-18550","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.9 - SSL Release Notes","ref":"notes.html#ssl-10-9"},{"type":"extras","doc":"- Fixed that new `dtls` connections from the same client ip port combination\n works. If there is a process waiting for accept the new connection will\n connect to that, otherwise it will try to re-connect to the old server\n connection.\n\n Own Id: OTP-18371 Aux Id: GH-6160\n\n- When shutting down a node that uses SSL distribution (`-proto_dist inet_tls`),\n a confusing error message about an unexpected process exit was printed. This\n particular message is no longer generated.\n\n Own Id: OTP-18443 Aux Id: PR-6810","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- fixes the type spec for ssl:format_error/1\n\n Own Id: OTP-18366 Aux Id: PR-6565, GH-6506\n\n- Replace size/1 with either tuple_size/1 or byte_size/1\n\n The [`size/1`](`size/1`) BIF is not optimized by the JIT, and its use can\n result in worse types for Dialyzer.\n\n When one knows that the value being tested must be a tuple,\n [`tuple_size/1`](`tuple_size/1`) should always be preferred.\n\n When one knows that the value being tested must be a binary,\n [`byte_size/1`](`byte_size/1`) should be preferred. However,\n [`byte_size/1`](`byte_size/1`) also accepts a bitstring (rounding up size to a\n whole number of bytes), so one must make sure that the call to `byte_size/` is\n preceded by a call to [`is_binary/1`](`is_binary/1`) to ensure that bitstrings\n are rejected. Note that the compiler removes redundant calls to\n [`is_binary/1`](`is_binary/1`), so if one is not sure whether previous code\n had made sure that the argument is a binary, it does not harm to add an\n [`is_binary/1`](`is_binary/1`) test immediately before the call to\n [`byte_size/1`](`byte_size/1`).\n\n Own Id: OTP-18432 Aux Id:\n GH-6672,PR-6793,PR-6784,PR-6787,PR-6785,PR-6682,PR-6800,PR-6797,PR-6798,PR-6799,PR-6796,PR-6813,PR-6671,PR-6673,PR-6684,PR-6694,GH-6677,PR-6696,PR-6670,PR-6674","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.8.7 - SSL Release Notes","ref":"notes.html#ssl-10-8-7"},{"type":"extras","doc":"- Maximize compatibility by ignoring change_cipher_spec during handshake even if\n middle_box_mode is not negotiated (mandated by client)\n\n Own Id: OTP-18433 Aux Id: GH-6772\n\n- Move assert of middlebox message after an hello_retry_request to maximize\n interoperability. Does not changes semantics of the protocol only allows\n unexpected message delay from server.\n\n Own Id: OTP-18467 Aux Id: GH-6807","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.8.6 - SSL Release Notes","ref":"notes.html#ssl-10-8-6"},{"type":"extras","doc":"- With this change, tls_sender process is hibernated after sufficient\n inactivity.\n\n Own Id: OTP-18314 Aux Id: GH-6373\n\n- Correct handling of legacy schemes so that ECDSA certs using sha1 may be used\n for some TLS-1.3 configurations.\n\n Own Id: OTP-18332 Aux Id: GH-6435, PR-6435, ERL-6435\n\n- With this change, tls_sender does not cause logger crash upon key update.\n\n Own Id: OTP-18349","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Enhance warning message\n\n Own Id: OTP-18257 Aux Id: GH-6307\n\n- Provide server option to make certificate_authorities extension in the TLS-1.3\n servers certificate request optional. This will allow clients to send\n incomplete chains that may be reconstructable and thereby verifiable by the\n server, but that would not adhere to the certificate_authorities extension.\n\n Own Id: OTP-18267 Aux Id: PR-6228, GH-6106\n\n- If the `verify_fun` handles four arguments the DER cert will be supplied as\n one of the arguments.\n\n Own Id: OTP-18302 Aux Id: ERIERL-867","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.8.5 - SSL Release Notes","ref":"notes.html#ssl-10-8-5"},{"type":"extras","doc":"- Fixes handling of symlinks in cacertfile option.\n\n Own Id: OTP-18266 Aux Id: GH-6328","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.8.4 - SSL Release Notes","ref":"notes.html#ssl-10-8-4"},{"type":"extras","doc":"- Reject unexpected application data in all relevant places for all TLS\n versions. Also, handle TLS-1.3 middlebox compatibility with more care. This\n will make malicious connections fail early and further, mitigate possible DoS\n attacks, that would be caught by the handshake timeout.\n\n Thanks to Aina Toky Rasoamanana and Olivier Levillain from Télécom SudParis\n for alerting us of the issues in our implementation.\n\n Own Id: OTP-18044\n\n- With this change, value of cacertfile option will be adjusted before loading\n certs from the file. Adjustments include converting relative paths to absolute\n and converting symlinks to actual file path.\n\n Thanks to Marcus Johansson\n\n Own Id: OTP-18099 Aux Id: PR-6287\n\n- In TLS-1.3, if chain certs are missing (so server auth domain adherence can\n not be determined) send peer cert and hope the server is able to recreate a\n chain in its auth domain.\n\n Own Id: OTP-18191 Aux Id: GH-6105\n\n- Make sure periodical refresh of CA certificate files repopulates cache\n properly.\n\n Own Id: OTP-18195\n\n- Correct internal CRL cache functions to use internal format consistently.\n\n Own Id: OTP-18203 Aux Id: PR-5996\n\n- Incorrect handling of client middlebox negotiation for TLS-1.3 could result in\n that a TLS-1.3 server would not use middlebox mode although the client was\n expecting it too and failing the negotiation with unexpected message.\n\n Own Id: OTP-18219 Aux Id: GH-6241, PR-6249\n\n- If the \"User\" process, the process starting the TLS connection, gets killed in\n the middle of spawning the dynamic connection tree make sure we do not leave\n any processes behind.\n\n Own Id: OTP-18233 Aux Id: GH-6244, PR-6270","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- A vulnerability has been discovered and corrected. It is registered as\n CVE-2022-37026 \"Client Authentication Bypass\". Corrections have been released\n on the supported tracks with patches 23.3.4.15, 24.3.4.2, and 25.0.2. The\n vulnerability might also exist in older OTP versions. We recommend that\n impacted users upgrade to one of these versions or later on the respective\n tracks. OTP 25.1 would be an even better choice. Impacted are those who are\n running an ssl/tls/dtls server using the ssl application either directly or\n indirectly via other applications. For example via inets (httpd), cowboy, etc.\n Note that the vulnerability only affects servers that request client\n certification, that is sets the option \\{verify, verify_peer\\}.\n\n Own Id: OTP-18241","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.8.3 - SSL Release Notes","ref":"notes.html#ssl-10-8-3"},{"type":"extras","doc":"- The link to crypto:engine_load refered the function with wrong arity.\n\n Own Id: OTP-18173","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.8.2 - SSL Release Notes","ref":"notes.html#ssl-10-8-2"},{"type":"extras","doc":"- Improved handling of unexpected messages during the handshake, taking the\n right action for unexpected messages.\n\n Own Id: OTP-18145","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.8.1 - SSL Release Notes","ref":"notes.html#ssl-10-8-1"},{"type":"extras","doc":"- When a TLS-1.3 enabled client tried to talk to a TLS-1.2 server that coalesces\n TLS-1.2 handshake message over one TLS record, the connection could fail due\n to some message being handled in the wrong state, this has been fixed.\n\n Own Id: OTP-18087 Aux Id: GH-5961\n\n- Correctly handles supported protocol version change from default to something\n else by sni_fun supplied to ssl:handshake/\\[2,3] together with a TCP-socket\n (so called upgrade).\n\n Own Id: OTP-18100 Aux Id: GH-5985\n\n- Also, TLS-1.3 should respond with a protocol version alert if previous\n versions, that are supported but not configured, are attempted.\n\n Own Id: OTP-18129 Aux Id: GH-5950","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.8 - SSL Release Notes","ref":"notes.html#ssl-10-8"},{"type":"extras","doc":"- When a TLS-1.3 enabled client tried to talk to a TLS-1.2 server that coalesces\n TLS-1.2 handshake message over one TLS record, the connection could fail due\n to some message being handled in the wrong state, this has been fixed.\n\n Own Id: OTP-18087 Aux Id: GH-5961\n\n- Fixed tls-1.3 session ticket lifetime which was discarded to quickly before.\n\n Own Id: OTP-18092 Aux Id: PR-5959","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- With this change, it is possible to provide several certificates. Most\n appropriate will be selected based on negotiated properties.\n\n Own Id: OTP-15993 Aux Id: GH-4143\n\n- Add options for users to be able to set spawn_opts for TLS processes (sender\n and receiver) this may be useful for tuning trade-offs between CPU and Memory\n usage.\n\n Own Id: OTP-17855 Aux Id: PR-5328\n\n- Allow key file passwords to be input as a single binary, that is we change the\n data type to be the more for the purpose logical data type iodata() instead of\n string().\n\n Own Id: OTP-17890\n\n- Logging enhancement, add location information to the warning log message.\n\n Own Id: OTP-18000 Aux Id: PR-5790\n\n- Now also accepts the signature_algs_cert option in TLS-1.2 configuration.\n\n Own Id: OTP-18014\n\n- Handle certificate selection correctly for server fallback and certificate\n authorities considerations.\n\n Own Id: OTP-18045 Aux Id: ERIERL-792, OTP-15993\n\n- Enhance handling of handshake decoding errors, especially for certificate\n authorities extension to ensure graceful termination.\n\n Own Id: OTP-18085","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.7.3.9 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-9"},{"type":"extras","doc":"- When a client initiated renegotiation was rejected and the client socket was\n in active mode the expected error message to the controlling process was not\n sent.\n\n Own Id: OTP-18712 Aux Id: GH-7431","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7.3.8 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-8"},{"type":"extras","doc":"- Added keylog information to all protocol versions in\n `ssl:connection_information/2`.\n\n Own Id: OTP-18643 Aux Id: ERIERL-932","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add RFC-6083 considerations for DTLS to enable gen_sctp based callback for the\n transport.\n\n Own Id: OTP-18618 Aux Id: ERIERL-932","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.7.3.7 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-7"},{"type":"extras","doc":"- Client signature algorithm list input order is now honored again , it was\n accidently reversed by a previous fix.\n\n Own Id: OTP-18550","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7.3.6 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-6"},{"type":"extras","doc":"- Maximize compatibility by ignoring change_cipher_spec during handshake even if\n middle_box_mode is not negotiated (mandated by client)\n\n Own Id: OTP-18433 Aux Id: GH-6772\n\n- Move assert of middlebox message after an hello_retry_request to maximize\n interoperability. Does not changes semantics of the protocol only allows\n unexpected message delay from server.\n\n Own Id: OTP-18467 Aux Id: GH-6807","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.7.3.5 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-5"},{"type":"extras","doc":"- Fixes handling of symlinks in cacertfile option.\n\n Own Id: OTP-18266 Aux Id: GH-6328","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7.3.4 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-4"},{"type":"extras","doc":"- With this change, value of cacertfile option will be adjusted before loading\n certs from the file. Adjustments include converting relative paths to absolute\n and converting symlinks to actual file path.\n\n Thanks to Marcus Johansson\n\n Own Id: OTP-18099 Aux Id: PR-6287\n\n- Incorrect handling of client middlebox negotiation for TLS-1.3 could result in\n that a TLS-1.3 server would not use middlebox mode although the client was\n expecting it too and failing the negotiation with unexpected message.\n\n Own Id: OTP-18219 Aux Id: GH-6241, PR-6249\n\n- If the \"User\" process, the process starting the TLS connection, gets killed in\n the middle of spawning the dynamic connection tree make sure we do not leave\n any processes behind.\n\n Own Id: OTP-18233 Aux Id: GH-6244, PR-6270","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7.3.3 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-3"},{"type":"extras","doc":"- Reject unexpected application data in all relevant places for all TLS\n versions. Also, handle TLS-1.3 middlebox compatibility with more care. This\n will make malicious connections fail early and further, mitigate possible DoS\n attacks, that would be caught by the handshake timeout.\n\n Thanks to Aina Toky Rasoamanana and Olivier Levillain from Télécom SudParis\n for alerting us of the issues in our implementation.\n\n Own Id: OTP-18044\n\n- The link to crypto:engine_load refered the function with wrong arity.\n\n Own Id: OTP-18173\n\n- Make sure periodical refresh of CA certificate files repopulates cache\n properly.\n\n Own Id: OTP-18195","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7.3.2 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-2"},{"type":"extras","doc":"- Improved handling of unexpected messages during the handshake, taking the\n right action for unexpected messages.\n\n Own Id: OTP-18145","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7.3.1 - SSL Release Notes","ref":"notes.html#ssl-10-7-3-1"},{"type":"extras","doc":"- When a TLS-1.3 enabled client tried to talk to a TLS-1.2 server that coalesces\n TLS-1.2 handshake message over one TLS record, the connection could fail due\n to some message being handled in the wrong state, this has been fixed.\n\n Own Id: OTP-18087 Aux Id: GH-5961\n\n- Fixed tls-1.3 session ticket lifetime which was discarded to quickly before.\n\n Own Id: OTP-18092 Aux Id: PR-5959\n\n- Correctly handles supported protocol version change from default to something\n else by sni_fun supplied to ssl:handshake/\\[2,3] together with a TCP-socket\n (so called upgrade).\n\n Own Id: OTP-18100 Aux Id: GH-5985\n\n- Also, TLS-1.3 should respond with a protocol version alert if previous\n versions, that are supported but not configured, are attempted.\n\n Own Id: OTP-18129 Aux Id: GH-5950","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Enhance handling of handshake decoding errors, especially for certificate\n authorities extension to ensure graceful termination.\n\n Own Id: OTP-18085","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.7.3 - SSL Release Notes","ref":"notes.html#ssl-10-7-3"},{"type":"extras","doc":"- Client certification could fail if TLS-1.3 enabled client negotiated TLS-1.2\n connection with the server, this is due to the wrong version being used when\n decoding the certificate request message from the server.\n\n Own Id: OTP-18028 Aux Id: GH-5835\n\n- socket option packet_size was not handled in ssl:setops/2 and ssl:getotps/2\n\n Own Id: OTP-18062 Aux Id: GH-5898\n\n- Remove legacy code to fix interoperability with new socket inet_backend.\n\n Own Id: OTP-18071 Aux Id: GH-5930","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7.2 - SSL Release Notes","ref":"notes.html#ssl-10-7-2"},{"type":"extras","doc":"- With this change, potential hanging of pre TLS1.3 client receiving OSCP staple\n message is avoided.\n\n Own Id: OTP-17994","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7.1 - SSL Release Notes","ref":"notes.html#ssl-10-7-1"},{"type":"extras","doc":"- Client certification could fail for TLS-1.3 servers that did not include the\n certificate_authorities extension in its certificate request message.\n\n Own Id: OTP-17971 Aux Id: GH-5783","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.7 - SSL Release Notes","ref":"notes.html#ssl-10-7"},{"type":"extras","doc":"- Improved error handling.\n\n Own Id: OTP-17759 Aux Id: GH-5367\n\n- Before this change, net_kernel used with TLS distribution might be leaking\n processes in case of connectivity issues.\n\n Own Id: OTP-17815 Aux Id: GH-5332\n\n- Fix makefile dependency bugs.\n\n Own Id: OTP-17847 Aux Id: PR-5574 GH-5548\n\n- Make sure the TLS sender process handles explicit calls to\n erlang:disconnect_node properly, avoiding potential hanging problems in\n net_kernel.\n\n Own Id: OTP-17929 Aux Id: GH-5708","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add support for TLS-1.3 certificate_authorities extension. And process\n certificate_authorities field in pre-TLS-1.3 certificate requests.\n\n Own Id: OTP-15719\n\n- Support password fun for protected keyfiles in ssl:connect function.\n\n Own Id: OTP-17816 Aux Id: PR-5607\n\n- Add in some cases earlier detection of possible DoS attacks by malicious\n clients sending unexpected TLS messages instead of the client hello. Note that\n such attacks are already mitigated by providing a timeout for the TLS\n handshake.\n\n Own Id: OTP-17903","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.6.1 - SSL Release Notes","ref":"notes.html#ssl-10-6-1"},{"type":"extras","doc":"- Improve SNI (server name indication) handling so that protocol version can be\n selected with regards to SNI. Also, make sure that\n ssl:connection_information/1 returns the correct SNI value.\n\n Own Id: OTP-17794 Aux Id: GH-5341, GH-4450\n\n- Fixed cipher suite listing functions so that the listing of all cipher suites\n will be complete. Another fix for cipher suite handling in OTP-24.1\n accidentally excludes a few cipher suites from the listing of all cipher\n suites.\n\n Own Id: OTP-17829 Aux Id: ERIERL-708\n\n- Reenable legacy cipher suite TLS_RSA_WITH_3DES_EDE_CBC_SHA for explicit\n configuration in TLS-1.2, not supported by default.\n\n Own Id: OTP-17879 Aux Id: GH-5624","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Avoid unnecessary logs by better adjusting the tls_sender process to the new\n supervisor structure in OTP-24.2\n\n Own Id: OTP-17831","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.6 - SSL Release Notes","ref":"notes.html#ssl-10-6"},{"type":"extras","doc":"- Allow re-connect on DTLS sockets\n\n Can happen when a computer reboots and connects from the same client port\n without the server noticing should be allowed according to RFC.\n\n Own Id: OTP-17411 Aux Id: ERL-1203, GH-4393\n\n- Fix tls and non-tls distribution to use erl_epmd:address_please to figure out\n if IPv4 or IPv6 addresses should be used when connecting to the remote node.\n\n Before this fix, a dns lookup of the remote node hostname determined which IP\n version was to be used which meant that the hostname had to resolve to a valid\n ip address.\n\n Own Id: OTP-17809 Aux Id: PR-5337 GH-5334","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Use supervisor significant child to manage tls connection process and tls\n sender process dependency.\n\n Own Id: OTP-17417\n\n- Random generation adjustment for TLS1.3\n\n Own Id: OTP-17699\n\n- Allow any \\{03,XX\\} TLS record version in the client hello for maximum\n interoperability\n\n Own Id: OTP-17761 Aux Id: GH-5380","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.5.3 - SSL Release Notes","ref":"notes.html#ssl-10-5-3"},{"type":"extras","doc":"- Correct typo of ECC curve name in signature algorithm handling. Will make the\n signature algorithm ecdsa_secp521r1_sha512 succeed.\n\n Own Id: OTP-17756 Aux Id: GH-5383, PR-5397\n\n- Suppress authenticity warning when option verify_none is explicitly supplied.\n\n Own Id: OTP-17757 Aux Id: GH-5352, PR-5395","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.5.2 - SSL Release Notes","ref":"notes.html#ssl-10-5-2"},{"type":"extras","doc":"- Fix TLS-1.2 RSA-PSS negotiation and also fix broken certificate request\n message for pre-TLS-1.3 servers.\n\n Own Id: OTP-17688 Aux Id: GH-5255\n\n- Fix CRL issuer verification that under some circumstances could fail with a\n function_clause error.\n\n Own Id: OTP-17723 Aux Id: GH-5300","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.5.1 - SSL Release Notes","ref":"notes.html#ssl-10-5-1"},{"type":"extras","doc":"- Before that change, TLS downgrade could occasionally fail when data intended\n for downgraded socket were delivered together with CLOSE_NOTIFY alert to ssl\n app.\n\n Own Id: OTP-17393\n\n- Avoid re-encoding of decoded certificates. This could cause unexpected\n failures as some subtle encoding errors can be tolerated when decoding but\n hence creating another sequence of bytes if the decoded value is re-encoded.\n\n Own Id: OTP-17657\n\n- Fix possible process leak when the process doing ssl:transport_accept dies\n before initiating the TLS handshake.\n\n Own Id: OTP-17666 Aux Id: GH-5239\n\n- Fix dtls memory leak, the replay window code was broken.\n\n Own Id: OTP-17670 Aux Id: GH-5224","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.5 - SSL Release Notes","ref":"notes.html#ssl-10-5"},{"type":"extras","doc":"- Fix Makefile dependency generation to work no matter what the `ERL_TOP` folder\n is called.\n\n Own Id: OTP-17423 Aux Id: GH-4823 PR-4829\n\n- If trying to downgrade a TLS-1.3 connection to a plain TCP connection,\n possible TLS-1.3 session ticket messages will be ignored in the \"downgrade\"\n state while waiting for the close notify alert.\n\n Own Id: OTP-17517 Aux Id: GH-5009\n\n- Corrected error handling to correctly generate an insufficient security alert\n when there are no suitable groups that can be negotiated in TLS-1.3 instead of\n crashing resulting in an internal error alert.\n\n Own Id: OTP-17521\n\n- Properly handle default session data storage.\n\n When a client tries to reuse an expired session the default server storage\n handling would crash losing other session data. This would cause a error\n report and possible loss of abbreviated handshakes.\n\n Own Id: OTP-17635 Aux Id: GH-5192","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add support for RSA-PSS-PSS signatures and signature_algorithms_cert in\n TLS-1.2. This is a TLS-1.3 RFC requirement to backport this functionality.\n\n Own Id: OTP-16590 Aux Id: ERL-625, GH-5029\n\n- Use inet:monitor/1 to monitor listen-sockets so that we are compatible with\n the new socket backend for gen_tcp.\n\n Own Id: OTP-17392 Aux Id: PR-5050\n\n- Enhance ssl:prf/4 handling and testing\n\n Own Id: OTP-17464\n\n- Enhanced cipher suite filtering functionality, making sure TLS-1.3 and TLS-1.2\n cipher suites can be supported correctly together even when TLS-1.2 anonymous\n ciphers are included.\n\n Own Id: OTP-17501 Aux Id: GH-4978\n\n- Enhance gracefulness especially in TLS-1.3\n\n Own Id: OTP-17530","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.4.2 - SSL Release Notes","ref":"notes.html#ssl-10-4-2"},{"type":"extras","doc":"- Handle cross-signed root certificates when old root expired as reported in\n GH-4877.\n\n Own Id: OTP-17475 Aux Id: GH-4877\n\n- The signature selection algorithm has been changed to also verify if the\n client supports signatures using the elliptic curve of the server's\n public/private key pair. This change fixes #4958.\n\n Own Id: OTP-17529 Aux Id: PR-4979, GH-4958","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Slight optimization of certificate decoding.\n\n Own Id: OTP-17150 Aux Id: GH-4877","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.4.1 - SSL Release Notes","ref":"notes.html#ssl-10-4-1"},{"type":"extras","doc":"- Fix cache invalidation problem for CA certs provided by the cacertfile option.\n\n Own Id: OTP-17435 Aux Id: ERIERL-653","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.4 - SSL Release Notes","ref":"notes.html#ssl-10-4"},{"type":"extras","doc":"- Missing runtime dependencies has been added to this application.\n\n Own Id: OTP-17243 Aux Id: PR-4557\n\n- TLS handshake should fail if OCSP staple is requested but missing. Note that\n OCSP support is still considered experimental and only partially implemented.\n\n Own Id: OTP-17343","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Removed ssl:ssl_accept/1,2,3 and ssl:cipher:suites/0,1 use ssl:handshake/1,2,3\n and ssl:cipher_suites/2,3 instead.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-16974\n\n- Make TLS handshakes in Erlang distribution concurrent.\n\n Own Id: OTP-17044 Aux Id: PR-2654\n\n- Randomize internal `{active,n}` optimization when running Erlang distribution\n over TLS to spread RAM/CPU spike that may occur when starting up a big\n cluster.\n\n Own Id: OTP-17117 Aux Id: PR-2933\n\n- TLS connections now support EdDSA certificates.\n\n Own Id: OTP-17142 Aux Id: PR-4756, GH-4637, GH-4650\n\n- Enhance documentation and logging of certificate handling.\n\n Own Id: OTP-17384 Aux Id: GH-4800","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.3.1.5 - SSL Release Notes","ref":"notes.html#ssl-10-3-1-5"},{"type":"extras","doc":"- Correct corner case of unexpected message handling for pre TLS-1.3 versions,\n could cause \"late failure\" and make the server dependent on its handshake\n timeout to prevent possible DoS attacks.\n\n Own Id: OTP-18224","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.3.1.4 - SSL Release Notes","ref":"notes.html#ssl-10-3-1-4"},{"type":"extras","doc":"- The link to crypto:engine_load refered the function with wrong arity.\n\n Own Id: OTP-18173","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.3.1.3 - SSL Release Notes","ref":"notes.html#ssl-10-3-1-3"},{"type":"extras","doc":"- Improved handling of unexpected messages during the handshake, taking the\n right action for unexpected messages.\n\n Own Id: OTP-18145","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.3.1.2 - SSL Release Notes","ref":"notes.html#ssl-10-3-1-2"},{"type":"extras","doc":"- Handle cross-signed root certificates when old root expired as reported in\n GH-4877.\n\n Own Id: OTP-17475 Aux Id: GH-4877\n\n- The signature selection algorithm has been changed to also verify if the\n client supports signatures using the elliptic curve of the server's\n public/private key pair. This change fixes #4958.\n\n Own Id: OTP-17529 Aux Id: PR-4979, GH-4958","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Slight optimization of certificate decoding.\n\n Own Id: OTP-17150 Aux Id: GH-4877","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.3.1.1 - SSL Release Notes","ref":"notes.html#ssl-10-3-1-1"},{"type":"extras","doc":"- Fix cache invalidation problem for CA certs provided by the cacertfile option.\n\n Own Id: OTP-17435 Aux Id: ERIERL-653","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.3.1 - SSL Release Notes","ref":"notes.html#ssl-10-3-1"},{"type":"extras","doc":"- Retain backwards compatible behavior of verify_fun when handling incomplete\n chains that are not verifiable.\n\n Own Id: OTP-17296 Aux Id: GH-4682\n\n- Avoid server session handler crash, this will increase session ruse\n opportunities.\n\n Own Id: OTP-17348 Aux Id: ERIERL-641","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.3 - SSL Release Notes","ref":"notes.html#ssl-10-3"},{"type":"extras","doc":"- Fix CRL handling that previously could fail to find the issuer cert under some\n circumstances.\n\n Own Id: OTP-17261 Aux Id: GH-4589\n\n- TLS-1.3 client could, under some circumstances, select an incorrect algorithm\n to sign the certificate verification message causing a TLS Decrypt Alert being\n issued by the server.\n\n Own Id: OTP-17281 Aux Id: GH-4620\n\n- Correct handling of default values for emulated socket options and retain the\n order of the ssl options list to ensure backwards compatible behavior if\n options should be set more than once.\n\n Own Id: OTP-17282","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Enhance pre TLS-1.3 session handling so the client and server side handling is\n completely separated and client disregards oldest session when reaching max\n limit of the session table.\n\n Own Id: OTP-16876\n\n- This change implements the early data feature for TLS 1.3 clients.\n\n TLS 1.3 allows clients to send data in the first flight using a Pre-Shared Key\n to authenticate the server and to encrypt the early data.\n\n Own Id: OTP-16985\n\n- This change implements the early data feature for TLS 1.3 servers.\n\n Own Id: OTP-17042","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.2.4.4 - SSL Release Notes","ref":"notes.html#ssl-10-2-4-4"},{"type":"extras","doc":"- Improved handling of unexpected messages during the handshake, taking the\n right action for unexpected messages.\n\n Own Id: OTP-18145","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.2.4.3 - SSL Release Notes","ref":"notes.html#ssl-10-2-4-3"},{"type":"extras","doc":"- Fix cache invalidation problem for CA certs provided by the cacertfile option.\n\n Own Id: OTP-17435 Aux Id: ERIERL-653","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.2.4.2 - SSL Release Notes","ref":"notes.html#ssl-10-2-4-2"},{"type":"extras","doc":"- Fix handling of emulated socket options, the previous patch was incomplete,\n\n Own Id: OTP-17305","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.2.4.1 - SSL Release Notes","ref":"notes.html#ssl-10-2-4-1"},{"type":"extras","doc":"- Backport of OTP-17282\n\n Correct handling of default values for emulated socket options and retain the\n order of the ssl options list to ensure backwards compatible behavior if\n options should be set more than once.\n\n Own Id: OTP-17289 Aux Id: GH-4585","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.2.4 - SSL Release Notes","ref":"notes.html#ssl-10-2-4"},{"type":"extras","doc":"- Enhance logging option log_level to support none and all, also restore\n backwards compatibility for log_alert option.\n\n Own Id: OTP-17228 Aux Id: ERIERL-614","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.2.3 - SSL Release Notes","ref":"notes.html#ssl-10-2-3"},{"type":"extras","doc":"- Avoid race when the first two upgrade server handshakes (that is servers that\n use a gen_tcp socket as input to ssl:handshake/2,3) start close to each other.\n Could lead to that one of the handshakes would fail.\n\n Own Id: OTP-17190 Aux Id: ERIERL-606","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 10.2.2 - SSL Release Notes","ref":"notes.html#ssl-10-2-2"},{"type":"extras","doc":"- Avoid that upgrade (from TCP to TLS) servers starts multiple session cache\n handlers for the same server. This applies to Erlang distribution over TLS\n servers.\n\n Own Id: OTP-17139 Aux Id: ERL-1458, OTP-16239\n\n- Legacy cipher suites defined before TLS-1.2 (but still supported) should be\n possible to use in TLS-1.2. They where accidentally excluded for available\n cipher suites for TLS-1.2 in OTP-23.2.2.\n\n Own Id: OTP-17174 Aux Id: ERIERL-597","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Enable Erlang distribution over TLS to run TLS-1.3, although TLS-1.2 will\n still be default.\n\n Own Id: OTP-16239 Aux Id: ERL-1458, OTP-17139","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.2.1 - SSL Release Notes","ref":"notes.html#ssl-10-2-1"},{"type":"extras","doc":"- Fix CVE-2020-35733 this only affects ssl-10.2 (OTP-23.2). This vulnerability\n could enable a man in the middle attack using a fake chain to a known trusted\n ROOT. Also limits alternative chain handling, for handling of possibly\n extraneous certs, to improve memory management.\n\n Own Id: OTP-17098","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add support for AES CCM based cipher suites defined in RFC 7251\n\n Also Correct cipher suite name conversion to OpenSSL names. A few names where\n corrected earlier in OTP-16267 For backwards compatible reasons we support\n usage of openSSL names for cipher suites. Mostly anonymous suites names where\n incorrect, but also some legacy suites.\n\n Own Id: OTP-17100","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.2 - SSL Release Notes","ref":"notes.html#ssl-10-2"},{"type":"extras","doc":"- SSL's Erlang Distribution Protocol modules inet_tls_dist and inet6_tls_dist\n lacked a callback function, so the start flag \"-dist_listen false\" did not\n work, which has now been fixed.\n\n Own Id: OTP-15126 Aux Id: ERL-1375\n\n- Correct OpenSSL names for newer cipher suites using DHE in their name that\n accidentally got the wrong value when fixing other older names using EDH\n instead.\n\n Own Id: OTP-16267 Aux Id: ERIERL-571, ERIERL-477\n\n- This change improves the handling of DTLS listening dockets, making it\n possible to open multiple listeners on the same port with different IP\n addresses.\n\n Own Id: OTP-16849 Aux Id: ERL-1339\n\n- Fix a bug that causes cross-build failure.\n\n This change excludes the ssl.d dependency file from the source tarballs.\n\n Own Id: OTP-16921\n\n- This change fixes ssl:peername/1 when called on a DTLS client socket.\n\n Own Id: OTP-16923 Aux Id: ERL-1341, PR-2786\n\n- Retain emulation of active once on a closed socket to behave as before 23.1\n\n Own Id: OTP-17018 Aux Id: ERL-1409\n\n- Corrected server session cache entry deletion pre TLS-1.3. May increase\n session reuse.\n\n Own Id: OTP-17019 Aux Id: ERL-1412","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Handle extraneous certs in certificate chains as well as chains that are\n incomplete but can be reconstructed or unordered chains. The cert and certfile\n options will now accept a list of certificates so that the user may specify\n the chain explicitly.\n\n Also, the default value of the depth option has been increased to allow longer\n chains by default.\n\n Own Id: OTP-16277\n\n- This change implements optional NSS-style keylog in\n ssl:connection_information/2 for debugging purposes.\n\n The keylog contains various TLS secrets that can be loaded in Wireshark to\n decrypt TLS packets.\n\n Own Id: OTP-16445 Aux Id: PR-2823\n\n- Use new gen_statem feature of changing callback mode to improve code\n maintainability.\n\n Own Id: OTP-16529\n\n- The handling of Service Name Indication has been aligned with RFC8446.\n\n Own Id: OTP-16762\n\n- Add explicit session reuse option to TLS clients for pre TLS-1.3 sessions.\n Also, add documentation to Users Guide for such sessions.\n\n Own Id: OTP-16893","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.1 - SSL Release Notes","ref":"notes.html#ssl-10-1"},{"type":"extras","doc":"- If a passive socket is created, ssl:recv/2,3 is never called and then the peer\n closes the socket the controlling process will no longer receive an active\n close message.\n\n Own Id: OTP-16697 Aux Id: ERIERL-496\n\n- Data deliver with ssl:recv/2,3 could fail for when using packet mode. This has\n been fixed by correcting the flow control handling of passive sockets when\n packet mode is used.\n\n Own Id: OTP-16764\n\n- This change fixes a potential man-in-the-middle vulnerability when the ssl\n client is configured to automatically handle session tickets\n (\\{session_tickets, auto\\}).\n\n Own Id: OTP-16765\n\n- Fix the internal handling of options 'verify' and 'verify_fun'.\n\n This change fixes a vulnerability when setting the ssl option 'verify' to\n verify_peer in a continued handshake won't take any effect resulting in the\n acceptance of expired peer certificates.\n\n Own Id: OTP-16767 Aux Id: ERIERL-512\n\n- This change fixes the handling of stateless session tickets when anti-replay\n is enabled.\n\n Own Id: OTP-16776 Aux Id: ERL-1316\n\n- Fix a crash due to the faulty handling of stateful session tickets received by\n servers expecting stateless session tickets.\n\n This change also improves the handling of faulty/invalid tickets.\n\n Own Id: OTP-16777 Aux Id: ERL-1317\n\n- Correct flow ctrl checks from OTP-16764 to work as intended. Probably will not\n have a noticeable affect but will make connections more well behaved under\n some circumstances.\n\n Own Id: OTP-16837 Aux Id: ERL-1319, OTP-16764\n\n- Distribution over TLS could exhibit livelock-like behaviour when there is a\n constant stream of distribution messages. Distribution data is now chunked\n every 16 Mb to avoid that.\n\n Own Id: OTP-16851 Aux Id: PR-2703","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Implement the cookie extension for TLS 1.3.\n\n Own Id: OTP-15855\n\n- Experimental OCSP client support.\n\n Own Id: OTP-16448\n\n- TLS 1.0 -TLS-1.2 sessions tables now have a absolute max value instead of\n using a shrinking mechanism when reaching the limit. To avoid out of memory\n problems under heavy load situations. Note that this change infers that\n implementations of ssl_session_cache_api needs to implement the size function\n (introduce in OTP 19) for session reuse to be optimally utilized.\n\n Own Id: OTP-16802 Aux Id: ERIERL-516","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 10.0 - SSL Release Notes","ref":"notes.html#ssl-10-0"},{"type":"extras","doc":"- Fix a bug that causes cross-build failure.\n\n This change excludes the ssl.d dependency file from the source tar balls.\n\n Own Id: OTP-16562 Aux Id: ERL-1168\n\n- Correct translation of OpenSSL legacy names for two legacy cipher suites\n\n Own Id: OTP-16573 Aux Id: ERIERL-477\n\n- Correct documentation for PSK identity and SRP username.\n\n Own Id: OTP-16585\n\n- Make sure client hostname check is run when client uses its own verify_fun\n\n Own Id: OTP-16626 Aux Id: ERL-1232\n\n- Improved signature selection mechanism in TLS 1.3 for increased\n interoperability.\n\n Own Id: OTP-16638 Aux Id: ERL-1206","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Drop support for SSL-3.0. Support for this legacy TLS version has not been\n enabled by default since OTP 19. Now all code to support it has been removed,\n that is SSL-3.0 protocol version can not be used and is considered invalid.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-14790\n\n- Added support for RSA-PSS signature schemes\n\n Own Id: OTP-15247\n\n- Improve interoperability by implementing the middlebox compatibility mode.\n\n The middlebox compatibility mode makes the TLS 1.3 handshake look more like a\n TLS 1.2 handshake and increases the chance of successfully establishing TLS\n 1.3 connections through legacy middleboxes.\n\n Own Id: OTP-15589\n\n- Utilize new properties of\n [`erlang:dist_ctrl_get_data()`](`erlang:dist_ctrl_get_data/1`) for performance\n improvement of Erlang distribution over TLS.\n\n Own Id: OTP-16127 Aux Id: OTP-15618\n\n- Calls of deprecated functions in the\n [Old Crypto API](`e:crypto:new_api.md#the-old-api`) are replaced by calls of\n their [substitutions](`e:crypto:new_api.md#the-new-api`).\n\n Own Id: OTP-16346\n\n- Implement cipher suite TLS_AES_128_CCM_8_SHA256.\n\n Own Id: OTP-16391\n\n- This change adds TLS-1.3 to the list of default supported versions. That is,\n TLS-1.3 and TLS-1.2 are configured when ssl option 'versions' is not\n explicitly set.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-16400\n\n- Refactored the internal handling of deprecated and removed functions.\n\n Own Id: OTP-16469\n\n- Extended ssl:versions so that it lists supported, available and implemented\n TLS/DTLS versions.\n\n Own Id: OTP-16519\n\n- Added new option exclusive for ssl:cipher_suites/2,3\n\n Own Id: OTP-16532\n\n- Avoid DoS attack against stateful session_tickets by making session ticket ids\n unpredictable.\n\n Own Id: OTP-16533\n\n- Add support for the max_fragment_length extension (RFC 6066).\n\n Own Id: OTP-16547 Aux Id: PR-2547\n\n- Add srp_username in ssl:connection_info, update the document with types of\n this function.\n\n Own Id: OTP-16584","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.6.2.3 - SSL Release Notes","ref":"notes.html#ssl-9-6-2-3"},{"type":"extras","doc":"- Correct flow ctrl checks from OTP-16764 to work as intended. Probably will not\n have a noticeable affect but will make connections more well behaved under\n some circumstances.\n\n Own Id: OTP-16837 Aux Id: ERL-1319, OTP-16764\n\n- Fix a bug that causes cross-build failure.\n\n This change excludes the ssl.d dependency file from the source tar balls.\n\n Own Id: OTP-16921","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.6.2.2 - SSL Release Notes","ref":"notes.html#ssl-9-6-2-2"},{"type":"extras","doc":"- Data deliver with ssl:recv/2,3 could fail for when using packet mode. This has\n been fixed by correcting the flow control handling of passive sockets when\n packet mode is used.\n\n Own Id: OTP-16764\n\n- Fix the internal handling of options 'verify' and 'verify_fun'.\n\n This change fixes a vulnerability when setting the ssl option 'verify' to\n verify_peer in a continued handshake won't take any effect resulting in the\n acceptance of expired peer certificates.\n\n Own Id: OTP-16767 Aux Id: ERIERL-512","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.6.2.1 - SSL Release Notes","ref":"notes.html#ssl-9-6-2-1"},{"type":"extras","doc":"- If a passive socket is created, ssl:recv/2,3 is never called and then the peer\n closes the socket the controlling process will no longer receive an active\n close message.\n\n Own Id: OTP-16697 Aux Id: ERIERL-496","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.6.2 - SSL Release Notes","ref":"notes.html#ssl-9-6-2"},{"type":"extras","doc":"- Fix timing bug that could cause ssl sockets to become unresponsive after an\n ssl:recv/3 call timed out\n\n Own Id: OTP-16619 Aux Id: ERL-1213","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.6.1 - SSL Release Notes","ref":"notes.html#ssl-9-6-1"},{"type":"extras","doc":"- Correct error handling when the partial_chain fun claims a certificate to be\n the trusted cert that is not part of the chain. This bug would hide the\n appropriate alert generating an \"INTERNAL_ERROR\" alert instead.\n\n Own Id: OTP-16567 Aux Id: ERIERL-481","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.6 - SSL Release Notes","ref":"notes.html#ssl-9-6"},{"type":"extras","doc":"- Correct handling of TLS record limit in TLS-1.3. The max value differs from\n previous versions. Also the payload data max record check was broken, that is\n record overflow problems could occur if user sent large amounts of data.\n\n Own Id: OTP-16258\n\n- Correct close handling for DTLS\n\n Own Id: OTP-16348 Aux Id: ERL-1110\n\n- Fix ssl:getstat/1-2 to also work for DTLS sockets\n\n Own Id: OTP-16352 Aux Id: ERL-1099\n\n- Correct internal handling och socket active mode to avoid reviving TCP data\n aimed for a downgraded TLS socket.\n\n Own Id: OTP-16425\n\n- When using the host name as fallback for SNI (server name indication) strip a\n possible trailing dot that is allowed in a host name but not in the SNI. Also\n if the server receives a SNI with a trailing dot send an UNRECOGNIZED_NAME\n alert.\n\n Own Id: OTP-16437 Aux Id: ERL-1135\n\n- Immediately remove session entries if handshake is abruptly closed at\n transport level.\n\n Own Id: OTP-16479","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Implementation of the key and initialization vector update feature, and\n general hardening of TLS 1.3.\n\n There are cryptographic limits on the amount of plaintext which can be safely\n encrypted under a given set of keys.\n\n This change enforces those limits by triggering automatic key updates on TLS\n 1.3 connections.\n\n Own Id: OTP-15856\n\n- Add support for TLS 1.3 Session Tickets (stateful and stateless). This allows\n session resumption using keying material from a previous successful handshake.\n\n Own Id: OTP-16253\n\n- Add support for key exchange with Edward curves and PSS-RSA padding in\n signature verification.\n\n Own Id: OTP-16528","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.5.3 - SSL Release Notes","ref":"notes.html#ssl-9-5-3"},{"type":"extras","doc":"- Enhance error handling, all ALERTS shall be handled gracefully and not cause a\n crash.\n\n Own Id: OTP-16413 Aux Id: ERL-1136\n\n- Enhance alert logging, in some places the role indication of the alert origin\n was missing. So the log would say undefined instead of client or server.\n\n Own Id: OTP-16424\n\n- Two different optimizations did not work together and resulted in the possible\n breakage of connections using stream ciphers (that is RC4). Reworked the\n implementation to avoid this.\n\n Own Id: OTP-16426 Aux Id: ERL-1136","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.5.2 - SSL Release Notes","ref":"notes.html#ssl-9-5-2"},{"type":"extras","doc":"- Fix the handling of GREASE values sent by web browsers when establishing TLS\n 1.3 connections. This change improves handling of GREASE values in various\n protocol elements sent in a TLS 1.3 ClientHello.\n\n Own Id: OTP-16388 Aux Id: ERL-1130\n\n- Correct DTLS listen emulation, could cause problems with opening a new DTLS\n listen socket for a port previously used by a now closed DTLS listen socket.\n\n Own Id: OTP-16396 Aux Id: ERL-1118","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.5.1 - SSL Release Notes","ref":"notes.html#ssl-9-5-1"},{"type":"extras","doc":"- Add missing alert handling clause for TLS record handling. Could sometimes\n cause confusing error behaviors of TLS connections.\n\n Own Id: OTP-16357 Aux Id: ERL-1166\n\n- Fix handling of ssl:recv that happens during a renegotiation. Using the\n passive receive function ssl:recv/\\[2,3] during a renegotiation would fail the\n connection with unexpected msg.\n\n Own Id: OTP-16361","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.5 - SSL Release Notes","ref":"notes.html#ssl-9-5"},{"type":"extras","doc":"- Corrected CRL handling which could cause CRL verification to fail. This could\n happen when the CRL distribution point explicitly specifies the CRL issuer,\n that is not using the fallback.\n\n Own Id: OTP-16156 Aux Id: ERL-1030\n\n- Correct handling of unordered chains so that it works as expected\n\n Own Id: OTP-16293\n\n- Fix bug causing ssl application to crash when handshake is paused and\n ClientHello contains extensions for session resumption\n (psk_key_exchange_modes, pre_shared_key).\n\n Own Id: OTP-16295 Aux Id: ERL-1095\n\n- Fix connectivity problems with legacy servers when client is configured to\n support a range of protocol versions including TLS 1.3.\n\n Own Id: OTP-16303","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Improve session handling for TLS-1.3 compatibility mode and cleaner internal\n handling so that removal of old session data can be more efficient, hopefully\n mitigating problems with big session tables during heavy load.\n\n Own Id: OTP-15524 Aux Id: OTP-15352\n\n- Correct handling of DTLS listen socket emulation. Could cause failure to\n create new listen socket after process that owned previous listen socket died.\n\n Own Id: OTP-15809 Aux Id: ERL-917\n\n- Add detailed info in ALERT description when client does not send a requested\n cert.\n\n Own Id: OTP-16266","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.4 - SSL Release Notes","ref":"notes.html#ssl-9-4"},{"type":"extras","doc":"- Handling of zero size fragments in TLS could cause an infinite loop. This has\n now been corrected.\n\n Own Id: OTP-15328 Aux Id: ERIERL-379\n\n- DTLS record check needs to consider that a resent hello message can have a\n different version than the negotiated.\n\n Own Id: OTP-15807 Aux Id: ERL-920","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Basic support for TLS 1.3 Client for experimental use. For more information\n see the Standards Compliance chapter of the User's Guide.\n\n Own Id: OTP-15431\n\n- Correct solution for retaining tcp flow control OTP-15802 (ERL-934) as to not\n break ssl:recv as reported in (ERL-938)\n\n Own Id: OTP-15823 Aux Id: ERL-934, ERL-938\n\n- Enhance dialyzer specs to reflect implementation better and avoid dialyzer\n warnings for the user that wants to use TLS with unix domain sockets.\n\n Own Id: OTP-15851 Aux Id: PR-2235\n\n- Add support for ECDSA signature algorithms in TLS 1.3.\n\n Own Id: OTP-15854\n\n- Correct error handling of TLS downgrade, possible return values form\n ssl:close/2 when downgrading is \\{ok, Port\\} or \\{error, Reason\\}, it could\n happen that only ok was returned instead of \\{error, closed\\} when downgrade\n failed due to that the peer closed the TCP connection.\n\n Own Id: OTP-16027","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.3.5 - SSL Release Notes","ref":"notes.html#ssl-9-3-5"},{"type":"extras","doc":"- Enhance error handling for erroneous alerts from the peer.\n\n Own Id: OTP-15943","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.3.4 - SSL Release Notes","ref":"notes.html#ssl-9-3-4"},{"type":"extras","doc":"- Fix handling of certificate decoding problems in TLS 1.3 similarly as in TLS\n 1.2.\n\n Own Id: OTP-15900\n\n- Hibernation now works as expected in all cases, was accidentally broken by\n optimization efforts.\n\n Own Id: OTP-15910\n\n- Fix interoperability problems with openssl when the TLS 1.3 server is\n configured with the option signature_algs_cert.\n\n Own Id: OTP-15913","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.3.3 - SSL Release Notes","ref":"notes.html#ssl-9-3-3"},{"type":"extras","doc":"- Correct handshake handling, might cause strange symptoms such as ASN.1\n certificate decoding issues.\n\n Own Id: OTP-15879 Aux Id: ERL-968\n\n- Fix handling of the signature_algorithms_cert extension in the ClientHello\n handshake message.\n\n Own Id: OTP-15887 Aux Id: ERL-973\n\n- Handle new ClientHello extensions when handshake is paused by the \\{handshake,\n hello\\} ssl option.\n\n Own Id: OTP-15888 Aux Id: ERL-975","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.3.2 - SSL Release Notes","ref":"notes.html#ssl-9-3-2"},{"type":"extras","doc":"- Returned \"alert error string\" is now same as logged alert string\n\n Own Id: OTP-15844\n\n- Fix returned extension map fields to follow the documentation.\n\n Own Id: OTP-15862 Aux Id: ERL-951\n\n- Avoid DTLS crash due to missing gen_server return value in DTLS packet demux\n process.\n\n Own Id: OTP-15864 Aux Id: ERL-962","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.3.1 - SSL Release Notes","ref":"notes.html#ssl-9-3-1"},{"type":"extras","doc":"- Missing check of size of user_data_buffer made internal socket behave as an\n active socket instead of active N. This could cause memory problems.\n\n Own Id: OTP-15825 Aux Id: ERL-934, OTP-15823","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.3 - SSL Release Notes","ref":"notes.html#ssl-9-3"},{"type":"extras","doc":"- The distribution handshake with TLS distribution (`inet_tls_dist`) does now\n utilize the socket option `{nodelay, true}`, which decreases the distribution\n setup time significantly.\n\n Own Id: OTP-14792\n\n- Correct shutdown reason to avoid an incorrect crash report\n\n Own Id: OTP-15710 Aux Id: ERL-893\n\n- Enhance documentation and type specifications.\n\n Own Id: OTP-15746 Aux Id: ERIERL-333","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- TLS-1.0, TLS-1.1 and DTLS-1.0 are now considered legacy and not supported by\n default\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-14865\n\n- Use new logger API in ssl. Introduce log levels and verbose debug logging for\n SSL.\n\n Own Id: OTP-15055\n\n- Add new API function str_to_suite/1, cipher_suites/3 (list cipher suites as\n rfc or OpenSSL name strings) and suite_to_openssl_str/1\n\n Own Id: OTP-15483 Aux Id: ERL-924\n\n- Basic support for TLS 1.3 Server for experimental use. The client is not yet\n functional, for more information see the Standards Compliance chapter of the\n User's Guide.\n\n Own Id: OTP-15591\n\n- Add support for PSK CCM ciphers from RFC 6655\n\n Own Id: OTP-15626","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.2.3.7 - SSL Release Notes","ref":"notes.html#ssl-9-2-3-7"},{"type":"extras","doc":"- Data deliver with ssl:recv/2,3 could fail for when using packet mode. This has\n been fixed by correcting the flow control handling of passive sockets when\n packet mode is used.\n\n Own Id: OTP-16764","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2.3.6 - SSL Release Notes","ref":"notes.html#ssl-9-2-3-6"},{"type":"extras","doc":"- Fix timing bug that could cause ssl sockets to become unresponsive after an\n ssl:recv/3 call timed out\n\n Own Id: OTP-16619 Aux Id: ERL-1213","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2.3.5 - SSL Release Notes","ref":"notes.html#ssl-9-2-3-5"},{"type":"extras","doc":"- Handling of zero size fragments in TLS could cause an infinite loop. This has\n now been corrected.\n\n Own Id: OTP-15328 Aux Id: ERIERL-379","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2.3.4 - SSL Release Notes","ref":"notes.html#ssl-9-2-3-4"},{"type":"extras","doc":"- Hibernation now works as expected in all cases, was accidentally broken by\n optimization efforts.\n\n Own Id: OTP-15910","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2.3.3 - SSL Release Notes","ref":"notes.html#ssl-9-2-3-3"},{"type":"extras","doc":"- Correct handshake handling, might cause strange symptoms such as ASN.1\n certificate decoding issues.\n\n Own Id: OTP-15879 Aux Id: ERL-968","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2.3.2 - SSL Release Notes","ref":"notes.html#ssl-9-2-3-2"},{"type":"extras","doc":"- Returned \"alert error string\" is now same as logged alert string\n\n Own Id: OTP-15844","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2.3.1 - SSL Release Notes","ref":"notes.html#ssl-9-2-3-1"},{"type":"extras","doc":"- Correct solution for retaining tcp flow control OTP-15802 (ERL-934) as to not\n break ssl:recv as reported in (ERL-938)\n\n Own Id: OTP-15823 Aux Id: ERL-934, ERL-938","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2.3 - SSL Release Notes","ref":"notes.html#ssl-9-2-3"},{"type":"extras","doc":"- Missing check of size of user_data_buffer made internal socket behave as an\n active socket instead of active N. This could cause memory problems.\n\n Own Id: OTP-15802 Aux Id: ERL-934","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Back port of bug fix ERL-893 from OTP-22 and document enhancements that will\n solve dialyzer warnings for users of the ssl application.\n\n This change also affects public_key, eldap (and inet doc).\n\n Own Id: OTP-15785 Aux Id: ERL-929, ERL-893, PR-2215","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.2.2 - SSL Release Notes","ref":"notes.html#ssl-9-2-2"},{"type":"extras","doc":"- With the default BEAST Mitigation strategy for TLS 1.0 an empty TLS fragment\n could be sent after a one-byte fragment. This glitch has been fixed.\n\n Own Id: OTP-15054 Aux Id: ERIERL-346","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2.1 - SSL Release Notes","ref":"notes.html#ssl-9-2-1"},{"type":"extras","doc":"- The timeout for a passive receive was sometimes not cancelled and later caused\n a server crash. This bug has now been corrected.\n\n Own Id: OTP-14701 Aux Id: ERL-883, ERL-884\n\n- Add tag for passive message (active N) in cb_info to retain transport\n transparency.\n\n Own Id: OTP-15679 Aux Id: ERL-861","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.2 - SSL Release Notes","ref":"notes.html#ssl-9-2"},{"type":"extras","doc":"- Fix bug that an incorrect return value for gen_statem could be created when\n alert was a result of handling renegotiation info extension\n\n Own Id: OTP-15502\n\n- Correct check for 3des_ede_cbc, could cause ssl to claim to support\n 3des_ede_cbc when cryptolib does not.\n\n Own Id: OTP-15539\n\n- Improved DTLS error handling, avoids unexpected connection failure in rare\n cases.\n\n Own Id: OTP-15561\n\n- Corrected active once emulation bug that could cause the ssl_closed meassage\n to not be sent. Bug introduced by OTP-15449\n\n Own Id: OTP-15666 Aux Id: ERIERL-316,","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add client option \\{reuse_session, SessionID::binary()\\} that can be used\n together with new option value \\{reuse_sessions, save\\}. This makes it\n possible to reuse a session from a specific connection establishment.\n\n Own Id: OTP-15369\n\n- The Reason part of of the error return from the functions connect and\n handshake has a better and documented format. This will sometimes differ from\n previous returned reasons, however those where only documented as term() and\n should for that reason not be relied on.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-15423\n\n- Refactor of state handling to improve TLS application data throughput and\n reduce CPU overhead\n\n Own Id: OTP-15445\n\n- The SSL code has been optimized in many small ways to reduce CPU load for\n encryption/decryption, especially for Erlang's distribution protocol over TLS.\n\n Own Id: OTP-15529\n\n- Add support for active N\n\n Own Id: OTP-15665 Aux Id: ERL-811, PR-2072","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.1.2 - SSL Release Notes","ref":"notes.html#ssl-9-1-2"},{"type":"extras","doc":"- Fix encoding of the SRP extension length field in ssl. The old encoding of the\n SRP extension length could cause interoperability problems with third party\n SSL implementations when SRP was used.\n\n Own Id: OTP-15477 Aux Id: ERL-790\n\n- Guarantee active once data delivery, handling TCP stream properly.\n\n Own Id: OTP-15504 Aux Id: ERL-371\n\n- Correct gen_statem returns for some error cases\n\n Own Id: OTP-15505","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.1.1 - SSL Release Notes","ref":"notes.html#ssl-9-1-1"},{"type":"extras","doc":"- Fixed renegotiation bug. Client did not handle server initiated renegotiation\n correctly after rewrite to two connection processes, due to ERL-622 commit\n d87ac1c55188f5ba5cdf72384125d94d42118c18. This could manifest it self as a \"\n bad_record_mac\" alert.\n\n Also included are some optimizations\n\n Own Id: OTP-15489 Aux Id: ERL-308","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.1 - SSL Release Notes","ref":"notes.html#ssl-9-1"},{"type":"extras","doc":"- PEM cache was not evicting expired entries due to due to timezone confusion.\n\n Own Id: OTP-15368\n\n- Make sure an error is returned if a \"transport_accept socket\" is used in some\n other call than ssl:handshake\\* or ssl:controlling_process\n\n Own Id: OTP-15384 Aux Id: ERL-756\n\n- Fix timestamp handling in the PEM-cache could cause entries to not be\n invalidated at the correct time.\n\n Own Id: OTP-15402\n\n- Extend check for undelivered data at closing, could under some circumstances\n fail to deliver all data that was actually received.\n\n Own Id: OTP-15412 Aux Id: ERL-731\n\n- Correct signature check for TLS-1.2 that allows different algorithms for\n signature of peer cert and peer cert key. Not all allowed combinations where\n accepted.\n\n Own Id: OTP-15415 Aux Id: ERL-763\n\n- Correct gen_statem return value, could cause renegotiation to fail.\n\n Own Id: OTP-15418 Aux Id: ERL-770","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add engine support for RSA key exchange\n\n Own Id: OTP-15420 Aux Id: ERIERL-268\n\n- ssl now uses active n internally to boost performance. Old active once\n behavior can be restored by setting application variable see manual page for\n ssl application (man 6).\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-15449","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.0.3 - SSL Release Notes","ref":"notes.html#ssl-9-0-3"},{"type":"extras","doc":"- Correct alert handling with new TLS sender process, from ssl-9.0.2. CLOSE\n ALERTS could under some circumstances be encoded using an incorrect cipher\n state. This would cause the peer to regard them as unknown messages.\n\n Own Id: OTP-15337 Aux Id: ERL-738\n\n- Correct handling of socket packet option with new TLS sender process, from\n ssl-9.0.2. When changing the socket option \\{packet, 1|2|3|4\\} with\n ssl:setopts/2 the option must internally be propagated to the sender process\n as well as the reader process as this particular option also affects the data\n to be sent.\n\n Own Id: OTP-15348 Aux Id: ERL-747","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.0.2 - SSL Release Notes","ref":"notes.html#ssl-9-0-2"},{"type":"extras","doc":"- Use separate processes for sending and receiving application data for TLS\n connections to avoid potential deadlock that was most likely to occur when\n using TLS for Erlang distribution. Note does not change the API.\n\n Own Id: OTP-15122\n\n- Correct handling of empty server SNI extension\n\n Own Id: OTP-15168\n\n- Correct PSK cipher suite handling and add selected_cipher_suite to connection\n information\n\n Own Id: OTP-15172\n\n- Adopt to the fact that cipher suite sign restriction are relaxed in TLS-1.2\n\n Own Id: OTP-15173\n\n- Enhance error handling of non existing PEM files\n\n Own Id: OTP-15174\n\n- Correct close handling of transport accepted sockets in the error state\n\n Own Id: OTP-15216\n\n- Correct PEM cache to not add references to empty entries when PEM file does\n not exist.\n\n Own Id: OTP-15224\n\n- Correct handling of all PSK cipher suites\n\n Before only some PSK suites would be correctly negotiated and most PSK ciphers\n suites would fail the connection.\n\n Own Id: OTP-15285","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- TLS will now try to order certificate chains if they appear to be unordered.\n That is prior to TLS 1.3, “certificate_list” ordering was required to be\n strict, however some implementations already allowed for some flexibility. For\n maximum compatibility, all implementations SHOULD be prepared to handle\n potentially extraneous certificates and arbitrary orderings from any TLS\n version.\n\n Own Id: OTP-12983\n\n- TLS will now try to reconstructed an incomplete certificate chains from its\n local CA-database and use that data for the certificate path validation. This\n especially makes sense for partial chains as then the peer might not send an\n intermediate CA as it is considered the trusted root in that case.\n\n Own Id: OTP-15060\n\n- Option keyfile defaults to certfile and should be trumped with key. This\n failed for engine keys.\n\n Own Id: OTP-15193\n\n- Error message improvement when own certificate has decoding issues, see also\n issue ERL-668.\n\n Own Id: OTP-15234\n\n- Correct dialyzer spec for key option\n\n Own Id: OTP-15281","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 9.0.1 - SSL Release Notes","ref":"notes.html#ssl-9-0-1"},{"type":"extras","doc":"- Correct cipher suite handling for ECDHE\\_\\*, the incorrect handling could\n cause an incorrrect suite to be selected and most likely fail the handshake.\n\n Own Id: OTP-15203","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 9.0 - SSL Release Notes","ref":"notes.html#ssl-9-0"},{"type":"extras","doc":"- Correct handling of ECDH suites.\n\n Own Id: OTP-14974\n\n- Proper handling of clients that choose to send an empty answer to a\n certificate request\n\n Own Id: OTP-15050","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Distribution over SSL (inet_tls) has, to improve performance, been rewritten\n to not use intermediate processes and ports.\n\n Own Id: OTP-14465\n\n- Add support for ECDHE_PSK cipher suites\n\n Own Id: OTP-14547\n\n- For security reasons no longer support 3-DES cipher suites by default\n\n \\*** INCOMPATIBILITY with possibly \\***\n\n Own Id: OTP-14768\n\n- For security reasons RSA-key exchange cipher suites are no longer supported by\n default\n\n \\*** INCOMPATIBILITY with possible \\***\n\n Own Id: OTP-14769\n\n- The interoperability option to fallback to insecure renegotiation now has to\n be explicitly turned on.\n\n \\*** INCOMPATIBILITY with possibly \\***\n\n Own Id: OTP-14789\n\n- Drop support for SSLv2 enabled clients. SSLv2 has been broken for decades and\n never supported by the Erlang SSL/TLS implementation. This option was by\n default disabled and enabling it has proved to sometimes break connections not\n using SSLv2 enabled clients.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-14824\n\n- Remove CHACHA20_POLY1305 ciphers form default for now. We have discovered\n interoperability problems, ERL-538, that we believe needs to be solved in\n crypto.\n\n \\*** INCOMPATIBILITY with possibly \\***\n\n Own Id: OTP-14882\n\n- Generalize DTLS packet multiplexing to make it easier to add future DTLS\n features and uses.\n\n Own Id: OTP-14888\n\n- Use uri_string module instead of http_uri.\n\n Own Id: OTP-14902\n\n- The SSL distribution protocol `-proto inet_tls` has stopped setting the SSL\n option `server_name_indication`. New verify funs for client and server in\n `inet_tls_dist` has been added, not documented yet, that checks node name if\n present in peer certificate. Usage is still also yet to be documented.\n\n Own Id: OTP-14969 Aux Id: OTP-14465, ERL-598\n\n- Deprecate ssl:ssl_accept/\\[1,2,3] in favour of ssl:handshake/\\[1,2,3]\n\n Own Id: OTP-15056\n\n- Customizes the hostname verification of the peer certificate, as different\n protocols that use TLS such as HTTP or LDAP may want to do it differently\n\n Own Id: OTP-15102 Aux Id: ERL-542, OTP-14962\n\n- Add utility function for converting erlang cipher suites to a string\n representation (ERL-600).\n\n Own Id: OTP-15106\n\n- First version with support for DTLS\n\n Own Id: OTP-15142","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.2.6.4 - SSL Release Notes","ref":"notes.html#ssl-8-2-6-4"},{"type":"extras","doc":"- Add engine support for RSA key exchange\n\n Own Id: OTP-15420","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.2.6.3 - SSL Release Notes","ref":"notes.html#ssl-8-2-6-3"},{"type":"extras","doc":"- Extend check for undelivered data at closing, could under some circumstances\n fail to deliverd all data that was acctualy recivied.\n\n Own Id: OTP-15412","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.2.6.2 - SSL Release Notes","ref":"notes.html#ssl-8-2-6-2"},{"type":"extras","doc":"- Correct handling of empty server SNI extension\n\n Own Id: OTP-15168\n\n- Correct cipher suite handling for ECDHE\\_\\*, the incorrect handling could\n cause an incorrrect suite to be selected and most likely fail the handshake.\n\n Own Id: OTP-15203","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.2.6.1 - SSL Release Notes","ref":"notes.html#ssl-8-2-6-1"},{"type":"extras","doc":"- Improve cipher suite handling correcting ECC and TLS-1.2 requierments.\n Backport of solution for ERL-641\n\n Own Id: OTP-15178","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Option keyfile defaults to certfile and should be trumped with key. This\n failed for engine keys.\n\n Own Id: OTP-15193","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.2.6 - SSL Release Notes","ref":"notes.html#ssl-8-2-6"},{"type":"extras","doc":"- Proper handling of clients that choose to send an empty answer to a\n certificate request\n\n Own Id: OTP-15050","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.2.5 - SSL Release Notes","ref":"notes.html#ssl-8-2-5"},{"type":"extras","doc":"- Fix filter function to not incorrectly exclude AEAD cipher suites\n\n Own Id: OTP-14981","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.2.4 - SSL Release Notes","ref":"notes.html#ssl-8-2-4"},{"type":"extras","doc":"- Optimization of bad merge conflict resolution causing dubble decode\n\n Own Id: OTP-14843\n\n- Restore error propagation to OTP-19.3 behaviour, in OTP-20.2 implementation\n adjustments to gen_statem needed some further adjustments to avoid a race\n condition. This could cause a TLS server to not always report file path errors\n correctly.\n\n Own Id: OTP-14852\n\n- Corrected RC4 suites listing function to regard TLS version\n\n Own Id: OTP-14871\n\n- Fix alert handling so that unexpected messages are logged and alerted\n correctly\n\n Own Id: OTP-14919\n\n- Correct handling of anonymous cipher suites\n\n Own Id: OTP-14952","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Added new API functions to facilitate cipher suite handling\n\n Own Id: OTP-14760\n\n- Correct TLS_FALLBACK_SCSV handling so that this special flag suite is always\n placed last in the cipher suite list in accordance with the specs. Also make\n sure this functionality is used in DTLS.\n\n Own Id: OTP-14828\n\n- Add TLS record version sanity check for early as possible error detection and\n consistency in ALERT codes generated\n\n Own Id: OTP-14892","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.2.3 - SSL Release Notes","ref":"notes.html#ssl-8-2-3"},{"type":"extras","doc":"- Packet options cannot be supported for unreliable transports, that is, packet\n option for DTLS over udp will not be supported.\n\n Own Id: OTP-14664\n\n- Ensure data delivery before close if possible. This fix is related to fix in\n PR-1479.\n\n Own Id: OTP-14794","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The crypto API is extended to use private/public keys stored in an Engine for\n sign/verify or encrypt/decrypt operations.\n\n The ssl application provides an API to use this new engine concept in TLS.\n\n Own Id: OTP-14448\n\n- Implemented renegotiation for DTLS\n\n Own Id: OTP-14563\n\n- A new command line option `-ssl_dist_optfile` has been added to facilitate\n specifying the many options needed when using SSL as the distribution\n protocol.\n\n Own Id: OTP-14657","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.2.2 - SSL Release Notes","ref":"notes.html#ssl-8-2-2"},{"type":"extras","doc":"- TLS sessions must be registered with SNI if provided, so that sessions where\n client hostname verification would fail cannot connect reusing a session\n created when the server name verification succeeded.\n\n Own Id: OTP-14632\n\n- An erlang TLS server configured with cipher suites using rsa key exchange, may\n be vulnerable to an Adaptive Chosen Ciphertext attack (AKA Bleichenbacher\n attack) against RSA, which when exploited, may result in plaintext recovery of\n encrypted messages and/or a Man-in-the-middle (MiTM) attack, despite the\n attacker not having gained access to the server’s private key itself.\n [CVE-2017-1000385](https://nvd.nist.gov/vuln/detail/CVE-2017-1000385)\n\n Exploiting this vulnerability to perform plaintext recovery of encrypted\n messages will, in most practical cases, allow an attacker to read the\n plaintext only after the session has completed. Only TLS sessions established\n using RSA key exchange are vulnerable to this attack.\n\n Exploiting this vulnerability to conduct a MiTM attack requires the attacker\n to complete the initial attack, which may require thousands of server\n requests, during the handshake phase of the targeted session within the window\n of the configured handshake timeout. This attack may be conducted against any\n TLS session using RSA signatures, but only if cipher suites using RSA key\n exchange are also enabled on the server. The limited window of opportunity,\n limitations in bandwidth, and latency make this attack significantly more\n difficult to execute.\n\n RSA key exchange is enabled by default although least prioritized if server\n order is honored. For such a cipher suite to be chosen it must also be\n supported by the client and probably the only shared cipher suite.\n\n Captured TLS sessions encrypted with ephemeral cipher suites (DHE or ECDHE)\n are not at risk for subsequent decryption due to this vulnerability.\n\n As a workaround if default cipher suite configuration was used you can\n configure the server to not use vulnerable suites with the ciphers option like\n this:\n\n `{ciphers, [Suite || Suite <- ssl:cipher_suites(), element(1,Suite) =/= rsa]}`\n\n that is your code will look somethingh like this:\n\n `ssl:listen(Port, [{ciphers, [Suite || Suite <- ssl:cipher_suites(), element(1,S) =/= rsa]} | Options]).`\n\n Thanks to Hanno Böck, Juraj Somorovsky and Craig Young for reporting this\n vulnerability.\n\n Own Id: OTP-14748","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- If no SNI is available and the hostname is an IP-address also check for\n IP-address match. This check is not as good as a DNS hostname check and\n certificates using IP-address are not recommended.\n\n Own Id: OTP-14655","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.2.1 - SSL Release Notes","ref":"notes.html#ssl-8-2-1"},{"type":"extras","doc":"- Max session table works correctly again\n\n Own Id: OTP-14556","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Customize alert handling for DTLS over UDP to mitigate DoS attacks\n\n Own Id: OTP-14078\n\n- Improved error propagation and reports\n\n Own Id: OTP-14236","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.2 - SSL Release Notes","ref":"notes.html#ssl-8-2"},{"type":"extras","doc":"- ECDH-ECDSA key exchange supported, was accidentally dismissed in earlier\n versions.\n\n Own Id: OTP-14421\n\n- Correct close semantics for active once connections. This was a timing\n dependent bug the resulted in the close message not always reaching the ssl\n user process.\n\n Own Id: OTP-14443","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- TLS-1.2 clients will now always send hello messages on its own format, as\n opposed to earlier versions that will send the hello on the lowest supported\n version, this is a change supported by the latest RFC.\n\n This will make interoperability with some newer servers smoother. Potentially,\n but unlikely, this could cause a problem with older servers if they do not\n adhere to the RFC and ignore unknown extensions.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-13820\n\n- Allow Erlang/OTP to use OpenSSL in FIPS-140 mode, in order to satisfy specific\n security requirements (mostly by different parts of the US federal\n government).\n\n See the new crypto users guide \"FIPS mode\" chapter about building and using\n the FIPS support which is disabled by default.\n\n (Thanks to dszoboszlay and legoscia)\n\n Own Id: OTP-13921 Aux Id: PR-1180\n\n- Implemented DTLS cookie generation, required by spec, instead of using a\n hardcoded value.\n\n Own Id: OTP-14076\n\n- Implement sliding window replay protection of DTLS records.\n\n Own Id: OTP-14077\n\n- TLS client processes will by default call public_key:pkix_verify_hostname/2 to\n verify the hostname of the connection with the server certificates specified\n hostname during certificate path validation. The user may explicitly disables\n it. Also if the hostname cannot be derived from the first argument to connect\n or is not supplied by the server name indication option, the check will not be\n performed.\n\n Own Id: OTP-14197\n\n- Extend connection_information/\\[1,2] . The values session_id, master_secret,\n client_random and server_random can no be accessed by\n connection_information/2. Note only session_id will be added to\n connection_information/1. The rational is that values concerning the\n connection security should have to be explicitly requested.\n\n Own Id: OTP-14291\n\n- Chacha cipher suites are currently not tested enough to be most preferred ones\n\n Own Id: OTP-14382\n\n- Basic support for DTLS that been tested together with OpenSSL.\n\n Test by providing the option \\{protocol, dtls\\} to the ssl API functions\n connect and listen.\n\n Own Id: OTP-14388","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.1.3.1.1 - SSL Release Notes","ref":"notes.html#ssl-8-1-3-1-1"},{"type":"extras","doc":"- Fix alert handling so that unexpected messages are logged and alerted\n correctly\n\n Own Id: OTP-14929","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.1.3.1 - SSL Release Notes","ref":"notes.html#ssl-8-1-3-1"},{"type":"extras","doc":"- An erlang TLS server configured with cipher suites using rsa key exchange, may\n be vulnerable to an Adaptive Chosen Ciphertext attack (AKA Bleichenbacher\n attack) against RSA, which when exploited, may result in plaintext recovery of\n encrypted messages and/or a Man-in-the-middle (MiTM) attack, despite the\n attacker not having gained access to the server’s private key itself.\n [CVE-2017-1000385](https://nvd.nist.gov/vuln/detail/CVE-2017-1000385)\n\n Exploiting this vulnerability to perform plaintext recovery of encrypted\n messages will, in most practical cases, allow an attacker to read the\n plaintext only after the session has completed. Only TLS sessions established\n using RSA key exchange are vulnerable to this attack.\n\n Exploiting this vulnerability to conduct a MiTM attack requires the attacker\n to complete the initial attack, which may require thousands of server\n requests, during the handshake phase of the targeted session within the window\n of the configured handshake timeout. This attack may be conducted against any\n TLS session using RSA signatures, but only if cipher suites using RSA key\n exchange are also enabled on the server. The limited window of opportunity,\n limitations in bandwidth, and latency make this attack significantly more\n difficult to execute.\n\n RSA key exchange is enabled by default although least prioritized if server\n order is honored. For such a cipher suite to be chosen it must also be\n supported by the client and probably the only shared cipher suite.\n\n Captured TLS sessions encrypted with ephemeral cipher suites (DHE or ECDHE)\n are not at risk for subsequent decryption due to this vulnerability.\n\n As a workaround if default cipher suite configuration was used you can\n configure the server to not use vulnerable suites with the ciphers option like\n this:\n\n `{ciphers, [Suite || Suite <- ssl:cipher_suites(), element(1,Suite) =/= rsa]}`\n\n that is your code will look somethingh like this:\n\n `ssl:listen(Port, [{ciphers, [Suite || Suite <- ssl:cipher_suites(), element(1,S) =/= rsa]} | Options]).`\n\n Thanks to Hanno Böck, Juraj Somorovsky and Craig Young for reporting this\n vulnerability.\n\n Own Id: OTP-14748","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.1.3 - SSL Release Notes","ref":"notes.html#ssl-8-1-3"},{"type":"extras","doc":"- Remove debug printout\n\n Own Id: OTP-14396","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.1.2 - SSL Release Notes","ref":"notes.html#ssl-8-1-2"},{"type":"extras","doc":"- Correct active once emulation, for TLS. Now all data received by the\n connection process will be delivered through active once, even when the active\n once arrives after that the gen_tcp socket is closed by the peer.\n\n Own Id: OTP-14300","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.1.1 - SSL Release Notes","ref":"notes.html#ssl-8-1-1"},{"type":"extras","doc":"- Corrected termination behavior, that caused a PEM cache bug and sometimes\n resulted in connection failures.\n\n Own Id: OTP-14100\n\n- Fix bug that could hang ssl connection processes when failing to require more\n data for very large handshake packages. Add option max_handshake_size to\n mitigate DoS attacks.\n\n Own Id: OTP-14138\n\n- Improved support for CRL handling that could fail to work as intended when an\n id-ce-extKeyUsage was present in the certificate. Also improvements where\n needed to distributionpoint handling so that all revocations actually are\n found and not deemed to be not determinable.\n\n Own Id: OTP-14141\n\n- A TLS handshake might accidentally match old sslv2 format and ssl application\n would incorrectly aborted TLS handshake with ssl_v2_client_hello_no_supported.\n Parsing was altered to avoid this problem.\n\n Own Id: OTP-14222\n\n- Correct default cipher list to prefer AES 128 before 3DES\n\n Own Id: OTP-14235","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Move PEM cache to a dedicated process, to avoid making the SSL manager process\n a bottleneck. This improves scalability of TLS connections.\n\n Own Id: OTP-13874","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.1 - SSL Release Notes","ref":"notes.html#ssl-8-1"},{"type":"extras","doc":"- List of possible anonymous suites, never supported by default, where incorrect\n for some TLS versions.\n\n Own Id: OTP-13926","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Experimental version of DTLS. It is runnable but not complete and cannot be\n considered reliable for production usage.\n\n Own Id: OTP-12982\n\n- Add API options to handle ECC curve selection.\n\n Own Id: OTP-13959","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.0.3 - SSL Release Notes","ref":"notes.html#ssl-8-0-3"},{"type":"extras","doc":"- A timing related bug in event handling could cause interoperability problems\n between an erlang TLS server and some TLS clients, especially noticed with\n Firefox as TLS client.\n\n Own Id: OTP-13917\n\n- Correct ECC curve selection, the error could cause the default to always be\n selected.\n\n Own Id: OTP-13918","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.0.2 - SSL Release Notes","ref":"notes.html#ssl-8-0-2"},{"type":"extras","doc":"- Correctly formed handshake messages received out of order will now correctly\n fail the connection with unexpected message.\n\n Own Id: OTP-13853\n\n- Correct handling of signature algorithm selection\n\n Own Id: OTP-13711","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- ssl application now behaves gracefully also on partially incorrect input from\n peer.\n\n Own Id: OTP-13834\n\n- Add application environment configuration bypass_pem_cache. This can be used\n as a workaround for the current implementation of the PEM-cache that has\n proven to be a bottleneck.\n\n Own Id: OTP-13883","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 8.0.1 - SSL Release Notes","ref":"notes.html#ssl-8-0-1"},{"type":"extras","doc":"- The TLS/SSL protocol version selection for the SSL server has been corrected\n to follow RFC 5246 Appendix E.1 especially in case where the list of supported\n versions has gaps. Now the server selects the highest protocol version it\n supports that is not higher than what the client supports.\n\n Own Id: OTP-13753 Aux Id: seq13150","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 8.0 - SSL Release Notes","ref":"notes.html#ssl-8-0"},{"type":"extras","doc":"- Server now rejects, a not requested client cert, as an incorrect handshake\n message and ends the connection.\n\n Own Id: OTP-13651","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Remove default support for DES cipher suites\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-13195\n\n- Deprecate the function `crypto:rand_bytes` and make sure that\n `crypto:strong_rand_bytes` is used in all places that are cryptographically\n significant.\n\n Own Id: OTP-13214\n\n- Better error handling of user error during TLS upgrade. ERL-69 is solved by\n gen_statem rewrite of ssl application.\n\n Own Id: OTP-13255\n\n- Provide user friendly error message when crypto rejects a key\n\n Own Id: OTP-13256\n\n- Add ssl:getstat/1 and ssl:getstat/2\n\n Own Id: OTP-13415\n\n- TLS distribution connections now allow specifying the options `verify_fun`,\n `crl_check` and `crl_cache`. See the documentation. GitHub pull req #956\n contributed by Magnus Henoch.\n\n Own Id: OTP-13429 Aux Id: Pull#956\n\n- Remove confusing error message when closing a distributed erlang node running\n over TLS\n\n Own Id: OTP-13431\n\n- Remove default support for use of md5 in TLS 1.2 signature algorithms\n\n Own Id: OTP-13463\n\n- ssl now uses gen_statem instead of gen_fsm to implement the ssl connection\n process, this solves some timing issues in addition to making the code more\n intuitive as the behaviour can be used cleanly instead of having a lot of\n workaround for shortcomings of the behaviour.\n\n Own Id: OTP-13464\n\n- Phase out interoperability with clients that offer SSLv2. By default they are\n no longer supported, but an option to provide interoperability is offered.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-13465\n\n- OpenSSL has functions to generate short (eight hex digits) hashes of issuers\n of certificates and CRLs. These hashes are used by the \"c_rehash\" script to\n populate directories of CA certificates and CRLs, e.g. in the Apache web\n server. Add functionality to let an Erlang program find the right CRL for a\n given certificate in such a directory.\n\n Own Id: OTP-13530\n\n- Some legacy TLS 1.0 software does not tolerate the 1/n-1 content split BEAST\n mitigation technique. Add a beast_mitigation SSL option (defaulting to\n one_n_minus_one) to select or disable the BEAST mitigation technique.\n\n Own Id: OTP-13629\n\n- Enhance error log messages to facilitate for users to understand the error\n\n Own Id: OTP-13632\n\n- Increased default DH params to 2048-bit\n\n Own Id: OTP-13636\n\n- Propagate CRL unknown CA error so that public_key validation process continues\n correctly and determines what should happen.\n\n Own Id: OTP-13656\n\n- Introduce a flight concept for handshake packages. This is a preparation for\n enabling DTLS, however it can also have a positive effects for TLS on slow and\n unreliable networks.\n\n Own Id: OTP-13678","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 7.3.3.2 - SSL Release Notes","ref":"notes.html#ssl-7-3-3-2"},{"type":"extras","doc":"- An erlang TLS server configured with cipher suites using rsa key exchange, may\n be vulnerable to an Adaptive Chosen Ciphertext attack (AKA Bleichenbacher\n attack) against RSA, which when exploited, may result in plaintext recovery of\n encrypted messages and/or a Man-in-the-middle (MiTM) attack, despite the\n attacker not having gained access to the server’s private key itself.\n [CVE-2017-1000385](https://nvd.nist.gov/vuln/detail/CVE-2017-1000385)\n\n Exploiting this vulnerability to perform plaintext recovery of encrypted\n messages will, in most practical cases, allow an attacker to read the\n plaintext only after the session has completed. Only TLS sessions established\n using RSA key exchange are vulnerable to this attack.\n\n Exploiting this vulnerability to conduct a MiTM attack requires the attacker\n to complete the initial attack, which may require thousands of server\n requests, during the handshake phase of the targeted session within the window\n of the configured handshake timeout. This attack may be conducted against any\n TLS session using RSA signatures, but only if cipher suites using RSA key\n exchange are also enabled on the server. The limited window of opportunity,\n limitations in bandwidth, and latency make this attack significantly more\n difficult to execute.\n\n RSA key exchange is enabled by default although least prioritized if server\n order is honored. For such a cipher suite to be chosen it must also be\n supported by the client and probably the only shared cipher suite.\n\n Captured TLS sessions encrypted with ephemeral cipher suites (DHE or ECDHE)\n are not at risk for subsequent decryption due to this vulnerability.\n\n As a workaround if default cipher suite configuration was used you can\n configure the server to not use vulnerable suites with the ciphers option like\n this:\n\n `{ciphers, [Suite || Suite <- ssl:cipher_suites(), element(1,Suite) =/= rsa]}`\n\n that is your code will look somethingh like this:\n\n `ssl:listen(Port, [{ciphers, [Suite || Suite <- ssl:cipher_suites(), element(1,S) =/= rsa]} | Options]).`\n\n Thanks to Hanno Böck, Juraj Somorovsky and Craig Young for reporting this\n vulnerability.\n\n Own Id: OTP-14748","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 7.3.3 - SSL Release Notes","ref":"notes.html#ssl-7-3-3"},{"type":"extras","doc":"- Correct ssl:prf/5 to use the negotiated cipher suite's prf function in\n ssl:prf/5 instead of the default prf.\n\n Own Id: OTP-13546\n\n- Timeouts may have the value 0, guards have been corrected to allow this\n\n Own Id: OTP-13635\n\n- Change of internal handling of hash sign pairs as the used one enforced to\n much restrictions making some valid combinations unavailable.\n\n Own Id: OTP-13670","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 7.3.3.0.1 - SSL Release Notes","ref":"notes.html#ssl-7-3-3-0-1"},{"type":"extras","doc":"- An erlang TLS server configured with cipher suites using rsa key exchange, may\n be vulnerable to an Adaptive Chosen Ciphertext attack (AKA Bleichenbacher\n attack) against RSA, which when exploited, may result in plaintext recovery of\n encrypted messages and/or a Man-in-the-middle (MiTM) attack, despite the\n attacker not having gained access to the server’s private key itself.\n [CVE-2017-1000385](https://nvd.nist.gov/vuln/detail/CVE-2017-1000385)\n\n Exploiting this vulnerability to perform plaintext recovery of encrypted\n messages will, in most practical cases, allow an attacker to read the\n plaintext only after the session has completed. Only TLS sessions established\n using RSA key exchange are vulnerable to this attack.\n\n Exploiting this vulnerability to conduct a MiTM attack requires the attacker\n to complete the initial attack, which may require thousands of server\n requests, during the handshake phase of the targeted session within the window\n of the configured handshake timeout. This attack may be conducted against any\n TLS session using RSA signatures, but only if cipher suites using RSA key\n exchange are also enabled on the server. The limited window of opportunity,\n limitations in bandwidth, and latency make this attack significantly more\n difficult to execute.\n\n RSA key exchange is enabled by default although least prioritized if server\n order is honored. For such a cipher suite to be chosen it must also be\n supported by the client and probably the only shared cipher suite.\n\n Captured TLS sessions encrypted with ephemeral cipher suites (DHE or ECDHE)\n are not at risk for subsequent decryption due to this vulnerability.\n\n As a workaround if default cipher suite configuration was used you can\n configure the server to not use vulnerable suites with the ciphers option like\n this:\n\n `{ciphers, [Suite || Suite <- ssl:cipher_suites(), element(1,Suite) =/= rsa]}`\n\n that is your code will look somethingh like this:\n\n `ssl:listen(Port, [{ciphers, [Suite || Suite <- ssl:cipher_suites(), element(1,S) =/= rsa]} | Options]).`\n\n Thanks to Hanno Böck, Juraj Somorovsky and Craig Young for reporting this\n vulnerability.\n\n Own Id: OTP-14748","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Create a little randomness in sending of session invalidation messages, to\n mitigate load when whole table is invalidated.\n\n Own Id: OTP-13490","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 7.3.2 - SSL Release Notes","ref":"notes.html#ssl-7-3-2"},{"type":"extras","doc":"- Correct cipher suites conversion and guard expression. Caused problems with\n GCM cipher suites and client side option to set signature_algorithms extension\n values.\n\n Own Id: OTP-13525","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 7.3.1 - SSL Release Notes","ref":"notes.html#ssl-7-3-1"},{"type":"extras","doc":"- Corrections to cipher suite handling using the 3 and 4 tuple format in\n addition to commit 89d7e21cf4ae988c57c8ef047bfe85127875c70c\n\n Own Id: OTP-13511","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Make values for the TLS-1.2 signature_algorithms extension configurable\n\n Own Id: OTP-13261","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 7.3 - SSL Release Notes","ref":"notes.html#ssl-7-3"},{"type":"extras","doc":"- Make sure there is only one poller validator at a time for validating the\n session cache.\n\n Own Id: OTP-13185\n\n- A timing related issue could cause ssl to hang, especially happened with newer\n versions of OpenSSL in combination with ECC ciphers.\n\n Own Id: OTP-13253\n\n- Work around a race condition in the TLS distribution start.\n\n Own Id: OTP-13268\n\n- Big handshake messages are now correctly fragmented in the TLS record layer.\n\n Own Id: OTP-13306\n\n- Improve portability of ECC tests in Crypto and SSL for \"exotic\" OpenSSL\n versions.\n\n Own Id: OTP-13311\n\n- Certificate extensions marked as critical are ignored when using verify_none\n\n Own Id: OTP-13377\n\n- If a certificate doesn't contain a CRL Distribution Points extension, and the\n relevant CRL is not in the cache, and the `crl_check` option is not set to\n `best_effort` , the revocation check should fail.\n\n Own Id: OTP-13378\n\n- Enable TLS distribution over IPv6\n\n Own Id: OTP-13391","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Improve error reporting for TLS distribution\n\n Own Id: OTP-13219\n\n- Include options from connect, listen and accept in\n `connection_information/1,2`\n\n Own Id: OTP-13232\n\n- Allow adding extra options for outgoing TLS distribution connections, as\n supported for plain TCP connections.\n\n Own Id: OTP-13285\n\n- Use loopback as server option in TLS-distribution module\n\n Own Id: OTP-13300\n\n- Verify certificate signature against original certificate binary.\n\n This avoids bugs due to encoding errors when re-encoding a decode certificate.\n As there exists several decode step and using of different ASN.1 specification\n this is a risk worth avoiding.\n\n Own Id: OTP-13334\n\n- Use `application:ensure_all_started/2` instead of hard-coding dependencies\n\n Own Id: OTP-13363","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 7.2 - SSL Release Notes","ref":"notes.html#ssl-7-2"},{"type":"extras","doc":"- Honor distribution port range options\n\n Own Id: OTP-12838\n\n- Correct supervisor specification in TLS distribution.\n\n Own Id: OTP-13134\n\n- Correct cache timeout\n\n Own Id: OTP-13141\n\n- Avoid crash and restart of ssl process when key file does not exist.\n\n Own Id: OTP-13144\n\n- Enable passing of raw socket options on the format \\{raw,_,_,\\_\\} to the\n underlying socket.\n\n Own Id: OTP-13166\n\n- Hibernation with small or a zero timeout will now work as expected\n\n Own Id: OTP-13189","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add upper limit for session cache, configurable on ssl application level.\n\n If upper limit is reached, invalidate the current cache entries, e.i the\n session lifetime is the max time a session will be kept, but it may be\n invalidated earlier if the max limit for the table is reached. This will keep\n the ssl manager process well behaved, not exhusting memory. Invalidating the\n entries will incrementally empty the cache to make room for fresh sessions\n entries.\n\n Own Id: OTP-12392\n\n- Use new time functions to measure passed time.\n\n Own Id: OTP-12457\n\n- Improved error handling in TLS distribution\n\n Own Id: OTP-13142\n\n- Distribution over TLS now honors the nodelay distribution flag\n\n Own Id: OTP-13143","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 7.1 - SSL Release Notes","ref":"notes.html#ssl-7-1"},{"type":"extras","doc":"- Add DER encoded ECPrivateKey as valid input format for key option.\n\n Own Id: OTP-12974\n\n- Correct return value of default session callback module\n\n This error had the symptom that the client check for unique session would\n always fail, potentially making the client session table grow a lot and\n causing long setup times.\n\n Own Id: OTP-12980","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add possibility to downgrade an SSL/TLS connection to a tcp connection, and\n give back the socket control to a user process.\n\n This also adds the possibility to specify a timeout to the ssl:close function.\n\n Own Id: OTP-11397\n\n- Add application setting to be able to change fatal alert shutdown timeout,\n also shorten the default timeout. The fatal alert timeout is the number of\n milliseconds between sending of a fatal alert and closing the connection.\n Waiting a little while improves the peers chances to properly receiving the\n alert so it may shutdown gracefully.\n\n Own Id: OTP-12832","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 7.0 - SSL Release Notes","ref":"notes.html#ssl-7-0"},{"type":"extras","doc":"- Ignore signature_algorithm (TLS 1.2 extension) sent to TLS 1.0 or TLS 1.1\n server\n\n Own Id: OTP-12670\n\n- Improve error handling in TLS distribution module to avoid lingering sockets.\n\n Own Id: OTP-12799 Aux Id: Tom Briden\n\n- Add option \\{client_renegotiation, boolean()\\} option to the server-side of\n the SSL application.\n\n Own Id: OTP-12815","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add new API functions to handle CRL-verification\n\n Own Id: OTP-10362 Aux Id: kunagi-215 \\[126]\n\n- Remove default support for SSL-3.0, due to Poodle vunrability in protocol\n specification.\n\n Add padding check for TLS-1.0 to remove Poodle vunrability from TLS 1.0, also\n add the option padding_check. This option only affects TLS-1.0 connections and\n if set to false it disables the block cipher padding check to be able to\n interoperate with legacy software.\n\n Remove default support for RC4 cipher suites, as they are consider too weak.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-12390\n\n- Add support for TLS ALPN (Application-Layer Protocol Negotiation) extension.\n\n Own Id: OTP-12580\n\n- Add SNI (Server Name Indication) support for the server side.\n\n Own Id: OTP-12736","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 6.0.1.1 - SSL Release Notes","ref":"notes.html#ssl-6-0-1-1"},{"type":"extras","doc":"- Gracefully ignore proprietary hash_sign algorithms\n\n Own Id: OTP-12829","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 6.0.1 - SSL Release Notes","ref":"notes.html#ssl-6-0-1"},{"type":"extras","doc":"- Terminate gracefully when receiving bad input to premaster secret calculation\n\n Own Id: OTP-12783","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 6.0 - SSL Release Notes","ref":"notes.html#ssl-6-0"},{"type":"extras","doc":"- Exclude self-signed trusted anchor certificates from certificate prospective\n certification path according to RFC 3280.\n\n This will avoid some unnecessary certificate processing.\n\n Own Id: OTP-12449","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Separate client and server session cache internally.\n\n Avoid session table growth when client starts many connections in such a\n manner that many connections are started before session reuse is possible.\n Only save a new session in client if there is no equivalent session already\n stored.\n\n Own Id: OTP-11365\n\n- The PEM cache is now validated by a background process, instead of always\n keeping it if it is small enough and clearing it otherwise. That strategy\n required that small caches where cleared by API function if a file changes on\n disk.\n\n However export the API function to clear the cache as it may still be useful.\n\n Own Id: OTP-12391\n\n- Add padding check for TLS-1.0 to remove Poodle vulnerability from TLS 1.0,\n also add the option padding_check. This option only affects TLS-1.0\n connections and if set to false it disables the block cipher padding check to\n be able to interoperate with legacy software.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-12420\n\n- Add support for TLS_FALLBACK_SCSV used to prevent undesired TLS version\n downgrades. If used by a client that is vulnerable to the POODLE attack, and\n the server also supports TLS_FALLBACK_SCSV, the attack can be prevented.\n\n Own Id: OTP-12458","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.3.8 - SSL Release Notes","ref":"notes.html#ssl-5-3-8"},{"type":"extras","doc":"- Make sure the clean rule for ssh, ssl, eunit and otp_mibs actually removes\n generated files.\n\n Own Id: OTP-12200","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Change code to reflect that state data may be secret to avoid breaking\n dialyzer contracts.\n\n Own Id: OTP-12341","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.3.7 - SSL Release Notes","ref":"notes.html#ssl-5-3-7"},{"type":"extras","doc":"- Handle the fact that servers may send an empty SNI extension to the client.\n\n Own Id: OTP-12198","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 5.3.6 - SSL Release Notes","ref":"notes.html#ssl-5-3-6"},{"type":"extras","doc":"- Corrected handling of ECC certificates, there where several small issues with\n the handling of such certificates in the ssl and public_key application. Now\n ECC signed ECC certificates shall work and not only RSA signed ECC\n certificates.\n\n Own Id: OTP-12026\n\n- Check that the certificate chain ends with a trusted ROOT CA e.i. a\n self-signed certificate, but provide an option partial_chain to enable the\n application to define an intermediat CA as trusted.\n\n Own Id: OTP-12149","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add decode functions for SNI (Server Name Indication)\n\n Own Id: OTP-12048","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.3.5 - SSL Release Notes","ref":"notes.html#ssl-5-3-5"},{"type":"extras","doc":"- ssl:recv now returns \\{error, einval\\} if applied to a non passive socket, the\n same as gen_tcp:recv.\n\n Thanks to Danil Zagoskin for reporting this issue\n\n Own Id: OTP-11878\n\n- Corrected handling of default values for signature_algorithms extension in\n TLS-1.2 and corresponding values used in previous versions that does not\n support this extension.\n\n Thanks to Danil Zagoskin\n\n Own Id: OTP-11886\n\n- Handle socket option inheritance when pooling of accept sockets is used\n\n Own Id: OTP-11897\n\n- Make sure that the list of versions, possibly supplied in the versions option,\n is not order dependent.\n\n Thanks to Ransom Richardson for reporting this issue\n\n Own Id: OTP-11912\n\n- Reject connection if the next_protocol message is sent twice.\n\n Own Id: OTP-11926\n\n- Correct options handling when ssl:ssl_accept/3 is called with new ssl options\n after calling ssl:listen/2\n\n Own Id: OTP-11950","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Gracefully handle unknown alerts\n\n Thanks to Atul Atri for reporting this issue\n\n Own Id: OTP-11874\n\n- Gracefully ignore cipher suites sent by client not supported by the SSL/TLS\n version that the client has negotiated.\n\n Thanks to Danil Zagoskin for reporting this issue\n\n Own Id: OTP-11875\n\n- Gracefully handle structured garbage, i.e a client sends some garbage in a ssl\n record instead of a valid fragment.\n\n Thanks to Danil Zagoskin\n\n Own Id: OTP-11880\n\n- Gracefully handle invalid alerts\n\n Own Id: OTP-11890\n\n- Generalize handling of default ciphers\n\n Thanks to Andreas Schultz\n\n Own Id: OTP-11966\n\n- Make sure change cipher spec is correctly handled\n\n Own Id: OTP-11975","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.3.4 - SSL Release Notes","ref":"notes.html#ssl-5-3-4"},{"type":"extras","doc":"- Fix incorrect dialyzer spec and types, also enhance documentation.\n\n Thanks to Ayaz Tuncer.\n\n Own Id: OTP-11627\n\n- Fix possible mismatch between SSL/TLS version and default ciphers. Could\n happen when you specified SSL/TLS-version in optionlist to listen or accept.\n\n Own Id: OTP-11712\n\n- Application upgrade (appup) files are corrected for the following\n applications:\n\n `asn1, common_test, compiler, crypto, debugger, dialyzer, edoc, eldap, erl_docgen, et, eunit, gs, hipe, inets, observer, odbc, os_mon, otp_mibs, parsetools, percept, public_key, reltool, runtime_tools, ssh, syntax_tools, test_server, tools, typer, webtool, wx, xmerl`\n\n A new test utility for testing appup files is added to test_server. This is\n now used by most applications in OTP.\n\n (Thanks to Tobias Schlager)\n\n Own Id: OTP-11744","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Moved elliptic curve definition from the crypto NIF/OpenSSL into Erlang code,\n adds the RFC-5639 brainpool curves and makes TLS use them (RFC-7027).\n\n Thanks to Andreas Schultz\n\n Own Id: OTP-11578\n\n- Unicode adaptations\n\n Own Id: OTP-11620\n\n- Added option honor_cipher_order. This instructs the server to prefer its own\n cipher ordering rather than the client's and can help protect against things\n like BEAST while maintaining compatibility with clients which only support\n older ciphers.\n\n Thanks to Andrew Thompson for the implementation, and Andreas Schultz for the\n test cases.\n\n Own Id: OTP-11621\n\n- Replace boolean checking in validate_option with is_boolean guard.\n\n Thanks to Andreas Schultz.\n\n Own Id: OTP-11634\n\n- Some function specs are corrected or moved and some edoc comments are\n corrected in order to allow use of edoc. (Thanks to Pierre Fenoll)\n\n Own Id: OTP-11702\n\n- Correct clean up of certificate database when certs are inputted in pure DER\n format.The incorrect code could cause a memory leek when certs where inputted\n in DER. Thanks to Bernard Duggan for reporting this.\n\n Own Id: OTP-11733\n\n- Improved documentation of the cacertfile option\n\n Own Id: OTP-11759 Aux Id: seq12535\n\n- Avoid next protocol negotiation failure due to incorrect option format.\n\n Own Id: OTP-11760\n\n- Handle v1 CRLs, with no extensions and fixes issues with IDP (Issuing\n Distribution Point) comparison during CRL validation.\n\n Thanks to Andrew Thompson\n\n Own Id: OTP-11761\n\n- Server now ignores client ECC curves that it does not support instead of\n crashing.\n\n Thanks to Danil Zagoskin for reporting the issue and suggesting a solution.\n\n Own Id: OTP-11780\n\n- Handle SNI (Server Name Indication) alert unrecognized_name and gracefully\n deal with unexpected alerts.\n\n Thanks to Masatake Daimon for reporting this.\n\n Own Id: OTP-11815\n\n- Add possibility to specify ssl options when calling ssl:ssl_accept\n\n Own Id: OTP-11837","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.3.3 - SSL Release Notes","ref":"notes.html#ssl-5-3-3"},{"type":"extras","doc":"- Add missing validation of the server_name_indication option and test for its\n explicit use. It was not possible to set or disable the default\n server_name_indication as the validation of the option was missing.\n\n Own Id: OTP-11567\n\n- Elliptic curve selection in server mode now properly selects a curve suggested\n by the client, if possible, and the fallback alternative is changed to a more\n widely supported curve.\n\n Own Id: OTP-11575\n\n- Bug in the TLS hello extension handling caused the server to behave as it did\n not understand secure renegotiation.\n\n Own Id: OTP-11595","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 5.3.2 - SSL Release Notes","ref":"notes.html#ssl-5-3-2"},{"type":"extras","doc":"- Honors the clients advertised support of elliptic curves and no longer sends\n incorrect elliptic curve extension in server hello.\n\n Own Id: OTP-11370\n\n- Fix initialization of DTLS fragment reassembler, in previously contributed\n code, for future support of DTLS . Thanks to Andreas Schultz.\n\n Own Id: OTP-11376\n\n- Corrected type error in client_preferred_next_protocols documentation. Thanks\n to Julien Barbot.\n\n Own Id: OTP-11457","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- TLS code has been refactored to prepare for future DTLS support. Also some\n DTLS code is in place but not yet runnable, some of it contributed by Andreas\n Schultz and some of it written by the OTP team. Thanks to to Andreas for his\n participation.\n\n Own Id: OTP-11292\n\n- Remove extraneous dev debug code left in the close function. Thanks to Ken\n Key.\n\n Own Id: OTP-11447\n\n- Add SSL Server Name Indication (SNI) client support. Thanks to Julien Barbot.\n\n Own Id: OTP-11460","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.3.1 - SSL Release Notes","ref":"notes.html#ssl-5-3-1"},{"type":"extras","doc":"- Setopts during renegotiation caused the renegotiation to be unsuccessful.\n\n If calling setopts during a renegotiation the FSM state might change during\n the handling of the setopts messages, this is now handled correctly.\n\n Own Id: OTP-11228\n\n- Now handles signature_algorithm field in digitally_signed properly with proper\n defaults. Prior to this change some elliptic curve cipher suites could fail\n reporting the error \"bad certificate\".\n\n Own Id: OTP-11229\n\n- The code emulating the inet header option was changed in the belief that it\n made it inet compatible. However the testing is a bit hairy as the inet option\n is actually broken, now the tests are corrected and the header option should\n work in the same broken way as inet again, preferably use the bitsyntax\n instead.\n\n Own Id: OTP-11230","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Make the ssl manager name for erlang distribution over SSL/TLS relative to the\n module name of the ssl_manager.\n\n This can be beneficial when making tools that rename modules for internal\n processing in the tool.\n\n Own Id: OTP-11255\n\n- Add documentation regarding log_alert option.\n\n Own Id: OTP-11271","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.3 - SSL Release Notes","ref":"notes.html#ssl-5-3"},{"type":"extras","doc":"- Honor the versions option to ssl:connect and ssl:listen.\n\n Own Id: OTP-10905\n\n- Next protocol negotiation with reused sessions will now succeed\n\n Own Id: OTP-10909","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add support for PSK (Pre Shared Key) and SRP (Secure Remote Password) cipher\n suites, thanks to Andreas Schultz.\n\n Own Id: OTP-10450 Aux Id: kunagi-269 \\[180]\n\n- Fix SSL Next Protocol Negotiation documentation. Thanks to Julien Barbot.\n\n Own Id: OTP-10955\n\n- Fix ssl_connection to support reading proxy/chain certificates. Thanks to\n Valentin Kuznetsov.\n\n Own Id: OTP-10980\n\n- Integrate elliptic curve contribution from Andreas Schultz\n\n In order to be able to support elliptic curve cipher suites in SSL/TLS,\n additions to handle elliptic curve infrastructure has been added to public_key\n and crypto.\n\n This also has resulted in a rewrite of the crypto API to gain consistency and\n remove unnecessary overhead. All OTP applications using crypto has been\n updated to use the new API.\n\n Impact: Elliptic curve cryptography (ECC) offers equivalent security with\n smaller key sizes than other public key algorithms. Smaller key sizes result\n in savings for power, memory, bandwidth, and computational cost that make ECC\n especially attractive for constrained environments.\n\n Own Id: OTP-11009","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.2.1 - SSL Release Notes","ref":"notes.html#ssl-5-2-1"},{"type":"extras","doc":"- Transport callback handling is changed so that gen_tcp is treated as a special\n case where inet will be called directly for functions such as setopts, as\n gen_tcp does not have its own setopts. This will enable users to use the\n transport callback for other customizations such as websockets.\n\n Own Id: OTP-10847\n\n- Follow up to OTP-10451 solved in ssl-5.2 R16A. Make sure format_error return\n good strings. Replace confusing legacy atoms with more descriptive atoms.\n\n Own Id: OTP-10864","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.1.2.1 - SSL Release Notes","ref":"notes.html#ssl-5-1-2-1"},{"type":"extras","doc":"- Make log_alert configurable as option in ssl, SSLLogLevel added as option to\n inets conf file\n\n Own Id: OTP-11259","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.2 - SSL Release Notes","ref":"notes.html#ssl-5-2"},{"type":"extras","doc":"- SSL: TLS 1.2, advertise sha224 support, thanks to Andreas Schultz.\n\n Own Id: OTP-10586\n\n- If an ssl server is restarted with new options and a client tries to reuse a\n session the server must make sure that it complies to the new options before\n agreeing to reuse it.\n\n Own Id: OTP-10595\n\n- Now handles cleaning of CA-certificate database correctly so that there will\n be no memory leek, bug was introduced in ssl- 5.1 when changing implementation\n to increase parallel execution.\n\n Impact: Improved memory usage, especially if you have many different\n certificates and upgrade tcp-connections to TLS-connections.\n\n Own Id: OTP-10710","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Support Next Protocol Negotiation in TLS, thanks to Ben Murphy for the\n contribution.\n\n Impact: Could give performance benefit if used as it saves a round trip.\n\n Own Id: OTP-10361 Aux Id: kunagi-214 \\[125]\n\n- TLS 1.2 will now be the default TLS version if sufficient crypto support is\n available otherwise TLS 1.1 will be default.\n\n Impact: A default TLS connection will have higher security and hence it may be\n perceived as slower then before.\n\n Own Id: OTP-10425 Aux Id: kunagi-275 \\[186]\n\n- It is now possible to call controlling_process on a listen socket, same as in\n gen_tcp.\n\n Own Id: OTP-10447\n\n- Remove filter mechanisms that made error messages backwards compatible with\n old ssl but hid information about what actually happened.\n\n This does not break the documented API however other reason terms may be\n returned, so code that matches on the reason part of \\{error, Reason\\} may\n fail.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-10451 Aux Id: kunagi-270 \\[181]\n\n- Added missing dependencies to Makefile\n\n Own Id: OTP-10594\n\n- Removed deprecated function ssl:pid/0, it has been pointless since R14 but has\n been keep for backwards compatibility.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-10613 Aux Id: kunagi-331 \\[242]\n\n- Refactor to simplify addition of key exchange methods, thanks to Andreas\n Schultz.\n\n Own Id: OTP-10709","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.1.2 - SSL Release Notes","ref":"notes.html#ssl-5-1-2"},{"type":"extras","doc":"- ssl:ssl_accept/2 timeout is no longer ignored\n\n Own Id: OTP-10600","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 5.1.1 - SSL Release Notes","ref":"notes.html#ssl-5-1-1"},{"type":"extras","doc":"- ssl:recv/3 could \"loose\" data when the timeout occurs. If the timeout in\n ssl:connect or ssl:ssl_accept expired the ssl connection process was not\n terminated as it should, this due to gen_fsm:send_all_state_event timeout is a\n client side time out. These timouts are now handled by the gen_fsm-procss\n instead.\n\n Own Id: OTP-10569","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Better termination handling that avoids hanging.\n\n Own Id: OTP-10574","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.1 - SSL Release Notes","ref":"notes.html#ssl-5-1"},{"type":"extras","doc":"- Sometimes the client process could receive an extra \\{error, closed\\} message\n after ssl:recv had returned \\{error, closed\\}.\n\n Own Id: OTP-10118\n\n- ssl v3 alert number 41 (no_certificate_RESERVED) is now recognized\n\n Own Id: OTP-10196","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Experimental support for TLS 1.1 is now available, will be officially\n supported from OTP-R16. Thanks to Andreas Schultz for implementing the first\n version.\n\n Own Id: OTP-8871\n\n- Experimental support for TLS 1.2 is now available, will be officially\n supported from OTP-R16. Thanks to Andreas Schultz for implementing the first\n version.\n\n Own Id: OTP-8872\n\n- Removed some bottlenecks increasing the applications parallelism especially\n for the client side.\n\n Own Id: OTP-10113\n\n- Workaround for handling certificates that wrongly encode X509countryname in\n utf-8 when the actual value is a valid ASCCI value of length 2. Such\n certificates are accepted by many browsers such as Chrome and Fierfox so for\n interoperability reasons we will too.\n\n Own Id: OTP-10222","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 5.0.1 - SSL Release Notes","ref":"notes.html#ssl-5-0-1"},{"type":"extras","doc":"- Robustness and improvement to distribution over SSL\n\n Fix a bug where ssl_tls_dist_proxy would crash at caller timeout. Fix a bug\n where a timeout from the SSL layer would block the distribution indefinitely.\n Run the proxy exclusively on the loopback interface. (Thanks to Paul Guyot)\n\n Own Id: OTP-9915\n\n- Fix setup loop of SSL TLS dist proxy\n\n Fix potential leak of processes waiting indefinitely for data from closed\n sockets during socket setup phase. (Thanks to Paul Guyot)\n\n Own Id: OTP-9916\n\n- Correct spelling of registered (Thanks to Richard Carlsson)\n\n Own Id: OTP-9925\n\n- Added TLS PRF function to the SSL API for generation of additional key\n material from a TLS session. (Thanks to Andreas Schultz)\n\n Own Id: OTP-10024","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 5.0 - SSL Release Notes","ref":"notes.html#ssl-5-0"},{"type":"extras","doc":"- Invalidation handling of sessions could cause the time_stamp field in the\n session record to be set to undefined crashing the session clean up process.\n This did not affect the connections but would result in that the session table\n would grow.\n\n Own Id: OTP-9696 Aux Id: seq11947\n\n- Changed code to use ets:foldl and throw instead of ets:next traversal,\n avoiding the need to explicitly call ets:safe_fixtable. It was possible to get\n a badarg-crash under special circumstances.\n\n Own Id: OTP-9703 Aux Id: seq11947\n\n- Send ssl_closed notification to active ssl user when a tcp error occurs.\n\n Own Id: OTP-9734 Aux Id: seq11946\n\n- If a passive receive was ongoing during a renegotiation the process evaluating\n ssl:recv could be left hanging for ever.\n\n Own Id: OTP-9744","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Support for the old ssl implementation is dropped and the code is removed.\n\n Own Id: OTP-7048\n\n- The erlang distribution can now be run over the new ssl implementation. All\n options can currently not be set but it is enough to replace to old ssl\n implementation.\n\n Own Id: OTP-7053\n\n- public_key, ssl and crypto now supports PKCS-8\n\n Own Id: OTP-9312\n\n- Implements a CBC timing attack counter measure. Thanks to Andreas Schultz for\n providing the patch.\n\n Own Id: OTP-9683\n\n- Mitigates an SSL/TLS Computational DoS attack by disallowing the client to\n renegotiate many times in a row in a short time interval, thanks to Tuncer\n Ayaz for alerting us about this.\n\n Own Id: OTP-9739\n\n- Implements the 1/n-1 splitting countermeasure to the Rizzo Duong BEAST attack,\n affects SSL 3.0 and TLS 1.0. Thanks to Tuncer Ayaz for alerting us about this.\n\n Own Id: OTP-9750","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 4.1.6 - SSL Release Notes","ref":"notes.html#ssl-4-1-6"},{"type":"extras","doc":"- replace \"a ssl\" with \"an ssl\" reindent pkix_path_validation/3 Trivial\n documentation fixes (Thanks to Christian von Roques )\n\n Own Id: OTP-9464","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Adds function clause to avoid denial of service attack. Thanks to Vinod for\n reporting this vulnerability.\n\n Own Id: OTP-9364\n\n- Error handling code now takes care of inet:getopts/2 and inets:setopts/2\n crashes. Thanks to Richard Jones for reporting this.\n\n Own Id: OTP-9382\n\n- Support explicit use of packet option httph and httph_bin\n\n Own Id: OTP-9461\n\n- Decoding of hello extensions could fail to come to the correct conclusion due\n to an error in a binary match pattern. Thanks to Ben Murphy.\n\n Own Id: OTP-9589","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 4.1.5 - SSL Release Notes","ref":"notes.html#ssl-4-1-5"},{"type":"extras","doc":"- Calling gen_tcp:connect with option \\{ip, \\{127,0,0,1\\}\\} results in an exit\n with reason badarg. Neither SSL nor INETS This was not caught, resulting in\n crashes with incomprehensible reasons.\n\n Own Id: OTP-9289 Aux Id: seq11845","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 4.1.3 - SSL Release Notes","ref":"notes.html#ssl-4-1-3"},{"type":"extras","doc":"- Fixed error in cache-handling fix from ssl-4.1.2\n\n Own Id: OTP-9018 Aux Id: seq11739\n\n- Verification of a critical extended_key_usage-extension corrected\n\n Own Id: OTP-9029 Aux Id: seq11541","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 4.1.2 - SSL Release Notes","ref":"notes.html#ssl-4-1-2"},{"type":"extras","doc":"- The ssl application caches certificate files, it will now invalidate cache\n entries if the diskfile is changed.\n\n Own Id: OTP-8965 Aux Id: seq11739\n\n- Now runs the terminate function before returning from the call made by\n ssl:close/1, as before the caller of ssl:close/1 could get problems with the\n reuseaddr option.\n\n Own Id: OTP-8992","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"SSL 4.1.1 - SSL Release Notes","ref":"notes.html#ssl-4-1-1"},{"type":"extras","doc":"- Correct handling of client certificate verify message When checking the client\n certificate verify message the server used the wrong algorithm identifier to\n determine the signing algorithm, causing a function clause error in the\n public_key application when the key-exchange algorithm and the public key\n algorithm of the client certificate happen to differ.\n\n Own Id: OTP-8897","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- For testing purposes ssl now also support some anonymous cipher suites when\n explicitly configured to do so.\n\n Own Id: OTP-8870\n\n- Sends an error alert instead of crashing if a crypto function for the selected\n cipher suite fails.\n\n Own Id: OTP-8930 Aux Id: seq11720","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 4.1 - SSL Release Notes","ref":"notes.html#ssl-4-1"},{"type":"extras","doc":"- Updated ssl to ignore CA certs that violate the asn1-spec for a certificate,\n and updated public key asn1 spec to handle inherited DSS-params.\n\n Own Id: OTP-7884\n\n- Changed ssl implementation to retain backwards compatibility for old option\n \\{verify, 0\\} that shall be equivalent to \\{verify, verify_none\\}, also\n separate the cases unknown ca and selfsigned peer cert, and restored return\n value of deprecated function public_key:pem_to_der/1.\n\n Own Id: OTP-8858\n\n- Changed the verify fun so that it differentiate between the peer certificate\n and CA certificates by using valid_peer or valid as the second argument to the\n verify fun. It may not always be trivial or even possible to know when the\n peer certificate is reached otherwise.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-8873","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 4.0.1 - SSL Release Notes","ref":"notes.html#ssl-4-0-1"},{"type":"extras","doc":"- The server now verifies the client certificate verify message correctly,\n instead of causing a case-clause.\n\n Own Id: OTP-8721\n\n- The client hello message now always include ALL available cipher suites (or\n those specified by the ciphers option). Previous implementation would filter\n them based on the client certificate key usage extension (such filtering only\n makes sense for the server certificate).\n\n Own Id: OTP-8772\n\n- Fixed handling of the option \\{mode, list\\} that was broken for some packet\n types for instance line.\n\n Own Id: OTP-8785\n\n- Empty packets were not delivered to the client.\n\n Own Id: OTP-8790\n\n- Building in a source tree without prebuilt platform independent build results\n failed on the SSL examples when:\n\n - cross building. This has been solved by not building the SSL examples during\n a cross build.\n - building on Windows.\n\n Own Id: OTP-8791\n\n- Fixed a handshake error which occurred on some ssl implementations.\n\n Own Id: OTP-8793","title":"Fixed Bugs and Malfunctions - SSL Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Revise the public_key API - Cleaned up and documented the public_key API to\n make it useful for general use, also changed ssl to use the new API.\n\n Own Id: OTP-8722\n\n- Added support for inputing certificates and keys directly in DER format these\n options will override the pem-file options if specified.\n\n Own Id: OTP-8723\n\n- To gain interoperability ssl will not check for padding errors when using TLS\n 1.0. It is first in TLS 1.1 that checking the padding is an requirement.\n\n Own Id: OTP-8740\n\n- Changed the semantics of the verify_fun option in the ssl-application so that\n it takes care of both application handling of path validation errors and\n verification of application specific extensions. This means that it is now\n possible for the server application in verify_peer mode to handle path\n validation errors. This change moved some functionality earlier in ssl to the\n public_key application.\n\n Own Id: OTP-8770\n\n- Added the functionality so that the verification fun will be called when a\n certificate is considered valid by the path validation to allow access to each\n certificate in the path to the user application. Also try to verify\n subject-AltName, if unable to verify it let the application verify it.\n\n Own Id: OTP-8825","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"SSL 4.0 - SSL Release Notes","ref":"notes.html#ssl-4-0"},{"type":"extras","doc":"- New ssl now support client/server-certificates signed by dsa keys.\n\n Own Id: OTP-8587\n\n- Ssl has now switched default implementation and removed deprecated certificate\n handling. All certificate handling is done by the public_key application.\n\n Own Id: OTP-8695","title":"Improvements and New Features - SSL Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"\n\n# TLS/DTLS Protocol Overview","title":"TLS/DTLS Protocol Overview","ref":"ssl_protocol.html"},{"type":"extras","doc":"Transport Layer Security (TLS) and its predecessor, the Secure Sockets Layer\n(SSL), are cryptographic protocols designed to provide communications security\nover a computer network. The protocols use X.509 certificates and hence public\nkey (asymmetric) cryptography to authenticate the counterpart with whom they\ncommunicate, and to exchange a symmetric key for payload encryption. The\nprotocol provides data/message confidentiality (encryption), integrity (through\nmessage authentication code checks) and host verification (through certificate\npath validation). DTLS (Datagram Transport Layer Security) that is based on TLS\nbut datagram oriented instead of stream oriented.\n\n# Erlang Support\n\nThe Erlang SSL application implements the TLS/DTLS protocol for the currently\nsupported versions, see the `m:ssl` manual page.\n\nBy default TLS is run over the TCP/IP protocol even though you can plug in any\nother reliable transport protocol with the same Application Programming\nInterface (API) as the `gen_tcp` module in Kernel. DTLS is by default run over\nUDP/IP, which means that application data has no delivery guarantees. Other\ntransports, such as SCTP, may be supported in future releases.\n\nIf a client and a server wants to use an upgrade mechanism, such as defined by\nRFC 2817, to upgrade a regular TCP/IP connection to a TLS connection, this is\nsupported by the Erlang SSL application API. This can be useful for, for\nexample, supporting HTTP and HTTPS on the same port and implementing virtual\nhosting. Note this is a TLS feature only.","title":"Purpose - TLS/DTLS Protocol Overview","ref":"ssl_protocol.html#purpose"},{"type":"extras","doc":"To achieve authentication and privacy, the client and server perform a TLS/DTLS\nhandshake procedure before transmitting or receiving any data. During the\nhandshake, they agree on a protocol version and cryptographic algorithms,\ngenerate shared secrets using public key cryptographies, and optionally\nauthenticate each other with digital certificates.","title":"Security Overview - TLS/DTLS Protocol Overview","ref":"ssl_protocol.html#security-overview"},{"type":"extras","doc":"A _symmetric key_ algorithm has one key only. The key is used for both\nencryption and decryption. These algorithms are fast, compared to public key\nalgorithms (using two keys, one public and one private) and are therefore\ntypically used for encrypting bulk data.\n\nThe keys for the symmetric encryption are generated uniquely for each connection\nand are based on a secret negotiated in the TLS/DTLS handshake.\n\nThe TLS/DTLS handshake protocol and data transfer is run on top of the TLS/DTLS\nRecord Protocol, which uses a keyed-hash Message Authenticity Code (MAC), or a\nHash-based MAC (HMAC), to protect the message data integrity. From the TLS RFC:\n\"A Message Authentication Code is a one-way hash computed from a message and\nsome secret data. It is difficult to forge without knowing the secret data. Its\npurpose is to detect if the message has been altered.\"","title":"Data Privacy and Integrity - TLS/DTLS Protocol Overview","ref":"ssl_protocol.html#data-privacy-and-integrity"},{"type":"extras","doc":"A certificate is similar to a driver's license, or a passport. The holder of the\ncertificate is called the _subject_. The certificate is signed with the private\nkey of the issuer of the certificate. A chain of trust is built by having the\nissuer in its turn being certified by another certificate, and so on, until you\nreach the so called root certificate, which is self-signed, that is, issued by\nitself.\n\nCertificates are issued by Certification Authorities (CAs) only. A handful of\ntop CAs in the world issue root certificates. You can examine several of these\ncertificates by clicking through the menus of your web browser.","title":"Digital Certificates - TLS/DTLS Protocol Overview","ref":"ssl_protocol.html#digital-certificates"},{"type":"extras","doc":"Authentication of the peer is done by public key path validation as defined in\nRFC 3280. This means basically the following:\n\n- Each certificate in the certificate chain is issued by the previous one.\n- The certificates attributes are valid.\n- The root certificate is a trusted certificate that is present in the trusted\n certificate database kept by the peer.\n\nThe server always sends a certificate chain as part of the TLS handshake, but\nthe client only sends one if requested by the server. If the client does not\nhave an appropriate certificate, it can send an \"empty\" certificate to the\nserver.\n\nThe client can choose to accept some path evaluation errors, for example, a web\nbrowser can ask the user whether to accept an unknown CA root certificate. The\nserver, if it requests a certificate, does however not accept any path\nvalidation errors. It is configurable if the server is to accept or reject an\n\"empty\" certificate as response to a certificate request.","title":"Peer Authentication - TLS/DTLS Protocol Overview","ref":"ssl_protocol.html#peer-authentication"},{"type":"extras","doc":"From the TLS RFC: \"A TLS session is an association between a client and a\nserver. Sessions are created by the handshake protocol. Sessions define a set of\ncryptographic security parameters, which can be shared among multiple\nconnections. Sessions are used to avoid the expensive negotiation of new\nsecurity parameters for each connection.\"\n\nSession data is by default kept by the SSL application in a memory storage,\nhence session data is lost at application restart or takeover. Users can define\ntheir own callback module to handle session data storage if persistent data\nstorage is required. Session data is also invalidated when session database\nexceeds its limit or 24 hours after being saved (RFC max lifetime\nrecommendation). The amount of time the session data is to be saved can be\nconfigured.\n\nBy default the TLS/DTLS clients try to reuse an available session and by default\nthe TLS/DTLS servers agree to reuse sessions when clients ask for it. See also\n[Session Reuse Prior to TLS-1.3](using_ssl.md#session-reuse-prior-to-tls-1-3)","title":"TLS Sessions - Prior to TLS-1.3 - TLS/DTLS Protocol Overview","ref":"ssl_protocol.html#tls-sessions-prior-to-tls-1-3"},{"type":"extras","doc":"In TLS 1.3 the session reuse is replaced by a new session tickets mechanism\nbased on the prior to shared key concept. This mechanism also obsoletes the session\ntickets from RFC5077, not implemented by this application. See also\n[Session Tickets and Session Resumption in TLS-1.3](using_ssl.md#session-tickets-and-session-resumption-in-tls-1-3)","title":"TLS-1.3 session tickets - TLS/DTLS Protocol Overview","ref":"ssl_protocol.html#tls-1-3-session-tickets"},{"type":"extras","doc":"\n# Examples\n\nTo see relevant version information for ssl, call `ssl:versions/0` .\n\nTo see all supported cipher suites, call\n[`ssl:cipher_suites(all, 'tlsv1.3')` ](`ssl:cipher_suites/2`). The available\ncipher suites for a connection depend on the TLS version and prior to TLS-1.3 also on\nthe certificate. To see the default cipher suite list change `all` to `default`.\nNote that TLS 1.3 and previous versions do not have any cipher suites in common,\nfor listing cipher suites for a specific version use\n[`ssl:cipher_suites(exclusive, 'tlsv1.3')` ](`ssl:cipher_suites/2`). Specific\ncipher suites that you want your connection to use can also be specified.\nDefault is to use the strongest available.\n\n\n> #### Warning {: .warning }\n>Enabling cipher suites using RSA as a key exchange algorithm is\n>strongly discouraged (only available prior to TLS-1.3). For some\n>configurations software preventions may exist, and can make them usable if they work,\n>but relying on them to work is risky and there are many more reliable\n>cipher suites that can be used instead.\n\nThe following sections shows small examples of how to set up client/server\nconnections using the Erlang shell. The returned value of the `sslsocket` is\nabbreviated with `[...]` as it can be fairly large and is opaque to the user\nexcept for the purpose of pattern matching.\n\n> #### Note {: .info }\n>\n> Note that client certificate verification is optional for the server and needs\n> additional conguration on both sides to work. The Certificate and keys, in the\n> examples, are provided using the `t:ssl:cert_key_conf/0` supplied in the `certs_keys`\n> introduced in OTP 25.","title":"Examples","ref":"using_ssl.html"},{"type":"extras","doc":"```erlang\n 1 > ssl:start(), ssl:connect(\"google.com\", 443, [{verify, verify_peer},\n {cacerts, public_key:cacerts_get()}]).\n {ok,{sslsocket, [...]}}\n```","title":"Basic Client - Examples","ref":"using_ssl.html#basic-client"},{"type":"extras","doc":"_Step 1:_ Start the server side:\n\n```erlang\n1 server> ssl:start().\nok\n```\n\n_Step 2:_ with alternative certificates, in this example the EDDSA certificate\nwill be preferred if TLS-1.3 is negotiated and the RSA certificate will always\nbe used for TLS-1.2 as it does not support the EDDSA algorithm:\n\n```erlang\n2 server> {ok, ListenSocket} =\nssl:listen(9999, [{certs_keys, [#{certfile => \"eddsacert.pem\",\n keyfile => \"eddsakey.pem\"},\n #{certfile => \"rsacert.pem\",\n keyfile => \"rsakey.pem\",\n password => \"foobar\"}\n ]},{reuseaddr, true}]).\n{ok,{sslsocket, [...]}}\n```\n\n_Step 3:_ Do a transport accept on the TLS listen socket:\n\n```erlang\n3 server> {ok, TLSTransportSocket} = ssl:transport_accept(ListenSocket).\n{ok,{sslsocket, [...]}}\n```\n\n> #### Note {: .info }\n>\n> ssl:transport_accept/1 and ssl:handshake/2 are separate functions so that the\n> handshake part can be called in a new erlang process dedicated to handling the\n> connection\n\n_Step 4:_ Start the client side:\n\n```erlang\n1 client> ssl:start().\nok\n```\n\nBe sure to configure trusted certificates to use for server certificate\nverification.\n\n```erlang\n2 client> {ok, Socket} = ssl:connect(\"localhost\", 9999,\n [{verify, verify_peer},\n {cacertfile, \"cacerts.pem\"}, {active, once}], infinity).\n{ok,{sslsocket, [...]}}\n```\n\n_Step 5:_ Do the TLS handshake:\n\n```erlang\n4 server> {ok, Socket} = ssl:handshake(TLSTransportSocket).\n{ok,{sslsocket, [...]}}\n```\n\n> #### Note {: .info }\n>\n> A real server should use ssl:handshake/2 that has a timeout to avoid DoS\n> attacks. In the example the timeout defaults to infinty.\n\n_Step 6:_ Send a message over TLS:\n\n```erlang\n5 server> ssl:send(Socket, \"foo\").\nok\n```\n\n_Step 7:_ Flush the shell message queue to see that the message sent on the\nserver side is recived by the client side:\n\n```erlang\n3 client> flush().\nShell got {ssl,{sslsocket,[...]},\"foo\"}\nok\n```","title":"Basic Connection - Examples","ref":"using_ssl.html#basic-connection"},{"type":"extras","doc":"Upgrading a a TCP/IP connection to a TLS connections is mostly used when there\nis a desire have unencrypted communication first and then later secure the\ncommunication channel by using TLS. Note that the client and server need to\nagree to do the upgrade in the protocol doing the communication. This is concept\nis often referenced as `STARTLS` and used in many protocols such as `SMTP`,\n`FTPS` and `HTTPS` via a proxy.\n\n> #### Warning {: .warning }\n>\n> Maximum security recommendations are however moving away from such solutions.\n\nTo upgrade to a TLS connection:\n\n_Step 1:_ Start the server side:\n\n```erlang\n1 server> ssl:start().\n ok\n```\n\n_Step 2:_ Create a normal TCP listen socket and ensure `active` is set to\n`false` and not set to any active mode otherwise TLS handshake messages can be\ndelivered to the wrong process.\n\n```erlang\n2 server> {ok, ListenSocket} = gen_tcp:listen(9999, [{reuseaddr, true},\n {active, false}]).\n {ok, #Port<0.475>}\n```\n\n_Step 3:_ Accept client connection:\n\n```erlang\n3 server> {ok, Socket} = gen_tcp:accept(ListenSocket).\n {ok, #Port<0.476>}\n```\n\n_Step 4:_ Start the client side:\n\n```erlang\n1 client> ssl:start().\n ok\n```\n\n```erlang\n2 client> {ok, Socket} = gen_tcp:connect(\"localhost\", 9999, [], infinity).\n```\n\n_Step 5:_ Do the TLS handshake:\n\n```erlang\n4 server> {ok, TLSSocket} = ssl:handshake(Socket, [{verify, verify_peer},\n {fail_if_no_peer_cert, true},\n {cacertfile, \"cacerts.pem\"},\n {certs_keys, [#{certfile => \"cert.pem\", keyfile => \"key.pem\"}]}]).\n {ok,{sslsocket,[...]}}\n```\n\n_Step 6:_ Upgrade to a TLS connection. The client and server must agree upon the\nupgrade. The server must be prepared to be a TLS server before the client can do\na successful connect.\n\n```erlang\n3 client>{ok, TLSSocket} = ssl:connect(Socket, [{verify, verify_peer},\n {cacertfile, \"cacerts.pem\"},\n {certs_keys, [#{certfile => \"cert.pem\", keyfile => \"key.pem\"}]}], infinity).\n{ok,{sslsocket,[...]}}\n```\n\n_Step 7:_ Send a message over TLS:\n\n```erlang\n4 client> ssl:send(TLSSocket, \"foo\").\n ok\n```\n\n_Step 8:_ Set `active once` on the TLS socket:\n\n```erlang\n5 server> ssl:setopts(TLSSocket, [{active, once}]).\n ok\n```\n\n_Step 9:_ Flush the shell message queue to see that the message sent on the\nclient side is recived by the server side:\n\n```erlang\n5 server> flush().\n Shell got {ssl,{sslsocket,[...]},\"foo\"}\n ok\n```","title":"Upgrade Example - TLS only - Examples","ref":"using_ssl.html#upgrade-example-tls-only"},{"type":"extras","doc":"Fetch default cipher suite list for a TLS/DTLS version. Change default to all to\nget all possible cipher suites.\n\n```erlang\n1> Default = ssl:cipher_suites(default, 'tlsv1.2').\n [#{cipher => aes_256_gcm,key_exchange => ecdhe_ecdsa,\n mac => aead,prf => sha384}, ....]\n```\n\nIn OTP 20 it is desirable to remove all cipher suites that uses rsa key exchange\n(removed from default in 21)\n\n```erlang\n2> NoRSA =\n ssl:filter_cipher_suites(Default,\n [{key_exchange, fun(rsa) -> false;\n (_) -> true\n end}]).\n [...]\n```\n\nPick just a few suites\n\n```erlang\n 3> Suites =\n ssl:filter_cipher_suites(Default,\n [{key_exchange, fun(ecdh_ecdsa) -> true;\n (_) -> false\n end},\n {cipher, fun(aes_128_cbc) -> true;\n (_) ->false\n end}]).\n\n[#{cipher => aes_128_cbc,key_exchange => ecdh_ecdsa,\n mac => sha256,prf => sha256},\n #{cipher => aes_128_cbc,key_exchange => ecdh_ecdsa,mac => sha,\n prf => default_prf}]\n```\n\nMake some particular suites the most preferred, or least preferred by changing\nprepend to append.\n\n```erlang\n 4>ssl:prepend_cipher_suites(Suites, Default).\n [#{cipher => aes_128_cbc,key_exchange => ecdh_ecdsa,\n mac => sha256,prf => sha256},\n #{cipher => aes_128_cbc,key_exchange => ecdh_ecdsa,mac => sha,\n prf => default_prf},\n #{cipher => aes_256_cbc,key_exchange => ecdhe_ecdsa,\n mac => sha384,prf => sha384}, ...]\n```","title":"Customizing cipher suites - Examples","ref":"using_ssl.html#customizing-cipher-suites"},{"type":"extras","doc":"Starting from TLS-1.2 signature algorithms (called signature schemes in TLS-1.3)\nis something that can be negotiated and hence also configured. These\nalgorithms/schemes will be used for digital signatures in protocol messages and\nin certificates.\n\n> #### Note {: .info }\n>\n> TLS-1.3 schemes have atom names whereas TLS-1.2 configuration is two element\n> tuples composed by one hash algorithm and one signature algorithm. When both\n> versions are supported the configuration can be a mix of these as both\n> versions might be negotiated. All `rsa_pss` based schemes are back ported to\n> TLS-1.2 and can be used also in a TLS-1.2 configuration. In TLS-1.2 the\n> signature algorithms chosen by the server will also be affected by the chiper\n> suite that is chosen, which is not the case in TLS-1.3.\n\nUsing the function `ssl:signature_algs/2` will let you inspect different aspects\nof possible configurations for your system. For example if TLS-1.3 and TLS-1.2\nis supported the default signature_algorithm list in OTP-26 and cryptolib from\nOpenSSL 3.0.2 would look like:\n\n```erlang\n 1> ssl:signature_algs(default, 'tlsv1.3').\n %% TLS-1.3 schemes\n [eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,\n ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,\n rsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,\n rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,\n %% Legacy schemes only valid for certificate signatures in TLS-1.3\n %% (would have a tuple name in TLS-1.2 only configuration)\n rsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256\n %% TLS 1.2 algorithms\n {sha512,ecdsa},\n {sha384,ecdsa},\n {sha256,ecdsa}]\n```\n\nIf you want to add support for non default supported algorithms you should\nappend them to the default list as the configuration is in prefered order,\nsomething like this:\n\n```erlang\n MySignatureAlgs = ssl:signature_algs(default, 'tlsv1.3') ++ [{sha, rsa}, {sha, dsa}],\n ssl:connect(Host,Port,[{signature_algs, MySignatureAlgs,...]}),\n ...\n```\n\nSee also `ssl:signature_algs/2` and [sign_algo()](`t:ssl:signature_algs/0`)","title":"Customizing signature algorithms(TLS-1.2)/schemes(TLS-1.3) - Examples","ref":"using_ssl.html#customizing-signature-algorithms-tls-1-2-schemes-tls-1-3"},{"type":"extras","doc":"Erlang ssl application is able to use private keys provided by OpenSSL engines\nusing the following mechanism:\n\n```erlang\n1> ssl:start().\nok\n```\n\nLoad a crypto engine, should be done once per engine used. For example\ndynamically load the engine called `MyEngine`:\n\n```erlang\n2> {ok, EngineRef} =\ncrypto:engine_load(<<\"dynamic\">>,\n[{<<\"SO_PATH\">>, \"/tmp/user/engines/MyEngine\"},<<\"LOAD\">>],\n[]).\n{ok,#Ref<0.2399045421.3028942852.173962>}\n```\n\nCreate a map with the engine information and the algorithm used by the engine:\n\n```erlang\n3> PrivKey =\n #{algorithm => rsa,\n engine => EngineRef,\n key_id => \"id of the private key in Engine\"}.\n```\n\nUse the map in the ssl key option:\n\n```erlang\n4> {ok, SSLSocket} =\n ssl:connect(\"localhost\", 9999,\n [{cacertfile, \"cacerts.pem\"},\n {certs_keys, [#{certfile => \"cert.pem\", key => PrivKey}]}\n ], infinity).\n\n```\n\nSee also [crypto documentation](`e:crypto:engine_load.md#engine_load`)","title":"Using an Engine Stored Key - Examples","ref":"using_ssl.html#using-an-engine-stored-key"},{"type":"extras","doc":"The NSS keylog debug feature can be used by authorized users to for instance\nenable wireshark to decrypt TLS packets.\n\n_Server (with NSS key logging)_\n\n```erlang\n server() ->\n application:load(ssl),\n {ok, _} = application:ensure_all_started(ssl),\n Port = 11029,\n LOpts = [{certs_keys, [#{certfile => \"cert.pem\", keyfile => \"key.pem\"}]},\n {reuseaddr, true},\n {versions, ['tlsv1.2','tlsv1.3']},\n {keep_secrets, true} %% Enable NSS key log (debug option)\n ],\n {ok, LSock} = ssl:listen(Port, LOpts),\n {ok, ASock} = ssl:transport_accept(LSock),\n {ok, CSock} = ssl:handshake(ASock).\n```\n\n_Exporting the secrets_\n\n```erlang\n {ok, [{keylog, KeylogItems}]} = ssl:connection_information(CSock, [keylog]).\n file:write_file(\"key.log\", [[KeylogItem,$\\n] || KeylogItem <- KeylogItems]).\n```","title":"NSS keylog - Examples","ref":"using_ssl.html#nss-keylog"},{"type":"extras","doc":"Clients can request to reuse a session established by a previous full handshake\nbetween that client and server by sending the id of the session in the initial\nhandshake message. The server may or may not agree to reuse it. If agreed the\nserver will send back the id and if not it will send a new id. The ssl\napplication has several options for handling session reuse.\n\nOn the client side the ssl application will save session data to try to automate\nsession reuse on behalf of the client processes on the Erlang node. Note that\nonly verified sessions will be saved for security reasons, that is session\nresumption relies on the certificate validation to have been run in the original\nhandshake. To minimize memory consumption only unique sessions will be saved\nunless the special `save` value is specified for the following option\n`{reuse_sessions, boolean() | save}` in which case a full handshake will be\nperformed and that specific session will have been saved before the handshake\nreturns. The session id and even an opaque binary containing the session data\ncan be retrieved using `ssl:connection_information/1` function. A saved session\n(guaranteed by the save option) can be explicitly reused using\n`{reuse_session, SessionId}`. Also it is possible for the client to reuse a\nsession that is not saved by the ssl application using\n`{reuse_session, {SessionId, SessionData}}`.\n\n> #### Note {: .info }\n>\n> When using explicit session reuse, it is up to the client to make sure that\n> the session being reused is for the correct server and has been verified.\n\nHere follows a client side example, divide into several steps for readability.\n\nStep 1 - Automated Session Reuse\n\n```erlang\n1> ssl:start().\nok\n\n2>{ok, C1} = ssl:connect(\"localhost\", 9999, [{verify, verify_peer},\n {versions, ['tlsv1.2']},\n {cacertfile, \"cacerts.pem\"}]).\n{ok,{sslsocket,{gen_tcp,#Port<0.7>,tls_connection,undefined}, ...}}\n\n3> ssl:connection_information(C1, [session_id]).\n{ok,[{session_id,<<95,32,43,22,35,63,249,22,26,36,106,\n 152,49,52,124,56,130,192,137,161,\n 146,145,164,232,...>>}]}\n\n%% Reuse session if possible, note that if C2 is really fast the session\n%% data might not be available for reuse.\n4>{ok, C2} = ssl:connect(\"localhost\", 9999, [{verify, verify_peer},\n {versions, ['tlsv1.2']},\n {cacertfile, \"cacerts.pem\"},\n {reuse_sessions, true}]).\n{ok,{sslsocket,{gen_tcp,#Port<0.8>,tls_connection,undefined}, ...]}}\n\n%% C2 got same session ID as client one, session was automatically reused.\n5> ssl:connection_information(C2, [session_id]).\n{ok,[{session_id,<<95,32,43,22,35,63,249,22,26,36,106,\n 152,49,52,124,56,130,192,137,161,\n 146,145,164,232,...>>}]}\n```\n\nStep 2- Using `save` Option\n\n```erlang\n%% We want save this particular session for\n%% reuse although it has the same basis as C1\n6> {ok, C3} = ssl:connect(\"localhost\", 9999, [{verify, verify_peer},\n {versions, ['tlsv1.2']},\n {cacertfile, \"cacerts.pem\"},\n {reuse_sessions, save}]).\n\n{ok,{sslsocket,{gen_tcp,#Port<0.9>,tls_connection,undefined}, ...]}}\n\n%% A full handshake is performed and we get a new session ID\n7> {ok, [{session_id, ID}]} = ssl:connection_information(C3, [session_id]).\n{ok,[{session_id,<<91,84,27,151,183,39,84,90,143,141,\n 121,190,66,192,10,1,27,192,33,95,78,\n 8,34,180,...>>}]}\n\n%% Use automatic session reuse\n8> {ok, C4} = ssl:connect(\"localhost\", 9999, [{verify, verify_peer},\n {versions, ['tlsv1.2']},\n {cacertfile, \"cacerts.pem\"},\n {reuse_sessions, true}]).\n\n{ok,{sslsocket,{gen_tcp,#Port<0.10>,tls_connection,\n undefined}, ...]}}\n\n%% The \"saved\" one happened to be selected, but this is not a guarantee\n9> ssl:connection_information(C4, [session_id]).\n{ok,[{session_id,<<91,84,27,151,183,39,84,90,143,141,\n 121,190,66,192,10,1,27,192,33,95,78,\n 8,34,180,...>>}]}\n\n%% Make sure to reuse the \"saved\" session\n10> {ok, C5} = ssl:connect(\"localhost\", 9999, [{verify, verify_peer},\n {versions, ['tlsv1.2']},\n {cacertfile, \"cacerts.pem\"},\n {reuse_session, ID}]).\n{ok,{sslsocket,{gen_tcp,#Port<0.11>,tls_connection,\n undefined}, ...]}}\n\n11> ssl:connection_information(C5, [session_id]).\n{ok,[{session_id,<<91,84,27,151,183,39,84,90,143,141,\n 121,190,66,192,10,1,27,192,33,95,78,\n 8,34,180,...>>}]}\n```\n\nStep 3 - Explicit Session Reuse\n\n```erlang\n%% Perform a full handshake and the session will not be saved for reuse\n12> {ok, C9} =\nssl:connect(\"localhost\", 9999, [{verify, verify_peer},\n {versions, ['tlsv1.2']},\n {cacertfile, \"cacerts.pem\"},\n {reuse_sessions, false},\n {server_name_indication, disable}]).\n{ok,{sslsocket,{gen_tcp,#Port<0.14>,tls_connection, ...}}\n\n%% Fetch session ID and data for C9 connection\n12> {ok, [{session_id, ID1}, {session_data, SessData}]} =\n ssl:connection_information(C9, [session_id, session_data]).\n{ok,[{session_id,<<9,233,4,54,170,88,170,180,17,96,202,\n 85,85,99,119,47,9,68,195,50,120,52,\n 130,239,...>>},\n {session_data,<<131,104,13,100,0,7,115,101,115,115,105,\n 111,110,109,0,0,0,32,9,233,4,54,170,...>>}]}\n\n%% Explicitly reuse the session from C9\n13> {ok, C10} = ssl:connect(\"localhost\", 9999, [{verify, verify_peer},\n {versions, ['tlsv1.2']},\n {cacertfile, \"cacerts.pem\"},\n {reuse_session, {ID1, SessData}}]).\n{ok,{sslsocket,{gen_tcp,#Port<0.15>,tls_connection,\n undefined}, ...}}\n\n14> ssl:connection_information(C10, [session_id]).\n{ok,[{session_id,<<9,233,4,54,170,88,170,180,17,96,202,\n 85,85,99,119,47,9,68,195,50,120,52,\n 130,239,...>>}]}\n```\n\nStep 4 - Not Possible to Reuse Explicit Session by ID Only\n\n```erlang\n%% Try to reuse the session from C9 using only the id\n15> {ok, E} = ssl:connect(\"localhost\", 9999, [{verify, verify_peer},\n {versions, ['tlsv1.2']},\n {cacertfile, \"cacerts.pem\"},\n {reuse_session, ID1}]).\n{ok,{sslsocket,{gen_tcp,#Port<0.18>,tls_connection,\n undefined}, ...}}\n\n%% This will fail (as it is not saved for reuse)\n%% and a full handshake will be performed, we get a new id.\n16> ssl:connection_information(E, [session_id]).\n{ok,[{session_id,<<87,46,43,126,175,68,160,153,37,29,\n 196,240,65,160,254,88,65,224,18,63,\n 18,17,174,39,...>>}]}\n```\n\nOn the server side the the `{reuse_sessions, boolean()}` option determines if\nthe server will save session data and allow session reuse or not. This can be\nfurther customized by the option `{reuse_session, fun()}` that may introduce a\nlocal policy for session reuse.","title":"Session Reuse Prior to TLS 1.3 - Examples","ref":"using_ssl.html#session-reuse-prior-to-tls-1-3"},{"type":"extras","doc":"TLS 1.3 introduces a new secure way of resuming sessions by using session\ntickets. A session ticket is an opaque data structure that is sent in the\npre_shared_key extension of a ClientHello, when a client attempts to resume a\nsession with keying material from a previous successful handshake.\n\nSession tickets can be stateful or stateless. A stateful session ticket is a\ndatabase reference (session ticket store) and used with stateful servers, while\na stateless ticket is a self-encrypted and self-authenticated data structure\nwith cryptographic keying material and state data, enabling session resumption\nwith stateless servers.\n\nThe choice between stateful or stateless depends on the server requirements as\nthe session tickets are opaque for the clients. Generally, stateful tickets are\nsmaller and the server can guarantee that tickets are only used once. Stateless\ntickets contain additional data, require less storage on the server side, but\nthey offer different guarantees against anti-replay. See also\n[Anti-Replay Protection in TLS 1.3](using_ssl.md#anti-replay-protection-in-tls-1-3)\n\nSession tickets are sent by servers on newly established TLS connections. The\nnumber of tickets sent and their lifetime are configurable by application\nvariables. See also [SSL's configuration](ssl_app.md#configuration).\n\nSession tickets are protected by application traffic keys, and in stateless\ntickets, the opaque data structure itself is self-encrypted.\n\nAn example with automatic and manual session resumption:\n\n```erlang\n {ok, _} = application:ensure_all_started(ssl).\n LOpts = [{certs_keys, [#{certfile => \"cert.pem\",\n keyfile => \"key.pem\"}]},\n {versions, ['tlsv1.2','tlsv1.3']},\n {session_tickets, stateless}].\n {ok, LSock} = ssl:listen(8001, LOpts).\n {ok, ASock} = ssl:transport_accept(LSock).\n```\n\n_Step 2 (client):_ Start the client and connect to server:\n\n```erlang\n {ok, _} = application:ensure_all_started(ssl).\n COpts = [{cacertfile, \"cert.pem\"},\n {versions, ['tlsv1.2','tlsv1.3']},\n {log_level, debug},\n {session_tickets, auto}].\n ssl:connect(\"localhost\", 8001, COpts).\n```\n\n_Step 3 (server):_ Start the TLS handshake:\n\n```erlang\n {ok, CSocket} = ssl:handshake(ASock).\n```\n\nA connection is established using a full handshake. Below is a summary of the\nexchanged messages:\n\n```erlang\n >>> TLS 1.3 Handshake, ClientHello ...\n << >> Handshake, Finished ...\n << >> TLS 1.3 Handshake, ClientHello ...\n << >> Handshake, Finished ...\n << TicketData end.\n```\n\n_Step 11 (server):_ Accept a new connection on the server:\n\n```erlang\n {ok, ASock4} = ssl:transport_accept(LSock).\n```\n\n_Step 12 (client):_ Initiate a new connection to the server with the session\nticket received in Step 10:\n\n```erlang\n {ok, _} = application:ensure_all_started(ssl).\n COpts2 = [{cacertfile, \"cert.pem\"},\n {versions, ['tlsv1.2','tlsv1.3']},\n {log_level, debug},\n {session_tickets, manual},\n {use_ticket, [Ticket]}].\n ssl:connect(\"localhost\", 8001, COpts).\n```\n\n_Step 13 (server):_ Start the handshake:\n\n```erlang\n {ok, CSock4} = ssl:handshake(ASock4).\n```","title":"Session Tickets and Session Resumption in TLS 1.3 - Examples","ref":"using_ssl.html#session-tickets-and-session-resumption-in-tls-1-3"},{"type":"extras","doc":"TLS 1.3 allows clients to send data on the first flight if the endpoints have a\nshared crypographic secret (pre-shared key). This means that clients can send\nearly data if they have a valid session ticket received in a previous successful\nhandshake. For more information about session resumption see\n[Session Tickets and Session Resumption in TLS 1.3](using_ssl.md#session-tickets-and-session-resumption-in-tls-1-3).\n\nThe security properties of Early Data are weaker than other kinds of TLS data.\nThis data is not forward secret, and it is vulnerable to replay attacks. For\navailable mitigation strategies see\n[Anti-Replay Protection in TLS 1.3](using_ssl.md#anti-replay-protection-in-tls-1-3).\n\nIn normal operation, clients will not know which, if any, of the available\nmitigation strategies servers actually implement, and hence must only send early\ndata which they deem safe to be replayed. For example, idempotent HTTP\noperations, such as HEAD and GET, can usually be regarded as safe but even they\ncan be exploited by a large number of replays causing resource limit exhaustion\nand other similar problems.\n\nAn example of sending early data with automatic and manual session ticket\nhandling:\n\n_Server_\n\n```erlang\nearly_data_server() ->\n application:load(ssl),\n {ok, _} = application:ensure_all_started(ssl),\n Port = 11029,\n LOpts = [{certs_keys, [#{certfile => \"cert.pem\", keyfile => \"key.pem\"}]},\n {reuseaddr, true},\n {versions, ['tlsv1.2','tlsv1.3']},\n {session_tickets, stateless},\n {early_data, enabled},\n ],\n {ok, LSock} = ssl:listen(Port, LOpts),\n %% Accept first connection\n {ok, ASock0} = ssl:transport_accept(LSock),\n {ok, CSock0} = ssl:handshake(ASock0),\n %% Accept second connection\n {ok, ASock1} = ssl:transport_accept(LSock),\n {ok, CSock1} = ssl:handshake(ASock1),\n Sock.\n```\n\n_Client (automatic ticket handling):_\n\n```erlang\nearly_data_auto() ->\n %% First handshake 1-RTT - get session tickets\n application:load(ssl),\n {ok, _} = application:ensure_all_started(ssl),\n Port = 11029,\n Data = <<\"HEAD / HTTP/1.1\\r\\nHost: \\r\\nConnection: close\\r\\n\">>,\n COpts0 = [{cacertfile, \"cacerts.pem\"},\n {versions, ['tlsv1.2', 'tlsv1.3']},\n {session_tickets, auto}],\n {ok, Sock0} = ssl:connect(\"localhost\", Port, COpts0),\n\n %% Wait for session tickets\n timer:sleep(500),\n %% Close socket if server cannot handle multiple\n %% connections e.g. openssl s_server\n ssl:close(Sock0),\n\n %% Second handshake 0-RTT\n COpts1 = [{cacertfile, \"cacerts.pem\"},\n {versions, ['tlsv1.2', 'tlsv1.3']},\n {session_tickets, auto},\n {early_data, Data}],\n {ok, Sock} = ssl:connect(\"localhost\", Port, COpts1),\n Sock.\n\n```\n\n_Client (manual ticket handling):_\n\n```erlang\nearly_data_manual() ->\n %% First handshake 1-RTT - get session tickets\n application:load(ssl),\n {ok, _} = application:ensure_all_started(ssl),\n Port = 11029,\n Data = <<\"HEAD / HTTP/1.1\\r\\nHost: \\r\\nConnection: close\\r\\n\">>,\n COpts0 = [{cacertfile, \"cacerts.pem\"},\n {versions, ['tlsv1.2', 'tlsv1.3']},\n {session_tickets, manual}],\n {ok, Sock0} = ssl:connect(\"localhost\", Port, COpts0),\n\n %% Wait for session tickets\n Ticket =\n receive\n {ssl, session_ticket, Ticket0} ->\n Ticket0\n end,\n\n %% Close socket if server cannot handle multiple connections\n %% e.g. openssl s_server\n ssl:close(Sock0),\n\n %% Second handshake 0-RTT\n COpts1 = [{cacertfile, \"cacerts.pem\"},\n {versions, ['tlsv1.2', 'tlsv1.3']},\n {session_tickets, manual},\n {use_ticket, [Ticket]},\n {early_data, Data}],\n {ok, Sock} = ssl:connect(\"localhost\", Port, COpts1),\n Sock.\n```","title":"Early Data in TLS-1.3 - Examples","ref":"using_ssl.html#early-data-in-tls-1-3"},{"type":"extras","doc":"The TLS 1.3 protocol does not provide inherent protection for replay of 0-RTT\ndata but describes mechanisms that SHOULD be implemented by compliant server\nimplementations. The implementation of TLS 1.3 in the SSL application employs\nall standard methods to prevent potential threats.\n\n_Single-use tickets_\n\nThis mechanism is available with stateful session tickets. Session tickets can\nonly be used once, subsequent use of the same ticket results in a full\nhandshake. Stateful servers enforce this rule by maintaining a database of\noutstanding valid tickets.\n\n_Client Hello Recording_\n\nThis mechanism is available with stateless session tickets. The server records a\nunique value derived from the ClientHello (PSK binder) in a given time window.\nThe ticket's age is verified by using both the \"obsfuscated_ticket_age\" and an\nadditional timestamp encrypted in the ticket data. As the used datastore allows\nfalse positives, apparent replays will be answered by doing a full 1-RTT\nhandshake.\n\n_Freshness Checks_\n\nThis mechanism is available with the stateless session tickets. As the ticket\ndata has an embedded timestamp, the server can determine if a ClientHello was\nsent reasonably recently and accept the 0-RTT handshake, otherwise if falls back\nto a full 1-RTT handshake. This mechanism is tightly coupled with the previous\none, it prevents storing an unlimited number of ClientHellos.\n\nThe current implementation uses a pair of Bloom filters to implement the last\ntwo mechanisms. Bloom filters are fast, memory-efficient, probabilistic data\nstructures that can tell if an element may be in a set or if it is definitely\nnot in the set.\n\nIf the option `anti_replay` is defined in the server, a\npair of Bloom filters (_current_ and _old_) are used to record incoming\nClientHello messages (it is the unique binder value that is actually stored).\nThe _current_ Bloom filter is used for `WindowSize` seconds to store new\nelements. At the end of the time window the Bloom filters are rotated (the\n_current_ Bloom filter becomes the _old_ and an empty Bloom filter is set as\n_current_.\n\nThe Anti-Replay protection feature in stateless servers executes in the\nfollowing steps when a new ClientHello is received:\n\n- Reported ticket age (obfuscated ticket age) shall be less than ticket\n lifetime.\n- Actual ticket age shall be less than the ticket lifetime (stateless session\n tickets contain the servers timestamp when the ticket was issued).\n- ClientHello created with the ticket shall be sent relatively recently\n (freshness checks).\n- If all above checks passed both _current_ and _old_ Bloom filters are checked\n to detect if binder was already seen. Being a probabilistic data structure,\n false positives can occur and they trigger a full handshake.\n- If the binder is not seen, the binder is validated. If the binder is valid,\n the server proceeds with the 0-RTT handshake.","title":"Anti-Replay Protection in TLS 1.3 - Examples","ref":"using_ssl.html#anti-replay-protection-in-tls-1-3"},{"type":"extras","doc":"Using DTLS has basically the same API as TLS. You need to add the option\n\\{protocol, dtls\\} to the connect and listen functions. For example\n\n```erlang\n client>{ok, Socket} = ssl:connect(\"localhost\", 9999, [{protocol, dtls},\n {verify, verify_peer},\n {cacertfile, \"cacerts.pem\"}],\n infinity).\n{ok,{sslsocket, [...]}}\n\n```","title":"Using DTLS - Examples","ref":"using_ssl.html#using-dtls"},{"type":"extras","doc":"\n# Erlang Distribution over TLS\n\nThis section describes how the Erlang distribution can use TLS to get extra\nverification and security.\n\nThe Erlang distribution can in theory use almost any connection-based protocol\nas bearer. However, a module that implements the protocol-specific parts of the\nconnection setup is needed. The default distribution module is `inet_tcp_dist`\nin the Kernel application. When starting an Erlang node distributed,\n`net_kernel` uses this module to set up listen ports and connections.\n\nIn the SSL application, an extra distribution module, `inet_tls_dist`, can be\nused as an alternative. All distribution connections will use TLS and all\nparticipating Erlang nodes in a distributed system must use this distribution\nmodule.\n\nThe security level depends on the parameters provided to the TLS connection\nsetup. Erlang node cookies are however always used, as they can be used to\ndifferentiate between two different Erlang networks.\n\nTo set up Erlang distribution over TLS:\n\n- _Step 1:_ Build boot scripts including the SSL application.\n- _Step 2:_ Specify the distribution module for `net_kernel`.\n- _Step 3:_ Specify the security options and other SSL options.\n- _Step 4:_ Set up the environment to always use TLS.\n\nThe following sections describe these steps.","title":"Erlang Distribution over TLS","ref":"ssl_distribution.html"},{"type":"extras","doc":"Boot scripts are built using the `systools` utility in the SASL application. For\nmore information on `systools`, see the SASL documentation. This is only an\nexample of what can be done.\n\nThe simplest boot script possible includes only the Kernel and STDLIB\napplications. Such a script is located in the `bin` directory of the Erlang\ndistribution. The source for the script is found under the Erlang installation\ntop directory under `releases/ /start_clean.rel`.\n\nDo the following:\n\n- Copy that script to another location (and preferably another name).\n- Add the applications Crypto, Public Key, and SSL with their current version\n numbers after the STDLIB application.\n\nThe following shows an example `.rel` file with TLS added:\n\n```erlang\n {release, {\"OTP APN 181 01\",\"R15A\"}, {erts, \"5.9\"},\n [{kernel,\"2.15\"},\n {stdlib,\"1.18\"},\n {crypto, \"2.0.3\"},\n {public_key, \"0.12\"},\n {asn1, \"4.0\"},\n {ssl, \"5.0\"}\n ]}.\n```\n\nThe version numbers differ in your system. Whenever one of the applications\nincluded in the script is upgraded, change the script.\n\nDo the following:\n\n- Build the boot script.\n\n Assuming the `.rel file` is stored in a file `start_ssl.rel` in the current\n directory, a boot script can be built as follows:\n\n```text\n 1> systools:make_script(\"start_ssl\",[]).\n```\n\nThere is now a `start_ssl.boot` file in the current directory.\n\nDo the following:\n\n- Test the boot script. To do this, start Erlang with the `-boot` command-line\n parameter specifying this boot script (with its full path, but without the\n `.boot` suffix). In UNIX it can look as follows:\n\n```text\n$ erl -boot /home/me/ssl/start_ssl\nErlang (BEAM) emulator version 5.0\n\nEshell V5.0 (abort with ^G)\n1> whereis(ssl_manager).\n<0.41.0>\n```\n\nThe `whereis` function-call verifies that the SSL application is started.\n\nAs an alternative to building a bootscript, you can explicitly add the path to\nthe SSL `ebin` directory on the command line. This is done with command-line\noption `-pa`. This works as the SSL application does not need to be started for\nthe distribution to come up, as a clone of the SSL application is hooked into\nthe Kernel application. So, as long as the SSL application code can be reached,\nthe distribution starts. The `-pa` method is only recommended for testing\npurposes.\n\n> #### Note {: .info }\n>\n> The clone of the SSL application must enable the use of the SSL code in such\n> an early bootstage as needed to set up the distribution. However, this makes\n> it impossible to soft upgrade the SSL application.","title":"Building Boot Scripts Including the SSL Application - Erlang Distribution over TLS","ref":"ssl_distribution.html#building-boot-scripts-including-the-ssl-application"},{"type":"extras","doc":"The distribution module for TLS is named `inet_tls_dist` and is specified on the\ncommand line with option `-proto_dist`. The argument to `-proto_dist` is to be\nthe module name without suffix `_dist`. So, this distribution module is\nspecified with `-proto_dist inet_tls` on the command line.\n\nExtending the command line gives the following:\n\n```text\n$ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls\n```\n\nFor the distribution to be started, give the emulator a name as well:\n\n```text\n$ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls -sname ssl_test\nErlang (BEAM) emulator version 5.0 [source]\n\nEshell V5.0 (abort with ^G)\n(ssl_test@myhost)1>\n```\n\nHowever, a node started in this way refuses to talk to other nodes, as no TLS\nparameters are supplied (see the next section).","title":"Specifying Distribution Module for net_kernel - Erlang Distribution over TLS","ref":"ssl_distribution.html#specifying-distribution-module-for-net_kernel"},{"type":"extras","doc":"The TLS distribution options can be written into a file that is consulted when\nthe node is started. This file name is then specified with the command line\nargument `-ssl_dist_optfile`.\n\nAny available TLS option can be specified in an options file.\n\n> #### Note {: .info }\nOptions that take a `fun()` has to use the syntax `fun Mod:Func/Arity` since a\nfunction body cannot be compiled when consulting a file. Also the encoding\nof the file can be specified as defined by module `m:epp`.\n\n> #### Warning {: .warning }\nDo not tamper with the socket options `list`, `binary`, `active`, `packet`,\n`nodelay` and `deliver` since they are used by the distribution protocol handler\nitself. Other raw socket options such as `packet_size` may interfere severely,\nso beware\\!\n\nFor TLS to work, at least a public key and a certificate must be specified for\nthe server side and the client needs to specify CAs that it trusts (client certification\nis optional and requires more configuration).\n\nIn the following example (to keep it simple), the PEM file `\"/home/me/ssl/erlserver.pem\"`\ncontains both the server certificate and its private key .\n\nCreate a file named for example `\"/home/me/ssl/ssl_test@myhost.conf\"`:\n\n```erlang\n[{server,\n [{certfile, \"/home/me/ssl/erlserver.pem\"}]},\n {client,\n [{cacertfile, \"/home/me/ssl/client_trusted.pem\"}]}].\n```\n\nAnd then start the node like this (line breaks in the command are for\nreadability, and shall not be there when typed):\n\n```text\n$ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls\n -ssl_dist_optfile \"/home/me/ssl/ssl_test@myhost.conf\"\n -sname ssl_test\n```\n\nThe options in the `{server, Opts}` tuple are used when calling\n`ssl:handshake/3`, and the options in the `{client, Opts}` tuple are used when\ncalling `ssl:connect/4`.\n\nFor the client, the option `{server_name_indication, atom_to_list(TargetNode)}`\nis added when connecting. This makes it possible to use the client option\n`{verify, verify_peer}`, and the client will verify that the certificate matches\nthe node name you are connecting to. This only works if the the server\ncertificate is issued to the name\n[`atom_to_list(TargetNode)`](`atom_to_list/1`).\n\nFor the server it is also possible to use the option `{verify, verify_peer}` and\nthe server will only accept client connections with certificates that are\ntrusted by a root certificate that the server knows. A client that presents an\nuntrusted certificate will be rejected. This option is preferably combined with\n`{fail_if_no_peer_cert, true}` or a client will still be accepted if it does not\npresent any certificate.\n\nA node started in this way is fully functional, using TLS as the distribution\nprotocol.","title":"Specifying TLS Options - Erlang Distribution over TLS","ref":"ssl_distribution.html#specifying-tls-options"},{"type":"extras","doc":"It is possible to use TLS distribution over IPv6 instead of IPv4. To do this,\npass the option `-proto_dist inet6_tls` instead of `-proto_dist inet_tls` when\nstarting Erlang, either on the command line or in the `ERL_FLAGS` environment\nvariable.\n\nAn example command line with this option would look like this:\n\n```text\n$ erl -boot /home/me/ssl/start_ssl -proto_dist inet6_tls\n -ssl_dist_optfile \"/home/me/ssl/ssl_test@myhost.conf\"\n -sname ssl_test\n```\n\nA node started in this way will only be able to communicate with other nodes\nusing TLS distribution over IPv6.","title":"Using TLS distribution over IPv6 - Erlang Distribution over TLS","ref":"ssl_distribution.html#using-tls-distribution-over-ipv6"},{"type":"extras","doc":"> #### Note {: .info }\n> The following section describes TLS Option handling prior to OTP 20.2\n> and can only handle a small subset of the actual available options.\n> It is here only for the sake of backwards compatibility .\n\nAs in the previous section the PEM file `\"/home/me/ssl/erlserver.pem\"` contains\nboth the server certificate and its private key.\n\nOn the `erl` command line you can specify options that the TLS distribution adds\nwhen creating a socket.\n\nThe simplest TLS options in the following list can be specified by adding the\nprefix `server_` or `client_` to the option name:\n\n- `certfile`\n- `keyfile`\n- `password`\n- `cacertfile`\n- `verify`\n- `verify_fun` (write as `{Module, Function, InitialUserState}`)\n- `crl_check`\n- `crl_cache` (write as Erlang term)\n- `reuse_sessions`\n- `secure_renegotiate`\n- `depth`\n- `hibernate_after`\n- `ciphers` (use old string format)\n\nNote that `verify_fun` needs to be written in a different form than the\ncorresponding TLS option, since funs are not accepted on the command line.\n\nThe server can also take the options `dhfile` and `fail_if_no_peer_cert` (also\nprefixed).\n\n`client_`\\-prefixed options are used when the distribution initiates a\nconnection to another node. `server_`\\-prefixed options are used when accepting\na connection from a remote node.\n\nRaw socket options, such as `packet` and `size` must not be specified on the\ncommand line.\n\nThe command-line argument for specifying the TLS options is named\n`-ssl_dist_opt` and is to be followed by pairs of SSL options and their values.\nArgument `-ssl_dist_opt` can be repeated any number of times.\n\nAn example command line doing the same as the example in the previous section\ncan now look as follows (line breaks in the command are for readability, and\nshall not be there when typed):\n\n```text\n$ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls\n -ssl_dist_opt server_certfile \"/home/me/ssl/erlserver.pem\"\n -ssl_dist_opt server_secure_renegotiate true client_secure_renegotiate true\n -sname ssl_test\nErlang (BEAM) emulator version 5.0 [source]\n\nEshell V5.0 (abort with ^G)\n(ssl_test@myhost)1>\n```","title":"Specifying TLS Options (Legacy) - Erlang Distribution over TLS","ref":"ssl_distribution.html#specifying-tls-options-legacy"},{"type":"extras","doc":"A convenient way to specify arguments to Erlang is to use environment variable\n`ERL_FLAGS`. All the flags needed to use the TLS distribution can be specified\nin that variable and are then interpreted as command-line arguments for all\nsubsequent invocations of Erlang.\n\nIn a Unix (Bourne) shell, it can look as follows (line breaks are for\nreadability, they are not to be there when typed):\n\n```erlang\n$ ERL_FLAGS=\"-boot /home/me/ssl/start_ssl -proto_dist inet_tls\n -ssl_dist_opt server_certfile /home/me/ssl/erlserver.pem\n -ssl_dist_opt server_secure_renegotiate true client_secure_renegotiate true\"\n$ export ERL_FLAGS\n$ erl -sname ssl_test\nErlang (BEAM) emulator version 5.0 [source]\n\nEshell V5.0 (abort with ^G)\n(ssl_test@myhost)1> init:get_arguments().\n[{root,[\"/usr/local/erlang\"]},\n {progname,[\"erl \"]},\n {sname,[\"ssl_test\"]},\n {boot,[\"/home/me/ssl/start_ssl\"]},\n {proto_dist,[\"inet_tls\"]},\n {ssl_dist_opt,[\"server_certfile\",\"/home/me/ssl/erlserver.pem\"]},\n {ssl_dist_opt,[\"server_secure_renegotiate\",\"true\",\n \"client_secure_renegotiate\",\"true\"]\n {home,[\"/home/me\"]}]\n```\n\nThe `init:get_arguments()` call verifies that the correct arguments are supplied\nto the emulator.","title":"Setting up Environment to Always Use TLS - Erlang Distribution over TLS","ref":"ssl_distribution.html#setting-up-environment-to-always-use-tls"},{"type":"extras","doc":"\n# Standards Compliance","title":"Standards Compliance","ref":"standards_compliance.html"},{"type":"extras","doc":"This section describes the current state of standards compliance of the ssl\napplication.","title":"Purpose - Standards Compliance","ref":"standards_compliance.html#purpose"},{"type":"extras","doc":"- For security reasons RSA key exchange cipher suites are no longer supported by\n default, but can be configured. (OTP 21)\n- For security reasons DES cipher suites are no longer supported by default, but\n can be configured. (OTP 20)\n- For security reasons 3DES cipher suites are no longer supported by default,\n but can be configured. (OTP 21)\n- Renegotiation Indication Extension\n [RFC 5746](http://www.ietf.org/rfc/rfc5746.txt) is supported\n- Ephemeral Diffie-Hellman cipher suites are supported, but not Diffie Hellman\n Certificates cipher suites.\n- Elliptic Curve cipher suites are supported if the Crypto application supports\n it and named curves are used.\n- Export cipher suites are not supported as the U.S. lifted its export\n restrictions in early 2000.\n- IDEA cipher suites are not supported as they have become deprecated by the TLS\n 1.2 specification so it is not motivated to implement them.\n- Compression is not supported.\n- It is possible to use Pre-Shared Key (PSK) and Secure Remote Password (SRP)\n cipher suites, but they are not enabled by default and need addition configuration.","title":"Common (prior to TLS 1.3) - Standards Compliance","ref":"standards_compliance.html#common-prior-to-tls-1-3"},{"type":"extras","doc":"- CRL validation is supported.\n- Policy certificate extensions are supported. (OTP 27)\n- 'Server Name Indication' extension\n ([RFC 6066](http://www.ietf.org/rfc/rfc6066.txt)) is supported.\n- Application Layer Protocol Negotiation (ALPN) and its successor Next Protocol\n Negotiation (NPN) are supported.","title":"Common - Standards Compliance","ref":"standards_compliance.html#common"},{"type":"extras","doc":"For security reasons SSL-2.0 is not supported. Interoperability with SSL-2.0\nenabled clients dropped. (OTP 21)","title":"SSL 2.0 - Standards Compliance","ref":"standards_compliance.html#ssl-2-0"},{"type":"extras","doc":"For security reasons SSL-3.0 is no longer supported at all. (OTP 23)\n\nFor security reasons SSL-3.0 is no longer supported by default, but can be\nconfigured. (OTP 19)","title":"SSL 3.0 - Standards Compliance","ref":"standards_compliance.html#ssl-3-0"},{"type":"extras","doc":"For security reasons TLS-1.0 is no longer supported by default, but can be\nconfigured. (OTP 22)","title":"TLS 1.0 - Standards Compliance","ref":"standards_compliance.html#tls-1-0"},{"type":"extras","doc":"For security reasons TLS-1.1 is no longer supported by default, but can be\nconfigured. (OTP 22)","title":"TLS 1.1 - Standards Compliance","ref":"standards_compliance.html#tls-1-1"},{"type":"extras","doc":"Supported","title":"TLS 1.2 - Standards Compliance","ref":"standards_compliance.html#tls-1-2"},{"type":"extras","doc":"For security reasons DTLS-1.0 (based on TLS 1.1) is no longer supported by\ndefault, but can be configured. (OTP 22)","title":"DTLS 1.0 - Standards Compliance","ref":"standards_compliance.html#dtls-1-0"},{"type":"extras","doc":"Supported (based on TLS 1.2)","title":"DTLS 1.2 - Standards Compliance","ref":"standards_compliance.html#dtls-1-2"},{"type":"extras","doc":"Not yet supported","title":"DTLS 1.3 - Standards Compliance","ref":"standards_compliance.html#dtls-1-3"},{"type":"extras","doc":"OTP-22 introduces support for TLS 1.3. The current implementation supports a\nselective set of cryptographic algorithms:\n\n- Key Exchange: ECDHE groups supported by default\n- Groups: all standard groups supported for the Diffie-Hellman key exchange\n- Groups: Support brainpool groups from RFC 8734\n- Ciphers: all mandatory cipher suites are supported\n- Signature Algorithms: All algorithms form RFC 8446\n- Certificates: RSA, ECDSA and EDDSA keys\n\nOther notable features:\n\n- PSK and session resumption is supported (stateful and stateless tickets)\n- Anti-replay protection using Bloom-filters with stateless tickets\n- Early data and 0-RTT is supported\n- Key and Initialization Vector Update is supported\n\nFor more detailed information see the\n[Standards Compliance](standards_compliance.md#soc_table) below.\n\nThe following table describes the current state of standards compliance for TLS\n1.3.\n\n(_C_ = Compliant, _NC_ = Non-Compliant, _PC_ = Partially-Compliant, _NA_ = Not\nApplicable)\n\n[](){: #soc_table }\n\n| _Section_ | _Feature_ | _State_ | _Since_ |\n| --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------- |\n| [1\\.3. Updates Affecting TLS 1.2](https://tools.ietf.org/html/rfc8446#section-1.2) | | _C_ | _24\\.1_ |\n| | Version downgrade protection mechanism | _C_ | _22_ |\n| | RSASSA-PSS signature schemes | _C_ | _24\\.1_ |\n| | supported_versions (ClientHello) extension | _C_ | _22_ |\n| | signature_algorithms_cert extension | _C_ | _24\\.1_ |\n| [2\\. Protocol Overview](https://tools.ietf.org/html/rfc8446#section/2) | | _PC_ | _22_ |\n| | (EC)DHE | _C_ | _22_ |\n| | PSK-only | _NC_ | |\n| | PSK with (EC)DHE | _C_ | _22\\.2_ |\n| [2\\.1. Incorrect DHE share](https://tools.ietf.org/html/rfc8446#section-2.1) | HelloRetryRequest | _C_ | _22_ |\n| [2\\.2. Resumption and Pre-Shared Key (PSK)](https://tools.ietf.org/html/rfc8446#section-2.2) | | _C_ | _22\\.2_ |\n| [2\\.3. 0-RTT Data](https://tools.ietf.org/html/rfc8446#section-2.3) | | _PC_ | _23\\.3_ |\n| [4\\.1.1. Cryptographic Negotiation](https://tools.ietf.org/html/rfc8446#section-4.1.1) | | _C_ | _22\\.2_ |\n| | supported_groups extension | _C_ | _22_ |\n| | signature_algorithms extension | _C_ | _22_ |\n| | pre_shared_key extension | _C_ | _22\\.2_ |\n| [4\\.1.2. Client Hello](https://tools.ietf.org/html/rfc8446#section-4.1.2) | _Client_ | _PC_ | _22\\.1_ |\n| | server_name (RFC6066) | _C_ | _23\\.2_ |\n| | max_fragment_length (RFC6066) | _C_ | _23\\.0_ |\n| | status_request (RFC6066) | _C_ | _27\\.0_ |\n| | supported_groups (RFC7919) | _C_ | _22\\.1_ |\n| | signature_algorithms (RFC8446) | _C_ | _22\\.1_ |\n| | use_srtp (RFC5764) | _C_ | 26\\.0 |\n| | heartbeat (RFC6520) | _NC_ | |\n| | application_layer_protocol_negotiation (RFC7301) | _C_ | _22\\.1_ |\n| | signed_certificate_timestamp (RFC6962) | _NC_ | |\n| | client_certificate_type (RFC7250) | _NC_ | |\n| | server_certificate_type (RFC7250) | _NC_ | |\n| | padding (RFC7685) | _NC_ | |\n| | key_share (RFC8446) | _C_ | _22\\.1_ |\n| | pre_shared_key (RFC8446) | _C_ | _22\\.2_ |\n| | psk_key_exchange_modes (RFC8446) | _C_ | _22\\.2_ |\n| | early_data (RFC8446) | _C_ | _23\\.3_ |\n| | cookie (RFC8446) | _C_ | _23\\.1_ |\n| | supported_versions (RFC8446) | _C_ | _22\\.1_ |\n| | certificate_authorities (RFC8446) | _C_ | 24\\.3 |\n| | oid_filters (RFC8446) | _NC_ | |\n| | post_handshake_auth (RFC8446) | _NC_ | |\n| | signature_algorithms_cert (RFC8446) | _C_ | _22\\.1_ |\n| | _Server_ | _PC_ | _22_ |\n| | server_name (RFC6066) | _C_ | _23\\.2_ |\n| | max_fragment_length (RFC6066) | _C_ | _23\\.0_ |\n| | status_request (RFC6066) | _NC_ | |\n| | supported_groups (RFC7919) | _C_ | _22_ |\n| | signature_algorithms (RFC8446) | _C_ | _22_ |\n| | use_srtp (RFC5764) | _C_ | 26\\.0 |\n| | heartbeat (RFC6520) | _NC_ | |\n| | application_layer_protocol_negotiation (RFC7301) | _C_ | _22\\.1_ |\n| | signed_certificate_timestamp (RFC6962) | _NC_ | |\n| | client_certificate_type (RFC7250) | _NC_ | |\n| | server_certificate_type (RFC7250) | _NC_ | |\n| | padding (RFC7685) | _NC_ | |\n| | key_share (RFC8446) | _C_ | _22_ |\n| | pre_shared_key (RFC8446) | _C_ | _22\\.2_ |\n| | psk_key_exchange_modes (RFC8446) | _C_ | _22\\.2_ |\n| | early_data (RFC8446) | _C_ | _23\\.3_ |\n| | cookie (RFC8446) | _C_ | _23\\.1_ |\n| | supported_versions (RFC8446) | _C_ | _22_ |\n| | oid_filters (RFC8446) | _NC_ | |\n| | post_handshake_auth (RFC8446) | _NC_ | |\n| | signature_algorithms_cert (RFC8446) | _C_ | _22_ |\n| [4\\.1.3. Server Hello](https://tools.ietf.org/html/rfc8446#section-4.1.3) | _Client_ | _C_ | _22\\.2_ |\n| | Version downgrade protection | _C_ | _22\\.1_ |\n| | key_share (RFC8446) | _C_ | _22\\.1_ |\n| | pre_shared_key (RFC8446) | _C_ | _22\\.2_ |\n| | supported_versions (RFC8446) | _C_ | _22\\.1_ |\n| | use_srtp (RFC5764) | _C_ | 26\\.0 |\n| | _Server_ | _C_ | _22\\.2_ |\n| | Version downgrade protection | _C_ | _22_ |\n| | key_share (RFC8446) | _C_ | _22_ |\n| | pre_shared_key (RFC8446) | _C_ | _22\\.2_ |\n| | supported_versions (RFC8446) | _C_ | _22_ |\n| | use_srtp (RFC5764) | _C_ | 26\\.0 |\n| [4\\.1.4. Hello Retry Request](https://tools.ietf.org/html/rfc8446#section-4.1.4) | _Server_ | _C_ | _22_ |\n| | key_share (RFC8446) | _C_ | _22_ |\n| | cookie (RFC8446) | _C_ | _23\\.1_ |\n| | supported_versions (RFC8446) | _C_ | _22_ |\n| [4\\.2.1. Supported Versions](https://tools.ietf.org/html/rfc8446#section-4.2.1) | _Client_ | _C_ | _22\\.1_ |\n| | _Server_ | _C_ | _22_ |\n| [4\\.2.2. Cookie](https://tools.ietf.org/html/rfc8446#section-4.2.2) | _Client_ | _C_ | _23\\.1_ |\n| | _Server_ | _C_ | _23\\.1_ |\n| [4\\.2.3. Signature Algorithms](https://tools.ietf.org/html/rfc8446#section-4.2.3) | _Client_ | _C_ | _24_ |\n| | rsa_pkcs1_sha256 | _C_ | _22\\.1_ |\n| | rsa_pkcs1_sha384 | _C_ | _22\\.1_ |\n| | rsa_pkcs1_sha512 | _C_ | _22\\.1_ |\n| | ecdsa_secp256r1_sha256 | _C_ | _22\\.1_ |\n| | ecdsa_secp384r1_sha384 | _C_ | _22\\.1_ |\n| | ecdsa_secp521r1_sha512 | _C_ | _22\\.1_ |\n| | rsa_pss_rsae_sha256 | _C_ | _22\\.1_ |\n| | rsa_pss_rsae_sha384 | _C_ | _22\\.1_ |\n| | rsa_pss_rsae_sha512 | _C_ | _22\\.1_ |\n| | ed25519 | _C_ | _24_ |\n| | ed448 | _C_ | _24_ |\n| | rsa_pss_pss_sha256 | _C_ | _23_ |\n| | rsa_pss_pss_sha384 | _C_ | _23_ |\n| | rsa_pss_pss_sha512 | _C_ | _23_ |\n| | rsa_pkcs1_sha1 | _C_ | _22\\.1_ |\n| | ecdsa_sha1 | _C_ | _22\\.1_ |\n| | _Server_ | _C_ | _24_ |\n| | rsa_pkcs1_sha256 | _C_ | _22_ |\n| | rsa_pkcs1_sha384 | _C_ | _22_ |\n| | rsa_pkcs1_sha512 | _C_ | _22_ |\n| | ecdsa_secp256r1_sha256 | _C_ | _22\\.1_ |\n| | ecdsa_secp384r1_sha384 | _C_ | _22\\.1_ |\n| | ecdsa_secp521r1_sha512 | _C_ | _22\\.1_ |\n| | rsa_pss_rsae_sha256 | _C_ | _22_ |\n| | rsa_pss_rsae_sha384 | _C_ | _22_ |\n| | rsa_pss_rsae_sha512 | _C_ | _22_ |\n| | ed25519 | _C_ | _24_ |\n| | ed448 | _C_ | _24_ |\n| | rsa_pss_pss_sha256 | _C_ | _23_ |\n| | rsa_pss_pss_sha384 | _C_ | _23_ |\n| | rsa_pss_pss_sha512 | _C_ | _23_ |\n| | rsa_pkcs1_sha1 | _C_ | _22_ |\n| | ecdsa_sha1 | _C_ | _22_ |\n| [4\\.2.4. Certificate Authorities](https://tools.ietf.org/html/rfc8446#section-4.2.4) | _Client_ | _C_ | 24\\.3 |\n| | _Server_ | _C_ | _24\\.3_ |\n| [4\\.2.5. OID Filters](https://tools.ietf.org/html/rfc8446#section-4.2.5) | _Client_ | _NC_ | |\n| | _Server_ | _NC_ | |\n| [4\\.2.6. Post-Handshake Client Authentication](https://tools.ietf.org/html/rfc8446#section-4.2.6) | _Client_ | _NC_ | |\n| | _Server_ | _NC_ | |\n| [4\\.2.7. Supported Groups](https://tools.ietf.org/html/rfc8446#section-4.2.7) | _Client_ | _C_ | _22\\.1_ |\n| | secp256r1 | _C_ | _22\\.1_ |\n| | secp384r1 | _C_ | _22\\.1_ |\n| | secp521r1 | _C_ | _22\\.1_ |\n| | x25519 | _C_ | _22\\.1_ |\n| | x448 | _C_ | _22\\.1_ |\n| | ffdhe2048 | _C_ | _22\\.1_ |\n| | ffdhe3072 | _C_ | _22\\.1_ |\n| | ffdhe4096 | _C_ | _22\\.1_ |\n| | ffdhe6144 | _C_ | _22\\.1_ |\n| | ffdhe8192 | _C_ | _22\\.1_ |\n| | _Server_ | _C_ | _22_ |\n| | secp256r1 | _C_ | _22_ |\n| | secp384r1 | _C_ | _22_ |\n| | secp521r1 | _C_ | _22_ |\n| | x25519 | _C_ | _22_ |\n| | x448 | _C_ | _22_ |\n| | ffdhe2048 | _C_ | _22_ |\n| | ffdhe3072 | _C_ | _22_ |\n| | ffdhe4096 | _C_ | _22_ |\n| | ffdhe6144 | _C_ | _22_ |\n| | ffdhe8192 | _C_ | _22_ |\n| [4\\.2.8. Key Share](https://tools.ietf.org/html/rfc8446#section-4.2.8) | _Client_ | _C_ | _22\\.1_ |\n| | _Server_ | _C_ | _22_ |\n| [4\\.2.9. Pre-Shared Key Exchange Modes](https://tools.ietf.org/html/rfc8446#section-4.2.9) | _Client_ | _C_ | _22\\.2_ |\n| | _Server_ | _C_ | _22\\.2_ |\n| [4\\.2.10. Early Data Indication](https://tools.ietf.org/html/rfc8446#section-4.2.10) | _Client_ | _C_ | _23\\.3_ |\n| | _Server_ | _C_ | _23\\.3_ |\n| [4\\.2.11. Pre-Shared Key Extension](https://tools.ietf.org/html/rfc8446#section-4.2.11) | _Client_ | _C_ | _22\\.2_ |\n| | _Server_ | _C_ | _22\\.2_ |\n| [4\\.2.11.1. Ticket Age](https://tools.ietf.org/html/rfc8446#section-4.2.11.1) | _Client_ | _C_ | _22\\.2_ |\n| | _Server_ | _C_ | _22\\.2_ |\n| [4\\.2.11.2. PSK Binder](https://tools.ietf.org/html/rfc8446#section-4.2.11.2) | _Client_ | _C_ | _22\\.2_ |\n| | _Server_ | _C_ | _22\\.2_ |\n| [4\\.2.11.3. Processing Order](https://tools.ietf.org/html/rfc8446#section-4.2.11.3) | _Client_ | _NC_ | |\n| | _Server_ | _NC_ | |\n| [4\\.3.1. Encrypted Extensions](https://tools.ietf.org/html/rfc8446#section-4.3.1) | _Client_ | _PC_ | _22\\.1_ |\n| | server_name (RFC6066) | _C_ | _23\\.2_ |\n| | max_fragment_length (RFC6066) | _C_ | _23\\.0_ |\n| | supported_groups (RFC7919) | _NC_ | |\n| | use_srtp (RFC5764) | _NC_ | |\n| | heartbeat (RFC6520) | _NC_ | |\n| | application_layer_protocol_negotiation (RFC7301) | _C_ | 23\\.0 |\n| | client_certificate_type (RFC7250) | _NC_ | |\n| | server_certificate_type (RFC7250) | _NC_ | |\n| | early_data (RFC8446) | _C_ | _23\\.3_ |\n| | _Server_ | _PC_ | _22_ |\n| | server_name (RFC6066) | _C_ | _23\\.2_ |\n| | max_fragment_length (RFC6066) | _C_ | _23\\.0_ |\n| | supported_groups (RFC7919) | _NC_ | |\n| | use_srtp (RFC5764) | _NC_ | |\n| | heartbeat (RFC6520) | _NC_ | |\n| | application_layer_protocol_negotiation (RFC7301) | _C_ | 23\\.0 |\n| | client_certificate_type (RFC7250) | _NC_ | |\n| | server_certificate_type (RFC7250) | _NC_ | |\n| | early_data (RFC8446) | _C_ | _23\\.3_ |\n| [4\\.3.2. Certificate Request](https://tools.ietf.org/html/rfc8446#section-4.3.2) | _Client_ | _PC_ | _22\\.1_ |\n| | status_request (RFC6066) | _NC_ | |\n| | signature_algorithms (RFC8446) | _C_ | _22\\.1_ |\n| | signed_certificate_timestamp (RFC6962) | _NC_ | |\n| | certificate_authorities (RFC8446) | _C_ | 24\\.3 |\n| | oid_filters (RFC8446) | _NC_ | |\n| | signature_algorithms_cert (RFC8446) | _C_ | _22\\.1_ |\n| | _Server_ | _PC_ | _22_ |\n| | status_request (RFC6066) | _NC_ | |\n| | signature_algorithms (RFC8446) | _C_ | _22_ |\n| | signed_certificate_timestamp (RFC6962) | _NC_ | |\n| | certificate_authorities (RFC8446) | _C_ | 24\\.3 |\n| | oid_filters (RFC8446) | _NC_ | |\n| | signature_algorithms_cert (RFC8446) | _C_ | _22_ |\n| [4\\.4.1. The Transcript Hash](https://tools.ietf.org/html/rfc8446#section-4.4.1) | | _C_ | _22_ |\n| [4\\.4.2. Certificate](https://tools.ietf.org/html/rfc8446#section-4.4.2) | _Client_ | _PC_ | _22\\.1_ |\n| | Arbitrary certificate chain orderings | _C_ | _22\\.2_ |\n| | Extraneous certificates in chain | _C_ | _23\\.2_ |\n| | status_request (RFC6066) | _C_ | 27\\.0 |\n| | signed_certificate_timestamp (RFC6962) | _NC_ | |\n| | _Server_ | _PC_ | _22_ |\n| | status_request (RFC6066) | _NC_ | |\n| | signed_certificate_timestamp (RFC6962) | _NC_ | |\n| [4\\.4.2.1. OCSP Status and SCT Extensions](https://tools.ietf.org/html/rfc8446#section-4.4.2.1) | _Client_ | _PC_ | _27\\.0_ |\n| | _Server_ | _NC_ | |\n| [4\\.4.2.2. Server Certificate Selection](https://tools.ietf.org/html/rfc8446#section-4.4.2.2) | | _C_ | _24\\.3_ |\n| | The certificate type MUST be X.509v3, unless explicitly negotiated otherwise | _C_ | _22_ |\n| | The server's end-entity certificate's public key (and associated restrictions) MUST be compatible with the selected authentication algorithm from the client's \"signature_algorithms\" extension (currently RSA, ECDSA, or EdDSA). | _C_ | _22_ |\n| | The certificate MUST allow the key to be used for signing with a signature scheme indicated in the client's \"signature_algorithms\"/\"signature_algorithms_cert\" extensions | _C_ | _22_ |\n| | The \"server_name\" and \"certificate_authorities\" extensions are used to guide certificate selection. As servers MAY require the presence of the \"server_name\" extension, clients SHOULD send this extension, when applicable. | _C_ | _24\\.3_ |\n| [4\\.4.2.3. Client Certificate Selection](https://tools.ietf.org/html/rfc8446#section-4.4.2.3) | | _PC_ | _22\\.1_ |\n| | The certificate type MUST be X.509v3, unless explicitly negotiated otherwise | _C_ | _22\\.1_ |\n| | If the \"certificate_authorities\" extension in the CertificateRequest message was present, at least one of the certificates in the certificate chain SHOULD be issued by one of the listed CAs. | _C_ | _24\\.3_ |\n| | The certificates MUST be signed using an acceptable signature algorithm | _C_ | _22\\.1_ |\n| | If the CertificateRequest message contained a non-empty \"oid_filters\" extension, the end-entity certificate MUST match the extension OIDs that are recognized by the client | _NC_ | |\n| [4\\.4.2.4. Receiving a Certificate Message](https://tools.ietf.org/html/rfc8446#section-4.4.2.4) | _Client_ | _C_ | _22\\.1_ |\n| | _Server_ | _C_ | _22_ |\n| [4\\.4.3. Certificate Verify](https://tools.ietf.org/html/rfc8446#section-4.4.3) | _Client_ | _C_ | _22\\.1_ |\n| | _Server_ | _C_ | _22_ |\n| [4\\.4.4. Finished](https://tools.ietf.org/html/rfc8446#section-4.4.4) | _Client_ | _C_ | _22\\.1_ |\n| | _Server_ | _C_ | _22_ |\n| [4\\.5. End of Early Data](https://tools.ietf.org/html/rfc8446#section-4.5) | _Client_ | _C_ | _23\\.3_ |\n| | _Server_ | _C_ | _23\\.3_ |\n| [4\\.6.1. New Session Ticket Message](https://tools.ietf.org/html/rfc8446#section-4.6.1) | _Client_ | _C_ | _23\\.3_ |\n| | early_data (RFC8446) | _C_ | _23\\.3_ |\n| | _Server_ | _C_ | _23\\.3_ |\n| | early_data (RFC8446) | _C_ | _23\\.3_ |\n| [4\\.6.2. Post-Handshake Authentication](https://tools.ietf.org/html/rfc8446#section-4.6.2) | _Client_ | _NC_ | |\n| | _Server_ | _NC_ | |\n| [4\\.6.3. Key and Initialization Vector Update](https://tools.ietf.org/html/rfc8446#section-4.6.3) | _Client_ | _C_ | _22\\.3_ |\n| | _Server_ | _C_ | _22\\.3_ |\n| [5\\.1. Record Layer](https://tools.ietf.org/html/rfc8446#section-5.1) | | _C_ | _22_ |\n| | MUST NOT be interleaved with other record types | _C_ | _22_ |\n| | MUST NOT span key changes | _C_ | _22_ |\n| | MUST NOT send zero-length fragments | _C_ | _22_ |\n| | Alert messages MUST NOT be fragmented | _C_ | _22_ |\n| [5\\.2. Record Payload Protection](https://tools.ietf.org/html/rfc8446#section-5.2) | | _C_ | _22_ |\n| [5\\.3. Per-Record Nonce](https://tools.ietf.org/html/rfc8446#section-5.3) | | _C_ | _22_ |\n| [5\\.4. Record Padding](https://tools.ietf.org/html/rfc8446#section-5.4) | | _PC_ | _22_ |\n| | MAY choose to pad | _NC_ | |\n| | MUST NOT send Handshake and Alert records that have a zero-length TLSInnerPlaintext.content | _NC_ | |\n| | The padding sent is automatically verified | _C_ | _22_ |\n| [5\\.5. Limits on Key Usage](https://tools.ietf.org/html/rfc8446#section-5.5) | | _C_ | _22\\.3_ |\n| [6\\.1. Closure Alerts](https://tools.ietf.org/html/rfc8446#section-6.1) | | _22_ | |\n| | close_notify | _C_ | _22_ | |\n| | user_cancelled | _C_ | _22_ | |\n| [6\\.2. Error Alerts](https://tools.ietf.org/html/rfc8446#section-6.2) | | _PC_ | _22_ |\n| [7\\.1. Key Schedule](https://tools.ietf.org/html/rfc8446#section-7.1) | | _C_ | _22_ |\n| [7\\.2. Updating Traffic Secrets](https://tools.ietf.org/html/rfc8446#section-7.2) | | _C_ | _22_ |\n| [7\\.3. Traffic Key Calculation](https://tools.ietf.org/html/rfc8446#section-7.3) | | _C_ | _22_ |\n| [7\\.5. Exporters](https://tools.ietf.org/html/rfc8446#section-7.5) | | _PC_ | _26\\.3_ |\n| [8\\. 0-RTT and Anti-Replay](https://tools.ietf.org/html/rfc8446#section/8) | | _C_ | _22\\.2_ |\n| [8\\.1. Single-Use Tickets](https://tools.ietf.org/html/rfc8446#section-8.1) | | _C_ | _22\\.2_ |\n| [8\\.2. Client Hello Recording](https://tools.ietf.org/html/rfc8446#section-8.2) | | _C_ | _22\\.2_ |\n| [8\\.3. Freshness Checks](https://tools.ietf.org/html/rfc8446#section-8.3) | | _C_ | _22\\.2_ |\n| [9\\.1. Mandatory-to-Implement Cipher Suites](https://tools.ietf.org/html/rfc8446#section-9.1) | | _C_ | _22\\.1_ |\n| | MUST implement the TLS_AES_128_GCM_SHA256 | _C_ | _22_ |\n| | SHOULD implement the TLS_AES_256_GCM_SHA384 | _C_ | _22_ |\n| | SHOULD implement the TLS_CHACHA20_POLY1305_SHA256 | _C_ | _22_ |\n| | _Digital signatures_ | _C_ | _22\\.1_ |\n| | MUST support rsa_pkcs1_sha256 (for certificates) | _C_ | _22_ |\n| | MUST support rsa_pss_rsae_sha256 (for CertificateVerify and certificates) | _C_ | _22_ |\n| | MUST support ecdsa_secp256r1_sha256 | _C_ | _22\\.1_ |\n| | _Key Exchange_ | _C_ | _22_ |\n| | MUST support key exchange with secp256r1 | _C_ | _22_ |\n| | SHOULD support key exchange with X25519 | _C_ | _22_ |\n| [9\\.2. Mandatory-to-Implement Extensions](https://tools.ietf.org/html/rfc8446#section-9.2) | | _C_ | _23\\.2_ |\n| | Supported Versions | _C_ | _22_ |\n| | Cookie | _C_ | _23\\.1_ |\n| | Signature Algorithms | _C_ | _22_ |\n| | Signature Algorithms Certificate | _C_ | _22_ |\n| | Negotiated Groups | _C_ | _22_ |\n| | Key Share | _C_ | _22_ |\n| | Server Name Indication | _C_ | _23\\.2_ |\n| | _MUST send and use these extensions_ | _C_ | _22\\.2_ |\n| | \"supported_versions\" is REQUIRED for ClientHello, ServerHello and HelloRetryRequest | _C_ | _22\\.1_ |\n| | \"signature_algorithms\" is REQUIRED for certificate authentication | _C_ | _22_ |\n| | \"supported_groups\" is REQUIRED for ClientHello messages using (EC)DHE key exchange | _C_ | _22_ |\n| | \"key_share\" is REQUIRED for (EC)DHE key exchange | _C_ | _22_ |\n| | \"pre_shared_key\" is REQUIRED for PSK key agreement | _C_ | _22\\.2_ |\n| | \"psk_key_exchange_modes\" is REQUIRED for PSK key agreement | _C_ | _22\\.2_ |\n| | _TLS 1.3 ClientHello_ | _C_ | _22\\.1_ |\n| | If not containing a \"pre_shared_key\" extension, it MUST contain both a \"signature_algorithms\" extension and a \"supported_groups\" extension. | _C_ | _22\\.1_ |\n| | If containing a \"supported_groups\" extension, it MUST also contain a \"key_share\" extension, and vice versa. An empty KeyShare.client_shares vector is permitted. | _C_ | _22\\.1_ |\n| | _TLS 1.3 ServerHello_ | _C_ | _23\\.2_ |\n| | MUST support the use of the \"server_name\" extension | _C_ | _23\\.2_ |\n| [9\\.3. Protocol Invariants](https://tools.ietf.org/html/rfc8446#section-9.3) | | _C_ | _22\\.1_ |\n| | _MUST correctly handle extensible fields_ | _C_ | _22\\.1_ |\n| | A client sending a ClientHello MUST support all parameters advertised in it. Otherwise, the server may fail to interoperate by selecting one of those parameters. | _C_ | _22\\.1_ |\n| | A server receiving a ClientHello MUST correctly ignore all unrecognized cipher suites, extensions, and other parameters. Otherwise, it may fail to interoperate with newer clients. In TLS 1.3, a client receiving a CertificateRequest or NewSessionTicket MUST also ignore all unrecognized extensions. | _C_ | _22\\.1_ |\n| | A middlebox which terminates a TLS connection MUST behave as a compliant TLS server | _NA_ | |\n| | A middlebox which forwards ClientHello parameters it does not understand MUST NOT process any messages beyond that ClientHello. It MUST forward all subsequent traffic unmodified. Otherwise, it may fail to interoperate with newer clients and servers. | _NA_ | |\n| [B.4. Cipher Suites](https://tools.ietf.org/html/rfc8446#section-B.4) | | _C_ | _23_ |\n| | TLS_AES_128_GCM_SHA256 | _C_ | _22_ |\n| | TLS_AES_256_GCM_SHA384 | _C_ | _22_ |\n| | TLS_CHACHA20_POLY1305_SHA256 | _C_ | _22_ |\n| | TLS_AES_128_CCM_SHA256 | _C_ | _22_ |\n| | TLS_AES_128_CCM_8_SHA256 | _C_ | _23_ |\n| [C.1. Random Number Generation and Seeding](https://tools.ietf.org/html/rfc8446#section-C.1) | | _C_ | _22_ |\n| [C.2. Certificates and Authentication](https://tools.ietf.org/html/rfc8446#section-C.2) | | _C_ | _22_ |\n| [C.3. Implementation Pitfalls](https://tools.ietf.org/html/rfc8446#section-C.3) | | _PC_ | _22_ |\n| [C.4. Client Tracking Prevention](https://tools.ietf.org/html/rfc8446#section-C.4) | | _C_ | _22\\.2_ |\n| [C.5. Unauthenticated Operation](https://tools.ietf.org/html/rfc8446#section-C.5) | | _C_ | _22_ |\n| [D.1. Negotiating with an Older Server](https://tools.ietf.org/html/rfc8446#section-D.1) | | _C_ | _22\\.2_ |\n| [D.2. Negotiating with an Older Client](https://tools.ietf.org/html/rfc8446#section-D.2) | | _C_ | _22_ |\n| [D.3. 0-RTT Backward Compatibility](https://tools.ietf.org/html/rfc8446#section-D.3) | | _NC_ | |\n| [D.4. Middlebox Compatibility Mode](https://tools.ietf.org/html/rfc8446#section-D.4) | | _C_ | _23_ |\n| [D.5. Security Restrictions Related to Backward Compatibility](https://tools.ietf.org/html/rfc8446#section-D.5) | | _C_ | _22_ |\n\n_Table: Standards Compliance_","title":"TLS 1.3 - Standards Compliance","ref":"standards_compliance.html#tls-1-3"}],"content_type":"text/plain","producer":{"name":"ex_doc","version":[48,46,51,52,46,49]}} \ No newline at end of file diff --git a/prs/8803/lib/ssl-11.2.1/doc/html/search.html b/prs/8803/lib/ssl-11.2.1/doc/html/search.html index a6ccd10acc150..42d13f668d422 100644 --- a/prs/8803/lib/ssl-11.2.1/doc/html/search.html +++ b/prs/8803/lib/ssl-11.2.1/doc/html/search.html @@ -122,7 +122,7 @@

    - +

    diff --git a/prs/8803/lib/ssl-11.2.1/doc/html/ssl.epub b/prs/8803/lib/ssl-11.2.1/doc/html/ssl.epub index 15f37535ffd80..a1bd73051da6b 100644 Binary files a/prs/8803/lib/ssl-11.2.1/doc/html/ssl.epub and b/prs/8803/lib/ssl-11.2.1/doc/html/ssl.epub differ diff --git a/prs/8803/lib/ssl-11.2.1/doc/html/ssl.html b/prs/8803/lib/ssl-11.2.1/doc/html/ssl.html index 8002004b1bd29..a4dae0fcdaf80 100644 --- a/prs/8803/lib/ssl-11.2.1/doc/html/ssl.html +++ b/prs/8803/lib/ssl-11.2.1/doc/html/ssl.html @@ -131,9 +131,9 @@

    Interface functions for TLS (Transport Layer Security) and DTLS (Datagram Transport Layer Security).

    Note

    The application's name is still SSL because the first versions of the TLS protocol were named SSL (Secure Socket Layer). However, no version -of the old SSL protocol is supported by this application.

    Example:

    1> ssl:start(), ssl:connect("google.com", 443, [{verify, verify_peer},
    -    {cacerts, public_key:cacerts_get()}]).
    -{ok,{sslsocket, [...]}}

    See Examples for detailed usage and more examples of +of the old SSL protocol is supported by this application.

    Example:

    1> ssl:start(), ssl:connect("google.com", 443, [{verify, verify_peer},
    +    {cacerts, public_key:cacerts_get()}]).
    +{ok,{sslsocket, [...]}}

    See Examples for detailed usage and more examples of this API.

    Special Erlang node configuration for the application can be found in SSL Application.

    @@ -2531,26 +2531,26 @@

    signature_algs()

    signature schemes supplied by the signature_algs_cert option.

    The TLS-1.2 default is Default_TLS_12_Alg_Pairs interleaved with rsa_pss_schemes since ssl-11.0 (Erlang/OTP 25). pss_pss is -preferred over pss_rsae, which in turn is preferred over rsa.

    The list for Default_TLS_12_Alg_Pairs is defined as follows:

    [
    -{sha512, ecdsa},
    -{sha512, rsa},
    -{sha384, ecdsa},
    -{sha384, rsa},
    -{sha256, ecdsa},
    -{sha256, rsa}
    -]

    Change

    • Support for {md5, rsa} was removed from the TLS-1.2 default in +preferred over pss_rsae, which in turn is preferred over rsa.

      The list for Default_TLS_12_Alg_Pairs is defined as follows:

      [
      +{sha512, ecdsa},
      +{sha512, rsa},
      +{sha384, ecdsa},
      +{sha384, rsa},
      +{sha256, ecdsa},
      +{sha256, rsa}
      +]

      Change

      • Support for {md5, rsa} was removed from the TLS-1.2 default in ssl-8.0 (Erlang/OTP 22).
      • Support for {sha, _} (SHA1) and {sha224, _} was removed -from the TLS-1.2 default in ssl-11.0 (Erlang/OTP 26).

      The list for rsa_pss_schemes is defined as follows:

      [rsa_pss_pss_sha512,
      +from the TLS-1.2 default in ssl-11.0 (Erlang/OTP 26).

    The list for rsa_pss_schemes is defined as follows:

    [rsa_pss_pss_sha512,
     rsa_pss_pss_sha384,
     rsa_pss_pss_sha256,
     rsa_pss_rsae_sha512,
     rsa_pss_rsae_sha384,
    -rsa_pss_rsae_sha256]

    The list of TLS_13_Legacy_Schemes is defined as follows:

    [
    +rsa_pss_rsae_sha256]

    The list of TLS_13_Legacy_Schemes is defined as follows:

    [
     %% Legacy algorithms only applicable to certificate signatures
     rsa_pkcs1_sha512, %% Corresponds to {sha512, rsa}
     rsa_pkcs1_sha384, %% Corresponds to {sha384, rsa}
     rsa_pkcs1_sha256, %% Corresponds to {sha256, rsa}
    -]

    The list of Default_TLS_13_Schemes is defined as follows:

    [
    +]

    The list of Default_TLS_13_Schemes is defined as follows:

    [
     %% EDDSA
     eddsa_ed25519,
     eddsa_ed448
    @@ -2640,8 +2640,8 @@ 

    anchor_fun()

    -

    Claim an intermediate CA in the chain as trusted.

    fun(Chain::[public_key:der_encoded()]) ->
    -      {trusted_ca, DerCert::public_key:der_encoded()} | unknown_ca.

    TLS then uses public_key:pkix_path_validation/3 with the selected CA +

    Claim an intermediate CA in the chain as trusted.

    fun(Chain::[public_key:der_encoded()]) ->
    +      {trusted_ca, DerCert::public_key:der_encoded()} | unknown_ca.

    TLS then uses public_key:pkix_path_validation/3 with the selected CA as the trusted anchor and verifies the rest of the chain.

    @@ -3093,7 +3093,7 @@

    client_option_cert()

    being sent and disables the hostname verification check.

  • {customize_hostname_check, HostNameCheckOpts} - Customization option

    Customizes the hostname verification of the peer certificate, as various protocols that use TLS, such as HTTP or LDAP, may require different approaches. For example, here is how to use standard hostname checking for HTTPS implemented in -Public_Key:

    {customize_hostname_check, [{match_fun, public_key:pkix_verify_hostname_match_fun(https)}]}

    For futher description of the customize options, see +Public_Key:

    {customize_hostname_check, [{match_fun, public_key:pkix_verify_hostname_match_fun(https)}]}

    For futher description of the customize options, see public_key:pkix_verify_hostname/3.

  • {client_certificate_authorities, UseCertAuth} - Inter-op hint option

    If UseCertAuth is set to true, sends the certificate authorities extension in the TLS-1.3 client hello. The default is false. Note that setting UseCertAuth to true can result in a significant @@ -3237,7 +3237,7 @@

    client_option_tls13()

    Options only relevant for TLS-1.3.

    • {session_tickets, SessionTickets} - Use of session tickets

      Configures the session ticket functionality. Allowed values are disabled, manual, and auto. If it is set to manual the client will send the ticket -information to user process in a 3-tuple:

      {ssl, session_ticket, {SNI, TicketData}}

      where SNI is the ServerNameIndication and TicketData is the extended ticket +information to user process in a 3-tuple:

      {ssl, session_ticket, {SNI, TicketData}}

      where SNI is the ServerNameIndication and TicketData is the extended ticket data that can be used in subsequent session resumptions.

      If it is set to auto, the client automatically handles received tickets and tries to use them when making new TLS connections (session resumption with pre-shared keys).

      Ticket lifetime, the number of tickets sent by the server, and the @@ -3247,7 +3247,7 @@

      client_option_tls13()

      mandatory option in manual mode ({session_tickets, manual}).

      Note

      Session tickets are only sent to the user if option session_tickets is set to manual

      This option is supported by TLS-1.3. See also SSL User's Guide, Session Tickets and Session Resumption in TLS 1.3.

    • {early_data, EarlyData}

      Configures the early data to be sent by the client.

      To verify that the server has the intention to process the early -data, the following tuple is sent to the user process:

      {ssl, SslSocket, {early_data, Result}}

      where Result is either accepted or rejected.

      Warning

      It is the responsibility of the user to handle rejected EarlyData and to +data, the following tuple is sent to the user process:

      {ssl, SslSocket, {early_data, Result}}

      where Result is either accepted or rejected.

      Warning

      It is the responsibility of the user to handle rejected EarlyData and to resend when appropriate.

    • {middlebox_comp_mode, MiddleBoxMode}

      Configures the middlebox compatibility mode for a TLS-1.3 connection.

      A significant number of middleboxes misbehave when a TLS-1.3 connection is negotiated. Implementations can increase the chance of making connections through those middleboxes by adapting the TLS-1.3 @@ -3585,11 +3585,11 @@

      common_option()

      -

      Options common to both client and server side.

      • {protocol, Protocol} - Choose TLS or DTLS protocol for the transport layer security.

        Defaults to tls.

      • {handshake_completion, Completion} - Possibly pause handshake at hello stage.

        Defaults to full. If hello is specified the handshake will pause +

        Options common to both client and server side.

        • {protocol, Protocol} - Choose TLS or DTLS protocol for the transport layer security.

          Defaults to tls.

        • {handshake, Completion} - Possibly pause handshake at hello stage.

          Defaults to full. If hello is specified the handshake will pause after the hello message, allowing the user to make decisions based on hello extensions before continuing or aborting the handshake by calling handshake_continue/3 or handshake_cancel/1.

        • {keep_secrets, KeepSecrets} - Configures a TLS 1.3 connection for keylogging.

          In order to retrieve keylog information on a TLS 1.3 connection, it must be -configured in advance to keep client_random and various handshake secrets.

          The keep_secrets functionality is disabled (false) by default.

          Added in OTP 23.2.

        • {handshake_size, HandshakeSize} - Limit the acceptable handshake packet size.

          Used to limit the size of valid TLS handshake packets to avoid DoS +configured in advance to keep client_random and various handshake secrets.

          The keep_secrets functionality is disabled (false) by default.

          Added in OTP 23.2.

        • {max_handshake_size, HandshakeSize} - Limit the acceptable handshake packet size.

          Used to limit the size of valid TLS handshake packets to avoid DoS attacks.

          Integer (24 bits, unsigned). Defaults to 256*1024.

        • {hibernate_after, HibernateTimeout} - Hibernate inactive connection processes.

          When an integer-value is specified, the TLS/DTLS connection goes into hibernation after the specified number of milliseconds of inactivity, thus reducing its memory footprint. When not specified the process never goes into hibernation.

        • {log_level, Level} - Specifies the log level for a TLS/DTLS connection.

          Alerts are logged on notice @@ -3661,20 +3661,20 @@

          common_option_cert()

          peer certificate in a valid certification path. So, if depth is 0 the PEER must be signed by the trusted ROOT-CA directly; if 1 the path can be PEER, CA, ROOT-CA; if 2 the path can be PEER, CA, CA, ROOT-CA, and so on. The default -value is 10. Used to mitigate DoS attack possibilities.

        • {verify_fun, Verify} - Customize certificate path validation

          The verification fun is to be defined as follows:

          fun(OtpCert :: #'OTPCertificate'{},
          -    Event, InitialUserState :: term()) ->
          -  {valid, UserState :: term()} |
          -  {fail, Reason :: term()} | {unknown, UserState :: term()}.
          +value is 10. Used to mitigate DoS attack possibilities.

        • {verify_fun, Verify} - Customize certificate path validation

          The verification fun is to be defined as follows:

          fun(OtpCert :: #'OTPCertificate'{},
          +    Event, InitialUserState :: term()) ->
          +  {valid, UserState :: term()} |
          +  {fail, Reason :: term()} | {unknown, UserState :: term()}.
           
          -fun(OtpCert :: #'OTPCertificate'{}, DerCert :: public_key:der_encoded(),
          -    Event, InitialUserState :: term()) ->
          -  {valid, UserState :: term()} |
          -  {fail, Reason :: term()} | {unknown, UserState :: term()}.
          +fun(OtpCert :: #'OTPCertificate'{}, DerCert :: public_key:der_encoded(),
          +    Event, InitialUserState :: term()) ->
          +  {valid, UserState :: term()} |
          +  {fail, Reason :: term()} | {unknown, UserState :: term()}.
           
           Types:
          -      Event = {bad_cert, Reason :: atom() |
          -              {revoked, atom()}} |
          -      {extension, #'Extension'{}} |
          +      Event = {bad_cert, Reason :: atom() |
          +              {revoked, atom()}} |
          +      {extension, #'Extension'{}} |
                         valid |
                         valid_peer

          The verification fun is called during the X.509-path validation when an error occurs or an extension unknown to the SSL application is @@ -3691,25 +3691,25 @@

          common_option_cert()

          handshake does not terminate regardless of verification failures, and the connection is established.
        • If called with an extension unknown to the user application, the fun is to return {unknown, UserState}.

        Note that if the fun returns unknown for an extension marked as critical, -validation will fail.

        Default option verify_fun in verify_peer mode:

        {fun(_, _, {bad_cert, _} = Reason, _) ->
        -   {fail, Reason};
        -    (_, _, {extension, _}, UserState) ->
        -   {unknown, UserState};
        -    (_, _, valid, UserState) ->
        -   {valid, UserState};
        -    (_, _, valid_peer, UserState) ->
        -       {valid, UserState}
        - end, []}

        Default option verify_fun in mode verify_none:

         {fun(_, _, {bad_cert, _}, UserState) ->
        -   {valid, UserState};
        -    (_, _, {extension, #'Extension'{critical = true}}, UserState) ->
        -   {valid, UserState};
        -    (_, _, {extension, _}, UserState) ->
        -   {unknown, UserState};
        -    (_, _, valid, UserState) ->
        -   {valid, UserState};
        -    (_, _, valid_peer, UserState) ->
        -       {valid, UserState}
        - end, []}

        The possible path validation errors are given in the form {bad_cert, Reason}, +validation will fail.

        Default option verify_fun in verify_peer mode:

        {fun(_, _, {bad_cert, _} = Reason, _) ->
        +   {fail, Reason};
        +    (_, _, {extension, _}, UserState) ->
        +   {unknown, UserState};
        +    (_, _, valid, UserState) ->
        +   {valid, UserState};
        +    (_, _, valid_peer, UserState) ->
        +       {valid, UserState}
        + end, []}

        Default option verify_fun in mode verify_none:

         {fun(_, _, {bad_cert, _}, UserState) ->
        +   {valid, UserState};
        +    (_, _, {extension, #'Extension'{critical = true}}, UserState) ->
        +   {valid, UserState};
        +    (_, _, {extension, _}, UserState) ->
        +   {unknown, UserState};
        +    (_, _, valid, UserState) ->
        +   {valid, UserState};
        +    (_, _, valid_peer, UserState) ->
        +       {valid, UserState}
        + end, []}

        The possible path validation errors are given in the form {bad_cert, Reason}, where Reason is:

        • unknown_ca

          No trusted CA was found in the trusted store. The trusted CA is normally a so-called ROOT CA, which is a self-signed certificate. Trust can be claimed for an intermediate CA (the trusted anchor does not have to be @@ -3850,11 +3850,11 @@

          common_option_pre_tls13()

          enforced. If SecureRenegotiate is false secure renegotiation will still be used if possible, but it falls back to insecure renegotiation if the peer does not support if RFC -5746.

        • {user_lookup_fun, {LookupFun, UserState}} - PSK/SRP cipher suite option

          The lookup fun is to be defined as follows:

          fun(psk, PSKIdentity :: binary(), UserState :: term()) ->
          -  {ok, SharedSecret :: binary()} | error;
          -fun(srp, Username :: binary(), UserState :: term()) ->
          -  {ok, {SRPParams :: srp_param_type(), Salt :: binary(),
          -        DerivedKey :: binary()}} | error.

          For Pre-Shared Key (PSK) cipher suites, the lookup fun is called by the client +5746.

        • {user_lookup_fun, {LookupFun, UserState}} - PSK/SRP cipher suite option

          The lookup fun is to be defined as follows:

          fun(psk, PSKIdentity :: binary(), UserState :: term()) ->
          +  {ok, SharedSecret :: binary()} | error;
          +fun(srp, Username :: binary(), UserState :: term()) ->
          +  {ok, {SRPParams :: srp_param_type(), Salt :: binary(),
          +        DerivedKey :: binary()}} | error.

          For Pre-Shared Key (PSK) cipher suites, the lookup fun is called by the client and server to determine the shared secret. When called by the client, PSKIdentity is the hint presented by the server or undefined. When called by the server, PSKIdentity is the identity presented by the client.

          For Secure Remote Password (SRP), the fun is only used by the server to obtain @@ -4167,8 +4167,8 @@

          connect(TCPSocketOrHost, TLSOptionsOrPort, -

          Opens a TLS/DTLS connection.

          connect(TCPSocket, TLSOptions, Timeout).

          Upgrades a gen_tcp (or equivalent) connected socket to a TLS socket by -performing the client-side TLS handshake.

          connect(Host, Port, TLSOptions).

          Opens a TLS/DTLS connection to Host, Port. This call is equivalent to:

          connect(Host, Port, TLSOptions, infinity).
          +

          Opens a TLS/DTLS connection.

          connect(TCPSocket, TLSOptions, Timeout).

          Upgrades a gen_tcp (or equivalent) connected socket to a TLS socket by +performing the client-side TLS handshake.

          connect(Host, Port, TLSOptions).

          Opens a TLS/DTLS connection to Host, Port. This call is equivalent to:

          connect(Host, Port, TLSOptions, infinity).
          @@ -4304,7 +4304,7 @@

          handshake(HsSocket, OptionsOrTimeout)

          -

          Performs the TLS/DTLS server-side handshake.

          If the second argument is a timeout value:

          handshake(HsSocket, Timeout).

          this call is equivalent to:

          handshake(HsSocket, [], Timeout).

          Otherwise, if the second argument is a list of options:

          handshake(HsSocket, Options).

          this call is equivalent to:

          handshake(HsSocket, Options, infinity).
          +

          Performs the TLS/DTLS server-side handshake.

          If the second argument is a timeout value:

          handshake(HsSocket, Timeout).

          this call is equivalent to:

          handshake(HsSocket, [], Timeout).

          Otherwise, if the second argument is a list of options:

          handshake(HsSocket, Options).

          this call is equivalent to:

          handshake(HsSocket, Options, infinity).
          @@ -5696,35 +5696,35 @@

          signature_algs(Description, Version)

          Lists all available signature algorithms corresponding to Description.

          The exclusive option will exclusively list algorithms or algorithm schemes for that protocol version, whereas the default and all options lists the combined list to support the range of protocols from (D)TLS-1.2, the first -version to support configuration of the signature algorithms, to Version.

          Example:

          1> ssl:signature_algs(default, 'tlsv1.3').
          -[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,
          +version to support configuration of the signature algorithms, to Version.

          Example:

          1> ssl:signature_algs(default, 'tlsv1.3').
          +[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,
           ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,
           rsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,
           rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,
           rsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256,
          -{sha512,ecdsa},
          -{sha384,ecdsa},
          -{sha256,ecdsa}]
          +{sha512,ecdsa},
          +{sha384,ecdsa},
          +{sha256,ecdsa}]
           
          -2> ssl:signature_algs(all, 'tlsv1.3').
          -[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,
          +2> ssl:signature_algs(all, 'tlsv1.3').
          +[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,
           ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,
           rsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,
           rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,
           rsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256,
          -{sha512,ecdsa},
          -{sha384,ecdsa},
          -{sha256,ecdsa},
          -{sha224,ecdsa},
          -{sha224,rsa},
          -{sha,rsa},
          -{sha,dsa}]
          -
          -3> ssl:signature_algs(exclusive, 'tlsv1.3').
          -[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,
          +{sha512,ecdsa},
          +{sha384,ecdsa},
          +{sha256,ecdsa},
          +{sha224,ecdsa},
          +{sha224,rsa},
          +{sha,rsa},
          +{sha,dsa}]
          +
          +3> ssl:signature_algs(exclusive, 'tlsv1.3').
          +[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,
           ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,
           rsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,
          -rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256]

          Note

          Some TLS-1-3 scheme names overlap with TLS-1.2 algorithm-tuple-pair-names and +rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256]

          Note

          Some TLS-1-3 scheme names overlap with TLS-1.2 algorithm-tuple-pair-names and then TLS-1.3 names will be used, for example rsa_pkcs1_sha256 instead of {sha256, rsa}. These are legacy algorithms in TLS-1.3 that apply only to certificate signatures in this version of the protocol.

          diff --git a/prs/8803/lib/ssl-11.2.1/doc/html/ssl_distribution.html b/prs/8803/lib/ssl-11.2.1/doc/html/ssl_distribution.html index b12496c5209e7..7ddf07fa2f60b 100644 --- a/prs/8803/lib/ssl-11.2.1/doc/html/ssl_distribution.html +++ b/prs/8803/lib/ssl-11.2.1/doc/html/ssl_distribution.html @@ -147,14 +147,14 @@

          applications. Such a script is located in the bin directory of the Erlang distribution. The source for the script is found under the Erlang installation top directory under releases/<OTP version>/start_clean.rel.

          Do the following:

          • Copy that script to another location (and preferably another name).
          • Add the applications Crypto, Public Key, and SSL with their current version -numbers after the STDLIB application.

          The following shows an example .rel file with TLS added:

                {release, {"OTP  APN 181 01","R15A"}, {erts, "5.9"},
          -      [{kernel,"2.15"},
          -      {stdlib,"1.18"},
          -      {crypto, "2.0.3"},
          -      {public_key, "0.12"},
          -      {asn1, "4.0"},
          -      {ssl, "5.0"}
          -      ]}.

          The version numbers differ in your system. Whenever one of the applications +numbers after the STDLIB application.

        The following shows an example .rel file with TLS added:

              {release, {"OTP  APN 181 01","R15A"}, {erts, "5.9"},
        +      [{kernel,"2.15"},
        +      {stdlib,"1.18"},
        +      {crypto, "2.0.3"},
        +      {public_key, "0.12"},
        +      {asn1, "4.0"},
        +      {ssl, "5.0"}
        +      ]}.

        The version numbers differ in your system. Whenever one of the applications included in the script is upgraded, change the script.

        Do the following:

        • Build the boot script.

          Assuming the .rel file is stored in a file start_ssl.rel in the current directory, a boot script can be built as follows:

           1> systools:make_script("start_ssl",[]).

        There is now a start_ssl.boot file in the current directory.

        Do the following:

        • Test the boot script. To do this, start Erlang with the -boot command-line parameter specifying this boot script (with its full path, but without the @@ -201,10 +201,10 @@

          so beware!

          For TLS to work, at least a public key and a certificate must be specified for the server side and the client needs to specify CAs that it trusts (client certification is optional and requires more configuration).

          In the following example (to keep it simple), the PEM file "/home/me/ssl/erlserver.pem" -contains both the server certificate and its private key .

          Create a file named for example "/home/me/ssl/ssl_test@myhost.conf":

          [{server,
          -  [{certfile, "/home/me/ssl/erlserver.pem"}]},
          - {client,
          -  [{cacertfile, "/home/me/ssl/client_trusted.pem"}]}].

          And then start the node like this (line breaks in the command are for +contains both the server certificate and its private key .

          Create a file named for example "/home/me/ssl/ssl_test@myhost.conf":

          [{server,
          +  [{certfile, "/home/me/ssl/erlserver.pem"}]},
          + {client,
          +  [{cacertfile, "/home/me/ssl/client_trusted.pem"}]}].

          And then start the node like this (line breaks in the command are for readability, and shall not be there when typed):

          $ erl -boot /home/me/ssl/start_ssl -proto_dist inet_tls
             -ssl_dist_optfile "/home/me/ssl/ssl_test@myhost.conf"
             -sname ssl_test

          The options in the {server, Opts} tuple are used when calling @@ -274,19 +274,19 @@

          -ssl_dist_opt server_secure_renegotiate true client_secure_renegotiate true" $ export ERL_FLAGS $ erl -sname ssl_test -Erlang (BEAM) emulator version 5.0 [source] - -Eshell V5.0 (abort with ^G) -(ssl_test@myhost)1> init:get_arguments(). -[{root,["/usr/local/erlang"]}, - {progname,["erl "]}, - {sname,["ssl_test"]}, - {boot,["/home/me/ssl/start_ssl"]}, - {proto_dist,["inet_tls"]}, - {ssl_dist_opt,["server_certfile","/home/me/ssl/erlserver.pem"]}, - {ssl_dist_opt,["server_secure_renegotiate","true", - "client_secure_renegotiate","true"] - {home,["/home/me"]}]

  • The init:get_arguments() call verifies that the correct arguments are supplied +Erlang (BEAM) emulator version 5.0 [source] + +Eshell V5.0 (abort with ^G) +(ssl_test@myhost)1> init:get_arguments(). +[{root,["/usr/local/erlang"]}, + {progname,["erl "]}, + {sname,["ssl_test"]}, + {boot,["/home/me/ssl/start_ssl"]}, + {proto_dist,["inet_tls"]}, + {ssl_dist_opt,["server_certfile","/home/me/ssl/erlserver.pem"]}, + {ssl_dist_opt,["server_secure_renegotiate","true", + "client_secure_renegotiate","true"] + {home,["/home/me"]}]

    The init:get_arguments() call verifies that the correct arguments are supplied to the emulator.

    diff --git a/prs/8803/lib/ssl-11.2.1/doc/html/using_ssl.html b/prs/8803/lib/ssl-11.2.1/doc/html/using_ssl.html index 34859196f1ed4..5fd74656428ba 100644 --- a/prs/8803/lib/ssl-11.2.1/doc/html/using_ssl.html +++ b/prs/8803/lib/ssl-11.2.1/doc/html/using_ssl.html @@ -149,38 +149,38 @@

    Basic Client

    -
     1 > ssl:start(), ssl:connect("google.com", 443, [{verify, verify_peer},
    -                                                 {cacerts, public_key:cacerts_get()}]).
    -   {ok,{sslsocket, [...]}}

    +
     1 > ssl:start(), ssl:connect("google.com", 443, [{verify, verify_peer},
    +                                                 {cacerts, public_key:cacerts_get()}]).
    +   {ok,{sslsocket, [...]}}

    Basic Connection

    -

    Step 1: Start the server side:

    1 server> ssl:start().
    +

    Step 1: Start the server side:

    1 server> ssl:start().
     ok

    Step 2: with alternative certificates, in this example the EDDSA certificate will be preferred if TLS-1.3 is negotiated and the RSA certificate will always -be used for TLS-1.2 as it does not support the EDDSA algorithm:

    2 server> {ok, ListenSocket} =
    -ssl:listen(9999, [{certs_keys, [#{certfile => "eddsacert.pem",
    -                                  keyfile => "eddsakey.pem"},
    -                                #{certfile => "rsacert.pem",
    +be used for TLS-1.2 as it does not support the EDDSA algorithm:

    2 server> {ok, ListenSocket} =
    +ssl:listen(9999, [{certs_keys, [#{certfile => "eddsacert.pem",
    +                                  keyfile => "eddsakey.pem"},
    +                                #{certfile => "rsacert.pem",
                                       keyfile => "rsakey.pem",
    -                                  password => "foobar"}
    -                               ]},{reuseaddr, true}]).
    -{ok,{sslsocket, [...]}}

    Step 3: Do a transport accept on the TLS listen socket:

    3 server> {ok, TLSTransportSocket} = ssl:transport_accept(ListenSocket).
    -{ok,{sslsocket, [...]}}

    Note

    ssl:transport_accept/1 and ssl:handshake/2 are separate functions so that the + password => "foobar"} + ]},{reuseaddr, true}]). +{ok,{sslsocket, [...]}}

    Step 3: Do a transport accept on the TLS listen socket:

    3 server> {ok, TLSTransportSocket} = ssl:transport_accept(ListenSocket).
    +{ok,{sslsocket, [...]}}

    Note

    ssl:transport_accept/1 and ssl:handshake/2 are separate functions so that the handshake part can be called in a new erlang process dedicated to handling the -connection

    Step 4: Start the client side:

    1 client> ssl:start().
    +connection

    Step 4: Start the client side:

    1 client> ssl:start().
     ok

    Be sure to configure trusted certificates to use for server certificate -verification.

    2 client> {ok, Socket} = ssl:connect("localhost", 9999,
    -      [{verify, verify_peer},
    -      {cacertfile, "cacerts.pem"}, {active, once}], infinity).
    -{ok,{sslsocket, [...]}}

    Step 5: Do the TLS handshake:

    4 server> {ok, Socket} = ssl:handshake(TLSTransportSocket).
    -{ok,{sslsocket, [...]}}

    Note

    A real server should use ssl:handshake/2 that has a timeout to avoid DoS -attacks. In the example the timeout defaults to infinty.

    Step 6: Send a message over TLS:

    5 server> ssl:send(Socket, "foo").
    +verification.

    2 client> {ok, Socket} = ssl:connect("localhost", 9999,
    +      [{verify, verify_peer},
    +      {cacertfile, "cacerts.pem"}, {active, once}], infinity).
    +{ok,{sslsocket, [...]}}

    Step 5: Do the TLS handshake:

    4 server> {ok, Socket} = ssl:handshake(TLSTransportSocket).
    +{ok,{sslsocket, [...]}}

    Note

    A real server should use ssl:handshake/2 that has a timeout to avoid DoS +attacks. In the example the timeout defaults to infinty.

    Step 6: Send a message over TLS:

    5 server> ssl:send(Socket, "foo").
     ok

    Step 7: Flush the shell message queue to see that the message sent on the -server side is recived by the client side:

    3 client> flush().
    -Shell got {ssl,{sslsocket,[...]},"foo"}
    +server side is recived by the client side:

    3 client> flush().
    +Shell got {ssl,{sslsocket,[...]},"foo"}
     ok

    @@ -192,27 +192,27 @@

    communication channel by using TLS. Note that the client and server need to agree to do the upgrade in the protocol doing the communication. This is concept is often referenced as STARTLS and used in many protocols such as SMTP, -FTPS and HTTPS via a proxy.

    Warning

    Maximum security recommendations are however moving away from such solutions.

    To upgrade to a TLS connection:

    Step 1: Start the server side:

    1 server> ssl:start().
    +FTPS and HTTPS via a proxy.

    Warning

    Maximum security recommendations are however moving away from such solutions.

    To upgrade to a TLS connection:

    Step 1: Start the server side:

    1 server> ssl:start().
       ok

    Step 2: Create a normal TCP listen socket and ensure active is set to false and not set to any active mode otherwise TLS handshake messages can be -delivered to the wrong process.

    2 server> {ok, ListenSocket} = gen_tcp:listen(9999, [{reuseaddr, true},
    -  {active, false}]).
    -  {ok, #Port<0.475>}

    Step 3: Accept client connection:

    3 server> {ok, Socket} = gen_tcp:accept(ListenSocket).
    -  {ok, #Port<0.476>}

    Step 4: Start the client side:

    1 client> ssl:start().
    -  ok
    2 client> {ok, Socket} = gen_tcp:connect("localhost", 9999,  [], infinity).

    Step 5: Do the TLS handshake:

    4 server> {ok, TLSSocket} = ssl:handshake(Socket, [{verify, verify_peer},
    -  {fail_if_no_peer_cert, true},
    -  {cacertfile, "cacerts.pem"},
    -  {certs_keys, [#{certfile => "cert.pem", keyfile => "key.pem"}]}]).
    -  {ok,{sslsocket,[...]}}

    Step 6: Upgrade to a TLS connection. The client and server must agree upon the +delivered to the wrong process.

    2 server> {ok, ListenSocket} = gen_tcp:listen(9999, [{reuseaddr, true},
    +  {active, false}]).
    +  {ok, #Port<0.475>}

    Step 3: Accept client connection:

    3 server> {ok, Socket} = gen_tcp:accept(ListenSocket).
    +  {ok, #Port<0.476>}

    Step 4: Start the client side:

    1 client> ssl:start().
    +  ok
    2 client> {ok, Socket} = gen_tcp:connect("localhost", 9999,  [], infinity).

    Step 5: Do the TLS handshake:

    4 server> {ok, TLSSocket} = ssl:handshake(Socket, [{verify, verify_peer},
    +  {fail_if_no_peer_cert, true},
    +  {cacertfile, "cacerts.pem"},
    +  {certs_keys, [#{certfile => "cert.pem", keyfile => "key.pem"}]}]).
    +  {ok,{sslsocket,[...]}}

    Step 6: Upgrade to a TLS connection. The client and server must agree upon the upgrade. The server must be prepared to be a TLS server before the client can do -a successful connect.

    3 client>{ok, TLSSocket} = ssl:connect(Socket, [{verify, verify_peer},
    -  {cacertfile, "cacerts.pem"},
    -  {certs_keys, [#{certfile => "cert.pem", keyfile => "key.pem"}]}], infinity).
    -{ok,{sslsocket,[...]}}

    Step 7: Send a message over TLS:

    4 client> ssl:send(TLSSocket, "foo").
    -      ok

    Step 8: Set active once on the TLS socket:

    5 server> ssl:setopts(TLSSocket, [{active, once}]).
    +a successful connect.

    3 client>{ok, TLSSocket} = ssl:connect(Socket, [{verify, verify_peer},
    +  {cacertfile, "cacerts.pem"},
    +  {certs_keys, [#{certfile => "cert.pem", keyfile => "key.pem"}]}], infinity).
    +{ok,{sslsocket,[...]}}

    Step 7: Send a message over TLS:

    4 client> ssl:send(TLSSocket, "foo").
    +      ok

    Step 8: Set active once on the TLS socket:

    5 server> ssl:setopts(TLSSocket, [{active, once}]).
           ok

    Step 9: Flush the shell message queue to see that the message sent on the -client side is recived by the server side:

    5 server> flush().
    -      Shell got {ssl,{sslsocket,[...]},"foo"}
    +client side is recived by the server side:

    5 server> flush().
    +      Shell got {ssl,{sslsocket,[...]},"foo"}
           ok

    @@ -220,34 +220,34 @@

    Customizing cipher suites

    Fetch default cipher suite list for a TLS/DTLS version. Change default to all to -get all possible cipher suites.

    1>  Default = ssl:cipher_suites(default, 'tlsv1.2').
    -    [#{cipher => aes_256_gcm,key_exchange => ecdhe_ecdsa,
    -    mac => aead,prf => sha384}, ....]

    In OTP 20 it is desirable to remove all cipher suites that uses rsa key exchange +get all possible cipher suites.

    1>  Default = ssl:cipher_suites(default, 'tlsv1.2').
    +    [#{cipher => aes_256_gcm,key_exchange => ecdhe_ecdsa,
    +    mac => aead,prf => sha384}, ....]

    In OTP 20 it is desirable to remove all cipher suites that uses rsa key exchange (removed from default in 21)

    2> NoRSA =
    -    ssl:filter_cipher_suites(Default,
    -                             [{key_exchange, fun(rsa) -> false;
    -                                                (_) -> true
    -                                             end}]).
    -    [...]

    Pick just a few suites

     3> Suites =
    - ssl:filter_cipher_suites(Default,
    -                             [{key_exchange, fun(ecdh_ecdsa) -> true;
    -                                                (_) -> false
    -                                             end},
    -                              {cipher, fun(aes_128_cbc) -> true;
    -                                          (_) ->false
    -                                       end}]).
    -
    -[#{cipher => aes_128_cbc,key_exchange => ecdh_ecdsa,
    -   mac => sha256,prf => sha256},
    - #{cipher => aes_128_cbc,key_exchange => ecdh_ecdsa,mac => sha,
    -   prf => default_prf}]

    Make some particular suites the most preferred, or least preferred by changing -prepend to append.

     4>ssl:prepend_cipher_suites(Suites, Default).
    -  [#{cipher => aes_128_cbc,key_exchange => ecdh_ecdsa,
    -     mac => sha256,prf => sha256},
    -   #{cipher => aes_128_cbc,key_exchange => ecdh_ecdsa,mac => sha,
    -     prf => default_prf},
    -   #{cipher => aes_256_cbc,key_exchange => ecdhe_ecdsa,
    -     mac => sha384,prf => sha384}, ...]

    + ssl:filter_cipher_suites(Default, + [{key_exchange, fun(rsa) -> false; + (_) -> true + end}]). + [...]

    Pick just a few suites

     3> Suites =
    + ssl:filter_cipher_suites(Default,
    +                             [{key_exchange, fun(ecdh_ecdsa) -> true;
    +                                                (_) -> false
    +                                             end},
    +                              {cipher, fun(aes_128_cbc) -> true;
    +                                          (_) ->false
    +                                       end}]).
    +
    +[#{cipher => aes_128_cbc,key_exchange => ecdh_ecdsa,
    +   mac => sha256,prf => sha256},
    + #{cipher => aes_128_cbc,key_exchange => ecdh_ecdsa,mac => sha,
    +   prf => default_prf}]

    Make some particular suites the most preferred, or least preferred by changing +prepend to append.

     4>ssl:prepend_cipher_suites(Suites, Default).
    +  [#{cipher => aes_128_cbc,key_exchange => ecdh_ecdsa,
    +     mac => sha256,prf => sha256},
    +   #{cipher => aes_128_cbc,key_exchange => ecdh_ecdsa,mac => sha,
    +     prf => default_prf},
    +   #{cipher => aes_256_cbc,key_exchange => ecdhe_ecdsa,
    +     mac => sha384,prf => sha384}, ...]

    @@ -265,9 +265,9 @@

    suite that is chosen, which is not the case in TLS-1.3.

    Using the function ssl:signature_algs/2 will let you inspect different aspects of possible configurations for your system. For example if TLS-1.3 and TLS-1.2 is supported the default signature_algorithm list in OTP-26 and cryptolib from -OpenSSL 3.0.2 would look like:

     1>  ssl:signature_algs(default, 'tlsv1.3').
    +OpenSSL 3.0.2 would look like:

     1>  ssl:signature_algs(default, 'tlsv1.3').
      %% TLS-1.3 schemes
    - [eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,
    + [eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,
       ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256,
       rsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,
       rsa_pss_rsae_sha512,rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,
    @@ -275,12 +275,12 @@ 

    %% (would have a tuple name in TLS-1.2 only configuration) rsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256 %% TLS 1.2 algorithms - {sha512,ecdsa}, - {sha384,ecdsa}, - {sha256,ecdsa}]

    If you want to add support for non default supported algorithms you should + {sha512,ecdsa}, + {sha384,ecdsa}, + {sha256,ecdsa}]

    If you want to add support for non default supported algorithms you should append them to the default list as the configuration is in prefered order, -something like this:

        MySignatureAlgs = ssl:signature_algs(default, 'tlsv1.3') ++ [{sha, rsa}, {sha, dsa}],
    -    ssl:connect(Host,Port,[{signature_algs, MySignatureAlgs,...]}),
    +something like this:

        MySignatureAlgs = ssl:signature_algs(default, 'tlsv1.3') ++ [{sha, rsa}, {sha, dsa}],
    +    ssl:connect(Host,Port,[{signature_algs, MySignatureAlgs,...]}),
         ...

    See also ssl:signature_algs/2 and sign_algo()

    @@ -288,20 +288,20 @@

    Using an Engine Stored Key

    Erlang ssl application is able to use private keys provided by OpenSSL engines -using the following mechanism:

    1> ssl:start().
    +using the following mechanism:

    1> ssl:start().
     ok

    Load a crypto engine, should be done once per engine used. For example -dynamically load the engine called MyEngine:

    2> {ok, EngineRef} =
    -crypto:engine_load(<<"dynamic">>,
    -[{<<"SO_PATH">>, "/tmp/user/engines/MyEngine"},<<"LOAD">>],
    -[]).
    -{ok,#Ref<0.2399045421.3028942852.173962>}

    Create a map with the engine information and the algorithm used by the engine:

    3> PrivKey =
    - #{algorithm => rsa,
    +dynamically load the engine called MyEngine:

    2> {ok, EngineRef} =
    +crypto:engine_load(<<"dynamic">>,
    +[{<<"SO_PATH">>, "/tmp/user/engines/MyEngine"},<<"LOAD">>],
    +[]).
    +{ok,#Ref<0.2399045421.3028942852.173962>}

    Create a map with the engine information and the algorithm used by the engine:

    3> PrivKey =
    + #{algorithm => rsa,
        engine => EngineRef,
    -   key_id => "id of the private key in Engine"}.

    Use the map in the ssl key option:

    4> {ok, SSLSocket} =
    - ssl:connect("localhost", 9999,
    -                [{cacertfile, "cacerts.pem"},
    -                 {certs_keys, [#{certfile => "cert.pem", key => PrivKey}]}
    -                ], infinity).
    +   key_id => "id of the private key in Engine"}.

    Use the map in the ssl key option:

    4> {ok, SSLSocket} =
    + ssl:connect("localhost", 9999,
    +                [{cacertfile, "cacerts.pem"},
    +                 {certs_keys, [#{certfile => "cert.pem", key => PrivKey}]}
    +                ], infinity).
     

    See also crypto documentation

    @@ -309,19 +309,19 @@

    NSS keylog

    The NSS keylog debug feature can be used by authorized users to for instance -enable wireshark to decrypt TLS packets.

    Server (with NSS key logging)

        server() ->
    -        application:load(ssl),
    -        {ok, _} = application:ensure_all_started(ssl),
    +enable wireshark to decrypt TLS packets.

    Server (with NSS key logging)

        server() ->
    +        application:load(ssl),
    +        {ok, _} = application:ensure_all_started(ssl),
             Port = 11029,
    -        LOpts = [{certs_keys, [#{certfile => "cert.pem", keyfile => "key.pem"}]},
    -        {reuseaddr, true},
    -        {versions, ['tlsv1.2','tlsv1.3']},
    -        {keep_secrets, true} %% Enable NSS key log (debug option)
    -        ],
    -        {ok, LSock} = ssl:listen(Port, LOpts),
    -        {ok, ASock} = ssl:transport_accept(LSock),
    -        {ok, CSock} = ssl:handshake(ASock).

    Exporting the secrets

          {ok, [{keylog, KeylogItems}]} = ssl:connection_information(CSock, [keylog]).
    -      file:write_file("key.log", [[KeylogItem,$\n] || KeylogItem <- KeylogItems]).

    + LOpts = [{certs_keys, [#{certfile => "cert.pem", keyfile => "key.pem"}]}, + {reuseaddr, true}, + {versions, ['tlsv1.2','tlsv1.3']}, + {keep_secrets, true} %% Enable NSS key log (debug option) + ], + {ok, LSock} = ssl:listen(Port, LOpts), + {ok, ASock} = ssl:transport_accept(LSock), + {ok, CSock} = ssl:handshake(ASock).

    Exporting the secrets

          {ok, [{keylog, KeylogItems}]} = ssl:connection_information(CSock, [keylog]).
    +      file:write_file("key.log", [[KeylogItem,$\n] || KeylogItem <- KeylogItems]).

    @@ -345,115 +345,115 @@

    {reuse_session, SessionId}. Also it is possible for the client to reuse a session that is not saved by the ssl application using {reuse_session, {SessionId, SessionData}}.

    Note

    When using explicit session reuse, it is up to the client to make sure that -the session being reused is for the correct server and has been verified.

    Here follows a client side example, divide into several steps for readability.

    Step 1 - Automated Session Reuse

    1> ssl:start().
    +the session being reused is for the correct server and has been verified.

    Here follows a client side example, divide into several steps for readability.

    Step 1 - Automated Session Reuse

    1> ssl:start().
     ok
     
    -2>{ok, C1} = ssl:connect("localhost", 9999, [{verify, verify_peer},
    -                                           {versions, ['tlsv1.2']},
    -                                           {cacertfile, "cacerts.pem"}]).
    -{ok,{sslsocket,{gen_tcp,#Port<0.7>,tls_connection,undefined}, ...}}
    +2>{ok, C1} = ssl:connect("localhost", 9999, [{verify, verify_peer},
    +                                           {versions, ['tlsv1.2']},
    +                                           {cacertfile, "cacerts.pem"}]).
    +{ok,{sslsocket,{gen_tcp,#Port<0.7>,tls_connection,undefined}, ...}}
     
    -3> ssl:connection_information(C1, [session_id]).
    -{ok,[{session_id,<<95,32,43,22,35,63,249,22,26,36,106,
    +3> ssl:connection_information(C1, [session_id]).
    +{ok,[{session_id,<<95,32,43,22,35,63,249,22,26,36,106,
                        152,49,52,124,56,130,192,137,161,
    -                   146,145,164,232,...>>}]}
    +                   146,145,164,232,...>>}]}
     
     %% Reuse session if possible, note that if C2 is really fast the session
     %% data might not be available for reuse.
    -4>{ok, C2} = ssl:connect("localhost", 9999, [{verify, verify_peer},
    -                                           {versions, ['tlsv1.2']},
    -                                           {cacertfile, "cacerts.pem"},
    -                                           {reuse_sessions, true}]).
    -{ok,{sslsocket,{gen_tcp,#Port<0.8>,tls_connection,undefined}, ...]}}
    +4>{ok, C2} = ssl:connect("localhost", 9999, [{verify, verify_peer},
    +                                           {versions, ['tlsv1.2']},
    +                                           {cacertfile, "cacerts.pem"},
    +                                           {reuse_sessions, true}]).
    +{ok,{sslsocket,{gen_tcp,#Port<0.8>,tls_connection,undefined}, ...]}}
     
     %% C2 got same session ID as client one, session was automatically reused.
    -5> ssl:connection_information(C2, [session_id]).
    -{ok,[{session_id,<<95,32,43,22,35,63,249,22,26,36,106,
    +5> ssl:connection_information(C2, [session_id]).
    +{ok,[{session_id,<<95,32,43,22,35,63,249,22,26,36,106,
                        152,49,52,124,56,130,192,137,161,
    -                   146,145,164,232,...>>}]}

    Step 2- Using save Option

    %% We want save this particular session for
    +                   146,145,164,232,...>>}]}

    Step 2- Using save Option

    %% We want save this particular session for
     %% reuse although it has the same basis as C1
    -6> {ok, C3} = ssl:connect("localhost", 9999, [{verify, verify_peer},
    -                                           {versions, ['tlsv1.2']},
    -                                           {cacertfile, "cacerts.pem"},
    -                                           {reuse_sessions, save}]).
    +6> {ok, C3} = ssl:connect("localhost", 9999, [{verify, verify_peer},
    +                                           {versions, ['tlsv1.2']},
    +                                           {cacertfile, "cacerts.pem"},
    +                                           {reuse_sessions, save}]).
     
    -{ok,{sslsocket,{gen_tcp,#Port<0.9>,tls_connection,undefined}, ...]}}
    +{ok,{sslsocket,{gen_tcp,#Port<0.9>,tls_connection,undefined}, ...]}}
     
     %% A full handshake is performed and we get a new session ID
    -7> {ok, [{session_id, ID}]} = ssl:connection_information(C3, [session_id]).
    -{ok,[{session_id,<<91,84,27,151,183,39,84,90,143,141,
    +7> {ok, [{session_id, ID}]} = ssl:connection_information(C3, [session_id]).
    +{ok,[{session_id,<<91,84,27,151,183,39,84,90,143,141,
                        121,190,66,192,10,1,27,192,33,95,78,
    -                   8,34,180,...>>}]}
    +                   8,34,180,...>>}]}
     
     %% Use automatic session reuse
    -8> {ok, C4} = ssl:connect("localhost", 9999, [{verify, verify_peer},
    -                                           {versions, ['tlsv1.2']},
    -                                           {cacertfile, "cacerts.pem"},
    -                                           {reuse_sessions, true}]).
    +8> {ok, C4} = ssl:connect("localhost", 9999, [{verify, verify_peer},
    +                                           {versions, ['tlsv1.2']},
    +                                           {cacertfile, "cacerts.pem"},
    +                                           {reuse_sessions, true}]).
     
    -{ok,{sslsocket,{gen_tcp,#Port<0.10>,tls_connection,
    -                        undefined}, ...]}}
    +{ok,{sslsocket,{gen_tcp,#Port<0.10>,tls_connection,
    +                        undefined}, ...]}}
     
     %% The "saved" one happened to be selected, but this is not a guarantee
    -9> ssl:connection_information(C4, [session_id]).
    -{ok,[{session_id,<<91,84,27,151,183,39,84,90,143,141,
    +9> ssl:connection_information(C4, [session_id]).
    +{ok,[{session_id,<<91,84,27,151,183,39,84,90,143,141,
                        121,190,66,192,10,1,27,192,33,95,78,
    -                   8,34,180,...>>}]}
    +                   8,34,180,...>>}]}
     
     %% Make sure to reuse the "saved" session
    -10> {ok, C5} = ssl:connect("localhost", 9999, [{verify, verify_peer},
    -                                           {versions, ['tlsv1.2']},
    -                                           {cacertfile, "cacerts.pem"},
    -                                           {reuse_session, ID}]).
    -{ok,{sslsocket,{gen_tcp,#Port<0.11>,tls_connection,
    -                        undefined}, ...]}}
    -
    -11> ssl:connection_information(C5, [session_id]).
    -{ok,[{session_id,<<91,84,27,151,183,39,84,90,143,141,
    +10> {ok, C5} = ssl:connect("localhost", 9999, [{verify, verify_peer},
    +                                           {versions, ['tlsv1.2']},
    +                                           {cacertfile, "cacerts.pem"},
    +                                           {reuse_session, ID}]).
    +{ok,{sslsocket,{gen_tcp,#Port<0.11>,tls_connection,
    +                        undefined}, ...]}}
    +
    +11> ssl:connection_information(C5, [session_id]).
    +{ok,[{session_id,<<91,84,27,151,183,39,84,90,143,141,
                        121,190,66,192,10,1,27,192,33,95,78,
    -                   8,34,180,...>>}]}

    Step 3 - Explicit Session Reuse

    %% Perform a full handshake and the session will not be saved for reuse
    -12> {ok, C9} =
    -ssl:connect("localhost", 9999, [{verify, verify_peer},
    -                                    {versions, ['tlsv1.2']},
    -                                    {cacertfile, "cacerts.pem"},
    -                                    {reuse_sessions, false},
    -                                    {server_name_indication, disable}]).
    -{ok,{sslsocket,{gen_tcp,#Port<0.14>,tls_connection, ...}}
    +                   8,34,180,...>>}]}

    Step 3 - Explicit Session Reuse

    %% Perform a full handshake and the session will not be saved for reuse
    +12> {ok, C9} =
    +ssl:connect("localhost", 9999, [{verify, verify_peer},
    +                                    {versions, ['tlsv1.2']},
    +                                    {cacertfile, "cacerts.pem"},
    +                                    {reuse_sessions, false},
    +                                    {server_name_indication, disable}]).
    +{ok,{sslsocket,{gen_tcp,#Port<0.14>,tls_connection, ...}}
     
     %% Fetch session ID and data for C9 connection
    -12> {ok, [{session_id, ID1}, {session_data, SessData}]} =
    -        ssl:connection_information(C9, [session_id, session_data]).
    -{ok,[{session_id,<<9,233,4,54,170,88,170,180,17,96,202,
    +12> {ok, [{session_id, ID1}, {session_data, SessData}]} =
    +        ssl:connection_information(C9, [session_id, session_data]).
    +{ok,[{session_id,<<9,233,4,54,170,88,170,180,17,96,202,
                        85,85,99,119,47,9,68,195,50,120,52,
    -                   130,239,...>>},
    -     {session_data,<<131,104,13,100,0,7,115,101,115,115,105,
    -                     111,110,109,0,0,0,32,9,233,4,54,170,...>>}]}
    +                   130,239,...>>},
    +     {session_data,<<131,104,13,100,0,7,115,101,115,115,105,
    +                     111,110,109,0,0,0,32,9,233,4,54,170,...>>}]}
     
     %% Explicitly reuse the session from C9
    -13> {ok, C10} = ssl:connect("localhost", 9999, [{verify, verify_peer},
    -                                    {versions, ['tlsv1.2']},
    -                                    {cacertfile, "cacerts.pem"},
    -                                    {reuse_session, {ID1, SessData}}]).
    -{ok,{sslsocket,{gen_tcp,#Port<0.15>,tls_connection,
    -                        undefined}, ...}}
    -
    -14> ssl:connection_information(C10, [session_id]).
    -{ok,[{session_id,<<9,233,4,54,170,88,170,180,17,96,202,
    +13> {ok, C10} = ssl:connect("localhost", 9999, [{verify, verify_peer},
    +                                    {versions, ['tlsv1.2']},
    +                                    {cacertfile, "cacerts.pem"},
    +                                    {reuse_session, {ID1, SessData}}]).
    +{ok,{sslsocket,{gen_tcp,#Port<0.15>,tls_connection,
    +                        undefined}, ...}}
    +
    +14> ssl:connection_information(C10, [session_id]).
    +{ok,[{session_id,<<9,233,4,54,170,88,170,180,17,96,202,
                        85,85,99,119,47,9,68,195,50,120,52,
    -                   130,239,...>>}]}

    Step 4 - Not Possible to Reuse Explicit Session by ID Only

    %% Try to reuse the session from C9 using only the id
    -15> {ok, E} =  ssl:connect("localhost", 9999, [{verify, verify_peer},
    -                                    {versions, ['tlsv1.2']},
    -                                    {cacertfile, "cacerts.pem"},
    -                                    {reuse_session, ID1}]).
    -{ok,{sslsocket,{gen_tcp,#Port<0.18>,tls_connection,
    -                        undefined}, ...}}
    +                   130,239,...>>}]}

    Step 4 - Not Possible to Reuse Explicit Session by ID Only

    %% Try to reuse the session from C9 using only the id
    +15> {ok, E} =  ssl:connect("localhost", 9999, [{verify, verify_peer},
    +                                    {versions, ['tlsv1.2']},
    +                                    {cacertfile, "cacerts.pem"},
    +                                    {reuse_session, ID1}]).
    +{ok,{sslsocket,{gen_tcp,#Port<0.18>,tls_connection,
    +                        undefined}, ...}}
     
     %% This will fail (as it is not saved for reuse)
     %% and a full handshake will be performed, we get a new id.
    -16>  ssl:connection_information(E, [session_id]).
    -{ok,[{session_id,<<87,46,43,126,175,68,160,153,37,29,
    +16>  ssl:connection_information(E, [session_id]).
    +{ok,[{session_id,<<87,46,43,126,175,68,160,153,37,29,
                        196,240,65,160,254,88,65,224,18,63,
    -                   18,17,174,39,...>>}]}

    On the server side the the {reuse_sessions, boolean()} option determines if + 18,17,174,39,...>>}]}

    On the server side the the {reuse_sessions, boolean()} option determines if the server will save session data and allow session reuse or not. This can be further customized by the option {reuse_session, fun()} that may introduce a local policy for session reuse.

    @@ -477,18 +477,18 @@

    Anti-Replay Protection in TLS 1.3

    Session tickets are sent by servers on newly established TLS connections. The number of tickets sent and their lifetime are configurable by application variables. See also SSL's configuration.

    Session tickets are protected by application traffic keys, and in stateless -tickets, the opaque data structure itself is self-encrypted.

    An example with automatic and manual session resumption:

          {ok, _} = application:ensure_all_started(ssl).
    -      LOpts = [{certs_keys, [#{certfile => "cert.pem",
    -                               keyfile => "key.pem"}]},
    -               {versions, ['tlsv1.2','tlsv1.3']},
    -               {session_tickets, stateless}].
    -      {ok, LSock} = ssl:listen(8001, LOpts).
    -      {ok, ASock} = ssl:transport_accept(LSock).

    Step 2 (client): Start the client and connect to server:

          {ok, _} = application:ensure_all_started(ssl).
    -      COpts = [{cacertfile, "cert.pem"},
    -               {versions, ['tlsv1.2','tlsv1.3']},
    -               {log_level, debug},
    -               {session_tickets, auto}].
    -      ssl:connect("localhost", 8001, COpts).

    Step 3 (server): Start the TLS handshake:

          {ok, CSocket} = ssl:handshake(ASock).

    A connection is established using a full handshake. Below is a summary of the +tickets, the opaque data structure itself is self-encrypted.

    An example with automatic and manual session resumption:

          {ok, _} = application:ensure_all_started(ssl).
    +      LOpts = [{certs_keys, [#{certfile => "cert.pem",
    +                               keyfile => "key.pem"}]},
    +               {versions, ['tlsv1.2','tlsv1.3']},
    +               {session_tickets, stateless}].
    +      {ok, LSock} = ssl:listen(8001, LOpts).
    +      {ok, ASock} = ssl:transport_accept(LSock).

    Step 2 (client): Start the client and connect to server:

          {ok, _} = application:ensure_all_started(ssl).
    +      COpts = [{cacertfile, "cert.pem"},
    +               {versions, ['tlsv1.2','tlsv1.3']},
    +               {log_level, debug},
    +               {session_tickets, auto}].
    +      ssl:connect("localhost", 8001, COpts).

    Step 3 (server): Start the TLS handshake:

          {ok, CSocket} = ssl:handshake(ASock).

    A connection is established using a full handshake. Below is a summary of the exchanged messages:

          >>> TLS 1.3 Handshake, ClientHello ...
           <<< TLS 1.3 Handshake, ServerHello ...
           <<< Handshake, EncryptedExtensions ...
    @@ -497,27 +497,27 @@ 

    <<< Handshake, Finished ... >>> Handshake, Finished ... <<< Post-Handshake, NewSessionTicket ...

    At this point the client has stored the received session tickets and ready to -use them when establishing new connections to the same server.

    Step 4 (server): Accept a new connection on the server:

          {ok, ASock2} = ssl:transport_accept(LSock).

    Step 5 (client): Make a new connection:

          ssl:connect("localhost", 8001, COpts).

    Step 6 (server): Start the handshake:

          {ok, CSock2} =ssl:handshake(ASock2).

    The second connection is a session resumption using keying material from the +use them when establishing new connections to the same server.

    Step 4 (server): Accept a new connection on the server:

          {ok, ASock2} = ssl:transport_accept(LSock).

    Step 5 (client): Make a new connection:

          ssl:connect("localhost", 8001, COpts).

    Step 6 (server): Start the handshake:

          {ok, CSock2} =ssl:handshake(ASock2).

    The second connection is a session resumption using keying material from the previous handshake:

          >>> TLS 1.3 Handshake, ClientHello ...
           <<< TLS 1.3 Handshake, ServerHello ...
           <<< Handshake, EncryptedExtensions ...
           <<< Handshake, Finished ...
           >>> Handshake, Finished ...
           <<< Post-Handshake, NewSessionTicket ...

    Manual handling of session tickets is also supported. In manual mode, it is the -responsibility of the client to handle received session tickets.

    Step 7 (server): Accept a new connection on the server:

          {ok, ASock3} = ssl:transport_accept(LSock).

    Step 8 (client): Make a new connection to server:

          {ok, _} = application:ensure_all_started(ssl).
    -      COpts2 = [{cacertfile, "cacerts.pem"},
    -                {versions, ['tlsv1.2','tlsv1.3']},
    -                {log_level, debug},
    -                {session_tickets, manual}].
    -      ssl:connect("localhost", 8001, COpts).

    Step 9 (server): Start the handshake:

          {ok, CSock3} = ssl:handshake(ASock3).

    After the handshake is performed, the user process receivess messages with the -tickets sent by the server.

    Step 10 (client): Receive a new session ticket:

          Ticket = receive {ssl, session_ticket, {_, TicketData}} -> TicketData end.

    Step 11 (server): Accept a new connection on the server:

          {ok, ASock4} = ssl:transport_accept(LSock).

    Step 12 (client): Initiate a new connection to the server with the session -ticket received in Step 10:

          {ok, _} = application:ensure_all_started(ssl).
    -      COpts2 = [{cacertfile, "cert.pem"},
    -                {versions, ['tlsv1.2','tlsv1.3']},
    -                {log_level, debug},
    -                {session_tickets, manual},
    -                {use_ticket, [Ticket]}].
    -      ssl:connect("localhost", 8001, COpts).

    Step 13 (server): Start the handshake:

          {ok, CSock4} = ssl:handshake(ASock4).

    +responsibility of the client to handle received session tickets.

    Step 7 (server): Accept a new connection on the server:

          {ok, ASock3} = ssl:transport_accept(LSock).

    Step 8 (client): Make a new connection to server:

          {ok, _} = application:ensure_all_started(ssl).
    +      COpts2 = [{cacertfile, "cacerts.pem"},
    +                {versions, ['tlsv1.2','tlsv1.3']},
    +                {log_level, debug},
    +                {session_tickets, manual}].
    +      ssl:connect("localhost", 8001, COpts).

    Step 9 (server): Start the handshake:

          {ok, CSock3} = ssl:handshake(ASock3).

    After the handshake is performed, the user process receivess messages with the +tickets sent by the server.

    Step 10 (client): Receive a new session ticket:

          Ticket = receive {ssl, session_ticket, {_, TicketData}} -> TicketData end.

    Step 11 (server): Accept a new connection on the server:

          {ok, ASock4} = ssl:transport_accept(LSock).

    Step 12 (client): Initiate a new connection to the server with the session +ticket received in Step 10:

          {ok, _} = application:ensure_all_started(ssl).
    +      COpts2 = [{cacertfile, "cert.pem"},
    +                {versions, ['tlsv1.2','tlsv1.3']},
    +                {log_level, debug},
    +                {session_tickets, manual},
    +                {use_ticket, [Ticket]}].
    +      ssl:connect("localhost", 8001, COpts).

    Step 13 (server): Start the handshake:

          {ok, CSock4} = ssl:handshake(ASock4).

    @@ -536,76 +536,76 @@

    operations, such as HEAD and GET, can usually be regarded as safe but even they can be exploited by a large number of replays causing resource limit exhaustion and other similar problems.

    An example of sending early data with automatic and manual session ticket -handling:

    Server

    early_data_server() ->
    -    application:load(ssl),
    -    {ok, _} = application:ensure_all_started(ssl),
    +handling:

    Server

    early_data_server() ->
    +    application:load(ssl),
    +    {ok, _} = application:ensure_all_started(ssl),
         Port = 11029,
    -    LOpts = [{certs_keys, [#{certfile => "cert.pem", keyfile => "key.pem"}]},
    -             {reuseaddr, true},
    -             {versions, ['tlsv1.2','tlsv1.3']},
    -             {session_tickets, stateless},
    -             {early_data, enabled},
    -            ],
    -    {ok, LSock} = ssl:listen(Port, LOpts),
    +    LOpts = [{certs_keys, [#{certfile => "cert.pem", keyfile => "key.pem"}]},
    +             {reuseaddr, true},
    +             {versions, ['tlsv1.2','tlsv1.3']},
    +             {session_tickets, stateless},
    +             {early_data, enabled},
    +            ],
    +    {ok, LSock} = ssl:listen(Port, LOpts),
         %% Accept first connection
    -    {ok, ASock0} = ssl:transport_accept(LSock),
    -    {ok, CSock0} = ssl:handshake(ASock0),
    +    {ok, ASock0} = ssl:transport_accept(LSock),
    +    {ok, CSock0} = ssl:handshake(ASock0),
         %% Accept second connection
    -    {ok, ASock1} = ssl:transport_accept(LSock),
    -    {ok, CSock1} = ssl:handshake(ASock1),
    -    Sock.

    Client (automatic ticket handling):

    early_data_auto() ->
    +    {ok, ASock1} = ssl:transport_accept(LSock),
    +    {ok, CSock1} = ssl:handshake(ASock1),
    +    Sock.

    Client (automatic ticket handling):

    early_data_auto() ->
         %% First handshake 1-RTT - get session tickets
    -    application:load(ssl),
    -    {ok, _} = application:ensure_all_started(ssl),
    +    application:load(ssl),
    +    {ok, _} = application:ensure_all_started(ssl),
         Port = 11029,
         Data = <<"HEAD / HTTP/1.1\r\nHost: \r\nConnection: close\r\n">>,
    -    COpts0 = [{cacertfile, "cacerts.pem"},
    -              {versions, ['tlsv1.2', 'tlsv1.3']},
    -              {session_tickets, auto}],
    -    {ok, Sock0} = ssl:connect("localhost", Port, COpts0),
    +    COpts0 = [{cacertfile, "cacerts.pem"},
    +              {versions, ['tlsv1.2', 'tlsv1.3']},
    +              {session_tickets, auto}],
    +    {ok, Sock0} = ssl:connect("localhost", Port, COpts0),
     
         %% Wait for session tickets
    -    timer:sleep(500),
    +    timer:sleep(500),
         %% Close socket if server cannot handle multiple
         %% connections e.g. openssl s_server
    -    ssl:close(Sock0),
    +    ssl:close(Sock0),
     
         %% Second handshake 0-RTT
    -    COpts1 = [{cacertfile,  "cacerts.pem"},
    -              {versions, ['tlsv1.2', 'tlsv1.3']},
    -              {session_tickets, auto},
    -              {early_data, Data}],
    -    {ok, Sock} = ssl:connect("localhost", Port, COpts1),
    +    COpts1 = [{cacertfile,  "cacerts.pem"},
    +              {versions, ['tlsv1.2', 'tlsv1.3']},
    +              {session_tickets, auto},
    +              {early_data, Data}],
    +    {ok, Sock} = ssl:connect("localhost", Port, COpts1),
         Sock.
    -

    Client (manual ticket handling):

    early_data_manual() ->
    +

    Client (manual ticket handling):

    early_data_manual() ->
         %% First handshake 1-RTT - get session tickets
    -    application:load(ssl),
    -    {ok, _} = application:ensure_all_started(ssl),
    +    application:load(ssl),
    +    {ok, _} = application:ensure_all_started(ssl),
         Port = 11029,
         Data = <<"HEAD / HTTP/1.1\r\nHost: \r\nConnection: close\r\n">>,
    -    COpts0 = [{cacertfile, "cacerts.pem"},
    -              {versions, ['tlsv1.2', 'tlsv1.3']},
    -              {session_tickets, manual}],
    -    {ok, Sock0} = ssl:connect("localhost", Port, COpts0),
    +    COpts0 = [{cacertfile, "cacerts.pem"},
    +              {versions, ['tlsv1.2', 'tlsv1.3']},
    +              {session_tickets, manual}],
    +    {ok, Sock0} = ssl:connect("localhost", Port, COpts0),
     
         %% Wait for session tickets
         Ticket =
             receive
    -            {ssl, session_ticket, Ticket0} ->
    +            {ssl, session_ticket, Ticket0} ->
                     Ticket0
             end,
     
         %% Close socket if server cannot handle multiple connections
         %% e.g. openssl s_server
    -    ssl:close(Sock0),
    +    ssl:close(Sock0),
     
         %% Second handshake 0-RTT
    -    COpts1 = [{cacertfile, "cacerts.pem"},
    -              {versions, ['tlsv1.2', 'tlsv1.3']},
    -              {session_tickets, manual},
    -              {use_ticket, [Ticket]},
    -              {early_data, Data}],
    -    {ok, Sock} = ssl:connect("localhost", Port, COpts1),
    +    COpts1 = [{cacertfile, "cacerts.pem"},
    +              {versions, ['tlsv1.2', 'tlsv1.3']},
    +              {session_tickets, manual},
    +              {use_ticket, [Ticket]},
    +              {early_data, Data}],
    +    {ok, Sock} = ssl:connect("localhost", Port, COpts1),
         Sock.

    @@ -650,11 +650,11 @@

    Using DTLS

    Using DTLS has basically the same API as TLS. You need to add the option -{protocol, dtls} to the connect and listen functions. For example

     client>{ok, Socket} = ssl:connect("localhost", 9999, [{protocol, dtls},
    -                                               {verify, verify_peer},
    -                                               {cacertfile, "cacerts.pem"}],
    -                           infinity).
    -{ok,{sslsocket, [...]}}
    +{protocol, dtls} to the connect and listen functions. For example

     client>{ok, Socket} = ssl:connect("localhost", 9999, [{protocol, dtls},
    +                                               {verify, verify_peer},
    +                                               {cacertfile, "cacerts.pem"}],
    +                           infinity).
    +{ok,{sslsocket, [...]}}
     
    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/argparse.html b/prs/8803/lib/stdlib-6.0.1/doc/html/argparse.html index e8bc3670a6a88..453cb551726cd 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/argparse.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/argparse.html @@ -147,20 +147,20 @@

    example below is a fully functioning Erlang program accepting two command line arguments and printing their product.

    #!/usr/bin/env escript
     
    -main(Args) ->
    -    argparse:run(Args, cli(), #{progname => mul}).
    -
    -cli() ->
    -    #{
    -        arguments => [
    -            #{name => left, type => integer},
    -            #{name => right, type => integer}
    -        ],
    +main(Args) ->
    +    argparse:run(Args, cli(), #{progname => mul}).
    +
    +cli() ->
    +    #{
    +        arguments => [
    +            #{name => left, type => integer},
    +            #{name => right, type => integer}
    +        ],
             handler =>
    -            fun (#{left := Left, right := Right}) ->
    -                io:format("~b~n", [Left * Right])
    +            fun (#{left := Left, right := Right}) ->
    +                io:format("~b~n", [Left * Right])
                 end
    -    }.

    Running this script with no arguments results in an error, accompanied by the + }.

    Running this script with no arguments results in an error, accompanied by the usage information.

    The cli function defines a single command with embedded handler accepting a map. Keys of the map are argument names as defined by the argument field of the command, left and right in the example. Values are taken from the @@ -174,25 +174,25 @@

    A command may contain nested commands, forming a hierarchy. Arguments defined at the upper level command are automatically added to all nested commands. Nested -commands example (assuming progname is nested):

    cli() ->
    -  #{
    +commands example (assuming progname is nested):

    cli() ->
    +  #{
         %% top level argument applicable to all commands
    -    arguments => [#{name => top}],
    -      commands => #{
    -        "first" => #{
    +    arguments => [#{name => top}],
    +      commands => #{
    +        "first" => #{
               %% argument applicable to "first" command and
               %%  all commands nested into "first"
    -          arguments => [#{name => mid}],
    -          commands => #{
    -            "second" => #{
    +          arguments => [#{name => mid}],
    +          commands => #{
    +            "second" => #{
                   %% argument only applicable for "second" command
    -              arguments => [#{name => bottom}],
    -              handler => fun (A) -> io:format("~p~n", [A]) end
    -          }
    -        }
    -      }
    -    }
    -  }.

    In the example above, a 3-level hierarchy is defined. First is the script itself + arguments => [#{name => bottom}], + handler => fun (A) -> io:format("~p~n", [A]) end + } + } + } + } + }.

    In the example above, a 3-level hierarchy is defined. First is the script itself (nested), accepting the only argument top. Since it has no associated handler, run/3 will not accept user input omitting nested command selection. For this example, user has to supply 5 arguments in the command line, two being @@ -210,14 +210,14 @@

    on all operating systems). Both options and positional arguments have 1 or more associated values. See argument specification to find more details about supported combinations.

    In the user input, short options may be concatenated with their values. Long -options support values separated by =. Consider this definition:

    cli() ->
    -  #{
    -    arguments => [
    -      #{name => long, long => "-long"},
    -      #{name => short, short => $s}
    -    ],
    -    handler => fun (Args) -> io:format("~p~n", [Args]) end
    -  }.

    Running ./args --long=VALUE prints #{long => "VALUE"}, running +options support values separated by =. Consider this definition:

    cli() ->
    +  #{
    +    arguments => [
    +      #{name => long, long => "-long"},
    +      #{name => short, short => $s}
    +    ],
    +    handler => fun (Args) -> io:format("~p~n", [Args]) end
    +  }.

    Running ./args --long=VALUE prints #{long => "VALUE"}, running ./args -sVALUE prints #{short => "VALUE"}

    argparse supports boolean flags concatenation: it is possible to shorten -r -f -v to -rfv.

    Shortened option names are not supported: it is not possible to use --my-argum instead of --my-argument-name even when such option can be unambiguously @@ -608,111 +608,111 @@

    argument()

    which case resulting argument map will either contain the default value, or not have the key at all.

    • name - Sets the argument name in the parsed argument map. If help is not defined, name is also used to generate the default usage message.

    • short - Defines a short (single character) form of an optional argument.

      %% Define a command accepting argument named myarg, with short form $a:
      -1> Cmd = #{arguments => [#{name => myarg, short => $a}]}.
      +1> Cmd = #{arguments => [#{name => myarg, short => $a}]}.
       %% Parse command line "-a str":
      -2> {ok, ArgMap, _, _} = argparse:parse(["-a", "str"], Cmd), ArgMap.
      +2> {ok, ArgMap, _, _} = argparse:parse(["-a", "str"], Cmd), ArgMap.
       
      -#{myarg => "str"}
      +#{myarg => "str"}
       
       %% Option value can be concatenated with the switch: "-astr"
      -3> {ok, ArgMap, _, _} = argparse:parse(["-astr"], Cmd), ArgMap.
      +3> {ok, ArgMap, _, _} = argparse:parse(["-astr"], Cmd), ArgMap.
       
      -#{myarg => "str"}

      By default all options expect a single value following the option switch. The -only exception is an option of a boolean type.

    • long - Defines a long form of an optional argument.

      1> Cmd = #{arguments => [#{name => myarg, long => "name"}]}.
      +#{myarg => "str"}

      By default all options expect a single value following the option switch. The +only exception is an option of a boolean type.

    • long - Defines a long form of an optional argument.

      1> Cmd = #{arguments => [#{name => myarg, long => "name"}]}.
       %% Parse command line "-name Erlang":
      -2> {ok, ArgMap, _, _} = argparse:parse(["-name", "Erlang"], Cmd), ArgMap.
      +2> {ok, ArgMap, _, _} = argparse:parse(["-name", "Erlang"], Cmd), ArgMap.
       
      -#{myarg => "Erlang"}
      +#{myarg => "Erlang"}
       %% Or use "=" to separate the switch and the value:
      -3> {ok, ArgMap, _, _} = argparse:parse(["-name=Erlang"], Cmd), ArgMap.
      +3> {ok, ArgMap, _, _} = argparse:parse(["-name=Erlang"], Cmd), ArgMap.
       
      -#{myarg => "Erlang"}

      If neither short not long is defined, the argument is treated as +#{myarg => "Erlang"}

    If neither short not long is defined, the argument is treated as positional.

  • required - Forces the parser to expect the argument to be present in the command line. By default, all positional argument are required, and all options are not.

  • default - Specifies the default value to put in the parsed argument map -if the value is not supplied in the command line.

    1> argparse:parse([], #{arguments => [#{name => myarg, short => $m}]}).
    +if the value is not supplied in the command line.

    1> argparse:parse([], #{arguments => [#{name => myarg, short => $m}]}).
     
    -{ok,#{}, ...
    -2> argparse:parse([], #{arguments => [#{name => myarg, short => $m, default => "def"}]}).
    +{ok,#{}, ...
    +2> argparse:parse([], #{arguments => [#{name => myarg, short => $m, default => "def"}]}).
     
    -{ok,#{myarg => "def"}, ...
  • type - Defines type conversion and validation routine. The default is +{ok,#{myarg => "def"}, ...

  • type - Defines type conversion and validation routine. The default is string, assuming no conversion.

  • nargs - Defines the number of following arguments to consume from the command line. By default, the parser consumes the next argument and converts it into an Erlang term according to the specified type.

    • pos_integer/0 - Consume exactly this number of positional arguments, fail if there is not enough. Value in the argument map contains a list of exactly this length. Example, defining a positional argument expecting 3 -integer values:

      1> Cmd = #{arguments => [#{name => ints, type => integer, nargs => 3}]},
      -argparse:parse(["1", "2", "3"], Cmd).
      +integer values:

      1> Cmd = #{arguments => [#{name => ints, type => integer, nargs => 3}]},
      +argparse:parse(["1", "2", "3"], Cmd).
       
      -{ok, #{ints => [1, 2, 3]}, ...

      Another example defining an option accepted as -env and expecting two -string arguments:

      1> Cmd = #{arguments => [#{name => env, long => "env", nargs => 2}]},
      -argparse:parse(["-env", "key", "value"], Cmd).
      +{ok, #{ints => [1, 2, 3]}, ...

      Another example defining an option accepted as -env and expecting two +string arguments:

      1> Cmd = #{arguments => [#{name => env, long => "env", nargs => 2}]},
      +argparse:parse(["-env", "key", "value"], Cmd).
       
      -{ok, #{env => ["key", "value"]}, ...
    • list - Consume all following arguments until hitting the next option +{ok, #{env => ["key", "value"]}, ...

  • list - Consume all following arguments until hitting the next option (starting with an option prefix). May result in an empty list added to the -arguments map.

    1> Cmd = #{arguments => [
    -  #{name => nodes, long => "nodes", nargs => list},
    -  #{name => verbose, short => $v, type => boolean}
    -]},
    -argparse:parse(["-nodes", "one", "two", "-v"], Cmd).
    +arguments map.

    1> Cmd = #{arguments => [
    +  #{name => nodes, long => "nodes", nargs => list},
    +  #{name => verbose, short => $v, type => boolean}
    +]},
    +argparse:parse(["-nodes", "one", "two", "-v"], Cmd).
     
    -{ok, #{nodes => ["one", "two"], verbose => true}, ...
  • nonempty_list - Same as list, but expects at least one argument. +{ok, #{nodes => ["one", "two"], verbose => true}, ...

  • nonempty_list - Same as list, but expects at least one argument. Returns an error if the following command line argument is an option switch (starting with the prefix).

  • 'maybe' - Consumes the next argument from the command line, if it does not start with an option prefix. Otherwise, adds a default value to the -arguments map.

    1> Cmd = #{arguments => [
    -  #{name => level, short => $l, nargs => 'maybe', default => "error"},
    -  #{name => verbose, short => $v, type => boolean}
    -]},
    -argparse:parse(["-l", "info", "-v"], Cmd).
    +arguments map.

    1> Cmd = #{arguments => [
    +  #{name => level, short => $l, nargs => 'maybe', default => "error"},
    +  #{name => verbose, short => $v, type => boolean}
    +]},
    +argparse:parse(["-l", "info", "-v"], Cmd).
     
    -{ok,#{level => "info",verbose => true}, ...
    +{ok,#{level => "info",verbose => true}, ...
     
     %% When "info" is omitted, argument maps receives the default "error"
    -2> argparse:parse(["-l", "-v"], Cmd).
    +2> argparse:parse(["-l", "-v"], Cmd).
     
    -{ok,#{level => "error",verbose => true}, ...
  • {'maybe', term()} - Consumes the next argument from the command line, +{ok,#{level => "error",verbose => true}, ...

  • {'maybe', term()} - Consumes the next argument from the command line, if it does not start with an option prefix. Otherwise, adds a specified Erlang term to the arguments map.

  • all - Fold all remaining command line arguments into a list, ignoring any option prefixes or switches. Useful for proxying arguments into another -command line utility.

    1> Cmd = #{arguments => [
    -    #{name => verbose, short => $v, type => boolean},
    -    #{name => raw, long => "-", nargs => all}
    -]},
    -argparse:parse(["-v", "--", "-kernel", "arg", "opt"], Cmd).
    +command line utility.

    1> Cmd = #{arguments => [
    +    #{name => verbose, short => $v, type => boolean},
    +    #{name => raw, long => "-", nargs => all}
    +]},
    +argparse:parse(["-v", "--", "-kernel", "arg", "opt"], Cmd).
     
    -{ok,#{raw => ["-kernel","arg","opt"],verbose => true}, ...
  • action - Defines an action to take when the argument is found in the +{ok,#{raw => ["-kernel","arg","opt"],verbose => true}, ...

  • action - Defines an action to take when the argument is found in the command line. The default action is store.

    • store - Store the value in the arguments map. Overwrites the value -previously written.

      1> Cmd = #{arguments => [#{name => str, short => $s}]},
      -argparse:parse(["-s", "one", "-s", "two"], Cmd).
      +previously written.

      1> Cmd = #{arguments => [#{name => str, short => $s}]},
      +argparse:parse(["-s", "one", "-s", "two"], Cmd).
       
      -{ok, #{str => "two"}, ...
    • {store, term()} - Stores the specified term instead of reading the -value from the command line.

      1> Cmd = #{arguments => [#{name => str, short => $s, action => {store, "two"}}]},
      -argparse:parse(["-s"], Cmd).
      +{ok, #{str => "two"}, ...
    • {store, term()} - Stores the specified term instead of reading the +value from the command line.

      1> Cmd = #{arguments => [#{name => str, short => $s, action => {store, "two"}}]},
      +argparse:parse(["-s"], Cmd).
       
      -{ok, #{str => "two"}, ...
    • append - Appends the repeating occurrences of the argument instead of -overwriting.

      1> Cmd = #{arguments => [#{name => node, short => $n, action => append}]},
      -argparse:parse(["-n", "one", "-n", "two", "-n", "three"], Cmd).
      +{ok, #{str => "two"}, ...
    • append - Appends the repeating occurrences of the argument instead of +overwriting.

      1> Cmd = #{arguments => [#{name => node, short => $n, action => append}]},
      +argparse:parse(["-n", "one", "-n", "two", "-n", "three"], Cmd).
       
      -{ok, #{node => ["one", "two", "three"]}, ...
      +{ok, #{node => ["one", "two", "three"]}, ...
       
       %% Always produces a list - even if there is one occurrence
      -2> argparse:parse(["-n", "one"], Cmd).
      +2> argparse:parse(["-n", "one"], Cmd).
       
      -{ok, #{node => ["one"]}, ...
    • {append, term()} - Same as append, but instead of consuming the +{ok, #{node => ["one"]}, ...

  • {append, term()} - Same as append, but instead of consuming the argument from the command line, appends a provided term/0.

  • count - Puts a counter as a value in the arguments map. Useful for -implementing verbosity option:

    1> Cmd = #{arguments => [#{name => verbose, short => $v, action => count}]},
    -argparse:parse(["-v"], Cmd).
    +implementing verbosity option:

    1> Cmd = #{arguments => [#{name => verbose, short => $v, action => count}]},
    +argparse:parse(["-v"], Cmd).
     
    -{ok, #{verbose => 1}, ...
    +{ok, #{verbose => 1}, ...
     
    -2> argparse:parse(["-vvvv"], Cmd).
    +2> argparse:parse(["-vvvv"], Cmd).
     
    -{ok, #{verbose => 4}, ...
  • extend - Works as append, but flattens the resulting list. Valid -only for nargs set to list, nonempty_list, all or pos_integer/0.

    1> Cmd = #{arguments => [#{name => duet, short => $d, nargs => 2, action => extend}]},
    -argparse:parse(["-d", "a", "b", "-d", "c", "d"], Cmd).
    +{ok, #{verbose => 4}, ...
  • extend - Works as append, but flattens the resulting list. Valid +only for nargs set to list, nonempty_list, all or pos_integer/0.

    1> Cmd = #{arguments => [#{name => duet, short => $d, nargs => 2, action => extend}]},
    +argparse:parse(["-d", "a", "b", "-d", "c", "d"], Cmd).
     
    -{ok, #{duet => ["a", "b", "c", "d"]}, ...
    +{ok, #{duet => ["a", "b", "c", "d"]}, ...
     
     %% 'append' would result in {ok, #{duet => [["a", "b"],["c", "d"]]},
  • help - Specifies help/usage text for the argument. argparse provides automatic generation based on the argument name, type and default value, but @@ -929,16 +929,16 @@

    handler()

    exported from Module, accepting argument map.

  • {fun(() -> term()), Default :: term()} - Function accepting as many arguments as there are in the arguments list for this command. Arguments missing from the parsed map are replaced with the Default. Convenient way to -expose existing functions.

    1> Cmd = #{arguments => [
    -        #{name => x, type => float},
    -        #{name => y, type => float, short => $p}],
    -    handler => {fun math:pow/2, 1}},
    -argparse:run(["2", "-p", "3"], Cmd, #{}).
    +expose existing functions.

    1> Cmd = #{arguments => [
    +        #{name => x, type => float},
    +        #{name => y, type => float, short => $p}],
    +    handler => {fun math:pow/2, 1}},
    +argparse:run(["2", "-p", "3"], Cmd, #{}).
     
     8.0
     
     %% default term 1 is passed to math:pow/2
    -2> argparse:run(["2"], Cmd, #{}).
    +2> argparse:run(["2"], Cmd, #{}).
     
     2.0
  • {Module :: module(), Function :: atom(), Default :: term()} - Function named Function, exported from Module, accepting as many arguments as diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/array.html b/prs/8803/lib/stdlib-6.0.1/doc/html/array.html index 657298784a64e..79d2430d80dbd 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/array.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/array.html @@ -136,14 +136,14 @@

    reset/2). If you need to differentiate between unset and set entries, ensure that the default value cannot be confused with the values of set entries.

    The array never shrinks automatically. If an index I has been used to set an entry successfully, all indices in the range [0,I] stay accessible unless the -array size is explicitly changed by calling resize/2.

    Examples:

    Create a fixed-size array with entries 0-9 set to undefined:

    A0 = array:new(10).
    -10 = array:size(A0).

    Create an extendible array and set entry 17 to true, causing the array to grow -automatically:

    A1 = array:set(17, true, array:new()).
    -18 = array:size(A1).

    Read back a stored value:

    true = array:get(17, A1).

    Accessing an unset entry returns default value:

    undefined = array:get(3, A1)

    Accessing an entry beyond the last set entry also returns the default value, if -the array does not have fixed size:

    undefined = array:get(18, A1).

    "Sparse" functions ignore default-valued entries:

    A2 = array:set(4, false, A1).
    -[{4, false}, {17, true}] = array:sparse_to_orddict(A2).

    An extendible array can be made fixed-size later:

    A3 = array:fix(A2).

    A fixed-size array does not grow automatically and does not allow accesses -beyond the last set entry:

    {'EXIT',{badarg,_}} = (catch array:set(18, true, A3)).
    -{'EXIT',{badarg,_}} = (catch array:get(18, A3)).
    +array size is explicitly changed by calling resize/2.

    Examples:

    Create a fixed-size array with entries 0-9 set to undefined:

    A0 = array:new(10).
    +10 = array:size(A0).

    Create an extendible array and set entry 17 to true, causing the array to grow +automatically:

    A1 = array:set(17, true, array:new()).
    +18 = array:size(A1).

    Read back a stored value:

    true = array:get(17, A1).

    Accessing an unset entry returns default value:

    undefined = array:get(3, A1)

    Accessing an entry beyond the last set entry also returns the default value, if +the array does not have fixed size:

    undefined = array:get(18, A1).

    "Sparse" functions ignore default-valued entries:

    A2 = array:set(4, false, A1).
    +[{4, false}, {17, true}] = array:sparse_to_orddict(A2).

    An extendible array can be made fixed-size later:

    A3 = array:fix(A2).

    A fixed-size array does not grow automatically and does not allow accesses +beyond the last set entry:

    {'EXIT',{badarg,_}} = (catch array:set(18, true, A3)).
    +{'EXIT',{badarg,_}} = (catch array:get(18, A3)).
    @@ -1184,7 +1184,7 @@

    new(Options)

    array size; this also implies {fixed, true}. If N is not a non-negative integer, the call fails with reason badarg.

  • fixed or {fixed, true} - Creates a fixed-size array. See also fix/1.

  • {fixed, false} - Creates an extendible (non-fixed-size) array.

  • {default, Value} - Sets the default value for the array to Value.

  • Options are processed in the order they occur in the list, that is, later options have higher precedence.

    The default value is used as the value of uninitialized entries, and cannot be -changed once the array has been created.

    Examples:

    array:new(100)

    creates a fixed-size array of size 100.

    array:new({default,0})

    creates an empty, extendible array whose default value is 0.

    array:new([{size,10},{fixed,false},{default,-1}])

    creates an extendible array with initial size 10 whose default value is -1.

    See also fix/1, from_list/2, get/2, new/0, new/2, set/3.

    +changed once the array has been created.

    Examples:

    array:new(100)

    creates a fixed-size array of size 100.

    array:new({default,0})

    creates an empty, extendible array whose default value is 0.

    array:new([{size,10},{fixed,false},{default,-1}])

    creates an extendible array with initial size 10 whose default value is -1.

    See also fix/1, from_list/2, get/2, new/0, new/2, set/3.

    @@ -1217,7 +1217,7 @@

    new(Size, Options)

    Options override parameter Size.

    If Options is a list, this is equivalent to new([{size, Size} | Options]), otherwise it is equivalent to new([{size, Size} | [Options]]). However, using this function -directly is more efficient.

    Example:

    array:new(100, {default,0})

    creates a fixed-size array of size 100, whose default value is 0.

    See also new/1.

    +directly is more efficient.

    Example:

    array:new(100, {default,0})

    creates a fixed-size array of size 100, whose default value is 0.

    See also new/1.

    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/assert_hrl.html b/prs/8803/lib/stdlib-6.0.1/doc/html/assert_hrl.html index e3798287f1710..93012e2b48cb6 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/assert_hrl.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/assert_hrl.html @@ -132,7 +132,7 @@

    Description

    The include file assert.hrl provides macros for inserting assertions in your -program code.

    Include the following directive in the module from which the function is called:

    -include_lib("stdlib/include/assert.hrl").

    When an assertion succeeds, the assert macro yields the atom ok. When an +program code.

    Include the following directive in the module from which the function is called:

    -include_lib("stdlib/include/assert.hrl").

    When an assertion succeeds, the assert macro yields the atom ok. When an assertion fails, an exception of type error is generated. The associated error term has the form {Macro, Info}. Macro is the macro name, for example, assertEqual. Info is a list of tagged values, such as @@ -160,7 +160,7 @@

    • assert(BoolExpr)

    • assert(BoolExpr, Comment) - Tests that BoolExpr completes normally returning true.

    • assertNot(BoolExpr)

    • assertNot(BoolExpr, Comment) - Tests that BoolExpr completes normally returning false.

    • assertMatch(GuardedPattern, Expr)

    • assertMatch(GuardedPattern, Expr, Comment) - Tests that Expr completes -normally yielding a value that matches GuardedPattern, for example:

      ?assertMatch({bork, _}, f())

      Notice that a guard when ... can be included:

      ?assertMatch({bork, X} when X > 0, f())
    • assertNotMatch(GuardedPattern, Expr)

    • assertNotMatch(GuardedPattern, Expr, Comment) - Tests that Expr +normally yielding a value that matches GuardedPattern, for example:

      ?assertMatch({bork, _}, f())

      Notice that a guard when ... can be included:

      ?assertMatch({bork, X} when X > 0, f())
    • assertNotMatch(GuardedPattern, Expr)

    • assertNotMatch(GuardedPattern, Expr, Comment) - Tests that Expr completes normally yielding a value that does not match GuardedPattern.

      As in assertMatch, GuardedPattern can have a when part.

    • assertEqual(ExpectedValue, Expr)

    • assertEqual(ExpectedValue, Expr, Comment) - Tests that Expr completes normally yielding a value that is exactly equal to ExpectedValue.

    • assertNotEqual(ExpectedValue, Expr)

    • assertNotEqual(ExpectedValue, Expr, Comment) - Tests that Expr completes normally yielding a value that is not exactly equal to diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/base64.html b/prs/8803/lib/stdlib-6.0.1/doc/html/base64.html index cba2a1bec1a91..305bbe863a261 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/base64.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/base64.html @@ -671,15 +671,15 @@

      decode(Base64, Options)

      Decodes a base64 string encoded using the standard alphabet according to RFC 4648 Section 4 to plain ASCII.

      The function will strips away any whitespace characters and check for the -the correct number of = padding characters at the end of the encoded string.

      See decode_options/0 for details on which options can be passed.

      Example:

      1> base64:decode("AQIDBA==").
      +the correct number of = padding characters at the end of the encoded string.

      See decode_options/0 for details on which options can be passed.

      Example:

      1> base64:decode("AQIDBA==").
       <<1,2,3,4>>
      -2> base64:decode("AQ ID BA==").
      +2> base64:decode("AQ ID BA==").
       <<1,2,3,4>>
      -3> base64:decode("AQIDBA=").
      +3> base64:decode("AQIDBA=").
       ** exception error: missing_padding
            in function  base64:decode_list/7 (base64.erl, line 734)
               *** data to decode is missing final = padding characters, if this is intended, use the `padding => false` option
      -4> base64:decode("AQIDBA=", #{ padding => false }).
      +4> base64:decode("AQIDBA=", #{ padding => false }).
       <<1,2,3,4>>

    @@ -934,9 +934,9 @@

    mime_decode(Base64, Options)

    Decodes a base64 "mime" string encoded using the standard alphabet according to RFC 4648 Section 4 to plain ASCII.

    The function will strips away any illegal characters. It does not check for the -the correct number of = padding characters at the end of the encoded string.

    See decode_options/0 for details on which options can be passed.

    Example:

    1> base64:mime_decode("AQIDBA==").
    +the correct number of = padding characters at the end of the encoded string.

    See decode_options/0 for details on which options can be passed.

    Example:

    1> base64:mime_decode("AQIDBA==").
     <<1,2,3,4>>
    -2> base64:mime_decode("AQIDB=A=").
    +2> base64:mime_decode("AQIDB=A=").
     <<1,2,3,4>>
    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/beam_lib.html b/prs/8803/lib/stdlib-6.0.1/doc/html/beam_lib.html index 2459131514fdb..69752dc15aa60 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/beam_lib.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/beam_lib.html @@ -151,8 +151,8 @@

    Reconstruct Source Code

    The following example shows how to reconstruct Erlang source code from the debug -information in a BEAM file Beam:

    {ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(Beam,[abstract_code]).
    -io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).

    +information in a BEAM file Beam:

    {ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(Beam,[abstract_code]).
    +io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).

    @@ -182,13 +182,13 @@

    user's home directory and then filename:basedir(user_config, "erlang"). If the file is found and contains a key, beam_lib implicitly creates a crypto key fun -and registers it.

    File .erlang.crypt is to contain a single list of tuples:

    {debug_info, Mode, Module, Key}

    Mode is the type of crypto algorithm; currently, the only allowed value is +and registers it.

    File .erlang.crypt is to contain a single list of tuples:

    {debug_info, Mode, Module, Key}

    Mode is the type of crypto algorithm; currently, the only allowed value is des3_cbc. Module is either an atom, in which case Key is only used for the module Module, or [], in which case Key is used for all modules. Key is the non-empty key string.

    Key in the first tuple where both Mode and Module match is used.

    The following is an example of an .erlang.crypt file that returns the same key -for all modules:

    [{debug_info, des3_cbc, [], "%>7}|pc/DM6Cga*68$Mw]L#&_Gejr]G^"}].

    The following is a slightly more complicated example of an .erlang.crypt -providing one key for module t and another key for all other modules:

    [{debug_info, des3_cbc, t, "My KEY"},
    - {debug_info, des3_cbc, [], "%>7}|pc/DM6Cga*68$Mw]L#&_Gejr]G^"}].

    Note

    Do not use any of the keys in these examples. Use your own keys.

    +for all modules:

    [{debug_info, des3_cbc, [], "%>7}|pc/DM6Cga*68$Mw]L#&_Gejr]G^"}].

    The following is a slightly more complicated example of an .erlang.crypt +providing one key for module t and another key for all other modules:

    [{debug_info, des3_cbc, t, "My KEY"},
    + {debug_info, des3_cbc, [], "%>7}|pc/DM6Cga*68$Mw]L#&_Gejr]G^"}].

    Note

    Do not use any of the keys in these examples. Use your own keys.

    @@ -1556,11 +1556,11 @@

    crypto_key_fun(CryptoKeyFun)

    Registers an unary fun that is called if beam_lib must read an debug_info chunk that has been encrypted. The fun is held in a process that is started by the function.

    If a fun is already registered when attempting to register a fun, -{error, exists} is returned.

    The fun must handle the following arguments:

    CryptoKeyFun(init) -> ok | {ok, NewCryptoKeyFun} | {error, Term}

    Called when the fun is registered, in the process that holds the fun. Here the +{error, exists} is returned.

    The fun must handle the following arguments:

    CryptoKeyFun(init) -> ok | {ok, NewCryptoKeyFun} | {error, Term}

    Called when the fun is registered, in the process that holds the fun. Here the crypto key fun can do any necessary initializations. If {ok, NewCryptoKeyFun} is returned, NewCryptoKeyFun is registered instead of CryptoKeyFun. If {error, Term} is returned, the registration is aborted and -crypto_key_fun/1 also returns {error, Term}.

    CryptoKeyFun({debug_info, Mode, Module, Filename}) -> Key

    Called when the key is needed for module Module in the file named Filename. +crypto_key_fun/1 also returns {error, Term}.

    CryptoKeyFun({debug_info, Mode, Module, Filename}) -> Key

    Called when the key is needed for module Module in the file named Filename. Mode is the type of crypto algorithm; currently, the only possible value is des3_cbc. The call is to fail (raise an exception) if no key is available.

    CryptoKeyFun(clear) -> term()

    Called before the fun is unregistered. Here any cleaning up can be done. The return value is not important, but is passed back to the caller of @@ -1927,14 +1927,14 @@

    version(Beam)

    -vsn(Vsn).

    If this attribute is not specified, the version defaults to the checksum of the module. Notice that if version Vsn is not a list, it is made into one, that is {ok,{Module,[Vsn]}} is returned. If there are many -vsn -module attributes, the result is the concatenated list of versions.

    Examples:

    1> beam_lib:version(a). % -vsn(1).
    -{ok,{a,[1]}}
    -2> beam_lib:version(b). % -vsn([1]).
    -{ok,{b,[1]}}
    -3> beam_lib:version(c). % -vsn([1]). -vsn(2).
    -{ok,{c,[1,2]}}
    -4> beam_lib:version(d). % no -vsn attribute
    -{ok,{d,[275613208176997377698094100858909383631]}}
    +module attributes, the result is the concatenated list of versions.

    Examples:

    1> beam_lib:version(a). % -vsn(1).
    +{ok,{a,[1]}}
    +2> beam_lib:version(b). % -vsn([1]).
    +{ok,{b,[1]}}
    +3> beam_lib:version(c). % -vsn([1]). -vsn(2).
    +{ok,{c,[1,2]}}
    +4> beam_lib:version(d). % no -vsn attribute
    +{ok,{d,[275613208176997377698094100858909383631]}}
    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/binary.html b/prs/8803/lib/stdlib-6.0.1/doc/html/binary.html index ddcda2509139e..2131947c3440f 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/binary.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/binary.html @@ -643,7 +643,7 @@

    bin_to_list(Subject)

    -

    Converts Subject to a list of byte/0s, each representing the value of one byte.

    Example:

    1> binary:bin_to_list(<<"erlang">>).
    +

    Converts Subject to a list of byte/0s, each representing the value of one byte.

    Example:

    1> binary:bin_to_list(<<"erlang">>).
     "erlang"
     %% or [101,114,108,97,110,103] in list notation.
    @@ -709,7 +709,7 @@

    bin_to_list(Subject, Pos, Len)

    Converts Subject to a list of byte/0s, each representing the value of one byte. PosLen or alternatively Pos and Len denote which part of the Subject binary to convert. By default, the entire Subject binary is -converted.

    Example:

    1> binary:bin_to_list(<<"erlang">>, {1,3}).
    +converted.

    Example:

    1> binary:bin_to_list(<<"erlang">>, {1,3}).
     "rla"
     %% or [114,108,97] in list notation.

    If PosLen or alternatively Pos and Len in any way reference outside the binary, a badarg exception is raised.

    @@ -851,7 +851,7 @@

    decode_hex(Bin)

    -

    Decodes a hex encoded binary into a binary.

    Example

    1> binary:decode_hex(<<"66">>).
    +

    Decodes a hex encoded binary into a binary.

    Example

    1> binary:decode_hex(<<"66">>).
     <<"f">>
    @@ -917,11 +917,11 @@

    decode_unsigned(Subject, Endianness)

    Converts the binary digit representation, in big endian or little endian, of a -positive integer in Subject to an Erlang integer/0.

    Example:

    1> binary:decode_unsigned(<<169,138,199>>).
    +positive integer in Subject to an Erlang integer/0.

    Example:

    1> binary:decode_unsigned(<<169,138,199>>).
     11111111
    -2> binary:decode_unsigned(<<169,138,199>>, big).
    +2> binary:decode_unsigned(<<169,138,199>>, big).
     11111111
    -3> binary:decode_unsigned(<<169,138,199>>, little).
    +3> binary:decode_unsigned(<<169,138,199>>, little).
     13077161
    @@ -984,13 +984,13 @@

    encode_hex(Bin, Case)

    Encodes a binary into a hex encoded binary using the specified case for the -hexadecimal digits "a" to "f".

    The default case is uppercase.

    Example:

    1> binary:encode_hex(<<"f">>).
    +hexadecimal digits "a" to "f".

    The default case is uppercase.

    Example:

    1> binary:encode_hex(<<"f">>).
     <<"66">>
    -2> binary:encode_hex(<<"/">>).
    +2> binary:encode_hex(<<"/">>).
     <<"2F">>
    -3> binary:encode_hex(<<"/">>, lowercase).
    +3> binary:encode_hex(<<"/">>, lowercase).
     <<"2f">>
    -4> binary:encode_hex(<<"/">>, uppercase).
    +4> binary:encode_hex(<<"/">>, uppercase).
     <<"2F">>
    @@ -1053,11 +1053,11 @@

    encode_unsigned(Unsigned, Endianness)

    Converts a positive integer to the smallest possible representation in a binary -digit representation, either big endian or little endian.

    Example:

    1> binary:encode_unsigned(11111111).
    +digit representation, either big endian or little endian.

    Example:

    1> binary:encode_unsigned(11111111).
     <<169,138,199>>
    -2> binary:encode_unsigned(11111111, big).
    +2> binary:encode_unsigned(11111111, big).
     <<169,138,199>>
    -2> binary:encode_unsigned(11111111, little).
    +2> binary:encode_unsigned(11111111, little).
     <<199,138,169>>
    @@ -1181,9 +1181,9 @@

    longest_common_prefix(Binaries)

    Returns the length of the longest common prefix of the binaries in list -Binaries.

    Example:

    1> binary:longest_common_prefix([<<"erlang">>, <<"ergonomy">>]).
    +Binaries.

    Example:

    1> binary:longest_common_prefix([<<"erlang">>, <<"ergonomy">>]).
     2
    -2> binary:longest_common_prefix([<<"erlang">>, <<"perl">>]).
    +2> binary:longest_common_prefix([<<"erlang">>, <<"perl">>]).
     0

    If Binaries is not a flat non-empty list of binaries, a badarg exception is raised.

    @@ -1216,9 +1216,9 @@

    longest_common_suffix(Binaries)

    Returns the length of the longest common suffix of the binaries in list -Binaries.

    Example:

    1> binary:longest_common_suffix([<<"erlang">>, <<"fang">>]).
    +Binaries.

    Example:

    1> binary:longest_common_suffix([<<"erlang">>, <<"fang">>]).
     3
    -2> binary:longest_common_suffix([<<"erlang">>, <<"perl">>]).
    +2> binary:longest_common_suffix([<<"erlang">>, <<"perl">>]).
     0

    If Binaries is not a flat non-empty list of binaries, a badarg exception is raised.

    @@ -1294,8 +1294,8 @@

    match(Subject, Pattern, Options)

    Searches for the first occurrence of Pattern in Subject and returns the position and length.

    The function returns {Pos, Length} for the binary in Pattern, starting at -the lowest position in Subject.

    Example:

    1> binary:match(<<"abcde">>, [<<"bcde">>, <<"cd">>],[]).
    -{1,4}

    Even though <<"cd">> ends before <<"bcde">>, <<"bcde">> begins first and +the lowest position in Subject.

    Example:

    1> binary:match(<<"abcde">>, [<<"bcde">>, <<"cd">>],[]).
    +{1,4}

    Even though <<"cd">> ends before <<"bcde">>, <<"bcde">> begins first and is therefore the first match. If two overlapping matches begin at the same position, the longest is returned.

    Summary of the options:

    • {scope, {Start, Length}} - Only the specified part is searched. Return values still have offsets from the beginning of Subject. A negative Length @@ -1375,9 +1375,9 @@

      matches(Subject, Pattern, Options)

      As match/2, but Subject is searched until exhausted and a list of all non-overlapping parts matching Pattern is returned (in order).

      The first and longest match is preferred to a shorter, which is illustrated by -the following example:

      1> binary:matches(<<"abcde">>,
      -                  [<<"bcde">>,<<"bc">>,<<"de">>],[]).
      -[{1,4}]

      The result shows that <<"bcde">> is selected instead of the shorter match +the following example:

      1> binary:matches(<<"abcde">>,
      +                  [<<"bcde">>,<<"bc">>,<<"de">>],[]).
      +[{1,4}]

      The result shows that <<"bcde">> is selected instead of the shorter match <<"bc">> (which would have given raise to one more match, <<"de">>). This corresponds to the behavior of POSIX regular expressions (and programs like awk), but is not consistent with alternative matches in re (and Perl), where @@ -1446,7 +1446,7 @@

      part(Subject, Pos, Len)

      Extracts the part of binary Subject described by PosLen.

      A negative length can be used to extract bytes at the end of a binary:

      1> Bin = <<1,2,3,4,5,6,7,8,9,10>>.
      -2> binary:part(Bin, {byte_size(Bin), -5}).
      +2> binary:part(Bin, {byte_size(Bin), -5}).
       <<6,7,8,9,10>>

      Note

      part/2 and part/3 are also available in the erlang module under the names binary_part/2 and binary_part/3. Those BIFs are allowed in guard tests.

      If PosLen in any way references outside the binary, a badarg exception is @@ -1484,33 +1484,33 @@

      referenced_byte_size(Binary)

      it can be useful to get the size of the referenced binary. This function can be used in a program to trigger the use of copy/1. By copying a binary, one can dereference the original, possibly large, binary that a -smaller binary is a reference to.

      Example:

      store(Binary, GBSet) ->
      +smaller binary is a reference to.

      Example:

      store(Binary, GBSet) ->
         NewBin =
      -      case binary:referenced_byte_size(Binary) of
      -          Large when Large > 2 * byte_size(Binary) ->
      -             binary:copy(Binary);
      +      case binary:referenced_byte_size(Binary) of
      +          Large when Large > 2 * byte_size(Binary) ->
      +             binary:copy(Binary);
                 _ ->
                    Binary
             end,
      -  gb_sets:insert(NewBin,GBSet).

      In this example, we chose to copy the binary content before inserting it in + gb_sets:insert(NewBin,GBSet).

      In this example, we chose to copy the binary content before inserting it in gb_sets:set() if it references a binary more than twice the data size we want to keep. Of course, different rules apply when copying to different programs.

      Binary sharing occurs whenever binaries are taken apart. This is the fundamental reason why binaries are fast, decomposition can always be done with O(1) complexity. In rare circumstances this data sharing is however undesirable, why this function together with copy/1 can be useful when optimizing -for memory use.

      Example of binary sharing:

      1> A = binary:copy(<<1>>, 100).
      +for memory use.

      Example of binary sharing:

      1> A = binary:copy(<<1>>, 100).
       <<1,1,1,1,1 ...
      -2> byte_size(A).
      +2> byte_size(A).
       100
      -3> binary:referenced_byte_size(A).
      +3> binary:referenced_byte_size(A).
       100
       4> <<B:10/binary, C:90/binary>> = A.
       <<1,1,1,1,1 ...
      -5> {byte_size(B), binary:referenced_byte_size(B)}.
      -{10,10}
      -6> {byte_size(C), binary:referenced_byte_size(C)}.
      -{90,100}

      In the above example, the small binary B was copied while the larger binary +5> {byte_size(B), binary:referenced_byte_size(B)}. +{10,10} +6> {byte_size(C), binary:referenced_byte_size(C)}. +{90,100}

      In the above example, the small binary B was copied while the larger binary C references binary A.

      Note

      Binary data is shared among processes. If another process still references the larger binary, copying the part this process uses only consumes more memory and does not free up the larger binary for garbage collection. Use this kind @@ -1599,28 +1599,28 @@

      replace(Subject, Pattern, Replacement, Opti at the specified position (or positions) before inserting Replacement into Subject. If Replacement is given as a fun instead, this option is ignored.

      If any position specified in InsPos > size of the replacement binary, a badarg exception is raised.

      Options global and {scope, part()} work as for split/3. The return type is -always a binary/0.

      For a description of Pattern, see compile_pattern/1.

      Examples:

      1> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], <<"X">>, []).
      +always a binary/0.

      For a description of Pattern, see compile_pattern/1.

      Examples:

      1> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], <<"X">>, []).
       <<"aXcde">>
       
      -2> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], <<"X">>, [global]).
      +2> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], <<"X">>, [global]).
       <<"aXcXe">>
       
      -3> binary:replace(<<"abcde">>, <<"b">>, <<"[]">>, [{insert_replaced, 1}]).
      +3> binary:replace(<<"abcde">>, <<"b">>, <<"[]">>, [{insert_replaced, 1}]).
       <<"a[b]cde">>
       
      -4> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], <<"[]">>, [global, {insert_replaced, 1}]).
      +4> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], <<"[]">>, [global, {insert_replaced, 1}]).
       <<"a[b]c[d]e">>
       
      -5> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], <<"[]">>, [global, {insert_replaced, [1, 1]}]).
      +5> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], <<"[]">>, [global, {insert_replaced, [1, 1]}]).
       <<"a[bb]c[dd]e">>
       
      -6> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], <<"[-]">>, [global, {insert_replaced, [1, 2]}]).
      +6> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], <<"[-]">>, [global, {insert_replaced, [1, 2]}]).
       <<"a[b-b]c[d-d]e">>
       
      -7> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], fun(M) -> <<$[, M/binary, $]>> end, []).
      +7> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], fun(M) -> <<$[, M/binary, $]>> end, []).
       <<"a[b]cde">>
       
      -8> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], fun(M) -> <<$[, M/binary, $]>> end, [global]).
      +8> binary:replace(<<"abcde">>, [<<"b">>, <<"d">>], fun(M) -> <<$[, M/binary, $]>> end, [global]).
       <<"a[b]c[d]e">>
      @@ -1694,20 +1694,20 @@

      split(Subject, Pattern, Options)

      Splits Subject into a list of binaries based on Pattern.

      If option global is not specified, only the first occurrence of Pattern in -Subject gives rise to a split.

      The parts of Pattern found in Subject are not included in the result.

      Example:

      1> binary:split(<<1,255,4,0,0,0,2,3>>, [<<0,0,0>>,<<2>>],[]).
      -[<<1,255,4>>, <<2,3>>]
      -2> binary:split(<<0,1,0,0,4,255,255,9>>, [<<0,0>>, <<255,255>>],[global]).
      -[<<0,1>>,<<4>>,<<9>>]

      Summary of options:

      • {scope, part()} - Works as in match/3 and matches/3. Notice that +Subject gives rise to a split.

        The parts of Pattern found in Subject are not included in the result.

        Example:

        1> binary:split(<<1,255,4,0,0,0,2,3>>, [<<0,0,0>>,<<2>>],[]).
        +[<<1,255,4>>, <<2,3>>]
        +2> binary:split(<<0,1,0,0,4,255,255,9>>, [<<0,0>>, <<255,255>>],[global]).
        +[<<0,1>>,<<4>>,<<9>>]

        Summary of options:

        • {scope, part()} - Works as in match/3 and matches/3. Notice that this only defines the scope of the search for matching strings, it does not cut the binary before splitting. The bytes before and after the scope are kept in the result. See the example below.

        • trim - Removes trailing empty parts of the result (as does trim in re:split/3.

        • trim_all - Removes all empty parts of the result.

        • global - Repeats the split until Subject is exhausted. Conceptually option global makes split work on the positions returned by matches/3, while it normally works on the position returned by match/3.

        Example of the difference between a scope and taking the binary apart before -splitting:

        1> binary:split(<<"banana">>, [<<"a">>],[{scope,{2,3}}]).
        -[<<"ban">>,<<"na">>]
        -2> binary:split(binary:part(<<"banana">>,{2,3}), [<<"a">>],[]).
        -[<<"n">>,<<"n">>]

        The return type is always a list of binaries that are all referencing Subject. +splitting:

        1> binary:split(<<"banana">>, [<<"a">>],[{scope,{2,3}}]).
        +[<<"ban">>,<<"na">>]
        +2> binary:split(binary:part(<<"banana">>,{2,3}), [<<"a">>],[]).
        +[<<"n">>,<<"n">>]

        The return type is always a list of binaries that are all referencing Subject. This means that the data in Subject is not copied to new binaries, and that Subject cannot be garbage collected until the results of the split are no longer referenced.

        For a description of Pattern, see compile_pattern/1.

        diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/c.html b/prs/8803/lib/stdlib-6.0.1/doc/html/c.html index a8cfabb5e7ba0..547e5c47af6e0 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/c.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/c.html @@ -1755,7 +1755,7 @@

        nc(File, Options)

        Compiles and then loads the code for a file on all nodes. Options defaults to -[]. Compilation is equivalent to:

        compile:file(File, Options ++ [report_errors, report_warnings])
        +[]. Compilation is equivalent to:

        compile:file(File, Options ++ [report_errors, report_warnings])
        diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/calendar.html b/prs/8803/lib/stdlib-6.0.1/doc/html/calendar.html index 40959fd51beb9..91630af71de01 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/calendar.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/calendar.html @@ -1845,10 +1845,10 @@

        rfc3339_to_system_time(DateTimeString, Opti

        Converts an RFC 3339 timestamp into system time. The data format of RFC 3339 timestamps is described by RFC 3339. Starting from OTP 25.1, the minutes part of the time zone is optional.

        Valid option:

        • {unit, Unit} - The time unit of the return value. The default is -second.
        1> calendar:rfc3339_to_system_time("2018-02-01T16:17:58+01:00").
        +second.

      1> calendar:rfc3339_to_system_time("2018-02-01T16:17:58+01:00").
       1517498278
      -2> calendar:rfc3339_to_system_time("2018-02-01 15:18:02.088Z",
      -   [{unit, nanosecond}]).
      +2> calendar:rfc3339_to_system_time("2018-02-01 15:18:02.088Z",
      +   [{unit, nanosecond}]).
       1517498282088000000
      @@ -2018,16 +2018,16 @@

      system_time_to_rfc3339(Time, Options)

      the formatted string includes a fraction of a second. The number of fractional second digits is three, six, or nine depending on what time unit is chosen. For native three fractional digits are included. Notice that trailing zeros -are not removed from the fraction.

    1> calendar:system_time_to_rfc3339(erlang:system_time(second)).
    +are not removed from the fraction.

    1> calendar:system_time_to_rfc3339(erlang:system_time(second)).
     "2018-04-23T14:56:28+02:00"
    -2> calendar:system_time_to_rfc3339(erlang:system_time(second),
    -   [{offset, "-02:00"}]).
    +2> calendar:system_time_to_rfc3339(erlang:system_time(second),
    +   [{offset, "-02:00"}]).
     "2018-04-23T10:56:52-02:00"
    -3> calendar:system_time_to_rfc3339(erlang:system_time(second),
    -   [{offset, -7200}]).
    +3> calendar:system_time_to_rfc3339(erlang:system_time(second),
    +   [{offset, -7200}]).
     "2018-04-23T10:57:05-02:00"
    -4> calendar:system_time_to_rfc3339(erlang:system_time(millisecond),
    -   [{unit, millisecond}, {time_designator, $\s}, {offset, "Z"}]).
    +4> calendar:system_time_to_rfc3339(erlang:system_time(millisecond),
    +   [{unit, millisecond}, {time_designator, $\s}, {offset, "Z"}]).
     "2018-04-23 12:57:20.482Z"
    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/dets.html b/prs/8803/lib/stdlib-6.0.1/doc/html/dets.html index 048ebf06f82aa..e7977f8711c84 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/dets.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/dets.html @@ -1914,14 +1914,14 @@

    lookup(Name, Key)

    Returns a list of all objects with key Key stored in table Name, for -example:

    2> dets:open_file(abc, [{type, bag}]).
    -{ok,abc}
    -3> dets:insert(abc, {1,2,3}).
    +example:

    2> dets:open_file(abc, [{type, bag}]).
    +{ok,abc}
    +3> dets:insert(abc, {1,2,3}).
     ok
    -4> dets:insert(abc, {1,3,4}).
    +4> dets:insert(abc, {1,3,4}).
     ok
    -5> dets:lookup(abc, 1).
    -[{1,2,3},{1,3,4}]

    If the table type is set, the function returns either the empty list or a list +5> dets:lookup(abc, 1). +[{1,2,3},{1,3,4}]

    If the table type is set, the function returns either the empty list or a list with one object, as there cannot be more than one object with a given key. If the table type is bag or duplicate_bag, the function returns a list of arbitrary length.

    Notice that the order of objects returned is unspecified. In particular, the @@ -2778,11 +2778,11 @@

    table(Name, Options)

    specification is specified explicitly. This is how to state match specifications that cannot easily be expressed within the syntax provided by qlc.

    The following example uses an explicit match specification to traverse the -table:

    1> dets:open_file(t, []),
    -ok = dets:insert(t, [{1,a},{2,b},{3,c},{4,d}]),
    -MS = ets:fun2ms(fun({X,Y}) when (X > 1) or (X < 5) -> {Y} end),
    -QH1 = dets:table(t, [{traverse, {select, MS}}]).

    An example with implicit match specification:

    2> QH2 = qlc:q([{Y} || {X,Y} <- dets:table(t), (X > 1) or (X < 5)]).

    The latter example is equivalent to the former, which can be verified using -function qlc:info/1:

    3> qlc:info(QH1) =:= qlc:info(QH2).
    +table:

    1> dets:open_file(t, []),
    +ok = dets:insert(t, [{1,a},{2,b},{3,c},{4,d}]),
    +MS = ets:fun2ms(fun({X,Y}) when (X > 1) or (X < 5) -> {Y} end),
    +QH1 = dets:table(t, [{traverse, {select, MS}}]).

    An example with implicit match specification:

    2> QH2 = qlc:q([{Y} || {X,Y} <- dets:table(t), (X > 1) or (X < 5)]).

    The latter example is equivalent to the former, which can be verified using +function qlc:info/1:

    3> qlc:info(QH1) =:= qlc:info(QH2).
     true

    qlc:info/1 returns information about a query handle. In this case identical information is returned for the two query handles.

    @@ -2856,7 +2856,7 @@

    traverse(Name, Fun)

    Applies Fun to each object stored in table Name in some unspecified order. Different actions are taken depending on the return value of Fun. The following Fun return values are allowed:

    • continue - Continue to perform the traversal. For example, the following -function can be used to print the contents of a table:

      fun(X) -> io:format("~p~n", [X]), continue end.
    • {continue, Val} - Continue the traversal and accumulate Val. The +function can be used to print the contents of a table:

      fun(X) -> io:format("~p~n", [X]), continue end.
    • {continue, Val} - Continue the traversal and accumulate Val. The following function is supplied to collect all objects of a table in a list:

      fun(X) -> {continue, X} end.
    • {done, Value} - Terminate the traversal and return [Value | Acc].

    Any other value OtherValue returned by Fun terminates the traversal and is returned immediately.

    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/dict.html b/prs/8803/lib/stdlib-6.0.1/doc/html/dict.html index bcff0c0766171..5b68e9f3187b5 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/dict.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/dict.html @@ -138,13 +138,13 @@

    Notes

    Functions append and append_list are included so that keyed values can be -stored in a list accumulator, for example:

    > D0 = dict:new(),
    -  D1 = dict:store(files, [], D0),
    -  D2 = dict:append(files, f1, D1),
    -  D3 = dict:append(files, f2, D2),
    -  D4 = dict:append(files, f3, D3),
    -  dict:fetch(files, D4).
    -[f1,f2,f3]

    This saves the trouble of first fetching a keyed value, appending a new value to +stored in a list accumulator, for example:

    > D0 = dict:new(),
    +  D1 = dict:store(files, [], D0),
    +  D2 = dict:append(files, f1, D1),
    +  D3 = dict:append(files, f2, D2),
    +  D4 = dict:append(files, f3, D3),
    +  dict:fetch(files, D4).
    +[f1,f2,f3]

    This saves the trouble of first fetching a keyed value, appending a new value to the list of stored values, and storing the result.

    Function fetch is to be used if the key is known to be in the dictionary, otherwise function find.

    @@ -905,10 +905,10 @@

    merge(Fun, Dict1, Dict2)

    the Key-Value pairs from both dictionaries are included in the new dictionary. If a key occurs in both dictionaries, Fun is called with the key and both values to return a new value. merge can be defined as follows, but is -faster:

    merge(Fun, D1, D2) ->
    -    fold(fun (K, V1, D) ->
    -                 update(K, fun (V2) -> Fun(K, V1, V2) end, V1, D)
    -         end, D2, D1).
    +faster:

    merge(Fun, D1, D2) ->
    +    fold(fun (K, V1, D) ->
    +                 update(K, fun (V2) -> Fun(K, V1, V2) end, V1, D)
    +         end, D2, D1).
    @@ -1121,8 +1121,8 @@

    update(Key, Fun, Initial, Dict1)

    Updates a value in a dictionary by calling Fun on the value to get a new value. If Key is not present in the dictionary, Initial is stored as the -first value. For example, append/3 can be defined as:

    append(Key, Val, D) ->
    -    update(Key, fun (Old) -> Old ++ [Val] end, [Val], D).
    +first value. For example, append/3 can be defined as:

    append(Key, Val, D) ->
    +    update(Key, fun (Old) -> Old ++ [Val] end, [Val], D).
    @@ -1153,8 +1153,8 @@

    update_counter(Key, Increment, Dict1)

    Adds Increment to the value associated with Key and stores this value. If Key is not present in the dictionary, Increment is stored as the first -value.

    This can be defined as follows, but is faster:

    update_counter(Key, Incr, D) ->
    -    update(Key, fun (Old) -> Old + Incr end, Incr, D).
    +value.

    This can be defined as follows, but is faster:

    update_counter(Key, Incr, D) ->
    +    update(Key, fun (Old) -> Old + Incr end, Incr, D).
    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/epp.html b/prs/8803/lib/stdlib-6.0.1/doc/html/epp.html index 3aae88987c0cd..f4ed4157c45bc 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/epp.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/epp.html @@ -140,7 +140,7 @@

    Error Information

    ErrorInfo is the standard ErrorInfo structure that is returned from all I/O -modules. The format is as follows:

    {ErrorLine, Module, ErrorDescriptor}

    A string describing the error is obtained with the following call:

    Module:format_error(ErrorDescriptor)

    +modules. The format is as follows:

    {ErrorLine, Module, ErrorDescriptor}

    A string describing the error is obtained with the following call:

    Module:format_error(ErrorDescriptor)

    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/erl_error.html b/prs/8803/lib/stdlib-6.0.1/doc/html/erl_error.html index a3c56a6985299..ffff93eb605a8 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/erl_error.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/erl_error.html @@ -317,7 +317,7 @@

    format_fun()

    A fun used to format function arguments for BIF and function calls. By default -the following fun will be used:

    fun(Term, I) -> io_lib:print(Term, I, 80, 30) end
    +the following fun will be used:

    fun(Term, I) -> io_lib:print(Term, I, 80, 30) end
    @@ -438,23 +438,23 @@

    format_error(Reason, StackTrace)

    caused the error starting at 1.

  • general - An error that is not associated with any argument caused the error.

  • reason - If the Reason should be printed differently than the default way.

  • If the text returned includes new-lines, format_exception/4 will indent the -text correctly.

    Example:

    -module(my_error_module).
    --export([atom_to_string/1, format_error/2]).
    -
    -atom_to_string(Arg) when is_atom(Arg) ->
    -  atom_to_list(Arg);
    -atom_to_string(Arg) ->
    -  erlang:error(badarg,[Arg],
    -               [{error_info,#{ module => ?MODULE,
    -                               cause => #{ 1 => "should be an atom" }}}]).
    -
    -format_error(Reason, [{_M,_F,_As,Info}|_]) ->
    -  ErrorInfo = proplists:get_value(error_info, Info, #{}),
    -  ErrorMap = maps:get(cause, ErrorInfo),
    -  ErrorMap#{ general => "optional general information",
    -             reason => io_lib:format("~p: ~p",[?MODULE, Reason]) }.
    1> c(my_error_module).
    -{ok,my_error_module}
    -2> my_error_module:atom_to_string(1).
    +text correctly.

    Example:

    -module(my_error_module).
    +-export([atom_to_string/1, format_error/2]).
    +
    +atom_to_string(Arg) when is_atom(Arg) ->
    +  atom_to_list(Arg);
    +atom_to_string(Arg) ->
    +  erlang:error(badarg,[Arg],
    +               [{error_info,#{ module => ?MODULE,
    +                               cause => #{ 1 => "should be an atom" }}}]).
    +
    +format_error(Reason, [{_M,_F,_As,Info}|_]) ->
    +  ErrorInfo = proplists:get_value(error_info, Info, #{}),
    +  ErrorMap = maps:get(cause, ErrorInfo),
    +  ErrorMap#{ general => "optional general information",
    +             reason => io_lib:format("~p: ~p",[?MODULE, Reason]) }.
    1> c(my_error_module).
    +{ok,my_error_module}
    +2> my_error_module:atom_to_string(1).
     ** exception error: my_error_module: badarg
          in function  my_error_module:atom_to_string/1
             called as my_error_module:atom_to_string(1)
    @@ -542,18 +542,18 @@ 

    format_exception(Class, Reason, StackTrace,

    Format the error reason and stack back-trace caught using try ... catch in the same style as the shell formats them.

    Example:

    try
    -    do_something()
    +    do_something()
     catch
         C:R:Stk ->
    -        Message = erl_error:format_exception(C, R, Stk),
    -        io:format(LogFile, "~ts\n", [Message])
    +        Message = erl_error:format_exception(C, R, Stk),
    +        io:format(LogFile, "~ts\n", [Message])
     end

    If error_info is provided with the exception, format_exception will use that information to provide additional information about the exception.

    Example:

    try
    -  erlang:raise(badarg,[],[{error_info,#{}}])
    +  erlang:raise(badarg,[],[{error_info,#{}}])
     catch
         C:R:Stk ->
    -        Message = erl_error:format_exception(C, R, Stk),
    -        io:format(LogFile, "~ts\n", [Message])
    +        Message = erl_error:format_exception(C, R, Stk),
    +        io:format(LogFile, "~ts\n", [Message])
     end

    See erlang:error/3 for details on how to raise an exception with error_info included.

    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/erl_eval.html b/prs/8803/lib/stdlib-6.0.1/doc/html/erl_eval.html index cc649a15a180a..3d42ea2e8607e 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/erl_eval.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/erl_eval.html @@ -141,13 +141,13 @@

    LocalFunctionHandler can be used to define a function that is called when there is a call to a local function. The argument can have the following formats:

    • {value,Func} - This defines a local function handler that is called -with:

      Func(Name, Arguments)

      Name is the name of the local function (an atom) and Arguments is a list +with:

      Func(Name, Arguments)

      Name is the name of the local function (an atom) and Arguments is a list of the evaluated arguments. The function handler returns the value of the local function. In this case, the current bindings cannot be accessed. To signal an error, the function handler calls exit/1 with a -suitable exit value.

    • {eval,Func} - This defines a local function handler that is called with:

      Func(Name, Arguments, Bindings)

      Name is the name of the local function (an atom), Arguments is a list of +suitable exit value.

    • {eval,Func} - This defines a local function handler that is called with:

      Func(Name, Arguments, Bindings)

      Name is the name of the local function (an atom), Arguments is a list of the unevaluated arguments, and Bindings are the current variable bindings. -The function handler returns:

      {value,Value,NewBindings}

      Value is the value of the local function and NewBindings are the updated +The function handler returns:

      {value,Value,NewBindings}

      Value is the value of the local function and NewBindings are the updated variable bindings. In this case, the function handler must itself evaluate all the function arguments and manage the bindings. To signal an error, the function handler calls exit/1 with a suitable exit value.

    • none - There is no local function handler.

    @@ -161,7 +161,7 @@

    expressions.
  • An operator Op/A is called (this is handled as a call to function erlang:Op/A).
  • Exceptions are calls to erlang:apply/2,3; neither of the function handlers are called for such calls. The argument can have the following formats:

    • {value,Func} - This defines a non-local function handler. The function -may be called with two arguments:

      Func(FuncSpec, Arguments)

      or three arguments:

      Func(Anno, FuncSpec, Arguments)

      Anno is the erl_anno:anno() of the node, FuncSpec +may be called with two arguments:

      Func(FuncSpec, Arguments)

      or three arguments:

      Func(Anno, FuncSpec, Arguments)

      Anno is the erl_anno:anno() of the node, FuncSpec is the name of the function on the form {Module,Function} or a fun, and Arguments is a list of the evaluated arguments. The function handler returns the value of the function. To signal an error, the function handler diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/erl_lint.html b/prs/8803/lib/stdlib-6.0.1/doc/html/erl_lint.html index 43938dfcffd5e..cde0ef47f8475 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/erl_lint.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/erl_lint.html @@ -139,7 +139,7 @@

      Error Information

      ErrorInfo is the standard ErrorInfo structure that is returned from all I/O -modules. The format is as follows:

      {ErrorLine, Module, ErrorDescriptor}

      A string describing the error is obtained with the following call:

      Module:format_error(ErrorDescriptor)

      +modules. The format is as follows:

      {ErrorLine, Module, ErrorDescriptor}

      A string describing the error is obtained with the following call:

      Module:format_error(ErrorDescriptor)

      diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/erl_parse.html b/prs/8803/lib/stdlib-6.0.1/doc/html/erl_parse.html index a5fe0d2c2c205..188b117526563 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/erl_parse.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/erl_parse.html @@ -138,7 +138,7 @@

      Error Information

      ErrorInfo is the standard ErrorInfo structure that is returned from all I/O modules. -The format is as follows:

      {ErrorLine, Module, ErrorDescriptor}

      A string describing the error is obtained with the following call:

      Module:format_error(ErrorDescriptor)

      +The format is as follows:

      {ErrorLine, Module, ErrorDescriptor}

      A string describing the error is obtained with the following call:

      Module:format_error(ErrorDescriptor)

      diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/erl_scan.html b/prs/8803/lib/stdlib-6.0.1/doc/html/erl_scan.html index fe1c4987dabdd..a27ce511a3d52 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/erl_scan.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/erl_scan.html @@ -136,7 +136,7 @@

      Error Information

      ErrorInfo is the standard ErrorInfo structure that is returned from all I/O -modules. The format is as follows:

      {ErrorLocation, Module, ErrorDescriptor}

      A string describing the error is obtained with the following call:

      Module:format_error(ErrorDescriptor)

      +modules. The format is as follows:

      {ErrorLocation, Module, ErrorDescriptor}

      A string describing the error is obtained with the following call:

      Module:format_error(ErrorDescriptor)

      diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/erl_tar.html b/prs/8803/lib/stdlib-6.0.1/doc/html/erl_tar.html index 46da1b79c3dfb..ab481824fe27c 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/erl_tar.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/erl_tar.html @@ -1291,14 +1291,14 @@

      init/3

      Notice that there is only an arity-2 read function, not an arity-1 function.

    • (position,{UserData,Position}) - Sets the position of UserData as defined for files in file:position/2

    Example:

    The following is a complete Fun parameter for reading and writing on files using the file module:

    ExampleFun =
    -   fun(write, {Fd,Data}) ->  file:write(Fd, Data);
    -      (position, {Fd,Pos}) -> file:position(Fd, Pos);
    -      (read2, {Fd,Size}) -> file:read(Fd, Size);
    -      (close, Fd) -> file:close(Fd)
    -   end

    Here Fd was specified to function init/3 as:

    {ok,Fd} = file:open(Name, ...).
    -{ok,TarDesc} = erl_tar:init(Fd, [write], ExampleFun),

    TarDesc is then used:

    erl_tar:add(TarDesc, SomeValueIwantToAdd, FileNameInTarFile),
    +   fun(write, {Fd,Data}) ->  file:write(Fd, Data);
    +      (position, {Fd,Pos}) -> file:position(Fd, Pos);
    +      (read2, {Fd,Size}) -> file:read(Fd, Size);
    +      (close, Fd) -> file:close(Fd)
    +   end

    Here Fd was specified to function init/3 as:

    {ok,Fd} = file:open(Name, ...).
    +{ok,TarDesc} = erl_tar:init(Fd, [write], ExampleFun),

    TarDesc is then used:

    erl_tar:add(TarDesc, SomeValueIwantToAdd, FileNameInTarFile),
     ...,
    -erl_tar:close(TarDesc)

    When the erl_tar core wants to, for example, write a piece of Data, it would +erl_tar:close(TarDesc)

    When the erl_tar core wants to, for example, write a piece of Data, it would call ExampleFun(write, {UserData,Data}).

    Note

    This example with the file module operations is not necessary to use directly, as that is what function open/2 in principle does.

    Warning

    The TarDescriptor term is not a file descriptor. You are advised not to rely on the specific contents of this term, as it can change in future Erlang/OTP diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/escript.html b/prs/8803/lib/stdlib-6.0.1/doc/html/escript.html index 5ea8c5f9d90b4..774c252a4fb9c 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/escript.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/escript.html @@ -522,67 +522,67 @@

    create(File, Options)

    number of schedulers with +S3. We also extract the different sections from the newly created script:

    > Source = "%% Demo\nmain(_Args) ->\n    io:format(\"~p\",[erlang:system_info(schedulers)]).\n".
     "%% Demo\nmain(_Args) ->\n    io:format(erlang:system_info(schedulers)).\n"
    -> io:format("~s\n", [Source]).
    +> io:format("~s\n", [Source]).
     %% Demo
    -main(_Args) ->
    -    io:format(erlang:system_info(schedulers)).
    +main(_Args) ->
    +    io:format(erlang:system_info(schedulers)).
     
     ok
    -> {ok, Bin} = escript:create(binary, [shebang, comment, {emu_args, "+S3"},
    -                                      {source, list_to_binary(Source)}]).
    -{ok,<<"#!/usr/bin/env escript\n%% This is an -*- erlang -*- file\n%%!+S3"...>>}
    -> file:write_file("demo.escript", Bin).
    +> {ok, Bin} = escript:create(binary, [shebang, comment, {emu_args, "+S3"},
    +                                      {source, list_to_binary(Source)}]).
    +{ok,<<"#!/usr/bin/env escript\n%% This is an -*- erlang -*- file\n%%!+S3"...>>}
    +> file:write_file("demo.escript", Bin).
     ok
    -> os:cmd("escript demo.escript").
    +> os:cmd("escript demo.escript").
     "3"
    -> escript:extract("demo.escript", []).
    -{ok,[{shebang,default}, {comment,default}, {emu_args,"+S3"},
    -     {source,<<"%% Demo\nmain(_Args) ->\n    io:format(erlang:system_info(schedu"...>>}]}

    An escript without header can be created as follows:

    > file:write_file("demo.erl",
    -                  ["%% demo.erl\n-module(demo).\n-export([main/1]).\n\n", Source]).
    +> escript:extract("demo.escript", []).
    +{ok,[{shebang,default}, {comment,default}, {emu_args,"+S3"},
    +     {source,<<"%% Demo\nmain(_Args) ->\n    io:format(erlang:system_info(schedu"...>>}]}

    An escript without header can be created as follows:

    > file:write_file("demo.erl",
    +                  ["%% demo.erl\n-module(demo).\n-export([main/1]).\n\n", Source]).
     ok
    -> {ok, _, BeamCode} = compile:file("demo.erl", [binary, debug_info]).
    -{ok,demo,
    +> {ok, _, BeamCode} = compile:file("demo.erl", [binary, debug_info]).
    +{ok,demo,
         <<70,79,82,49,0,0,2,208,66,69,65,77,65,116,111,109,0,0,0,
    -      79,0,0,0,9,4,100,...>>}
    -> escript:create("demo.beam", [{beam, BeamCode}]).
    +      79,0,0,0,9,4,100,...>>}
    +> escript:create("demo.beam", [{beam, BeamCode}]).
     ok
    -> escript:extract("demo.beam", []).
    -{ok,[{shebang,undefined}, {comment,undefined}, {emu_args,undefined},
    -     {beam,<<70,79,82,49,0,0,3,68,66,69,65,77,65,116,
    -             111,109,0,0,0,83,0,0,0,9,...>>}]}
    -> os:cmd("escript demo.beam").
    +> escript:extract("demo.beam", []).
    +{ok,[{shebang,undefined}, {comment,undefined}, {emu_args,undefined},
    +     {beam,<<70,79,82,49,0,0,3,68,66,69,65,77,65,116,
    +             111,109,0,0,0,83,0,0,0,9,...>>}]}
    +> os:cmd("escript demo.beam").
     "true"

    Here we create an archive script containing both Erlang code and Beam code, then we iterate over all files in the archive and collect their contents and some -information about them:

    > {ok, SourceCode} = file:read_file("demo.erl").
    -{ok,<<"%% demo.erl\n-module(demo).\n-export([main/1]).\n\n%% Demo\nmain(_Arg"...>>}
    -> escript:create("demo.escript",
    -                 [shebang,
    -                  {archive, [{"demo.erl", SourceCode},
    -                             {"demo.beam", BeamCode}], []}]).
    +information about them:

    > {ok, SourceCode} = file:read_file("demo.erl").
    +{ok,<<"%% demo.erl\n-module(demo).\n-export([main/1]).\n\n%% Demo\nmain(_Arg"...>>}
    +> escript:create("demo.escript",
    +                 [shebang,
    +                  {archive, [{"demo.erl", SourceCode},
    +                             {"demo.beam", BeamCode}], []}]).
     ok
    -> {ok, [{shebang,default}, {comment,undefined}, {emu_args,undefined},
    -     {archive, ArchiveBin}]} = escript:extract("demo.escript", []).
    -{ok,[{shebang,default}, {comment,undefined}, {emu_args,undefined},
    -     {{archive,<<80,75,3,4,20,0,0,0,8,0,118,7,98,60,105,
    -                152,61,93,107,0,0,0,118,0,...>>}]}
    -> file:write_file("demo.zip", ArchiveBin).
    +> {ok, [{shebang,default}, {comment,undefined}, {emu_args,undefined},
    +     {archive, ArchiveBin}]} = escript:extract("demo.escript", []).
    +{ok,[{shebang,default}, {comment,undefined}, {emu_args,undefined},
    +     {{archive,<<80,75,3,4,20,0,0,0,8,0,118,7,98,60,105,
    +                152,61,93,107,0,0,0,118,0,...>>}]}
    +> file:write_file("demo.zip", ArchiveBin).
     ok
    -> zip:foldl(fun(N, I, B, A) -> [{N, I(), B()} | A] end, [], "demo.zip").
    -{ok,[{"demo.beam",
    -      {file_info,748,regular,read_write,
    -                 {{2010,3,2},{0,59,22}},
    -                 {{2010,3,2},{0,59,22}},
    -                 {{2010,3,2},{0,59,22}},
    -                 54,1,0,0,0,0,0},
    +> zip:foldl(fun(N, I, B, A) -> [{N, I(), B()} | A] end, [], "demo.zip").
    +{ok,[{"demo.beam",
    +      {file_info,748,regular,read_write,
    +                 {{2010,3,2},{0,59,22}},
    +                 {{2010,3,2},{0,59,22}},
    +                 {{2010,3,2},{0,59,22}},
    +                 54,1,0,0,0,0,0},
           <<70,79,82,49,0,0,2,228,66,69,65,77,65,116,111,109,0,0,0,
    -        83,0,0,...>>},
    -     {"demo.erl",
    -      {file_info,118,regular,read_write,
    -                 {{2010,3,2},{0,59,22}},
    -                 {{2010,3,2},{0,59,22}},
    -                 {{2010,3,2},{0,59,22}},
    -                 54,1,0,0,0,0,0},
    -      <<"%% demo.erl\n-module(demo).\n-export([main/1]).\n\n%% Demo\nmain(_Arg"...>>}]}
    +
    83,0,0,...>>}, + {"demo.erl", + {file_info,118,regular,read_write, + {{2010,3,2},{0,59,22}}, + {{2010,3,2},{0,59,22}}, + {{2010,3,2},{0,59,22}}, + 54,1,0,0,0,0,0}, + <<"%% demo.erl\n-module(demo).\n-export([main/1]).\n\n%% Demo\nmain(_Arg"...>>}]}
    @@ -615,16 +615,16 @@

    extract(File, Options)

    extracted value is set to the atom default. If a section is missing, the extracted value is set to the atom undefined.

    Option compile_source only affects the result if the escript contains source code. In this case the Erlang code is automatically compiled and -{source, BeamCode} is returned instead of {source, SourceCode}.

    Example:

    > escript:create("demo.escript",
    -                 [shebang, {archive, [{"demo.erl", SourceCode},
    -                                      {"demo.beam", BeamCode}], []}]).
    +{source, BeamCode} is returned instead of {source, SourceCode}.

    Example:

    > escript:create("demo.escript",
    +                 [shebang, {archive, [{"demo.erl", SourceCode},
    +                                      {"demo.beam", BeamCode}], []}]).
     ok
    -> {ok, [{shebang,default}, {comment,undefined}, {emu_args,undefined},
    -     {archive, ArchiveBin}]} =
    -              escript:extract("demo.escript", []).
    -{ok,[{{archive,<<80,75,3,4,20,0,0,0,8,0,118,7,98,60,105,
    -                152,61,93,107,0,0,0,118,0,...>>}
    -     {emu_args,undefined}]}
    +>
    {ok, [{shebang,default}, {comment,undefined}, {emu_args,undefined}, + {archive, ArchiveBin}]} = + escript:extract("demo.escript", []). +{ok,[{{archive,<<80,75,3,4,20,0,0,0,8,0,118,7,98,60,105, + 152,61,93,107,0,0,0,118,0,...>>} + {emu_args,undefined}]}
    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/ets.html b/prs/8803/lib/stdlib-6.0.1/doc/html/ets.html index 8c35f1c1effdd..7bb2a4563674e 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/ets.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/ets.html @@ -220,10 +220,10 @@

    find the next key is not done with such guarantees. This is often not a problem, but may cause rare subtle "unexpected" effects if a concurrent process inserts objects during a traversal. For example, consider one process -doing

    ets:new(t, [ordered_set, named_table]),
    -ets:insert(t, {1}),
    -ets:insert(t, {2}),
    -ets:insert(t, {3}),

    A concurrent call to ets:first(t), done by another process, may then in rare +doing

    ets:new(t, [ordered_set, named_table]),
    +ets:insert(t, {1}),
    +ets:insert(t, {2}),
    +ets:insert(t, {3}),

    A concurrent call to ets:first(t), done by another process, may then in rare cases return 2 even though 2 has never existed in the table ordered as the first key. In the same way, a concurrent call to ets:next(t, 1) may return 3 even though 3 never existed in the table ordered directly after 1.

    Effects like this are improbable but possible. The probability will further be @@ -236,11 +236,11 @@

    lookup without any table traversal at all. For ordered_set a partially bound key will limit the traversal to only scan a subset of the table based on term order. A partially bound key is either a list or a tuple with a prefix that is -fully bound. Example:

    1> T = ets:new(t,[ordered_set]), ets:insert(T, {"555-1234", "John Smith"}).
    +fully bound. Example:

    1> T = ets:new(t,[ordered_set]), ets:insert(T, {"555-1234", "John Smith"}).
     true
     2> %% Efficient search of all with area code 555
    -2> ets:match(T,{[$5,$5,$5,$- |'$1'],'$2'}).
    -[["1234","John Smith"]]

    +2> ets:match(T,{[$5,$5,$5,$- |'$1'],'$2'}). +[["1234","John Smith"]]

    @@ -1936,19 +1936,19 @@

    fun2ms(LiteralFun)

    -include_lib("stdlib/include/ms_transform.hrl"). to the source file.

    The fun is very restricted, it can take only a single parameter (the object to match): a sole variable or a tuple. It must use the is_ guard tests. Language constructs that have no representation in a match specification (if, case, -receive, and so on) are not allowed.

    The return value is the resulting match specification.

    Example:

    1> ets:fun2ms(fun({M,N}) when N > 3 -> M end).
    -[{{'$1','$2'},[{'>','$2',3}],['$1']}]

    Variables from the environment can be imported, so that the following works:

    2> X=3.
    +receive, and so on) are not allowed.

    The return value is the resulting match specification.

    Example:

    1> ets:fun2ms(fun({M,N}) when N > 3 -> M end).
    +[{{'$1','$2'},[{'>','$2',3}],['$1']}]

    Variables from the environment can be imported, so that the following works:

    2> X=3.
     3
    -3> ets:fun2ms(fun({M,N}) when N > X -> M end).
    -[{{'$1','$2'},[{'>','$2',{const,3}}],['$1']}]

    The imported variables are replaced by match specification const expressions, +3> ets:fun2ms(fun({M,N}) when N > X -> M end). +[{{'$1','$2'},[{'>','$2',{const,3}}],['$1']}]

    The imported variables are replaced by match specification const expressions, which is consistent with the static scoping for Erlang funs. However, local or global function calls cannot be in the guard or body of the fun. Calls to -built-in match specification functions is of course allowed:

    4> ets:fun2ms(fun({M,N}) when N > X, my_fun(M) -> M end).
    +built-in match specification functions is of course allowed:

    4> ets:fun2ms(fun({M,N}) when N > X, my_fun(M) -> M end).
     Error: fun containing local Erlang function calls
    -('my_fun' called in guard) cannot be translated into match_spec
    -{error,transform_error}
    -5> ets:fun2ms(fun({M,N}) when N > X, is_atom(M) -> M end).
    -[{{'$1','$2'},[{'>','$2',{const,3}},{is_atom,'$1'}],['$1']}]

    As shown by the example, the function can be called from the shell also. The fun +('my_fun' called in guard) cannot be translated into match_spec +{error,transform_error} +5> ets:fun2ms(fun({M,N}) when N > X, is_atom(M) -> M end). +[{{'$1','$2'},[{'>','$2',{const,3}},{is_atom,'$1'}],['$1']}]

    As shown by the example, the function can be called from the shell also. The fun must be literally in the call when used from the shell as well.

    Warning

    If the parse_transform is not applied to a module that calls this pseudo function, the call fails in runtime (with a badarg). The ets module exports a function with this name, but it is never to be called except when @@ -2573,12 +2573,12 @@

    match(Table, Pattern)

    Matches the objects in table Table against pattern Pattern.

    A pattern is a term that can contain:

    • Bound parts (Erlang terms)
    • '_' that matches any Erlang term
    • Pattern variables '$N', where N=0,1,...

    The function returns a list with one element for each matching object, where -each element is an ordered list of pattern variable bindings, for example:

    6> ets:match(T, '$1'). % Matches every object in table
    -[[{rufsen,dog,7}],[{brunte,horse,5}],[{ludde,dog,5}]]
    -7> ets:match(T, {'_',dog,'$1'}).
    -[[7],[5]]
    -8> ets:match(T, {'_',cow,'$1'}).
    -[]

    If the key is specified in the pattern, the match is very efficient. If the key +each element is an ordered list of pattern variable bindings, for example:

    6> ets:match(T, '$1'). % Matches every object in table
    +[[{rufsen,dog,7}],[{brunte,horse,5}],[{ludde,dog,5}]]
    +7> ets:match(T, {'_',dog,'$1'}).
    +[[7],[5]]
    +8> ets:match(T, {'_',cow,'$1'}).
    +[]

    If the key is specified in the pattern, the match is very efficient. If the key is not specified, that is, if it is a variable or an underscore, the entire table must be searched. The search time can be substantial if the table is very large.

    For tables of type ordered_set, the result is in the same order as in a @@ -2830,10 +2830,10 @@

    match_spec_run(List, CompiledMatchSpec)

    Table = ets:new...
     MatchSpec = ...
     % The following call...
    -ets:match_spec_run(ets:tab2list(Table),
    -                   ets:match_spec_compile(MatchSpec)),
    +ets:match_spec_run(ets:tab2list(Table),
    +                   ets:match_spec_compile(MatchSpec)),
     % ...gives the same result as the more common (and more efficient)
    -ets:select(Table, MatchSpec),

    Note

    This function has limited use in normal code. It is used by the dets +ets:select(Table, MatchSpec),

    Note

    This function has limited use in normal code. It is used by the dets module to perform the dets:select/1 operations and by Mnesia during transactions.

    @@ -3196,19 +3196,19 @@

    repair_continuation(Continuation, MatchSpec format. Given that the original match specification is kept intact, the continuation can be restored, meaning it can once again be used in subsequent select/1 calls even though it has been stored on disk or on -another node.

    Examples:

    The following sequence of calls may fail:

    T=ets:new(x,[]),
    +another node.

    Examples:

    The following sequence of calls may fail:

    T=ets:new(x,[]),
     ...
    -MS = ets:fun2ms(fun({N,_}=A) when (N rem 10) =:= 0 -> A end),
    -{_,C} = ets:select(T, MS, 10),
    -MaybeBroken = binary_to_term(term_to_binary(C)),
    -ets:select(MaybeBroken).

    The following sequence works, as the call to +MS = ets:fun2ms(fun({N,_}=A) when (N rem 10) =:= 0 -> A end), +{_,C} = ets:select(T, MS, 10), +MaybeBroken = binary_to_term(term_to_binary(C)), +ets:select(MaybeBroken).

    The following sequence works, as the call to repair_continuation/2 reestablishes the -MaybeBroken continuation.

    T=ets:new(x,[]),
    +MaybeBroken continuation.

    T=ets:new(x,[]),
     ...
    -MS = ets:fun2ms(fun({N,_}=A) when (N rem 10) =:= 0 -> A end),
    -{_,C} = ets:select(T,MS,10),
    -MaybeBroken = binary_to_term(term_to_binary(C)),
    -ets:select(ets:repair_continuation(MaybeBroken,MS)).

    Note

    This function is rarely needed in application code. It is used by Mnesia to +MS = ets:fun2ms(fun({N,_}=A) when (N rem 10) =:= 0 -> A end), +{_,C} = ets:select(T,MS,10), +MaybeBroken = binary_to_term(term_to_binary(C)), +ets:select(ets:repair_continuation(MaybeBroken,MS)).

    Note

    This function is rarely needed in application code. It is used by Mnesia to provide distributed select/3 and select/1 sequences. A normal application would either use Mnesia or keep the continuation from being converted to external format.

    The actual behavior of compiled match specifications when recreated from @@ -3253,21 +3253,21 @@

    safe_fixtable(Table, Fix)

    to succeed even if keys are removed during the traversal. The keys for objects inserted or deleted during a traversal may or may not be returned by next/2 depending on the ordering of keys within the table and if -the key exists at the time next/2 is called.

    Example:

    clean_all_with_value(Table,X) ->
    -    safe_fixtable(Table,true),
    -    clean_all_with_value(Table,X,ets:first(Table)),
    -    safe_fixtable(Table,false).
    +the key exists at the time next/2 is called.

    Example:

    clean_all_with_value(Table,X) ->
    +    safe_fixtable(Table,true),
    +    clean_all_with_value(Table,X,ets:first(Table)),
    +    safe_fixtable(Table,false).
     
    -clean_all_with_value(Table,X,'$end_of_table') ->
    +clean_all_with_value(Table,X,'$end_of_table') ->
         true;
    -clean_all_with_value(Table,X,Key) ->
    -    case ets:lookup(Table,Key) of
    -        [{Key,X}] ->
    -            ets:delete(Table,Key);
    +clean_all_with_value(Table,X,Key) ->
    +    case ets:lookup(Table,Key) of
    +        [{Key,X}] ->
    +            ets:delete(Table,Key);
             _ ->
                 true
         end,
    -    clean_all_with_value(Table,X,ets:next(Table,Key)).

    Notice that deleted objects are not freed from a fixed table until it has been + clean_all_with_value(Table,X,ets:next(Table,Key)).

    Notice that deleted objects are not freed from a fixed table until it has been released. If a process fixes a table but never releases it, the memory used by the deleted objects is never freed. The performance of operations on the table also degrades significantly.

    To retrieve information about which processes have fixed which tables, use @@ -3355,7 +3355,7 @@

    select(Table, MatchSpec)

    a list, so that the following code:

    ets:select(Table,[{{'$1','$2','$3'},[],['$$']}])

    gives the same output as:

    ets:select(Table,[{{'$1','$2','$3'},[],[['$1','$2','$3']]}])

    That is, all the bound variables in the match head as a list. If tuples are to be constructed, one has to write a tuple of arity 1 where the single element in the tuple is the tuple one wants to construct (as an ordinary tuple can be -mistaken for a Guard).

    Therefore the following call:

    ets:select(Table,[{{'$1','$2','$1'},[],['$_']}])

    gives the same output as:

    ets:select(Table,[{{'$1','$2','$1'},[],[{{'$1','$2','$3'}}]}])

    This syntax is equivalent to the syntax used in the trace patterns (see the +mistaken for a Guard).

    Therefore the following call:

    ets:select(Table,[{{'$1','$2','$1'},[],['$_']}])

    gives the same output as:

    ets:select(Table,[{{'$1','$2','$1'},[],[{{'$1','$2','$3'}}]}])

    This syntax is equivalent to the syntax used in the trace patterns (see the dbg) module in Runtime_Tools.

    The Guards are constructed as tuples, where the first element is the test name and the remaining elements are the test parameters. To check for a specific type (say a list) of the element bound to the match variable '$1', one would write @@ -3517,16 +3517,16 @@

    select_replace(Table, MatchSpec)

    object. If not, select_replace will fail with badarg without updating any objects.

    For the moment, due to performance and semantic constraints, tables of type bag are not yet supported.

    The function returns the total number of replaced objects.

    Example

    For all 2-tuples with a list in second position, add atom 'marker' first in -the list:

    1> T = ets:new(x,[]), ets:insert(T, {key, [1, 2, 3]}).
    +the list:

    1> T = ets:new(x,[]), ets:insert(T, {key, [1, 2, 3]}).
     true
    -2> MS = ets:fun2ms(fun({K, L}) when is_list(L) -> {K, [marker | L]} end).
    -[{{'$1','$2'},[{is_list,'$2'}],[{{'$1',[marker|'$2']}}]}]
    -3> ets:select_replace(T, MS).
    +2> MS = ets:fun2ms(fun({K, L}) when is_list(L) -> {K, [marker | L]} end).
    +[{{'$1','$2'},[{is_list,'$2'}],[{{'$1',[marker|'$2']}}]}]
    +3> ets:select_replace(T, MS).
     1
    -4> ets:tab2list(T).
    -[{key,[marker,1,2,3]}]

    A generic single object compare-and-swap operation:

    [Old] = ets:lookup(T, Key),
    -New = update_object(Old),
    -Success = (1 =:= ets:select_replace(T, [{Old, [], [{const, New}]}])),
    +4>
    ets:tab2list(T). +[{key,[marker,1,2,3]}]

    A generic single object compare-and-swap operation:

    [Old] = ets:lookup(T, Key),
    +New = update_object(Old),
    +Success = (1 =:= ets:select_replace(T, [{Old, [], [{const, New}]}])),
    @@ -3561,22 +3561,22 @@

    select_reverse(Continuation)

    ordered_set, the traversal of the table continues to objects with keys earlier in the Erlang term order. The returned list also contains objects with keys in reverse order. For all other table types, the behavior is exactly that of -select/1.

    Example:

    1> T = ets:new(x,[ordered_set]).
    -2> [ ets:insert(T,{N}) || N <- lists:seq(1,10) ].
    +select/1.

    Example:

    1> T = ets:new(x,[ordered_set]).
    +2> [ ets:insert(T,{N}) || N <- lists:seq(1,10) ].
     ...
    -3> {R0,C0} = ets:select_reverse(T,[{'_',[],['$_']}],4).
    +3> {R0,C0} = ets:select_reverse(T,[{'_',[],['$_']}],4).
     ...
     4> R0.
    -[{10},{9},{8},{7}]
    -5> {R1,C1} = ets:select_reverse(C0).
    +[{10},{9},{8},{7}]
    +5> {R1,C1} = ets:select_reverse(C0).
     ...
     6> R1.
    -[{6},{5},{4},{3}]
    -7> {R2,C2} = ets:select_reverse(C1).
    +[{6},{5},{4},{3}]
    +7> {R2,C2} = ets:select_reverse(C1).
     ...
     8> R2.
    -[{2},{1}]
    -9> '$end_of_table' = ets:select_reverse(C2).
    +[{2},{1}]
    +9> '$end_of_table' = ets:select_reverse(C2).
     ...
    @@ -3977,10 +3977,10 @@

    table(Table, Options)

    match specification that matches all objects.

  • {select, MatchSpec} - As for select, the table is traversed by calling select/3 and select/1. The difference is that the match specification is explicitly specified. This is how to state match specifications that cannot -easily be expressed within the syntax provided by QLC.

  • Examples:

    An explicit match specification is here used to traverse the table:

    9> true = ets:insert(Table = ets:new(t, []), [{1,a},{2,b},{3,c},{4,d}]),
    -MS = ets:fun2ms(fun({X,Y}) when (X > 1) or (X < 5) -> {Y} end),
    -QH1 = ets:table(Table, [{traverse, {select, MS}}]).

    An example with an implicit match specification:

    10> QH2 = qlc:q([{Y} || {X,Y} <- ets:table(Table), (X > 1) or (X < 5)]).

    The latter example is equivalent to the former, which can be verified using -function qlc:info/1:

    11> qlc:info(QH1) =:= qlc:info(QH2).
    +easily be expressed within the syntax provided by QLC.

    Examples:

    An explicit match specification is here used to traverse the table:

    9> true = ets:insert(Table = ets:new(t, []), [{1,a},{2,b},{3,c},{4,d}]),
    +MS = ets:fun2ms(fun({X,Y}) when (X > 1) or (X < 5) -> {Y} end),
    +QH1 = ets:table(Table, [{traverse, {select, MS}}]).

    An example with an implicit match specification:

    10> QH2 = qlc:q([{Y} || {X,Y} <- ets:table(Table), (X > 1) or (X < 5)]).

    The latter example is equivalent to the former, which can be verified using +function qlc:info/1:

    11> qlc:info(QH1) =:= qlc:info(QH2).
     true

    qlc:info/1 returns information about a query handle, and in this case identical information is returned for the two query handles.

    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/file_sorter.html b/prs/8803/lib/stdlib-6.0.1/doc/html/file_sorter.html index ff42a1c57f509..9d15b27ba5205 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/file_sorter.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/file_sorter.html @@ -195,35 +195,35 @@

    argument {value, Value}. This makes it easy to initiate the sequence of output functions with a value calculated by the input functions.

    As an example, consider sorting the terms on a disk log file. A function that reads chunks from the disk log and returns a list of binaries is used as input. -The results are collected in a list of terms.

    sort(Log) ->
    -    {ok, _} = disk_log:open([{name,Log}, {mode,read_only}]),
    -    Input = input(Log, start),
    -    Output = output([]),
    -    Reply = file_sorter:sort(Input, Output, {format,term}),
    -    ok = disk_log:close(Log),
    +The results are collected in a list of terms.

    sort(Log) ->
    +    {ok, _} = disk_log:open([{name,Log}, {mode,read_only}]),
    +    Input = input(Log, start),
    +    Output = output([]),
    +    Reply = file_sorter:sort(Input, Output, {format,term}),
    +    ok = disk_log:close(Log),
         Reply.
     
    -input(Log, Cont) ->
    -    fun(close) ->
    +input(Log, Cont) ->
    +    fun(close) ->
                 ok;
    -       (read) ->
    -            case disk_log:chunk(Log, Cont) of
    -                {error, Reason} ->
    -                    {error, Reason};
    -                {Cont2, Terms} ->
    -                    {Terms, input(Log, Cont2)};
    -                {Cont2, Terms, _Badbytes} ->
    -                    {Terms, input(Log, Cont2)};
    +       (read) ->
    +            case disk_log:chunk(Log, Cont) of
    +                {error, Reason} ->
    +                    {error, Reason};
    +                {Cont2, Terms} ->
    +                    {Terms, input(Log, Cont2)};
    +                {Cont2, Terms, _Badbytes} ->
    +                    {Terms, input(Log, Cont2)};
                     eof ->
                         end_of_input
                 end
         end.
     
    -output(L) ->
    -    fun(close) ->
    -            lists:append(lists:reverse(L));
    -       (Terms) ->
    -            output([Terms | L])
    +output(L) ->
    +    fun(close) ->
    +            lists:append(lists:reverse(L));
    +       (Terms) ->
    +            output([Terms | L])
         end.

    For more examples of functions as input and output, see the end of the file_sorter module; the term format is implemented with functions.

    The possible values of Reason returned when an error occurs are:

    • bad_object, {bad_object, FileName} - Applying the format function failed for some binary, or the key(s) could not be extracted from some term.
    • {bad_term, FileName} - io:read/2 failed to read some term.
    • {file_error, FileName, file:posix()} - For an explanation of diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/filelib.html b/prs/8803/lib/stdlib-6.0.1/doc/html/filelib.html index 3f4c3be5b781c..2ef09d0363672 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/filelib.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/filelib.html @@ -1030,15 +1030,15 @@

      safe_relative_path(Filename, Cwd)

      Sanitizes the relative path by eliminating ".." and "." components to protect against directory traversal attacks.

      Either returns the sanitized path name, or the atom unsafe if the path is unsafe. -The path is considered unsafe in the following circumstances:

      • The path is not relative.
      • A ".." component would climb up above the root of the relative path.
      • A symbolic link in the path points above the root of the relative path.

      Examples:

      1> {ok, Cwd} = file:get_cwd().
      +The path is considered unsafe in the following circumstances:

      • The path is not relative.
      • A ".." component would climb up above the root of the relative path.
      • A symbolic link in the path points above the root of the relative path.

      Examples:

      1> {ok, Cwd} = file:get_cwd().
       ...
      -2> filelib:safe_relative_path("dir/sub_dir/..", Cwd).
      +2> filelib:safe_relative_path("dir/sub_dir/..", Cwd).
       "dir"
      -3> filelib:safe_relative_path("dir/..", Cwd).
      -[]
      -4> filelib:safe_relative_path("dir/../..", Cwd).
      +3> filelib:safe_relative_path("dir/..", Cwd).
      +[]
      +4> filelib:safe_relative_path("dir/../..", Cwd).
       unsafe
      -5> filelib:safe_relative_path("/abs/path", Cwd).
      +5> filelib:safe_relative_path("/abs/path", Cwd).
       unsafe
      diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/filename.html b/prs/8803/lib/stdlib-6.0.1/doc/html/filename.html index a04eb131463ba..769722fb259bc 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/filename.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/filename.html @@ -526,20 +526,20 @@

      absname(Filename)

      Converts a relative Filename and returns an absolute name. No attempt is made to create the shortest absolute name, as this can give incorrect results on file -systems that allow links.

      Unix examples:

      1> pwd().
      +systems that allow links.

      Unix examples:

      1> pwd().
       "/usr/local"
      -2> filename:absname("foo").
      +2> filename:absname("foo").
       "/usr/local/foo"
      -3> filename:absname("../x").
      +3> filename:absname("../x").
       "/usr/local/../x"
      -4> filename:absname("/").
      -"/"

      Windows examples:

      1> pwd().
      +4> filename:absname("/").
      +"/"

      Windows examples:

      1> pwd().
       "D:/usr/local"
      -2> filename:absname("foo").
      +2> filename:absname("foo").
       "D:/usr/local/foo"
      -3> filename:absname("../x").
      +3> filename:absname("../x").
       "D:/usr/local/../x"
      -4> filename:absname("/").
      +4> filename:absname("/").
       "D:/"
      @@ -679,58 +679,58 @@

      basedir(Type, Application, Opts)

      Opts the function will default to the native option, that is 'linux', 'darwin' or 'windows', as understood by os:type/0. Anything not recognized as 'darwin' or 'windows' is interpreted as 'linux'.

      The options 'author' and 'version' are only used with 'windows' option -mode.

      • user_cache

        The path location is intended for transient data files on a local machine.

        On Linux: Respects the os environment variable XDG_CACHE_HOME.

        1> filename:basedir(user_cache, "my_application", #{os=>linux}).
        -"/home/otptest/.cache/my_application"

        On Darwin:

        1> filename:basedir(user_cache, "my_application", #{os=>darwin}).
        -"/home/otptest/Library/Caches/my_application"

        On Windows:

        1> filename:basedir(user_cache, "My App").
        +mode.

        • user_cache

          The path location is intended for transient data files on a local machine.

          On Linux: Respects the os environment variable XDG_CACHE_HOME.

          1> filename:basedir(user_cache, "my_application", #{os=>linux}).
          +"/home/otptest/.cache/my_application"

          On Darwin:

          1> filename:basedir(user_cache, "my_application", #{os=>darwin}).
          +"/home/otptest/Library/Caches/my_application"

          On Windows:

          1> filename:basedir(user_cache, "My App").
           "c:/Users/otptest/AppData/Local/My App/Cache"
          -2> filename:basedir(user_cache, "My App").
          +2> filename:basedir(user_cache, "My App").
           "c:/Users/otptest/AppData/Local/My App/Cache"
          -3> filename:basedir(user_cache, "My App", #{author=>"Erlang"}).
          +3> filename:basedir(user_cache, "My App", #{author=>"Erlang"}).
           "c:/Users/otptest/AppData/Local/Erlang/My App/Cache"
          -4> filename:basedir(user_cache, "My App", #{version=>"1.2"}).
          +4> filename:basedir(user_cache, "My App", #{version=>"1.2"}).
           "c:/Users/otptest/AppData/Local/My App/1.2/Cache"
          -5> filename:basedir(user_cache, "My App", #{author=>"Erlang",version=>"1.2"}).
          -"c:/Users/otptest/AppData/Local/Erlang/My App/1.2/Cache"
        • user_config

          The path location is intended for persistent configuration files.

          On Linux: Respects the os environment variable XDG_CONFIG_HOME.

          2> filename:basedir(user_config, "my_application", #{os=>linux}).
          -"/home/otptest/.config/my_application"

          On Darwin:

          2> filename:basedir(user_config, "my_application", #{os=>darwin}).
          -"/home/otptest/Library/Application Support/my_application"

          On Windows:

          1> filename:basedir(user_config, "My App").
          +5> filename:basedir(user_cache, "My App", #{author=>"Erlang",version=>"1.2"}).
          +"c:/Users/otptest/AppData/Local/Erlang/My App/1.2/Cache"
        • user_config

          The path location is intended for persistent configuration files.

          On Linux: Respects the os environment variable XDG_CONFIG_HOME.

          2> filename:basedir(user_config, "my_application", #{os=>linux}).
          +"/home/otptest/.config/my_application"

          On Darwin:

          2> filename:basedir(user_config, "my_application", #{os=>darwin}).
          +"/home/otptest/Library/Application Support/my_application"

          On Windows:

          1> filename:basedir(user_config, "My App").
           "c:/Users/otptest/AppData/Roaming/My App"
          -2> filename:basedir(user_config, "My App", #{author=>"Erlang", version=>"1.2"}).
          -"c:/Users/otptest/AppData/Roaming/Erlang/My App/1.2"
        • user_data

          The path location is intended for persistent data files.

          On Linux: Respects the os environment variable XDG_DATA_HOME.

          3> filename:basedir(user_data, "my_application", #{os=>linux}).
          -"/home/otptest/.local/my_application"

          On Darwin:

          3> filename:basedir(user_data, "my_application", #{os=>darwin}).
          -"/home/otptest/Library/Application Support/my_application"

          On Windows:

          8> filename:basedir(user_data, "My App").
          +2> filename:basedir(user_config, "My App", #{author=>"Erlang", version=>"1.2"}).
          +"c:/Users/otptest/AppData/Roaming/Erlang/My App/1.2"
        • user_data

          The path location is intended for persistent data files.

          On Linux: Respects the os environment variable XDG_DATA_HOME.

          3> filename:basedir(user_data, "my_application", #{os=>linux}).
          +"/home/otptest/.local/my_application"

          On Darwin:

          3> filename:basedir(user_data, "my_application", #{os=>darwin}).
          +"/home/otptest/Library/Application Support/my_application"

          On Windows:

          8> filename:basedir(user_data, "My App").
           "c:/Users/otptest/AppData/Local/My App"
          -9> filename:basedir(user_data, "My App",#{author=>"Erlang",version=>"1.2"}).
          -"c:/Users/otptest/AppData/Local/Erlang/My App/1.2"
        • user_log

          The path location is intended for transient log files on a local machine.

          On Linux: Respects the os environment variable XDG_CACHE_HOME.

          4> filename:basedir(user_log, "my_application", #{os=>linux}).
          -"/home/otptest/.cache/my_application/log"

          On Darwin:

          4> filename:basedir(user_log, "my_application", #{os=>darwin}).
          -"/home/otptest/Library/Logs/my_application"

          On Windows:

          12> filename:basedir(user_log, "My App").
          +9> filename:basedir(user_data, "My App",#{author=>"Erlang",version=>"1.2"}).
          +"c:/Users/otptest/AppData/Local/Erlang/My App/1.2"
        • user_log

          The path location is intended for transient log files on a local machine.

          On Linux: Respects the os environment variable XDG_CACHE_HOME.

          4> filename:basedir(user_log, "my_application", #{os=>linux}).
          +"/home/otptest/.cache/my_application/log"

          On Darwin:

          4> filename:basedir(user_log, "my_application", #{os=>darwin}).
          +"/home/otptest/Library/Logs/my_application"

          On Windows:

          12> filename:basedir(user_log, "My App").
           "c:/Users/otptest/AppData/Local/My App/Logs"
          -13> filename:basedir(user_log, "My App",#{author=>"Erlang",version=>"1.2"}).
          -"c:/Users/otptest/AppData/Local/Erlang/My App/1.2/Logs"
        • site_config

          On Linux: Respects the os environment variable XDG_CONFIG_DIRS.

          5> filename:basedir(site_config, "my_application", #{os=>linux}).
          -["/usr/local/share/my_application",
          - "/usr/share/my_application"]
          -6> os:getenv("XDG_CONFIG_DIRS").
          +13> filename:basedir(user_log, "My App",#{author=>"Erlang",version=>"1.2"}).
          +"c:/Users/otptest/AppData/Local/Erlang/My App/1.2/Logs"
        • site_config

          On Linux: Respects the os environment variable XDG_CONFIG_DIRS.

          5> filename:basedir(site_config, "my_application", #{os=>linux}).
          +["/usr/local/share/my_application",
          + "/usr/share/my_application"]
          +6> os:getenv("XDG_CONFIG_DIRS").
           "/etc/xdg/xdg-ubuntu:/usr/share/upstart/xdg:/etc/xdg"
          -7> filename:basedir(site_config, "my_application", #{os=>linux}).
          -["/etc/xdg/xdg-ubuntu/my_application",
          +7> filename:basedir(site_config, "my_application", #{os=>linux}).
          +["/etc/xdg/xdg-ubuntu/my_application",
            "/usr/share/upstart/xdg/my_application",
          - "/etc/xdg/my_application"]
          -8> os:unsetenv("XDG_CONFIG_DIRS").
          + "/etc/xdg/my_application"]
          +8> os:unsetenv("XDG_CONFIG_DIRS").
           true
          -9> filename:basedir(site_config, "my_application", #{os=>linux}).
          -["/etc/xdg/my_application"]

          On Darwin:

          5> filename:basedir(site_config, "my_application", #{os=>darwin}).
          -["/Library/Application Support/my_application"]
        • site_data

          On Linux: Respects the os environment variable XDG_DATA_DIRS.

          10> os:getenv("XDG_DATA_DIRS").
          +9> filename:basedir(site_config, "my_application", #{os=>linux}).
          +["/etc/xdg/my_application"]

          On Darwin:

          5> filename:basedir(site_config, "my_application", #{os=>darwin}).
          +["/Library/Application Support/my_application"]
        • site_data

          On Linux: Respects the os environment variable XDG_DATA_DIRS.

          10> os:getenv("XDG_DATA_DIRS").
           "/usr/share/ubuntu:/usr/share/gnome:/usr/local/share/:/usr/share/"
          -11> filename:basedir(site_data, "my_application", #{os=>linux}).
          -["/usr/share/ubuntu/my_application",
          +11> filename:basedir(site_data, "my_application", #{os=>linux}).
          +["/usr/share/ubuntu/my_application",
            "/usr/share/gnome/my_application",
            "/usr/local/share/my_application",
          - "/usr/share/my_application"]
          -12> os:unsetenv("XDG_DATA_DIRS").
          + "/usr/share/my_application"]
          +12> os:unsetenv("XDG_DATA_DIRS").
           true
          -13> filename:basedir(site_data, "my_application", #{os=>linux}).
          -["/usr/local/share/my_application",
          - "/usr/share/my_application"]

          On Darwin:

          5> filename:basedir(site_data, "my_application", #{os=>darwin}).
          -["/Library/Application Support/my_application"]
        +13>
        filename:basedir(site_data, "my_application", #{os=>linux}). +["/usr/local/share/my_application", + "/usr/share/my_application"]

        On Darwin:

        5> filename:basedir(site_data, "my_application", #{os=>darwin}).
        +["/Library/Application Support/my_application"]
      @@ -759,12 +759,12 @@

      basename(Filename)

      Returns the last component of Filename, or Filename itself if it does not -contain any directory separators.

      Examples:

      5> filename:basename("foo").
      +contain any directory separators.

      Examples:

      5> filename:basename("foo").
       "foo"
      -6> filename:basename("/usr/foo").
      +6> filename:basename("/usr/foo").
       "foo"
      -7> filename:basename("/").
      -[]
      +7>
      filename:basename("/"). +[]
      @@ -795,15 +795,15 @@

      basename(Filename, Ext)

      Returns the last component of Filename with extension Ext stripped.

      This function is to be used to remove a (possible) specific extension. To remove an existing extension when you are unsure which one it is, use -rootname(basename(Filename)).

      Examples:

      8> filename:basename("~/src/kalle.erl", ".erl").
      +rootname(basename(Filename)).

      Examples:

      8> filename:basename("~/src/kalle.erl", ".erl").
       "kalle"
      -9> filename:basename("~/src/kalle.beam", ".erl").
      +9> filename:basename("~/src/kalle.beam", ".erl").
       "kalle.beam"
      -10> filename:basename("~/src/kalle.old.erl", ".erl").
      +10> filename:basename("~/src/kalle.old.erl", ".erl").
       "kalle.old"
      -11> filename:rootname(filename:basename("~/src/kalle.erl")).
      +11> filename:rootname(filename:basename("~/src/kalle.erl")).
       "kalle"
      -12> filename:rootname(filename:basename("~/src/kalle.beam")).
      +12> filename:rootname(filename:basename("~/src/kalle.beam")).
       "kalle"
      @@ -832,10 +832,10 @@

      dirname(Filename)

      -

      Returns the directory part of Filename.

      Examples:

      13> filename:dirname("/usr/src/kalle.erl").
      +

      Returns the directory part of Filename.

      Examples:

      13> filename:dirname("/usr/src/kalle.erl").
       "/usr/src"
      -14> filename:dirname("kalle.erl").
      -"."
      5> filename:dirname("\\usr\\src/kalle.erl"). % Windows
      +14> filename:dirname("kalle.erl").
      +"."
      5> filename:dirname("\\usr\\src/kalle.erl"). % Windows
       "/usr/src"
      @@ -865,10 +865,10 @@

      extension(Filename)

      Returns the file extension of Filename, including the period. Returns an empty -string if no extension exists.

      Examples:

      15> filename:extension("foo.erl").
      +string if no extension exists.

      Examples:

      15> filename:extension("foo.erl").
       ".erl"
      -16> filename:extension("beam.src/kalle").
      -[]
      +16>
      filename:extension("beam.src/kalle"). +[]
      @@ -928,10 +928,10 @@

      join(Components)

      Joins a list of filename Components with directory separators. If one of the elements of Components includes an absolute path, such as "/xxx", the preceding elements, if any, are removed from the result.

      The result is "normalized":

      • Redundant directory separators are removed.
      • In Windows, all directory separators are forward slashes and the drive letter -is in lower case.

      Examples:

      17> filename:join(["/usr", "local", "bin"]).
      +is in lower case.

    Examples:

    17> filename:join(["/usr", "local", "bin"]).
     "/usr/local/bin"
    -18> filename:join(["a/b///c/"]).
    -"a/b/c"
    6> filename:join(["B:a\\b///c/"]). % Windows
    +18> filename:join(["a/b///c/"]).
    +"a/b/c"
    6> filename:join(["B:a\\b///c/"]). % Windows
     "b:a/b/c"
    @@ -991,8 +991,8 @@

    nativename(Path)

    Converts Path to a form accepted by the command shell and native applications on the current platform. On Windows, forward slashes are converted to backward -slashes. On all platforms, the name is normalized as done by join/1.

    Examples:

    19> filename:nativename("/usr/local/bin/"). % Unix
    -"/usr/local/bin"
    7> filename:nativename("/usr/local/bin/"). % Windows
    +slashes. On all platforms, the name is normalized as done by join/1.

    Examples:

    19> filename:nativename("/usr/local/bin/"). % Unix
    +"/usr/local/bin"
    7> filename:nativename("/usr/local/bin/"). % Windows
     "\\usr\\local\\bin"
    @@ -1052,9 +1052,9 @@

    rootname(Filename)

    -

    Removes the filename extension.

    Examples:

    1> filename:rootname("/beam.src/kalle").
    +

    Removes the filename extension.

    Examples:

    1> filename:rootname("/beam.src/kalle").
     "/beam.src/kalle"
    -2> filename:rootname("/beam.src/foo.erl").
    +2> filename:rootname("/beam.src/foo.erl").
     "/beam.src/foo"
    @@ -1084,9 +1084,9 @@

    rootname(Filename, Ext)

    -

    Removes the filename extension Ext from Filename.

    Examples:

    1> filename:rootname("/beam.src/foo.erl", ".erl").
    +

    Removes the filename extension Ext from Filename.

    Examples:

    1> filename:rootname("/beam.src/foo.erl", ".erl").
     "/beam.src/foo"
    -2> filename:rootname("/beam.src/foo.beam", ".erl").
    +2> filename:rootname("/beam.src/foo.beam", ".erl").
     "/beam.src/foo.beam"
    @@ -1115,12 +1115,12 @@

    split(Filename)

    -

    Returns a list whose elements are the path components of Filename.

    Examples:

    24> filename:split("/usr/local/bin").
    -["/","usr","local","bin"]
    -25> filename:split("foo/bar").
    -["foo","bar"]
    -26> filename:split("a:\\msdev\\include").
    -["a:/","msdev","include"]
    +

    Returns a list whose elements are the path components of Filename.

    Examples:

    24> filename:split("/usr/local/bin").
    +["/","usr","local","bin"]
    +25> filename:split("foo/bar").
    +["foo","bar"]
    +26> filename:split("a:\\msdev\\include").
    +["a:/","msdev","include"]
    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/gen_event.html b/prs/8803/lib/stdlib-6.0.1/doc/html/gen_event.html index 5272cd8912483..76af26c6f57da 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/gen_event.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/gen_event.html @@ -1303,15 +1303,15 @@

    format_status(Status)

    but it may transform some values.

    Two possible use cases for this callback is to remove sensitive information from the state to prevent it from being printed in log files, or to compact large irrelevant status items -that would only clutter the logs.

    Example:

    format_status(Status) ->
    -  maps:map(
    -    fun(state,State) ->
    -            maps:remove(private_key, State);
    -       (message,{password, _Pass}) ->
    -            {password, removed};
    -       (_,Value) ->
    +that would only clutter the logs.

    Example:

    format_status(Status) ->
    +  maps:map(
    +    fun(state,State) ->
    +            maps:remove(private_key, State);
    +       (message,{password, _Pass}) ->
    +            {password, removed};
    +       (_,Value) ->
                 Value
    -    end, Status).

    Note

    This callback is optional, so event handler modules need not export it. + end, Status).

    Note

    This callback is optional, so event handler modules need not export it. If a handler does not export this function, the gen_event module uses the handler state directly for the purposes described below.

    If this callback is exported but fails, to hide possibly sensitive data, the default function will instead return the fact that diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/gen_fsm.html b/prs/8803/lib/stdlib-6.0.1/doc/html/gen_fsm.html index 4a37281e3d9a2..af510679dbabf 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/gen_fsm.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/gen_fsm.html @@ -135,163 +135,163 @@

    Migration to gen_statem

    Here follows a simple example of turning a gen_fsm into a gen_statem. -The example comes from the previous User's Guide for gen_fsm

    -module(code_lock).
    --define(NAME, code_lock).
    +The example comes from the previous User's Guide for gen_fsm

    -module(code_lock).
    +-define(NAME, code_lock).
     %-define(BEFORE_REWRITE, true).
     
    --ifdef(BEFORE_REWRITE).
    --behaviour(gen_fsm).
    +-ifdef(BEFORE_REWRITE).
    +-behaviour(gen_fsm).
     -else.
    --behaviour(gen_statem).
    +-behaviour(gen_statem).
     -endif.
     
    --export([start_link/1, button/1, stop/0]).
    +-export([start_link/1, button/1, stop/0]).
     
    --ifdef(BEFORE_REWRITE).
    --export([init/1, locked/2, open/2, handle_sync_event/4, handle_event/3,
    -     handle_info/3, terminate/3, code_change/4]).
    +-ifdef(BEFORE_REWRITE).
    +-export([init/1, locked/2, open/2, handle_sync_event/4, handle_event/3,
    +     handle_info/3, terminate/3, code_change/4]).
     -else.
    --export([init/1, callback_mode/0, locked/3, open/3,
    -     terminate/3, code_change/4]).
    +-export([init/1, callback_mode/0, locked/3, open/3,
    +     terminate/3, code_change/4]).
     %% Add callback__mode/0
     %% Change arity of the state functions
     %% Remove handle_info/3
     -endif.
     
    --ifdef(BEFORE_REWRITE).
    -start_link(Code) ->
    -    gen_fsm:start_link({local, ?NAME}, ?MODULE, Code, []).
    +-ifdef(BEFORE_REWRITE).
    +start_link(Code) ->
    +    gen_fsm:start_link({local, ?NAME}, ?MODULE, Code, []).
     -else.
    -start_link(Code) ->
    -    gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).
    +start_link(Code) ->
    +    gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).
     -endif.
     
    --ifdef(BEFORE_REWRITE).
    -button(Digit) ->
    -    gen_fsm:send_event(?NAME, {button, Digit}).
    +-ifdef(BEFORE_REWRITE).
    +button(Digit) ->
    +    gen_fsm:send_event(?NAME, {button, Digit}).
     -else.
    -button(Digit) ->
    -    gen_statem:cast(?NAME, {button,Digit}).
    +button(Digit) ->
    +    gen_statem:cast(?NAME, {button,Digit}).
         %% send_event is asynchronous and becomes a cast
     -endif.
     
    --ifdef(BEFORE_REWRITE).
    -stop() ->
    -    gen_fsm:sync_send_all_state_event(?NAME, stop).
    +-ifdef(BEFORE_REWRITE).
    +stop() ->
    +    gen_fsm:sync_send_all_state_event(?NAME, stop).
     -else.
    -stop() ->
    -    gen_statem:call(?NAME, stop).
    +stop() ->
    +    gen_statem:call(?NAME, stop).
         %% sync_send is synchronous and becomes call
         %% all_state is handled by callback code in gen_statem
     -endif.
     
    -init(Code) ->
    -    do_lock(),
    -    Data = #{code => Code, remaining => Code},
    -    {ok, locked, Data}.
    +init(Code) ->
    +    do_lock(),
    +    Data = #{code => Code, remaining => Code},
    +    {ok, locked, Data}.
     
    --ifdef(BEFORE_REWRITE).
    +-ifdef(BEFORE_REWRITE).
     -else.
    -callback_mode() ->
    +callback_mode() ->
         state_functions.
     %% state_functions mode is the mode most similar to
     %% gen_fsm. There is also handle_event mode which is
     %% a fairly different concept.
     -endif.
     
    --ifdef(BEFORE_REWRITE).
    -locked({button, Digit}, Data0) ->
    -    case analyze_lock(Digit, Data0) of
    -    {open = StateName, Data} ->
    -        {next_state, StateName, Data, 10000};
    -    {StateName, Data} ->
    -        {next_state, StateName, Data}
    +-ifdef(BEFORE_REWRITE).
    +locked({button, Digit}, Data0) ->
    +    case analyze_lock(Digit, Data0) of
    +    {open = StateName, Data} ->
    +        {next_state, StateName, Data, 10000};
    +    {StateName, Data} ->
    +        {next_state, StateName, Data}
         end.
     -else.
    -locked(cast, {button,Digit}, Data0) ->
    -    case analyze_lock(Digit, Data0) of
    -    {open = StateName, Data} ->
    -        {next_state, StateName, Data, 10000};
    -    {StateName, Data} ->
    -        {next_state, StateName, Data}
    +locked(cast, {button,Digit}, Data0) ->
    +    case analyze_lock(Digit, Data0) of
    +    {open = StateName, Data} ->
    +        {next_state, StateName, Data, 10000};
    +    {StateName, Data} ->
    +        {next_state, StateName, Data}
         end;
    -locked({call, From}, Msg, Data) ->
    -    handle_call(From, Msg, Data);
    -locked({info, Msg}, StateName, Data) ->
    -    handle_info(Msg, StateName, Data).
    +locked({call, From}, Msg, Data) ->
    +    handle_call(From, Msg, Data);
    +locked({info, Msg}, StateName, Data) ->
    +    handle_info(Msg, StateName, Data).
     %% Arity differs
     %% All state events are dispatched to handle_call and handle_info help
     %% functions. If you want to handle a call or cast event specifically
     %% for this state you would add a special clause for it above.
     -endif.
     
    --ifdef(BEFORE_REWRITE).
    -open(timeout, State) ->
    -     do_lock(),
    -    {next_state, locked, State};
    -open({button,_}, Data) ->
    -    {next_state, locked, Data}.
    +-ifdef(BEFORE_REWRITE).
    +open(timeout, State) ->
    +     do_lock(),
    +    {next_state, locked, State};
    +open({button,_}, Data) ->
    +    {next_state, locked, Data}.
     -else.
    -open(timeout, _, Data) ->
    -    do_lock(),
    -    {next_state, locked, Data};
    -open(cast, {button,_}, Data) ->
    -    {next_state, locked, Data};
    -open({call, From}, Msg, Data) ->
    -    handle_call(From, Msg, Data);
    -open(info, Msg, Data) ->
    -    handle_info(Msg, open, Data).
    +open(timeout, _, Data) ->
    +    do_lock(),
    +    {next_state, locked, Data};
    +open(cast, {button,_}, Data) ->
    +    {next_state, locked, Data};
    +open({call, From}, Msg, Data) ->
    +    handle_call(From, Msg, Data);
    +open(info, Msg, Data) ->
    +    handle_info(Msg, open, Data).
     %% Arity differs
     %% All state events are dispatched to handle_call and handle_info help
     %% functions. If you want to handle a call or cast event specifically
     %% for this state you would add a special clause for it above.
     -endif.
     
    --ifdef(BEFORE_REWRITE).
    -handle_sync_event(stop, _From, _StateName, Data) ->
    -    {stop, normal, ok, Data}.
    +-ifdef(BEFORE_REWRITE).
    +handle_sync_event(stop, _From, _StateName, Data) ->
    +    {stop, normal, ok, Data}.
     
    -handle_event(Event, StateName, Data) ->
    -    {stop, {shutdown, {unexpected, Event, StateName}}, Data}.
    +handle_event(Event, StateName, Data) ->
    +    {stop, {shutdown, {unexpected, Event, StateName}}, Data}.
     
    -handle_info(Info, StateName, Data) ->
    -    {stop, {shutdown, {unexpected, Info, StateName}}, StateName, Data}.
    +handle_info(Info, StateName, Data) ->
    +    {stop, {shutdown, {unexpected, Info, StateName}}, StateName, Data}.
     -else.
     -endif.
     
    -terminate(_Reason, State, _Data) ->
    -    State =/= locked andalso do_lock(),
    +terminate(_Reason, State, _Data) ->
    +    State =/= locked andalso do_lock(),
         ok.
    -code_change(_Vsn, State, Data, _Extra) ->
    -    {ok, State, Data}.
    +code_change(_Vsn, State, Data, _Extra) ->
    +    {ok, State, Data}.
     
     %% Internal functions
    --ifdef(BEFORE_REWRITE).
    +-ifdef(BEFORE_REWRITE).
     -else.
    -handle_call(From, stop, Data) ->
    -     {stop_and_reply, normal,  {reply, From, ok}, Data}.
    +handle_call(From, stop, Data) ->
    +     {stop_and_reply, normal,  {reply, From, ok}, Data}.
     
    -handle_info(Info, StateName, Data) ->
    -    {stop, {shutdown, {unexpected, Info, StateName}}, StateName, Data}.
    +handle_info(Info, StateName, Data) ->
    +    {stop, {shutdown, {unexpected, Info, StateName}}, StateName, Data}.
     %% These are internal functions for handling all state events
     %% and not behaviour callbacks as in gen_fsm
     -endif.
     
    -analyze_lock(Digit, #{code := Code, remaining := Remaining} = Data) ->
    +analyze_lock(Digit, #{code := Code, remaining := Remaining} = Data) ->
          case Remaining of
    -         [Digit] ->
    -         do_unlock(),
    -         {open,  Data#{remaining := Code}};
    -         [Digit|Rest] -> % Incomplete
    -             {locked, Data#{remaining := Rest}};
    +         [Digit] ->
    +         do_unlock(),
    +         {open,  Data#{remaining := Code}};
    +         [Digit|Rest] -> % Incomplete
    +             {locked, Data#{remaining := Rest}};
              _Wrong ->
    -             {locked, Data#{remaining := Code}}
    +             {locked, Data#{remaining := Code}}
          end.
     
    -do_lock() ->
    -    io:format("Lock~n", []).
    -do_unlock() ->
    -    io:format("Unlock~n", []).

    +do_lock() -> + io:format("Lock~n", []). +do_unlock() -> + io:format("Unlock~n", []).

    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/gen_server.html b/prs/8803/lib/stdlib-6.0.1/doc/html/gen_server.html index 45d49259e18d7..eb5bdcd499e82 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/gen_server.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/gen_server.html @@ -1279,15 +1279,15 @@

    format_status(Status)

    but it may transform some values.

    Two possible use cases for this callback is to remove sensitive information from the state to prevent it from being printed in log files, or to compact large irrelevant status items -that would only clutter the logs.

    Example:

    format_status(Status) ->
    -  maps:map(
    -    fun(state,State) ->
    -            maps:remove(private_key, State);
    -       (message,{password, _Pass}) ->
    -            {password, removed};
    -       (_,Value) ->
    +that would only clutter the logs.

    Example:

    format_status(Status) ->
    +  maps:map(
    +    fun(state,State) ->
    +            maps:remove(private_key, State);
    +       (message,{password, _Pass}) ->
    +            {password, removed};
    +       (_,Value) ->
                 Value
    -    end, Status).

    Note

    This callback is optional, so callback modules need not export it. The + end, Status).

    Note

    This callback is optional, so callback modules need not export it. The gen_server module provides a default implementation of this function that returns the callback module state.

    If this callback is exported but fails, to hide possibly sensitive data, diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/gen_statem.html b/prs/8803/lib/stdlib-6.0.1/doc/html/gen_statem.html index f0cc7fa84cd4a..f1cab429addc0 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/gen_statem.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/gen_statem.html @@ -176,7 +176,7 @@

    depending on callback mode Release upgrade/downgrade -(code change) +(code change) -----> Module:code_change/4

    State callback

    The state callback for a specific state in a gen_statem is the callback function that is called for all events in this state. It is selected depending on which callback mode @@ -302,97 +302,97 @@

    Pushbutton Code

    -

    The following is the complete callback module file pushbutton.erl:

    -module(pushbutton).
    --behaviour(gen_statem).
    +

    The following is the complete callback module file pushbutton.erl:

    -module(pushbutton).
    +-behaviour(gen_statem).
     
    --export([start/0,push/0,get_count/0,stop/0]).
    --export([terminate/3,code_change/4,init/1,callback_mode/0]).
    --export([on/3,off/3]).
    +-export([start/0,push/0,get_count/0,stop/0]).
    +-export([terminate/3,code_change/4,init/1,callback_mode/0]).
    +-export([on/3,off/3]).
     
    -name() -> pushbutton_statem. % The registered server name
    +name() -> pushbutton_statem. % The registered server name
     
     %% API.  This example uses a registered name name()
     %% and does not link to the caller.
    -start() ->
    -    gen_statem:start({local,name()}, ?MODULE, [], []).
    -push() ->
    -    gen_statem:call(name(), push).
    -get_count() ->
    -    gen_statem:call(name(), get_count).
    -stop() ->
    -    gen_statem:stop(name()).
    +start() ->
    +    gen_statem:start({local,name()}, ?MODULE, [], []).
    +push() ->
    +    gen_statem:call(name(), push).
    +get_count() ->
    +    gen_statem:call(name(), get_count).
    +stop() ->
    +    gen_statem:stop(name()).
     
     %% Mandatory callback functions
    -terminate(_Reason, _State, _Data) ->
    +terminate(_Reason, _State, _Data) ->
         void.
    -code_change(_Vsn, State, Data, _Extra) ->
    -    {ok,State,Data}.
    -init([]) ->
    +code_change(_Vsn, State, Data, _Extra) ->
    +    {ok,State,Data}.
    +init([]) ->
         %% Set the initial state + data.  Data is used only as a counter.
         State = off, Data = 0,
    -    {ok,State,Data}.
    -callback_mode() -> state_functions.
    +    {ok,State,Data}.
    +callback_mode() -> state_functions.
     
     %%% state callback(s)
     
    -off({call,From}, push, Data) ->
    +off({call,From}, push, Data) ->
         %% Go to 'on', increment count and reply
         %% that the resulting status is 'on'
    -    {next_state,on,Data+1,[{reply,From,on}]};
    -off(EventType, EventContent, Data) ->
    -    handle_event(EventType, EventContent, Data).
    +    {next_state,on,Data+1,[{reply,From,on}]};
    +off(EventType, EventContent, Data) ->
    +    handle_event(EventType, EventContent, Data).
     
    -on({call,From}, push, Data) ->
    +on({call,From}, push, Data) ->
         %% Go to 'off' and reply that the resulting status is 'off'
    -    {next_state,off,Data,[{reply,From,off}]};
    -on(EventType, EventContent, Data) ->
    -    handle_event(EventType, EventContent, Data).
    +    {next_state,off,Data,[{reply,From,off}]};
    +on(EventType, EventContent, Data) ->
    +    handle_event(EventType, EventContent, Data).
     
     %% Handle events common to all states
    -handle_event({call,From}, get_count, Data) ->
    +handle_event({call,From}, get_count, Data) ->
         %% Reply with the current count
    -    {keep_state,Data,[{reply,From,Data}]};
    -handle_event(_, _, Data) ->
    +    {keep_state,Data,[{reply,From,Data}]};
    +handle_event(_, _, Data) ->
         %% Ignore all other events
    -    {keep_state,Data}.

    The following is a shell session when running it:

    1> pushbutton:start().
    -{ok,<0.36.0>}
    -2> pushbutton:get_count().
    +    {keep_state,Data}.

    The following is a shell session when running it:

    1> pushbutton:start().
    +{ok,<0.36.0>}
    +2> pushbutton:get_count().
     0
    -3> pushbutton:push().
    +3> pushbutton:push().
     on
    -4> pushbutton:get_count().
    +4> pushbutton:get_count().
     1
    -5> pushbutton:push().
    +5> pushbutton:push().
     off
    -6> pushbutton:get_count().
    +6> pushbutton:get_count().
     1
    -7> pushbutton:stop().
    +7> pushbutton:stop().
     ok
    -8> pushbutton:push().
    +8> pushbutton:push().
     ** exception exit: {noproc,{gen_statem,call,[pushbutton_statem,push,infinity]}}
          in function  gen:do_for_proc/2 (gen.erl, line 261)
          in call from gen_statem:call/3 (gen_statem.erl, line 386)

    To compare styles, here follows the same example using callback mode handle_event_function, or rather, the code to replace after function init/1 -of the pushbutton.erl example file above:

    callback_mode() -> handle_event_function.
    +of the pushbutton.erl example file above:

    callback_mode() -> handle_event_function.
     
     %%% state callback(s)
     
    -handle_event({call,From}, push, off, Data) ->
    +handle_event({call,From}, push, off, Data) ->
         %% Go to 'on', increment count and reply
         %% that the resulting status is 'on'
    -    {next_state,on,Data+1,[{reply,From,on}]};
    -handle_event({call,From}, push, on, Data) ->
    +    {next_state,on,Data+1,[{reply,From,on}]};
    +handle_event({call,From}, push, on, Data) ->
         %% Go to 'off' and reply that the resulting status is 'off'
    -    {next_state,off,Data,[{reply,From,off}]};
    +    {next_state,off,Data,[{reply,From,off}]};
     %%
     %% Event handling common to all states
    -handle_event({call,From}, get_count, State, Data) ->
    +handle_event({call,From}, get_count, State, Data) ->
         %% Reply with the current count
    -    {next_state,State,Data,[{reply,From,Data}]};
    -handle_event(_, _, State, Data) ->
    +    {next_state,State,Data,[{reply,From,Data}]};
    +handle_event(_, _, State, Data) ->
         %% Ignore all other events
    -    {next_state,State,Data}.

    Note

    + {next_state,State,Data}.

    Note

    @@ -3177,15 +3177,15 @@

    format_status(Status)

    containing the same keys as the input map, but it may transform some values.

    One use case for this function is to return compact alternative state representations to avoid having large state terms printed in log files. -Another is to hide sensitive data from being written to the error log.

    Example:

    format_status(Status) ->
    -  maps:map(
    -    fun(state,State) ->
    -            maps:remove(private_key, State);
    -       (message,{password, _Pass}) ->
    -            {password, removed};
    -       (_,Value) ->
    +Another is to hide sensitive data from being written to the error log.

    Example:

    format_status(Status) ->
    +  maps:map(
    +    fun(state,State) ->
    +            maps:remove(private_key, State);
    +       (message,{password, _Pass}) ->
    +            {password, removed};
    +       (_,Value) ->
                 Value
    -    end, Status).

    Note

    This callback is optional, so a callback module does not need + end, Status).

    Note

    This callback is optional, so a callback module does not need to export it. The gen_statem module provides a default implementation of this function that returns {State, Data}.

    If this callback is exported but fails, to hide possibly sensitive data, the default function will instead return {State, Info}, @@ -3359,8 +3359,8 @@

    init(Args)

    to initialize the implementation state and server data.

    Args is the Args argument provided to that start function.

    Note

    Note that if the gen_statem is started through proc_lib and enter_loop/4,5,6, this callback will never be called. Since this callback is not optional -it can in that case be implemented as:

    -spec init(_) -> no_return().
    -init(Args) -> erlang:error(not_implemented, [Args]).
    +it can in that case be implemented as:

    -spec init(_) -> no_return().
    +init(Args) -> erlang:error(not_implemented, [Args]).
    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/io.html b/prs/8803/lib/stdlib-6.0.1/doc/html/io.html index eebccce2eae10..25aab9b19d2a0 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/io.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/io.html @@ -148,7 +148,7 @@

    Error Information

    The ErrorInfo mentioned in this module is the standard ErrorInfo structure -that is returned from all I/O modules. It has the following format:

    {ErrorLocation, Module, ErrorDescriptor}

    A string that describes the error is obtained with the following call:

    Module:format_error(ErrorDescriptor)
    +that is returned from all I/O modules. It has the following format:

    {ErrorLocation, Module, ErrorDescriptor}

    A string that describes the error is obtained with the following call:

    Module:format_error(ErrorDescriptor)
    @@ -1189,12 +1189,12 @@

    standard_io()

    no IoDevice argument is specified in the function calls in this module.

    It is sometimes desirable to use an explicit IoDevice argument that refers to the default I/O device. This is the case with functions that can access either a file or the default I/O device. The atom standard_io has this -special meaning. The following example illustrates this:

    27> io:read('enter>').
    +special meaning. The following example illustrates this:

    27> io:read('enter>').
     enter>foo.
    -{ok,foo}
    -28> io:read(standard_io, 'enter>').
    +{ok,foo}
    +28> io:read(standard_io, 'enter>').
     enter>bar.
    -{ok,bar}

    By default all I/O sent to standard_io will end up in the user +{ok,bar}

    By default all I/O sent to standard_io will end up in the user I/O device of the node that spawned the calling process.

    standard_io is an alias for group_leader/0, so in order to change where the default input/output requests are sent you can change the group leader of the current process using @@ -1469,33 +1469,33 @@

    fread(IoDevice, Prompt, Format)

    whitespace characters are stripped. An Erlang string (list of characters) is returned.

    If Unicode translation is in effect (~ts), characters > 255 are accepted, otherwise not. With the translation modifier, the returned list can as a -consequence also contain integers > 255:

    1> io:fread("Prompt> ","~s").
    +consequence also contain integers > 255:

    1> io:fread("Prompt> ","~s").
     Prompt> <Characters beyond latin1 range not printable in this medium>
    -{error,{fread,string}}
    -2> io:fread("Prompt> ","~ts").
    +{error,{fread,string}}
    +2> io:fread("Prompt> ","~ts").
     Prompt> <Characters beyond latin1 range not printable in this medium>
    -{ok,[[1091,1085,1080,1094,1086,1076,1077]]}
  • a - Similar to s, but the resulting string is converted into an +{ok,[[1091,1085,1080,1094,1086,1076,1077]]}

  • a - Similar to s, but the resulting string is converted into an atom.

  • c - The number of characters equal to the field width are read (default is 1) and returned as an Erlang string. However, leading and trailing whitespace characters are not omitted as they are with s. All -characters are returned.

    The Unicode translation modifier works as with s:

    1> io:fread("Prompt> ","~c").
    +characters are returned.

    The Unicode translation modifier works as with s:

    1> io:fread("Prompt> ","~c").
     Prompt> <Character beyond latin1 range not printable in this medium>
    -{error,{fread,string}}
    -2> io:fread("Prompt> ","~tc").
    +{error,{fread,string}}
    +2> io:fread("Prompt> ","~tc").
     Prompt> <Character beyond latin1 range not printable in this medium>
    -{ok,[[1091]]}
  • l - Returns the number of characters that have been scanned up to that +{ok,[[1091]]}

  • l - Returns the number of characters that have been scanned up to that point, including whitespace characters.

  • The function returns:
    • {ok, Terms} - The read was successful and Terms is the list of successfully matched and read items.

    • eof - End of file was encountered.

    • {error, FreadError} - The reading failed and FreadError gives a hint about the error.

    • {error, ErrorDescription} - The read operation failed and parameter -ErrorDescription gives a hint about the error.

    Examples:

    20> io:fread('enter>', "~f~f~f").
    +ErrorDescription gives a hint about the error.

    Examples:

    20> io:fread('enter>', "~f~f~f").
     enter>1.9 35.5e3 15.0
    -{ok,[1.9,3.55e4,15.0]}
    -21> io:fread('enter>', "~10f~d").
    +{ok,[1.9,3.55e4,15.0]}
    +21> io:fread('enter>', "~10f~d").
     enter>     5.67899
    -{ok,[5.678,99]}
    -22> io:fread('enter>', ":~10s:~10c:").
    +{ok,[5.678,99]}
    +22> io:fread('enter>', ":~10s:~10c:").
     enter>:   alan   :   joe    :
    -{ok, ["alan", "   joe    "]}
    +
    {ok, ["alan", " joe "]}
    @@ -1584,7 +1584,7 @@

    fwrite(IoDevice, Format, Data)

    the output device, and control sequences for formatting, see below. If Format is an atom or a binary, it is first converted to a list with the aid of atom_to_list/1 or -binary_to_list/1. Example:

    1> io:fwrite("Hello world!~n", []).
    +binary_to_list/1. Example:

    1> io:fwrite("Hello world!~n", []).
     Hello world!
     ok

    The general format of a control sequence is ~F.P.PadModC.

    The character C determines the type of control sequence to be used. It is the only required field. All of F, P, Pad, and Mod are optional. For @@ -1602,25 +1602,25 @@

    fwrite(IoDevice, Format, Data)

    padding character is ' ' (space).

  • Mod is the control sequence modifier. This is one or more characters that change the interpretation of Data.

    The current modifiers are:

    • t - For Unicode translation.

    • l - For stopping p and P from detecting printable characters.

    • k - For use with p, P, w, and W to format maps in map-key ordered order (see maps:iterator_order/0).

    • K - Similar to k, for formatting maps in map-key order, but takes an -extra argument that specifies the maps:iterator_order/0.

      For example:

      > M = #{ a => 1, b => 2 }.
      -#{a => 1,b => 2}
      -> io:format("~Kp~n", [reversed, M]).
      -#{b => 2,a => 1}
      +extra argument that specifies the maps:iterator_order/0.

      For example:

      > M = #{ a => 1, b => 2 }.
      +#{a => 1,b => 2}
      +> io:format("~Kp~n", [reversed, M]).
      +#{b => 2,a => 1}
       ok
  • If F, P, or Pad is a * character, the next argument in Data is used as -the value. For example:

    1> io:fwrite("~*.*.0f~n",[9, 5, 3.14159265]).
    +the value. For example:

    1> io:fwrite("~*.*.0f~n",[9, 5, 3.14159265]).
     003.14159
    -ok

    To use a literal * character as Pad, it must be passed as an argument:

    2> io:fwrite("~*.*.*f~n",[9, 5, $*, 3.14159265]).
    +ok

    To use a literal * character as Pad, it must be passed as an argument:

    2> io:fwrite("~*.*.*f~n",[9, 5, $*, 3.14159265]).
     **3.14159
     ok

    Available control sequences:

    • ~ - Character ~ is written.

    • c - The argument is a number that is interpreted as an ASCII code. The precision is the number of times the character is printed and defaults to the -field width, which in turn defaults to 1. Example:

      1> io:fwrite("|~10.5c|~-10.5c|~5c|~n", [$a, $b, $c]).
      +field width, which in turn defaults to 1. Example:

      1> io:fwrite("|~10.5c|~-10.5c|~5c|~n", [$a, $b, $c]).
       |     aaaaa|bbbbb     |ccccc|
       ok

      If the Unicode translation modifier (t) is in effect, the integer argument can be any number representing a valid Unicode codepoint, otherwise it is to -be an integer less than or equal to 255, otherwise it is masked with 16#FF:

      2> io:fwrite("~tc~n",[1024]).
      -\x{400}
      +be an integer less than or equal to 255, otherwise it is masked with 16#FF:

      2> io:fwrite("~tc~n",[1024]).
      +\x{400}
       ok
      -3> io:fwrite("~c~n",[1024]).
      +3> io:fwrite("~c~n",[1024]).
       ^@
       ok
    • f - The argument is a float that is written as [-]ddd.ddd, where the precision is the number of digits after the decimal point. The default @@ -1638,18 +1638,18 @@

      fwrite(IoDevice, Format, Data)

      binaries are in UTF-8. The characters are printed without quotes. The string is first truncated by the specified precision and then padded and justified to the specified field width. The default precision is the field width.

      This format can be used for printing any object and truncating the output so -it fits a specified field:

      1> io:fwrite("|~10w|~n", [{hey, hey, hey}]).
      +it fits a specified field:

      1> io:fwrite("|~10w|~n", [{hey, hey, hey}]).
       |**********|
       ok
      -2> io:fwrite("|~10s|~n", [io_lib:write({hey, hey, hey})]).
      -|{hey,hey,h|
      -3> io:fwrite("|~-10.8s|~n", [io_lib:write({hey, hey, hey})]).
      -|{hey,hey  |
      +2> io:fwrite("|~10s|~n", [io_lib:write({hey, hey, hey})]).
      +|{hey,hey,h|
      +3> io:fwrite("|~-10.8s|~n", [io_lib:write({hey, hey, hey})]).
      +|{hey,hey  |
       ok

      A list with integers > 255 is considered an error if the Unicode translation -modifier is not specified:

      4> io:fwrite("~ts~n",[[1024]]).
      -\x{400}
      +modifier is not specified:

      4> io:fwrite("~ts~n",[[1024]]).
      +\x{400}
       ok
      -5> io:fwrite("~s~n",[[1024]]).
      +5> io:fwrite("~s~n",[[1024]]).
       ** exception error: bad argument
            in function  io:format/3
               called as io:format(<0.53.0>,"~s~n",[[1024]])
    • w - Writes data with the standard syntax. This is used to output Erlang @@ -1660,122 +1660,122 @@

      fwrite(IoDevice, Format, Data)

      breaks terms whose printed representation is longer than one line into many lines and indents each line sensibly. Left-justification is not supported. It also tries to detect flat lists of printable characters and output these as -strings. For example:

      1> T = [{attributes,[[{id,age,1.50000},{mode,explicit},
      -{typename,"INTEGER"}], [{id,cho},{mode,explicit},{typename,'Cho'}]]},
      -{typename,'Person'},{tag,{'PRIVATE',3}},{mode,implicit}].
      +strings. For example:

      1> T = [{attributes,[[{id,age,1.50000},{mode,explicit},
      +{typename,"INTEGER"}], [{id,cho},{mode,explicit},{typename,'Cho'}]]},
      +{typename,'Person'},{tag,{'PRIVATE',3}},{mode,implicit}].
       ...
      -2> io:fwrite("~w~n", [T]).
      -[{attributes,[[{id,age,1.5},{mode,explicit},{typename,
      -[73,78,84,69,71,69,82]}],[{id,cho},{mode,explicit},{typena
      -me,'Cho'}]]},{typename,'Person'},{tag,{'PRIVATE',3}},{mode
      -,implicit}]
      +2> io:fwrite("~w~n", [T]).
      +[{attributes,[[{id,age,1.5},{mode,explicit},{typename,
      +[73,78,84,69,71,69,82]}],[{id,cho},{mode,explicit},{typena
      +me,'Cho'}]]},{typename,'Person'},{tag,{'PRIVATE',3}},{mode
      +,implicit}]
       ok
      -3> io:fwrite("~62p~n", [T]).
      -[{attributes,[[{id,age,1.5},
      -               {mode,explicit},
      -               {typename,"INTEGER"}],
      -              [{id,cho},{mode,explicit},{typename,'Cho'}]]},
      - {typename,'Person'},
      - {tag,{'PRIVATE',3}},
      - {mode,implicit}]
      +3> io:fwrite("~62p~n", [T]).
      +[{attributes,[[{id,age,1.5},
      +               {mode,explicit},
      +               {typename,"INTEGER"}],
      +              [{id,cho},{mode,explicit},{typename,'Cho'}]]},
      + {typename,'Person'},
      + {tag,{'PRIVATE',3}},
      + {mode,implicit}]
       ok

      The field width specifies the maximum line length. It defaults to 80. The precision specifies the initial indentation of the term. It defaults to the number of characters printed on this line in the same call to write/1 or -format/1,2,3. For example, using T above:

      4> io:fwrite("Here T = ~62p~n", [T]).
      -Here T = [{attributes,[[{id,age,1.5},
      -                        {mode,explicit},
      -                        {typename,"INTEGER"}],
      -                       [{id,cho},
      -                        {mode,explicit},
      -                        {typename,'Cho'}]]},
      -          {typename,'Person'},
      -          {tag,{'PRIVATE',3}},
      -          {mode,implicit}]
      +format/1,2,3. For example, using T above:

      4> io:fwrite("Here T = ~62p~n", [T]).
      +Here T = [{attributes,[[{id,age,1.5},
      +                        {mode,explicit},
      +                        {typename,"INTEGER"}],
      +                       [{id,cho},
      +                        {mode,explicit},
      +                        {typename,'Cho'}]]},
      +          {typename,'Person'},
      +          {tag,{'PRIVATE',3}},
      +          {mode,implicit}]
       ok

      As from Erlang/OTP 21.0, a field width of value 0 can be used for specifying that a line is infinitely long, which means that no line breaks are inserted. -For example:

      5> io:fwrite("~0p~n", [lists:seq(1, 30)]).
      -[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]
      +For example:

      5> io:fwrite("~0p~n", [lists:seq(1, 30)]).
      +[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]
       ok

      When the modifier l is specified, no detection of printable character lists -takes place, for example:

      6> S = [{a,"a"}, {b, "b"}],
      -   io:fwrite("~15p~n", [S]).
      -[{a,"a"},
      - {b,"b"}]
      +takes place, for example:

      6> S = [{a,"a"}, {b, "b"}],
      +   io:fwrite("~15p~n", [S]).
      +[{a,"a"},
      + {b,"b"}]
       ok
      -7> io:fwrite("~15lp~n", [S]).
      -[{a,[97]},
      - {b,[98]}]
      +7> io:fwrite("~15lp~n", [S]).
      +[{a,[97]},
      + {b,[98]}]
       ok

      The Unicode translation modifier t specifies how to treat characters outside the Latin-1 range of codepoints, in atoms, strings, and binaries. For example, -printing an atom containing a character > 255:

      8> io:fwrite("~p~n",[list_to_atom([1024])]).
      +printing an atom containing a character > 255:

      8> io:fwrite("~p~n",[list_to_atom([1024])]).
       '\x{400}'
       ok
      -9> io:fwrite("~tp~n",[list_to_atom([1024])]).
      +9> io:fwrite("~tp~n",[list_to_atom([1024])]).
       'Ѐ'
       ok

      By default, Erlang only detects lists of characters in the Latin-1 range as strings, but the +pc unicode flag can be used to change this (see -printable_range/0 for details). For example:

      10> io:fwrite("~p~n",[[214]]).
      +printable_range/0 for details). For example:

      10> io:fwrite("~p~n",[[214]]).
       "Ö"
       ok
      -11> io:fwrite("~p~n",[[1024]]).
      -[1024]
      +11> io:fwrite("~p~n",[[1024]]).
      +[1024]
       ok
      -12> io:fwrite("~tp~n",[[1024]]).
      -[1024]
      -ok

      but if Erlang was started with +pc unicode:

      13> io:fwrite("~p~n",[[1024]]).
      -[1024]
      +12> io:fwrite("~tp~n",[[1024]]).
      +[1024]
      +ok

      but if Erlang was started with +pc unicode:

      13> io:fwrite("~p~n",[[1024]]).
      +[1024]
       ok
      -14> io:fwrite("~tp~n",[[1024]]).
      +14> io:fwrite("~tp~n",[[1024]]).
       "Ѐ"
       ok

      Similarly, binaries that look like UTF-8 encoded strings are output with the -binary string syntax if the t modifier is specified:

      15> io:fwrite("~p~n", [<<208,128>>]).
      +binary string syntax if the t modifier is specified:

      15> io:fwrite("~p~n", [<<208,128>>]).
       <<208,128>>
       ok
      -16> io:fwrite("~tp~n", [<<208,128>>]).
      +16> io:fwrite("~tp~n", [<<208,128>>]).
       <<"Ѐ"/utf8>>
       ok
      -17> io:fwrite("~tp~n", [<<128,128>>]).
      +17> io:fwrite("~tp~n", [<<128,128>>]).
       <<128,128>>
       ok
    • W - Writes data in the same way as ~w, but takes an extra argument that is the maximum depth to which terms are printed. Anything below this -depth is replaced with .... For example, using T above:

      8> io:fwrite("~W~n", [T,9]).
      -[{attributes,[[{id,age,1.5},{mode,explicit},{typename,...}],
      -[{id,cho},{mode,...},{...}]]},{typename,'Person'},
      -{tag,{'PRIVATE',3}},{mode,implicit}]
      +depth is replaced with .... For example, using T above:

      8> io:fwrite("~W~n", [T,9]).
      +[{attributes,[[{id,age,1.5},{mode,explicit},{typename,...}],
      +[{id,cho},{mode,...},{...}]]},{typename,'Person'},
      +{tag,{'PRIVATE',3}},{mode,implicit}]
       ok

      If the maximum depth is reached, it cannot be read in the resultant output. Also, the ,... form in a tuple denotes that there are more elements in the tuple but these are below the print depth.

    • P - Writes data in the same way as ~p, but takes an extra argument that is the maximum depth to which terms are printed. Anything below this -depth is replaced with ..., for example:

      9> io:fwrite("~62P~n", [T,9]).
      -[{attributes,[[{id,age,1.5},{mode,explicit},{typename,...}],
      -              [{id,cho},{mode,...},{...}]]},
      - {typename,'Person'},
      - {tag,{'PRIVATE',3}},
      - {mode,implicit}]
      +depth is replaced with ..., for example:

      9> io:fwrite("~62P~n", [T,9]).
      +[{attributes,[[{id,age,1.5},{mode,explicit},{typename,...}],
      +              [{id,cho},{mode,...},{...}]]},
      + {typename,'Person'},
      + {tag,{'PRIVATE',3}},
      + {mode,implicit}]
       ok
    • B - Writes an integer in base 2-36, the default base is 10. A leading -dash is printed for negative integers.

      The precision field selects base, for example:

      1> io:fwrite("~.16B~n", [31]).
      +dash is printed for negative integers.

      The precision field selects base, for example:

      1> io:fwrite("~.16B~n", [31]).
       1F
       ok
      -2> io:fwrite("~.2B~n", [-19]).
      +2> io:fwrite("~.2B~n", [-19]).
       -10011
       ok
      -3> io:fwrite("~.36B~n", [5*36+35]).
      +3> io:fwrite("~.36B~n", [5*36+35]).
       5Z
       ok
    • X - Like B, but takes an extra argument that is a prefix to insert -before the number, but after the leading dash, if any.

      The prefix can be a possibly deep list of characters or an atom. Example:

      1> io:fwrite("~X~n", [31,"10#"]).
      +before the number, but after the leading dash, if any.

      The prefix can be a possibly deep list of characters or an atom. Example:

      1> io:fwrite("~X~n", [31,"10#"]).
       10#31
       ok
      -2> io:fwrite("~.16X~n", [-31,"0x"]).
      +2> io:fwrite("~.16X~n", [-31,"0x"]).
       -0x1F
       ok
    • # - Like B, but prints the number with an Erlang style #-separated -base prefix. Example:

      1> io:fwrite("~.10#~n", [31]).
      +base prefix. Example:

      1> io:fwrite("~.10#~n", [31]).
       10#31
       ok
      -2> io:fwrite("~.16#~n", [-31]).
      +2> io:fwrite("~.16#~n", [-31]).
       -16#1F
      -ok
    • b - Like B, but prints lowercase letters.

    • x - Like X, but prints lowercase letters.

    • + - Like #, but prints lowercase letters.

    • n - Writes a new line.

    • i - Ignores the next term.

    The function returns:

    • ok - The formatting succeeded.

    If an error occurs, there is no output. Example:

    1> io:fwrite("~s ~w ~i ~w ~c ~n",['abc def', 'abc def', {foo, 1},{foo, 1}, 65]).
    -abc def 'abc def'  {foo,1} A
    +ok
  • b - Like B, but prints lowercase letters.

  • x - Like X, but prints lowercase letters.

  • + - Like #, but prints lowercase letters.

  • n - Writes a new line.

  • i - Ignores the next term.

  • The function returns:

    • ok - The formatting succeeded.

    If an error occurs, there is no output. Example:

    1> io:fwrite("~s ~w ~i ~w ~c ~n",['abc def', 'abc def', {foo, 1},{foo, 1}, 65]).
    +abc def 'abc def'  {foo,1} A
     ok
    -2> io:fwrite("~s", [65]).
    +2> io:fwrite("~s", [65]).
     ** exception error: bad argument
          in function  io:format/3
             called as io:format(<0.53.0>,"~s","A")

    In this example, an attempt was made to output the single character 65 with the @@ -1972,20 +1972,20 @@

    getopts(IoDevice)

    -

    Requests all available options and their current values for a IoDevice.

    For example:

    1> {ok,F} = file:open("/dev/null",[read]).
    -{ok,<0.42.0>}
    -2> io:getopts(F).
    -[{binary,false},{encoding,latin1}]

    Here the file I/O server returns all available options for a file, which are the +

    Requests all available options and their current values for a IoDevice.

    For example:

    1> {ok,F} = file:open("/dev/null",[read]).
    +{ok,<0.42.0>}
    +2> io:getopts(F).
    +[{binary,false},{encoding,latin1}]

    Here the file I/O server returns all available options for a file, which are the expected ones, encoding and binary. However, the standard shell has some -more options:

    3> io:getopts().
    -[{expand_fun,#Fun<group.0.120017273>},
    - {echo,true},
    - {binary,false},
    - {encoding,unicode},
    - {terminal,true},
    - {stdout,true},
    - {stderr,true},
    - {stdin,true}]

    This example is, as can be seen, run in an environment where the terminal +more options:

    3> io:getopts().
    +[{expand_fun,#Fun<group.0.120017273>},
    + {echo,true},
    + {binary,false},
    + {encoding,unicode},
    + {terminal,true},
    + {stdout,true},
    + {stderr,true},
    + {stdin,true}]

    This example is, as can be seen, run in an environment where the terminal supports Unicode input and output.

    The stdin, stdout and stderr options are read only and indicates whether the stream is a terminal or not. When it is a terminal, most systems that Erlang runs on allows the use of ANSI escape codes @@ -2176,12 +2176,12 @@

    parse_erl_exprs(IoDevice, Prompt, StartLoca and parsed as if it was a sequence of Erlang expressions until a final dot (.) is reached.

    The function returns:

    • {ok, ExprList, EndLocation} - The parsing was successful.

    • {eof, EndLocation} - End of file was encountered by the tokenizer.

    • eof - End of file was encountered by the I/O server.

    • {error, ErrorInfo, ErrorLocation} - An error occurred while tokenizing or parsing.

    • {error, ErrorDescription} - Other (rare) error condition, such as -{error, estale} if reading from an NFS file system.

    Example:

    25> io:parse_erl_exprs('enter>').
    -enter>abc(), "hey".
    -{ok, [{call,1,{atom,1,abc},[]},{string,1,"hey"}],2}
    -26> io:parse_erl_exprs('enter>').
    -enter>abc("hey".
    -{error,{1,erl_parse,["syntax error before: ",["'.'"]]},2}
    +{error, estale} if reading from an NFS file system.

    Example:

    25> io:parse_erl_exprs('enter>').
    +enter>abc(), "hey".
    +{ok, [{call,1,{atom,1,abc},[]},{string,1,"hey"}],2}
    +26> io:parse_erl_exprs('enter>').
    +enter>abc("hey".
    +{error,{1,erl_parse,["syntax error before: ",["'.'"]]},2}

    @@ -2748,12 +2748,12 @@

    scan_erl_exprs(Device, Prompt, StartLocatio argument Options of function erl_scan:tokens/4. The data is tokenized as if it were a sequence of Erlang expressions until a final dot (.) is reached. This token is also returned.

    The function returns:

    • {ok, Tokens, EndLocation} - The tokenization succeeded.

    • {eof, EndLocation} - End of file was encountered by the tokenizer.

    • eof - End of file was encountered by the I/O server.

    • {error, ErrorInfo, ErrorLocation} - An error occurred while tokenizing.

    • {error, ErrorDescription} - Other (rare) error condition, such as -{error, estale} if reading from an NFS file system.

    Example:

    23> io:scan_erl_exprs('enter>').
    -enter>abc(), "hey".
    -{ok,[{atom,1,abc},{'(',1},{')',1},{',',1},{string,1,"hey"},{dot,1}],2}
    -24> io:scan_erl_exprs('enter>').
    +{error, estale} if reading from an NFS file system.

    Example:

    23> io:scan_erl_exprs('enter>').
    +enter>abc(), "hey".
    +{ok,[{atom,1,abc},{'(',1},{')',1},{',',1},{string,1,"hey"},{dot,1}],2}
    +24> io:scan_erl_exprs('enter>').
     enter>1.0er.
    -{error,{1,erl_scan,{illegal,float}},2}
    +
    {error,{1,erl_scan,{illegal,float}},2}

    @@ -2968,8 +2968,8 @@

    setopts(IoDevice, Opts)

    current input line. The list of possible expansions can be formatted in different ways to make more advanced expansion suggestions more readable to the user, see edlin_expand:expand/2 for documentation of that.

    Trivial example (beep on anything except empty line, which is expanded to -"quit"):

    fun("") -> {yes, "quit", []};
    -   (_) -> {no, "", ["quit"]} end

    This option is only supported by the standard shell (group.erl).

  • {encoding, latin1 | unicode} - Specifies how characters are input or +"quit"):

    fun("") -> {yes, "quit", []};
    +   (_) -> {no, "", ["quit"]} end

    This option is only supported by the standard shell (group.erl).

  • {encoding, latin1 | unicode} - Specifies how characters are input or output from or to the I/O device, implying that, for example, a terminal is set to handle Unicode input and output or a file is set to handle UTF-8 data encoding.

    The option does not affect how data is returned from the I/O functions or diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/io_lib.html b/prs/8803/lib/stdlib-6.0.1/doc/html/io_lib.html index 8a313d9277cc0..8cfd67c9de8a6 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/io_lib.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/io_lib.html @@ -1032,8 +1032,8 @@

    fread(Format, String)

    input is needed to complete the original format string. RestFormat is the remaining format string, Nchars is the number of characters scanned, and InputStack is the reversed list of inputs matched up to that point.

  • {error, What} - The read operation failed and parameter What gives a -hint about the error.

  • Example:

    3> io_lib:fread("~f~f~f", "15.6 17.3e-6 24.5").
    -{ok,[15.6,1.73e-5,24.5],[]}
    +hint about the error.

    Example:

    3> io_lib:fread("~f~f~f", "15.6 17.3e-6 24.5").
    +{ok,[15.6,1.73e-5,24.5],[]}
    @@ -1538,11 +1538,11 @@

    write(Term, DepthOrOptions)

    "...".

    Depth defaults to -1, which means no limitation. Option CharsLimit puts a soft limit on the number of characters returned. When the number of characters is reached, remaining structures are replaced by "...". CharsLimit defaults to -1, -which means no limit on the number of characters returned.

    Example:

    1> lists:flatten(io_lib:write({1,[2],[3],[4,5],6,7,8,9})).
    +which means no limit on the number of characters returned.

    Example:

    1> lists:flatten(io_lib:write({1,[2],[3],[4,5],6,7,8,9})).
     "{1,[2],[3],[4,5],6,7,8,9}"
    -2> lists:flatten(io_lib:write({1,[2],[3],[4,5],6,7,8,9}, 5)).
    +2> lists:flatten(io_lib:write({1,[2],[3],[4,5],6,7,8,9}, 5)).
     "{1,[2],[3],[...],...}"
    -3> lists:flatten(io_lib:write({[1,2,3],[4,5],6,7,8,9}, [{chars_limit,20}])).
    +3> lists:flatten(io_lib:write({[1,2,3],[4,5],6,7,8,9}, [{chars_limit,20}])).
     "{[1,2|...],[4|...],...}"
    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/io_protocol.html b/prs/8803/lib/stdlib-6.0.1/doc/html/io_protocol.html index ffa6a378b90c5..f11128fd55986 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/io_protocol.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/io_protocol.html @@ -146,8 +146,8 @@

    Protocol Basics

    As described in Robert's paper, I/O servers and clients communicate using -io_request/io_reply tuples as follows:

    {io_request, From, ReplyAs, Request}
    -{io_reply, ReplyAs, Reply}

    The client sends an io_request tuple to the I/O server and the server +io_request/io_reply tuples as follows:

    {io_request, From, ReplyAs, Request}
    +{io_reply, ReplyAs, Reply}

    The client sends an io_request tuple to the I/O server and the server eventually sends a corresponding io_reply tuple.

    • From is the pid/0 of the client, the process which the I/O server sends the I/O reply to.

    • ReplyAs can be any datum and is returned in the corresponding io_reply. The io module monitors the I/O server and uses the monitor reference as @@ -164,8 +164,8 @@

      Output Requests

      -

      To output characters on an I/O device, the following Requests exist:

      {put_chars, Encoding, Characters}
      -{put_chars, Encoding, Module, Function, Args}
      • Encoding is unicode or latin1, meaning that the characters are (in case +

        To output characters on an I/O device, the following Requests exist:

        {put_chars, Encoding, Characters}
        +{put_chars, Encoding, Module, Function, Args}
        • Encoding is unicode or latin1, meaning that the characters are (in case of binaries) encoded as UTF-8 or ISO Latin-1 (pure bytes). A well-behaved I/O server is also to return an error indication if list elements contain integers > 255 when Encoding is set to latin1.

          Notice that this does not in any way tell how characters are to be put on the @@ -184,14 +184,14 @@

          the function returns anything else than a binary or list, or throws an exception, an error is to be sent back to the client.

        The I/O server replies to the client with an io_reply tuple, where element Reply is one of:

        ok
        -{error, Error}
        • Error describes the error to the client, which can do whatever it wants with +{error, Error}
    • Error describes the error to the client, which can do whatever it wants with it. The io module typically returns it "as is".

    Input Requests

    -

    To read characters from an I/O device, the following Requests exist:

    {get_until, Encoding, Prompt, Module, Function, ExtraArgs}
    • Encoding denotes how data is to be sent back to the client and what data is +

      To read characters from an I/O device, the following Requests exist:

      {get_until, Encoding, Prompt, Module, Function, ExtraArgs}
      • Encoding denotes how data is to be sent back to the client and what data is sent to the function denoted by Module/Function/ExtraArgs. If the function supplied returns data as a list, the data is converted to this encoding. If the function supplied returns data in some other format, no @@ -207,8 +207,8 @@

        nothing being written to the I/O device).

      • Module, Function, and ExtraArgs denote a function and arguments to determine when enough data is written. The function is to take two more arguments, the last state, and a list of characters. The function is to return -one of:

        {done, Result, RestChars}
        -{more, Continuation}

        Result can be any Erlang term, but if it is a list/0, the I/O server can +one of:

        {done, Result, RestChars}
        +{more, Continuation}

        Result can be any Erlang term, but if it is a list/0, the I/O server can convert it to a binary/0 of appropriate format before returning it to the client, if the I/O server is set in binary mode (see below).

        The function is called with the data the I/O server finds on its I/O device, returning one of:

        • {done, Result, RestChars} when enough data is read. In this case Result @@ -218,38 +218,38 @@

          characters are available. When no more characters are available, the function must return {done, eof, Rest}. The initial state is the empty list. The data when an end of file is reached on the IO device is the atom eof.

          An emulation of the get_line request can be (inefficiently) implemented -using the following functions:

          -module(demo).
          --export([until_newline/3, get_line/1]).
          +using the following functions:

          -module(demo).
          +-export([until_newline/3, get_line/1]).
           
          -until_newline(_ThisFar,eof,_MyStopCharacter) ->
          -    {done,eof,[]};
          -until_newline(ThisFar,CharList,MyStopCharacter) ->
          +until_newline(_ThisFar,eof,_MyStopCharacter) ->
          +    {done,eof,[]};
          +until_newline(ThisFar,CharList,MyStopCharacter) ->
               case
          -        lists:splitwith(fun(X) -> X =/= MyStopCharacter end,  CharList)
          +        lists:splitwith(fun(X) -> X =/= MyStopCharacter end,  CharList)
               of
          -  {L,[]} ->
          -            {more,ThisFar++L};
          -  {L2,[MyStopCharacter|Rest]} ->
          -      {done,ThisFar++L2++[MyStopCharacter],Rest}
          +  {L,[]} ->
          +            {more,ThisFar++L};
          +  {L2,[MyStopCharacter|Rest]} ->
          +      {done,ThisFar++L2++[MyStopCharacter],Rest}
               end.
           
          -get_line(IoServer) ->
          -    IoServer ! {io_request,
          -                self(),
          +get_line(IoServer) ->
          +    IoServer ! {io_request,
          +                self(),
                           IoServer,
          -                {get_until, unicode, '', ?MODULE, until_newline, [$\n]}},
          +                {get_until, unicode, '', ?MODULE, until_newline, [$\n]}},
               receive
          -        {io_reply, IoServer, Data} ->
          +        {io_reply, IoServer, Data} ->
                 Data
               end.

          Notice that the last element in the Request tuple ([$\n]) is appended to the argument list when the function is called. The function is to be called like apply(Module, Function, [ State, Data | ExtraArgs ]) by -the I/O server.

        A fixed number of characters is requested using the following Request:

        {get_chars, Encoding, Prompt, N}
        • Encoding and Prompt as for get_until.
        • N is the number of characters to be read from the I/O device.

        A single line (as in former example) is requested with the following Request:

        {get_line, Encoding, Prompt}
        • Encoding and Prompt as for get_until.

        Clearly, get_chars and get_line could be implemented with the get_until +the I/O server.

      A fixed number of characters is requested using the following Request:

      {get_chars, Encoding, Prompt, N}
      • Encoding and Prompt as for get_until.
      • N is the number of characters to be read from the I/O device.

      A single line (as in former example) is requested with the following Request:

      {get_line, Encoding, Prompt}
      • Encoding and Prompt as for get_until.

      Clearly, get_chars and get_line could be implemented with the get_until request (and indeed they were originally), but demands for efficiency have made these additions necessary.

      The I/O server replies to the client with an io_reply tuple, where element Reply is one of:

      Data
       eof
      -{error, Error}
      • Data is the characters read, in list or binary form (depending on the I/O +{error, Error}
    • Data is the characters read, in list or binary form (depending on the I/O server mode, see the next section).
    • eof is returned when input end is reached and no more data is available to the client process.
    • Error describes the error to the client, which can do whatever it wants with it. The io module typically returns it as is.

    @@ -275,22 +275,22 @@

    This is done in the example in section An Annotated and Working Example I/O Server.

    An I/O server in binary mode affects the data sent to the client, so that it must be able to handle binary data. For convenience, the modes of an I/O server -can be set and retrieved using the following I/O requests:

    {setopts, Opts}
    • Opts is a list of options in the format recognized by the proplists +can be set and retrieved using the following I/O requests:

      {setopts, Opts}
      • Opts is a list of options in the format recognized by the proplists module (and by the I/O server).

      As an example, the I/O server for the interactive shell (in group.erl) -understands the following options:

      {binary, boolean()} (or binary/list)
      -{echo, boolean()}
      -{expand_fun, fun()}
      -{encoding, unicode/latin1} (or unicode/latin1)

      Options binary and encoding are common for all I/O servers in OTP, while +understands the following options:

      {binary, boolean()} (or binary/list)
      +{echo, boolean()}
      +{expand_fun, fun()}
      +{encoding, unicode/latin1} (or unicode/latin1)

      Options binary and encoding are common for all I/O servers in OTP, while echo and expand are valid only for this I/O server. Option unicode notifies how characters are put on the physical I/O device, that is, if the terminal itself is Unicode-aware. It does not affect how characters are sent in the I/O protocol, where each request contains encoding information for the provided or returned data.

      The I/O server is to send one of the following as Reply:

      ok
      -{error, Error}

      An error (preferably enotsup) is to be expected if the option is not supported +{error, Error}

    An error (preferably enotsup) is to be expected if the option is not supported by the I/O server (like if an echo option is sent in a setopts request to a plain file).

    To retrieve options, the following request is used:

    getopts

    This request asks for a complete list of all options supported by the I/O server as well as their current values.

    The I/O server replies:

    OptList
    -{error, Error}
    • OptList is a list of tuples {Option, Value}, where Option always is an +{error, Error}

    • OptList is a list of tuples {Option, Value}, where Option always is an atom.

    @@ -298,22 +298,22 @@

    Multiple I/O Requests

    The Request element can in itself contain many Requests by using the -following format:

    {requests, Requests}
    • Requests is a list of valid io_request tuples for the protocol. They must +following format:

      {requests, Requests}
      • Requests is a list of valid io_request tuples for the protocol. They must be executed in the order that they appear in the list. The execution is to continue until one of the requests results in an error or the list is consumed. The result of the last request is sent back to the client.

      The I/O server can, for a list of requests, send any of the following valid results in the reply, depending on the requests in the list:

      ok
      -{ok, Data}
      -{ok, Options}
      -{error, Error}

      +{ok, Data} +{ok, Options} +{error, Error}

    Optional I/O Request

    The following I/O request is optional to implement and a client is to be -prepared for an error return:

    {get_geometry, Geometry}
    • Geometry is the atom rows or the atom columns.

    The I/O server is to send one of the following as Reply:

    N
    -{error, Error}
    • N is the number of character rows or columns that the I/O device has, if +prepared for an error return:

      {get_geometry, Geometry}
      • Geometry is the atom rows or the atom columns.

      The I/O server is to send one of the following as Reply:

      N
      +{error, Error}
      • N is the number of character rows or columns that the I/O device has, if applicable to the I/O device handled by the I/O server, otherwise {error, enotsup} is a good answer.

      @@ -323,7 +323,7 @@

      If an I/O server encounters a request that it does not recognize (that is, the io_request tuple has the expected format, but the Request is unknown), the -I/O server is to send a valid reply with the error tuple:

      {error, request}

      This makes it possible to extend the protocol with optional requests and for the +I/O server is to send a valid reply with the error tuple:

      {error, request}

      This makes it possible to extend the protocol with optional requests and for the clients to be somewhat backward compatible.

      @@ -335,128 +335,128 @@

      process handling incoming requests, usually both I/O-requests and other I/O device-specific requests (positioning, closing, and so on).

      The example I/O server stores characters in an ETS table, making up a fairly crude RAM file.

      The module begins with the usual directives, a function to start the I/O server -and a main loop handling the requests:

      -module(ets_io_server).
      +and a main loop handling the requests:

      -module(ets_io_server).
       
      --export([start_link/0, init/0, loop/1, until_newline/3, until_enough/3]).
      +-export([start_link/0, init/0, loop/1, until_newline/3, until_enough/3]).
       
      --define(CHARS_PER_REC, 10).
      +-define(CHARS_PER_REC, 10).
       
      --record(state, {
      +-record(state, {
       	  table,
       	  position, % absolute
       	  mode % binary | list
      -	 }).
      +	 }).
       
      -start_link() ->
      -    spawn_link(?MODULE,init,[]).
      +start_link() ->
      +    spawn_link(?MODULE,init,[]).
       
      -init() ->
      -    Table = ets:new(noname,[ordered_set]),
      -    ?MODULE:loop(#state{table = Table, position = 0, mode=list}).
      +init() ->
      +    Table = ets:new(noname,[ordered_set]),
      +    ?MODULE:loop(#state{table = Table, position = 0, mode=list}).
       
      -loop(State) ->
      +loop(State) ->
           receive
      -	{io_request, From, ReplyAs, Request} ->
      -	    case request(Request,State) of
      -		{Tag, Reply, NewState} when Tag =:= ok; Tag =:= error ->
      -		    reply(From, ReplyAs, Reply),
      -		    ?MODULE:loop(NewState);
      -		{stop, Reply, _NewState} ->
      -		    reply(From, ReplyAs, Reply),
      -		    exit(Reply)
      +	{io_request, From, ReplyAs, Request} ->
      +	    case request(Request,State) of
      +		{Tag, Reply, NewState} when Tag =:= ok; Tag =:= error ->
      +		    reply(From, ReplyAs, Reply),
      +		    ?MODULE:loop(NewState);
      +		{stop, Reply, _NewState} ->
      +		    reply(From, ReplyAs, Reply),
      +		    exit(Reply)
       	    end;
       	%% Private message
      -	{From, rewind} ->
      -	    From ! {self(), ok},
      -	    ?MODULE:loop(State#state{position = 0});
      +	{From, rewind} ->
      +	    From ! {self(), ok},
      +	    ?MODULE:loop(State#state{position = 0});
       	_Unknown ->
      -	    ?MODULE:loop(State)
      +	    ?MODULE:loop(State)
           end.

      The main loop receives messages from the client (which can use the the io module to send requests). For each request, the function request/2 is called and a reply is eventually sent using function reply/3.

      The "private" message {From, rewind} results in the current position in the pseudo-file to be reset to 0 (the beginning of the "file"). This is a typical example of I/O device-specific messages not being part of the I/O protocol. It is usually a bad idea to embed such private messages in io_request tuples, as -that can confuse the reader.

      First, we examine the reply function:

      reply(From, ReplyAs, Reply) ->
      -    From ! {io_reply, ReplyAs, Reply}.

      It sends the io_reply tuple back to the client, providing element ReplyAs +that can confuse the reader.

      First, we examine the reply function:

      reply(From, ReplyAs, Reply) ->
      +    From ! {io_reply, ReplyAs, Reply}.

      It sends the io_reply tuple back to the client, providing element ReplyAs received in the request along with the result of the request, as described -earlier.

      We need to handle some requests. First the requests for writing characters:

      request({put_chars, Encoding, Chars}, State) ->
      -    put_chars(unicode:characters_to_list(Chars,Encoding),State);
      -request({put_chars, Encoding, Module, Function, Args}, State) ->
      +earlier.

      We need to handle some requests. First the requests for writing characters:

      request({put_chars, Encoding, Chars}, State) ->
      +    put_chars(unicode:characters_to_list(Chars,Encoding),State);
      +request({put_chars, Encoding, Module, Function, Args}, State) ->
           try
      -	request({put_chars, Encoding, apply(Module, Function, Args)}, State)
      +	request({put_chars, Encoding, apply(Module, Function, Args)}, State)
           catch
       	_:_ ->
      -	    {error, {error,Function}, State}
      +	    {error, {error,Function}, State}
           end;

      The Encoding says how the characters in the request are represented. We want to store the characters as lists in the ETS table, so we convert them to lists using function unicode:characters_to_list/2. The conversion function conveniently accepts the encoding types unicode and latin1, so we can use Encoding directly.

      When Module, Function, and Arguments are provided, we apply it and do the -same with the result as if the data was provided directly.

      We handle the requests for retrieving data:

      request({get_until, Encoding, _Prompt, M, F, As}, State) ->
      -    get_until(Encoding, M, F, As, State);
      -request({get_chars, Encoding, _Prompt, N}, State) ->
      +same with the result as if the data was provided directly.

      We handle the requests for retrieving data:

      request({get_until, Encoding, _Prompt, M, F, As}, State) ->
      +    get_until(Encoding, M, F, As, State);
      +request({get_chars, Encoding, _Prompt, N}, State) ->
           %% To simplify the code, get_chars is implemented using get_until
      -    get_until(Encoding, ?MODULE, until_enough, [N], State);
      -request({get_line, Encoding, _Prompt}, State) ->
      +    get_until(Encoding, ?MODULE, until_enough, [N], State);
      +request({get_line, Encoding, _Prompt}, State) ->
           %% To simplify the code, get_line is implemented using get_until
      -    get_until(Encoding, ?MODULE, until_newline, [$\n], State);

      Here we have cheated a little by more or less only implementing get_until and + get_until(Encoding, ?MODULE, until_newline, [$\n], State);

      Here we have cheated a little by more or less only implementing get_until and using internal helpers to implement get_chars and get_line. In production code, this can be inefficient, but that depends on the frequency of the different requests. Before we start implementing functions put_chars/2 and -get_until/5, we examine the few remaining requests:

      request({get_geometry,_}, State) ->
      -    {error, {error,enotsup}, State};
      -request({setopts, Opts}, State) ->
      -    setopts(Opts, State);
      -request(getopts, State) ->
      -    getopts(State);
      -request({requests, Reqs}, State) ->
      -     multi_request(Reqs, {ok, ok, State});

      Request get_geometry has no meaning for this I/O server, so the reply is +get_until/5, we examine the few remaining requests:

      request({get_geometry,_}, State) ->
      +    {error, {error,enotsup}, State};
      +request({setopts, Opts}, State) ->
      +    setopts(Opts, State);
      +request(getopts, State) ->
      +    getopts(State);
      +request({requests, Reqs}, State) ->
      +     multi_request(Reqs, {ok, ok, State});

      Request get_geometry has no meaning for this I/O server, so the reply is {error, enotsup}. The only option we handle is binary/list, which is done in separate functions.

      The multi-request tag (requests) is handled in a separate loop function -applying the requests in the list one after another, returning the last result.

      {error, request} must be returned if the request is not recognized:

      request(_Other, State) ->
      -    {error, {error, request}, State}.

      Next we handle the different requests, first the fairly generic multi-request -type:

      multi_request([R|Rs], {ok, _Res, State}) ->
      -    multi_request(Rs, request(R, State));
      -multi_request([_|_], Error) ->
      +applying the requests in the list one after another, returning the last result.

      {error, request} must be returned if the request is not recognized:

      request(_Other, State) ->
      +    {error, {error, request}, State}.

      Next we handle the different requests, first the fairly generic multi-request +type:

      multi_request([R|Rs], {ok, _Res, State}) ->
      +    multi_request(Rs, request(R, State));
      +multi_request([_|_], Error) ->
           Error;
      -multi_request([], Result) ->
      +multi_request([], Result) ->
           Result.

      We loop through the requests one at the time, stopping when we either encounter an error or the list is exhausted. The last return value is sent back to the client (it is first returned to the main loop and then sent back by function io_reply).

      Requests getopts and setopts are also simple to handle. We only change or -read the state record:

      setopts(Opts0,State) ->
      -    Opts = proplists:unfold(
      -	     proplists:substitute_negations(
      -	       [{list,binary}],
      -	       Opts0)),
      -    case check_valid_opts(Opts) of
      +read the state record:

      setopts(Opts0,State) ->
      +    Opts = proplists:unfold(
      +	     proplists:substitute_negations(
      +	       [{list,binary}],
      +	       Opts0)),
      +    case check_valid_opts(Opts) of
       	true ->
      -	        case proplists:get_value(binary, Opts) of
      +	        case proplists:get_value(binary, Opts) of
       		    true ->
      -			{ok,ok,State#state{mode=binary}};
      +			{ok,ok,State#state{mode=binary}};
       		    false ->
      -			{ok,ok,State#state{mode=binary}};
      +			{ok,ok,State#state{mode=binary}};
       		    _ ->
      -			{ok,ok,State}
      +			{ok,ok,State}
       		end;
       	false ->
      -	    {error,{error,enotsup},State}
      +	    {error,{error,enotsup},State}
           end.
      -check_valid_opts([]) ->
      +check_valid_opts([]) ->
           true;
      -check_valid_opts([{binary,Bool}|T]) when is_boolean(Bool) ->
      -    check_valid_opts(T);
      -check_valid_opts(_) ->
      +check_valid_opts([{binary,Bool}|T]) when is_boolean(Bool) ->
      +    check_valid_opts(T);
      +check_valid_opts(_) ->
           false.
       
      -getopts(#state{mode=M} = S) ->
      -    {ok,[{binary, case M of
      +getopts(#state{mode=M} = S) ->
      +    {ok,[{binary, case M of
       		      binary ->
       			  true;
       		      _ ->
       			  false
      -		  end}],S}.

      As a convention, all I/O servers handle both {setopts, [binary]}, + end}],S}.

      As a convention, all I/O servers handle both {setopts, [binary]}, {setopts, [list]}, and {setopts,[{binary, boolean()}]}, hence the trick with proplists:substitute_negations/2 and proplists:unfold/1. If invalid options are sent to us, we send {error, enotsup} back to the client.

      Request getopts is to return a list of {Option, Value} tuples. This has the @@ -464,50 +464,50 @@

      of this I/O server. We have only one option, and hence return that.

      So far this I/O server is fairly generic (except for request rewind handled in the main loop and the creation of an ETS table). Most I/O servers contain code similar to this one.

      To make the example runnable, we start implementing the reading and writing of -the data to/from the ETS table. First function put_chars/3:

      put_chars(Chars, #state{table = T, position = P} = State) ->
      +the data to/from the ETS table. First function put_chars/3:

      put_chars(Chars, #state{table = T, position = P} = State) ->
           R = P div ?CHARS_PER_REC,
           C = P rem ?CHARS_PER_REC,
      -    [ apply_update(T,U) || U <- split_data(Chars, R, C) ],
      -    {ok, ok, State#state{position = (P + length(Chars))}}.

      We already have the data as (Unicode) lists and therefore only split the list in + [ apply_update(T,U) || U <- split_data(Chars, R, C) ], + {ok, ok, State#state{position = (P + length(Chars))}}.

      We already have the data as (Unicode) lists and therefore only split the list in runs of a predefined size and put each run in the table at the current position (and forward). Functions split_data/3 and apply_update/2 are implemented below.

      Now we want to read data from the table. Function get_until/5 reads data and applies the function until it says that it is done. The result is sent back to -the client:

      get_until(Encoding, Mod, Func, As,
      -	  #state{position = P, mode = M, table = T} = State) ->
      -    case get_loop(Mod,Func,As,T,P,[]) of
      -	{done,Data,_,NewP} when is_binary(Data); is_list(Data) ->
      +the client:

      get_until(Encoding, Mod, Func, As,
      +	  #state{position = P, mode = M, table = T} = State) ->
      +    case get_loop(Mod,Func,As,T,P,[]) of
      +	{done,Data,_,NewP} when is_binary(Data); is_list(Data) ->
       	    if
       		M =:= binary ->
      -		    {ok,
      -		     unicode:characters_to_binary(Data, unicode, Encoding),
      -		     State#state{position = NewP}};
      +		    {ok,
      +		     unicode:characters_to_binary(Data, unicode, Encoding),
      +		     State#state{position = NewP}};
       		true ->
      -		    case check(Encoding,
      -		               unicode:characters_to_list(Data, unicode))
      +		    case check(Encoding,
      +		               unicode:characters_to_list(Data, unicode))
                           of
      -			{error, _} = E ->
      -			    {error, E, State};
      +			{error, _} = E ->
      +			    {error, E, State};
       			List ->
      -			    {ok, List,
      -			     State#state{position = NewP}}
      +			    {ok, List,
      +			     State#state{position = NewP}}
       		    end
       	    end;
      -	{done,Data,_,NewP} ->
      -	    {ok, Data, State#state{position = NewP}};
      +	{done,Data,_,NewP} ->
      +	    {ok, Data, State#state{position = NewP}};
       	Error ->
      -	    {error, Error, State}
      +	    {error, Error, State}
           end.
       
      -get_loop(M,F,A,T,P,C) ->
      -    {NewP,L} = get(P,T),
      -    case catch apply(M,F,[C,L|A]) of
      -	{done, List, Rest} ->
      -	    {done, List, [], NewP - length(Rest)};
      -	{more, NewC} ->
      -	    get_loop(M,F,A,T,NewP,NewC);
      +get_loop(M,F,A,T,P,C) ->
      +    {NewP,L} = get(P,T),
      +    case catch apply(M,F,[C,L|A]) of
      +	{done, List, Rest} ->
      +	    {done, List, [], NewP - length(Rest)};
      +	{more, NewC} ->
      +	    get_loop(M,F,A,T,NewP,NewC);
       	_ ->
      -	    {error,F}
      +	    {error,F}
           end.

      Here we also handle the mode (binary or list) that can be set by request setopts. By default, all OTP I/O servers send data back to the client as lists, but switching mode to binary can increase efficiency if the I/O server @@ -524,80 +524,80 @@

      is only to get characters in the range 0..255. Function check/2 takes care of not returning arbitrary Unicode code points in lists if the encoding was specified as latin1. If the function does not return a list, the check cannot -be performed and the result is that of the supplied function untouched.

      To manipulate the table we implement the following utility functions:

      check(unicode, List) ->
      +be performed and the result is that of the supplied function untouched.

      To manipulate the table we implement the following utility functions:

      check(unicode, List) ->
           List;
      -check(latin1, List) ->
      +check(latin1, List) ->
           try
      -	[ throw(not_unicode) || X <- List,
      -				X > 255 ],
      +	[ throw(not_unicode) || X <- List,
      +				X > 255 ],
       	List
           catch
       	throw:_ ->
      -	    {error,{cannot_convert, unicode, latin1}}
      +	    {error,{cannot_convert, unicode, latin1}}
           end.

      The function check provides an error tuple if Unicode code points > 255 are to be returned if the client requested latin1.

      The two functions until_newline/3 and until_enough/3 are helpers used together with function get_until/5 to implement get_chars and get_line -(inefficiently):

      until_newline([],eof,_MyStopCharacter) ->
      -    {done,eof,[]};
      -until_newline(ThisFar,eof,_MyStopCharacter) ->
      -    {done,ThisFar,[]};
      -until_newline(ThisFar,CharList,MyStopCharacter) ->
      +(inefficiently):

      until_newline([],eof,_MyStopCharacter) ->
      +    {done,eof,[]};
      +until_newline(ThisFar,eof,_MyStopCharacter) ->
      +    {done,ThisFar,[]};
      +until_newline(ThisFar,CharList,MyStopCharacter) ->
           case
      -        lists:splitwith(fun(X) -> X =/= MyStopCharacter end,  CharList)
      +        lists:splitwith(fun(X) -> X =/= MyStopCharacter end,  CharList)
           of
      -	{L,[]} ->
      -            {more,ThisFar++L};
      -	{L2,[MyStopCharacter|Rest]} ->
      -	    {done,ThisFar++L2++[MyStopCharacter],Rest}
      +	{L,[]} ->
      +            {more,ThisFar++L};
      +	{L2,[MyStopCharacter|Rest]} ->
      +	    {done,ThisFar++L2++[MyStopCharacter],Rest}
           end.
       
      -until_enough([],eof,_N) ->
      -    {done,eof,[]};
      -until_enough(ThisFar,eof,_N) ->
      -    {done,ThisFar,[]};
      -until_enough(ThisFar,CharList,N)
      -  when length(ThisFar) + length(CharList) >= N ->
      -    {Res,Rest} = my_split(N,ThisFar ++ CharList, []),
      -    {done,Res,Rest};
      -until_enough(ThisFar,CharList,_N) ->
      -    {more,ThisFar++CharList}.

      As can be seen, the functions above are just the type of functions that are to +until_enough([],eof,_N) -> + {done,eof,[]}; +until_enough(ThisFar,eof,_N) -> + {done,ThisFar,[]}; +until_enough(ThisFar,CharList,N) + when length(ThisFar) + length(CharList) >= N -> + {Res,Rest} = my_split(N,ThisFar ++ CharList, []), + {done,Res,Rest}; +until_enough(ThisFar,CharList,_N) -> + {more,ThisFar++CharList}.

      As can be seen, the functions above are just the type of functions that are to be provided in get_until requests.

      To complete the I/O server, we only need to read and write the table in an -appropriate way:

      get(P,Tab) ->
      +appropriate way:

      get(P,Tab) ->
           R = P div ?CHARS_PER_REC,
           C = P rem ?CHARS_PER_REC,
      -    case ets:lookup(Tab,R) of
      -	[] ->
      -	    {P,eof};
      -	[{R,List}] ->
      -	    case my_split(C,List,[]) of
      -		{_,[]} ->
      -		    {P+length(List),eof};
      -		{_,Data} ->
      -		    {P+length(Data),Data}
      +    case ets:lookup(Tab,R) of
      +	[] ->
      +	    {P,eof};
      +	[{R,List}] ->
      +	    case my_split(C,List,[]) of
      +		{_,[]} ->
      +		    {P+length(List),eof};
      +		{_,Data} ->
      +		    {P+length(Data),Data}
       	    end
           end.
       
      -my_split(0,Left,Acc) ->
      -    {lists:reverse(Acc),Left};
      -my_split(_,[],Acc) ->
      -    {lists:reverse(Acc),[]};
      -my_split(N,[H|T],Acc) ->
      -    my_split(N-1,T,[H|Acc]).
      -
      -split_data([],_,_) ->
      -    [];
      -split_data(Chars, Row, Col) ->
      -    {This,Left} = my_split(?CHARS_PER_REC - Col, Chars, []),
      -    [ {Row, Col, This} | split_data(Left, Row + 1, 0) ].
      -
      -apply_update(Table, {Row, Col, List}) ->
      -    case ets:lookup(Table,Row) of
      -	[] ->
      -	    ets:insert(Table,{Row, lists:duplicate(Col,0) ++ List});
      -	[{Row, OldData}] ->
      -	    {Part1,_} = my_split(Col,OldData,[]),
      -	    {_,Part2} = my_split(Col+length(List),OldData,[]),
      -	    ets:insert(Table,{Row, Part1 ++ List ++ Part2})
      +my_split(0,Left,Acc) ->
      +    {lists:reverse(Acc),Left};
      +my_split(_,[],Acc) ->
      +    {lists:reverse(Acc),[]};
      +my_split(N,[H|T],Acc) ->
      +    my_split(N-1,T,[H|Acc]).
      +
      +split_data([],_,_) ->
      +    [];
      +split_data(Chars, Row, Col) ->
      +    {This,Left} = my_split(?CHARS_PER_REC - Col, Chars, []),
      +    [ {Row, Col, This} | split_data(Left, Row + 1, 0) ].
      +
      +apply_update(Table, {Row, Col, List}) ->
      +    case ets:lookup(Table,Row) of
      +	[] ->
      +	    ets:insert(Table,{Row, lists:duplicate(Col,0) ++ List});
      +	[{Row, OldData}] ->
      +	    {Part1,_} = my_split(Col,OldData,[]),
      +	    {_,Part2} = my_split(Col+length(List),OldData,[]),
      +	    ets:insert(Table,{Row, Part1 ++ List ++ Part2})
           end.

      The table is read or written in chunks of ?CHARS_PER_REC, overwriting when necessary. The implementation is clearly not efficient, it is just working.

      This concludes the example. It is fully runnable and you can read or write to the I/O server by using, for example, the io module or even the file diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/json.html b/prs/8803/lib/stdlib-6.0.1/doc/html/json.html index 9c7d0a93e8976..d1d525f1beecf 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/json.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/json.html @@ -991,8 +991,8 @@

      decode(Binary)

      Example

      -
      > json:decode(<<"{\"foo\": 1}">>).
      -#{<<"foo">> => 1}
      +
      > json:decode(<<"{\"foo\": 1}">>).
      +#{<<"foo">> => 1}
      @@ -1044,9 +1044,9 @@

      decode(Binary, Acc0, Decoders)

      Example

      -

      Decoding object keys as atoms:

      > Push = fun(Key, Value, Acc) -> [{binary_to_existing_atom(Key), Value} | Acc] end.
      -> json:decode(<<"{\"foo\": 1}">>, ok, #{object_push => Push}).
      -{#{foo => 1},ok,<<>>}
      +

      Decoding object keys as atoms:

      > Push = fun(Key, Value, Acc) -> [{binary_to_existing_atom(Key), Value} | Acc] end.
      +> json:decode(<<"{\"foo\": 1}">>, ok, #{object_push => Push}).
      +{#{foo => 1},ok,<<>>}
      @@ -1079,11 +1079,11 @@

      decode_continue/2

      Continue parsing a stream of bytes of a JSON value.

      Similar to decode_start/3, if the function returns {continue, State} and -there is no more data, use end_of_input instead of a binary.

      > {continue, State} = json:decode_start(<<"{\"foo\":">>, ok, #{}).
      -> json:decode_continue(<<"1}">>, State).
      -{#{foo => 1},ok,<<>>}
      > {continue, State} = json:decode_start(<<"123">>, ok, #{}).
      -> json:decode_continue(end_of_input, State).
      -{123,ok,<<>>}
      +there is no more data, use end_of_input instead of a binary.

      > {continue, State} = json:decode_start(<<"{\"foo\":">>, ok, #{}).
      +> json:decode_continue(<<"1}">>, State).
      +{#{foo => 1},ok,<<>>}
      > {continue, State} = json:decode_start(<<"123">>, ok, #{}).
      +> json:decode_continue(end_of_input, State).
      +{123,ok,<<>>}
      @@ -1153,7 +1153,7 @@

      encode(Term)

      Examples

      -
      > iolist_to_binary(json:encode(#{foo => <<"bar">>})).
      +
      > iolist_to_binary(json:encode(#{foo => <<"bar">>})).
       <<"{\"foo\":\"bar\"}">>
      @@ -1195,10 +1195,10 @@

      encode(Term, Encoder)

      Examples

      An encoder that uses a heuristic to differentiate object-like -lists of key-value pairs from plain lists:

      > encoder([{_, _} | _] = Value, Encode) -> json:encode_key_value_list(Value, Encode);
      -> encoder(Other, Encode) -> json:encode_value(Other, Encode).
      -> custom_encode(Value) -> json:encode(Value, fun(Value, Encode) -> encoder(Value, Encode) end).
      -> iolist_to_binary(custom_encode([{a, []}, {b, 1}])).
      +lists of key-value pairs from plain lists:

      > encoder([{_, _} | _] = Value, Encode) -> json:encode_key_value_list(Value, Encode);
      +> encoder(Other, Encode) -> json:encode_value(Other, Encode).
      +> custom_encode(Value) -> json:encode(Value, fun(Value, Encode) -> encoder(Value, Encode) end).
      +> iolist_to_binary(custom_encode([{a, []}, {b, 1}])).
       <<"{\"a\":[],\"b\":1}">>
      @@ -1590,11 +1590,11 @@

      format(Term)

      -

      Generates formatted JSON corresponding to Term.

      Similiar to encode/1 but with added whitespaces for formatting.

      > io:put_chars(json:format(#{foo => <<"bar">>, baz => 52})).
      -{
      +

      Generates formatted JSON corresponding to Term.

      Similiar to encode/1 but with added whitespaces for formatting.

      > io:put_chars(json:format(#{foo => <<"bar">>, baz => 52})).
      +{
         "baz": 52,
         "foo": "bar"
      -}
      +}
       ok
      @@ -1659,20 +1659,20 @@

      format(Term, Encoder, Options)

      Generates formatted JSON corresponding to Term.

      Similar to encode/2, can be customised with the Encoder callback and Options.

      Options can include 'indent' to specify number of spaces per level and 'max' which loosely limits the width of lists.

      The Encoder will get a 'State' argument which contains the 'Options' maps merged with other data when recursing through 'Term'.

      format_value/3 or various encode_* functions in this module can be used -to help in constructing such callbacks.

      > formatter({posix_time, SysTimeSecs}, Encode, State) ->
      -    TimeStr = calendar:system_time_to_rfc3339(SysTimeSecs, [{offset, "Z"}]),
      -    json:format_value(unicode:characters_to_binary(TimeStr), Encode, State);
      -> formatter(Other, Encode, State) -> json:format_value(Other, Encode, State).
      +to help in constructing such callbacks.

      > formatter({posix_time, SysTimeSecs}, Encode, State) ->
      +    TimeStr = calendar:system_time_to_rfc3339(SysTimeSecs, [{offset, "Z"}]),
      +    json:format_value(unicode:characters_to_binary(TimeStr), Encode, State);
      +> formatter(Other, Encode, State) -> json:format_value(Other, Encode, State).
       >
      -> Fun = fun(Value, Encode, State) -> formatter(Value, Encode, State) end.
      -> Options = #{indent => 4}.
      -> Term = #{id => 1, time => {posix_time, erlang:system_time(seconds)}}.
      +> Fun = fun(Value, Encode, State) -> formatter(Value, Encode, State) end.
      +> Options = #{indent => 4}.
      +> Term = #{id => 1, time => {posix_time, erlang:system_time(seconds)}}.
       >
      -> io:put_chars(json:format(Term, Fun, Options)).
      -{
      +> io:put_chars(json:format(Term, Fun, Options)).
      +{
           "id": 1,
           "time": "2024-05-23T16:07:48Z"
      -}
      +}
       ok
      diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/lists.html b/prs/8803/lib/stdlib-6.0.1/doc/html/lists.html index 785db1c74daf9..e2decbcd824bb 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/lists.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/lists.html @@ -1167,8 +1167,8 @@

      append(ListOfLists)

      -

      Returns a list in which all the sublists of ListOfLists have been appended.

      Example:

      > lists:append([[1, 2, 3], [a, b], [4, 5, 6]]).
      -[1,2,3,a,b,4,5,6]
      +

      Returns a list in which all the sublists of ListOfLists have been appended.

      Example:

      > lists:append([[1, 2, 3], [a, b], [4, 5, 6]]).
      +[1,2,3,a,b,4,5,6]
      @@ -1197,7 +1197,7 @@

      append(List1, List2)

      Returns a new list List3, which is made from the elements of List1 followed -by the elements of List2.

      Example:

      > lists:append("abc", "def").
      +by the elements of List2.

      Example:

      > lists:append("abc", "def").
       "abcdef"

      lists:append(A, B) is equivalent to A ++ B.

      @@ -1228,7 +1228,7 @@

      concat(Things)

      Concatenates the text representation of the elements of Things. The elements -of Things can be atoms, integers, floats, or strings.

      Example:

      > lists:concat([doc, '/', file, '.', 3]).
      +of Things can be atoms, integers, floats, or strings.

      Example:

      > lists:concat([doc, '/', file, '.', 3]).
       "doc/file.3"
      @@ -1347,8 +1347,8 @@

      duplicate(N, Elem)

      -

      Returns a list containing N copies of term Elem.

      Example:

      > lists:duplicate(5, xx).
      -[xx,xx,xx,xx,xx]
      +

      Returns a list containing N copies of term Elem.

      Example:

      > lists:duplicate(5, xx).
      +[xx,xx,xx,xx,xx]
      @@ -1449,12 +1449,12 @@

      enumerate(Index, Step, List1)

      Returns List1 with each element H replaced by a tuple of form {I, H} where I is the position of H in List1. The enumeration starts with Index and increases by Step in each step.

      That is, enumerate/3 behaves as if it had been defined as -follows:

      enumerate(I, S, List) ->
      -  {List1, _ } = lists:mapfoldl(fun(T, Acc) -> {{Acc, T}, Acc+S} end, I, List),
      -  List1.

      The default values for Index and Step are both 1.

      Examples:

      > lists:enumerate([a,b,c]).
      -[{1,a},{2,b},{3,c}]
      > lists:enumerate(10, [a,b,c]).
      -[{10,a},{11,b},{12,c}]
      > lists:enumerate(0, -2, [a,b,c]).
      -[{0,a},{-2,b},{-4,c}]
      +follows:

      enumerate(I, S, List) ->
      +  {List1, _ } = lists:mapfoldl(fun(T, Acc) -> {{Acc, T}, Acc+S} end, I, List),
      +  List1.

      The default values for Index and Step are both 1.

      Examples:

      > lists:enumerate([a,b,c]).
      +[{1,a},{2,b},{3,c}]
      > lists:enumerate(10, [a,b,c]).
      +[{10,a},{11,b},{12,c}]
      > lists:enumerate(0, -2, [a,b,c]).
      +[{0,a},{-2,b},{-4,c}]
      @@ -1523,15 +1523,15 @@

      filtermap(Fun, List1)

      Calls Fun(Elem) on successive elements Elem of List1 in order to update or remove elements from List1.

      Fun/1 must return either a Boolean or a tuple {true, Value}. The function returns the list of elements for which Fun returns a new value, where a value -of true is synonymous with {true, Elem}.

      That is, filtermap behaves as if it had been defined as follows:

      filtermap(Fun, List1) ->
      -    lists:foldr(fun(Elem, Acc) ->
      -                       case Fun(Elem) of
      +of true is synonymous with {true, Elem}.

      That is, filtermap behaves as if it had been defined as follows:

      filtermap(Fun, List1) ->
      +    lists:foldr(fun(Elem, Acc) ->
      +                       case Fun(Elem) of
                                  false -> Acc;
      -                           true -> [Elem|Acc];
      -                           {true,Value} -> [Value|Acc]
      +                           true -> [Elem|Acc];
      +                           {true,Value} -> [Value|Acc]
                              end
      -                end, [], List1).

      Example:

      > lists:filtermap(fun(X) -> case X rem 2 of 0 -> {true, X div 2}; _ -> false end end, [1,2,3,4,5]).
      -[1,2]
      +
      end, [], List1).

      Example:

      > lists:filtermap(fun(X) -> case X rem 2 of 0 -> {true, X div 2}; _ -> false end end, [1,2,3,4,5]).
      +[1,2]
      @@ -1590,9 +1590,9 @@

      flatmap(Fun, List1)

      Takes a function from As to lists of Bs, and a list of As (List1) and produces a list of Bs by applying the function to every element in List1 and -appending the resulting lists.

      That is, flatmap behaves as if it had been defined as follows:

      flatmap(Fun, List1) ->
      -    append(map(Fun, List1)).

      Example:

      > lists:flatmap(fun(X)->[X,X] end, [a,b,c]).
      -[a,a,b,b,c,c]
      +appending the resulting lists.

      That is, flatmap behaves as if it had been defined as follows:

      flatmap(Fun, List1) ->
      +    append(map(Fun, List1)).

      Example:

      > lists:flatmap(fun(X)->[X,X] end, [a,b,c]).
      +[a,a,b,b,c,c]
      @@ -1688,9 +1688,9 @@

      foldl(Fun, Acc0, List)

      Calls Fun(Elem, AccIn) on successive elements A of List, starting with AccIn == Acc0. Fun/2 must return a new accumulator, which is passed to the next call. The function returns the final value of the accumulator. Acc0 is -returned if the list is empty.

      Example:

      > lists:foldl(fun(X, Sum) -> X + Sum end, 0, [1,2,3,4,5]).
      +returned if the list is empty.

      Example:

      > lists:foldl(fun(X, Sum) -> X + Sum end, 0, [1,2,3,4,5]).
       15
      -> lists:foldl(fun(X, Prod) -> X * Prod end, 1, [1,2,3,4,5]).
      +> lists:foldl(fun(X, Prod) -> X * Prod end, 1, [1,2,3,4,5]).
       120
      @@ -1727,11 +1727,11 @@

      foldr(Fun, Acc0, List)

      -

      Like foldl/3, but the list is traversed from right to left.

      Example:

      > P = fun(A, AccIn) -> io:format("~p ", [A]), AccIn end.
      +

      Like foldl/3, but the list is traversed from right to left.

      Example:

      > P = fun(A, AccIn) -> io:format("~p ", [A]), AccIn end.
       #Fun<erl_eval.12.2225172>
      -> lists:foldl(P, void, [1,2,3]).
      +> lists:foldl(P, void, [1,2,3]).
       1 2 3 void
      -> lists:foldr(P, void, [1,2,3]).
      +> lists:foldr(P, void, [1,2,3]).
       3 2 1 void

      foldl/3 is tail recursive and is usually preferred to foldr/3.

      @@ -1794,12 +1794,12 @@

      join(Sep, List1)

      Inserts Sep between each element in List1. Has no effect on the empty list -and on a singleton list. For example:

      > lists:join(x, [a,b,c]).
      -[a,x,b,x,c]
      -> lists:join(x, [a]).
      -[a]
      -> lists:join(x, []).
      -[]
      +and on a singleton list. For example:

      > lists:join(x, [a,b,c]).
      +[a,x,b,x,c]
      +> lists:join(x, [a]).
      +[a]
      +> lists:join(x, []).
      +[]
      @@ -1900,10 +1900,10 @@

      keymap(Fun, N, TupleList1)

      Returns a list of tuples where, for each tuple in TupleList1, the Nth element Term1 of the tuple has been replaced with the result of calling -Fun(Term1).

      Examples:

      > Fun = fun(Atom) -> atom_to_list(Atom) end.
      +Fun(Term1).

      Examples:

      > Fun = fun(Atom) -> atom_to_list(Atom) end.
       #Fun<erl_eval.6.10732646>
      -2> lists:keymap(Fun, 2, [{name,jane,22},{name,lizzie,20},{name,lydia,15}]).
      -[{name,"jane",22},{name,"lizzie",20},{name,"lydia",15}]
      +2>
      lists:keymap(Fun, 2, [{name,jane,22},{name,lizzie,20},{name,lydia,15}]). +[{name,"jane",22},{name,"lizzie",20},{name,"lydia",15}]
      @@ -2244,9 +2244,9 @@

      mapfoldl(Fun, Acc0, List1)

      -

      Combines the operations of map/2 and foldl/3 into one pass.

      Example:

      Summing the elements in a list and double them at the same time:

      > lists:mapfoldl(fun(X, Sum) -> {2*X, X+Sum} end,
      -0, [1,2,3,4,5]).
      -{[2,4,6,8,10],15}
      +

      Combines the operations of map/2 and foldl/3 into one pass.

      Example:

      Summing the elements in a list and double them at the same time:

      > lists:mapfoldl(fun(X, Sum) -> {2*X, X+Sum} end,
      +0, [1,2,3,4,5]).
      +{[2,4,6,8,10],15}
      @@ -2538,7 +2538,7 @@

      nth(N, List)

      -

      Returns the Nth element of List.

      Example:

      > lists:nth(3, [a, b, c, d, e]).
      +

      Returns the Nth element of List.

      Example:

      > lists:nth(3, [a, b, c, d, e]).
       c
      @@ -2568,14 +2568,14 @@

      nthtail(N, List)

      Returns the Nth tail of List, that is, the sublist of List starting at -N+1 and continuing up to the end of the list.

      Example

      > lists:nthtail(3, [a, b, c, d, e]).
      -[d,e]
      -> tl(tl(tl([a, b, c, d, e]))).
      -[d,e]
      -> lists:nthtail(0, [a, b, c, d, e]).
      -[a,b,c,d,e]
      -> lists:nthtail(5, [a, b, c, d, e]).
      -[]
      +N+1 and continuing up to the end of the list.

      Example

      > lists:nthtail(3, [a, b, c, d, e]).
      +[d,e]
      +> tl(tl(tl([a, b, c, d, e]))).
      +[d,e]
      +> lists:nthtail(0, [a, b, c, d, e]).
      +[a,b,c,d,e]
      +> lists:nthtail(5, [a, b, c, d, e]).
      +[]
      @@ -2611,10 +2611,10 @@

      partition(Pred, List)

      Partitions List into two lists, where the first list contains all elements for which Pred(Elem) returns true, and the second list contains all elements for -which Pred(Elem) returns false.

      Examples:

      > lists:partition(fun(A) -> A rem 2 == 1 end, [1,2,3,4,5,6,7]).
      -{[1,3,5,7],[2,4,6]}
      -> lists:partition(fun(A) -> is_atom(A) end, [a,b,1,c,d,2,3,4,e]).
      -{[a,b,c,d,e],[1,2,3,4]}

      For a different way to partition a list, see splitwith/2.

      +which Pred(Elem) returns false.

      Examples:

      > lists:partition(fun(A) -> A rem 2 == 1 end, [1,2,3,4,5,6,7]).
      +{[1,3,5,7],[2,4,6]}
      +> lists:partition(fun(A) -> is_atom(A) end, [a,b,1,c,d,2,3,4,e]).
      +{[a,b,c,d,e],[1,2,3,4]}

      For a different way to partition a list, see splitwith/2.

      @@ -2699,8 +2699,8 @@

      reverse(List1, Tail)

      Returns a list with the elements in List1 in reverse order, with tail Tail -appended.

      Example:

      > lists:reverse([1, 2, 3, 4], [a, b, c]).
      -[4,3,2,1,a,b,c]
      +appended.

      Example:

      > lists:reverse([1, 2, 3, 4], [a, b, c]).
      +[4,3,2,1,a,b,c]
      @@ -2793,17 +2793,17 @@

      seq(From, To, Incr)

      Returns a sequence of integers that starts with From and contains the successive results of adding Incr to the previous element, until To is reached or passed (in the latter case, To is not an element of the sequence). -Incr defaults to 1.

      Failures:

      • If To < From - Incr and Incr > 0.
      • If To > From - Incr and Incr < 0.
      • If Incr =:= 0 and From =/= To.

      The following equalities hold for all sequences:

      length(lists:seq(From, To)) =:= To - From + 1
      -length(lists:seq(From, To, Incr)) =:= (To - From + Incr) div Incr

      Examples:

      > lists:seq(1, 10).
      -[1,2,3,4,5,6,7,8,9,10]
      -> lists:seq(1, 20, 3).
      -[1,4,7,10,13,16,19]
      -> lists:seq(1, 0, 1).
      -[]
      -> lists:seq(10, 6, 4).
      -[]
      -> lists:seq(1, 1, 0).
      -[1]
      +Incr defaults to 1.

      Failures:

      • If To < From - Incr and Incr > 0.
      • If To > From - Incr and Incr < 0.
      • If Incr =:= 0 and From =/= To.

      The following equalities hold for all sequences:

      length(lists:seq(From, To)) =:= To - From + 1
      +length(lists:seq(From, To, Incr)) =:= (To - From + Incr) div Incr

      Examples:

      > lists:seq(1, 10).
      +[1,2,3,4,5,6,7,8,9,10]
      +> lists:seq(1, 20, 3).
      +[1,4,7,10,13,16,19]
      +> lists:seq(1, 0, 1).
      +[]
      +> lists:seq(10, 6, 4).
      +[]
      +> lists:seq(1, 1, 0).
      +[1]
      @@ -2928,11 +2928,11 @@

      splitwith(Pred, List)

      Partitions List into two lists according to Pred. -splitwith/2 behaves as if it is defined as follows:

      splitwith(Pred, List) ->
      -    {takewhile(Pred, List), dropwhile(Pred, List)}.

      Examples:

      > lists:splitwith(fun(A) -> A rem 2 == 1 end, [1,2,3,4,5,6,7]).
      -{[1],[2,3,4,5,6,7]}
      -> lists:splitwith(fun(A) -> is_atom(A) end, [a,b,1,c,d,2,3,4,e]).
      -{[a,b],[1,c,d,2,3,4,e]}

      The Pred function must return a boolean. For a different way to partition a +splitwith/2 behaves as if it is defined as follows:

      splitwith(Pred, List) ->
      +    {takewhile(Pred, List), dropwhile(Pred, List)}.

      Examples:

      > lists:splitwith(fun(A) -> A rem 2 == 1 end, [1,2,3,4,5,6,7]).
      +{[1],[2,3,4,5,6,7]}
      +> lists:splitwith(fun(A) -> is_atom(A) end, [a,b,1,c,d,2,3,4,e]).
      +{[a,b],[1,c,d,2,3,4,e]}

      The Pred function must return a boolean. For a different way to partition a list, see partition/2.

      @@ -2999,12 +2999,12 @@

      sublist(List1, Start, Len)

      Returns the sublist of List1 starting at Start and with (maximum) Len -elements. It is not an error for Start+Len to exceed the length of the list.

      Examples:

      > lists:sublist([1,2,3,4], 2, 2).
      -[2,3]
      -> lists:sublist([1,2,3,4], 2, 5).
      -[2,3,4]
      -> lists:sublist([1,2,3,4], 5, 2).
      -[]
      +elements. It is not an error for Start+Len to exceed the length of the list.

      Examples:

      > lists:sublist([1,2,3,4], 2, 2).
      +[2,3]
      +> lists:sublist([1,2,3,4], 2, 5).
      +[2,3,4]
      +> lists:sublist([1,2,3,4], 5, 2).
      +[]
      @@ -3034,7 +3034,7 @@

      subtract(List1, List2)

      Returns a new list List3 that is a copy of List1, subjected to the following procedure: for each element in List2, its first occurrence in List1 is -deleted.

      Example:

      > lists:subtract("123212", "212").
      +deleted.

      Example:

      > lists:subtract("123212", "212").
       "312".

      lists:subtract(A, B) is equivalent to A -- B.

      @@ -3370,10 +3370,10 @@

      uniq(List1)

      Returns a list containing the elements of List1 with duplicated elements removed (preserving the order of the elements). The first occurrence of each -element is kept.

      Examples:

      > lists:uniq([3,3,1,2,1,2,3]).
      -[3,1,2]
      -> lists:uniq([a, a, 1, b, 2, a, 3]).
      -[a, 1, b, 2, 3]
      +element is kept.

      Examples:

      > lists:uniq([3,3,1,2,1,2,3]).
      +[3,1,2]
      +> lists:uniq([a, a, 1, b, 2, a, 3]).
      +[a, 1, b, 2, 3]
      @@ -3405,8 +3405,8 @@

      uniq(Fun, List1)

      Returns a list containing the elements of List1 without the elements for which Fun returned duplicate values (preserving the order of the elements). The -first occurrence of each element is kept.

      Examples:

      > lists:uniq(fun({X, _}) -> X end, [{b, 2}, {a, 1}, {c, 3}, {a, 2}]).
      -[{b, 2}, {a, 1}, {c, 3}]
      +first occurrence of each element is kept.

      Examples:

      > lists:uniq(fun({X, _}) -> X end, [{b, 2}, {a, 1}, {c, 3}, {a, 2}]).
      +[{b, 2}, {a, 1}, {c, 3}]
      @@ -3690,14 +3690,14 @@

      zip(List1, List2, How)

      tuple is taken from the first list and the second element is taken from the corresponding element in the second list.

      The How parameter specifies the behavior if the given lists are of different lengths.

      • fail - The call will fail if the given lists are not of equal length. -This is the default.

      • trim - Surplus elements from the longer list will be ignored.

        Examples:

        > lists:zip([a, b], [1, 2, 3], trim).
        -[{a,1},{b,2}]
        -> lists:zip([a, b, c], [1, 2], trim).
        -[{a,1},{b,2}]
      • {pad, Defaults} - The shorter list will be padded to the length of the -longer list, using the respective elements from the given Defaults tuple.

        Examples:

        > lists:zip([a, b], [1, 2, 3], {pad, {x, 0}}).
        -[{a,1},{b,2},{x,3}]
        -> lists:zip([a, b, c], [1, 2], {pad, {x, 0}}).
        -[{a,1},{b,2},{c,0}]
      +This is the default.

    • trim - Surplus elements from the longer list will be ignored.

      Examples:

      > lists:zip([a, b], [1, 2, 3], trim).
      +[{a,1},{b,2}]
      +> lists:zip([a, b, c], [1, 2], trim).
      +[{a,1},{b,2}]
    • {pad, Defaults} - The shorter list will be padded to the length of the +longer list, using the respective elements from the given Defaults tuple.

      Examples:

      > lists:zip([a, b], [1, 2, 3], {pad, {x, 0}}).
      +[{a,1},{b,2},{x,3}]
      +> lists:zip([a, b, c], [1, 2], {pad, {x, 0}}).
      +[{a,1},{b,2},{c,0}]
    @@ -3782,10 +3782,10 @@

    zipwith3(Combine, List1, List2, List3, How)

    Combines the elements of three lists into one list. For each triple X, Y, Z of list elements from the three lists, the element in the result list is Combine(X, Y, Z).

    For a description of the How parameter, see zip/3.

    zipwith3(fun(X, Y, Z) -> {X,Y,Z} end, List1, List2, List3) is -equivalent to zip3(List1, List2, List3).

    Examples:

    > lists:zipwith3(fun(X, Y, Z) -> X+Y+Z end, [1,2,3], [4,5,6], [7,8,9]).
    -[12,15,18]
    -> lists:zipwith3(fun(X, Y, Z) -> [X,Y,Z] end, [a,b,c], [x,y,z], [1,2,3]).
    -[[a,x,1],[b,y,2],[c,z,3]]
    +equivalent to zip3(List1, List2, List3).

    Examples:

    > lists:zipwith3(fun(X, Y, Z) -> X+Y+Z end, [1,2,3], [4,5,6], [7,8,9]).
    +[12,15,18]
    +> lists:zipwith3(fun(X, Y, Z) -> [X,Y,Z] end, [a,b,c], [x,y,z], [1,2,3]).
    +[[a,x,1],[b,y,2],[c,z,3]]

    @@ -3864,8 +3864,8 @@

    zipwith(Combine, List1, List2, How)

    Combines the elements of two lists into one list. For each pair X, Y of list elements from the two lists, the element in the result list is Combine(X, Y).

    For a description of the How parameter, see zip/3.

    zipwith(fun(X, Y) -> {X,Y} end, List1, List2) is equivalent to -zip(List1, List2).

    Example:

    > lists:zipwith(fun(X, Y) -> X+Y end, [1,2,3], [4,5,6]).
    -[5,7,9]
    +zip(List1, List2).

    Example:

    > lists:zipwith(fun(X, Y) -> X+Y end, [1,2,3], [4,5,6]).
    +[5,7,9]
    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/maps.html b/prs/8803/lib/stdlib-6.0.1/doc/html/maps.html index efee040635b24..e5a3c4c57b101 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/maps.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/maps.html @@ -745,10 +745,10 @@

    filter(Pred, MapOrIter)

    Returns a map Map for which predicate Pred holds true in MapOrIter.

    The call fails with a {badmap,Map} exception if MapOrIter is not a map or -valid iterator, or with badarg if Pred is not a function of arity 2.

    Example:

    > M = #{a => 2, b => 3, c=> 4, "a" => 1, "b" => 2, "c" => 4},
    -  Pred = fun(K,V) -> is_atom(K) andalso (V rem 2) =:= 0 end,
    -  maps:filter(Pred,M).
    -#{a => 2,c => 4}
    +valid iterator, or with badarg if Pred is not a function of arity 2.

    Example:

    > M = #{a => 2, b => 3, c=> 4, "a" => 1, "b" => 2, "c" => 4},
    +  Pred = fun(K,V) -> is_atom(K) andalso (V rem 2) =:= 0 end,
    +  maps:filter(Pred,M).
    +#{a => 2,c => 4}
    @@ -787,10 +787,10 @@

    filtermap(Fun, MapOrIter)

    map. If it returns false, the association is not copied. If it returns {true, NewValue}, the value for Key is replaced with NewValue in the result map.

    The call fails with a {badmap,Map} exception if MapOrIter is not a map or -valid iterator, or with badarg if Fun is not a function of arity 2.

    Example:

    > Fun = fun(K,V) when is_atom(K) -> {true, V*2}; (_,V) -> (V rem 2) =:= 0 end,
    -  Map = #{k1 => 1, "k2" => 2, "k3" => 3},
    -  maps:filtermap(Fun,Map).
    -#{k1 => 2,"k2" => 2}
    +valid iterator, or with badarg if Fun is not a function of arity 2.

    Example:

    > Fun = fun(K,V) when is_atom(K) -> {true, V*2}; (_,V) -> (V rem 2) =:= 0 end,
    +  Map = #{k1 => 1, "k2" => 2, "k3" => 3},
    +  maps:filtermap(Fun,Map).
    +#{k1 => 2,"k2" => 2}
    @@ -821,10 +821,10 @@

    find(Key, Map)

    Returns a tuple {ok, Value}, where Value is the value associated with Key, -or error if no value is associated with Key in Map.

    The call fails with a {badmap,Map} exception if Map is not a map.

    Example:

    > Map = #{"hi" => 42},
    +or error if no value is associated with Key in Map.

    The call fails with a {badmap,Map} exception if Map is not a map.

    Example:

    > Map = #{"hi" => 42},
       Key = "hi",
    -  maps:find(Key,Map).
    -{ok,42}
    +
    maps:find(Key,Map). +{ok,42}
    @@ -865,9 +865,9 @@

    fold(Fun, Init, MapOrIter)

    which is passed to the next successive call. This function returns the final value of the accumulator. The initial accumulator value Init is returned if the map is empty.

    The call fails with a {badmap,Map} exception if MapOrIter is not a map or -valid iterator, or with badarg if Fun is not a function of arity 3.

    Example:

    > Fun = fun(K,V,AccIn) when is_list(K) -> AccIn + V end,
    -  Map = #{"k1" => 1, "k2" => 2, "k3" => 3},
    -  maps:fold(Fun,0,Map).
    +valid iterator, or with badarg if Fun is not a function of arity 3.

    Example:

    > Fun = fun(K,V,AccIn) when is_list(K) -> AccIn + V end,
    +  Map = #{"k1" => 1, "k2" => 2, "k3" => 3},
    +  maps:fold(Fun,0,Map).
     6
    @@ -934,8 +934,8 @@

    from_keys(Keys, Value)

    Takes a list of keys and a value and builds a map where all keys point to the -same value. The key can be in any order, and keys and value can be of any term.

    Example:

    > Keys = ["a", "b", "c"], maps:from_keys(Keys, ok).
    -#{"a" => ok,"b" => ok,"c" => ok}
    +same value. The key can be in any order, and keys and value can be of any term.

    Example:

    > Keys = ["a", "b", "c"], maps:from_keys(Keys, ok).
    +#{"a" => ok,"b" => ok,"c" => ok}
    @@ -967,9 +967,9 @@

    from_list(List)

    Takes a list of key-value tuples elements and builds a map. The associations can be in any order, and both keys and values in the association can be of any term.

    If the same key appears more than once, the latter (right-most) value is used -and the previous values are ignored.

    Example:

    > List = [{"a",ignored},{1337,"value two"},{42,value_three},{"a",1}],
    -  maps:from_list(List).
    -#{42 => value_three,1337 => "value two","a" => 1}
    +and the previous values are ignored.

    Example:

    > List = [{"a",ignored},{1337,"value two"},{42,value_three},{"a",1}],
    +  maps:from_list(List).
    +#{42 => value_three,1337 => "value two","a" => 1}
    @@ -1001,8 +1001,8 @@

    get(Key, Map)

    Returns value Value associated with Key if Map contains Key.

    The call fails with a {badmap,Map} exception if Map is not a map, or with a {badkey,Key} exception if no value is associated with Key.

    Example:

    > Key = 1337,
    -  Map = #{42 => value_two,1337 => "value one","a" => 1},
    -  maps:get(Key,Map).
    +  Map = #{42 => value_two,1337 => "value one","a" => 1},
    +  maps:get(Key,Map).
     "value one"
    @@ -1034,11 +1034,11 @@

    get(Key, Map, Default)

    Returns value Value associated with Key if Map contains Key. If no value -is associated with Key, Default is returned.

    The call fails with a {badmap,Map} exception if Map is not a map.

    Example:

    > Map = #{ key1 => val1, key2 => val2 }.
    -#{key1 => val1,key2 => val2}
    -> maps:get(key1, Map, "Default value").
    +is associated with Key, Default is returned.

    The call fails with a {badmap,Map} exception if Map is not a map.

    Example:

    > Map = #{ key1 => val1, key2 => val2 }.
    +#{key1 => val1,key2 => val2}
    +> maps:get(key1, Map, "Default value").
     val1
    -> maps:get(key3, Map, "Default value").
    +> maps:get(key3, Map, "Default value").
     "Default value"
    @@ -1078,11 +1078,11 @@

    groups_from_list(KeyFun, List)

    Partitions the given List into a map of groups.

    The result is a map where each key is given by KeyFun and each value is a list of elements from the given List for which KeyFun returned the same key.

    The order of elements within each group list is preserved from the original -list.

    Examples:

    > EvenOdd = fun(X) -> case X rem 2 of 0 -> even; 1 -> odd end end,
    -maps:groups_from_list(EvenOdd, [1, 2, 3]).
    -#{even => [2], odd => [1, 3]}
    -> maps:groups_from_list(fun erlang:length/1, ["ant", "buffalo", "cat", "dingo"]).
    -#{3 => ["ant", "cat"], 5 => ["dingo"], 7 => ["buffalo"]}
    +list.

    Examples:

    > EvenOdd = fun(X) -> case X rem 2 of 0 -> even; 1 -> odd end end,
    +maps:groups_from_list(EvenOdd, [1, 2, 3]).
    +#{even => [2], odd => [1, 3]}
    +> maps:groups_from_list(fun erlang:length/1, ["ant", "buffalo", "cat", "dingo"]).
    +#{3 => ["ant", "cat"], 5 => ["dingo"], 7 => ["buffalo"]}
    @@ -1094,7 +1094,7 @@

    groups_from_list(KeyFun, List)

    groups_from_list(KeyFun, ValueFun, List)

    - + View Source @@ -1124,15 +1124,15 @@

    groups_from_list(KeyFun, ValueFun, List)Partitions the given List into a map of groups.

    The result is a map where each key is given by KeyFun and each value is a list of elements from the given List, mapped via ValueFun, for which KeyFun returned the same key.

    The order of elements within each group list is preserved from the original -list.

    Examples:

    > EvenOdd = fun(X) -> case X rem 2 of 0 -> even; 1 -> odd end end,
    -> Square = fun(X) -> X * X end,
    -> maps:groups_from_list(EvenOdd, Square, [1, 2, 3]).
    -#{even => [4], odd => [1, 9]}
    -> maps:groups_from_list(
    +list.

    Examples:

    > EvenOdd = fun(X) -> case X rem 2 of 0 -> even; 1 -> odd end end,
    +> Square = fun(X) -> X * X end,
    +> maps:groups_from_list(EvenOdd, Square, [1, 2, 3]).
    +#{even => [4], odd => [1, 9]}
    +> maps:groups_from_list(
         fun erlang:length/1,
         fun lists:reverse/1,
    -    ["ant", "buffalo", "cat", "dingo"]).
    -#{3 => ["tna", "tac"],5 => ["ognid"],7 => ["olaffub"]}
    +
    ["ant", "buffalo", "cat", "dingo"]). +#{3 => ["tna", "tac"],5 => ["ognid"],7 => ["olaffub"]}

    @@ -1164,10 +1164,10 @@

    intersect(Map1, Map2)

    Intersects two maps into a single map Map3. If a key exists in both maps, the -value in Map1 is superseded by the value in Map2.

    The call fails with a {badmap,Map} exception if Map1 or Map2 is not a map.

    Example:

    > Map1 = #{a => "value_one", b => "value_two"},
    -  Map2 = #{a => 1, c => 2},
    -  maps:intersect(Map1,Map2).
    -#{a => 1}
    +value in Map1 is superseded by the value in Map2.

    The call fails with a {badmap,Map} exception if Map1 or Map2 is not a map.

    Example:

    > Map1 = #{a => "value_one", b => "value_two"},
    +  Map2 = #{a => 1, c => 2},
    +  maps:intersect(Map1,Map2).
    +#{a => 1}
    @@ -1207,10 +1207,10 @@

    intersect_with(Combiner, Map1, Map2)

    the value from Map1 is the second parameter, and the value from Map2 is the third parameter.

    The call fails with a {badmap,Map} exception if Map1 or Map2 is not a map. The call fails with a badarg exception if Combiner is not a fun that takes -three arguments.

    Example:

    > Map1 = #{a => "value_one", b => "value_two"},
    -  Map2 = #{a => 1, c => 2},
    -  maps:intersect_with(fun(_Key, Value1, Value2) -> {Value1, Value2} end, Map1, Map2).
    -#{a => {"value_one",1}}
    +three arguments.

    Example:

    > Map1 = #{a => "value_one", b => "value_two"},
    +  Map2 = #{a => 1, c => 2},
    +  maps:intersect_with(fun(_Key, Value1, Value2) -> {Value1, Value2} end, Map1, Map2).
    +#{a => {"value_one",1}}
    @@ -1241,11 +1241,11 @@

    is_key(Key, Map)

    Returns true if map Map contains Key and returns false if it does not -contain the Key.

    The call fails with a {badmap,Map} exception if Map is not a map.

    Example:

    > Map = #{"42" => value}.
    -#{"42" => value}
    -> maps:is_key("42",Map).
    +contain the Key.

    The call fails with a {badmap,Map} exception if Map is not a map.

    Example:

    > Map = #{"42" => value}.
    +#{"42" => value}
    +> maps:is_key("42",Map).
     true
    -> maps:is_key(value,Map).
    +> maps:is_key(value,Map).
     false
    @@ -1278,15 +1278,15 @@

    iterator(Map)

    Returns a map iterator Iterator that can be used by maps:next/1 to traverse the key-value associations in a map. When iterating over a map, the -memory usage is guaranteed to be bounded no matter the size of the map.

    The call fails with a {badmap,Map} exception if Map is not a map.

    Example:

    > M = #{ a => 1, b => 2 }.
    -#{a => 1,b => 2}
    -> I = maps:iterator(M), ok.
    +memory usage is guaranteed to be bounded no matter the size of the map.

    The call fails with a {badmap,Map} exception if Map is not a map.

    Example:

    > M = #{ a => 1, b => 2 }.
    +#{a => 1,b => 2}
    +> I = maps:iterator(M), ok.
     ok
    -> {K1, V1, I2} = maps:next(I), {K1, V1}.
    -{a,1}
    -> {K2, V2, I3} = maps:next(I2),{K2, V2}.
    -{b,2}
    -> maps:next(I3).
    +> {K1, V1, I2} = maps:next(I), {K1, V1}.
    +{a,1}
    +> {K2, V2, I3} = maps:next(I2),{K2, V2}.
    +{b,2}
    +> maps:next(I3).
     none
    @@ -1324,34 +1324,34 @@

    iterator(Map, Order)

    Returns a map iterator Iterator that can be used by maps:next/1 to traverse the key-value associations in a map sorted by key using the given Order.

    The call fails with a {badmap,Map} exception if Map is not a map or if -Order is invalid.

    Example (when Order is ordered):

    > M = #{ a => 1, b => 2 }.
    -#{a => 1,b => 2}
    -> OrdI = maps:iterator(M, ordered), ok.
    +Order is invalid.

    Example (when Order is ordered):

    > M = #{ a => 1, b => 2 }.
    +#{a => 1,b => 2}
    +> OrdI = maps:iterator(M, ordered), ok.
     ok
    -> {K1, V1, OrdI2} = maps:next(OrdI), {K1, V1}.
    -{a,1}
    -> {K2, V2, OrdI3} = maps:next(OrdI2),{K2, V2}.
    -{b,2}
    -> maps:next(OrdI3).
    -none

    Example (when Order is reversed):

    > M = #{ a => 1, b => 2 }.
    -#{a => 1,b => 2}
    -> RevI = maps:iterator(M, reversed), ok.
    +> {K1, V1, OrdI2} = maps:next(OrdI), {K1, V1}.
    +{a,1}
    +> {K2, V2, OrdI3} = maps:next(OrdI2),{K2, V2}.
    +{b,2}
    +> maps:next(OrdI3).
    +none

    Example (when Order is reversed):

    > M = #{ a => 1, b => 2 }.
    +#{a => 1,b => 2}
    +> RevI = maps:iterator(M, reversed), ok.
     ok
    -> {K2, V2, RevI2} = maps:next(RevI), {K2, V2}.
    -{b,2}
    -> {K1, V1, RevI3} = maps:next(RevI2),{K1, V1}.
    -{a,1}
    -> maps:next(RevI3).
    -none

    Example (when Order is an arithmetic sorting function):

    > M = #{ -1 => a, -1.0 => b, 0 => c, 0.0 => d }.
    -#{-1 => a,0 => c,-1.0 => b,0.0 => d}
    -> ArithOrdI = maps:iterator(M, fun(A, B) -> A =< B end), ok.
    +> {K2, V2, RevI2} = maps:next(RevI), {K2, V2}.
    +{b,2}
    +> {K1, V1, RevI3} = maps:next(RevI2),{K1, V1}.
    +{a,1}
    +> maps:next(RevI3).
    +none

    Example (when Order is an arithmetic sorting function):

    > M = #{ -1 => a, -1.0 => b, 0 => c, 0.0 => d }.
    +#{-1 => a,0 => c,-1.0 => b,0.0 => d}
    +> ArithOrdI = maps:iterator(M, fun(A, B) -> A =< B end), ok.
     ok
    -> maps:to_list(ArithOrdI).
    -[{-1,a},{-1.0,b},{0,c},{0.0,d}]
    -> ArithRevI = maps:iterator(M, fun(A, B) -> B < A end), ok.
    +> maps:to_list(ArithOrdI).
    +[{-1,a},{-1.0,b},{0,c},{0.0,d}]
    +> ArithRevI = maps:iterator(M, fun(A, B) -> B < A end), ok.
     ok
    -> maps:to_list(ArithRevI).
    -[{0.0,d},{0,c},{-1.0,b},{-1,a}]
    +>
    maps:to_list(ArithRevI). +[{0.0,d},{0,c},{-1.0,b},{-1,a}]
    @@ -1381,9 +1381,9 @@

    keys(Map)

    -

    Returns a complete list of keys, in any order, which resides within Map.

    The call fails with a {badmap,Map} exception if Map is not a map.

    Example:

    > Map = #{42 => value_three,1337 => "value two","a" => 1},
    -  maps:keys(Map).
    -[42,1337,"a"]
    +

    Returns a complete list of keys, in any order, which resides within Map.

    The call fails with a {badmap,Map} exception if Map is not a map.

    Example:

    > Map = #{42 => value_three,1337 => "value two","a" => 1},
    +  maps:keys(Map).
    +[42,1337,"a"]
    @@ -1421,10 +1421,10 @@

    map(Fun, MapOrIter)

    Key to value Value1 association in MapOrIter in any order. Function fun Fun/2 must return value Value2 to be associated with key Key for the new map Map.

    The call fails with a {badmap,Map} exception if MapOrIter is not a map or -valid iterator, or with badarg if Fun is not a function of arity 2.

    Example:

    > Fun = fun(K,V1) when is_list(K) -> V1*2 end,
    -  Map = #{"k1" => 1, "k2" => 2, "k3" => 3},
    -  maps:map(Fun,Map).
    -#{"k1" => 2,"k2" => 4,"k3" => 6}
    +valid iterator, or with badarg if Fun is not a function of arity 2.

    Example:

    > Fun = fun(K,V1) when is_list(K) -> V1*2 end,
    +  Map = #{"k1" => 1, "k2" => 2, "k3" => 3},
    +  maps:map(Fun,Map).
    +#{"k1" => 2,"k2" => 4,"k3" => 6}
    @@ -1455,10 +1455,10 @@

    merge(Map1, Map2)

    Merges two maps into a single map Map3. If two keys exist in both maps, the -value in Map1 is superseded by the value in Map2.

    The call fails with a {badmap,Map} exception if Map1 or Map2 is not a map.

    Example:

    > Map1 = #{a => "value_one", b => "value_two"},
    -  Map2 = #{a => 1, c => 2},
    -  maps:merge(Map1,Map2).
    -#{a => 1,b => "value_two",c => 2}
    +value in Map1 is superseded by the value in Map2.

    The call fails with a {badmap,Map} exception if Map1 or Map2 is not a map.

    Example:

    > Map1 = #{a => "value_one", b => "value_two"},
    +  Map2 = #{a => 1, c => 2},
    +  maps:merge(Map1,Map2).
    +#{a => 1,b => "value_two",c => 2}
    @@ -1498,10 +1498,10 @@

    merge_with(Combiner, Map1, Map2)

    the value from Map1 is the second parameter, and the value from Map2 is the third parameter.

    The call fails with a {badmap,Map} exception if Map1 or Map2 is not a map. The call fails with a badarg exception if Combiner is not a fun that takes -three arguments.

    Example:

    > Map1 = #{a => "value_one", b => "value_two"},
    -  Map2 = #{a => 1, c => 2},
    -  maps:merge_with(fun(_Key, Value1, Value2) -> {Value1, Value2} end, Map1, Map2).
    -#{a => {"value_one",1},b => "value_two",c => 2}
    +three arguments.

    Example:

    > Map1 = #{a => "value_one", b => "value_two"},
    +  Map2 = #{a => 1, c => 2},
    +  maps:merge_with(fun(_Key, Value1, Value2) -> {Value1, Value2} end, Map1, Map2).
    +#{a => {"value_one",1},b => "value_two",c => 2}
    @@ -1564,17 +1564,17 @@

    next(Iterator)

    Returns the next key-value association in Iterator and a new iterator for the -remaining associations in the iterator.

    If there are no more associations in the iterator, none is returned.

    Example:

    > Map = #{a => 1, b => 2, c => 3}.
    -#{a => 1,b => 2,c => 3}
    -> I = maps:iterator(Map), ok.
    +remaining associations in the iterator.

    If there are no more associations in the iterator, none is returned.

    Example:

    > Map = #{a => 1, b => 2, c => 3}.
    +#{a => 1,b => 2,c => 3}
    +> I = maps:iterator(Map), ok.
     ok
    -> {K1, V1, I1} = maps:next(I), {K1, V1}.
    -{a,1}
    -> {K2, V2, I2} = maps:next(I1), {K2, V2}.
    -{b,2}
    -> {K3, V3, I3} = maps:next(I2), {K3, V3}.
    -{c,3}
    -> maps:next(I3).
    +> {K1, V1, I1} = maps:next(I), {K1, V1}.
    +{a,1}
    +> {K2, V2, I2} = maps:next(I1), {K2, V2}.
    +{b,2}
    +> {K3, V3, I3} = maps:next(I2), {K3, V3}.
    +{c,3}
    +> maps:next(I3).
     none
    @@ -1608,12 +1608,12 @@

    put(Key, Value, Map1)

    Associates Key with value Value and inserts the association into map Map2. If key Key already exists in map Map1, the old associated value is replaced by value Value. The function returns a new map Map2 containing the new -association and the old associations in Map1.

    The call fails with a {badmap,Map} exception if Map1 is not a map.

    Example:

    > Map = #{"a" => 1}.
    -#{"a" => 1}
    -> maps:put("a", 42, Map).
    -#{"a" => 42}
    -> maps:put("b", 1337, Map).
    -#{"a" => 1,"b" => 1337}
    +association and the old associations in Map1.

    The call fails with a {badmap,Map} exception if Map1 is not a map.

    Example:

    > Map = #{"a" => 1}.
    +#{"a" => 1}
    +> maps:put("a", 42, Map).
    +#{"a" => 42}
    +> maps:put("b", 1337, Map).
    +#{"a" => 1,"b" => 1337}
    @@ -1644,12 +1644,12 @@

    remove(Key, Map1)

    Removes the Key, if it exists, and its associated value from Map1 and -returns a new map Map2 without key Key.

    The call fails with a {badmap,Map} exception if Map1 is not a map.

    Example:

    > Map = #{"a" => 1}.
    -#{"a" => 1}
    -> maps:remove("a",Map).
    -#{}
    -> maps:remove("b",Map).
    -#{"a" => 1}
    +returns a new map Map2 without key Key.

    The call fails with a {badmap,Map} exception if Map1 is not a map.

    Example:

    > Map = #{"a" => 1}.
    +#{"a" => 1}
    +> maps:remove("a",Map).
    +#{}
    +> maps:remove("b",Map).
    +#{"a" => 1}
    @@ -1680,8 +1680,8 @@

    size(Map)

    Returns the number of key-value associations in Map. This operation occurs in -constant time.

    Example:

    > Map = #{42 => value_two,1337 => "value one","a" => 1},
    -  maps:size(Map).
    +constant time.

    Example:

    > Map = #{42 => value_two,1337 => "value one","a" => 1},
    +  maps:size(Map).
     3
    @@ -1714,11 +1714,11 @@

    take(Key, Map1)

    The function removes the Key, if it exists, and its associated value from Map1 and returns a tuple with the removed Value and the new map Map2 -without key Key. If the key does not exist error is returned.

    The call will fail with a {badmap,Map} exception if Map1 is not a map.

    Example:

    > Map = #{"a" => "hello", "b" => "world"}.
    -#{"a" => "hello", "b" => "world"}
    -> maps:take("a",Map).
    -{"hello",#{"b" => "world"}}
    -> maps:take("does not exist",Map).
    +without key Key. If the key does not exist error is returned.

    The call will fail with a {badmap,Map} exception if Map1 is not a map.

    Example:

    > Map = #{"a" => "hello", "b" => "world"}.
    +#{"a" => "hello", "b" => "world"}
    +> maps:take("a",Map).
    +{"hello",#{"b" => "world"}}
    +> maps:take("does not exist",Map).
     error
    @@ -1753,12 +1753,12 @@

    to_list(MapOrIterator)

    Returns a list of pairs representing the key-value associations of MapOrIterator, where the pairs [{K1,V1}, ..., {Kn,Vn}] are returned in arbitrary order.

    The call fails with a {badmap,Map} exception if MapOrIterator is not a map -or an iterator obtained by a call to iterator/1 or iterator/2.

    Example:

    > Map = #{42 => value_three,1337 => "value two","a" => 1},
    -  maps:to_list(Map).
    -[{42,value_three},{1337,"value two"},{"a",1}]

    Example (using iterator/2):

    > Map = #{ z => 1, y => 2, x => 3 }.
    -#{x => 3,y => 2,z => 1}
    -> maps:to_list(maps:iterator(Map, ordered)).
    -[{x,3},{y,2},{z,1}]
    +or an iterator obtained by a call to iterator/1 or iterator/2.

    Example:

    > Map = #{42 => value_three,1337 => "value two","a" => 1},
    +  maps:to_list(Map).
    +[{42,value_three},{1337,"value two"},{"a",1}]

    Example (using iterator/2):

    > Map = #{ z => 1, y => 2, x => 3 }.
    +#{x => 3,y => 2,z => 1}
    +> maps:to_list(maps:iterator(Map, ordered)).
    +[{x,3},{y,2},{z,1}]
    @@ -1791,10 +1791,10 @@

    update(Key, Value, Map1)

    If Key exists in Map1, the old associated value is replaced by value Value. The function returns a new map Map2 containing the new associated value.

    The call fails with a {badmap,Map} exception if Map1 is not a map, or with a -{badkey,Key} exception if no value is associated with Key.

    Example:

    > Map = #{"a" => 1}.
    -#{"a" => 1}
    -> maps:update("a", 42, Map).
    -#{"a" => 42}
    +{badkey,Key} exception if no value is associated with Key.

    Example:

    > Map = #{"a" => 1}.
    +#{"a" => 1}
    +> maps:update("a", 42, Map).
    +#{"a" => 42}
    @@ -1830,10 +1830,10 @@

    update_with(Key, Fun, Map1)

    Update a value in a Map1 associated with Key by calling Fun on the old value to get a new value. An exception {badkey,Key} is generated if Key is -not present in the map.

    Example:

    > Map = #{"counter" => 1},
    -  Fun = fun(V) -> V + 1 end,
    -  maps:update_with("counter",Fun,Map).
    -#{"counter" => 2}
    +not present in the map.

    Example:

    > Map = #{"counter" => 1},
    +  Fun = fun(V) -> V + 1 end,
    +  maps:update_with("counter",Fun,Map).
    +#{"counter" => 2}
    @@ -1869,10 +1869,10 @@

    update_with(Key, Fun, Init, Map1)

    Update a value in a Map1 associated with Key by calling Fun on the old value to get a new value. If Key is not present in Map1 then Init will be -associated with Key.

    Example:

    > Map = #{"counter" => 1},
    -  Fun = fun(V) -> V + 1 end,
    -  maps:update_with("new counter",Fun,42,Map).
    -#{"counter" => 1,"new counter" => 42}
    +associated with Key.

    Example:

    > Map = #{"counter" => 1},
    +  Fun = fun(V) -> V + 1 end,
    +  maps:update_with("new counter",Fun,42,Map).
    +#{"counter" => 1,"new counter" => 42}
    @@ -1902,9 +1902,9 @@

    values(Map)

    -

    Returns a complete list of values, in arbitrary order, contained in map Map.

    The call fails with a {badmap,Map} exception if Map is not a map.

    Example:

    > Map = #{42 => value_three,1337 => "value two","a" => 1},
    -  maps:values(Map).
    -[value_three,"value two",1]
    +

    Returns a complete list of values, in arbitrary order, contained in map Map.

    The call fails with a {badmap,Map} exception if Map is not a map.

    Example:

    > Map = #{42 => value_three,1337 => "value two","a" => 1},
    +  maps:values(Map).
    +[value_three,"value two",1]
    @@ -1936,10 +1936,10 @@

    with(Ks, Map1)

    Returns a new map Map2 with the keys K1 through Kn and their associated values from map Map1. Any key in Ks that does not exist in Map1 is -ignored.

    Example:

    > Map = #{42 => value_three,1337 => "value two","a" => 1},
    -  Ks = ["a",42,"other key"],
    -  maps:with(Ks,Map).
    -#{42 => value_three,"a" => 1}
    +ignored.

    Example:

    > Map = #{42 => value_three,1337 => "value two","a" => 1},
    +  Ks = ["a",42,"other key"],
    +  maps:with(Ks,Map).
    +#{42 => value_three,"a" => 1}
    @@ -1970,10 +1970,10 @@

    without(Ks, Map1)

    Returns a new map Map2 without keys K1 through Kn and their associated -values from map Map1. Any key in Ks that does not exist in Map1 is ignored

    Example:

    > Map = #{42 => value_three,1337 => "value two","a" => 1},
    -  Ks = ["a",42,"other key"],
    -  maps:without(Ks,Map).
    -#{1337 => "value two"}
    +values from map Map1. Any key in Ks that does not exist in Map1 is ignored

    Example:

    > Map = #{42 => value_three,1337 => "value two","a" => 1},
    +  Ks = ["a",42,"other key"],
    +  maps:without(Ks,Map).
    +#{1337 => "value two"}
    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/ms_transform.html b/prs/8803/lib/stdlib-6.0.1/doc/html/ms_transform.html index b1e71231128d3..88918c44afc22 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/ms_transform.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/ms_transform.html @@ -154,31 +154,31 @@

    table and construct a list of tuples containing relevant parts of the data in these rows. One can use ets:foldl/3 instead, but the ets:select/2 call is far more efficient. Without the translation provided by ms_transform, one must -struggle with writing match specifications terms to accommodate this.

    Consider a simple table of employees:

    -record(emp, {empno,     %Employee number as a string, the key
    +struggle with writing match specifications terms to accommodate this.

    Consider a simple table of employees:

    -record(emp, {empno,     %Employee number as a string, the key
                   surname,   %Surname of the employee
                   givenname, %Given name of employee
                   dept,      %Department, one of {dev,sales,prod,adm}
    -              empyear}). %Year the employee was employed

    We create the table using:

    ets:new(emp_tab, [{keypos,#emp.empno},named_table,ordered_set]).

    We fill the table with randomly chosen data:

    [{emp,"011103","Black","Alfred",sales,2000},
    - {emp,"041231","Doe","John",prod,2001},
    - {emp,"052341","Smith","John",dev,1997},
    - {emp,"076324","Smith","Ella",sales,1995},
    - {emp,"122334","Weston","Anna",prod,2002},
    - {emp,"535216","Chalker","Samuel",adm,1998},
    - {emp,"789789","Harrysson","Joe",adm,1996},
    - {emp,"963721","Scott","Juliana",dev,2003},
    - {emp,"989891","Brown","Gabriel",prod,1999}]

    Assuming that we want the employee numbers of everyone in the sales department, -there are several ways.

    ets:match/2 can be used:

    1> ets:match(emp_tab, {'_', '$1', '_', '_', sales, '_'}).
    -[["011103"],["076324"]]

    ets:match/2 uses a simpler type of match specification, but it is still + empyear}). %Year the employee was employed

    We create the table using:

    ets:new(emp_tab, [{keypos,#emp.empno},named_table,ordered_set]).

    We fill the table with randomly chosen data:

    [{emp,"011103","Black","Alfred",sales,2000},
    + {emp,"041231","Doe","John",prod,2001},
    + {emp,"052341","Smith","John",dev,1997},
    + {emp,"076324","Smith","Ella",sales,1995},
    + {emp,"122334","Weston","Anna",prod,2002},
    + {emp,"535216","Chalker","Samuel",adm,1998},
    + {emp,"789789","Harrysson","Joe",adm,1996},
    + {emp,"963721","Scott","Juliana",dev,2003},
    + {emp,"989891","Brown","Gabriel",prod,1999}]

    Assuming that we want the employee numbers of everyone in the sales department, +there are several ways.

    ets:match/2 can be used:

    1> ets:match(emp_tab, {'_', '$1', '_', '_', sales, '_'}).
    +[["011103"],["076324"]]

    ets:match/2 uses a simpler type of match specification, but it is still unreadable, and one has little control over the returned result. It is always a -list of lists.

    ets:foldl/3 or ets:foldr/3 can be used to avoid the nested lists:

    ets:foldr(fun(#emp{empno = E, dept = sales},Acc) -> [E | Acc];
    -             (_,Acc) -> Acc
    +list of lists.

    ets:foldl/3 or ets:foldr/3 can be used to avoid the nested lists:

    ets:foldr(fun(#emp{empno = E, dept = sales},Acc) -> [E | Acc];
    +             (_,Acc) -> Acc
               end,
    -          [],
    -          emp_tab).

    The result is ["011103","076324"]. The fun is straightforward, so the only + [], + emp_tab).

    The result is ["011103","076324"]. The fun is straightforward, so the only problem is that all the data from the table must be transferred from the table to the calling process for filtering. That is inefficient compared to the ets:match/2 call where the filtering can be done "inside" the emulator and -only the result is transferred to the process.

    Consider a "pure" ets:select/2 call that does what ets:foldr does:

    ets:select(emp_tab, [{#emp{empno = '$1', dept = sales, _='_'},[],['$1']}]).

    Although the record syntax is used, it is still hard to read and even harder to +only the result is transferred to the process.

    Consider a "pure" ets:select/2 call that does what ets:foldr does:

    ets:select(emp_tab, [{#emp{empno = '$1', dept = sales, _='_'},[],['$1']}]).

    Although the record syntax is used, it is still hard to read and even harder to write. The first element of the tuple, #emp{empno = '$1', dept = sales, _='_'}, tells what to match. Elements not matching this are not returned, as in the ets:match/2 example. The second @@ -189,12 +189,12 @@

    hence the employee number is returned. The result is ["011103","076324"], as in the ets:foldr/3 example, but the result is retrieved much more efficiently in terms of execution speed and memory consumption.

    Using ets:fun2ms/1, we can combine the ease of use of the ets:foldr/3 and -the efficiency of the pure ets:select/2 example:

    -include_lib("stdlib/include/ms_transform.hrl").
    +the efficiency of the pure ets:select/2 example:

    -include_lib("stdlib/include/ms_transform.hrl").
     
    -ets:select(emp_tab, ets:fun2ms(
    -                      fun(#emp{empno = E, dept = sales}) ->
    +ets:select(emp_tab, ets:fun2ms(
    +                      fun(#emp{empno = E, dept = sales}) ->
                                   E
    -                      end)).

    This example requires no special knowledge of match specifications to + end)).

    This example requires no special knowledge of match specifications to understand. The head of the fun matches what you want to filter out and the body returns what you want returned. As long as the fun can be kept within the limits of the match specifications, there is no need to transfer all table data to the @@ -216,22 +216,22 @@

    Assume that we want to get all the employee numbers of employees hired before year 2000. Using ets:match/2 is not an alternative here, as relational operators cannot be expressed there. Once again, ets:foldr/3 can do it -(slowly, but correct):

    ets:foldr(fun(#emp{empno = E, empyear = Y},Acc) when Y < 2000 -> [E | Acc];
    -                  (_,Acc) -> Acc
    +(slowly, but correct):

    ets:foldr(fun(#emp{empno = E, empyear = Y},Acc) when Y < 2000 -> [E | Acc];
    +                  (_,Acc) -> Acc
               end,
    -          [],
    -          emp_tab).

    The result is ["052341","076324","535216","789789","989891"], as expected. The + [], + emp_tab).

    The result is ["052341","076324","535216","789789","989891"], as expected. The equivalent expression using a handwritten match specification would look like -this:

    ets:select(emp_tab, [{#emp{empno = '$1', empyear = '$2', _='_'},
    -                     [{'<', '$2', 2000}],
    -                     ['$1']}]).

    This gives the same result. [{'<', '$2', 2000}] is in the guard part and +this:

    ets:select(emp_tab, [{#emp{empno = '$1', empyear = '$2', _='_'},
    +                     [{'<', '$2', 2000}],
    +                     ['$1']}]).

    This gives the same result. [{'<', '$2', 2000}] is in the guard part and therefore discards anything that does not have an empyear (bound to '$2' in -the head) less than 2000, as the guard in the foldr/3 example.

    We write it using ets:fun2ms/1:

    -include_lib("stdlib/include/ms_transform.hrl").
    +the head) less than 2000, as the guard in the foldr/3 example.

    We write it using ets:fun2ms/1:

    -include_lib("stdlib/include/ms_transform.hrl").
     
    -ets:select(emp_tab, ets:fun2ms(
    -                      fun(#emp{empno = E, empyear = Y}) when Y < 2000 ->
    +ets:select(emp_tab, ets:fun2ms(
    +                      fun(#emp{empno = E, empyear = Y}) when Y < 2000 ->
                                E
    -                      end)).

    + end)).

    @@ -239,11 +239,11 @@

    Assume that we want the whole object matching instead of only one element. One alternative is to assign a variable to every part of the record and build it up -once again in the body of the fun, but the following is easier:

    ets:select(emp_tab, ets:fun2ms(
    -                      fun(Obj = #emp{empno = E, empyear = Y})
    +once again in the body of the fun, but the following is easier:

    ets:select(emp_tab, ets:fun2ms(
    +                      fun(Obj = #emp{empno = E, empyear = Y})
                              when Y < 2000 ->
                                   Obj
    -                      end)).

    As in ordinary Erlang matching, you can bind a variable to the whole matched + end)).

    As in ordinary Erlang matching, you can bind a variable to the whole matched object using a "match inside the match", that is, a =. Unfortunately in funs translated to match specifications, it is allowed only at the "top-level", that is, matching the whole object arriving to be matched into a separate variable. @@ -258,10 +258,10 @@

    This example concerns the body of the fun. Assume that all employee numbers beginning with zero (0) must be changed to begin with one (1) instead, and -that we want to create the list [{<Old empno>,<New empno>}]:

    ets:select(emp_tab, ets:fun2ms(
    -                      fun(#emp{empno = [$0 | Rest] }) ->
    -                              {[$0|Rest],[$1|Rest]}
    -                      end)).

    This query hits the feature of partially bound keys in table type ordered_set, +that we want to create the list [{<Old empno>,<New empno>}]:

    ets:select(emp_tab, ets:fun2ms(
    +                      fun(#emp{empno = [$0 | Rest] }) ->
    +                              {[$0|Rest],[$1|Rest]}
    +                      end)).

    This query hits the feature of partially bound keys in table type ordered_set, so that not the whole table needs to be searched, only the part containing keys beginning with 0 is looked into.

    @@ -274,24 +274,24 @@

    {rookie, <employee number>}.
  • For all other employees, return {newbie, <employee number>}, except for those named Smith as they would be affronted by anything other than the tag guru and that is also what is returned for their numbers: -{guru, <employee number>}.
  • This is accomplished as follows:

    ets:select(emp_tab, ets:fun2ms(
    -                      fun(#emp{empno = E, surname = "Smith" }) ->
    -                              {guru,E};
    -                         (#emp{empno = E, empyear = Y}) when Y < 1997  ->
    -                              {inventory, E};
    -                         (#emp{empno = E, empyear = Y}) when Y > 2001  ->
    -                              {newbie, E};
    -                         (#emp{empno = E, empyear = Y}) -> % 1997 -- 2001
    -                              {rookie, E}
    -                      end)).

    The result is as follows:

    [{rookie,"011103"},
    - {rookie,"041231"},
    - {guru,"052341"},
    - {guru,"076324"},
    - {newbie,"122334"},
    - {rookie,"535216"},
    - {inventory,"789789"},
    - {newbie,"963721"},
    - {rookie,"989891"}]

    +{guru, <employee number>}.

    This is accomplished as follows:

    ets:select(emp_tab, ets:fun2ms(
    +                      fun(#emp{empno = E, surname = "Smith" }) ->
    +                              {guru,E};
    +                         (#emp{empno = E, empyear = Y}) when Y < 1997  ->
    +                              {inventory, E};
    +                         (#emp{empno = E, empyear = Y}) when Y > 2001  ->
    +                              {newbie, E};
    +                         (#emp{empno = E, empyear = Y}) -> % 1997 -- 2001
    +                              {rookie, E}
    +                      end)).

    The result is as follows:

    [{rookie,"011103"},
    + {rookie,"041231"},
    + {guru,"052341"},
    + {guru,"076324"},
    + {newbie,"122334"},
    + {rookie,"535216"},
    + {inventory,"789789"},
    + {newbie,"963721"},
    + {rookie,"989891"}]

    @@ -338,18 +338,18 @@

    more, as filtering using Erlang code is not a good idea when tracing (except afterwards, if you trace to file). The concept is similar to that of ets:fun2ms/1 except that you usually use it directly from the shell (which can -also be done with ets:fun2ms/1).

    The following is an example module to trace on:

    -module(toy).
    +also be done with ets:fun2ms/1).

    The following is an example module to trace on:

    -module(toy).
     
    --export([start/1, store/2, retrieve/1]).
    +-export([start/1, store/2, retrieve/1]).
     
    -start(Args) ->
    -    toy_table = ets:new(toy_table, Args).
    +start(Args) ->
    +    toy_table = ets:new(toy_table, Args).
     
    -store(Key, Value) ->
    -    ets:insert(toy_table, {Key,Value}).
    +store(Key, Value) ->
    +    ets:insert(toy_table, {Key,Value}).
     
    -retrieve(Key) ->
    -    [{Key, Value}] = ets:lookup(toy_table, Key),
    +retrieve(Key) ->
    +    [{Key, Value}] = ets:lookup(toy_table, Key),
         Value.

    During model testing, the first test results in {badmatch,16} in {toy,start,1}, why?

    We suspect the ets:new/2 call, as we match hard on the return value, but want only the particular new/2 call with toy_table as first parameter. So we @@ -358,32 +358,32 @@

    trace pattern, so there is no need to call trace only a few processes (usually it is not):

    2> dbg:p(all,call).
     {ok,[{matched,nonode@nohost,25}]}

    We specify the filter, we want to view calls that resemble -ets:new(toy_table, <something>):

    3> dbg:tp(ets,new,dbg:fun2ms(fun([toy_table,_]) -> true end)).
    -{ok,[{matched,nonode@nohost,1},{saved,1}]}

    As can be seen, the fun used with dbg:fun2ms/1 takes a single list as +ets:new(toy_table, <something>):

    3> dbg:tp(ets,new,dbg:fun2ms(fun([toy_table,_]) -> true end)).
    +{ok,[{matched,nonode@nohost,1},{saved,1}]}

    As can be seen, the fun used with dbg:fun2ms/1 takes a single list as parameter instead of a single tuple. The list matches a list of the parameters to the traced function. A single variable can also be used. The body of the fun expresses, in a more imperative way, actions to be taken if the fun head (and the guards) matches. true is returned here, only because the body of a fun -cannot be empty. The return value is discarded.

    The following trace output is received during test:

    (<0.86.0>) call ets:new(toy_table, [ordered_set])

    Assume that we have not found the problem yet, and want to see what ets:new/2 -returns. We use a slightly different trace pattern:

    4> dbg:tp(ets,new,dbg:fun2ms(fun([toy_table,_]) -> return_trace() end)).

    The following trace output is received during test:

    (<0.86.0>) call ets:new(toy_table,[ordered_set])
    -(<0.86.0>) returned from ets:new/2 -> 24

    The call to return_trace results in a trace message when the function returns. +cannot be empty. The return value is discarded.

    The following trace output is received during test:

    (<0.86.0>) call ets:new(toy_table, [ordered_set])

    Assume that we have not found the problem yet, and want to see what ets:new/2 +returns. We use a slightly different trace pattern:

    4> dbg:tp(ets,new,dbg:fun2ms(fun([toy_table,_]) -> return_trace() end)).

    The following trace output is received during test:

    (<0.86.0>) call ets:new(toy_table,[ordered_set])
    +(<0.86.0>) returned from ets:new/2 -> 24

    The call to return_trace results in a trace message when the function returns. It applies only to the specific function call triggering the match specification (and matching the head/guards of the match specification). This is by far the most common call in the body of a dbg match specification.

    The test now fails with {badmatch,24} because the atom toy_table does not match the number returned for an unnamed table. So, the problem is found, the table is to be named, and the arguments supplied by the test program do not -include named_table. We rewrite the start function:

    start(Args) ->
    -    toy_table = ets:new(toy_table, [named_table|Args]).

    With the same tracing turned on, the following trace output is received:

    (<0.86.0>) call ets:new(toy_table,[named_table,ordered_set])
    -(<0.86.0>) returned from ets:new/2 -> toy_table

    Assume that the module now passes all testing and goes into the system. After a +include named_table. We rewrite the start function:

    start(Args) ->
    +    toy_table = ets:new(toy_table, [named_table|Args]).

    With the same tracing turned on, the following trace output is received:

    (<0.86.0>) call ets:new(toy_table,[named_table,ordered_set])
    +(<0.86.0>) returned from ets:new/2 -> toy_table

    Assume that the module now passes all testing and goes into the system. After a while, it is found that table toy_table grows while the system is running and that there are many elements with atoms as keys. We expected only integer keys and so does the rest of the system, but clearly not the entire system. We turn -on call tracing and try to see calls to the module with an atom as the key:

    1> dbg:tracer().
    -{ok,<0.88.0>}
    -2> dbg:p(all,call).
    -{ok,[{matched,nonode@nohost,25}]}
    -3> dbg:tpl(toy,store,dbg:fun2ms(fun([A,_]) when is_atom(A) -> true end)).
    -{ok,[{matched,nonode@nohost,1},{saved,1}]}

    We use dbg:tpl/3 to ensure to catch local calls (assume that the module has +on call tracing and try to see calls to the module with an atom as the key:

    1> dbg:tracer().
    +{ok,<0.88.0>}
    +2> dbg:p(all,call).
    +{ok,[{matched,nonode@nohost,25}]}
    +3> dbg:tpl(toy,store,dbg:fun2ms(fun([A,_]) when is_atom(A) -> true end)).
    +{ok,[{matched,nonode@nohost,1},{saved,1}]}

    We use dbg:tpl/3 to ensure to catch local calls (assume that the module has grown since the smaller version and we are unsure if this inserting of atoms is not done locally). When in doubt, always use local call tracing.

    Assume that nothing happens when tracing in this way. The function is never called with these parameters. We conclude that someone else (some other module) @@ -391,11 +391,11 @@

    calling function. The calling function can be retrieved using the match specification function caller. To get it into the trace message, the match specification function message must be used. The filter call looks like this -(looking for calls to ets:insert/2):

    4> dbg:tpl(ets,insert,dbg:fun2ms(fun([toy_table,{A,_}]) when is_atom(A) ->
    -                                    message(caller())
    -                                  end)).
    -{ok,[{matched,nonode@nohost,1},{saved,2}]}

    The caller is now displayed in the "additional message" part of the trace -output, and the following is displayed after a while:

    (<0.86.0>) call ets:insert(toy_table,{garbage,can}) ({evil_mod,evil_fun,2})

    You have realized that function evil_fun of the evil_mod module, with arity +(looking for calls to ets:insert/2):

    4> dbg:tpl(ets,insert,dbg:fun2ms(fun([toy_table,{A,_}]) when is_atom(A) ->
    +                                    message(caller())
    +                                  end)).
    +{ok,[{matched,nonode@nohost,1},{saved,2}]}

    The caller is now displayed in the "additional message" part of the trace +output, and the following is displayed after a while:

    (<0.86.0>) call ets:insert(toy_table,{garbage,can}) ({evil_mod,evil_fun,2})

    You have realized that function evil_fun of the evil_mod module, with arity 2, is causing all this trouble.

    This example illustrates the most used calls in match specifications for dbg. The other, more esoteric, calls are listed and explained in Match specifications in Erlang in ERTS User's Guide, @@ -430,26 +430,26 @@

    [{{'$1','$2'},[{is_atom,'$1'}],['$2']}].

  • Variables that are not included in the head are imported from the environment and made into match specification const expressions. Example from the shell:

    1> X = 25.
     25
    -2> ets:fun2ms(fun({A,B}) when A > X -> B end).
    -[{{'$1','$2'},[{'>','$1',{const,25}}],['$2']}]
  • Matching with = cannot be used in the body. It can only be used on the -top-level in the head of the fun. Example from the shell again:

    1> ets:fun2ms(fun({A,[B|C]} = D) when A > B -> D end).
    -[{{'$1',['$2'|'$3']},[{'>','$1','$2'}],['$_']}]
    -2> ets:fun2ms(fun({A,[B|C]=D}) when A > B -> D end).
    -Error: fun with head matching ('=' in head) cannot be translated into
    +2> ets:fun2ms(fun({A,B}) when A > X -> B end).
    +[{{'$1','$2'},[{'>','$1',{const,25}}],['$2']}]
  • Matching with = cannot be used in the body. It can only be used on the +top-level in the head of the fun. Example from the shell again:

    1> ets:fun2ms(fun({A,[B|C]} = D) when A > B -> D end).
    +[{{'$1',['$2'|'$3']},[{'>','$1','$2'}],['$_']}]
    +2> ets:fun2ms(fun({A,[B|C]=D}) when A > B -> D end).
    +Error: fun with head matching ('=' in head) cannot be translated into
     match_spec
    -{error,transform_error}
    -3> ets:fun2ms(fun({A,[B|C]}) when A > B -> D = [B|C], D end).
    -Error: fun with body matching ('=' in body) is illegal as match_spec
    -{error,transform_error}

    All variables are bound in the head of a match specification, so the +{error,transform_error} +3> ets:fun2ms(fun({A,[B|C]}) when A > B -> D = [B|C], D end). +Error: fun with body matching ('=' in body) is illegal as match_spec +{error,transform_error}

  • All variables are bound in the head of a match specification, so the translator cannot allow multiple bindings. The special case when matching is done on the top-level makes the variable bind to '$_' in the resulting match specification. It is to allow a more natural access to the whole matched -object. Pseudo function object() can be used instead, see below.

    The following expressions are translated equally:

    ets:fun2ms(fun({a,_} = A) -> A end).
    -ets:fun2ms(fun({a,_}) -> object() end).
  • The special match specification variables '$_' and '$*' can be accessed +object. Pseudo function object() can be used instead, see below.

    The following expressions are translated equally:

    ets:fun2ms(fun({a,_} = A) -> A end).
    +ets:fun2ms(fun({a,_}) -> object() end).
  • The special match specification variables '$_' and '$*' can be accessed through the pseudo functions object() (for '$_') and bindings() (for '$*'). As an example, one can translate the following ets:match_object/2 -call to a ets:select/2 call:

    ets:match_object(Table, {'$1',test,'$2'}).

    This is the same as:

    ets:select(Table, ets:fun2ms(fun({A,test,B}) -> object() end)).

    In this simple case, the former expression is probably preferable in terms of -readability.

    The ets:select/2 call conceptually looks like this in the resulting code:

    ets:select(Table, [{{'$1',test,'$2'},[],['$_']}]).

    Matching on the top-level of the fun head can be a more natural way to access +call to a ets:select/2 call:

    ets:match_object(Table, {'$1',test,'$2'}).

    This is the same as:

    ets:select(Table, ets:fun2ms(fun({A,test,B}) -> object() end)).

    In this simple case, the former expression is probably preferable in terms of +readability.

    The ets:select/2 call conceptually looks like this in the resulting code:

    ets:select(Table, [{{'$1',test,'$2'},[],['$_']}]).

    Matching on the top-level of the fun head can be a more natural way to access '$_', see above.

  • Term constructions/literals are translated as much as is needed to get them into valid match specification. This way tuples are made into match specification tuple constructions (a one element tuple containing the tuple) diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/notes.html b/prs/8803/lib/stdlib-6.0.1/doc/html/notes.html index 4aa70b0ab3e4d..4fd1b3b5df07b 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/notes.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/notes.html @@ -160,8 +160,8 @@

    Improvements and New Features

    • The functions is_equal/2, map/2, and filtermap/2 have been added to the modules sets, ordsets, and gb_sets.

      Own Id: OTP-18622 Aux Id: PR-7183, PR-7232

    • The compiler now emits nicer error message for function head mismatches. -For example, given:

      a() -> ok;
      -a(_) -> error.

      Erlang/OTP 26 and earlier would emit a diagnostic similar to:

      t.erl:6:1: head mismatch
      +For example, given:

      a() -> ok;
      +a(_) -> error.

      Erlang/OTP 26 and earlier would emit a diagnostic similar to:

      t.erl:6:1: head mismatch
       %    6| a(_) -> error.
       %     | ^

      while in Erlang/OTP 27 the diagnostic is similar to:

      t.erl:6:1: head mismatch: function a with arities 0 and 1 is regarded as two distinct functions. Is the number of arguments incorrect or is the semicolon in a/0 unwanted?
       %    6| a(_) -> error.
      @@ -194,12 +194,12 @@ 

      shell:prompt_width/1 have been exported to help with custom prompt implementations.

      Own Id: OTP-18834 Aux Id: PR-7675

    • The shell now pages long output from the documentation help command (h(Module)), auto completions and the search command.

      Own Id: OTP-18846 Aux Id: PR-7845

    • The M-h hotkey (Alt/Option-h) now outputs help for the module or function directly before the cursor.

      Own Id: OTP-18847 Aux Id: PR-7846

    • Added support for adding a custom code formatter that formats your multi-line shell commands in your preferred formatting on submission. See shell:format_shell_func/ and shell:erl_pp_format_func/1.

      Own Id: OTP-18848 Aux Id: PR-7847

    • Added shell functions for viewing, forgetting and saving locally defined functions, types and records.

      Own Id: OTP-18852 Aux Id: PR-7844

    • Added string:jaro_similarity/2, which can be used to calculate the similarity between two strings.

      Own Id: OTP-18865 Aux Id: PR-7879

    • The new function ets:update_element/4 is similar to ets:update_element/3, but takes a default tuple as the fourth argument, which will be inserted if no previous record with that key exists.

      Own Id: OTP-18870 Aux Id: PR-7857

    • Added functions to retrieve the next higher or lower key/element from gb_trees and gb_sets, as well as returning iterators that start at given keys/elements.

      Own Id: OTP-18874 Aux Id: PR-7745

    • When the shell built-in function c/1,2 is used to re-compile a module, the current working directory of the original compilation is now added to the include path.

      Own Id: OTP-18908 Aux Id: PR-7957

    • The timer module now uses a private table for its internal state, slightly improving its performance.

      Own Id: OTP-18914 Aux Id: PR-7973

    • EEP-59 - Documentation Attributes has been implemented.

      Documentation attributes can be used to document functions, types, callbacks, and modules. The keyword -moduledoc "Documentation here". is used to document modules, while -doc "Documentation here". can be used on top of functions, types, and callbacks to document them, respectively.

      • Types, callbacks, and function documentation can be set to hidden either via -doc false or -doc hidden. When documentation attributes mark a type as hidden, they will not be part of the documentation.

      • The documentation from moduledoc and doc gets added by default to the binary beam file, following the format of EEP-48.

      • Using the compiler flag warn_missing_doc will raise a warning when -doc attributes are missing in exported functions, types, and callbacks.

      • Using the compiler flag warn_missing_spec_documented will raise a warning when -spec attributes are missing in documented functions, types, and callbacks.

      • moduledocs and docs may refer to external files to be embedded, such as -doc {file, "README.md"}., which refers to the file README.md found in the current working directory.

      • The compiler warns about exported functions whose specs refer to hidden types. Thus, there will be warnings when a hidden type (meaning, the type is not part of the documentation) gets used in an exported function.

      Own Id: OTP-18916 Aux Id: PR-7936

    • New ets functions ets:first_lookup/1, ets:next_lookup/2, ets:prev_lookup/2 and ets:last_lookup/1. Example: ets:next_lookup/1 is equivalent to ets:next/2 followed by ets:lookup/2 with the next key. The new combined functions are more efficient and with guaranteed atomicity.

      Own Id: OTP-18923 Aux Id: PR-6791

    • The maybe expression is now enabled by default.

      To use maybe as an atom, it needs to be single-quoted. Alternatively, the maybe expression can be disabled by disabling the maybe_expr feature. That can be done by placing the following the line at the beginning of an Erlang source file:

      -feature(maybe_expr, disable).

      Another way to disable the maybe_expr feature is by passing the -disable-feature option to erlc:

      erlc -disable-feature maybe_expr some_file.erl

      Own Id: OTP-18944 Aux Id: PR-8067

    • The compiler will now raise a warning when updating record/map literals. As an example, consider this module:

      -module(t).
      --export([f/0]).
      --record(r, {a,b,c}).
      +spec attributes are missing in documented functions, types, and callbacks.

    • moduledocs and docs may refer to external files to be embedded, such as -doc {file, "README.md"}., which refers to the file README.md found in the current working directory.

    • The compiler warns about exported functions whose specs refer to hidden types. Thus, there will be warnings when a hidden type (meaning, the type is not part of the documentation) gets used in an exported function.

    Own Id: OTP-18916 Aux Id: PR-7936

  • New ets functions ets:first_lookup/1, ets:next_lookup/2, ets:prev_lookup/2 and ets:last_lookup/1. Example: ets:next_lookup/1 is equivalent to ets:next/2 followed by ets:lookup/2 with the next key. The new combined functions are more efficient and with guaranteed atomicity.

    Own Id: OTP-18923 Aux Id: PR-6791

  • The maybe expression is now enabled by default.

    To use maybe as an atom, it needs to be single-quoted. Alternatively, the maybe expression can be disabled by disabling the maybe_expr feature. That can be done by placing the following the line at the beginning of an Erlang source file:

    -feature(maybe_expr, disable).

    Another way to disable the maybe_expr feature is by passing the -disable-feature option to erlc:

    erlc -disable-feature maybe_expr some_file.erl

    Own Id: OTP-18944 Aux Id: PR-8067

  • The compiler will now raise a warning when updating record/map literals. As an example, consider this module:

    -module(t).
    +-export([f/0]).
    +-record(r, {a,b,c}).
     
    -f() ->
    -    #r{a=1}#r{b=2}.

    The compiler raises the following warning:

    1> c(t).
    +f() ->
    +    #r{a=1}#r{b=2}.

    The compiler raises the following warning:

    1> c(t).
     t.erl:6:12: Warning: expression updates a literal
     %    6|     #r{a=1}#r{b=2}.
     %     |            ^

    Own Id: OTP-18951 Aux Id: PR-8069

  • The documentation has been migrated to use Markdown and ExDoc.

    Own Id: OTP-18955 Aux Id: PR-8026

  • Optimized ets:foldl and ets:foldr to use new ets:next_lookup. Also made them immune against table renaming.

    Own Id: OTP-18993 Aux Id: PR-8048

  • Windows now supports all functions in math.

    Own Id: OTP-19001 Aux Id: PR-8164

  • erl_lint (and by extension the compiler) will now warn for code using deprecated callbacks.

    The only callback currenly deprecated is format_status/2 in gen_server, gen_event and gen_statem.

    You can use nowarn_deprecated_callback to silence the warning.

    Own Id: OTP-19010 Aux Id: PR-8205

  • There is a new module json for encoding and decoding JSON.

    Both encoding and decoding can be customized. Decoding can be done in a SAX-like fashion and handle multiple documents and streams of data.

    Own Id: OTP-19020 Aux Id: PR-8111

  • diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/orddict.html b/prs/8803/lib/stdlib-6.0.1/doc/html/orddict.html index ee6ce6be1cf71..4630cbdbcac6b 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/orddict.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/orddict.html @@ -142,13 +142,13 @@

    Functions append/3 and append_list/3 are included so that keyed values can be stored in a list accumulator, for -example:

    > D0 = orddict:new(),
    -  D1 = orddict:store(files, [], D0),
    -  D2 = orddict:append(files, f1, D1),
    -  D3 = orddict:append(files, f2, D2),
    -  D4 = orddict:append(files, f3, D3),
    -  orddict:fetch(files, D4).
    -[f1,f2,f3]

    This saves the trouble of first fetching a keyed value, appending a new value to +example:

    > D0 = orddict:new(),
    +  D1 = orddict:store(files, [], D0),
    +  D2 = orddict:append(files, f1, D1),
    +  D3 = orddict:append(files, f2, D2),
    +  D4 = orddict:append(files, f3, D3),
    +  orddict:fetch(files, D4).
    +[f1,f2,f3]

    This saves the trouble of first fetching a keyed value, appending a new value to the list of stored values, and storing the result.

    Function fetch/2 is to be used if the key is known to be in the dictionary, otherwise function find/2.

    @@ -537,16 +537,16 @@

    append(Key, Value, Orddict1)

    Appends a new Value to the current list of values associated with Key. An exception is generated if the initial value associated with Key is not a list -of values.

    See also section Notes.

    Example 1:

    1> OrdDict1 = orddict:from_list([{x, []}]).
    -[{x,[]}]
    -2> OrdDict2 = orddict:append(x, 1, OrdDict1).
    -[{x,[1]}]
    -3> OrdDict3 = orddict:append(x, 2, OrdDict2).
    -[{x,[1,2]}]
    -4> orddict:append(y, 3, OrdDict3).
    -[{x,[1,2]},{y,[3]}]

    Example 2:

    1> OrdDict1 = orddict:from_list([{a, no_list}]).
    -[{a,no_list}]
    -2> orddict:append(a, 1, OrdDict1).
    +of values.

    See also section Notes.

    Example 1:

    1> OrdDict1 = orddict:from_list([{x, []}]).
    +[{x,[]}]
    +2> OrdDict2 = orddict:append(x, 1, OrdDict1).
    +[{x,[1]}]
    +3> OrdDict3 = orddict:append(x, 2, OrdDict2).
    +[{x,[1,2]}]
    +4> orddict:append(y, 3, OrdDict3).
    +[{x,[1,2]},{y,[3]}]

    Example 2:

    1> OrdDict1 = orddict:from_list([{a, no_list}]).
    +[{a,no_list}]
    +2> orddict:append(a, 1, OrdDict1).
     ** exception error: bad argument
          in operator  ++/2
             called as no_list ++ [1]
    @@ -583,12 +583,12 @@

    append_list(Key, ValList, Orddict1)

    Appends a list of values ValList to the current list of values associated with Key. An exception is generated if the initial value associated with Key is -not a list of values.

    See also section Notes.

    Example:

    1> OrdDict1 = orddict:from_list([{x, []}]).
    -[{x,[]}]
    -2> OrdDict2 = orddict:append_list(x, [1,2], OrdDict1).
    -[{x,[1,2]}]
    -3> OrdDict3 = orddict:append_list(y, [3,4], OrdDict2).
    -[{x,[1,2]},{y,[3,4]}]
    +not a list of values.

    See also section Notes.

    Example:

    1> OrdDict1 = orddict:from_list([{x, []}]).
    +[{x,[]}]
    +2> OrdDict2 = orddict:append_list(x, [1,2], OrdDict1).
    +[{x,[1,2]}]
    +3> OrdDict3 = orddict:append_list(y, [3,4], OrdDict2).
    +[{x,[1,2]},{y,[3,4]}]
    @@ -617,10 +617,10 @@

    erase(Key, Orddict1)

    -

    Erases all items with a specified key from a dictionary.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    -[{a,1},{b,2}]
    -2> orddict:erase(a, OrdDict1).
    -[{b,2}]
    +

    Erases all items with a specified key from a dictionary.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    +[{a,1},{b,2}]
    +2> orddict:erase(a, OrdDict1).
    +[{b,2}]
    @@ -650,11 +650,11 @@

    fetch(Key, Orddict)

    Returns the value associated with Key in dictionary Orddict. This function assumes that the Key is present in the dictionary. An exception is generated -if Key is not in the dictionary.

    See also section Notes.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    -[{a,1},{b,2}]
    -2> orddict:fetch(a, OrdDict1).
    +if Key is not in the dictionary.

    See also section Notes.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    +[{a,1},{b,2}]
    +2> orddict:fetch(a, OrdDict1).
     1
    -3> orddict:fetch(missing, OrdDict1).
    +3> orddict:fetch(missing, OrdDict1).
     ** exception error: no function clause matching orddict:fetch(missing,[])
    @@ -683,10 +683,10 @@

    fetch_keys(Orddict)

    -

    Returns a list of all keys in a dictionary.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    -[{a,1},{b,2}]
    -2> orddict:fetch_keys(OrdDict1).
    -[a,b]
    +

    Returns a list of all keys in a dictionary.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    +[{a,1},{b,2}]
    +2> orddict:fetch_keys(OrdDict1).
    +[a,b]
    @@ -719,10 +719,10 @@

    filter(Pred, Orddict1)

    Orddict2 is a dictionary of all keys and values in Orddict1 for which -Pred(Key, Value) is true.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    -[{a,1},{b,2}]
    -2> orddict:filter(fun (K, V) -> V > 1 end, OrdDict1).
    -[{b,2}]
    +Pred(Key, Value) is true.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    +[{a,1},{b,2}]
    +2> orddict:filter(fun (K, V) -> V > 1 end, OrdDict1).
    +[{b,2}]
    @@ -752,11 +752,11 @@

    find(Key, Orddict)

    Searches for a key in a dictionary. Returns {ok, Value}, where Value is the value associated with Key, or error if the key is not present in the -dictionary.

    See also section Notes.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    -[{a,1},{b,2}]
    -2> orddict:find(a, OrdDict1).
    -{ok,1}
    -3> orddict:find(c, OrdDict1).
    +dictionary.

    See also section Notes.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    +[{a,1},{b,2}]
    +2> orddict:find(a, OrdDict1).
    +{ok,1}
    +3> orddict:find(c, OrdDict1).
     error
    @@ -794,10 +794,10 @@

    fold(Fun, Acc0, Orddict)

    Calls Fun on successive keys and values of Orddict together with an extra argument Acc (short for accumulator). Fun must return a new accumulator that -is passed to the next call. Acc0 is returned if the list is empty.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    -[{a,1},{b,2}]
    -2> orddict:fold(fun (K, V, Acc) -> [{K, V+100} | Acc] end, [], OrdDict1).
    -[{b,102},{a,101}]
    +is passed to the next call. Acc0 is returned if the list is empty.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    +[{a,1},{b,2}]
    +2> orddict:fold(fun (K, V, Acc) -> [{K, V+100} | Acc] end, [], OrdDict1).
    +[{b,102},{a,101}]
    @@ -916,10 +916,10 @@

    map(Fun, Orddict1)

    Calls Fun on successive keys and values of Orddict1 to return a new value -for each key.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    -[{a,1},{b,2}]
    -2> orddict:map(fun (_K, V) -> V + 100 end, OrdDict1).
    -[{a,101},{b,102}]
    +for each key.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    +[{a,1},{b,2}]
    +2> orddict:map(fun (_K, V) -> V + 100 end, OrdDict1).
    +[{a,101},{b,102}]
    @@ -955,15 +955,15 @@

    merge(Fun, Orddict1, Orddict2)

    Merges two dictionaries, Orddict1 and Orddict2, to create a new dictionary. All the Key-Value pairs from both dictionaries are included in the new dictionary.

    If a key occurs in both dictionaries, Fun is called with the key -and both values to return a new value.

    merge/3 can be defined as follows, but is faster:

    merge(Fun, D1, D2) ->
    -    fold(fun (K, V1, D) ->
    -                 update(K, fun (V2) -> Fun(K, V1, V2) end, V1, D)
    -         end, D2, D1).

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    -[{a,1},{b,2}]
    -2> OrdDict2 = orddict:from_list([{b, 7}, {c, 8}]).
    -[{b,7},{c,8}]
    -3> orddict:merge(fun (K, V1, V2) -> V1 * V2 end, OrdDict1, OrdDict2).
    -[{a,1},{b,14},{c,8}]
    +and both values to return a new value.

    merge/3 can be defined as follows, but is faster:

    merge(Fun, D1, D2) ->
    +    fold(fun (K, V1, D) ->
    +                 update(K, fun (V2) -> Fun(K, V1, V2) end, V1, D)
    +         end, D2, D1).

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    +[{a,1},{b,2}]
    +2> OrdDict2 = orddict:from_list([{b, 7}, {c, 8}]).
    +[{b,7},{c,8}]
    +3> orddict:merge(fun (K, V1, V2) -> V1 * V2 end, OrdDict1, OrdDict2).
    +[{a,1},{b,14},{c,8}]
    @@ -1049,12 +1049,12 @@

    store(Key, Value, Orddict1)

    Stores a Key-Value pair in a dictionary. If the Key already exists in -Orddict1, the associated value is replaced by Value.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    -[{a,1},{b,2}]
    -2> orddict:store(a, 99, OrdDict1).
    -[{a,99},{b,2}]
    -3> orddict:store(c, 100, OrdDict1).
    -[{a,1},{b,2},{c,100}]
    +Orddict1, the associated value is replaced by Value.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    +[{a,1},{b,2}]
    +2> orddict:store(a, 99, OrdDict1).
    +[{a,99},{b,2}]
    +3> orddict:store(c, 100, OrdDict1).
    +[{a,1},{b,2},{c,100}]
    @@ -1090,11 +1090,11 @@

    take(Key, Orddict)

    This function returns value from dictionary and new dictionary without this -value. Returns error if the key is not present in the dictionary.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    -[{a,1},{b,2}]
    -2> orddict:take(a, OrdDict1).
    -{1,[{b,2}]}
    -3> orddict:take(missing, OrdDict1).
    +value. Returns error if the key is not present in the dictionary.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    +[{a,1},{b,2}]
    +2> orddict:take(a, OrdDict1).
    +{1,[{b,2}]}
    +3> orddict:take(missing, OrdDict1).
     error
    @@ -1156,10 +1156,10 @@

    update(Key, Fun, Orddict1)

    Updates a value in a dictionary by calling Fun on the value to get a new -value. An exception is generated if Key is not present in the dictionary.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    -[{a,1},{b,2}]
    -2> orddict:update(a, fun (V) -> V + 100 end, OrdDict1).
    -[{a,101},{b,2}]
    +value. An exception is generated if Key is not present in the dictionary.

    Example:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    +[{a,1},{b,2}]
    +2> orddict:update(a, fun (V) -> V + 100 end, OrdDict1).
    +[{a,101},{b,2}]
    @@ -1194,14 +1194,14 @@

    update(Key, Fun, Initial, Orddict1)

    Updates a value in a dictionary by calling Fun on the value to get a new value. If Key is not present in the dictionary, Initial is stored as the -first value.

    For example, append/3 can be defined as follows:

    append(Key, Val, D) ->
    -    update(Key, fun (Old) -> Old ++ [Val] end, [Val], D).

    Example 1:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    -[{a,1},{b,2}]
    -2> orddict:update(c, fun (V) -> V + 100 end, 99, OrdDict1).
    -[{a,1},{b,2},{c,99}]

    Example 2:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    -[{a,1},{b,2}]
    -2> orddict:update(a, fun (V) -> V + 100 end, 99, OrdDict1).
    -[{a,101},{b,2}]
    +first value.

    For example, append/3 can be defined as follows:

    append(Key, Val, D) ->
    +    update(Key, fun (Old) -> Old ++ [Val] end, [Val], D).

    Example 1:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    +[{a,1},{b,2}]
    +2> orddict:update(c, fun (V) -> V + 100 end, 99, OrdDict1).
    +[{a,1},{b,2},{c,99}]

    Example 2:

    1> OrdDict1 = orddict:from_list([{a, 1}, {b, 2}]).
    +[{a,1},{b,2}]
    +2> orddict:update(a, fun (V) -> V + 100 end, 99, OrdDict1).
    +[{a,101},{b,2}]
    @@ -1235,8 +1235,8 @@

    update_counter(Key, Increment, Orddict1)Adds Increment to the value associated with Key and store this value. If Key is not present in the dictionary, Increment is stored as the first -value.

    This can be defined as follows, but is faster:

    update_counter(Key, Incr, D) ->
    -    update(Key, fun (Old) -> Old + Incr end, Incr, D).
    +value.

    This can be defined as follows, but is faster:

    update_counter(Key, Incr, D) ->
    +    update(Key, fun (Old) -> Old + Incr end, Incr, D).

    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/peer.html b/prs/8803/lib/stdlib-6.0.1/doc/html/peer.html index c2be24a879086..ebc0f27b0fe9c 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/peer.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/peer.html @@ -161,127 +161,127 @@

    manual analysis. If the test case fails, the CRASH REPORT contains these arguments
  • multiple test cases can run concurrently speeding up overall testing process, peer node names are unique even when there are multiple instances of the same -test suite running in parallel
  • -module(my_SUITE).
    --behaviour(ct_suite).
    --export([all/0, groups/0]).
    --export([basic/1, args/1, named/1, restart_node/1, multi_node/1]).
    +test suite running in parallel
    -module(my_SUITE).
    +-behaviour(ct_suite).
    +-export([all/0, groups/0]).
    +-export([basic/1, args/1, named/1, restart_node/1, multi_node/1]).
     
    --include_lib("common_test/include/ct.hrl").
    +-include_lib("common_test/include/ct.hrl").
     
    -groups() ->
    -    [{quick, [parallel],
    -        [basic, args, named, restart_node, multi_node]}].
    +groups() ->
    +    [{quick, [parallel],
    +        [basic, args, named, restart_node, multi_node]}].
     
    -all() ->
    -    [{group, quick}].
    +all() ->
    +    [{group, quick}].
     
    -basic(Config) when is_list(Config) ->
    -    {ok, Peer, _Node} = ?CT_PEER(),
    -    peer:stop(Peer).
    +basic(Config) when is_list(Config) ->
    +    {ok, Peer, _Node} = ?CT_PEER(),
    +    peer:stop(Peer).
     
    -args(Config) when is_list(Config) ->
    +args(Config) when is_list(Config) ->
         %% specify additional arguments to the new node
    -    {ok, Peer, _Node} = ?CT_PEER(["-emu_flavor", "smp"]),
    -    peer:stop(Peer).
    +    {ok, Peer, _Node} = ?CT_PEER(["-emu_flavor", "smp"]),
    +    peer:stop(Peer).
     
    -named(Config) when is_list(Config) ->
    +named(Config) when is_list(Config) ->
         %% pass test case name down to function starting nodes
    -    Peer = start_node_impl(named_test),
    -    peer:stop(Peer).
    +    Peer = start_node_impl(named_test),
    +    peer:stop(Peer).
     
    -start_node_impl(ActualTestCase) ->
    -    {ok, Peer, Node} = ?CT_PEER(#{name => ?CT_PEER_NAME(ActualTestCase)}),
    +start_node_impl(ActualTestCase) ->
    +    {ok, Peer, Node} = ?CT_PEER(#{name => ?CT_PEER_NAME(ActualTestCase)}),
         %% extra setup needed for multiple test cases
    -    ok = rpc:call(Node, application, set_env, [kernel, key, value]),
    +    ok = rpc:call(Node, application, set_env, [kernel, key, value]),
         Peer.
     
    -restart_node(Config) when is_list(Config) ->
    -    Name = ?CT_PEER_NAME(),
    -    {ok, Peer, Node} = ?CT_PEER(#{name => Name}),
    -    peer:stop(Peer),
    +restart_node(Config) when is_list(Config) ->
    +    Name = ?CT_PEER_NAME(),
    +    {ok, Peer, Node} = ?CT_PEER(#{name => Name}),
    +    peer:stop(Peer),
         %% restart the node with the same name as before
    -    {ok, Peer2, Node} = ?CT_PEER(#{name => Name, args => ["+fnl"]}),
    -    peer:stop(Peer2).

    The next example demonstrates how to start multiple nodes concurrently:

    multi_node(Config) when is_list(Config) ->
    -    Peers = [?CT_PEER(#{wait_boot => {self(), tag}})
    -        || _ <- lists:seq(1, 4)],
    +    {ok, Peer2, Node} = ?CT_PEER(#{name => Name, args => ["+fnl"]}),
    +    peer:stop(Peer2).

    The next example demonstrates how to start multiple nodes concurrently:

    multi_node(Config) when is_list(Config) ->
    +    Peers = [?CT_PEER(#{wait_boot => {self(), tag}})
    +        || _ <- lists:seq(1, 4)],
         %% wait for all nodes to complete boot process, get their names:
    -    _Nodes = [receive {tag, {started, Node, Peer}} -> Node end
    -        || {ok, Peer} <- Peers],
    -    [peer:stop(Peer) || {ok, Peer} <- Peers].

    Start a peer on a different host. Requires ssh key-based authentication set -up, allowing "another_host" connection without password prompt.

    Ssh = os:find_executable("ssh"),
    -peer:start_link(#{exec => {Ssh, ["another_host", "erl"]},
    -    connection => standard_io}),

    The following Common Test case demonstrates Docker integration, starting two + _Nodes = [receive {tag, {started, Node, Peer}} -> Node end + || {ok, Peer} <- Peers], + [peer:stop(Peer) || {ok, Peer} <- Peers].

    Start a peer on a different host. Requires ssh key-based authentication set +up, allowing "another_host" connection without password prompt.

    Ssh = os:find_executable("ssh"),
    +peer:start_link(#{exec => {Ssh, ["another_host", "erl"]},
    +    connection => standard_io}),

    The following Common Test case demonstrates Docker integration, starting two containers with hostnames "one" and "two". In this example Erlang nodes running -inside containers form an Erlang cluster.

    docker(Config) when is_list(Config) ->
    -    Docker = os:find_executable("docker"),
    -    PrivDir = proplists:get_value(priv_dir, Config),
    -    build_release(PrivDir),
    -    build_image(PrivDir),
    +inside containers form an Erlang cluster.

    docker(Config) when is_list(Config) ->
    +    Docker = os:find_executable("docker"),
    +    PrivDir = proplists:get_value(priv_dir, Config),
    +    build_release(PrivDir),
    +    build_image(PrivDir),
     
         %% start two Docker containers
    -    {ok, Peer, Node} = peer:start_link(#{name => lambda,
    +    {ok, Peer, Node} = peer:start_link(#{name => lambda,
             connection => standard_io,
    -        exec => {Docker, ["run", "-h", "one", "-i", "lambda"]}}),
    -    {ok, Peer2, Node2} = peer:start_link(#{name => lambda,
    +        exec => {Docker, ["run", "-h", "one", "-i", "lambda"]}}),
    +    {ok, Peer2, Node2} = peer:start_link(#{name => lambda,
             connection => standard_io,
    -        exec => {Docker, ["run", "-h", "two", "-i", "lambda"]}}),
    +        exec => {Docker, ["run", "-h", "two", "-i", "lambda"]}}),
     
         %% find IP address of the second node using alternative connection RPC
    -    {ok, Ips} = peer:call(Peer2, inet, getifaddrs, []),
    -    {"eth0", Eth0} = lists:keyfind("eth0", 1, Ips),
    -    {addr, Ip} = lists:keyfind(addr, 1, Eth0),
    +    {ok, Ips} = peer:call(Peer2, inet, getifaddrs, []),
    +    {"eth0", Eth0} = lists:keyfind("eth0", 1, Ips),
    +    {addr, Ip} = lists:keyfind(addr, 1, Eth0),
     
         %% make first node to discover second one
    -    ok = peer:call(Peer, inet_db, set_lookup, [[file]]),
    -    ok = peer:call(Peer, inet_db, add_host, [Ip, ["two"]]),
    +    ok = peer:call(Peer, inet_db, set_lookup, [[file]]),
    +    ok = peer:call(Peer, inet_db, add_host, [Ip, ["two"]]),
     
         %% join a cluster
    -    true = peer:call(Peer, net_kernel, connect_node, [Node2]),
    +    true = peer:call(Peer, net_kernel, connect_node, [Node2]),
         %% verify that second peer node has only the first node visible
    -    [Node] = peer:call(Peer2, erlang, nodes, []),
    +    [Node] = peer:call(Peer2, erlang, nodes, []),
     
         %% stop peers, causing containers to also stop
    -    peer:stop(Peer2),
    -    peer:stop(Peer).
    +    peer:stop(Peer2),
    +    peer:stop(Peer).
     
    -build_release(Dir) ->
    +build_release(Dir) ->
         %% load sasl.app file, otherwise application:get_key will fail
    -    application:load(sasl),
    +    application:load(sasl),
         %% create *.rel - release file
    -    RelFile = filename:join(Dir, "lambda.rel"),
    -    Release = {release, {"lambda", "1.0.0"},
    -        {erts, erlang:system_info(version)},
    -        [{App, begin {ok, Vsn} = application:get_key(App, vsn), Vsn end}
    -            || App <- [kernel, stdlib, sasl]]},
    -    ok = file:write_file(RelFile, list_to_binary(lists:flatten(
    -        io_lib:format("~tp.", [Release])))),
    -    RelFileNoExt = filename:join(Dir, "lambda"),
    +    RelFile = filename:join(Dir, "lambda.rel"),
    +    Release = {release, {"lambda", "1.0.0"},
    +        {erts, erlang:system_info(version)},
    +        [{App, begin {ok, Vsn} = application:get_key(App, vsn), Vsn end}
    +            || App <- [kernel, stdlib, sasl]]},
    +    ok = file:write_file(RelFile, list_to_binary(lists:flatten(
    +        io_lib:format("~tp.", [Release])))),
    +    RelFileNoExt = filename:join(Dir, "lambda"),
     
         %% create boot script
    -    {ok, systools_make, []} = systools:make_script(RelFileNoExt,
    -        [silent, {outdir, Dir}]),
    +    {ok, systools_make, []} = systools:make_script(RelFileNoExt,
    +        [silent, {outdir, Dir}]),
         %% package release into *.tar.gz
    -    ok = systools:make_tar(RelFileNoExt, [{erts, code:root_dir()}]).
    +    ok = systools:make_tar(RelFileNoExt, [{erts, code:root_dir()}]).
     
    -build_image(Dir) ->
    +build_image(Dir) ->
         %% Create Dockerfile example, working only for Ubuntu 20.04
         %% Expose port 4445, and make Erlang distribution to listen
         %%  on this port, and connect to it without EPMD
         %% Set cookie on both nodes to be the same.
    -    BuildScript = filename:join(Dir, "Dockerfile"),
    +    BuildScript = filename:join(Dir, "Dockerfile"),
         Dockerfile =
           "FROM ubuntu:20.04 as runner\n"
           "EXPOSE 4445\n"
           "WORKDIR /opt/lambda\n"
           "COPY lambda.tar.gz /tmp\n"
           "RUN tar -zxvf /tmp/lambda.tar.gz -C /opt/lambda\n"
    -      "ENTRYPOINT [\"/opt/lambda/erts-" ++ erlang:system_info(version) ++
    +      "ENTRYPOINT [\"/opt/lambda/erts-" ++ erlang:system_info(version) ++
           "/bin/dyn_erl\", \"-boot\", \"/opt/lambda/releases/1.0.0/start\","
           " \"-kernel\", \"inet_dist_listen_min\", \"4445\","
           " \"-erl_epmd_port\", \"4445\","
           " \"-setcookie\", \"secret\"]\n",
    -    ok = file:write_file(BuildScript, Dockerfile),
    -    os:cmd("docker build -t lambda " ++ Dir).
    +
    ok = file:write_file(BuildScript, Dockerfile), + os:cmd("docker build -t lambda " ++ Dir).
    @@ -733,11 +733,11 @@

    start_options()

    connection type. Default is true.

  • args - Extra command line arguments to append to the "erl" command. Arguments are passed as is, no escaping or quoting is needed or accepted.

  • post_process_args - Allows the user to change the arguments passed to exec before the peer is started. This can for example be useful when the -exec program wants the arguments to "erl" as a single argument. Example:

    peer:start(#{ name => peer:random_name(),
    -  exec => {os:find_executable("bash"),["-c","erl"]},
    +exec program wants the arguments to "erl" as a single argument. Example:

    peer:start(#{ name => peer:random_name(),
    +  exec => {os:find_executable("bash"),["-c","erl"]},
       post_process_args =>
    -     fun(["-c"|Args]) -> ["-c", lists:flatten(lists:join($\s, Args))] end
    -  }).
  • env - List of environment variables with their values. This list is + fun(["-c"|Args]) -> ["-c", lists:flatten(lists:join($\s, Args))] end + }).

  • env - List of environment variables with their values. This list is applied to a locally started executable. If you need to change the environment of the remote peer, adjust args to contain -env ENV_KEY ENV_VALUE.

  • wait_boot - Specifies the start/start_link timeout. See wait_boot datatype.

  • shutdown - Specifies the peer node stopping behaviour. See diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/proc_lib.html b/prs/8803/lib/stdlib-6.0.1/doc/html/proc_lib.html index 0d0b52b993b58..c963cf6827c50 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/proc_lib.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/proc_lib.html @@ -995,21 +995,21 @@

    init_ack(Parent, Ret)

    failed. When doing so the start function can return before the failing process has exited, which may block VM resources required for a new start attempt to succeed. Use init_fail/2,3 for that purpose.

    The following example illustrates how this function and proc_lib:start_link/3 -are used:

    -module(my_proc).
    --export([start_link/0]).
    --export([init/1]).
    +are used:

    -module(my_proc).
    +-export([start_link/0]).
    +-export([init/1]).
     
    -start_link() ->
    -    proc_lib:start_link(my_proc, init, [self()]).
    +start_link() ->
    +    proc_lib:start_link(my_proc, init, [self()]).
     
    -init(Parent) ->
    -    case do_initialization() of
    +init(Parent) ->
    +    case do_initialization() of
             ok ->
    -            proc_lib:init_ack(Parent, {ok, self()});
    -        {error, Reason} ->
    -            exit(Reason)
    +            proc_lib:init_ack(Parent, {ok, self()});
    +        {error, Reason} ->
    +            exit(Reason)
         end,
    -    loop().
    +    loop().
     
     ...
    @@ -1082,21 +1082,21 @@

    init_fail(Parent, Return, Exception)

    started process, the start function returns an error tuple when the started process exits, or when the start function time-out (if used) has passed, see start/3,4,5.

    The following example illustrates how this function and proc_lib:start_link/3 -can be used:

    -module(my_proc).
    --export([start_link/0]).
    --export([init/1]).
    +can be used:

    -module(my_proc).
    +-export([start_link/0]).
    +-export([init/1]).
     
    -start_link() ->
    -    proc_lib:start_link(my_proc, init, [self()]).
    +start_link() ->
    +    proc_lib:start_link(my_proc, init, [self()]).
     
    -init(Parent) ->
    -    case do_initialization() of
    +init(Parent) ->
    +    case do_initialization() of
             ok ->
    -            proc_lib:init_ack(Parent, {ok, self()});
    -        {error, Reason} = Error ->
    -            proc_lib:init_fail(Parent, Error, {exit, normal})
    +            proc_lib:init_ack(Parent, {ok, self()});
    +        {error, Reason} = Error ->
    +            proc_lib:init_fail(Parent, Error, {exit, normal})
         end,
    -    loop().
    +    loop().
     
     ...
    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/proplists.html b/prs/8803/lib/stdlib-6.0.1/doc/html/proplists.html index 23d42f14220e0..8c7ce1ea3cb9f 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/proplists.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/proplists.html @@ -532,7 +532,7 @@

    append_values(Key, ListIn)

    Similar to get_all_values/2, but each value is wrapped in a list unless it is already itself a list. The resulting list of lists is concatenated. This is -often useful for "incremental" options.

    Example:

    append_values(a, [{a, [1,2]}, {b, 0}, {a, 3}, {c, -1}, {a, [4]}])

    returns:

    [1,2,3,4]
    +often useful for "incremental" options.

    Example:

    append_values(a, [{a, [1,2]}, {b, 0}, {a, 3}, {c, -1}, {a, [4]}])

    returns:

    [1,2,3,4]
    @@ -626,10 +626,10 @@

    expand(Expansions, ListIn)

    first entry in ListIn with the same key as Property, and E and Property have equivalent normal forms, then E is replaced with the terms in Expansion, and any following entries with the same key are deleted from -ListIn.

    For example, the following expressions all return [fie, bar, baz, fum]:

    expand([{foo, [bar, baz]}], [fie, foo, fum])
    -expand([{{foo, true}, [bar, baz]}], [fie, foo, fum])
    -expand([{{foo, false}, [bar, baz]}], [fie, {foo, false}, fum])

    However, no expansion is done in the following call because {foo, false} -shadows foo:

    expand([{{foo, true}, [bar, baz]}], [{foo, false}, fie, foo, fum])

    Notice that if the original property term is to be preserved in the result when +ListIn.

    For example, the following expressions all return [fie, bar, baz, fum]:

    expand([{foo, [bar, baz]}], [fie, foo, fum])
    +expand([{{foo, true}, [bar, baz]}], [fie, foo, fum])
    +expand([{{foo, false}, [bar, baz]}], [fie, {foo, false}, fum])

    However, no expansion is done in the following call because {foo, false} +shadows foo:

    expand([{{foo, true}, [bar, baz]}], [{foo, false}, fie, foo, fum])

    Notice that if the original property term is to be preserved in the result when expanded, it must be included in the expansion list. The inserted terms are not expanded recursively. If Expansions contains more than one property with the same key, only the first occurrence is used.

    See also normalize/2.

    @@ -1034,7 +1034,7 @@

    split(List, Keys)

    Partitions List into a list of sublists and a remainder.

    Lists contains one sublist for each key in Keys, in the corresponding order. The relative order of the elements in each sublist is preserved from the original List. Rest contains the elements in List that are not associated with any of the -specified keys, also with their original relative order preserved.

    Example:

    split([{c, 2}, {e, 1}, a, {c, 3, 4}, d, {b, 5}, b], [a, b, c])

    returns:

    {[[a], [{b, 5}, b],[{c, 2}, {c, 3, 4}]], [{e, 1}, d]}
    +specified keys, also with their original relative order preserved.

    Example:

    split([{c, 2}, {e, 1}, a, {c, 3, 4}, d, {b, 5}, b], [a, b, c])

    returns:

    {[[a], [{b, 5}, b],[{c, 2}, {c, 3, 4}]], [{e, 1}, d]}
    @@ -1157,7 +1157,7 @@

    to_map(List)

    an association of the form Key => Value. Anything else will be silently ignored.

    If the same key appears in List multiple times, the value of the one appearing nearest to the head of List will be in the result map, that is the value that -would be returned by a call to get_value(Key, List).

    Example:

    to_map([a, {b, 1}, {c, 2}, {c, 3}])

    returns:

    #{a => true, b => 1, c => 2}
    +would be returned by a call to get_value(Key, List).

    Example:

    to_map([a, {b, 1}, {c, 2}, {c, 3}])

    returns:

    #{a => true, b => 1, c => 2}
    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/qlc.html b/prs/8803/lib/stdlib-6.0.1/doc/html/qlc.html index c15fad95061ac..12e8270220859 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/qlc.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/qlc.html @@ -285,24 +285,24 @@

    If a tuple {finished} exists among the answers to QH, it is returned twice from append/2.

    As another example, consider concatenating the answers to two queries QH1 and QH2 while removing all duplicates. This is accomplished by using option -unique:

    qlc:q([X || X <- qlc:append(QH1, QH2)], {unique, true})

    The cost is substantial: every returned answer is stored in an ETS table. Before +unique:

    qlc:q([X || X <- qlc:append(QH1, QH2)], {unique, true})

    The cost is substantial: every returned answer is stored in an ETS table. Before returning an answer, it is looked up in the ETS table to check if it has already been returned. Without the unique option, all answers to QH1 would be returned followed by all answers to QH2. The unique option keeps the order between the remaining answers.

    If the order of the answers is not important, there is an alternative to the -unique option, namely to sort the answers uniquely:

    qlc:sort(qlc:q([X || X <- qlc:append(QH1, QH2)], {unique, true})).

    This query also removes duplicates but the answers are sorted. If there are many +unique option, namely to sort the answers uniquely:

    qlc:sort(qlc:q([X || X <- qlc:append(QH1, QH2)], {unique, true})).

    This query also removes duplicates but the answers are sorted. If there are many answers, temporary files are used. Notice that to get the first unique answer, all answers must be found and sorted. Both alternatives find duplicates by comparing answers, that is, if A1 and A2 are answers found in that order, then A2 is a removed if A1 == A2.

    To return only a few answers, cursors can be used. The following code returns no -more than five answers using an ETS table for storing the unique answers:

    C = qlc:cursor(qlc:q([X || X <- qlc:append(QH1, QH2)],{unique,true})),
    -R = qlc:next_answers(C, 5),
    -ok = qlc:delete_cursor(C),
    +more than five answers using an ETS table for storing the unique answers:

    C = qlc:cursor(qlc:q([X || X <- qlc:append(QH1, QH2)],{unique,true})),
    +R = qlc:next_answers(C, 5),
    +ok = qlc:delete_cursor(C),
     R.

    QLCs are convenient for stating constraints on data from two or more tables. The -following example does a natural join on two query handles on position 2:

    qlc:q([{X1,X2,X3,Y1} ||
    -          {X1,X2,X3} <- QH1,
    -          {Y1,Y2} <- QH2,
    -          X2 =:= Y2])

    The qlc module evaluates this differently depending on the query handles QH1 +following example does a natural join on two query handles on position 2:

    qlc:q([{X1,X2,X3,Y1} ||
    +          {X1,X2,X3} <- QH1,
    +          {Y1,Y2} <- QH2,
    +          X2 =:= Y2])

    The qlc module evaluates this differently depending on the query handles QH1 and QH2. If, for example, X2 is matched against the key of a QLC table, the lookup join method traverses the objects of QH2 while looking up key values in the table. However, if not X2 or Y2 is matched against the key or an indexed @@ -310,11 +310,11 @@

    both sorted on position 2 and next do the join by traversing the objects one by one.

    Option join can be used to force the qlc module to use a certain join method. For the rest of this section it is assumed that the excessively slow -join method called "nested loop" has been chosen:

    qlc:q([{X1,X2,X3,Y1} ||
    -          {X1,X2,X3} <- QH1,
    -          {Y1,Y2} <- QH2,
    -          X2 =:= Y2],
    -      {join, nested_loop})

    In this case the filter is applied to every possible pair of answers to QH1 +join method called "nested loop" has been chosen:

    qlc:q([{X1,X2,X3,Y1} ||
    +          {X1,X2,X3} <- QH1,
    +          {Y1,Y2} <- QH2,
    +          X2 =:= Y2],
    +      {join, nested_loop})

    In this case the filter is applied to every possible pair of answers to QH1 and QH2, one at a time. If there are M answers to QH1 and N answers to QH2, the filter is run M*N times.

    If QH2 is a call to the function for gb_trees, as defined in section Implementing a QLC Table, then @@ -328,7 +328,7 @@

    no side effects so that the meaning of the query does not change if QH2 is evaluated only once. One way of caching the answers is to evaluate QH2 first of all and substitute the list of answers for QH2 in the query. Another way is -to use option cache. It is expressed like this:

    QH2' = qlc:q([X || X <- QH2], {cache, ets})

    or only

    QH2' = qlc:q([X || X <- QH2], cache)

    The effect of option cache is that when generator QH2' is run the first +to use option cache. It is expressed like this:

    QH2' = qlc:q([X || X <- QH2], {cache, ets})

    or only

    QH2' = qlc:q([X || X <- QH2], cache)

    The effect of option cache is that when generator QH2' is run the first time, every answer is stored in an ETS table. When the next answer of QH1 is tried, answers to QH2' are copied from the ETS table, which is very fast. As for option unique the cost is a possibly substantial amount of RAM memory.

    Option {cache, list} offers the possibility to store the answers in a list on @@ -350,62 +350,62 @@

    Implementing a QLC Table

    As an example of how to use function table/2, the implementation of a QLC -table for the gb_trees module is given:

    -module(gb_table).
    +table for the gb_trees module is given:

    -module(gb_table).
     
    --export([table/1]).
    -
    -table(T) ->
    -    TF = fun() -> qlc_next(gb_trees:next(gb_trees:iterator(T))) end,
    -    InfoFun = fun(num_of_objects) -> gb_trees:size(T);
    -                 (keypos) -> 1;
    -                 (is_sorted_key) -> true;
    -                 (is_unique_objects) -> true;
    -                 (_) -> undefined
    +-export([table/1]).
    +
    +table(T) ->
    +    TF = fun() -> qlc_next(gb_trees:next(gb_trees:iterator(T))) end,
    +    InfoFun = fun(num_of_objects) -> gb_trees:size(T);
    +                 (keypos) -> 1;
    +                 (is_sorted_key) -> true;
    +                 (is_unique_objects) -> true;
    +                 (_) -> undefined
                   end,
         LookupFun =
    -        fun(1, Ks) ->
    -                lists:flatmap(fun(K) ->
    -                                      case gb_trees:lookup(K, T) of
    -                                          {value, V} -> [{K,V}];
    -                                          none -> []
    +        fun(1, Ks) ->
    +                lists:flatmap(fun(K) ->
    +                                      case gb_trees:lookup(K, T) of
    +                                          {value, V} -> [{K,V}];
    +                                          none -> []
                                           end
    -                              end, Ks)
    +                              end, Ks)
             end,
         FormatFun =
    -        fun({all, NElements, ElementFun}) ->
    -                ValsS = io_lib:format("gb_trees:from_orddict(~w)",
    -                                      [gb_nodes(T, NElements, ElementFun)]),
    -                io_lib:format("gb_table:table(~s)", [ValsS]);
    -           ({lookup, 1, KeyValues, _NElements, ElementFun}) ->
    -                ValsS = io_lib:format("gb_trees:from_orddict(~w)",
    -                                      [gb_nodes(T, infinity, ElementFun)]),
    -                io_lib:format("lists:flatmap(fun(K) -> "
    +        fun({all, NElements, ElementFun}) ->
    +                ValsS = io_lib:format("gb_trees:from_orddict(~w)",
    +                                      [gb_nodes(T, NElements, ElementFun)]),
    +                io_lib:format("gb_table:table(~s)", [ValsS]);
    +           ({lookup, 1, KeyValues, _NElements, ElementFun}) ->
    +                ValsS = io_lib:format("gb_trees:from_orddict(~w)",
    +                                      [gb_nodes(T, infinity, ElementFun)]),
    +                io_lib:format("lists:flatmap(fun(K) -> "
                                   "case gb_trees:lookup(K, ~s) of "
                                   "{value, V} -> [{K,V}];none -> [] end "
                                   "end, ~w)",
    -                              [ValsS, [ElementFun(KV) || KV <- KeyValues]])
    +                              [ValsS, [ElementFun(KV) || KV <- KeyValues]])
             end,
    -    qlc:table(TF, [{info_fun, InfoFun}, {format_fun, FormatFun},
    -                   {lookup_fun, LookupFun},{key_equality,'=='}]).
    +    qlc:table(TF, [{info_fun, InfoFun}, {format_fun, FormatFun},
    +                   {lookup_fun, LookupFun},{key_equality,'=='}]).
     
    -qlc_next({X, V, S}) ->
    -    [{X,V} | fun() -> qlc_next(gb_trees:next(S)) end];
    -qlc_next(none) ->
    -    [].
    +qlc_next({X, V, S}) ->
    +    [{X,V} | fun() -> qlc_next(gb_trees:next(S)) end];
    +qlc_next(none) ->
    +    [].
     
    -gb_nodes(T, infinity, ElementFun) ->
    -    gb_nodes(T, -1, ElementFun);
    -gb_nodes(T, NElements, ElementFun) ->
    -    gb_iter(gb_trees:iterator(T), NElements, ElementFun).
    +gb_nodes(T, infinity, ElementFun) ->
    +    gb_nodes(T, -1, ElementFun);
    +gb_nodes(T, NElements, ElementFun) ->
    +    gb_iter(gb_trees:iterator(T), NElements, ElementFun).
     
    -gb_iter(_I, 0, _EFun) ->
    +gb_iter(_I, 0, _EFun) ->
         '...';
    -gb_iter(I0, N, EFun) ->
    -    case gb_trees:next(I0) of
    -        {X, V, I} ->
    -            [EFun({X,V}) | gb_iter(I, N-1, EFun)];
    +gb_iter(I0, N, EFun) ->
    +    case gb_trees:next(I0) of
    +        {X, V, I} ->
    +            [EFun({X,V}) | gb_iter(I, N-1, EFun)];
             none ->
    -            []
    +            []
         end.

    TF is the traversal function. The qlc module requires that there is a way of traversing all objects of the data structure. gb_trees has an iterator function suitable for that purpose. Notice that for each object returned, a new @@ -441,49 +441,49 @@

    example, 2 == 2.0 evaluates to true while 2 =:= 2.0 evaluates to false. Normally this is a minor issue, but the qlc module cannot ignore the difference, which affects the user's choice of operators in QLCs.

    If the qlc module at compile time can determine that some constant is free of -integers, it does not matter which one of ==/2 or =:=/2 is used:

    1> E1 = ets:new(t, [set]), % uses =:=/2 for key equality
    -Q1 = qlc:q([K ||
    -{K} <- ets:table(E1),
    -K == 2.71 orelse K == a]),
    -io:format("~s~n", [qlc:info(Q1)]).
    -ets:match_spec_run(
    -       lists:flatmap(fun(V) ->
    -			    ets:lookup(#Ref<0.3098908599.2283929601.256025>,
    -				       V)
    +integers, it does not matter which one of ==/2 or =:=/2 is used:

    1> E1 = ets:new(t, [set]), % uses =:=/2 for key equality
    +Q1 = qlc:q([K ||
    +{K} <- ets:table(E1),
    +K == 2.71 orelse K == a]),
    +io:format("~s~n", [qlc:info(Q1)]).
    +ets:match_spec_run(
    +       lists:flatmap(fun(V) ->
    +			    ets:lookup(#Ref<0.3098908599.2283929601.256025>,
    +				       V)
     		     end,
    -		     [a, 2.71]),
    -       ets:match_spec_compile([{{'$1'}, [], ['$1']}]))

    In the example, operator ==/2 has been handled exactly as =:=/2 would have + [a, 2.71]), + ets:match_spec_compile([{{'$1'}, [], ['$1']}]))

    In the example, operator ==/2 has been handled exactly as =:=/2 would have been handled. However, if it cannot be determined at compile time that some constant is free of integers, and the table uses =:=/2 when comparing keys for equality (see option key_equality), then the qlc module does not try to look up the constant. The reason is that there is in the general case no upper limit on the number of key values that can compare equal -to such a constant; every combination of integers and floats must be looked up:

    2> E2 = ets:new(t, [set]),
    -true = ets:insert(E2, [{{2,2},a},{{2,2.0},b},{{2.0,2},c}]),
    -F2 = fun(I) ->
    -qlc:q([V || {K,V} <- ets:table(E2), K == I])
    +to such a constant; every combination of integers and floats must be looked up:

    2> E2 = ets:new(t, [set]),
    +true = ets:insert(E2, [{{2,2},a},{{2,2.0},b},{{2.0,2},c}]),
    +F2 = fun(I) ->
    +qlc:q([V || {K,V} <- ets:table(E2), K == I])
     end,
    -Q2 = F2({2,2}),
    -io:format("~s~n", [qlc:info(Q2)]).
    -ets:table(#Ref<0.3098908599.2283929601.256125>,
    -          [{traverse,
    -            {select,
    -             [{{'$1', '$2'}, [{'==', '$1', {const, {2, 2}}}], ['$2']}]}}])
    -3> lists:sort(qlc:e(Q2)).
    -[a,b,c]

    Looking up only {2,2} would not return b and c.

    If the table uses ==/2 when comparing keys for equality, the qlc module +Q2 = F2({2,2}), +io:format("~s~n", [qlc:info(Q2)]). +ets:table(#Ref<0.3098908599.2283929601.256125>, + [{traverse, + {select, + [{{'$1', '$2'}, [{'==', '$1', {const, {2, 2}}}], ['$2']}]}}]) +3> lists:sort(qlc:e(Q2)). +[a,b,c]

    Looking up only {2,2} would not return b and c.

    If the table uses ==/2 when comparing keys for equality, the qlc module looks up the constant regardless of which operator is used in the QLC. However, -==/2 is to be preferred:

    4> E3 = ets:new(t, [ordered_set]), % uses ==/2 for key equality
    -true = ets:insert(E3, [{{2,2.0},b}]),
    -F3 = fun(I) ->
    -qlc:q([V || {K,V} <- ets:table(E3), K == I])
    +==/2 is to be preferred:

    4> E3 = ets:new(t, [ordered_set]), % uses ==/2 for key equality
    +true = ets:insert(E3, [{{2,2.0},b}]),
    +F3 = fun(I) ->
    +qlc:q([V || {K,V} <- ets:table(E3), K == I])
     end,
    -Q3 = F3({2,2}),
    -io:format("~s~n", [qlc:info(Q3)]).
    -ets:match_spec_run(ets:lookup(#Ref<0.3098908599.2283929601.256211>,
    -                              {2, 2}),
    -                   ets:match_spec_compile([{{'$1', '$2'}, [], ['$2']}]))
    -5> qlc:e(Q3).
    -[b]

    Lookup join is handled analogously to lookup of constants in a table: if the +Q3 = F3({2,2}), +io:format("~s~n", [qlc:info(Q3)]). +ets:match_spec_run(ets:lookup(#Ref<0.3098908599.2283929601.256211>, + {2, 2}), + ets:match_spec_compile([{{'$1', '$2'}, [], ['$2']}])) +5> qlc:e(Q3). +[b]

    Lookup join is handled analogously to lookup of constants in a table: if the join operator is ==/2, and the table where constants are to be looked up uses =:=/2 when testing keys for equality, then the qlc module does not consider lookup join for that table.

    @@ -1697,15 +1697,15 @@

    cursor(QH, Options)

    and (eventually) delete_cursor/1. Calls erlang:spawn_opt/2 to spawn and link to a process that evaluates the query handle. The value of option spawn_options is used as last argument when calling -spawn_opt/2. Defaults to [link].

    Example:

    1> QH = qlc:q([{X,Y} || X <- [a,b], Y <- [1,2]]),
    -QC = qlc:cursor(QH),
    -qlc:next_answers(QC, 1).
    -[{a,1}]
    -2> qlc:next_answers(QC, 1).
    -[{a,2}]
    -3> qlc:next_answers(QC, all_remaining).
    -[{b,1},{b,2}]
    -4> qlc:delete_cursor(QC).
    +spawn_opt/2. Defaults to [link].

    Example:

    1> QH = qlc:q([{X,Y} || X <- [a,b], Y <- [1,2]]),
    +QC = qlc:cursor(QH),
    +qlc:next_answers(QC, 1).
    +[{a,1}]
    +2> qlc:next_answers(QC, 1).
    +[{a,2}]
    +3> qlc:next_answers(QC, all_remaining).
    +[{b,1},{b,2}]
    +4> qlc:delete_cursor(QC).
     ok

    @@ -1885,9 +1885,9 @@

    eval(QH, Options)

    Evaluates a query handle in the calling process and collects all answers in a -list.

    Example:

    1> QH = qlc:q([{X,Y} || X <- [a,b], Y <- [1,2]]),
    -qlc:eval(QH).
    -[{a,1},{a,2},{b,1},{b,2}]
    +list.

    Example:

    1> QH = qlc:q([{X,Y} || X <- [a,b], Y <- [1,2]]),
    +qlc:eval(QH).
    +[{a,1},{a,2},{b,1},{b,2}]
    @@ -1973,8 +1973,8 @@

    fold(Function, Acc0, QH, Options)

    Calls Function on successive answers to the query handle together with an extra argument AccIn.

    The query handle and the function are evaluated in the calling process. Function must return a new accumulator, which is passed to -the next call. Acc0 is returned if there are no answers to the query handle.

    Example:

    1> QH = [1,2,3,4,5,6],
    -qlc:fold(fun(X, Sum) -> X + Sum end, 0, QH).
    +the next call. Acc0 is returned if there are no answers to the query handle.

    Example:

    1> QH = [1,2,3,4,5,6],
    +qlc:fold(fun(X, Sum) -> X + Sum end, 0, QH).
     21
    @@ -2091,59 +2091,59 @@

    info(QH, Options)

    returned.
  • The default is to show all parts of objects and match specifications, but if option {depth, Depth} is specified, parts of terms below a certain depth are replaced by '...'.
  • Examples:

    In the following example two simple QLCs are inserted only to hold option -{unique, true}:

    1> QH = qlc:q([{X,Y} || X <- [x,y], Y <- [a,b]]),
    -io:format("~s~n", [qlc:info(QH, unique_all)]).
    +{unique, true}:

    1> QH = qlc:q([{X,Y} || X <- [x,y], Y <- [a,b]]),
    +io:format("~s~n", [qlc:info(QH, unique_all)]).
     begin
         V1 =
    -        qlc:q([
    +        qlc:q([
                    SQV ||
    -                   SQV <- [x, y]
    -              ],
    -              [{unique, true}]),
    +                   SQV <- [x, y]
    +              ],
    +              [{unique, true}]),
         V2 =
    -        qlc:q([
    +        qlc:q([
                    SQV ||
    -                   SQV <- [a, b]
    -              ],
    -              [{unique, true}]),
    -    qlc:q([
    -           {X,Y} ||
    +                   SQV <- [a, b]
    +              ],
    +              [{unique, true}]),
    +    qlc:q([
    +           {X,Y} ||
                    X <- V1,
                    Y <- V2
    -          ],
    -          [{unique, true}])
    +          ],
    +          [{unique, true}])
     end

    In the following example QLC V2 has been inserted to show the joined generators and the join method chosen. A convention is used for lookup join: the first generator (G2) is the one traversed, the second (G1) is the table -where constants are looked up.

    1> E1 = ets:new(e1, []),
    -E2 = ets:new(e2, []),
    -true = ets:insert(E1, [{1,a},{2,b}]),
    -true = ets:insert(E2, [{a,1},{b,2}]),
    -Q = qlc:q([{X,Z,W} ||
    -{X, Z} <- ets:table(E1),
    -{W, Y} <- ets:table(E2),
    -X =:= Y]),
    -io:format("~s~n", [qlc:info(Q)]).
    +where constants are looked up.

    1> E1 = ets:new(e1, []),
    +E2 = ets:new(e2, []),
    +true = ets:insert(E1, [{1,a},{2,b}]),
    +true = ets:insert(E2, [{a,1},{b,2}]),
    +Q = qlc:q([{X,Z,W} ||
    +{X, Z} <- ets:table(E1),
    +{W, Y} <- ets:table(E2),
    +X =:= Y]),
    +io:format("~s~n", [qlc:info(Q)]).
     begin
         V1 =
    -        qlc:q([
    +        qlc:q([
                    P0 ||
    -                   P0 = {W, Y} <-
    -                       ets:table(#Ref<0.3098908599.2283929601.256549>)
    -              ]),
    +                   P0 = {W, Y} <-
    +                       ets:table(#Ref<0.3098908599.2283929601.256549>)
    +              ]),
         V2 =
    -        qlc:q([
    -               [G1 | G2] ||
    +        qlc:q([
    +               [G1 | G2] ||
                        G2 <- V1,
                        G1 <-
    -                       ets:table(#Ref<0.3098908599.2283929601.256548>),
    -                   element(2, G1) =:= element(1, G2)
    -              ],
    -              [{join, lookup}]),
    -    qlc:q([
    -           {X, Z, W} ||
    -               [{X, Z} | {W, Y}] <- V2
    -          ])
    +                       ets:table(#Ref<0.3098908599.2283929601.256548>),
    +                   element(2, G1) =:= element(1, G2)
    +              ],
    +              [{join, lookup}]),
    +    qlc:q([
    +           {X, Z, W} ||
    +               [{X, Z} | {W, Y}] <- V2
    +          ])
     end
    @@ -2352,13 +2352,13 @@

    q(QLC, Options)

    Returns a query handle for a QLC. The QLC must be the first argument to this function, otherwise it is evaluated as an ordinary list comprehension. It is -also necessary to add the following line to the source code:

    -include_lib("stdlib/include/qlc.hrl").

    This causes a parse transform to substitute a fun for the QLC. The (compiled) +also necessary to add the following line to the source code:

    -include_lib("stdlib/include/qlc.hrl").

    This causes a parse transform to substitute a fun for the QLC. The (compiled) fun is called when the query handle is evaluated.

    When calling qlc:q/1,2 from the Erlang shell, the parse transform is automatically called. When this occurs, the fun substituted for the QLC is not compiled but is evaluated by erl_eval. This is also true when expressions are evaluated by file:eval/1,2 or in the debugger.

    To be explicit, this does not work:

    ...
    -A = [X || {X} <- [{1},{2}]],
    -QH = qlc:q(A),
    +A = [X || {X} <- [{1},{2}]],
    +QH = qlc:q(A),
     ...

    Variable A is bound to the evaluated value of the list comprehension ([1,2]). The compiler complains with an error message ("argument is not a query list comprehension"); the shell process stops with a badarg reason.

    Options:

    • Option {cache, ets} can be used to cache the answers to a QLC. The answers @@ -2386,40 +2386,40 @@

      q(QLC, Options)

      results of looking up constants, running match specifications, and joining handles.

      Example:

      In the following example the cached results of the merge join are traversed for each value of A. Notice that without option cache the join would have been -carried out three times, once for each value of A.

      1> Q = qlc:q([{A,X,Z,W} ||
      -A <- [a,b,c],
      -{X,Z} <- [{a,1},{b,4},{c,6}],
      -{W,Y} <- [{2,a},{3,b},{4,c}],
      -X =:= Y],
      -{cache, list}),
      -io:format("~s~n", [qlc:info(Q)]).
      +carried out three times, once for each value of A.

      1> Q = qlc:q([{A,X,Z,W} ||
      +A <- [a,b,c],
      +{X,Z} <- [{a,1},{b,4},{c,6}],
      +{W,Y} <- [{2,a},{3,b},{4,c}],
      +X =:= Y],
      +{cache, list}),
      +io:format("~s~n", [qlc:info(Q)]).
       begin
           V1 =
      -        qlc:q([
      +        qlc:q([
                      P0 ||
      -                   P0 = {X, Z} <-
      -                       qlc:keysort(1, [{a, 1}, {b, 4}, {c, 6}], [])
      -              ]),
      +                   P0 = {X, Z} <-
      +                       qlc:keysort(1, [{a, 1}, {b, 4}, {c, 6}], [])
      +              ]),
           V2 =
      -        qlc:q([
      +        qlc:q([
                      P0 ||
      -                   P0 = {W, Y} <-
      -                       qlc:keysort(2, [{2, a}, {3, b}, {4, c}], [])
      -              ]),
      +                   P0 = {W, Y} <-
      +                       qlc:keysort(2, [{2, a}, {3, b}, {4, c}], [])
      +              ]),
           V3 =
      -        qlc:q([
      -               [G1 | G2] ||
      +        qlc:q([
      +               [G1 | G2] ||
                          G1 <- V1,
                          G2 <- V2,
      -                   element(1, G1) == element(2, G2)
      -              ],
      -              [{join, merge}, {cache, list}]),
      -    qlc:q([
      -           {A, X, Z, W} ||
      -               A <- [a, b, c],
      -               [{X, Z} | {W, Y}] <- V3,
      +                   element(1, G1) == element(2, G2)
      +              ],
      +              [{join, merge}, {cache, list}]),
      +    qlc:q([
      +           {A, X, Z, W} ||
      +               A <- [a, b, c],
      +               [{X, Z} | {W, Y}] <- V3,
                      X =:= Y
      -          ])
      +          ])
       end

      sort/1,2 and keysort/2,3 can also be used for caching answers and for removing duplicates. When sorting answers are cached in a list, possibly stored on a temporary file, and no ETS tables are used.

      Sometimes (see table/2) traversal of tables can be done by looking up key @@ -2431,32 +2431,32 @@

      q(QLC, Options)

      limit on the number of keys to look up.

      Example:

      In the following example, using the gb_table module from section Implementing a QLC Table, there are six keys to look up: {1,a}, {1,b}, {1,c}, {2,a}, {2,b}, and {2,c}. The reason -is that the two elements of key {X, Y} are compared separately.

      1> T = gb_trees:empty(),
      -QH = qlc:q([X || {{X,Y},_} <- gb_table:table(T),
      -((X == 1) or (X == 2)) andalso
      -((Y == a) or (Y == b) or (Y == c))]),
      -io:format("~s~n", [qlc:info(QH)]).
      -ets:match_spec_run(
      -       lists:flatmap(fun(K) ->
      +is that the two elements of key {X, Y} are compared separately.

      1> T = gb_trees:empty(),
      +QH = qlc:q([X || {{X,Y},_} <- gb_table:table(T),
      +((X == 1) or (X == 2)) andalso
      +((Y == a) or (Y == b) or (Y == c))]),
      +io:format("~s~n", [qlc:info(QH)]).
      +ets:match_spec_run(
      +       lists:flatmap(fun(K) ->
                                   case
      -                                gb_trees:lookup(K,
      -                                                gb_trees:from_orddict([]))
      +                                gb_trees:lookup(K,
      +                                                gb_trees:from_orddict([]))
                                   of
      -                                {value, V} ->
      -                                    [{K, V}];
      +                                {value, V} ->
      +                                    [{K, V}];
                                       none ->
      -                                    []
      +                                    []
                                   end
                            end,
      -                     [{1, a},
      -                      {1, b},
      -                      {1, c},
      -                      {2, a},
      -                      {2, b},
      -                      {2, c}]),
      -       ets:match_spec_compile([{{{'$1', '$2'}, '_'},
      -                                [],
      -                                ['$1']}]))

      Options:

      • Option {lookup, true} can be used to ensure that the qlc module looks up + [{1, a}, + {1, b}, + {1, c}, + {2, a}, + {2, b}, + {2, c}]), + ets:match_spec_compile([{{{'$1', '$2'}, '_'}, + [], + ['$1']}]))

      Options:

      • Option {lookup, true} can be used to ensure that the qlc module looks up constants in some QLC table. If there are more than one QLC table among the list expressions of the generators, constants must be looked up in at least one of the tables. The evaluation of the query fails if there are no constants @@ -2653,11 +2653,11 @@

        string_to_handle(QueryString, Options, Bind

        A string version of q/1,2. When the query handle is evaluated, the fun created by the parse transform is interpreted by erl_eval. The query -string is to be one single QLC terminated by a period.

        Example:

        1> L = [1,2,3],
        -Bs = erl_eval:add_binding('L', L, erl_eval:new_bindings()),
        -QH = qlc:string_to_handle("[X+1 || X <- L].", [], Bs),
        -qlc:eval(QH).
        -[2,3,4]

        This function is probably mainly useful when called from outside of Erlang, for +string is to be one single QLC terminated by a period.

        Example:

        1> L = [1,2,3],
        +Bs = erl_eval:add_binding('L', L, erl_eval:new_bindings()),
        +QH = qlc:string_to_handle("[X+1 || X <- L].", [], Bs),
        +qlc:eval(QH).
        +[2,3,4]

        This function is probably mainly useful when called from outside of Erlang, for example from a driver written in C.

        Note

        Query handles created this way may have worse performance than when created directly via q/1,2.

        diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/queue.html b/prs/8803/lib/stdlib-6.0.1/doc/html/queue.html index 9b13a47ace86e..1c19128616f8d 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/queue.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/queue.html @@ -723,10 +723,10 @@

        all(Pred, Q)

        Returns true if Pred(Item) returns true for all items Item in Q, -otherwise false.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        -2> queue:all(fun (E) -> E > 3 end, Queue).
        +otherwise false.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        +2> queue:all(fun (E) -> E > 3 end, Queue).
         false
        -3> queue:all(fun (E) -> E > 0 end, Queue).
        +3> queue:all(fun (E) -> E > 0 end, Queue).
         true
        @@ -758,10 +758,10 @@

        any(Pred, Q)

        Returns true if Pred(Item) returns true for at least one item Item in -Q, otherwise false.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        -2> queue:any(fun (E) -> E > 10 end, Queue).
        +Q, otherwise false.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        +2> queue:any(fun (E) -> E > 10 end, Queue).
         false
        -3> queue:any(fun (E) -> E > 3 end, Queue).
        +3> queue:any(fun (E) -> E > 3 end, Queue).
         true
        @@ -793,9 +793,9 @@

        delete(Item, Q1)

        Returns a copy of Q1 where the first item matching Item is deleted, if there -is such an item.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        -2> Queue1 = queue:delete(3, Queue).
        -3> queue:member(3, Queue1).
        +is such an item.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        +2> Queue1 = queue:delete(3, Queue).
        +3> queue:member(3, Queue1).
         false
        @@ -827,10 +827,10 @@

        delete_r(Item, Q1)

        Returns a copy of Q1 where the last item matching Item is deleted, if there -is such an item.

        Example:

        1> Queue = queue:from_list([1,2,3,4,3,5]).
        -2> Queue1 = queue:delete_r(3, Queue).
        -3> queue:to_list(Queue1).
        -[1,2,3,4,5]
        +is such an item.

        Example:

        1> Queue = queue:from_list([1,2,3,4,3,5]).
        +2> Queue1 = queue:delete_r(3, Queue).
        +3> queue:to_list(Queue1).
        +[1,2,3,4,5]
        @@ -866,10 +866,10 @@

        delete_with(Pred, Q1)

        Returns a copy of Q1 where the first item for which Pred returns true is -deleted, if there is such an item.

        Example:

        1> Queue = queue:from_list([100,1,2,3,4,5]).
        -2> Queue1 = queue:delete_with(fun (E) -> E > 0, Queue).
        -3> queue:to_list(Queue1).
        -[1,2,3,4,5]
        +deleted, if there is such an item.

        Example:

        1> Queue = queue:from_list([100,1,2,3,4,5]).
        +2> Queue1 = queue:delete_with(fun (E) -> E > 0, Queue).
        +3> queue:to_list(Queue1).
        +[1,2,3,4,5]
        @@ -905,10 +905,10 @@

        delete_with_r(Pred, Q1)

        Returns a copy of Q1 where the last item for which Pred returns true is -deleted, if there is such an item.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5,100]).
        -2> Queue1 = queue:delete_with(fun (E) -> E > 10, Queue).
        -3> queue:to_list(Queue1).
        -[1,2,3,4,5]
        +deleted, if there is such an item.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5,100]).
        +2> Queue1 = queue:delete_with(fun (E) -> E > 10, Queue).
        +3> queue:to_list(Queue1).
        +[1,2,3,4,5]
        @@ -939,19 +939,19 @@

        filter(Fun, Q1)

        Returns a queue Q2 that is the result of calling Fun(Item) on all items in Q1.

        If Fun(Item) returns true, Item is copied to the result queue. If it returns false, Item is not copied. If it returns a list, the list elements -are inserted instead of Item in the result queue.

        Example 1:

        1> Queue = queue:from_list([1,2,3,4,5]).
        -{[5,4,3],[1,2]}
        -2> Queue1 = queue:filter(fun (E) -> E > 2 end, Queue).
        -{[5],[3,4]}
        -3> queue:to_list(Queue1).
        -[3,4,5]

        So, Fun(Item) returning [Item] is thereby semantically equivalent to +are inserted instead of Item in the result queue.

        Example 1:

        1> Queue = queue:from_list([1,2,3,4,5]).
        +{[5,4,3],[1,2]}
        +2> Queue1 = queue:filter(fun (E) -> E > 2 end, Queue).
        +{[5],[3,4]}
        +3> queue:to_list(Queue1).
        +[3,4,5]

        So, Fun(Item) returning [Item] is thereby semantically equivalent to returning true, just as returning [] is semantically equivalent to returning -false. But returning a list builds more garbage than returning an atom.

        Example 2:

        1> Queue = queue:from_list([1,2,3,4,5]).
        -{[5,4,3],[1,2]}
        -2> Queue1 = queue:filter(fun (E) -> [E, E+1] end, Queue).
        -{[6,5,5,4,4,3],[1,2,2,3]}
        -3> queue:to_list(Queue1).
        -[1,2,2,3,3,4,4,5,5,6]
        +false. But returning a list builds more garbage than returning an atom.

        Example 2:

        1> Queue = queue:from_list([1,2,3,4,5]).
        +{[5,4,3],[1,2]}
        +2> Queue1 = queue:filter(fun (E) -> [E, E+1] end, Queue).
        +{[6,5,5,4,4,3],[1,2,2,3]}
        +3> queue:to_list(Queue1).
        +[1,2,2,3,3,4,4,5,5,6]
        @@ -990,15 +990,15 @@

        filtermap(Fun, Q1)

        Returns a queue Q2 that is the result of calling Fun(Item) on all items in Q1.

        If Fun(Item) returns true, Item is copied to the result queue. If it returns false, Item is not copied. If it returns {true, NewItem}, the -queue element at this position is replaced with NewItem in the result queue.

        Example 1:

        1> Queue = queue:from_list([1,2,3,4,5]).
        -{[5,4,3],[1,2]}
        -2> Queue1 = queue:filtermap(fun (E) -> E > 2 end, Queue).
        -{[5],[3,4]}
        -3> queue:to_list(Queue1).
        -[3,4,5]
        -4> Queue1 = queue:filtermap(fun (E) -> {true, E+100} end, Queue).
        -{"ihg","ef"}
        -5> queue:to_list(Queue1).
        +queue element at this position is replaced with NewItem in the result queue.

        Example 1:

        1> Queue = queue:from_list([1,2,3,4,5]).
        +{[5,4,3],[1,2]}
        +2> Queue1 = queue:filtermap(fun (E) -> E > 2 end, Queue).
        +{[5],[3,4]}
        +3> queue:to_list(Queue1).
        +[3,4,5]
        +4> Queue1 = queue:filtermap(fun (E) -> {true, E+100} end, Queue).
        +{"ihg","ef"}
        +5> queue:to_list(Queue1).
         "efghi
        @@ -1039,9 +1039,9 @@

        fold(Fun, Acc0, Q)

        AccIn == Acc0. The queue is traversed in queue order, that is, from front to rear. Fun/2 must return a new accumulator, which is passed to the next call. The function returns the final value of the accumulator. Acc0 is returned if -the queue is empty.

        Example:

        1> queue:fold(fun(X, Sum) -> X + Sum end, 0, queue:from_list([1,2,3,4,5])).
        +the queue is empty.

        Example:

        1> queue:fold(fun(X, Sum) -> X + Sum end, 0, queue:from_list([1,2,3,4,5])).
         15
        -2> queue:fold(fun(X, Prod) -> X * Prod end, 1, queue:from_list([1,2,3,4,5])).
        +2> queue:fold(fun(X, Prod) -> X * Prod end, 1, queue:from_list([1,2,3,4,5])).
         120
        @@ -1099,12 +1099,12 @@

        in(Item, Q1)

        -

        Inserts Item at the rear of queue Q1. Returns the resulting queue Q2.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        -{[5,4,3],[1,2]}
        -2> Queue1 = queue:in(100, Queue).
        -{[100,5,4,3],[1,2]}
        -3> queue:to_list(Queue1).
        -[1,2,3,4,5,100]
        +

        Inserts Item at the rear of queue Q1. Returns the resulting queue Q2.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        +{[5,4,3],[1,2]}
        +2> Queue1 = queue:in(100, Queue).
        +{[100,5,4,3],[1,2]}
        +3> queue:to_list(Queue1).
        +[1,2,3,4,5,100]
        @@ -1132,12 +1132,12 @@

        in_r(Item, Q1)

        -

        Inserts Item at the front of queue Q1. Returns the resulting queue Q2.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        -{[5,4,3],[1,2]}
        -2> Queue1 = queue:in_r(100, Queue).
        -{[5,4,3],[100,1,2]}
        -3> queue:to_list(Queue1).
        -[100,1,2,3,4,5]
        +

        Inserts Item at the front of queue Q1. Returns the resulting queue Q2.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        +{[5,4,3],[1,2]}
        +2> Queue1 = queue:in_r(100, Queue).
        +{[5,4,3],[100,1,2]}
        +3> queue:to_list(Queue1).
        +[100,1,2,3,4,5]
        @@ -1225,12 +1225,12 @@

        join(Q1, Q2)

        Returns a queue Q3 that is the result of joining Q1 and Q2 with Q1 in -front of Q2.

        Example:

        1> Queue1 = queue:from_list([1,3]).
        -{[3],[1]}
        -2> Queue2 = queue:from_list([2,4]).
        -{[4],[2]}
        -3> queue:to_list(queue:join(Queue1, Queue2)).
        -[1,3,2,4]
        +front of Q2.

        Example:

        1> Queue1 = queue:from_list([1,3]).
        +{[3],[1]}
        +2> Queue2 = queue:from_list([2,4]).
        +{[4],[2]}
        +3> queue:to_list(queue:join(Queue1, Queue2)).
        +[1,3,2,4]
        @@ -1344,12 +1344,12 @@

        out(Q1)

        Removes the item at the front of queue Q1. Returns tuple {{value, Item}, Q2}, where Item is the item removed and Q2 is the -resulting queue. If Q1 is empty, tuple {empty, Q1} is returned.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        -{[5,4,3],[1,2]}
        -2> {{value, 1=Item}, Queue1} = queue:out(Queue).
        -{{value,1},{[5,4,3],[2]}}
        -3> queue:to_list(Queue1).
        -[2,3,4,5]
        +resulting queue. If Q1 is empty, tuple {empty, Q1} is returned.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        +{[5,4,3],[1,2]}
        +2> {{value, 1=Item}, Queue1} = queue:out(Queue).
        +{{value,1},{[5,4,3],[2]}}
        +3> queue:to_list(Queue1).
        +[2,3,4,5]
        @@ -1379,12 +1379,12 @@

        out_r(Q1)

        Removes the item at the rear of queue Q1. Returns tuple {{value, Item}, Q2}, where Item is the item removed and Q2 is the new queue. If Q1 is empty, -tuple {empty, Q1} is returned.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        -{[5,4,3],[1,2]}
        -2> {{value, 5=Item}, Queue1} = queue:out_r(Queue).
        -{{value,5},{[4,3],[1,2]}}
        -3> queue:to_list(Queue1).
        -[1,2,3,4]
        +tuple {empty, Q1} is returned.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        +{[5,4,3],[1,2]}
        +2> {{value, 5=Item}, Queue1} = queue:out_r(Queue).
        +{{value,5},{[4,3],[1,2]}}
        +3> queue:to_list(Queue1).
        +[1,2,3,4]
        @@ -1469,9 +1469,9 @@

        to_list(Q)

        Returns a list of the items in the queue in the same order; the front item of -the queue becomes the head of the list.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        -{[5,4,3],[1,2]}
        -2> List == queue:to_list(Queue).
        +the queue becomes the head of the list.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        +{[5,4,3],[1,2]}
        +2> List == queue:to_list(Queue).
         true
        @@ -1512,12 +1512,12 @@

        drop(Q1)

        -

        Returns a queue Q2 that is the result of removing the front item from Q1.

        Fails with reason empty if Q1 is empty.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        -{[5,4,3],[1,2]}
        -2> Queue = queue:drop(Queue).
        -{[5,4,3],[2]}
        -3> queue:to_list(Queue1).
        -[2,3,4,5]
        +

        Returns a queue Q2 that is the result of removing the front item from Q1.

        Fails with reason empty if Q1 is empty.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        +{[5,4,3],[1,2]}
        +2> Queue = queue:drop(Queue).
        +{[5,4,3],[2]}
        +3> queue:to_list(Queue1).
        +[2,3,4,5]
        @@ -1545,12 +1545,12 @@

        drop_r(Q1)

        -

        Returns a queue Q2 that is the result of removing the rear item from Q1.

        Fails with reason empty if Q1 is empty.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        -{[5,4,3],[1,2]}
        -2> Queue = queue:drop_r(Queue).
        -{[4,3],[1,2]}
        -3> queue:to_list(Queue1).
        -[1,2,3,4]
        +

        Returns a queue Q2 that is the result of removing the rear item from Q1.

        Fails with reason empty if Q1 is empty.

        Example:

        1> Queue = queue:from_list([1,2,3,4,5]).
        +{[5,4,3],[1,2]}
        +2> Queue = queue:drop_r(Queue).
        +{[4,3],[1,2]}
        +3> queue:to_list(Queue1).
        +[1,2,3,4]
        @@ -1578,9 +1578,9 @@

        get(Q)

        -

        Returns Item at the front of queue Q.

        Fails with reason empty if Q is empty.

        Example 1:

        1> Queue = queue:from_list([1,2,3,4,5]).
        -{[5,4,3],[1,2]}
        -2> 1 == queue:get(Queue).
        +

        Returns Item at the front of queue Q.

        Fails with reason empty if Q is empty.

        Example 1:

        1> Queue = queue:from_list([1,2,3,4,5]).
        +{[5,4,3],[1,2]}
        +2> 1 == queue:get(Queue).
         true
        @@ -1609,9 +1609,9 @@

        get_r(Q)

        -

        Returns Item at the rear of queue Q.

        Fails with reason empty if Q is empty.

        Example 1:

        1> Queue = queue:from_list([1,2,3,4,5]).
        -{[5,4,3],[1,2]}
        -2> 5 == queue:get_r(Queue).
        +

        Returns Item at the rear of queue Q.

        Fails with reason empty if Q is empty.

        Example 1:

        1> Queue = queue:from_list([1,2,3,4,5]).
        +{[5,4,3],[1,2]}
        +2> 5 == queue:get_r(Queue).
         true
        @@ -1641,12 +1641,12 @@

        peek(Q)

        Returns tuple {value, Item}, where Item is the front item of Q, or empty -if Q is empty.

        Example 1:

        1> queue:peek(queue:new()).
        +if Q is empty.

        Example 1:

        1> queue:peek(queue:new()).
         empty
        -2> Queue = queue:from_list([1,2,3,4,5]).
        -{[5,4,3],[1,2]}
        -3> queue:peek(Queue).
        -{value, 1}
        +2>
        Queue = queue:from_list([1,2,3,4,5]). +{[5,4,3],[1,2]} +3> queue:peek(Queue). +{value, 1}
        @@ -1675,12 +1675,12 @@

        peek_r(Q)

        Returns tuple {value, Item}, where Item is the rear item of Q, or empty -if Q is empty.

        Example 1:

        1> queue:peek_r(queue:new()).
        +if Q is empty.

        Example 1:

        1> queue:peek_r(queue:new()).
         empty
        -2> Queue = queue:from_list([1,2,3,4,5]).
        -{[5,4,3],[1,2]}
        -3> queue:peek_r(Queue).
        -{value, 5}
        +2>
        Queue = queue:from_list([1,2,3,4,5]). +{[5,4,3],[1,2]} +3> queue:peek_r(Queue). +{value, 5}
        @@ -1720,10 +1720,10 @@

        cons(Item, Q1)

        -

        Inserts Item at the head of queue Q1. Returns the new queue Q2.

        Example:

        1> Queue = queue:cons(0, queue:from_list([1,2,3])).
        -{[3,2],[0,1]}
        -2> queue:to_list(Queue).
        -[0,1,2,3]
        +

        Inserts Item at the head of queue Q1. Returns the new queue Q2.

        Example:

        1> Queue = queue:cons(0, queue:from_list([1,2,3])).
        +{[3,2],[0,1]}
        +2> queue:to_list(Queue).
        +[0,1,2,3]
        @@ -1751,7 +1751,7 @@

        daeh(Q)

        -

        Returns the tail item of queue Q.

        Fails with reason empty if Q is empty.

        Example 1:

        1> queue:daeh(queue:from_list([1,2,3])).
        +

        Returns the tail item of queue Q.

        Fails with reason empty if Q is empty.

        Example 1:

        1> queue:daeh(queue:from_list([1,2,3])).
         3
        @@ -1780,7 +1780,7 @@

        head(Q)

        -

        Returns Item from the head of queue Q.

        Fails with reason empty if Q is empty.

        Example 1:

        1> queue:head(queue:from_list([1,2,3])).
        +

        Returns Item from the head of queue Q.

        Fails with reason empty if Q is empty.

        Example 1:

        1> queue:head(queue:from_list([1,2,3])).
         1
        @@ -1809,10 +1809,10 @@

        init(Q1)

        -

        Returns a queue Q2 that is the result of removing the tail item from Q1.

        Fails with reason empty if Q1 is empty.

        Example:

        1> Queue = queue:init(queue:from_list([1,2,3])).
        -{[2],[1]}
        -2> queue:to_list(Queue).
        -[1,2]
        +

        Returns a queue Q2 that is the result of removing the tail item from Q1.

        Fails with reason empty if Q1 is empty.

        Example:

        1> Queue = queue:init(queue:from_list([1,2,3])).
        +{[2],[1]}
        +2> queue:to_list(Queue).
        +[1,2]
        @@ -1872,7 +1872,7 @@

        last(Q)

        -

        Returns the tail item of queue Q.

        Fails with reason empty if Q is empty.

        Example:

        1> queue:last(queue:from_list([1,2,3])).
        +

        Returns the tail item of queue Q.

        Fails with reason empty if Q is empty.

        Example:

        1> queue:last(queue:from_list([1,2,3])).
         3
        @@ -1901,10 +1901,10 @@

        liat(Q1)

        -

        Returns a queue Q2 that is the result of removing the tail item from Q1.

        Fails with reason empty if Q1 is empty.

        Example:

        1> Queue = queue:liat(queue:from_list([1,2,3])).
        -{[2],[1]}
        -2> queue:to_list(Queue).
        -[1,2]
        +

        Returns a queue Q2 that is the result of removing the tail item from Q1.

        Fails with reason empty if Q1 is empty.

        Example:

        1> Queue = queue:liat(queue:from_list([1,2,3])).
        +{[2],[1]}
        +2> queue:to_list(Queue).
        +[1,2]
        @@ -1932,10 +1932,10 @@

        snoc(Q1, Item)

        -

        Inserts Item as the tail item of queue Q1. Returns the new queue Q2.

        Example:

        1> Queue = queue:snoc(queue:from_list([1,2,3]), 4).
        -{[4,3,2],[1]}
        -2> queue:to_list(Queue).
        -[1,2,3,4]
        +

        Inserts Item as the tail item of queue Q1. Returns the new queue Q2.

        Example:

        1> Queue = queue:snoc(queue:from_list([1,2,3]), 4).
        +{[4,3,2],[1]}
        +2> queue:to_list(Queue).
        +[1,2,3,4]
        diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/rand.html b/prs/8803/lib/stdlib-6.0.1/doc/html/rand.html index 84a9f5fe02041..b70b31cecefb6 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/rand.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/rand.html @@ -201,13 +201,13 @@

        a reasonably unpredictable seed.

        The functions with explicit state don't use the process dictionary.

        Examples

        Simple use; create and seed the default algorithm with a non-fixed seed, if not already done, and generate two uniformly distibuted -floating point numbers.

        R0 = rand:uniform(),
        -R1 = rand:uniform(),

        Use a specified algorithm:

        _ = rand:seed(exro928ss),
        -R2 = rand:uniform(),

        Use a specified algorithm with a fixed seed:

        _ = rand:seed(exro928ss, {123, 123534, 345345}),
        -R3 = rand:uniform(),

        Use the functional API with a non-fixed seed:

        S0 = rand:seed_s(exsss),
        -{R4, S1} = rand:uniform_s(S0),

        Generate a textbook basic form Box-Muller standard normal distribution number:

        R5 = rand:uniform_real(),
        -R6 = rand:uniform(),
        -SND0 = math:sqrt(-2 * math:log(R5)) * math:cos(math:pi() * R6)

        Generate a standard normal distribution number:

        {SND1, S2} = rand:normal_s(S1),

        Generate a normal distribution number with with mean -3 and variance 0.5:

        {ND0, S3} = rand:normal_s(-3, 0.5, S2),

        Quality of the Generated Numbers

        Note

        The builtin random number generator algorithms are not cryptographically +floating point numbers.

        R0 = rand:uniform(),
        +R1 = rand:uniform(),

        Use a specified algorithm:

        _ = rand:seed(exro928ss),
        +R2 = rand:uniform(),

        Use a specified algorithm with a fixed seed:

        _ = rand:seed(exro928ss, {123, 123534, 345345}),
        +R3 = rand:uniform(),

        Use the functional API with a non-fixed seed:

        S0 = rand:seed_s(exsss),
        +{R4, S1} = rand:uniform_s(S0),

        Generate a textbook basic form Box-Muller standard normal distribution number:

        R5 = rand:uniform_real(),
        +R6 = rand:uniform(),
        +SND0 = math:sqrt(-2 * math:log(R5)) * math:cos(math:pi() * R6)

        Generate a standard normal distribution number:

        {SND1, S2} = rand:normal_s(S1),

        Generate a normal distribution number with with mean -3 and variance 0.5:

        {ND0, S3} = rand:normal_s(-3, 0.5, S2),

        Quality of the Generated Numbers

        Note

        The builtin random number generator algorithms are not cryptographically strong. If a cryptographically strong random number generator is needed, use something like crypto:rand_seed/0.

        For all these generators except exro928ss and exsss the lowest bit(s) have got a slightly less random behaviour than all other bits. @@ -218,7 +218,7 @@

        up to (and included) 16TB, with the exception of binary rank tests, which fail due to the lowest bit being an LFSR; all other bits pass all tests. We suggest to use a sign test to extract a random Boolean value.

        If this is a problem; to generate a boolean with these algorithms, -use something like this:

        (rand:uniform(256) > 128) % -> boolean()
        ((rand:uniform(256) - 1) bsr 7) % -> 0 | 1

        For a general range, with N = 1 for exrop, and N = 3 for exs1024s:

        (((rand:uniform(Range bsl N) - 1) bsr N) + 1)

        The floating point generating functions in this module waste the lowest bits +use something like this:

        (rand:uniform(256) > 128) % -> boolean()
        ((rand:uniform(256) - 1) bsr 7) % -> 0 | 1

        For a general range, with N = 1 for exrop, and N = 3 for exs1024s:

        (((rand:uniform(Range bsl N) - 1) bsr N) + 1)

        The floating point generating functions in this module waste the lowest bits when converting from an integer so they avoid this snag.

        @@ -1947,10 +1947,10 @@

        uniform_s(State)

        equally spaced in the interval.

        Warning

        This function may return exactly 0.0 which can be fatal for certain applications. If that is undesired you can use (1.0 - rand:uniform()) to get the interval 0.0 < X =< 1.0, or instead use uniform_real/0.

        If neither endpoint is desired you can achieve the range -0.0 < X < 1.0 using test and re-try like this:

        my_uniform() ->
        -    case rand:uniform() of
        +0.0 < X < 1.0 using test and re-try like this:

        my_uniform() ->
        +    case rand:uniform() of
                 X when 0.0 < X -> X;
        -        _ -> my_uniform()
        +        _ -> my_uniform()
             end.

        @@ -2111,7 +2111,7 @@

        mwc59(CX0)

        16#7fa6502 * 2^32 - 1, which have been selected, in collaboration with Sebastiano Vigna, to avoid bignum operations and still get good statistical quality. It has been named "MWC59" and can be written as:

        C = CX0 bsr 32
        -X = CX0 band ((1 bsl 32)-1))
        +X = CX0 band ((1 bsl 32)-1))
         CX1 = 16#7fa6502 * X + C

        Because the generator uses a multiplier that is a power of 2 it gets statistical flaws for collision tests and birthday spacings tests in 2 and 3 dimensions, and these caveats apply even when looking diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/random.html b/prs/8803/lib/stdlib-6.0.1/doc/html/random.html index 1e8f55f6db3b8..0fbb3a592e5f7 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/random.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/random.html @@ -472,9 +472,9 @@

        seed(A1, A2, A3)

        Seeds random number generation with integer values in the process dictionary and -returns the old state.

        The following is an easy way of obtaining a unique value to seed with:

        random:seed(erlang:phash2([node()]),
        -            erlang:monotonic_time(),
        -            erlang:unique_integer())

        For details, see erlang:phash2/1, erlang:node/0, erlang:monotonic_time/0, +returns the old state.

        The following is an easy way of obtaining a unique value to seed with:

        random:seed(erlang:phash2([node()]),
        +            erlang:monotonic_time(),
        +            erlang:unique_integer())

        For details, see erlang:phash2/1, erlang:node/0, erlang:monotonic_time/0, and erlang:unique_integer/0.

        diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/re.html b/prs/8803/lib/stdlib-6.0.1/doc/html/re.html index 541dbb5444a79..b4e40f82f1adf 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/re.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/re.html @@ -1375,9 +1375,9 @@

        follows (COMMIT) can be triggered first, so merely passing (COMMIT) during a match does not always guarantee that a match must be at this starting point.

        Notice that (*COMMIT) at the start of a pattern is not the same as an anchor, unless the PCRE start-of-match optimizations are turned off, as shown in the -following example:

        1> re:run("xyzabc","(*COMMIT)abc",[{capture,all,list}]).
        -{match,["abc"]}
        -2> re:run("xyzabc","(*COMMIT)abc",[{capture,all,list},no_start_optimize]).
        +following example:

        1> re:run("xyzabc","(*COMMIT)abc",[{capture,all,list}]).
        +{match,["abc"]}
        +2> re:run("xyzabc","(*COMMIT)abc",[{capture,all,list},no_start_optimize]).
         nomatch

        For this pattern, PCRE knows that any match must start with "a", so the optimization skips along the subject to "a" before applying the pattern to the first set of data. The match attempt then succeeds. In the second call the @@ -2110,32 +2110,32 @@

        inspect(MP, Item)

        Takes a compiled regular expression and an item, and returns the relevant data from the regular expression.

        The only supported item is namelist, which returns the tuple {namelist, [binary()]}, -containing the names of all (unique) named subpatterns in the regular expression.

        For example:

        1> {ok,MP} = re:compile("(?<A>A)|(?<B>B)|(?<C>C)").
        -{ok,{re_pattern,3,0,0,
        +containing the names of all (unique) named subpatterns in the regular expression.

        For example:

        1> {ok,MP} = re:compile("(?<A>A)|(?<B>B)|(?<C>C)").
        +{ok,{re_pattern,3,0,0,
                         <<69,82,67,80,119,0,0,0,0,0,0,0,1,0,0,0,255,255,255,255,
        -                  255,255,...>>}}
        -2> re:inspect(MP,namelist).
        -{namelist,[<<"A">>,<<"B">>,<<"C">>]}
        -3> {ok,MPD} = re:compile("(?<C>A)|(?<B>B)|(?<C>C)",[dupnames]).
        -{ok,{re_pattern,3,0,0,
        +                  255,255,...>>}}
        +2> re:inspect(MP,namelist).
        +{namelist,[<<"A">>,<<"B">>,<<"C">>]}
        +3> {ok,MPD} = re:compile("(?<C>A)|(?<B>B)|(?<C>C)",[dupnames]).
        +{ok,{re_pattern,3,0,0,
                         <<69,82,67,80,119,0,0,0,0,0,8,0,1,0,0,0,255,255,255,255,
        -                  255,255,...>>}}
        -4> re:inspect(MPD,namelist).
        -{namelist,[<<"B">>,<<"C">>]}

        Notice in the second example that the duplicate name only occurs once in the + 255,255,...>>}} +4> re:inspect(MPD,namelist). +{namelist,[<<"B">>,<<"C">>]}

        Notice in the second example that the duplicate name only occurs once in the returned list, and that the list is in alphabetical order regardless of where the names are positioned in the regular expression. The order of the names is the same as the order of captured subexpressions if {capture, all_names} is specified as an option to run/3. You can therefore create a name-to-value -mapping from the result of run/3 like this:

        1> {ok,MP} = re:compile("(?<A>A)|(?<B>B)|(?<C>C)").
        -{ok,{re_pattern,3,0,0,
        +mapping from the result of run/3 like this:

        1> {ok,MP} = re:compile("(?<A>A)|(?<B>B)|(?<C>C)").
        +{ok,{re_pattern,3,0,0,
                         <<69,82,67,80,119,0,0,0,0,0,0,0,1,0,0,0,255,255,255,255,
        -                  255,255,...>>}}
        -2> {namelist, N} = re:inspect(MP,namelist).
        -{namelist,[<<"A">>,<<"B">>,<<"C">>]}
        -3> {match,L} = re:run("AA",MP,[{capture,all_names,binary}]).
        -{match,[<<"A">>,<<>>,<<>>]}
        -4> NameMap = lists:zip(N,L).
        -[{<<"A">>,<<"A">>},{<<"B">>,<<>>},{<<"C">>,<<>>}]
        +
        255,255,...>>}} +2> {namelist, N} = re:inspect(MP,namelist). +{namelist,[<<"A">>,<<"B">>,<<"C">>]} +3> {match,L} = re:run("AA",MP,[{capture,all_names,binary}]). +{match,[<<"A">>,<<>>,<<>>]} +4> NameMap = lists:zip(N,L). +[{<<"A">>,<<"A">>},{<<"B">>,<<>>},{<<"C">>,<<>>}]
        @@ -2228,16 +2228,16 @@

        replace(Subject, RE, Replacement, Options)< subexpression number N, is inserted in the result. If no subexpression with that number is generated by the regular expression, nothing is inserted.

        To insert an & or a \ in the result, precede it with a \. Notice that Erlang already gives a special meaning to \ in literal strings, so a single \ must be -written as "\\" and therefore a double \ as "\\\\".

        Example:

        1> re:replace("abcd","c","[&]",[{return,list}]).
        -"ab[c]d"

        while

        2> re:replace("abcd","c","[\\&]",[{return,list}]).
        +written as "\\" and therefore a double \ as "\\\\".

        Example:

        1> re:replace("abcd","c","[&]",[{return,list}]).
        +"ab[c]d"

        while

        2> re:replace("abcd","c","[\\&]",[{return,list}]).
         "ab[&]d"

        If the replacement is given as a fun, it will be called with the whole matching expression as the first argument and a list of subexpression matches in the order in which they appear in the regular expression. The returned value will be -inserted in the result.

        Example:

        3> re:replace("abcd", ".(.)",
        -    fun(Whole, [<<C>>]) ->
        -         <<$#, Whole/binary, $-, (C - $a + $A), $#>>
        +inserted in the result.

        Example:

        3> re:replace("abcd", ".(.)",
        +    fun(Whole, [<<C>>]) ->
        +         <<$#, Whole/binary, $-, (C - $a + $A), $#>>
             end,
        -    [{return, list}]).
        +    [{return, list}]).
         "#ab-B#cd"

        Note

        Non-matching optional subexpressions will not be included in the list of subexpression matches if they are the last subexpressions in the regular expression.

        Example:

        The regular expression "(a)(b)?(c)?" ("a", optionally followed by "b", @@ -2354,7 +2354,7 @@

        run(Subject, RE, Options)

        run/3 handles empty matches in the same way as Perl: a zero-length match at any point is also retried with options [anchored, notempty_atstart]. If that search gives a result of length > 0, -the result is included. Example:

        re:run("cat","(|at)",[global]).

        The following matchings are performed:

        • At offset 0 - The regular expression (|at) first match at the +the result is included. Example:

          re:run("cat","(|at)",[global]).

          The following matchings are performed:

          • At offset 0 - The regular expression (|at) first match at the initial position of string cat, giving the result set [{0,0},{0,0}] (the second {0,0} is because of the subexpression marked by the parentheses). As the length of the match is 0, we do not advance to the next position yet.

          • At offset 0 with [anchored, notempty_atstart] - The search is @@ -2366,7 +2366,7 @@

            run(Subject, RE, Options)

            of results and the position in the search string is advanced two steps.

          • At offset 3 - The search once again matches the empty string, giving [{3,0},{3,0}].

          • At offset 1 with [anchored, notempty_atstart] - This gives no result of length > 0 and we are at the last position, so the global search is -complete.

          The result of the call is:

          {match,[[{0,0},{0,0}],[{1,0},{1,0}],[{1,2},{1,2}],[{3,0},{3,0}]]}
        • notempty - An empty string is not considered to be a valid match if this +complete.

        The result of the call is:

        {match,[[{0,0},{0,0}],[{1,0},{1,0}],[{1,2},{1,2}],[{3,0},{3,0}]]}

      • notempty - An empty string is not considered to be a valid match if this option is specified. If alternatives in the pattern exist, they are tried. If all the alternatives match the empty string, the entire match fails.

        Example:

        If the following pattern is applied to a string not beginning with "a" or "b", it would normally match the empty string at the start of the subject:

        a?b?

        With option notempty, this match is invalid, so run/3 searches @@ -2437,12 +2437,12 @@

        run(Subject, RE, Options)

        instead of the stack, the amount of heap memory that can be used.

        The Erlang VM uses a PCRE library where heap memory is used when regular expression match recursion occurs. This therefore limits the use of machine heap, not C stack.

        Specifying a lower value can result in matches with deep recursion failing, -when they should have matched:

        1> re:run("aaaaaaaaaaaaaz","(a+)*z").
        -{match,[{0,14},{0,13}]}
        -2> re:run("aaaaaaaaaaaaaz","(a+)*z",[{match_limit_recursion,5}]).
        +when they should have matched:

        1> re:run("aaaaaaaaaaaaaz","(a+)*z").
        +{match,[{0,14},{0,13}]}
        +2> re:run("aaaaaaaaaaaaaz","(a+)*z",[{match_limit_recursion,5}]).
         nomatch
        -3> re:run("aaaaaaaaaaaaaz","(a+)*z",[{match_limit_recursion,5},report_errors]).
        -{error,match_limit_recursion}

        This option and option match_limit are only to be used in rare cases. +3> re:run("aaaaaaaaaaaaaz","(a+)*z",[{match_limit_recursion,5},report_errors]). +{error,match_limit_recursion}

        This option and option match_limit are only to be used in rare cases. Understanding of the PCRE library internals is recommended before tampering with these limits.

      • {offset, integer() >= 0} - Start matching at the offset (position) specified in the subject string. The offset is zero-based, so that the default @@ -2464,9 +2464,9 @@

        run(Subject, RE, Options)

        capturing).

        As an example of the default behavior, the following call returns, as first and only captured string, the matching part of the subject ("abcd" in the middle) as an index pair {3,4}, where character positions are zero-based, -just as in offsets:

        re:run("ABCabcdABC","abcd",[]).

        The return value of this call is:

        {match,[{3,4}]}

        Another (and quite common) case is where the regular expression matches all of -the subject:

        re:run("ABCabcdABC",".*abcd.*",[]).

        Here the return value correspondingly points out all of the string, beginning -at index 0, and it is 10 characters long:

        {match,[{0,10}]}

        If the regular expression contains capturing subpatterns, like in:

        re:run("ABCabcdABC",".*(abcd).*",[]).

        all of the matched subject is captured, as well as the captured substrings:

        {match,[{0,10},{3,4}]}

        The complete matching pattern always gives the first return value in the list +just as in offsets:

        re:run("ABCabcdABC","abcd",[]).

        The return value of this call is:

        {match,[{3,4}]}

        Another (and quite common) case is where the regular expression matches all of +the subject:

        re:run("ABCabcdABC",".*abcd.*",[]).

        Here the return value correspondingly points out all of the string, beginning +at index 0, and it is 10 characters long:

        {match,[{0,10}]}

        If the regular expression contains capturing subpatterns, like in:

        re:run("ABCabcdABC",".*(abcd).*",[]).

        all of the matched subject is captured, as well as the captured substrings:

        {match,[{0,10},{3,4}]}

        The complete matching pattern always gives the first return value in the list and the remaining subpatterns are added in the order they occurred in the regular expression.

        The capture tuple is built up as follows:

        • ValueSpec - Specifies which captured (sub)patterns are to be returned. ValueSpec can either be an atom describing a predefined set of return @@ -2491,12 +2491,12 @@

          run(Subject, RE, Options)

          subpatterns (see below) in the regular expression, one can use atom/0s or string/0s to specify the subpatterns to be returned. For example, consider the regular expression:

          ".*(abcd).*"

          matched against string "ABCabcdABC", capturing only the "abcd" part (the -first explicit subpattern):

          re:run("ABCabcdABC",".*(abcd).*",[{capture,[1]}]).

          The call gives the following result, as the first explicitly captured +first explicit subpattern):

          re:run("ABCabcdABC",".*(abcd).*",[{capture,[1]}]).

          The call gives the following result, as the first explicitly captured subpattern is "(abcd)", matching "abcd" in the subject, at (zero-based) -position 3, of length 4:

          {match,[{3,4}]}

          Consider the same regular expression, but with the subpattern explicitly +position 3, of length 4:

          {match,[{3,4}]}

          Consider the same regular expression, but with the subpattern explicitly named 'FOO':

          ".*(?<FOO>abcd).*"

          With this expression, we could still give the index of the subpattern with -the following call:

          re:run("ABCabcdABC",".*(?<FOO>abcd).*",[{capture,[1]}]).

          giving the same result as before. But, as the subpattern is named, we can -also specify its name in the value list:

          re:run("ABCabcdABC",".*(?<FOO>abcd).*",[{capture,['FOO']}]).

          This would give the same result as the earlier examples, namely:

          {match,[{3,4}]}

          The values list can specify indexes or names not present in the regular +the following call:

          re:run("ABCabcdABC",".*(?<FOO>abcd).*",[{capture,[1]}]).

          giving the same result as before. But, as the subpattern is named, we can +also specify its name in the value list:

          re:run("ABCabcdABC",".*(?<FOO>abcd).*",[{capture,['FOO']}]).

          This would give the same result as the earlier examples, namely:

          {match,[{3,4}]}

          The values list can specify indexes or names not present in the regular expression, in which case the return values vary depending on the type. If the type is index, the tuple {-1,0} is returned for values with no corresponding subpattern in the regular expression, but for the other types @@ -2531,12 +2531,12 @@

          run(Subject, RE, Options)

          string:

          "ABCabcdABC"

          the subpattern at index 2 does not match, as "abdd" is not present in the string, but the complete pattern matches (because of the alternative a(..d)). The subpattern at index 2 is therefore unassigned and the default -return value is:

          {match,[{0,10},{3,4},{-1,0},{4,3}]}

          Setting the capture Type to binary gives:

          {match,[<<"ABCabcdABC">>,<<"abcd">>,<<>>,<<"bcd">>]}

          Here the empty binary (<<>>) represents the unassigned subpattern. In the +return value is:

          {match,[{0,10},{3,4},{-1,0},{4,3}]}

          Setting the capture Type to binary gives:

          {match,[<<"ABCabcdABC">>,<<"abcd">>,<<>>,<<"bcd">>]}

          Here the empty binary (<<>>) represents the unassigned subpattern. In the binary case, some information about the matching is therefore lost, as <<>> can also be an empty string captured.

          If differentiation between empty matches and non-existing subpatterns is necessary, use the type index and do the conversion to the final type in Erlang code.

          When option global is speciified, the capture specification affects each -match separately, so that:

          re:run("cacb","c(a|b)",[global,{capture,[1],list}]).

          gives

          {match,[["a"],["b"]]}

        For a descriptions of options only affecting the compilation step, see +match separately, so that:

        re:run("cacb","c(a|b)",[global,{capture,[1],list}]).

        gives

        {match,[["a"],["b"]]}

      For a descriptions of options only affecting the compilation step, see compile/2.

      @@ -2625,7 +2625,7 @@

      split(Subject, RE, Options)

      compilation option is specified to this function, both the regular expression and Subject are to be specified as valid Unicode charlist()s.

      The result is given as a list of "strings", the preferred data type specified in option return (default iodata).

      If subexpressions are specified in the regular expression, the matching -subexpressions are returned in the resulting list as well. For example:

      re:split("Erlang","[ln]",[{return,list}]).

      gives

      ["Er","a","g"]

      while

      re:split("Erlang","([ln])",[{return,list}]).

      gives

      ["Er","l","a","n","g"]

      The text matching the subexpression (marked by the parentheses in the regular +subexpressions are returned in the resulting list as well. For example:

      re:split("Erlang","[ln]",[{return,list}]).

      gives

      ["Er","a","g"]

      while

      re:split("Erlang","([ln])",[{return,list}]).

      gives

      ["Er","l","a","n","g"]

      The text matching the subexpression (marked by the parentheses in the regular expression) is inserted in the result list where it was found. This means that concatenating the result of a split where the whole regular expression is a single subexpression (as in the last example) always results in the original @@ -2633,21 +2633,21 @@

      split(Subject, RE, Options)

      "g"), nothing is inserted after that. To make the group of strings and the parts matching the subexpressions more obvious, one can use option group, which groups together the part of the subject string with the parts matching the -subexpressions when the string was split:

      re:split("Erlang","([ln])",[{return,list},group]).

      gives

      [["Er","l"],["a","n"],["g"]]

      Here the regular expression first matched the "l", causing "Er" to be the first +subexpressions when the string was split:

      re:split("Erlang","([ln])",[{return,list},group]).

      gives

      [["Er","l"],["a","n"],["g"]]

      Here the regular expression first matched the "l", causing "Er" to be the first part in the result. When the regular expression matched, the (only) subexpression was bound to the "l", so the "l" is inserted in the group together with "Er". The next match is of the "n", making "a" the next part to be returned. As the subexpression is bound to substring "n" in this case, the "n" is inserted into this group. The last group consists of the remaining string, as no more matches are found.

      By default, all parts of the string, including the empty strings, are returned -from the function, for example:

      re:split("Erlang","[lg]",[{return,list}]).

      gives

      ["Er","an",[]]

      as the matching of the "g" in the end of the string leaves an empty rest, which +from the function, for example:

      re:split("Erlang","[lg]",[{return,list}]).

      gives

      ["Er","an",[]]

      as the matching of the "g" in the end of the string leaves an empty rest, which is also returned. This behavior differs from the default behavior of the split function in Perl, where empty strings at the end are by default removed. To get -the "trimming" default behavior of Perl, specify trim as an option:

      re:split("Erlang","[lg]",[{return,list},trim]).

      gives

      ["Er","an"]

      The "trim" option says; "give me as many parts as possible except the empty +the "trimming" default behavior of Perl, specify trim as an option:

      re:split("Erlang","[lg]",[{return,list},trim]).

      gives

      ["Er","an"]

      The "trim" option says; "give me as many parts as possible except the empty ones", which sometimes can be useful. You can also specify how many parts you -want, by specifying {parts,N}:

      re:split("Erlang","[lg]",[{return,list},{parts,2}]).

      gives

      ["Er","ang"]

      Notice that the last part is "ang", not "an", as splitting was specified into +want, by specifying {parts,N}:

      re:split("Erlang","[lg]",[{return,list},{parts,2}]).

      gives

      ["Er","ang"]

      Notice that the last part is "ang", not "an", as splitting was specified into two parts, and the splitting stops when enough parts are given, which is why the -result differs from that of trim.

      More than three parts are not possible with this indata, so

      re:split("Erlang","[lg]",[{return,list},{parts,4}]).

      gives the same result as the default, which is to be viewed as "an infinite +result differs from that of trim.

      More than three parts are not possible with this indata, so

      re:split("Erlang","[lg]",[{return,list},{parts,4}]).

      gives the same result as the default, which is to be viewed as "an infinite number of parts".

      Specifying 0 as the number of parts gives the same effect as option trim. If subexpressions are captured, empty subexpressions matched at the end are also stripped from the result if trim or {parts,0} is specified.

      The trim behavior corresponds exactly to the Perl default. {parts,N}, where diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/sets.html b/prs/8803/lib/stdlib-6.0.1/doc/html/sets.html index deb5eccce6d03..2acdf07232c41 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/sets.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/sets.html @@ -154,11 +154,11 @@

      respect to the aforementioned functions, their overall behavior may differ. As mentioned, this module considers elements as different if and only if they do not match (=:=), while both ordsets and gb_sets consider elements -as different if and only if they do not compare equal (==).

      Example:

      1> sets:is_element(1.0, sets:from_list([1])).
      +as different if and only if they do not compare equal (==).

      Example:

      1> sets:is_element(1.0, sets:from_list([1])).
       false
      -2> ordsets:is_element(1.0, ordsets:from_list([1])).
      +2> ordsets:is_element(1.0, ordsets:from_list([1])).
       true
      -2> gb_sets:is_element(1.0, gb_sets:from_list([1])).
      +2> gb_sets:is_element(1.0, gb_sets:from_list([1])).
       true

      diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/shell.html b/prs/8803/lib/stdlib-6.0.1/doc/html/shell.html index de970f68ee703..c467c130b388e 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/shell.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/shell.html @@ -166,7 +166,7 @@

      definitions. To facilitate matters, record definitions in modules shell_default and user_default (if loaded) are read each time a new job is started. For example, adding the following line to user_default makes the -definition of file_info readily available in the shell:

      -include_lib("kernel/include/file.hrl").

      The shell runs in two modes:

      Command 1 sets variable Str to string "abcd".

      2> L = length(Str).
      +4

      Command 2 sets L to the length of string Str.

      3> Descriptor = {L, list_to_atom(Str)}.
      +{4,abcd}

      Command 3 builds the tuple Descriptor, evaluating the BIF list_to_atom/1 .

      4> L.
      -4

      Command 4 prints the value of variable L.

      5> b().
      -Descriptor = {4,abcd}
      +4

      Command 4 prints the value of variable L.

      5> b().
      +Descriptor = {4,abcd}
       L = 4
       Str = "abcd"
       ok

      Command 5 evaluates the internal shell command b(), which is an abbreviation of "bindings". This prints the current shell variables and their bindings. ok -at the end is the return value of function b().

      6> f(L).
      +at the end is the return value of function b().

      6> f(L).
       ok

      Command 6 evaluates the internal shell command f(L) (abbreviation of -"forget"). The value of variable L is removed.

      7> b().
      -Descriptor = {4,abcd}
      +"forget"). The value of variable L is removed.

      7> b().
      +Descriptor = {4,abcd}
       Str = "abcd"
      -ok

      Command 7 prints the new bindings.

      8> f(L).
      -ok

      Command 8 has no effect, as L has no value.

      9> {L, _} = Descriptor.
      -{4,abcd}

      Command 9 performs a pattern matching operation on Descriptor, binding a new +ok

      Command 7 prints the new bindings.

      8> f(L).
      +ok

      Command 8 has no effect, as L has no value.

      9> {L, _} = Descriptor.
      +{4,abcd}

      Command 9 performs a pattern matching operation on Descriptor, binding a new value to L.

      10> L.
      -4

      Command 10 prints the current value of L.

      11> {P, Q, R} = Descriptor.
      +4

      Command 10 prints the current value of L.

      11> {P, Q, R} = Descriptor.
       ** exception error: no match of right hand side value {4,abcd}

      Command 11 tries to match {P, Q, R} against Descriptor, which is {4, abc}. The match fails and none of the new variables become bound. The printout starting with "** exception error:" is not the value of the expression (the @@ -266,74 +266,74 @@

      other variables (L, Str, and so on) are unchanged.

      12> P.
       * 1:1: variable 'P' is unbound
       13> Descriptor.
      -{4,abcd}

      Commands 12 and 13 show that P is unbound because the previous command failed, -and that Descriptor has not changed.

      14>{P, Q} = Descriptor.
      -{4,abcd}
      +{4,abcd}

      Commands 12 and 13 show that P is unbound because the previous command failed, +and that Descriptor has not changed.

      14>{P, Q} = Descriptor.
      +{4,abcd}
       15> P.
      -4

      Commands 14 and 15 show a correct match where P and Q are bound.

      16> f().
      -ok

      Command 16 clears all bindings.

      The next few commands assume that test1:demo(X) is defined as follows:

      demo(X) ->
      -    put(aa, worked),
      +4

      Commands 14 and 15 show a correct match where P and Q are bound.

      16> f().
      +ok

      Command 16 clears all bindings.

      The next few commands assume that test1:demo(X) is defined as follows:

      demo(X) ->
      +    put(aa, worked),
           X = 1,
      -    X + 10.
      17> put(aa, hello).
      +    X + 10.
      17> put(aa, hello).
       undefined
      -18> get(aa).
      +18> get(aa).
       hello

      Commands 17 and 18 set and inspect the value of item aa in the process -dictionary.

      19> Y = test1:demo(1).
      +dictionary.

      19> Y = test1:demo(1).
       11

      Command 19 evaluates test1:demo(1). The evaluation succeeds and the changes made in the process dictionary become visible to the shell. The new value of -dictionary item aa can be seen in command 20.

      20> get().
      -[{aa,worked}]
      -21> put(aa, hello).
      +dictionary item aa can be seen in command 20.

      20> get().
      +[{aa,worked}]
      +21> put(aa, hello).
       worked
      -22> Z = test1:demo(2).
      +22> Z = test1:demo(2).
       ** exception error: no match of right hand side value 1
            in function  test1:demo/1

      Commands 21 and 22 change the value of dictionary item aa to hello and call test1:demo(2). Evaluation fails and the changes made to the dictionary in test1:demo(2), before the error occurred, are discarded.

      23> Z.
       * 1:1: variable 'Z' is unbound
      -24> get(aa).
      +24> get(aa).
       hello

      Commands 23 and 24 show that Z was not bound and that dictionary item aa has -retained its original value.

      25> erase(), put(aa, hello).
      +retained its original value.

      25> erase(), put(aa, hello).
       undefined
      -26> spawn(test1, demo, [1]).
      +26> spawn(test1, demo, [1]).
       <0.57.0>
      -27> get(aa).
      +27> get(aa).
       hello

      Commands 25, 26, and 27 show the effect of evaluating test1:demo(1) in the background. In this case, the expression is evaluated in a newly spawned process. Any changes made in the process dictionary are local to the newly -spawned process and therefore not visible to the shell.

      28> io:format("hello hello\n").
      +spawned process and therefore not visible to the shell.

      28> io:format("hello hello\n").
       hello hello
       ok
      -29> e(28).
      +29> e(28).
       hello hello
       ok
      -30> v(28).
      +30> v(28).
       ok

      Commands 28, 29 and 30 use the history facilities of the shell. Command 29 re-evaluates command 28. Command 30 uses the value (result) of command 28. In the cases of a pure function (a function with no side effects), the result is the same. For a function with side effects, the result can be different.

      The next few commands show some record manipulation. It is assumed that ex.erl -defines a record as follows:

      -record(rec, {a, b = val()}).

      val() ->
          3.

      31> c(ex).
      -{ok,ex}
      -32> rr(ex).
      -[rec]

      Commands 31 and 32 compile file ex.erl and read the record definitions in +defines a record as follows:

      -record(rec, {a, b = val()}).

      val() ->
          3.

      31> c(ex).
      +{ok,ex}
      +32> rr(ex).
      +[rec]

      Commands 31 and 32 compile file ex.erl and read the record definitions in ex.beam. If the compiler did not output any record definitions on the BEAM -file, rr(ex) tries to read record definitions from the source file instead.

      33> rl(rec).
      --record(rec,{a,b = val()}).
      -ok

      Command 33 prints the definition of the record named rec.

      34> #rec{}.
      +file, rr(ex) tries to read record definitions from the source file instead.

      33> rl(rec).
      +-record(rec,{a,b = val()}).
      +ok

      Command 33 prints the definition of the record named rec.

      34> #rec{}.
       ** exception error: undefined shell command val/0

      Command 34 tries to create a rec record, but fails as function val/0 is -undefined.

      35> #rec{b = 3}.
      -#rec{a = undefined,b = 3}

      Command 35 shows the workaround: explicitly assign values to record fields that -cannot otherwise be initialized.

      36> rp(v(-1)).
      -#rec{a = undefined,b = 3}
      +undefined.

      35> #rec{b = 3}.
      +#rec{a = undefined,b = 3}

      Command 35 shows the workaround: explicitly assign values to record fields that +cannot otherwise be initialized.

      36> rp(v(-1)).
      +#rec{a = undefined,b = 3}
       ok

      Command 36 prints the newly created record using record definitions maintained -by the shell.

      37> rd(rec, {f = orddict:new()}).
      +by the shell.

      37> rd(rec, {f = orddict:new()}).
       rec

      Command 37 defines a record directly in the shell. The definition replaces the -one read from file ex.beam.

      38> #rec{}.
      -#rec{f = []}
      -ok

      Command 38 creates a record using the new definition, and prints the result.

      39> rd(rec, {c}), A.
      +one read from file ex.beam.

      38> #rec{}.
      +#rec{f = []}
      +ok

      Command 38 creates a record using the new definition, and prints the result.

      39> rd(rec, {c}), A.
       * 1:15: variable 'A' is unbound
      -40> #rec{}.
      -#rec{c = undefined}
      +40> #rec{}.
      +#rec{c = undefined}
       ok

      Command 39 and 40 show that record definitions are updated as side effects. The evaluation of the command fails, but the definition of rec has been carried out.

      For the next command, it is assumed that test1:loop(N) is defined as follows:

      loop(N) ->
          io:format("Hello Number: ~w~n", [N]),
          loop(N+1).

      41> test1:loop(0).
      @@ -359,31 +359,31 @@ 

      JCL mode the user can start and stop jobs.

      In this particular case, command i ("interrupt") terminates the looping program, and command c connects to the shell again. As the process was running in the background before we killed it, more printouts occur before message -"** exception exit: killed" is shown.

      42> E = ets:new(t, []).
      -#Ref<0.1662103692.2407923716.214192>

      Command 42 creates an ETS table.

      43> ets:insert({d,1,2}).
      +"** exception exit: killed" is shown.

      42> E = ets:new(t, []).
      +#Ref<0.1662103692.2407923716.214192>

      Command 42 creates an ETS table.

      43> ets:insert({d,1,2}).
       ** exception error: undefined function ets:insert/1

      Command 43 tries to insert a tuple into the ETS table, but the first argument -(the table) is missing. The exception kills the evaluator process.

      44> ets:insert(E, {d,1,2}).
      +(the table) is missing. The exception kills the evaluator process.

      44> ets:insert(E, {d,1,2}).
       ** exception error: argument is of wrong type
            in function  ets:insert/2
               called as ets:insert(16,{d,1,2})

      Command 44 corrects the mistake, but the ETS table has been destroyed as it was -owned by the killed evaluator process.

      45> f(E).
      +owned by the killed evaluator process.

      45> f(E).
       ok
      -46> catch_exception(true).
      +46> catch_exception(true).
       false

      Command 46 sets the exception handling of the evaluator process to true. The exception handling can also be set when starting Erlang by -erl -stdlib shell_catch_exception true.

      47> E = ets:new(t, []).
      +erl -stdlib shell_catch_exception true.

      47> E = ets:new(t, []).
       #Ref<0.1662103692.2407923716.214197>
      -48> ets:insert({d,1,2}).
      +48> ets:insert({d,1,2}).
       * exception error: undefined function ets:insert/1

      Command 48 makes the same mistake as in command 43, but this time the evaluator process lives on. The single star at the beginning of the printout signals that -the exception has been caught.

      49> ets:insert(E, {d,1,2}).
      -true

      Command 49 successfully inserts the tuple into the ETS table.

      50> ets:insert(#Ref<0.1662103692.2407923716.214197>, {e,3,4}).
      +the exception has been caught.

      49> ets:insert(E, {d,1,2}).
      +true

      Command 49 successfully inserts the tuple into the ETS table.

      50> ets:insert(#Ref<0.1662103692.2407923716.214197>, {e,3,4}).
       true

      Command 50 inserts another tuple into the ETS table. This time the first argument is the table identifier itself. The shell can parse commands with pids (<0.60.0>), ports (#Port<0.536>), references (#Ref<0.1662103692.2407792644.214210>), and external functions (#Fun<a.b.1>), but the command fails unless the corresponding pid, port, -reference, or function can be created in the running system.

      51> halt().
      +reference, or function can be created in the running system.

      51> halt().
       strider 2>

      Command 51 exits the Erlang runtime system.

      @@ -856,7 +856,7 @@

      format_shell_func(ShellFormatFunc)

      stdlib app config for how to set it before shell started.

      If instead a string is provided, it will be used as a shell command. Your command must include ${file} somewhere in the string, for the shell to know -where the file goes in the command.

      shell:format_shell_func("\"emacs -batch \${file} -l ~/erlang-format/emacs-format-file -f emacs-format-function\"").
      shell:format_shell_func({shell, erl_pp_format_func}).
      +where the file goes in the command.

      shell:format_shell_func("\"emacs -batch \${file} -l ~/erlang-format/emacs-format-file -f emacs-format-function\"").
      shell:format_shell_func({shell, erl_pp_format_func}).
      @@ -1075,19 +1075,19 @@

      prompt_width(String, Encoding)

      It receives a prompt and computes its width, considering its Unicode characters -and ANSI escapes.

      Useful for creating custom multiline prompts.

      Example:

      1> shell:prompt_width("olá> ", unicode).
      +and ANSI escapes.

      Useful for creating custom multiline prompts.

      Example:

      1> shell:prompt_width("olá> ", unicode).
       5
       %% "olá> " is printed as "ol\341> " on a latin1 systems
      -2> shell:prompt_width("olá> ", latin1).
      +2> shell:prompt_width("olá> ", latin1).
       8
       %% Ansi escapes are ignored
      -3> shell:prompt_width("\e[32molá\e[0m> ", unicode).
      +3> shell:prompt_width("\e[32molá\e[0m> ", unicode).
       5
       %% Double width characters count as 2
      -4> shell:prompt_width("😀> ", unicode).
      +4> shell:prompt_width("😀> ", unicode).
       4
       %% "😀> " is printed as "\x{1F600}> " on latin1 systems
      -5> shell:prompt_width("😀> ", latin1).
      +5> shell:prompt_width("😀> ", latin1).
       11
      diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/shell_default.html b/prs/8803/lib/stdlib-6.0.1/doc/html/shell_default.html index 478083ff780c2..7b84a55d141db 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/shell_default.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/shell_default.html @@ -129,10 +129,10 @@

      Customizing the Erlang environment.

      The functions in this module are called when no module name is specified in a -shell command.

      Consider the following shell dialog:

      1> lists:reverse("abc").
      +shell command.

      Consider the following shell dialog:

      1> lists:reverse("abc").
       "cba"
      -2> c(foo).
      -{ok, foo}

      In command one, module lists is called. In command two, no module name is +2> c(foo). +{ok, foo}

      In command one, module lists is called. In command two, no module name is specified. The shell searches module user_default followed by module shell_default for function c/1.

      shell_default is intended for "system wide" customizations to the shell. user_default is intended for "local" or individual user customizations.

      diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/slave.html b/prs/8803/lib/stdlib-6.0.1/doc/html/slave.html index 0e2d56e46b09b..ac073974e0540 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/slave.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/slave.html @@ -375,7 +375,7 @@

      pseudo(Master, ServerList)

      at a master node. A pseudo server is an intermediary that only has the same registered name as the real server.

      For example, if you have started a slave node N and want to execute pxw graphics code on this node, you can start server pxw_server as a pseudo server -at the slave node. This is illustrated as follows:

      rpc:call(N, slave, pseudo, [node(), [pxw_server]]).
      +at the slave node. This is illustrated as follows:

      rpc:call(N, slave, pseudo, [node(), [pxw_server]]).
      @@ -529,9 +529,9 @@

      start(Host, Name, Args)

      passed to the new node and can be used for a variety of purposes; see erl(1).

      As an example, suppose that you want to start a slave node at host H with node name Name@H and want the slave node to have the following properties:

      • Directory Dir is to be added to the code path.
      • The Mnesia directory is to be set to M.
      • The Unix DISPLAY environment variable is to be set to the display of the -master node.

      The following code is executed to achieve this:

      E = " -env DISPLAY " ++ net_adm:localhost() ++ ":0 ",
      +master node.

    The following code is executed to achieve this:

    E = " -env DISPLAY " ++ net_adm:localhost() ++ ":0 ",
     Arg = "-mnesia_dir " ++ M ++ " -pa " ++ Dir ++ E,
    -slave:start(H, Name, Arg).

    The function returns {ok, Node}, where Node is the name of the new node, +slave:start(H, Name, Arg).

    The function returns {ok, Node}, where Node is the name of the new node, otherwise {error, Reason}, where Reason can be one of:

    • timeout - The master node failed to get in contact with the slave node. This can occur in a number of circumstances:

      • Erlang/OTP is not installed on the remote host.
      • The file system on the other host has a different structure to the the master.
      • The Erlang nodes have different cookies.
    • no_rsh - No remote shell program was found on the computer. Note that diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/sofs.html b/prs/8803/lib/stdlib-6.0.1/doc/html/sofs.html index 04751d1fe1528..c9a47ca38b628 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/sofs.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/sofs.html @@ -262,11 +262,11 @@

      selecting, duplicating, or rearranging parts of the elements.

    • Specifying a SetFun as an integer I is equivalent to specifying {external, fun(X) -> element(I, X) end}, but is to be preferred, as it makes it possible to handle this case even more efficiently.

    Examples of SetFuns:

    fun sofs:union/1
    -fun(S) -> sofs:partition(1, S) end
    -{external, fun(A) -> A end}
    -{external, fun({A,_,C}) -> {C,A} end}
    -{external, fun({_,{_,C}}) -> C end}
    -{external, fun({_,{_,{_,E}=C}}) -> {E,{E,C}} end}
    +fun(S) -> sofs:partition(1, S) end
    +{external, fun(A) -> A end}
    +{external, fun({A,_,C}) -> {C,A} end}
    +{external, fun({_,{_,C}}) -> C end}
    +{external, fun({_,{_,{_,E}=C}}) -> {E,{E,C}} end}
     2

    The order in which a SetFun is applied to the elements of an unordered set is not specified, and can change in future versions of this module.

    The execution time of the functions of this module is dominated by the time it takes to sort lists. When no sorting is needed, the execution time is in the @@ -1832,10 +1832,10 @@

    canonical_relation(SetOfSets)

    belongs to SetOfSets and E belongs to Set.

    If SetOfSets is a partition of a set X and R is the equivalence relation in X induced by SetOfSets, then the returned relation is the canonical map from X onto the equivalence classes with -respect to R.

    1> Ss = sofs:from_term([[a,b],[b,c]]),
    -CR = sofs:canonical_relation(Ss),
    -sofs:to_external(CR).
    -[{a,[a,b]},{b,[a,b]},{b,[b,c]},{c,[b,c]}]
    +respect to R.

    1> Ss = sofs:from_term([[a,b],[b,c]]),
    +CR = sofs:canonical_relation(Ss),
    +sofs:to_external(CR).
    +[{a,[a,b]},{b,[a,b]},{b,[b,c]},{c,[b,c]}]
    @@ -1865,11 +1865,11 @@

    composite(Function1, Function2)

    Returns the composite of the functions Function1 and -Function2.

    1> F1 = sofs:a_function([{a,1},{b,2},{c,2}]),
    -F2 = sofs:a_function([{1,x},{2,y},{3,z}]),
    -F = sofs:composite(F1, F2),
    -sofs:to_external(F).
    -[{a,x},{b,y},{c,y}]
    +Function2.

    1> F1 = sofs:a_function([{a,1},{b,2},{c,2}]),
    +F2 = sofs:a_function([{1,x},{2,y},{3,z}]),
    +F = sofs:composite(F1, F2),
    +sofs:to_external(F).
    +[{a,x},{b,y},{c,y}]
    @@ -1899,11 +1899,11 @@

    constant_function(Set, AnySet)

    Creates the function that maps each element of set Set -onto AnySet.

    1> S = sofs:set([a,b]),
    -E = sofs:from_term(1),
    -R = sofs:constant_function(S, E),
    -sofs:to_external(R).
    -[{a,1},{b,1}]
    +onto AnySet.

    1> S = sofs:set([a,b]),
    +E = sofs:from_term(1),
    +R = sofs:constant_function(S, E),
    +sofs:to_external(R).
    +[{a,1},{b,1}]
    @@ -1931,10 +1931,10 @@

    converse(BinRel1)

    -

    Returns the converse of the binary relation BinRel1.

    1> R1 = sofs:relation([{1,a},{2,b},{3,a}]),
    -R2 = sofs:converse(R1),
    -sofs:to_external(R2).
    -[{a,1},{a,3},{b,2}]
    +

    Returns the converse of the binary relation BinRel1.

    1> R1 = sofs:relation([{1,a},{2,b},{3,a}]),
    +R2 = sofs:converse(R1),
    +sofs:to_external(R2).
    +[{a,1},{a,3},{b,2}]
    @@ -2052,10 +2052,10 @@

    domain(BinRel)

    -

    Returns the domain of the binary relation BinRel.

    1> R = sofs:relation([{1,a},{1,b},{2,b},{2,c}]),
    -S = sofs:domain(R),
    -sofs:to_external(S).
    -[1,2]
    +

    Returns the domain of the binary relation BinRel.

    1> R = sofs:relation([{1,a},{1,b},{2,b},{2,c}]),
    +S = sofs:domain(R),
    +sofs:to_external(S).
    +[1,2]
    @@ -2085,11 +2085,11 @@

    drestriction(BinRel1, Set)

    Returns the difference between the binary relation BinRel1 and the -restriction of BinRel1 to Set.

    1> R1 = sofs:relation([{1,a},{2,b},{3,c}]),
    -S = sofs:set([2,4,6]),
    -R2 = sofs:drestriction(R1, S),
    -sofs:to_external(R2).
    -[{1,a},{3,c}]

    drestriction(R, S) is equivalent to +restriction of BinRel1 to Set.

    1> R1 = sofs:relation([{1,a},{2,b},{3,c}]),
    +S = sofs:set([2,4,6]),
    +R2 = sofs:drestriction(R1, S),
    +sofs:to_external(R2).
    +[{1,a},{3,c}]

    drestriction(R, S) is equivalent to difference(R, restriction(R, S)).

    @@ -2120,12 +2120,12 @@

    drestriction(SetFun, Set1, Set2)

    Returns a subset of Set1 containing those elements that do not give an element -in Set2 as the result of applying SetFun.

    1> SetFun = {external, fun({_A,B,C}) -> {B,C} end},
    -R1 = sofs:relation([{a,aa,1},{b,bb,2},{c,cc,3}]),
    -R2 = sofs:relation([{bb,2},{cc,3},{dd,4}]),
    -R3 = sofs:drestriction(SetFun, R1, R2),
    -sofs:to_external(R3).
    -[{a,aa,1}]

    drestriction(F, S1, S2) is equivalent to +in Set2 as the result of applying SetFun.

    1> SetFun = {external, fun({_A,B,C}) -> {B,C} end},
    +R1 = sofs:relation([{a,aa,1},{b,bb,2},{c,cc,3}]),
    +R2 = sofs:relation([{bb,2},{cc,3},{dd,4}]),
    +R3 = sofs:drestriction(SetFun, R1, R2),
    +sofs:to_external(R3).
    +[{a,aa,1}]

    drestriction(F, S1, S2) is equivalent to difference(S1, restriction(F, S1, S2)).

    @@ -2190,12 +2190,12 @@

    extension(BinRel1, Set, AnySet)

    Returns the extension of BinRel1 such that for each element E in Set that does not belong to the domain of -BinRel1, BinRel2 contains the pair (E, AnySet).

    1> S = sofs:set([b,c]),
    -A = sofs:empty_set(),
    -R = sofs:family([{a,[1,2]},{b,[3]}]),
    -X = sofs:extension(R, S, A),
    -sofs:to_external(X).
    -[{a,[1,2]},{b,[3]},{c,[]}]
    +BinRel1, BinRel2 contains the pair (E, AnySet).

    1> S = sofs:set([b,c]),
    +A = sofs:empty_set(),
    +R = sofs:family([{a,[1,2]},{b,[3]}]),
    +X = sofs:extension(R, S, A),
    +sofs:to_external(X).
    +[{a,[1,2]},{b,[3]},{c,[]}]
    @@ -2284,11 +2284,11 @@

    family_difference(Family1, Family2)

    If Family1 and Family2 are families, then Family3 is the family such that the index set is equal to the index set of Family1, and Family3[i] is the difference between Family1[i] and Family2[i] if -Family2 maps i, otherwise Family1[i].

    1> F1 = sofs:family([{a,[1,2]},{b,[3,4]}]),
    -F2 = sofs:family([{b,[4,5]},{c,[6,7]}]),
    -F3 = sofs:family_difference(F1, F2),
    -sofs:to_external(F3).
    -[{a,[1,2]},{b,[3]}]
    +Family2 maps i, otherwise Family1[i].

    1> F1 = sofs:family([{a,[1,2]},{b,[3,4]}]),
    +F2 = sofs:family([{b,[4,5]},{c,[6,7]}]),
    +F3 = sofs:family_difference(F1, F2),
    +sofs:to_external(F3).
    +[{a,[1,2]},{b,[3]}]
    @@ -2319,10 +2319,10 @@

    family_domain(Family1)

    If Family1 is a family and Family1[i] is a binary relation for every i in the index set of Family1, then Family2 is the family with the same index set as Family1 such that Family2[i] is the -domain of Family1[i].

    1> FR = sofs:from_term([{a,[{1,a},{2,b},{3,c}]},{b,[]},{c,[{4,d},{5,e}]}]),
    -F = sofs:family_domain(FR),
    -sofs:to_external(F).
    -[{a,[1,2,3]},{b,[]},{c,[4,5]}]
    +domain of Family1[i].

    1> FR = sofs:from_term([{a,[{1,a},{2,b},{3,c}]},{b,[]},{c,[{4,d},{5,e}]}]),
    +F = sofs:family_domain(FR),
    +sofs:to_external(F).
    +[{a,[1,2,3]},{b,[]},{c,[4,5]}]
    @@ -2353,10 +2353,10 @@

    family_field(Family1)

    If Family1 is a family and Family1[i] is a binary relation for every i in the index set of Family1, then Family2 is the family with the same index set as Family1 such that Family2[i] is the -field of Family1[i].

    1> FR = sofs:from_term([{a,[{1,a},{2,b},{3,c}]},{b,[]},{c,[{4,d},{5,e}]}]),
    -F = sofs:family_field(FR),
    -sofs:to_external(F).
    -[{a,[1,2,3,a,b,c]},{b,[]},{c,[4,5,d,e]}]

    family_field(Family1) is equivalent to +field of Family1[i].

    1> FR = sofs:from_term([{a,[{1,a},{2,b},{3,c}]},{b,[]},{c,[{4,d},{5,e}]}]),
    +F = sofs:family_field(FR),
    +sofs:to_external(F).
    +[{a,[1,2,3,a,b,c]},{b,[]},{c,[4,5,d,e]}]

    family_field(Family1) is equivalent to family_union(family_domain(Family1), family_range(Family1)).

    @@ -2389,10 +2389,10 @@

    family_intersection(Family1)

    for every i in the index set of Family1, then Family2 is the family with the same index set as Family1 such that Family2[i] is the intersection of Family1[i].

    If Family1[i] is an empty set for some i, the process exits with a badarg -message.

    1> F1 = sofs:from_term([{a,[[1,2,3],[2,3,4]]},{b,[[x,y,z],[x,y]]}]),
    -F2 = sofs:family_intersection(F1),
    -sofs:to_external(F2).
    -[{a,[2,3]},{b,[x,y]}]
    +message.

    1> F1 = sofs:from_term([{a,[[1,2,3],[2,3,4]]},{b,[[x,y,z],[x,y]]}]),
    +F2 = sofs:family_intersection(F1),
    +sofs:to_external(F2).
    +[{a,[2,3]},{b,[x,y]}]
    @@ -2424,11 +2424,11 @@

    family_intersection(Family1, Family2)

    If Family1 and Family2 are families, then Family3 is the family such that the index set is the intersection of Family1:s and Family2:s index sets, and Family3[i] is the intersection of Family1[i] -and Family2[i].

    1> F1 = sofs:family([{a,[1,2]},{b,[3,4]},{c,[5,6]}]),
    -F2 = sofs:family([{b,[4,5]},{c,[7,8]},{d,[9,10]}]),
    -F3 = sofs:family_intersection(F1, F2),
    -sofs:to_external(F3).
    -[{b,[4]},{c,[]}]
    +and Family2[i].

    1> F1 = sofs:family([{a,[1,2]},{b,[3,4]},{c,[5,6]}]),
    +F2 = sofs:family([{b,[4,5]},{c,[7,8]},{d,[9,10]}]),
    +F3 = sofs:family_intersection(F1, F2),
    +sofs:to_external(F3).
    +[{b,[4]},{c,[]}]
    @@ -2459,10 +2459,10 @@

    family_projection(SetFun, Family1)

    If Family1 is a family, then Family2 is the family with the same index set as Family1 such that Family2[i] is the result of calling -SetFun with Family1[i] as argument.

    1> F1 = sofs:from_term([{a,[[1,2],[2,3]]},{b,[[]]}]),
    -F2 = sofs:family_projection(fun sofs:union/1, F1),
    -sofs:to_external(F2).
    -[{a,[1,2,3]},{b,[]}]
    +SetFun with Family1[i] as argument.

    1> F1 = sofs:from_term([{a,[[1,2],[2,3]]},{b,[[]]}]),
    +F2 = sofs:family_projection(fun sofs:union/1, F1),
    +sofs:to_external(F2).
    +[{a,[1,2,3]},{b,[]}]
    @@ -2493,10 +2493,10 @@

    family_range(Family1)

    If Family1 is a family and Family1[i] is a binary relation for every i in the index set of Family1, then Family2 is the family with the same index set as Family1 such that Family2[i] is the -range of Family1[i].

    1> FR = sofs:from_term([{a,[{1,a},{2,b},{3,c}]},{b,[]},{c,[{4,d},{5,e}]}]),
    -F = sofs:family_range(FR),
    -sofs:to_external(F).
    -[{a,[a,b,c]},{b,[]},{c,[d,e]}]
    +range of Family1[i].

    1> FR = sofs:from_term([{a,[{1,a},{2,b},{3,c}]},{b,[]},{c,[{4,d},{5,e}]}]),
    +F = sofs:family_range(FR),
    +sofs:to_external(F).
    +[{a,[a,b,c]},{b,[]},{c,[d,e]}]
    @@ -2530,11 +2530,11 @@

    family_specification(Fun, Family1)

    index set for which Fun applied to Family1[i] returns true. If Fun is a tuple {external, Fun2}, then Fun2 is applied to the external set of Family1[i], otherwise Fun is -applied to Family1[i].

    1> F1 = sofs:family([{a,[1,2,3]},{b,[1,2]},{c,[1]}]),
    -SpecFun = fun(S) -> sofs:no_elements(S) =:= 2 end,
    -F2 = sofs:family_specification(SpecFun, F1),
    -sofs:to_external(F2).
    -[{b,[1,2]}]
    +applied to Family1[i].

    1> F1 = sofs:family([{a,[1,2,3]},{b,[1,2]},{c,[1]}]),
    +SpecFun = fun(S) -> sofs:no_elements(S) =:= 2 end,
    +F2 = sofs:family_specification(SpecFun, F1),
    +sofs:to_external(F2).
    +[{b,[1,2]}]
    @@ -2629,10 +2629,10 @@

    family_to_relation(Family)

    If Family is a family, then BinRel is the binary relation containing all pairs (i, x) such that i belongs to the index set of Family and -x belongs to Family[i].

    1> F = sofs:family([{a,[]}, {b,[1]}, {c,[2,3]}]),
    -R = sofs:family_to_relation(F),
    -sofs:to_external(R).
    -[{b,1},{c,2},{c,3}]
    +x belongs to Family[i].

    1> F = sofs:family([{a,[]}, {b,[1]}, {c,[2,3]}]),
    +R = sofs:family_to_relation(F),
    +sofs:to_external(R).
    +[{b,1},{c,2},{c,3}]
    @@ -2663,10 +2663,10 @@

    family_union(Family1)

    If Family1 is a family and Family1[i] is a set of sets for each i in the index set of Family1, then Family2 is the family with the same index set as Family1 such that Family2[i] is the -union of Family1[i].

    1> F1 = sofs:from_term([{a,[[1,2],[2,3]]},{b,[[]]}]),
    -F2 = sofs:family_union(F1),
    -sofs:to_external(F2).
    -[{a,[1,2,3]},{b,[]}]

    family_union(F) is equivalent to +union of Family1[i].

    1> F1 = sofs:from_term([{a,[[1,2],[2,3]]},{b,[[]]}]),
    +F2 = sofs:family_union(F1),
    +sofs:to_external(F2).
    +[{a,[1,2,3]},{b,[]}]

    family_union(F) is equivalent to family_projection(fun sofs:union/1, F).

    @@ -2699,11 +2699,11 @@

    family_union(Family1, Family2)

    If Family1 and Family2 are families, then Family3 is the family such that the index set is the union of Family1:s and Family2:s index sets, and Family3[i] is the union of Family1[i] and Family2[i] if -both map i, otherwise Family1[i] or Family2[i].

    1> F1 = sofs:family([{a,[1,2]},{b,[3,4]},{c,[5,6]}]),
    -F2 = sofs:family([{b,[4,5]},{c,[7,8]},{d,[9,10]}]),
    -F3 = sofs:family_union(F1, F2),
    -sofs:to_external(F3).
    -[{a,[1,2]},{b,[3,4,5]},{c,[5,6,7,8]},{d,[9,10]}]
    +both map i, otherwise Family1[i] or Family2[i].

    1> F1 = sofs:family([{a,[1,2]},{b,[3,4]},{c,[5,6]}]),
    +F2 = sofs:family([{b,[4,5]},{c,[7,8]},{d,[9,10]}]),
    +F3 = sofs:family_union(F1, F2),
    +sofs:to_external(F3).
    +[{a,[1,2]},{b,[3,4,5]},{c,[5,6,7,8]},{d,[9,10]}]
    @@ -2731,10 +2731,10 @@

    field(BinRel)

    -

    Returns the field of the binary relation BinRel.

    1> R = sofs:relation([{1,a},{1,b},{2,b},{2,c}]),
    -S = sofs:field(R),
    -sofs:to_external(S).
    -[1,2,a,b,c]

    field(R) is equivalent to +

    Returns the field of the binary relation BinRel.

    1> R = sofs:relation([{1,a},{1,b},{2,b},{2,c}]),
    +S = sofs:field(R),
    +sofs:to_external(S).
    +[1,2,a,b,c]

    field(R) is equivalent to union(domain(R), range(R)).

    @@ -2796,11 +2796,11 @@

    from_sets/1

    Returns the unordered set containing the sets of -list ListOfSets.

    1> S1 = sofs:relation([{a,1},{b,2}]),
    -S2 = sofs:relation([{x,3},{y,4}]),
    -S = sofs:from_sets([S1,S2]),
    -sofs:to_external(S).
    -[[{a,1},{b,2}],[{x,3},{y,4}]]

    Returns the ordered set containing the sets of the +list ListOfSets.

    1> S1 = sofs:relation([{a,1},{b,2}]),
    +S2 = sofs:relation([{x,3},{y,4}]),
    +S = sofs:from_sets([S1,S2]),
    +sofs:to_external(S).
    +[[{a,1},{b,2}],[{x,3},{y,4}]]

    Returns the ordered set containing the sets of the non-empty tuple TupleOfSets.

    @@ -2861,22 +2861,22 @@

    from_term(Term, Type)

    traversing term Term, sorting lists, removing duplicates, and deriving or verifying a valid type for the so obtained external set.

    An explicitly specified type Type can be used to limit the depth of the traversal; an atomic type stops the traversal, as shown by the -following example where "foo" and {"foo"} are left unmodified:

    1> S = sofs:from_term([{{"foo"},[1,1]},{"foo",[2,2]}],
    -                      [{atom,[atom]}]),
    -   sofs:to_external(S).
    -[{{"foo"},[1]},{"foo",[2]}]

    from_term can be used for creating atomic or ordered sets. The only purpose of +following example where "foo" and {"foo"} are left unmodified:

    1> S = sofs:from_term([{{"foo"},[1,1]},{"foo",[2,2]}],
    +                      [{atom,[atom]}]),
    +   sofs:to_external(S).
    +[{{"foo"},[1]},{"foo",[2]}]

    from_term can be used for creating atomic or ordered sets. The only purpose of such a set is that of later building unordered sets, as all functions in this module that do anything operate on unordered sets. Creating unordered sets from a collection of ordered sets can be the way to go if the ordered sets are big and one does not want to waste heap by rebuilding the elements of the unordered set. The following example shows that a set can be built "layer by -layer":

    1> A = sofs:from_term(a),
    -S = sofs:set([1,2,3]),
    -P1 = sofs:from_sets({A,S}),
    -P2 = sofs:from_term({b,[6,5,4]}),
    -Ss = sofs:from_sets([P1,P2]),
    -sofs:to_external(Ss).
    -[{a,[1,2,3]},{b,[4,5,6]}]

    Other functions that create sets are from_external/2 and from_sets/1. +layer":

    1> A = sofs:from_term(a),
    +S = sofs:set([1,2,3]),
    +P1 = sofs:from_sets({A,S}),
    +P2 = sofs:from_term({b,[6,5,4]}),
    +Ss = sofs:from_sets([P1,P2]),
    +sofs:to_external(Ss).
    +[{a,[1,2,3]},{b,[4,5,6]}]

    Other functions that create sets are from_external/2 and from_sets/1. Special cases of from_term/2 are a_function/1,2, empty_set/0, family/1,2, relation/1,2, and set/1,2.

    @@ -2908,11 +2908,11 @@

    image(BinRel, Set1)

    Returns the image of set Set1 under the binary relation -BinRel.

    1> R = sofs:relation([{1,a},{2,b},{2,c},{3,d}]),
    -S1 = sofs:set([1,2]),
    -S2 = sofs:image(R, S1),
    -sofs:to_external(S2).
    -[a,b,c]
    +BinRel.

    1> R = sofs:relation([{1,a},{2,b},{2,c},{3,d}]),
    +S1 = sofs:set([1,2]),
    +S2 = sofs:image(R, S1),
    +sofs:to_external(S2).
    +[a,b,c]
    @@ -2997,10 +2997,10 @@

    intersection_of_family(Family)

    -

    Returns the intersection of family Family.

    Intersecting an empty family exits the process with a badarg message.

    1> F = sofs:family([{a,[0,2,4]},{b,[0,1,2]},{c,[2,3]}]),
    -S = sofs:intersection_of_family(F),
    -sofs:to_external(S).
    -[2]
    +

    Returns the intersection of family Family.

    Intersecting an empty family exits the process with a badarg message.

    1> F = sofs:family([{a,[0,2,4]},{b,[0,1,2]},{c,[2,3]}]),
    +S = sofs:intersection_of_family(F),
    +sofs:to_external(S).
    +[2]
    @@ -3028,10 +3028,10 @@

    inverse(Function1)

    -

    Returns the inverse of function Function1.

    1> R1 = sofs:relation([{1,a},{2,b},{3,c}]),
    -R2 = sofs:inverse(R1),
    -sofs:to_external(R2).
    -[{a,1},{b,2},{c,3}]
    +

    Returns the inverse of function Function1.

    1> R1 = sofs:relation([{1,a},{2,b},{3,c}]),
    +R2 = sofs:inverse(R1),
    +sofs:to_external(R2).
    +[{a,1},{b,2},{c,3}]
    @@ -3061,11 +3061,11 @@

    inverse_image(BinRel, Set1)

    Returns the inverse image of Set1 under the binary -relation BinRel.

    1> R = sofs:relation([{1,a},{2,b},{2,c},{3,d}]),
    -S1 = sofs:set([c,d,e]),
    -S2 = sofs:inverse_image(R, S1),
    -sofs:to_external(S2).
    -[2,3]
    +relation BinRel.

    1> R = sofs:relation([{1,a},{2,b},{2,c},{3,d}]),
    +S1 = sofs:set([c,d,e]),
    +S2 = sofs:inverse_image(R, S1),
    +sofs:to_external(S2).
    +[2,3]
    @@ -3182,9 +3182,9 @@

    is_equal(AnySet1, AnySet2)

    Returns true if AnySet1 and AnySet2 are equal, otherwise false. The following example shows that ==/2 is used when comparing sets for -equality:

    1> S1 = sofs:set([1.0]),
    -S2 = sofs:set([1]),
    -sofs:is_equal(S1, S2).
    +equality:

    1> S1 = sofs:set([1.0]),
    +S2 = sofs:set([1]),
    +sofs:is_equal(S1, S2).
     true
    @@ -3341,11 +3341,11 @@

    join(Relation1, I, Relation2, J)

    Returns the natural join of the relations Relation1 -and Relation2 on coordinates I and J.

    1> R1 = sofs:relation([{a,x,1},{b,y,2}]),
    -R2 = sofs:relation([{1,f,g},{1,h,i},{2,3,4}]),
    -J = sofs:join(R1, 3, R2, 1),
    -sofs:to_external(J).
    -[{a,x,1,f,g},{a,x,1,h,i},{b,y,2,3,4}]
    +and Relation2 on coordinates I and J.

    1> R1 = sofs:relation([{a,x,1},{b,y,2}]),
    +R2 = sofs:relation([{1,f,g},{1,h,i},{2,3,4}]),
    +J = sofs:join(R1, 3, R2, 1),
    +sofs:to_external(J).
    +[{a,x,1,f,g},{a,x,1,h,i},{b,y,2,3,4}]
    @@ -3381,11 +3381,11 @@

    multiple_relative_product(TupleOfBinRels, B

    If TupleOfBinRels is a non-empty tuple {R[1], ..., R[n]} of binary relations and BinRel1 is a binary relation, then BinRel2 is the multiple relative product of the ordered -set (R[i], ..., R[n]) and BinRel1.

    1> Ri = sofs:relation([{a,1},{b,2},{c,3}]),
    -R = sofs:relation([{a,b},{b,c},{c,a}]),
    -MP = sofs:multiple_relative_product({Ri, Ri}, R),
    -sofs:to_external(sofs:range(MP)).
    -[{1,2},{2,3},{3,1}]
    +set (R[i], ..., R[n]) and BinRel1.

    1> Ri = sofs:relation([{a,1},{b,2},{c,3}]),
    +R = sofs:relation([{a,b},{b,c},{c,a}]),
    +MP = sofs:multiple_relative_product({Ri, Ri}, R),
    +sofs:to_external(sofs:range(MP)).
    +[{1,2},{2,3},{3,1}]

    @@ -3443,11 +3443,11 @@

    partition(SetOfSets)

    Returns the partition of the union of the set of sets SetOfSets such that two elements are considered equal if they belong to the -same elements of SetOfSets.

    1> Sets1 = sofs:from_term([[a,b,c],[d,e,f],[g,h,i]]),
    -Sets2 = sofs:from_term([[b,c,d],[e,f,g],[h,i,j]]),
    -P = sofs:partition(sofs:union(Sets1, Sets2)),
    -sofs:to_external(P).
    -[[a],[b,c],[d],[e,f],[g],[h,i],[j]]
    +same elements of SetOfSets.

    1> Sets1 = sofs:from_term([[a,b,c],[d,e,f],[g,h,i]]),
    +Sets2 = sofs:from_term([[b,c,d],[e,f,g],[h,i,j]]),
    +P = sofs:partition(sofs:union(Sets1, Sets2)),
    +sofs:to_external(P).
    +[[a],[b,c],[d],[e,f],[g],[h,i],[j]]
    @@ -3476,11 +3476,11 @@

    partition(SetFun, Set)

    Returns the partition of Set such that two elements are -considered equal if the results of applying SetFun are equal.

    1> Ss = sofs:from_term([[a],[b],[c,d],[e,f]]),
    -SetFun = fun(S) -> sofs:from_term(sofs:no_elements(S)) end,
    -P = sofs:partition(SetFun, Ss),
    -sofs:to_external(P).
    -[[[a],[b]],[[c,d],[e,f]]]
    +considered equal if the results of applying SetFun are equal.

    1> Ss = sofs:from_term([[a],[b],[c,d],[e,f]]),
    +SetFun = fun(S) -> sofs:from_term(sofs:no_elements(S)) end,
    +P = sofs:partition(SetFun, Ss),
    +sofs:to_external(P).
    +[[[a],[b]],[[c,d],[e,f]]]
    @@ -3517,11 +3517,11 @@

    partition(SetFun, Set1, Set2)

    Returns a pair of sets that, regarded as constituting a set, forms a partition of Set1. If the result of applying SetFun to an element of Set1 gives an element in Set2, the element belongs to Set3, -otherwise the element belongs to Set4.

    1> R1 = sofs:relation([{1,a},{2,b},{3,c}]),
    -S = sofs:set([2,4,6]),
    -{R2,R3} = sofs:partition(1, R1, S),
    -{sofs:to_external(R2),sofs:to_external(R3)}.
    -{[{2,b}],[{1,a},{3,c}]}

    partition(F, S1, S2) is equivalent to +otherwise the element belongs to Set4.

    1> R1 = sofs:relation([{1,a},{2,b},{3,c}]),
    +S = sofs:set([2,4,6]),
    +{R2,R3} = sofs:partition(1, R1, S),
    +{sofs:to_external(R2),sofs:to_external(R3)}.
    +{[{2,b}],[{1,a},{3,c}]}

    partition(F, S1, S2) is equivalent to {restriction(F, S1, S2), drestriction(F, S1, S2)}.

    @@ -3555,11 +3555,11 @@

    partition_family(SetFun, Set)

    partition of Set such that two elements are considered equal if the results of applying SetFun are the same value i. This i is the index that Family maps onto the -equivalence class.

    1> S = sofs:relation([{a,a,a,a},{a,a,b,b},{a,b,b,b}]),
    -SetFun = {external, fun({A,_,C,_}) -> {A,C} end},
    -F = sofs:partition_family(SetFun, S),
    -sofs:to_external(F).
    -[{{a,a},[{a,a,a,a}]},{{a,b},[{a,a,b,b},{a,b,b,b}]}]
    +equivalence class.

    1> S = sofs:relation([{a,a,a,a},{a,a,b,b},{a,b,b,b}]),
    +SetFun = {external, fun({A,_,C,_}) -> {A,C} end},
    +F = sofs:partition_family(SetFun, S),
    +sofs:to_external(F).
    +[{{a,a},[{a,a,a,a}]},{{a,b},[{a,a,b,b},{a,b,b,b}]}]
    @@ -3590,12 +3590,12 @@

    product(TupleOfSets)

    Returns the Cartesian product of the non-empty tuple of sets TupleOfSets. If (x[1], ..., x[n]) is an element of the n-ary relation Relation, then x[i] is drawn from element i of -TupleOfSets.

    1> S1 = sofs:set([a,b]),
    -S2 = sofs:set([1,2]),
    -S3 = sofs:set([x,y]),
    -P3 = sofs:product({S1,S2,S3}),
    -sofs:to_external(P3).
    -[{a,1,x},{a,1,y},{a,2,x},{a,2,y},{b,1,x},{b,1,y},{b,2,x},{b,2,y}]
    +TupleOfSets.

    1> S1 = sofs:set([a,b]),
    +S2 = sofs:set([1,2]),
    +S3 = sofs:set([x,y]),
    +P3 = sofs:product({S1,S2,S3}),
    +sofs:to_external(P3).
    +[{a,1,x},{a,1,y},{a,2,x},{a,2,y},{b,1,x},{b,1,y},{b,2,x},{b,2,y}]
    @@ -3624,11 +3624,11 @@

    product(Set1, Set2)

    Returns the Cartesian product of Set1 and -Set2.

    1> S1 = sofs:set([1,2]),
    -S2 = sofs:set([a,b]),
    -R = sofs:product(S1, S2),
    -sofs:to_external(R).
    -[{1,a},{1,b},{2,a},{2,b}]

    product(S1, S2) is equivalent to +Set2.

    1> S1 = sofs:set([1,2]),
    +S2 = sofs:set([a,b]),
    +R = sofs:product(S1, S2),
    +sofs:to_external(R).
    +[{1,a},{1,b},{2,a},{2,b}]

    product(S1, S2) is equivalent to product({S1, S2}).

    @@ -3659,10 +3659,10 @@

    projection(SetFun, Set1)

    Returns the set created by substituting each element of Set1 by the result of applying SetFun to the element.

    If SetFun is a number i >= 1 and Set1 is a relation, then the returned set -is the projection of Set1 onto coordinate i.

    1> S1 = sofs:from_term([{1,a},{2,b},{3,a}]),
    -S2 = sofs:projection(2, S1),
    -sofs:to_external(S2).
    -[a,b]
    +is the projection of Set1 onto coordinate i.

    1> S1 = sofs:from_term([{1,a},{2,b},{3,a}]),
    +S2 = sofs:projection(2, S1),
    +sofs:to_external(S2).
    +[a,b]
    @@ -3690,10 +3690,10 @@

    range(BinRel)

    -

    Returns the range of the binary relation BinRel.

    1> R = sofs:relation([{1,a},{1,b},{2,b},{2,c}]),
    -S = sofs:range(R),
    -sofs:to_external(S).
    -[a,b,c]
    +

    Returns the range of the binary relation BinRel.

    1> R = sofs:relation([{1,a},{1,b},{2,b},{2,c}]),
    +S = sofs:range(R),
    +sofs:to_external(S).
    +[a,b,c]
    @@ -3784,10 +3784,10 @@

    relation_to_family(BinRel)

    Returns family Family such that the index set is equal to the domain of the binary relation BinRel, and Family[i] -is the image of the set of i under BinRel.

    1> R = sofs:relation([{b,1},{c,2},{c,3}]),
    -F = sofs:relation_to_family(R),
    -sofs:to_external(F).
    -[{b,[1]},{c,[2,3]}]
    +is the image of the set of i under BinRel.

    1> R = sofs:relation([{b,1},{c,2},{c,3}]),
    +F = sofs:relation_to_family(R),
    +sofs:to_external(F).
    +[{b,[1]},{c,[2,3]}]
    @@ -3821,11 +3821,11 @@

    relative_product1(BinRel1, BinRel2)

    Returns the relative product of the converse of the binary relation BinRel1 and the binary -relation BinRel2.

    1> R1 = sofs:relation([{1,a},{1,aa},{2,b}]),
    -R2 = sofs:relation([{1,u},{2,v},{3,c}]),
    -R3 = sofs:relative_product1(R1, R2),
    -sofs:to_external(R3).
    -[{a,u},{aa,u},{b,v}]

    relative_product1(R1, R2) is equivalent to +relation BinRel2.

    1> R1 = sofs:relation([{1,a},{1,aa},{2,b}]),
    +R2 = sofs:relation([{1,u},{2,v},{3,c}]),
    +R3 = sofs:relative_product1(R1, R2),
    +sofs:to_external(R3).
    +[{a,u},{aa,u},{b,v}]

    relative_product1(R1, R2) is equivalent to relative_product(converse(R1), R2).

    @@ -3902,11 +3902,11 @@

    relative_product/2

    (R[i], ..., R[n]) and BinRel1.

    If BinRel1 is omitted, the relation of equality between the elements of the Cartesian product of the ranges of R[i], range R[1] × ... × range R[n], is used instead (intuitively, nothing is -"lost").

    1> TR = sofs:relation([{1,a},{1,aa},{2,b}]),
    -R1 = sofs:relation([{1,u},{2,v},{3,c}]),
    -R2 = sofs:relative_product([TR, R1]),
    -sofs:to_external(R2).
    -[{1,{a,u}},{1,{aa,u}},{2,{b,v}}]

    Notice that relative_product([R1], R2) is different +"lost").

    1> TR = sofs:relation([{1,a},{1,aa},{2,b}]),
    +R1 = sofs:relation([{1,u},{2,v},{3,c}]),
    +R2 = sofs:relative_product([TR, R1]),
    +sofs:to_external(R2).
    +[{1,{a,u}},{1,{aa,u}},{2,{b,v}}]

    Notice that relative_product([R1], R2) is different from relative_product(R1, R2); the list of one element is not identified with the element itself.

    Returns the relative product of the binary relations BinRel1 and BinRel2.

    @@ -3939,11 +3939,11 @@

    restriction(BinRel1, Set)

    Returns the restriction of the binary relation BinRel1 -to Set.

    1> R1 = sofs:relation([{1,a},{2,b},{3,c}]),
    -S = sofs:set([1,2,4]),
    -R2 = sofs:restriction(R1, S),
    -sofs:to_external(R2).
    -[{1,a},{2,b}]
    +to Set.

    1> R1 = sofs:relation([{1,a},{2,b},{3,c}]),
    +S = sofs:set([1,2,4]),
    +R2 = sofs:restriction(R1, S),
    +sofs:to_external(R2).
    +[{1,a},{2,b}]
    @@ -3973,11 +3973,11 @@

    restriction(SetFun, Set1, Set2)

    Returns a subset of Set1 containing those elements that gives an element in -Set2 as the result of applying SetFun.

    1> S1 = sofs:relation([{1,a},{2,b},{3,c}]),
    -S2 = sofs:set([b,c,d]),
    -S3 = sofs:restriction(2, S1, S2),
    -sofs:to_external(S3).
    -[{2,b},{3,c}]
    +Set2 as the result of applying SetFun.

    1> S1 = sofs:relation([{1,a},{2,b},{3,c}]),
    +S2 = sofs:set([b,c,d]),
    +S3 = sofs:restriction(2, S1, S2),
    +sofs:to_external(S3).
    +[{2,b},{3,c}]
    @@ -4066,12 +4066,12 @@

    specification(Fun, Set1)

    Returns the set containing every element of Set1 for which Fun returns true. If Fun is a tuple {external, Fun2}, Fun2 is applied to the external set of each element, otherwise Fun is -applied to each element.

    1> R1 = sofs:relation([{a,1},{b,2}]),
    -R2 = sofs:relation([{x,1},{x,2},{y,3}]),
    -S1 = sofs:from_sets([R1,R2]),
    -S2 = sofs:specification(fun sofs:is_a_function/1, S1),
    -sofs:to_external(S2).
    -[[{a,1},{b,2}]]
    +applied to each element.

    1> R1 = sofs:relation([{a,1},{b,2}]),
    +R2 = sofs:relation([{x,1},{x,2},{y,3}]),
    +S1 = sofs:from_sets([R1,R2]),
    +S2 = sofs:specification(fun sofs:is_a_function/1, S1),
    +sofs:to_external(S2).
    +[[{a,1},{b,2}]]
    @@ -4101,10 +4101,10 @@

    strict_relation(BinRel1)

    Returns the strict relation corresponding to the -binary relation BinRel1.

    1> R1 = sofs:relation([{1,1},{1,2},{2,1},{2,2}]),
    -R2 = sofs:strict_relation(R1),
    -sofs:to_external(R2).
    -[{1,2},{2,1}]
    +binary relation BinRel1.

    1> R1 = sofs:relation([{1,1},{1,2},{2,1},{2,2}]),
    +R2 = sofs:strict_relation(R1),
    +sofs:to_external(R2).
    +[{1,2},{2,1}]
    @@ -4133,29 +4133,29 @@

    substitution(SetFun, Set1)

    Returns a function, the domain of which is Set1. The value of an element of -the domain is the result of applying SetFun to the element.

    1> L = [{a,1},{b,2}].
    -[{a,1},{b,2}]
    -2> sofs:to_external(sofs:projection(1,sofs:relation(L))).
    -[a,b]
    -3> sofs:to_external(sofs:substitution(1,sofs:relation(L))).
    -[{{a,1},a},{{b,2},b}]
    -4> SetFun = {external, fun({A,_}=E) -> {E,A} end},
    -sofs:to_external(sofs:projection(SetFun,sofs:relation(L))).
    -[{{a,1},a},{{b,2},b}]

    The relation of equality between the elements of {a,b,c}:

    1> I = sofs:substitution(fun(A) -> A end, sofs:set([a,b,c])),
    -sofs:to_external(I).
    -[{a,a},{b,b},{c,c}]

    Let SetOfSets be a set of sets and BinRel a binary relation. The function +the domain is the result of applying SetFun to the element.

    1> L = [{a,1},{b,2}].
    +[{a,1},{b,2}]
    +2> sofs:to_external(sofs:projection(1,sofs:relation(L))).
    +[a,b]
    +3> sofs:to_external(sofs:substitution(1,sofs:relation(L))).
    +[{{a,1},a},{{b,2},b}]
    +4> SetFun = {external, fun({A,_}=E) -> {E,A} end},
    +sofs:to_external(sofs:projection(SetFun,sofs:relation(L))).
    +[{{a,1},a},{{b,2},b}]

    The relation of equality between the elements of {a,b,c}:

    1> I = sofs:substitution(fun(A) -> A end, sofs:set([a,b,c])),
    +sofs:to_external(I).
    +[{a,a},{b,b},{c,c}]

    Let SetOfSets be a set of sets and BinRel a binary relation. The function that maps each element Set of SetOfSets onto the image of -Set under BinRel is returned by the following function:

    images(SetOfSets, BinRel) ->
    -   Fun = fun(Set) -> sofs:image(BinRel, Set) end,
    -   sofs:substitution(Fun, SetOfSets).

    External unordered sets are represented as sorted lists. So, creating the image +Set under BinRel is returned by the following function:

    images(SetOfSets, BinRel) ->
    +   Fun = fun(Set) -> sofs:image(BinRel, Set) end,
    +   sofs:substitution(Fun, SetOfSets).

    External unordered sets are represented as sorted lists. So, creating the image of a set under a relation R can traverse all elements of R (to that comes the sorting of results, the image). In image/2, BinRel is traversed once for each element of SetOfSets, which can take too long. The following efficient function can be used instead under the assumption that the image of each element -of SetOfSets under BinRel is non-empty:

    images2(SetOfSets, BinRel) ->
    -   CR = sofs:canonical_relation(SetOfSets),
    -   R = sofs:relative_product1(CR, BinRel),
    -   sofs:relation_to_family(R).
    +of SetOfSets under BinRel is non-empty:

    images2(SetOfSets, BinRel) ->
    +   CR = sofs:canonical_relation(SetOfSets),
    +   R = sofs:relative_product1(CR, BinRel),
    +   sofs:relation_to_family(R).
    @@ -4184,11 +4184,11 @@

    symdiff(Set1, Set2)

    Returns the symmetric difference (or the -Boolean sum) of Set1 and Set2.

    1> S1 = sofs:set([1,2,3]),
    -S2 = sofs:set([2,3,4]),
    -P = sofs:symdiff(S1, S2),
    -sofs:to_external(P).
    -[1,4]
    +Boolean sum) of Set1 and Set2.

    1> S1 = sofs:set([1,2,3]),
    +S2 = sofs:set([2,3,4]),
    +P = sofs:symdiff(S1, S2),
    +sofs:to_external(P).
    +[1,4]
    @@ -4395,10 +4395,10 @@

    union_of_family(Family)

    -

    Returns the union of family Family.

    1> F = sofs:family([{a,[0,2,4]},{b,[0,1,2]},{c,[2,3]}]),
    -S = sofs:union_of_family(F),
    -sofs:to_external(S).
    -[0,1,2,3,4]
    +

    Returns the union of family Family.

    1> F = sofs:family([{a,[0,2,4]},{b,[0,1,2]},{c,[2,3]}]),
    +S = sofs:union_of_family(F),
    +sofs:to_external(S).
    +[0,1,2,3,4]
    @@ -4429,10 +4429,10 @@

    weak_relation(BinRel1)

    Returns a subset S of the weak relation W corresponding to the binary relation BinRel1. Let F be the field of BinRel1. The subset S is defined so that x S y if x -W y for some x in F and for some y in F.

    1> R1 = sofs:relation([{1,1},{1,2},{3,1}]),
    -R2 = sofs:weak_relation(R1),
    -sofs:to_external(R2).
    -[{1,1},{1,2},{2,2},{3,1},{3,3}]
    +W y for some x in F and for some y in F.

    1> R1 = sofs:relation([{1,1},{1,2},{3,1}]),
    +R2 = sofs:weak_relation(R1),
    +sofs:to_external(R2).
    +[{1,1},{1,2},{2,2},{3,1},{3,3}]
    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/stdlib.epub b/prs/8803/lib/stdlib-6.0.1/doc/html/stdlib.epub index 70a3534c5b0d6..59854c7e61063 100644 Binary files a/prs/8803/lib/stdlib-6.0.1/doc/html/stdlib.epub and b/prs/8803/lib/stdlib-6.0.1/doc/html/stdlib.epub differ diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/stdlib_app.html b/prs/8803/lib/stdlib-6.0.1/doc/html/stdlib_app.html index 21546a0a9eaad..c0140f99d12fe 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/stdlib_app.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/stdlib_app.html @@ -162,13 +162,13 @@

    prompt function takes the main prompt as its only parameter.

  • shell_saved_results = integer() >= 0 - Can be used to determine how many results are saved by the Erlang shell.

  • shell_session_slogan = string() | fun() -> string()) - The slogan printed when starting an Erlang shell. Example:

    $ erl -stdlib shell_session_slogan '"Test slogan"'
    -Erlang/OTP 26 [DEVELOPMENT] [erts-13.0.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]
    +Erlang/OTP 26 [DEVELOPMENT] [erts-13.0.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]
     
     Test slogan
     1>
  • shell_slogan = string() | fun(() -> string()) - The slogan printed when starting the Erlang shell subsystem. Example:

    $ erl -stdlib shell_slogan '"Test slogan"'
     Test slogan
    -Eshell V13.0.2  (abort with ^G)
    +Eshell V13.0.2  (abort with ^G)
     1>

    The default is the return value of erlang:system_info(system_version).

  • shell_strings = boolean() - Can be used to determine how the Erlang shell outputs lists of integers.

  • diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/string.html b/prs/8803/lib/stdlib-6.0.1/doc/html/string.html index 8b20e3454dc97..d3b3e98e6e209 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/string.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/string.html @@ -149,14 +149,14 @@

    expect UTF-8 binaries but not all functions verify that all binaries are encoded correctly.

    Unless otherwise specified the return value type is the same as the input type. That is, binary input returns binary output, list input returns a list output, -and mixed input can return a mixed output.

    1> string:trim("  sarah  ").
    +and mixed input can return a mixed output.

    1> string:trim("  sarah  ").
     "sarah"
    -2> string:trim(<<"  sarah  ">>).
    +2> string:trim(<<"  sarah  ">>).
     <<"sarah">>
    -3> string:lexemes("foo bar", " ").
    -["foo","bar"]
    -4> string:lexemes(<<"foo bar">>, " ").
    -[<<"foo">>,<<"bar">>]

    This module has been reworked in Erlang/OTP 20 to handle unicode:chardata/0 +3> string:lexemes("foo bar", " "). +["foo","bar"] +4> string:lexemes(<<"foo bar">>, " "). +[<<"foo">>,<<"bar">>]

    This module has been reworked in Erlang/OTP 20 to handle unicode:chardata/0 and operate on grapheme clusters. The old functions that only work on Latin-1 lists as input are still available but should not be used, they will be @@ -1072,7 +1072,7 @@

    casefold(String)

    Converts String to a case-agnostic comparable string. Function casefold/1 is preferred over lowercase/1 -when two strings are to be compared for equality. See also equal/4.

    Example:

    1> string:casefold("Ω and ẞ SHARP S").
    +when two strings are to be compared for equality. See also equal/4.

    Example:

    1> string:casefold("Ω and ẞ SHARP S").
     "ω and ss sharp s"
    @@ -1104,9 +1104,9 @@

    chomp(String)

    Returns a string where any trailing \n or \r\n have been removed from -String.

    Example:

    182> string:chomp(<<"\nHello\n\n">>).
    +String.

    Example:

    182> string:chomp(<<"\nHello\n\n">>).
     <<"\nHello">>
    -183> string:chomp("\nHello\r\r\n").
    +183> string:chomp("\nHello\r\r\n").
     "\nHello\r"
    @@ -1207,11 +1207,11 @@

    equal(A, B, IgnoreCase, Norm)

    nfc, nfd, nfkc, and -nfkd.

    Example:

    1> string:equal("åäö", <<"åäö"/utf8>>).
    +nfkd.

    Example:

    1> string:equal("åäö", <<"åäö"/utf8>>).
     true
    -2> string:equal("åäö", unicode:characters_to_nfd_binary("åäö")).
    +2> string:equal("åäö", unicode:characters_to_nfd_binary("åäö")).
     false
    -3> string:equal("åäö", unicode:characters_to_nfd_binary("ÅÄÖ"), true, nfc).
    +3> string:equal("åäö", unicode:characters_to_nfd_binary("ÅÄÖ"), true, nfc).
     true
    @@ -1277,13 +1277,13 @@

    find(String, SearchPattern, Dir)

    Removes anything before SearchPattern in String and returns the remainder of the string or nomatch if SearchPattern is not found. Dir, which can be leading or trailing, indicates from which direction characters are to be -searched.

    Example:

    1> string:find("ab..cd..ef", ".").
    +searched.

    Example:

    1> string:find("ab..cd..ef", ".").
     "..cd..ef"
    -2> string:find(<<"ab..cd..ef">>, "..", trailing).
    +2> string:find(<<"ab..cd..ef">>, "..", trailing).
     <<"..ef">>
    -3> string:find(<<"ab..cd..ef">>, "x", leading).
    +3> string:find(<<"ab..cd..ef">>, "x", leading).
     nomatch
    -4> string:find("ab..cd..ef", "x", trailing).
    +4> string:find("ab..cd..ef", "x", trailing).
     nomatch
    @@ -1314,9 +1314,9 @@

    is_empty(String)

    -

    Returns true if String is the empty string, otherwise false.

    Example:

    1> string:is_empty("foo").
    +

    Returns true if String is the empty string, otherwise false.

    Example:

    1> string:is_empty("foo").
     false
    -2> string:is_empty(["",<<>>]).
    +2> string:is_empty(["",<<>>]).
     true
    @@ -1354,13 +1354,13 @@

    jaro_similarity(String1, String2)

    Returns a float between +0.0 and 1.0 representing the Jaro similarity between the given strings. Strings with a higher similarity will score closer -to 1.0, with +0.0 meaning no similarity and 1.0 meaning an exact match.

    Example:

    1> string:jaro_similarity("ditto", "ditto").
    +to 1.0, with +0.0 meaning no similarity and 1.0 meaning an exact match.

    Example:

    1> string:jaro_similarity("ditto", "ditto").
     1.0
    -2> string:jaro_similarity("foo", "bar").
    +2> string:jaro_similarity("foo", "bar").
     +0.0
    -3> string:jaro_similarity("michelle", "michael").
    +3> string:jaro_similarity("michelle", "michael").
     0.8690476190476191
    -4> string:jaro_similarity(<<"Édouard"/utf8>>, <<"Claude">>).
    +4> string:jaro_similarity(<<"Édouard"/utf8>>, <<"Claude">>).
     0.5317460317460317

    The Jaro distance between two strings can be calculated with JaroDistance = 1.0 - JaroSimilarity.

    @@ -1392,9 +1392,9 @@

    length(String)

    -

    Returns the number of grapheme clusters in String.

    Example:

    1> string:length("ß↑e̊").
    +

    Returns the number of grapheme clusters in String.

    Example:

    1> string:length("ß↑e̊").
     3
    -2> string:length(<<195,159,226,134,145,101,204,138>>).
    +2> string:length(<<195,159,226,134,145,101,204,138>>).
     3
    @@ -1429,10 +1429,10 @@

    lexemes(String, SeparatorList)

    Returns a list of lexemes in String, separated by the grapheme clusters in SeparatorList.

    Notice that, as shown in this example, two or more adjacent separator graphemes clusters in String are treated as one. That is, there are no empty strings in -the resulting list of lexemes. See also split/3 which returns empty strings.

    Notice that [$\r,$\n] is one grapheme cluster.

    Example:

    1> string:lexemes("abc de̊fxxghix jkl\r\nfoo", "x e" ++ [[$\r,$\n]]).
    -["abc","de̊f","ghi","jkl","foo"]
    -2> string:lexemes(<<"abc de̊fxxghix jkl\r\nfoo"/utf8>>, "x e" ++ [$\r,$\n]).
    -[<<"abc">>,<<"de̊f"/utf8>>,<<"ghi">>,<<"jkl\r\nfoo">>]
    +the resulting list of lexemes. See also split/3 which returns empty strings.

    Notice that [$\r,$\n] is one grapheme cluster.

    Example:

    1> string:lexemes("abc de̊fxxghix jkl\r\nfoo", "x e" ++ [[$\r,$\n]]).
    +["abc","de̊f","ghi","jkl","foo"]
    +2> string:lexemes(<<"abc de̊fxxghix jkl\r\nfoo"/utf8>>, "x e" ++ [$\r,$\n]).
    +[<<"abc">>,<<"de̊f"/utf8>>,<<"ghi">>,<<"jkl\r\nfoo">>]
    @@ -1463,7 +1463,7 @@

    lowercase(String)

    Converts String to lowercase.

    Notice that function casefold/1 should be used when converting a string to be -tested for equality.

    Example:

    2> string:lowercase(string:uppercase("Michał")).
    +tested for equality.

    Example:

    2> string:lowercase(string:uppercase("Michał")).
     "michał"
    @@ -1497,8 +1497,8 @@

    next_codepoint(String)

    Returns the first codepoint in String and the rest of String in the tail. Returns an empty list if String is empty or an {error, String} tuple if the -next byte is invalid.

    Example:

    1> string:next_codepoint(unicode:characters_to_binary("e̊fg")).
    -[101|<<"̊fg"/utf8>>]
    +next byte is invalid.

    Example:

    1> string:next_codepoint(unicode:characters_to_binary("e̊fg")).
    +[101|<<"̊fg"/utf8>>]
    @@ -1532,8 +1532,8 @@

    next_grapheme(String)

    Returns the first grapheme cluster in String and the rest of String in the tail. Returns an empty list if String is empty or an {error, String} tuple -if the next byte is invalid.

    Example:

    1> string:next_grapheme(unicode:characters_to_binary("e̊fg")).
    -["e̊"|<<"fg">>]
    +if the next byte is invalid.

    Example:

    1> string:next_grapheme(unicode:characters_to_binary("e̊fg")).
    +["e̊"|<<"fg">>]
    @@ -1568,7 +1568,7 @@

    nth_lexeme(String, N, SeparatorList)

    Returns lexeme number N in String, where lexemes are separated by the -grapheme clusters in SeparatorList.

    Example:

    1> string:nth_lexeme("abc.de̊f.ghiejkl", 3, ".e").
    +grapheme clusters in SeparatorList.

    Example:

    1> string:nth_lexeme("abc.de̊f.ghiejkl", 3, ".e").
     "ghi"
    @@ -1666,11 +1666,11 @@

    pad(String, Length, Dir, Char)

    Pads String to Length with grapheme cluster Char. Dir, which can be -leading, trailing, or both, indicates where the padding should be added.

    Example:

    1> string:pad(<<"He̊llö"/utf8>>, 8).
    -[<<72,101,204,138,108,108,195,182>>,32,32,32]
    -2> io:format("'~ts'~n",[string:pad("He̊llö", 8, leading)]).
    +leading, trailing, or both, indicates where the padding should be added.

    Example:

    1> string:pad(<<"He̊llö"/utf8>>, 8).
    +[<<72,101,204,138,108,108,195,182>>,32,32,32]
    +2> io:format("'~ts'~n",[string:pad("He̊llö", 8, leading)]).
     '   He̊llö'
    -3> io:format("'~ts'~n",[string:pad("He̊llö", 8, both)]).
    +3> io:format("'~ts'~n",[string:pad("He̊llö", 8, both)]).
     ' He̊llö  '
    @@ -1702,9 +1702,9 @@

    prefix(String, Prefix)

    If Prefix is the prefix of String, removes it and returns the remainder of -String, otherwise returns nomatch.

    Example:

    1> string:prefix(<<"prefix of string">>, "pre").
    +String, otherwise returns nomatch.

    Example:

    1> string:prefix(<<"prefix of string">>, "pre").
     <<"fix of string">>
    -2> string:prefix("pre", "prefix").
    +2> string:prefix("pre", "prefix").
     nomatch
    @@ -1775,10 +1775,10 @@

    replace(String, SearchPattern, Replacement,

    Replaces SearchPattern in String with Replacement. Where, indicates whether -the leading, the trailing or all encounters of SearchPattern are to be replaced.

    Can be implemented as:

    lists:join(Replacement, split(String, SearchPattern, Where)).

    Example:

    1> string:replace(<<"ab..cd..ef">>, "..", "*").
    -[<<"ab">>,"*",<<"cd..ef">>]
    -2> string:replace(<<"ab..cd..ef">>, "..", "*", all).
    -[<<"ab">>,"*",<<"cd">>,"*",<<"ef">>]
    +the leading, the trailing or all encounters of SearchPattern are to be replaced.

    Can be implemented as:

    lists:join(Replacement, split(String, SearchPattern, Where)).

    Example:

    1> string:replace(<<"ab..cd..ef">>, "..", "*").
    +[<<"ab">>,"*",<<"cd..ef">>]
    +2> string:replace(<<"ab..cd..ef">>, "..", "*", all).
    +[<<"ab">>,"*",<<"cd">>,"*",<<"ef">>]
    @@ -1808,9 +1808,9 @@

    reverse(String)

    -

    Returns the reverse list of the grapheme clusters in String.

    Example:

    1> Reverse = string:reverse(unicode:characters_to_nfd_binary("ÅÄÖ")).
    -[[79,776],[65,776],[65,778]]
    -2> io:format("~ts~n",[Reverse]).
    +

    Returns the reverse list of the grapheme clusters in String.

    Example:

    1> Reverse = string:reverse(unicode:characters_to_nfd_binary("ÅÄÖ")).
    +[[79,776],[65,776],[65,778]]
    +2> io:format("~ts~n",[Reverse]).
     ÖÄÅ
    @@ -1879,11 +1879,11 @@

    slice(String, Start, Length)

    Returns a substring of String of at most Length grapheme clusters, starting -at position Start.

    Example:

    1> string:slice(<<"He̊llö Wörld"/utf8>>, 4).
    +at position Start.

    Example:

    1> string:slice(<<"He̊llö Wörld"/utf8>>, 4).
     <<"ö Wörld"/utf8>>
    -2> string:slice(["He̊llö ", <<"Wörld"/utf8>>], 4,4).
    +2> string:slice(["He̊llö ", <<"Wörld"/utf8>>], 4,4).
     "ö Wö"
    -3> string:slice(["He̊llö ", <<"Wörld"/utf8>>], 4,50).
    +3> string:slice(["He̊llö ", <<"Wörld"/utf8>>], 4,50).
     "ö Wörld"
    @@ -1951,12 +1951,12 @@

    split(String, SearchPattern, Where)

    Splits String where SearchPattern is encountered and return the remaining parts. Where, default leading, indicates whether the leading, the -trailing or all encounters of SearchPattern will split String.

    Example:

    0> string:split("ab..bc..cd", "..").
    -["ab","bc..cd"]
    -1> string:split(<<"ab..bc..cd">>, "..", trailing).
    -[<<"ab..bc">>,<<"cd">>]
    -2> string:split(<<"ab..bc....cd">>, "..", all).
    -[<<"ab">>,<<"bc">>,<<>>,<<"cd">>]
    +trailing or all encounters of SearchPattern will split String.

    Example:

    0> string:split("ab..bc..cd", "..").
    +["ab","bc..cd"]
    +1> string:split(<<"ab..bc..cd">>, "..", trailing).
    +[<<"ab..bc">>,<<"cd">>]
    +2> string:split(<<"ab..bc....cd">>, "..", all).
    +[<<"ab">>,<<"bc">>,<<>>,<<"cd">>]
    @@ -2067,14 +2067,14 @@

    take(String, Characters, Complement, Dir)Takes characters from String as long as the characters are members of set Characters or the complement of set Characters. Dir, which can be leading or trailing, indicates from which direction characters are to be -taken.

    Example:

    5> string:take("abc0z123", lists:seq($a,$z)).
    -{"abc","0z123"}
    -6> string:take(<<"abc0z123">>, lists:seq($0,$9), true, leading).
    -{<<"abc">>,<<"0z123">>}
    -7> string:take("abc0z123", lists:seq($0,$9), false, trailing).
    -{"abc0z","123"}
    -8> string:take(<<"abc0z123">>, lists:seq($a,$z), true, trailing).
    -{<<"abc0z">>,<<"123">>}
    +taken.

    Example:

    5> string:take("abc0z123", lists:seq($a,$z)).
    +{"abc","0z123"}
    +6> string:take(<<"abc0z123">>, lists:seq($0,$9), true, leading).
    +{<<"abc">>,<<"0z123">>}
    +7> string:take("abc0z123", lists:seq($0,$9), false, trailing).
    +{"abc0z","123"}
    +8> string:take(<<"abc0z123">>, lists:seq($a,$z), true, trailing).
    +{<<"abc0z">>,<<"123">>}

    @@ -2104,7 +2104,7 @@

    titlecase(String)

    -

    Converts String to titlecase.

    Example:

    1> string:titlecase("ß is a SHARP s").
    +

    Converts String to titlecase.

    Example:

    1> string:titlecase("ß is a SHARP s").
     "Ss is a SHARP s"
    @@ -2140,14 +2140,14 @@

    to_float(String)

    Argument String is expected to start with a valid text represented float (the digits are ASCII values). Remaining characters in the string after the float are -returned in Rest.

    Example:

    1> {F1,Fs} = string:to_float("1.0-1.0e-1"),
    -1> {F2,[]} = string:to_float(Fs),
    +returned in Rest.

    Example:

    1> {F1,Fs} = string:to_float("1.0-1.0e-1"),
    +1> {F2,[]} = string:to_float(Fs),
     1> F1+F2.
     0.9
    -2> string:to_float("3/2=1.5").
    -{error,no_float}
    -3> string:to_float("-1.5eX").
    -{-1.5,"eX"}
    +2>
    string:to_float("3/2=1.5"). +{error,no_float} +3> string:to_float("-1.5eX"). +{-1.5,"eX"}
    @@ -2177,10 +2177,10 @@

    to_graphemes(String)

    -

    Converts String to a list of grapheme clusters.

    Example:

    1> string:to_graphemes("ß↑e̊").
    -[223,8593,[101,778]]
    -2> string:to_graphemes(<<"ß↑e̊"/utf8>>).
    -[223,8593,[101,778]]
    +

    Converts String to a list of grapheme clusters.

    Example:

    1> string:to_graphemes("ß↑e̊").
    +[223,8593,[101,778]]
    +2> string:to_graphemes(<<"ß↑e̊"/utf8>>).
    +[223,8593,[101,778]]
    @@ -2215,14 +2215,14 @@

    to_integer(String)

    Argument String is expected to start with a valid text represented integer (the digits are ASCII values). Remaining characters in the string after the -integer are returned in Rest.

    Example:

    1> {I1,Is} = string:to_integer("33+22"),
    -1> {I2,[]} = string:to_integer(Is),
    +integer are returned in Rest.

    Example:

    1> {I1,Is} = string:to_integer("33+22"),
    +1> {I2,[]} = string:to_integer(Is),
     1> I1-I2.
     11
    -2> string:to_integer("0.5").
    -{0,".5"}
    -3> string:to_integer("x=2").
    -{error,no_integer}
    +2>
    string:to_integer("0.5"). +{0,".5"} +3> string:to_integer("x=2"). +{error,no_integer}
    @@ -2323,11 +2323,11 @@

    trim(String, Dir, Characters)

    Returns a string, where leading or trailing, or both, Characters have been removed.

    Dir which can be leading, trailing, or both, indicates from which direction characters are to be removed.

    Note that [$\r,$\n] is one grapheme cluster according to the Unicode -Standard.

    Example:

    1> string:trim("\t  Hello  \n").
    +Standard.

    Example:

    1> string:trim("\t  Hello  \n").
     "Hello"
    -2> string:trim(<<"\t  Hello  \n">>, leading).
    +2> string:trim(<<"\t  Hello  \n">>, leading).
     <<"Hello  \n">>
    -3> string:trim(<<".Hello.\n">>, trailing, "\n.").
    +3> string:trim(<<".Hello.\n">>, trailing, "\n.").
     <<".Hello">>
    @@ -2358,7 +2358,7 @@

    uppercase(String)

    -

    Converts String to uppercase.

    See also titlecase/1.

    Example:

    1> string:uppercase("Michał").
    +

    Converts String to uppercase.

    See also titlecase/1.

    Example:

    1> string:uppercase("Michał").
     "MICHAŁ"
    @@ -2620,7 +2620,7 @@

    cspan(String, Chars)

    Returns the length of the maximum initial segment of String, which consists -entirely of characters not from Chars.

    This function is obsolete. Use take/3.

    Example:

    1> string:cspan("\t    abcdef", " \t").
    +entirely of characters not from Chars.

    This function is obsolete. Use take/3.

    Example:

    1> string:cspan("\t    abcdef", " \t").
     0
    @@ -2652,7 +2652,7 @@

    join(StringList, Separator)

    Returns a string with the elements of StringList separated by the string in Separator.

    This function is obsolete. Use -lists:join/2.

    Example:

    1> join(["one", "two", "three"], ", ").
    +lists:join/2.

    Example:

    1> join(["one", "two", "three"], ", ").
     "one, two, three"
    @@ -2715,7 +2715,7 @@

    left(String, Number, Character)

    Returns String with the length adjusted in accordance with Number. The left margin is fixed. If length(String) < Number, then String is padded with blanks or Characters.

    This function is obsolete. Use pad/2 or -pad/3.

    Example:

    1> string:left("Hello",10,$.).
    +pad/3.

    Example:

    1> string:left("Hello",10,$.).
     "Hello....."
    @@ -2838,7 +2838,7 @@

    right(String, Number, Character)

    Returns String with the length adjusted in accordance with Number. The right margin is fixed. If the length of (String) < Number, then String is padded -with blanks or Characters.

    This function is obsolete. Use pad/3.

    Example:

    1> string:right("Hello", 10, $.).
    +with blanks or Characters.

    This function is obsolete. Use pad/3.

    Example:

    1> string:right("Hello", 10, $.).
     ".....Hello"
    @@ -2869,7 +2869,7 @@

    rstr(String, SubString)

    Returns the position where the last occurrence of SubString begins in -String. Returns 0 if SubString does not exist in String.

    This function is obsolete. Use find/3.

    Example:

    1> string:rstr(" Hello Hello World World ", "Hello World").
    +String. Returns 0 if SubString does not exist in String.

    This function is obsolete. Use find/3.

    Example:

    1> string:rstr(" Hello Hello World World ", "Hello World").
     8
    @@ -2900,7 +2900,7 @@

    span(String, Chars)

    Returns the length of the maximum initial segment of String, which consists -entirely of characters from Chars.

    This function is obsolete. Use take/2.

    Example:

    1> string:span("\t    abcdef", " \t").
    +entirely of characters from Chars.

    This function is obsolete. Use take/2.

    Example:

    1> string:span("\t    abcdef", " \t").
     5
    @@ -2931,7 +2931,7 @@

    str(String, SubString)

    Returns the position where the first occurrence of SubString begins in -String. Returns 0 if SubString does not exist in String.

    This function is obsolete. Use find/2.

    Example:

    1> string:str(" Hello Hello World World ", "Hello World").
    +String. Returns 0 if SubString does not exist in String.

    This function is obsolete. Use find/2.

    Example:

    1> string:str(" Hello Hello World World ", "Hello World").
     8
    @@ -3025,7 +3025,7 @@

    strip(String, Direction, Character)

    Returns a string, where leading or trailing, or both, blanks or a number of Character have been removed.

    Direction, which can be left, right, or both, indicates from which direction blanks are to be removed. -strip/1 is equivalent to strip(String, both).

    This function is obsolete. Use trim/3.

    Example:

    1> string:strip("...Hello.....", both, $.).
    +strip/1 is equivalent to strip(String, both).

    This function is obsolete. Use trim/3.

    Example:

    1> string:strip("...Hello.....", both, $.).
     "Hello"
    @@ -3089,7 +3089,7 @@

    sub_string(String, Start, Stop)

    Returns a substring of String, starting at position Start to the end of the -string, or to and including position Stop.

    This function is obsolete. Use slice/3.

    Example:

    1> sub_string("Hello World", 4, 8).
    +string, or to and including position Stop.

    This function is obsolete. Use slice/3.

    Example:

    1> sub_string("Hello World", 4, 8).
     "lo Wo"
    @@ -3149,7 +3149,7 @@

    sub_word(String, Number, Character)

    Returns the word in position Number of String. Words are separated by blanks or Characters.

    This function is obsolete. Use -nth_lexeme/3.

    Example:

    1> string:sub_word(" Hello old boy !",3,$o).
    +nth_lexeme/3.

    Example:

    1> string:sub_word(" Hello old boy !",3,$o).
     "ld b"
    @@ -3213,7 +3213,7 @@

    substr(String, Start, Length)

    Returns a substring of String, starting at position Start, and ending at the -end of the string or at length Length.

    This function is obsolete. Use slice/3.

    Example:

    1> substr("Hello World", 4, 5).
    +end of the string or at length Length.

    This function is obsolete. Use slice/3.

    Example:

    1> substr("Hello World", 4, 5).
     "lo Wo"
    @@ -3311,8 +3311,8 @@

    tokens(String, SeparatorList)

    Returns a list of tokens in String, separated by the characters in -SeparatorList.

    Example:

    1> tokens("abc defxxghix jkl", "x ").
    -["abc", "def", "ghi", "jkl"]

    Notice that, as shown in this example, two or more adjacent separator characters +SeparatorList.

    Example:

    1> tokens("abc defxxghix jkl", "x ").
    +["abc", "def", "ghi", "jkl"]

    Notice that, as shown in this example, two or more adjacent separator characters in String are treated as one. That is, there are no empty strings in the resulting list of tokens.

    This function is obsolete. Use lexemes/2.

    @@ -3371,7 +3371,7 @@

    words(String, Character)

    -

    Returns the number of words in String, separated by blanks or Character.

    This function is obsolete. Use lexemes/2.

    Example:

    1> words(" Hello old boy!", $o).
    +

    Returns the number of words in String, separated by blanks or Character.

    This function is obsolete. Use lexemes/2.

    Example:

    1> words(" Hello old boy!", $o).
     4
    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/supervisor.html b/prs/8803/lib/stdlib-6.0.1/doc/html/supervisor.html index bf0e69187a5a9..a9937d21ac6ff 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/supervisor.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/supervisor.html @@ -158,10 +158,10 @@

    Supervisor flags

    The supervisor properties are defined by the supervisor flags. The type -definition for the supervisor flags is as follows:

    sup_flags() = #{strategy => strategy(),           % optional
    -                intensity => non_neg_integer(),   % optional
    -                period => pos_integer(),          % optional
    -                auto_shutdown => auto_shutdown()} % optional

    Restart Strategies

    A supervisor can have one of the following restart strategies specified with +definition for the supervisor flags is as follows:

    sup_flags() = #{strategy => strategy(),           % optional
    +                intensity => non_neg_integer(),   % optional
    +                period => pos_integer(),          % optional
    +                auto_shutdown => auto_shutdown()} % optional

    Restart Strategies

    A supervisor can have one of the following restart strategies specified with the strategy key in the above map:

    • one_for_one - If one child process terminates and is to be restarted, only that child process is affected. This is the default restart strategy.

    • one_for_all - If one child process terminates and is to be restarted, all other child processes are terminated and then all child processes are @@ -205,13 +205,13 @@

      Child specification

      -

      The type definition of a child specification is as follows:

      child_spec() = #{id => child_id(),             % mandatory
      -                 start => mfargs(),            % mandatory
      -                 restart => restart(),         % optional
      -                 significant => significant(), % optional
      -                 shutdown => shutdown(),       % optional
      -                 type => worker(),             % optional
      -                 modules => modules()}         % optional

      The old tuple format is kept for backwards compatibility, see child_spec/0, +

      The type definition of a child specification is as follows:

      child_spec() = #{id => child_id(),             % mandatory
      +                 start => mfargs(),            % mandatory
      +                 restart => restart(),         % optional
      +                 significant => significant(), % optional
      +                 shutdown => shutdown(),       % optional
      +                 type => worker(),             % optional
      +                 modules => modules()}         % optional

      The old tuple format is kept for backwards compatibility, see child_spec/0, but the map is preferred.

      • id is used to identify the child specification internally by the supervisor.

        The id key is mandatory.

        Notice that this identifier on occations has been called "name". As far as possible, the terms "identifier" or "id" are now used but to keep backward compatibility, some occurences of "name" can still be found, for example in diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/timer.html b/prs/8803/lib/stdlib-6.0.1/doc/html/timer.html index b85b117c30af7..438e56477ddbb 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/timer.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/timer.html @@ -143,15 +143,15 @@

        Examples

        -

        Example 1

        The following example shows how to print "Hello World!" in 5 seconds:

        1> timer:apply_after(5000, io, format, ["~nHello World!~n", []]).
        -{ok,TRef}
        +

        Example 1

        The following example shows how to print "Hello World!" in 5 seconds:

        1> timer:apply_after(5000, io, format, ["~nHello World!~n", []]).
        +{ok,TRef}
         Hello World!

        Example 2

        The following example shows a process performing a certain action, and if this -action is not completed within a certain limit, the process is killed:

        Pid = spawn(mod, fun, [foo, bar]),
        +action is not completed within a certain limit, the process is killed:

        Pid = spawn(mod, fun, [foo, bar]),
         %% If pid is not finished in 10 seconds, kill him
        -{ok, R} = timer:kill_after(timer:seconds(10), Pid),
        +{ok, R} = timer:kill_after(timer:seconds(10), Pid),
         ...
         %% We change our mind...
        -timer:cancel(R),
        +timer:cancel(R),
         ...

        @@ -178,20 +178,20 @@

        process which set the timer about its completion, by sending it a done message.

        Using self/0 inside the timed function, the code below does not work as intended. The task gets done, but the done message gets sent to the wrong -process and is lost.

        1> timer:apply_after(1000, fun() -> do_something(), self() ! done end).
        -{ok,TRef}
        +process and is lost.

        1> timer:apply_after(1000, fun() -> do_something(), self() ! done end).
        +{ok,TRef}
         2> receive done -> done after 5000 -> timeout end.
         %% ... 5s pass...
         timeout

        The code below calls self/0 in the process which sets the timer and assigns it to a variable, which is then used in the function to send the done message to, -and so works as intended.

        1> Target = self()
        +and so works as intended.

        1> Target = self()
         <0.82.0>
        -2> timer:apply_after(1000, fun() -> do_something(), Target ! done end).
        -{ok,TRef}
        +2> timer:apply_after(1000, fun() -> do_something(), Target ! done end).
        +{ok,TRef}
         3> receive done -> done after 5000 -> timeout end.
         %% ... 1s passes...
        -done

        Another option is to pass the message target as a parameter to the function.

        1> timer:apply_after(1000, fun(Target) -> do_something(), Target ! done end, [self()]).
        -{ok,TRef}
        +done

        Another option is to pass the message target as a parameter to the function.

        1> timer:apply_after(1000, fun(Target) -> do_something(), Target ! done end, [self()]).
        +{ok,TRef}
         2> receive done -> done after 5000 -> timeout end.
         %% ... 1s passes...
         done
        diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/unicode.html b/prs/8803/lib/stdlib-6.0.1/doc/html/unicode.html index 1d74150c33fca..73b4633e48359 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/unicode.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/unicode.html @@ -1071,13 +1071,13 @@

        characters_to_list(Data, InEncoding)

        the first part of a (so far) valid UTF character.

        If one UTF character is split over two consecutive binaries in the Data, the conversion succeeds. This means that a character can be decoded from a range of binaries as long as the whole range is specified as input without errors -occurring.

        Example:

        decode_data(Data) ->
        -   case unicode:characters_to_list(Data,unicode) of
        -      {incomplete,Encoded, Rest} ->
        -            More = get_some_more_data(),
        -            Encoded ++ decode_data([Rest, More]);
        -      {error,Encoded,Rest} ->
        -            handle_error(Encoded,Rest);
        +occurring.

        Example:

        decode_data(Data) ->
        +   case unicode:characters_to_list(Data,unicode) of
        +      {incomplete,Encoded, Rest} ->
        +            More = get_some_more_data(),
        +            Encoded ++ decode_data([Rest, More]);
        +      {error,Encoded,Rest} ->
        +            handle_error(Encoded,Rest);
               List ->
                     List
            end.

        However, bit strings that are not whole bytes are not allowed, so a UTF @@ -1112,7 +1112,7 @@

        characters_to_nfc_binary(CD)

        Converts a possibly deep list of characters and binaries into a Normalized Form -of canonical equivalent Composed characters according to the Unicode standard.

        Any binaries in the input must be encoded with utf8 encoding.

        The result is an utf8 encoded binary.

        4> unicode:characters_to_nfc_binary([<<"abc..a">>,[778],$a,[776],$o,[776]]).
        +of canonical equivalent Composed characters according to the Unicode standard.

        Any binaries in the input must be encoded with utf8 encoding.

        The result is an utf8 encoded binary.

        4> unicode:characters_to_nfc_binary([<<"abc..a">>,[778],$a,[776],$o,[776]]).
         <<"abc..åäö"/utf8>>
        @@ -1144,7 +1144,7 @@

        characters_to_nfc_list(CD)

        Converts a possibly deep list of characters and binaries into a Normalized Form -of canonical equivalent Composed characters according to the Unicode standard.

        Any binaries in the input must be encoded with utf8 encoding.

        The result is a list of characters.

        3> unicode:characters_to_nfc_list([<<"abc..a">>,[778],$a,[776],$o,[776]]).
        +of canonical equivalent Composed characters according to the Unicode standard.

        Any binaries in the input must be encoded with utf8 encoding.

        The result is a list of characters.

        3> unicode:characters_to_nfc_list([<<"abc..a">>,[778],$a,[776],$o,[776]]).
         "abc..åäö"
        @@ -1176,7 +1176,7 @@

        characters_to_nfd_binary(CD)

        Converts a possibly deep list of characters and binaries into a Normalized Form -of canonical equivalent Decomposed characters according to the Unicode standard.

        Any binaries in the input must be encoded with utf8 encoding.

        The result is an utf8 encoded binary.

        2> unicode:characters_to_nfd_binary("abc..åäö").
        +of canonical equivalent Decomposed characters according to the Unicode standard.

        Any binaries in the input must be encoded with utf8 encoding.

        The result is an utf8 encoded binary.

        2> unicode:characters_to_nfd_binary("abc..åäö").
         <<97,98,99,46,46,97,204,138,97,204,136,111,204,136>>
        @@ -1208,8 +1208,8 @@

        characters_to_nfd_list(CD)

        Converts a possibly deep list of characters and binaries into a Normalized Form -of canonical equivalent Decomposed characters according to the Unicode standard.

        Any binaries in the input must be encoded with utf8 encoding.

        The result is a list of characters.

        1> unicode:characters_to_nfd_list("abc..åäö").
        -[97,98,99,46,46,97,778,97,776,111,776]
        +of canonical equivalent Decomposed characters according to the Unicode standard.

        Any binaries in the input must be encoded with utf8 encoding.

        The result is a list of characters.

        1> unicode:characters_to_nfd_list("abc..åäö").
        +[97,98,99,46,46,97,778,97,776,111,776]
        @@ -1240,7 +1240,7 @@

        characters_to_nfkc_binary(CD)

        Converts a possibly deep list of characters and binaries into a Normalized Form -of compatibly equivalent Composed characters according to the Unicode standard.

        Any binaries in the input must be encoded with utf8 encoding.

        The result is an utf8 encoded binary.

        4> unicode:characters_to_nfkc_binary([<<"abc..a">>,[778],$a,[776],$o,[776],[65299,65298]]).
        +of compatibly equivalent Composed characters according to the Unicode standard.

        Any binaries in the input must be encoded with utf8 encoding.

        The result is an utf8 encoded binary.

        4> unicode:characters_to_nfkc_binary([<<"abc..a">>,[778],$a,[776],$o,[776],[65299,65298]]).
         <<"abc..åäö32"/utf8>>
        @@ -1272,7 +1272,7 @@

        characters_to_nfkc_list(CD)

        Converts a possibly deep list of characters and binaries into a Normalized Form -of compatibly equivalent Composed characters according to the Unicode standard.

        Any binaries in the input must be encoded with utf8 encoding.

        The result is a list of characters.

        3> unicode:characters_to_nfkc_list([<<"abc..a">>,[778],$a,[776],$o,[776],[65299,65298]]).
        +of compatibly equivalent Composed characters according to the Unicode standard.

        Any binaries in the input must be encoded with utf8 encoding.

        The result is a list of characters.

        3> unicode:characters_to_nfkc_list([<<"abc..a">>,[778],$a,[776],$o,[776],[65299,65298]]).
         "abc..åäö32"
        @@ -1305,7 +1305,7 @@

        characters_to_nfkd_binary(CD)

        Converts a possibly deep list of characters and binaries into a Normalized Form of compatibly equivalent Decomposed characters according to the Unicode -standard.

        Any binaries in the input must be encoded with utf8 encoding.

        The result is an utf8 encoded binary.

        2> unicode:characters_to_nfkd_binary(["abc..åäö",[65299,65298]]).
        +standard.

        Any binaries in the input must be encoded with utf8 encoding.

        The result is an utf8 encoded binary.

        2> unicode:characters_to_nfkd_binary(["abc..åäö",[65299,65298]]).
         <<97,98,99,46,46,97,204,138,97,204,136,111,204,136,51,50>>
        @@ -1338,8 +1338,8 @@

        characters_to_nfkd_list(CD)

        Converts a possibly deep list of characters and binaries into a Normalized Form of compatibly equivalent Decomposed characters according to the Unicode -standard.

        Any binaries in the input must be encoded with utf8 encoding.

        The result is a list of characters.

        1> unicode:characters_to_nfkd_list(["abc..åäö",[65299,65298]]).
        -[97,98,99,46,46,97,778,97,776,111,776,51,50]
        +standard.

        Any binaries in the input must be encoded with utf8 encoding.

        The result is a list of characters.

        1> unicode:characters_to_nfkd_list(["abc..åäö",[65299,65298]]).
        +[97,98,99,46,46,97,778,97,776,111,776,51,50]
        diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/unicode_usage.html b/prs/8803/lib/stdlib-6.0.1/doc/html/unicode_usage.html index a35fe01393112..ab2e363556c30 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/unicode_usage.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/unicode_usage.html @@ -339,20 +339,20 @@

        iolists, where binaries and lists can be combined to represent a sequence of bytes. In the same way, the Unicode-aware modules often allow for combinations of binaries and lists, where the binaries have characters encoded in UTF-8 and -the lists contain such binaries or numbers representing Unicode code points:

        unicode_binary() = binary() with characters encoded in UTF-8 coding standard
        +the lists contain such binaries or numbers representing Unicode code points:

        unicode_binary() = binary() with characters encoded in UTF-8 coding standard
         
        -chardata() = charlist() | unicode_binary()
        +chardata() = charlist() | unicode_binary()
         
        -charlist() = maybe_improper_list(char() | unicode_binary() | charlist(),
        -  unicode_binary() | nil())

        The module unicode even supports similar mixes with binaries containing +charlist() = maybe_improper_list(char() | unicode_binary() | charlist(), + unicode_binary() | nil())

        The module unicode even supports similar mixes with binaries containing other encodings than UTF-8, but that is a special case to allow for conversions -to and from external data:

        external_unicode_binary() = binary() with characters coded in a user-specified
        -  Unicode encoding other than UTF-8 (UTF-16 or UTF-32)
        +to and from external data:

        external_unicode_binary() = binary() with characters coded in a user-specified
        +  Unicode encoding other than UTF-8 (UTF-16 or UTF-32)
         
        -external_chardata() = external_charlist() | external_unicode_binary()
        +external_chardata() = external_charlist() | external_unicode_binary()
         
        -external_charlist() = maybe_improper_list(char() | external_unicode_binary() |
        -  external_charlist(), external_unicode_binary() | nil())

        +external_charlist() = maybe_improper_list(char() | external_unicode_binary() | + external_charlist(), external_unicode_binary() | nil())

        @@ -400,7 +400,7 @@

        In certain output functions and in the output of return values in the shell, Erlang tries to detect string data in lists and binaries heuristically. -Typically you will see heuristic detection in a situation like this:

        1> [97,98,99].
        +Typically you will see heuristic detection in a situation like this:

        1> [97,98,99].
         "abc"
         2> <<97,98,99>>.
         <<"abc">>
        @@ -420,27 +420,27 @@ 

        controls how heuristic string detection is done. More ranges are expected to be added in the future, enabling tailoring of the heuristics to the language and region relevant to the user.

        The following examples show the two startup options:

        $ erl +pc latin1
        -Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]
        +Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]
         
        -Eshell V5.10.1  (abort with ^G)
        -1> [1024].
        -[1024]
        -2> [1070,1085,1080,1082,1086,1076].
        -[1070,1085,1080,1082,1086,1076]
        -3> [229,228,246].
        +Eshell V5.10.1  (abort with ^G)
        +1> [1024].
        +[1024]
        +2> [1070,1085,1080,1082,1086,1076].
        +[1070,1085,1080,1082,1086,1076]
        +3> [229,228,246].
         "åäö"
         4> <<208,174,208,189,208,184,208,186,208,190,208,180>>.
         <<208,174,208,189,208,184,208,186,208,190,208,180>>
         5> <<229/utf8,228/utf8,246/utf8>>.
         <<"åäö"/utf8>>
        $ erl +pc unicode
        -Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]
        +Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]
         
        -Eshell V5.10.1  (abort with ^G)
        -1> [1024].
        +Eshell V5.10.1  (abort with ^G)
        +1> [1024].
         "Ѐ"
        -2> [1070,1085,1080,1082,1086,1076].
        +2> [1070,1085,1080,1082,1086,1076].
         "Юникод"
        -3> [229,228,246].
        +3> [229,228,246].
         "åäö"
         4> <<208,174,208,189,208,184,208,186,208,190,208,180>>.
         <<"Юникод"/utf8>>
        @@ -453,17 +453,17 @@ 

        outputs anything containing printable Unicode data (in binaries, either UTF-8 or bytewise encoded) as string data.

        These heuristics are also used by io:format/2, io_lib:format/2, and friends when modifier t is used with ~p or ~P:

        $ erl +pc latin1
        -Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]
        +Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]
         
        -Eshell V5.10.1  (abort with ^G)
        -1> io:format("~tp~n",[{<<"åäö">>, <<"åäö"/utf8>>, <<208,174,208,189,208,184,208,186,208,190,208,180>>}]).
        -{<<"åäö">>,<<"åäö"/utf8>>,<<208,174,208,189,208,184,208,186,208,190,208,180>>}
        +Eshell V5.10.1  (abort with ^G)
        +1> io:format("~tp~n",[{<<"åäö">>, <<"åäö"/utf8>>, <<208,174,208,189,208,184,208,186,208,190,208,180>>}]).
        +{<<"åäö">>,<<"åäö"/utf8>>,<<208,174,208,189,208,184,208,186,208,190,208,180>>}
         ok
        $ erl +pc unicode
        -Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]
        +Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]
         
        -Eshell V5.10.1  (abort with ^G)
        -1> io:format("~tp~n",[{<<"åäö">>, <<"åäö"/utf8>>, <<208,174,208,189,208,184,208,186,208,190,208,180>>}]).
        -{<<"åäö">>,<<"åäö"/utf8>>,<<"Юникод"/utf8>>}
        +Eshell V5.10.1  (abort with ^G)
        +1> io:format("~tp~n",[{<<"åäö">>, <<"åäö"/utf8>>, <<208,174,208,189,208,184,208,186,208,190,208,180>>}]).
        +{<<"åäö">>,<<"åäö"/utf8>>,<<"Юникод"/utf8>>}
         ok

        Notice that this only affects heuristic interpretation of lists and binaries on output. For example, the ~ts format sequence always outputs a valid list of characters, regardless of the +pc setting, as the programmer has explicitly @@ -486,19 +486,19 @@

        capable of. There is no portable way for Erlang to ask the terminal about its UTF-8 capacity, we have to rely on the language and character type settings.

        To investigate what Erlang thinks about the terminal, the call io:getopts() can be used when the shell is started:

        $ LC_CTYPE=en_US.ISO-8859-1 erl
        -Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]
        +Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]
         
        -Eshell V5.10.1  (abort with ^G)
        -1> lists:keyfind(encoding, 1, io:getopts()).
        -{encoding,latin1}
        -2> q().
        +Eshell V5.10.1  (abort with ^G)
        +1> lists:keyfind(encoding, 1, io:getopts()).
        +{encoding,latin1}
        +2> q().
         ok
         $ LC_CTYPE=en_US.UTF-8 erl
        -Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]
        +Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]
         
        -Eshell V5.10.1  (abort with ^G)
        -1> lists:keyfind(encoding, 1, io:getopts()).
        -{encoding,unicode}
        +Eshell V5.10.1  (abort with ^G)
        +1> lists:keyfind(encoding, 1, io:getopts()).
        +{encoding,unicode}
         2>

        When (finally?) everything is in order with the locale settings, fonts. and the terminal emulator, you have probably found a way to input characters in the script you desire. For testing, the simplest way is to add some keyboard @@ -511,14 +511,14 @@

        easily if you are not used to this. For example, entering commands using a Cyrillic character set is not easily done in the Erlang shell.

        Now you are set up for some Unicode input and output. The simplest thing to do is to enter a string in the shell:

        $ erl
        -Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]
        +Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]
         
        -Eshell V5.10.1  (abort with ^G)
        -1> lists:keyfind(encoding, 1, io:getopts()).
        -{encoding,unicode}
        +Eshell V5.10.1  (abort with ^G)
        +1> lists:keyfind(encoding, 1, io:getopts()).
        +{encoding,unicode}
         2> "Юникод".
         "Юникод"
        -3> io:format("~ts~n", [v(2)]).
        +3> io:format("~ts~n", [v(2)]).
         Юникод
         ok
         4>

        While strings can be input as Unicode characters, the language elements are @@ -551,10 +551,10 @@

        charlist() represented by it.

        #!/usr/bin/env escript
         %%! -kernel standard_io_encoding latin1
         
        -main(_) ->
        -  {ok, Char} = file:read_line(standard_io),
        -  ok = file:write(standard_io, string:trim(Char)),
        -  ok = file:write(standard_io, io_lib:format(": ~w~n",[string:trim(Char)])),
        +main(_) ->
        +  {ok, Char} = file:read_line(standard_io),
        +  ok = file:write(standard_io, string:trim(Char)),
        +  ok = file:write(standard_io, io_lib:format(": ~w~n",[string:trim(Char)])),
           ok.
        $ escript test.es
         ξ
         ξ: [206,190]

        ξ would normally be represented as the integer 958, but since we are using @@ -790,13 +790,13 @@

        example {encoding,utf8}).

      Functions reading Erlang syntax from files recognize the coding: comment and can therefore handle Unicode data on input. When writing Erlang terms to a file, you are advised to insert such comments when applicable:

      $ erl +fna +pc unicode
      -Erlang R16B (erts-5.10.1) [source]  [async-threads:0] [hipe] [kernel-poll:false]
      +Erlang R16B (erts-5.10.1) [source]  [async-threads:0] [hipe] [kernel-poll:false]
       
      -Eshell V5.10.1  (abort with ^G)
      -1> file:write_file("test.term",<<"%% coding: utf-8\n[{\"Юникод\",4711}].\n"/utf8>>).
      +Eshell V5.10.1  (abort with ^G)
      +1> file:write_file("test.term",<<"%% coding: utf-8\n[{\"Юникод\",4711}].\n"/utf8>>).
       ok
      -2> file:consult("test.term").
      -{ok,[[{"Юникод",4711}]]}

      +2> file:consult("test.term"). +{ok,[[{"Юникод",4711}]]}

    @@ -875,21 +875,21 @@

    same way as the remaining file. If such a file is to be read, the first few bytes (depending on encoding) are not part of the text. This code outlines how to open a file that is believed to have a BOM, and sets the files encoding and -position for further sequential reading (preferably using the io module).

    Notice that error handling is omitted from the code:

    open_bom_file_for_reading(File) ->
    -    {ok,F} = file:open(File,[read,binary]),
    -    {ok,Bin} = file:read(F,4),
    -    {Type,Bytes} = unicode:bom_to_encoding(Bin),
    -    file:position(F,Bytes),
    -    io:setopts(F,[{encoding,Type}]),
    -    {ok,F}.

    Function unicode:bom_to_encoding/1 identifies the encoding from a binary of at +position for further sequential reading (preferably using the io module).

    Notice that error handling is omitted from the code:

    open_bom_file_for_reading(File) ->
    +    {ok,F} = file:open(File,[read,binary]),
    +    {ok,Bin} = file:read(F,4),
    +    {Type,Bytes} = unicode:bom_to_encoding(Bin),
    +    file:position(F,Bytes),
    +    io:setopts(F,[{encoding,Type}]),
    +    {ok,F}.

    Function unicode:bom_to_encoding/1 identifies the encoding from a binary of at least four bytes. It returns, along with a term suitable for setting the encoding of the file, the byte length of the BOM, so that the file position can be set accordingly. Notice that function file:position/2 always works on -byte-offsets, so that the byte length of the BOM is needed.

    To open a file for writing and place the BOM first is even simpler:

    open_bom_file_for_writing(File,Encoding) ->
    -    {ok,F} = file:open(File,[write,binary]),
    -    ok = file:write(File,unicode:encoding_to_bom(Encoding)),
    -    io:setopts(F,[{encoding,Encoding}]),
    -    {ok,F}.

    The file is in both these cases then best processed using the io module, as +byte-offsets, so that the byte length of the BOM is needed.

    To open a file for writing and place the BOM first is even simpler:

    open_bom_file_for_writing(File,Encoding) ->
    +    {ok,F} = file:open(File,[write,binary]),
    +    ok = file:write(File,unicode:encoding_to_bom(Encoding)),
    +    io:setopts(F,[{encoding,Encoding}]),
    +    {ok,F}.

    The file is in both these cases then best processed using the io module, as the functions in that module can handle code points beyond the ISO Latin-1 range.

    @@ -903,10 +903,10 @@

    compatibility reasons, these functions do not accept any list as a string, but require a special translation modifier when working with Unicode texts. The modifier is t. When applied to control character s in a formatting string, -it accepts all Unicode code points and expects binaries to be in UTF-8:

    1> io:format("~ts~n",[<<"åäö"/utf8>>]).
    +it accepts all Unicode code points and expects binaries to be in UTF-8:

    1> io:format("~ts~n",[<<"åäö"/utf8>>]).
     åäö
     ok
    -2> io:format("~s~n",[<<"åäö"/utf8>>]).
    +2> io:format("~s~n",[<<"åäö"/utf8>>]).
     åäÃ
     ok

    Clearly, the second io:format/2 gives undesired output, as the UTF-8 binary is not in latin1. For backward compatibility, the non-prefixed control character @@ -923,12 +923,12 @@

    cannot be stored in one byte. The call to erlang:list_to_binary/1 then fails. However, if the I/O server you want to communicate with is Unicode-aware, the returned list can still be used directly:

    $ erl +pc unicode
    -Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]
    +Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]
     
    -Eshell V5.10.1 (abort with ^G)
    -1> io_lib:format("~ts~n", ["Γιούνικοντ"]).
    -["Γιούνικοντ","\n"]
    -2> io:put_chars(io_lib:format("~ts~n", ["Γιούνικοντ"])).
    +Eshell V5.10.1 (abort with ^G)
    +1> io_lib:format("~ts~n", ["Γιούνικοντ"]).
    +["Γιούνικοντ","\n"]
    +2> io:put_chars(io_lib:format("~ts~n", ["Γιούνικοντ"])).
     Γιούνικοντ
     ok

    The Unicode string is returned as a Unicode list, which is recognized as such, as the Erlang shell uses the Unicode encoding (and is started with all Unicode @@ -953,8 +953,8 @@

    ASCII range are seldom considered valid when decoded as UTF-8. Therefore one can usually use heuristics to determine if a file is in UTF-8 or if it is encoded in ISO Latin-1 (one byte per character). The unicode module can be used to -determine if data can be interpreted as UTF-8:

    heuristic_encoding_bin(Bin) when is_binary(Bin) ->
    -    case unicode:characters_to_binary(Bin,utf8,utf8) of
    +determine if data can be interpreted as UTF-8:

    heuristic_encoding_bin(Bin) when is_binary(Bin) ->
    +    case unicode:characters_to_binary(Bin,utf8,utf8) of
     	Bin ->
     	    utf8;
     	_ ->
    @@ -965,34 +965,34 @@ 

    unicode:characters_to_binary/1,2,3 comes in handy. The incomplete rest from one chunk of data read from the file is prepended to the next chunk and we therefore avoid the problem of character -boundaries when reading chunks of bytes in UTF-8 encoding:

    heuristic_encoding_file(FileName) ->
    -    {ok,F} = file:open(FileName,[read,binary]),
    -    loop_through_file(F,<<>>,file:read(F,1024)).
    +boundaries when reading chunks of bytes in UTF-8 encoding:

    heuristic_encoding_file(FileName) ->
    +    {ok,F} = file:open(FileName,[read,binary]),
    +    loop_through_file(F,<<>>,file:read(F,1024)).
     
    -loop_through_file(_,<<>>,eof) ->
    +loop_through_file(_,<<>>,eof) ->
         utf8;
    -loop_through_file(_,_,eof) ->
    +loop_through_file(_,_,eof) ->
         latin1;
    -loop_through_file(F,Acc,{ok,Bin}) when is_binary(Bin) ->
    -    case unicode:characters_to_binary([Acc,Bin]) of
    -	{error,_,_} ->
    +loop_through_file(F,Acc,{ok,Bin}) when is_binary(Bin) ->
    +    case unicode:characters_to_binary([Acc,Bin]) of
    +	{error,_,_} ->
     	    latin1;
    -	{incomplete,_,Rest} ->
    -	    loop_through_file(F,Rest,file:read(F,1024));
    -	Res when is_binary(Res) ->
    -	    loop_through_file(F,<<>>,file:read(F,1024))
    +	{incomplete,_,Rest} ->
    +	    loop_through_file(F,Rest,file:read(F,1024));
    +	Res when is_binary(Res) ->
    +	    loop_through_file(F,<<>>,file:read(F,1024))
         end.

    Another option is to try to read the whole file in UTF-8 encoding and see if it fails. Here we need to read the file using function io:get_chars/3, as we have -to read characters with a code point > 255:

    heuristic_encoding_file2(FileName) ->
    -    {ok,F} = file:open(FileName,[read,binary,{encoding,utf8}]),
    -    loop_through_file2(F,io:get_chars(F,'',1024)).
    +to read characters with a code point > 255:

    heuristic_encoding_file2(FileName) ->
    +    {ok,F} = file:open(FileName,[read,binary,{encoding,utf8}]),
    +    loop_through_file2(F,io:get_chars(F,'',1024)).
     
    -loop_through_file2(_,eof) ->
    +loop_through_file2(_,eof) ->
         utf8;
    -loop_through_file2(_,{error,_Err}) ->
    +loop_through_file2(_,{error,_Err}) ->
         latin1;
    -loop_through_file2(F,Bin) when is_binary(Bin) ->
    -    loop_through_file2(F,io:get_chars(F,'',1024)).

    +loop_through_file2(F,Bin) when is_binary(Bin) -> + loop_through_file2(F,io:get_chars(F,'',1024)).

    @@ -1003,8 +1003,8 @@

    character. Instead you get the "raw" UTF-8 encoding that you have in binaries. This is easily converted to a proper Unicode string by first converting byte per byte into a binary, and then converting the binary of UTF-8 encoded characters -back to a Unicode string:

    utf8_list_to_string(StrangeList) ->
    -  unicode:characters_to_list(list_to_binary(StrangeList)).

    +back to a Unicode string:

    utf8_list_to_string(StrangeList) ->
    +  unicode:characters_to_list(list_to_binary(StrangeList)).

    @@ -1022,26 +1022,26 @@

    encoded in which format, and never convert UTF-8 data (possibly read byte by byte from a file) into UTF-8 again.

    By far the most common situation where this occurs, is when you get lists of UTF-8 instead of proper Unicode strings, and then convert them to UTF-8 in a -binary or on a file:

    wrong_thing_to_do() ->
    -  {ok,Bin} = file:read_file("an_utf8_encoded_file.txt"),
    -  MyList = binary_to_list(Bin), %% Wrong! It is an utf8 binary!
    -  {ok,C} = file:open("catastrophe.txt",[write,{encoding,utf8}]),
    -  io:put_chars(C,MyList), %% Expects a Unicode string, but get UTF-8
    +binary or on a file:

    wrong_thing_to_do() ->
    +  {ok,Bin} = file:read_file("an_utf8_encoded_file.txt"),
    +  MyList = binary_to_list(Bin), %% Wrong! It is an utf8 binary!
    +  {ok,C} = file:open("catastrophe.txt",[write,{encoding,utf8}]),
    +  io:put_chars(C,MyList), %% Expects a Unicode string, but get UTF-8
                               %% bytes in a list!
    -  file:close(C). %% The file catastrophe.txt contains more or less unreadable
    +  file:close(C). %% The file catastrophe.txt contains more or less unreadable
                      %% garbage!

    Ensure you know what a binary contains before converting it to a string. If no -other option exists, try heuristics:

    if_you_can_not_know() ->
    -  {ok,Bin} = file:read_file("maybe_utf8_encoded_file.txt"),
    -  MyList = case unicode:characters_to_list(Bin) of
    -    L when is_list(L) ->
    +other option exists, try heuristics:

    if_you_can_not_know() ->
    +  {ok,Bin} = file:read_file("maybe_utf8_encoded_file.txt"),
    +  MyList = case unicode:characters_to_list(Bin) of
    +    L when is_list(L) ->
           L;
         _ ->
    -      binary_to_list(Bin) %% The file was bytewise encoded
    +      binary_to_list(Bin) %% The file was bytewise encoded
       end,
       %% Now we know that the list is a Unicode string, not a list of UTF-8 bytes
    -  {ok,G} = file:open("greatness.txt",[write,{encoding,utf8}]),
    -  io:put_chars(G,MyList), %% Expects a Unicode string, which is what it gets!
    -  file:close(G). %% The file contains valid UTF-8 encoded Unicode characters!
    +
    {ok,G} = file:open("greatness.txt",[write,{encoding,utf8}]), + io:put_chars(G,MyList), %% Expects a Unicode string, which is what it gets! + file:close(G). %% The file contains valid UTF-8 encoded Unicode characters!
    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/uri_string.html b/prs/8803/lib/stdlib-6.0.1/doc/html/uri_string.html index d8bb61ee073ef..3dd3776ad8cae 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/uri_string.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/uri_string.html @@ -601,10 +601,10 @@

    compose_query(QueryList)

    Composes a form-urlencoded QueryString based on a QueryList, a list of non-percent-encoded key-value pairs.

    Form-urlencoding is defined in section 4.10.21.6 of the HTML 5.2 specification and in section 4.10.22.6 of the HTML 5.0 -specification for non-UTF-8 encodings.

    See also the opposite operation dissect_query/1.

    Example:

    1> uri_string:compose_query([{"foo bar","1"},{"city","örebro"}]).
    +specification for non-UTF-8 encodings.

    See also the opposite operation dissect_query/1.

    Example:

    1> uri_string:compose_query([{"foo bar","1"},{"city","örebro"}]).
     "foo+bar=1&city=%C3%B6rebro"
    -2> uri_string:compose_query([{<<"foo bar">>,<<"1">>},
    -2> {<<"city">>,<<"örebro"/utf8>>}]).
    +2> uri_string:compose_query([{<<"foo bar">>,<<"1">>},
    +2> {<<"city">>,<<"örebro"/utf8>>}]).
     <<"foo+bar=1&city=%C3%B6rebro">>
    @@ -648,11 +648,11 @@

    compose_query(QueryList, Options)

    ";" (U+003B) character.

    Bytes that are out of the range 0x2A, 0x2D, 0x2E, 0x30 to 0x39, 0x41 to 0x5A, 0x5F, 0x61 to 0x7A, are percent-encoded (U+0025 PERCENT SIGN character (%) followed by uppercase ASCII hex digits representing the hexadecimal value of the -byte).

    See also the opposite operation dissect_query/1.

    Example:

    1> uri_string:compose_query([{"foo bar","1"},{"city","örebro"}],
    -1> [{encoding, latin1}]).
    +byte).

    See also the opposite operation dissect_query/1.

    Example:

    1> uri_string:compose_query([{"foo bar","1"},{"city","örebro"}],
    +1> [{encoding, latin1}]).
     "foo+bar=1&city=%F6rebro"
    -2> uri_string:compose_query([{<<"foo bar">>,<<"1">>},
    -2> {<<"city">>,<<"東京"/utf8>>}], [{encoding, latin1}]).
    +2> uri_string:compose_query([{<<"foo bar">>,<<"1">>},
    +2> {<<"city">>,<<"東京"/utf8>>}], [{encoding, latin1}]).
     <<"foo+bar=1&city=%26%2326481%3B%26%2320140%3B">>
    @@ -689,11 +689,11 @@

    dissect_query(QueryString)

    Dissects an urlencoded QueryString and returns a QueryList, a list of non-percent-encoded key-value pairs.

    Form-urlencoding is defined in section 4.10.21.6 of the HTML 5.2 specification and in section 4.10.22.6 of the HTML 5.0 -specification for non-UTF-8 encodings.

    See also the opposite operation compose_query/1.

    Example:

    1> uri_string:dissect_query("foo+bar=1&city=%C3%B6rebro").
    -[{"foo bar","1"},{"city","örebro"}]
    -2> uri_string:dissect_query(<<"foo+bar=1&city=%26%2326481%3B%26%2320140%3B">>).
    -[{<<"foo bar">>,<<"1">>},
    - {<<"city">>,<<230,157,177,228,186,172>>}]
    +specification for non-UTF-8 encodings.

    See also the opposite operation compose_query/1.

    Example:

    1> uri_string:dissect_query("foo+bar=1&city=%C3%B6rebro").
    +[{"foo bar","1"},{"city","örebro"}]
    +2> uri_string:dissect_query(<<"foo+bar=1&city=%26%2326481%3B%26%2320140%3B">>).
    +[{<<"foo bar">>,<<"1">>},
    + {<<"city">>,<<230,157,177,228,186,172>>}]
    @@ -727,14 +727,14 @@

    normalize(URI)

    Transforms an URI into a normalized form using Syntax-Based Normalization as defined by RFC 3986.

    This function implements case normalization, percent-encoding normalization, path segment normalization and scheme based normalization for HTTP(S) with basic -support for FTP, SSH, SFTP and TFTP.

    Example:

    1> uri_string:normalize("/a/b/c/./../../g").
    +support for FTP, SSH, SFTP and TFTP.

    Example:

    1> uri_string:normalize("/a/b/c/./../../g").
     "/a/g"
    -2> uri_string:normalize(<<"mid/content=5/../6">>).
    +2> uri_string:normalize(<<"mid/content=5/../6">>).
     <<"mid/6">>
    -3> uri_string:normalize("http://localhost:80").
    +3> uri_string:normalize("http://localhost:80").
     "http://localhost/"
    -4> uri_string:normalize(#{scheme => "http",port => 80,path => "/a/b/c/./../../g",
    -4> host => "localhost-örebro"}).
    +4> uri_string:normalize(#{scheme => "http",port => 80,path => "/a/b/c/./../../g",
    +4> host => "localhost-örebro"}).
     "http://localhost-%C3%B6rebro/a/g"
    @@ -771,15 +771,15 @@

    normalize(URI, Options)

    Same as normalize/1 but with an additional Options parameter, that controls whether the normalized URI shall be returned as an -uri_map().

    There is one supported option: return_map.

    Example:

    1> uri_string:normalize("/a/b/c/./../../g", [return_map]).
    -#{path => "/a/g"}
    -2> uri_string:normalize(<<"mid/content=5/../6">>, [return_map]).
    -#{path => <<"mid/6">>}
    -3> uri_string:normalize("http://localhost:80", [return_map]).
    -#{scheme => "http",path => "/",host => "localhost"}
    -4> uri_string:normalize(#{scheme => "http",port => 80,path => "/a/b/c/./../../g",
    -4> host => "localhost-örebro"}, [return_map]).
    -#{scheme => "http",path => "/a/g",host => "localhost-örebro"}
    +uri_map().

    There is one supported option: return_map.

    Example:

    1> uri_string:normalize("/a/b/c/./../../g", [return_map]).
    +#{path => "/a/g"}
    +2> uri_string:normalize(<<"mid/content=5/../6">>, [return_map]).
    +#{path => <<"mid/6">>}
    +3> uri_string:normalize("http://localhost:80", [return_map]).
    +#{scheme => "http",path => "/",host => "localhost"}
    +4> uri_string:normalize(#{scheme => "http",port => 80,path => "/a/b/c/./../../g",
    +4> host => "localhost-örebro"}, [return_map]).
    +#{scheme => "http",path => "/a/g",host => "localhost-örebro"}
    @@ -811,14 +811,14 @@

    parse(URIString)

    Parses an RFC 3986 compliant uri_string/0 into a uri_map/0, that holds the parsed components of the -URI. If parsing fails, an error tuple is returned.

    See also the opposite operation recompose/1.

    Example:

    1> uri_string:parse("foo://user@example.com:8042/over/there?name=ferret#nose").
    -#{fragment => "nose",host => "example.com",
    +URI. If parsing fails, an error tuple is returned.

    See also the opposite operation recompose/1.

    Example:

    1> uri_string:parse("foo://user@example.com:8042/over/there?name=ferret#nose").
    +#{fragment => "nose",host => "example.com",
       path => "/over/there",port => 8042,query => "name=ferret",
    -  scheme => foo,userinfo => "user"}
    -2> uri_string:parse(<<"foo://user@example.com:8042/over/there?name=ferret">>).
    -#{host => <<"example.com">>,path => <<"/over/there">>,
    +  scheme => foo,userinfo => "user"}
    +2> uri_string:parse(<<"foo://user@example.com:8042/over/there?name=ferret">>).
    +#{host => <<"example.com">>,path => <<"/over/there">>,
       port => 8042,query => <<"name=ferret">>,scheme => <<"foo">>,
    -  userinfo => <<"user">>}
    +
    userinfo => <<"user">>}
    @@ -857,15 +857,15 @@

    percent_decode(URI)

    Decodes all percent-encoded triplets in the input that can be both a uri_string/0 and a uri_map/0.

    Note, that this function performs raw decoding and it shall be used on already parsed URI components. Applying this function directly on a standard URI can -effectively change it.

    If the input encoding is not UTF-8, an error tuple is returned.

    Example:

    1> uri_string:percent_decode(#{host => "localhost-%C3%B6rebro",path => [],
    -1> scheme => "http"}).
    -#{host => "localhost-örebro",path => [],scheme => "http"}
    -2> uri_string:percent_decode(<<"%C3%B6rebro">>).
    +effectively change it.

    If the input encoding is not UTF-8, an error tuple is returned.

    Example:

    1> uri_string:percent_decode(#{host => "localhost-%C3%B6rebro",path => [],
    +1> scheme => "http"}).
    +#{host => "localhost-örebro",path => [],scheme => "http"}
    +2> uri_string:percent_decode(<<"%C3%B6rebro">>).
     <<"örebro"/utf8>>

    Warning

    Using uri_string:percent_decode/1 directly on a URI is not safe. This example shows, that after each consecutive application of the function the -resulting URI will be changed. None of these URIs refer to the same resource.

    3> uri_string:percent_decode(<<"http://local%252Fhost/path">>).
    +resulting URI will be changed. None of these URIs refer to the same resource.

    3> uri_string:percent_decode(<<"http://local%252Fhost/path">>).
     <<"http://local%2Fhost/path">>
    -4> uri_string:percent_decode(<<"http://local%2Fhost/path">>).
    +4> uri_string:percent_decode(<<"http://local%2Fhost/path">>).
     <<"http://local/host/path">>
    @@ -898,9 +898,9 @@

    quote(Data)

    Replaces characters out of unreserved set with their percent encoded equivalents.

    Unreserved characters defined in -RFC 3986 are not quoted.

    Example:

    1> uri_string:quote("SomeId/04").
    +RFC 3986 are not quoted.

    Example:

    1> uri_string:quote("SomeId/04").
     "SomeId%2F04"
    -2> uri_string:quote(<<"SomeId/04">>).
    +2> uri_string:quote(<<"SomeId/04">>).
     <<"SomeId%2F04">>

    Warning

    Function is not aware about any URI component context and should not be used on whole URI. If applied more than once on the same data, might produce unexpected results.

    @@ -935,9 +935,9 @@

    quote(Data, Safe)

    Same as quote/1, but Safe allows user to provide a list of -characters to be protected from encoding.

    Example:

    1> uri_string:quote("SomeId/04", "/").
    +characters to be protected from encoding.

    Example:

    1> uri_string:quote("SomeId/04", "/").
     "SomeId/04"
    -2> uri_string:quote(<<"SomeId/04">>, "/").
    +2> uri_string:quote(<<"SomeId/04">>, "/").
     <<"SomeId/04">>

    Warning

    Function is not aware about any URI component context and should not be used on whole URI. If applied more than once on the same data, might produce unexpected results.

    @@ -972,13 +972,13 @@

    recompose(URIMap)

    Creates an RFC 3986 compliant URIString (percent-encoded), based on the components of URIMap. If the -URIMap is invalid, an error tuple is returned.

    See also the opposite operation parse/1.

    Example:

    1> URIMap = #{fragment => "nose", host => "example.com", path => "/over/there",
    -1> port => 8042, query => "name=ferret", scheme => "foo", userinfo => "user"}.
    -#{fragment => "nose",host => "example.com",
    +URIMap is invalid, an error tuple is returned.

    See also the opposite operation parse/1.

    Example:

    1> URIMap = #{fragment => "nose", host => "example.com", path => "/over/there",
    +1> port => 8042, query => "name=ferret", scheme => "foo", userinfo => "user"}.
    +#{fragment => "nose",host => "example.com",
       path => "/over/there",port => 8042,query => "name=ferret",
    -  scheme => "foo",userinfo => "user"}
    +  scheme => "foo",userinfo => "user"}
     
    -2> uri_string:recompose(URIMap).
    +2> uri_string:recompose(URIMap).
     "foo://example.com:8042/over/there?name=ferret#nose"
    @@ -1015,13 +1015,13 @@

    resolve(RefURI, BaseURI)

    Convert a RefURI reference that might be relative to a given base URI into the parsed components of the reference's target, which can then be recomposed to -form the target URI.

    Example:

    1> uri_string:resolve("/abs/ol/ute", "http://localhost/a/b/c?q").
    +form the target URI.

    Example:

    1> uri_string:resolve("/abs/ol/ute", "http://localhost/a/b/c?q").
     "http://localhost/abs/ol/ute"
    -2> uri_string:resolve("../relative", "http://localhost/a/b/c?q").
    +2> uri_string:resolve("../relative", "http://localhost/a/b/c?q").
     "http://localhost/a/relative"
    -3> uri_string:resolve("http://localhost/full", "http://localhost/a/b/c?q").
    +3> uri_string:resolve("http://localhost/full", "http://localhost/a/b/c?q").
     "http://localhost/full"
    -4> uri_string:resolve(#{path => "path", query => "xyz"}, "http://localhost/a/b/c?q").
    +4> uri_string:resolve(#{path => "path", query => "xyz"}, "http://localhost/a/b/c?q").
     "http://localhost/a/b/path?xyz"
    @@ -1059,11 +1059,11 @@

    resolve(RefURI, BaseURI, Options)

    Same as resolve/2 but with an additional Options parameter, that controls whether the target URI shall be returned as an uri_map(). There is -one supported option: return_map.

    Example:

    1> uri_string:resolve("/abs/ol/ute", "http://localhost/a/b/c?q", [return_map]).
    -#{host => "localhost",path => "/abs/ol/ute",scheme => "http"}
    -2> uri_string:resolve(#{path => "/abs/ol/ute"}, #{scheme => "http",
    -2> host => "localhost", path => "/a/b/c?q"}, [return_map]).
    -#{host => "localhost",path => "/abs/ol/ute",scheme => "http"}
    +one supported option: return_map.

    Example:

    1> uri_string:resolve("/abs/ol/ute", "http://localhost/a/b/c?q", [return_map]).
    +#{host => "localhost",path => "/abs/ol/ute",scheme => "http"}
    +2> uri_string:resolve(#{path => "/abs/ol/ute"}, #{scheme => "http",
    +2> host => "localhost", path => "/a/b/c?q"}, [return_map]).
    +#{host => "localhost",path => "/abs/ol/ute",scheme => "http"}
    @@ -1103,11 +1103,11 @@

    transcode(URIString, Options)

    (in_encoding) and outbound (out_encoding) encodings.

    in_encoding and out_encoding specifies both binary encoding and percent-encoding for the input and output data. Mixed encoding, where binary encoding is not the same as percent-encoding, is not supported. If an argument is invalid, an error tuple is -returned.

    Example:

    1> uri_string:transcode(<<"foo%00%00%00%F6bar"/utf32>>,
    -1> [{in_encoding, utf32},{out_encoding, utf8}]).
    +returned.

    Example:

    1> uri_string:transcode(<<"foo%00%00%00%F6bar"/utf32>>,
    +1> [{in_encoding, utf32},{out_encoding, utf8}]).
     <<"foo%C3%B6bar"/utf8>>
    -2> uri_string:transcode("foo%F6bar", [{in_encoding, latin1},
    -2> {out_encoding, utf8}]).
    +2> uri_string:transcode("foo%F6bar", [{in_encoding, latin1},
    +2> {out_encoding, utf8}]).
     "foo%C3%B6bar"
    @@ -1138,9 +1138,9 @@

    unquote(QuotedData)

    -

    Percent decode characters.

    Example:

    1> uri_string:unquote("SomeId%2F04").
    +

    Percent decode characters.

    Example:

    1> uri_string:unquote("SomeId%2F04").
     "SomeId/04"
    -2> uri_string:unquote(<<"SomeId%2F04">>).
    +2> uri_string:unquote(<<"SomeId%2F04">>).
     <<"SomeId/04">>

    Warning

    Function is not aware about any URI component context and should not be used on whole URI. If applied more than once on the same data, might produce unexpected results.

    diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/uri_string_usage.html b/prs/8803/lib/stdlib-6.0.1/doc/html/uri_string_usage.html index 4123350e1d00e..3b355366da664 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/uri_string_usage.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/uri_string_usage.html @@ -194,19 +194,19 @@

    to explain this by an example.

    Let's say that we would like to create the following URI and send it over the network: http://cities/örebro?foo bar. This is not a valid URI as it contains characters that are not allowed in a URI such as "ö" and the space. We can -verify this by parsing the URI:

      1> uri_string:parse("http://cities/örebro?foo bar").
    -  {error,invalid_uri,":"}

    The URI parser tries all possible combinations to interpret the input and fails +verify this by parsing the URI:

      1> uri_string:parse("http://cities/örebro?foo bar").
    +  {error,invalid_uri,":"}

    The URI parser tries all possible combinations to interpret the input and fails at the last attempt when it encounters the colon character ":". Note, that the inital fault occurs when the parser attempts to interpret the character "ö" and after a failure back-tracks to the point where it has another possible parsing alternative.

    The proper way to solve this problem is to use uri_string:recompose/1 with a -uri_map() as input:

      2> uri_string:recompose(#{scheme => "http", host => "cities", path => "/örebro",
    -  query => "foo bar"}).
    +uri_map() as input:

      2> uri_string:recompose(#{scheme => "http", host => "cities", path => "/örebro",
    +  query => "foo bar"}).
       "http://cities/%C3%B6rebro?foo%20bar"

    The result is a valid URI where all the special characters are encoded as defined by the standard. Applying uri_string:parse/1 and -uri_string:percent_decode/1 on the URI returns the original input:

      3> uri_string:percent_decode(uri_string:parse("http://cities/%C3%B6rebro?foo%20bar")).
    -  #{host => "cities",path => "/örebro",query => "foo bar",
    -  scheme => "http"}

    This symmetric property is heavily used in our property test suite.

    +uri_string:percent_decode/1 on the URI returns the original input:

      3> uri_string:percent_decode(uri_string:parse("http://cities/%C3%B6rebro?foo%20bar")).
    +  #{host => "cities",path => "/örebro",query => "foo bar",
    +  scheme => "http"}

    This symmetric property is heavily used in our property test suite.

    @@ -229,27 +229,27 @@

    question the library provides a utility function, uri_string:allowed_characters/0, that lists the allowed set of characters in each major URI component, and also in the -most important standard character sets.

        1> uri_string:allowed_characters().
    -    [{scheme,
    -     "+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"},
    -    {userinfo,
    -     "!$%&'()*+,-.0123456789:;=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"},
    -    {host,
    -     "!$&'()*+,-.0123456789:;=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"},
    -    {ipv4,".0123456789"},
    -    {ipv6,".0123456789:ABCDEFabcdef"},
    -    {regname,
    -     "!$%&'()*+,-.0123456789;=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"},
    -    {path,
    -     "!$%&'()*+,-./0123456789:;=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"},
    -    {query,
    -     "!$%&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"},
    -    {fragment,
    -     "!$%&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"},
    -    {reserved,"!#$&'()*+,/:;=?@[]"},
    -    {unreserved,
    -     "-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"}]

    If a URI component has a character that is not allowed, it will be -percent-encoded when the URI is produced:

        2> uri_string:recompose(#{scheme => "https", host => "local#host", path => ""}).
    +most important standard character sets.

        1> uri_string:allowed_characters().
    +    [{scheme,
    +     "+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"},
    +    {userinfo,
    +     "!$%&'()*+,-.0123456789:;=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"},
    +    {host,
    +     "!$&'()*+,-.0123456789:;=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"},
    +    {ipv4,".0123456789"},
    +    {ipv6,".0123456789:ABCDEFabcdef"},
    +    {regname,
    +     "!$%&'()*+,-.0123456789;=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"},
    +    {path,
    +     "!$%&'()*+,-./0123456789:;=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"},
    +    {query,
    +     "!$%&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"},
    +    {fragment,
    +     "!$%&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"},
    +    {reserved,"!#$&'()*+,/:;=?@[]"},
    +    {unreserved,
    +     "-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"}]

    If a URI component has a character that is not allowed, it will be +percent-encoded when the URI is produced:

        2> uri_string:recompose(#{scheme => "https", host => "local#host", path => ""}).
         "https://local%23host"

    Consuming a URI containing percent-encoded triplets can take many steps. The following example shows how to handle an input URI that is not normalized and contains multiple percent-encoded triplets. First, the input @@ -261,32 +261,32 @@

    You can try to normalize the input with uri_string:normalize/1. The normalize operation decodes those percent-encoded triplets that correspond to a character in the unreserved set. Normalization is a safe, idempotent operation that -converts a URI into its canonical form:

        4> uri_string:normalize("http://%6C%6Fcal%23host/%F6re%26bro%20").
    +converts a URI into its canonical form:

        4> uri_string:normalize("http://%6C%6Fcal%23host/%F6re%26bro%20").
         "http://local%23host/%F6re%26bro%20"
    -    5> uri_string:normalize("http://%6C%6Fcal%23host/%F6re%26bro%20", [return_map]).
    -    #{host => "local%23host",path => "/%F6re%26bro%20",
    -      scheme => "http"}

    There are still a few percent-encoded triplets left in the output. At this + 5> uri_string:normalize("http://%6C%6Fcal%23host/%F6re%26bro%20", [return_map]). + #{host => "local%23host",path => "/%F6re%26bro%20", + scheme => "http"}

    There are still a few percent-encoded triplets left in the output. At this point, when the URI is already parsed, it is safe to apply application specific decoding on the remaining character triplets. Erlang/OTP provides a function, uri_string:percent_decode/1 for raw percent decoding that you can use on the -host and path components, or on the whole map:

        6> uri_string:percent_decode("local%23host").
    +host and path components, or on the whole map:

        6> uri_string:percent_decode("local%23host").
         "local#host"
    -    7> uri_string:percent_decode("/%F6re%26bro%20").
    -    {error,invalid_utf8,<<"/öre&bro ">>}
    -    8> uri_string:percent_decode(#{host => "local%23host",path => "/%F6re%26bro%20",
    -    scheme => "http"}).
    -    {error,{invalid,{path,{invalid_utf8,<<"/öre&bro ">>}}}}

    The host was successfully decoded but the path contains at least one character + 7> uri_string:percent_decode("/%F6re%26bro%20"). + {error,invalid_utf8,<<"/öre&bro ">>} + 8> uri_string:percent_decode(#{host => "local%23host",path => "/%F6re%26bro%20", + scheme => "http"}). + {error,{invalid,{path,{invalid_utf8,<<"/öre&bro ">>}}}}

    The host was successfully decoded but the path contains at least one character with non-UTF-8 encoding. In order to be able to decode this, you have to make assumptions about the encoding used in these triplets. The most obvious choice is latin-1, so you can try uri_string:transcode/2, to transcode the path to -UTF-8 and run the percent-decode operation on the transcoded string:

        9> uri_string:transcode("/%F6re%26bro%20", [{in_encoding, latin1}]).
    +UTF-8 and run the percent-decode operation on the transcoded string:

        9> uri_string:transcode("/%F6re%26bro%20", [{in_encoding, latin1}]).
         "/%C3%B6re%26bro%20"
    -    10> uri_string:percent_decode("/%C3%B6re%26bro%20").
    +    10> uri_string:percent_decode("/%C3%B6re%26bro%20").
         "/öre&bro "

    It is important to emphasize that it is not safe to apply -uri_string:percent_decode/1 directly on an input URI:

        11> uri_string:percent_decode("http://%6C%6Fcal%23host/%C3%B6re%26bro%20").
    +uri_string:percent_decode/1 directly on an input URI:

        11> uri_string:percent_decode("http://%6C%6Fcal%23host/%C3%B6re%26bro%20").
         "http://local#host/öre&bro "
    -    12> uri_string:parse("http://local#host/öre&bro ").
    -    {error,invalid_uri,":"}

    Note

    Percent-encoding is implemented in uri_string:recompose/1 and it happens + 12> uri_string:parse("http://local#host/öre&bro "). + {error,invalid_uri,":"}

    Note

    Percent-encoding is implemented in uri_string:recompose/1 and it happens when converting a uri_map() into a uri_string(). Applying any percent-encoding directly on an input URI would not be safe just as in the case of diff --git a/prs/8803/lib/stdlib-6.0.1/doc/html/zip.html b/prs/8803/lib/stdlib-6.0.1/doc/html/zip.html index 3d14bde9bc160..a23e7cfddf640 100644 --- a/prs/8803/lib/stdlib-6.0.1/doc/html/zip.html +++ b/prs/8803/lib/stdlib-6.0.1/doc/html/zip.html @@ -1054,28 +1054,28 @@

    foldl(Fun, Acc0, Archive)

    archive. The iteration can be ended prematurely in a controlled manner by throwing an exception.

    Example:

    > Name = "dummy.zip".
     "dummy.zip"
    -> {ok, {Name, Bin}} = zip:create(Name, [{"foo", <<"FOO">>}, {"bar", <<"BAR">>}], [memory]).
    -{ok,{"dummy.zip",
    +> {ok, {Name, Bin}} = zip:create(Name, [{"foo", <<"FOO">>}, {"bar", <<"BAR">>}], [memory]).
    +{ok,{"dummy.zip",
          <<80,75,3,4,20,0,0,0,0,0,74,152,97,60,171,39,212,26,3,0,
    -       0,0,3,0,0,...>>}}
    -> {ok, FileSpec} = zip:foldl(fun(N, I, B, Acc) -> [{N, B(), I()} | Acc] end, [], {Name, Bin}).
    -{ok,[{"bar",<<"BAR">>,
    -      {file_info,3,regular,read_write,
    -                 {{2010,3,1},{19,2,10}},
    -                 {{2010,3,1},{19,2,10}},
    -                 {{2010,3,1},{19,2,10}},
    -                 54,1,0,0,0,0,0}},
    -     {"foo",<<"FOO">>,
    -      {file_info,3,regular,read_write,
    -                 {{2010,3,1},{19,2,10}},
    -                 {{2010,3,1},{19,2,10}},
    -                 {{2010,3,1},{19,2,10}},
    -                 54,1,0,0,0,0,0}}]}
    -> {ok, {Name, Bin}} = zip:create(Name, lists:reverse(FileSpec), [memory]).
    -{ok,{"dummy.zip",
    +       0,0,3,0,0,...>>}}
    +> {ok, FileSpec} = zip:foldl(fun(N, I, B, Acc) -> [{N, B(), I()} | Acc] end, [], {Name, Bin}).
    +{ok,[{"bar",<<"BAR">>,
    +      {file_info,3,regular,read_write,
    +                 {{2010,3,1},{19,2,10}},
    +                 {{2010,3,1},{19,2,10}},
    +                 {{2010,3,1},{19,2,10}},
    +                 54,1,0,0,0,0,0}},
    +     {"foo",<<"FOO">>,
    +      {file_info,3,regular,read_write,
    +                 {{2010,3,1},{19,2,10}},
    +                 {{2010,3,1},{19,2,10}},
    +                 {{2010,3,1},{19,2,10}},
    +                 54,1,0,0,0,0,0}}]}
    +> {ok, {Name, Bin}} = zip:create(Name, lists:reverse(FileSpec), [memory]).
    +{ok,{"dummy.zip",
          <<80,75,3,4,20,0,0,0,0,0,74,152,97,60,171,39,212,26,3,0,
    -       0,0,3,0,0,...>>}}
    -> catch zip:foldl(fun("foo", _, B, _) -> throw(B()); (_,_,_,Acc) -> Acc end, [], {Name, Bin}).
    +       0,0,3,0,0,...>>}}
    +> catch zip:foldl(fun("foo", _, B, _) -> throw(B()); (_,_,_,Acc) -> Acc end, [], {Name, Bin}).
     <<"FOO">>
    diff --git a/prs/8803/lib/syntax_tools-3.2/doc/html/erl_syntax.html b/prs/8803/lib/syntax_tools-3.2/doc/html/erl_syntax.html index db3c596b838fe..606622401c787 100644 --- a/prs/8803/lib/syntax_tools-3.2/doc/html/erl_syntax.html +++ b/prs/8803/lib/syntax_tools-3.2/doc/html/erl_syntax.html @@ -6854,10 +6854,10 @@

    get_postcomments(Node)

    Returns the associated post-comments of a node.

    This is a possibly empty list of abstract comments, in top-down textual order. When the code is formatted, post-comments are typically -displayed to the right of and/or below the node. For example:

    {foo, X, Y}     % Post-comment of tuple

    If possible, the comment should be moved past any following separator characters +displayed to the right of and/or below the node. For example:

    {foo, X, Y}     % Post-comment of tuple

    If possible, the comment should be moved past any following separator characters on the same line, rather than placing the separators on the following line. -For example:

    foo([X | Xs], Y) ->
    -    foo(Xs, bar(X));     % Post-comment of 'bar(X)' node
    +For example:

    foo([X | Xs], Y) ->
    +    foo(Xs, bar(X));     % Post-comment of 'bar(X)' node
      ...

    (where the comment is moved past the rightmost ")" and the ";").

    See also: comment/2, get_attrs/1, get_precomments/1, set_postcomments/2.

    @@ -6890,10 +6890,10 @@

    get_precomments(Node)

    Returns the associated pre-comments of a node.

    This is a possibly empty list of abstract comments, in top-down textual order. When the code is formatted, pre-comments are typically displayed directly above the node. For example:

    % Pre-comment of function
    -foo(X) -> {bar, X}.

    If possible, the comment should be moved before any preceding separator -characters on the same line. For example:

    foo([X | Xs]) ->
    +foo(X) -> {bar, X}.

    If possible, the comment should be moved before any preceding separator +characters on the same line. For example:

    foo([X | Xs]) ->
         % Pre-comment of 'bar(X)' node
    -    [bar(X) | foo(Xs)];
    +    [bar(X) | foo(Xs)];
     ...

    (where the comment is moved before the "[").

    See also: comment/2, get_attrs/1, get_postcomments/1, set_precomments/2.

    diff --git a/prs/8803/lib/syntax_tools-3.2/doc/html/merl.html b/prs/8803/lib/syntax_tools-3.2/doc/html/merl.html index 0750941330d61..0803ea7939f10 100644 --- a/prs/8803/lib/syntax_tools-3.2/doc/html/merl.html +++ b/prs/8803/lib/syntax_tools-3.2/doc/html/merl.html @@ -138,30 +138,30 @@

    Quick start

    To enable the full power of Merl, your module needs to include the Merl header -file:

    -include_lib("syntax_tools/include/merl.hrl").

    Then, you can use the ?Q(Text) macros in your code to create ASTs or match on -existing ASTs. For example:

    Tuple = ?Q("{foo, 42}"),
    -?Q("{foo, _@Number}") = Tuple,
    -Call = ?Q("foo:bar(_@Number)")

    Calling merl:print(Call) will then print the following code:

    foo:bar(42)

    The ?Q macros turn the quoted code fragments into ASTs, and lifts +file:

    -include_lib("syntax_tools/include/merl.hrl").

    Then, you can use the ?Q(Text) macros in your code to create ASTs or match on +existing ASTs. For example:

    Tuple = ?Q("{foo, 42}"),
    +?Q("{foo, _@Number}") = Tuple,
    +Call = ?Q("foo:bar(_@Number)")

    Calling merl:print(Call) will then print the following code:

    foo:bar(42)

    The ?Q macros turn the quoted code fragments into ASTs, and lifts metavariables such as _@Tuple and _@Number to the level of your Erlang code, so you can use the corresponding Erlang variables Tuple and Number directly. This is the most straightforward way to use Merl, and in many cases it's all you need.

    You can even write case switches using ?Q macros as patterns. For example:

    case AST of
    -    ?Q("{foo, _@Foo}") -> handle(Foo);
    -    ?Q("{bar, _@Bar}") when erl_syntax:is_integer(Bar) -> handle(Bar);
    -    _ -> handle_default()
    +    ?Q("{foo, _@Foo}") -> handle(Foo);
    +    ?Q("{bar, _@Bar}") when erl_syntax:is_integer(Bar) -> handle(Bar);
    +    _ -> handle_default()
     end

    These case switches only allow ?Q(...) or _ as clause patterns, and the guards may contain any expressions, not just Erlang guard expressions.

    If the macro MERL_NO_TRANSFORM is defined before the merl.hrl header file is included, the parse transform used by Merl will be disabled, and in that case, the match expressions ?Q(...) = ..., case switches using ?Q(...) patterns, and automatic metavariables like _@Tuple cannot be used in your code, but the Merl macros and functions still work. To do metavariable substitution, you need -to use the ?Q(Text, Map) macro. For example:

    Tuple = ?Q("{foo, _@bar, _@baz}", [{bar, Bar}, {baz,Baz}])

    The text given to a ?Q(Text) macro can be either a single string or a list of +to use the ?Q(Text, Map) macro. For example:

    Tuple = ?Q("{foo, _@bar, _@baz}", [{bar, Bar}, {baz,Baz}])

    The text given to a ?Q(Text) macro can be either a single string or a list of strings. The latter is useful when you need to split a long expression over -multiple lines. For example:

    ?Q(["case _@Expr of",
    +multiple lines. For example:

    ?Q(["case _@Expr of",
         "  {foo, X} -> f(X);",
         "  {bar, X} -> g(X)",
         "  _ -> h(X)"
    -"end"])

    If there is a syntax error somewhere in the text (like the missing semicolon in +"end"])

    If there is a syntax error somewhere in the text (like the missing semicolon in the second clause above) this allows Merl to generate an error message pointing to the exact line in your source code. (Just remember to comma-separate the strings in the list, otherwise Erlang will concatenate the string fragments as @@ -184,23 +184,23 @@

    uppercase character, as in _@Foo or _@_@Foo, it will become a variable on the Erlang level, and can be used to easily deconstruct and construct syntax trees:

    case Input of
    -    ?Q("{foo, _@Number}") -> ?Q("foo:bar(_@Number)");
    +    ?Q("{foo, _@Number}") -> ?Q("foo:bar(_@Number)");
         ...

    We refer to these as "automatic metavariables". If in addition the name ends with @, as in _@Foo@, the value of the variable as an Erlang term will be automatically converted to the corresponding abstract syntax tree when used to -construct a larger tree. For example, in:

    Bar = {bar, 42},
    -Foo = ?Q("{foo, _@Bar@}")

    (where Bar is just some term, not a syntax tree) the result Foo will be a +construct a larger tree. For example, in:

    Bar = {bar, 42},
    +Foo = ?Q("{foo, _@Bar@}")

    (where Bar is just some term, not a syntax tree) the result Foo will be a syntax tree representing {foo, {bar, 42}}. This avoids the need for temporary -variables in order to inject data, as in

    TmpBar = erl_syntax:abstract(Bar),
    -Foo = ?Q("{foo, _@TmpBar}")

    If the context requires an integer rather than a variable, an atom, or a string, +variables in order to inject data, as in

    TmpBar = erl_syntax:abstract(Bar),
    +Foo = ?Q("{foo, _@TmpBar}")

    If the context requires an integer rather than a variable, an atom, or a string, you cannot use the uppercase convention to mark an automatic metavariable. Instead, if the integer (without the 909-prefix and lift/glob markers) ends in a 9, the integer will become an Erlang-level variable prefixed with Q, and if it ends with 99 it will also be automatically abstracted. For example, the following will increment the arity of the exported function f:

    case Form of
    -    ?Q("-export([f/90919]).") ->
    -        Q2 = erl_syntax:concrete(Q1) + 1,
    -        ?Q("-export([f/909299]).");
    +    ?Q("-export([f/90919]).") ->
    +        Q2 = erl_syntax:concrete(Q1) + 1,
    +        ?Q("-export([f/909299]).");
         ...

    @@ -209,40 +209,40 @@

    Merl can only parse a fragment of text if it follows the basic syntactical rules of Erlang. In most places, a normal Erlang variable can be used as metavariable, -for example:

    ?Q("f(_@Arg)") = Expr

    but if you want to match on something like the name of a function, you have to -use an atom as metavariable:

    ?Q("'@Name'() -> _@@_." = Function

    (note the anonymous glob variable _@@_ to ignore the function body).

    In some contexts, only a string or an integer is allowed. For example, the +for example:

    ?Q("f(_@Arg)") = Expr

    but if you want to match on something like the name of a function, you have to +use an atom as metavariable:

    ?Q("'@Name'() -> _@@_." = Function

    (note the anonymous glob variable _@@_ to ignore the function body).

    In some contexts, only a string or an integer is allowed. For example, the directive -file(Name, Line) requires that Name is a string literal and -Line an integer literal:

    ?Q("-file(\"'@File\", 9090).") = ?Q("-file(\"foo.erl\", 42).")).

    This will extract the string literal "foo.erl" into the variable Foo. Note +Line an integer literal:

    ?Q("-file(\"'@File\", 9090).") = ?Q("-file(\"foo.erl\", 42).")).

    This will extract the string literal "foo.erl" into the variable Foo. Note the use of the anonymous variable 9090 to ignore the line number. To match and also bind a metavariable that must be an integer literal, we can use the convention of ending the integer with a 9, turning it into a Q-prefixed variable on the Erlang level (see the previous section).

    Globs

    Whenever you want to match out a number of elements in a sequence (zero or more) -rather than a fixed set of elements, you need to use a glob. For example:

    ?Q("{_@@Elements}") = ?Q({a, b, c})

    will bind Elements to the list of individual syntax trees representing the atoms +rather than a fixed set of elements, you need to use a glob. For example:

    ?Q("{_@@Elements}") = ?Q({a, b, c})

    will bind Elements to the list of individual syntax trees representing the atoms a, b, and c. This can also be used with static prefix and suffix elements -in the sequence. For example:

    ?Q("{a, b, _@@Elements}") = ?Q({a, b, c, d})

    will bind Elements to the list of the c and d subtrees, and

    ?Q("{_@@Elements, c, d}") = ?Q({a, b, c, d})

    will bind Elements to the list of the a and b subtrees. You can even use -plain metavariables in the prefix or suffix:

    ?Q("{_@First, _@@Rest}") = ?Q({a, b, c})

    or

    ?Q("{_@@_, _@Last}") = ?Q({a, b, c})

    (ignoring all but the last element). However, you cannot have two globs as part +in the sequence. For example:

    ?Q("{a, b, _@@Elements}") = ?Q({a, b, c, d})

    will bind Elements to the list of the c and d subtrees, and

    ?Q("{_@@Elements, c, d}") = ?Q({a, b, c, d})

    will bind Elements to the list of the a and b subtrees. You can even use +plain metavariables in the prefix or suffix:

    ?Q("{_@First, _@@Rest}") = ?Q({a, b, c})

    or

    ?Q("{_@@_, _@Last}") = ?Q({a, b, c})

    (ignoring all but the last element). However, you cannot have two globs as part of the same sequence.

    Lifted metavariables

    In some cases, the Erlang syntax rules make it impossible to place a -metavariable directly where you would like it. For example, you cannot write:

    ?Q("-export([_@@Name]).")

    to match out all name/arity pairs in the export list, or to insert a list of +metavariable directly where you would like it. For example, you cannot write:

    ?Q("-export([_@@Name]).")

    to match out all name/arity pairs in the export list, or to insert a list of exports in a declaration, because the Erlang parser only allows elements on the form A/I (where A is an atom and I an integer) in the export list. A variable like the above is not allowed, but neither is a single atom or integer, so '@@Name' or 909919 would not work either.

    What you have to do in such cases is to write your metavariable in a syntactically valid position, and use lifting markers to denote where it should -really apply, as in:

    ?Q("-export(['@_@Name'/0]).")

    This causes the variable to be lifted (after parsing) to the next higher level +really apply, as in:

    ?Q("-export(['@_@Name'/0]).")

    This causes the variable to be lifted (after parsing) to the next higher level in the syntax tree, replacing that entire subtree. In this case, the '@_@Name'/0 will be replaced with '@@Name', and the /0 part was just used as dummy notation and will be discarded.

    You may even need to apply lifting more than once. To match the entire export -list as a single syntax tree, you can write:

    ?Q("-export(['@__Name'/0]).")

    using two underscores, but with no glob marker this time. This will make the +list as a single syntax tree, you can write:

    ?Q("-export(['@__Name'/0]).")

    using two underscores, but with no glob marker this time. This will make the entire ['@__Name'/0] part be replaced with '@Name'.

    Sometimes, the tree structure of a code fragment is not very obvious, and parts of the structure may be invisible when printed as source code. For instance, a -simple function definition like the following:

    zero() -> 0.

    consists of the name (the atom zero), and a list of clauses containing the +simple function definition like the following:

    zero() -> 0.

    consists of the name (the atom zero), and a list of clauses containing the single clause () -> 0. The clause consists of an argument list (empty), a guard (empty), and a body (which is always a list of expressions) containing the single expression 0. This means that to match out the name and the list of clauses of any function, you'll need to use a pattern like ?Q("'@Name'() -> _@_@Body."), using a dummy clause whose body is a glob lifted one level.

    To visualize the structure of a syntax tree, you can use the function -merl:show(T), which prints a summary. For example, entering

    merl:show(merl:quote("inc(X, Y) when Y > 0 -> X + Y."))

    in the Erlang shell will print the following (where the + signs separate +merl:show(T), which prints a summary. For example, entering

    merl:show(merl:quote("inc(X, Y) when Y > 0 -> X + Y."))

    in the Erlang shell will print the following (where the + signs separate groups of subtrees on the same level):

    function: inc(X, Y) when ... -> X + Y.
       atom: inc
       +
    diff --git a/prs/8803/lib/tftp-1.2/doc/html/.build b/prs/8803/lib/tftp-1.2/doc/html/.build
    index 40e6f180c63c5..5b8ef34d32c3f 100644
    --- a/prs/8803/lib/tftp-1.2/doc/html/.build
    +++ b/prs/8803/lib/tftp-1.2/doc/html/.build
    @@ -18,7 +18,7 @@ dist/lato-latin-ext-300-normal-VPGGJKJL.woff2
     dist/lato-latin-ext-400-normal-N27NCBWW.woff2
     dist/lato-latin-ext-700-normal-Q2L5DVMW.woff2
     dist/remixicon-NKANDIL5.woff2
    -dist/search_data-AF02D849.js
    +dist/search_data-C5EAE448.js
     dist/sidebar_items-C15E3309.js
     getting_started.html
     index.html
    diff --git a/prs/8803/lib/tftp-1.2/doc/html/dist/search_data-AF02D849.js b/prs/8803/lib/tftp-1.2/doc/html/dist/search_data-AF02D849.js
    deleted file mode 100644
    index d065014d58277..0000000000000
    --- a/prs/8803/lib/tftp-1.2/doc/html/dist/search_data-AF02D849.js
    +++ /dev/null
    @@ -1 +0,0 @@
    -searchData={"items":[{"type":"behaviour","title":"tftp","doc":"Trivial FTP.\n\nInterface module for the `tftp` application.","ref":"tftp.html"},{"type":"behaviour","title":"Overwiew - tftp","doc":"This is a complete implementation of the following IETF standards:\n    RFC 1350, The TFTP Protocol (revision 2).\n    RFC 2347, TFTP Option Extension.\n    RFC 2348, TFTP Blocksize Option.\n    RFC 2349, TFTP Timeout Interval and Transfer Size Options.\n\nThe only feature that not is implemented in this release is\nthe \"netascii\" transfer mode.\n\nThe [start](`start/1`) function starts a daemon process which, listens\nfor UDP packets on a port. When it receives a request for read or\nwrite it spawns a temporary server process which handles the actual\ntransfer of the file. On the client side the\n[read_file/3](`read_file/3`) and [write_file/3](`write_file/3`)\nfunctions spawns a temporary client process which establishes contact\nwith a TFTP daemon and performs the actual transfer of the file.\n\nMost of the options are common for both the client and the server\nside, but some of them differs a little.","ref":"tftp.html#module-overwiew"},{"type":"behaviour","title":"Callbacks - tftp","doc":"A `tftp` callback module is to be implemented as a `tftp` behavior and export\nthe functions listed in the following.\n\nOn the server side, the callback interaction starts with a call to `open/5` with\nthe registered initial callback state. `open/5` is expected to open the\n(virtual) file. Then either function [`Module:read/1`](`c:read/1`) or\n[`Module:write/2`](`c:write/2`) is invoked repeatedly, once per transferred block. At\neach function call, the state returned from the previous call is obtained. When\nthe last block is encountered, function [`Module:read/1`](`c:read/1`) or\n[`Module:write/2`](`c:write/2`) is expected to close the (virtual) file and return its\nlast state. Function [`Module:abort/3`](`c:abort/3`) is only used in error situations.\nFunction `prepare/5` is not used on the server side.\n\nOn the client side, the callback interaction is the same, but it starts and ends\na bit differently. It starts with a call to `prepare/5` with the same arguments\nas `open/5` takes. `prepare/5` is expected to validate the TFTP options\nsuggested by the user and to return the subset of them that it accepts. Then the\noptions are sent to the server, which performs the same TFTP option negotiation\nprocedure. The options that are accepted by the server are forwarded to function\n`open/5` on the client side. On the client side, function `open/5` must accept\nall option as-is or reject the transfer. Then the callback interaction follows\nthe same pattern as described for the server side. When the last block is\nencountered in [`Module:read/1`](`c:read/1`) or [`Module:write/2`](`c:write/2`), the returned\nstate is forwarded to the user and returned from `read_file`/3 or\n[`write_file/3`](`write_file/3`).\n\nIf a callback (performing the file access in the TFTP server) takes too long\ntime (more than the double TFTP time-out), the server aborts the connection and\nsends an error reply to the client. The server simply\nassumes that the client has given up.\n\nIf the TFTP server receives yet another request from the same client (same host\nand port) while it already has an active connection to the client, it ignores\nthe new request if the request is equal to the first one (same filename and\noptions). This implies that the (new) client will be served by the already\nongoing connection on the server side. By not setting up yet another connection,\nin parallel with the ongoing one, the server consumes less resources.\n\n[](){: #prepare }","ref":"tftp.html#module-callbacks"},{"type":"callback","title":"tftp.abort/3","doc":"Invoked when the file transfer is aborted.\n\nThe callback function is expected to clean up its used resources after the\naborted file transfer, such as closing open file descriptors and so on. The\nfunction is not invoked if any of the other callback functions returns an error,\nas it is expected that they already have cleaned up the necessary resources.\nHowever, it is invoked if the functions fail (crash).","ref":"tftp.html#c:abort/3"},{"type":"function","title":"tftp.change_config/2","doc":"Changes configuration a TFTP Server","ref":"tftp.html#change_config/2"},{"type":"function","title":"tftp.info/1","doc":"Returns information about all TFTP server.","ref":"tftp.html#info/1"},{"type":"callback","title":"tftp.open/6","doc":"Opens a file for read or write access.\n\nOn the client side, where the `open/5` call has been preceded by a call to\n`prepare/5`, all options must be accepted or rejected.\n\nOn the server side, where there is no preceding `prepare/5` call, no new options\ncan be added, but those present in `SuggestedOptions` can be omitted or replaced\nwith new values in `AcceptedOptions`.\n\n[](){: #read }","ref":"tftp.html#c:open/6"},{"type":"callback","title":"tftp.prepare/6","doc":"Prepares to open a file on the client side.\n\nNo new options can be added, but those present in `SuggestedOptions` can be\nomitted or replaced with new values in `AcceptedOptions`.\n\nThis is followed by a call to `open/4` before any read/write access is\nperformed. `AcceptedOptions` is sent to the server, which replies with the\noptions that it accepts. These are then forwarded to `open/4` as\n`SuggestedOptions`.\n\n[](){: #open }","ref":"tftp.html#c:prepare/6"},{"type":"callback","title":"tftp.read/1","doc":"Reads a chunk from the file.\n\nThe callback function is expected to close the file when the last file chunk is\nencountered. When an error is encountered, the callback function is expected to\nclean up after the aborted file transfer, such as closing open file descriptors,\nand so on. In both cases there will be no more calls to any of the callback\nfunctions.\n\n[](){: #write }","ref":"tftp.html#c:read/1"},{"type":"function","title":"tftp.read_file/3","doc":"Reads a (virtual) file `RemoteFilename` from a TFTP server.\n\nIf `LocalFilename` is the atom `binary`, `tftp_binary` is used as callback\nmodule. It concatenates all transferred blocks and returns them as one single\nbinary in `LastCallbackState`.\n\nIf `LocalFilename` is a string and there are no registered callback modules,\n`tftp_file` is used as callback module. It writes each transferred block to the\nfile named `LocalFilename` and returns the number of transferred bytes in\n`LastCallbackState`.\n\nIf `LocalFilename` is a string and there are registered callback modules,\n`LocalFilename` is tested against the regexps of these and the callback module\ncorresponding to the first match is used, or an error tuple is returned if no\nmatching regexp is found.","ref":"tftp.html#read_file/3"},{"type":"function","title":"tftp.start/1","doc":"Starts a daemon process listening for UDP packets on a port.\n\nWhen it receives a request for read or write, it spawns a temporary\nserver process handling the actual transfer of the (virtual) file.","ref":"tftp.html#start/1"},{"type":"callback","title":"tftp.write/2","doc":"Writes a chunk to the file.\n\nThe callback function is expected to close the file when the last file chunk is\nencountered. When an error is encountered, the callback function is expected to\nclean up after the aborted file transfer, such as closing open file descriptors,\nand so on. In both cases there will be no more calls to any of the callback\nfunctions.\n\n[](){: #abort }","ref":"tftp.html#c:write/2"},{"type":"function","title":"tftp.write_file/3","doc":"Writes a (virtual) file `RemoteFilename` to a TFTP server.\n\nIf `LocalFilename` is a binary, `tftp_binary` is used as callback module. The\nbinary is transferred block by block and the number of transferred bytes is\nreturned in `LastCallbackState`.\n\nIf `LocalFilename` is a string and there are no registered callback modules,\n`tftp_file` is used as callback module. It reads the file named `LocalFilename`\nblock by block and returns the number of transferred bytes in\n`LastCallbackState`.\n\nIf `LocalFilename` is a string and there are registered callback modules,\n`LocalFilename` is tested against the regexps of these and the callback module\ncorresponding to the first match is used, or an error tuple is returned if no\nmatching regexp is found.","ref":"tftp.html#write_file/3"},{"type":"type","title":"tftp.access/0","doc":"Access mode.","ref":"tftp.html#t:access/0"},{"type":"type","title":"tftp.connection_option/0","doc":"All options most of them common to the client and server.\n\n- **`{debug, Level::none | error | warning | brief | normal | verbose | all}`**\n\n  Controls the level of debug printouts. Default is `none`.\n\n- **`{host, Host::inet:hostname()}`** -\n\n  The name or IP address of the host where the TFTP daemon resides. This option\n  is only used by the client.\n\n- **`{port, Port::inet:port_number()}`**\n\n  The TFTP port where the daemon listens. Defaults is the standardized\n  number 69. On the server side, it can sometimes make sense to set it to 0,\n  meaning that the daemon just picks a free port (which one is returned by\n  function [`info/1`](`info/1`)).\n\n  If a socket is connected already, option `{udp, [{fd, integer()}]}` can be\n  used to pass the open file descriptor to `gen_udp`. This can be automated by\n  using a command-line argument stating the prebound file descriptor number. For\n  example, if the port is 69 and file descriptor 22 is opened by\n  `setuid_socket_wrap`, the command-line argument \"-tftpd_69 22\" triggers the\n  prebound file descriptor 22 to be used instead of opening port 69. The UDP\n  option `{udp, [{fd, 22}]}` is automatically added. See `init:get_argument/`\n  about command-line arguments and `gen_udp:open/2` about UDP options.\n\n- **`{port_policy, random | inet:port_number() | {range, Min::inet:port_number(), Max::inet:port_nuber()}`**\n\n  Policy for the selection of the temporary port that is used by the\n  server/client during the file transfer. Default is `random`, which is the\n  standardized policy. With this policy a randomized free port is used. A single\n  port or a range of ports can be useful if the protocol passes through a\n  firewall.\n\n- **`{udp, Options::gen_udp:option}`**\n\n- **`{use_tsize, boolean()}`**\n\n  Flag for automated use of option `tsize`. With this set to `true`, the\n  [`write_file/3`](`write_file/3`) client determines the filesize and sends it\n  to the server as the standardized `tsize` option. A\n  [`read_file/3`](`read_file/3`) client acquires only a filesize from the server\n  by sending a zero `tsize`.\n\n- **`{max_tsize, MaxTsize::pos_integer() | infinity}`**\n\n  Threshold for the maximal filesize in bytes. The transfer is aborted if the\n  limit is exceeded. Default is `infinity`.\n\n- **`{max_conn, MaxConn::pos_integer() | infinity}`**\n\n  Threshold for the maximal number of active connections. The daemon rejects the\n  setup of new connections if the limit is exceeded. Default is `infinity`.\n\n- **TftpOption::option()**\n\n  Name and value of a TFTP option.\n\n- **`{reject, Feature:: access() | TftpKey::string()}`**\n\n  Controls which features to reject. This is mostly useful for the server as it\n  can restrict the use of certain TFTP options or read/write access.\n\n- **`{callback, {RegExp ::string(), Module::module(), State :: term()}}`**\n\n  Registration of a callback module. When a file is to be transferred, its local\n  filename is matched to the regular expressions of the registered callbacks.\n  The first matching callback is used during the transfer. See `read_file/3` and\n  `write_file/3`.\n\n  The callback module must implement the `tftp` behavior, see\n  [callbacks](`m:tftp#callbacks`).\n\n- **`{logger, module()}`**\n\n  Callback module for customized logging of errors, warnings, and info messages.\n  The callback module must implement the `m:tftp_logger` behavior. The default\n  module is `tftp_logger`.\n\n- **`{max_retries, MaxRetries::non_neg_integer()}`**\n\n  Threshold for the maximal number of retries. By default the server/client\n  tries to resend a message up to five times when the time-out expires.","ref":"tftp.html#t:connection_option/0"},{"type":"type","title":"tftp.error_code/0","doc":"Error reason codes.","ref":"tftp.html#t:error_code/0"},{"type":"type","title":"tftp.option/0","doc":"Specific TFTP protocol options","ref":"tftp.html#t:option/0"},{"type":"type","title":"tftp.peer/0","doc":"Information about the peer provided for callback.","ref":"tftp.html#t:peer/0"},{"type":"behaviour","title":"tftp_logger","doc":"Trivial FTP logger.\n\nA `tftp_logger` callback module is to be implemented as a `tftp_logger` behavior\nand export the following functions:","ref":"tftp_logger.html"},{"type":"callback","title":"tftp_logger.error_msg/2","doc":"Logs an error message. See `logger:error/2` for details.","ref":"tftp_logger.html#c:error_msg/2"},{"type":"callback","title":"tftp_logger.info_msg/2","doc":"Logs an info message. See `logger:info/2` for details.","ref":"tftp_logger.html#c:info_msg/2"},{"type":"callback","title":"tftp_logger.warning_msg/2","doc":"Logs a warning message. See `logger:warning/2` for details.","ref":"tftp_logger.html#c:warning_msg/2"},{"type":"extras","title":"TFTP Release Notes","doc":"\n# TFTP Release Notes","ref":"notes.html"},{"type":"extras","title":"Tftp 1.2 - TFTP Release Notes","doc":"","ref":"notes.html#tftp-1-2"},{"type":"extras","title":"Improvements and New Features - TFTP Release Notes","doc":"- There is a new [`tftp_logger`](`m:tftp_logger`) callback behavior module.\n\n  Own Id: OTP-18787 Aux Id: [PR-7700]\n\n- The documentation has been migrated to use Markdown and ExDoc.\n\n  Own Id: OTP-18955 Aux Id: [PR-8026]\n\n[PR-7700]: https://github.com/erlang/otp/pull/7700\n[PR-8026]: https://github.com/erlang/otp/pull/8026","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tftp 1.1.1 - TFTP Release Notes","doc":"","ref":"notes.html#tftp-1-1-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - TFTP Release Notes","doc":"- Replaced unintentional Erlang Public License 1.1 headers in some files with\n  the intended Apache License 2.0 header.\n\n  Own Id: OTP-18815 Aux Id: PR-7780","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tftp 1.1 - TFTP Release Notes","doc":"","ref":"notes.html#tftp-1-1"},{"type":"extras","title":"Improvements and New Features - TFTP Release Notes","doc":"- The implementation has been fixed to use `proc_lib:init_fail/2,3` where\n  appropriate, instead of `proc_lib:init_ack/1,2`.\n\n  \\*** POTENTIAL INCOMPATIBILITY \\***\n\n  Own Id: OTP-18490 Aux Id: OTP-18471, GH-6339, PR-6843","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tftp 1.0.4 - TFTP Release Notes","doc":"","ref":"notes.html#tftp-1-0-4"},{"type":"extras","title":"Improvements and New Features - TFTP Release Notes","doc":"- Replace size/1 with either tuple_size/1 or byte_size/1\n\n  The [`size/1`](`size/1`) BIF is not optimized by the JIT, and its use can\n  result in worse types for Dialyzer.\n\n  When one knows that the value being tested must be a tuple,\n  [`tuple_size/1`](`tuple_size/1`) should always be preferred.\n\n  When one knows that the value being tested must be a binary,\n  [`byte_size/1`](`byte_size/1`) should be preferred. However,\n  [`byte_size/1`](`byte_size/1`) also accepts a bitstring (rounding up size to a\n  whole number of bytes), so one must make sure that the call to `byte_size/` is\n  preceded by a call to [`is_binary/1`](`is_binary/1`) to ensure that bitstrings\n  are rejected. Note that the compiler removes redundant calls to\n  [`is_binary/1`](`is_binary/1`), so if one is not sure whether previous code\n  had made sure that the argument is a binary, it does not harm to add an\n  [`is_binary/1`](`is_binary/1`) test immediately before the call to\n  [`byte_size/1`](`byte_size/1`).\n\n  Own Id: OTP-18432 Aux Id:\n  GH-6672,PR-6793,PR-6784,PR-6787,PR-6785,PR-6682,PR-6800,PR-6797,PR-6798,PR-6799,PR-6796,PR-6813,PR-6671,PR-6673,PR-6684,PR-6694,GH-6677,PR-6696,PR-6670,PR-6674","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tftp 1.0.3 - TFTP Release Notes","doc":"","ref":"notes.html#tftp-1-0-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - TFTP Release Notes","doc":"- Missing runtime dependencies has been added to this application.\n\n  Own Id: OTP-17243 Aux Id: PR-4557","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tftp 1.0.2 - TFTP Release Notes","doc":"","ref":"notes.html#tftp-1-0-2"},{"type":"extras","title":"Improvements and New Features - TFTP Release Notes","doc":"- Removed compiler warnings.\n\n  Own Id: OTP-16317 Aux Id: OTP-16183","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tftp 1.0.1 - TFTP Release Notes","doc":"","ref":"notes.html#tftp-1-0-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - TFTP Release Notes","doc":"- Improved documentation.\n\n  Own Id: OTP-15190","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"TFTP 1.0 - TFTP Release Notes","doc":"","ref":"notes.html#tftp-1-0"},{"type":"extras","title":"First released version - TFTP Release Notes","doc":"- Inets application was split into multiple smaller protocol specific\n  applications. The TFTP application is a standalone TFTP client and server with\n  the same functionality as TFTP in Inets.\n\n  Own Id: OTP-14113","ref":"notes.html#first-released-version"},{"type":"extras","title":"Overview","doc":"\n# Overview\n\nTrivial File Transfer Protocol (TFTP) is a very simple protocol used\nto transfer files over the transport datagram protocol UDP.\n\nOn the client side, function [read_file/3](`tftp:read_file/3`) and\n[write_file/3](`tftp:write_file/3`) spawn a temporary client process\nestablishing contact with a TFTP daemon and perform the file transfer.\n\n`tftp` uses a callback module to handle the file transfer. Two such callback\nmodules are provided, `tftp_binary` and `tftp_file`. See\n[read_file/3](`tftp:read_file/3`) and [write_file/3](`tftp:write_file/3`) for\ndetails. You can also implement your own callback modules, see\n[callbacks](`m:tftp#callbacks`).\n\n# Security Considerations\n\nAs stated in ([RFC 1350](https://datatracker.ietf.org/doc/html/rfc1350))\nbe aware that \"Since TFTP includes no login or access\ncontrol mechanisms, care must be taken in the rights granted to a TFTP\nserver process so as not to violate the security of the server hosts\nfile system.  TFTP is often installed with controls such that only\nfiles that have public read access are available via TFTP and writing\nfiles via TFTP is disallowed.\"","ref":"introduction.html"},{"type":"extras","title":"Examples","doc":"\n# Examples\n\n\nThe [start/1](`tftp:start/1`) function starts a daemon process listening for UDP\npackets on a port. When it receives a request for read or write, it spawns a\ntemporary server process handling the transfer.\n\nThis is a simple example of starting the TFTP server and reading the content of\na sample file using the TFTP client.\n\n_Step 1._ Create a sample file to be used for the transfer:\n\n```text\n      $ echo \"Erlang/OTP 21\" > file.txt\n```\n\n_Step 2._ Start the TFTP server:\n\n```erlang\n      1> {ok, Pid} = tftp:start([{port, 19999}]).\n      {ok,<0.65.0>}\n```\n\n_Step 3._ Start the TFTP client (in another shell):\n\n```erlang\n      1> tftp:read_file(\"file.txt\", binary, [{port, 19999}]).\n      {ok,<<\"Erlang/OTP 21\\n\">>}\n```","ref":"getting_started.html"}],"content_type":"text/plain","producer":{"name":"ex_doc","version":[48,46,51,52,46,49]}}
    \ No newline at end of file
    diff --git a/prs/8803/lib/tftp-1.2/doc/html/dist/search_data-C5EAE448.js b/prs/8803/lib/tftp-1.2/doc/html/dist/search_data-C5EAE448.js
    new file mode 100644
    index 0000000000000..96339b4084a9f
    --- /dev/null
    +++ b/prs/8803/lib/tftp-1.2/doc/html/dist/search_data-C5EAE448.js
    @@ -0,0 +1 @@
    +searchData={"items":[{"type":"behaviour","doc":"Trivial FTP.\n\nInterface module for the `tftp` application.","title":"tftp","ref":"tftp.html"},{"type":"behaviour","doc":"This is a complete implementation of the following IETF standards:\n    RFC 1350, The TFTP Protocol (revision 2).\n    RFC 2347, TFTP Option Extension.\n    RFC 2348, TFTP Blocksize Option.\n    RFC 2349, TFTP Timeout Interval and Transfer Size Options.\n\nThe only feature that not is implemented in this release is\nthe \"netascii\" transfer mode.\n\nThe [start](`start/1`) function starts a daemon process which, listens\nfor UDP packets on a port. When it receives a request for read or\nwrite it spawns a temporary server process which handles the actual\ntransfer of the file. On the client side the\n[read_file/3](`read_file/3`) and [write_file/3](`write_file/3`)\nfunctions spawns a temporary client process which establishes contact\nwith a TFTP daemon and performs the actual transfer of the file.\n\nMost of the options are common for both the client and the server\nside, but some of them differs a little.","title":"Overwiew - tftp","ref":"tftp.html#module-overwiew"},{"type":"behaviour","doc":"A `tftp` callback module is to be implemented as a `tftp` behavior and export\nthe functions listed in the following.\n\nOn the server side, the callback interaction starts with a call to `open/5` with\nthe registered initial callback state. `open/5` is expected to open the\n(virtual) file. Then either function [`Module:read/1`](`c:read/1`) or\n[`Module:write/2`](`c:write/2`) is invoked repeatedly, once per transferred block. At\neach function call, the state returned from the previous call is obtained. When\nthe last block is encountered, function [`Module:read/1`](`c:read/1`) or\n[`Module:write/2`](`c:write/2`) is expected to close the (virtual) file and return its\nlast state. Function [`Module:abort/3`](`c:abort/3`) is only used in error situations.\nFunction `prepare/5` is not used on the server side.\n\nOn the client side, the callback interaction is the same, but it starts and ends\na bit differently. It starts with a call to `prepare/5` with the same arguments\nas `open/5` takes. `prepare/5` is expected to validate the TFTP options\nsuggested by the user and to return the subset of them that it accepts. Then the\noptions are sent to the server, which performs the same TFTP option negotiation\nprocedure. The options that are accepted by the server are forwarded to function\n`open/5` on the client side. On the client side, function `open/5` must accept\nall option as-is or reject the transfer. Then the callback interaction follows\nthe same pattern as described for the server side. When the last block is\nencountered in [`Module:read/1`](`c:read/1`) or [`Module:write/2`](`c:write/2`), the returned\nstate is forwarded to the user and returned from `read_file`/3 or\n[`write_file/3`](`write_file/3`).\n\nIf a callback (performing the file access in the TFTP server) takes too long\ntime (more than the double TFTP time-out), the server aborts the connection and\nsends an error reply to the client. The server simply\nassumes that the client has given up.\n\nIf the TFTP server receives yet another request from the same client (same host\nand port) while it already has an active connection to the client, it ignores\nthe new request if the request is equal to the first one (same filename and\noptions). This implies that the (new) client will be served by the already\nongoing connection on the server side. By not setting up yet another connection,\nin parallel with the ongoing one, the server consumes less resources.\n\n[](){: #prepare }","title":"Callbacks - tftp","ref":"tftp.html#module-callbacks"},{"type":"callback","doc":"Invoked when the file transfer is aborted.\n\nThe callback function is expected to clean up its used resources after the\naborted file transfer, such as closing open file descriptors and so on. The\nfunction is not invoked if any of the other callback functions returns an error,\nas it is expected that they already have cleaned up the necessary resources.\nHowever, it is invoked if the functions fail (crash).","title":"tftp.abort/3","ref":"tftp.html#c:abort/3"},{"type":"function","doc":"Changes configuration a TFTP Server","title":"tftp.change_config/2","ref":"tftp.html#change_config/2"},{"type":"function","doc":"Returns information about all TFTP server.","title":"tftp.info/1","ref":"tftp.html#info/1"},{"type":"callback","doc":"Opens a file for read or write access.\n\nOn the client side, where the `open/5` call has been preceded by a call to\n`prepare/5`, all options must be accepted or rejected.\n\nOn the server side, where there is no preceding `prepare/5` call, no new options\ncan be added, but those present in `SuggestedOptions` can be omitted or replaced\nwith new values in `AcceptedOptions`.\n\n[](){: #read }","title":"tftp.open/6","ref":"tftp.html#c:open/6"},{"type":"callback","doc":"Prepares to open a file on the client side.\n\nNo new options can be added, but those present in `SuggestedOptions` can be\nomitted or replaced with new values in `AcceptedOptions`.\n\nThis is followed by a call to `open/4` before any read/write access is\nperformed. `AcceptedOptions` is sent to the server, which replies with the\noptions that it accepts. These are then forwarded to `open/4` as\n`SuggestedOptions`.\n\n[](){: #open }","title":"tftp.prepare/6","ref":"tftp.html#c:prepare/6"},{"type":"callback","doc":"Reads a chunk from the file.\n\nThe callback function is expected to close the file when the last file chunk is\nencountered. When an error is encountered, the callback function is expected to\nclean up after the aborted file transfer, such as closing open file descriptors,\nand so on. In both cases there will be no more calls to any of the callback\nfunctions.\n\n[](){: #write }","title":"tftp.read/1","ref":"tftp.html#c:read/1"},{"type":"function","doc":"Reads a (virtual) file `RemoteFilename` from a TFTP server.\n\nIf `LocalFilename` is the atom `binary`, `tftp_binary` is used as callback\nmodule. It concatenates all transferred blocks and returns them as one single\nbinary in `LastCallbackState`.\n\nIf `LocalFilename` is a string and there are no registered callback modules,\n`tftp_file` is used as callback module. It writes each transferred block to the\nfile named `LocalFilename` and returns the number of transferred bytes in\n`LastCallbackState`.\n\nIf `LocalFilename` is a string and there are registered callback modules,\n`LocalFilename` is tested against the regexps of these and the callback module\ncorresponding to the first match is used, or an error tuple is returned if no\nmatching regexp is found.","title":"tftp.read_file/3","ref":"tftp.html#read_file/3"},{"type":"function","doc":"Starts a daemon process listening for UDP packets on a port.\n\nWhen it receives a request for read or write, it spawns a temporary\nserver process handling the actual transfer of the (virtual) file.","title":"tftp.start/1","ref":"tftp.html#start/1"},{"type":"callback","doc":"Writes a chunk to the file.\n\nThe callback function is expected to close the file when the last file chunk is\nencountered. When an error is encountered, the callback function is expected to\nclean up after the aborted file transfer, such as closing open file descriptors,\nand so on. In both cases there will be no more calls to any of the callback\nfunctions.\n\n[](){: #abort }","title":"tftp.write/2","ref":"tftp.html#c:write/2"},{"type":"function","doc":"Writes a (virtual) file `RemoteFilename` to a TFTP server.\n\nIf `LocalFilename` is a binary, `tftp_binary` is used as callback module. The\nbinary is transferred block by block and the number of transferred bytes is\nreturned in `LastCallbackState`.\n\nIf `LocalFilename` is a string and there are no registered callback modules,\n`tftp_file` is used as callback module. It reads the file named `LocalFilename`\nblock by block and returns the number of transferred bytes in\n`LastCallbackState`.\n\nIf `LocalFilename` is a string and there are registered callback modules,\n`LocalFilename` is tested against the regexps of these and the callback module\ncorresponding to the first match is used, or an error tuple is returned if no\nmatching regexp is found.","title":"tftp.write_file/3","ref":"tftp.html#write_file/3"},{"type":"type","doc":"Access mode.","title":"tftp.access/0","ref":"tftp.html#t:access/0"},{"type":"type","doc":"All options most of them common to the client and server.\n\n- **`{debug, Level::none | error | warning | brief | normal | verbose | all}`**\n\n  Controls the level of debug printouts. Default is `none`.\n\n- **`{host, Host::inet:hostname()}`** -\n\n  The name or IP address of the host where the TFTP daemon resides. This option\n  is only used by the client.\n\n- **`{port, Port::inet:port_number()}`**\n\n  The TFTP port where the daemon listens. Defaults is the standardized\n  number 69. On the server side, it can sometimes make sense to set it to 0,\n  meaning that the daemon just picks a free port (which one is returned by\n  function [`info/1`](`info/1`)).\n\n  If a socket is connected already, option `{udp, [{fd, integer()}]}` can be\n  used to pass the open file descriptor to `gen_udp`. This can be automated by\n  using a command-line argument stating the prebound file descriptor number. For\n  example, if the port is 69 and file descriptor 22 is opened by\n  `setuid_socket_wrap`, the command-line argument \"-tftpd_69 22\" triggers the\n  prebound file descriptor 22 to be used instead of opening port 69. The UDP\n  option `{udp, [{fd, 22}]}` is automatically added. See `init:get_argument/`\n  about command-line arguments and `gen_udp:open/2` about UDP options.\n\n- **`{port_policy, random | inet:port_number() | {range, Min::inet:port_number(), Max::inet:port_nuber()}`**\n\n  Policy for the selection of the temporary port that is used by the\n  server/client during the file transfer. Default is `random`, which is the\n  standardized policy. With this policy a randomized free port is used. A single\n  port or a range of ports can be useful if the protocol passes through a\n  firewall.\n\n- **`{udp, Options::gen_udp:option}`**\n\n- **`{use_tsize, boolean()}`**\n\n  Flag for automated use of option `tsize`. With this set to `true`, the\n  [`write_file/3`](`write_file/3`) client determines the filesize and sends it\n  to the server as the standardized `tsize` option. A\n  [`read_file/3`](`read_file/3`) client acquires only a filesize from the server\n  by sending a zero `tsize`.\n\n- **`{max_tsize, MaxTsize::pos_integer() | infinity}`**\n\n  Threshold for the maximal filesize in bytes. The transfer is aborted if the\n  limit is exceeded. Default is `infinity`.\n\n- **`{max_conn, MaxConn::pos_integer() | infinity}`**\n\n  Threshold for the maximal number of active connections. The daemon rejects the\n  setup of new connections if the limit is exceeded. Default is `infinity`.\n\n- **TftpOption::option()**\n\n  Name and value of a TFTP option.\n\n- **`{reject, Feature:: access() | TftpKey::string()}`**\n\n  Controls which features to reject. This is mostly useful for the server as it\n  can restrict the use of certain TFTP options or read/write access.\n\n- **`{callback, {RegExp ::string(), Module::module(), State :: term()}}`**\n\n  Registration of a callback module. When a file is to be transferred, its local\n  filename is matched to the regular expressions of the registered callbacks.\n  The first matching callback is used during the transfer. See `read_file/3` and\n  `write_file/3`.\n\n  The callback module must implement the `tftp` behavior, see\n  [callbacks](`m:tftp#callbacks`).\n\n- **`{logger, module()}`**\n\n  Callback module for customized logging of errors, warnings, and info messages.\n  The callback module must implement the `m:tftp_logger` behavior. The default\n  module is `tftp_logger`.\n\n- **`{max_retries, MaxRetries::non_neg_integer()}`**\n\n  Threshold for the maximal number of retries. By default the server/client\n  tries to resend a message up to five times when the time-out expires.","title":"tftp.connection_option/0","ref":"tftp.html#t:connection_option/0"},{"type":"type","doc":"Error reason codes.","title":"tftp.error_code/0","ref":"tftp.html#t:error_code/0"},{"type":"type","doc":"Specific TFTP protocol options","title":"tftp.option/0","ref":"tftp.html#t:option/0"},{"type":"type","doc":"Information about the peer provided for callback.","title":"tftp.peer/0","ref":"tftp.html#t:peer/0"},{"type":"behaviour","doc":"Trivial FTP logger.\n\nA `tftp_logger` callback module is to be implemented as a `tftp_logger` behavior\nand export the following functions:","title":"tftp_logger","ref":"tftp_logger.html"},{"type":"callback","doc":"Logs an error message. See `logger:error/2` for details.","title":"tftp_logger.error_msg/2","ref":"tftp_logger.html#c:error_msg/2"},{"type":"callback","doc":"Logs an info message. See `logger:info/2` for details.","title":"tftp_logger.info_msg/2","ref":"tftp_logger.html#c:info_msg/2"},{"type":"callback","doc":"Logs a warning message. See `logger:warning/2` for details.","title":"tftp_logger.warning_msg/2","ref":"tftp_logger.html#c:warning_msg/2"},{"type":"extras","doc":"\n# TFTP Release Notes","title":"TFTP Release Notes","ref":"notes.html"},{"type":"extras","doc":"","title":"Tftp 1.2 - TFTP Release Notes","ref":"notes.html#tftp-1-2"},{"type":"extras","doc":"- There is a new [`tftp_logger`](`m:tftp_logger`) callback behavior module.\n\n  Own Id: OTP-18787 Aux Id: [PR-7700]\n\n- The documentation has been migrated to use Markdown and ExDoc.\n\n  Own Id: OTP-18955 Aux Id: [PR-8026]\n\n[PR-7700]: https://github.com/erlang/otp/pull/7700\n[PR-8026]: https://github.com/erlang/otp/pull/8026","title":"Improvements and New Features - TFTP Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tftp 1.1.1 - TFTP Release Notes","ref":"notes.html#tftp-1-1-1"},{"type":"extras","doc":"- Replaced unintentional Erlang Public License 1.1 headers in some files with\n  the intended Apache License 2.0 header.\n\n  Own Id: OTP-18815 Aux Id: PR-7780","title":"Fixed Bugs and Malfunctions - TFTP Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tftp 1.1 - TFTP Release Notes","ref":"notes.html#tftp-1-1"},{"type":"extras","doc":"- The implementation has been fixed to use `proc_lib:init_fail/2,3` where\n  appropriate, instead of `proc_lib:init_ack/1,2`.\n\n  \\*** POTENTIAL INCOMPATIBILITY \\***\n\n  Own Id: OTP-18490 Aux Id: OTP-18471, GH-6339, PR-6843","title":"Improvements and New Features - TFTP Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tftp 1.0.4 - TFTP Release Notes","ref":"notes.html#tftp-1-0-4"},{"type":"extras","doc":"- Replace size/1 with either tuple_size/1 or byte_size/1\n\n  The [`size/1`](`size/1`) BIF is not optimized by the JIT, and its use can\n  result in worse types for Dialyzer.\n\n  When one knows that the value being tested must be a tuple,\n  [`tuple_size/1`](`tuple_size/1`) should always be preferred.\n\n  When one knows that the value being tested must be a binary,\n  [`byte_size/1`](`byte_size/1`) should be preferred. However,\n  [`byte_size/1`](`byte_size/1`) also accepts a bitstring (rounding up size to a\n  whole number of bytes), so one must make sure that the call to `byte_size/` is\n  preceded by a call to [`is_binary/1`](`is_binary/1`) to ensure that bitstrings\n  are rejected. Note that the compiler removes redundant calls to\n  [`is_binary/1`](`is_binary/1`), so if one is not sure whether previous code\n  had made sure that the argument is a binary, it does not harm to add an\n  [`is_binary/1`](`is_binary/1`) test immediately before the call to\n  [`byte_size/1`](`byte_size/1`).\n\n  Own Id: OTP-18432 Aux Id:\n  GH-6672,PR-6793,PR-6784,PR-6787,PR-6785,PR-6682,PR-6800,PR-6797,PR-6798,PR-6799,PR-6796,PR-6813,PR-6671,PR-6673,PR-6684,PR-6694,GH-6677,PR-6696,PR-6670,PR-6674","title":"Improvements and New Features - TFTP Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tftp 1.0.3 - TFTP Release Notes","ref":"notes.html#tftp-1-0-3"},{"type":"extras","doc":"- Missing runtime dependencies has been added to this application.\n\n  Own Id: OTP-17243 Aux Id: PR-4557","title":"Fixed Bugs and Malfunctions - TFTP Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tftp 1.0.2 - TFTP Release Notes","ref":"notes.html#tftp-1-0-2"},{"type":"extras","doc":"- Removed compiler warnings.\n\n  Own Id: OTP-16317 Aux Id: OTP-16183","title":"Improvements and New Features - TFTP Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tftp 1.0.1 - TFTP Release Notes","ref":"notes.html#tftp-1-0-1"},{"type":"extras","doc":"- Improved documentation.\n\n  Own Id: OTP-15190","title":"Fixed Bugs and Malfunctions - TFTP Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"TFTP 1.0 - TFTP Release Notes","ref":"notes.html#tftp-1-0"},{"type":"extras","doc":"- Inets application was split into multiple smaller protocol specific\n  applications. The TFTP application is a standalone TFTP client and server with\n  the same functionality as TFTP in Inets.\n\n  Own Id: OTP-14113","title":"First released version - TFTP Release Notes","ref":"notes.html#first-released-version"},{"type":"extras","doc":"\n# Overview\n\nTrivial File Transfer Protocol (TFTP) is a very simple protocol used\nto transfer files over the transport datagram protocol UDP.\n\nOn the client side, function [read_file/3](`tftp:read_file/3`) and\n[write_file/3](`tftp:write_file/3`) spawn a temporary client process\nestablishing contact with a TFTP daemon and perform the file transfer.\n\n`tftp` uses a callback module to handle the file transfer. Two such callback\nmodules are provided, `tftp_binary` and `tftp_file`. See\n[read_file/3](`tftp:read_file/3`) and [write_file/3](`tftp:write_file/3`) for\ndetails. You can also implement your own callback modules, see\n[callbacks](`m:tftp#callbacks`).\n\n# Security Considerations\n\nAs stated in ([RFC 1350](https://datatracker.ietf.org/doc/html/rfc1350))\nbe aware that \"Since TFTP includes no login or access\ncontrol mechanisms, care must be taken in the rights granted to a TFTP\nserver process so as not to violate the security of the server hosts\nfile system.  TFTP is often installed with controls such that only\nfiles that have public read access are available via TFTP and writing\nfiles via TFTP is disallowed.\"","title":"Overview","ref":"introduction.html"},{"type":"extras","doc":"\n# Examples\n\n\nThe [start/1](`tftp:start/1`) function starts a daemon process listening for UDP\npackets on a port. When it receives a request for read or write, it spawns a\ntemporary server process handling the transfer.\n\nThis is a simple example of starting the TFTP server and reading the content of\na sample file using the TFTP client.\n\n_Step 1._ Create a sample file to be used for the transfer:\n\n```text\n      $ echo \"Erlang/OTP 21\" > file.txt\n```\n\n_Step 2._ Start the TFTP server:\n\n```erlang\n      1> {ok, Pid} = tftp:start([{port, 19999}]).\n      {ok,<0.65.0>}\n```\n\n_Step 3._ Start the TFTP client (in another shell):\n\n```erlang\n      1> tftp:read_file(\"file.txt\", binary, [{port, 19999}]).\n      {ok,<<\"Erlang/OTP 21\\n\">>}\n```","title":"Examples","ref":"getting_started.html"}],"content_type":"text/plain","producer":{"name":"ex_doc","version":[48,46,51,52,46,49]}}
    \ No newline at end of file
    diff --git a/prs/8803/lib/tftp-1.2/doc/html/getting_started.html b/prs/8803/lib/tftp-1.2/doc/html/getting_started.html
    index 416ed2657d741..48447bf24f797 100644
    --- a/prs/8803/lib/tftp-1.2/doc/html/getting_started.html
    +++ b/prs/8803/lib/tftp-1.2/doc/html/getting_started.html
    @@ -128,9 +128,9 @@ 

    The start/1 function starts a daemon process listening for UDP packets on a port. When it receives a request for read or write, it spawns a temporary server process handling the transfer.

    This is a simple example of starting the TFTP server and reading the content of -a sample file using the TFTP client.

    Step 1. Create a sample file to be used for the transfer:

          $ echo "Erlang/OTP 21" > file.txt

    Step 2. Start the TFTP server:

          1> {ok, Pid} = tftp:start([{port, 19999}]).
    -      {ok,<0.65.0>}

    Step 3. Start the TFTP client (in another shell):

          1> tftp:read_file("file.txt", binary, [{port, 19999}]).
    -      {ok,<<"Erlang/OTP 21\n">>}
    +a sample file using the TFTP client.

    Step 1. Create a sample file to be used for the transfer:

          $ echo "Erlang/OTP 21" > file.txt

    Step 2. Start the TFTP server:

          1> {ok, Pid} = tftp:start([{port, 19999}]).
    +      {ok,<0.65.0>}

    Step 3. Start the TFTP client (in another shell):

          1> tftp:read_file("file.txt", binary, [{port, 19999}]).
    +      {ok,<<"Erlang/OTP 21\n">>}
    diff --git a/prs/8803/lib/tftp-1.2/doc/html/search.html b/prs/8803/lib/tftp-1.2/doc/html/search.html index 614e314ff1895..731da8f09d112 100644 --- a/prs/8803/lib/tftp-1.2/doc/html/search.html +++ b/prs/8803/lib/tftp-1.2/doc/html/search.html @@ -122,7 +122,7 @@

    - +

    diff --git a/prs/8803/lib/tftp-1.2/doc/html/tftp.epub b/prs/8803/lib/tftp-1.2/doc/html/tftp.epub index 9064cac49f4b4..30fdc1366a7c6 100644 Binary files a/prs/8803/lib/tftp-1.2/doc/html/tftp.epub and b/prs/8803/lib/tftp-1.2/doc/html/tftp.epub differ diff --git a/prs/8803/lib/tftp-1.2/doc/html/tftp.html b/prs/8803/lib/tftp-1.2/doc/html/tftp.html index c950a1872cf30..4191a47e6b7eb 100644 --- a/prs/8803/lib/tftp-1.2/doc/html/tftp.html +++ b/prs/8803/lib/tftp-1.2/doc/html/tftp.html @@ -134,7 +134,7 @@

    Overwiew

    -

    This is a complete implementation of the following IETF standards:

    RFC 1350, The TFTP Protocol (revision 2).
    +

    This is a complete implementation of the following IETF standards:

    RFC 1350, The TFTP Protocol (revision 2).
     RFC 2347, TFTP Option Extension.
     RFC 2348, TFTP Blocksize Option.
     RFC 2349, TFTP Timeout Interval and Transfer Size Options.

    The only feature that not is implemented in this release is diff --git a/prs/8803/lib/tools-4.0/doc/html/.build b/prs/8803/lib/tools-4.0/doc/html/.build index 4d9ea5e3dbece..8dd2e03946912 100644 --- a/prs/8803/lib/tools-4.0/doc/html/.build +++ b/prs/8803/lib/tools-4.0/doc/html/.build @@ -25,7 +25,7 @@ dist/lato-latin-ext-300-normal-VPGGJKJL.woff2 dist/lato-latin-ext-400-normal-N27NCBWW.woff2 dist/lato-latin-ext-700-normal-Q2L5DVMW.woff2 dist/remixicon-NKANDIL5.woff2 -dist/search_data-8780CEA5.js +dist/search_data-536C0AEB.js dist/sidebar_items-7275BB77.js eprof.html erlang-el.html diff --git a/prs/8803/lib/tools-4.0/doc/html/cover.html b/prs/8803/lib/tools-4.0/doc/html/cover.html index 71034e9dee566..ad7599cd5d920 100644 --- a/prs/8803/lib/tools-4.0/doc/html/cover.html +++ b/prs/8803/lib/tools-4.0/doc/html/cover.html @@ -1561,7 +1561,7 @@

    analyse(Arg)

    call is equivalent to analyse('_', coverage, Arg).

    Otherwise Arg is assumed to be a module name, and this call is equivalent to analyse(Arg, coverage, function).

    Note

    To analyze a module whose name overlaps with one the values in analysis() or level(), the module -name has to be in a list. For example, to analyze a module named calls:

    cover:analyse([calls]).
    +name has to be in a list. For example, to analyze a module named calls:

    cover:analyse([calls]).

    @@ -1603,7 +1603,7 @@

    analyse(Arg1, Arg2)

    analyse(Arg1, Arg2, function).

    If Arg2 is one of the values in level(), Arg1 is assumed to be a module and this call is equivalent to analyse(Arg1, coverage, Arg2).

    Note

    To analyze a module whose name overlaps with one of the values in analysis(), the module name needs to be in a -list. For example, to analyze a module named calls:

    cover:analyse([calls], function).
    +list. For example, to analyze a module named calls:

    cover:analyse([calls], function).
    @@ -1712,7 +1712,7 @@

    analyse_to_file(Arg)

    options, this call is equivalent to analyse_to_file('_', Arg).

    Otherwise Arg is assumed to be a module, and this call is equivalent to analyse_to_file(Arg, []).

    Note

    To analyze a module of the name html (which overlaps with an option in analyse_option()), it is necessary to -use cover:analyse_to_file/2:

    cover:analyse_to_file([html], []).
    +use cover:analyse_to_file/2:

    cover:analyse_to_file([html], []).
    diff --git a/prs/8803/lib/tools-4.0/doc/html/cover_chapter.html b/prs/8803/lib/tools-4.0/doc/html/cover_chapter.html index 413364031c370..642fc0bb4cf13 100644 --- a/prs/8803/lib/tools-4.0/doc/html/cover_chapter.html +++ b/prs/8803/lib/tools-4.0/doc/html/cover_chapter.html @@ -146,81 +146,81 @@

    Example

    -

    Assume that a test case for the following program should be verified:

    -module(channel).
    --behaviour(gen_server).
    +

    Assume that a test case for the following program should be verified:

    -module(channel).
    +-behaviour(gen_server).
     
    --export([start_link/0,stop/0]).
    --export([alloc/0,free/1]). % client interface
    --export([init/1,handle_call/3,terminate/2]). % callback functions
    +-export([start_link/0,stop/0]).
    +-export([alloc/0,free/1]). % client interface
    +-export([init/1,handle_call/3,terminate/2]). % callback functions
     
    -start_link() ->
    -    gen_server:start_link({local,channel}, channel, [], []).
    +start_link() ->
    +    gen_server:start_link({local,channel}, channel, [], []).
     
    -stop() ->
    -    gen_server:call(channel, stop).
    +stop() ->
    +    gen_server:call(channel, stop).
     
     %%%-Client interface functions-------------------------------------------
     
    -alloc() ->
    -    gen_server:call(channel, alloc).
    +alloc() ->
    +    gen_server:call(channel, alloc).
     
    -free(Channel) ->
    -    gen_server:call(channel, {free,Channel}).
    +free(Channel) ->
    +    gen_server:call(channel, {free,Channel}).
     
     %%%-gen_server callback functions----------------------------------------
     
    -init(_Arg) ->
    -    {ok,channels()}.
    +init(_Arg) ->
    +    {ok,channels()}.
     
    -handle_call(stop, _Client, Channels) ->
    -    {stop,normal,ok,Channels};
    +handle_call(stop, _Client, Channels) ->
    +    {stop,normal,ok,Channels};
     
    -handle_call(alloc, _Client, Channels) ->
    -    {Ch,Channels2} = alloc(Channels),
    -    {reply,{ok,Ch},Channels2};
    +handle_call(alloc, _Client, Channels) ->
    +    {Ch,Channels2} = alloc(Channels),
    +    {reply,{ok,Ch},Channels2};
     
    -handle_call({free,Channel}, _Client, Channels) ->
    -    Channels2 = free(Channel, Channels),
    -    {reply,ok,Channels2}.
    +handle_call({free,Channel}, _Client, Channels) ->
    +    Channels2 = free(Channel, Channels),
    +    {reply,ok,Channels2}.
     
    -terminate(_Reason, _Channels) ->
    +terminate(_Reason, _Channels) ->
         ok.
     
     %%%-Internal functions---------------------------------------------------
     
    -channels() ->
    -    [ch1,ch2,ch3].
    +channels() ->
    +    [ch1,ch2,ch3].
     
    -alloc([Channel|Channels]) ->
    -    {Channel,Channels};
    -alloc([]) ->
    +alloc([Channel|Channels]) ->
    +    {Channel,Channels};
    +alloc([]) ->
         false.
     
    -free(Channel, Channels) ->
    -    [Channel|Channels].

    The test case is implemented as follows:

    -module(test).
    --export([s/0]).
    +free(Channel, Channels) ->
    +    [Channel|Channels].

    The test case is implemented as follows:

    -module(test).
    +-export([s/0]).
     
    -s() ->
    -    {ok,Pid} = channel:start_link(),
    -    {ok,Ch1} = channel:alloc(),
    -    ok = channel:free(Ch1),
    -    ok = channel:stop().

    +s() -> + {ok,Pid} = channel:start_link(), + {ok,Ch1} = channel:alloc(), + ok = channel:free(Ch1), + ok = channel:stop().

    Preparation

    First of all, Cover must be started. This spawns a process which owns the Cover -database where all coverage data will be stored.

    1> cover:start().
    -{ok,<0.90.0>}

    To include other nodes in the coverage analysis, use +database where all coverage data will be stored.

    1> cover:start().
    +{ok,<0.90.0>}

    To include other nodes in the coverage analysis, use cover:start/1. All cover-compiled modules will then be loaded on all nodes, and data from all nodes will be summed up when analysing. For simplicity this example only involves the current node.

    Before any analysis can take place, the involved modules must be cover-compiled. This means that some extra information is added to the module before beging compiled into a binary and loaded. The source file of the module is -not affected and no .beam file is created.

    2> cover:compile_module(channel).
    -{ok,channel}

    Each time a function in the cover-compiled module channel is called, +not affected and no .beam file is created.

    2> cover:compile_module(channel).
    +{ok,channel}

    Each time a function in the cover-compiled module channel is called, information about the call will be added to the Cover database. Run the test case:

    3> test:s().
     ok

    Cover analysis is performed by examining the contents of the Cover database. The @@ -238,56 +238,56 @@

    {Cov,NotCov}, where Cov is the number of executable lines that have been executed at least once and NotCov is the number of executable lines that have not been executed.

    If the analysis is made on module level, the result is given for the entire -module as a tuple {Module,{Cov,NotCov}}:

    4> cover:analyse(channel, coverage, module).
    -{ok,{channel,{14,1}}}

    For channel, the result shows that 14 lines in the module are covered but one +module as a tuple {Module,{Cov,NotCov}}:

    4> cover:analyse(channel, coverage, module).
    +{ok,{channel,{14,1}}}

    For channel, the result shows that 14 lines in the module are covered but one line is not covered.

    If the analysis is made on function level, the result is given as a list of tuples {Function,{Cov,NotCov}}, one for each function in the module. A -function is specified by its module name, function name and arity:

    5> cover:analyse(channel, coverage, function).
    -{ok,[{{channel,start_link,0},{1,0}},
    -     {{channel,stop,0},{1,0}},
    -     {{channel,alloc,0},{1,0}},
    -     {{channel,free,1},{1,0}},
    -     {{channel,init,1},{1,0}},
    -     {{channel,handle_call,3},{5,0}},
    -     {{channel,terminate,2},{1,0}},
    -     {{channel,channels,0},{1,0}},
    -     {{channel,alloc,1},{1,1}},
    -     {{channel,free,2},{1,0}}]}

    For channel, the result shows that the uncovered line is in the function +function is specified by its module name, function name and arity:

    5> cover:analyse(channel, coverage, function).
    +{ok,[{{channel,start_link,0},{1,0}},
    +     {{channel,stop,0},{1,0}},
    +     {{channel,alloc,0},{1,0}},
    +     {{channel,free,1},{1,0}},
    +     {{channel,init,1},{1,0}},
    +     {{channel,handle_call,3},{5,0}},
    +     {{channel,terminate,2},{1,0}},
    +     {{channel,channels,0},{1,0}},
    +     {{channel,alloc,1},{1,1}},
    +     {{channel,free,2},{1,0}}]}

    For channel, the result shows that the uncovered line is in the function channel:alloc/1.

    If the analysis is made on clause level, the result is given as a list of tuples {Clause,{Cov,NotCov}}, one for each function clause in the module. A clause is specified by its module name, function name, arity and position within the -function definition:

    6> cover:analyse(channel, coverage, clause).
    -{ok,[{{channel,start_link,0,1},{1,0}},
    -     {{channel,stop,0,1},{1,0}},
    -     {{channel,alloc,0,1},{1,0}},
    -     {{channel,free,1,1},{1,0}},
    -     {{channel,init,1,1},{1,0}},
    -     {{channel,handle_call,3,1},{1,0}},
    -     {{channel,handle_call,3,2},{2,0}},
    -     {{channel,handle_call,3,3},{2,0}},
    -     {{channel,terminate,2,1},{1,0}},
    -     {{channel,channels,0,1},{1,0}},
    -     {{channel,alloc,1,1},{1,0}},
    -     {{channel,alloc,1,2},{0,1}},
    -     {{channel,free,2,1},{1,0}}]}

    For channel, the result shows that the uncovered line is in the second clause +function definition:

    6> cover:analyse(channel, coverage, clause).
    +{ok,[{{channel,start_link,0,1},{1,0}},
    +     {{channel,stop,0,1},{1,0}},
    +     {{channel,alloc,0,1},{1,0}},
    +     {{channel,free,1,1},{1,0}},
    +     {{channel,init,1,1},{1,0}},
    +     {{channel,handle_call,3,1},{1,0}},
    +     {{channel,handle_call,3,2},{2,0}},
    +     {{channel,handle_call,3,3},{2,0}},
    +     {{channel,terminate,2,1},{1,0}},
    +     {{channel,channels,0,1},{1,0}},
    +     {{channel,alloc,1,1},{1,0}},
    +     {{channel,alloc,1,2},{0,1}},
    +     {{channel,free,2,1},{1,0}}]}

    For channel, the result shows that the uncovered line is in the second clause of channel:alloc/1.

    Finally, if the analysis is made on line level, the result is given as a list of tuples {Line,{Cov,NotCov}}, one for each executable line in the source code. A -line is specified by its module name and line number.

    7> cover:analyse(channel, coverage, line).
    -{ok,[{{channel,9},{1,0}},
    -     {{channel,12},{1,0}},
    -     {{channel,17},{1,0}},
    -     {{channel,20},{1,0}},
    -     {{channel,25},{1,0}},
    -     {{channel,28},{1,0}},
    -     {{channel,31},{1,0}},
    -     {{channel,32},{1,0}},
    -     {{channel,35},{1,0}},
    -     {{channel,36},{1,0}},
    -     {{channel,39},{1,0}},
    -     {{channel,44},{1,0}},
    -     {{channel,47},{1,0}},
    -     {{channel,49},{0,1}},
    -     {{channel,52},{1,0}}]}

    For channel, the result shows that the uncovered line is line number 49.

    +line is specified by its module name and line number.

    7> cover:analyse(channel, coverage, line).
    +{ok,[{{channel,9},{1,0}},
    +     {{channel,12},{1,0}},
    +     {{channel,17},{1,0}},
    +     {{channel,20},{1,0}},
    +     {{channel,25},{1,0}},
    +     {{channel,28},{1,0}},
    +     {{channel,31},{1,0}},
    +     {{channel,32},{1,0}},
    +     {{channel,35},{1,0}},
    +     {{channel,36},{1,0}},
    +     {{channel,39},{1,0}},
    +     {{channel,44},{1,0}},
    +     {{channel,47},{1,0}},
    +     {{channel,49},{0,1}},
    +     {{channel,52},{1,0}}]}

    For channel, the result shows that the uncovered line is line number 49.

    @@ -296,53 +296,53 @@

    Analysis of type calls is used to find out how many times something has been called and is represented by an integer Calls.

    If the analysis is made on module level, the result is given as a tuple {Module,Calls}. Here Calls is the total number of calls to functions in the -module:

    8> cover:analyse(channel, calls, module).
    -{ok,{channel,12}}

    For channel, the result shows that a total of twelve calls have been made to +module:

    8> cover:analyse(channel, calls, module).
    +{ok,{channel,12}}

    For channel, the result shows that a total of twelve calls have been made to functions in the module.

    If the analysis is made on function level, the result is given as a list of -tuples {Function,Calls}. Here Calls is the number of calls to each function:

    9> cover:analyse(channel, calls, function).
    -{ok,[{{channel,start_link,0},1},
    -     {{channel,stop,0},1},
    -     {{channel,alloc,0},1},
    -     {{channel,free,1},1},
    -     {{channel,init,1},1},
    -     {{channel,handle_call,3},3},
    -     {{channel,terminate,2},1},
    -     {{channel,channels,0},1},
    -     {{channel,alloc,1},1},
    -     {{channel,free,2},1}]}

    For channel, the result shows that handle_call/3 is the most called function +tuples {Function,Calls}. Here Calls is the number of calls to each function:

    9> cover:analyse(channel, calls, function).
    +{ok,[{{channel,start_link,0},1},
    +     {{channel,stop,0},1},
    +     {{channel,alloc,0},1},
    +     {{channel,free,1},1},
    +     {{channel,init,1},1},
    +     {{channel,handle_call,3},3},
    +     {{channel,terminate,2},1},
    +     {{channel,channels,0},1},
    +     {{channel,alloc,1},1},
    +     {{channel,free,2},1}]}

    For channel, the result shows that handle_call/3 is the most called function in the module (three calls). All other functions have been called once.

    If the analysis is made on clause level, the result is given as a list of tuples -{Clause,Calls}. Here Calls is the number of calls to each function clause:

    10> cover:analyse(channel, calls, clause).
    -{ok,[{{channel,start_link,0,1},1},
    -     {{channel,stop,0,1},1},
    -     {{channel,alloc,0,1},1},
    -     {{channel,free,1,1},1},
    -     {{channel,init,1,1},1},
    -     {{channel,handle_call,3,1},1},
    -     {{channel,handle_call,3,2},1},
    -     {{channel,handle_call,3,3},1},
    -     {{channel,terminate,2,1},1},
    -     {{channel,channels,0,1},1},
    -     {{channel,alloc,1,1},1},
    -     {{channel,alloc,1,2},0},
    -     {{channel,free,2,1},1}]}

    For channel, the result shows that all clauses have been called once, except +{Clause,Calls}. Here Calls is the number of calls to each function clause:

    10> cover:analyse(channel, calls, clause).
    +{ok,[{{channel,start_link,0,1},1},
    +     {{channel,stop,0,1},1},
    +     {{channel,alloc,0,1},1},
    +     {{channel,free,1,1},1},
    +     {{channel,init,1,1},1},
    +     {{channel,handle_call,3,1},1},
    +     {{channel,handle_call,3,2},1},
    +     {{channel,handle_call,3,3},1},
    +     {{channel,terminate,2,1},1},
    +     {{channel,channels,0,1},1},
    +     {{channel,alloc,1,1},1},
    +     {{channel,alloc,1,2},0},
    +     {{channel,free,2,1},1}]}

    For channel, the result shows that all clauses have been called once, except the second clause of channel:alloc/1 which has not been called at all.

    Finally, if the analysis is made on line level, the result is given as a list of tuples {Line,Calls}. Here Calls is the number of times each line has been -executed:

    11> cover:analyse(channel, calls, line).
    -{ok,[{{channel,9},1},
    -     {{channel,12},1},
    -     {{channel,17},1},
    -     {{channel,20},1},
    -     {{channel,25},1},
    -     {{channel,28},1},
    -     {{channel,31},1},
    -     {{channel,32},1},
    -     {{channel,35},1},
    -     {{channel,36},1},
    -     {{channel,39},1},
    -     {{channel,44},1},
    -     {{channel,47},1},
    -     {{channel,49},0},
    -     {{channel,52},1}]}

    For channel, the result shows that all lines have been executed once, except +executed:

    11> cover:analyse(channel, calls, line).
    +{ok,[{{channel,9},1},
    +     {{channel,12},1},
    +     {{channel,17},1},
    +     {{channel,20},1},
    +     {{channel,25},1},
    +     {{channel,28},1},
    +     {{channel,31},1},
    +     {{channel,32},1},
    +     {{channel,35},1},
    +     {{channel,36},1},
    +     {{channel,39},1},
    +     {{channel,44},1},
    +     {{channel,47},1},
    +     {{channel,49},0},
    +     {{channel,52},1}]}

    For channel, the result shows that all lines have been executed once, except line number 49 which has not been executed at all.

    @@ -350,65 +350,65 @@

    Analysis to File

    A line level calls analysis of channel can be written to a file using -cover:analyse_to_file/1:

    12> cover:analyse_to_file(channel).
    -{ok,"channel.COVER.out"}

    The function creates a copy of channel.erl where it for each executable line +cover:analyse_to_file/1:

    12> cover:analyse_to_file(channel).
    +{ok,"channel.COVER.out"}

    The function creates a copy of channel.erl where it for each executable line is specified how many times that line has been executed. The output file is called channel.COVER.out.

    File generated from /Users/bjorng/git/otp/channel.erl by COVER 2024-03-20 at 13:25:04
     
     ****************************************************************************
     
    -        |  -module(channel).
    -        |  -behaviour(gen_server).
    +        |  -module(channel).
    +        |  -behaviour(gen_server).
             |
    -        |  -export([start_link/0,stop/0]).
    -        |  -export([alloc/0,free/1]). % client interface
    -        |  -export([init/1,handle_call/3,terminate/2]). % callback functions
    +        |  -export([start_link/0,stop/0]).
    +        |  -export([alloc/0,free/1]). % client interface
    +        |  -export([init/1,handle_call/3,terminate/2]). % callback functions
             |
    -        |  start_link() ->
    -     1..|      gen_server:start_link({local,channel}, channel, [], []).
    +        |  start_link() ->
    +     1..|      gen_server:start_link({local,channel}, channel, [], []).
             |
    -        |  stop() ->
    -     1..|      gen_server:call(channel, stop).
    +        |  stop() ->
    +     1..|      gen_server:call(channel, stop).
             |
             |  %%%-Client interface functions-------------------------------------------
             |
    -        |  alloc() ->
    -     1..|      gen_server:call(channel, alloc).
    +        |  alloc() ->
    +     1..|      gen_server:call(channel, alloc).
             |
    -        |  free(Channel) ->
    -     1..|      gen_server:call(channel, {free,Channel}).
    +        |  free(Channel) ->
    +     1..|      gen_server:call(channel, {free,Channel}).
             |
             |  %%%-gen_server callback functions----------------------------------------
             |
    -        |  init(_Arg) ->
    -     1..|      {ok,channels()}.
    +        |  init(_Arg) ->
    +     1..|      {ok,channels()}.
             |
    -        |  handle_call(stop, _Client, Channels) ->
    -     1..|      {stop,normal,ok,Channels};
    +        |  handle_call(stop, _Client, Channels) ->
    +     1..|      {stop,normal,ok,Channels};
             |
    -        |  handle_call(alloc, _Client, Channels) ->
    -     1..|      {Ch,Channels2} = alloc(Channels),
    -     1..|      {reply,{ok,Ch},Channels2};
    +        |  handle_call(alloc, _Client, Channels) ->
    +     1..|      {Ch,Channels2} = alloc(Channels),
    +     1..|      {reply,{ok,Ch},Channels2};
             |
    -        |  handle_call({free,Channel}, _Client, Channels) ->
    -     1..|      Channels2 = free(Channel, Channels),
    -     1..|      {reply,ok,Channels2}.
    +        |  handle_call({free,Channel}, _Client, Channels) ->
    +     1..|      Channels2 = free(Channel, Channels),
    +     1..|      {reply,ok,Channels2}.
             |
    -        |  terminate(_Reason, _Channels) ->
    +        |  terminate(_Reason, _Channels) ->
          1..|      ok.
             |
             |  %%%-Internal functions---------------------------------------------------
             |
    -        |  channels() ->
    -     1..|      [ch1,ch2,ch3].
    +        |  channels() ->
    +     1..|      [ch1,ch2,ch3].
             |
    -        |  alloc([Channel|Channels]) ->
    -     1..|      {Channel,Channels};
    -        |  alloc([]) ->
    +        |  alloc([Channel|Channels]) ->
    +     1..|      {Channel,Channels};
    +        |  alloc([]) ->
          0..|      false.
             |
    -        |  free(Channel, Channels) ->
    -     1..|      [Channel|Channels].

    + | free(Channel, Channels) -> + 1..| [Channel|Channels].

    @@ -419,11 +419,11 @@

    and test.erl should be extended accordingly. Incidentally, when the test case is corrected a bug in channel will be discovered.

    When the Cover analysis is ready, Cover is stopped and all cover-compiled modules are unloaded. The code for channel is now -loaded as usual from a .beam file in the current path.

    13> code:which(channel).
    +loaded as usual from a .beam file in the current path.

    13> code:which(channel).
     cover_compiled
    -14> cover:stop().
    +14> cover:stop().
     ok
    -15> code:which(channel).
    +15> code:which(channel).
     "./channel.beam"

    @@ -451,12 +451,12 @@

    Cover uses the concept of executable lines, which is code lines containing an executable expression such as a matching or a function call. A blank line or a line containing a comment, function head or pattern in a case or receive -statement is not executable.

    In the example below, lines number 2, 4, 6, 8, and 11 are executable lines:

    1: is_loaded(Module, Compiled) ->
    -2:   case get_file(Module, Compiled) of
    -3:     {ok,File} ->
    -4:       case code:which(Module) of
    +statement is not executable.

    In the example below, lines number 2, 4, 6, 8, and 11 are executable lines:

    1: is_loaded(Module, Compiled) ->
    +2:   case get_file(Module, Compiled) of
    +3:     {ok,File} ->
    +4:       case code:which(Module) of
     5:         ?TAG ->
    -6:           {loaded,File};
    +6:           {loaded,File};
     7:         _ ->
     8:           unloaded
     9:       end;
    diff --git a/prs/8803/lib/tools-4.0/doc/html/cprof.html b/prs/8803/lib/tools-4.0/doc/html/cprof.html
    index aa9a072c8ce10..adb7938b84481 100644
    --- a/prs/8803/lib/tools-4.0/doc/html/cprof.html
    +++ b/prs/8803/lib/tools-4.0/doc/html/cprof.html
    @@ -590,7 +590,7 @@ 

    analyse(Module, Limit)

    -

    Collects and analyses all call counters for module Module.

    This function returns:

    {Module, ModuleCount, FuncAnalysisList}

    where FuncAnalysisList is a list of tuples, one for each function:

    {{Module, FunctionName, Arity}, FuncCallCount}

    If call counters are still running while analyse/0,1,2 is executing, the result +

    Collects and analyses all call counters for module Module.

    This function returns:

    {Module, ModuleCount, FuncAnalysisList}

    where FuncAnalysisList is a list of tuples, one for each function:

    {{Module, FunctionName, Arity}, FuncCallCount}

    If call counters are still running while analyse/0,1,2 is executing, the result could be inconsistent. This happens if the process executing analyse/0,1,2 is scheduled out so some other process can increment the counters that are being analysed. Calling pause() before analysing takes care of diff --git a/prs/8803/lib/tools-4.0/doc/html/cprof_chapter.html b/prs/8803/lib/tools-4.0/doc/html/cprof_chapter.html index 69026d2d17a3a..8662540467f90 100644 --- a/prs/8803/lib/tools-4.0/doc/html/cprof_chapter.html +++ b/prs/8803/lib/tools-4.0/doc/html/cprof_chapter.html @@ -156,36 +156,36 @@

    Example: Background work

    -

    From the Erlang shell:

    1> cprof:start(), cprof:pause(). % Stop counters just after start
    +

    From the Erlang shell:

    1> cprof:start(), cprof:pause(). % Stop counters just after start
     8492
    -2> cprof:analyse().
    -{539,
    - [{shell,155,
    -         [{{shell,prep_check,1},55},
    -          {{shell,used_records,4},45},
    -          {{shell,used_records,1},45},
    -          {{shell,used_record_defs,2},1},
    -          {{shell,record_defs,2},1},
    -          {{shell,record_bindings,2},1},
    -          {{shell,exprs,7},1},
    -          {{shell,expr,4},1},
    -          {{shell,expand_records,2},1},
    -          {{shell,check_command,2},1},
    -          {{shell,apply_fun,3},1},
    -          {{shell,'-exprs/7-lc$^0/1-0-',1},1},
    -          {{shell,'-eval_loop/3-fun-0-',3},1}]},
    +2> cprof:analyse().
    +{539,
    + [{shell,155,
    +         [{{shell,prep_check,1},55},
    +          {{shell,used_records,4},45},
    +          {{shell,used_records,1},45},
    +          {{shell,used_record_defs,2},1},
    +          {{shell,record_defs,2},1},
    +          {{shell,record_bindings,2},1},
    +          {{shell,exprs,7},1},
    +          {{shell,expr,4},1},
    +          {{shell,expand_records,2},1},
    +          {{shell,check_command,2},1},
    +          {{shell,apply_fun,3},1},
    +          {{shell,'-exprs/7-lc$^0/1-0-',1},1},
    +          {{shell,'-eval_loop/3-fun-0-',3},1}]},
       %% Information about many modules omitted.
                          .
                          .
                          .
       %% Here is the last part.
    -  {erts_internal,2,[{{erts_internal,trace_pattern,3},2}]},
    -  {otp_internal,1,[{{otp_internal,obsolete,3},1}]},
    -  {maps,1,[{{maps,from_list,1},1}]},
    -  {erl_internal,1,[{{erl_internal,bif,3},1}]}]}
    -3> cprof:analyse(cprof).
    -{cprof,3,[{{cprof,tr,2},2},{{cprof,pause,0},1}]}
    -4> cprof:stop().
    +  {erts_internal,2,[{{erts_internal,trace_pattern,3},2}]},
    +  {otp_internal,1,[{{otp_internal,obsolete,3},1}]},
    +  {maps,1,[{{maps,from_list,1},1}]},
    +  {erl_internal,1,[{{erl_internal,bif,3},1}]}]}
    +3> cprof:analyse(cprof).
    +{cprof,3,[{{cprof,tr,2},2},{{cprof,pause,0},1}]}
    +4> cprof:stop().
     8586

    The example showed some of the background work that the shell performs just to interpret the first command line.

    What is captured in this example is the part of the work the shell does while interpreting the command line that occurs between the actual calls to @@ -195,20 +195,20 @@

    Example: One module

    -

    From the Erlang shell:

    1> cprof:start(),R=calendar:day_of_the_week(1896,4,27),cprof:pause(),R.
    +

    From the Erlang shell:

    1> cprof:start(),R=calendar:day_of_the_week(1896,4,27),cprof:pause(),R.
     1
    -2> cprof:analyse(calendar).
    -{calendar,9,
    -          [{{calendar,last_day_of_the_month1,2},1},
    -           {{calendar,last_day_of_the_month,2},1},
    -           {{calendar,is_leap_year1,1},1},
    -           {{calendar,is_leap_year,1},1},
    -           {{calendar,dy,1},1},
    -           {{calendar,dm,1},1},
    -           {{calendar,df,2},1},
    -           {{calendar,day_of_the_week,3},1},
    -           {{calendar,date_to_gregorian_days,3},1}]}
    -3> cprof:stop().
    +2> cprof:analyse(calendar).
    +{calendar,9,
    +          [{{calendar,last_day_of_the_month1,2},1},
    +           {{calendar,last_day_of_the_month,2},1},
    +           {{calendar,is_leap_year1,1},1},
    +           {{calendar,is_leap_year,1},1},
    +           {{calendar,dy,1},1},
    +           {{calendar,dm,1},1},
    +           {{calendar,df,2},1},
    +           {{calendar,day_of_the_week,3},1},
    +           {{calendar,date_to_gregorian_days,3},1}]}
    +3> cprof:stop().
     8648

    The example tells us that "Aktiebolaget LM Ericsson & Co" was registered on a Monday (since the return value of the first command is 1), and that the calendar module needed 9 function calls to calculate that.

    Using cprof:analyse() in this example also shows approximately the same @@ -218,60 +218,60 @@

    Example: In the code

    -

    Write a module:

    -module(sort).
    --export([do/1]).
    +

    Write a module:

    -module(sort).
    +-export([do/1]).
     
    -do(N) ->
    -    cprof:stop(),
    -    cprof:start(),
    -    do(N, []).
    +do(N) ->
    +    cprof:stop(),
    +    cprof:start(),
    +    do(N, []).
     
    -do(0, L) ->
    -    R = lists:sort(L),
    -    cprof:pause(),
    +do(0, L) ->
    +    R = lists:sort(L),
    +    cprof:pause(),
         R;
    -do(N, L) ->
    -    do(N-1, [rand:uniform(256)-1 | L]).

    From the Erlang shell:

    1> c(sort).
    -{ok,sort}
    -2> rand:seed(default, 42), ok.
    +do(N, L) ->
    +    do(N-1, [rand:uniform(256)-1 | L]).

    From the Erlang shell:

    1> c(sort).
    +{ok,sort}
    +2> rand:seed(default, 42), ok.
     ok.
    -3> sort:do(1000).
    -[0,0,0,1,1,1,1,2,2,3,3,4,4,4,4,5,5,5,6,6,6,6,7,7,7,7,7,8,8|...]
    -4> cprof:analyse().
    -{13180,
    - [{lists,6173,
    -         [{{lists,rmerge3_1,6},1045},
    -          {{lists,rmerge3_2,6},977},
    -          {{lists,split_1,5},652},
    -          {{lists,merge3_1,6},579},
    -          {{lists,merge3_2,6},577},
    -          {{lists,rmerge3_12_3,6},511},
    -          {{lists,split_1_1,6},347},
    -          {{lists,merge3_12_3,6},310},
    -          {{lists,rmerge3_21_3,6},282},
    -          {{lists,merge3_21_3,6},221},
    -          {{lists,merge2_1,4},154},
    -          {{lists,merge2_2,5},138},
    -          {{lists,reverse,2},106},
    -          {{lists,rmerge2_2,5},87},
    -          {{lists,rmergel,2},81},
    -          {{lists,rmerge2_1,4},75},
    -          {{lists,mergel,2},28},
    -          {{lists,keyfind,3},2},
    -          {{lists,sort,1},1}]},
    -  {rand,5000,
    -        [{{rand,uniform_s,2},1000},
    -         {{rand,uniform,1},1000},
    -         {{rand,seed_put,1},1000},
    -         {{rand,seed_get,0},1000},
    -         {{rand,exsss_uniform,2},1000}]},
    -  {erlang,1004,
    -          [{{erlang,put,2},1000},
    -           {{erlang,trace_pattern,3},2},
    -           {{erlang,ensure_tracer_module_loaded,2},2}]},
    -  {sort,1001,[{{sort,do,2},1001}]},
    -  {erts_internal,2,[{{erts_internal,trace_pattern,3},2}]}]}
    -5> cprof:stop().
    +3> sort:do(1000).
    +[0,0,0,1,1,1,1,2,2,3,3,4,4,4,4,5,5,5,6,6,6,6,7,7,7,7,7,8,8|...]
    +4> cprof:analyse().
    +{13180,
    + [{lists,6173,
    +         [{{lists,rmerge3_1,6},1045},
    +          {{lists,rmerge3_2,6},977},
    +          {{lists,split_1,5},652},
    +          {{lists,merge3_1,6},579},
    +          {{lists,merge3_2,6},577},
    +          {{lists,rmerge3_12_3,6},511},
    +          {{lists,split_1_1,6},347},
    +          {{lists,merge3_12_3,6},310},
    +          {{lists,rmerge3_21_3,6},282},
    +          {{lists,merge3_21_3,6},221},
    +          {{lists,merge2_1,4},154},
    +          {{lists,merge2_2,5},138},
    +          {{lists,reverse,2},106},
    +          {{lists,rmerge2_2,5},87},
    +          {{lists,rmergel,2},81},
    +          {{lists,rmerge2_1,4},75},
    +          {{lists,mergel,2},28},
    +          {{lists,keyfind,3},2},
    +          {{lists,sort,1},1}]},
    +  {rand,5000,
    +        [{{rand,uniform_s,2},1000},
    +         {{rand,uniform,1},1000},
    +         {{rand,seed_put,1},1000},
    +         {{rand,seed_get,0},1000},
    +         {{rand,exsss_uniform,2},1000}]},
    +  {erlang,1004,
    +          [{{erlang,put,2},1000},
    +           {{erlang,trace_pattern,3},2},
    +           {{erlang,ensure_tracer_module_loaded,2},2}]},
    +  {sort,1001,[{{sort,do,2},1001}]},
    +  {erts_internal,2,[{{erts_internal,trace_pattern,3},2}]}]}
    +5> cprof:stop().
     12625

    The example shows some details of how lists:sort/1 works. It used 6173 function calls in module lists to complete the work.

    This time, since the shell was not involved in starting and stopping cprof, no other work was done in the system during the profiling.

    diff --git a/prs/8803/lib/tools-4.0/doc/html/dist/search_data-536C0AEB.js b/prs/8803/lib/tools-4.0/doc/html/dist/search_data-536C0AEB.js new file mode 100644 index 0000000000000..06e401d62e383 --- /dev/null +++ b/prs/8803/lib/tools-4.0/doc/html/dist/search_data-536C0AEB.js @@ -0,0 +1 @@ +searchData={"items":[{"type":"module","doc":"A Coverage Analysis Tool for Erlang\n\nThe module `cover` provides a set of functions for coverage analysis\nof Erlang programs, counting how many times each _executable line_ of\ncode is executed when a program is run. Executable lines are\nlines in the body of a clause in a function, `case`,\n`receive`, or `try`. Lines in clause heads, blank lines, and lines\ncontaining only comments are not executable.\n\nCoverage analysis can be used to verify that test cases covers all\nrelevant line in the code being test. It can also be helpful when\nlooking for bottlenecks in the code.\n\nBefore any analysis can take place, the involved modules has to be\n_cover-compiled_. This means that some extra information is added to\nthe module before it is compiled into a binary which then is\nloaded. The source file of the module is not affected and no `.beam`\nfile is created. If the runtime system supports coverage natively,\nCover will automatically use that functionality to lower the execution\noverhead for cover-compiled code.\n\n> #### Change {: .info }\n>\n> Native coverage support was added in Erlang/OTP 27.\n\nEach time a function in a cover-compiled module is called, information about the\ncall is added to an internal database of Cover. The coverage analysis is\nperformed by examining the contents of the Cover database. The output `Answer`\nis determined by two parameters: `Level` and `Analysis`.\n\n- `Level = module`\n\n `Answer = {Module,Value}`, where `Module` is the module name.\n\n- `Level = function`\n\n `Answer = [{Function,Value}]`, one tuple for each function in the module. A\n function is specified by its module name `M`, function name `F` and arity `A`\n as a tuple `{M,F,A}`.\n\n- `Level = clause`\n\n `Answer = [{Clause,Value}]`, one tuple for each clause in the module. A clause\n is specified by its module name `M`, function name `F`, arity `A` and position\n in the function definition `C` as a tuple `{M,F,A,C}`.\n\n- `Level = line`\n\n `Answer = [{Line,Value}]`, one tuple for each executable line in the module. A\n line is specified by its module name `M` and line number in the source file\n `N` as a tuple `{M,N}`.\n\n- `Analysis = coverage`\n\n `Value = {Cov,NotCov}` where `Cov` is the number of executable lines in the\n module, function, clause or line that have been executed at least once and\n `NotCov` is the number of executable lines that have not been executed.\n\n- `Analysis = calls`\n\n `Value = Calls` which is the number of times the module, function, or clause\n has been called. In the case of line level analysis, `Calls` is the number of\n times the line has been executed.","title":"cover","ref":"cover.html"},{"type":"module","doc":"Cover can be used in a distributed Erlang system. One of the nodes in the system\nhas to be selected as the _main node_, and all Cover commands must be\nexecuted from that node. The error reason `not_main_node` is returned if an\ninterface function is called on one of the remote nodes.\n\nUse `cover:start/1` and `cover:stop/1` to add or remove nodes. The\nsame cover-compiled code will be loaded on each node, and analysis\nwill collect and sum up coverage data results from all nodes.\n\nTo only collect data from remote nodes without stopping `cover` on those nodes,\nuse `cover:flush/1`\n\nIf the connection to a remote node goes down, the main node will mark it as\nlost. If the node comes back it will be added again. If the remote node was\nalive during the disconnected period, cover data from before and during this\nperiod will be included in the analysis.","title":"Distribution - cover","ref":"cover.html#module-distribution"},{"type":"function","doc":"","title":"cover.analyse/0","ref":"cover.html#analyse/0"},{"type":"function","doc":"Analyzes one or more modules as specified by `Arg`.\n\nIf `Arg` is one of the values in [`analysis()`](`t:analysis/0`), this\ncall is equivalent to [`analyse('_', Arg, function)`](`analyse/3`).\n\nIf `Arg` is one of the values in [`level()`](`t:level/0`), this\ncall is equivalent to [`analyse('_', coverage, Arg)`](`analyse/3`).\n\nOtherwise `Arg` is assumed to be a module name, and this call is equivalent\nto [`analyse(Arg, coverage, function)`](`analyse/3`).\n\n> #### Note {: .info }\n>\n> To analyze a module whose name overlaps with one the values in\n> [`analysis()`](`t:analysis/0`) or [`level()`](`t:level/0`), the module\n> name has to be in a list. For example, to analyze a module named `calls`:\n>\n> ```\n> cover:analyse([calls]).\n> ```","title":"cover.analyse/1","ref":"cover.html#analyse/1"},{"type":"function","doc":"Analyzes one or more modules as specified by `Arg1` and `Arg2`.\n\nIf `Arg1` is one of the values in [`analysis()`](`t:analysis/0`) and\n`Arg2` is one of the values in [`level()`](`t:level/0`), this\ncall is equivalent to [`analyse('_', Arg1, Arg2)`](`analyse/3`).\n\nIf `Arg2` is one of the values in [`analysis()`](`t:analysis/0`),\n`Arg1` is assumed to be a module and this call is equivalent to\n[`analyse(Arg1, Arg2, function)`](`analyse/3`).\n\nIf `Arg2` is one of the values in [`level()`](`t:level/0`), `Arg1` is\nassumed to be a module and this call is equivalent to [`analyse(Arg1,\ncoverage, Arg2)`](`analyse/3`).\n\n> #### Note {: .info }\n>\n> To analyze a module whose name overlaps with one of the values in\n> [`analysis()`](`t:analysis/0`), the module name needs to be in a\n> list. For example, to analyze a module named `calls`:\n>\n> ```\n> cover:analyse([calls], function).\n> ```","title":"cover.analyse/2","ref":"cover.html#analyse/2"},{"type":"function","doc":"Perform analysis of one or more cover-compiled modules, as specified by\n`Analysis` and `Level`, by examining the contents of the internal\ndatabase.\n\nIf `Modules` is an atom (a single module), the return is `OneResult`,\notherwise the return is `{result, Ok, Fail}`.\n\nIf `Modules` is atom `'_'`, all modules that have data in the cover data table\nare analysed. Note that this includes both cover-compiled modules and imported\nmodules.\n\nIf a given module is not cover-compiled, this is indicated by the error reason\n`{not_cover_compiled, Module}`.","title":"cover.analyse/3","ref":"cover.html#analyse/3"},{"type":"function","doc":"","title":"cover.analyse_to_file/0","ref":"cover.html#analyse_to_file/0"},{"type":"function","doc":"If `Arg` is a list of [`analyse_option()`](`t:analyse_option/0`)\noptions, this call is equivalent to [`analyse_to_file('_',\nArg)`](`analyse_to_file/2`).\n\nOtherwise `Arg` is assumed to be a module, and this call is equivalent to\n[`analyse_to_file(Arg, [])`](`analyse_to_file/2`).\n\n> #### Note {: .info }\n>\n> To analyze a module of the name `html` (which overlaps with an option\n> in [`analyse_option()`](`t:analyse_option/0`)), it is necessary to\n> use `cover:analyse_to_file/2`:\n>\n> ```\n> cover:analyse_to_file([html], []).\n> ```","title":"cover.analyse_to_file/1","ref":"cover.html#analyse_to_file/1"},{"type":"function","doc":"Outputs copies of the source code for the given modules annotated with\nexecution counts for each executable line.\n\nThe output file `OutFile` defaults to `Module.COVER.out`, and to `Module.COVER.html`\nif option `html` is used.\n\nIf `Modules` is an atom (one module), the return will be `Answer`, otherwise the\nreturn will be a list, `{result, Ok, Fail}`.\n\nIf `Modules` is '_', all modules that have data in the Cover data table\nare analysed. Note that this includes both cover-compiled modules and imported\nmodules.\n\nIf a module is not cover-compiled, this is indicated by the error reason\n`{not_cover_compiled, Module}`.\n\nIf the source file and/or the output file cannot be opened using `file:open/2`,\nthe function returns `{error, {file, File, Reason}}`, where `File` is the file\nname and `Reason` is the error reason.\n\nIf a module was cover compiled from the `.beam` file, that is, using\n`compile_beam/1` or\n[`compile_beam_directory/0,1` ](`compile_beam_directory/0`), it is assumed that\nthe source code can be found in one of the following locations:\n\n- the same directory as the `.beam` file\n- `../src` relative to the directory with `.beam` file\n- the source path in `Module:module_info(compile)`, in which case two paths\n are examined:\n * first the one constructed by joining `../src` and the tail of the compiled path\n below a trailing `src` component\n * the compiled path itself\n\nIf no source code is found, this is indicated by the error reason\n`{no_source_code_found, Module}`.","title":"cover.analyse_to_file/2","ref":"cover.html#analyse_to_file/2"},{"type":"function","doc":"","title":"cover.async_analyse_to_file/1","ref":"cover.html#async_analyse_to_file/1"},{"type":"function","doc":"","title":"cover.async_analyse_to_file/2","ref":"cover.html#async_analyse_to_file/2"},{"type":"function","doc":"This function works the same way as\n[`analyse_to_file/2`](`analyse_to_file/2`) except that it is asynchronous instead\nof synchronous.\n\nThe spawned process will link with the caller when created. If an\nerror of type [`analyse_rsn()`](`t:analyse_rsn/0`) occurs while doing\nthe cover analysis the process will crash with the same error reason\nas [`analyse_to_file`](`analyse_to_file/1`) would return.","title":"cover.async_analyse_to_file/3","ref":"cover.html#async_analyse_to_file/3"},{"type":"function","doc":"","title":"cover.compile/1","ref":"cover.html#compile/1"},{"type":"function","doc":"","title":"cover.compile/2","ref":"cover.html#compile/2"},{"type":"function","doc":"Cover-compiles one or more modules based `.beam` files containing\nabstract code (option `debug_info`).\n\nCover-compiling from `.beam` files is faster than compiling from\nsource and less hassle, because there is no need to supply options for\ninclude paths or macros. However, the existing `.beam` files must have\nbeen compiled with option\n[`debug_info`](`e:compiler:compile.md#debug_info`) so that they contain\n[*abstract code*](`e:erts:absform`).\n\nIf abstract code is missing, the error reason `{no_abstract_code,\nBeamFile}` is returned. If the abstract code is encrypted, and no key\nis available for decrypting it, the error reason\n`{encrypted_abstract_code, BeamFile}` is returned.\n\nIf only the module name (that is, not the full name of the `.beam`\nfile) is given to this function, the `.beam` file is found by calling\n[`code:which(Module)`](`code:which/1`). If no `.beam` file is found,\nthe error reason `non_existing` is returned. If the module is already\ncover compiled with [`compile_beam/1`](`compile_beam/1`), the `.beam`\nfile will be picked from the same location as the first time it was\ncompiled. If the module is already cover-compiled with\n`compile_module/2`, there is no way to find the correct `.beam` file,\nso the error reason `{already_cover_compiled, no_beam_found, Module}`\nis returned.\n\n`{error, BeamFile}` is returned if the compiled code cannot be loaded on the\nnode.\n\nIf a list of `ModFiles` is given as input, a list of `Result` will be returned.\nThe order of the returned list is undefined.","title":"cover.compile_beam/1","ref":"cover.html#compile_beam/1"},{"type":"function","doc":"","title":"cover.compile_beam_directory/0","ref":"cover.html#compile_beam_directory/0"},{"type":"function","doc":"Cover-compiles all `.beam` files in directory `Dir` in the same way\nas `compile_beam/1`.\n\nThis function returns a list of [`compile_beam_result()`](`t:compile_beam_result/0`)\nif successful. Otherwise, it returns `{error, eacces}` if the directory is not\nreadable, and `{error, enoent}` if the directory does not exist.","title":"cover.compile_beam_directory/1","ref":"cover.html#compile_beam_directory/1"},{"type":"function","doc":"","title":"cover.compile_directory/0","ref":"cover.html#compile_directory/0"},{"type":"function","doc":"","title":"cover.compile_directory/1","ref":"cover.html#compile_directory/1"},{"type":"function","doc":"Compiles all modules (`.erl` files) in a directory `Dir` for Cover analysis the\nsame way as [`compile_module/1,2`](`compile_module/1`) and returns a list of\n[`Result`](`t:compile_result/0`).\n\nThis function returns `{error, eacces}` if the directory is not readable or\n`{error, enoent}` if the directory does not exist.","title":"cover.compile_directory/2","ref":"cover.html#compile_directory/2"},{"type":"function","doc":"","title":"cover.compile_module/1","ref":"cover.html#compile_module/1"},{"type":"function","doc":"Cover-compiles one or more modules.\n\nThe module is given by its module name `Module` or by its file name\n`File`.\n\nThe `.erl` extension can be omitted. If the module is not located in\nthe current directory, the full path to it must be specified.\n\n`Options` is a list of compiler options. Only options defining include\nfile directories and macros are passed to `compile:file/2`;\neverything else is ignored.\n\nIf the module is successfully cover-compiled, the function returns\n`{ok, Module}`. Otherwise the function returns `{error, File}`. Errors and\nwarnings are printed as they occur.\n\nIf a list of `ModFiles` is given as input, a list of [`Result`](`t:compile_result/0`)\nwill be returned. The order of the returned results in the list is undefined.\n\nNote that the internal database is initialized during the compilation,\nwhich means that any previously collected coverage data for the module\nis lost.","title":"cover.compile_module/2","ref":"cover.html#compile_module/2"},{"type":"function","doc":"","title":"cover.export/1","ref":"cover.html#export/1"},{"type":"function","doc":"Exports the current coverage data for `Module` to the file `ExportFile`.\n\nIt is recommended to name the `ExportFile` with the extension `.coverdata`.\n\nIf `Module` is '_', data for all cover-compiled or earlier imported\nmodules is exported.\n\nThis function is useful if coverage data from different systems is to be merged.\n\nSee also `import/1`.","title":"cover.export/2","ref":"cover.html#export/2"},{"type":"function","doc":"Fetches data from the Cover database on the remote nodes and stores it on the main\nnode.","title":"cover.flush/1","ref":"cover.html#flush/1"},{"type":"function","doc":"Imports coverage data from the file `ExportFile` created with\n[`export/1,2`](`export/2`).\n\nAny analysis performed after this call will include the imported data.\n\nNote that when compiling a module _all existing coverage data is removed_,\nincluding imported data. If a module is already compiled when data is imported,\nthe imported data is _added_ to the existing coverage data.\n\nCoverage data from several export files can be imported into one system. The\ncoverage data is then added up when analysing.\n\nCoverage data for a module cannot be imported from the same file twice unless\nthe module is first reset or compiled. The check is based on the filename, so\nyou can easily fool the system by renaming your export file.","title":"cover.import/1","ref":"cover.html#import/1"},{"type":"function","doc":"Returns a list of all imported files.","title":"cover.imported/0","ref":"cover.html#imported/0"},{"type":"function","doc":"Returns a list of all modules for which there are imported data.","title":"cover.imported_modules/0","ref":"cover.html#imported_modules/0"},{"type":"function","doc":"Returns `{file, File}` if the module `Module` is cover-compiled, or `false`\notherwise.\n\n`File` is the `.erl` file used by [`compile_module/1,2`](`compile_module/2`)\nor the `.beam` file used by `compile_beam/1`.","title":"cover.is_compiled/1","ref":"cover.html#is_compiled/1"},{"type":"function","doc":"Only support running Cover on the local node.\n\nThis function has to be called before any modules have been compiled or\nany nodes added. When running in this mode, modules will be\ncover-compiled in a more efficient way, but the resulting code will\nonly work on the same node they were compiled on.","title":"cover.local_only/0","ref":"cover.html#local_only/0"},{"type":"function","doc":"Returns a list with all modules that are currently cover-compiled.","title":"cover.modules/0","ref":"cover.html#modules/0"},{"type":"function","doc":"Resets all coverage data for all cover-compiled modules in the Cover\ndatabase on all nodes.","title":"cover.reset/0","ref":"cover.html#reset/0"},{"type":"function","doc":"Resets all coverage data for the cover-compiled module `Module` in the Cover\ndatabase on all nodes.\n\nIf `Module` is not cover-compiled, the function returns\n`{error, {not_cover_compiled, Module}}`.","title":"cover.reset/1","ref":"cover.html#reset/1"},{"type":"function","doc":"Starts the Cover server which owns the Cover internal database. This function is\ncalled automatically by the other functions in the module.","title":"cover.start/0","ref":"cover.html#start/0"},{"type":"function","doc":"Starts a Cover server on the each of given nodes, and loads all cover compiled\nmodules.\n\nThis call will fail if `cover:local_only/0` has been called.","title":"cover.start/1","ref":"cover.html#start/1"},{"type":"function","doc":"Stops the Cover server and unloads all cover-compiled code.","title":"cover.stop/0","ref":"cover.html#stop/0"},{"type":"function","doc":"Stops the Cover server and unloads all cover-compiled code on the given nodes.\n\nData stored in the Cover database on the remote nodes is fetched and stored on\nthe main node.","title":"cover.stop/1","ref":"cover.html#stop/1"},{"type":"function","doc":"Returns a list with all nodes that are part of the coverage analysis.\n\nNote that the current node is not included, because it is always part\nof the analysis.","title":"cover.which_nodes/0","ref":"cover.html#which_nodes/0"},{"type":"type","doc":"","title":"cover.analyse_answer/0","ref":"cover.html#t:analyse_answer/0"},{"type":"type","doc":"","title":"cover.analyse_fail/0","ref":"cover.html#t:analyse_fail/0"},{"type":"type","doc":"","title":"cover.analyse_file_fail/0","ref":"cover.html#t:analyse_file_fail/0"},{"type":"type","doc":"","title":"cover.analyse_file_ok/0","ref":"cover.html#t:analyse_file_ok/0"},{"type":"type","doc":"","title":"cover.analyse_item/0","ref":"cover.html#t:analyse_item/0"},{"type":"type","doc":"","title":"cover.analyse_ok/0","ref":"cover.html#t:analyse_ok/0"},{"type":"type","doc":"","title":"cover.analyse_option/0","ref":"cover.html#t:analyse_option/0"},{"type":"type","doc":"","title":"cover.analyse_rsn/0","ref":"cover.html#t:analyse_rsn/0"},{"type":"type","doc":"","title":"cover.analyse_value/0","ref":"cover.html#t:analyse_value/0"},{"type":"type","doc":"","title":"cover.analysis/0","ref":"cover.html#t:analysis/0"},{"type":"type","doc":"","title":"cover.beam_mod_file/0","ref":"cover.html#t:beam_mod_file/0"},{"type":"type","doc":"","title":"cover.beam_mod_files/0","ref":"cover.html#t:beam_mod_files/0"},{"type":"type","doc":"","title":"cover.compile_beam_result/0","ref":"cover.html#t:compile_beam_result/0"},{"type":"type","doc":"","title":"cover.compile_beam_rsn/0","ref":"cover.html#t:compile_beam_rsn/0"},{"type":"type","doc":"","title":"cover.compile_result/0","ref":"cover.html#t:compile_result/0"},{"type":"type","doc":"","title":"cover.export_reason/0","ref":"cover.html#t:export_reason/0"},{"type":"type","doc":"","title":"cover.file_error/0","ref":"cover.html#t:file_error/0"},{"type":"type","doc":"","title":"cover.level/0","ref":"cover.html#t:level/0"},{"type":"type","doc":"","title":"cover.mod_file/0","ref":"cover.html#t:mod_file/0"},{"type":"type","doc":"","title":"cover.mod_files/0","ref":"cover.html#t:mod_files/0"},{"type":"type","doc":"","title":"cover.modules/0","ref":"cover.html#t:modules/0"},{"type":"type","doc":"","title":"cover.one_result/0","ref":"cover.html#t:one_result/0"},{"type":"type","doc":"","title":"cover.option/0","ref":"cover.html#t:option/0"},{"type":"module","doc":"A simple Call Count Profiling Tool using breakpoints for minimal runtime\nperformance impact.\n\nThe `cprof` module is used to profile a program to find out how many times\ndifferent functions are called. To minimize runtime performance impact,\nbreakpoints containing counters are used.\n\nSince breakpoints are used there is no need for special compilation of the\nmodules to be profiled. These breakpoints can only be set on BEAM code, so\nBIFs cannot be call-count traced.\n\nThe size of the call counters is the host machine word size. One bit is used\nwhen pausing the counter, so the maximum counter value for a 32-bit host\nis 2,147,483,647.\n\nThe profiling result is delivered as a term containing a sorted list of entries,\none per module. Each module entry contains a sorted list of functions. The\nsorting order in both cases is of decreasing call count.\n\nCall count tracing is lightweight compared to other forms of tracing,\nsuch as `m:eprof` or `m:fprof`, since no trace messages have to be\ngenerated. Some measurements indicates that the performance degradation is\nabout 10 percent.\n\nFor more information and some examples, see the\n[User's Guide for `cprof`](cprof_chapter.md).","title":"cprof","ref":"cprof.html"},{"type":"function","doc":"","title":"cprof.analyse/0","ref":"cprof.html#analyse/0"},{"type":"function","doc":"Collect call counters for one or more modules.\n\nIf `ModLimit` is a module name (an atom), this call is equivalent to\n[`analyse(ModLimit, 1)`](`analyse/2`).\n\nIf `ModLimit` is an integer, this function calls\n[`analyse(Module, ModLimit)`](`analyse/2`) for each `Module` that is\ncurrently loaded (except the `cprof` module itself).\nThe result from those calls are returned in a list.","title":"cprof.analyse/1","ref":"cprof.html#analyse/1"},{"type":"function","doc":"Collects and analyses all call counters for module `Module`.\n\nThis function returns:\n\n```\n{Module, ModuleCount, FuncAnalysisList}\n```\n\nwhere `FuncAnalysisList` is a list of tuples, one for each function:\n\n```\n{{Module, FunctionName, Arity}, FuncCallCount}\n```\n\nIf call counters are still running while `analyse/0,1,2` is executing, the result\ncould be inconsistent. This happens if the process executing `analyse/0,1,2`\nis scheduled out so some other process can increment the counters that are\nbeing analysed. Calling [`pause()`](`pause/0`) before analysing takes care of\nthat problem.\n\nAll functions with a `FuncCallCount` lower than `Limit` are excluded from\n`FuncAnalysisList`. They are still included in `ModCallCount`, though.","title":"cprof.analyse/2","ref":"cprof.html#analyse/2"},{"type":"function","doc":"Pause call count tracing for all functions in all modules and stop it for all\nfunctions in modules to be loaded.\n\nThis call is equivalent to\n[`pause('_', '_', '_') + stop({on_load})`](`pause/3`).","title":"cprof.pause/0","ref":"cprof.html#pause/0"},{"type":"function","doc":"If `FuncSpec` is an atom, it is assumed to be a module name, and\nthis call is equivalent to [`pause(FuncSpec, '_', '_')`](`pause/3`).\n\nIf `FuncSpec` is an MFA tuple, `{Module, Name, Arity`}, this call\nis equivalent to [`pause(Module, Name, Arity)`](`pause/3`).\n\nIf `FuncSpec` is tuple `{FS}`, `FS` is the first argument to\n`erlang:trace_pattern/3`. For example, if `FuncSpec` is `{on_load}`,\ncall counters will be paused for all functions in modules to be loaded.","title":"cprof.pause/1","ref":"cprof.html#pause/1"},{"type":"function","doc":"","title":"cprof.pause/2","ref":"cprof.html#pause/2"},{"type":"function","doc":"Pause call counters for matching functions in matching modules.\n\nThe call counters for all matching functions that have call count breakpoints\nare paused at their current count.\n\nReturn the number of matching functions that can have call count breakpoints,\nthe same as [`start/*`](`start/3`) with the same arguments would have\nreturned.","title":"cprof.pause/3","ref":"cprof.html#pause/3"},{"type":"function","doc":"","title":"cprof.restart/0","ref":"cprof.html#restart/0"},{"type":"function","doc":"If `FuncSpec` is an atom, it is assumed to be a module name, and\nthis call is equivalent to [`restart(FuncSpec, '_', '_')`](`restart/3`).\n\nIf `FuncSpec` is an MFA tuple, `{Module, Name, Arity`}, this call\nis equivalent to [`restart(Module, Name, Arity)`](`restart/3`).\n\nIf `FuncSpec` is tuple `{FS}`, `FS` is the first argument to\n`erlang:trace_pattern/3`. For example, if `FuncSpec` is `{on_load}`,\ncall counters will be set to zero and running for all functions in\nmodules to be loaded.","title":"cprof.restart/1","ref":"cprof.html#restart/1"},{"type":"function","doc":"","title":"cprof.restart/2","ref":"cprof.html#restart/2"},{"type":"function","doc":"Restart call counters for the matching functions in matching modules that are\ncall-count traced.\n\nThe call counters for all matching functions that has call count breakpoints\nare set to zero and running.\n\nReturn the number of matching functions that can have call count breakpoints,\nthe same as [`start/*`](`start/3`) with the same arguments would have\nreturned.","title":"cprof.restart/3","ref":"cprof.html#restart/3"},{"type":"function","doc":"Start call count tracing for all functions in all modules, and also for all\nfunctions in modules to be loaded.\n\nThis is equivalent to\n[`start('_', '_', '_') + start({on_load})`](`start/3`).","title":"cprof.start/0","ref":"cprof.html#start/0"},{"type":"function","doc":"If `FuncSpec` is an atom, it is assumed to be a module name, and\nthis call is equivalent to [`start(FuncSpec, '_', '_')`](`start/3`).\n\nIf `FuncSpec` is an MFA tuple, `{Module, Name, Arity`}, this call\nis equivalent to [`start(Module, Name, Arity)`](`start/3`).\n\nIf `FuncSpec` is tuple `{FS}`, `FS` is the first argument to\n`erlang:trace_pattern/3`. For example, if `FuncSpec` is `{on_load}`,\ncall counters will be set to zero and running for all functions in\nmodules to be loaded.","title":"cprof.start/1","ref":"cprof.html#start/1"},{"type":"function","doc":"","title":"cprof.start/2","ref":"cprof.html#start/2"},{"type":"function","doc":"Start call count tracing for matching functions in matching modules.\n\nSet call count breakpoints on the matching functions that has no call count\nbreakpoints. Call counters are set to zero and running for all matching\nfunctions.\n\nReturn the number of matching functions that has call count breakpoints.","title":"cprof.start/3","ref":"cprof.html#start/3"},{"type":"function","doc":"Stop call count tracing for all functions in all modules, and also for all\nfunctions in modules to be loaded.\n\nThis is equivalent to\n[`stop('_', '_', '_') + stop({on_load})`](`stop/3`).","title":"cprof.stop/0","ref":"cprof.html#stop/0"},{"type":"function","doc":"If `FuncSpec` is an atom, it is assumed to be a module name, and\nthis call is equivalent to [`stop(FuncSpec, '_', '_')`](`stop/3`).\n\nIf `FuncSpec` is an MFA tuple, `{Module, Name, Arity`}, this call\nis equivalent to [`stop(Module, Name, Arity)`](`stop/3`).\n\nIf `FuncSpec` is tuple `{FS}`, `FS` is the first argument to\n`erlang:trace_pattern/3`. For example, if `FuncSpec` is `{on_load}`,\ncall counters be disabled for all functions in modules to be loaded.","title":"cprof.stop/1","ref":"cprof.html#stop/1"},{"type":"function","doc":"","title":"cprof.stop/2","ref":"cprof.html#stop/2"},{"type":"function","doc":"Stop call count tracing for matching functions in matching modules.\n\nRemove call count breakpoints from the matching functions that has call count\nbreakpoints.\n\nReturn the number of matching functions that can have call count breakpoints,\nwhich is the same as [`start/*`](`start/3`) with the same arguments would have\nreturned.","title":"cprof.stop/3","ref":"cprof.html#stop/3"},{"type":"type","doc":"","title":"cprof.func_analysis_list/0","ref":"cprof.html#t:func_analysis_list/0"},{"type":"type","doc":"","title":"cprof.mod_analysis/0","ref":"cprof.html#t:mod_analysis/0"},{"type":"type","doc":"","title":"cprof.mod_analysis_list/0","ref":"cprof.html#t:mod_analysis_list/0"},{"type":"module","doc":"A Time Profiling Tool for Erlang\n\nThe module `eprof` provides a set of functions for time profiling of Erlang\nprograms to find out how the execution time is used. The profiling is done using\nthe Erlang trace BIFs. Tracing of local function calls for a specified set of\nprocesses is enabled when profiling is begun, and disabled when profiling is\nstopped.\n\nWhen using Eprof, expect a slowdown in program execution.","title":"eprof","ref":"eprof.html"},{"type":"function","doc":"","title":"eprof.analyze/0","ref":"eprof.html#analyze/0"},{"type":"function","doc":"If `TypeOpts` is an atom, it is assumed to be a module name, and this\ncall is equivalent to [`analyze(TypeOpts, [])`](`analyze/2`).\n\nOtherwise, if `TypeOpts` is a list, it assumed to be a list of options, and this\ncall is equivalent to [`analyze(procs, TypeOpts)`](`analyze/2`).","title":"eprof.analyze/1","ref":"eprof.html#analyze/1"},{"type":"function","doc":"Call this function when profiling has been stopped to display the results.\n\nIf `Type` is `procs`, the time spent in each function is shown separately\nfor each profiled process.\n\nIf `Type` is `total`, the time spent in each function is shown combined\nfor each profiled process.\n\nTime is shown as percentage of total time and as absolute time in micro seconds.","title":"eprof.analyze/2","ref":"eprof.html#analyze/2"},{"type":"function","doc":"Call this function to ensure that the results displayed by\n[`analyze/0,1,2`](`analyze/0`) are printed to the file `File` as well as to the\nscreen.","title":"eprof.log/1","ref":"eprof.html#log/1"},{"type":"function","doc":"If `FunRootset` is a fun, this call is equivalent to\n[`profile([], FunRootset)`](`profile/2`).\n\nIf `FunRootset` is a list, it is assumed to be a `Rootset`, and this\ncall is equivalent to [`start_profiling(Rootset)`](`start_profiling/1`).","title":"eprof.profile/1","ref":"eprof.html#profile/1"},{"type":"function","doc":"If `Arg1` is a fun and `Arg2` is list, this call is equivalent to\n[`profile([], Arg1, {'_','_','_'}, Arg2)`](`profile/4`).\n\nIf `Arg1` is a list and `Arg2` is a fun, this call is equivalent to\n[`profile(Arg1, Arg2, {'_','_','_'}, Arg1)`](`profile/4`).","title":"eprof.profile/2","ref":"eprof.html#profile/2"},{"type":"function","doc":"","title":"eprof.profile/3","ref":"eprof.html#profile/3"},{"type":"function","doc":"This function spawns a process that applies a fun or an an function,\nand then starts profiling for the spawned proceses as well as the\nprocesses in `Rootset` (and any new processes spawned from them).\n\nIf `Arg1` is a fun, `Arg2` is expected to be a trace pattern, and\n`Arg3` a list of options. In that case, this call is equivalent to:\n\n[`profile(Rootset, erlang, apply, [Arg1, []], Arg2, Arg3)`](`profile/6`)\n\nIf `Arg1` is an atom, `Arg1` is assumed to be a module name, `Arg2` the\nname of the function in that module, and `Arg3` a list of arguments to\nbe used when calling that function. In that case, this call is equivalent\nto:\n\n[`profile(Rootset, Arg1, Arg2, Arg3, {'_','_','_'}, [{set_on_spawn, true}])`](`profile/6`)","title":"eprof.profile/4","ref":"eprof.html#profile/4"},{"type":"function","doc":"","title":"eprof.profile/5","ref":"eprof.html#profile/5"},{"type":"function","doc":"This function spawns a process `P` that [`apply(Module, Function,\nArgs)`](`apply/3`), and then starts profiling for `P` and the\nprocesses in `Rootset` (and any new processes spawned from them).\n\n`Rootset` is a list of pids and registered names.\n\nInformation about activity in any profiled process is stored in the Eprof\ndatabase.\n\nIf tracing could be enabled for `P` and all processes in `Rootset`, the function\nreturns `{ok,Value}` when `Fun()`/`apply` returns with the value `Value`, or\n`{error,Reason}` if `Fun()`/`apply` fails with exit reason `Reason`. Otherwise\nit returns `{error, Reason}` immediately.\n\nThe `set_on_spawn` option will active call time tracing for all processes\nspawned by processes in the rootset. This is the default behaviour.\n\nThe programmer must ensure that the function given as argument is truly\nsynchronous and that no work continues after the function has returned a value.","title":"eprof.profile/6","ref":"eprof.html#profile/6"},{"type":"function","doc":"Starts the Eprof server which holds the internal state of the collected data.","title":"eprof.start/0","ref":"eprof.html#start/0"},{"type":"function","doc":"","title":"eprof.start_profiling/1","ref":"eprof.html#start_profiling/1"},{"type":"function","doc":"","title":"eprof.start_profiling/2","ref":"eprof.html#start_profiling/2"},{"type":"function","doc":"Starts profiling for the processes in `Rootset` (and any new processes spawned\nfrom them).\n\nInformation about activity in any profiled process is stored in the\nEprof database.\n\n`Rootset` is a list of pids and registered names.\n\nThe function returns `profiling` if tracing could be enabled for all processes\nin `Rootset`, or `error` otherwise.\n\nA pattern can be selected to narrow the profiling. For instance a specific\nmodule can be selected, and only the code executed in that module will be\nprofiled.\n\nThe `set_on_spawn` option will active call time tracing for all processes\nspawned by processes in the rootset. This is the default behaviour.","title":"eprof.start_profiling/3","ref":"eprof.html#start_profiling/3"},{"type":"function","doc":"Stops the Eprof server.","title":"eprof.stop/0","ref":"eprof.html#stop/0"},{"type":"function","doc":"Stops profiling started with `start_profiling/1` or `profile/1`.","title":"eprof.stop_profiling/0","ref":"eprof.html#stop_profiling/0"},{"type":"type","doc":"","title":"eprof.analyze_type/0","ref":"eprof.html#t:analyze_type/0"},{"type":"type","doc":"","title":"eprof.trace_pattern_mfa/0","ref":"eprof.html#t:trace_pattern_mfa/0"},{"type":"module","doc":"A Time Profiling Tool using trace to file for minimal runtime performance\nimpact.\n\nThis module is used to profile a program to find out how the execution time is\nused. Tracing to file is used to minimize the runtime performance degradation.\n\nThe `fprof` module uses tracing to collect profiling data, hence there is no\nneed for special compilation of any module to be profiled. When it starts\ntracing, `fprof` will erase all previous tracing in the node and set the\nnecessary trace flags on the profiling target processes as well as local call\ntrace on all functions in all loaded modules and all modules to be loaded.\n`fprof` disable all tracing in the node when it stops tracing.\n\n`fprof` presents both _own time_ that is, how much time a function has\nused for its own execution, and _accumulated time_ that is, including\ncalled functions. All presented times are collected using trace\ntimestamps. `fprof` tries to collect CPU time timestamps, if the host\nmachine OS supports it. Therefore, the times can be wallclock times and\nOS scheduling will randomly strike all called functions in a\npresumably fair way.\n\nHowever, if the profiling time is short, and the host machine OS does\nnot support high resolution CPU time measurements, a few OS\nschedulings can show up as ridiculously long execution times for\nfunctions doing practically nothing. As an example, it has been\nobserved that a function that more or less just composing a tuple, was\nrunning 100 times slower than normal. When tracing was repeated, the\nexecution time was normal.\n\nProfiling is essentially done in 3 steps:\n\n- Tracing: to a file. The trace data contains entries for function\n calls, returns to function, process scheduling, other process\n related events (for example `spawn`), and garbage collection. All trace\n entries are timestamped.\n\n- Profiling: the trace file is read, the execution call stack is\n simulated, and raw profile data is calculated from the simulated call stack\n and the trace timestamps. The profile data is stored in the `fprof` server\n state. During this step the trace data may be dumped in text format to file or\n console.\n\n- Analysing: the raw profile data is sorted, filtered and dumped in\n text format either to file or console. The text format intended to be both\n readable for a human reader, as well as parsable with the standard erlang\n parsing tools.\n\nSince `fprof` sends trace data to afile, the runtime performance\ndegradation is minimized, but still far from negligible, especially\nfor programs that themselves use the filesystem heavily. Where the\ntrace file is placed is also important, for example, on Unix systems\n`/tmp` is usually a good choice since it is essentially a RAM disk,\nwhile any network-mounted disk is a bad idea.\n\n`fprof` can also skip the file step and trace to a tracer process that does the\nprofiling in runtime.\n\n[](){: #analysis }","title":"fprof","ref":"fprof.html"},{"type":"module","doc":"This section describes the output format of the `analyse/1` function.\n\nThe format is parsable with the standard Erlang parsing tools\n`m:erl_scan` and `m:erl_parse`, `file:consult/1`, or `io:read/2`. The\nparse format is not described here — it should be easy enough for the\ninterested reader to try it out. Note that some flags to\n[`analyse/1`](`analyse/1`) will affect the format.\n\nThe following example was run on Erlang/OTP R8 on Solaris 8; all OTP\ninternals in this example are version dependent.\n\nAs an example, we will use the following function, which is a\nslightly modified benchmark function from module `m:file`:\n\n```erlang\n-module(foo).\n-export([create_file_slow/2]).\n\ncreate_file_slow(Name, N) when is_integer(N), N >= 0 ->\n {ok, FD} =\n file:open(Name, [raw, write, delayed_write, binary]),\n if N > 256 ->\n ok = file:write(FD,\n lists:map(fun (X) -> < > end,\n lists:seq(0, 255))),\n ok = create_file_slow(FD, 256, N);\n true ->\n ok = create_file_slow(FD, 0, N)\n end,\n ok = file:close(FD).\n\ncreate_file_slow(FD, M, M) ->\n ok;\ncreate_file_slow(FD, M, N) ->\n ok = file:write(FD, < >),\n create_file_slow(FD, M+1, N).\n```\n\nLet us have a look at the printout after running:\n\n```erlang\n1> fprof:apply(foo, create_file_slow, [junk, 1024]).\n2> fprof:profile().\n3> fprof:analyse().\n```\n\nThe printout starts with:\n\n```erlang\n%% Analysis results:\n{ analysis_options,\n [{callers, true},\n {sort, acc},\n {totals, false},\n {details, true}]}.\n\n% CNT ACC OWN\n[{ totals, 9627, 1691.119, 1659.074}]. %%%\n```\n\nThe `CNT` column shows the total number of function calls that was found in the\ntrace. In the `ACC` column is the total time of the trace from first timestamp to\nlast. And in the `OWN` column is the sum of the execution time in functions found\nin the trace, not including called functions. In this case it is very close to\nthe `ACC` time since the emulator had practically nothing to do except\nexecuting our test program.\n\nAll time values in the printout are in milliseconds.\n\nThe printout continues:\n\n```erlang\n% CNT ACC OWN\n[{ \"<0.28.0>\", 9627,undefined, 1659.074}]. %%\n```\n\nThis is the printout header of one process. The printout contains only this one\nprocess since we called `fprof:apply/3` that traces only the current process.\nTherefore the `CNT` and `OWN` columns perfectly matches the totals above. The `ACC`\ncolumn is undefined since summing the `ACC` times of all calls in the process\nmakes no sense — one would get something like the `ACC` value from totals above\nmultiplied by the average depth of the call stack.\n\nAll paragraphs up to the next process header only concerns function calls within\nthis process.\n\nNow we come to something more interesting:\n\n```erlang\n{[{undefined, 0, 1691.076, 0.030}],\n { {fprof,apply_start_stop,4}, 0, 1691.076, 0.030}, %\n [{{foo,create_file_slow,2}, 1, 1691.046, 0.103},\n {suspend, 1, 0.000, 0.000}]}.\n\n{[{{fprof,apply_start_stop,4}, 1, 1691.046, 0.103}],\n { {foo,create_file_slow,2}, 1, 1691.046, 0.103}, %\n [{{file,close,1}, 1, 1398.873, 0.019},\n {{foo,create_file_slow,3}, 1, 249.678, 0.029},\n {{file,open,2}, 1, 20.778, 0.055},\n {{lists,map,2}, 1, 16.590, 0.043},\n {{lists,seq,2}, 1, 4.708, 0.017},\n {{file,write,2}, 1, 0.316, 0.021}]}.\n```\n\nThe printout consists of one paragraph per called function. The function\n_marked_ with `%` is the one the paragraph concerns — `foo:create_file_slow/2`.\nAbove the marked function are the _calling_ functions — those that has called\nthe marked, and below are those _called_ by the marked function.\n\nThe paragraphs are per default sorted in descending order of the `ACC` column for\nthe marked function. The calling list and called list within one paragraph are\nalso per default sorted in descending order of their `ACC` column.\n\nThe columns are:\n\n* `CNT` - the number of times the function has been called\n* `ACC` - the time spent in the function including called functions\n* `OWN` - the time spent in the function not including called functions\n\nThe rows for the _calling_ functions contain statistics for the _marked_\nfunction with the constraint that only the occasions when a call was made from\nthe _row's_ function to the _marked_ function are accounted for.\n\nThe row for the _marked_ function simply contains the sum of all _calling_ rows.\n\nThe rows for the _called_ functions contains statistics for the _row's_ function\nwith the constraint that only the occasions when a call was made from the\n_marked_ to the _row's_ function are accounted for.\n\nSo, we see that `foo:create_file_slow/2` used very little time for its own\nexecution. It spent most of its time in `file:close/1`. The function\n`foo:create_file_slow/3` that writes 3/4 of the file contents is the second\nbiggest time thief.\n\nWe also see that the call to `file:write/2` that writes 1/4 of the file contents\ntakes very little time in itself. What takes time is to build the data\n(`lists:seq/2` and `lists:map/2`).\n\nThe function `undefined` that has called `fprof:apply_start_stop/4` is an\nunknown function because that call was not recorded in the trace. It was only\nrecorded that the execution returned from `fprof:apply_start_stop/4` to some\nother function above in the call stack, or that the process exited from there.\n\nLet us continue down the printout to find:\n\n```erlang\n{[{{foo,create_file_slow,2}, 1, 249.678, 0.029},\n {{foo,create_file_slow,3}, 768, 0.000, 23.294}],\n { {foo,create_file_slow,3}, 769, 249.678, 23.323}, %\n [{{file,write,2}, 768, 220.314, 14.539},\n {suspend, 57, 6.041, 0.000},\n {{foo,create_file_slow,3}, 768, 0.000, 23.294}]}.\n```\n\nIf you compare with the code you will see there also that\n`foo:create_file_slow/3` was called only from `foo:create_file_slow/2` and\nitself, and called only `file:write/2`, note the number of calls to\n`file:write/2`. But here we see that `suspend` was called a few times. This is a\npseudo function that indicates that the process was suspended while executing in\n`foo:create_file_slow/3`, and since there is no `receive` or `erlang:yield/0` in\nthe code, it must be Erlang scheduling suspensions, or the trace file driver\ncompensating for large file write operations (these are regarded as a schedule\nout followed by a schedule in to the same process).\n\nLet us find the `suspend` entry:\n\n```erlang\n{[{{file,write,2}, 53, 6.281, 0.000},\n {{foo,create_file_slow,3}, 57, 6.041, 0.000},\n {{prim_file,drv_command,4}, 50, 4.582, 0.000},\n {{prim_file,drv_get_response,1}, 34, 2.986, 0.000},\n {{lists,map,2}, 10, 2.104, 0.000},\n {{prim_file,write,2}, 17, 1.852, 0.000},\n {{erlang,port_command,2}, 15, 1.713, 0.000},\n {{prim_file,drv_command,2}, 22, 1.482, 0.000},\n {{prim_file,translate_response,2}, 11, 1.441, 0.000},\n {{prim_file,'-drv_command/2-fun-0-',1}, 15, 1.340, 0.000},\n {{lists,seq,4}, 3, 0.880, 0.000},\n {{foo,'-create_file_slow/2-fun-0-',1}, 5, 0.523, 0.000},\n {{erlang,bump_reductions,1}, 4, 0.503, 0.000},\n {{prim_file,open_int_setopts,3}, 1, 0.165, 0.000},\n {{prim_file,i32,4}, 1, 0.109, 0.000},\n {{fprof,apply_start_stop,4}, 1, 0.000, 0.000}],\n { suspend, 299, 32.002, 0.000}, %\n [ ]}.\n```\n\nWe find no particularly long suspend times, so no function seems to have waited\nin a receive statement. Actually, `prim_file:drv_command/4` contains a receive\nstatement, but in this test program, the message lies in the process receive\nbuffer when the receive statement is entered. We also see that the total suspend\ntime for the test run is small.\n\nThe `suspend` pseudo function has an `OWN` time of zero. This is to prevent\nthe process total `OWN` time from including time in suspension. Whether suspend\ntime is really `ACC` or `OWN` time is more of a philosophical question.\n\nNow we look at another interesting pseudo function, `garbage_collect`:\n\n```erlang\n{[{{prim_file,drv_command,4}, 25, 0.873, 0.873},\n {{prim_file,write,2}, 16, 0.692, 0.692},\n {{lists,map,2}, 2, 0.195, 0.195}],\n { garbage_collect, 43, 1.760, 1.760}, %\n [ ]}.\n```\n\nHere we see that no function stands out, which is very normal.\n\nThe `garbage_collect` pseudo function has not an `OWN` time of zero like\n`suspend`, instead it is equal to the `ACC` time.\n\nGarbage collection often occurs while a process is suspended, but `fprof` hides\nthis fact by pretending that the suspended function was first unsuspended and\nthen garbage collected. Otherwise the printout would show `garbage_collect`\nbeing called from `suspend`, but not which function that might have caused the\ngarbage collection.\n\nLet us now get back to the test code:\n\n```erlang\n{[{{foo,create_file_slow,3}, 768, 220.314, 14.539},\n {{foo,create_file_slow,2}, 1, 0.316, 0.021}],\n { {file,write,2}, 769, 220.630, 14.560}, %\n [{{prim_file,write,2}, 769, 199.789, 22.573},\n {suspend, 53, 6.281, 0.000}]}.\n```\n\nNot unexpectedly, we see that `file:write/2` was called from\n`foo:create_file_slow/3` and `foo:create_file_slow/2`. The number of calls in\neach case as well as the used time are also confirms the previous results.\n\nWe see that `file:write/2` only calls `prim_file:write/2`, but let us refrain\nfrom digging into the internals of the kernel application.\n\nIf we nevertheless _do_ dig down we find the call to the linked-in driver\nthat does the file operations towards the host operating system:\n\n```erlang\n{[{{prim_file,drv_command,4}, 772, 1458.356, 1456.643}],\n { {erlang,port_command,2}, 772, 1458.356, 1456.643}, %\n [{suspend, 15, 1.713, 0.000}]}.\n```\n\nThis is 86 % of the total run time, and as we saw before it is the close\noperation the absolutely biggest contributor. We find a comparison ratio a\nlittle bit up in the call stack:\n\n```erlang\n{[{{prim_file,close,1}, 1, 1398.748, 0.024},\n {{prim_file,write,2}, 769, 174.672, 12.810},\n {{prim_file,open_int,4}, 1, 19.755, 0.017},\n {{prim_file,open_int_setopts,3}, 1, 0.147, 0.016}],\n { {prim_file,drv_command,2}, 772, 1593.322, 12.867}, %\n [{{prim_file,drv_command,4}, 772, 1578.973, 27.265},\n {suspend, 22, 1.482, 0.000}]}.\n```\n\nThe time for file operations in the linked in driver distributes itself as 1 %\nfor open, 11 % for write, and 87 % for close. All data is probably buffered in\nthe operating system until the close.\n\nThe observant reader may notice that the ACC times for\n`prim_file:drv_command/2` and `prim_file:drv_command/4` is not equal between the\nparagraphs above, even though it is easy to believe that\n`prim_file:drv_command/2` is just a passthrough function.\n\nThe missing time can be found in the paragraph for `prim_file:drv_command/4`\nwhere it is evident that not only `prim_file:drv_command/2` is called but also a\nfun:\n\n```erlang\n{[{{prim_file,drv_command,2}, 772, 1578.973, 27.265}],\n { {prim_file,drv_command,4}, 772, 1578.973, 27.265}, %\n [{{erlang,port_command,2}, 772, 1458.356, 1456.643},\n {{prim_file,'-drv_command/2-fun-0-',1}, 772, 87.897, 12.736},\n {suspend, 50, 4.582, 0.000},\n {garbage_collect, 25, 0.873, 0.873}]}.\n```\n\nAnd some more missing time can be explained by the fact that\n`prim_file:open_int/4` both calls `prim_file:drv_command/2` directly as well as\nthrough `prim_file:open_int_setopts/3`, which complicates the picture.\n\n```erlang\n{[{{prim_file,open,2}, 1, 20.309, 0.029},\n {{prim_file,open_int,4}, 1, 0.000, 0.057}],\n { {prim_file,open_int,4}, 2, 20.309, 0.086}, %\n [{{prim_file,drv_command,2}, 1, 19.755, 0.017},\n {{prim_file,open_int_setopts,3}, 1, 0.360, 0.032},\n {{prim_file,drv_open,2}, 1, 0.071, 0.030},\n {{erlang,list_to_binary,1}, 1, 0.020, 0.020},\n {{prim_file,i32,1}, 1, 0.017, 0.017},\n {{prim_file,open_int,4}, 1, 0.000, 0.057}]}.\n.\n.\n.\n{[{{prim_file,open_int,4}, 1, 0.360, 0.032},\n {{prim_file,open_int_setopts,3}, 1, 0.000, 0.016}],\n { {prim_file,open_int_setopts,3}, 2, 0.360, 0.048}, %\n [{suspend, 1, 0.165, 0.000},\n {{prim_file,drv_command,2}, 1, 0.147, 0.016},\n {{prim_file,open_int_setopts,3}, 1, 0.000, 0.016}]}.\n```","title":"Analysis format - fprof","ref":"fprof.html#module-analysis-format"},{"type":"module","doc":"The actual supervision of execution times is in itself a CPU-intensive activity.\nA message is written on the trace file for every function call that is made by\nthe profiled code.\n\nThe `ACC` time calculation is sometimes difficult to make correct, since it is\ndifficult to define. This happens especially when a function occurs in several\ninstances in the call stack, for example by calling itself perhaps through other\nfunctions and perhaps even non-tail recursively.\n\nTo produce sensible results, `fprof` tries not to charge any function more than\nonce for `ACC` time. The instance highest up (with longest duration) in the call\nstack is chosen.\n\nSometimes a function can unexpectedly waste a lot (some 10 ms or more depending\non host machine OS) of `OWN` (and `ACC`) time, even functions that do practically\nnothing at all. The problem may be that the OS has chosen to schedule out the\nErlang runtime system process for a while, and if the OS does not support high\nresolution CPU time measurements `fprof` will use wallclock time for its\ncalculations, and it will appear as if functions are randomly burning virtual\nmachine time.","title":"Notes - fprof","ref":"fprof.html#module-notes"},{"type":"module","doc":"[fprof - The File Trace Profiler](fprof_chapter.md), `m:dbg`, `m:eprof`","title":"See Also - fprof","ref":"fprof.html#module-see-also"},{"type":"function","doc":"","title":"fprof.analyse/0","ref":"fprof.html#analyse/0"},{"type":"function","doc":"Analyses raw profile data in the `fprof` server.\n\nIf `Arg` is an atom, this call is equivalent to `analyse([Arg])`.\n\nIf `Arg` is a a tuple `{Option, _}`, this call is equivalent to\n`analyse([Option])`.\n\nOtherwise `Arg` must be a list of valid options.\n\nIf called when no raw profile data is available, `{error, no_profile}`\nis returned.\n\n`Destfile` is used to call `file:open/2`.\n\nOption description:\n\n- **`dest` | `{dest, Dest}`** - Specifies the destination for the analysis. If\n this option is not given or it is `dest`, the destination will be the caller's\n group leader, otherwise the destination `Dest` is either the `t:pid/0` of an\n I/O device or a filename. If the filename is `[]`, `\"fprof.analysis\"` is used\n instead.\n\n- **`append`** - Causes the analysis to be appended to the destination file.\n This option is only allowed with the `{dest, Destfile}` option.\n\n- **`{cols, Cols}`** - Specifies the number of columns in the analysis text. If\n this option is not given the number of columns is set to 80.\n\n- **`callers` | `{callers, true}`** - Prints callers and called information in\n the analysis. This is the default.\n\n- **`{callers, false}` | `no_callers`** - Suppresses the printing of callers and\n called information in the analysis.\n\n- **`{sort, SortSpec}`** - Specifies if the analysis should be sorted according\n to the ACC column, which is the default, or the OWN column. See\n [Analysis Format](`m:fprof#analysis`) below.\n\n- **`totals` | `{totals, true}`** - Includes a section containing call\n statistics for all calls regardless of process, in the analysis.\n\n- **`{totals, false}`** - Suppresses the totals section in the analysis, which\n is the default.\n\n- **`details` | `{details, true}`** - Prints call statistics for each process in\n the analysis. This is the default.\n\n- **`{details, false}` | `no_details`** - Suppresses the call statistics for\n each process from the analysis.","title":"fprof.analyse/1","ref":"fprof.html#analyse/1"},{"type":"function","doc":"","title":"fprof.analyse/2","ref":"fprof.html#analyse/2"},{"type":"function","doc":"","title":"fprof.apply/2","ref":"fprof.html#apply/2"},{"type":"function","doc":"Calls the given function surrounded by\n[`trace([start, ...])`](`trace/1`) and\n[`trace(stop)`](`trace/1`).\n\nIf the function arguments (`Arg1`, `Arg2`, and `Arg3`) are `Module`\n(an atom), `Function` (an atom), and `Args` (a list), the function\nwill be called using\n[`erlang:apply(Module, Function, Args)`](`erlang:apply/3`).\n\nIf the function arguments are `Func` (a fun), `Args` (a list), and\n`OptionList` (a list of options), the fun will be called using\n[`erlang:apply(Func, Args)`](`erlang:apply/2`).\n\nSome effort is made to keep the trace clean from unnecessary trace messages;\ntracing is started and stopped from a spawned process while `erlang:apply/2`\nis called in the current process only surrounded by `receive` and `send`\nstatements towards the trace starting process. The trace starting process exits\nwhen it is not needed any more.\n\nThe `TraceStartOption` is any option allowed for `trace/1`. The\noptions `[start, {procs, [self() | PidList]} | OptList]` are given to\n[`trace/1`](`trace/1`), where `OptList` is `OptionList` with the\n`continue`, `start` and `{procs, _}` options removed.\n\nThe `continue` option inhibits the call to [`trace(stop)`](`trace/1`) and leaves\nit up to the caller to stop tracing at a suitable time.","title":"fprof.apply/3","ref":"fprof.html#apply/3"},{"type":"function","doc":"","title":"fprof.apply/4","ref":"fprof.html#apply/4"},{"type":"function","doc":"","title":"fprof.profile/0","ref":"fprof.html#profile/0"},{"type":"function","doc":"Compiles a trace into raw profile data held by the `fprof` server.\n\nIf `Arg` is an atom, this call is equivalent to `profile([Arg])`.\n\nIf `Arg` is a tuple `{OptionName, OptionValue}`,\nthis call is equivalent to `profile([Arg])`.\n\nOtherwise, `Arg` must be a list of options.\n\n`Dumpfile` is used to call `file:open/2`, and `Filename` is used to call\n[`dbg:trace_port(file, Filename)`](`dbg:trace_port/2`).\n\nThe following options are supported:\n\n- **`file` | `{file, Filename}`** - Reads the file `Filename` and creates raw\n profile data that is stored in RAM by the `fprof` server. If the option `file`\n is given, or none of these options are given, the file `fprof.trace` is\n read. The call will return when the whole trace has been read with the return\n value `ok` if successful. This option is not allowed with the `start` or\n `stop` options.\n\n- **`dump` | `{dump, Dump}`** - Specifies the destination for the trace text\n dump. If this option is not given, no dump is generated, if it is `dump` the\n destination will be the caller's group leader, otherwise the destination\n `Dump` is either the pid of an I/O device or a filename. If the\n filename is `[]`, `\"fprof.dump\"` is used instead. This option cannot be\n combined with the `stop` option.\n\n- **`append`** - Causes the trace text dump to be appended to the destination\n file. This option is only allowed with the `{dump, Dumpfile}` option.\n\n- **`start`** - Starts a tracer process that profiles trace data in runtime. The\n call will return immediately with the return value `{ok, Tracer}` if\n successful. This option is not allowed with the `stop`, `file`, or\n `{file, Filename}` options.\n\n- **`stop`** - Stops the tracer process that profiles trace data in runtime. The\n return value will be value `ok` if successful. This option cannot be combined\n with the `start`, `file`, or `{file, Filename}` options.","title":"fprof.profile/1","ref":"fprof.html#profile/1"},{"type":"function","doc":"","title":"fprof.profile/2","ref":"fprof.html#profile/2"},{"type":"function","doc":"Starts the `fprof` server.\n\nNote that there is seldom any need to call this function directly, since\nthe server will be automatically started by any function that will need it.","title":"fprof.start/0","ref":"fprof.html#start/0"},{"type":"function","doc":"","title":"fprof.stop/0","ref":"fprof.html#stop/0"},{"type":"function","doc":"Stops the `fprof` server.\n\nThe supplied `Reason` becomes the exit reason for the server process. By default,\nany `Reason` other than `kill` sends a request to the server and waits for it to\nclean up, reply, and exit. If `Reason` is `kill`, the server is bluntly killed.\n\nIf the `fprof` server is not running, this function returns immediately.\n\n> #### Note {: .info }\n>\n> When the `fprof` server is stopped the collected raw profile data is lost.","title":"fprof.stop/1","ref":"fprof.html#stop/1"},{"type":"function","doc":"Starts or stops tracing.\n\nIf `Arg` is atom `verbose`, this call is equivalent to\n`trace([start, verbose])`.\n\nIf `Arg` is an atom, this call is equivalent to\n`trace([Arg])`.\n\nIf `Arg` is a tuple `{OptionName, OptionValue}`, this call is equivalent to\n`trace([Arg])`.\n\nOtherwise, `Arg` has to be a list of [trace options](`t:trace_option/0`).\n\n`PidSpec` and `Tracer` are used in calls to\n[`erlang:trace(PidSpec, true, [{tracer, Tracer} | Flags])`](`erlang:trace/3`),\nand `Filename` is used to call\n[`dbg:trace_port(file, Filename)`](`dbg:trace_port/2`).\n\nOption description:\n\n- **`stop`** - Stops a running `fprof` trace and clears all tracing from the\n node. Either option `stop` or `start` must be specified, but not both.\n\n- **`start`** - Clears all tracing from the node and starts a new `fprof` trace.\n Either option `start` or `stop` must be specified, but not both.\n\n- **`verbose` | `{verbose, boolean()}`** - The `verbose` or\n `{verbose, true}` options add some trace flags that `fprof` does not need, but that\n can be interesting for general debugging purposes. These options are only allowed\n with the `start` option.\n\n- **`cpu_time` | `{cpu_time, boolean()}`** - The `cpu_time` or\n `{cpu_time, true}` options make the timestamps in the trace be in CPU time instead of\n the default wallclock time. These options are only allowed with the\n `start` option.\n\n > #### Note {: .info }\n >\n > Getting correct values out of `cpu_time` can be difficult. The best way to get\n > correct values is to run using a single scheduler and bind that scheduler to\n > a specific CPU. For example:\n >\n > ```bash\n > erl +S 1 +sbt db`\n > ```\n\n- **`{procs, PidSpec}` | `{procs, [PidSpec]}`** - Specifies which processes that\n should be traced. If this option is not given, the calling process is traced.\n All processes spawned by the traced processes are also traced. This option is\n only allowed with the `start` option.\n\n- **`file` | `{file, Filename}`** - Specifies the filename of the trace. If the\n option `file` is given, or none of these options are given, the file\n `fprof.trace` is used. This option is only allowed with the `start` option,\n but not with the `{tracer, Tracer}` option.\n\n- **`{tracer, Tracer}`** - Specifies that trace to process or port shall be done\n instead of trace to file. This option is only allowed with the `start` option,\n but not with the `{file, Filename}` option.","title":"fprof.trace/1","ref":"fprof.html#trace/1"},{"type":"function","doc":"Starts or stop tracing.\n\nIf `What` is atom `start`, this call is equivalent to\n[`trace([start, {file, Value}])`](`trace/1`).\n\nIf `What` is atom `verbose`, this call is equivalent to\n[`trace([start, verbose, {file, Value}])`](`trace/1`).\n\nIf `What` is a tuple `{OptionName, OptionValue}`,\nthis call is equivalent to\n[`trace([What])`](`trace/1`).","title":"fprof.trace/2","ref":"fprof.html#trace/2"},{"type":"type","doc":"","title":"fprof.analyse_option/0","ref":"fprof.html#t:analyse_option/0"},{"type":"type","doc":"","title":"fprof.apply_option/0","ref":"fprof.html#t:apply_option/0"},{"type":"type","doc":"","title":"fprof.pid_spec/0","ref":"fprof.html#t:pid_spec/0"},{"type":"type","doc":"","title":"fprof.profile_option/0","ref":"fprof.html#t:profile_option/0"},{"type":"type","doc":"","title":"fprof.trace_option/0","ref":"fprof.html#t:trace_option/0"},{"type":"module","doc":"A runtime system Lock Profiling tool.\n\nThe `lcnt` module is used to profile the internal ethread locks in the Erlang\nRuntime System. With `lcnt` enabled, internal counters in the runtime system are\nupdated each time a lock is taken. The counters stores information about the\nnumber of acquisition tries and the number of collisions that has occurred\nduring the acquisition tries. The counters also record the waiting time a lock\nhas caused for a blocked thread when a collision has occurred.\n\nThe data produced by the lock counters will give an estimate on how well the\nruntime system will behave from a parallelizable view point for the scenarios\ntested. This tool was mainly developed to help Erlang runtime developers iron\nout potential and generic bottlenecks.\n\nLocks in the emulator are named after what type of resource they protect and\nwhere in the emulator they are initialized, those are lock 'classes'. Most of\nthose locks are also instantiated several times, and given unique identifiers,\nto increase locking granularity. Typically an instantiated lock protects a\ndisjunct set of the resource, for example ets tables, processes or ports. In\nother cases it protects a specific range of a resource, for example `pix_lock`\nwhich protects index to process mappings, and is given a unique number within\nthe class. A unique lock in `lcnt` is referenced by a name (class) and an\nidentifier: `{Name, Id}`.\n\nSome locks in the system are static and protects global resources, for example\n`bif_timers` and the `run_queue` locks. Other locks are dynamic and not\nnecessarily long lived, for example process locks and ets-table locks. The\nstatistics data from short lived locks can be stored separately when the locks\nare deleted. This behavior is by default turned off to save memory but can be\nturned on via `lcnt:rt_opt({copy_save, true})`. The `lcnt:apply/1,2,3` functions\nenables this behavior during profiling.","title":"lcnt","ref":"lcnt.html"},{"type":"module","doc":"[LCNT User's Guide](lcnt_chapter.md)","title":"See Also - lcnt","ref":"lcnt.html#module-see-also"},{"type":"function","doc":"","title":"lcnt.apply/1","ref":"lcnt.html#apply/1"},{"type":"function","doc":"Sets up lock counters, applies `Fun` with `Args`, and cleans up.\n\nClears the lock counters and then setups the instrumentation to save all\ndestroyed locks. After setup the function is called, passing the elements in\n`Args` as arguments. When the function returns the statistics are immediately\ncollected to the server. After the collection the instrumentation is returned to\nits previous behavior. The result of the applied function is returned.\n\n> #### Warning {: .warning }\n>\n> This function should only be used for micro-benchmarks; it sets `copy_save` to\n> `true` for the duration of the call, which can quickly lead to running out of\n> memory.","title":"lcnt.apply/2","ref":"lcnt.html#apply/2"},{"type":"function","doc":"","title":"lcnt.apply/3","ref":"lcnt.html#apply/3"},{"type":"function","doc":"","title":"lcnt.clear/0","ref":"lcnt.html#clear/0"},{"type":"function","doc":"Clears the internal lock statistics from the runtime system.\n\nThis clears the data in the runtime system but not in server. All\ncounters for static locks are zeroed, all dynamic locks currently\nalive are zeroed and all saved locks now destroyed are removed. It\nalso resets the duration timer.","title":"lcnt.clear/1","ref":"lcnt.html#clear/1"},{"type":"function","doc":"","title":"lcnt.collect/0","ref":"lcnt.html#collect/0"},{"type":"function","doc":"Collects lock statistics from the runtime system.\n\nThe function starts a server if it is not already started. It then\npopulates the server with lock statistics. If the server held any\nlock statistics data before the collect then that data is lost.","title":"lcnt.collect/1","ref":"lcnt.html#collect/1"},{"type":"function","doc":"","title":"lcnt.conflicts/0","ref":"lcnt.html#conflicts/0"},{"type":"function","doc":"Prints a list of internal locks and its statistics.\n\nFor option description, see [`lcnt:inspect/2`](`inspect/2`).","title":"lcnt.conflicts/1","ref":"lcnt.html#conflicts/1"},{"type":"function","doc":"Prints `lcnt` server state and generic information about collected lock\nstatistics.","title":"lcnt.information/0","ref":"lcnt.html#information/0"},{"type":"function","doc":"","title":"lcnt.inspect/1","ref":"lcnt.html#inspect/1"},{"type":"function","doc":"Prints a list of internal lock counters for a specific lock.\n\nLock `Name` and `Id` for ports and processes are interchangeable with the use of\n[`lcnt:swap_pid_keys/0`](`swap_pid_keys/0`) and is the reason why `t:pid/0` and\n`t:port/0` options can be used in both `Name` and `Id` space. Both pids and\nports are special identifiers with stripped creation and can be recreated with\n[`lcnt:pid/2,3`](`pid/3`) and [`lcnt:port/1,2`](`port/2`).\n\nOption description:\n\n- **`{combine, boolean()}`** - Combine the statistics from different instances\n of a lock class. \n Default: `true`\n\n- **`{locations, boolean()}`** - Print the statistics by source file and line\n numbers. \n Default: `false`\n\n- **`{max_locks, MaxLocks}`** - Maximum number of locks printed or no limit with\n `none`. \n Default: `20`\n\n- **`{print, PrintOptions}`** - Printing options:\n\n - **`name`** - Named lock or named set of locks (classes). The same name used\n for initializing the lock in the VM.\n\n - **`id`** - Internal id for set of locks, not always unique. This could be\n table name for ets tables (db_tab), port id for ports, integer identifiers\n for allocators, etc.\n\n - **`type`** - Type of lock: `rw_mutex`, `mutex`, `spinlock`, `rw_spinlock` or\n `proclock`.\n\n - **`entry`** - In combination with `{locations, true}` this option prints the\n lock operations source file and line number entry-points along with\n statistics for each entry.\n\n - **`tries`** - Number of acquisitions of this lock.\n\n - **`colls`** - Number of collisions when a thread tried to acquire this lock.\n This is when a trylock is EBUSY, a write try on read held rw_lock, a try\n read on write held rw_lock, a thread tries to lock an already locked lock.\n (Internal states supervises this.)\n\n - **`ratio`** - The ratio between the number of collisions and the number of\n tries (acquisitions) in percentage.\n\n - **`time`** - Accumulated waiting time for this lock. This could be greater\n than actual wall clock time, it is accumulated for all threads. Trylock\n conflicts does not accumulate time.\n\n - **`duration`** - Percentage of accumulated waiting time of wall clock time.\n This percentage can be higher than 100% since accumulated time is from all\n threads.\n\n Default: `[name,id,tries,colls,ratio,time,duration]`\n\n- **`{reverse, boolean()}`** - Reverses the order of sorting. \n Default: `false`\n\n- **`{sort, Sort}`** - Column sorting orders. \n Default: `time`\n\n- **`{thresholds, Thresholds}`** - Filtering thresholds. Anything values above\n the threshold value are passed through. \n Default: `[{tries, 0}, {colls, 0}, {time, 0}]`","title":"lcnt.inspect/2","ref":"lcnt.html#inspect/2"},{"type":"function","doc":"Restores previously saved data to the server.","title":"lcnt.load/1","ref":"lcnt.html#load/1"},{"type":"function","doc":"","title":"lcnt.locations/0","ref":"lcnt.html#locations/0"},{"type":"function","doc":"Prints a list of internal lock counters by source code locations.\n\nFor option description, see [`lcnt:inspect/2`](`inspect/2`).","title":"lcnt.locations/1","ref":"lcnt.html#locations/1"},{"type":"function","doc":"","title":"lcnt.pid/2","ref":"lcnt.html#pid/2"},{"type":"function","doc":"Creates a process id with creation 0.","title":"lcnt.pid/3","ref":"lcnt.html#pid/3"},{"type":"function","doc":"","title":"lcnt.port/1","ref":"lcnt.html#port/1"},{"type":"function","doc":"Creates a port id with creation 0.","title":"lcnt.port/2","ref":"lcnt.html#port/2"},{"type":"function","doc":"","title":"lcnt.rt_clear/0","ref":"lcnt.html#rt_clear/0"},{"type":"function","doc":"Clear the internal counters.\n\nEquivalent to [`lcnt:clear(Node)`](`clear/1`).","title":"lcnt.rt_clear/1","ref":"lcnt.html#rt_clear/1"},{"type":"function","doc":"","title":"lcnt.rt_collect/0","ref":"lcnt.html#rt_collect/0"},{"type":"function","doc":"Returns a list of raw lock counter data.","title":"lcnt.rt_collect/1","ref":"lcnt.html#rt_collect/1"},{"type":"function","doc":"Return the current category mask for the current node.","title":"lcnt.rt_mask/0","ref":"lcnt.html#rt_mask/0"},{"type":"function","doc":"Sets the current lock category mask for the current node or\nretrieves the current mask for a remote node.\n\nIf `Arg` is an atom, it is assumed to be a node, and this\ncall returns the current lock category mask for node `Arg`.\n\nIf `Arg` is a list, this call is equivalent to\n[`rt_mask(node(), Arg)`](`rt_mask/2`).","title":"lcnt.rt_mask/1","ref":"lcnt.html#rt_mask/1"},{"type":"function","doc":"Sets the lock category mask according to `Categories` on node `Node`.\n\nThis call will fail if the `copy_save` option is enabled; see\n[`lcnt:rt_opt/2`](`rt_opt/2`).\n\nValid categories are:\n\n- `allocator`\n- `db` (ETS tables)\n- `debug`\n- `distribution`\n- `generic`\n- `io`\n- `process`\n- `scheduler`\n\nThis list is subject to change at any time, as is the category any given lock\nbelongs to.","title":"lcnt.rt_mask/2","ref":"lcnt.html#rt_mask/2"},{"type":"function","doc":"","title":"lcnt.rt_opt/1","ref":"lcnt.html#rt_opt/1"},{"type":"function","doc":"Sets a single option on node `Node`.\n\nOption description:\n\n- **`{copy_save, boolean()}`** - Retains the statistics of destroyed locks. \n Default: `false`\n\n > #### Warning {: .warning }\n >\n > This option will use a lot of memory when enabled, which must be reclaimed\n > with [`lcnt:rt_clear/0,1`](`lcnt:rt_clear/1`). Note that it makes no\n > distinction between locks that were destroyed and locks for which counting\n > was disabled, so enabling this option will disable changes to the lock\n > category mask.\n\n- **`{process_locks, boolean()}`** - Profile process locks, equal to adding\n `process` to the lock category mask; see `lcnt:rt_mask/2`. \n Default: `true`","title":"lcnt.rt_opt/2","ref":"lcnt.html#rt_opt/2"},{"type":"function","doc":"Saves the collected data to file.","title":"lcnt.save/1","ref":"lcnt.html#save/1"},{"type":"function","doc":"Starts the lock profiler server.\n\nThe server only act as a medium for the user and performs filtering\nand printing of data collected by `lcnt:collect/1`.","title":"lcnt.start/0","ref":"lcnt.html#start/0"},{"type":"function","doc":"Stops the lock profiler server.","title":"lcnt.stop/0","ref":"lcnt.html#stop/0"},{"type":"function","doc":"Swaps places on `Name` and `Id` space for ports and processes.","title":"lcnt.swap_pid_keys/0","ref":"lcnt.html#swap_pid_keys/0"},{"type":"type","doc":"","title":"lcnt.category_atom/0","ref":"lcnt.html#t:category_atom/0"},{"type":"type","doc":"","title":"lcnt.lock_counter_data/0","ref":"lcnt.html#t:lock_counter_data/0"},{"type":"type","doc":"","title":"lcnt.option/0","ref":"lcnt.html#t:option/0"},{"type":"type","doc":"","title":"lcnt.print/0","ref":"lcnt.html#t:print/0"},{"type":"type","doc":"","title":"lcnt.sort/0","ref":"lcnt.html#t:sort/0"},{"type":"type","doc":"","title":"lcnt.threshold/0","ref":"lcnt.html#t:threshold/0"},{"type":"module","doc":"A Make Utility for Erlang\n\nThe module `make` provides a set of functions similar to the UNIX type `Make`\nfunctions.","title":"make","ref":"make.html"},{"type":"module","doc":"[`make:all/0,1`](`all/1`) and [`make:files/1,2`](`files/2`) first looks for\n`{emake, Emake}` in options, then in the current working directory for a file\nnamed `Emakefile`. If present `Emake` should contain elements like this:\n\n```text\nModules.\n{Modules,Options}.\n```\n\n`Modules` is an atom or a list of atoms. It can be\n\n- a module name, for exmaple, `file1`\n- a module name in another directory, for exmaple, `'../foo/file3'`\n- a set of modules specified with a wildcards, for exmaple, `'file*'`\n- a wildcard indicating all modules in current directory, that is: `'*'`\n- a list of any of the above, for exmaple, `['file*','../foo/file3','File4']`\n\n`Options` is a list of compiler options.\n\n`Emakefile` is read from top to bottom. If a module matches more than one entry,\nthe first match is used. For example, the following `Emakefile` means that\n`file1` should be compiled with the options `[debug_info,{i,\"../foo\"}]`, while\nall other files in the current directory should be compiled with only the\n`debug_info` flag.\n\n```erlang\n{'file1',[debug_info,{i,\"../foo\"}]}.\n{'*',[debug_info]}.\n```","title":"Emakefile - make","ref":"make.html#module-emakefile"},{"type":"module","doc":"[The Compiler Application](`m:compile`)","title":"See Also - make","ref":"make.html#module-see-also"},{"type":"function","doc":"","title":"make.all/0","ref":"make.html#all/0"},{"type":"function","doc":"This function determines the set of modules to compile and the compile options\nto use, by first looking for the `emake` make option, if not present reads the\nconfiguration from a file named `Emakefile` (see below). If no such file is\nfound, the set of modules to compile defaults to all modules in the current\nworking directory.\n\nTraversing the set of modules, it then recompiles every module for which at\nleast one of the following conditions apply:\n\n- there is no object file, or\n- the source file has been modified since it was last compiled, or,\n- an include file has been modified since the source file was last compiled.\n\nAs a side effect, the function prints the name of each module it tries to\ncompile. If compilation fails for a module, the make procedure stops and `error`\nis returned.\n\n`Options` is a list of options for `make` and the Erlang compiler. The following\n`make` options exist:\n\n- `noexec`\n No execution mode. Just prints the name of each module that needs to be\n compiled.\n- `load`\n Load mode. Loads all recompiled modules.\n- `netload`\n Net load mode. Loads all recompiled modules on all known nodes.\n- `{emake, Emake}`\n Rather than reading the `Emakefile` specify configuration explicitly.\n\nAll items in `Options` that are not make options are assumed to be compiler\noptions and are passed as-is to `compile:file/2`.","title":"make.all/1","ref":"make.html#all/1"},{"type":"function","doc":"","title":"make.files/1","ref":"make.html#files/1"},{"type":"function","doc":"This function does exactly the same thing as [`all/0,1`](`all/0`), but for the\nspecified `ModFiles`, which is a list of module or file names.\n\nThe file extension `.erl` can be omitted.\n\nThe `Emakefile` (if it exists) in the current directory is searched for compiler\noptions for each module. If a given module does not exist in `Emakefile` or if\n`Emakefile` does not exist, the module is still compiled.","title":"make.files/2","ref":"make.html#files/2"},{"type":"module","doc":"Generate Emacs TAGS file from Erlang source files\n\nA `TAGS` file is used by Emacs to find function and variable definitions in any\nsource file in large projects. This module can generate a `TAGS` file from\nErlang source files. It recognises functions, records, and macro definitions.","title":"tags","ref":"tags.html"},{"type":"module","doc":"The functions in this module have an optional argument `Options`. It\nis a list which can contain the following elements:\n\n- `{outfile, NameOfTAGSFile}` Create a `TAGS` file named `NameOfTAGSFile`.\n- `{outdir, NameOfDirectory}` Create a file named `TAGS` in the directory\n `NameOfDirectory`.\n\nThe default behaviour is to create a file named `TAGS` in the current directory.","title":"Options - tags","ref":"tags.html#module-options"},{"type":"module","doc":"- `tags:root([{outfile, \"root.TAGS\"}]).`\n\n This command will create a file named `root.TAGS` in the current directory.\n The file will contain references to all Erlang source files in the Erlang\n distribution.\n\n- `tags:files([\"foo.erl\", \"bar.erl\", \"baz.erl\"], [{outdir, \"../projectdir\"}]).`\n\n This command will create a file named `TAGS` placed it in the\n directory `../projectdir`. The file contains information about the\n functions, records, and macro definitions of the three files.","title":"Examples - tags","ref":"tags.html#module-examples"},{"type":"module","doc":"- Richard M. Stallman. GNU Emacs Manual, chapter \"Editing Programs\", section\n \"Tag Tables\". Free Software Foundation, 1995.\n- Anders Lindgren. The Erlang editing mode for Emacs. Ericsson, 1998.","title":"See Also - tags","ref":"tags.html#module-see-also"},{"type":"function","doc":"","title":"tags.dir/1","ref":"tags.html#dir/1"},{"type":"function","doc":"Create a `TAGS` file for all files in directory `Dir`.","title":"tags.dir/2","ref":"tags.html#dir/2"},{"type":"function","doc":"","title":"tags.dirs/1","ref":"tags.html#dirs/1"},{"type":"function","doc":"Create a `TAGS` file for all files in any directory in `DirList`.","title":"tags.dirs/2","ref":"tags.html#dirs/2"},{"type":"function","doc":"","title":"tags.file/1","ref":"tags.html#file/1"},{"type":"function","doc":"Create a `TAGS` file for the file `File`.","title":"tags.file/2","ref":"tags.html#file/2"},{"type":"function","doc":"","title":"tags.files/1","ref":"tags.html#files/1"},{"type":"function","doc":"Create a `TAGS` file for the files in the list `FileList`.","title":"tags.files/2","ref":"tags.html#files/2"},{"type":"function","doc":"","title":"tags.root/0","ref":"tags.html#root/0"},{"type":"function","doc":"Create a `TAGS` file covering all files in the Erlang distribution.","title":"tags.root/1","ref":"tags.html#root/1"},{"type":"function","doc":"","title":"tags.subdir/1","ref":"tags.html#subdir/1"},{"type":"function","doc":"Descend recursively into the directory `Dir` and create a `TAGS` file based on\nall files found.","title":"tags.subdir/2","ref":"tags.html#subdir/2"},{"type":"function","doc":"","title":"tags.subdirs/1","ref":"tags.html#subdirs/1"},{"type":"function","doc":"Descend recursively into the directories in `DirList` and create a `TAGS`\nfile based on all files found.","title":"tags.subdirs/2","ref":"tags.html#subdirs/2"},{"type":"type","doc":"","title":"tags.option/0","ref":"tags.html#t:option/0"},{"type":"module","doc":"Process Tracing Profiling Tool\n\n`tprof` provides convenience helpers for Erlang process profiling using\nthe trace BIFs.\n\n> #### Warning {: .warning }\n>\n> This module aims to replace `eprof` and `cprof` into a unified API for\n> measuring call count, time, and allocation. It is experimental in Erlang/OTP\n> 27.0.\n\nIt is possible to analyze the number of calls, the time spent by function, and\nheap allocations by function. Profiling can be done [ad-hoc](#module-ad-hoc-profiling)\n or run in a [server-aided mode](#module-server-aided-profiling) for deeper\nintrospection of the code running in production. The server-aided mode can be\nrun using the default tprof server or an isolated `t:server/0` started through\n[`start(#{ session => atom() })`](`start/1`).\n\nThere are [three kinds of profiling](`t:trace_type/0`) supported by this module:\n\n- `call_count`\n- `call_time`\n- `call_memory`\n\nThe default is `call_count`, which has the smallest peformance impact\nand memory footprint, but it does not support per-process\nprofiling. For this reason, all of the examples below uses\n`call_memory`, which measures heap allocation, and provide a more complex\nfeature set to demonstrate.\n\nErlang terms that do not fit in a single machine word are allocated on\nthe process heap. For example, a function returning a tuple of two\nelements needs to allocate the tuple on the process heap. The actual\nconsumption is three words, because the runtime systems also need an\nextra word to store the tuple size.\n\n> #### Note {: .info }\n>\n> Expect a slowdown in the program execution when profiling is enabled.\n>\n> For profiling convenience, measurements are accumulated for functions that are\n> not enabled in some trace pattern. Consider this call stack example:\n>\n> ```text\n> top_traced_function(...)\n> not_traced_function()\n> bottom_traced_function()\n> ```\n>\n> Allocations that happened within `not_traced_function` will be added to\n> the allocations for `top_traced_function`. However, allocations that occurred\n> within `bottom_traced_function` are not included in the `top_traced_function`.\n> To only keep track of each function own allocations, it is necessary to\n> trace all functions.\n\n> #### Warning {: .warning }\n>\n> Avoid hot code reloading for modules participating in the tracing.\n> Reloading a module disables tracing and discards the accumulated statistics.\n> The `tprof` results will probably be incorrect when the profiled code was\n> reloading during a profiling session.","title":"tprof","ref":"tprof.html"},{"type":"module","doc":"Ad-hoc profiling is convenient for profiling a single function call.\n\nFor example:\n\n```erlang\n1> tprof:profile(lists, seq, [1, 16], #{type => call_memory}).\n\n****** Process <0.92.0> -- 100.00% of total *** \nFUNCTION CALLS WORDS PER CALL [ %]\nlists:seq_loop/3 5 32 6.40 [100.00]\n 32 [ 100.0]\nok\n```\n\nBy default tracing is enabled for all functions in all modules. When funs\nare created in the interactive shell, parts of shell code are also traced:\n\n```erlang\n1> tprof:profile(fun() -> lists:seq(1, 16) end, #{type => call_memory}).\n\n****** Process <0.95.0> -- 100.00% of total *** \nFUNCTION CALLS WORDS PER CALL [ %]\nerl_eval:do_apply/7 1 3 3.00 [ 3.61]\nerl_eval:match_list/6 1 3 3.00 [ 3.61]\nlists:reverse/1 1 4 4.00 [ 4.82]\nerl_eval:expr_list/7 3 7 2.33 [ 8.43]\nerl_eval:ret_expr/3 4 16 4.00 [19.28]\nerl_eval:merge_bindings/4 3 18 6.00 [21.69]\nlists:seq_loop/3 5 32 6.40 [38.55]\n 83 [100.0]\nok\n```\n\nHowever, it is possible to limit the trace to specific functions or modules:\n\n```erlang\n2> tprof:profile(fun() -> lists:seq(1, 16) end,\n #{type => call_memory, pattern => [{lists, seq_loop, '_'}]}).\n****** Process <0.98.0> -- 100.00% of total *** \nFUNCTION CALLS WORDS PER CALL [ %]\nlists:seq_loop/3 5 32 6.40 [100.00]\n 32 [ 100.0]\n\nok\n```\n\nAd-hoc profiling results can be printed in a few different ways. The following\nexamples use the `test` module defined like this:\n\n```erlang\n-module(test).\n-export([test_spawn/0]).\ntest_spawn() ->\n {Pid, MRef} = spawn_monitor(fun () -> lists:seq(1, 32) end),\n receive\n {'DOWN', MRef, process, Pid, normal} ->\n done\n end.\n```\n\nBy default per-process statistics is shown:\n\n```erlang\n1> tprof:profile(test, test_spawn, [], #{type => call_memory}).\n\n****** Process <0.176.0> -- 23.66 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\nerlang:spawn_monitor/1 1 2 2 [ 9.09]\nerlang:spawn_opt/4 1 6 6 [27.27]\ntest:test_spawn/0 1 14 14 [63.64]\n 22 [100.0]\n\n****** Process <0.177.0> -- 76.34 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\nerlang:apply/2 1 7 7 [ 9.86]\nlists:seq_loop/3 9 64 7 [90.14]\n 71 [100.0]\n```\n\nThe following example prints the combined memory allocation of all\nprocesses, sorted by the total number of allocated words in descending\norder:\n\n```erlang\n2> tprof:profile(test, test_spawn, [],\n #{type => call_memory, report => {total, {measurement, descending}}}).\n\nFUNCTION CALLS WORDS PER CALL [ %]\nlists:seq_loop/3 9 64 7 [68.82]\ntest:test_spawn/0 1 14 14 [15.05]\nerlang:apply/2 1 7 7 [ 7.53]\nerlang:spawn_opt/4 1 6 6 [ 6.45]\nerlang:spawn_monitor/1 1 2 2 [ 2.15]\n 93 [100.0]\n```\n\nThe profiling data can also be collected for further inspection:\n\n```erlang\n3> {done, ProfileData} = tprof:profile(fun test:test_spawn/0,\n #{type => call_memory, report => return}).\n<...>\n4> tprof:format(tprof:inspect(ProfileData, process, {percent, descending})).\n\n****** Process <0.223.0> -- 23.66 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\ntest:test_spawn/0 1 14 14 [63.64]\nerlang:spawn_opt/4 1 6 6 [27.27]\nerlang:spawn_monitor/1 1 2 2 [ 9.09]\n 22 [100.0]\n\n****** Process <0.224.0> -- 76.34 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\nlists:seq_loop/3 9 64 7 [90.14]\nerlang:apply/2 1 7 7 [ 9.86]\n 71 [100.0]\n```\n\nWhich processes that are profiled depends on the profiling type.\n\n* `call_count` (default) counts calls in all processes.\n\n* `call_time` and `call_memory` limits the profiling to the processes\n spawned from the user-provided function (using the `set_on_spawn`\n option for `trace:process/4`).\n\n`call_time` and `call_memory` can be restricted to profile a single process:\n\n```erlang\n2> tprof:profile(test, test_spawn, [],\n #{type => call_memory, set_on_spawn => false}).\n\n****** Process <0.183.0> -- 100.00 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\nerlang:spawn_monitor/1 1 2 2 [ 9.09]\nerlang:spawn_opt/4 1 6 6 [27.27]\ntest:test_spawn/0 1 14 14 [63.64]\n```\n\n[](){: #pg_example }\n\nErlang programs can perform expensive operations in other processes\nthan the original one. You can include multiple, new, or even all\nprocesses in the trace when measuring time or memory:\n\n```erlang\n7> pg:start_link().\n{ok,<0.252.0>}\n8> tprof:profile(fun() -> pg:join(group, self()) end,\n #{type => call_memory, rootset => [pg]}).\n****** Process <0.252.0> -- 52.86 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\npg:leave_local_update_ets/5 1 2 2 [ 1.80]\ngen:reply/2 1 3 3 [ 2.70]\nerlang:monitor/2 1 3 3 [ 2.70]\ngen_server:try_handle_call/4 1 3 3 [ 2.70]\ngen_server:try_dispatch/4 1 3 3 [ 2.70]\nmaps:iterator/1 2 4 2 [ 3.60]\nmaps:take/2 1 6 6 [ 5.41]\npg:join_local_update_ets/5 1 8 8 [ 7.21]\npg:handle_info/2 1 8 8 [ 7.21]\npg:handle_call/3 1 9 9 [ 8.11]\ngen_server:loop/7 2 9 4 [ 8.11]\nets:lookup/2 2 10 5 [ 9.01]\npg:join_local/3 1 11 11 [ 9.91]\npg:notify_group/5 2 16 8 [14.41]\nerlang:setelement/3 2 16 8 [14.41]\n 111 [100.0]\n\n****** Process <0.255.0> -- 47.14 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\nerl_eval:match_list/6 1 3 3 [ 3.03]\nerlang:monitor/2 1 3 3 [ 3.03]\nlists:reverse/1 2 4 2 [ 4.04]\npg:join/3 1 4 4 [ 4.04]\nerl_eval:add_bindings/2 1 5 5 [ 5.05]\nerl_eval:do_apply/7 2 6 3 [ 6.06]\ngen:call/4 1 8 8 [ 8.08]\nerl_eval:expr_list/7 4 10 2 [10.10]\ngen:do_call/4 1 16 16 [16.16]\nerl_eval:ret_expr/3 4 16 4 [16.16]\nerl_eval:merge_bindings/4 3 24 8 [24.24]\n 99 [100.0]\n```\n\nBy default, there is no limit for the profiling time. For ac-hoc\nprofiling, is is possible to configure a time limit. If the profiled\nfunction does not return before that time expires, the process is\nterminated with reason `kill`. Any unlinked children processes started\nby the user-supplied function are kept; it is the responsibility of\nthe developer to take care of such processes.\n\n```erlang\n9> tprof:profile(timer, sleep, [100000], #{timeout => 1000}).\n```\n\nBy default, only one ad-hoc or server-aided profiling session is\nallowed at any point in time. It is possible to force multiple ad-hoc\nsessions concurrently, but it is the responsibility of the developer\nto ensure that trace patterns do not overlap:\n\n```erlang\n1> tprof:profile(fun() -> lists:seq(1, 32) end,\n #{registered => false, pattern => [{lists, '_', '_'}]}).\n```","title":"Ad-hoc profiling - tprof","ref":"tprof.html#module-ad-hoc-profiling"},{"type":"module","doc":"Server-aided profiling can be done on a system that is up and\nrunning. To do that, start the `tprof` server, and then add trace\npatterns and processes to trace while the system handles actual\ntraffic. Data can extracted, inspected, and printed at any time. The\nfollowing example traces activity of all processes supervised by\nthe Kernel supervisor:\n\n```erlang\n1> tprof:start(#{type => call_memory}).\n{ok,<0.200.0>}\n2> tprof:enable_trace({all_children, kernel_sup}).\n34\n3> tprof:set_pattern('_', '_' , '_').\n16728\n4> Sample = tprof:collect().\n{call_memory,\n [{gen_server,try_dispatch,4,[{<0.154.0>,2,6}]},\n {erlang,iolist_to_iovec,1,[{<0.161.0>,1,8}]},\n<...>\n5 > tprof:format(tprof:inspect(Sample)).\n\n****** Process <0.154.0> -- 14.21 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\nmaps:iterator/1 2 4 2 [15.38]\ngen_server:try_dispatch/4 2 6 3 [23.08]\nnet_kernel:handle_info/2 2 16 8 [61.54]\n 26 [100.0]\n\n****** Process <0.161.0> -- 85.79 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\ndisk_log:handle/2 2 2 1 [ 1.27]\ndisk_log_1:maybe_start_timer/1 1 3 3 [ 1.91]\ndisk_log_1:mf_write_cache/1 1 3 3 [ 1.91]\n<...>\n```\n\n[](){: #inspect_example }\n\nIt is possible to profile the entire running system, and then examine individual\nprocesses:\n\n```erlang\n1> tprof:start(#{type => call_memory}).\n2> tprof:enable_trace(all), tprof:set_pattern('_', '_' , '_').\n9041\n3> timer:sleep(10000), tprof:disable_trace(all), Sample = tprof:collect().\n{call_memory,\n [{user_drv,server,3,[{<0.64.0>,12,136}]},\n {user_drv,contains_ctrl_g_or_ctrl_c,1,[{<0.64.0>,80,10}]},\n<...>\n4> Inspected = tprof:inspect(Sample, process, measurement), Shell = maps:get(self(), Inspected).\n{call_memory, 2743,\n [{shell,{enc,0},1,2,2,0.07291286912139992},\n<...>\n5> tprof:format(Shell).\n\nFUNCTION CALLS WORDS PER CALL [ %]\n<...>\nerl_lint:start/2 2 300 150 [10.94]\nshell:used_records/1 114 342 3 [12.47]\n```","title":"Server-aided profiling - tprof","ref":"tprof.html#module-server-aided-profiling"},{"type":"function","doc":"Disables tracing functions matching the supplied pattern.\n\n```erlang\n1> tprof:set_pattern(lists, seq, '_').\n2\n2> tprof:clear_pattern(lists, seq, 3).\n1\n3> tprof:get_trace_map().\n#{lists => [{seq,2}]}\n```\n\nRequires that the default `tprof` server has been [`started`](`start/1`).","title":"tprof.clear_pattern/3","ref":"tprof.html#clear_pattern/3"},{"type":"function","doc":"Equivalent to [`clear_pattern(Mod, Fun, Arity)`](`clear_pattern/3`) but uses the provided `Server`.","title":"tprof.clear_pattern/4","ref":"tprof.html#clear_pattern/4"},{"type":"function","doc":"Returns statistics for current trace map.","title":"tprof.collect/0","ref":"tprof.html#collect/0"},{"type":"function","doc":"Equivalent to `collect/0` but uses the provided `Server`.","title":"tprof.collect/1","ref":"tprof.html#collect/1"},{"type":"function","doc":"Resumes previously paused profiling.","title":"tprof.continue/0","ref":"tprof.html#continue/0"},{"type":"function","doc":"Equivalent to `continue/0` but uses the provided `Server`.","title":"tprof.continue/1","ref":"tprof.html#continue/1"},{"type":"function","doc":"","title":"tprof.disable_trace/1","ref":"tprof.html#disable_trace/1"},{"type":"function","doc":"Stops accumulating traces for specified processes.\n\nSee `enable_trace/2` for a description of the options.\n\nThe profile data accumulated before the process is removed from the\ntraced list is retained. This makes it possible to enable tracing for\nmany or all processes in the system, sleep for a short period of\ntime, then disable tracing for all processes (to avoid system\noverload), but keeping profile data.","title":"tprof.disable_trace/2","ref":"tprof.html#disable_trace/2"},{"type":"function","doc":"","title":"tprof.disable_trace/3","ref":"tprof.html#disable_trace/3"},{"type":"function","doc":"","title":"tprof.enable_trace/1","ref":"tprof.html#enable_trace/1"},{"type":"function","doc":"Similar to `trace:process/4`, but supports a few more options for tracing\nconvenience.\n\nTracing per process is not supported by `call_count` profilers.\n\n`Spec` is either a process identifier (pid) for a local process, one of the\nfollowing atoms, or a list of local process identifiers or their registered\nnames:\n\n- **`all`** - All currently existing processes and all that will be\n created in the future.\n\n- **`existing`** - All currently existing processes.\n\n- **`new`** - All processes that will be created in the future.\n\n- **`children`** - All currently running processes that were directly spawned by\n the specified process. This mode is helpful for tracing workers of a single\n supervisor.\n\n- **`all_children`** - All currently running processes that were spawned by the\n specified process, or any recursive descendant of it. This mode is designed to\n facilitate tracing of supervision trees.\n\nReturns the number of processes for which tracing was enabled.\n\nWhen a list of pids, `children` or `all_children` is used, the processes that\ntracing failed to be enabled on will also be returned. Tracing can fail to be\nenabled if the process has terminated before tracing could be enabled.\n\n> #### Note {: .info }\n>\n> The profiling server does not keep track of processes that were added to the\n> tracing set. It is permitted to stop the profiling server (wiping out any\n> accumulated data), restart the server, set entirely different tracing pattern\n> keeping the list of traced processes for future use. Use\n> [`disable_trace(Processes)`](`disable_trace/2`) to clear the list of traced\n> processes.\n\nSpecify `Options` to modify tracing behavior:\n\n- **`set_on_spawn`** - Automatically start tracing for processes spawned by the\n traced process. On by default.","title":"tprof.enable_trace/2","ref":"tprof.html#enable_trace/2"},{"type":"function","doc":"Equivalent to `enable_trace/2` but uses the provided `Server`.","title":"tprof.enable_trace/3","ref":"tprof.html#enable_trace/3"},{"type":"function","doc":"Formats profile data transformed with [`inspect/3`](`inspect/3`), outputting to\nthe default output device.","title":"tprof.format/1","ref":"tprof.html#format/1"},{"type":"function","doc":"Formats profile transformed with [`inspect/3`](`inspect/3`),\noutputting to device `IoDevice`.","title":"tprof.format/2","ref":"tprof.html#format/2"},{"type":"function","doc":"Returns a map of module names to functions with their arities.","title":"tprof.get_trace_map/0","ref":"tprof.html#get_trace_map/0"},{"type":"function","doc":"Equivalent to `get_trace_map/0` but uses the provided `Server`.","title":"tprof.get_trace_map/1","ref":"tprof.html#get_trace_map/1"},{"type":"function","doc":"Equivalent to [`inspect(Profile, process, percent)`](`inspect/3`).\n\nTransforms raw profile into a map of process identifiers to a tuple containing total count\nof words allocated, and a list of all traced functions sorted in the ascending\norder by the allocation percentage.","title":"tprof.inspect/1","ref":"tprof.html#inspect/1"},{"type":"function","doc":"Transforms raw data returned by tracing BIFs into a form convenient for\nsubsequent analysis and formatting.\n\n* When the `Type` argument is `process`, this function returns a map of process\n identifiers with corresponding profiling results sorted by the selected column.\n\n* When `Type` argument is `total` or when profiling by `call_count`, this function\n returns a map with a single `all` key with profiling results from all processes.\n\nThe inspected profile data can be leveraged to\n[print profiling results](`m:tprof#inspect_example`).","title":"tprof.inspect/3","ref":"tprof.html#inspect/3"},{"type":"function","doc":"Pauses trace collection for all currently traced functions, retaining existing traces.\n\nUse `continue/0` to resume trace collection.","title":"tprof.pause/0","ref":"tprof.html#pause/0"},{"type":"function","doc":"Equivalent to `pause/0` but uses the provided `Server`.","title":"tprof.pause/1","ref":"tprof.html#pause/1"},{"type":"function","doc":"","title":"tprof.profile/1","ref":"tprof.html#profile/1"},{"type":"function","doc":"Does ad-hoc profiling of the call `Fun()`.\n\nBy default, the result is formatted to the output device; use the `report`\noption to change this behavior.\n\nAd-hoc profiling starts a new instance of `tprof` server, runs the\nprofiling routine, extracts results, and shuts down the server.\n\nSee `profile/4` for a list of the supported options.","title":"tprof.profile/2","ref":"tprof.html#profile/2"},{"type":"function","doc":"","title":"tprof.profile/3","ref":"tprof.html#profile/3"},{"type":"function","doc":"Does ad-hoc profiling for the call `apply(Module, Function, Args)`.\n\nBy default, the result is formatted to the output device; use option `report`\nto change this behavior.\n\nAd-hoc profiling starts a new instance of `tprof` server, runs the\nprofiling routine, extracts results, and shuts down the server.\n\nThe ad-hoc profiler supports the following `Options`:\n\n- **`type`** - The type of profiling to perform.\n\n- **`device`** - Specifies I/O devices to print the profile to. Useful to\n redirect text output to console or `standard_error`.\n\n- **`pattern`** - Specifies a trace pattern, or a list of trace patterns to\n enable. By default, all functions (`{'_', '_', '_'}`) are traced.\n\n- **`report`** - Controls output format. The default is `process`; printing\n per-process profiling data sorted by percentage of the total allocation.\n Specify `report => return` to suppress printing and get the raw data for\n further evaluation with `inspect/3` and formatting with `format/2`.\n\n- **`rootset`** - Includes extra processes in the trace list. Useful for\n profiling allocations for `m:gen_server`, calls, or other allocations caused\n by inter-process communications. See [this example](`m:tprof#pg_example`).\n\n- **`set_on_spawn`** - Automatically start tracing for processes spawned by the\n traced process. Enabled by default.\n\n- **`timeout`** - Terminate profiling after the specified amount of time\n (milliseconds).","title":"tprof.profile/4","ref":"tprof.html#profile/4"},{"type":"function","doc":"Clears accumulated profiles and starts profiling if it was paused.","title":"tprof.restart/0","ref":"tprof.html#restart/0"},{"type":"function","doc":"Equivalent to `restart/0` but uses the provided `Server`.","title":"tprof.restart/1","ref":"tprof.html#restart/1"},{"type":"function","doc":"Enables tracing for all functions matching the supplied pattern.\n\nPatterns are additive, following the same rules as `trace:function/4`.\nReturns the number of functions matching the supplied pattern.\n\n```erlang\n1> tprof:set_pattern(lists, seq, '_').\n2\n2> tprof:set_pattern(lists, keyfind, 3).\n1\n3> tprof:get_trace_map().\n#{lists => [{keyfind,3},{seq,2},{seq,3}]}\n```\n\nIf no functions match the pattern, an `error` tuple is returned:\n\n```erlang\n> tprof:set_pattern(no_module, func, '_').\n{error,{trace_pattern,no_module,func,'_'}}\n```\n\nRequires that the default `tprof` server has been [`started`](`start/1`).","title":"tprof.set_pattern/3","ref":"tprof.html#set_pattern/3"},{"type":"function","doc":"Equivalent to `set_pattern/3` but uses the provided `Server`.","title":"tprof.set_pattern/4","ref":"tprof.html#set_pattern/4"},{"type":"function","doc":"","title":"tprof.start/0","ref":"tprof.html#start/0"},{"type":"function","doc":"Starts the server, not supervised.\n\nProfiling server stores current trace patterns and owns the [trace session](`t:trace:session/0`)\nused for profiling.\n\nIf no `session` is provided in `Config`, then a default session called `tprof` is\nused and the profiling server is [registered](`register/2`) as `tprof`.\n\nIf `session` is provided in `Config`, then a session with that name is created\nand all profiling is done within that session. The profiling server is not [registered](`register/2`)\nin this case. When using `m:tprof` like this the `t:pid/0` returned from this\nfunction needs to be provided to the functions in this module.","title":"tprof.start/1","ref":"tprof.html#start/1"},{"type":"function","doc":"","title":"tprof.start_link/0","ref":"tprof.html#start_link/0"},{"type":"function","doc":"Equivalent to `start/1` but also links the profiling server to the caller.","title":"tprof.start_link/1","ref":"tprof.html#start_link/1"},{"type":"function","doc":"Stops the default `tprof` server and disable tracing enabled by the server.","title":"tprof.stop/0","ref":"tprof.html#stop/0"},{"type":"function","doc":"Equivalent to `stop/0` but uses the provided `Server`.","title":"tprof.stop/1","ref":"tprof.html#stop/1"},{"type":"type","doc":"Column to sort by `inspect/3` or [`profile/4`](`profile/4`).\n\n- **`module`** - Module name.\n\n- **`function`** - Function name.\n\n- **`calls`** - Number of calls to the function.\n\n- **`measurement`** - Total measurement (call count, time, or heap allocation)\n throughout all calls to the function.\n\n- **`measurement_per_call`** - Measurement (call count, time, or heap\n allocation) on average per function call.\n\n- **`percent`** - Percentage of measurement to total amount during the entire\n profile collection.","title":"tprof.column/0","ref":"tprof.html#t:column/0"},{"type":"type","doc":"A process identifier (pid) or a registered process name.","title":"tprof.process/0","ref":"tprof.html#t:process/0"},{"type":"type","doc":"Inspected data for a single function of the specified `Module`.","title":"tprof.profile_line/0","ref":"tprof.html#t:profile_line/0"},{"type":"type","doc":"Ad-hoc profiler options; see [`profile/4`](`profile/4`).","title":"tprof.profile_options/0","ref":"tprof.html#t:profile_options/0"},{"type":"type","doc":"Profile of a single process, or combined profile of multiple processes, sorted\nby a selected column.","title":"tprof.profile_result/0","ref":"tprof.html#t:profile_result/0"},{"type":"type","doc":"","title":"tprof.rootset/0","ref":"tprof.html#t:rootset/0"},{"type":"type","doc":"A tprof server.\n\nEach server uses a separate `t:trace:session/0` in order to\nkeep profiling isolated.","title":"tprof.server/0","ref":"tprof.html#t:server/0"},{"type":"type","doc":"","title":"tprof.sort_by/0","ref":"tprof.html#t:sort_by/0"},{"type":"type","doc":"","title":"tprof.start_options/0","ref":"tprof.html#t:start_options/0"},{"type":"type","doc":"Raw data extracted from tracing BIFs.","title":"tprof.trace_info/0","ref":"tprof.html#t:trace_info/0"},{"type":"type","doc":"Traced functions (with their arities) grouped by module name,\nor `all` if all code is traced.","title":"tprof.trace_map/0","ref":"tprof.html#t:trace_map/0"},{"type":"type","doc":"Options for enabling profiling of the selected processes; see `enable_trace/2`.","title":"tprof.trace_options/0","ref":"tprof.html#t:trace_options/0"},{"type":"type","doc":"","title":"tprof.trace_pattern/0","ref":"tprof.html#t:trace_pattern/0"},{"type":"type","doc":"The type of profiling that the tprof server will do.\n\n- **call_count** - Counts the number of calls made to functions. This\n is a global profiling event that cannot be limited to specific processes.\n See [call_count](`trace#call_count`) in `trace:function/4` for more details.\n- **call_time** - Counts the accumulated time spent in functions.\n See [call_time](`trace#call_time`) in `trace:function/4` for more details.\n- **call_memory** - Counts the accumulated memory allocated in functions.\n See [call_memory](`trace#call_memory`) in `trace:function/4` for more details.","title":"tprof.trace_type/0","ref":"tprof.html#t:trace_type/0"},{"type":"module","doc":"A Cross Reference Tool for analyzing dependencies between functions, modules,\napplications, and releases.\n\nCalls between functions are either _local calls_{: #local_call } such as `f()`,\nor _external calls_{: #external_call } such as `mod:f()`.\n\n_Module data_{:#module_data }, which are extracted from BEAM files,\ninclude local functions, exported functions, local calls, and external\ncalls. By default, calls to built-in functions (BIF) are ignored, but\nif the option `builtins`, accepted by some of this module's functions,\nis set to `true`, calls to BIFs are included as well. It is the\nanalyzing OTP version that decides what functions are BIFs.\nFunctional objects are assumed to be called where they are created\n(and nowhere else).\n\n_Unresolved calls_{: #unresolved_call } are calls to `apply` or\n`spawn` with variable module, variable function, or variable\narguments. Examples are `M:F(a)`, [`apply(M, f, [a])`](`apply/3`), and\n[`spawn(m, f(), Args)`](`spawn/3`). Unresolved calls are represented\nby calls where variable modules have been replaced with the atom\n`'$M_EXPR'`, variable functions have been replaced with the atom\n`'$F_EXPR'`, and variable number of arguments have been replaced with\nthe number `-1`. The above mentioned examples are represented by calls\nto `'$M_EXPR':'$F_EXPR'/1`, `'$M_EXPR':f/1`, and `m:'$F_EXPR'/-1`. The\nunresolved calls are a subset of the external calls.\n\n> #### Warning {: .warning }\n>\n> Unresolved calls make module data incomplete, which implies that the results\n> of analyses may be invalid.\n\n_Applications_ are collections of modules. The BEAM files for the\nmodules are located in the `ebin` subdirectory of the application\ndirectory. The name of the application directory determines the name\nand version of the application.\n\n_Releases_ are collections of applications located in the `lib` subdirectory of\nthe release directory. There is more to read about applications and releases in\nthe Design Principles book.\n\n_Xref servers_{: #xref_server } are identified by names, supplied when\ncreating new servers. Each Xref server holds a set of releases, a set\nof applications, and a set of modules with module data. Xref servers\nare independent of each other, and all analyses are evaluated in the\ncontext of one single Xref server (exceptions are the functions\n[`m/1`](`m/1`) and [`d/1`](`d/1`) which do not use servers at\nall).\n\nThe _mode_{: #mode } of an Xref server determines what module data are\nextracted from BEAM files as modules are added to the server. BEAM\nfiles compiled with the option `debug_info` contain [](){: #debug_info\n} \"debug information\", which is an abstract representation of the\ncode.\n\n- In `functions` mode, which is the default mode, function calls\n and line numbers are extracted from debug information.\n\n- In `modules` mode, debug information is ignored if present, but\n dependencies between modules are extracted from other parts of the\n BEAM files. The `modules` mode is significantly less time and space\n consuming than the `functions` mode, but the analyses that can be\n done are limited.\n\nAn _analyzed module_{: #analyzed_module } is a module that has been added to an\nXref server together with its module data. A _library module_{: #library_module\n} is a module located in some directory mentioned in the _library path_{:\n#library_path }. A library module is said to be used if some of its exported\nfunctions are used by some analyzed module. An _unknown module_{:\n#unknown_module } is a module that is neither an analyzed module nor a library\nmodule, but whose exported functions are used by some analyzed module.\n\nAn _unknown function_{: #unknown_function } is a used function that is\nneither local or exported by any analyzed module nor exported by any\nlibrary module. An _undefined function_{: #undefined_function } is an\nexternally used function that is not exported by any analyzed module\nor library module. With this notion, a local function can be an\nundefined function, namely if it is externally used from some\nmodule. All unknown functions are also undefined functions; there is a\n[figure](xref_chapter.md#venn2) in the User's Guide that illustrates\nthis relationship.\n\nThe module attribute tag `deprecated` can be used to inform\nXref about _deprecated functions_{: #deprecated_function } and optionally when\nfunctions are planned to be removed. A few examples show the idea:\n\n- `-deprecated({f,1}).` - The exported function `f/1` is deprecated.\n Nothing is said whether `f/1` will be removed or not.\n\n- `-deprecated({f,1,\"Use g/1 instead\"}).` - As above but with a descriptive\n string. The string is currently unused by `xref` but other tools can make use\n of it.\n\n- `-deprecated({f,'_'}).` - All exported functions `f/0`, `f/1`, and so on\n are deprecated.\n\n- `-deprecated(module).` - All exported functions in the module are\n deprecated. Equivalent to `-deprecated({'_','_'}).`.\n\n- `-deprecated([{g,1,next_version}]).` - The function `g/1` is deprecated\n and will be removed in next version.\n\n- `-deprecated([{g,2,next_major_release}]).` - The function `g/2` is\n deprecated and will be removed in next major release.\n\n- `-deprecated([{g,3,eventually}]).` - The function `g/3` is deprecated\n and will eventually be removed.\n\n- `-deprecated({'_','_',eventually}).` - All exported functions in the\n module are deprecated and will eventually be removed.\n\nBefore any analysis can take place, module data must be _set up_. For instance,\nthe cross reference and the unknown functions are computed when all module data\nare known. The functions that need complete data\n([`analyze/2,3`](`analyze/3`), [`q/2,3`](`q/3`), [`variables/1,2`](`variables/2`)\ntake care of setting up data automatically. Module data need to be set up\n(again) after calls to any of the `add`, `replace`, `remove`,\n[`set_library_path/2,3`](`set_library_path/3`), or\n[`update/1,2`](`update/2`) functions.\n\nThe result of setting up module data is the _Call Graph_{: #call_graph }. A\n(directed) graph consists of a set of vertices and a set of (directed) edges.\nThe edges represent _calls_{: #call } (From, To) between functions, modules,\napplications, or releases. From is said to call To, and To is said to be used by\nFrom. The vertices of the Call Graph are the functions of all module data: local\nand exported functions of analyzed modules; used BIFs; used exported functions\nof library modules; and unknown functions. The functions `module_info/0,1` added\nby the compiler are included among the exported functions, but only when called\nfrom some module. The edges are the function calls of all module data. A\nconsequence of the edges being a set is that there is only one edge if a\nfunction is locally or externally used several times on one and the same line of\ncode.\n\nThe Call Graph is [](){: #representation } represented by Erlang terms (the sets\nare lists), which is suitable for many analyses. But for analyses that look at\nchains of calls, a list representation is much too slow. Instead the\nrepresentation offered by the `digraph` module is used. The translation of the\nlist representation of the Call Graph - or a subgraph thereof - to the `digraph`\nrepresentation does not come for free, so the language used for expressing\nqueries to be described below has a special operator for this task and a\npossibility to save the `digraph` representation for subsequent analyses.\n\nIn addition to the Call Graph there is a graph called the _Inter Call Graph_{:\n#inter_call_graph }. This is a graph of calls (From, To) such that there is a\nchain of calls from From to To in the Call Graph, and every From and To is an\nexported function or an unused local function. The vertices are the same as for\nthe Call Graph.\n\nCalls between modules, applications and releases are also directed graphs. The\n_types_{: #type } of the vertices and edges of these graphs are (ranging from\nthe most special to the most general): `Fun` for functions; `Mod` for modules;\n`App` for applications; and `Rel` for releases. The following paragraphs will\ndescribe the different constructs of the language used for selecting and\nanalyzing parts of the graphs, beginning with the _constants_{: #constants }:\n\n- Expression ::= Constants\n- Constants ::= Consts | Consts `:` Type | RegExpr\n- Consts ::= Constant | `[`Constant`,` ...`]` | `{`Constant`,` ...`}`\n- Constant ::= Call | Const\n- Call ::= FunSpec `->` FunSpec | `{`MFA`,` MFA`}` | AtomConst `->` AtomConst |\n `{`AtomConst`,` AtomConst`}`\n- Const ::= AtomConst | FunSpec | MFA\n- AtomConst ::= Application | Module | Release\n- FunSpec ::= Module `:` Function `/` Arity\n- MFA ::= `{`Module`,` Function`,` Arity`}`\n- RegExpr ::= RegString `:` Type | RegFunc | RegFunc `:` Type\n- RegFunc ::= RegModule `:` RegFunction `/` RegArity\n- RegModule ::= RegAtom\n- RegFunction ::= RegAtom\n- RegArity ::= RegString | Number | `_` | `-1`\n- RegAtom ::= RegString | Atom | `_`\n- RegString ::= - a regular expression, as described in the `re` module,\n enclosed in double quotes -\n- Type ::= `Fun` | `Mod` | `App` | `Rel`\n- Function ::= Atom\n- Application ::= Atom\n- Module ::= Atom\n- Release ::= Atom\n- Arity ::= Number | `-1`\n- Atom ::= - same as Erlang atoms -\n- Number ::= - same as non-negative Erlang integers -\n\nExamples of constants are: `kernel`, `kernel->stdlib`, `[kernel, sasl]`,\n`[pg -> mnesia, {tv, mnesia}] : Mod`. It is an error if an instance of `Const`\ndoes not match any vertex of any graph. If there are more than one vertex\nmatching an untyped instance of `AtomConst`, then the one of the most general\ntype is chosen. A list of constants is interpreted as a set of constants, all of\nthe same type. A tuple of constants constitute a chain of calls (which may, but\ndoes not have to, correspond to an actual chain of calls of some graph).\nAssigning a type to a list or tuple of `Constant` is equivalent to assigning the\ntype to each `Constant`.\n\n_Regular expressions_{: #regexp } are used as a means to select some of the\nvertices of a graph. A `RegExpr` consisting of a `RegString` and a type - an\nexample is `\"xref_.*\" : Mod` \\- is interpreted as those modules (or applications\nor releases, depending on the type) that match the expression. Similarly, a\n`RegFunc` is interpreted as those vertices of the Call Graph that match the\nexpression. An example is `\"xref_.*\":\"add_.*\"/\"(2|3)\"`, which matches all `add`\nfunctions of arity two or three of any of the xref modules. Another example, one\nthat matches all functions of arity 10 or more: `_:_/\"[1-9].+\"`. Here `_` is an\nabbreviation for `\".*\"`, that is, the regular expression that matches anything.\n\nThe syntax of _variables_{: #variable } is simple:\n\n- Expression ::= Variable\n- Variable ::= - same as Erlang variables -\n\nThere are two kinds of variables:\n\n* **Predefined variables** {: #predefined_variable } - hold module data, and\n cannot be assigned to but only used in queries.\n\n* **User variables** {: #user_variable } - can be assigned to, and are\n typically used for temporary results while evaluating a query, and\n for keeping results of queries for use in subsequent queries.\n\nThe predefined variables are (variables marked with (\\*) are available\nin `functions` mode only):\n\n- **`E`** - Call Graph Edges (\\*).\n\n- **`V`** - Call Graph Vertices (\\*).\n\n- **`M`** - Modules. All modules: analyzed modules, used library modules, and\n unknown modules.\n\n- **`A`** - Applications.\n\n- **`R`** - Releases.\n\n- **`ME`** - Module Edges. All module calls.\n\n- **`AE`** - Application Edges. All application calls.\n\n- **`RE`** - Release Edges. All release calls.\n\n- **`L`** - Local Functions (\\*). All local functions of analyzed modules.\n\n- **`X`** - Exported Functions. All exported functions of analyzed modules and\n all used exported functions of library modules.\n\n- **`F`** - Functions (\\*).\n\n- **`B`** - Used BIFs. `B` is empty if `builtins` is `false` for all analyzed\n modules.\n\n- **`U`** - Unknown Functions.\n\n- **`UU`** - Unused Functions (\\*). All local and exported functions of analyzed\n modules that have not been used.\n\n- **`XU`** - Externally Used Functions. Functions of all modules - including\n local functions - that have been used in some external call.\n\n- **`LU`** - Locally Used Functions (\\*). Functions of all modules that have\n been used in some local call.\n\n- **`OL`** - Functions with an attribute tag `on_load` (\\*).\n\n- **`LC`** - Local Calls (\\*).\n\n- **`XC`** - External Calls (\\*).\n\n- **`AM`** - Analyzed Modules.\n\n- **`UM`** - Unknown Modules.\n\n- **`LM`** - Used Library Modules.\n\n- **`UC`** - Unresolved Calls. Empty in `modules` mode.\n\n- **`EE`** - Inter Call Graph Edges (\\*).\n\n- **`DF`** - Deprecated Functions. All deprecated exported functions and all\n used deprecated BIFs.\n\n- **`DF_1`** - Deprecated Functions. All deprecated functions to be removed in\n next version.\n\n- **`DF_2`** - Deprecated Functions. All deprecated functions to be removed in\n next version or next major release.\n\n- **`DF_3`** - Deprecated Functions. All deprecated functions to be removed in\n next version, next major release, or later.\n\nThese are a few [](){: #simple_facts } facts about the predefined variables (the\nset operators `+` (union) and `-` (difference) as well as the cast operator\n`(`Type`)` are described below):\n\n- `F` is equal to `L + X`.\n- `V` is equal to `X + L + B + U`, where `X`, `L`, `B` and `U` are pairwise\n disjoint (that is, have no elements in common).\n- `UU` is equal to `V - (XU + LU)`, where `LU` and `XU` may have elements in\n common. Put in another way:\n- `V` is equal to `UU + XU + LU`.\n- `OL` is a subset of `F`.\n- `E` is equal to `LC + XC`. Note that `LC` and `XC` may have elements in\n common, namely if some function is locally and externally used from one and\n the same function.\n- `U` is a subset of `XU`.\n- `B` is a subset of `XU`.\n- `LU` is equal to `range LC`.\n- `XU` is equal to `range XC`.\n- `LU` is a subset of `F`.\n- `UU` is a subset of `F`.\n- `range UC` is a subset of `U`.\n- `M` is equal to `AM + LM + UM`, where `AM`, `LM` and `UM` are pairwise\n disjoint.\n- `ME` is equal to `(Mod) E`.\n- `AE` is equal to `(App) E`.\n- `RE` is equal to `(Rel) E`.\n- `(Mod) V` is a subset of `M`. Equality holds if all analyzed modules have some\n local, exported, or unknown function.\n- `(App) M` is a subset of `A`. Equality holds if all applications have some\n module.\n- `(Rel) A` is a subset of `R`. Equality holds if all releases have some\n application.\n- `DF_1` is a subset of `DF_2`.\n- `DF_2` is a subset of `DF_3`.\n- `DF_3` is a subset of `DF`.\n- `DF` is a subset of `X + B`.\n\nAn important notion is that of _conversion_{: #conversion } of expressions. The\nsyntax of a cast expression is:\n\n- Expression ::= `(` Type `)` Expression\n\nThe interpretation of the cast operator depends on the named type `Type`, the\ntype of `Expression`, and the structure of the elements of the interpretation of\n`Expression`. If the named type is equal to the expression type, no conversion\nis done. Otherwise, the conversion is done one step at a time; `(Fun) (App) RE`,\nfor instance, is equivalent to `(Fun) (Mod) (App) RE`. Now assume that the\ninterpretation of `Expression` is a set of constants (functions, modules,\napplications or releases). If the named type is more general than the expression\ntype, say `Mod` and `Fun` respectively, then the interpretation of the cast\nexpression is the set of modules that have at least one of their functions\nmentioned in the interpretation of the expression. If the named type is more\nspecial than the expression type, say `Fun` and `Mod`, then the interpretation\nis the set of all the functions of the modules (in `modules` mode, the\nconversion is partial since the local functions are not known). The conversions\nto and from applications and releases work analogously. For instance,\n`(App) \"xref_.*\" : Mod` returns all applications containing at least one module\nsuch that `xref_` is a prefix of the module name.\n\nNow assume that the interpretation of `Expression` is a set of calls. If the\nnamed type is more general than the expression type, say `Mod` and `Fun`\nrespectively, then the interpretation of the cast expression is the set of calls\n(M1, M2) such that the interpretation of the expression contains a call from\nsome function of M1 to some function of M2. If the named type is more special\nthan the expression type, say `Fun` and `Mod`, then the interpretation is the\nset of all function calls (F1, F2) such that the interpretation of the\nexpression contains a call (M1, M2) and F1 is a function of M1 and F2 is a\nfunction of M2 (in `modules` mode, there are no functions calls, so a cast to\n`Fun` always yields an empty set). Again, the conversions to and from\napplications and releases work analogously.\n\nThe interpretation of constants and variables are sets, and those sets can be\nused as the basis for forming new sets by the application of _set operators_{:\n#set_operator }. The syntax:\n\n- Expression ::= Expression BinarySetOp Expression\n- BinarySetOp ::= `+` | `*` | `-`\n\n`+`, `*` and `-` are interpreted as union, intersection and difference\nrespectively: the union of two sets contains the elements of both sets; the\nintersection of two sets contains the elements common to both sets; and the\ndifference of two sets contains the elements of the first set that are not\nmembers of the second set. The elements of the two sets must be of the same\nstructure; for instance, a function call cannot be combined with a function. But\nif a cast operator can make the elements compatible, then the more general\nelements are converted to the less general element type. For instance, `M + F`\nis equivalent to `(Fun) M + F`, and `E - AE` is equivalent to `E - (Fun) AE`.\nOne more example: `X * xref : Mod` is interpreted as the set of functions\nexported by the module `xref`; `xref : Mod` is converted to the more special\ntype of `X` (`Fun`, that is) yielding all functions of `xref`, and the\nintersection with `X` (all functions exported by analyzed modules and library\nmodules) is interpreted as those functions that are exported by some module\n_and_ functions of `xref`.\n\nThere are also unary set operators:\n\n- Expression ::= UnarySetOp Expression\n- UnarySetOp ::= `domain` | `range` | `strict`\n\nRecall that a call is a pair (From, To). `domain` applied to a set of calls is\ninterpreted as the set of all vertices From, and `range` as the set of all\nvertices To. The interpretation of the `strict` operator is the operand with all\ncalls on the form (A, A) removed.\n\nThe interpretation of the _restriction operators_{: #restriction } is a subset\nof the first operand, a set of calls. The second operand, a set of vertices, is\nconverted to the type of the first operand. The syntax of the restriction\noperators:\n\n- Expression ::= Expression RestrOp Expression\n- RestrOp ::= `|`\n- RestrOp ::= `||`\n- RestrOp ::= `|||`\n\nThe interpretation in some detail for the three operators:\n\n- **`|`** - The subset of calls from any of the vertices.\n\n- **`||`** - The subset of calls to any of the vertices.\n\n- **`|||`** - The subset of calls to and from any of the vertices. For all sets\n of calls `CS` and all sets of vertices `VS`, `CS ||| VS ` is equivalent to\n `CS | VS * CS || VS`.\n\n[](){: #graph_analyses } Two functions (modules, applications, releases) belong\nto the same strongly connected component if they call each other (in)directly.\nThe interpretation of the `components` operator is the set of strongly connected\ncomponents of a set of calls. The `condensation` of a set of calls is a new set\nof calls between the strongly connected components such that there is an edge\nbetween two components if there is some constant of the first component that\ncalls some constant of the second component.\n\nThe interpretation of the `of` operator is a chain of calls of the second\noperand (a set of calls) that passes throw all of the vertices of the first\noperand (a tuple of constants), in the given order. The second operand is\nconverted to the type of the first operand. For instance, the `of` operator can\nbe used for finding out whether a function calls another function indirectly,\nand the chain of calls demonstrates how. The syntax of the graph analyzing\noperators:\n\n- Expression ::= Expression BinaryGraphOp Expression\n- Expression ::= UnaryGraphOp Expression\n- UnaryGraphOp ::= `components` | `condensation`\n- BinaryGraphOp ::= `of`\n\nAs was mentioned before, the graph analyses operate on the `digraph`\nrepresentation of graphs. By default, the `digraph` representation is created\nwhen needed (and deleted when no longer used), but it can also be created\nexplicitly by use of the `closure` operator:\n\n- Expression ::= ClosureOp Expression\n- ClosureOp ::= `closure`\n\nThe interpretation of the `closure` operator is the transitive closure of the\noperand.\n\nThe restriction operators are defined for closures as well;\n`closure E | xref : Mod` is interpreted as the direct or indirect function calls\nfrom the `xref` module, while the interpretation of `E | xref : Mod` is the set\nof direct calls from `xref`. If some graph is to be used in several graph\nanalyses, it saves time to assign the `digraph` representation of the graph to a\nuser variable, and then make sure that every graph analysis operates on that\nvariable instead of the list representation of the graph.\n\nThe lines where functions are defined (more precisely: where the first clause\nbegins) and the lines where functions are used are available in `functions`\nmode. The line numbers refer to the files where the functions are defined. This\nholds also for files included with the `-include` and `-include_lib` directives,\nwhich may result in functions defined apparently in the same line. The _line\noperators_ are used for assigning line numbers to functions and for assigning\nsets of line numbers to function calls. The syntax is similar to the one of the\ncast operator:\n\n- Expression ::= `(` LineOp`)` Expression\n- Expression ::= `(` XLineOp`)` Expression\n- LineOp ::= `Lin` | `ELin` | `LLin` | `XLin`\n- XLineOp ::= `XXL`\n\nThe interpretation of the `Lin` operator applied to a set of functions assigns\nto each function the line number where the function is defined. Unknown\nfunctions and functions of library modules are assigned the number 0.\n\nThe interpretation of some LineOp operator applied to a set of function calls\nassigns to each call the set of line numbers where the first function calls the\nsecond function. Not all calls are assigned line numbers by all operators:\n\n- the `Lin` operator is defined for Call Graph Edges;\n- the `LLin` operator is defined for Local Calls.\n- the `XLin` operator is defined for External Calls.\n- the `ELin` operator is defined for Inter Call Graph Edges.\n\nThe `Lin` (`LLin`, `XLin`) operator assigns the lines where calls (local calls,\nexternal calls) are made. The `ELin` operator assigns to each call (From, To),\nfor which it is defined, every line L such that there is a chain of calls from\nFrom to To beginning with a call on line L.\n\nThe `XXL` operator is defined for the interpretation of any of the LineOp\noperators applied to a set of function calls. The result is that of replacing\nthe function call with a line numbered function call, that is, each of the two\nfunctions of the call is replaced by a pair of the function and the line where\nthe function is defined. The effect of the `XXL` operator can be undone by the\nLineOp operators. For instance, `(Lin) (XXL) (Lin) E` is equivalent to\n`(Lin) E`.\n\nThe `+`, `-`, `*`, and `#` operators are defined for line number expressions,\nprovided the operands are compatible. The LineOp operators are also defined for\nmodules, applications, and releases; the operand is implicitly converted to\nfunctions. Similarly, the cast operator is defined for the interpretation of the\nLineOp operators.\n\nThe interpretation of the _counting operator_{: #count } is the number of\nelements of a set. The operator is undefined for closures. The `+`, `-` and `*`\noperators are interpreted as the obvious arithmetical operators when applied to\nnumbers. The syntax of the counting operator:\n\n- Expression ::= CountOp Expression\n- CountOp ::= `#`\n\nAll binary operators are left associative; for instance, `A | B  || C` is\nequivalent to `(A | B) || C`. The following is a list of all operators, in\nincreasing order of _precedence_{: #precedence }:\n\n- `+`, `-`\n- `*`\n- `#`\n- `|`, `||`, `|||`\n- `of`\n- `(`Type`)`\n- `closure`, `components`, `condensation`, `domain`, `range`, `strict`\n\nParentheses are used for grouping, either to make an expression more readable or\nto override the default precedence of operators:\n\n- Expression ::= `(` Expression `)`\n\nA _query_{: #query } is a non-empty sequence of statements. A statement is\neither an assignment of a user variable or an expression. The value of an\nassignment is the value of the right hand side expression. It makes no sense to\nput a plain expression anywhere else but last in queries. The syntax of queries\nis summarized by these productions:\n\n- Query ::= Statement`,` ...\n- Statement ::= Assignment | Expression\n- Assignment ::= Variable `:=` Expression | Variable `=` Expression\n\nA variable cannot be assigned a new value unless first removed. Variables\nassigned to by the `=` operator are removed at the end of the query, while\nvariables assigned to by the `:=` operator can only be removed by calls to\n`forget`. There are no user variables when module data need to be set up again;\nif any of the functions that make it necessary to set up module data again is\ncalled, all user variables are forgotten.","title":"xref","ref":"xref.html"},{"type":"module","doc":"`m:beam_lib`, `m:digraph`, `m:digraph_utils`, `m:re`,\n[User's Guide for Xref](xref_chapter.md)","title":"See Also - xref","ref":"xref.html#module-see-also"},{"type":"function","doc":"","title":"xref.add_application/2","ref":"xref.html#add_application/2"},{"type":"function","doc":"Adds an application, the modules of the application, and\n[module data](`m:xref#module_data`) of the modules to an\n[Xref server](`m:xref#xref_server`).\n\nThe modules will be members of the application. The default is to use\nthe base name of the directory with the version removed as application\nname, but this can be overridden by the `name` option. Returns the\nname of the application.\n\nIf the given directory has a subdirectory named `ebin`, modules (BEAM files) are\nsearched for in that directory, otherwise modules are searched for in the given\ndirectory.\n\nIf the [mode](`m:xref#mode`) of the Xref server is `functions`, BEAM files that\ncontain no [debug information](`m:xref#debug_info`) are ignored.","title":"xref.add_application/3","ref":"xref.html#add_application/3"},{"type":"function","doc":"","title":"xref.add_directory/2","ref":"xref.html#add_directory/2"},{"type":"function","doc":"Adds the modules found in the given directory and the\n[modules' data](`m:xref#module_data`) to an [Xref server](`m:xref#xref_server`).\n\nThe default is not to examine subdirectories, but if the option `recurse` has\nthe value `true`, modules are searched for in subdirectories on all levels as\nwell as in the given directory. Returns a sorted list of the names of the added\nmodules.\n\nThe modules added will not be members of any applications.\n\nIf the [mode](`m:xref#mode`) of the Xref server is `functions`, BEAM files that\ncontain no [debug information](`m:xref#debug_info`) are ignored.","title":"xref.add_directory/3","ref":"xref.html#add_directory/3"},{"type":"function","doc":"","title":"xref.add_module/2","ref":"xref.html#add_module/2"},{"type":"function","doc":"Adds a module and its [module data](`m:xref#module_data`) to an\n[Xref server](`m:xref#xref_server`).\n\nThe module will not be member of any application. Returns the name of the module.\n\nIf the [mode](`m:xref#mode`) of the Xref server is `functions`, and the BEAM\nfile contains no [debug information](`m:xref#debug_info`), the error message\n`no_debug_info` is returned.","title":"xref.add_module/3","ref":"xref.html#add_module/3"},{"type":"function","doc":"","title":"xref.add_release/2","ref":"xref.html#add_release/2"},{"type":"function","doc":"Adds a release, the applications of the release, the modules of the\napplications, and [module data](`m:xref#module_data`) of the modules to an\n[Xref server](`m:xref#xref_server`).\n\nThe applications will be members of the release, and the modules will\nbe members of the applications. The default is to use the base name of\nthe directory as release name, but this can be overridden by the\n`name` option. Returns the name of the release.\n\nIf the given directory has a subdirectory named `lib`, the directories in that\ndirectory are assumed to be application directories, otherwise all\nsubdirectories of the given directory are assumed to be application directories.\nIf there are several versions of some application, the one with the highest\nversion is chosen.\n\nIf the [mode](`m:xref#mode`) of the Xref server is `functions`, BEAM files that\ncontain no [debug information](`m:xref#debug_info`) are ignored.","title":"xref.add_release/3","ref":"xref.html#add_release/3"},{"type":"function","doc":"","title":"xref.analyze/2","ref":"xref.html#analyze/2"},{"type":"function","doc":"[](){: #analyze } Evaluates a predefined analysis.\n\nReturns a sorted list without duplicates of `t:call/0` or\n`t:constant/0`, depending on the chosen analysis. The predefined\nanalyses, which operate on all [analyzed\nmodules](`m:xref#analyzed_module`), are (analyses marked with (\\*) are\navailable only in [mode `functions`](`m:xref#mode`)):\n\n- **`undefined_function_calls`(\\*)** - Returns a list of calls to\n [undefined functions](`m:xref#undefined_function`).\n\n- **`undefined_functions`** - Returns a list of\n [undefined functions](`m:xref#undefined_function`).\n\n- **`locals_not_used`(\\*)** - Returns a list of local functions that have not\n been locally used.\n\n- **`exports_not_used`** - Returns a list of exported functions that have not\n been externally used. Note that in `modules` mode, `M:behaviour_info/1` is\n never reported as unused.\n\n- **`deprecated_function_calls`(\\*)** - Returns a list of external calls to\n [deprecated functions](`m:xref#deprecated_function`).\n\n- **`{deprecated_function_calls, DeprFlag}`(\\*)** - Returns a list of external\n calls to deprecated functions. If `DeprFlag` is equal to `next_version`, calls\n to functions to be removed in next version are returned. If `DeprFlag` is\n equal to `next_major_release`, calls to functions to be removed in next major\n release are returned as well as calls to functions to be removed in next\n version. Finally, if `DeprFlag` is equal to `eventually`, all calls to\n functions to be removed are returned, including calls to functions to be\n removed in next version or next major release.\n\n- **`deprecated_functions`** - Returns a list of externally used deprecated\n functions.\n\n- **`{deprecated_functions, DeprFlag}`** - Returns a list of externally used\n deprecated functions. If `DeprFlag` is equal to `next_version`, functions to\n be removed in next version are returned. If `DeprFlag` is equal to\n `next_major_release`, functions to be removed in next major release are\n returned as well as functions to be removed in next version. Finally, if\n `DeprFlag` is equal to `eventually`, all functions to be removed are returned,\n including functions to be removed in next version or next major release.\n\n- **`{call, FuncSpec}`(\\*)** - Returns a list of functions called by some of the\n given functions.\n\n- **`{use, FuncSpec}`(\\*)** - Returns a list of functions that use some of the\n given functions.\n\n- **`{module_call, ModSpec}`** - Returns a list of modules called by some of the\n given modules.\n\n- **`{module_use, ModSpec}`** - Returns a list of modules that use some of the\n given modules.\n\n- **`{application_call, AppSpec}`** - Returns a list of applications called by\n some of the given applications.\n\n- **`{application_use, AppSpec}`** - Returns a list of applications that use\n some of the given applications.\n\n- **`{release_call, RelSpec}`** - Returns a list of releases called by some of\n the given releases.\n\n- **`{release_use, RelSpec}`** - Returns a list of releases that use some of the\n given releases.","title":"xref.analyze/3","ref":"xref.html#analyze/3"},{"type":"function","doc":"The modules found in the given directory are checked for calls to\n[deprecated functions](`m:xref#deprecated_function`), calls to\n[undefined functions](`m:xref#undefined_function`), and for unused local\nfunctions.\n\nThe code path is used as [library path](`m:xref#library_path`).\n\nIf some of the found BEAM files contain\n[debug information](`m:xref#debug_info`), then those modules are checked and a\nlist of tuples is returned. The first element of each tuple is one of:\n\n- `deprecated`, the second element is a sorted list of calls to deprecated\n functions;\n- `undefined`, the second element is a sorted list of calls to undefined\n functions;\n- `unused`, the second element is a sorted list of unused local functions.\n\nIf no BEAM file contains debug information, then a list of tuples is returned.\nThe first element of each tuple is one of:\n\n- `deprecated`, the second element is a sorted list of externally used\n deprecated functions;\n- `undefined`, the second element is a sorted list of undefined functions.","title":"xref.d/1","ref":"xref.html#d/1"},{"type":"function","doc":"Removes all [user variables](`m:xref#user_variable`) of an\n[Xref server](`m:xref#xref_server`).","title":"xref.forget/1","ref":"xref.html#forget/1"},{"type":"function","doc":"Removes the [user variables](`m:xref#user_variable`) given by `Variables` from\nan [Xref server](`m:xref#xref_server`).","title":"xref.forget/2","ref":"xref.html#forget/2"},{"type":"function","doc":"Given the error returned by any function of this module, the function\n`format_error` returns a descriptive string of the error in English.\n\nFor file errors, the function `file:format_error/1` is called.","title":"xref.format_error/1","ref":"xref.html#format_error/1"},{"type":"function","doc":"Returns a list of all options and their default values.","title":"xref.get_default/1","ref":"xref.html#get_default/1"},{"type":"function","doc":"Returns the default value for option `Option`.","title":"xref.get_default/2","ref":"xref.html#get_default/2"},{"type":"function","doc":"Returns the [library path](`m:xref#library_path`).","title":"xref.get_library_path/1","ref":"xref.html#get_library_path/1"},{"type":"function","doc":"The `info/1` function returns information as a list of pairs `{Tag, term()` in\nsome order about the state and the [module data](`m:xref#module_data`) of an\n[Xref server](`m:xref#xref_server`).\n\n[`info/1`](`info/1`) returns information with the following tags (tags marked\nwith (\\*) are only available in `functions` mode):\n\n- `library_path`, the [library path](`m:xref#library_path`);\n- `mode`, the [mode](`m:xref#mode`);\n- `no_releases`, number of releases;\n- `no_applications`, total number of applications (of all releases);\n- `no_analyzed_modules`, total number of\n [analyzed modules](`m:xref#analyzed_module`);\n- `no_calls` (\\*), total number of calls (in all modules), regarding instances\n of one function call in different lines as separate calls;\n- `no_function_calls` (\\*), total number of [local calls](`m:xref#local_call`),\n resolved [external calls](`m:xref#external_call`) and\n [unresolved calls](`m:xref#unresolved_call`);\n- `no_functions` (\\*), total number of local and exported functions;\n- `no_inter_function_calls` (\\*), total number of calls of the\n [Inter Call Graph](`m:xref#inter_call_graph`).","title":"xref.info/1","ref":"xref.html#info/1"},{"type":"function","doc":"Returns information about all items belonging to category `Category`.\nSee `info/3` for details.","title":"xref.info/2","ref":"xref.html#info/2"},{"type":"function","doc":"The `info` functions return information as a list of pairs `{Tag, term()}` in\nsome order about the state and the [module data](`m:xref#module_data`) of an\n[Xref server](`m:xref#xref_server`).\n\n[`info/2`](`info/2`) and [`info/3`](`info/3`) return information about all or\nsome of the analyzed modules, applications, releases, or library modules of an\nXref server. The following information is returned for every analyzed module:\n\n- `application`, an empty list if the module does not belong to any application,\n otherwise a list of the application name;\n- `builtins`, whether calls to BIFs are included in the module's data;\n- `directory`, the directory where the module's BEAM file is located;\n- `no_calls` (\\*), number of calls, regarding instances of one function call in\n different lines as separate calls;\n- `no_function_calls` (\\*), number of local calls, resolved external calls and\n unresolved calls;\n- `no_functions` (\\*), number of local and exported functions;\n- `no_inter_function_calls` (\\*), number of calls of the Inter Call Graph;\n\nThe following information is returned for every application:\n\n- `directory`, the directory where the modules' BEAM files are located;\n- `no_analyzed_modules`, number of analyzed modules;\n- `no_calls` (\\*), number of calls of the application's modules, regarding\n instances of one function call in different lines as separate calls;\n- `no_function_calls` (\\*), number of local calls, resolved external calls and\n unresolved calls of the application's modules;\n- `no_functions` (\\*), number of local and exported functions of the\n application's modules;\n- `no_inter_function_calls` (\\*), number of calls of the Inter Call Graph of the\n application's modules;\n- `release`, an empty list if the application does not belong to any release,\n otherwise a list of the release name;\n- `version`, the application's version as a list of numbers. For instance, the\n directory \"kernel-2.6\" results in the application name `kernel` and the\n application version \\[2,6]; \"kernel\" yields the name `kernel` and the version\n [].\n\nThe following information is returned for every release:\n\n- `directory`, the release directory;\n- `no_analyzed_modules`, number of analyzed modules;\n- `no_applications`, number of applications;\n- `no_calls` (\\*), number of calls of the release's modules, regarding instances\n of one function call in different lines as separate calls;\n- `no_function_calls` (\\*), number of local calls, resolved external calls and\n unresolved calls of the release's modules;\n- `no_functions` (\\*), number of local and exported functions of the release's\n modules;\n- `no_inter_function_calls` (\\*), number of calls of the Inter Call Graph of the\n release's modules.\n\nThe following information is returned for every library module:\n\n- `directory`, the directory where the\n [library module's](`m:xref#library_module`) BEAM file is located.\n\nFor every number of calls, functions, and so on returned by the `no_` tags, there is a\nquery returning the same number. Listed below are examples of such queries. Some\nof the queries return the sum of a two or more of the `no_` tags numbers. `mod`\n(`app`, `rel`) refers to any module (application, release).\n\n- `no_analyzed_modules`\n\n - `\"# AM\"` (info/1)\n - `\"# (Mod) app:App\"` (application)\n - `\"# (Mod) rel:Rel\"` (release)\n\n- `no_applications`\n\n - `\"# A\"` (info/1)\n\n- `no_calls`. The sum of the number of resolved and unresolved calls:\n\n - `\"# (XLin) E + # (LLin) E\"` (info/1)\n - `\"T = E | mod:Mod, # (LLin) T + # (XLin) T\"` (module)\n - `\"T = E | app:App, # (LLin) T + # (XLin) T\"` (application)\n - `\"T = E | rel:Rel, # (LLin) T + # (XLin) T\"` (release)\n\n- `no_functions`. Functions in library modules and the functions\n `module_info/0,1` are not counted by `info`. Assuming that\n `\"Extra := _:module_info/\\\"(0|1)\\\" + LM\"` has been evaluated, the sum of the\n number of local and exported functions are:\n\n - `\"# (F - Extra)\"` (info/1)\n - `\"# (F * mod:Mod - Extra)\"` (module)\n - `\"# (F * app:App - Extra)\"` (application)\n - `\"# (F * rel:Rel - Extra)\"` (release)\n\n- `no_function_calls`. The sum of the number of local calls, resolved external\n calls and unresolved calls:\n\n - `\"# LC + # XC\"` (info/1)\n - `\"# LC | mod:Mod + # XC | mod:Mod\"` (module)\n - `\"# LC | app:App + # XC | app:App\"` (application)\n - `\"# LC | rel:Rel + # XC | mod:Rel\"` (release)\n\n- `no_inter_function_calls`\n\n - `\"# EE\"` (info/1)\n - `\"# EE | mod:Mod\"` (module)\n - `\"# EE | app:App\"` (application)\n - `\"# EE | rel:Rel\"` (release)\n\n- `no_releases`\n\n - `\"# R\"` (info/1)","title":"xref.info/3","ref":"xref.html#info/3"},{"type":"function","doc":"The given BEAM file (with or without the `.beam` extension) or the file found by\ncalling `code:which(Module)` is checked for calls to\n[deprecated functions](`m:xref#deprecated_function`), calls to\n[undefined functions](`m:xref#undefined_function`), and for unused local\nfunctions.\n\nThe code path is used as [library path](`m:xref#library_path`).\n\nIf the BEAM file contains [debug information](`m:xref#debug_info`), a list\nof tuples is returned. The first element of each tuple is one of:\n\n- `deprecated`, the second element is a sorted list of calls to deprecated\n functions;\n- `undefined`, the second element is a sorted list of calls to undefined\n functions;\n- `unused`, the second element is a sorted list of unused local functions.\n\nIf the BEAM file does not contain debug information, a list of tuples is\nreturned. The first element of each tuple is one of:\n\n- `deprecated`, the second element is a sorted list of externally used\n deprecated functions;\n- `undefined`, the second element is a sorted list of undefined functions.","title":"xref.m/1","ref":"xref.html#m/1"},{"type":"function","doc":"","title":"xref.q/2","ref":"xref.html#q/2"},{"type":"function","doc":"Evaluates a [query](`m:xref#query`) in the context of an\n[Xref server](`m:xref#xref_server`), and returns the value of the last\nstatement.\n\nThe syntax of the value depends on the expression:\n\n- A set of calls is represented by a sorted list without duplicates of\n `t:call/0`.\n- A set of constants is represented by a sorted list without duplicates of\n `t:constant/0`.\n- A set of strongly connected components is a sorted list without duplicates of\n `Component`.\n- A set of calls between strongly connected components is a sorted list without\n duplicates of `ComponentCall`.\n- A chain of calls is represented by a list of `t:constant/0`. The list contains\n the From vertex of every call and the To vertex of the last call.\n- The `of` operator returns `false` if no chain of calls between the given\n constants can be found.\n- The value of the `closure` operator (the `digraph` representation) is\n represented by the atom `'closure()'`.\n- A set of line numbered functions is represented by a sorted list without\n duplicates of `DefineAt`.\n- A set of line numbered function calls is represented by a sorted list without\n duplicates of `CallAt`.\n- A set of line numbered functions and function calls is represented by a sorted\n list without duplicates of `AllLines`.\n\nFor both `CallAt` and `AllLines` it holds that for no list element is\n`LineNumbers` an empty list; such elements have been removed. The constants of\n`component` and the integers of `LineNumbers` are sorted and without duplicates.","title":"xref.q/3","ref":"xref.html#q/3"},{"type":"function","doc":"Removes applications and their modules and [module data](`m:xref#module_data`)\nfrom an [Xref server](`m:xref#xref_server`).","title":"xref.remove_application/2","ref":"xref.html#remove_application/2"},{"type":"function","doc":"Removes [analyzed modules](`m:xref#analyzed_module`) and\n[module data](`m:xref#module_data`) from an [Xref server](`m:xref#xref_server`).","title":"xref.remove_module/2","ref":"xref.html#remove_module/2"},{"type":"function","doc":"Removes releases and their applications, modules, and\n[module data](`m:xref#module_data`) from an [Xref server](`m:xref#xref_server`).","title":"xref.remove_release/2","ref":"xref.html#remove_release/2"},{"type":"function","doc":"","title":"xref.replace_application/3","ref":"xref.html#replace_application/3"},{"type":"function","doc":"Replaces the modules of an application with other modules read from an\napplication directory.\n\nRelease membership of the application is retained. Note that the name\nof the application is kept; the name of the given directory is not\nused.","title":"xref.replace_application/4","ref":"xref.html#replace_application/4"},{"type":"function","doc":"","title":"xref.replace_module/3","ref":"xref.html#replace_module/3"},{"type":"function","doc":"Replaces [module data](`m:xref#module_data`) of an\n[analyzed module](`m:xref#analyzed_module`) with data read from a BEAM file.\n\nApplication membership of the module is retained, and so is the value of the\n`builtins` option of the module. An error is returned if the name of the read\nmodule differs from the given module.\n\nThe `update` function is an alternative for updating module data of recompiled\nmodules.","title":"xref.replace_module/4","ref":"xref.html#replace_module/4"},{"type":"function","doc":"Sets default values for multiple options given by `OptionValues`.\n\nSee `set_default/3` for the name of options and their allowed values.","title":"xref.set_default/2","ref":"xref.html#set_default/2"},{"type":"function","doc":"Sets the default value of one or more options.\n\nThe options that can be set this way are:\n\n- `builtins`, with initial default value `false`;\n- `recurse`, with initial default value `false`;\n- `verbose`, with initial default value `false`;\n- `warnings`, with initial default value `true`.\n\nThe initial default values are set when creating an\n[Xref server](`m:xref#xref_server`).","title":"xref.set_default/3","ref":"xref.html#set_default/3"},{"type":"function","doc":"","title":"xref.set_library_path/2","ref":"xref.html#set_library_path/2"},{"type":"function","doc":"Sets the [library path](`m:xref#library_path`).\n\nIf the given path is a list of directories, the set of [library\nmodules](`m:xref#library_module`) is determined by choosing the first\nmodule encountered while traversing the directories in the given\norder, for those modules that occur in more than one directory. By\ndefault, the library path is an empty list.\n\nThe library path `code_path`{: #code_path } is used by the functions\n[`m/1`](`m/1`) and [`d/1`](`d/1`), but can also be set explicitly. However,\nnote that the code path will be traversed once for each used\n[library module](`m:xref#library_module`) while setting up module data. On the\nother hand, if there are only a few modules that are used but not analyzed,\nusing `code_path` may be faster than setting the library path to\n`code:get_path/0`.\n\nIf the library path is set to `code_path`, the set of library modules is not\ndetermined, and the `info` functions will return empty lists of library modules.","title":"xref.set_library_path/3","ref":"xref.html#set_library_path/3"},{"type":"function","doc":"Creates an [Xref server](`m:xref#xref_server`).\n\nThe process can optionally be given a name. The default\n[mode](`m:xref#mode`) is `functions`. Options that are\nnot recognized by Xref are passed on to `gen_server:start/4`.","title":"xref.start/1","ref":"xref.html#start/1"},{"type":"function","doc":"Creates an [Xref server](`m:xref#xref_server`) with a given name.\n\nThe default [mode](`m:xref#mode`) is `functions`. Options that are\nnot recognized by Xref are passed on to `gen_server:start/4`.","title":"xref.start/2","ref":"xref.html#start/2"},{"type":"function","doc":"Stops an [Xref server](`m:xref#xref_server`).","title":"xref.stop/1","ref":"xref.html#stop/1"},{"type":"function","doc":"","title":"xref.update/1","ref":"xref.html#update/1"},{"type":"function","doc":"Replaces the [module data](`m:xref#module_data`) of all\n[analyzed modules](`m:xref#analyzed_module`) the BEAM files of which have been\nmodified since last read by an `add` function or `update`.\n\nApplication membership of the modules is retained, and so is the value\nof the `builtins`option. Returns a sorted list of the names of\nthe replaced modules.","title":"xref.update/2","ref":"xref.html#update/2"},{"type":"function","doc":"","title":"xref.variables/1","ref":"xref.html#variables/1"},{"type":"function","doc":"Returns a sorted lists of the names of the variables of an\n[Xref server](`m:xref#xref_server`).\n\nThe default is to return only the\n[user variables](`m:xref#user_variable`).","title":"xref.variables/2","ref":"xref.html#variables/2"},{"type":"type","doc":"","title":"xref.add_dir_rsn/0","ref":"xref.html#t:add_dir_rsn/0"},{"type":"type","doc":"","title":"xref.add_mod_rsn/0","ref":"xref.html#t:add_mod_rsn/0"},{"type":"type","doc":"","title":"xref.analysis/0","ref":"xref.html#t:analysis/0"},{"type":"type","doc":"","title":"xref.analyze_rsn/0","ref":"xref.html#t:analyze_rsn/0"},{"type":"type","doc":"","title":"xref.answer/0","ref":"xref.html#t:answer/0"},{"type":"type","doc":"","title":"xref.app_spec/0","ref":"xref.html#t:app_spec/0"},{"type":"type","doc":"","title":"xref.application/0","ref":"xref.html#t:application/0"},{"type":"type","doc":"","title":"xref.call/0","ref":"xref.html#t:call/0"},{"type":"type","doc":"","title":"xref.component/0","ref":"xref.html#t:component/0"},{"type":"type","doc":"","title":"xref.constant/0","ref":"xref.html#t:constant/0"},{"type":"type","doc":"","title":"xref.define_at/0","ref":"xref.html#t:define_at/0"},{"type":"type","doc":"","title":"xref.depr_flag/0","ref":"xref.html#t:depr_flag/0"},{"type":"type","doc":"","title":"xref.directory/0","ref":"xref.html#t:directory/0"},{"type":"type","doc":"","title":"xref.file/0","ref":"xref.html#t:file/0"},{"type":"type","doc":"","title":"xref.file_error/0","ref":"xref.html#t:file_error/0"},{"type":"type","doc":"","title":"xref.func_spec/0","ref":"xref.html#t:func_spec/0"},{"type":"type","doc":"","title":"xref.funcall/0","ref":"xref.html#t:funcall/0"},{"type":"type","doc":"","title":"xref.function_name/0","ref":"xref.html#t:function_name/0"},{"type":"type","doc":"","title":"xref.info/0","ref":"xref.html#t:info/0"},{"type":"type","doc":"","title":"xref.library/0","ref":"xref.html#t:library/0"},{"type":"type","doc":"","title":"xref.library_path/0","ref":"xref.html#t:library_path/0"},{"type":"type","doc":"","title":"xref.mod_spec/0","ref":"xref.html#t:mod_spec/0"},{"type":"type","doc":"","title":"xref.mode/0","ref":"xref.html#t:mode/0"},{"type":"type","doc":"","title":"xref.path/0","ref":"xref.html#t:path/0"},{"type":"type","doc":"","title":"xref.q_rsn/0","ref":"xref.html#t:q_rsn/0"},{"type":"type","doc":"","title":"xref.rel_spec/0","ref":"xref.html#t:rel_spec/0"},{"type":"type","doc":"","title":"xref.release/0","ref":"xref.html#t:release/0"},{"type":"type","doc":"","title":"xref.string_position/0","ref":"xref.html#t:string_position/0"},{"type":"type","doc":"","title":"xref.variable/0","ref":"xref.html#t:variable/0"},{"type":"type","doc":"","title":"xref.xarity/0","ref":"xref.html#t:xarity/0"},{"type":"type","doc":"","title":"xref.xmfa/0","ref":"xref.html#t:xmfa/0"},{"type":"type","doc":"","title":"xref.xref/0","ref":"xref.html#t:xref/0"},{"type":"extras","doc":"\n# Tools Release Notes\n\nThis document describes the changes made to the Tools application.","title":"Tools Release Notes","ref":"notes.html"},{"type":"extras","doc":"","title":"Tools 4.0 - Tools Release Notes","ref":"notes.html#tools-4-0"},{"type":"extras","doc":"- Dialyzer warnings due to type specs added in `m:dbg` have been eliminated.\n\n Own Id: OTP-18860\n\n- In Erlang/OTP 26, doing a `m:cover` analysis on the `line` level would return multiple entries for lines on which multiple functions were defined.\n \n For example, consider this module:\n \n -module(foo).\n -export([bar/0, baz/0]).\n \n bar() -> ok. baz() -> not_ok.\n \n In Erlang/OTP 26, analysing on the `line` level would return two entries\n for line 4:\n \n 1> cover:compile_module(foo).\n {ok,foo}\n 2> foo:bar().\n ok\n 3> cover:analyse(foo, coverage, line).\n {ok,[{{foo,4},{1,0}},{{foo,4},{0,1}}]}\n 4> cover:analyse(foo, calls, line).\n {ok,[{{foo,4},1},{{foo,4},0}]}\n \n In Erlang/OTP 27, there will only be a single entry for line 4:\n \n 1> cover:compile_module(foo).\n {ok,foo}\n 2> foo:bar().\n ok\n 3> cover:analyse(foo, coverage, line).\n {ok,[{{foo,4},{1,0}}]}\n 4> cover:analyse(foo, calls, line).\n {ok,[{{foo,4},1}]}\n\n Own Id: OTP-18998 Aux Id: [GH-8159], [PR-8182]\n\n- Fixed align command in emacs mode.\n\n Own Id: OTP-19026 Aux Id: [PR-8155]\n\n[GH-8159]: https://github.com/erlang/otp/issues/8159\n[PR-8182]: https://github.com/erlang/otp/pull/8182\n[PR-8155]: https://github.com/erlang/otp/pull/8155","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Triple-Quoted Strings has been implemented as per [EEP 64](https://www.erlang.org/eeps/eep-0064). See [String](`e:system:data_types.md#string`) in the Reference Manual.\n \n Example:\n \n ```erlang\n 1> \"\"\"\n a\n b\n c\n \"\"\".\n \"a\\nb\\nc\"\n ```\n \n Adjacent string literals without intervening white space is now a syntax error, to avoid possible confusion with triple-quoted strings. For example:\n \n ```erlang\n 1> \"abc\"\"xyz\".\n \"xyz\".\n * 1:6: adjacent string literals without intervening white space\n ```\n\n *** POTENTIAL INCOMPATIBILITY ***\n\n Own Id: OTP-18750 Aux Id: OTP-18746, [PR-7313], [PR-7451]\n\n- There is a new tool `m:tprof`, which combines the functionality of `m:eprof` and `m:cprof` under one interface and adds heap profiling. It also has functionality to help with profiling process hierarchies.\n \n *Example*:\n \n ```erlang\n 1> tprof:profile(lists, seq, [1, 16], #{type => call_memory}).\n \n ****** Process <0.92.0> -- 100.00% of total *** \n FUNCTION CALLS WORDS PER CALL [ %]\n lists:seq_loop/3 5 32 6.40 [100.00]\n 32 [ 100.0]\n ok\n ```\n\n Own Id: OTP-18756 Aux Id: [PR-6639]\n\n- Native coverage support has been implemented in the JIT. It will automatically be used by the `m:cover` tool to reduce the execution overhead when running cover-compiled code.\n \n There are also new APIs to support native coverage without using the `cover` tool.\n \n To instrument code for native coverage it must be compiled with the [`line_coverage`](`m:compile#line_coverage`) option.\n \n To enable native coverage in the runtime system, start it like so:\n \n ```text\n $ erl +JPcover true\n ```\n \n There are also the following new functions for supporting native coverage:\n \n * `code:coverage_support/0`\n * `code:get_coverage/2`\n * `code:reset_coverage/1`\n * `code:get_coverage_mode/0`\n * `code:get_coverage_mode/1`\n * `code:set_coverage_mode/1`\n\n Own Id: OTP-18856 Aux Id: [PR-7856]\n\n- The documentation has been migrated to use Markdown and ExDoc.\n\n Own Id: OTP-18955 Aux Id: [PR-8026]\n\n- Improved the align command in emacs mode.\n\n Own Id: OTP-19080 Aux Id: [PR-8288]\n\n[PR-7313]: https://github.com/erlang/otp/pull/7313\n[PR-7451]: https://github.com/erlang/otp/pull/7451\n[PR-6639]: https://github.com/erlang/otp/pull/6639\n[PR-7856]: https://github.com/erlang/otp/pull/7856\n[PR-8026]: https://github.com/erlang/otp/pull/8026\n[PR-8288]: https://github.com/erlang/otp/pull/8288","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 3.6 - Tools Release Notes","ref":"notes.html#tools-3-6"},{"type":"extras","doc":"- Map comprehensions as suggested in EEP 58 has now been implemented.\n\n Own Id: OTP-18413 Aux Id: EEP-58, PR-6727\n\n- The `instrument` module has been moved from `tools` to `runtime_tools`.\n\n Own Id: OTP-18487 Aux Id: PR-6829","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 3.5.3 - Tools Release Notes","ref":"notes.html#tools-3-5-3"},{"type":"extras","doc":"- Removed the previously undocumented and unsupported `emem` tool.\n\n Own Id: OTP-17892 Aux Id: PR-5591","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 3.5.2 - Tools Release Notes","ref":"notes.html#tools-3-5-2"},{"type":"extras","doc":"- Erlang-mode fixed for newer versions of xref using CL-Lib structures instead\n of EIEIO classes.\n\n Own Id: OTP-17746 Aux Id: GH-5314, PR-5324","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 3.5.1 - Tools Release Notes","ref":"notes.html#tools-3-5-1"},{"type":"extras","doc":"- The `cover` tool would not work on modules compiled with the `tuple_calls`\n option.\n\n Own Id: OTP-17440 Aux Id: GH-4796","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 3.5 - Tools Release Notes","ref":"notes.html#tools-3-5"},{"type":"extras","doc":"- For cover-compiled code, the error behaviour of list and binary comprehensions\n that used `andalso`/`orelse` in guards could be changed so that a filter that\n was supposed be evaluated in guard context was evaluated in body context. That\n is, there was a possibility that comprehensions that did not raise exceptions\n could raise exceptions when being run using `cover`.\n\n Own Id: OTP-17221 Aux Id: PR-4547","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Support for handling abstract code created before OTP R15 has been dropped.\n\n Own Id: OTP-16678 Aux Id: PR-2627\n\n- Add types and specifications for documentation.\n\n Own Id: OTP-16957\n\n- The experimental HiPE application has been removed, together with all related\n functionality in other applications.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-16963","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 3.4.4 - Tools Release Notes","ref":"notes.html#tools-3-4-4"},{"type":"extras","doc":"- `cover` would crash when compiling a module having an exported function named\n `clauses`.\n\n Own Id: OTP-17162 Aux Id: GH-4549, PR-2997, PR-4555, elixir-lang/elixir#10666\n\n- If `beam_lib` is asked to return abstract code for a BEAM file produced by\n Elixir and Elixir is not installed on the computer, `beam_lib` will no longer\n crash, but will return an error tuple. The `cover:compile_beam()` and\n `cover:compile_beam_directory()` functions have been updated to also return an\n error tuple in that situation.\n\n Own Id: OTP-17194 Aux Id: GH-4353\n\n- Make emacs mode work on emacs-27.\n\n Own Id: OTP-17225 Aux Id: PR-4542, GH-4451","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 3.4.3 - Tools Release Notes","ref":"notes.html#tools-3-4-3"},{"type":"extras","doc":"- Correct the Xref analysis `undefined_functions` to not report internally\n generated behaviour_info/1.\n\n Own Id: OTP-17191 Aux Id: OTP-16922, ERL-1476, GH-4192","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 3.4.2 - Tools Release Notes","ref":"notes.html#tools-3-4-2"},{"type":"extras","doc":"- Correct the Xref analysis `exports_not_used` to not report internally\n generated `behaviour_info/1`.\n\n Own Id: OTP-16922 Aux Id: PR-2752","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 3.4.1 - Tools Release Notes","ref":"notes.html#tools-3-4-1"},{"type":"extras","doc":"- Correct the Xref analysis `locals_not_used` to find functions called\n exclusively from `on_load` functions.\n\n Own Id: OTP-16854 Aux Id: PR-2750","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 3.4 - Tools Release Notes","ref":"notes.html#tools-3-4"},{"type":"extras","doc":"- Updates for new `erlang:term_to_iovec()` BIF.\n\n Own Id: OTP-16128 Aux Id: OTP-15618\n\n- Improved the presentation of allocations and carriers in the `instrument`\n module.\n\n Own Id: OTP-16327\n\n- Minor updates due to the new spawn improvements made.\n\n Own Id: OTP-16368 Aux Id: OTP-15251","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 3.3.1.1 - Tools Release Notes","ref":"notes.html#tools-3-3-1-1"},{"type":"extras","doc":"- `cover` would crash when compiling a module having an exported function named\n `clauses`.\n\n Own Id: OTP-17162 Aux Id: GH-4549, PR-2997, PR-4555, elixir-lang/elixir#10666","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 3.3.1 - Tools Release Notes","ref":"notes.html#tools-3-3-1"},{"type":"extras","doc":"- An Emacs warning due to lacking type in defcustom declaration has been fixed.\n\n Own Id: OTP-16356\n\n- Improve emacs indentation.\n\n Own Id: OTP-16472 Aux Id: ERL-1140\n\n- The cover tool could generate instrumented code for a module that would cause\n warnings to be issued.\n\n Own Id: OTP-16476 Aux Id: ERL-1147\n\n- Fixed generated [fprof analysis format](`m:fprof#analysis`) to also handle\n data in maps.\n\n Own Id: OTP-16498 Aux Id: ERL-814","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 3.3 - Tools Release Notes","ref":"notes.html#tools-3-3"},{"type":"extras","doc":"- Improve `-spec` indentation in emacs mode.\n\n Own Id: OTP-16164","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The Emacs erlang-mode function that lets the user open the documentation for\n an Erlang/OTP function in an Emacs buffer has been improved. Bugs in this\n function has been fixed and and the user will now be asked if the man pages\n should be downloaded automatically by Emacs when they can't be found on the\n system. To test this functionality, put the cursor over the function name in a\n call to an Erlang/OTP function (e.g., \"io:format(\"arg\")\") and type C-c C-d\n (i.e., Ctrl-key and c-key and then Ctrl-key and d-key). There is also a new\n menu item under the Erlang menu (labeled \"Man - Function Under Cursor\").\n\n Own Id: OTP-16174","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 3.2.1 - Tools Release Notes","ref":"notes.html#tools-3-2-1"},{"type":"extras","doc":"- `cover` would fail to start if two processes tried to start it at the exact\n same time.\n\n Own Id: OTP-15813 Aux Id: ERL-943","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 3.2 - Tools Release Notes","ref":"notes.html#tools-3-2"},{"type":"extras","doc":"- Add `cprof` and `tags` modules to .app file so that they are included in\n releases.\n\n Own Id: OTP-15534 Aux Id: PR-2078\n\n- Improved documentation parsing in emacs erldoc functionality.\n\n Own Id: OTP-15699 Aux Id: PR-2184","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The `cover` tool now uses the `counters` module instead of `ets` for updating\n the counters for how many times a line has been executed. By default, Cover\n will work with distributed nodes, but a new function `cover:local_only/0`\n allows running the Cover in a restricted but faster local-only mode.\n\n The increase in speed will vary depending on the type of code being\n cover-compiled, but as an example, the compiler test suite runs more than\n twice as fast with the new Cover.\n\n Own Id: OTP-15575","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 3.1.0.1 - Tools Release Notes","ref":"notes.html#tools-3-1-0-1"},{"type":"extras","doc":"- `cover` would fail to start if two processes tried to start it at the exact\n same time.\n\n Own Id: OTP-15813 Aux Id: ERL-943","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 3.1 - Tools Release Notes","ref":"notes.html#tools-3-1"},{"type":"extras","doc":"- Minor fixes for `make clean`.\n\n Own Id: OTP-15657","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- In the HTML file generated by `cover:analyse_to_file/1,2`, a link is now added\n to the line number. This makes it easier to share pointers to specific lines.\n\n Own Id: OTP-15541\n\n- Uncovered lines are now marked with a sad face, `:-(`, in the HTML output from\n `cover:analyse_to_file/1,2`. This is to make these lines easier to find by\n search.\n\n Own Id: OTP-15542","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 3.0.2 - Tools Release Notes","ref":"notes.html#tools-3-0-2"},{"type":"extras","doc":"- Remove emacs warnings and added more tests.\n\n Own Id: OTP-15476","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 3.0.1 - Tools Release Notes","ref":"notes.html#tools-3-0-1"},{"type":"extras","doc":"- The HTML pages generated by cover:analyse_to_file/1 and related functions is\n improved for readability.\n\n Own Id: OTP-15213 Aux Id: PR-1807\n\n- Add alignment functionality in emacs.\n\n Own Id: OTP-15239 Aux Id: PR-1728","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 3.0 - Tools Release Notes","ref":"notes.html#tools-3-0"},{"type":"extras","doc":"- Added `instrument:allocations` and `instrument:carriers` for retrieving\n information about memory utilization and fragmentation.\n\n The old `instrument` interface has been removed, as have the related options\n `+Mim` and `+Mis`.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-14961","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.11.2.2 - Tools Release Notes","ref":"notes.html#tools-2-11-2-2"},{"type":"extras","doc":"- `cover` would fail to start if two processes tried to start it at the exact\n same time.\n\n Own Id: OTP-15813 Aux Id: ERL-943","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.11.2.1 - Tools Release Notes","ref":"notes.html#tools-2-11-2-1"},{"type":"extras","doc":"- Minor fixes for `make clean`.\n\n Own Id: OTP-15657","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.11.2 - Tools Release Notes","ref":"notes.html#tools-2-11-2"},{"type":"extras","doc":"- A counting bug is corrected in `Cover`. The bug was introduced in Erlang/OTP\n 18.0.\n\n Own Id: OTP-14817 Aux Id: PR 1641\n\n- The `lcnt` server will no longer crash if `lcnt:information/0` is called\n before `lcnt:collect/0`.\n\n Own Id: OTP-14912\n\n- `lcnt:collect` will now implicitly start the `lcnt` server, as per the\n documentation.\n\n Own Id: OTP-14913","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Improved indentation in emacs and various other updates.\n\n Own Id: OTP-14944","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.11.1 - Tools Release Notes","ref":"notes.html#tools-2-11-1"},{"type":"extras","doc":"- Removed all old unused files in the documentation.\n\n Own Id: OTP-14475 Aux Id: ERL-409, PR-1493","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.11 - Tools Release Notes","ref":"notes.html#tools-2-11"},{"type":"extras","doc":"- The predefined Xref analysis `locals_not_used` no longer reports unused\n functions with the `-on_load()` attribute.\n\n The new predefined Xref variable `OL` holds all functions with the\n `-on_load()` attribute.\n\n Own Id: OTP-14344\n\n- In fprof when sampling multiple processes and analyzing with totals set to\n true, the output now sums together all caller and callee entries which\n concerns the same function. Previous behaviour was to report each contributing\n entry separately.\n\n Own Id: OTP-14500","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Lock counting can now be fully toggled at runtime in the lock counting\n emulator (`-emu_type lcnt`). Everything is enabled by default to match the old\n behavior, but specific categories can be toggled at will with minimal runtime\n overhead when disabled. Refer to the documentation on `lcnt:rt_mask/1` for\n details.\n\n Own Id: OTP-13170\n\n- `lcnt:collect` and `lcnt:clear` will no longer block all other threads in the\n runtime system.\n\n Own Id: OTP-14412\n\n- General Unicode improvements.\n\n Own Id: OTP-14462\n\n- Tools are updated to show Unicode atoms correctly.\n\n Own Id: OTP-14464\n\n- Add `erlang:iolist_to_iovec/1`, which converts an iolist() to an\n erlang:iovec(), which suitable for use with `enif_inspect_iovec`.\n\n Own Id: OTP-14520","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.10.1 - Tools Release Notes","ref":"notes.html#tools-2-10-1"},{"type":"extras","doc":"- In OTP-20.0, the behavior of c, make, and ct_make was changed so that in some\n cases the beam files by default would be written to the directory where the\n source files were found. This is now changed back to the old behavior so beam\n files are by default written to current directory.\n\n Own Id: OTP-14489 Aux Id: ERL-438","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.10 - Tools Release Notes","ref":"notes.html#tools-2-10"},{"type":"extras","doc":"- In some situations, `make:all()` and friends did not detect changes in include\n files located in the current directory. This is now corrected.\n\n Own Id: OTP-14339 Aux Id: ERL-395","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- The `make` module now accepts the `{emake,Emake}` option.\n\n Own Id: OTP-14253\n\n- Miscellaneous updates due to atoms containing arbitrary Unicode characters.\n\n Own Id: OTP-14285","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.9.1 - Tools Release Notes","ref":"notes.html#tools-2-9-1"},{"type":"extras","doc":"- Improved edoc support in emacs mode.\n\n Own Id: OTP-14217 Aux Id: PR-1282","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.9 - Tools Release Notes","ref":"notes.html#tools-2-9"},{"type":"extras","doc":"- Fix unhandled trace event send_to_non_existing_process in fprof.\n\n Own Id: OTP-13998","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Improved edoc support in emacs erlang-mode.\n\n Own Id: OTP-13945 Aux Id: PR-1157\n\n- Added erldoc to emacs mode which opens html documentation in browser from\n emacs. For example `M-x erldoc-browse RET lists:foreach/2`.\n\n Own Id: OTP-14018 Aux Id: PR-1197","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.8.6 - Tools Release Notes","ref":"notes.html#tools-2-8-6"},{"type":"extras","doc":"- Errors in type specification and Emacs template generation for\n `gen_statem:code_change/4` has been fixed from bugs.erlang.org's Jira cases\n ERL-172 and ERL-187.\n\n Own Id: OTP-13746 Aux Id: ERL-172, ERL-187\n\n- Fix gc_start/gc_end in fprof tags when parsing old trace logs.\n\n Own Id: OTP-13778 Aux Id: PR-1136\n\n- `make` (tools) and `ct_make` (common_test) would crash if an Erlang source\n file contained a `-warning()` directive.\n\n Own Id: OTP-13855","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.8.5 - Tools Release Notes","ref":"notes.html#tools-2-8-5"},{"type":"extras","doc":"- Correct a bug when adding multiple modules to an Xref server. The bug was\n introduced in OTP-19.0.\n\n Own Id: OTP-13708 Aux Id: ERL-173","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.8.4 - Tools Release Notes","ref":"notes.html#tools-2-8-4"},{"type":"extras","doc":"- Update fprof to use the new 'spawned' trace event to determine when a process\n has been created.\n\n Own Id: OTP-13499","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Optimize adding multiple modules to an Xref server.\n\n Own Id: OTP-13593\n\n- Various emacs mode improvements, such as better tags support.\n\n Own Id: OTP-13610","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.8.3 - Tools Release Notes","ref":"notes.html#tools-2-8-3"},{"type":"extras","doc":"- `cover:compile_beam/1` and `cover:compile_beam_directory/1,2` crashed when\n trying to compile a beam file without a `'file'` attribute. This has been\n corrected and an error is returned instead.\n\n Thanks to Louis-Philippe Gauthier for reporting this bug.\n\n Own Id: OTP-13200\n\n- Fix a bit string comprehension bug in Cover.\n\n Own Id: OTP-13277 Aux Id: PR 856","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.8.2 - Tools Release Notes","ref":"notes.html#tools-2-8-2"},{"type":"extras","doc":"- The emacs mode does not add a newline after the arrow on -callback lines\n anymore.\n\n Own Id: OTP-13042","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.8.1 - Tools Release Notes","ref":"notes.html#tools-2-8-1"},{"type":"extras","doc":"- If a module includes eunit.hrl, a parse transform adds the function test/0 on\n line 0 in the module. A bug in OTP-18.0 caused cover:analyse_to_file/1 to fail\n to insert cover data in the output file when line 0 existed in the cover data\n table. This is now corrected.\n\n Own Id: OTP-12981","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.8 - Tools Release Notes","ref":"notes.html#tools-2-8"},{"type":"extras","doc":"- In order to improve performance of the cover tool, new functions are added for\n cover compilation and analysis on multiple files. This allows for more\n parallelisation.\n\n Some improvements of the data base access is also done in order to improve the\n performance when analysing and resetting cover data.\n\n Minor incompatibility: An error reason from analyse_to_file is changed from\n no_source_code_found to \\{no_source_code_found,Module\\}.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-12330 Aux Id: seq12757\n\n- Attempting to do a `cover` analysis when neither source code nor beam file\n could be found would hang the `cover` server. Corrected to return a proper\n error.\n\n Own Id: OTP-12806","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Allow maps for supervisor flags and child specs\n\n Earlier, supervisor flags and child specs were given as tuples. While this is\n kept for backwards compatibility, it is now also allowed to give these\n parameters as maps, see [sup_flags](`m:supervisor#sup_flags`) and\n [child_spec](`m:supervisor#child_spec`).\n\n Own Id: OTP-11043\n\n- Remove Mnemosyne rules support.\n\n Own Id: OTP-12511\n\n- Add printout of total number of calls and time in eprof\n\n Own Id: OTP-12681","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.7.2 - Tools Release Notes","ref":"notes.html#tools-2-7-2"},{"type":"extras","doc":"- Fix lcnt sorting and printout of histograms.\n\n Own Id: OTP-12364\n\n- Fix a Unicode bug in the `tags` module.\n\n Own Id: OTP-12567\n\n- Fix tags completion in erlang.el for GNU Emacs 23+\n\n Own Id: OTP-12583","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.7.1 - Tools Release Notes","ref":"notes.html#tools-2-7-1"},{"type":"extras","doc":"- Fixed a typo in erlang-mode comment.\n\n Own Id: OTP-12214\n\n- Add a skeleton for -spec in Erlang mode for Emacs\n\n Own Id: OTP-12283","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Cover no longer crashes when compiling `receive` and the like with just an\n `after` clause. Thanks to José Valim for providing a fix.\n\n Own Id: OTP-12328","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.7 - Tools Release Notes","ref":"notes.html#tools-2-7"},{"type":"extras","doc":"- Add log2 histogram to lcnt for lock wait time\n\n Own Id: OTP-12059","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.6.15 - Tools Release Notes","ref":"notes.html#tools-2-6-15"},{"type":"extras","doc":"- Removed `erlang:bitstr_to_list/1` and `erlang:list_to_bitstr/1`. They were\n added by mistake, and have always raised an `undefined` exception when called.\n\n Own Id: OTP-11942","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.6.14 - Tools Release Notes","ref":"notes.html#tools-2-6-14"},{"type":"extras","doc":"- Removed the support for the query keyword from emacs mode (Thanks to Paul\n Oliver)\n\n Own Id: OTP-11568\n\n- Emacs mode improvements (Thanks to Steve Vinoski)\n\n Own Id: OTP-11601\n\n- Application upgrade (appup) files are corrected for the following\n applications:\n\n `asn1, common_test, compiler, crypto, debugger, dialyzer, edoc, eldap, erl_docgen, et, eunit, gs, hipe, inets, observer, odbc, os_mon, otp_mibs, parsetools, percept, public_key, reltool, runtime_tools, ssh, syntax_tools, test_server, tools, typer, webtool, wx, xmerl`\n\n A new test utility for testing appup files is added to test_server. This is\n now used by most applications in OTP.\n\n (Thanks to Tobias Schlager)\n\n Own Id: OTP-11744\n\n- The emacs erlang mode now match erlang keywords more carefully (Thanks to\n Steve Vinoski)\n\n Own Id: OTP-11786\n\n- The emacs erlang-mode now auto loads for more file types (Thanks to Phil\n Hagelberg)\n\n Own Id: OTP-11788","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- `cover` can run on itself. Also, support for reading BEAM files produced by\n ancient OTP versions before R9C has been removed.\n\n Own Id: OTP-11692\n\n- Support maps in cover\n\n Own Id: OTP-11764","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.6.13 - Tools Release Notes","ref":"notes.html#tools-2-6-13"},{"type":"extras","doc":"- Erlang-specific compilation error regexp is added in erlang-eunit.el. This\n defvar was earlier in erlang.el, but was erroneously removed in R15B02, while\n still used by erlang-eunit.el.\n\n Own Id: OTP-11417 Aux Id: seq12447\n\n- Take compiler options from beam in cover:compile_beam. Thanks to Péter Gömöri.\n\n Own Id: OTP-11439\n\n- Silence warnings (Thanks to Anthony Ramine)\n\n Own Id: OTP-11517","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add iodata, nonempty_string to built-in type highlighting for emacs. Thanks to\n Paul Oliver.\n\n Own Id: OTP-11394","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.6.12 - Tools Release Notes","ref":"notes.html#tools-2-6-12"},{"type":"extras","doc":"- Remove trailing spaces in Emacs templates. Thanks to Roberto Aloi.\n\n Own Id: OTP-11198\n\n- Fixed the Emacs erlang-mode to accommodate the coding style where lists\n written across several lines have each line starting with a comma. Thanks to\n Magnus Henoch.\n\n Own Id: OTP-11242\n\n- Make the Emacs Erlang mode TRAMP-aware when compiling. Thanks to Tomas\n Abrahamsson.\n\n Own Id: OTP-11270","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.6.11 - Tools Release Notes","ref":"notes.html#tools-2-6-11"},{"type":"extras","doc":"- When cover:stop(Node) was called on a non-existing node, a process waiting for\n cover data from the node would hang forever. This has been corrected.\n\n Own Id: OTP-10979","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Make cover smarter about finding source from beam.\n\n In particular, search using the source path in module_info if the current\n heuristic fails.\n\n Own Id: OTP-10902\n\n- Remove Flymake dependency in erlang-pkg.el. Thanks to Magnus Henoch.\n\n Own Id: OTP-10930\n\n- Erlang-mode: Add autoload cookies for file extension associations. Thanks to\n Magnus Henoch.\n\n Own Id: OTP-10999\n\n- Postscript files no longer needed for the generation of PDF files have been\n removed.\n\n Own Id: OTP-11016\n\n- Fix a race condition when there're several applications in apps directory.\n Thanks to Manuel Rubio.\n\n Own Id: OTP-11028\n\n- New option for eprof, 'set_on_spawn'. This option was previously always on and\n is also the default.\n\n Own Id: OTP-11144","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.6.10 - Tools Release Notes","ref":"notes.html#tools-2-6-10"},{"type":"extras","doc":"- Fix a bug in cover when used with no_auto_import. Thanks to José Valim.\n\n Own Id: OTP-10778","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.6.9 - Tools Release Notes","ref":"notes.html#tools-2-6-9"},{"type":"extras","doc":"- Add missing modules in app-file\n\n Own Id: OTP-10439\n\n- Make erlang-mode more compatible with package.el (Thanks to Gleb Peregud)\n\n Own Id: OTP-10465\n\n- Fix various typos (thanks to Tuncer Ayaz)\n\n Own Id: OTP-10611\n\n- Add separate face for exported functions (Thanks to Thomas Järvstrand)\n\n Own Id: OTP-10637\n\n- The BIF highlighting in the emacs mode has been updated to correspond with the\n correct BIFs.\n\n Own Id: OTP-10774","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Support for Unicode has been implemented.\n\n Own Id: OTP-10302\n\n- A new function, cover:flush(Nodes), is added which will fetch data from remote\n nodes without stopping cover on those nodes. This is used by test_server and\n common_test when it is safe to assume that the node will be terminated after\n the test anyway. The purpose is to avoid processes crashing when re-loading\n the original beam if the processes is still running old code.\n\n Remote nodes will now continue to count code coverage if the connection to the\n main node is broken. Earlier, a broken connection would cause the cover_server\n on the remote node to die and thus any still cover compiled modules would\n cause process crash when trying to insert cover data in ets tables that used\n to exist on the cover_server. The new functionality also involves\n synchronization with the main node if the nodes are reconnected.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-10523 Aux Id: OTP-10427\n\n- Where necessary a comment stating encoding has been added to Erlang files. The\n comment is meant to be removed in Erlang/OTP R17B when UTF-8 becomes the\n default encoding.\n\n Own Id: OTP-10630\n\n- Fix syntax highlighting of $\\\\' in Emacs mode. Thanks to Magnus Henoch.\n\n Own Id: OTP-10766","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.6.8 - Tools Release Notes","ref":"notes.html#tools-2-6-8"},{"type":"extras","doc":"- The last tuple fun call has been removed from fprof.\n\n Own Id: OTP-10091 Aux Id: seq12067\n\n- Fix indentation of record fields in Emacs (Thanks to Tomas Abrahamsson)\n\n Own Id: OTP-10120\n\n- Documentation fixes (Thanks to Ricardo Catalinas Jiménez )\n\n Own Id: OTP-10121\n\n- Remove Erlang-specific compilation error regexp in erlang.el\n\n Own Id: OTP-10168\n\n- Fix highlighting of atoms ending with a dollar sign\n\n Like this: 'atom$'. In that example, the last single quote should be\n recognised as ending the atom. This needs a font-lock workaround similar to\n the one for strings. Thanks to Magnus Henoch\n\n Own Id: OTP-10178\n\n- Xref now accepts filenames with character codes greater than 126. (Thanks to\n Emile Joubert for reporting the issue.)\n\n Own Id: OTP-10192\n\n- Add test_indentation target to lib/tools/emacs/Makefile\n\n Automatically indent test.erl.orig, save to test.erl, and compare to\n test.erl.intended. Thanks to Magnus Henoch.\n\n Own Id: OTP-10226","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.6.7 - Tools Release Notes","ref":"notes.html#tools-2-6-7"},{"type":"extras","doc":"- Makefiles in erts, hipe and tools have been corrected to enable parallel make,\n i.e MAKEFLAGS=-jX where X is the parallelity number. As a result of this\n dependencies were corrected since that is what is needed for parallel make to\n work.\n\n Own Id: OTP-9857 Aux Id: OTP-9451\n\n- Minor suppressions and fixes of compilation warnings\n\n Own Id: OTP-10016","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.6.6.6 - Tools Release Notes","ref":"notes.html#tools-2-6-6-6"},{"type":"extras","doc":"- Update system profiling principles to reflect eprof performance improvements.\n\n Own Id: OTP-9656\n\n- \\[cover] fix leftover \\{'DOWN', ..\\} msg in callers queue\n\n After stopping cover with cover:stop() there could still be a \\{'DOWN',...\\}\n leftover message in the calling process's message queue. This unexpected\n leftover could be eliminated if erlang:demonitor/2 with option flush would be\n used in certain points\n\n Own Id: OTP-9694\n\n- Add deps as erlang-flymake include directory.\n\n Update erlang-flymake to recognize the \"deps\" folder as an include directory.\n This makes erlang-flymake compatible with the rebar dependency management\n tool's default folder structure, which puts included dependencies in\n \"deps\".(Thanks to Kevin Albrecht)\n\n Own Id: OTP-9791","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Variables are now now allowed in '`fun M:F/A`' as suggested by Richard O'Keefe\n in EEP-23.\n\n The representation of '`fun M:F/A`' in the abstract format has been changed in\n an incompatible way. Tools that directly read or manipulate the abstract\n format (such as parse transforms) may need to be updated. The compiler can\n handle both the new and the old format (i.e. extracting the abstract format\n from a pre-R15 BEAM file and compiling it using compile:forms/1,2 will work).\n The `syntax_tools` application can also handle both formats.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-9643\n\n- Tuple funs (a two-element tuple with a module name and a function) are now\n officially deprecated and will be removed in R16. Use '`fun M:F/A`' instead.\n To make you aware that your system uses tuple funs, the very first time a\n tuple fun is applied, a warning will be sent to the error logger.\n\n Own Id: OTP-9649\n\n- Eliminate use of deprecated regexp module\n\n Own Id: OTP-9810","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.6.6.5 - Tools Release Notes","ref":"notes.html#tools-2-6-6-5"},{"type":"extras","doc":"- Teach the emacs mode to compile yecc and leex files\n\n If visiting a .yrl or .xrl file in emacs with erlang-mode, then the\n \\`erlang-compile' function (normally bound to C-c C-k), now knows how to\n compile yecc and leex files, and then, if that compilation succeeds, also\n compiles the resulting .erl files.\n\n Also introduce a \\`erlang-compile-command-function-alist' to make it possible\n to hook in other functions for computing compilation commands/expressions,\n depending on file name. (Thanks to Tomas Abrahamsson )\n\n Own Id: OTP-9503","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Bugs in xref(3) have been fixed. (Thanks to Matthias Lang.)\n\n Own Id: OTP-9416","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.6.6.4 - Tools Release Notes","ref":"notes.html#tools-2-6-6-4"},{"type":"extras","doc":"- Change make:files to behave more like erlc\n\n This change removes the unnecessary checks on the files when make:files is\n called and allows the error checking to be done in compile:file, where the\n error messages are produced. It does not affect the return value.\n\n (Thanks to Sam bobroff)\n\n Own Id: OTP-9179\n\n- add user specified compiler options on form reloading\n\n In order to be able to test non-exported functions from another (test) module\n it is necessary to compile the specific module (at least during the test\n phase) with the export*all compiler option. This allows complete separation of\n testing and productive code. At the moment it is not possible to combine this\n with a test code coverage using the cover module. The problem is that when\n cover compiling a module using cover:compile*\\* the code is reloaded into the\n emulator omitting/filtering the passed user options. In my example above the\n export_all option would be removed and the non-exported functions cannot be\n called any more. (Thanks to Tobias Schlager)\n\n Own Id: OTP-9204\n\n- Inhibit electric newline after \"->\" when inside a type spec\n\n The Erlang mode for Emacs inserts a newline after every \"->\", which saves you\n one keystroke when writing a function, but that is inappropriate when writing\n a type spec, as you'd normally keep the spec on one line. This change inhibits\n the automatic insertion when the current line starts with \"-spec\" or\n \"-type\".(Thanks to Magnus Henoch)\n\n Own Id: OTP-9255\n\n- Add a check logic to prevent file descriptor leak\n\n cover module handle files as raw in export and import. Assert counts of ports\n are the same at the beginning and at the end of the test case.(Thanks to\n Shunichi Shinohara)\n\n Own Id: OTP-9300","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.6.6.3 - Tools Release Notes","ref":"notes.html#tools-2-6-6-3"},{"type":"extras","doc":"- Declare indentation options as \"safe\" in erlang-mode for Emacs\n\n Emacs has a facility for setting options on a per-file basis based on comments\n in the source file. By default, all options are considered \"unsafe\", and the\n user is queried before the variable is set. This patch declares the variables\n erlang-indent-level, erlang-indent-guard and erlang-argument-indent to be\n safe, if the value specified in the source file is valid.\n\n Such declarations usually look like this:\n\n %% -_- erlang-indent-level: 2 -_-\n\n and appear on the first line of the file. (thanks to Magnus Henoch)\n\n Own Id: OTP-9122","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Cover has been improved to take less memory and allow parallel analysis of\n cover data. Data collection from nodes is now done in parallel and it is now\n possible to issue multiple analyse and analyse_to_file requests at the same\n time. A new function call async_analyse_to_file has also been introduced, see\n the documentation for more details.\n\n Own Id: OTP-9043 Aux Id: seq11771","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.6.6.2 - Tools Release Notes","ref":"notes.html#tools-2-6-6-2"},{"type":"extras","doc":"- eprof: API sort mismatch has now been fixed.\n\n Own Id: OTP-8853\n\n- eprof: fix division by zero in statistics\n\n Own Id: OTP-8963","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.6.6.1 - Tools Release Notes","ref":"notes.html#tools-2-6-6-1"},{"type":"extras","doc":"- `cover` will now show ampersand characters in the source code correctly.\n (Thanks to Tom Moertel.)\n\n Own Id: OTP-8776","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.6.6 - Tools Release Notes","ref":"notes.html#tools-2-6-6"},{"type":"extras","doc":"- A race condition affecting Cover has been removed.\n\n Own Id: OTP-8469\n\n- Emacs improvements:\n\n Fixed emacs-mode installation problems.\n\n Fixed a couple of -spec and -type indentation and font-lock problems.\n\n Fixed error messages on emacs-21.\n\n Magnus Henoch fixed several issues.\n\n Ralf Doering, Klas Johansson and Chris Bernard contributed various emacs-eunit\n improvements.\n\n Klas Johansson and Dave Peticolas added emacs-flymake support.\n\n Own Id: OTP-8530","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Xref has been updated to use the `re` module instead of the deprecated\n `regexp` module.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-8472\n\n- When given the option `{builtins,true}` Xref now adds calls to operators.\n\n Own Id: OTP-8647\n\n- `eprof` has been reimplemented with support in the Erlang virtual machine and\n is now both faster (i.e. slows down the code being measured less) and scales\n much better. In measurements we saw speed-ups compared to the old eprof\n ranging from 6 times (for sequential code that only uses one scheduler/core)\n up to 84 times (for parallel code that uses 8 cores).\n\n Note: The API for the `eprof` has been cleaned up and extended. See the\n documentation.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-8706","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.6.5.1 - Tools Release Notes","ref":"notes.html#tools-2-6-5-1"},{"type":"extras","doc":"- A bug concerning bit comprehensions has been fixed in Cover. The bug was\n introduced in R13B03. (Thanks to Matthew Sackman.)\n\n Own Id: OTP-8340","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Add lock profiling tool.\n\n The Lock profiling tool, lcnt, can make use of the internal lock statistics\n when the runtime system is built with this feature enabled.\n\n This provides a mechanism to examine potential lock bottlenecks within the\n runtime itself.\n\n \\- Add erts_debug:lock_counters(\\{copy_save, bool()\\}). This option enables or\n disables statistics saving for destroyed processes and ets-tables. Enabling\n this might consume a lot of memory.\n\n \\- Add id-numbering for lock classes which is otherwise undefined.\n\n Own Id: OTP-8424\n\n- emacs: Moved code skeletons to a separate file and and added a configurable\n variable to choose skeleton. Thanks Dave Peticolas.\n\n Own Id: OTP-8446","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.6.5 - Tools Release Notes","ref":"notes.html#tools-2-6-5"},{"type":"extras","doc":"- The coverage analysis tool `cover` has been improved when it comes to handling\n list and bit string comprehensions (a counter for each qualifier), bit syntax\n expressions (the Value and Size expressions), and try expressions (the body\n called `Exprs` in the Reference Manual). A few (not all) situations where\n several expressions are put on the same line are also handled better than\n before.\n\n Own Id: OTP-8188 Aux Id: seq11397\n\n- When loading Cover compiled code on remote nodes running code in the loaded\n module, a `badarg` failure was sometimes the result. This bug has been fixed.\n\n Own Id: OTP-8270 Aux Id: seq11423\n\n- The short-circuit operators `andalso` and `orelse` are now handled correctly\n by the coverage analysis tool `cover` (it is no longer checked that the second\n argument returns a Boolean value.)\n\n Own Id: OTP-8273","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.6.4 - Tools Release Notes","ref":"notes.html#tools-2-6-4"},{"type":"extras","doc":"- `cover` now properly escapes greater-than and less-than characters in comments\n in HTML reports. (Thanks to Magnus Henoch.)\n\n Own Id: OTP-7939","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.6.3 - Tools Release Notes","ref":"notes.html#tools-2-6-3"},{"type":"extras","doc":"- xref:start/1 does now allow anonymous XREF processes to be started\n\n Own Id: OTP-7831","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.6.2 - Tools Release Notes","ref":"notes.html#tools-2-6-2"},{"type":"extras","doc":"- A bug in the Xref scanner has been fixed.\n\n Own Id: OTP-7423\n\n- A bug in Fprof where the function 'undefined' appeared to call 'undefined' has\n been corrected.\n\n Own Id: OTP-7509","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.6.1 - Tools Release Notes","ref":"notes.html#tools-2-6-1"},{"type":"extras","doc":"- The documentation has been updated so as to reflect the last updates of the\n Erlang shell as well as the minor modifications of the control sequence `p` of\n the `io_lib` module.\n\n Superfluous empty lines have been removed from code examples and from Erlang\n shell examples.\n\n Own Id: OTP-6944 Aux Id: OTP-6554, OTP-6911\n\n- [`tuple_size/1`](`tuple_size/1`) and [`byte_size/1`](`byte_size/1`) have been\n substituted for [`size/1`](`size/1`).\n\n Own Id: OTP-7009\n\n- The coverage analysis tool `cover` now handles the short-circuit Boolean\n expressions `andalso/2` and `orelse/2` properly.\n\n Own Id: OTP-7095","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.6 - Tools Release Notes","ref":"notes.html#tools-2-6"},{"type":"extras","doc":"- The `cover` tool could use huge amounts of memory when used in a distributed\n system.\n\n Own Id: OTP-6758","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.5.5 - Tools Release Notes","ref":"notes.html#tools-2-5-5"},{"type":"extras","doc":"- Missing buffer-local declaration in erlang.el has been added. Before this fix\n there could arise problems in other emacs modes after visiting a buffer using\n the erlang mode.\n\n Own Id: OTP-6721\n\n- Key-map for 'backward-delete-char-untabif updated to work properly with\n Xemacs.\n\n Own Id: OTP-6723","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Minor updates of Xref.\n\n Own Id: OTP-6586\n\n- Minor Makefile changes.\n\n Own Id: OTP-6689 Aux Id: OTP-6742\n\n- \"C-u C-c C-k\" now does a compile with both \"debug_info\" and \"export_all\".\n\n Own Id: OTP-6741","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.5.4.1 - Tools Release Notes","ref":"notes.html#tools-2-5-4-1"},{"type":"extras","doc":"- Changes due to internal interface changes in the erts application which are\n needed at compile-time. No functionality has been changed.\n\n Own Id: OTP-6611 Aux Id: OTP-6580","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.5.4 - Tools Release Notes","ref":"notes.html#tools-2-5-4"},{"type":"extras","doc":"- Made change to support the function erlang-find-tag for xemacs and emacs-21.\n\n Own Id: OTP-6512","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Minor updates of xref for future compatibility.\n\n Own Id: OTP-6513","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.5.3 - Tools Release Notes","ref":"notes.html#tools-2-5-3"},{"type":"extras","doc":"- `eprof` did not work reliably in the SMP emulator, because the trace receiver\n process could not process the trace messages fast enough. Therefore, `eprof`\n now blocks the other schedulers while profiling.\n\n Own Id: OTP-6373","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.5.2 - Tools Release Notes","ref":"notes.html#tools-2-5-2"},{"type":"extras","doc":"- Fprof traces could become truncated for the SMP emulator. This bug has now\n been corrected.\n\n Own Id: OTP-6246","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.5.1 - Tools Release Notes","ref":"notes.html#tools-2-5-1"},{"type":"extras","doc":"- eprof now works somewhat better in the SMP emulator.\n\n Own Id: OTP-6152","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.5 - Tools Release Notes","ref":"notes.html#tools-2-5"},{"type":"extras","doc":"- Fixed some bugs in `make`:\n\n `make:files/1,2` can now handle a file in another directory as argument,\n similar to `make:all/0,1`.\n\n When specifying a file name including the `.erl` extension in `Emakefile`,\n `make:all/0,1` looked for the object code in the wrong place.\n\n When specifying a file name including the `.erl` extension in `Emakefile` and\n some compile options for the file, `make:files/0,1` did not use the options as\n it should do.\n\n Own Id: OTP-6057 Aux Id: seq10299\n\n- `cover`: When `cover:stop()` was called, the cover compiled code was not\n unloaded (as stated in the documentation) but simply marked as 'old'. This\n meant that processes lingering in (or with funs referencing to) the cover\n compiled code would survive even when the cover server and its ETS tables was\n terminated.\n\n Now the cover compiled code is unloaded, meaning that processes lingering\n in/with references to it will be killed when `cover:stop` is called, instead\n of later crashing with `badarg` when trying to bump counters in ETS tables no\n longer existing.","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"- Replaced call to deprecated function `file:file_info/1` with call to\n `filelib:is_dir/1` and `filelib:is_regular/1` in `tags.erl`.\n\n Own Id: OTP-6079","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.4.7 - Tools Release Notes","ref":"notes.html#tools-2-4-7"},{"type":"extras","doc":"- A bug in `fprof` profiling causing erroneous inconsistent trace failure has\n been corrected.\n\n Own Id: OTP-5922 Aux Id: seq10203","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.4.6 - Tools Release Notes","ref":"notes.html#tools-2-4-6"},{"type":"extras","doc":"- Emacs: `erlang-man-function` and `erlang-man-module` used a pattern matching\n to find the requested module that sometimes yielded unexpected results. For\n example, `erlang-man-module file` would display the man page for\n `CosFileTransfer_File`.\n\n Own Id: OTP-5746 Aux Id: seq10096\n\n- Some compiler warnings and Dialyzer warnings were eliminated in the Tools\n application.\n\n When tracing to a port (which `fprof` does), there could be fake schedule\n out/schedule in messages sent for a process that had exited.\n\n Own Id: OTP-5757","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.4.5 - Tools Release Notes","ref":"notes.html#tools-2-4-5"},{"type":"extras","doc":"- The cross reference tool `xref` did not handle the new `fun M:F/A` construct\n properly. This problem has been fixed.\n\n Own Id: OTP-5653","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.4.4 - Tools Release Notes","ref":"notes.html#tools-2-4-4"},{"type":"extras","doc":"- The `cover` tool did not escape '<' and '>' not being part of HTML tags in\n HTML log files.\n\n Own Id: OTP-5588","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.4.3 - Tools Release Notes","ref":"notes.html#tools-2-4-3"},{"type":"extras","doc":"- It is now possible to encrypt the debug information in beam files, to help\n keep the source code secret. See `m:compile` for how to provide the key for\n encrypting, and `m:beam_lib` for how to provide the key for decryption so that\n tools such as Debugger, `xref`, or `cover` can be used.\n\n The `beam_lib:chunks/2` functions now accepts an additional chunk type\n '`compile_info`' to retrieve the compilation information directly as a term.\n (Thanks to Tobias Lindahl.)\n\n Own Id: OTP-5460 Aux Id: seq9787","title":"Improvements and New Features - Tools Release Notes","ref":"notes.html#improvements-and-new-features"},{"type":"extras","doc":"","title":"Tools 2.4.2 - Tools Release Notes","ref":"notes.html#tools-2-4-2"},{"type":"extras","doc":"- The `cover` tool could not analyze empty modules on module level.\n\n Own Id: OTP-5418","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"","title":"Tools 2.4.1 - Tools Release Notes","ref":"notes.html#tools-2-4-1"},{"type":"extras","doc":"- The `xref` analysis `locals_not_used` could return too many functions. This\n problem has been fixed.\n\n Own Id: OTP-5071\n\n- The `cover` tool could not always compile parse transformed modules. This\n problem has been fixed.\n\n Own Id: OTP-5305","title":"Fixed Bugs and Malfunctions - Tools Release Notes","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","doc":"\n# cover - The Coverage Analysis Tool","title":"cover - The Coverage Analysis Tool","ref":"cover_chapter.html"},{"type":"extras","doc":"The module `cover` provides a set of functions for coverage analysis of Erlang\nprograms, counting how many times each [executable line](cover_chapter.md#lines)\nis executed.\n\nCoverage analysis can be used to verify test cases, making sure all relevant\ncode is covered, and can be helpful when looking for bottlenecks in the code.","title":"Introduction - cover - The Coverage Analysis Tool","ref":"cover_chapter.html#introduction"},{"type":"extras","doc":"","title":"Getting Started With Cover - cover - The Coverage Analysis Tool","ref":"cover_chapter.html#getting-started-with-cover"},{"type":"extras","doc":"Assume that a test case for the following program should be verified:\n\n```erlang\n-module(channel).\n-behaviour(gen_server).\n\n-export([start_link/0,stop/0]).\n-export([alloc/0,free/1]). % client interface\n-export([init/1,handle_call/3,terminate/2]). % callback functions\n\nstart_link() ->\n gen_server:start_link({local,channel}, channel, [], []).\n\nstop() ->\n gen_server:call(channel, stop).\n\n%%%-Client interface functions-------------------------------------------\n\nalloc() ->\n gen_server:call(channel, alloc).\n\nfree(Channel) ->\n gen_server:call(channel, {free,Channel}).\n\n%%%-gen_server callback functions----------------------------------------\n\ninit(_Arg) ->\n {ok,channels()}.\n\nhandle_call(stop, _Client, Channels) ->\n {stop,normal,ok,Channels};\n\nhandle_call(alloc, _Client, Channels) ->\n {Ch,Channels2} = alloc(Channels),\n {reply,{ok,Ch},Channels2};\n\nhandle_call({free,Channel}, _Client, Channels) ->\n Channels2 = free(Channel, Channels),\n {reply,ok,Channels2}.\n\nterminate(_Reason, _Channels) ->\n ok.\n\n%%%-Internal functions---------------------------------------------------\n\nchannels() ->\n [ch1,ch2,ch3].\n\nalloc([Channel|Channels]) ->\n {Channel,Channels};\nalloc([]) ->\n false.\n\nfree(Channel, Channels) ->\n [Channel|Channels].\n```\n\nThe test case is implemented as follows:\n\n```erlang\n-module(test).\n-export([s/0]).\n\ns() ->\n {ok,Pid} = channel:start_link(),\n {ok,Ch1} = channel:alloc(),\n ok = channel:free(Ch1),\n ok = channel:stop().\n```","title":"Example - cover - The Coverage Analysis Tool","ref":"cover_chapter.html#example"},{"type":"extras","doc":"First of all, Cover must be started. This spawns a process which owns the Cover\ndatabase where all coverage data will be stored.\n\n```erlang\n1> cover:start().\n{ok,<0.90.0>}\n```\n\nTo include other nodes in the coverage analysis, use\n`cover:start/1`. All cover-compiled modules will then be loaded on all\nnodes, and data from all nodes will be summed up when analysing. For\nsimplicity this example only involves the current node.\n\nBefore any analysis can take place, the involved modules must be\n_cover-compiled_. This means that some extra information is added to\nthe module before beging compiled into a binary and\n[loaded](cover_chapter.md#loading). The source file of the module is\nnot affected and no `.beam` file is created.\n\n```erlang\n2> cover:compile_module(channel).\n{ok,channel}\n```\n\nEach time a function in the cover-compiled module `channel` is called,\ninformation about the call will be added to the Cover database. Run the test\ncase:\n\n```text\n3> test:s().\nok\n```\n\nCover analysis is performed by examining the contents of the Cover database. The\noutput is determined by two parameters, `Level` and `Analysis`. `Analysis` is\neither `coverage` or `calls` and determines the type of the analysis. `Level` is\neither `module`, `function`, `clause`, or `line` and determines the level of the\nanalysis.","title":"Preparation - cover - The Coverage Analysis Tool","ref":"cover_chapter.html#preparation"},{"type":"extras","doc":"Analysis of type `coverage` is used to find out how much of the code has been\nexecuted and how much has not been executed. Coverage is represented by a tuple\n`{Cov,NotCov}`, where `Cov` is the number of executable lines that have been\nexecuted at least once and `NotCov` is the number of executable lines that have\nnot been executed.\n\nIf the analysis is made on module level, the result is given for the entire\nmodule as a tuple `{Module,{Cov,NotCov}}`:\n\n```erlang\n4> cover:analyse(channel, coverage, module).\n{ok,{channel,{14,1}}}\n```\n\nFor `channel`, the result shows that 14 lines in the module are covered but one\nline is not covered.\n\nIf the analysis is made on function level, the result is given as a list of\ntuples `{Function,{Cov,NotCov}}`, one for each function in the module. A\nfunction is specified by its module name, function name and arity:\n\n```erlang\n5> cover:analyse(channel, coverage, function).\n{ok,[{{channel,start_link,0},{1,0}},\n {{channel,stop,0},{1,0}},\n {{channel,alloc,0},{1,0}},\n {{channel,free,1},{1,0}},\n {{channel,init,1},{1,0}},\n {{channel,handle_call,3},{5,0}},\n {{channel,terminate,2},{1,0}},\n {{channel,channels,0},{1,0}},\n {{channel,alloc,1},{1,1}},\n {{channel,free,2},{1,0}}]}\n```\n\nFor `channel`, the result shows that the uncovered line is in the function\n`channel:alloc/1`.\n\nIf the analysis is made on clause level, the result is given as a list of tuples\n`{Clause,{Cov,NotCov}}`, one for each function clause in the module. A clause is\nspecified by its module name, function name, arity and position within the\nfunction definition:\n\n```erlang\n6> cover:analyse(channel, coverage, clause).\n{ok,[{{channel,start_link,0,1},{1,0}},\n {{channel,stop,0,1},{1,0}},\n {{channel,alloc,0,1},{1,0}},\n {{channel,free,1,1},{1,0}},\n {{channel,init,1,1},{1,0}},\n {{channel,handle_call,3,1},{1,0}},\n {{channel,handle_call,3,2},{2,0}},\n {{channel,handle_call,3,3},{2,0}},\n {{channel,terminate,2,1},{1,0}},\n {{channel,channels,0,1},{1,0}},\n {{channel,alloc,1,1},{1,0}},\n {{channel,alloc,1,2},{0,1}},\n {{channel,free,2,1},{1,0}}]}\n```\n\nFor `channel`, the result shows that the uncovered line is in the second clause\nof `channel:alloc/1`.\n\nFinally, if the analysis is made on line level, the result is given as a list of\ntuples `{Line,{Cov,NotCov}}`, one for each executable line in the source code. A\nline is specified by its module name and line number.\n\n```erlang\n7> cover:analyse(channel, coverage, line).\n{ok,[{{channel,9},{1,0}},\n {{channel,12},{1,0}},\n {{channel,17},{1,0}},\n {{channel,20},{1,0}},\n {{channel,25},{1,0}},\n {{channel,28},{1,0}},\n {{channel,31},{1,0}},\n {{channel,32},{1,0}},\n {{channel,35},{1,0}},\n {{channel,36},{1,0}},\n {{channel,39},{1,0}},\n {{channel,44},{1,0}},\n {{channel,47},{1,0}},\n {{channel,49},{0,1}},\n {{channel,52},{1,0}}]}\n```\n\nFor `channel`, the result shows that the uncovered line is line number 49.","title":"Coverage Analysis - cover - The Coverage Analysis Tool","ref":"cover_chapter.html#coverage-analysis"},{"type":"extras","doc":"Analysis of type `calls` is used to find out how many times something has been\ncalled and is represented by an integer `Calls`.\n\nIf the analysis is made on module level, the result is given as a tuple\n`{Module,Calls}`. Here `Calls` is the total number of calls to functions in the\nmodule:\n\n```erlang\n8> cover:analyse(channel, calls, module).\n{ok,{channel,12}}\n```\n\nFor `channel`, the result shows that a total of twelve calls have been made to\nfunctions in the module.\n\nIf the analysis is made on function level, the result is given as a list of\ntuples `{Function,Calls}`. Here `Calls` is the number of calls to each function:\n\n```erlang\n9> cover:analyse(channel, calls, function).\n{ok,[{{channel,start_link,0},1},\n {{channel,stop,0},1},\n {{channel,alloc,0},1},\n {{channel,free,1},1},\n {{channel,init,1},1},\n {{channel,handle_call,3},3},\n {{channel,terminate,2},1},\n {{channel,channels,0},1},\n {{channel,alloc,1},1},\n {{channel,free,2},1}]}\n```\n\nFor `channel`, the result shows that `handle_call/3` is the most called function\nin the module (three calls). All other functions have been called once.\n\nIf the analysis is made on clause level, the result is given as a list of tuples\n`{Clause,Calls}`. Here `Calls` is the number of calls to each function clause:\n\n```erlang\n10> cover:analyse(channel, calls, clause).\n{ok,[{{channel,start_link,0,1},1},\n {{channel,stop,0,1},1},\n {{channel,alloc,0,1},1},\n {{channel,free,1,1},1},\n {{channel,init,1,1},1},\n {{channel,handle_call,3,1},1},\n {{channel,handle_call,3,2},1},\n {{channel,handle_call,3,3},1},\n {{channel,terminate,2,1},1},\n {{channel,channels,0,1},1},\n {{channel,alloc,1,1},1},\n {{channel,alloc,1,2},0},\n {{channel,free,2,1},1}]}\n```\n\nFor `channel`, the result shows that all clauses have been called once, except\nthe second clause of `channel:alloc/1` which has not been called at all.\n\nFinally, if the analysis is made on line level, the result is given as a list of\ntuples `{Line,Calls}`. Here `Calls` is the number of times each line has been\nexecuted:\n\n```erlang\n11> cover:analyse(channel, calls, line).\n{ok,[{{channel,9},1},\n {{channel,12},1},\n {{channel,17},1},\n {{channel,20},1},\n {{channel,25},1},\n {{channel,28},1},\n {{channel,31},1},\n {{channel,32},1},\n {{channel,35},1},\n {{channel,36},1},\n {{channel,39},1},\n {{channel,44},1},\n {{channel,47},1},\n {{channel,49},0},\n {{channel,52},1}]}\n```\n\nFor `channel`, the result shows that all lines have been executed once, except\nline number 49 which has not been executed at all.","title":"Call Statistics - cover - The Coverage Analysis Tool","ref":"cover_chapter.html#call-statistics"},{"type":"extras","doc":"A line level calls analysis of `channel` can be written to a file using\n`cover:analyse_to_file/1`:\n\n```erlang\n12> cover:analyse_to_file(channel).\n{ok,\"channel.COVER.out\"}\n```\n\nThe function creates a copy of `channel.erl` where it for each executable line\nis specified how many times that line has been executed. The output file is\ncalled `channel.COVER.out`.\n\n```erlang\nFile generated from /Users/bjorng/git/otp/channel.erl by COVER 2024-03-20 at 13:25:04\n\n****************************************************************************\n\n | -module(channel).\n | -behaviour(gen_server).\n |\n | -export([start_link/0,stop/0]).\n | -export([alloc/0,free/1]). % client interface\n | -export([init/1,handle_call/3,terminate/2]). % callback functions\n |\n | start_link() ->\n 1..| gen_server:start_link({local,channel}, channel, [], []).\n |\n | stop() ->\n 1..| gen_server:call(channel, stop).\n |\n | %%%-Client interface functions-------------------------------------------\n |\n | alloc() ->\n 1..| gen_server:call(channel, alloc).\n |\n | free(Channel) ->\n 1..| gen_server:call(channel, {free,Channel}).\n |\n | %%%-gen_server callback functions----------------------------------------\n |\n | init(_Arg) ->\n 1..| {ok,channels()}.\n |\n | handle_call(stop, _Client, Channels) ->\n 1..| {stop,normal,ok,Channels};\n |\n | handle_call(alloc, _Client, Channels) ->\n 1..| {Ch,Channels2} = alloc(Channels),\n 1..| {reply,{ok,Ch},Channels2};\n |\n | handle_call({free,Channel}, _Client, Channels) ->\n 1..| Channels2 = free(Channel, Channels),\n 1..| {reply,ok,Channels2}.\n |\n | terminate(_Reason, _Channels) ->\n 1..| ok.\n |\n | %%%-Internal functions---------------------------------------------------\n |\n | channels() ->\n 1..| [ch1,ch2,ch3].\n |\n | alloc([Channel|Channels]) ->\n 1..| {Channel,Channels};\n | alloc([]) ->\n 0..| false.\n |\n | free(Channel, Channels) ->\n 1..| [Channel|Channels].\n```","title":"Analysis to File - cover - The Coverage Analysis Tool","ref":"cover_chapter.html#analysis-to-file"},{"type":"extras","doc":"By looking at the results from the analyses, it can be deduced that\nthe test case does not cover the case when all channels are allocated\nand `test.erl` should be extended accordingly. Incidentally, when the\ntest case is corrected a bug in `channel` will be discovered.\n\nWhen the Cover analysis is ready, Cover is stopped and all cover-compiled\nmodules are [unloaded](cover_chapter.md#loading). The code for `channel` is now\nloaded as usual from a `.beam` file in the current path.\n\n```erlang\n13> code:which(channel).\ncover_compiled\n14> cover:stop().\nok\n15> code:which(channel).\n\"./channel.beam\"\n```","title":"Conclusion - cover - The Coverage Analysis Tool","ref":"cover_chapter.html#conclusion"},{"type":"extras","doc":"","title":"Miscellaneous - cover - The Coverage Analysis Tool","ref":"cover_chapter.html#miscellaneous"},{"type":"extras","doc":"Execution of code in cover-compiled modules is slower and more memory consuming\nthan for regularly compiled modules. As the Cover database contains information\nabout each executable line in each cover-compiled module, performance decreases\nproportionally to the size and number of the cover-compiled modules.\n\nTo improve performance when analysing cover results it is possible to do\nmultiple calls to [analyse](`cover:analyse/1`) and\n[analyse_to_file](`cover:analyse_to_file/1`) at once. You can also use the\n[async_analyse_to_file](`cover:async_analyse_to_file/1`) convenience function.\n\n[](){: #lines }","title":"Performance - cover - The Coverage Analysis Tool","ref":"cover_chapter.html#performance"},{"type":"extras","doc":"Cover uses the concept of _executable lines_, which is code lines containing\nan executable expression such as a matching or a function call. A blank line or\na line containing a comment, function head or pattern in a `case` or `receive`\nstatement is not executable.\n\nIn the example below, lines number 2, 4, 6, 8, and 11 are executable lines:\n\n```erlang\n1: is_loaded(Module, Compiled) ->\n2: case get_file(Module, Compiled) of\n3: {ok,File} ->\n4: case code:which(Module) of\n5: ?TAG ->\n6: {loaded,File};\n7: _ ->\n8: unloaded\n9: end;\n10: false ->\n11: false\n12: end.\n```\n\n[](){: #loading }","title":"Executable Lines - cover - The Coverage Analysis Tool","ref":"cover_chapter.html#executable-lines"},{"type":"extras","doc":"When a module is cover-compiled, it is also loaded using the normal code loading\nmechanism of Erlang. This means that if a cover-compiled module is re-loaded\nduring a Cover session, for example using `c(Module)`, it will no longer be\ncover-compiled.\n\nUse `cover:is_compiled/1` or `code:which/1` to see whether or not a\nmodule is cover-compiled (and still loaded).\n\nWhen Cover is stopped, all cover-compiled modules are unloaded.","title":"Code Loading Mechanism - cover - The Coverage Analysis Tool","ref":"cover_chapter.html#code-loading-mechanism"},{"type":"extras","doc":"\n# cprof - The Call Count Profiler\n\n`cprof` is a profiling tool that can be used to get a picture of how often\ndifferent functions in the system are called.\n\n`cprof` uses breakpoints similar to local call trace, but containing counters,\nto collect profiling data. Therefore there is no need for special compilation of\nany module to be profiled.\n\n`cprof` presents all profiled modules in descending total call count order, and\nfor each module presents all profiled functions also in descending call count\norder. A call count limit can be specified to filter out all functions below the\nlimit.\n\nProfiling is done in the following steps:\n\n- **[`cprof:start/*`](`cprof:start/3`)** - Starts profiling with\n zeroed call counters for specified functions by setting call count\n breakpoints on them.\n\n- **`Mod:Fun()`** - Runs the code to be profiled.\n\n- **[`cprof:pause/*`](`cprof:pause/3`)** - Pauses the call counters for\n specified functions. This minimizes the impact of code running in\n the background or in the shell. Call counters are automatically\n paused when they \"hit the ceiling\" of the host machine word\n size. For a 32 bit host the maximum counter value is 2,147,483,647.\n\n- **[`cprof:analyse/*`](`cprof:analyse/2`)** - Collects call counters\n and computes the result.\n\n- **[`cprof:restart/*`](`cprof:restart/3`)** - Restarts the call\n counters from zero for specified functions. Can be used to collect a\n new set of counters without having to stop and start call count\n profiling.\n\n- **[`cprof:stop/0..3`](`cprof:stop/3`)** - Stops profiling by\n removing call count breakpoints from specified functions.\n\nFunctions can be specified as either all in the system, all in one module, all\narities of one function, one function, or all functions in all modules not yet\nloaded. BIFs cannot be call-count traced.\n\nThe analysis result can either be for a single module or for all modules. In either\ncase a call count limit can be given to filter out the functions with a call\ncount below the limit. The all modules analysis does _not_ contain the module\n`cprof` itself; the only way to analyze `cprof` is by specifying it as a single\nmodule to analyse.\n\nCall count tracing is very lightweight compared to other forms of tracing since\nno trace message has to be generated. Some measurements indicates performance\ndegradations in the vicinity of 10 percent.\n\nThe following sections show some examples of profiling with `m:cprof`.","title":"cprof - The Call Count Profiler","ref":"cprof_chapter.html"},{"type":"extras","doc":"From the Erlang shell:\n\n```erlang\n1> cprof:start(), cprof:pause(). % Stop counters just after start\n8492\n2> cprof:analyse().\n{539,\n [{shell,155,\n [{{shell,prep_check,1},55},\n {{shell,used_records,4},45},\n {{shell,used_records,1},45},\n {{shell,used_record_defs,2},1},\n {{shell,record_defs,2},1},\n {{shell,record_bindings,2},1},\n {{shell,exprs,7},1},\n {{shell,expr,4},1},\n {{shell,expand_records,2},1},\n {{shell,check_command,2},1},\n {{shell,apply_fun,3},1},\n {{shell,'-exprs/7-lc$^0/1-0-',1},1},\n {{shell,'-eval_loop/3-fun-0-',3},1}]},\n %% Information about many modules omitted.\n .\n .\n .\n %% Here is the last part.\n {erts_internal,2,[{{erts_internal,trace_pattern,3},2}]},\n {otp_internal,1,[{{otp_internal,obsolete,3},1}]},\n {maps,1,[{{maps,from_list,1},1}]},\n {erl_internal,1,[{{erl_internal,bif,3},1}]}]}\n3> cprof:analyse(cprof).\n{cprof,3,[{{cprof,tr,2},2},{{cprof,pause,0},1}]}\n4> cprof:stop().\n8586\n```\n\nThe example showed some of the background work that the shell performs just to\ninterpret the first command line.\n\nWhat is captured in this example is the part of the work the shell does while\ninterpreting the command line that occurs between the actual calls to\n[`cprof:start()`](`cprof:start/0`) and [`cprof:analyse()`](`cprof:analyse/1`).","title":"Example: Background work - cprof - The Call Count Profiler","ref":"cprof_chapter.html#example-background-work"},{"type":"extras","doc":"From the Erlang shell:\n\n```erlang\n1> cprof:start(),R=calendar:day_of_the_week(1896,4,27),cprof:pause(),R.\n1\n2> cprof:analyse(calendar).\n{calendar,9,\n [{{calendar,last_day_of_the_month1,2},1},\n {{calendar,last_day_of_the_month,2},1},\n {{calendar,is_leap_year1,1},1},\n {{calendar,is_leap_year,1},1},\n {{calendar,dy,1},1},\n {{calendar,dm,1},1},\n {{calendar,df,2},1},\n {{calendar,day_of_the_week,3},1},\n {{calendar,date_to_gregorian_days,3},1}]}\n3> cprof:stop().\n8648\n```\n\nThe example tells us that \"Aktiebolaget LM Ericsson & Co\" was registered on a\nMonday (since the return value of the first command is 1), and that the\n`calendar` module needed 9 function calls to calculate that.\n\nUsing `cprof:analyse()` in this example also shows approximately the same\nbackground work as in the first example.","title":"Example: One module - cprof - The Call Count Profiler","ref":"cprof_chapter.html#example-one-module"},{"type":"extras","doc":"Write a module:\n\n```erlang\n-module(sort).\n-export([do/1]).\n\ndo(N) ->\n cprof:stop(),\n cprof:start(),\n do(N, []).\n\ndo(0, L) ->\n R = lists:sort(L),\n cprof:pause(),\n R;\ndo(N, L) ->\n do(N-1, [rand:uniform(256)-1 | L]).\n```\n\nFrom the Erlang shell:\n\n```erlang\n1> c(sort).\n{ok,sort}\n2> rand:seed(default, 42), ok.\nok.\n3> sort:do(1000).\n[0,0,0,1,1,1,1,2,2,3,3,4,4,4,4,5,5,5,6,6,6,6,7,7,7,7,7,8,8|...]\n4> cprof:analyse().\n{13180,\n [{lists,6173,\n [{{lists,rmerge3_1,6},1045},\n {{lists,rmerge3_2,6},977},\n {{lists,split_1,5},652},\n {{lists,merge3_1,6},579},\n {{lists,merge3_2,6},577},\n {{lists,rmerge3_12_3,6},511},\n {{lists,split_1_1,6},347},\n {{lists,merge3_12_3,6},310},\n {{lists,rmerge3_21_3,6},282},\n {{lists,merge3_21_3,6},221},\n {{lists,merge2_1,4},154},\n {{lists,merge2_2,5},138},\n {{lists,reverse,2},106},\n {{lists,rmerge2_2,5},87},\n {{lists,rmergel,2},81},\n {{lists,rmerge2_1,4},75},\n {{lists,mergel,2},28},\n {{lists,keyfind,3},2},\n {{lists,sort,1},1}]},\n {rand,5000,\n [{{rand,uniform_s,2},1000},\n {{rand,uniform,1},1000},\n {{rand,seed_put,1},1000},\n {{rand,seed_get,0},1000},\n {{rand,exsss_uniform,2},1000}]},\n {erlang,1004,\n [{{erlang,put,2},1000},\n {{erlang,trace_pattern,3},2},\n {{erlang,ensure_tracer_module_loaded,2},2}]},\n {sort,1001,[{{sort,do,2},1001}]},\n {erts_internal,2,[{{erts_internal,trace_pattern,3},2}]}]}\n5> cprof:stop().\n12625\n```\n\nThe example shows some details of how `lists:sort/1` works. It used 6173\nfunction calls in module `m:lists` to complete the work.\n\nThis time, since the shell was not involved in starting and stopping `cprof`, no\nother work was done in the system during the profiling.","title":"Example: In the code - cprof - The Call Count Profiler","ref":"cprof_chapter.html#example-in-the-code"},{"type":"extras","doc":"\n# The Erlang mode for Emacs","title":"The Erlang mode for Emacs","ref":"erlang_mode_chapter.html"},{"type":"extras","doc":"The purpose of this user guide is to introduce you to the Erlang mode\nfor Emacs and gives some relevant background information of the\nfunctions and features. See also [Erlang mode reference\nmanual](../references/erlang.el.md) The purpose of the Erlang mode\nitself is to facilitate the developing process for the Erlang\nprogrammer.","title":"Purpose - The Erlang mode for Emacs","ref":"erlang_mode_chapter.html#purpose"},{"type":"extras","doc":"Basic knowledge of Emacs and Erlang/OTP.","title":"Pre-requisites - The Erlang mode for Emacs","ref":"erlang_mode_chapter.html#pre-requisites"},{"type":"extras","doc":"Two Elisp modules are included in this tool package for\nEmacs. `erlang.el` defines the actual Erlang mode and\n`erlang-start.el` makes some nice initializations.","title":"Elisp - The Erlang mode for Emacs","ref":"erlang_mode_chapter.html#elisp"},{"type":"extras","doc":"To set up the Erlang Emacs mode on a UNIX systems, edit or create the file `.emacs`\nin the your home directory.\n\nBelow is a complete example of what should be added to a user's `.emacs`\nprovided that OTP is installed in the directory `/usr/local/otp `:\n\n```text\n(setq load-path (cons \"/usr/local/otp/lib/tools- /emacs\"\nload-path))\n(setq erlang-root-dir \"/usr/local/otp\")\n(setq exec-path (cons \"/usr/local/otp/bin\" exec-path))\n(require 'erlang-start)\n```","title":"Setup on UNIX - The Erlang mode for Emacs","ref":"erlang_mode_chapter.html#setup-on-unix"},{"type":"extras","doc":"To set up the Erlang Emacs mode on a Windows systems, edit/create the file\n`.emacs`, the location of the file depends on the configuration of the system.\nIf the _HOME_ environment variable is set, Emacs will look for the `.emacs` file\nin the directory indicated by the `HOME` variable. If `HOME` is not set, Emacs\nwill look for the `.emacs` file in `C:\\ `.\n\nBelow is a complete example of what should be added to a user's `.emacs`\nprovided that OTP is installed in the directory `C:\\Program Files\\Erlang OTP`:\n\n```lisp\n(setq load-path (cons \"C:/Program Files/Erlang OTP/lib/tools- /emacs\"\nload-path))\n(setq erlang-root-dir \"C:/Program Files/Erlang OTP\")\n(setq exec-path (cons \"C:/Program Files/Erlang OTP/bin\" exec-path))\n(require 'erlang-start)\n```\n\n> #### Note {: .info }\n>\n> In `.emacs`, the slash character (`/`) can be used as path separator. But if you\n> decide to use the backslash character (`\\`), note that backslashes have to be\n> doubled, since they are treated as escape characters by Emacs.","title":"Setup on Windows - The Erlang mode for Emacs","ref":"erlang_mode_chapter.html#setup-on-windows"},{"type":"extras","doc":"The \"Oxford Advanced Learners Dictionary of Current English\" says the following\nabout the word \"indent\":\n\n> \"start (a line of print or writing) farther from the margin than the others\".\n\nThe Erlang mode does, of course, provide this feature. The layout used is based\non the common use of the language.\n\nIt is strongly recommended to use this feature and avoid to indent lines in a\nnonstandard way. Some motivations are:\n\n- Code using the same layout is easy to read and maintain.\n- Since several features of Erlang mode is based on the standard layout they\n might not work correctly if a nonstandard layout is used.\n\nThe indentation features can be used to reindent large sections of a file. If\nsome lines use nonstandard indentation they will be reindented.","title":"Indentation - The Erlang mode for Emacs","ref":"erlang_mode_chapter.html#indentation"},{"type":"extras","doc":"- _`M-x erlang-mode RET`_ \\- This command activates the Erlang major mode for\n the current buffer. When this mode is active the mode line contain the word\n \"Erlang\".\n\nWhen the Erlang mode is correctly installed, it is automatically activated when\na file ending in `.erl` or `.hrl` is opened in Emacs.\n\nWhen a file is saved the name in the `-module().` line is checked against the\nfile name. Should they mismatch Emacs can change the module specifier so that it\nmatches the file name. By default, the user is asked before the change is\nperformed.\n\nAn \"electric\" command is a character that in addition to just inserting the\ncharacter performs some type of action. For example the `;` character is typed\nin a situation where is ends a function clause a new function header is\ngenerated. The electric commands are as follows:\n\n- `erlang-electric-comma` \\- Insert a comma character and possibly a new\n indented line.\n- `erlang-electric-semicolon` \\- Insert a semicolon character and possibly a\n prototype for the next line.\n- `erlang-electric-gt` \\- Insert a `>` character and possible a new indented line.\n\nTo disable all electric commands set the variable `erlang-electric-commands` to\nthe empty list. In short, place the following line in your `.emacs`\\-file:\n\n```text\n(setq erlang-electric-commands '())\n```","title":"Editing - The Erlang mode for Emacs","ref":"erlang_mode_chapter.html#editing"},{"type":"extras","doc":"It is possible for Emacs to use colors when displaying a buffer. By \"syntax\nhighlighting\", we mean that syntactic components, for example keywords and\nfunction names, will be colored.\n\nThe basic idea of syntax highlighting is to make the structure of a program\nclearer. For example, the highlighting will make it easier to spot simple bugs.\nHave not you ever written a variable in lower-case only? With syntax\nhighlighting a variable will colored while atoms will be shown with the normal\ntext color.","title":"Syntax highlighting - The Erlang mode for Emacs","ref":"erlang_mode_chapter.html#syntax-highlighting"},{"type":"extras","doc":"Tags is a standard Emacs package used to record information about source files\nin large development projects. In addition to listing the files of a project, a\ntags file normally contains information about all functions and variables that\nare defined. By far, the most useful command of the tags system is its ability\nto find the definition of functions in any file in the project. But the Tags\nsystem is not limited to this feature, for example, it is possible to do a text\nsearch in all files in a project, or to perform a project-wide search and\nreplace.\n\nIn order to use the Tags system a file named `TAGS` must be created. The file\ncan be seen as a database over all functions, records, and macros in all files\nin the project. The `TAGS` file can be created using two different methods for\nErlang. The first is the standard Emacs utility \"etags\", the second is by using\nthe Erlang module `tags`.","title":"Tags - The Erlang mode for Emacs","ref":"erlang_mode_chapter.html#tags"},{"type":"extras","doc":"`etags` is a program that is part of the Emacs distribution. It is normally\nexecuted from a command line, like a Unix shell or a DOS box.\n\nThe `etags` program of fairly modern versions of Emacs and XEmacs has native\nsupport for Erlang. To check if your version does include this support, issue\nthe command `etags --help` at a the command line prompt. At the end of the help\ntext there is a list of supported languages. Unless Erlang is a member of this\nlist I suggest that you should upgrade to a newer version of Emacs.\n\nAs seen in the help text — unless you have not upgraded your Emacs yet — `etags`\nassociate the file extensions `.erl` and `.hrl` with Erlang.\n\nBasically, the `etags` utility is run using the following form:\n\n```bash\netags file1.erl file2.erl\n```\n\nThis will create a file named `TAGS` in the current directory.\n\nThe `etags` utility can also read a list of files from its standard input by\nsupplying a single dash in place of the file names. This feature is useful when\na project consists of a large number of files. The standard UNIX command `find`\ncan be used to generate the list of files, for example:\n\n```bash\nfind . -name \"*.[he]rl\" -print | etags -\n```\n\nThe above line will create a `TAGS` file covering all the Erlang source files in\nthe current directory, and in the subdirectories below.\n\nSee the GNU Emacs Manual and the etags man page for more info.","title":"Etags - The Erlang mode for Emacs","ref":"erlang_mode_chapter.html#etags"},{"type":"extras","doc":"The look and feel on an Erlang shell inside Emacs should be the same as in a\nnormal Erlang shell. There is just one major difference, the cursor keys will\nactually move the cursor around just like in any normal Emacs buffer. The\ncommand line history can be accessed by the following commands:\n\n- *`C-up `*or _`M-p `_(`comint-previous-input`) - Move to the previous line in\n the input history.\n- *`C-down `*or _`M-n `_(`comint-next-input`) - Move to the next line in the\n input history.\n\nIf the Erlang shell buffer would be killed the command line history is saved to\na file. The command line history is automatically retrieved when a new Erlang\nshell is started.","title":"Shell - The Erlang mode for Emacs","ref":"erlang_mode_chapter.html#shell"},{"type":"extras","doc":"The classic edit-compile-bugfix cycle for Erlang is to edit the source file in\nan editor, save it to a file and switch to an Erlang shell. In the shell the\ncompilation command is given. Should the compilation fail you have to bring out\nthe editor and locate the correct line.\n\nWith the Erlang editing mode the entire edit-compile-bugfix cycle can be\nperformed without leaving Emacs. Emacs can order Erlang to compile a file and it\ncan parse the error messages to automatically place the point on the erroneous\nlines.","title":"Compilation - The Erlang mode for Emacs","ref":"erlang_mode_chapter.html#compilation"},{"type":"extras","doc":"\n# fprof - The File Trace Profiler\n\n`m:fprof` is a profiling tool that can be used to get a picture of how much\nprocessing time different functions consumes and in which processes.\n\n`fprof` uses tracing with timestamps to collect profiling data. Therefore there\nis no need for special compilation of any module to be profiled.\n\n`fprof` presents wall clock times from the host machine OS, with the assumption\nthat OS scheduling will randomly load the profiled functions in a fair way. Both\n_own time_, that is, the time used by a function for its own execution, and\n_accumulated time_, that is, execution time including called functions.\n\nProfiling is essentially done in 3 steps:\n\n- Tracing to a file.\n\n- Profiling: the trace file is read and raw profile data is collected\n into an internal RAM storage on the node. During this step the trace data may\n be dumped in text format to file or console.\n\n- Analysing: the raw profile data is sorted and dumped in text format\n either to file or console.\n\nSince `fprof` stores trace data to a file, the runtime performance degradation is\nminimized, but still far from negligible, especially for programs that themselves\nuse the filesystem heavily. Where the trace file is placed is also important;\non Unix systems `/tmp` is usually a good choice, while any\nnetwork-mounted disk is a bad choice.\n\n`fprof` can also skip the file step and trace to a tracer process of its own that\ndoes the profiling in runtime.\n\nThe following sections show some examples of how to profile with `m:fprof`.","title":"fprof - The File Trace Profiler","ref":"fprof_chapter.html"},{"type":"extras","doc":"If you can edit and recompile the source code, it is convenient to\ninsert [`fprof:trace(start)`](`fprof:trace/1`) and\n[`fprof:trace(stop)`](`fprof:trace/1`) before and after the code to be profiled.\nAll spawned processes are also traced. If you want some other filename than\nthe default, use [`fprof:trace(start, \"my_fprof.trace\")`](`fprof:trace/2`).\n\nWhen execution is finished, the raw profile can be processed using\n[`fprof:profile()`](`fprof:profile/0`),\nor [`fprof:profile(file, \"my_fprof.trace\")`](`fprof:profile/2`)\nfor a non-default filename.\n\nFinally create an informative table dumped on the console with\n[`fprof:analyse()`](`fprof:analyse/0`), or on file with\n[`fprof:analyse(dest, [])`](`fprof:analyse/2`), or\n[`fprof:analyse([{dest, \"my_fprof.analysis\"}, {cols, 120}])`](`fprof:analyse/1`)\nfor a wider listing of a non-default filename.","title":"Profiling from the source code - fprof - The File Trace Profiler","ref":"fprof_chapter.html#profiling-from-the-source-code"},{"type":"extras","doc":"If you have one function that does the task that you want to profile, and the\nfunction returns when the profiling should stop, it is convenient to use\n[`fprof:apply(Module, Function, Args)`](`fprof:apply/3`) for the tracing step.\n\nIf the tracing should continue after the function has returned, for\nexample if it is a start function that spawns processes to be\nprofiled, use\n[`fprof:apply(M, F, Args, [continue | OtherOpts])`](`fprof:apply/4`).\nThe tracing has to be stopped at a suitable later time using\n[`fprof:trace(stop)`](`fprof:trace/1`).","title":"Profiling a function - fprof - The File Trace Profiler","ref":"fprof_chapter.html#profiling-a-function"},{"type":"extras","doc":"It is also possible to trace immediately into the profiling process that creates\nthe raw profile data, that is to short circuit the tracing and profiling steps\nso that the filesystem is not used for tracing.\n\nDo something like this:\n\n```erlang\n{ok, Tracer} = fprof:profile(start),\nfprof:trace([start, {tracer, Tracer}]),\n%% Run code to profile\nfprof:trace(stop);\n```\n\nThis puts less load on the filesystem, but much more load on the Erlang runtime\nsystem.","title":"Immediate profiling - fprof - The File Trace Profiler","ref":"fprof_chapter.html#immediate-profiling"},{"type":"extras","doc":"\n# lcnt - The Lock Profiler\n\nInternally in the Erlang runtime system locks are used to protect resources from\nbeing updated from multiple threads in a fatal way. Locks are necessary to\nensure that the runtime system works properly, but it also introduces\nlimitations, namely _lock contention_ and _locking overhead_.\n\nWith lock contention we mean when one thread locks a resource, and another\nthread (or threads) tries to acquire the same resource at the same time. The\nlock will deny the other thread access to the resource and the thread will be\nblocked from continuing its execution. The second thread has to wait until the\nfirst thread has completed its access to the resource and unlocked it. The\n`lcnt` tool measures these lock conflicts.\n\nLocks have an inherent cost in execution time and memory space. It takes time to\ninitialize, destroy, acquire, or release locks. To decrease lock contention\nit is sometimes necessary to use finer-grained locking strategies. This\nusually also increases the locking overhead. Hence there is a tradeoff between\nlock contention and overhead. In general, lock contention increases with the\nnumber of threads running concurrently.\n\nThe `lcnt` tool does not measure locking overhead.","title":"lcnt - The Lock Profiler","ref":"lcnt_chapter.html"},{"type":"extras","doc":"For investigation of locks in the emulator we use an internal tool called `lcnt`\n(short for lock-count). The VM needs to be compiled with this option enabled. To\ncompile a lock-counting VM along with a normal VM, use:\n\n```text\ncd $ERL_TOP\n./configure --enable-lock-counter\nmake\n```\n\nStart the lock-counting VM like this:\n\n```text\n$ERL_TOP/bin/erl -emu_type lcnt\n```\n\nTo verify that lock counting is enabled check that `[lock-counting]` appears in\nthe status text when the VM is started.\n\n```text\nErlang/OTP 27 [erts-15.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [lock-counting]\n```","title":"Enabling lock-counting - lcnt - The Lock Profiler","ref":"lcnt_chapter.html#enabling-lock-counting"},{"type":"extras","doc":"Once you have a lock counting enabled VM the module `lcnt` can be used. The\nmodule is intended to be used from the current running nodes shell. To access\nremote nodes use [`lcnt:clear(Node)`](`lcnt:clear/1`) and\n[`lcnt:collect(Node)`](`lcnt:collect/1`).\n\nAll locks are continuously monitored and its statistics updated. Use\n[`lcnt:clear/0`](`lcnt:clear/1`) to initially clear all counters\nbefore running any specific tests. This command will also reset the\ninternal duration timer.\n\nTo retrieve lock statistics information, use\n[`lcnt:collect/0,1`](`lcnt:collect/1`). The collect operation will\nstart a `lcnt` server if it not already started. All collected data\nwill be stored in an Erlang term and uploaded to the server along with\nthe duration time. The duration time is the time between\n[`lcnt:clear/0,1`](`lcnt:clear/1`) and\n[`lcnt:collect/0,1`](`lcnt:collect/1`).\n\nOnce the data is collected to the server it can be filtered, sorted, and printed\nin multiple ways.","title":"Getting started - lcnt - The Lock Profiler","ref":"lcnt_chapter.html#getting-started"},{"type":"extras","doc":"Here is an example of running the [Big Bang Benchmark](#the-big-bang-benchmark):\n\n```text\nErlang/OTP 27 [erts-15.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [lock-counting]\n\nEshell V15.0 (press Ctrl+G to abort, type help(). for help)\n1> lcnt:rt_opt({copy_save, true}).\nfalse\n2> lcnt:clear(), big:bang(1000), lcnt:collect().\nok\n3> lcnt:conflicts().\n lock id #tries #collisions collisions [%] time [us] duration [%]\n ----- --- ------- ------------ --------------- ---------- -------------\n run_queue 10 590799 8875 1.5022 37906 2.2167\n proc_msgq 1048 2515180 4667 0.1856 20962 1.2258\n proc_main 1048 2195317 23775 1.0830 1664 0.0973\nok\n```\n\nAnother way to to profile a specific function is to use `lcnt:apply/3` or\n`lcnt:apply/1`, which calls `lcnt:clear/0` before calling the function and\n`lcnt:collect/0` after its invocation. This method should only be used in\nmicro-benchmarks since it sets `copy_save` to `true` for the duration of the\nfunction call, which may cause the emulator to run out of memory if attempted\nunder load.\n\n```text\n1> lcnt:apply(fun() -> big:bang(1000) end).\n1845411\n2> lcnt:conflicts().\n lock id #tries #collisions collisions [%] time [us] duration [%]\n ----- --- ------- ------------ --------------- ---------- -------------\n run_queue 10 582789 9237 1.5850 41929 2.2633\n proc_msgq 1047 2494483 4731 0.1897 11173 0.6031\n proc_main 1047 2192806 23283 1.0618 1500 0.0810\nok\n```\n\nThe process locks are sorted after its class like all other locks. It is\nconvenient to look at specific processes and ports as classes. We can do this by\nswapping class and class identifiers with `lcnt:swap_pid_keys/0`.\n\n```text\n3> lcnt:swap_pid_keys().\nok\n4> lcnt:conflicts([{print, [name, tries, ratio, time]}]).\n lock #tries collisions [%] time [us]\n ----- ------- --------------- ----------\n run_queue 582789 1.5850 41929\n 5692 0.5095 484\n 4989 0.4410 393\n 6319 2.1839 284\n 6077 1.9747 198\n 5071 1.3015 192\n 5846 1.7106 186\n 6305 1.2054 179\n 5820 1.2715 176\n 6329 1.4852 168\n 5172 0.8701 167\n 5306 0.4146 166\n 5838 1.9870 160\n 6346 1.5443 143\n 5542 0.4331 141\n 5260 0.2662 137\n 5610 0.9447 127\n 5354 0.5230 118\n 5845 0.9239 115\n 5140 0.7782 108\nok\n```","title":"Example of usage - lcnt - The Lock Profiler","ref":"lcnt_chapter.html#example-of-usage"},{"type":"extras","doc":"From the Erlang shell:\n\n```erlang\nErlang/OTP 27 [erts-15.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [lock-counting]\n\nEshell V15.0 (press Ctrl+G to abort, type help(). for help)\n1> Conf = [{db_nodes, [node()]}, {driver_nodes, [node()]}, {replica_nodes, [node()]},\n {n_drivers_per_node, 10}, {n_branches, 1000}, {n_accounts_per_branch, 10},\n {replica_type, ram_copies}, {stop_after, 60000}, {reuse_history_id, true}], ok.\nok\n2> mnesia_tpcb:init([{use_running_mnesia, false}|Conf]).\n .\n .\n .\nignore\n```\n\nInitial configuring of the benchmark is done. It is time to profile the actual\nMnesia benchmark:\n\n```erlang\n3> lcnt:apply(fun() -> {ok,{time, Tps,_,_,_,_}} = mnesia_tpcb:run([{use_running_mnesia,\n true}|Conf]), Tps/60 end).\n .\n .\n .\n50204.666666666664\n```\n\nThe benchmark runs for 60 seconds (followed by verification and\nanalysis), and then returns the number of transactions per seconds.\n\n```text\n4> lcnt:swap_pid_keys().\nok\n5> lcnt:conflicts().\n lock id #tries #collisions collisions [%] time [us] duration [%]\n ----- --- ------- ------------ --------------- ---------- -------------\n run_queue 10 89329288 3227515 3.6131 5018119 8.3606\n mnesia_locker 5 64793236 8231226 12.7038 98654 0.1644\n db_tab 3012324 416847817 140631 0.0337 75308 0.1255\n 5 14499900 36934 0.2547 4878 0.0081\n 5 14157504 35797 0.2528 4727 0.0079\n 5 14194934 34510 0.2431 4403 0.0073\n 5 14149447 35326 0.2497 4150 0.0069\n 5 14316525 35675 0.2492 4116 0.0069\n 5 14241146 35358 0.2483 4101 0.0068\n 5 14224491 35182 0.2473 4094 0.0068\n 5 14190075 35328 0.2490 4075 0.0068\n 5 14308906 35031 0.2448 3896 0.0065\n 5 14457330 36182 0.2503 3856 0.0064\n mnesia_tm 5 28149333 179294 0.6369 1057 0.0018\n pix_lock 1024 132 1 0.7576 549 0.0009\n 5 17 2 11.7647 87 0.0001\n 5 1335 6 0.4494 1 0.0000\nok\n```\n\nThe `id` header represents the number of unique identifiers under a\nclass when the option `{combine, true}` is used (which is enabled by\ndefault). It will otherwise show the specific identifier. The `db_tab`\nlisting shows 3,012,324 unique locks, which is one for each ETS table\ncreated. Mnesia creates one ETS table for each transaction.\n\nThe listing shows also shows that the `mnesia_locker` process has highly contended locks.\nUsing `lcnt:inspect/1` more information can be displayed for that process:\n\n```text\n6> lcnt:inspect(mnesia_locker).\n lock id #tries #collisions collisions [%] time [us] duration [%] histogram [log2(us)]\n ----- --- ------- ------------ --------------- ---------- ------------- ---------------------\n mnesia_locker proc_main 19853372 7591248 38.2366 80550 0.1342 |. ...X........ |\n mnesia_locker proc_msgq 30917225 639627 2.0688 17126 0.0285 |. .X......... |\n mnesia_locker proc_status 9348426 351 0.0038 978 0.0016 | .xxX. . |\n mnesia_locker proc_btm 0 0 0.0000 0 0.0000 | |\n mnesia_locker proc_trace 4674213 0 0.0000 0 0.0000 | |\nok\n```\n\nListing the conflicts without class combiner:\n\n```text\n7> lcnt:conflicts([{combine, false}, {print, [name, id, tries, ratio, time]}]).\n lock id #tries collisions [%] time [us]\n ----- --- ------- --------------- ----------\n run_queue 2 31075249 3.5676 1728233\n run_queue 1 29738521 3.6348 1683219\n run_queue 3 27912150 3.6429 1573593\n mnesia_locker proc_main 19853372 38.2366 80550\n db_tab mnesia_transient_decision 3012281 2.5675 55104\n run_queue 4 512077 3.7041 29486\n mnesia_locker proc_msgq 30917225 2.0688 17126\n db_tab account 6044562 0.3599 7909\n db_tab branch 6026659 0.3132 5654\n db_tab teller 6044659 0.2684 4727\n proc_main 3207155 0.7178 3726\n proc_main 3138532 0.7485 3593\n proc_main 3133180 0.7156 3547\n proc_main 3165128 0.7609 3517\n proc_main 3128838 0.7525 3477\n proc_main 3137627 0.7559 3433\n proc_main 3144886 0.7509 3425\n proc_main 3149315 0.7487 3372\n proc_main 3196546 0.7591 3310\n proc_main 3164333 0.7483 3309\nok\n```\n\nIn this scenario the locks for the scheduler's run queues dominate the time waiting\nfor locks. The most contended lock for ETS tables is for the `mnesia_transient_decision`\nETS table.\n\nHere is how to show the information for the ETS tables.\n\n```text\n8> lcnt:inspect(db_tab, [{print, [name, id, tries, colls, ratio, duration]}]).\n lock id #tries #collisions collisions [%] duration [%]\n ----- --- ------- ------------ --------------- -------------\n db_tab mnesia_transient_decision 3012281 77341 2.5675 0.0918\n db_tab account 6044562 21753 0.3599 0.0132\n db_tab branch 6026659 18873 0.3132 0.0094\n db_tab teller 6044659 16221 0.2684 0.0079\n db_tab history 3012281 4005 0.1330 0.0022\n db_tab mnesia_stats 3071064 2437 0.0794 0.0010\n db_tab mnesia_trans_store 15 0 0.0000 0.0000\n db_tab mnesia_decision 3012281 0 0.0000 0.0000\n db_tab schema 0 0 0.0000 0.0000\n db_tab dets 0 0 0.0000 0.0000\n db_tab dets_owners 0 0 0.0000 0.0000\n db_tab dets_registry 0 0 0.0000 0.0000\n db_tab mnesia_lock_queue 36154974 0 0.0000 0.0000\n db_tab mnesia_sticky_locks 12108098 0 0.0000 0.0000\n db_tab mnesia_tid_locks 27176721 0 0.0000 0.0000\n db_tab mnesia_held_locks 48321870 0 0.0000 0.0000\n db_tab mnesia_subscr 0 0 0.0000 0.0000\n db_tab mnesia_gvar 102680683 1 0.0000 0.0000\n db_tab user_functions 0 0 0.0000 0.0000\n db_tab shell_records 0 0 0.0000 0.0000\nok\n```","title":"Example with Mnesia Transaction Benchmark - lcnt - The Lock Profiler","ref":"lcnt_chapter.html#example-with-mnesia-transaction-benchmark"},{"type":"extras","doc":"Typically high `time` values are bad and this is often the thing to look for.\nHowever, one should also look for high lock acquisition frequencies (`#tries`)\nsince locks generate overhead and because high frequency could become\nproblematic if they begin to have conflicts even if it is not shown in a\nparticular test.","title":"Deciphering the output - lcnt - The Lock Profiler","ref":"lcnt_chapter.html#deciphering-the-output"},{"type":"extras","doc":"```erlang\n-module(big).\n-export([bang/1]).\n\npinger([], [], true) ->\n receive\n\t{procs, Procs, ReportTo} ->\n\t pinger(Procs, [], ReportTo)\n end;\npinger([], [], false) ->\n receive {ping, From} -> From ! {pong, self()} end,\n pinger([],[],false);\npinger([], [], ReportTo) ->\n ReportTo ! {done, self()},\n pinger([],[],false);\npinger([], [Po|Pos] = Pongers, ReportTo) ->\n receive\n\t{ping, From} ->\n\t From ! {pong, self()},\n\t pinger([], Pongers, ReportTo);\n\t{pong, Po} ->\n\t pinger([], Pos, ReportTo)\n end;\npinger([Pi|Pis], Pongers, ReportTo) ->\n receive {ping, From} -> From ! {pong, self()}\n after 0 -> ok\n end,\n Pi ! {ping, self()},\n pinger(Pis, [Pi|Pongers], ReportTo).\n\nspawn_procs(N) when N =< 0 ->\n [];\nspawn_procs(N) ->\n [spawn_link(fun () -> pinger([],[],true) end) | spawn_procs(N-1)].\n\nsend_procs([], Msg) ->\n Msg;\nsend_procs([P|Ps], Msg) ->\n P ! Msg,\n send_procs(Ps, Msg).\n\nreceive_msgs([]) ->\n ok;\nreceive_msgs([M|Ms]) ->\n receive\n\tM ->\n\t receive_msgs(Ms)\n end.\n\nbang(N) when integer(N) ->\n Procs = spawn_procs(N),\n RMsgs = lists:map(fun (P) -> {done, P} end, Procs),\n Start = now(),\n send_procs(Procs, {procs, Procs, self()}),\n receive_msgs(RMsgs),\n Stop = now(),\n lists:foreach(fun (P) -> exit(P, normal) end, Procs),\n timer:now_diff(Stop, Start).\n```","title":"The Big Bang Benchmark - lcnt - The Lock Profiler","ref":"lcnt_chapter.html#the-big-bang-benchmark"},{"type":"extras","doc":"[LCNT Reference Manual](`m:lcnt`)","title":"See Also - lcnt - The Lock Profiler","ref":"lcnt_chapter.html#see-also"},{"type":"extras","doc":"\n# Xref - The Cross Reference Tool\n\nXref is a cross reference tool that can be used for finding dependencies between\nfunctions, modules, applications and releases. It does so by analyzing the\ndefined functions and the function calls.\n\nIn order to make Xref easy to use, there are predefined analyses that perform\nsome common tasks. Typically, a module or a release can be checked for calls to\nundefined functions. For the somewhat more advanced user there is a small but\nflexible language that can be used for selecting parts of the analyzed\nsystem and for doing some simple graph analyses on selected calls.\n\nThe following sections show some features of Xref, beginning with a module check\nand a predefined analysis. Then follow examples that can be skipped on the first\nreading; not all of the concepts used are explained, and it is assumed that the\n[reference manual](`m:xref`) has been at least skimmed.","title":"Xref - The Cross Reference Tool","ref":"xref_chapter.html"},{"type":"extras","doc":"Assume we want to check the following module:\n\n```erlang\n-module(my_module).\n\n-export([t/1]).\n\nt(A) ->\n my_module:t2(A).\n\nt2(_) ->\n true.\n```\n\nCross reference data are read from BEAM files, so the first step when checking\nan edited module is to compile it:\n\n```erlang\n1> c(my_module, debug_info).\n./my_module.erl:10: Warning: function t2/1 is unused\n{ok, my_module}\n```\n\nThe `debug_info` option ensures that the BEAM file contains debug information,\nwhich makes it possible to find unused local functions.\n\nThe module can now be checked for calls to\n[deprecated functions](`m:xref#deprecated_function`), calls to\n[undefined functions](`m:xref#undefined_function`), and for unused local\nfunctions:\n\n```erlang\n2> xref:m(my_module)\n[{deprecated,[]},\n {undefined,[{{my_module,t,1},{my_module,t2,1}}]},\n {unused,[{my_module,t2,1}]}]\n```\n\n`m/1` is also suitable for checking that the BEAM file of a module that is about\nto be loaded into a running a system does not call any undefined functions. In\neither case, the code path of the code server (see the module `code`) is used\nfor finding modules that export externally called functions not exported by the\nchecked module itself, so called [library modules](`m:xref#library_module`).","title":"Module Check - Xref - The Cross Reference Tool","ref":"xref_chapter.html#module-check"},{"type":"extras","doc":"In the last example the module to analyze was given as an argument to `m/1`, and\nthe code path was (implicitly) used as [library path](`m:xref#library_path`). In\nthis example an [xref server](`m:xref#xref_server`) will be used, which makes it\npossible to analyze applications and releases, and also to select the library\npath explicitly.\n\nEach Xref server is referred to by a unique name. The name is given when\ncreating the server:\n\n```erlang\n1> xref:start(s).\n{ok,<0.27.0>}\n```\n\nNext the system to be analyzed is added to the Xref server. Here the system will\nbe OTP, so no library path will be needed. Otherwise, when analyzing a system\nthat uses OTP, the OTP modules are typically made library modules by setting the\nlibrary path to the default OTP code path (or to `code_path`, see the\n[reference manual](`m:xref#code_path`)). By default, the names of read BEAM\nfiles and warnings are output when adding analyzed modules, but these messages\ncan be avoided by setting default values of some options:\n\n```erlang\n2> xref:set_default(s, [{verbose,false}, {warnings,false}]).\nok\n3> xref:add_release(s, code:lib_dir(), {name, otp}).\n{ok,otp}\n```\n\n`add_release/3` assumes that all subdirectories of the library directory\nreturned by [`code:lib_dir()`](`code:lib_dir/0`) contain applications;\nthe effect is that of reading all BEAM files for the application.\n\nIt is now easy to check the release for calls to undefined functions:\n\n```erlang\n4> xref:analyze(s, undefined_function_calls).\n{ok, [...]}\n```\n\nWe can now continue with further analyses, or we can delete the Xref server:\n\n```erlang\n5> xref:stop(s).\n```\n\nThe check for calls to undefined functions is an example of a predefined\nanalysis, probably the most useful one. Other examples are the analyses that\nfind unused local functions, or functions that call some given functions. See\nthe [analyze/2,3](`m:xref#analyze`) functions for a complete list of predefined\nanalyses.\n\nEach predefined analysis is a shorthand for a [query](`m:xref#query`), a\nsentence of a tiny language providing cross reference data as values of\n[predefined variables](`m:xref#predefined_variable`). The check for calls to\nundefined functions can thus be stated as a query:\n\n```erlang\n4> xref:q(s, \"(XC - UC) || (XU - X - B)\").\n{ok,[...]}\n```\n\nThe query asks for the restriction of external calls except the unresolved calls\nto calls to functions that are externally used but neither exported nor built-in\nfunctions (the `||` operator restricts the used functions while the `|` operator\nrestricts the calling functions). The `-` operator returns the difference of two\nsets, and the `+` operator to be used below returns the union of two sets.\n\nThe relationships between the predefined variables `XU`, `X`, `B` and a few\nothers are worth elaborating upon. The reference manual mentions two ways of\nexpressing the set of all functions, one that focuses on how they are defined:\n`X + L + B + U`, and one that focuses on how they are used: `UU + LU + XU`. The\nreference also mentions some [facts](`m:xref#simple_facts`) about the variables:\n\n- `F` is equal to `L + X` (the defined functions are the local functions and the\n external functions);\n- `U` is a subset of `XU` (the unknown functions are a subset of the externally\n used functions since the compiler ensures that locally used functions are\n defined);\n- `B` is a subset of `XU` (calls to built-in functions are always external by\n definition, and unused built-in functions are ignored);\n- `LU` is a subset of `F` (the locally used functions are either local functions\n or exported functions, again ensured by the compiler);\n- `UU` is equal to `F - (XU + LU)` (the unused functions are defined functions\n that are neither used externally nor locally);\n- `UU` is a subset of `F` (the unused functions are defined in analyzed\n modules).\n\nUsing these facts, the two small circles in the picture below can be combined.\n\n![Definition and use of functions](assets/venn1.gif \"Definition and use of functions\")\n\nIt is often clarifying to mark the variables of a query in such a circle. This\nis illustrated in the picture below for some of the predefined analyses. Note\nthat local functions used by local functions only are not marked in the\n`locals_not_used` circle.[](){: #venn2 }\n\n![Some predefined analyses as subsets of all functions](assets/venn2.gif \"Some predefined analyses as subsets of all functions\")","title":"Predefined Analysis - Xref - The Cross Reference Tool","ref":"xref_chapter.html#predefined-analysis"},{"type":"extras","doc":"The module check and the predefined analyses are useful, but limited. Sometimes\nmore flexibility is needed, for instance one might not need to apply a graph\nanalysis on all calls, but some subset will do equally well. That flexibility is\nprovided with a simple language. Below are some expressions of the language with\ncomments, focusing on elements of the language rather than providing useful\nexamples. The analyzed system is assumed to be OTP, so in order to run the\nqueries, first evaluate these calls:\n\n```erlang\nxref:start(s).\nxref:add_release(s, code:root_dir()).\n```\n\n- **`xref:q(s, \"(Fun) xref : Mod\").`** - All functions of the `xref` module.\n\n- **`xref:q(s, \"xref : Mod * X\").`** - All exported functions of the `xref`\n module. The first operand of the intersection operator `*` is implicitly\n converted to the more special type of the second operand.\n\n- **`xref:q(s, \"(Mod) tools\").`** - All modules of the Tools application.\n\n- **`xref:q(s, '\"xref_.*\" : Mod').`** - All modules with a name beginning with\n `xref_`.\n\n- **`xref:q(s, \"# E | X \").`** - Number of calls from exported functions.\n\n- **`xref:q(s, \"XC || L \").`** - All external calls to local functions.\n\n- **`xref:q(s, \"XC * LC\").`** - All calls that have both an external and a local\n version.\n\n- **`xref:q(s, \"(LLin) (LC * XC)\").`** - The lines where the local calls of the\n last example are made.\n\n- **`xref:q(s, \"(XLin) (LC * XC)\").`** - The lines where the external calls of\n the example before last are made.\n\n- **`xref:q(s, \"XC * (ME - strict ME)\").`** - External calls within some module.\n\n- **`xref:q(s, \"E ||| kernel\").`** - All calls within the Kernel application.\n\n- **`xref:q(s, \"closure E | kernel || kernel\").`** - All direct and indirect\n calls within the Kernel application. Both the calling and the used functions\n of indirect calls are defined in modules of the kernel application, but it is\n possible that some functions outside the kernel application are used by\n indirect calls.\n\n- **`xref:q(s, \"{toolbar,debugger}:Mod of ME\").`** - A chain of module calls\n from `toolbar` to `debugger`, if there is such a chain, otherwise `false`. The\n chain of calls is represented by a list of modules, `toolbar` being the first\n element and `debugger`the last element.\n\n- **`xref:q(s, \"closure E | toolbar:Mod || debugger:Mod\").`** - All (in)direct\n calls from functions in `toolbar` to functions in `debugger`.\n\n- **`xref:q(s, \"(Fun) xref -> xref_base\").`** - All function calls from `xref`\n to `xref_base`.\n\n- **`xref:q(s, \"E * xref -> xref_base\").`** - Same interpretation as last\n expression.\n\n- **`xref:q(s, \"E || xref_base | xref\").`** - Same interpretation as last\n expression.\n\n- **`xref:q(s, \"E * [xref -> lists, xref_base -> digraph]\").`** - All function\n calls from `xref` to `lists`, and all function calls from `xref_base` to\n `digraph`.\n\n- **`xref:q(s, \"E | [xref, xref_base] || [lists, digraph]\").`** - All function\n calls from `xref` and `xref_base` to `lists` and `digraph`.\n\n- **`xref:q(s, \"components EE\").`** - All strongly connected components of the\n Inter Call Graph. Each component is a set of exported or unused local\n functions that call each other (in)directly.\n\n- **`xref:q(s, \"X * digraph * range (closure (E | digraph) | (L * digraph))\").`** -\n All exported functions of the `digraph` module used (in)directly by some\n function in `digraph`.\n\n- **`xref:q(s, \"L * yeccparser:Mod - range (closure (E |`**\n\n- **`yeccparser:Mod) | (X * yeccparser:Mod))\").`** - The interpretation is left\n as an exercise.","title":"Expressions - Xref - The Cross Reference Tool","ref":"xref_chapter.html#expressions"},{"type":"extras","doc":"The list [representation of graphs](`m:xref#representation`) is used analyzing\ndirect calls, while the `digraph` representation is suited for analyzing\nindirect calls. The restriction operators (`|`, `||` and `|||`) are the only\noperators that accept both representations. This means that in order to analyze\nindirect calls using restriction, the `closure` operator (which creates the\n`digraph` representation of graphs) has to be explicitly applied.\n\nAs an example of analyzing indirect calls, the following Erlang function tries\nto answer the question: if we want to know which modules are used indirectly by\nsome module(s), is it worth while using the\n[function graph](`m:xref#call_graph`) rather than the module graph? Recall that\na module M1 is said to call a module M2 if there is some function in M1 that\ncalls some function in M2. It would be nice if we could use the much smaller\nmodule graph, since it is available also in the light weight\n`modules`[mode](`m:xref#mode`) of Xref servers.\n\n```erlang\nt(S) ->\n {ok, _} = xref:q(S, \"Eplus := closure E\"),\n {ok, Ms} = xref:q(S, \"AM\"),\n Fun = fun(M, N) ->\n Q = io_lib:format(\"# (Mod) (Eplus | ~p : Mod)\", [M]),\n {ok, N0} = xref:q(S, lists:flatten(Q)),\n N + N0\n end,\n Sum = lists:foldl(Fun, 0, Ms),\n ok = xref:forget(S, 'Eplus'),\n {ok, Tot} = xref:q(S, \"# (closure ME | AM)\"),\n 100 * ((Tot - Sum) / Tot).\n```\n\nComments on the code:\n\n- We want to find the reduction of the closure of the function graph to modules.\n The direct expression for doing that would be `(Mod) (closure E | AM)`, but\n then we would have to represent all of the transitive closure of E in memory.\n Instead the number of indirectly used modules is found for each analyzed\n module, and the sum over all modules is calculated.\n- A user variable is employed for holding the `digraph` representation of the\n function graph for use in many queries. The reason is efficiency. As opposed\n to the `=` operator, the `:=` operator saves a value for subsequent analyses.\n Here might be the place to note that equal subexpressions within a query are\n evaluated only once; `=` cannot be used for speeding things up.\n- `Eplus | ~p : Mod`. The `|` operator converts the second operand to the type\n of the first operand. In this case the module is converted to all functions of\n the module. It is necessary to assign a type to the module (`: Mod`),\n otherwise modules like `kernel` would be converted to all functions of the\n application with the same name; the most general constant is used in cases of\n ambiguity.\n- Since we are only interested in a ratio, the unary operator `#` that counts\n the elements of the operand is used. It cannot be applied to the `digraph`\n representation of graphs.\n- We could find the size of the closure of the module graph with a loop similar\n to one used for the function graph, but since the module graph is so much\n smaller, a more direct method is feasible.\n\nWhen the Erlang function `t/1` was applied to an Xref server loaded with the\ncurrent version of OTP, the returned value was close to 84 (percent). This means\nthat the number of indirectly used modules is approximately six times greater\nwhen using the module graph. So the answer to the above stated question is that\nit is definitely worth while using the function graph for this particular\nanalysis. Finally, note that in the presence of unresolved calls, the graphs may\nbe incomplete, which means that there may be indirectly used modules that do not\nshow up.","title":"Graph Analysis - Xref - The Cross Reference Tool","ref":"xref_chapter.html#graph-analysis"},{"type":"extras","doc":"# Erlang mode for Emacs\n\nPossibly the most important feature of an editor designed for programmers is the\nability to indent a line of code in accordance with the structure of the\nprogramming language. The Erlang mode does, of course, provide this feature. The\nlayout used is based on the common use of the language. The mode also provides\nthings as syntax highlighting, electric commands, module name verification,\ncomment support including paragraph filling, skeletons, tags support etc.\n\nIn the following descriptions the use of the word _Point_ means: \"Point can be\nseen as the position of the cursor. More precisely, the point is the position\nbetween two characters while the cursor is drawn over the character following\nthe point\".","title":"Erlang mode for Emacs","ref":"erlang-el.html"},{"type":"extras","doc":"The following command are directly available for indentation.\n\n- _`TAB`_ (`erlang-indent-command`) - Indents the current line of code.\n- _`M-C-\\`_ (`indent-region`) - Indents all lines in the region.\n- _`M-l`_ (`indent-for-comment`) - Insert a comment character to the right of\n the code on the line (if any).\n\nLines containing comment are indented differently depending on the number of\n%-characters used:\n\n- Lines with one %-character is indented to the right of the code. The column\n is specified by the variable `comment-column`, by default column 48 is used.\n- Lines with two %-characters will be indented to the same depth as code would\n have been in the same situation.\n- Lines with three of more %-characters are indented to the left margin.\n- _`C-c C-q`_ (`erlang-indent-function`) - Indents the current Erlang\n function.\n- _`M-x erlang-indent-clause RET`_ - Indent the current Erlang clause.\n- _`M-x erlang-indent-current-buffer RET`_ - Indent the entire buffer.","title":"Indent - Erlang mode for Emacs","ref":"erlang-el.html#indent"},{"type":"extras","doc":"When editing normal text in text mode you can let Emacs reformat the text by the\n`fill-paragraph` command. This command will not work for comments since it will\ntreat the comment characters as words. The Erlang editing mode provides a\ncommand that knows about the Erlang comment structure and can be used to fill\ntext paragraphs in comments. Ex:\n\n```erlang\n%% This is just a very simple test to show\n%% how the Erlang fill\n%% paragraph command works.\n```\n\nClearly, the text is badly formatted. Instead of formatting this paragraph line\nby line, let's try `erlang-fill-paragraph` by pressing _`M-q`_. The result is:\n\n```erlang\n%% This is just a very simple test to show how the Erlang fill\n%% paragraph command works.\n```","title":"Edit - Fill Comment - Erlang mode for Emacs","ref":"erlang-el.html#edit-fill-comment"},{"type":"extras","doc":"_`C-c C-c`_ will put comment characters at the beginning of all lines in a\nmarked region. If you want to have two comment characters instead of one you can\ndo _`C-u 2 C-c C-c`_\n\n_`C-c C-u`_ will undo a comment-region command.","title":"Edit - Comment/Uncomment Region - Erlang mode for Emacs","ref":"erlang-el.html#edit-comment-uncomment-region"},{"type":"extras","doc":"- _`M-C-a`_ (`erlang-beginning-of-function`) - Move the point to the beginning\n of the current or preceding Erlang function. With an numeric argument (ex\n _`C-u 2 M-C-a`_) the function skips backwards over this many Erlang\n functions. Should the argument be negative the point is moved to the\n beginning of a function below the current function.\n- _`C-c M-a`_ (`erlang-beginning-of-clause`) - As above but move point to the\n beginning of the current or preceding Erlang clause.\n- _`M-C-e`_ (`erlang-end-of-function`) - Move to the end of the current or\n following Erlang function. With an numeric argument (ex _`C-u 2 M-C-e`_) the\n function skips backwards over this many Erlang functions. Should the\n argument be negative the point is moved to the end of a function below the\n current function.\n- _`C-c M-e`_ (`erlang-end-of-clause`) - As above but move point to the end of\n the current or following Erlang clause.","title":"Edit - Moving the point - Erlang mode for Emacs","ref":"erlang-el.html#edit-moving-the-point"},{"type":"extras","doc":"- _`M-C-h`_ (`erlang-mark-function`) - Put the region around the current\n Erlang function. The point is placed in the beginning and the mark at the\n end of the function.\n- _`C-c M-h`_ (`erlang-mark-clause`) Put the region around the current Erlang\n clause. The point is placed in the beginning and the mark at the end of the\n function.","title":"Edit - Marking - Erlang mode for Emacs","ref":"erlang-el.html#edit-marking"},{"type":"extras","doc":"- _`C-c C-j`_ (`erlang-generate-new-clause`) - Create a new clause in the\n current Erlang function. The point is placed between the parentheses of the\n argument list.\n- _`C-c C-y`_ (`erlang-clone-arguments`) - Copy the function arguments of the\n preceding Erlang clause. This command is useful when defining a new clause\n with almost the same argument as the preceding.","title":"Edit - Function Header Commands - Erlang mode for Emacs","ref":"erlang-el.html#edit-function-header-commands"},{"type":"extras","doc":"- _`C-c C-a`_ (`align-current`) - aligns comments, arrows, assignments,\n and type annotations around the cursor.\n\n```erlang\nExample:\n\nsum(L) -> sum(L, 0).\nsum([H|T], Sum) -> sum(T, Sum + H); % recurse\nsum([], Sum) -> Sum. % base case\n\n-record { two :: int(), % hello\n three = hello :: string(), % there\n four = 42 :: int() }.\n\nbecomes:\n\nsum(L) -> sum(L, 0).\nsum([H|T], Sum) -> sum(T, Sum + H); % recurse\nsum([], Sum) -> Sum. % base case\n\n-record { two :: int(), % hello\n three = hello :: string(), % there\n four = 42 :: int() }.\n```","title":"Edit - Alignment - Erlang mode for Emacs","ref":"erlang-el.html#edit-alignment"},{"type":"extras","doc":"The syntax highlighting can be activated from the Erlang menu. There are four\ndifferent alternatives:\n\n- Off: Normal black and white display.\n- Level 1: Function headers, reserved words, comments, strings, quoted atoms,\n and character constants will be colored.\n- Level 2: The above, attributes, Erlang bif:s, guards, and words in comments\n enclosed in single quotes will be colored.\n- Level 3: The above, variables, records, and macros will be colored. (This\n level is also known as the Christmas tree level.)","title":"Syntax highlighting - Erlang mode for Emacs","ref":"erlang-el.html#syntax-highlighting"},{"type":"extras","doc":"For the tag commands to work it requires that you have generated a tag file. See\n[Erlang mode users guide](erlang_mode_chapter.md#tags)\n\n- _`M-.`_ (`find-tag`) - Find a function definition. The default value is the\n function name under the point.\n- Find Tag (`erlang-find-tag`) - Like the Elisp-function\n `find-tag'. Capable of retrieving Erlang modules. Tags can be given on the forms `tag',\n `module:', `module:tag'.\n- _`M-+`_ (`erlang-find-next-tag`) - Find the next occurrence of tag.\n- _`M-TAB`_ (`erlang-complete-tag`) - Perform completion on the tag entered in\n a tag search. Completes to the set of names listed in the current tags\n table.\n- Tags aprops (`tags-apropos`) - Display list of all tags in tags table REGEXP\n matches.\n- _`C-x t s`_ (`tags-search`) - Search through all files listed in tags table\n for match for REGEXP. Stops when a match is found.","title":"Tags - Erlang mode for Emacs","ref":"erlang-el.html#tags"},{"type":"extras","doc":"A skeleton is a piece of pre-written code that can be inserted into the buffer.\nErlang mode comes with a set of predefined skeletons. The skeletons can be\naccessed either from the Erlang menu of from commands named\n`tempo-template-erlang-*`, as the skeletons is defined using the standard Emacs\npackage \"tempo\". Here follows a brief description of the available skeletons:\n\n- Simple skeletons: If, Case, Receive, Receive After, Receive Loop - Basic\n code constructs.\n- Header elements: Module, Author - These commands insert lines on the form\n `-module('xxx').` and `-author('my@home').`. They can be used directly, but\n are also used as part of the full headers described below.\n- Full Headers: Small (minimum requirement), Medium (with fields for basic\n information about the module), and Large Header (medium header with some\n extra layout structure).\n- Small Server - skeleton for a simple server not using OTP.\n- Application - skeletons for the OTP application behavior\n- Supervisor - skeleton for the OTP supervisor behavior\n- Supervisor Bridge - skeleton for the OTP supervisor bridge behavior\n- gen_server - skeleton for the OTP gen_server behavior\n- gen_event - skeleton for the OTP gen_event behavior\n- gen_fsm - skeleton for the OTP gen_fsm behavior\n- gen_statem (StateName/3) - skeleton for the OTP gen_statem behavior using\n state name functions\n- gen_statem (handle_event/4) - skeleton for the OTP gen_statem behavior using\n one state function\n- Library module - skeleton for a module that does not implement a process.\n- Corba callback - skeleton for a Corba callback module.\n- Erlang test suite - skeleton for a callback module for the erlang test\n server.","title":"Skeletons - Erlang mode for Emacs","ref":"erlang-el.html#skeletons"},{"type":"extras","doc":"- New shell (`erlang-shell`) - Starts a new Erlang shell.\n- _`C-c C-z,`_ (`erlang-shell-display `) - Displays an Erlang shell, or starts\n a new one if there is no shell started.","title":"Shell - Erlang mode for Emacs","ref":"erlang-el.html#shell"},{"type":"extras","doc":"- _`C-c C-k,`_ (`erlang-compile`) - Compiles the Erlang module in the current\n buffer. You can also use _`C-u C-c C-k`_ to debug compile the module with\n the debug options `debug_info` and `export_all`.\n- _`C-c C-l,`_ (`erlang-compile-display`) - Display compilation output.\n- _``C-u C-x` ``_ Start parsing the compiler output from the beginning. This\n command will place the point on the line where the first error was found.\n- _`` C-x` ``_ (`erlang-next-error`) - Move the point on to the next error.\n The buffer displaying the compilation errors will be updated so that the\n current error will be visible.","title":"Compile - Erlang mode for Emacs","ref":"erlang-el.html#compile"},{"type":"extras","doc":"On unix you can view the manual pages in emacs. In order to find the manual\npages, the variable `erlang-root-dir` should be bound to the name of the\ndirectory containing the Erlang installation. The name should not include the\nfinal slash. Practically, you should add a line on the following form to your\n~/.emacs,\n\n```text\n(setq erlang-root-dir \"/the/erlang/root/dir/goes/here\")\n```","title":"Man - Erlang mode for Emacs","ref":"erlang-el.html#man"},{"type":"extras","doc":"- _`M-x imenu-add-to-menubar RET`_ - This command will create the IMenu menu\n containing all the functions in the current buffer.The command will ask you\n for a suitable name for the menu. Not supported by Xemacs.","title":"Starting IMenu - Erlang mode for Emacs","ref":"erlang-el.html#starting-imenu"},{"type":"extras","doc":"- _`M-x erlang-version RET`_ - This command displays the version number of the\n Erlang editing mode. Remember to always supply the version number when\n asking questions about the Erlang mode.","title":"Version - Erlang mode for Emacs","ref":"erlang-el.html#version"}],"content_type":"text/plain","producer":{"name":"ex_doc","version":[48,46,51,52,46,49]}} \ No newline at end of file diff --git a/prs/8803/lib/tools-4.0/doc/html/dist/search_data-8780CEA5.js b/prs/8803/lib/tools-4.0/doc/html/dist/search_data-8780CEA5.js deleted file mode 100644 index 05eea50e9b454..0000000000000 --- a/prs/8803/lib/tools-4.0/doc/html/dist/search_data-8780CEA5.js +++ /dev/null @@ -1 +0,0 @@ -searchData={"items":[{"type":"module","title":"cover","doc":"A Coverage Analysis Tool for Erlang\n\nThe module `cover` provides a set of functions for coverage analysis\nof Erlang programs, counting how many times each _executable line_ of\ncode is executed when a program is run. Executable lines are\nlines in the body of a clause in a function, `case`,\n`receive`, or `try`. Lines in clause heads, blank lines, and lines\ncontaining only comments are not executable.\n\nCoverage analysis can be used to verify that test cases covers all\nrelevant line in the code being test. It can also be helpful when\nlooking for bottlenecks in the code.\n\nBefore any analysis can take place, the involved modules has to be\n_cover-compiled_. This means that some extra information is added to\nthe module before it is compiled into a binary which then is\nloaded. The source file of the module is not affected and no `.beam`\nfile is created. If the runtime system supports coverage natively,\nCover will automatically use that functionality to lower the execution\noverhead for cover-compiled code.\n\n> #### Change {: .info }\n>\n> Native coverage support was added in Erlang/OTP 27.\n\nEach time a function in a cover-compiled module is called, information about the\ncall is added to an internal database of Cover. The coverage analysis is\nperformed by examining the contents of the Cover database. The output `Answer`\nis determined by two parameters: `Level` and `Analysis`.\n\n- `Level = module`\n\n `Answer = {Module,Value}`, where `Module` is the module name.\n\n- `Level = function`\n\n `Answer = [{Function,Value}]`, one tuple for each function in the module. A\n function is specified by its module name `M`, function name `F` and arity `A`\n as a tuple `{M,F,A}`.\n\n- `Level = clause`\n\n `Answer = [{Clause,Value}]`, one tuple for each clause in the module. A clause\n is specified by its module name `M`, function name `F`, arity `A` and position\n in the function definition `C` as a tuple `{M,F,A,C}`.\n\n- `Level = line`\n\n `Answer = [{Line,Value}]`, one tuple for each executable line in the module. A\n line is specified by its module name `M` and line number in the source file\n `N` as a tuple `{M,N}`.\n\n- `Analysis = coverage`\n\n `Value = {Cov,NotCov}` where `Cov` is the number of executable lines in the\n module, function, clause or line that have been executed at least once and\n `NotCov` is the number of executable lines that have not been executed.\n\n- `Analysis = calls`\n\n `Value = Calls` which is the number of times the module, function, or clause\n has been called. In the case of line level analysis, `Calls` is the number of\n times the line has been executed.","ref":"cover.html"},{"type":"module","title":"Distribution - cover","doc":"Cover can be used in a distributed Erlang system. One of the nodes in the system\nhas to be selected as the _main node_, and all Cover commands must be\nexecuted from that node. The error reason `not_main_node` is returned if an\ninterface function is called on one of the remote nodes.\n\nUse `cover:start/1` and `cover:stop/1` to add or remove nodes. The\nsame cover-compiled code will be loaded on each node, and analysis\nwill collect and sum up coverage data results from all nodes.\n\nTo only collect data from remote nodes without stopping `cover` on those nodes,\nuse `cover:flush/1`\n\nIf the connection to a remote node goes down, the main node will mark it as\nlost. If the node comes back it will be added again. If the remote node was\nalive during the disconnected period, cover data from before and during this\nperiod will be included in the analysis.","ref":"cover.html#module-distribution"},{"type":"function","title":"cover.analyse/0","doc":"","ref":"cover.html#analyse/0"},{"type":"function","title":"cover.analyse/1","doc":"Analyzes one or more modules as specified by `Arg`.\n\nIf `Arg` is one of the values in [`analysis()`](`t:analysis/0`), this\ncall is equivalent to [`analyse('_', Arg, function)`](`analyse/3`).\n\nIf `Arg` is one of the values in [`level()`](`t:level/0`), this\ncall is equivalent to [`analyse('_', coverage, Arg)`](`analyse/3`).\n\nOtherwise `Arg` is assumed to be a module name, and this call is equivalent\nto [`analyse(Arg, coverage, function)`](`analyse/3`).\n\n> #### Note {: .info }\n>\n> To analyze a module whose name overlaps with one the values in\n> [`analysis()`](`t:analysis/0`) or [`level()`](`t:level/0`), the module\n> name has to be in a list. For example, to analyze a module named `calls`:\n>\n> ```\n> cover:analyse([calls]).\n> ```","ref":"cover.html#analyse/1"},{"type":"function","title":"cover.analyse/2","doc":"Analyzes one or more modules as specified by `Arg1` and `Arg2`.\n\nIf `Arg1` is one of the values in [`analysis()`](`t:analysis/0`) and\n`Arg2` is one of the values in [`level()`](`t:level/0`), this\ncall is equivalent to [`analyse('_', Arg1, Arg2)`](`analyse/3`).\n\nIf `Arg2` is one of the values in [`analysis()`](`t:analysis/0`),\n`Arg1` is assumed to be a module and this call is equivalent to\n[`analyse(Arg1, Arg2, function)`](`analyse/3`).\n\nIf `Arg2` is one of the values in [`level()`](`t:level/0`), `Arg1` is\nassumed to be a module and this call is equivalent to [`analyse(Arg1,\ncoverage, Arg2)`](`analyse/3`).\n\n> #### Note {: .info }\n>\n> To analyze a module whose name overlaps with one of the values in\n> [`analysis()`](`t:analysis/0`), the module name needs to be in a\n> list. For example, to analyze a module named `calls`:\n>\n> ```\n> cover:analyse([calls], function).\n> ```","ref":"cover.html#analyse/2"},{"type":"function","title":"cover.analyse/3","doc":"Perform analysis of one or more cover-compiled modules, as specified by\n`Analysis` and `Level`, by examining the contents of the internal\ndatabase.\n\nIf `Modules` is an atom (a single module), the return is `OneResult`,\notherwise the return is `{result, Ok, Fail}`.\n\nIf `Modules` is atom `'_'`, all modules that have data in the cover data table\nare analysed. Note that this includes both cover-compiled modules and imported\nmodules.\n\nIf a given module is not cover-compiled, this is indicated by the error reason\n`{not_cover_compiled, Module}`.","ref":"cover.html#analyse/3"},{"type":"function","title":"cover.analyse_to_file/0","doc":"","ref":"cover.html#analyse_to_file/0"},{"type":"function","title":"cover.analyse_to_file/1","doc":"If `Arg` is a list of [`analyse_option()`](`t:analyse_option/0`)\noptions, this call is equivalent to [`analyse_to_file('_',\nArg)`](`analyse_to_file/2`).\n\nOtherwise `Arg` is assumed to be a module, and this call is equivalent to\n[`analyse_to_file(Arg, [])`](`analyse_to_file/2`).\n\n> #### Note {: .info }\n>\n> To analyze a module of the name `html` (which overlaps with an option\n> in [`analyse_option()`](`t:analyse_option/0`)), it is necessary to\n> use `cover:analyse_to_file/2`:\n>\n> ```\n> cover:analyse_to_file([html], []).\n> ```","ref":"cover.html#analyse_to_file/1"},{"type":"function","title":"cover.analyse_to_file/2","doc":"Outputs copies of the source code for the given modules annotated with\nexecution counts for each executable line.\n\nThe output file `OutFile` defaults to `Module.COVER.out`, and to `Module.COVER.html`\nif option `html` is used.\n\nIf `Modules` is an atom (one module), the return will be `Answer`, otherwise the\nreturn will be a list, `{result, Ok, Fail}`.\n\nIf `Modules` is '_', all modules that have data in the Cover data table\nare analysed. Note that this includes both cover-compiled modules and imported\nmodules.\n\nIf a module is not cover-compiled, this is indicated by the error reason\n`{not_cover_compiled, Module}`.\n\nIf the source file and/or the output file cannot be opened using `file:open/2`,\nthe function returns `{error, {file, File, Reason}}`, where `File` is the file\nname and `Reason` is the error reason.\n\nIf a module was cover compiled from the `.beam` file, that is, using\n`compile_beam/1` or\n[`compile_beam_directory/0,1` ](`compile_beam_directory/0`), it is assumed that\nthe source code can be found in one of the following locations:\n\n- the same directory as the `.beam` file\n- `../src` relative to the directory with `.beam` file\n- the source path in `Module:module_info(compile)`, in which case two paths\n are examined:\n * first the one constructed by joining `../src` and the tail of the compiled path\n below a trailing `src` component\n * the compiled path itself\n\nIf no source code is found, this is indicated by the error reason\n`{no_source_code_found, Module}`.","ref":"cover.html#analyse_to_file/2"},{"type":"function","title":"cover.async_analyse_to_file/1","doc":"","ref":"cover.html#async_analyse_to_file/1"},{"type":"function","title":"cover.async_analyse_to_file/2","doc":"","ref":"cover.html#async_analyse_to_file/2"},{"type":"function","title":"cover.async_analyse_to_file/3","doc":"This function works the same way as\n[`analyse_to_file/2`](`analyse_to_file/2`) except that it is asynchronous instead\nof synchronous.\n\nThe spawned process will link with the caller when created. If an\nerror of type [`analyse_rsn()`](`t:analyse_rsn/0`) occurs while doing\nthe cover analysis the process will crash with the same error reason\nas [`analyse_to_file`](`analyse_to_file/1`) would return.","ref":"cover.html#async_analyse_to_file/3"},{"type":"function","title":"cover.compile/1","doc":"","ref":"cover.html#compile/1"},{"type":"function","title":"cover.compile/2","doc":"","ref":"cover.html#compile/2"},{"type":"function","title":"cover.compile_beam/1","doc":"Cover-compiles one or more modules based `.beam` files containing\nabstract code (option `debug_info`).\n\nCover-compiling from `.beam` files is faster than compiling from\nsource and less hassle, because there is no need to supply options for\ninclude paths or macros. However, the existing `.beam` files must have\nbeen compiled with option\n[`debug_info`](`e:compiler:compile.md#debug_info`) so that they contain\n[*abstract code*](`e:erts:absform`).\n\nIf abstract code is missing, the error reason `{no_abstract_code,\nBeamFile}` is returned. If the abstract code is encrypted, and no key\nis available for decrypting it, the error reason\n`{encrypted_abstract_code, BeamFile}` is returned.\n\nIf only the module name (that is, not the full name of the `.beam`\nfile) is given to this function, the `.beam` file is found by calling\n[`code:which(Module)`](`code:which/1`). If no `.beam` file is found,\nthe error reason `non_existing` is returned. If the module is already\ncover compiled with [`compile_beam/1`](`compile_beam/1`), the `.beam`\nfile will be picked from the same location as the first time it was\ncompiled. If the module is already cover-compiled with\n`compile_module/2`, there is no way to find the correct `.beam` file,\nso the error reason `{already_cover_compiled, no_beam_found, Module}`\nis returned.\n\n`{error, BeamFile}` is returned if the compiled code cannot be loaded on the\nnode.\n\nIf a list of `ModFiles` is given as input, a list of `Result` will be returned.\nThe order of the returned list is undefined.","ref":"cover.html#compile_beam/1"},{"type":"function","title":"cover.compile_beam_directory/0","doc":"","ref":"cover.html#compile_beam_directory/0"},{"type":"function","title":"cover.compile_beam_directory/1","doc":"Cover-compiles all `.beam` files in directory `Dir` in the same way\nas `compile_beam/1`.\n\nThis function returns a list of [`compile_beam_result()`](`t:compile_beam_result/0`)\nif successful. Otherwise, it returns `{error, eacces}` if the directory is not\nreadable, and `{error, enoent}` if the directory does not exist.","ref":"cover.html#compile_beam_directory/1"},{"type":"function","title":"cover.compile_directory/0","doc":"","ref":"cover.html#compile_directory/0"},{"type":"function","title":"cover.compile_directory/1","doc":"","ref":"cover.html#compile_directory/1"},{"type":"function","title":"cover.compile_directory/2","doc":"Compiles all modules (`.erl` files) in a directory `Dir` for Cover analysis the\nsame way as [`compile_module/1,2`](`compile_module/1`) and returns a list of\n[`Result`](`t:compile_result/0`).\n\nThis function returns `{error, eacces}` if the directory is not readable or\n`{error, enoent}` if the directory does not exist.","ref":"cover.html#compile_directory/2"},{"type":"function","title":"cover.compile_module/1","doc":"","ref":"cover.html#compile_module/1"},{"type":"function","title":"cover.compile_module/2","doc":"Cover-compiles one or more modules.\n\nThe module is given by its module name `Module` or by its file name\n`File`.\n\nThe `.erl` extension can be omitted. If the module is not located in\nthe current directory, the full path to it must be specified.\n\n`Options` is a list of compiler options. Only options defining include\nfile directories and macros are passed to `compile:file/2`;\neverything else is ignored.\n\nIf the module is successfully cover-compiled, the function returns\n`{ok, Module}`. Otherwise the function returns `{error, File}`. Errors and\nwarnings are printed as they occur.\n\nIf a list of `ModFiles` is given as input, a list of [`Result`](`t:compile_result/0`)\nwill be returned. The order of the returned results in the list is undefined.\n\nNote that the internal database is initialized during the compilation,\nwhich means that any previously collected coverage data for the module\nis lost.","ref":"cover.html#compile_module/2"},{"type":"function","title":"cover.export/1","doc":"","ref":"cover.html#export/1"},{"type":"function","title":"cover.export/2","doc":"Exports the current coverage data for `Module` to the file `ExportFile`.\n\nIt is recommended to name the `ExportFile` with the extension `.coverdata`.\n\nIf `Module` is '_', data for all cover-compiled or earlier imported\nmodules is exported.\n\nThis function is useful if coverage data from different systems is to be merged.\n\nSee also `import/1`.","ref":"cover.html#export/2"},{"type":"function","title":"cover.flush/1","doc":"Fetches data from the Cover database on the remote nodes and stores it on the main\nnode.","ref":"cover.html#flush/1"},{"type":"function","title":"cover.import/1","doc":"Imports coverage data from the file `ExportFile` created with\n[`export/1,2`](`export/2`).\n\nAny analysis performed after this call will include the imported data.\n\nNote that when compiling a module _all existing coverage data is removed_,\nincluding imported data. If a module is already compiled when data is imported,\nthe imported data is _added_ to the existing coverage data.\n\nCoverage data from several export files can be imported into one system. The\ncoverage data is then added up when analysing.\n\nCoverage data for a module cannot be imported from the same file twice unless\nthe module is first reset or compiled. The check is based on the filename, so\nyou can easily fool the system by renaming your export file.","ref":"cover.html#import/1"},{"type":"function","title":"cover.imported/0","doc":"Returns a list of all imported files.","ref":"cover.html#imported/0"},{"type":"function","title":"cover.imported_modules/0","doc":"Returns a list of all modules for which there are imported data.","ref":"cover.html#imported_modules/0"},{"type":"function","title":"cover.is_compiled/1","doc":"Returns `{file, File}` if the module `Module` is cover-compiled, or `false`\notherwise.\n\n`File` is the `.erl` file used by [`compile_module/1,2`](`compile_module/2`)\nor the `.beam` file used by `compile_beam/1`.","ref":"cover.html#is_compiled/1"},{"type":"function","title":"cover.local_only/0","doc":"Only support running Cover on the local node.\n\nThis function has to be called before any modules have been compiled or\nany nodes added. When running in this mode, modules will be\ncover-compiled in a more efficient way, but the resulting code will\nonly work on the same node they were compiled on.","ref":"cover.html#local_only/0"},{"type":"function","title":"cover.modules/0","doc":"Returns a list with all modules that are currently cover-compiled.","ref":"cover.html#modules/0"},{"type":"function","title":"cover.reset/0","doc":"Resets all coverage data for all cover-compiled modules in the Cover\ndatabase on all nodes.","ref":"cover.html#reset/0"},{"type":"function","title":"cover.reset/1","doc":"Resets all coverage data for the cover-compiled module `Module` in the Cover\ndatabase on all nodes.\n\nIf `Module` is not cover-compiled, the function returns\n`{error, {not_cover_compiled, Module}}`.","ref":"cover.html#reset/1"},{"type":"function","title":"cover.start/0","doc":"Starts the Cover server which owns the Cover internal database. This function is\ncalled automatically by the other functions in the module.","ref":"cover.html#start/0"},{"type":"function","title":"cover.start/1","doc":"Starts a Cover server on the each of given nodes, and loads all cover compiled\nmodules.\n\nThis call will fail if `cover:local_only/0` has been called.","ref":"cover.html#start/1"},{"type":"function","title":"cover.stop/0","doc":"Stops the Cover server and unloads all cover-compiled code.","ref":"cover.html#stop/0"},{"type":"function","title":"cover.stop/1","doc":"Stops the Cover server and unloads all cover-compiled code on the given nodes.\n\nData stored in the Cover database on the remote nodes is fetched and stored on\nthe main node.","ref":"cover.html#stop/1"},{"type":"function","title":"cover.which_nodes/0","doc":"Returns a list with all nodes that are part of the coverage analysis.\n\nNote that the current node is not included, because it is always part\nof the analysis.","ref":"cover.html#which_nodes/0"},{"type":"type","title":"cover.analyse_answer/0","doc":"","ref":"cover.html#t:analyse_answer/0"},{"type":"type","title":"cover.analyse_fail/0","doc":"","ref":"cover.html#t:analyse_fail/0"},{"type":"type","title":"cover.analyse_file_fail/0","doc":"","ref":"cover.html#t:analyse_file_fail/0"},{"type":"type","title":"cover.analyse_file_ok/0","doc":"","ref":"cover.html#t:analyse_file_ok/0"},{"type":"type","title":"cover.analyse_item/0","doc":"","ref":"cover.html#t:analyse_item/0"},{"type":"type","title":"cover.analyse_ok/0","doc":"","ref":"cover.html#t:analyse_ok/0"},{"type":"type","title":"cover.analyse_option/0","doc":"","ref":"cover.html#t:analyse_option/0"},{"type":"type","title":"cover.analyse_rsn/0","doc":"","ref":"cover.html#t:analyse_rsn/0"},{"type":"type","title":"cover.analyse_value/0","doc":"","ref":"cover.html#t:analyse_value/0"},{"type":"type","title":"cover.analysis/0","doc":"","ref":"cover.html#t:analysis/0"},{"type":"type","title":"cover.beam_mod_file/0","doc":"","ref":"cover.html#t:beam_mod_file/0"},{"type":"type","title":"cover.beam_mod_files/0","doc":"","ref":"cover.html#t:beam_mod_files/0"},{"type":"type","title":"cover.compile_beam_result/0","doc":"","ref":"cover.html#t:compile_beam_result/0"},{"type":"type","title":"cover.compile_beam_rsn/0","doc":"","ref":"cover.html#t:compile_beam_rsn/0"},{"type":"type","title":"cover.compile_result/0","doc":"","ref":"cover.html#t:compile_result/0"},{"type":"type","title":"cover.export_reason/0","doc":"","ref":"cover.html#t:export_reason/0"},{"type":"type","title":"cover.file_error/0","doc":"","ref":"cover.html#t:file_error/0"},{"type":"type","title":"cover.level/0","doc":"","ref":"cover.html#t:level/0"},{"type":"type","title":"cover.mod_file/0","doc":"","ref":"cover.html#t:mod_file/0"},{"type":"type","title":"cover.mod_files/0","doc":"","ref":"cover.html#t:mod_files/0"},{"type":"type","title":"cover.modules/0","doc":"","ref":"cover.html#t:modules/0"},{"type":"type","title":"cover.one_result/0","doc":"","ref":"cover.html#t:one_result/0"},{"type":"type","title":"cover.option/0","doc":"","ref":"cover.html#t:option/0"},{"type":"module","title":"cprof","doc":"A simple Call Count Profiling Tool using breakpoints for minimal runtime\nperformance impact.\n\nThe `cprof` module is used to profile a program to find out how many times\ndifferent functions are called. To minimize runtime performance impact,\nbreakpoints containing counters are used.\n\nSince breakpoints are used there is no need for special compilation of the\nmodules to be profiled. These breakpoints can only be set on BEAM code, so\nBIFs cannot be call-count traced.\n\nThe size of the call counters is the host machine word size. One bit is used\nwhen pausing the counter, so the maximum counter value for a 32-bit host\nis 2,147,483,647.\n\nThe profiling result is delivered as a term containing a sorted list of entries,\none per module. Each module entry contains a sorted list of functions. The\nsorting order in both cases is of decreasing call count.\n\nCall count tracing is lightweight compared to other forms of tracing,\nsuch as `m:eprof` or `m:fprof`, since no trace messages have to be\ngenerated. Some measurements indicates that the performance degradation is\nabout 10 percent.\n\nFor more information and some examples, see the\n[User's Guide for `cprof`](cprof_chapter.md).","ref":"cprof.html"},{"type":"function","title":"cprof.analyse/0","doc":"","ref":"cprof.html#analyse/0"},{"type":"function","title":"cprof.analyse/1","doc":"Collect call counters for one or more modules.\n\nIf `ModLimit` is a module name (an atom), this call is equivalent to\n[`analyse(ModLimit, 1)`](`analyse/2`).\n\nIf `ModLimit` is an integer, this function calls\n[`analyse(Module, ModLimit)`](`analyse/2`) for each `Module` that is\ncurrently loaded (except the `cprof` module itself).\nThe result from those calls are returned in a list.","ref":"cprof.html#analyse/1"},{"type":"function","title":"cprof.analyse/2","doc":"Collects and analyses all call counters for module `Module`.\n\nThis function returns:\n\n```\n{Module, ModuleCount, FuncAnalysisList}\n```\n\nwhere `FuncAnalysisList` is a list of tuples, one for each function:\n\n```\n{{Module, FunctionName, Arity}, FuncCallCount}\n```\n\nIf call counters are still running while `analyse/0,1,2` is executing, the result\ncould be inconsistent. This happens if the process executing `analyse/0,1,2`\nis scheduled out so some other process can increment the counters that are\nbeing analysed. Calling [`pause()`](`pause/0`) before analysing takes care of\nthat problem.\n\nAll functions with a `FuncCallCount` lower than `Limit` are excluded from\n`FuncAnalysisList`. They are still included in `ModCallCount`, though.","ref":"cprof.html#analyse/2"},{"type":"function","title":"cprof.pause/0","doc":"Pause call count tracing for all functions in all modules and stop it for all\nfunctions in modules to be loaded.\n\nThis call is equivalent to\n[`pause('_', '_', '_') + stop({on_load})`](`pause/3`).","ref":"cprof.html#pause/0"},{"type":"function","title":"cprof.pause/1","doc":"If `FuncSpec` is an atom, it is assumed to be a module name, and\nthis call is equivalent to [`pause(FuncSpec, '_', '_')`](`pause/3`).\n\nIf `FuncSpec` is an MFA tuple, `{Module, Name, Arity`}, this call\nis equivalent to [`pause(Module, Name, Arity)`](`pause/3`).\n\nIf `FuncSpec` is tuple `{FS}`, `FS` is the first argument to\n`erlang:trace_pattern/3`. For example, if `FuncSpec` is `{on_load}`,\ncall counters will be paused for all functions in modules to be loaded.","ref":"cprof.html#pause/1"},{"type":"function","title":"cprof.pause/2","doc":"","ref":"cprof.html#pause/2"},{"type":"function","title":"cprof.pause/3","doc":"Pause call counters for matching functions in matching modules.\n\nThe call counters for all matching functions that have call count breakpoints\nare paused at their current count.\n\nReturn the number of matching functions that can have call count breakpoints,\nthe same as [`start/*`](`start/3`) with the same arguments would have\nreturned.","ref":"cprof.html#pause/3"},{"type":"function","title":"cprof.restart/0","doc":"","ref":"cprof.html#restart/0"},{"type":"function","title":"cprof.restart/1","doc":"If `FuncSpec` is an atom, it is assumed to be a module name, and\nthis call is equivalent to [`restart(FuncSpec, '_', '_')`](`restart/3`).\n\nIf `FuncSpec` is an MFA tuple, `{Module, Name, Arity`}, this call\nis equivalent to [`restart(Module, Name, Arity)`](`restart/3`).\n\nIf `FuncSpec` is tuple `{FS}`, `FS` is the first argument to\n`erlang:trace_pattern/3`. For example, if `FuncSpec` is `{on_load}`,\ncall counters will be set to zero and running for all functions in\nmodules to be loaded.","ref":"cprof.html#restart/1"},{"type":"function","title":"cprof.restart/2","doc":"","ref":"cprof.html#restart/2"},{"type":"function","title":"cprof.restart/3","doc":"Restart call counters for the matching functions in matching modules that are\ncall-count traced.\n\nThe call counters for all matching functions that has call count breakpoints\nare set to zero and running.\n\nReturn the number of matching functions that can have call count breakpoints,\nthe same as [`start/*`](`start/3`) with the same arguments would have\nreturned.","ref":"cprof.html#restart/3"},{"type":"function","title":"cprof.start/0","doc":"Start call count tracing for all functions in all modules, and also for all\nfunctions in modules to be loaded.\n\nThis is equivalent to\n[`start('_', '_', '_') + start({on_load})`](`start/3`).","ref":"cprof.html#start/0"},{"type":"function","title":"cprof.start/1","doc":"If `FuncSpec` is an atom, it is assumed to be a module name, and\nthis call is equivalent to [`start(FuncSpec, '_', '_')`](`start/3`).\n\nIf `FuncSpec` is an MFA tuple, `{Module, Name, Arity`}, this call\nis equivalent to [`start(Module, Name, Arity)`](`start/3`).\n\nIf `FuncSpec` is tuple `{FS}`, `FS` is the first argument to\n`erlang:trace_pattern/3`. For example, if `FuncSpec` is `{on_load}`,\ncall counters will be set to zero and running for all functions in\nmodules to be loaded.","ref":"cprof.html#start/1"},{"type":"function","title":"cprof.start/2","doc":"","ref":"cprof.html#start/2"},{"type":"function","title":"cprof.start/3","doc":"Start call count tracing for matching functions in matching modules.\n\nSet call count breakpoints on the matching functions that has no call count\nbreakpoints. Call counters are set to zero and running for all matching\nfunctions.\n\nReturn the number of matching functions that has call count breakpoints.","ref":"cprof.html#start/3"},{"type":"function","title":"cprof.stop/0","doc":"Stop call count tracing for all functions in all modules, and also for all\nfunctions in modules to be loaded.\n\nThis is equivalent to\n[`stop('_', '_', '_') + stop({on_load})`](`stop/3`).","ref":"cprof.html#stop/0"},{"type":"function","title":"cprof.stop/1","doc":"If `FuncSpec` is an atom, it is assumed to be a module name, and\nthis call is equivalent to [`stop(FuncSpec, '_', '_')`](`stop/3`).\n\nIf `FuncSpec` is an MFA tuple, `{Module, Name, Arity`}, this call\nis equivalent to [`stop(Module, Name, Arity)`](`stop/3`).\n\nIf `FuncSpec` is tuple `{FS}`, `FS` is the first argument to\n`erlang:trace_pattern/3`. For example, if `FuncSpec` is `{on_load}`,\ncall counters be disabled for all functions in modules to be loaded.","ref":"cprof.html#stop/1"},{"type":"function","title":"cprof.stop/2","doc":"","ref":"cprof.html#stop/2"},{"type":"function","title":"cprof.stop/3","doc":"Stop call count tracing for matching functions in matching modules.\n\nRemove call count breakpoints from the matching functions that has call count\nbreakpoints.\n\nReturn the number of matching functions that can have call count breakpoints,\nwhich is the same as [`start/*`](`start/3`) with the same arguments would have\nreturned.","ref":"cprof.html#stop/3"},{"type":"type","title":"cprof.func_analysis_list/0","doc":"","ref":"cprof.html#t:func_analysis_list/0"},{"type":"type","title":"cprof.mod_analysis/0","doc":"","ref":"cprof.html#t:mod_analysis/0"},{"type":"type","title":"cprof.mod_analysis_list/0","doc":"","ref":"cprof.html#t:mod_analysis_list/0"},{"type":"module","title":"eprof","doc":"A Time Profiling Tool for Erlang\n\nThe module `eprof` provides a set of functions for time profiling of Erlang\nprograms to find out how the execution time is used. The profiling is done using\nthe Erlang trace BIFs. Tracing of local function calls for a specified set of\nprocesses is enabled when profiling is begun, and disabled when profiling is\nstopped.\n\nWhen using Eprof, expect a slowdown in program execution.","ref":"eprof.html"},{"type":"function","title":"eprof.analyze/0","doc":"","ref":"eprof.html#analyze/0"},{"type":"function","title":"eprof.analyze/1","doc":"If `TypeOpts` is an atom, it is assumed to be a module name, and this\ncall is equivalent to [`analyze(TypeOpts, [])`](`analyze/2`).\n\nOtherwise, if `TypeOpts` is a list, it assumed to be a list of options, and this\ncall is equivalent to [`analyze(procs, TypeOpts)`](`analyze/2`).","ref":"eprof.html#analyze/1"},{"type":"function","title":"eprof.analyze/2","doc":"Call this function when profiling has been stopped to display the results.\n\nIf `Type` is `procs`, the time spent in each function is shown separately\nfor each profiled process.\n\nIf `Type` is `total`, the time spent in each function is shown combined\nfor each profiled process.\n\nTime is shown as percentage of total time and as absolute time in micro seconds.","ref":"eprof.html#analyze/2"},{"type":"function","title":"eprof.log/1","doc":"Call this function to ensure that the results displayed by\n[`analyze/0,1,2`](`analyze/0`) are printed to the file `File` as well as to the\nscreen.","ref":"eprof.html#log/1"},{"type":"function","title":"eprof.profile/1","doc":"If `FunRootset` is a fun, this call is equivalent to\n[`profile([], FunRootset)`](`profile/2`).\n\nIf `FunRootset` is a list, it is assumed to be a `Rootset`, and this\ncall is equivalent to [`start_profiling(Rootset)`](`start_profiling/1`).","ref":"eprof.html#profile/1"},{"type":"function","title":"eprof.profile/2","doc":"If `Arg1` is a fun and `Arg2` is list, this call is equivalent to\n[`profile([], Arg1, {'_','_','_'}, Arg2)`](`profile/4`).\n\nIf `Arg1` is a list and `Arg2` is a fun, this call is equivalent to\n[`profile(Arg1, Arg2, {'_','_','_'}, Arg1)`](`profile/4`).","ref":"eprof.html#profile/2"},{"type":"function","title":"eprof.profile/3","doc":"","ref":"eprof.html#profile/3"},{"type":"function","title":"eprof.profile/4","doc":"This function spawns a process that applies a fun or an an function,\nand then starts profiling for the spawned proceses as well as the\nprocesses in `Rootset` (and any new processes spawned from them).\n\nIf `Arg1` is a fun, `Arg2` is expected to be a trace pattern, and\n`Arg3` a list of options. In that case, this call is equivalent to:\n\n[`profile(Rootset, erlang, apply, [Arg1, []], Arg2, Arg3)`](`profile/6`)\n\nIf `Arg1` is an atom, `Arg1` is assumed to be a module name, `Arg2` the\nname of the function in that module, and `Arg3` a list of arguments to\nbe used when calling that function. In that case, this call is equivalent\nto:\n\n[`profile(Rootset, Arg1, Arg2, Arg3, {'_','_','_'}, [{set_on_spawn, true}])`](`profile/6`)","ref":"eprof.html#profile/4"},{"type":"function","title":"eprof.profile/5","doc":"","ref":"eprof.html#profile/5"},{"type":"function","title":"eprof.profile/6","doc":"This function spawns a process `P` that [`apply(Module, Function,\nArgs)`](`apply/3`), and then starts profiling for `P` and the\nprocesses in `Rootset` (and any new processes spawned from them).\n\n`Rootset` is a list of pids and registered names.\n\nInformation about activity in any profiled process is stored in the Eprof\ndatabase.\n\nIf tracing could be enabled for `P` and all processes in `Rootset`, the function\nreturns `{ok,Value}` when `Fun()`/`apply` returns with the value `Value`, or\n`{error,Reason}` if `Fun()`/`apply` fails with exit reason `Reason`. Otherwise\nit returns `{error, Reason}` immediately.\n\nThe `set_on_spawn` option will active call time tracing for all processes\nspawned by processes in the rootset. This is the default behaviour.\n\nThe programmer must ensure that the function given as argument is truly\nsynchronous and that no work continues after the function has returned a value.","ref":"eprof.html#profile/6"},{"type":"function","title":"eprof.start/0","doc":"Starts the Eprof server which holds the internal state of the collected data.","ref":"eprof.html#start/0"},{"type":"function","title":"eprof.start_profiling/1","doc":"","ref":"eprof.html#start_profiling/1"},{"type":"function","title":"eprof.start_profiling/2","doc":"","ref":"eprof.html#start_profiling/2"},{"type":"function","title":"eprof.start_profiling/3","doc":"Starts profiling for the processes in `Rootset` (and any new processes spawned\nfrom them).\n\nInformation about activity in any profiled process is stored in the\nEprof database.\n\n`Rootset` is a list of pids and registered names.\n\nThe function returns `profiling` if tracing could be enabled for all processes\nin `Rootset`, or `error` otherwise.\n\nA pattern can be selected to narrow the profiling. For instance a specific\nmodule can be selected, and only the code executed in that module will be\nprofiled.\n\nThe `set_on_spawn` option will active call time tracing for all processes\nspawned by processes in the rootset. This is the default behaviour.","ref":"eprof.html#start_profiling/3"},{"type":"function","title":"eprof.stop/0","doc":"Stops the Eprof server.","ref":"eprof.html#stop/0"},{"type":"function","title":"eprof.stop_profiling/0","doc":"Stops profiling started with `start_profiling/1` or `profile/1`.","ref":"eprof.html#stop_profiling/0"},{"type":"type","title":"eprof.analyze_type/0","doc":"","ref":"eprof.html#t:analyze_type/0"},{"type":"type","title":"eprof.trace_pattern_mfa/0","doc":"","ref":"eprof.html#t:trace_pattern_mfa/0"},{"type":"module","title":"fprof","doc":"A Time Profiling Tool using trace to file for minimal runtime performance\nimpact.\n\nThis module is used to profile a program to find out how the execution time is\nused. Tracing to file is used to minimize the runtime performance degradation.\n\nThe `fprof` module uses tracing to collect profiling data, hence there is no\nneed for special compilation of any module to be profiled. When it starts\ntracing, `fprof` will erase all previous tracing in the node and set the\nnecessary trace flags on the profiling target processes as well as local call\ntrace on all functions in all loaded modules and all modules to be loaded.\n`fprof` disable all tracing in the node when it stops tracing.\n\n`fprof` presents both _own time_ that is, how much time a function has\nused for its own execution, and _accumulated time_ that is, including\ncalled functions. All presented times are collected using trace\ntimestamps. `fprof` tries to collect CPU time timestamps, if the host\nmachine OS supports it. Therefore, the times can be wallclock times and\nOS scheduling will randomly strike all called functions in a\npresumably fair way.\n\nHowever, if the profiling time is short, and the host machine OS does\nnot support high resolution CPU time measurements, a few OS\nschedulings can show up as ridiculously long execution times for\nfunctions doing practically nothing. As an example, it has been\nobserved that a function that more or less just composing a tuple, was\nrunning 100 times slower than normal. When tracing was repeated, the\nexecution time was normal.\n\nProfiling is essentially done in 3 steps:\n\n- Tracing: to a file. The trace data contains entries for function\n calls, returns to function, process scheduling, other process\n related events (for example `spawn`), and garbage collection. All trace\n entries are timestamped.\n\n- Profiling: the trace file is read, the execution call stack is\n simulated, and raw profile data is calculated from the simulated call stack\n and the trace timestamps. The profile data is stored in the `fprof` server\n state. During this step the trace data may be dumped in text format to file or\n console.\n\n- Analysing: the raw profile data is sorted, filtered and dumped in\n text format either to file or console. The text format intended to be both\n readable for a human reader, as well as parsable with the standard erlang\n parsing tools.\n\nSince `fprof` sends trace data to afile, the runtime performance\ndegradation is minimized, but still far from negligible, especially\nfor programs that themselves use the filesystem heavily. Where the\ntrace file is placed is also important, for example, on Unix systems\n`/tmp` is usually a good choice since it is essentially a RAM disk,\nwhile any network-mounted disk is a bad idea.\n\n`fprof` can also skip the file step and trace to a tracer process that does the\nprofiling in runtime.\n\n[](){: #analysis }","ref":"fprof.html"},{"type":"module","title":"Analysis format - fprof","doc":"This section describes the output format of the `analyse/1` function.\n\nThe format is parsable with the standard Erlang parsing tools\n`m:erl_scan` and `m:erl_parse`, `file:consult/1`, or `io:read/2`. The\nparse format is not described here — it should be easy enough for the\ninterested reader to try it out. Note that some flags to\n[`analyse/1`](`analyse/1`) will affect the format.\n\nThe following example was run on Erlang/OTP R8 on Solaris 8; all OTP\ninternals in this example are version dependent.\n\nAs an example, we will use the following function, which is a\nslightly modified benchmark function from module `m:file`:\n\n```erlang\n-module(foo).\n-export([create_file_slow/2]).\n\ncreate_file_slow(Name, N) when is_integer(N), N >= 0 ->\n {ok, FD} =\n file:open(Name, [raw, write, delayed_write, binary]),\n if N > 256 ->\n ok = file:write(FD,\n lists:map(fun (X) -> < > end,\n lists:seq(0, 255))),\n ok = create_file_slow(FD, 256, N);\n true ->\n ok = create_file_slow(FD, 0, N)\n end,\n ok = file:close(FD).\n\ncreate_file_slow(FD, M, M) ->\n ok;\ncreate_file_slow(FD, M, N) ->\n ok = file:write(FD, < >),\n create_file_slow(FD, M+1, N).\n```\n\nLet us have a look at the printout after running:\n\n```erlang\n1> fprof:apply(foo, create_file_slow, [junk, 1024]).\n2> fprof:profile().\n3> fprof:analyse().\n```\n\nThe printout starts with:\n\n```erlang\n%% Analysis results:\n{ analysis_options,\n [{callers, true},\n {sort, acc},\n {totals, false},\n {details, true}]}.\n\n% CNT ACC OWN\n[{ totals, 9627, 1691.119, 1659.074}]. %%%\n```\n\nThe `CNT` column shows the total number of function calls that was found in the\ntrace. In the `ACC` column is the total time of the trace from first timestamp to\nlast. And in the `OWN` column is the sum of the execution time in functions found\nin the trace, not including called functions. In this case it is very close to\nthe `ACC` time since the emulator had practically nothing to do except\nexecuting our test program.\n\nAll time values in the printout are in milliseconds.\n\nThe printout continues:\n\n```erlang\n% CNT ACC OWN\n[{ \"<0.28.0>\", 9627,undefined, 1659.074}]. %%\n```\n\nThis is the printout header of one process. The printout contains only this one\nprocess since we called `fprof:apply/3` that traces only the current process.\nTherefore the `CNT` and `OWN` columns perfectly matches the totals above. The `ACC`\ncolumn is undefined since summing the `ACC` times of all calls in the process\nmakes no sense — one would get something like the `ACC` value from totals above\nmultiplied by the average depth of the call stack.\n\nAll paragraphs up to the next process header only concerns function calls within\nthis process.\n\nNow we come to something more interesting:\n\n```erlang\n{[{undefined, 0, 1691.076, 0.030}],\n { {fprof,apply_start_stop,4}, 0, 1691.076, 0.030}, %\n [{{foo,create_file_slow,2}, 1, 1691.046, 0.103},\n {suspend, 1, 0.000, 0.000}]}.\n\n{[{{fprof,apply_start_stop,4}, 1, 1691.046, 0.103}],\n { {foo,create_file_slow,2}, 1, 1691.046, 0.103}, %\n [{{file,close,1}, 1, 1398.873, 0.019},\n {{foo,create_file_slow,3}, 1, 249.678, 0.029},\n {{file,open,2}, 1, 20.778, 0.055},\n {{lists,map,2}, 1, 16.590, 0.043},\n {{lists,seq,2}, 1, 4.708, 0.017},\n {{file,write,2}, 1, 0.316, 0.021}]}.\n```\n\nThe printout consists of one paragraph per called function. The function\n_marked_ with `%` is the one the paragraph concerns — `foo:create_file_slow/2`.\nAbove the marked function are the _calling_ functions — those that has called\nthe marked, and below are those _called_ by the marked function.\n\nThe paragraphs are per default sorted in descending order of the `ACC` column for\nthe marked function. The calling list and called list within one paragraph are\nalso per default sorted in descending order of their `ACC` column.\n\nThe columns are:\n\n* `CNT` - the number of times the function has been called\n* `ACC` - the time spent in the function including called functions\n* `OWN` - the time spent in the function not including called functions\n\nThe rows for the _calling_ functions contain statistics for the _marked_\nfunction with the constraint that only the occasions when a call was made from\nthe _row's_ function to the _marked_ function are accounted for.\n\nThe row for the _marked_ function simply contains the sum of all _calling_ rows.\n\nThe rows for the _called_ functions contains statistics for the _row's_ function\nwith the constraint that only the occasions when a call was made from the\n_marked_ to the _row's_ function are accounted for.\n\nSo, we see that `foo:create_file_slow/2` used very little time for its own\nexecution. It spent most of its time in `file:close/1`. The function\n`foo:create_file_slow/3` that writes 3/4 of the file contents is the second\nbiggest time thief.\n\nWe also see that the call to `file:write/2` that writes 1/4 of the file contents\ntakes very little time in itself. What takes time is to build the data\n(`lists:seq/2` and `lists:map/2`).\n\nThe function `undefined` that has called `fprof:apply_start_stop/4` is an\nunknown function because that call was not recorded in the trace. It was only\nrecorded that the execution returned from `fprof:apply_start_stop/4` to some\nother function above in the call stack, or that the process exited from there.\n\nLet us continue down the printout to find:\n\n```erlang\n{[{{foo,create_file_slow,2}, 1, 249.678, 0.029},\n {{foo,create_file_slow,3}, 768, 0.000, 23.294}],\n { {foo,create_file_slow,3}, 769, 249.678, 23.323}, %\n [{{file,write,2}, 768, 220.314, 14.539},\n {suspend, 57, 6.041, 0.000},\n {{foo,create_file_slow,3}, 768, 0.000, 23.294}]}.\n```\n\nIf you compare with the code you will see there also that\n`foo:create_file_slow/3` was called only from `foo:create_file_slow/2` and\nitself, and called only `file:write/2`, note the number of calls to\n`file:write/2`. But here we see that `suspend` was called a few times. This is a\npseudo function that indicates that the process was suspended while executing in\n`foo:create_file_slow/3`, and since there is no `receive` or `erlang:yield/0` in\nthe code, it must be Erlang scheduling suspensions, or the trace file driver\ncompensating for large file write operations (these are regarded as a schedule\nout followed by a schedule in to the same process).\n\nLet us find the `suspend` entry:\n\n```erlang\n{[{{file,write,2}, 53, 6.281, 0.000},\n {{foo,create_file_slow,3}, 57, 6.041, 0.000},\n {{prim_file,drv_command,4}, 50, 4.582, 0.000},\n {{prim_file,drv_get_response,1}, 34, 2.986, 0.000},\n {{lists,map,2}, 10, 2.104, 0.000},\n {{prim_file,write,2}, 17, 1.852, 0.000},\n {{erlang,port_command,2}, 15, 1.713, 0.000},\n {{prim_file,drv_command,2}, 22, 1.482, 0.000},\n {{prim_file,translate_response,2}, 11, 1.441, 0.000},\n {{prim_file,'-drv_command/2-fun-0-',1}, 15, 1.340, 0.000},\n {{lists,seq,4}, 3, 0.880, 0.000},\n {{foo,'-create_file_slow/2-fun-0-',1}, 5, 0.523, 0.000},\n {{erlang,bump_reductions,1}, 4, 0.503, 0.000},\n {{prim_file,open_int_setopts,3}, 1, 0.165, 0.000},\n {{prim_file,i32,4}, 1, 0.109, 0.000},\n {{fprof,apply_start_stop,4}, 1, 0.000, 0.000}],\n { suspend, 299, 32.002, 0.000}, %\n [ ]}.\n```\n\nWe find no particularly long suspend times, so no function seems to have waited\nin a receive statement. Actually, `prim_file:drv_command/4` contains a receive\nstatement, but in this test program, the message lies in the process receive\nbuffer when the receive statement is entered. We also see that the total suspend\ntime for the test run is small.\n\nThe `suspend` pseudo function has an `OWN` time of zero. This is to prevent\nthe process total `OWN` time from including time in suspension. Whether suspend\ntime is really `ACC` or `OWN` time is more of a philosophical question.\n\nNow we look at another interesting pseudo function, `garbage_collect`:\n\n```erlang\n{[{{prim_file,drv_command,4}, 25, 0.873, 0.873},\n {{prim_file,write,2}, 16, 0.692, 0.692},\n {{lists,map,2}, 2, 0.195, 0.195}],\n { garbage_collect, 43, 1.760, 1.760}, %\n [ ]}.\n```\n\nHere we see that no function stands out, which is very normal.\n\nThe `garbage_collect` pseudo function has not an `OWN` time of zero like\n`suspend`, instead it is equal to the `ACC` time.\n\nGarbage collection often occurs while a process is suspended, but `fprof` hides\nthis fact by pretending that the suspended function was first unsuspended and\nthen garbage collected. Otherwise the printout would show `garbage_collect`\nbeing called from `suspend`, but not which function that might have caused the\ngarbage collection.\n\nLet us now get back to the test code:\n\n```erlang\n{[{{foo,create_file_slow,3}, 768, 220.314, 14.539},\n {{foo,create_file_slow,2}, 1, 0.316, 0.021}],\n { {file,write,2}, 769, 220.630, 14.560}, %\n [{{prim_file,write,2}, 769, 199.789, 22.573},\n {suspend, 53, 6.281, 0.000}]}.\n```\n\nNot unexpectedly, we see that `file:write/2` was called from\n`foo:create_file_slow/3` and `foo:create_file_slow/2`. The number of calls in\neach case as well as the used time are also confirms the previous results.\n\nWe see that `file:write/2` only calls `prim_file:write/2`, but let us refrain\nfrom digging into the internals of the kernel application.\n\nIf we nevertheless _do_ dig down we find the call to the linked-in driver\nthat does the file operations towards the host operating system:\n\n```erlang\n{[{{prim_file,drv_command,4}, 772, 1458.356, 1456.643}],\n { {erlang,port_command,2}, 772, 1458.356, 1456.643}, %\n [{suspend, 15, 1.713, 0.000}]}.\n```\n\nThis is 86 % of the total run time, and as we saw before it is the close\noperation the absolutely biggest contributor. We find a comparison ratio a\nlittle bit up in the call stack:\n\n```erlang\n{[{{prim_file,close,1}, 1, 1398.748, 0.024},\n {{prim_file,write,2}, 769, 174.672, 12.810},\n {{prim_file,open_int,4}, 1, 19.755, 0.017},\n {{prim_file,open_int_setopts,3}, 1, 0.147, 0.016}],\n { {prim_file,drv_command,2}, 772, 1593.322, 12.867}, %\n [{{prim_file,drv_command,4}, 772, 1578.973, 27.265},\n {suspend, 22, 1.482, 0.000}]}.\n```\n\nThe time for file operations in the linked in driver distributes itself as 1 %\nfor open, 11 % for write, and 87 % for close. All data is probably buffered in\nthe operating system until the close.\n\nThe observant reader may notice that the ACC times for\n`prim_file:drv_command/2` and `prim_file:drv_command/4` is not equal between the\nparagraphs above, even though it is easy to believe that\n`prim_file:drv_command/2` is just a passthrough function.\n\nThe missing time can be found in the paragraph for `prim_file:drv_command/4`\nwhere it is evident that not only `prim_file:drv_command/2` is called but also a\nfun:\n\n```erlang\n{[{{prim_file,drv_command,2}, 772, 1578.973, 27.265}],\n { {prim_file,drv_command,4}, 772, 1578.973, 27.265}, %\n [{{erlang,port_command,2}, 772, 1458.356, 1456.643},\n {{prim_file,'-drv_command/2-fun-0-',1}, 772, 87.897, 12.736},\n {suspend, 50, 4.582, 0.000},\n {garbage_collect, 25, 0.873, 0.873}]}.\n```\n\nAnd some more missing time can be explained by the fact that\n`prim_file:open_int/4` both calls `prim_file:drv_command/2` directly as well as\nthrough `prim_file:open_int_setopts/3`, which complicates the picture.\n\n```erlang\n{[{{prim_file,open,2}, 1, 20.309, 0.029},\n {{prim_file,open_int,4}, 1, 0.000, 0.057}],\n { {prim_file,open_int,4}, 2, 20.309, 0.086}, %\n [{{prim_file,drv_command,2}, 1, 19.755, 0.017},\n {{prim_file,open_int_setopts,3}, 1, 0.360, 0.032},\n {{prim_file,drv_open,2}, 1, 0.071, 0.030},\n {{erlang,list_to_binary,1}, 1, 0.020, 0.020},\n {{prim_file,i32,1}, 1, 0.017, 0.017},\n {{prim_file,open_int,4}, 1, 0.000, 0.057}]}.\n.\n.\n.\n{[{{prim_file,open_int,4}, 1, 0.360, 0.032},\n {{prim_file,open_int_setopts,3}, 1, 0.000, 0.016}],\n { {prim_file,open_int_setopts,3}, 2, 0.360, 0.048}, %\n [{suspend, 1, 0.165, 0.000},\n {{prim_file,drv_command,2}, 1, 0.147, 0.016},\n {{prim_file,open_int_setopts,3}, 1, 0.000, 0.016}]}.\n```","ref":"fprof.html#module-analysis-format"},{"type":"module","title":"Notes - fprof","doc":"The actual supervision of execution times is in itself a CPU-intensive activity.\nA message is written on the trace file for every function call that is made by\nthe profiled code.\n\nThe `ACC` time calculation is sometimes difficult to make correct, since it is\ndifficult to define. This happens especially when a function occurs in several\ninstances in the call stack, for example by calling itself perhaps through other\nfunctions and perhaps even non-tail recursively.\n\nTo produce sensible results, `fprof` tries not to charge any function more than\nonce for `ACC` time. The instance highest up (with longest duration) in the call\nstack is chosen.\n\nSometimes a function can unexpectedly waste a lot (some 10 ms or more depending\non host machine OS) of `OWN` (and `ACC`) time, even functions that do practically\nnothing at all. The problem may be that the OS has chosen to schedule out the\nErlang runtime system process for a while, and if the OS does not support high\nresolution CPU time measurements `fprof` will use wallclock time for its\ncalculations, and it will appear as if functions are randomly burning virtual\nmachine time.","ref":"fprof.html#module-notes"},{"type":"module","title":"See Also - fprof","doc":"[fprof - The File Trace Profiler](fprof_chapter.md), `m:dbg`, `m:eprof`","ref":"fprof.html#module-see-also"},{"type":"function","title":"fprof.analyse/0","doc":"","ref":"fprof.html#analyse/0"},{"type":"function","title":"fprof.analyse/1","doc":"Analyses raw profile data in the `fprof` server.\n\nIf `Arg` is an atom, this call is equivalent to `analyse([Arg])`.\n\nIf `Arg` is a a tuple `{Option, _}`, this call is equivalent to\n`analyse([Option])`.\n\nOtherwise `Arg` must be a list of valid options.\n\nIf called when no raw profile data is available, `{error, no_profile}`\nis returned.\n\n`Destfile` is used to call `file:open/2`.\n\nOption description:\n\n- **`dest` | `{dest, Dest}`** - Specifies the destination for the analysis. If\n this option is not given or it is `dest`, the destination will be the caller's\n group leader, otherwise the destination `Dest` is either the `t:pid/0` of an\n I/O device or a filename. If the filename is `[]`, `\"fprof.analysis\"` is used\n instead.\n\n- **`append`** - Causes the analysis to be appended to the destination file.\n This option is only allowed with the `{dest, Destfile}` option.\n\n- **`{cols, Cols}`** - Specifies the number of columns in the analysis text. If\n this option is not given the number of columns is set to 80.\n\n- **`callers` | `{callers, true}`** - Prints callers and called information in\n the analysis. This is the default.\n\n- **`{callers, false}` | `no_callers`** - Suppresses the printing of callers and\n called information in the analysis.\n\n- **`{sort, SortSpec}`** - Specifies if the analysis should be sorted according\n to the ACC column, which is the default, or the OWN column. See\n [Analysis Format](`m:fprof#analysis`) below.\n\n- **`totals` | `{totals, true}`** - Includes a section containing call\n statistics for all calls regardless of process, in the analysis.\n\n- **`{totals, false}`** - Suppresses the totals section in the analysis, which\n is the default.\n\n- **`details` | `{details, true}`** - Prints call statistics for each process in\n the analysis. This is the default.\n\n- **`{details, false}` | `no_details`** - Suppresses the call statistics for\n each process from the analysis.","ref":"fprof.html#analyse/1"},{"type":"function","title":"fprof.analyse/2","doc":"","ref":"fprof.html#analyse/2"},{"type":"function","title":"fprof.apply/2","doc":"","ref":"fprof.html#apply/2"},{"type":"function","title":"fprof.apply/3","doc":"Calls the given function surrounded by\n[`trace([start, ...])`](`trace/1`) and\n[`trace(stop)`](`trace/1`).\n\nIf the function arguments (`Arg1`, `Arg2`, and `Arg3`) are `Module`\n(an atom), `Function` (an atom), and `Args` (a list), the function\nwill be called using\n[`erlang:apply(Module, Function, Args)`](`erlang:apply/3`).\n\nIf the function arguments are `Func` (a fun), `Args` (a list), and\n`OptionList` (a list of options), the fun will be called using\n[`erlang:apply(Func, Args)`](`erlang:apply/2`).\n\nSome effort is made to keep the trace clean from unnecessary trace messages;\ntracing is started and stopped from a spawned process while `erlang:apply/2`\nis called in the current process only surrounded by `receive` and `send`\nstatements towards the trace starting process. The trace starting process exits\nwhen it is not needed any more.\n\nThe `TraceStartOption` is any option allowed for `trace/1`. The\noptions `[start, {procs, [self() | PidList]} | OptList]` are given to\n[`trace/1`](`trace/1`), where `OptList` is `OptionList` with the\n`continue`, `start` and `{procs, _}` options removed.\n\nThe `continue` option inhibits the call to [`trace(stop)`](`trace/1`) and leaves\nit up to the caller to stop tracing at a suitable time.","ref":"fprof.html#apply/3"},{"type":"function","title":"fprof.apply/4","doc":"","ref":"fprof.html#apply/4"},{"type":"function","title":"fprof.profile/0","doc":"","ref":"fprof.html#profile/0"},{"type":"function","title":"fprof.profile/1","doc":"Compiles a trace into raw profile data held by the `fprof` server.\n\nIf `Arg` is an atom, this call is equivalent to `profile([Arg])`.\n\nIf `Arg` is a tuple `{OptionName, OptionValue}`,\nthis call is equivalent to `profile([Arg])`.\n\nOtherwise, `Arg` must be a list of options.\n\n`Dumpfile` is used to call `file:open/2`, and `Filename` is used to call\n[`dbg:trace_port(file, Filename)`](`dbg:trace_port/2`).\n\nThe following options are supported:\n\n- **`file` | `{file, Filename}`** - Reads the file `Filename` and creates raw\n profile data that is stored in RAM by the `fprof` server. If the option `file`\n is given, or none of these options are given, the file `fprof.trace` is\n read. The call will return when the whole trace has been read with the return\n value `ok` if successful. This option is not allowed with the `start` or\n `stop` options.\n\n- **`dump` | `{dump, Dump}`** - Specifies the destination for the trace text\n dump. If this option is not given, no dump is generated, if it is `dump` the\n destination will be the caller's group leader, otherwise the destination\n `Dump` is either the pid of an I/O device or a filename. If the\n filename is `[]`, `\"fprof.dump\"` is used instead. This option cannot be\n combined with the `stop` option.\n\n- **`append`** - Causes the trace text dump to be appended to the destination\n file. This option is only allowed with the `{dump, Dumpfile}` option.\n\n- **`start`** - Starts a tracer process that profiles trace data in runtime. The\n call will return immediately with the return value `{ok, Tracer}` if\n successful. This option is not allowed with the `stop`, `file`, or\n `{file, Filename}` options.\n\n- **`stop`** - Stops the tracer process that profiles trace data in runtime. The\n return value will be value `ok` if successful. This option cannot be combined\n with the `start`, `file`, or `{file, Filename}` options.","ref":"fprof.html#profile/1"},{"type":"function","title":"fprof.profile/2","doc":"","ref":"fprof.html#profile/2"},{"type":"function","title":"fprof.start/0","doc":"Starts the `fprof` server.\n\nNote that there is seldom any need to call this function directly, since\nthe server will be automatically started by any function that will need it.","ref":"fprof.html#start/0"},{"type":"function","title":"fprof.stop/0","doc":"","ref":"fprof.html#stop/0"},{"type":"function","title":"fprof.stop/1","doc":"Stops the `fprof` server.\n\nThe supplied `Reason` becomes the exit reason for the server process. By default,\nany `Reason` other than `kill` sends a request to the server and waits for it to\nclean up, reply, and exit. If `Reason` is `kill`, the server is bluntly killed.\n\nIf the `fprof` server is not running, this function returns immediately.\n\n> #### Note {: .info }\n>\n> When the `fprof` server is stopped the collected raw profile data is lost.","ref":"fprof.html#stop/1"},{"type":"function","title":"fprof.trace/1","doc":"Starts or stops tracing.\n\nIf `Arg` is atom `verbose`, this call is equivalent to\n`trace([start, verbose])`.\n\nIf `Arg` is an atom, this call is equivalent to\n`trace([Arg])`.\n\nIf `Arg` is a tuple `{OptionName, OptionValue}`, this call is equivalent to\n`trace([Arg])`.\n\nOtherwise, `Arg` has to be a list of [trace options](`t:trace_option/0`).\n\n`PidSpec` and `Tracer` are used in calls to\n[`erlang:trace(PidSpec, true, [{tracer, Tracer} | Flags])`](`erlang:trace/3`),\nand `Filename` is used to call\n[`dbg:trace_port(file, Filename)`](`dbg:trace_port/2`).\n\nOption description:\n\n- **`stop`** - Stops a running `fprof` trace and clears all tracing from the\n node. Either option `stop` or `start` must be specified, but not both.\n\n- **`start`** - Clears all tracing from the node and starts a new `fprof` trace.\n Either option `start` or `stop` must be specified, but not both.\n\n- **`verbose` | `{verbose, boolean()}`** - The `verbose` or\n `{verbose, true}` options add some trace flags that `fprof` does not need, but that\n can be interesting for general debugging purposes. These options are only allowed\n with the `start` option.\n\n- **`cpu_time` | `{cpu_time, boolean()}`** - The `cpu_time` or\n `{cpu_time, true}` options make the timestamps in the trace be in CPU time instead of\n the default wallclock time. These options are only allowed with the\n `start` option.\n\n > #### Note {: .info }\n >\n > Getting correct values out of `cpu_time` can be difficult. The best way to get\n > correct values is to run using a single scheduler and bind that scheduler to\n > a specific CPU. For example:\n >\n > ```bash\n > erl +S 1 +sbt db`\n > ```\n\n- **`{procs, PidSpec}` | `{procs, [PidSpec]}`** - Specifies which processes that\n should be traced. If this option is not given, the calling process is traced.\n All processes spawned by the traced processes are also traced. This option is\n only allowed with the `start` option.\n\n- **`file` | `{file, Filename}`** - Specifies the filename of the trace. If the\n option `file` is given, or none of these options are given, the file\n `fprof.trace` is used. This option is only allowed with the `start` option,\n but not with the `{tracer, Tracer}` option.\n\n- **`{tracer, Tracer}`** - Specifies that trace to process or port shall be done\n instead of trace to file. This option is only allowed with the `start` option,\n but not with the `{file, Filename}` option.","ref":"fprof.html#trace/1"},{"type":"function","title":"fprof.trace/2","doc":"Starts or stop tracing.\n\nIf `What` is atom `start`, this call is equivalent to\n[`trace([start, {file, Value}])`](`trace/1`).\n\nIf `What` is atom `verbose`, this call is equivalent to\n[`trace([start, verbose, {file, Value}])`](`trace/1`).\n\nIf `What` is a tuple `{OptionName, OptionValue}`,\nthis call is equivalent to\n[`trace([What])`](`trace/1`).","ref":"fprof.html#trace/2"},{"type":"type","title":"fprof.analyse_option/0","doc":"","ref":"fprof.html#t:analyse_option/0"},{"type":"type","title":"fprof.apply_option/0","doc":"","ref":"fprof.html#t:apply_option/0"},{"type":"type","title":"fprof.pid_spec/0","doc":"","ref":"fprof.html#t:pid_spec/0"},{"type":"type","title":"fprof.profile_option/0","doc":"","ref":"fprof.html#t:profile_option/0"},{"type":"type","title":"fprof.trace_option/0","doc":"","ref":"fprof.html#t:trace_option/0"},{"type":"module","title":"lcnt","doc":"A runtime system Lock Profiling tool.\n\nThe `lcnt` module is used to profile the internal ethread locks in the Erlang\nRuntime System. With `lcnt` enabled, internal counters in the runtime system are\nupdated each time a lock is taken. The counters stores information about the\nnumber of acquisition tries and the number of collisions that has occurred\nduring the acquisition tries. The counters also record the waiting time a lock\nhas caused for a blocked thread when a collision has occurred.\n\nThe data produced by the lock counters will give an estimate on how well the\nruntime system will behave from a parallelizable view point for the scenarios\ntested. This tool was mainly developed to help Erlang runtime developers iron\nout potential and generic bottlenecks.\n\nLocks in the emulator are named after what type of resource they protect and\nwhere in the emulator they are initialized, those are lock 'classes'. Most of\nthose locks are also instantiated several times, and given unique identifiers,\nto increase locking granularity. Typically an instantiated lock protects a\ndisjunct set of the resource, for example ets tables, processes or ports. In\nother cases it protects a specific range of a resource, for example `pix_lock`\nwhich protects index to process mappings, and is given a unique number within\nthe class. A unique lock in `lcnt` is referenced by a name (class) and an\nidentifier: `{Name, Id}`.\n\nSome locks in the system are static and protects global resources, for example\n`bif_timers` and the `run_queue` locks. Other locks are dynamic and not\nnecessarily long lived, for example process locks and ets-table locks. The\nstatistics data from short lived locks can be stored separately when the locks\nare deleted. This behavior is by default turned off to save memory but can be\nturned on via `lcnt:rt_opt({copy_save, true})`. The `lcnt:apply/1,2,3` functions\nenables this behavior during profiling.","ref":"lcnt.html"},{"type":"module","title":"See Also - lcnt","doc":"[LCNT User's Guide](lcnt_chapter.md)","ref":"lcnt.html#module-see-also"},{"type":"function","title":"lcnt.apply/1","doc":"","ref":"lcnt.html#apply/1"},{"type":"function","title":"lcnt.apply/2","doc":"Sets up lock counters, applies `Fun` with `Args`, and cleans up.\n\nClears the lock counters and then setups the instrumentation to save all\ndestroyed locks. After setup the function is called, passing the elements in\n`Args` as arguments. When the function returns the statistics are immediately\ncollected to the server. After the collection the instrumentation is returned to\nits previous behavior. The result of the applied function is returned.\n\n> #### Warning {: .warning }\n>\n> This function should only be used for micro-benchmarks; it sets `copy_save` to\n> `true` for the duration of the call, which can quickly lead to running out of\n> memory.","ref":"lcnt.html#apply/2"},{"type":"function","title":"lcnt.apply/3","doc":"","ref":"lcnt.html#apply/3"},{"type":"function","title":"lcnt.clear/0","doc":"","ref":"lcnt.html#clear/0"},{"type":"function","title":"lcnt.clear/1","doc":"Clears the internal lock statistics from the runtime system.\n\nThis clears the data in the runtime system but not in server. All\ncounters for static locks are zeroed, all dynamic locks currently\nalive are zeroed and all saved locks now destroyed are removed. It\nalso resets the duration timer.","ref":"lcnt.html#clear/1"},{"type":"function","title":"lcnt.collect/0","doc":"","ref":"lcnt.html#collect/0"},{"type":"function","title":"lcnt.collect/1","doc":"Collects lock statistics from the runtime system.\n\nThe function starts a server if it is not already started. It then\npopulates the server with lock statistics. If the server held any\nlock statistics data before the collect then that data is lost.","ref":"lcnt.html#collect/1"},{"type":"function","title":"lcnt.conflicts/0","doc":"","ref":"lcnt.html#conflicts/0"},{"type":"function","title":"lcnt.conflicts/1","doc":"Prints a list of internal locks and its statistics.\n\nFor option description, see [`lcnt:inspect/2`](`inspect/2`).","ref":"lcnt.html#conflicts/1"},{"type":"function","title":"lcnt.information/0","doc":"Prints `lcnt` server state and generic information about collected lock\nstatistics.","ref":"lcnt.html#information/0"},{"type":"function","title":"lcnt.inspect/1","doc":"","ref":"lcnt.html#inspect/1"},{"type":"function","title":"lcnt.inspect/2","doc":"Prints a list of internal lock counters for a specific lock.\n\nLock `Name` and `Id` for ports and processes are interchangeable with the use of\n[`lcnt:swap_pid_keys/0`](`swap_pid_keys/0`) and is the reason why `t:pid/0` and\n`t:port/0` options can be used in both `Name` and `Id` space. Both pids and\nports are special identifiers with stripped creation and can be recreated with\n[`lcnt:pid/2,3`](`pid/3`) and [`lcnt:port/1,2`](`port/2`).\n\nOption description:\n\n- **`{combine, boolean()}`** - Combine the statistics from different instances\n of a lock class. \n Default: `true`\n\n- **`{locations, boolean()}`** - Print the statistics by source file and line\n numbers. \n Default: `false`\n\n- **`{max_locks, MaxLocks}`** - Maximum number of locks printed or no limit with\n `none`. \n Default: `20`\n\n- **`{print, PrintOptions}`** - Printing options:\n\n - **`name`** - Named lock or named set of locks (classes). The same name used\n for initializing the lock in the VM.\n\n - **`id`** - Internal id for set of locks, not always unique. This could be\n table name for ets tables (db_tab), port id for ports, integer identifiers\n for allocators, etc.\n\n - **`type`** - Type of lock: `rw_mutex`, `mutex`, `spinlock`, `rw_spinlock` or\n `proclock`.\n\n - **`entry`** - In combination with `{locations, true}` this option prints the\n lock operations source file and line number entry-points along with\n statistics for each entry.\n\n - **`tries`** - Number of acquisitions of this lock.\n\n - **`colls`** - Number of collisions when a thread tried to acquire this lock.\n This is when a trylock is EBUSY, a write try on read held rw_lock, a try\n read on write held rw_lock, a thread tries to lock an already locked lock.\n (Internal states supervises this.)\n\n - **`ratio`** - The ratio between the number of collisions and the number of\n tries (acquisitions) in percentage.\n\n - **`time`** - Accumulated waiting time for this lock. This could be greater\n than actual wall clock time, it is accumulated for all threads. Trylock\n conflicts does not accumulate time.\n\n - **`duration`** - Percentage of accumulated waiting time of wall clock time.\n This percentage can be higher than 100% since accumulated time is from all\n threads.\n\n Default: `[name,id,tries,colls,ratio,time,duration]`\n\n- **`{reverse, boolean()}`** - Reverses the order of sorting. \n Default: `false`\n\n- **`{sort, Sort}`** - Column sorting orders. \n Default: `time`\n\n- **`{thresholds, Thresholds}`** - Filtering thresholds. Anything values above\n the threshold value are passed through. \n Default: `[{tries, 0}, {colls, 0}, {time, 0}]`","ref":"lcnt.html#inspect/2"},{"type":"function","title":"lcnt.load/1","doc":"Restores previously saved data to the server.","ref":"lcnt.html#load/1"},{"type":"function","title":"lcnt.locations/0","doc":"","ref":"lcnt.html#locations/0"},{"type":"function","title":"lcnt.locations/1","doc":"Prints a list of internal lock counters by source code locations.\n\nFor option description, see [`lcnt:inspect/2`](`inspect/2`).","ref":"lcnt.html#locations/1"},{"type":"function","title":"lcnt.pid/2","doc":"","ref":"lcnt.html#pid/2"},{"type":"function","title":"lcnt.pid/3","doc":"Creates a process id with creation 0.","ref":"lcnt.html#pid/3"},{"type":"function","title":"lcnt.port/1","doc":"","ref":"lcnt.html#port/1"},{"type":"function","title":"lcnt.port/2","doc":"Creates a port id with creation 0.","ref":"lcnt.html#port/2"},{"type":"function","title":"lcnt.rt_clear/0","doc":"","ref":"lcnt.html#rt_clear/0"},{"type":"function","title":"lcnt.rt_clear/1","doc":"Clear the internal counters.\n\nEquivalent to [`lcnt:clear(Node)`](`clear/1`).","ref":"lcnt.html#rt_clear/1"},{"type":"function","title":"lcnt.rt_collect/0","doc":"","ref":"lcnt.html#rt_collect/0"},{"type":"function","title":"lcnt.rt_collect/1","doc":"Returns a list of raw lock counter data.","ref":"lcnt.html#rt_collect/1"},{"type":"function","title":"lcnt.rt_mask/0","doc":"Return the current category mask for the current node.","ref":"lcnt.html#rt_mask/0"},{"type":"function","title":"lcnt.rt_mask/1","doc":"Sets the current lock category mask for the current node or\nretrieves the current mask for a remote node.\n\nIf `Arg` is an atom, it is assumed to be a node, and this\ncall returns the current lock category mask for node `Arg`.\n\nIf `Arg` is a list, this call is equivalent to\n[`rt_mask(node(), Arg)`](`rt_mask/2`).","ref":"lcnt.html#rt_mask/1"},{"type":"function","title":"lcnt.rt_mask/2","doc":"Sets the lock category mask according to `Categories` on node `Node`.\n\nThis call will fail if the `copy_save` option is enabled; see\n[`lcnt:rt_opt/2`](`rt_opt/2`).\n\nValid categories are:\n\n- `allocator`\n- `db` (ETS tables)\n- `debug`\n- `distribution`\n- `generic`\n- `io`\n- `process`\n- `scheduler`\n\nThis list is subject to change at any time, as is the category any given lock\nbelongs to.","ref":"lcnt.html#rt_mask/2"},{"type":"function","title":"lcnt.rt_opt/1","doc":"","ref":"lcnt.html#rt_opt/1"},{"type":"function","title":"lcnt.rt_opt/2","doc":"Sets a single option on node `Node`.\n\nOption description:\n\n- **`{copy_save, boolean()}`** - Retains the statistics of destroyed locks. \n Default: `false`\n\n > #### Warning {: .warning }\n >\n > This option will use a lot of memory when enabled, which must be reclaimed\n > with [`lcnt:rt_clear/0,1`](`lcnt:rt_clear/1`). Note that it makes no\n > distinction between locks that were destroyed and locks for which counting\n > was disabled, so enabling this option will disable changes to the lock\n > category mask.\n\n- **`{process_locks, boolean()}`** - Profile process locks, equal to adding\n `process` to the lock category mask; see `lcnt:rt_mask/2`. \n Default: `true`","ref":"lcnt.html#rt_opt/2"},{"type":"function","title":"lcnt.save/1","doc":"Saves the collected data to file.","ref":"lcnt.html#save/1"},{"type":"function","title":"lcnt.start/0","doc":"Starts the lock profiler server.\n\nThe server only act as a medium for the user and performs filtering\nand printing of data collected by `lcnt:collect/1`.","ref":"lcnt.html#start/0"},{"type":"function","title":"lcnt.stop/0","doc":"Stops the lock profiler server.","ref":"lcnt.html#stop/0"},{"type":"function","title":"lcnt.swap_pid_keys/0","doc":"Swaps places on `Name` and `Id` space for ports and processes.","ref":"lcnt.html#swap_pid_keys/0"},{"type":"type","title":"lcnt.category_atom/0","doc":"","ref":"lcnt.html#t:category_atom/0"},{"type":"type","title":"lcnt.lock_counter_data/0","doc":"","ref":"lcnt.html#t:lock_counter_data/0"},{"type":"type","title":"lcnt.option/0","doc":"","ref":"lcnt.html#t:option/0"},{"type":"type","title":"lcnt.print/0","doc":"","ref":"lcnt.html#t:print/0"},{"type":"type","title":"lcnt.sort/0","doc":"","ref":"lcnt.html#t:sort/0"},{"type":"type","title":"lcnt.threshold/0","doc":"","ref":"lcnt.html#t:threshold/0"},{"type":"module","title":"make","doc":"A Make Utility for Erlang\n\nThe module `make` provides a set of functions similar to the UNIX type `Make`\nfunctions.","ref":"make.html"},{"type":"module","title":"Emakefile - make","doc":"[`make:all/0,1`](`all/1`) and [`make:files/1,2`](`files/2`) first looks for\n`{emake, Emake}` in options, then in the current working directory for a file\nnamed `Emakefile`. If present `Emake` should contain elements like this:\n\n```text\nModules.\n{Modules,Options}.\n```\n\n`Modules` is an atom or a list of atoms. It can be\n\n- a module name, for exmaple, `file1`\n- a module name in another directory, for exmaple, `'../foo/file3'`\n- a set of modules specified with a wildcards, for exmaple, `'file*'`\n- a wildcard indicating all modules in current directory, that is: `'*'`\n- a list of any of the above, for exmaple, `['file*','../foo/file3','File4']`\n\n`Options` is a list of compiler options.\n\n`Emakefile` is read from top to bottom. If a module matches more than one entry,\nthe first match is used. For example, the following `Emakefile` means that\n`file1` should be compiled with the options `[debug_info,{i,\"../foo\"}]`, while\nall other files in the current directory should be compiled with only the\n`debug_info` flag.\n\n```erlang\n{'file1',[debug_info,{i,\"../foo\"}]}.\n{'*',[debug_info]}.\n```","ref":"make.html#module-emakefile"},{"type":"module","title":"See Also - make","doc":"[The Compiler Application](`m:compile`)","ref":"make.html#module-see-also"},{"type":"function","title":"make.all/0","doc":"","ref":"make.html#all/0"},{"type":"function","title":"make.all/1","doc":"This function determines the set of modules to compile and the compile options\nto use, by first looking for the `emake` make option, if not present reads the\nconfiguration from a file named `Emakefile` (see below). If no such file is\nfound, the set of modules to compile defaults to all modules in the current\nworking directory.\n\nTraversing the set of modules, it then recompiles every module for which at\nleast one of the following conditions apply:\n\n- there is no object file, or\n- the source file has been modified since it was last compiled, or,\n- an include file has been modified since the source file was last compiled.\n\nAs a side effect, the function prints the name of each module it tries to\ncompile. If compilation fails for a module, the make procedure stops and `error`\nis returned.\n\n`Options` is a list of options for `make` and the Erlang compiler. The following\n`make` options exist:\n\n- `noexec`\n No execution mode. Just prints the name of each module that needs to be\n compiled.\n- `load`\n Load mode. Loads all recompiled modules.\n- `netload`\n Net load mode. Loads all recompiled modules on all known nodes.\n- `{emake, Emake}`\n Rather than reading the `Emakefile` specify configuration explicitly.\n\nAll items in `Options` that are not make options are assumed to be compiler\noptions and are passed as-is to `compile:file/2`.","ref":"make.html#all/1"},{"type":"function","title":"make.files/1","doc":"","ref":"make.html#files/1"},{"type":"function","title":"make.files/2","doc":"This function does exactly the same thing as [`all/0,1`](`all/0`), but for the\nspecified `ModFiles`, which is a list of module or file names.\n\nThe file extension `.erl` can be omitted.\n\nThe `Emakefile` (if it exists) in the current directory is searched for compiler\noptions for each module. If a given module does not exist in `Emakefile` or if\n`Emakefile` does not exist, the module is still compiled.","ref":"make.html#files/2"},{"type":"module","title":"tags","doc":"Generate Emacs TAGS file from Erlang source files\n\nA `TAGS` file is used by Emacs to find function and variable definitions in any\nsource file in large projects. This module can generate a `TAGS` file from\nErlang source files. It recognises functions, records, and macro definitions.","ref":"tags.html"},{"type":"module","title":"Options - tags","doc":"The functions in this module have an optional argument `Options`. It\nis a list which can contain the following elements:\n\n- `{outfile, NameOfTAGSFile}` Create a `TAGS` file named `NameOfTAGSFile`.\n- `{outdir, NameOfDirectory}` Create a file named `TAGS` in the directory\n `NameOfDirectory`.\n\nThe default behaviour is to create a file named `TAGS` in the current directory.","ref":"tags.html#module-options"},{"type":"module","title":"Examples - tags","doc":"- `tags:root([{outfile, \"root.TAGS\"}]).`\n\n This command will create a file named `root.TAGS` in the current directory.\n The file will contain references to all Erlang source files in the Erlang\n distribution.\n\n- `tags:files([\"foo.erl\", \"bar.erl\", \"baz.erl\"], [{outdir, \"../projectdir\"}]).`\n\n This command will create a file named `TAGS` placed it in the\n directory `../projectdir`. The file contains information about the\n functions, records, and macro definitions of the three files.","ref":"tags.html#module-examples"},{"type":"module","title":"See Also - tags","doc":"- Richard M. Stallman. GNU Emacs Manual, chapter \"Editing Programs\", section\n \"Tag Tables\". Free Software Foundation, 1995.\n- Anders Lindgren. The Erlang editing mode for Emacs. Ericsson, 1998.","ref":"tags.html#module-see-also"},{"type":"function","title":"tags.dir/1","doc":"","ref":"tags.html#dir/1"},{"type":"function","title":"tags.dir/2","doc":"Create a `TAGS` file for all files in directory `Dir`.","ref":"tags.html#dir/2"},{"type":"function","title":"tags.dirs/1","doc":"","ref":"tags.html#dirs/1"},{"type":"function","title":"tags.dirs/2","doc":"Create a `TAGS` file for all files in any directory in `DirList`.","ref":"tags.html#dirs/2"},{"type":"function","title":"tags.file/1","doc":"","ref":"tags.html#file/1"},{"type":"function","title":"tags.file/2","doc":"Create a `TAGS` file for the file `File`.","ref":"tags.html#file/2"},{"type":"function","title":"tags.files/1","doc":"","ref":"tags.html#files/1"},{"type":"function","title":"tags.files/2","doc":"Create a `TAGS` file for the files in the list `FileList`.","ref":"tags.html#files/2"},{"type":"function","title":"tags.root/0","doc":"","ref":"tags.html#root/0"},{"type":"function","title":"tags.root/1","doc":"Create a `TAGS` file covering all files in the Erlang distribution.","ref":"tags.html#root/1"},{"type":"function","title":"tags.subdir/1","doc":"","ref":"tags.html#subdir/1"},{"type":"function","title":"tags.subdir/2","doc":"Descend recursively into the directory `Dir` and create a `TAGS` file based on\nall files found.","ref":"tags.html#subdir/2"},{"type":"function","title":"tags.subdirs/1","doc":"","ref":"tags.html#subdirs/1"},{"type":"function","title":"tags.subdirs/2","doc":"Descend recursively into the directories in `DirList` and create a `TAGS`\nfile based on all files found.","ref":"tags.html#subdirs/2"},{"type":"type","title":"tags.option/0","doc":"","ref":"tags.html#t:option/0"},{"type":"module","title":"tprof","doc":"Process Tracing Profiling Tool\n\n`tprof` provides convenience helpers for Erlang process profiling using\nthe trace BIFs.\n\n> #### Warning {: .warning }\n>\n> This module aims to replace `eprof` and `cprof` into a unified API for\n> measuring call count, time, and allocation. It is experimental in Erlang/OTP\n> 27.0.\n\nIt is possible to analyze the number of calls, the time spent by function, and\nheap allocations by function. Profiling can be done [ad-hoc](#module-ad-hoc-profiling)\n or run in a [server-aided mode](#module-server-aided-profiling) for deeper\nintrospection of the code running in production. The server-aided mode can be\nrun using the default tprof server or an isolated `t:server/0` started through\n[`start(#{ session => atom() })`](`start/1`).\n\nThere are [three kinds of profiling](`t:trace_type/0`) supported by this module:\n\n- `call_count`\n- `call_time`\n- `call_memory`\n\nThe default is `call_count`, which has the smallest peformance impact\nand memory footprint, but it does not support per-process\nprofiling. For this reason, all of the examples below uses\n`call_memory`, which measures heap allocation, and provide a more complex\nfeature set to demonstrate.\n\nErlang terms that do not fit in a single machine word are allocated on\nthe process heap. For example, a function returning a tuple of two\nelements needs to allocate the tuple on the process heap. The actual\nconsumption is three words, because the runtime systems also need an\nextra word to store the tuple size.\n\n> #### Note {: .info }\n>\n> Expect a slowdown in the program execution when profiling is enabled.\n>\n> For profiling convenience, measurements are accumulated for functions that are\n> not enabled in some trace pattern. Consider this call stack example:\n>\n> ```text\n> top_traced_function(...)\n> not_traced_function()\n> bottom_traced_function()\n> ```\n>\n> Allocations that happened within `not_traced_function` will be added to\n> the allocations for `top_traced_function`. However, allocations that occurred\n> within `bottom_traced_function` are not included in the `top_traced_function`.\n> To only keep track of each function own allocations, it is necessary to\n> trace all functions.\n\n> #### Warning {: .warning }\n>\n> Avoid hot code reloading for modules participating in the tracing.\n> Reloading a module disables tracing and discards the accumulated statistics.\n> The `tprof` results will probably be incorrect when the profiled code was\n> reloading during a profiling session.","ref":"tprof.html"},{"type":"module","title":"Ad-hoc profiling - tprof","doc":"Ad-hoc profiling is convenient for profiling a single function call.\n\nFor example:\n\n```erlang\n1> tprof:profile(lists, seq, [1, 16], #{type => call_memory}).\n\n****** Process <0.92.0> -- 100.00% of total *** \nFUNCTION CALLS WORDS PER CALL [ %]\nlists:seq_loop/3 5 32 6.40 [100.00]\n 32 [ 100.0]\nok\n```\n\nBy default tracing is enabled for all functions in all modules. When funs\nare created in the interactive shell, parts of shell code are also traced:\n\n```erlang\n1> tprof:profile(fun() -> lists:seq(1, 16) end, #{type => call_memory}).\n\n****** Process <0.95.0> -- 100.00% of total *** \nFUNCTION CALLS WORDS PER CALL [ %]\nerl_eval:do_apply/7 1 3 3.00 [ 3.61]\nerl_eval:match_list/6 1 3 3.00 [ 3.61]\nlists:reverse/1 1 4 4.00 [ 4.82]\nerl_eval:expr_list/7 3 7 2.33 [ 8.43]\nerl_eval:ret_expr/3 4 16 4.00 [19.28]\nerl_eval:merge_bindings/4 3 18 6.00 [21.69]\nlists:seq_loop/3 5 32 6.40 [38.55]\n 83 [100.0]\nok\n```\n\nHowever, it is possible to limit the trace to specific functions or modules:\n\n```erlang\n2> tprof:profile(fun() -> lists:seq(1, 16) end,\n #{type => call_memory, pattern => [{lists, seq_loop, '_'}]}).\n****** Process <0.98.0> -- 100.00% of total *** \nFUNCTION CALLS WORDS PER CALL [ %]\nlists:seq_loop/3 5 32 6.40 [100.00]\n 32 [ 100.0]\n\nok\n```\n\nAd-hoc profiling results can be printed in a few different ways. The following\nexamples use the `test` module defined like this:\n\n```erlang\n-module(test).\n-export([test_spawn/0]).\ntest_spawn() ->\n {Pid, MRef} = spawn_monitor(fun () -> lists:seq(1, 32) end),\n receive\n {'DOWN', MRef, process, Pid, normal} ->\n done\n end.\n```\n\nBy default per-process statistics is shown:\n\n```erlang\n1> tprof:profile(test, test_spawn, [], #{type => call_memory}).\n\n****** Process <0.176.0> -- 23.66 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\nerlang:spawn_monitor/1 1 2 2 [ 9.09]\nerlang:spawn_opt/4 1 6 6 [27.27]\ntest:test_spawn/0 1 14 14 [63.64]\n 22 [100.0]\n\n****** Process <0.177.0> -- 76.34 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\nerlang:apply/2 1 7 7 [ 9.86]\nlists:seq_loop/3 9 64 7 [90.14]\n 71 [100.0]\n```\n\nThe following example prints the combined memory allocation of all\nprocesses, sorted by the total number of allocated words in descending\norder:\n\n```erlang\n2> tprof:profile(test, test_spawn, [],\n #{type => call_memory, report => {total, {measurement, descending}}}).\n\nFUNCTION CALLS WORDS PER CALL [ %]\nlists:seq_loop/3 9 64 7 [68.82]\ntest:test_spawn/0 1 14 14 [15.05]\nerlang:apply/2 1 7 7 [ 7.53]\nerlang:spawn_opt/4 1 6 6 [ 6.45]\nerlang:spawn_monitor/1 1 2 2 [ 2.15]\n 93 [100.0]\n```\n\nThe profiling data can also be collected for further inspection:\n\n```erlang\n3> {done, ProfileData} = tprof:profile(fun test:test_spawn/0,\n #{type => call_memory, report => return}).\n<...>\n4> tprof:format(tprof:inspect(ProfileData, process, {percent, descending})).\n\n****** Process <0.223.0> -- 23.66 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\ntest:test_spawn/0 1 14 14 [63.64]\nerlang:spawn_opt/4 1 6 6 [27.27]\nerlang:spawn_monitor/1 1 2 2 [ 9.09]\n 22 [100.0]\n\n****** Process <0.224.0> -- 76.34 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\nlists:seq_loop/3 9 64 7 [90.14]\nerlang:apply/2 1 7 7 [ 9.86]\n 71 [100.0]\n```\n\nWhich processes that are profiled depends on the profiling type.\n\n* `call_count` (default) counts calls in all processes.\n\n* `call_time` and `call_memory` limits the profiling to the processes\n spawned from the user-provided function (using the `set_on_spawn`\n option for `trace:process/4`).\n\n`call_time` and `call_memory` can be restricted to profile a single process:\n\n```erlang\n2> tprof:profile(test, test_spawn, [],\n #{type => call_memory, set_on_spawn => false}).\n\n****** Process <0.183.0> -- 100.00 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\nerlang:spawn_monitor/1 1 2 2 [ 9.09]\nerlang:spawn_opt/4 1 6 6 [27.27]\ntest:test_spawn/0 1 14 14 [63.64]\n```\n\n[](){: #pg_example }\n\nErlang programs can perform expensive operations in other processes\nthan the original one. You can include multiple, new, or even all\nprocesses in the trace when measuring time or memory:\n\n```erlang\n7> pg:start_link().\n{ok,<0.252.0>}\n8> tprof:profile(fun() -> pg:join(group, self()) end,\n #{type => call_memory, rootset => [pg]}).\n****** Process <0.252.0> -- 52.86 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\npg:leave_local_update_ets/5 1 2 2 [ 1.80]\ngen:reply/2 1 3 3 [ 2.70]\nerlang:monitor/2 1 3 3 [ 2.70]\ngen_server:try_handle_call/4 1 3 3 [ 2.70]\ngen_server:try_dispatch/4 1 3 3 [ 2.70]\nmaps:iterator/1 2 4 2 [ 3.60]\nmaps:take/2 1 6 6 [ 5.41]\npg:join_local_update_ets/5 1 8 8 [ 7.21]\npg:handle_info/2 1 8 8 [ 7.21]\npg:handle_call/3 1 9 9 [ 8.11]\ngen_server:loop/7 2 9 4 [ 8.11]\nets:lookup/2 2 10 5 [ 9.01]\npg:join_local/3 1 11 11 [ 9.91]\npg:notify_group/5 2 16 8 [14.41]\nerlang:setelement/3 2 16 8 [14.41]\n 111 [100.0]\n\n****** Process <0.255.0> -- 47.14 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\nerl_eval:match_list/6 1 3 3 [ 3.03]\nerlang:monitor/2 1 3 3 [ 3.03]\nlists:reverse/1 2 4 2 [ 4.04]\npg:join/3 1 4 4 [ 4.04]\nerl_eval:add_bindings/2 1 5 5 [ 5.05]\nerl_eval:do_apply/7 2 6 3 [ 6.06]\ngen:call/4 1 8 8 [ 8.08]\nerl_eval:expr_list/7 4 10 2 [10.10]\ngen:do_call/4 1 16 16 [16.16]\nerl_eval:ret_expr/3 4 16 4 [16.16]\nerl_eval:merge_bindings/4 3 24 8 [24.24]\n 99 [100.0]\n```\n\nBy default, there is no limit for the profiling time. For ac-hoc\nprofiling, is is possible to configure a time limit. If the profiled\nfunction does not return before that time expires, the process is\nterminated with reason `kill`. Any unlinked children processes started\nby the user-supplied function are kept; it is the responsibility of\nthe developer to take care of such processes.\n\n```erlang\n9> tprof:profile(timer, sleep, [100000], #{timeout => 1000}).\n```\n\nBy default, only one ad-hoc or server-aided profiling session is\nallowed at any point in time. It is possible to force multiple ad-hoc\nsessions concurrently, but it is the responsibility of the developer\nto ensure that trace patterns do not overlap:\n\n```erlang\n1> tprof:profile(fun() -> lists:seq(1, 32) end,\n #{registered => false, pattern => [{lists, '_', '_'}]}).\n```","ref":"tprof.html#module-ad-hoc-profiling"},{"type":"module","title":"Server-aided profiling - tprof","doc":"Server-aided profiling can be done on a system that is up and\nrunning. To do that, start the `tprof` server, and then add trace\npatterns and processes to trace while the system handles actual\ntraffic. Data can extracted, inspected, and printed at any time. The\nfollowing example traces activity of all processes supervised by\nthe Kernel supervisor:\n\n```erlang\n1> tprof:start(#{type => call_memory}).\n{ok,<0.200.0>}\n2> tprof:enable_trace({all_children, kernel_sup}).\n34\n3> tprof:set_pattern('_', '_' , '_').\n16728\n4> Sample = tprof:collect().\n{call_memory,\n [{gen_server,try_dispatch,4,[{<0.154.0>,2,6}]},\n {erlang,iolist_to_iovec,1,[{<0.161.0>,1,8}]},\n<...>\n5 > tprof:format(tprof:inspect(Sample)).\n\n****** Process <0.154.0> -- 14.21 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\nmaps:iterator/1 2 4 2 [15.38]\ngen_server:try_dispatch/4 2 6 3 [23.08]\nnet_kernel:handle_info/2 2 16 8 [61.54]\n 26 [100.0]\n\n****** Process <0.161.0> -- 85.79 % of total allocations ***\nFUNCTION CALLS WORDS PER CALL [ %]\ndisk_log:handle/2 2 2 1 [ 1.27]\ndisk_log_1:maybe_start_timer/1 1 3 3 [ 1.91]\ndisk_log_1:mf_write_cache/1 1 3 3 [ 1.91]\n<...>\n```\n\n[](){: #inspect_example }\n\nIt is possible to profile the entire running system, and then examine individual\nprocesses:\n\n```erlang\n1> tprof:start(#{type => call_memory}).\n2> tprof:enable_trace(all), tprof:set_pattern('_', '_' , '_').\n9041\n3> timer:sleep(10000), tprof:disable_trace(all), Sample = tprof:collect().\n{call_memory,\n [{user_drv,server,3,[{<0.64.0>,12,136}]},\n {user_drv,contains_ctrl_g_or_ctrl_c,1,[{<0.64.0>,80,10}]},\n<...>\n4> Inspected = tprof:inspect(Sample, process, measurement), Shell = maps:get(self(), Inspected).\n{call_memory, 2743,\n [{shell,{enc,0},1,2,2,0.07291286912139992},\n<...>\n5> tprof:format(Shell).\n\nFUNCTION CALLS WORDS PER CALL [ %]\n<...>\nerl_lint:start/2 2 300 150 [10.94]\nshell:used_records/1 114 342 3 [12.47]\n```","ref":"tprof.html#module-server-aided-profiling"},{"type":"function","title":"tprof.clear_pattern/3","doc":"Disables tracing functions matching the supplied pattern.\n\n```erlang\n1> tprof:set_pattern(lists, seq, '_').\n2\n2> tprof:clear_pattern(lists, seq, 3).\n1\n3> tprof:get_trace_map().\n#{lists => [{seq,2}]}\n```\n\nRequires that the default `tprof` server has been [`started`](`start/1`).","ref":"tprof.html#clear_pattern/3"},{"type":"function","title":"tprof.clear_pattern/4","doc":"Equivalent to [`clear_pattern(Mod, Fun, Arity)`](`clear_pattern/3`) but uses the provided `Server`.","ref":"tprof.html#clear_pattern/4"},{"type":"function","title":"tprof.collect/0","doc":"Returns statistics for current trace map.","ref":"tprof.html#collect/0"},{"type":"function","title":"tprof.collect/1","doc":"Equivalent to `collect/0` but uses the provided `Server`.","ref":"tprof.html#collect/1"},{"type":"function","title":"tprof.continue/0","doc":"Resumes previously paused profiling.","ref":"tprof.html#continue/0"},{"type":"function","title":"tprof.continue/1","doc":"Equivalent to `continue/0` but uses the provided `Server`.","ref":"tprof.html#continue/1"},{"type":"function","title":"tprof.disable_trace/1","doc":"","ref":"tprof.html#disable_trace/1"},{"type":"function","title":"tprof.disable_trace/2","doc":"Stops accumulating traces for specified processes.\n\nSee `enable_trace/2` for a description of the options.\n\nThe profile data accumulated before the process is removed from the\ntraced list is retained. This makes it possible to enable tracing for\nmany or all processes in the system, sleep for a short period of\ntime, then disable tracing for all processes (to avoid system\noverload), but keeping profile data.","ref":"tprof.html#disable_trace/2"},{"type":"function","title":"tprof.disable_trace/3","doc":"","ref":"tprof.html#disable_trace/3"},{"type":"function","title":"tprof.enable_trace/1","doc":"","ref":"tprof.html#enable_trace/1"},{"type":"function","title":"tprof.enable_trace/2","doc":"Similar to `trace:process/4`, but supports a few more options for tracing\nconvenience.\n\nTracing per process is not supported by `call_count` profilers.\n\n`Spec` is either a process identifier (pid) for a local process, one of the\nfollowing atoms, or a list of local process identifiers or their registered\nnames:\n\n- **`all`** - All currently existing processes and all that will be\n created in the future.\n\n- **`existing`** - All currently existing processes.\n\n- **`new`** - All processes that will be created in the future.\n\n- **`children`** - All currently running processes that were directly spawned by\n the specified process. This mode is helpful for tracing workers of a single\n supervisor.\n\n- **`all_children`** - All currently running processes that were spawned by the\n specified process, or any recursive descendant of it. This mode is designed to\n facilitate tracing of supervision trees.\n\nReturns the number of processes for which tracing was enabled.\n\nWhen a list of pids, `children` or `all_children` is used, the processes that\ntracing failed to be enabled on will also be returned. Tracing can fail to be\nenabled if the process has terminated before tracing could be enabled.\n\n> #### Note {: .info }\n>\n> The profiling server does not keep track of processes that were added to the\n> tracing set. It is permitted to stop the profiling server (wiping out any\n> accumulated data), restart the server, set entirely different tracing pattern\n> keeping the list of traced processes for future use. Use\n> [`disable_trace(Processes)`](`disable_trace/2`) to clear the list of traced\n> processes.\n\nSpecify `Options` to modify tracing behavior:\n\n- **`set_on_spawn`** - Automatically start tracing for processes spawned by the\n traced process. On by default.","ref":"tprof.html#enable_trace/2"},{"type":"function","title":"tprof.enable_trace/3","doc":"Equivalent to `enable_trace/2` but uses the provided `Server`.","ref":"tprof.html#enable_trace/3"},{"type":"function","title":"tprof.format/1","doc":"Formats profile data transformed with [`inspect/3`](`inspect/3`), outputting to\nthe default output device.","ref":"tprof.html#format/1"},{"type":"function","title":"tprof.format/2","doc":"Formats profile transformed with [`inspect/3`](`inspect/3`),\noutputting to device `IoDevice`.","ref":"tprof.html#format/2"},{"type":"function","title":"tprof.get_trace_map/0","doc":"Returns a map of module names to functions with their arities.","ref":"tprof.html#get_trace_map/0"},{"type":"function","title":"tprof.get_trace_map/1","doc":"Equivalent to `get_trace_map/0` but uses the provided `Server`.","ref":"tprof.html#get_trace_map/1"},{"type":"function","title":"tprof.inspect/1","doc":"Equivalent to [`inspect(Profile, process, percent)`](`inspect/3`).\n\nTransforms raw profile into a map of process identifiers to a tuple containing total count\nof words allocated, and a list of all traced functions sorted in the ascending\norder by the allocation percentage.","ref":"tprof.html#inspect/1"},{"type":"function","title":"tprof.inspect/3","doc":"Transforms raw data returned by tracing BIFs into a form convenient for\nsubsequent analysis and formatting.\n\n* When the `Type` argument is `process`, this function returns a map of process\n identifiers with corresponding profiling results sorted by the selected column.\n\n* When `Type` argument is `total` or when profiling by `call_count`, this function\n returns a map with a single `all` key with profiling results from all processes.\n\nThe inspected profile data can be leveraged to\n[print profiling results](`m:tprof#inspect_example`).","ref":"tprof.html#inspect/3"},{"type":"function","title":"tprof.pause/0","doc":"Pauses trace collection for all currently traced functions, retaining existing traces.\n\nUse `continue/0` to resume trace collection.","ref":"tprof.html#pause/0"},{"type":"function","title":"tprof.pause/1","doc":"Equivalent to `pause/0` but uses the provided `Server`.","ref":"tprof.html#pause/1"},{"type":"function","title":"tprof.profile/1","doc":"","ref":"tprof.html#profile/1"},{"type":"function","title":"tprof.profile/2","doc":"Does ad-hoc profiling of the call `Fun()`.\n\nBy default, the result is formatted to the output device; use the `report`\noption to change this behavior.\n\nAd-hoc profiling starts a new instance of `tprof` server, runs the\nprofiling routine, extracts results, and shuts down the server.\n\nSee `profile/4` for a list of the supported options.","ref":"tprof.html#profile/2"},{"type":"function","title":"tprof.profile/3","doc":"","ref":"tprof.html#profile/3"},{"type":"function","title":"tprof.profile/4","doc":"Does ad-hoc profiling for the call `apply(Module, Function, Args)`.\n\nBy default, the result is formatted to the output device; use option `report`\nto change this behavior.\n\nAd-hoc profiling starts a new instance of `tprof` server, runs the\nprofiling routine, extracts results, and shuts down the server.\n\nThe ad-hoc profiler supports the following `Options`:\n\n- **`type`** - The type of profiling to perform.\n\n- **`device`** - Specifies I/O devices to print the profile to. Useful to\n redirect text output to console or `standard_error`.\n\n- **`pattern`** - Specifies a trace pattern, or a list of trace patterns to\n enable. By default, all functions (`{'_', '_', '_'}`) are traced.\n\n- **`report`** - Controls output format. The default is `process`; printing\n per-process profiling data sorted by percentage of the total allocation.\n Specify `report => return` to suppress printing and get the raw data for\n further evaluation with `inspect/3` and formatting with `format/2`.\n\n- **`rootset`** - Includes extra processes in the trace list. Useful for\n profiling allocations for `m:gen_server`, calls, or other allocations caused\n by inter-process communications. See [this example](`m:tprof#pg_example`).\n\n- **`set_on_spawn`** - Automatically start tracing for processes spawned by the\n traced process. Enabled by default.\n\n- **`timeout`** - Terminate profiling after the specified amount of time\n (milliseconds).","ref":"tprof.html#profile/4"},{"type":"function","title":"tprof.restart/0","doc":"Clears accumulated profiles and starts profiling if it was paused.","ref":"tprof.html#restart/0"},{"type":"function","title":"tprof.restart/1","doc":"Equivalent to `restart/0` but uses the provided `Server`.","ref":"tprof.html#restart/1"},{"type":"function","title":"tprof.set_pattern/3","doc":"Enables tracing for all functions matching the supplied pattern.\n\nPatterns are additive, following the same rules as `trace:function/4`.\nReturns the number of functions matching the supplied pattern.\n\n```erlang\n1> tprof:set_pattern(lists, seq, '_').\n2\n2> tprof:set_pattern(lists, keyfind, 3).\n1\n3> tprof:get_trace_map().\n#{lists => [{keyfind,3},{seq,2},{seq,3}]}\n```\n\nIf no functions match the pattern, an `error` tuple is returned:\n\n```erlang\n> tprof:set_pattern(no_module, func, '_').\n{error,{trace_pattern,no_module,func,'_'}}\n```\n\nRequires that the default `tprof` server has been [`started`](`start/1`).","ref":"tprof.html#set_pattern/3"},{"type":"function","title":"tprof.set_pattern/4","doc":"Equivalent to `set_pattern/3` but uses the provided `Server`.","ref":"tprof.html#set_pattern/4"},{"type":"function","title":"tprof.start/0","doc":"","ref":"tprof.html#start/0"},{"type":"function","title":"tprof.start/1","doc":"Starts the server, not supervised.\n\nProfiling server stores current trace patterns and owns the [trace session](`t:trace:session/0`)\nused for profiling.\n\nIf no `session` is provided in `Config`, then a default session called `tprof` is\nused and the profiling server is [registered](`register/2`) as `tprof`.\n\nIf `session` is provided in `Config`, then a session with that name is created\nand all profiling is done within that session. The profiling server is not [registered](`register/2`)\nin this case. When using `m:tprof` like this the `t:pid/0` returned from this\nfunction needs to be provided to the functions in this module.","ref":"tprof.html#start/1"},{"type":"function","title":"tprof.start_link/0","doc":"","ref":"tprof.html#start_link/0"},{"type":"function","title":"tprof.start_link/1","doc":"Equivalent to `start/1` but also links the profiling server to the caller.","ref":"tprof.html#start_link/1"},{"type":"function","title":"tprof.stop/0","doc":"Stops the default `tprof` server and disable tracing enabled by the server.","ref":"tprof.html#stop/0"},{"type":"function","title":"tprof.stop/1","doc":"Equivalent to `stop/0` but uses the provided `Server`.","ref":"tprof.html#stop/1"},{"type":"type","title":"tprof.column/0","doc":"Column to sort by `inspect/3` or [`profile/4`](`profile/4`).\n\n- **`module`** - Module name.\n\n- **`function`** - Function name.\n\n- **`calls`** - Number of calls to the function.\n\n- **`measurement`** - Total measurement (call count, time, or heap allocation)\n throughout all calls to the function.\n\n- **`measurement_per_call`** - Measurement (call count, time, or heap\n allocation) on average per function call.\n\n- **`percent`** - Percentage of measurement to total amount during the entire\n profile collection.","ref":"tprof.html#t:column/0"},{"type":"type","title":"tprof.process/0","doc":"A process identifier (pid) or a registered process name.","ref":"tprof.html#t:process/0"},{"type":"type","title":"tprof.profile_line/0","doc":"Inspected data for a single function of the specified `Module`.","ref":"tprof.html#t:profile_line/0"},{"type":"type","title":"tprof.profile_options/0","doc":"Ad-hoc profiler options; see [`profile/4`](`profile/4`).","ref":"tprof.html#t:profile_options/0"},{"type":"type","title":"tprof.profile_result/0","doc":"Profile of a single process, or combined profile of multiple processes, sorted\nby a selected column.","ref":"tprof.html#t:profile_result/0"},{"type":"type","title":"tprof.rootset/0","doc":"","ref":"tprof.html#t:rootset/0"},{"type":"type","title":"tprof.server/0","doc":"A tprof server.\n\nEach server uses a separate `t:trace:session/0` in order to\nkeep profiling isolated.","ref":"tprof.html#t:server/0"},{"type":"type","title":"tprof.sort_by/0","doc":"","ref":"tprof.html#t:sort_by/0"},{"type":"type","title":"tprof.start_options/0","doc":"","ref":"tprof.html#t:start_options/0"},{"type":"type","title":"tprof.trace_info/0","doc":"Raw data extracted from tracing BIFs.","ref":"tprof.html#t:trace_info/0"},{"type":"type","title":"tprof.trace_map/0","doc":"Traced functions (with their arities) grouped by module name,\nor `all` if all code is traced.","ref":"tprof.html#t:trace_map/0"},{"type":"type","title":"tprof.trace_options/0","doc":"Options for enabling profiling of the selected processes; see `enable_trace/2`.","ref":"tprof.html#t:trace_options/0"},{"type":"type","title":"tprof.trace_pattern/0","doc":"","ref":"tprof.html#t:trace_pattern/0"},{"type":"type","title":"tprof.trace_type/0","doc":"The type of profiling that the tprof server will do.\n\n- **call_count** - Counts the number of calls made to functions. This\n is a global profiling event that cannot be limited to specific processes.\n See [call_count](`trace#call_count`) in `trace:function/4` for more details.\n- **call_time** - Counts the accumulated time spent in functions.\n See [call_time](`trace#call_time`) in `trace:function/4` for more details.\n- **call_memory** - Counts the accumulated memory allocated in functions.\n See [call_memory](`trace#call_memory`) in `trace:function/4` for more details.","ref":"tprof.html#t:trace_type/0"},{"type":"module","title":"xref","doc":"A Cross Reference Tool for analyzing dependencies between functions, modules,\napplications, and releases.\n\nCalls between functions are either _local calls_{: #local_call } such as `f()`,\nor _external calls_{: #external_call } such as `mod:f()`.\n\n_Module data_{:#module_data }, which are extracted from BEAM files,\ninclude local functions, exported functions, local calls, and external\ncalls. By default, calls to built-in functions (BIF) are ignored, but\nif the option `builtins`, accepted by some of this module's functions,\nis set to `true`, calls to BIFs are included as well. It is the\nanalyzing OTP version that decides what functions are BIFs.\nFunctional objects are assumed to be called where they are created\n(and nowhere else).\n\n_Unresolved calls_{: #unresolved_call } are calls to `apply` or\n`spawn` with variable module, variable function, or variable\narguments. Examples are `M:F(a)`, [`apply(M, f, [a])`](`apply/3`), and\n[`spawn(m, f(), Args)`](`spawn/3`). Unresolved calls are represented\nby calls where variable modules have been replaced with the atom\n`'$M_EXPR'`, variable functions have been replaced with the atom\n`'$F_EXPR'`, and variable number of arguments have been replaced with\nthe number `-1`. The above mentioned examples are represented by calls\nto `'$M_EXPR':'$F_EXPR'/1`, `'$M_EXPR':f/1`, and `m:'$F_EXPR'/-1`. The\nunresolved calls are a subset of the external calls.\n\n> #### Warning {: .warning }\n>\n> Unresolved calls make module data incomplete, which implies that the results\n> of analyses may be invalid.\n\n_Applications_ are collections of modules. The BEAM files for the\nmodules are located in the `ebin` subdirectory of the application\ndirectory. The name of the application directory determines the name\nand version of the application.\n\n_Releases_ are collections of applications located in the `lib` subdirectory of\nthe release directory. There is more to read about applications and releases in\nthe Design Principles book.\n\n_Xref servers_{: #xref_server } are identified by names, supplied when\ncreating new servers. Each Xref server holds a set of releases, a set\nof applications, and a set of modules with module data. Xref servers\nare independent of each other, and all analyses are evaluated in the\ncontext of one single Xref server (exceptions are the functions\n[`m/1`](`m/1`) and [`d/1`](`d/1`) which do not use servers at\nall).\n\nThe _mode_{: #mode } of an Xref server determines what module data are\nextracted from BEAM files as modules are added to the server. BEAM\nfiles compiled with the option `debug_info` contain [](){: #debug_info\n} \"debug information\", which is an abstract representation of the\ncode.\n\n- In `functions` mode, which is the default mode, function calls\n and line numbers are extracted from debug information.\n\n- In `modules` mode, debug information is ignored if present, but\n dependencies between modules are extracted from other parts of the\n BEAM files. The `modules` mode is significantly less time and space\n consuming than the `functions` mode, but the analyses that can be\n done are limited.\n\nAn _analyzed module_{: #analyzed_module } is a module that has been added to an\nXref server together with its module data. A _library module_{: #library_module\n} is a module located in some directory mentioned in the _library path_{:\n#library_path }. A library module is said to be used if some of its exported\nfunctions are used by some analyzed module. An _unknown module_{:\n#unknown_module } is a module that is neither an analyzed module nor a library\nmodule, but whose exported functions are used by some analyzed module.\n\nAn _unknown function_{: #unknown_function } is a used function that is\nneither local or exported by any analyzed module nor exported by any\nlibrary module. An _undefined function_{: #undefined_function } is an\nexternally used function that is not exported by any analyzed module\nor library module. With this notion, a local function can be an\nundefined function, namely if it is externally used from some\nmodule. All unknown functions are also undefined functions; there is a\n[figure](xref_chapter.md#venn2) in the User's Guide that illustrates\nthis relationship.\n\nThe module attribute tag `deprecated` can be used to inform\nXref about _deprecated functions_{: #deprecated_function } and optionally when\nfunctions are planned to be removed. A few examples show the idea:\n\n- `-deprecated({f,1}).` - The exported function `f/1` is deprecated.\n Nothing is said whether `f/1` will be removed or not.\n\n- `-deprecated({f,1,\"Use g/1 instead\"}).` - As above but with a descriptive\n string. The string is currently unused by `xref` but other tools can make use\n of it.\n\n- `-deprecated({f,'_'}).` - All exported functions `f/0`, `f/1`, and so on\n are deprecated.\n\n- `-deprecated(module).` - All exported functions in the module are\n deprecated. Equivalent to `-deprecated({'_','_'}).`.\n\n- `-deprecated([{g,1,next_version}]).` - The function `g/1` is deprecated\n and will be removed in next version.\n\n- `-deprecated([{g,2,next_major_release}]).` - The function `g/2` is\n deprecated and will be removed in next major release.\n\n- `-deprecated([{g,3,eventually}]).` - The function `g/3` is deprecated\n and will eventually be removed.\n\n- `-deprecated({'_','_',eventually}).` - All exported functions in the\n module are deprecated and will eventually be removed.\n\nBefore any analysis can take place, module data must be _set up_. For instance,\nthe cross reference and the unknown functions are computed when all module data\nare known. The functions that need complete data\n([`analyze/2,3`](`analyze/3`), [`q/2,3`](`q/3`), [`variables/1,2`](`variables/2`)\ntake care of setting up data automatically. Module data need to be set up\n(again) after calls to any of the `add`, `replace`, `remove`,\n[`set_library_path/2,3`](`set_library_path/3`), or\n[`update/1,2`](`update/2`) functions.\n\nThe result of setting up module data is the _Call Graph_{: #call_graph }. A\n(directed) graph consists of a set of vertices and a set of (directed) edges.\nThe edges represent _calls_{: #call } (From, To) between functions, modules,\napplications, or releases. From is said to call To, and To is said to be used by\nFrom. The vertices of the Call Graph are the functions of all module data: local\nand exported functions of analyzed modules; used BIFs; used exported functions\nof library modules; and unknown functions. The functions `module_info/0,1` added\nby the compiler are included among the exported functions, but only when called\nfrom some module. The edges are the function calls of all module data. A\nconsequence of the edges being a set is that there is only one edge if a\nfunction is locally or externally used several times on one and the same line of\ncode.\n\nThe Call Graph is [](){: #representation } represented by Erlang terms (the sets\nare lists), which is suitable for many analyses. But for analyses that look at\nchains of calls, a list representation is much too slow. Instead the\nrepresentation offered by the `digraph` module is used. The translation of the\nlist representation of the Call Graph - or a subgraph thereof - to the `digraph`\nrepresentation does not come for free, so the language used for expressing\nqueries to be described below has a special operator for this task and a\npossibility to save the `digraph` representation for subsequent analyses.\n\nIn addition to the Call Graph there is a graph called the _Inter Call Graph_{:\n#inter_call_graph }. This is a graph of calls (From, To) such that there is a\nchain of calls from From to To in the Call Graph, and every From and To is an\nexported function or an unused local function. The vertices are the same as for\nthe Call Graph.\n\nCalls between modules, applications and releases are also directed graphs. The\n_types_{: #type } of the vertices and edges of these graphs are (ranging from\nthe most special to the most general): `Fun` for functions; `Mod` for modules;\n`App` for applications; and `Rel` for releases. The following paragraphs will\ndescribe the different constructs of the language used for selecting and\nanalyzing parts of the graphs, beginning with the _constants_{: #constants }:\n\n- Expression ::= Constants\n- Constants ::= Consts | Consts `:` Type | RegExpr\n- Consts ::= Constant | `[`Constant`,` ...`]` | `{`Constant`,` ...`}`\n- Constant ::= Call | Const\n- Call ::= FunSpec `->` FunSpec | `{`MFA`,` MFA`}` | AtomConst `->` AtomConst |\n `{`AtomConst`,` AtomConst`}`\n- Const ::= AtomConst | FunSpec | MFA\n- AtomConst ::= Application | Module | Release\n- FunSpec ::= Module `:` Function `/` Arity\n- MFA ::= `{`Module`,` Function`,` Arity`}`\n- RegExpr ::= RegString `:` Type | RegFunc | RegFunc `:` Type\n- RegFunc ::= RegModule `:` RegFunction `/` RegArity\n- RegModule ::= RegAtom\n- RegFunction ::= RegAtom\n- RegArity ::= RegString | Number | `_` | `-1`\n- RegAtom ::= RegString | Atom | `_`\n- RegString ::= - a regular expression, as described in the `re` module,\n enclosed in double quotes -\n- Type ::= `Fun` | `Mod` | `App` | `Rel`\n- Function ::= Atom\n- Application ::= Atom\n- Module ::= Atom\n- Release ::= Atom\n- Arity ::= Number | `-1`\n- Atom ::= - same as Erlang atoms -\n- Number ::= - same as non-negative Erlang integers -\n\nExamples of constants are: `kernel`, `kernel->stdlib`, `[kernel, sasl]`,\n`[pg -> mnesia, {tv, mnesia}] : Mod`. It is an error if an instance of `Const`\ndoes not match any vertex of any graph. If there are more than one vertex\nmatching an untyped instance of `AtomConst`, then the one of the most general\ntype is chosen. A list of constants is interpreted as a set of constants, all of\nthe same type. A tuple of constants constitute a chain of calls (which may, but\ndoes not have to, correspond to an actual chain of calls of some graph).\nAssigning a type to a list or tuple of `Constant` is equivalent to assigning the\ntype to each `Constant`.\n\n_Regular expressions_{: #regexp } are used as a means to select some of the\nvertices of a graph. A `RegExpr` consisting of a `RegString` and a type - an\nexample is `\"xref_.*\" : Mod` \\- is interpreted as those modules (or applications\nor releases, depending on the type) that match the expression. Similarly, a\n`RegFunc` is interpreted as those vertices of the Call Graph that match the\nexpression. An example is `\"xref_.*\":\"add_.*\"/\"(2|3)\"`, which matches all `add`\nfunctions of arity two or three of any of the xref modules. Another example, one\nthat matches all functions of arity 10 or more: `_:_/\"[1-9].+\"`. Here `_` is an\nabbreviation for `\".*\"`, that is, the regular expression that matches anything.\n\nThe syntax of _variables_{: #variable } is simple:\n\n- Expression ::= Variable\n- Variable ::= - same as Erlang variables -\n\nThere are two kinds of variables:\n\n* **Predefined variables** {: #predefined_variable } - hold module data, and\n cannot be assigned to but only used in queries.\n\n* **User variables** {: #user_variable } - can be assigned to, and are\n typically used for temporary results while evaluating a query, and\n for keeping results of queries for use in subsequent queries.\n\nThe predefined variables are (variables marked with (\\*) are available\nin `functions` mode only):\n\n- **`E`** - Call Graph Edges (\\*).\n\n- **`V`** - Call Graph Vertices (\\*).\n\n- **`M`** - Modules. All modules: analyzed modules, used library modules, and\n unknown modules.\n\n- **`A`** - Applications.\n\n- **`R`** - Releases.\n\n- **`ME`** - Module Edges. All module calls.\n\n- **`AE`** - Application Edges. All application calls.\n\n- **`RE`** - Release Edges. All release calls.\n\n- **`L`** - Local Functions (\\*). All local functions of analyzed modules.\n\n- **`X`** - Exported Functions. All exported functions of analyzed modules and\n all used exported functions of library modules.\n\n- **`F`** - Functions (\\*).\n\n- **`B`** - Used BIFs. `B` is empty if `builtins` is `false` for all analyzed\n modules.\n\n- **`U`** - Unknown Functions.\n\n- **`UU`** - Unused Functions (\\*). All local and exported functions of analyzed\n modules that have not been used.\n\n- **`XU`** - Externally Used Functions. Functions of all modules - including\n local functions - that have been used in some external call.\n\n- **`LU`** - Locally Used Functions (\\*). Functions of all modules that have\n been used in some local call.\n\n- **`OL`** - Functions with an attribute tag `on_load` (\\*).\n\n- **`LC`** - Local Calls (\\*).\n\n- **`XC`** - External Calls (\\*).\n\n- **`AM`** - Analyzed Modules.\n\n- **`UM`** - Unknown Modules.\n\n- **`LM`** - Used Library Modules.\n\n- **`UC`** - Unresolved Calls. Empty in `modules` mode.\n\n- **`EE`** - Inter Call Graph Edges (\\*).\n\n- **`DF`** - Deprecated Functions. All deprecated exported functions and all\n used deprecated BIFs.\n\n- **`DF_1`** - Deprecated Functions. All deprecated functions to be removed in\n next version.\n\n- **`DF_2`** - Deprecated Functions. All deprecated functions to be removed in\n next version or next major release.\n\n- **`DF_3`** - Deprecated Functions. All deprecated functions to be removed in\n next version, next major release, or later.\n\nThese are a few [](){: #simple_facts } facts about the predefined variables (the\nset operators `+` (union) and `-` (difference) as well as the cast operator\n`(`Type`)` are described below):\n\n- `F` is equal to `L + X`.\n- `V` is equal to `X + L + B + U`, where `X`, `L`, `B` and `U` are pairwise\n disjoint (that is, have no elements in common).\n- `UU` is equal to `V - (XU + LU)`, where `LU` and `XU` may have elements in\n common. Put in another way:\n- `V` is equal to `UU + XU + LU`.\n- `OL` is a subset of `F`.\n- `E` is equal to `LC + XC`. Note that `LC` and `XC` may have elements in\n common, namely if some function is locally and externally used from one and\n the same function.\n- `U` is a subset of `XU`.\n- `B` is a subset of `XU`.\n- `LU` is equal to `range LC`.\n- `XU` is equal to `range XC`.\n- `LU` is a subset of `F`.\n- `UU` is a subset of `F`.\n- `range UC` is a subset of `U`.\n- `M` is equal to `AM + LM + UM`, where `AM`, `LM` and `UM` are pairwise\n disjoint.\n- `ME` is equal to `(Mod) E`.\n- `AE` is equal to `(App) E`.\n- `RE` is equal to `(Rel) E`.\n- `(Mod) V` is a subset of `M`. Equality holds if all analyzed modules have some\n local, exported, or unknown function.\n- `(App) M` is a subset of `A`. Equality holds if all applications have some\n module.\n- `(Rel) A` is a subset of `R`. Equality holds if all releases have some\n application.\n- `DF_1` is a subset of `DF_2`.\n- `DF_2` is a subset of `DF_3`.\n- `DF_3` is a subset of `DF`.\n- `DF` is a subset of `X + B`.\n\nAn important notion is that of _conversion_{: #conversion } of expressions. The\nsyntax of a cast expression is:\n\n- Expression ::= `(` Type `)` Expression\n\nThe interpretation of the cast operator depends on the named type `Type`, the\ntype of `Expression`, and the structure of the elements of the interpretation of\n`Expression`. If the named type is equal to the expression type, no conversion\nis done. Otherwise, the conversion is done one step at a time; `(Fun) (App) RE`,\nfor instance, is equivalent to `(Fun) (Mod) (App) RE`. Now assume that the\ninterpretation of `Expression` is a set of constants (functions, modules,\napplications or releases). If the named type is more general than the expression\ntype, say `Mod` and `Fun` respectively, then the interpretation of the cast\nexpression is the set of modules that have at least one of their functions\nmentioned in the interpretation of the expression. If the named type is more\nspecial than the expression type, say `Fun` and `Mod`, then the interpretation\nis the set of all the functions of the modules (in `modules` mode, the\nconversion is partial since the local functions are not known). The conversions\nto and from applications and releases work analogously. For instance,\n`(App) \"xref_.*\" : Mod` returns all applications containing at least one module\nsuch that `xref_` is a prefix of the module name.\n\nNow assume that the interpretation of `Expression` is a set of calls. If the\nnamed type is more general than the expression type, say `Mod` and `Fun`\nrespectively, then the interpretation of the cast expression is the set of calls\n(M1, M2) such that the interpretation of the expression contains a call from\nsome function of M1 to some function of M2. If the named type is more special\nthan the expression type, say `Fun` and `Mod`, then the interpretation is the\nset of all function calls (F1, F2) such that the interpretation of the\nexpression contains a call (M1, M2) and F1 is a function of M1 and F2 is a\nfunction of M2 (in `modules` mode, there are no functions calls, so a cast to\n`Fun` always yields an empty set). Again, the conversions to and from\napplications and releases work analogously.\n\nThe interpretation of constants and variables are sets, and those sets can be\nused as the basis for forming new sets by the application of _set operators_{:\n#set_operator }. The syntax:\n\n- Expression ::= Expression BinarySetOp Expression\n- BinarySetOp ::= `+` | `*` | `-`\n\n`+`, `*` and `-` are interpreted as union, intersection and difference\nrespectively: the union of two sets contains the elements of both sets; the\nintersection of two sets contains the elements common to both sets; and the\ndifference of two sets contains the elements of the first set that are not\nmembers of the second set. The elements of the two sets must be of the same\nstructure; for instance, a function call cannot be combined with a function. But\nif a cast operator can make the elements compatible, then the more general\nelements are converted to the less general element type. For instance, `M + F`\nis equivalent to `(Fun) M + F`, and `E - AE` is equivalent to `E - (Fun) AE`.\nOne more example: `X * xref : Mod` is interpreted as the set of functions\nexported by the module `xref`; `xref : Mod` is converted to the more special\ntype of `X` (`Fun`, that is) yielding all functions of `xref`, and the\nintersection with `X` (all functions exported by analyzed modules and library\nmodules) is interpreted as those functions that are exported by some module\n_and_ functions of `xref`.\n\nThere are also unary set operators:\n\n- Expression ::= UnarySetOp Expression\n- UnarySetOp ::= `domain` | `range` | `strict`\n\nRecall that a call is a pair (From, To). `domain` applied to a set of calls is\ninterpreted as the set of all vertices From, and `range` as the set of all\nvertices To. The interpretation of the `strict` operator is the operand with all\ncalls on the form (A, A) removed.\n\nThe interpretation of the _restriction operators_{: #restriction } is a subset\nof the first operand, a set of calls. The second operand, a set of vertices, is\nconverted to the type of the first operand. The syntax of the restriction\noperators:\n\n- Expression ::= Expression RestrOp Expression\n- RestrOp ::= `|`\n- RestrOp ::= `||`\n- RestrOp ::= `|||`\n\nThe interpretation in some detail for the three operators:\n\n- **`|`** - The subset of calls from any of the vertices.\n\n- **`||`** - The subset of calls to any of the vertices.\n\n- **`|||`** - The subset of calls to and from any of the vertices. For all sets\n of calls `CS` and all sets of vertices `VS`, `CS ||| VS ` is equivalent to\n `CS | VS * CS || VS`.\n\n[](){: #graph_analyses } Two functions (modules, applications, releases) belong\nto the same strongly connected component if they call each other (in)directly.\nThe interpretation of the `components` operator is the set of strongly connected\ncomponents of a set of calls. The `condensation` of a set of calls is a new set\nof calls between the strongly connected components such that there is an edge\nbetween two components if there is some constant of the first component that\ncalls some constant of the second component.\n\nThe interpretation of the `of` operator is a chain of calls of the second\noperand (a set of calls) that passes throw all of the vertices of the first\noperand (a tuple of constants), in the given order. The second operand is\nconverted to the type of the first operand. For instance, the `of` operator can\nbe used for finding out whether a function calls another function indirectly,\nand the chain of calls demonstrates how. The syntax of the graph analyzing\noperators:\n\n- Expression ::= Expression BinaryGraphOp Expression\n- Expression ::= UnaryGraphOp Expression\n- UnaryGraphOp ::= `components` | `condensation`\n- BinaryGraphOp ::= `of`\n\nAs was mentioned before, the graph analyses operate on the `digraph`\nrepresentation of graphs. By default, the `digraph` representation is created\nwhen needed (and deleted when no longer used), but it can also be created\nexplicitly by use of the `closure` operator:\n\n- Expression ::= ClosureOp Expression\n- ClosureOp ::= `closure`\n\nThe interpretation of the `closure` operator is the transitive closure of the\noperand.\n\nThe restriction operators are defined for closures as well;\n`closure E | xref : Mod` is interpreted as the direct or indirect function calls\nfrom the `xref` module, while the interpretation of `E | xref : Mod` is the set\nof direct calls from `xref`. If some graph is to be used in several graph\nanalyses, it saves time to assign the `digraph` representation of the graph to a\nuser variable, and then make sure that every graph analysis operates on that\nvariable instead of the list representation of the graph.\n\nThe lines where functions are defined (more precisely: where the first clause\nbegins) and the lines where functions are used are available in `functions`\nmode. The line numbers refer to the files where the functions are defined. This\nholds also for files included with the `-include` and `-include_lib` directives,\nwhich may result in functions defined apparently in the same line. The _line\noperators_ are used for assigning line numbers to functions and for assigning\nsets of line numbers to function calls. The syntax is similar to the one of the\ncast operator:\n\n- Expression ::= `(` LineOp`)` Expression\n- Expression ::= `(` XLineOp`)` Expression\n- LineOp ::= `Lin` | `ELin` | `LLin` | `XLin`\n- XLineOp ::= `XXL`\n\nThe interpretation of the `Lin` operator applied to a set of functions assigns\nto each function the line number where the function is defined. Unknown\nfunctions and functions of library modules are assigned the number 0.\n\nThe interpretation of some LineOp operator applied to a set of function calls\nassigns to each call the set of line numbers where the first function calls the\nsecond function. Not all calls are assigned line numbers by all operators:\n\n- the `Lin` operator is defined for Call Graph Edges;\n- the `LLin` operator is defined for Local Calls.\n- the `XLin` operator is defined for External Calls.\n- the `ELin` operator is defined for Inter Call Graph Edges.\n\nThe `Lin` (`LLin`, `XLin`) operator assigns the lines where calls (local calls,\nexternal calls) are made. The `ELin` operator assigns to each call (From, To),\nfor which it is defined, every line L such that there is a chain of calls from\nFrom to To beginning with a call on line L.\n\nThe `XXL` operator is defined for the interpretation of any of the LineOp\noperators applied to a set of function calls. The result is that of replacing\nthe function call with a line numbered function call, that is, each of the two\nfunctions of the call is replaced by a pair of the function and the line where\nthe function is defined. The effect of the `XXL` operator can be undone by the\nLineOp operators. For instance, `(Lin) (XXL) (Lin) E` is equivalent to\n`(Lin) E`.\n\nThe `+`, `-`, `*`, and `#` operators are defined for line number expressions,\nprovided the operands are compatible. The LineOp operators are also defined for\nmodules, applications, and releases; the operand is implicitly converted to\nfunctions. Similarly, the cast operator is defined for the interpretation of the\nLineOp operators.\n\nThe interpretation of the _counting operator_{: #count } is the number of\nelements of a set. The operator is undefined for closures. The `+`, `-` and `*`\noperators are interpreted as the obvious arithmetical operators when applied to\nnumbers. The syntax of the counting operator:\n\n- Expression ::= CountOp Expression\n- CountOp ::= `#`\n\nAll binary operators are left associative; for instance, `A | B  || C` is\nequivalent to `(A | B) || C`. The following is a list of all operators, in\nincreasing order of _precedence_{: #precedence }:\n\n- `+`, `-`\n- `*`\n- `#`\n- `|`, `||`, `|||`\n- `of`\n- `(`Type`)`\n- `closure`, `components`, `condensation`, `domain`, `range`, `strict`\n\nParentheses are used for grouping, either to make an expression more readable or\nto override the default precedence of operators:\n\n- Expression ::= `(` Expression `)`\n\nA _query_{: #query } is a non-empty sequence of statements. A statement is\neither an assignment of a user variable or an expression. The value of an\nassignment is the value of the right hand side expression. It makes no sense to\nput a plain expression anywhere else but last in queries. The syntax of queries\nis summarized by these productions:\n\n- Query ::= Statement`,` ...\n- Statement ::= Assignment | Expression\n- Assignment ::= Variable `:=` Expression | Variable `=` Expression\n\nA variable cannot be assigned a new value unless first removed. Variables\nassigned to by the `=` operator are removed at the end of the query, while\nvariables assigned to by the `:=` operator can only be removed by calls to\n`forget`. There are no user variables when module data need to be set up again;\nif any of the functions that make it necessary to set up module data again is\ncalled, all user variables are forgotten.","ref":"xref.html"},{"type":"module","title":"See Also - xref","doc":"`m:beam_lib`, `m:digraph`, `m:digraph_utils`, `m:re`,\n[User's Guide for Xref](xref_chapter.md)","ref":"xref.html#module-see-also"},{"type":"function","title":"xref.add_application/2","doc":"","ref":"xref.html#add_application/2"},{"type":"function","title":"xref.add_application/3","doc":"Adds an application, the modules of the application, and\n[module data](`m:xref#module_data`) of the modules to an\n[Xref server](`m:xref#xref_server`).\n\nThe modules will be members of the application. The default is to use\nthe base name of the directory with the version removed as application\nname, but this can be overridden by the `name` option. Returns the\nname of the application.\n\nIf the given directory has a subdirectory named `ebin`, modules (BEAM files) are\nsearched for in that directory, otherwise modules are searched for in the given\ndirectory.\n\nIf the [mode](`m:xref#mode`) of the Xref server is `functions`, BEAM files that\ncontain no [debug information](`m:xref#debug_info`) are ignored.","ref":"xref.html#add_application/3"},{"type":"function","title":"xref.add_directory/2","doc":"","ref":"xref.html#add_directory/2"},{"type":"function","title":"xref.add_directory/3","doc":"Adds the modules found in the given directory and the\n[modules' data](`m:xref#module_data`) to an [Xref server](`m:xref#xref_server`).\n\nThe default is not to examine subdirectories, but if the option `recurse` has\nthe value `true`, modules are searched for in subdirectories on all levels as\nwell as in the given directory. Returns a sorted list of the names of the added\nmodules.\n\nThe modules added will not be members of any applications.\n\nIf the [mode](`m:xref#mode`) of the Xref server is `functions`, BEAM files that\ncontain no [debug information](`m:xref#debug_info`) are ignored.","ref":"xref.html#add_directory/3"},{"type":"function","title":"xref.add_module/2","doc":"","ref":"xref.html#add_module/2"},{"type":"function","title":"xref.add_module/3","doc":"Adds a module and its [module data](`m:xref#module_data`) to an\n[Xref server](`m:xref#xref_server`).\n\nThe module will not be member of any application. Returns the name of the module.\n\nIf the [mode](`m:xref#mode`) of the Xref server is `functions`, and the BEAM\nfile contains no [debug information](`m:xref#debug_info`), the error message\n`no_debug_info` is returned.","ref":"xref.html#add_module/3"},{"type":"function","title":"xref.add_release/2","doc":"","ref":"xref.html#add_release/2"},{"type":"function","title":"xref.add_release/3","doc":"Adds a release, the applications of the release, the modules of the\napplications, and [module data](`m:xref#module_data`) of the modules to an\n[Xref server](`m:xref#xref_server`).\n\nThe applications will be members of the release, and the modules will\nbe members of the applications. The default is to use the base name of\nthe directory as release name, but this can be overridden by the\n`name` option. Returns the name of the release.\n\nIf the given directory has a subdirectory named `lib`, the directories in that\ndirectory are assumed to be application directories, otherwise all\nsubdirectories of the given directory are assumed to be application directories.\nIf there are several versions of some application, the one with the highest\nversion is chosen.\n\nIf the [mode](`m:xref#mode`) of the Xref server is `functions`, BEAM files that\ncontain no [debug information](`m:xref#debug_info`) are ignored.","ref":"xref.html#add_release/3"},{"type":"function","title":"xref.analyze/2","doc":"","ref":"xref.html#analyze/2"},{"type":"function","title":"xref.analyze/3","doc":"[](){: #analyze } Evaluates a predefined analysis.\n\nReturns a sorted list without duplicates of `t:call/0` or\n`t:constant/0`, depending on the chosen analysis. The predefined\nanalyses, which operate on all [analyzed\nmodules](`m:xref#analyzed_module`), are (analyses marked with (\\*) are\navailable only in [mode `functions`](`m:xref#mode`)):\n\n- **`undefined_function_calls`(\\*)** - Returns a list of calls to\n [undefined functions](`m:xref#undefined_function`).\n\n- **`undefined_functions`** - Returns a list of\n [undefined functions](`m:xref#undefined_function`).\n\n- **`locals_not_used`(\\*)** - Returns a list of local functions that have not\n been locally used.\n\n- **`exports_not_used`** - Returns a list of exported functions that have not\n been externally used. Note that in `modules` mode, `M:behaviour_info/1` is\n never reported as unused.\n\n- **`deprecated_function_calls`(\\*)** - Returns a list of external calls to\n [deprecated functions](`m:xref#deprecated_function`).\n\n- **`{deprecated_function_calls, DeprFlag}`(\\*)** - Returns a list of external\n calls to deprecated functions. If `DeprFlag` is equal to `next_version`, calls\n to functions to be removed in next version are returned. If `DeprFlag` is\n equal to `next_major_release`, calls to functions to be removed in next major\n release are returned as well as calls to functions to be removed in next\n version. Finally, if `DeprFlag` is equal to `eventually`, all calls to\n functions to be removed are returned, including calls to functions to be\n removed in next version or next major release.\n\n- **`deprecated_functions`** - Returns a list of externally used deprecated\n functions.\n\n- **`{deprecated_functions, DeprFlag}`** - Returns a list of externally used\n deprecated functions. If `DeprFlag` is equal to `next_version`, functions to\n be removed in next version are returned. If `DeprFlag` is equal to\n `next_major_release`, functions to be removed in next major release are\n returned as well as functions to be removed in next version. Finally, if\n `DeprFlag` is equal to `eventually`, all functions to be removed are returned,\n including functions to be removed in next version or next major release.\n\n- **`{call, FuncSpec}`(\\*)** - Returns a list of functions called by some of the\n given functions.\n\n- **`{use, FuncSpec}`(\\*)** - Returns a list of functions that use some of the\n given functions.\n\n- **`{module_call, ModSpec}`** - Returns a list of modules called by some of the\n given modules.\n\n- **`{module_use, ModSpec}`** - Returns a list of modules that use some of the\n given modules.\n\n- **`{application_call, AppSpec}`** - Returns a list of applications called by\n some of the given applications.\n\n- **`{application_use, AppSpec}`** - Returns a list of applications that use\n some of the given applications.\n\n- **`{release_call, RelSpec}`** - Returns a list of releases called by some of\n the given releases.\n\n- **`{release_use, RelSpec}`** - Returns a list of releases that use some of the\n given releases.","ref":"xref.html#analyze/3"},{"type":"function","title":"xref.d/1","doc":"The modules found in the given directory are checked for calls to\n[deprecated functions](`m:xref#deprecated_function`), calls to\n[undefined functions](`m:xref#undefined_function`), and for unused local\nfunctions.\n\nThe code path is used as [library path](`m:xref#library_path`).\n\nIf some of the found BEAM files contain\n[debug information](`m:xref#debug_info`), then those modules are checked and a\nlist of tuples is returned. The first element of each tuple is one of:\n\n- `deprecated`, the second element is a sorted list of calls to deprecated\n functions;\n- `undefined`, the second element is a sorted list of calls to undefined\n functions;\n- `unused`, the second element is a sorted list of unused local functions.\n\nIf no BEAM file contains debug information, then a list of tuples is returned.\nThe first element of each tuple is one of:\n\n- `deprecated`, the second element is a sorted list of externally used\n deprecated functions;\n- `undefined`, the second element is a sorted list of undefined functions.","ref":"xref.html#d/1"},{"type":"function","title":"xref.forget/1","doc":"Removes all [user variables](`m:xref#user_variable`) of an\n[Xref server](`m:xref#xref_server`).","ref":"xref.html#forget/1"},{"type":"function","title":"xref.forget/2","doc":"Removes the [user variables](`m:xref#user_variable`) given by `Variables` from\nan [Xref server](`m:xref#xref_server`).","ref":"xref.html#forget/2"},{"type":"function","title":"xref.format_error/1","doc":"Given the error returned by any function of this module, the function\n`format_error` returns a descriptive string of the error in English.\n\nFor file errors, the function `file:format_error/1` is called.","ref":"xref.html#format_error/1"},{"type":"function","title":"xref.get_default/1","doc":"Returns a list of all options and their default values.","ref":"xref.html#get_default/1"},{"type":"function","title":"xref.get_default/2","doc":"Returns the default value for option `Option`.","ref":"xref.html#get_default/2"},{"type":"function","title":"xref.get_library_path/1","doc":"Returns the [library path](`m:xref#library_path`).","ref":"xref.html#get_library_path/1"},{"type":"function","title":"xref.info/1","doc":"The `info/1` function returns information as a list of pairs `{Tag, term()` in\nsome order about the state and the [module data](`m:xref#module_data`) of an\n[Xref server](`m:xref#xref_server`).\n\n[`info/1`](`info/1`) returns information with the following tags (tags marked\nwith (\\*) are only available in `functions` mode):\n\n- `library_path`, the [library path](`m:xref#library_path`);\n- `mode`, the [mode](`m:xref#mode`);\n- `no_releases`, number of releases;\n- `no_applications`, total number of applications (of all releases);\n- `no_analyzed_modules`, total number of\n [analyzed modules](`m:xref#analyzed_module`);\n- `no_calls` (\\*), total number of calls (in all modules), regarding instances\n of one function call in different lines as separate calls;\n- `no_function_calls` (\\*), total number of [local calls](`m:xref#local_call`),\n resolved [external calls](`m:xref#external_call`) and\n [unresolved calls](`m:xref#unresolved_call`);\n- `no_functions` (\\*), total number of local and exported functions;\n- `no_inter_function_calls` (\\*), total number of calls of the\n [Inter Call Graph](`m:xref#inter_call_graph`).","ref":"xref.html#info/1"},{"type":"function","title":"xref.info/2","doc":"Returns information about all items belonging to category `Category`.\nSee `info/3` for details.","ref":"xref.html#info/2"},{"type":"function","title":"xref.info/3","doc":"The `info` functions return information as a list of pairs `{Tag, term()}` in\nsome order about the state and the [module data](`m:xref#module_data`) of an\n[Xref server](`m:xref#xref_server`).\n\n[`info/2`](`info/2`) and [`info/3`](`info/3`) return information about all or\nsome of the analyzed modules, applications, releases, or library modules of an\nXref server. The following information is returned for every analyzed module:\n\n- `application`, an empty list if the module does not belong to any application,\n otherwise a list of the application name;\n- `builtins`, whether calls to BIFs are included in the module's data;\n- `directory`, the directory where the module's BEAM file is located;\n- `no_calls` (\\*), number of calls, regarding instances of one function call in\n different lines as separate calls;\n- `no_function_calls` (\\*), number of local calls, resolved external calls and\n unresolved calls;\n- `no_functions` (\\*), number of local and exported functions;\n- `no_inter_function_calls` (\\*), number of calls of the Inter Call Graph;\n\nThe following information is returned for every application:\n\n- `directory`, the directory where the modules' BEAM files are located;\n- `no_analyzed_modules`, number of analyzed modules;\n- `no_calls` (\\*), number of calls of the application's modules, regarding\n instances of one function call in different lines as separate calls;\n- `no_function_calls` (\\*), number of local calls, resolved external calls and\n unresolved calls of the application's modules;\n- `no_functions` (\\*), number of local and exported functions of the\n application's modules;\n- `no_inter_function_calls` (\\*), number of calls of the Inter Call Graph of the\n application's modules;\n- `release`, an empty list if the application does not belong to any release,\n otherwise a list of the release name;\n- `version`, the application's version as a list of numbers. For instance, the\n directory \"kernel-2.6\" results in the application name `kernel` and the\n application version \\[2,6]; \"kernel\" yields the name `kernel` and the version\n [].\n\nThe following information is returned for every release:\n\n- `directory`, the release directory;\n- `no_analyzed_modules`, number of analyzed modules;\n- `no_applications`, number of applications;\n- `no_calls` (\\*), number of calls of the release's modules, regarding instances\n of one function call in different lines as separate calls;\n- `no_function_calls` (\\*), number of local calls, resolved external calls and\n unresolved calls of the release's modules;\n- `no_functions` (\\*), number of local and exported functions of the release's\n modules;\n- `no_inter_function_calls` (\\*), number of calls of the Inter Call Graph of the\n release's modules.\n\nThe following information is returned for every library module:\n\n- `directory`, the directory where the\n [library module's](`m:xref#library_module`) BEAM file is located.\n\nFor every number of calls, functions, and so on returned by the `no_` tags, there is a\nquery returning the same number. Listed below are examples of such queries. Some\nof the queries return the sum of a two or more of the `no_` tags numbers. `mod`\n(`app`, `rel`) refers to any module (application, release).\n\n- `no_analyzed_modules`\n\n - `\"# AM\"` (info/1)\n - `\"# (Mod) app:App\"` (application)\n - `\"# (Mod) rel:Rel\"` (release)\n\n- `no_applications`\n\n - `\"# A\"` (info/1)\n\n- `no_calls`. The sum of the number of resolved and unresolved calls:\n\n - `\"# (XLin) E + # (LLin) E\"` (info/1)\n - `\"T = E | mod:Mod, # (LLin) T + # (XLin) T\"` (module)\n - `\"T = E | app:App, # (LLin) T + # (XLin) T\"` (application)\n - `\"T = E | rel:Rel, # (LLin) T + # (XLin) T\"` (release)\n\n- `no_functions`. Functions in library modules and the functions\n `module_info/0,1` are not counted by `info`. Assuming that\n `\"Extra := _:module_info/\\\"(0|1)\\\" + LM\"` has been evaluated, the sum of the\n number of local and exported functions are:\n\n - `\"# (F - Extra)\"` (info/1)\n - `\"# (F * mod:Mod - Extra)\"` (module)\n - `\"# (F * app:App - Extra)\"` (application)\n - `\"# (F * rel:Rel - Extra)\"` (release)\n\n- `no_function_calls`. The sum of the number of local calls, resolved external\n calls and unresolved calls:\n\n - `\"# LC + # XC\"` (info/1)\n - `\"# LC | mod:Mod + # XC | mod:Mod\"` (module)\n - `\"# LC | app:App + # XC | app:App\"` (application)\n - `\"# LC | rel:Rel + # XC | mod:Rel\"` (release)\n\n- `no_inter_function_calls`\n\n - `\"# EE\"` (info/1)\n - `\"# EE | mod:Mod\"` (module)\n - `\"# EE | app:App\"` (application)\n - `\"# EE | rel:Rel\"` (release)\n\n- `no_releases`\n\n - `\"# R\"` (info/1)","ref":"xref.html#info/3"},{"type":"function","title":"xref.m/1","doc":"The given BEAM file (with or without the `.beam` extension) or the file found by\ncalling `code:which(Module)` is checked for calls to\n[deprecated functions](`m:xref#deprecated_function`), calls to\n[undefined functions](`m:xref#undefined_function`), and for unused local\nfunctions.\n\nThe code path is used as [library path](`m:xref#library_path`).\n\nIf the BEAM file contains [debug information](`m:xref#debug_info`), a list\nof tuples is returned. The first element of each tuple is one of:\n\n- `deprecated`, the second element is a sorted list of calls to deprecated\n functions;\n- `undefined`, the second element is a sorted list of calls to undefined\n functions;\n- `unused`, the second element is a sorted list of unused local functions.\n\nIf the BEAM file does not contain debug information, a list of tuples is\nreturned. The first element of each tuple is one of:\n\n- `deprecated`, the second element is a sorted list of externally used\n deprecated functions;\n- `undefined`, the second element is a sorted list of undefined functions.","ref":"xref.html#m/1"},{"type":"function","title":"xref.q/2","doc":"","ref":"xref.html#q/2"},{"type":"function","title":"xref.q/3","doc":"Evaluates a [query](`m:xref#query`) in the context of an\n[Xref server](`m:xref#xref_server`), and returns the value of the last\nstatement.\n\nThe syntax of the value depends on the expression:\n\n- A set of calls is represented by a sorted list without duplicates of\n `t:call/0`.\n- A set of constants is represented by a sorted list without duplicates of\n `t:constant/0`.\n- A set of strongly connected components is a sorted list without duplicates of\n `Component`.\n- A set of calls between strongly connected components is a sorted list without\n duplicates of `ComponentCall`.\n- A chain of calls is represented by a list of `t:constant/0`. The list contains\n the From vertex of every call and the To vertex of the last call.\n- The `of` operator returns `false` if no chain of calls between the given\n constants can be found.\n- The value of the `closure` operator (the `digraph` representation) is\n represented by the atom `'closure()'`.\n- A set of line numbered functions is represented by a sorted list without\n duplicates of `DefineAt`.\n- A set of line numbered function calls is represented by a sorted list without\n duplicates of `CallAt`.\n- A set of line numbered functions and function calls is represented by a sorted\n list without duplicates of `AllLines`.\n\nFor both `CallAt` and `AllLines` it holds that for no list element is\n`LineNumbers` an empty list; such elements have been removed. The constants of\n`component` and the integers of `LineNumbers` are sorted and without duplicates.","ref":"xref.html#q/3"},{"type":"function","title":"xref.remove_application/2","doc":"Removes applications and their modules and [module data](`m:xref#module_data`)\nfrom an [Xref server](`m:xref#xref_server`).","ref":"xref.html#remove_application/2"},{"type":"function","title":"xref.remove_module/2","doc":"Removes [analyzed modules](`m:xref#analyzed_module`) and\n[module data](`m:xref#module_data`) from an [Xref server](`m:xref#xref_server`).","ref":"xref.html#remove_module/2"},{"type":"function","title":"xref.remove_release/2","doc":"Removes releases and their applications, modules, and\n[module data](`m:xref#module_data`) from an [Xref server](`m:xref#xref_server`).","ref":"xref.html#remove_release/2"},{"type":"function","title":"xref.replace_application/3","doc":"","ref":"xref.html#replace_application/3"},{"type":"function","title":"xref.replace_application/4","doc":"Replaces the modules of an application with other modules read from an\napplication directory.\n\nRelease membership of the application is retained. Note that the name\nof the application is kept; the name of the given directory is not\nused.","ref":"xref.html#replace_application/4"},{"type":"function","title":"xref.replace_module/3","doc":"","ref":"xref.html#replace_module/3"},{"type":"function","title":"xref.replace_module/4","doc":"Replaces [module data](`m:xref#module_data`) of an\n[analyzed module](`m:xref#analyzed_module`) with data read from a BEAM file.\n\nApplication membership of the module is retained, and so is the value of the\n`builtins` option of the module. An error is returned if the name of the read\nmodule differs from the given module.\n\nThe `update` function is an alternative for updating module data of recompiled\nmodules.","ref":"xref.html#replace_module/4"},{"type":"function","title":"xref.set_default/2","doc":"Sets default values for multiple options given by `OptionValues`.\n\nSee `set_default/3` for the name of options and their allowed values.","ref":"xref.html#set_default/2"},{"type":"function","title":"xref.set_default/3","doc":"Sets the default value of one or more options.\n\nThe options that can be set this way are:\n\n- `builtins`, with initial default value `false`;\n- `recurse`, with initial default value `false`;\n- `verbose`, with initial default value `false`;\n- `warnings`, with initial default value `true`.\n\nThe initial default values are set when creating an\n[Xref server](`m:xref#xref_server`).","ref":"xref.html#set_default/3"},{"type":"function","title":"xref.set_library_path/2","doc":"","ref":"xref.html#set_library_path/2"},{"type":"function","title":"xref.set_library_path/3","doc":"Sets the [library path](`m:xref#library_path`).\n\nIf the given path is a list of directories, the set of [library\nmodules](`m:xref#library_module`) is determined by choosing the first\nmodule encountered while traversing the directories in the given\norder, for those modules that occur in more than one directory. By\ndefault, the library path is an empty list.\n\nThe library path `code_path`{: #code_path } is used by the functions\n[`m/1`](`m/1`) and [`d/1`](`d/1`), but can also be set explicitly. However,\nnote that the code path will be traversed once for each used\n[library module](`m:xref#library_module`) while setting up module data. On the\nother hand, if there are only a few modules that are used but not analyzed,\nusing `code_path` may be faster than setting the library path to\n`code:get_path/0`.\n\nIf the library path is set to `code_path`, the set of library modules is not\ndetermined, and the `info` functions will return empty lists of library modules.","ref":"xref.html#set_library_path/3"},{"type":"function","title":"xref.start/1","doc":"Creates an [Xref server](`m:xref#xref_server`).\n\nThe process can optionally be given a name. The default\n[mode](`m:xref#mode`) is `functions`. Options that are\nnot recognized by Xref are passed on to `gen_server:start/4`.","ref":"xref.html#start/1"},{"type":"function","title":"xref.start/2","doc":"Creates an [Xref server](`m:xref#xref_server`) with a given name.\n\nThe default [mode](`m:xref#mode`) is `functions`. Options that are\nnot recognized by Xref are passed on to `gen_server:start/4`.","ref":"xref.html#start/2"},{"type":"function","title":"xref.stop/1","doc":"Stops an [Xref server](`m:xref#xref_server`).","ref":"xref.html#stop/1"},{"type":"function","title":"xref.update/1","doc":"","ref":"xref.html#update/1"},{"type":"function","title":"xref.update/2","doc":"Replaces the [module data](`m:xref#module_data`) of all\n[analyzed modules](`m:xref#analyzed_module`) the BEAM files of which have been\nmodified since last read by an `add` function or `update`.\n\nApplication membership of the modules is retained, and so is the value\nof the `builtins`option. Returns a sorted list of the names of\nthe replaced modules.","ref":"xref.html#update/2"},{"type":"function","title":"xref.variables/1","doc":"","ref":"xref.html#variables/1"},{"type":"function","title":"xref.variables/2","doc":"Returns a sorted lists of the names of the variables of an\n[Xref server](`m:xref#xref_server`).\n\nThe default is to return only the\n[user variables](`m:xref#user_variable`).","ref":"xref.html#variables/2"},{"type":"type","title":"xref.add_dir_rsn/0","doc":"","ref":"xref.html#t:add_dir_rsn/0"},{"type":"type","title":"xref.add_mod_rsn/0","doc":"","ref":"xref.html#t:add_mod_rsn/0"},{"type":"type","title":"xref.analysis/0","doc":"","ref":"xref.html#t:analysis/0"},{"type":"type","title":"xref.analyze_rsn/0","doc":"","ref":"xref.html#t:analyze_rsn/0"},{"type":"type","title":"xref.answer/0","doc":"","ref":"xref.html#t:answer/0"},{"type":"type","title":"xref.app_spec/0","doc":"","ref":"xref.html#t:app_spec/0"},{"type":"type","title":"xref.application/0","doc":"","ref":"xref.html#t:application/0"},{"type":"type","title":"xref.call/0","doc":"","ref":"xref.html#t:call/0"},{"type":"type","title":"xref.component/0","doc":"","ref":"xref.html#t:component/0"},{"type":"type","title":"xref.constant/0","doc":"","ref":"xref.html#t:constant/0"},{"type":"type","title":"xref.define_at/0","doc":"","ref":"xref.html#t:define_at/0"},{"type":"type","title":"xref.depr_flag/0","doc":"","ref":"xref.html#t:depr_flag/0"},{"type":"type","title":"xref.directory/0","doc":"","ref":"xref.html#t:directory/0"},{"type":"type","title":"xref.file/0","doc":"","ref":"xref.html#t:file/0"},{"type":"type","title":"xref.file_error/0","doc":"","ref":"xref.html#t:file_error/0"},{"type":"type","title":"xref.func_spec/0","doc":"","ref":"xref.html#t:func_spec/0"},{"type":"type","title":"xref.funcall/0","doc":"","ref":"xref.html#t:funcall/0"},{"type":"type","title":"xref.function_name/0","doc":"","ref":"xref.html#t:function_name/0"},{"type":"type","title":"xref.info/0","doc":"","ref":"xref.html#t:info/0"},{"type":"type","title":"xref.library/0","doc":"","ref":"xref.html#t:library/0"},{"type":"type","title":"xref.library_path/0","doc":"","ref":"xref.html#t:library_path/0"},{"type":"type","title":"xref.mod_spec/0","doc":"","ref":"xref.html#t:mod_spec/0"},{"type":"type","title":"xref.mode/0","doc":"","ref":"xref.html#t:mode/0"},{"type":"type","title":"xref.path/0","doc":"","ref":"xref.html#t:path/0"},{"type":"type","title":"xref.q_rsn/0","doc":"","ref":"xref.html#t:q_rsn/0"},{"type":"type","title":"xref.rel_spec/0","doc":"","ref":"xref.html#t:rel_spec/0"},{"type":"type","title":"xref.release/0","doc":"","ref":"xref.html#t:release/0"},{"type":"type","title":"xref.string_position/0","doc":"","ref":"xref.html#t:string_position/0"},{"type":"type","title":"xref.variable/0","doc":"","ref":"xref.html#t:variable/0"},{"type":"type","title":"xref.xarity/0","doc":"","ref":"xref.html#t:xarity/0"},{"type":"type","title":"xref.xmfa/0","doc":"","ref":"xref.html#t:xmfa/0"},{"type":"type","title":"xref.xref/0","doc":"","ref":"xref.html#t:xref/0"},{"type":"extras","title":"Tools Release Notes","doc":"\n# Tools Release Notes\n\nThis document describes the changes made to the Tools application.","ref":"notes.html"},{"type":"extras","title":"Tools 4.0 - Tools Release Notes","doc":"","ref":"notes.html#tools-4-0"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Dialyzer warnings due to type specs added in `m:dbg` have been eliminated.\n\n Own Id: OTP-18860\n\n- In Erlang/OTP 26, doing a `m:cover` analysis on the `line` level would return multiple entries for lines on which multiple functions were defined.\n \n For example, consider this module:\n \n -module(foo).\n -export([bar/0, baz/0]).\n \n bar() -> ok. baz() -> not_ok.\n \n In Erlang/OTP 26, analysing on the `line` level would return two entries\n for line 4:\n \n 1> cover:compile_module(foo).\n {ok,foo}\n 2> foo:bar().\n ok\n 3> cover:analyse(foo, coverage, line).\n {ok,[{{foo,4},{1,0}},{{foo,4},{0,1}}]}\n 4> cover:analyse(foo, calls, line).\n {ok,[{{foo,4},1},{{foo,4},0}]}\n \n In Erlang/OTP 27, there will only be a single entry for line 4:\n \n 1> cover:compile_module(foo).\n {ok,foo}\n 2> foo:bar().\n ok\n 3> cover:analyse(foo, coverage, line).\n {ok,[{{foo,4},{1,0}}]}\n 4> cover:analyse(foo, calls, line).\n {ok,[{{foo,4},1}]}\n\n Own Id: OTP-18998 Aux Id: [GH-8159], [PR-8182]\n\n- Fixed align command in emacs mode.\n\n Own Id: OTP-19026 Aux Id: [PR-8155]\n\n[GH-8159]: https://github.com/erlang/otp/issues/8159\n[PR-8182]: https://github.com/erlang/otp/pull/8182\n[PR-8155]: https://github.com/erlang/otp/pull/8155","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Triple-Quoted Strings has been implemented as per [EEP 64](https://www.erlang.org/eeps/eep-0064). See [String](`e:system:data_types.md#string`) in the Reference Manual.\n \n Example:\n \n ```erlang\n 1> \"\"\"\n a\n b\n c\n \"\"\".\n \"a\\nb\\nc\"\n ```\n \n Adjacent string literals without intervening white space is now a syntax error, to avoid possible confusion with triple-quoted strings. For example:\n \n ```erlang\n 1> \"abc\"\"xyz\".\n \"xyz\".\n * 1:6: adjacent string literals without intervening white space\n ```\n\n *** POTENTIAL INCOMPATIBILITY ***\n\n Own Id: OTP-18750 Aux Id: OTP-18746, [PR-7313], [PR-7451]\n\n- There is a new tool `m:tprof`, which combines the functionality of `m:eprof` and `m:cprof` under one interface and adds heap profiling. It also has functionality to help with profiling process hierarchies.\n \n *Example*:\n \n ```erlang\n 1> tprof:profile(lists, seq, [1, 16], #{type => call_memory}).\n \n ****** Process <0.92.0> -- 100.00% of total *** \n FUNCTION CALLS WORDS PER CALL [ %]\n lists:seq_loop/3 5 32 6.40 [100.00]\n 32 [ 100.0]\n ok\n ```\n\n Own Id: OTP-18756 Aux Id: [PR-6639]\n\n- Native coverage support has been implemented in the JIT. It will automatically be used by the `m:cover` tool to reduce the execution overhead when running cover-compiled code.\n \n There are also new APIs to support native coverage without using the `cover` tool.\n \n To instrument code for native coverage it must be compiled with the [`line_coverage`](`m:compile#line_coverage`) option.\n \n To enable native coverage in the runtime system, start it like so:\n \n ```text\n $ erl +JPcover true\n ```\n \n There are also the following new functions for supporting native coverage:\n \n * `code:coverage_support/0`\n * `code:get_coverage/2`\n * `code:reset_coverage/1`\n * `code:get_coverage_mode/0`\n * `code:get_coverage_mode/1`\n * `code:set_coverage_mode/1`\n\n Own Id: OTP-18856 Aux Id: [PR-7856]\n\n- The documentation has been migrated to use Markdown and ExDoc.\n\n Own Id: OTP-18955 Aux Id: [PR-8026]\n\n- Improved the align command in emacs mode.\n\n Own Id: OTP-19080 Aux Id: [PR-8288]\n\n[PR-7313]: https://github.com/erlang/otp/pull/7313\n[PR-7451]: https://github.com/erlang/otp/pull/7451\n[PR-6639]: https://github.com/erlang/otp/pull/6639\n[PR-7856]: https://github.com/erlang/otp/pull/7856\n[PR-8026]: https://github.com/erlang/otp/pull/8026\n[PR-8288]: https://github.com/erlang/otp/pull/8288","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 3.6 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-6"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Map comprehensions as suggested in EEP 58 has now been implemented.\n\n Own Id: OTP-18413 Aux Id: EEP-58, PR-6727\n\n- The `instrument` module has been moved from `tools` to `runtime_tools`.\n\n Own Id: OTP-18487 Aux Id: PR-6829","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 3.5.3 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-5-3"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Removed the previously undocumented and unsupported `emem` tool.\n\n Own Id: OTP-17892 Aux Id: PR-5591","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 3.5.2 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-5-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Erlang-mode fixed for newer versions of xref using CL-Lib structures instead\n of EIEIO classes.\n\n Own Id: OTP-17746 Aux Id: GH-5314, PR-5324","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 3.5.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-5-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- The `cover` tool would not work on modules compiled with the `tuple_calls`\n option.\n\n Own Id: OTP-17440 Aux Id: GH-4796","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 3.5 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-5"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- For cover-compiled code, the error behaviour of list and binary comprehensions\n that used `andalso`/`orelse` in guards could be changed so that a filter that\n was supposed be evaluated in guard context was evaluated in body context. That\n is, there was a possibility that comprehensions that did not raise exceptions\n could raise exceptions when being run using `cover`.\n\n Own Id: OTP-17221 Aux Id: PR-4547","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Support for handling abstract code created before OTP R15 has been dropped.\n\n Own Id: OTP-16678 Aux Id: PR-2627\n\n- Add types and specifications for documentation.\n\n Own Id: OTP-16957\n\n- The experimental HiPE application has been removed, together with all related\n functionality in other applications.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-16963","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 3.4.4 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-4-4"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- `cover` would crash when compiling a module having an exported function named\n `clauses`.\n\n Own Id: OTP-17162 Aux Id: GH-4549, PR-2997, PR-4555, elixir-lang/elixir#10666\n\n- If `beam_lib` is asked to return abstract code for a BEAM file produced by\n Elixir and Elixir is not installed on the computer, `beam_lib` will no longer\n crash, but will return an error tuple. The `cover:compile_beam()` and\n `cover:compile_beam_directory()` functions have been updated to also return an\n error tuple in that situation.\n\n Own Id: OTP-17194 Aux Id: GH-4353\n\n- Make emacs mode work on emacs-27.\n\n Own Id: OTP-17225 Aux Id: PR-4542, GH-4451","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 3.4.3 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-4-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Correct the Xref analysis `undefined_functions` to not report internally\n generated behaviour_info/1.\n\n Own Id: OTP-17191 Aux Id: OTP-16922, ERL-1476, GH-4192","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 3.4.2 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-4-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Correct the Xref analysis `exports_not_used` to not report internally\n generated `behaviour_info/1`.\n\n Own Id: OTP-16922 Aux Id: PR-2752","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 3.4.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-4-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Correct the Xref analysis `locals_not_used` to find functions called\n exclusively from `on_load` functions.\n\n Own Id: OTP-16854 Aux Id: PR-2750","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 3.4 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-4"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Updates for new `erlang:term_to_iovec()` BIF.\n\n Own Id: OTP-16128 Aux Id: OTP-15618\n\n- Improved the presentation of allocations and carriers in the `instrument`\n module.\n\n Own Id: OTP-16327\n\n- Minor updates due to the new spawn improvements made.\n\n Own Id: OTP-16368 Aux Id: OTP-15251","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 3.3.1.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-3-1-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- `cover` would crash when compiling a module having an exported function named\n `clauses`.\n\n Own Id: OTP-17162 Aux Id: GH-4549, PR-2997, PR-4555, elixir-lang/elixir#10666","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 3.3.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-3-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- An Emacs warning due to lacking type in defcustom declaration has been fixed.\n\n Own Id: OTP-16356\n\n- Improve emacs indentation.\n\n Own Id: OTP-16472 Aux Id: ERL-1140\n\n- The cover tool could generate instrumented code for a module that would cause\n warnings to be issued.\n\n Own Id: OTP-16476 Aux Id: ERL-1147\n\n- Fixed generated [fprof analysis format](`m:fprof#analysis`) to also handle\n data in maps.\n\n Own Id: OTP-16498 Aux Id: ERL-814","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 3.3 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Improve `-spec` indentation in emacs mode.\n\n Own Id: OTP-16164","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- The Emacs erlang-mode function that lets the user open the documentation for\n an Erlang/OTP function in an Emacs buffer has been improved. Bugs in this\n function has been fixed and and the user will now be asked if the man pages\n should be downloaded automatically by Emacs when they can't be found on the\n system. To test this functionality, put the cursor over the function name in a\n call to an Erlang/OTP function (e.g., \"io:format(\"arg\")\") and type C-c C-d\n (i.e., Ctrl-key and c-key and then Ctrl-key and d-key). There is also a new\n menu item under the Erlang menu (labeled \"Man - Function Under Cursor\").\n\n Own Id: OTP-16174","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 3.2.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-2-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- `cover` would fail to start if two processes tried to start it at the exact\n same time.\n\n Own Id: OTP-15813 Aux Id: ERL-943","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 3.2 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Add `cprof` and `tags` modules to .app file so that they are included in\n releases.\n\n Own Id: OTP-15534 Aux Id: PR-2078\n\n- Improved documentation parsing in emacs erldoc functionality.\n\n Own Id: OTP-15699 Aux Id: PR-2184","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- The `cover` tool now uses the `counters` module instead of `ets` for updating\n the counters for how many times a line has been executed. By default, Cover\n will work with distributed nodes, but a new function `cover:local_only/0`\n allows running the Cover in a restricted but faster local-only mode.\n\n The increase in speed will vary depending on the type of code being\n cover-compiled, but as an example, the compiler test suite runs more than\n twice as fast with the new Cover.\n\n Own Id: OTP-15575","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 3.1.0.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-1-0-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- `cover` would fail to start if two processes tried to start it at the exact\n same time.\n\n Own Id: OTP-15813 Aux Id: ERL-943","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 3.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Minor fixes for `make clean`.\n\n Own Id: OTP-15657","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- In the HTML file generated by `cover:analyse_to_file/1,2`, a link is now added\n to the line number. This makes it easier to share pointers to specific lines.\n\n Own Id: OTP-15541\n\n- Uncovered lines are now marked with a sad face, `:-(`, in the HTML output from\n `cover:analyse_to_file/1,2`. This is to make these lines easier to find by\n search.\n\n Own Id: OTP-15542","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 3.0.2 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-0-2"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Remove emacs warnings and added more tests.\n\n Own Id: OTP-15476","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 3.0.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-0-1"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- The HTML pages generated by cover:analyse_to_file/1 and related functions is\n improved for readability.\n\n Own Id: OTP-15213 Aux Id: PR-1807\n\n- Add alignment functionality in emacs.\n\n Own Id: OTP-15239 Aux Id: PR-1728","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 3.0 - Tools Release Notes","doc":"","ref":"notes.html#tools-3-0"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Added `instrument:allocations` and `instrument:carriers` for retrieving\n information about memory utilization and fragmentation.\n\n The old `instrument` interface has been removed, as have the related options\n `+Mim` and `+Mis`.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-14961","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.11.2.2 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-11-2-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- `cover` would fail to start if two processes tried to start it at the exact\n same time.\n\n Own Id: OTP-15813 Aux Id: ERL-943","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.11.2.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-11-2-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Minor fixes for `make clean`.\n\n Own Id: OTP-15657","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.11.2 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-11-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- A counting bug is corrected in `Cover`. The bug was introduced in Erlang/OTP\n 18.0.\n\n Own Id: OTP-14817 Aux Id: PR 1641\n\n- The `lcnt` server will no longer crash if `lcnt:information/0` is called\n before `lcnt:collect/0`.\n\n Own Id: OTP-14912\n\n- `lcnt:collect` will now implicitly start the `lcnt` server, as per the\n documentation.\n\n Own Id: OTP-14913","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Improved indentation in emacs and various other updates.\n\n Own Id: OTP-14944","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.11.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-11-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Removed all old unused files in the documentation.\n\n Own Id: OTP-14475 Aux Id: ERL-409, PR-1493","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.11 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-11"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- The predefined Xref analysis `locals_not_used` no longer reports unused\n functions with the `-on_load()` attribute.\n\n The new predefined Xref variable `OL` holds all functions with the\n `-on_load()` attribute.\n\n Own Id: OTP-14344\n\n- In fprof when sampling multiple processes and analyzing with totals set to\n true, the output now sums together all caller and callee entries which\n concerns the same function. Previous behaviour was to report each contributing\n entry separately.\n\n Own Id: OTP-14500","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Lock counting can now be fully toggled at runtime in the lock counting\n emulator (`-emu_type lcnt`). Everything is enabled by default to match the old\n behavior, but specific categories can be toggled at will with minimal runtime\n overhead when disabled. Refer to the documentation on `lcnt:rt_mask/1` for\n details.\n\n Own Id: OTP-13170\n\n- `lcnt:collect` and `lcnt:clear` will no longer block all other threads in the\n runtime system.\n\n Own Id: OTP-14412\n\n- General Unicode improvements.\n\n Own Id: OTP-14462\n\n- Tools are updated to show Unicode atoms correctly.\n\n Own Id: OTP-14464\n\n- Add `erlang:iolist_to_iovec/1`, which converts an iolist() to an\n erlang:iovec(), which suitable for use with `enif_inspect_iovec`.\n\n Own Id: OTP-14520","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.10.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-10-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- In OTP-20.0, the behavior of c, make, and ct_make was changed so that in some\n cases the beam files by default would be written to the directory where the\n source files were found. This is now changed back to the old behavior so beam\n files are by default written to current directory.\n\n Own Id: OTP-14489 Aux Id: ERL-438","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.10 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-10"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- In some situations, `make:all()` and friends did not detect changes in include\n files located in the current directory. This is now corrected.\n\n Own Id: OTP-14339 Aux Id: ERL-395","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- The `make` module now accepts the `{emake,Emake}` option.\n\n Own Id: OTP-14253\n\n- Miscellaneous updates due to atoms containing arbitrary Unicode characters.\n\n Own Id: OTP-14285","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.9.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-9-1"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Improved edoc support in emacs mode.\n\n Own Id: OTP-14217 Aux Id: PR-1282","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.9 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-9"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Fix unhandled trace event send_to_non_existing_process in fprof.\n\n Own Id: OTP-13998","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Improved edoc support in emacs erlang-mode.\n\n Own Id: OTP-13945 Aux Id: PR-1157\n\n- Added erldoc to emacs mode which opens html documentation in browser from\n emacs. For example `M-x erldoc-browse RET lists:foreach/2`.\n\n Own Id: OTP-14018 Aux Id: PR-1197","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.8.6 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-8-6"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Errors in type specification and Emacs template generation for\n `gen_statem:code_change/4` has been fixed from bugs.erlang.org's Jira cases\n ERL-172 and ERL-187.\n\n Own Id: OTP-13746 Aux Id: ERL-172, ERL-187\n\n- Fix gc_start/gc_end in fprof tags when parsing old trace logs.\n\n Own Id: OTP-13778 Aux Id: PR-1136\n\n- `make` (tools) and `ct_make` (common_test) would crash if an Erlang source\n file contained a `-warning()` directive.\n\n Own Id: OTP-13855","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.8.5 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-8-5"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Correct a bug when adding multiple modules to an Xref server. The bug was\n introduced in OTP-19.0.\n\n Own Id: OTP-13708 Aux Id: ERL-173","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.8.4 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-8-4"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Update fprof to use the new 'spawned' trace event to determine when a process\n has been created.\n\n Own Id: OTP-13499","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Optimize adding multiple modules to an Xref server.\n\n Own Id: OTP-13593\n\n- Various emacs mode improvements, such as better tags support.\n\n Own Id: OTP-13610","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.8.3 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-8-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- `cover:compile_beam/1` and `cover:compile_beam_directory/1,2` crashed when\n trying to compile a beam file without a `'file'` attribute. This has been\n corrected and an error is returned instead.\n\n Thanks to Louis-Philippe Gauthier for reporting this bug.\n\n Own Id: OTP-13200\n\n- Fix a bit string comprehension bug in Cover.\n\n Own Id: OTP-13277 Aux Id: PR 856","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.8.2 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-8-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- The emacs mode does not add a newline after the arrow on -callback lines\n anymore.\n\n Own Id: OTP-13042","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.8.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-8-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- If a module includes eunit.hrl, a parse transform adds the function test/0 on\n line 0 in the module. A bug in OTP-18.0 caused cover:analyse_to_file/1 to fail\n to insert cover data in the output file when line 0 existed in the cover data\n table. This is now corrected.\n\n Own Id: OTP-12981","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.8 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-8"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- In order to improve performance of the cover tool, new functions are added for\n cover compilation and analysis on multiple files. This allows for more\n parallelisation.\n\n Some improvements of the data base access is also done in order to improve the\n performance when analysing and resetting cover data.\n\n Minor incompatibility: An error reason from analyse_to_file is changed from\n no_source_code_found to \\{no_source_code_found,Module\\}.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-12330 Aux Id: seq12757\n\n- Attempting to do a `cover` analysis when neither source code nor beam file\n could be found would hang the `cover` server. Corrected to return a proper\n error.\n\n Own Id: OTP-12806","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Allow maps for supervisor flags and child specs\n\n Earlier, supervisor flags and child specs were given as tuples. While this is\n kept for backwards compatibility, it is now also allowed to give these\n parameters as maps, see [sup_flags](`m:supervisor#sup_flags`) and\n [child_spec](`m:supervisor#child_spec`).\n\n Own Id: OTP-11043\n\n- Remove Mnemosyne rules support.\n\n Own Id: OTP-12511\n\n- Add printout of total number of calls and time in eprof\n\n Own Id: OTP-12681","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.7.2 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-7-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Fix lcnt sorting and printout of histograms.\n\n Own Id: OTP-12364\n\n- Fix a Unicode bug in the `tags` module.\n\n Own Id: OTP-12567\n\n- Fix tags completion in erlang.el for GNU Emacs 23+\n\n Own Id: OTP-12583","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.7.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-7-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Fixed a typo in erlang-mode comment.\n\n Own Id: OTP-12214\n\n- Add a skeleton for -spec in Erlang mode for Emacs\n\n Own Id: OTP-12283","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Cover no longer crashes when compiling `receive` and the like with just an\n `after` clause. Thanks to José Valim for providing a fix.\n\n Own Id: OTP-12328","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.7 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-7"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Add log2 histogram to lcnt for lock wait time\n\n Own Id: OTP-12059","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.6.15 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-15"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Removed `erlang:bitstr_to_list/1` and `erlang:list_to_bitstr/1`. They were\n added by mistake, and have always raised an `undefined` exception when called.\n\n Own Id: OTP-11942","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.6.14 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-14"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Removed the support for the query keyword from emacs mode (Thanks to Paul\n Oliver)\n\n Own Id: OTP-11568\n\n- Emacs mode improvements (Thanks to Steve Vinoski)\n\n Own Id: OTP-11601\n\n- Application upgrade (appup) files are corrected for the following\n applications:\n\n `asn1, common_test, compiler, crypto, debugger, dialyzer, edoc, eldap, erl_docgen, et, eunit, gs, hipe, inets, observer, odbc, os_mon, otp_mibs, parsetools, percept, public_key, reltool, runtime_tools, ssh, syntax_tools, test_server, tools, typer, webtool, wx, xmerl`\n\n A new test utility for testing appup files is added to test_server. This is\n now used by most applications in OTP.\n\n (Thanks to Tobias Schlager)\n\n Own Id: OTP-11744\n\n- The emacs erlang mode now match erlang keywords more carefully (Thanks to\n Steve Vinoski)\n\n Own Id: OTP-11786\n\n- The emacs erlang-mode now auto loads for more file types (Thanks to Phil\n Hagelberg)\n\n Own Id: OTP-11788","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- `cover` can run on itself. Also, support for reading BEAM files produced by\n ancient OTP versions before R9C has been removed.\n\n Own Id: OTP-11692\n\n- Support maps in cover\n\n Own Id: OTP-11764","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.6.13 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-13"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Erlang-specific compilation error regexp is added in erlang-eunit.el. This\n defvar was earlier in erlang.el, but was erroneously removed in R15B02, while\n still used by erlang-eunit.el.\n\n Own Id: OTP-11417 Aux Id: seq12447\n\n- Take compiler options from beam in cover:compile_beam. Thanks to Péter Gömöri.\n\n Own Id: OTP-11439\n\n- Silence warnings (Thanks to Anthony Ramine)\n\n Own Id: OTP-11517","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Add iodata, nonempty_string to built-in type highlighting for emacs. Thanks to\n Paul Oliver.\n\n Own Id: OTP-11394","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.6.12 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-12"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Remove trailing spaces in Emacs templates. Thanks to Roberto Aloi.\n\n Own Id: OTP-11198\n\n- Fixed the Emacs erlang-mode to accommodate the coding style where lists\n written across several lines have each line starting with a comma. Thanks to\n Magnus Henoch.\n\n Own Id: OTP-11242\n\n- Make the Emacs Erlang mode TRAMP-aware when compiling. Thanks to Tomas\n Abrahamsson.\n\n Own Id: OTP-11270","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.6.11 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-11"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- When cover:stop(Node) was called on a non-existing node, a process waiting for\n cover data from the node would hang forever. This has been corrected.\n\n Own Id: OTP-10979","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Make cover smarter about finding source from beam.\n\n In particular, search using the source path in module_info if the current\n heuristic fails.\n\n Own Id: OTP-10902\n\n- Remove Flymake dependency in erlang-pkg.el. Thanks to Magnus Henoch.\n\n Own Id: OTP-10930\n\n- Erlang-mode: Add autoload cookies for file extension associations. Thanks to\n Magnus Henoch.\n\n Own Id: OTP-10999\n\n- Postscript files no longer needed for the generation of PDF files have been\n removed.\n\n Own Id: OTP-11016\n\n- Fix a race condition when there're several applications in apps directory.\n Thanks to Manuel Rubio.\n\n Own Id: OTP-11028\n\n- New option for eprof, 'set_on_spawn'. This option was previously always on and\n is also the default.\n\n Own Id: OTP-11144","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.6.10 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-10"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Fix a bug in cover when used with no_auto_import. Thanks to José Valim.\n\n Own Id: OTP-10778","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.6.9 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-9"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Add missing modules in app-file\n\n Own Id: OTP-10439\n\n- Make erlang-mode more compatible with package.el (Thanks to Gleb Peregud)\n\n Own Id: OTP-10465\n\n- Fix various typos (thanks to Tuncer Ayaz)\n\n Own Id: OTP-10611\n\n- Add separate face for exported functions (Thanks to Thomas Järvstrand)\n\n Own Id: OTP-10637\n\n- The BIF highlighting in the emacs mode has been updated to correspond with the\n correct BIFs.\n\n Own Id: OTP-10774","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Support for Unicode has been implemented.\n\n Own Id: OTP-10302\n\n- A new function, cover:flush(Nodes), is added which will fetch data from remote\n nodes without stopping cover on those nodes. This is used by test_server and\n common_test when it is safe to assume that the node will be terminated after\n the test anyway. The purpose is to avoid processes crashing when re-loading\n the original beam if the processes is still running old code.\n\n Remote nodes will now continue to count code coverage if the connection to the\n main node is broken. Earlier, a broken connection would cause the cover_server\n on the remote node to die and thus any still cover compiled modules would\n cause process crash when trying to insert cover data in ets tables that used\n to exist on the cover_server. The new functionality also involves\n synchronization with the main node if the nodes are reconnected.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-10523 Aux Id: OTP-10427\n\n- Where necessary a comment stating encoding has been added to Erlang files. The\n comment is meant to be removed in Erlang/OTP R17B when UTF-8 becomes the\n default encoding.\n\n Own Id: OTP-10630\n\n- Fix syntax highlighting of $\\\\' in Emacs mode. Thanks to Magnus Henoch.\n\n Own Id: OTP-10766","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.6.8 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-8"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- The last tuple fun call has been removed from fprof.\n\n Own Id: OTP-10091 Aux Id: seq12067\n\n- Fix indentation of record fields in Emacs (Thanks to Tomas Abrahamsson)\n\n Own Id: OTP-10120\n\n- Documentation fixes (Thanks to Ricardo Catalinas Jiménez )\n\n Own Id: OTP-10121\n\n- Remove Erlang-specific compilation error regexp in erlang.el\n\n Own Id: OTP-10168\n\n- Fix highlighting of atoms ending with a dollar sign\n\n Like this: 'atom$'. In that example, the last single quote should be\n recognised as ending the atom. This needs a font-lock workaround similar to\n the one for strings. Thanks to Magnus Henoch\n\n Own Id: OTP-10178\n\n- Xref now accepts filenames with character codes greater than 126. (Thanks to\n Emile Joubert for reporting the issue.)\n\n Own Id: OTP-10192\n\n- Add test_indentation target to lib/tools/emacs/Makefile\n\n Automatically indent test.erl.orig, save to test.erl, and compare to\n test.erl.intended. Thanks to Magnus Henoch.\n\n Own Id: OTP-10226","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.6.7 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-7"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Makefiles in erts, hipe and tools have been corrected to enable parallel make,\n i.e MAKEFLAGS=-jX where X is the parallelity number. As a result of this\n dependencies were corrected since that is what is needed for parallel make to\n work.\n\n Own Id: OTP-9857 Aux Id: OTP-9451\n\n- Minor suppressions and fixes of compilation warnings\n\n Own Id: OTP-10016","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.6.6.6 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-6-6"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Update system profiling principles to reflect eprof performance improvements.\n\n Own Id: OTP-9656\n\n- \\[cover] fix leftover \\{'DOWN', ..\\} msg in callers queue\n\n After stopping cover with cover:stop() there could still be a \\{'DOWN',...\\}\n leftover message in the calling process's message queue. This unexpected\n leftover could be eliminated if erlang:demonitor/2 with option flush would be\n used in certain points\n\n Own Id: OTP-9694\n\n- Add deps as erlang-flymake include directory.\n\n Update erlang-flymake to recognize the \"deps\" folder as an include directory.\n This makes erlang-flymake compatible with the rebar dependency management\n tool's default folder structure, which puts included dependencies in\n \"deps\".(Thanks to Kevin Albrecht)\n\n Own Id: OTP-9791","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Variables are now now allowed in '`fun M:F/A`' as suggested by Richard O'Keefe\n in EEP-23.\n\n The representation of '`fun M:F/A`' in the abstract format has been changed in\n an incompatible way. Tools that directly read or manipulate the abstract\n format (such as parse transforms) may need to be updated. The compiler can\n handle both the new and the old format (i.e. extracting the abstract format\n from a pre-R15 BEAM file and compiling it using compile:forms/1,2 will work).\n The `syntax_tools` application can also handle both formats.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-9643\n\n- Tuple funs (a two-element tuple with a module name and a function) are now\n officially deprecated and will be removed in R16. Use '`fun M:F/A`' instead.\n To make you aware that your system uses tuple funs, the very first time a\n tuple fun is applied, a warning will be sent to the error logger.\n\n Own Id: OTP-9649\n\n- Eliminate use of deprecated regexp module\n\n Own Id: OTP-9810","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.6.6.5 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-6-5"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Teach the emacs mode to compile yecc and leex files\n\n If visiting a .yrl or .xrl file in emacs with erlang-mode, then the\n \\`erlang-compile' function (normally bound to C-c C-k), now knows how to\n compile yecc and leex files, and then, if that compilation succeeds, also\n compiles the resulting .erl files.\n\n Also introduce a \\`erlang-compile-command-function-alist' to make it possible\n to hook in other functions for computing compilation commands/expressions,\n depending on file name. (Thanks to Tomas Abrahamsson )\n\n Own Id: OTP-9503","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Bugs in xref(3) have been fixed. (Thanks to Matthias Lang.)\n\n Own Id: OTP-9416","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.6.6.4 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-6-4"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Change make:files to behave more like erlc\n\n This change removes the unnecessary checks on the files when make:files is\n called and allows the error checking to be done in compile:file, where the\n error messages are produced. It does not affect the return value.\n\n (Thanks to Sam bobroff)\n\n Own Id: OTP-9179\n\n- add user specified compiler options on form reloading\n\n In order to be able to test non-exported functions from another (test) module\n it is necessary to compile the specific module (at least during the test\n phase) with the export*all compiler option. This allows complete separation of\n testing and productive code. At the moment it is not possible to combine this\n with a test code coverage using the cover module. The problem is that when\n cover compiling a module using cover:compile*\\* the code is reloaded into the\n emulator omitting/filtering the passed user options. In my example above the\n export_all option would be removed and the non-exported functions cannot be\n called any more. (Thanks to Tobias Schlager)\n\n Own Id: OTP-9204\n\n- Inhibit electric newline after \"->\" when inside a type spec\n\n The Erlang mode for Emacs inserts a newline after every \"->\", which saves you\n one keystroke when writing a function, but that is inappropriate when writing\n a type spec, as you'd normally keep the spec on one line. This change inhibits\n the automatic insertion when the current line starts with \"-spec\" or\n \"-type\".(Thanks to Magnus Henoch)\n\n Own Id: OTP-9255\n\n- Add a check logic to prevent file descriptor leak\n\n cover module handle files as raw in export and import. Assert counts of ports\n are the same at the beginning and at the end of the test case.(Thanks to\n Shunichi Shinohara)\n\n Own Id: OTP-9300","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.6.6.3 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-6-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Declare indentation options as \"safe\" in erlang-mode for Emacs\n\n Emacs has a facility for setting options on a per-file basis based on comments\n in the source file. By default, all options are considered \"unsafe\", and the\n user is queried before the variable is set. This patch declares the variables\n erlang-indent-level, erlang-indent-guard and erlang-argument-indent to be\n safe, if the value specified in the source file is valid.\n\n Such declarations usually look like this:\n\n %% -_- erlang-indent-level: 2 -_-\n\n and appear on the first line of the file. (thanks to Magnus Henoch)\n\n Own Id: OTP-9122","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Cover has been improved to take less memory and allow parallel analysis of\n cover data. Data collection from nodes is now done in parallel and it is now\n possible to issue multiple analyse and analyse_to_file requests at the same\n time. A new function call async_analyse_to_file has also been introduced, see\n the documentation for more details.\n\n Own Id: OTP-9043 Aux Id: seq11771","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.6.6.2 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-6-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- eprof: API sort mismatch has now been fixed.\n\n Own Id: OTP-8853\n\n- eprof: fix division by zero in statistics\n\n Own Id: OTP-8963","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.6.6.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-6-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- `cover` will now show ampersand characters in the source code correctly.\n (Thanks to Tom Moertel.)\n\n Own Id: OTP-8776","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.6.6 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-6"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- A race condition affecting Cover has been removed.\n\n Own Id: OTP-8469\n\n- Emacs improvements:\n\n Fixed emacs-mode installation problems.\n\n Fixed a couple of -spec and -type indentation and font-lock problems.\n\n Fixed error messages on emacs-21.\n\n Magnus Henoch fixed several issues.\n\n Ralf Doering, Klas Johansson and Chris Bernard contributed various emacs-eunit\n improvements.\n\n Klas Johansson and Dave Peticolas added emacs-flymake support.\n\n Own Id: OTP-8530","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Xref has been updated to use the `re` module instead of the deprecated\n `regexp` module.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-8472\n\n- When given the option `{builtins,true}` Xref now adds calls to operators.\n\n Own Id: OTP-8647\n\n- `eprof` has been reimplemented with support in the Erlang virtual machine and\n is now both faster (i.e. slows down the code being measured less) and scales\n much better. In measurements we saw speed-ups compared to the old eprof\n ranging from 6 times (for sequential code that only uses one scheduler/core)\n up to 84 times (for parallel code that uses 8 cores).\n\n Note: The API for the `eprof` has been cleaned up and extended. See the\n documentation.\n\n \\*** POTENTIAL INCOMPATIBILITY \\***\n\n Own Id: OTP-8706","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.6.5.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-5-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- A bug concerning bit comprehensions has been fixed in Cover. The bug was\n introduced in R13B03. (Thanks to Matthew Sackman.)\n\n Own Id: OTP-8340","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Add lock profiling tool.\n\n The Lock profiling tool, lcnt, can make use of the internal lock statistics\n when the runtime system is built with this feature enabled.\n\n This provides a mechanism to examine potential lock bottlenecks within the\n runtime itself.\n\n \\- Add erts_debug:lock_counters(\\{copy_save, bool()\\}). This option enables or\n disables statistics saving for destroyed processes and ets-tables. Enabling\n this might consume a lot of memory.\n\n \\- Add id-numbering for lock classes which is otherwise undefined.\n\n Own Id: OTP-8424\n\n- emacs: Moved code skeletons to a separate file and and added a configurable\n variable to choose skeleton. Thanks Dave Peticolas.\n\n Own Id: OTP-8446","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.6.5 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-5"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- The coverage analysis tool `cover` has been improved when it comes to handling\n list and bit string comprehensions (a counter for each qualifier), bit syntax\n expressions (the Value and Size expressions), and try expressions (the body\n called `Exprs` in the Reference Manual). A few (not all) situations where\n several expressions are put on the same line are also handled better than\n before.\n\n Own Id: OTP-8188 Aux Id: seq11397\n\n- When loading Cover compiled code on remote nodes running code in the loaded\n module, a `badarg` failure was sometimes the result. This bug has been fixed.\n\n Own Id: OTP-8270 Aux Id: seq11423\n\n- The short-circuit operators `andalso` and `orelse` are now handled correctly\n by the coverage analysis tool `cover` (it is no longer checked that the second\n argument returns a Boolean value.)\n\n Own Id: OTP-8273","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.6.4 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-4"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- `cover` now properly escapes greater-than and less-than characters in comments\n in HTML reports. (Thanks to Magnus Henoch.)\n\n Own Id: OTP-7939","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.6.3 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-3"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- xref:start/1 does now allow anonymous XREF processes to be started\n\n Own Id: OTP-7831","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.6.2 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- A bug in the Xref scanner has been fixed.\n\n Own Id: OTP-7423\n\n- A bug in Fprof where the function 'undefined' appeared to call 'undefined' has\n been corrected.\n\n Own Id: OTP-7509","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.6.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6-1"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- The documentation has been updated so as to reflect the last updates of the\n Erlang shell as well as the minor modifications of the control sequence `p` of\n the `io_lib` module.\n\n Superfluous empty lines have been removed from code examples and from Erlang\n shell examples.\n\n Own Id: OTP-6944 Aux Id: OTP-6554, OTP-6911\n\n- [`tuple_size/1`](`tuple_size/1`) and [`byte_size/1`](`byte_size/1`) have been\n substituted for [`size/1`](`size/1`).\n\n Own Id: OTP-7009\n\n- The coverage analysis tool `cover` now handles the short-circuit Boolean\n expressions `andalso/2` and `orelse/2` properly.\n\n Own Id: OTP-7095","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.6 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-6"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- The `cover` tool could use huge amounts of memory when used in a distributed\n system.\n\n Own Id: OTP-6758","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.5.5 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-5-5"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Missing buffer-local declaration in erlang.el has been added. Before this fix\n there could arise problems in other emacs modes after visiting a buffer using\n the erlang mode.\n\n Own Id: OTP-6721\n\n- Key-map for 'backward-delete-char-untabif updated to work properly with\n Xemacs.\n\n Own Id: OTP-6723","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Minor updates of Xref.\n\n Own Id: OTP-6586\n\n- Minor Makefile changes.\n\n Own Id: OTP-6689 Aux Id: OTP-6742\n\n- \"C-u C-c C-k\" now does a compile with both \"debug_info\" and \"export_all\".\n\n Own Id: OTP-6741","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.5.4.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-5-4-1"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Changes due to internal interface changes in the erts application which are\n needed at compile-time. No functionality has been changed.\n\n Own Id: OTP-6611 Aux Id: OTP-6580","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.5.4 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-5-4"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Made change to support the function erlang-find-tag for xemacs and emacs-21.\n\n Own Id: OTP-6512","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Minor updates of xref for future compatibility.\n\n Own Id: OTP-6513","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.5.3 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-5-3"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- `eprof` did not work reliably in the SMP emulator, because the trace receiver\n process could not process the trace messages fast enough. Therefore, `eprof`\n now blocks the other schedulers while profiling.\n\n Own Id: OTP-6373","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.5.2 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-5-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Fprof traces could become truncated for the SMP emulator. This bug has now\n been corrected.\n\n Own Id: OTP-6246","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.5.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-5-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- eprof now works somewhat better in the SMP emulator.\n\n Own Id: OTP-6152","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.5 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-5"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Fixed some bugs in `make`:\n\n `make:files/1,2` can now handle a file in another directory as argument,\n similar to `make:all/0,1`.\n\n When specifying a file name including the `.erl` extension in `Emakefile`,\n `make:all/0,1` looked for the object code in the wrong place.\n\n When specifying a file name including the `.erl` extension in `Emakefile` and\n some compile options for the file, `make:files/0,1` did not use the options as\n it should do.\n\n Own Id: OTP-6057 Aux Id: seq10299\n\n- `cover`: When `cover:stop()` was called, the cover compiled code was not\n unloaded (as stated in the documentation) but simply marked as 'old'. This\n meant that processes lingering in (or with funs referencing to) the cover\n compiled code would survive even when the cover server and its ETS tables was\n terminated.\n\n Now the cover compiled code is unloaded, meaning that processes lingering\n in/with references to it will be killed when `cover:stop` is called, instead\n of later crashing with `badarg` when trying to bump counters in ETS tables no\n longer existing.","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- Replaced call to deprecated function `file:file_info/1` with call to\n `filelib:is_dir/1` and `filelib:is_regular/1` in `tags.erl`.\n\n Own Id: OTP-6079","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.4.7 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-4-7"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- A bug in `fprof` profiling causing erroneous inconsistent trace failure has\n been corrected.\n\n Own Id: OTP-5922 Aux Id: seq10203","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.4.6 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-4-6"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- Emacs: `erlang-man-function` and `erlang-man-module` used a pattern matching\n to find the requested module that sometimes yielded unexpected results. For\n example, `erlang-man-module file` would display the man page for\n `CosFileTransfer_File`.\n\n Own Id: OTP-5746 Aux Id: seq10096\n\n- Some compiler warnings and Dialyzer warnings were eliminated in the Tools\n application.\n\n When tracing to a port (which `fprof` does), there could be fake schedule\n out/schedule in messages sent for a process that had exited.\n\n Own Id: OTP-5757","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.4.5 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-4-5"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- The cross reference tool `xref` did not handle the new `fun M:F/A` construct\n properly. This problem has been fixed.\n\n Own Id: OTP-5653","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.4.4 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-4-4"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- The `cover` tool did not escape '<' and '>' not being part of HTML tags in\n HTML log files.\n\n Own Id: OTP-5588","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.4.3 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-4-3"},{"type":"extras","title":"Improvements and New Features - Tools Release Notes","doc":"- It is now possible to encrypt the debug information in beam files, to help\n keep the source code secret. See `m:compile` for how to provide the key for\n encrypting, and `m:beam_lib` for how to provide the key for decryption so that\n tools such as Debugger, `xref`, or `cover` can be used.\n\n The `beam_lib:chunks/2` functions now accepts an additional chunk type\n '`compile_info`' to retrieve the compilation information directly as a term.\n (Thanks to Tobias Lindahl.)\n\n Own Id: OTP-5460 Aux Id: seq9787","ref":"notes.html#improvements-and-new-features"},{"type":"extras","title":"Tools 2.4.2 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-4-2"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- The `cover` tool could not analyze empty modules on module level.\n\n Own Id: OTP-5418","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"Tools 2.4.1 - Tools Release Notes","doc":"","ref":"notes.html#tools-2-4-1"},{"type":"extras","title":"Fixed Bugs and Malfunctions - Tools Release Notes","doc":"- The `xref` analysis `locals_not_used` could return too many functions. This\n problem has been fixed.\n\n Own Id: OTP-5071\n\n- The `cover` tool could not always compile parse transformed modules. This\n problem has been fixed.\n\n Own Id: OTP-5305","ref":"notes.html#fixed-bugs-and-malfunctions"},{"type":"extras","title":"cover - The Coverage Analysis Tool","doc":"\n# cover - The Coverage Analysis Tool","ref":"cover_chapter.html"},{"type":"extras","title":"Introduction - cover - The Coverage Analysis Tool","doc":"The module `cover` provides a set of functions for coverage analysis of Erlang\nprograms, counting how many times each [executable line](cover_chapter.md#lines)\nis executed.\n\nCoverage analysis can be used to verify test cases, making sure all relevant\ncode is covered, and can be helpful when looking for bottlenecks in the code.","ref":"cover_chapter.html#introduction"},{"type":"extras","title":"Getting Started With Cover - cover - The Coverage Analysis Tool","doc":"","ref":"cover_chapter.html#getting-started-with-cover"},{"type":"extras","title":"Example - cover - The Coverage Analysis Tool","doc":"Assume that a test case for the following program should be verified:\n\n```erlang\n-module(channel).\n-behaviour(gen_server).\n\n-export([start_link/0,stop/0]).\n-export([alloc/0,free/1]). % client interface\n-export([init/1,handle_call/3,terminate/2]). % callback functions\n\nstart_link() ->\n gen_server:start_link({local,channel}, channel, [], []).\n\nstop() ->\n gen_server:call(channel, stop).\n\n%%%-Client interface functions-------------------------------------------\n\nalloc() ->\n gen_server:call(channel, alloc).\n\nfree(Channel) ->\n gen_server:call(channel, {free,Channel}).\n\n%%%-gen_server callback functions----------------------------------------\n\ninit(_Arg) ->\n {ok,channels()}.\n\nhandle_call(stop, _Client, Channels) ->\n {stop,normal,ok,Channels};\n\nhandle_call(alloc, _Client, Channels) ->\n {Ch,Channels2} = alloc(Channels),\n {reply,{ok,Ch},Channels2};\n\nhandle_call({free,Channel}, _Client, Channels) ->\n Channels2 = free(Channel, Channels),\n {reply,ok,Channels2}.\n\nterminate(_Reason, _Channels) ->\n ok.\n\n%%%-Internal functions---------------------------------------------------\n\nchannels() ->\n [ch1,ch2,ch3].\n\nalloc([Channel|Channels]) ->\n {Channel,Channels};\nalloc([]) ->\n false.\n\nfree(Channel, Channels) ->\n [Channel|Channels].\n```\n\nThe test case is implemented as follows:\n\n```erlang\n-module(test).\n-export([s/0]).\n\ns() ->\n {ok,Pid} = channel:start_link(),\n {ok,Ch1} = channel:alloc(),\n ok = channel:free(Ch1),\n ok = channel:stop().\n```","ref":"cover_chapter.html#example"},{"type":"extras","title":"Preparation - cover - The Coverage Analysis Tool","doc":"First of all, Cover must be started. This spawns a process which owns the Cover\ndatabase where all coverage data will be stored.\n\n```erlang\n1> cover:start().\n{ok,<0.90.0>}\n```\n\nTo include other nodes in the coverage analysis, use\n`cover:start/1`. All cover-compiled modules will then be loaded on all\nnodes, and data from all nodes will be summed up when analysing. For\nsimplicity this example only involves the current node.\n\nBefore any analysis can take place, the involved modules must be\n_cover-compiled_. This means that some extra information is added to\nthe module before beging compiled into a binary and\n[loaded](cover_chapter.md#loading). The source file of the module is\nnot affected and no `.beam` file is created.\n\n```erlang\n2> cover:compile_module(channel).\n{ok,channel}\n```\n\nEach time a function in the cover-compiled module `channel` is called,\ninformation about the call will be added to the Cover database. Run the test\ncase:\n\n```text\n3> test:s().\nok\n```\n\nCover analysis is performed by examining the contents of the Cover database. The\noutput is determined by two parameters, `Level` and `Analysis`. `Analysis` is\neither `coverage` or `calls` and determines the type of the analysis. `Level` is\neither `module`, `function`, `clause`, or `line` and determines the level of the\nanalysis.","ref":"cover_chapter.html#preparation"},{"type":"extras","title":"Coverage Analysis - cover - The Coverage Analysis Tool","doc":"Analysis of type `coverage` is used to find out how much of the code has been\nexecuted and how much has not been executed. Coverage is represented by a tuple\n`{Cov,NotCov}`, where `Cov` is the number of executable lines that have been\nexecuted at least once and `NotCov` is the number of executable lines that have\nnot been executed.\n\nIf the analysis is made on module level, the result is given for the entire\nmodule as a tuple `{Module,{Cov,NotCov}}`:\n\n```erlang\n4> cover:analyse(channel, coverage, module).\n{ok,{channel,{14,1}}}\n```\n\nFor `channel`, the result shows that 14 lines in the module are covered but one\nline is not covered.\n\nIf the analysis is made on function level, the result is given as a list of\ntuples `{Function,{Cov,NotCov}}`, one for each function in the module. A\nfunction is specified by its module name, function name and arity:\n\n```erlang\n5> cover:analyse(channel, coverage, function).\n{ok,[{{channel,start_link,0},{1,0}},\n {{channel,stop,0},{1,0}},\n {{channel,alloc,0},{1,0}},\n {{channel,free,1},{1,0}},\n {{channel,init,1},{1,0}},\n {{channel,handle_call,3},{5,0}},\n {{channel,terminate,2},{1,0}},\n {{channel,channels,0},{1,0}},\n {{channel,alloc,1},{1,1}},\n {{channel,free,2},{1,0}}]}\n```\n\nFor `channel`, the result shows that the uncovered line is in the function\n`channel:alloc/1`.\n\nIf the analysis is made on clause level, the result is given as a list of tuples\n`{Clause,{Cov,NotCov}}`, one for each function clause in the module. A clause is\nspecified by its module name, function name, arity and position within the\nfunction definition:\n\n```erlang\n6> cover:analyse(channel, coverage, clause).\n{ok,[{{channel,start_link,0,1},{1,0}},\n {{channel,stop,0,1},{1,0}},\n {{channel,alloc,0,1},{1,0}},\n {{channel,free,1,1},{1,0}},\n {{channel,init,1,1},{1,0}},\n {{channel,handle_call,3,1},{1,0}},\n {{channel,handle_call,3,2},{2,0}},\n {{channel,handle_call,3,3},{2,0}},\n {{channel,terminate,2,1},{1,0}},\n {{channel,channels,0,1},{1,0}},\n {{channel,alloc,1,1},{1,0}},\n {{channel,alloc,1,2},{0,1}},\n {{channel,free,2,1},{1,0}}]}\n```\n\nFor `channel`, the result shows that the uncovered line is in the second clause\nof `channel:alloc/1`.\n\nFinally, if the analysis is made on line level, the result is given as a list of\ntuples `{Line,{Cov,NotCov}}`, one for each executable line in the source code. A\nline is specified by its module name and line number.\n\n```erlang\n7> cover:analyse(channel, coverage, line).\n{ok,[{{channel,9},{1,0}},\n {{channel,12},{1,0}},\n {{channel,17},{1,0}},\n {{channel,20},{1,0}},\n {{channel,25},{1,0}},\n {{channel,28},{1,0}},\n {{channel,31},{1,0}},\n {{channel,32},{1,0}},\n {{channel,35},{1,0}},\n {{channel,36},{1,0}},\n {{channel,39},{1,0}},\n {{channel,44},{1,0}},\n {{channel,47},{1,0}},\n {{channel,49},{0,1}},\n {{channel,52},{1,0}}]}\n```\n\nFor `channel`, the result shows that the uncovered line is line number 49.","ref":"cover_chapter.html#coverage-analysis"},{"type":"extras","title":"Call Statistics - cover - The Coverage Analysis Tool","doc":"Analysis of type `calls` is used to find out how many times something has been\ncalled and is represented by an integer `Calls`.\n\nIf the analysis is made on module level, the result is given as a tuple\n`{Module,Calls}`. Here `Calls` is the total number of calls to functions in the\nmodule:\n\n```erlang\n8> cover:analyse(channel, calls, module).\n{ok,{channel,12}}\n```\n\nFor `channel`, the result shows that a total of twelve calls have been made to\nfunctions in the module.\n\nIf the analysis is made on function level, the result is given as a list of\ntuples `{Function,Calls}`. Here `Calls` is the number of calls to each function:\n\n```erlang\n9> cover:analyse(channel, calls, function).\n{ok,[{{channel,start_link,0},1},\n {{channel,stop,0},1},\n {{channel,alloc,0},1},\n {{channel,free,1},1},\n {{channel,init,1},1},\n {{channel,handle_call,3},3},\n {{channel,terminate,2},1},\n {{channel,channels,0},1},\n {{channel,alloc,1},1},\n {{channel,free,2},1}]}\n```\n\nFor `channel`, the result shows that `handle_call/3` is the most called function\nin the module (three calls). All other functions have been called once.\n\nIf the analysis is made on clause level, the result is given as a list of tuples\n`{Clause,Calls}`. Here `Calls` is the number of calls to each function clause:\n\n```erlang\n10> cover:analyse(channel, calls, clause).\n{ok,[{{channel,start_link,0,1},1},\n {{channel,stop,0,1},1},\n {{channel,alloc,0,1},1},\n {{channel,free,1,1},1},\n {{channel,init,1,1},1},\n {{channel,handle_call,3,1},1},\n {{channel,handle_call,3,2},1},\n {{channel,handle_call,3,3},1},\n {{channel,terminate,2,1},1},\n {{channel,channels,0,1},1},\n {{channel,alloc,1,1},1},\n {{channel,alloc,1,2},0},\n {{channel,free,2,1},1}]}\n```\n\nFor `channel`, the result shows that all clauses have been called once, except\nthe second clause of `channel:alloc/1` which has not been called at all.\n\nFinally, if the analysis is made on line level, the result is given as a list of\ntuples `{Line,Calls}`. Here `Calls` is the number of times each line has been\nexecuted:\n\n```erlang\n11> cover:analyse(channel, calls, line).\n{ok,[{{channel,9},1},\n {{channel,12},1},\n {{channel,17},1},\n {{channel,20},1},\n {{channel,25},1},\n {{channel,28},1},\n {{channel,31},1},\n {{channel,32},1},\n {{channel,35},1},\n {{channel,36},1},\n {{channel,39},1},\n {{channel,44},1},\n {{channel,47},1},\n {{channel,49},0},\n {{channel,52},1}]}\n```\n\nFor `channel`, the result shows that all lines have been executed once, except\nline number 49 which has not been executed at all.","ref":"cover_chapter.html#call-statistics"},{"type":"extras","title":"Analysis to File - cover - The Coverage Analysis Tool","doc":"A line level calls analysis of `channel` can be written to a file using\n`cover:analyse_to_file/1`:\n\n```erlang\n12> cover:analyse_to_file(channel).\n{ok,\"channel.COVER.out\"}\n```\n\nThe function creates a copy of `channel.erl` where it for each executable line\nis specified how many times that line has been executed. The output file is\ncalled `channel.COVER.out`.\n\n```erlang\nFile generated from /Users/bjorng/git/otp/channel.erl by COVER 2024-03-20 at 13:25:04\n\n****************************************************************************\n\n | -module(channel).\n | -behaviour(gen_server).\n |\n | -export([start_link/0,stop/0]).\n | -export([alloc/0,free/1]). % client interface\n | -export([init/1,handle_call/3,terminate/2]). % callback functions\n |\n | start_link() ->\n 1..| gen_server:start_link({local,channel}, channel, [], []).\n |\n | stop() ->\n 1..| gen_server:call(channel, stop).\n |\n | %%%-Client interface functions-------------------------------------------\n |\n | alloc() ->\n 1..| gen_server:call(channel, alloc).\n |\n | free(Channel) ->\n 1..| gen_server:call(channel, {free,Channel}).\n |\n | %%%-gen_server callback functions----------------------------------------\n |\n | init(_Arg) ->\n 1..| {ok,channels()}.\n |\n | handle_call(stop, _Client, Channels) ->\n 1..| {stop,normal,ok,Channels};\n |\n | handle_call(alloc, _Client, Channels) ->\n 1..| {Ch,Channels2} = alloc(Channels),\n 1..| {reply,{ok,Ch},Channels2};\n |\n | handle_call({free,Channel}, _Client, Channels) ->\n 1..| Channels2 = free(Channel, Channels),\n 1..| {reply,ok,Channels2}.\n |\n | terminate(_Reason, _Channels) ->\n 1..| ok.\n |\n | %%%-Internal functions---------------------------------------------------\n |\n | channels() ->\n 1..| [ch1,ch2,ch3].\n |\n | alloc([Channel|Channels]) ->\n 1..| {Channel,Channels};\n | alloc([]) ->\n 0..| false.\n |\n | free(Channel, Channels) ->\n 1..| [Channel|Channels].\n```","ref":"cover_chapter.html#analysis-to-file"},{"type":"extras","title":"Conclusion - cover - The Coverage Analysis Tool","doc":"By looking at the results from the analyses, it can be deduced that\nthe test case does not cover the case when all channels are allocated\nand `test.erl` should be extended accordingly. Incidentally, when the\ntest case is corrected a bug in `channel` will be discovered.\n\nWhen the Cover analysis is ready, Cover is stopped and all cover-compiled\nmodules are [unloaded](cover_chapter.md#loading). The code for `channel` is now\nloaded as usual from a `.beam` file in the current path.\n\n```erlang\n13> code:which(channel).\ncover_compiled\n14> cover:stop().\nok\n15> code:which(channel).\n\"./channel.beam\"\n```","ref":"cover_chapter.html#conclusion"},{"type":"extras","title":"Miscellaneous - cover - The Coverage Analysis Tool","doc":"","ref":"cover_chapter.html#miscellaneous"},{"type":"extras","title":"Performance - cover - The Coverage Analysis Tool","doc":"Execution of code in cover-compiled modules is slower and more memory consuming\nthan for regularly compiled modules. As the Cover database contains information\nabout each executable line in each cover-compiled module, performance decreases\nproportionally to the size and number of the cover-compiled modules.\n\nTo improve performance when analysing cover results it is possible to do\nmultiple calls to [analyse](`cover:analyse/1`) and\n[analyse_to_file](`cover:analyse_to_file/1`) at once. You can also use the\n[async_analyse_to_file](`cover:async_analyse_to_file/1`) convenience function.\n\n[](){: #lines }","ref":"cover_chapter.html#performance"},{"type":"extras","title":"Executable Lines - cover - The Coverage Analysis Tool","doc":"Cover uses the concept of _executable lines_, which is code lines containing\nan executable expression such as a matching or a function call. A blank line or\na line containing a comment, function head or pattern in a `case` or `receive`\nstatement is not executable.\n\nIn the example below, lines number 2, 4, 6, 8, and 11 are executable lines:\n\n```erlang\n1: is_loaded(Module, Compiled) ->\n2: case get_file(Module, Compiled) of\n3: {ok,File} ->\n4: case code:which(Module) of\n5: ?TAG ->\n6: {loaded,File};\n7: _ ->\n8: unloaded\n9: end;\n10: false ->\n11: false\n12: end.\n```\n\n[](){: #loading }","ref":"cover_chapter.html#executable-lines"},{"type":"extras","title":"Code Loading Mechanism - cover - The Coverage Analysis Tool","doc":"When a module is cover-compiled, it is also loaded using the normal code loading\nmechanism of Erlang. This means that if a cover-compiled module is re-loaded\nduring a Cover session, for example using `c(Module)`, it will no longer be\ncover-compiled.\n\nUse `cover:is_compiled/1` or `code:which/1` to see whether or not a\nmodule is cover-compiled (and still loaded).\n\nWhen Cover is stopped, all cover-compiled modules are unloaded.","ref":"cover_chapter.html#code-loading-mechanism"},{"type":"extras","title":"cprof - The Call Count Profiler","doc":"\n# cprof - The Call Count Profiler\n\n`cprof` is a profiling tool that can be used to get a picture of how often\ndifferent functions in the system are called.\n\n`cprof` uses breakpoints similar to local call trace, but containing counters,\nto collect profiling data. Therefore there is no need for special compilation of\nany module to be profiled.\n\n`cprof` presents all profiled modules in descending total call count order, and\nfor each module presents all profiled functions also in descending call count\norder. A call count limit can be specified to filter out all functions below the\nlimit.\n\nProfiling is done in the following steps:\n\n- **[`cprof:start/*`](`cprof:start/3`)** - Starts profiling with\n zeroed call counters for specified functions by setting call count\n breakpoints on them.\n\n- **`Mod:Fun()`** - Runs the code to be profiled.\n\n- **[`cprof:pause/*`](`cprof:pause/3`)** - Pauses the call counters for\n specified functions. This minimizes the impact of code running in\n the background or in the shell. Call counters are automatically\n paused when they \"hit the ceiling\" of the host machine word\n size. For a 32 bit host the maximum counter value is 2,147,483,647.\n\n- **[`cprof:analyse/*`](`cprof:analyse/2`)** - Collects call counters\n and computes the result.\n\n- **[`cprof:restart/*`](`cprof:restart/3`)** - Restarts the call\n counters from zero for specified functions. Can be used to collect a\n new set of counters without having to stop and start call count\n profiling.\n\n- **[`cprof:stop/0..3`](`cprof:stop/3`)** - Stops profiling by\n removing call count breakpoints from specified functions.\n\nFunctions can be specified as either all in the system, all in one module, all\narities of one function, one function, or all functions in all modules not yet\nloaded. BIFs cannot be call-count traced.\n\nThe analysis result can either be for a single module or for all modules. In either\ncase a call count limit can be given to filter out the functions with a call\ncount below the limit. The all modules analysis does _not_ contain the module\n`cprof` itself; the only way to analyze `cprof` is by specifying it as a single\nmodule to analyse.\n\nCall count tracing is very lightweight compared to other forms of tracing since\nno trace message has to be generated. Some measurements indicates performance\ndegradations in the vicinity of 10 percent.\n\nThe following sections show some examples of profiling with `m:cprof`.","ref":"cprof_chapter.html"},{"type":"extras","title":"Example: Background work - cprof - The Call Count Profiler","doc":"From the Erlang shell:\n\n```erlang\n1> cprof:start(), cprof:pause(). % Stop counters just after start\n8492\n2> cprof:analyse().\n{539,\n [{shell,155,\n [{{shell,prep_check,1},55},\n {{shell,used_records,4},45},\n {{shell,used_records,1},45},\n {{shell,used_record_defs,2},1},\n {{shell,record_defs,2},1},\n {{shell,record_bindings,2},1},\n {{shell,exprs,7},1},\n {{shell,expr,4},1},\n {{shell,expand_records,2},1},\n {{shell,check_command,2},1},\n {{shell,apply_fun,3},1},\n {{shell,'-exprs/7-lc$^0/1-0-',1},1},\n {{shell,'-eval_loop/3-fun-0-',3},1}]},\n %% Information about many modules omitted.\n .\n .\n .\n %% Here is the last part.\n {erts_internal,2,[{{erts_internal,trace_pattern,3},2}]},\n {otp_internal,1,[{{otp_internal,obsolete,3},1}]},\n {maps,1,[{{maps,from_list,1},1}]},\n {erl_internal,1,[{{erl_internal,bif,3},1}]}]}\n3> cprof:analyse(cprof).\n{cprof,3,[{{cprof,tr,2},2},{{cprof,pause,0},1}]}\n4> cprof:stop().\n8586\n```\n\nThe example showed some of the background work that the shell performs just to\ninterpret the first command line.\n\nWhat is captured in this example is the part of the work the shell does while\ninterpreting the command line that occurs between the actual calls to\n[`cprof:start()`](`cprof:start/0`) and [`cprof:analyse()`](`cprof:analyse/1`).","ref":"cprof_chapter.html#example-background-work"},{"type":"extras","title":"Example: One module - cprof - The Call Count Profiler","doc":"From the Erlang shell:\n\n```erlang\n1> cprof:start(),R=calendar:day_of_the_week(1896,4,27),cprof:pause(),R.\n1\n2> cprof:analyse(calendar).\n{calendar,9,\n [{{calendar,last_day_of_the_month1,2},1},\n {{calendar,last_day_of_the_month,2},1},\n {{calendar,is_leap_year1,1},1},\n {{calendar,is_leap_year,1},1},\n {{calendar,dy,1},1},\n {{calendar,dm,1},1},\n {{calendar,df,2},1},\n {{calendar,day_of_the_week,3},1},\n {{calendar,date_to_gregorian_days,3},1}]}\n3> cprof:stop().\n8648\n```\n\nThe example tells us that \"Aktiebolaget LM Ericsson & Co\" was registered on a\nMonday (since the return value of the first command is 1), and that the\n`calendar` module needed 9 function calls to calculate that.\n\nUsing `cprof:analyse()` in this example also shows approximately the same\nbackground work as in the first example.","ref":"cprof_chapter.html#example-one-module"},{"type":"extras","title":"Example: In the code - cprof - The Call Count Profiler","doc":"Write a module:\n\n```erlang\n-module(sort).\n-export([do/1]).\n\ndo(N) ->\n cprof:stop(),\n cprof:start(),\n do(N, []).\n\ndo(0, L) ->\n R = lists:sort(L),\n cprof:pause(),\n R;\ndo(N, L) ->\n do(N-1, [rand:uniform(256)-1 | L]).\n```\n\nFrom the Erlang shell:\n\n```erlang\n1> c(sort).\n{ok,sort}\n2> rand:seed(default, 42), ok.\nok.\n3> sort:do(1000).\n[0,0,0,1,1,1,1,2,2,3,3,4,4,4,4,5,5,5,6,6,6,6,7,7,7,7,7,8,8|...]\n4> cprof:analyse().\n{13180,\n [{lists,6173,\n [{{lists,rmerge3_1,6},1045},\n {{lists,rmerge3_2,6},977},\n {{lists,split_1,5},652},\n {{lists,merge3_1,6},579},\n {{lists,merge3_2,6},577},\n {{lists,rmerge3_12_3,6},511},\n {{lists,split_1_1,6},347},\n {{lists,merge3_12_3,6},310},\n {{lists,rmerge3_21_3,6},282},\n {{lists,merge3_21_3,6},221},\n {{lists,merge2_1,4},154},\n {{lists,merge2_2,5},138},\n {{lists,reverse,2},106},\n {{lists,rmerge2_2,5},87},\n {{lists,rmergel,2},81},\n {{lists,rmerge2_1,4},75},\n {{lists,mergel,2},28},\n {{lists,keyfind,3},2},\n {{lists,sort,1},1}]},\n {rand,5000,\n [{{rand,uniform_s,2},1000},\n {{rand,uniform,1},1000},\n {{rand,seed_put,1},1000},\n {{rand,seed_get,0},1000},\n {{rand,exsss_uniform,2},1000}]},\n {erlang,1004,\n [{{erlang,put,2},1000},\n {{erlang,trace_pattern,3},2},\n {{erlang,ensure_tracer_module_loaded,2},2}]},\n {sort,1001,[{{sort,do,2},1001}]},\n {erts_internal,2,[{{erts_internal,trace_pattern,3},2}]}]}\n5> cprof:stop().\n12625\n```\n\nThe example shows some details of how `lists:sort/1` works. It used 6173\nfunction calls in module `m:lists` to complete the work.\n\nThis time, since the shell was not involved in starting and stopping `cprof`, no\nother work was done in the system during the profiling.","ref":"cprof_chapter.html#example-in-the-code"},{"type":"extras","title":"The Erlang mode for Emacs","doc":"\n# The Erlang mode for Emacs","ref":"erlang_mode_chapter.html"},{"type":"extras","title":"Purpose - The Erlang mode for Emacs","doc":"The purpose of this user guide is to introduce you to the Erlang mode\nfor Emacs and gives some relevant background information of the\nfunctions and features. See also [Erlang mode reference\nmanual](../references/erlang.el.md) The purpose of the Erlang mode\nitself is to facilitate the developing process for the Erlang\nprogrammer.","ref":"erlang_mode_chapter.html#purpose"},{"type":"extras","title":"Pre-requisites - The Erlang mode for Emacs","doc":"Basic knowledge of Emacs and Erlang/OTP.","ref":"erlang_mode_chapter.html#pre-requisites"},{"type":"extras","title":"Elisp - The Erlang mode for Emacs","doc":"Two Elisp modules are included in this tool package for\nEmacs. `erlang.el` defines the actual Erlang mode and\n`erlang-start.el` makes some nice initializations.","ref":"erlang_mode_chapter.html#elisp"},{"type":"extras","title":"Setup on UNIX - The Erlang mode for Emacs","doc":"To set up the Erlang Emacs mode on a UNIX systems, edit or create the file `.emacs`\nin the your home directory.\n\nBelow is a complete example of what should be added to a user's `.emacs`\nprovided that OTP is installed in the directory `/usr/local/otp `:\n\n```text\n(setq load-path (cons \"/usr/local/otp/lib/tools- /emacs\"\nload-path))\n(setq erlang-root-dir \"/usr/local/otp\")\n(setq exec-path (cons \"/usr/local/otp/bin\" exec-path))\n(require 'erlang-start)\n```","ref":"erlang_mode_chapter.html#setup-on-unix"},{"type":"extras","title":"Setup on Windows - The Erlang mode for Emacs","doc":"To set up the Erlang Emacs mode on a Windows systems, edit/create the file\n`.emacs`, the location of the file depends on the configuration of the system.\nIf the _HOME_ environment variable is set, Emacs will look for the `.emacs` file\nin the directory indicated by the `HOME` variable. If `HOME` is not set, Emacs\nwill look for the `.emacs` file in `C:\\ `.\n\nBelow is a complete example of what should be added to a user's `.emacs`\nprovided that OTP is installed in the directory `C:\\Program Files\\Erlang OTP`:\n\n```lisp\n(setq load-path (cons \"C:/Program Files/Erlang OTP/lib/tools- /emacs\"\nload-path))\n(setq erlang-root-dir \"C:/Program Files/Erlang OTP\")\n(setq exec-path (cons \"C:/Program Files/Erlang OTP/bin\" exec-path))\n(require 'erlang-start)\n```\n\n> #### Note {: .info }\n>\n> In `.emacs`, the slash character (`/`) can be used as path separator. But if you\n> decide to use the backslash character (`\\`), note that backslashes have to be\n> doubled, since they are treated as escape characters by Emacs.","ref":"erlang_mode_chapter.html#setup-on-windows"},{"type":"extras","title":"Indentation - The Erlang mode for Emacs","doc":"The \"Oxford Advanced Learners Dictionary of Current English\" says the following\nabout the word \"indent\":\n\n> \"start (a line of print or writing) farther from the margin than the others\".\n\nThe Erlang mode does, of course, provide this feature. The layout used is based\non the common use of the language.\n\nIt is strongly recommended to use this feature and avoid to indent lines in a\nnonstandard way. Some motivations are:\n\n- Code using the same layout is easy to read and maintain.\n- Since several features of Erlang mode is based on the standard layout they\n might not work correctly if a nonstandard layout is used.\n\nThe indentation features can be used to reindent large sections of a file. If\nsome lines use nonstandard indentation they will be reindented.","ref":"erlang_mode_chapter.html#indentation"},{"type":"extras","title":"Editing - The Erlang mode for Emacs","doc":"- _`M-x erlang-mode RET`_ \\- This command activates the Erlang major mode for\n the current buffer. When this mode is active the mode line contain the word\n \"Erlang\".\n\nWhen the Erlang mode is correctly installed, it is automatically activated when\na file ending in `.erl` or `.hrl` is opened in Emacs.\n\nWhen a file is saved the name in the `-module().` line is checked against the\nfile name. Should they mismatch Emacs can change the module specifier so that it\nmatches the file name. By default, the user is asked before the change is\nperformed.\n\nAn \"electric\" command is a character that in addition to just inserting the\ncharacter performs some type of action. For example the `;` character is typed\nin a situation where is ends a function clause a new function header is\ngenerated. The electric commands are as follows:\n\n- `erlang-electric-comma` \\- Insert a comma character and possibly a new\n indented line.\n- `erlang-electric-semicolon` \\- Insert a semicolon character and possibly a\n prototype for the next line.\n- `erlang-electric-gt` \\- Insert a `>` character and possible a new indented line.\n\nTo disable all electric commands set the variable `erlang-electric-commands` to\nthe empty list. In short, place the following line in your `.emacs`\\-file:\n\n```text\n(setq erlang-electric-commands '())\n```","ref":"erlang_mode_chapter.html#editing"},{"type":"extras","title":"Syntax highlighting - The Erlang mode for Emacs","doc":"It is possible for Emacs to use colors when displaying a buffer. By \"syntax\nhighlighting\", we mean that syntactic components, for example keywords and\nfunction names, will be colored.\n\nThe basic idea of syntax highlighting is to make the structure of a program\nclearer. For example, the highlighting will make it easier to spot simple bugs.\nHave not you ever written a variable in lower-case only? With syntax\nhighlighting a variable will colored while atoms will be shown with the normal\ntext color.","ref":"erlang_mode_chapter.html#syntax-highlighting"},{"type":"extras","title":"Tags - The Erlang mode for Emacs","doc":"Tags is a standard Emacs package used to record information about source files\nin large development projects. In addition to listing the files of a project, a\ntags file normally contains information about all functions and variables that\nare defined. By far, the most useful command of the tags system is its ability\nto find the definition of functions in any file in the project. But the Tags\nsystem is not limited to this feature, for example, it is possible to do a text\nsearch in all files in a project, or to perform a project-wide search and\nreplace.\n\nIn order to use the Tags system a file named `TAGS` must be created. The file\ncan be seen as a database over all functions, records, and macros in all files\nin the project. The `TAGS` file can be created using two different methods for\nErlang. The first is the standard Emacs utility \"etags\", the second is by using\nthe Erlang module `tags`.","ref":"erlang_mode_chapter.html#tags"},{"type":"extras","title":"Etags - The Erlang mode for Emacs","doc":"`etags` is a program that is part of the Emacs distribution. It is normally\nexecuted from a command line, like a Unix shell or a DOS box.\n\nThe `etags` program of fairly modern versions of Emacs and XEmacs has native\nsupport for Erlang. To check if your version does include this support, issue\nthe command `etags --help` at a the command line prompt. At the end of the help\ntext there is a list of supported languages. Unless Erlang is a member of this\nlist I suggest that you should upgrade to a newer version of Emacs.\n\nAs seen in the help text — unless you have not upgraded your Emacs yet — `etags`\nassociate the file extensions `.erl` and `.hrl` with Erlang.\n\nBasically, the `etags` utility is run using the following form:\n\n```bash\netags file1.erl file2.erl\n```\n\nThis will create a file named `TAGS` in the current directory.\n\nThe `etags` utility can also read a list of files from its standard input by\nsupplying a single dash in place of the file names. This feature is useful when\na project consists of a large number of files. The standard UNIX command `find`\ncan be used to generate the list of files, for example:\n\n```bash\nfind . -name \"*.[he]rl\" -print | etags -\n```\n\nThe above line will create a `TAGS` file covering all the Erlang source files in\nthe current directory, and in the subdirectories below.\n\nSee the GNU Emacs Manual and the etags man page for more info.","ref":"erlang_mode_chapter.html#etags"},{"type":"extras","title":"Shell - The Erlang mode for Emacs","doc":"The look and feel on an Erlang shell inside Emacs should be the same as in a\nnormal Erlang shell. There is just one major difference, the cursor keys will\nactually move the cursor around just like in any normal Emacs buffer. The\ncommand line history can be accessed by the following commands:\n\n- *`C-up `*or _`M-p `_(`comint-previous-input`) - Move to the previous line in\n the input history.\n- *`C-down `*or _`M-n `_(`comint-next-input`) - Move to the next line in the\n input history.\n\nIf the Erlang shell buffer would be killed the command line history is saved to\na file. The command line history is automatically retrieved when a new Erlang\nshell is started.","ref":"erlang_mode_chapter.html#shell"},{"type":"extras","title":"Compilation - The Erlang mode for Emacs","doc":"The classic edit-compile-bugfix cycle for Erlang is to edit the source file in\nan editor, save it to a file and switch to an Erlang shell. In the shell the\ncompilation command is given. Should the compilation fail you have to bring out\nthe editor and locate the correct line.\n\nWith the Erlang editing mode the entire edit-compile-bugfix cycle can be\nperformed without leaving Emacs. Emacs can order Erlang to compile a file and it\ncan parse the error messages to automatically place the point on the erroneous\nlines.","ref":"erlang_mode_chapter.html#compilation"},{"type":"extras","title":"fprof - The File Trace Profiler","doc":"\n# fprof - The File Trace Profiler\n\n`m:fprof` is a profiling tool that can be used to get a picture of how much\nprocessing time different functions consumes and in which processes.\n\n`fprof` uses tracing with timestamps to collect profiling data. Therefore there\nis no need for special compilation of any module to be profiled.\n\n`fprof` presents wall clock times from the host machine OS, with the assumption\nthat OS scheduling will randomly load the profiled functions in a fair way. Both\n_own time_, that is, the time used by a function for its own execution, and\n_accumulated time_, that is, execution time including called functions.\n\nProfiling is essentially done in 3 steps:\n\n- Tracing to a file.\n\n- Profiling: the trace file is read and raw profile data is collected\n into an internal RAM storage on the node. During this step the trace data may\n be dumped in text format to file or console.\n\n- Analysing: the raw profile data is sorted and dumped in text format\n either to file or console.\n\nSince `fprof` stores trace data to a file, the runtime performance degradation is\nminimized, but still far from negligible, especially for programs that themselves\nuse the filesystem heavily. Where the trace file is placed is also important;\non Unix systems `/tmp` is usually a good choice, while any\nnetwork-mounted disk is a bad choice.\n\n`fprof` can also skip the file step and trace to a tracer process of its own that\ndoes the profiling in runtime.\n\nThe following sections show some examples of how to profile with `m:fprof`.","ref":"fprof_chapter.html"},{"type":"extras","title":"Profiling from the source code - fprof - The File Trace Profiler","doc":"If you can edit and recompile the source code, it is convenient to\ninsert [`fprof:trace(start)`](`fprof:trace/1`) and\n[`fprof:trace(stop)`](`fprof:trace/1`) before and after the code to be profiled.\nAll spawned processes are also traced. If you want some other filename than\nthe default, use [`fprof:trace(start, \"my_fprof.trace\")`](`fprof:trace/2`).\n\nWhen execution is finished, the raw profile can be processed using\n[`fprof:profile()`](`fprof:profile/0`),\nor [`fprof:profile(file, \"my_fprof.trace\")`](`fprof:profile/2`)\nfor a non-default filename.\n\nFinally create an informative table dumped on the console with\n[`fprof:analyse()`](`fprof:analyse/0`), or on file with\n[`fprof:analyse(dest, [])`](`fprof:analyse/2`), or\n[`fprof:analyse([{dest, \"my_fprof.analysis\"}, {cols, 120}])`](`fprof:analyse/1`)\nfor a wider listing of a non-default filename.","ref":"fprof_chapter.html#profiling-from-the-source-code"},{"type":"extras","title":"Profiling a function - fprof - The File Trace Profiler","doc":"If you have one function that does the task that you want to profile, and the\nfunction returns when the profiling should stop, it is convenient to use\n[`fprof:apply(Module, Function, Args)`](`fprof:apply/3`) for the tracing step.\n\nIf the tracing should continue after the function has returned, for\nexample if it is a start function that spawns processes to be\nprofiled, use\n[`fprof:apply(M, F, Args, [continue | OtherOpts])`](`fprof:apply/4`).\nThe tracing has to be stopped at a suitable later time using\n[`fprof:trace(stop)`](`fprof:trace/1`).","ref":"fprof_chapter.html#profiling-a-function"},{"type":"extras","title":"Immediate profiling - fprof - The File Trace Profiler","doc":"It is also possible to trace immediately into the profiling process that creates\nthe raw profile data, that is to short circuit the tracing and profiling steps\nso that the filesystem is not used for tracing.\n\nDo something like this:\n\n```erlang\n{ok, Tracer} = fprof:profile(start),\nfprof:trace([start, {tracer, Tracer}]),\n%% Run code to profile\nfprof:trace(stop);\n```\n\nThis puts less load on the filesystem, but much more load on the Erlang runtime\nsystem.","ref":"fprof_chapter.html#immediate-profiling"},{"type":"extras","title":"lcnt - The Lock Profiler","doc":"\n# lcnt - The Lock Profiler\n\nInternally in the Erlang runtime system locks are used to protect resources from\nbeing updated from multiple threads in a fatal way. Locks are necessary to\nensure that the runtime system works properly, but it also introduces\nlimitations, namely _lock contention_ and _locking overhead_.\n\nWith lock contention we mean when one thread locks a resource, and another\nthread (or threads) tries to acquire the same resource at the same time. The\nlock will deny the other thread access to the resource and the thread will be\nblocked from continuing its execution. The second thread has to wait until the\nfirst thread has completed its access to the resource and unlocked it. The\n`lcnt` tool measures these lock conflicts.\n\nLocks have an inherent cost in execution time and memory space. It takes time to\ninitialize, destroy, acquire, or release locks. To decrease lock contention\nit is sometimes necessary to use finer-grained locking strategies. This\nusually also increases the locking overhead. Hence there is a tradeoff between\nlock contention and overhead. In general, lock contention increases with the\nnumber of threads running concurrently.\n\nThe `lcnt` tool does not measure locking overhead.","ref":"lcnt_chapter.html"},{"type":"extras","title":"Enabling lock-counting - lcnt - The Lock Profiler","doc":"For investigation of locks in the emulator we use an internal tool called `lcnt`\n(short for lock-count). The VM needs to be compiled with this option enabled. To\ncompile a lock-counting VM along with a normal VM, use:\n\n```text\ncd $ERL_TOP\n./configure --enable-lock-counter\nmake\n```\n\nStart the lock-counting VM like this:\n\n```text\n$ERL_TOP/bin/erl -emu_type lcnt\n```\n\nTo verify that lock counting is enabled check that `[lock-counting]` appears in\nthe status text when the VM is started.\n\n```text\nErlang/OTP 27 [erts-15.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [lock-counting]\n```","ref":"lcnt_chapter.html#enabling-lock-counting"},{"type":"extras","title":"Getting started - lcnt - The Lock Profiler","doc":"Once you have a lock counting enabled VM the module `lcnt` can be used. The\nmodule is intended to be used from the current running nodes shell. To access\nremote nodes use [`lcnt:clear(Node)`](`lcnt:clear/1`) and\n[`lcnt:collect(Node)`](`lcnt:collect/1`).\n\nAll locks are continuously monitored and its statistics updated. Use\n[`lcnt:clear/0`](`lcnt:clear/1`) to initially clear all counters\nbefore running any specific tests. This command will also reset the\ninternal duration timer.\n\nTo retrieve lock statistics information, use\n[`lcnt:collect/0,1`](`lcnt:collect/1`). The collect operation will\nstart a `lcnt` server if it not already started. All collected data\nwill be stored in an Erlang term and uploaded to the server along with\nthe duration time. The duration time is the time between\n[`lcnt:clear/0,1`](`lcnt:clear/1`) and\n[`lcnt:collect/0,1`](`lcnt:collect/1`).\n\nOnce the data is collected to the server it can be filtered, sorted, and printed\nin multiple ways.","ref":"lcnt_chapter.html#getting-started"},{"type":"extras","title":"Example of usage - lcnt - The Lock Profiler","doc":"Here is an example of running the [Big Bang Benchmark](#the-big-bang-benchmark):\n\n```text\nErlang/OTP 27 [erts-15.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [lock-counting]\n\nEshell V15.0 (press Ctrl+G to abort, type help(). for help)\n1> lcnt:rt_opt({copy_save, true}).\nfalse\n2> lcnt:clear(), big:bang(1000), lcnt:collect().\nok\n3> lcnt:conflicts().\n lock id #tries #collisions collisions [%] time [us] duration [%]\n ----- --- ------- ------------ --------------- ---------- -------------\n run_queue 10 590799 8875 1.5022 37906 2.2167\n proc_msgq 1048 2515180 4667 0.1856 20962 1.2258\n proc_main 1048 2195317 23775 1.0830 1664 0.0973\nok\n```\n\nAnother way to to profile a specific function is to use `lcnt:apply/3` or\n`lcnt:apply/1`, which calls `lcnt:clear/0` before calling the function and\n`lcnt:collect/0` after its invocation. This method should only be used in\nmicro-benchmarks since it sets `copy_save` to `true` for the duration of the\nfunction call, which may cause the emulator to run out of memory if attempted\nunder load.\n\n```text\n1> lcnt:apply(fun() -> big:bang(1000) end).\n1845411\n2> lcnt:conflicts().\n lock id #tries #collisions collisions [%] time [us] duration [%]\n ----- --- ------- ------------ --------------- ---------- -------------\n run_queue 10 582789 9237 1.5850 41929 2.2633\n proc_msgq 1047 2494483 4731 0.1897 11173 0.6031\n proc_main 1047 2192806 23283 1.0618 1500 0.0810\nok\n```\n\nThe process locks are sorted after its class like all other locks. It is\nconvenient to look at specific processes and ports as classes. We can do this by\nswapping class and class identifiers with `lcnt:swap_pid_keys/0`.\n\n```text\n3> lcnt:swap_pid_keys().\nok\n4> lcnt:conflicts([{print, [name, tries, ratio, time]}]).\n lock #tries collisions [%] time [us]\n ----- ------- --------------- ----------\n run_queue 582789 1.5850 41929\n 5692 0.5095 484\n 4989 0.4410 393\n 6319 2.1839 284\n 6077 1.9747 198\n 5071 1.3015 192\n 5846 1.7106 186\n 6305 1.2054 179\n 5820 1.2715 176\n 6329 1.4852 168\n 5172 0.8701 167\n 5306 0.4146 166\n 5838 1.9870 160\n 6346 1.5443 143\n 5542 0.4331 141\n 5260 0.2662 137\n 5610 0.9447 127\n 5354 0.5230 118\n 5845 0.9239 115\n 5140 0.7782 108\nok\n```","ref":"lcnt_chapter.html#example-of-usage"},{"type":"extras","title":"Example with Mnesia Transaction Benchmark - lcnt - The Lock Profiler","doc":"From the Erlang shell:\n\n```erlang\nErlang/OTP 27 [erts-15.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [lock-counting]\n\nEshell V15.0 (press Ctrl+G to abort, type help(). for help)\n1> Conf = [{db_nodes, [node()]}, {driver_nodes, [node()]}, {replica_nodes, [node()]},\n {n_drivers_per_node, 10}, {n_branches, 1000}, {n_accounts_per_branch, 10},\n {replica_type, ram_copies}, {stop_after, 60000}, {reuse_history_id, true}], ok.\nok\n2> mnesia_tpcb:init([{use_running_mnesia, false}|Conf]).\n .\n .\n .\nignore\n```\n\nInitial configuring of the benchmark is done. It is time to profile the actual\nMnesia benchmark:\n\n```erlang\n3> lcnt:apply(fun() -> {ok,{time, Tps,_,_,_,_}} = mnesia_tpcb:run([{use_running_mnesia,\n true}|Conf]), Tps/60 end).\n .\n .\n .\n50204.666666666664\n```\n\nThe benchmark runs for 60 seconds (followed by verification and\nanalysis), and then returns the number of transactions per seconds.\n\n```text\n4> lcnt:swap_pid_keys().\nok\n5> lcnt:conflicts().\n lock id #tries #collisions collisions [%] time [us] duration [%]\n ----- --- ------- ------------ --------------- ---------- -------------\n run_queue 10 89329288 3227515 3.6131 5018119 8.3606\n mnesia_locker 5 64793236 8231226 12.7038 98654 0.1644\n db_tab 3012324 416847817 140631 0.0337 75308 0.1255\n 5 14499900 36934 0.2547 4878 0.0081\n 5 14157504 35797 0.2528 4727 0.0079\n 5 14194934 34510 0.2431 4403 0.0073\n 5 14149447 35326 0.2497 4150 0.0069\n 5 14316525 35675 0.2492 4116 0.0069\n 5 14241146 35358 0.2483 4101 0.0068\n 5 14224491 35182 0.2473 4094 0.0068\n 5 14190075 35328 0.2490 4075 0.0068\n 5 14308906 35031 0.2448 3896 0.0065\n 5 14457330 36182 0.2503 3856 0.0064\n mnesia_tm 5 28149333 179294 0.6369 1057 0.0018\n pix_lock 1024 132 1 0.7576 549 0.0009\n 5 17 2 11.7647 87 0.0001\n 5 1335 6 0.4494 1 0.0000\nok\n```\n\nThe `id` header represents the number of unique identifiers under a\nclass when the option `{combine, true}` is used (which is enabled by\ndefault). It will otherwise show the specific identifier. The `db_tab`\nlisting shows 3,012,324 unique locks, which is one for each ETS table\ncreated. Mnesia creates one ETS table for each transaction.\n\nThe listing shows also shows that the `mnesia_locker` process has highly contended locks.\nUsing `lcnt:inspect/1` more information can be displayed for that process:\n\n```text\n6> lcnt:inspect(mnesia_locker).\n lock id #tries #collisions collisions [%] time [us] duration [%] histogram [log2(us)]\n ----- --- ------- ------------ --------------- ---------- ------------- ---------------------\n mnesia_locker proc_main 19853372 7591248 38.2366 80550 0.1342 |. ...X........ |\n mnesia_locker proc_msgq 30917225 639627 2.0688 17126 0.0285 |. .X......... |\n mnesia_locker proc_status 9348426 351 0.0038 978 0.0016 | .xxX. . |\n mnesia_locker proc_btm 0 0 0.0000 0 0.0000 | |\n mnesia_locker proc_trace 4674213 0 0.0000 0 0.0000 | |\nok\n```\n\nListing the conflicts without class combiner:\n\n```text\n7> lcnt:conflicts([{combine, false}, {print, [name, id, tries, ratio, time]}]).\n lock id #tries collisions [%] time [us]\n ----- --- ------- --------------- ----------\n run_queue 2 31075249 3.5676 1728233\n run_queue 1 29738521 3.6348 1683219\n run_queue 3 27912150 3.6429 1573593\n mnesia_locker proc_main 19853372 38.2366 80550\n db_tab mnesia_transient_decision 3012281 2.5675 55104\n run_queue 4 512077 3.7041 29486\n mnesia_locker proc_msgq 30917225 2.0688 17126\n db_tab account 6044562 0.3599 7909\n db_tab branch 6026659 0.3132 5654\n db_tab teller 6044659 0.2684 4727\n proc_main 3207155 0.7178 3726\n proc_main 3138532 0.7485 3593\n proc_main 3133180 0.7156 3547\n proc_main 3165128 0.7609 3517\n proc_main 3128838 0.7525 3477\n proc_main 3137627 0.7559 3433\n proc_main 3144886 0.7509 3425\n proc_main 3149315 0.7487 3372\n proc_main 3196546 0.7591 3310\n proc_main 3164333 0.7483 3309\nok\n```\n\nIn this scenario the locks for the scheduler's run queues dominate the time waiting\nfor locks. The most contended lock for ETS tables is for the `mnesia_transient_decision`\nETS table.\n\nHere is how to show the information for the ETS tables.\n\n```text\n8> lcnt:inspect(db_tab, [{print, [name, id, tries, colls, ratio, duration]}]).\n lock id #tries #collisions collisions [%] duration [%]\n ----- --- ------- ------------ --------------- -------------\n db_tab mnesia_transient_decision 3012281 77341 2.5675 0.0918\n db_tab account 6044562 21753 0.3599 0.0132\n db_tab branch 6026659 18873 0.3132 0.0094\n db_tab teller 6044659 16221 0.2684 0.0079\n db_tab history 3012281 4005 0.1330 0.0022\n db_tab mnesia_stats 3071064 2437 0.0794 0.0010\n db_tab mnesia_trans_store 15 0 0.0000 0.0000\n db_tab mnesia_decision 3012281 0 0.0000 0.0000\n db_tab schema 0 0 0.0000 0.0000\n db_tab dets 0 0 0.0000 0.0000\n db_tab dets_owners 0 0 0.0000 0.0000\n db_tab dets_registry 0 0 0.0000 0.0000\n db_tab mnesia_lock_queue 36154974 0 0.0000 0.0000\n db_tab mnesia_sticky_locks 12108098 0 0.0000 0.0000\n db_tab mnesia_tid_locks 27176721 0 0.0000 0.0000\n db_tab mnesia_held_locks 48321870 0 0.0000 0.0000\n db_tab mnesia_subscr 0 0 0.0000 0.0000\n db_tab mnesia_gvar 102680683 1 0.0000 0.0000\n db_tab user_functions 0 0 0.0000 0.0000\n db_tab shell_records 0 0 0.0000 0.0000\nok\n```","ref":"lcnt_chapter.html#example-with-mnesia-transaction-benchmark"},{"type":"extras","title":"Deciphering the output - lcnt - The Lock Profiler","doc":"Typically high `time` values are bad and this is often the thing to look for.\nHowever, one should also look for high lock acquisition frequencies (`#tries`)\nsince locks generate overhead and because high frequency could become\nproblematic if they begin to have conflicts even if it is not shown in a\nparticular test.","ref":"lcnt_chapter.html#deciphering-the-output"},{"type":"extras","title":"The Big Bang Benchmark - lcnt - The Lock Profiler","doc":"```erlang\n-module(big).\n-export([bang/1]).\n\npinger([], [], true) ->\n receive\n\t{procs, Procs, ReportTo} ->\n\t pinger(Procs, [], ReportTo)\n end;\npinger([], [], false) ->\n receive {ping, From} -> From ! {pong, self()} end,\n pinger([],[],false);\npinger([], [], ReportTo) ->\n ReportTo ! {done, self()},\n pinger([],[],false);\npinger([], [Po|Pos] = Pongers, ReportTo) ->\n receive\n\t{ping, From} ->\n\t From ! {pong, self()},\n\t pinger([], Pongers, ReportTo);\n\t{pong, Po} ->\n\t pinger([], Pos, ReportTo)\n end;\npinger([Pi|Pis], Pongers, ReportTo) ->\n receive {ping, From} -> From ! {pong, self()}\n after 0 -> ok\n end,\n Pi ! {ping, self()},\n pinger(Pis, [Pi|Pongers], ReportTo).\n\nspawn_procs(N) when N =< 0 ->\n [];\nspawn_procs(N) ->\n [spawn_link(fun () -> pinger([],[],true) end) | spawn_procs(N-1)].\n\nsend_procs([], Msg) ->\n Msg;\nsend_procs([P|Ps], Msg) ->\n P ! Msg,\n send_procs(Ps, Msg).\n\nreceive_msgs([]) ->\n ok;\nreceive_msgs([M|Ms]) ->\n receive\n\tM ->\n\t receive_msgs(Ms)\n end.\n\nbang(N) when integer(N) ->\n Procs = spawn_procs(N),\n RMsgs = lists:map(fun (P) -> {done, P} end, Procs),\n Start = now(),\n send_procs(Procs, {procs, Procs, self()}),\n receive_msgs(RMsgs),\n Stop = now(),\n lists:foreach(fun (P) -> exit(P, normal) end, Procs),\n timer:now_diff(Stop, Start).\n```","ref":"lcnt_chapter.html#the-big-bang-benchmark"},{"type":"extras","title":"See Also - lcnt - The Lock Profiler","doc":"[LCNT Reference Manual](`m:lcnt`)","ref":"lcnt_chapter.html#see-also"},{"type":"extras","title":"Xref - The Cross Reference Tool","doc":"\n# Xref - The Cross Reference Tool\n\nXref is a cross reference tool that can be used for finding dependencies between\nfunctions, modules, applications and releases. It does so by analyzing the\ndefined functions and the function calls.\n\nIn order to make Xref easy to use, there are predefined analyses that perform\nsome common tasks. Typically, a module or a release can be checked for calls to\nundefined functions. For the somewhat more advanced user there is a small but\nflexible language that can be used for selecting parts of the analyzed\nsystem and for doing some simple graph analyses on selected calls.\n\nThe following sections show some features of Xref, beginning with a module check\nand a predefined analysis. Then follow examples that can be skipped on the first\nreading; not all of the concepts used are explained, and it is assumed that the\n[reference manual](`m:xref`) has been at least skimmed.","ref":"xref_chapter.html"},{"type":"extras","title":"Module Check - Xref - The Cross Reference Tool","doc":"Assume we want to check the following module:\n\n```erlang\n-module(my_module).\n\n-export([t/1]).\n\nt(A) ->\n my_module:t2(A).\n\nt2(_) ->\n true.\n```\n\nCross reference data are read from BEAM files, so the first step when checking\nan edited module is to compile it:\n\n```erlang\n1> c(my_module, debug_info).\n./my_module.erl:10: Warning: function t2/1 is unused\n{ok, my_module}\n```\n\nThe `debug_info` option ensures that the BEAM file contains debug information,\nwhich makes it possible to find unused local functions.\n\nThe module can now be checked for calls to\n[deprecated functions](`m:xref#deprecated_function`), calls to\n[undefined functions](`m:xref#undefined_function`), and for unused local\nfunctions:\n\n```erlang\n2> xref:m(my_module)\n[{deprecated,[]},\n {undefined,[{{my_module,t,1},{my_module,t2,1}}]},\n {unused,[{my_module,t2,1}]}]\n```\n\n`m/1` is also suitable for checking that the BEAM file of a module that is about\nto be loaded into a running a system does not call any undefined functions. In\neither case, the code path of the code server (see the module `code`) is used\nfor finding modules that export externally called functions not exported by the\nchecked module itself, so called [library modules](`m:xref#library_module`).","ref":"xref_chapter.html#module-check"},{"type":"extras","title":"Predefined Analysis - Xref - The Cross Reference Tool","doc":"In the last example the module to analyze was given as an argument to `m/1`, and\nthe code path was (implicitly) used as [library path](`m:xref#library_path`). In\nthis example an [xref server](`m:xref#xref_server`) will be used, which makes it\npossible to analyze applications and releases, and also to select the library\npath explicitly.\n\nEach Xref server is referred to by a unique name. The name is given when\ncreating the server:\n\n```erlang\n1> xref:start(s).\n{ok,<0.27.0>}\n```\n\nNext the system to be analyzed is added to the Xref server. Here the system will\nbe OTP, so no library path will be needed. Otherwise, when analyzing a system\nthat uses OTP, the OTP modules are typically made library modules by setting the\nlibrary path to the default OTP code path (or to `code_path`, see the\n[reference manual](`m:xref#code_path`)). By default, the names of read BEAM\nfiles and warnings are output when adding analyzed modules, but these messages\ncan be avoided by setting default values of some options:\n\n```erlang\n2> xref:set_default(s, [{verbose,false}, {warnings,false}]).\nok\n3> xref:add_release(s, code:lib_dir(), {name, otp}).\n{ok,otp}\n```\n\n`add_release/3` assumes that all subdirectories of the library directory\nreturned by [`code:lib_dir()`](`code:lib_dir/0`) contain applications;\nthe effect is that of reading all BEAM files for the application.\n\nIt is now easy to check the release for calls to undefined functions:\n\n```erlang\n4> xref:analyze(s, undefined_function_calls).\n{ok, [...]}\n```\n\nWe can now continue with further analyses, or we can delete the Xref server:\n\n```erlang\n5> xref:stop(s).\n```\n\nThe check for calls to undefined functions is an example of a predefined\nanalysis, probably the most useful one. Other examples are the analyses that\nfind unused local functions, or functions that call some given functions. See\nthe [analyze/2,3](`m:xref#analyze`) functions for a complete list of predefined\nanalyses.\n\nEach predefined analysis is a shorthand for a [query](`m:xref#query`), a\nsentence of a tiny language providing cross reference data as values of\n[predefined variables](`m:xref#predefined_variable`). The check for calls to\nundefined functions can thus be stated as a query:\n\n```erlang\n4> xref:q(s, \"(XC - UC) || (XU - X - B)\").\n{ok,[...]}\n```\n\nThe query asks for the restriction of external calls except the unresolved calls\nto calls to functions that are externally used but neither exported nor built-in\nfunctions (the `||` operator restricts the used functions while the `|` operator\nrestricts the calling functions). The `-` operator returns the difference of two\nsets, and the `+` operator to be used below returns the union of two sets.\n\nThe relationships between the predefined variables `XU`, `X`, `B` and a few\nothers are worth elaborating upon. The reference manual mentions two ways of\nexpressing the set of all functions, one that focuses on how they are defined:\n`X + L + B + U`, and one that focuses on how they are used: `UU + LU + XU`. The\nreference also mentions some [facts](`m:xref#simple_facts`) about the variables:\n\n- `F` is equal to `L + X` (the defined functions are the local functions and the\n external functions);\n- `U` is a subset of `XU` (the unknown functions are a subset of the externally\n used functions since the compiler ensures that locally used functions are\n defined);\n- `B` is a subset of `XU` (calls to built-in functions are always external by\n definition, and unused built-in functions are ignored);\n- `LU` is a subset of `F` (the locally used functions are either local functions\n or exported functions, again ensured by the compiler);\n- `UU` is equal to `F - (XU + LU)` (the unused functions are defined functions\n that are neither used externally nor locally);\n- `UU` is a subset of `F` (the unused functions are defined in analyzed\n modules).\n\nUsing these facts, the two small circles in the picture below can be combined.\n\n![Definition and use of functions](assets/venn1.gif \"Definition and use of functions\")\n\nIt is often clarifying to mark the variables of a query in such a circle. This\nis illustrated in the picture below for some of the predefined analyses. Note\nthat local functions used by local functions only are not marked in the\n`locals_not_used` circle.[](){: #venn2 }\n\n![Some predefined analyses as subsets of all functions](assets/venn2.gif \"Some predefined analyses as subsets of all functions\")","ref":"xref_chapter.html#predefined-analysis"},{"type":"extras","title":"Expressions - Xref - The Cross Reference Tool","doc":"The module check and the predefined analyses are useful, but limited. Sometimes\nmore flexibility is needed, for instance one might not need to apply a graph\nanalysis on all calls, but some subset will do equally well. That flexibility is\nprovided with a simple language. Below are some expressions of the language with\ncomments, focusing on elements of the language rather than providing useful\nexamples. The analyzed system is assumed to be OTP, so in order to run the\nqueries, first evaluate these calls:\n\n```erlang\nxref:start(s).\nxref:add_release(s, code:root_dir()).\n```\n\n- **`xref:q(s, \"(Fun) xref : Mod\").`** - All functions of the `xref` module.\n\n- **`xref:q(s, \"xref : Mod * X\").`** - All exported functions of the `xref`\n module. The first operand of the intersection operator `*` is implicitly\n converted to the more special type of the second operand.\n\n- **`xref:q(s, \"(Mod) tools\").`** - All modules of the Tools application.\n\n- **`xref:q(s, '\"xref_.*\" : Mod').`** - All modules with a name beginning with\n `xref_`.\n\n- **`xref:q(s, \"# E | X \").`** - Number of calls from exported functions.\n\n- **`xref:q(s, \"XC || L \").`** - All external calls to local functions.\n\n- **`xref:q(s, \"XC * LC\").`** - All calls that have both an external and a local\n version.\n\n- **`xref:q(s, \"(LLin) (LC * XC)\").`** - The lines where the local calls of the\n last example are made.\n\n- **`xref:q(s, \"(XLin) (LC * XC)\").`** - The lines where the external calls of\n the example before last are made.\n\n- **`xref:q(s, \"XC * (ME - strict ME)\").`** - External calls within some module.\n\n- **`xref:q(s, \"E ||| kernel\").`** - All calls within the Kernel application.\n\n- **`xref:q(s, \"closure E | kernel || kernel\").`** - All direct and indirect\n calls within the Kernel application. Both the calling and the used functions\n of indirect calls are defined in modules of the kernel application, but it is\n possible that some functions outside the kernel application are used by\n indirect calls.\n\n- **`xref:q(s, \"{toolbar,debugger}:Mod of ME\").`** - A chain of module calls\n from `toolbar` to `debugger`, if there is such a chain, otherwise `false`. The\n chain of calls is represented by a list of modules, `toolbar` being the first\n element and `debugger`the last element.\n\n- **`xref:q(s, \"closure E | toolbar:Mod || debugger:Mod\").`** - All (in)direct\n calls from functions in `toolbar` to functions in `debugger`.\n\n- **`xref:q(s, \"(Fun) xref -> xref_base\").`** - All function calls from `xref`\n to `xref_base`.\n\n- **`xref:q(s, \"E * xref -> xref_base\").`** - Same interpretation as last\n expression.\n\n- **`xref:q(s, \"E || xref_base | xref\").`** - Same interpretation as last\n expression.\n\n- **`xref:q(s, \"E * [xref -> lists, xref_base -> digraph]\").`** - All function\n calls from `xref` to `lists`, and all function calls from `xref_base` to\n `digraph`.\n\n- **`xref:q(s, \"E | [xref, xref_base] || [lists, digraph]\").`** - All function\n calls from `xref` and `xref_base` to `lists` and `digraph`.\n\n- **`xref:q(s, \"components EE\").`** - All strongly connected components of the\n Inter Call Graph. Each component is a set of exported or unused local\n functions that call each other (in)directly.\n\n- **`xref:q(s, \"X * digraph * range (closure (E | digraph) | (L * digraph))\").`** -\n All exported functions of the `digraph` module used (in)directly by some\n function in `digraph`.\n\n- **`xref:q(s, \"L * yeccparser:Mod - range (closure (E |`**\n\n- **`yeccparser:Mod) | (X * yeccparser:Mod))\").`** - The interpretation is left\n as an exercise.","ref":"xref_chapter.html#expressions"},{"type":"extras","title":"Graph Analysis - Xref - The Cross Reference Tool","doc":"The list [representation of graphs](`m:xref#representation`) is used analyzing\ndirect calls, while the `digraph` representation is suited for analyzing\nindirect calls. The restriction operators (`|`, `||` and `|||`) are the only\noperators that accept both representations. This means that in order to analyze\nindirect calls using restriction, the `closure` operator (which creates the\n`digraph` representation of graphs) has to be explicitly applied.\n\nAs an example of analyzing indirect calls, the following Erlang function tries\nto answer the question: if we want to know which modules are used indirectly by\nsome module(s), is it worth while using the\n[function graph](`m:xref#call_graph`) rather than the module graph? Recall that\na module M1 is said to call a module M2 if there is some function in M1 that\ncalls some function in M2. It would be nice if we could use the much smaller\nmodule graph, since it is available also in the light weight\n`modules`[mode](`m:xref#mode`) of Xref servers.\n\n```erlang\nt(S) ->\n {ok, _} = xref:q(S, \"Eplus := closure E\"),\n {ok, Ms} = xref:q(S, \"AM\"),\n Fun = fun(M, N) ->\n Q = io_lib:format(\"# (Mod) (Eplus | ~p : Mod)\", [M]),\n {ok, N0} = xref:q(S, lists:flatten(Q)),\n N + N0\n end,\n Sum = lists:foldl(Fun, 0, Ms),\n ok = xref:forget(S, 'Eplus'),\n {ok, Tot} = xref:q(S, \"# (closure ME | AM)\"),\n 100 * ((Tot - Sum) / Tot).\n```\n\nComments on the code:\n\n- We want to find the reduction of the closure of the function graph to modules.\n The direct expression for doing that would be `(Mod) (closure E | AM)`, but\n then we would have to represent all of the transitive closure of E in memory.\n Instead the number of indirectly used modules is found for each analyzed\n module, and the sum over all modules is calculated.\n- A user variable is employed for holding the `digraph` representation of the\n function graph for use in many queries. The reason is efficiency. As opposed\n to the `=` operator, the `:=` operator saves a value for subsequent analyses.\n Here might be the place to note that equal subexpressions within a query are\n evaluated only once; `=` cannot be used for speeding things up.\n- `Eplus | ~p : Mod`. The `|` operator converts the second operand to the type\n of the first operand. In this case the module is converted to all functions of\n the module. It is necessary to assign a type to the module (`: Mod`),\n otherwise modules like `kernel` would be converted to all functions of the\n application with the same name; the most general constant is used in cases of\n ambiguity.\n- Since we are only interested in a ratio, the unary operator `#` that counts\n the elements of the operand is used. It cannot be applied to the `digraph`\n representation of graphs.\n- We could find the size of the closure of the module graph with a loop similar\n to one used for the function graph, but since the module graph is so much\n smaller, a more direct method is feasible.\n\nWhen the Erlang function `t/1` was applied to an Xref server loaded with the\ncurrent version of OTP, the returned value was close to 84 (percent). This means\nthat the number of indirectly used modules is approximately six times greater\nwhen using the module graph. So the answer to the above stated question is that\nit is definitely worth while using the function graph for this particular\nanalysis. Finally, note that in the presence of unresolved calls, the graphs may\nbe incomplete, which means that there may be indirectly used modules that do not\nshow up.","ref":"xref_chapter.html#graph-analysis"},{"type":"extras","title":"Erlang mode for Emacs","doc":"# Erlang mode for Emacs\n\nPossibly the most important feature of an editor designed for programmers is the\nability to indent a line of code in accordance with the structure of the\nprogramming language. The Erlang mode does, of course, provide this feature. The\nlayout used is based on the common use of the language. The mode also provides\nthings as syntax highlighting, electric commands, module name verification,\ncomment support including paragraph filling, skeletons, tags support etc.\n\nIn the following descriptions the use of the word _Point_ means: \"Point can be\nseen as the position of the cursor. More precisely, the point is the position\nbetween two characters while the cursor is drawn over the character following\nthe point\".","ref":"erlang-el.html"},{"type":"extras","title":"Indent - Erlang mode for Emacs","doc":"The following command are directly available for indentation.\n\n- _`TAB`_ (`erlang-indent-command`) - Indents the current line of code.\n- _`M-C-\\`_ (`indent-region`) - Indents all lines in the region.\n- _`M-l`_ (`indent-for-comment`) - Insert a comment character to the right of\n the code on the line (if any).\n\nLines containing comment are indented differently depending on the number of\n%-characters used:\n\n- Lines with one %-character is indented to the right of the code. The column\n is specified by the variable `comment-column`, by default column 48 is used.\n- Lines with two %-characters will be indented to the same depth as code would\n have been in the same situation.\n- Lines with three of more %-characters are indented to the left margin.\n- _`C-c C-q`_ (`erlang-indent-function`) - Indents the current Erlang\n function.\n- _`M-x erlang-indent-clause RET`_ - Indent the current Erlang clause.\n- _`M-x erlang-indent-current-buffer RET`_ - Indent the entire buffer.","ref":"erlang-el.html#indent"},{"type":"extras","title":"Edit - Fill Comment - Erlang mode for Emacs","doc":"When editing normal text in text mode you can let Emacs reformat the text by the\n`fill-paragraph` command. This command will not work for comments since it will\ntreat the comment characters as words. The Erlang editing mode provides a\ncommand that knows about the Erlang comment structure and can be used to fill\ntext paragraphs in comments. Ex:\n\n```erlang\n%% This is just a very simple test to show\n%% how the Erlang fill\n%% paragraph command works.\n```\n\nClearly, the text is badly formatted. Instead of formatting this paragraph line\nby line, let's try `erlang-fill-paragraph` by pressing _`M-q`_. The result is:\n\n```erlang\n%% This is just a very simple test to show how the Erlang fill\n%% paragraph command works.\n```","ref":"erlang-el.html#edit-fill-comment"},{"type":"extras","title":"Edit - Comment/Uncomment Region - Erlang mode for Emacs","doc":"_`C-c C-c`_ will put comment characters at the beginning of all lines in a\nmarked region. If you want to have two comment characters instead of one you can\ndo _`C-u 2 C-c C-c`_\n\n_`C-c C-u`_ will undo a comment-region command.","ref":"erlang-el.html#edit-comment-uncomment-region"},{"type":"extras","title":"Edit - Moving the point - Erlang mode for Emacs","doc":"- _`M-C-a`_ (`erlang-beginning-of-function`) - Move the point to the beginning\n of the current or preceding Erlang function. With an numeric argument (ex\n _`C-u 2 M-C-a`_) the function skips backwards over this many Erlang\n functions. Should the argument be negative the point is moved to the\n beginning of a function below the current function.\n- _`C-c M-a`_ (`erlang-beginning-of-clause`) - As above but move point to the\n beginning of the current or preceding Erlang clause.\n- _`M-C-e`_ (`erlang-end-of-function`) - Move to the end of the current or\n following Erlang function. With an numeric argument (ex _`C-u 2 M-C-e`_) the\n function skips backwards over this many Erlang functions. Should the\n argument be negative the point is moved to the end of a function below the\n current function.\n- _`C-c M-e`_ (`erlang-end-of-clause`) - As above but move point to the end of\n the current or following Erlang clause.","ref":"erlang-el.html#edit-moving-the-point"},{"type":"extras","title":"Edit - Marking - Erlang mode for Emacs","doc":"- _`M-C-h`_ (`erlang-mark-function`) - Put the region around the current\n Erlang function. The point is placed in the beginning and the mark at the\n end of the function.\n- _`C-c M-h`_ (`erlang-mark-clause`) Put the region around the current Erlang\n clause. The point is placed in the beginning and the mark at the end of the\n function.","ref":"erlang-el.html#edit-marking"},{"type":"extras","title":"Edit - Function Header Commands - Erlang mode for Emacs","doc":"- _`C-c C-j`_ (`erlang-generate-new-clause`) - Create a new clause in the\n current Erlang function. The point is placed between the parentheses of the\n argument list.\n- _`C-c C-y`_ (`erlang-clone-arguments`) - Copy the function arguments of the\n preceding Erlang clause. This command is useful when defining a new clause\n with almost the same argument as the preceding.","ref":"erlang-el.html#edit-function-header-commands"},{"type":"extras","title":"Edit - Alignment - Erlang mode for Emacs","doc":"- _`C-c C-a`_ (`align-current`) - aligns comments, arrows, assignments,\n and type annotations around the cursor.\n\n```erlang\nExample:\n\nsum(L) -> sum(L, 0).\nsum([H|T], Sum) -> sum(T, Sum + H); % recurse\nsum([], Sum) -> Sum. % base case\n\n-record { two :: int(), % hello\n three = hello :: string(), % there\n four = 42 :: int() }.\n\nbecomes:\n\nsum(L) -> sum(L, 0).\nsum([H|T], Sum) -> sum(T, Sum + H); % recurse\nsum([], Sum) -> Sum. % base case\n\n-record { two :: int(), % hello\n three = hello :: string(), % there\n four = 42 :: int() }.\n```","ref":"erlang-el.html#edit-alignment"},{"type":"extras","title":"Syntax highlighting - Erlang mode for Emacs","doc":"The syntax highlighting can be activated from the Erlang menu. There are four\ndifferent alternatives:\n\n- Off: Normal black and white display.\n- Level 1: Function headers, reserved words, comments, strings, quoted atoms,\n and character constants will be colored.\n- Level 2: The above, attributes, Erlang bif:s, guards, and words in comments\n enclosed in single quotes will be colored.\n- Level 3: The above, variables, records, and macros will be colored. (This\n level is also known as the Christmas tree level.)","ref":"erlang-el.html#syntax-highlighting"},{"type":"extras","title":"Tags - Erlang mode for Emacs","doc":"For the tag commands to work it requires that you have generated a tag file. See\n[Erlang mode users guide](erlang_mode_chapter.md#tags)\n\n- _`M-.`_ (`find-tag`) - Find a function definition. The default value is the\n function name under the point.\n- Find Tag (`erlang-find-tag`) - Like the Elisp-function\n `find-tag'. Capable of retrieving Erlang modules. Tags can be given on the forms `tag',\n `module:', `module:tag'.\n- _`M-+`_ (`erlang-find-next-tag`) - Find the next occurrence of tag.\n- _`M-TAB`_ (`erlang-complete-tag`) - Perform completion on the tag entered in\n a tag search. Completes to the set of names listed in the current tags\n table.\n- Tags aprops (`tags-apropos`) - Display list of all tags in tags table REGEXP\n matches.\n- _`C-x t s`_ (`tags-search`) - Search through all files listed in tags table\n for match for REGEXP. Stops when a match is found.","ref":"erlang-el.html#tags"},{"type":"extras","title":"Skeletons - Erlang mode for Emacs","doc":"A skeleton is a piece of pre-written code that can be inserted into the buffer.\nErlang mode comes with a set of predefined skeletons. The skeletons can be\naccessed either from the Erlang menu of from commands named\n`tempo-template-erlang-*`, as the skeletons is defined using the standard Emacs\npackage \"tempo\". Here follows a brief description of the available skeletons:\n\n- Simple skeletons: If, Case, Receive, Receive After, Receive Loop - Basic\n code constructs.\n- Header elements: Module, Author - These commands insert lines on the form\n `-module('xxx').` and `-author('my@home').`. They can be used directly, but\n are also used as part of the full headers described below.\n- Full Headers: Small (minimum requirement), Medium (with fields for basic\n information about the module), and Large Header (medium header with some\n extra layout structure).\n- Small Server - skeleton for a simple server not using OTP.\n- Application - skeletons for the OTP application behavior\n- Supervisor - skeleton for the OTP supervisor behavior\n- Supervisor Bridge - skeleton for the OTP supervisor bridge behavior\n- gen_server - skeleton for the OTP gen_server behavior\n- gen_event - skeleton for the OTP gen_event behavior\n- gen_fsm - skeleton for the OTP gen_fsm behavior\n- gen_statem (StateName/3) - skeleton for the OTP gen_statem behavior using\n state name functions\n- gen_statem (handle_event/4) - skeleton for the OTP gen_statem behavior using\n one state function\n- Library module - skeleton for a module that does not implement a process.\n- Corba callback - skeleton for a Corba callback module.\n- Erlang test suite - skeleton for a callback module for the erlang test\n server.","ref":"erlang-el.html#skeletons"},{"type":"extras","title":"Shell - Erlang mode for Emacs","doc":"- New shell (`erlang-shell`) - Starts a new Erlang shell.\n- _`C-c C-z,`_ (`erlang-shell-display `) - Displays an Erlang shell, or starts\n a new one if there is no shell started.","ref":"erlang-el.html#shell"},{"type":"extras","title":"Compile - Erlang mode for Emacs","doc":"- _`C-c C-k,`_ (`erlang-compile`) - Compiles the Erlang module in the current\n buffer. You can also use _`C-u C-c C-k`_ to debug compile the module with\n the debug options `debug_info` and `export_all`.\n- _`C-c C-l,`_ (`erlang-compile-display`) - Display compilation output.\n- _``C-u C-x` ``_ Start parsing the compiler output from the beginning. This\n command will place the point on the line where the first error was found.\n- _`` C-x` ``_ (`erlang-next-error`) - Move the point on to the next error.\n The buffer displaying the compilation errors will be updated so that the\n current error will be visible.","ref":"erlang-el.html#compile"},{"type":"extras","title":"Man - Erlang mode for Emacs","doc":"On unix you can view the manual pages in emacs. In order to find the manual\npages, the variable `erlang-root-dir` should be bound to the name of the\ndirectory containing the Erlang installation. The name should not include the\nfinal slash. Practically, you should add a line on the following form to your\n~/.emacs,\n\n```text\n(setq erlang-root-dir \"/the/erlang/root/dir/goes/here\")\n```","ref":"erlang-el.html#man"},{"type":"extras","title":"Starting IMenu - Erlang mode for Emacs","doc":"- _`M-x imenu-add-to-menubar RET`_ - This command will create the IMenu menu\n containing all the functions in the current buffer.The command will ask you\n for a suitable name for the menu. Not supported by Xemacs.","ref":"erlang-el.html#starting-imenu"},{"type":"extras","title":"Version - Erlang mode for Emacs","doc":"- _`M-x erlang-version RET`_ - This command displays the version number of the\n Erlang editing mode. Remember to always supply the version number when\n asking questions about the Erlang mode.","ref":"erlang-el.html#version"}],"content_type":"text/plain","producer":{"name":"ex_doc","version":[48,46,51,52,46,49]}} \ No newline at end of file diff --git a/prs/8803/lib/tools-4.0/doc/html/erlang-el.html b/prs/8803/lib/tools-4.0/doc/html/erlang-el.html index eab5fc9dd064a..e49841369d212 100644 --- a/prs/8803/lib/tools-4.0/doc/html/erlang-el.html +++ b/prs/8803/lib/tools-4.0/doc/html/erlang-el.html @@ -211,23 +211,23 @@

    • C-c C-a (align-current) - aligns comments, arrows, assignments, and type annotations around the cursor.
    Example:
     
    -sum(L) -> sum(L, 0).
    -sum([H|T], Sum) -> sum(T, Sum + H);  % recurse
    -sum([], Sum) -> Sum.   % base case
    +sum(L) -> sum(L, 0).
    +sum([H|T], Sum) -> sum(T, Sum + H);  % recurse
    +sum([], Sum) -> Sum.   % base case
     
    --record { two :: int(), % hello
    -          three = hello :: string(),    % there
    -          four = 42 :: int() }.
    +-record { two :: int(), % hello
    +          three = hello :: string(),    % there
    +          four = 42 :: int() }.
     
     becomes:
     
    -sum(L) -> sum(L, 0).
    -sum([H|T], Sum) -> sum(T, Sum + H); % recurse
    -sum([], Sum)    -> Sum.             % base case
    +sum(L) -> sum(L, 0).
    +sum([H|T], Sum) -> sum(T, Sum + H); % recurse
    +sum([], Sum)    -> Sum.             % base case
     
    --record { two           :: int(),    % hello
    -          three = hello :: string(), % there
    -          four  = 42    :: int() }.

    +-record { two :: int(), % hello + three = hello :: string(), % there + four = 42 :: int() }.

    diff --git a/prs/8803/lib/tools-4.0/doc/html/fprof.html b/prs/8803/lib/tools-4.0/doc/html/fprof.html index 6d4b4c703b31d..524aafea9540a 100644 --- a/prs/8803/lib/tools-4.0/doc/html/fprof.html +++ b/prs/8803/lib/tools-4.0/doc/html/fprof.html @@ -175,61 +175,61 @@

    interested reader to try it out. Note that some flags to analyse/1 will affect the format.

    The following example was run on Erlang/OTP R8 on Solaris 8; all OTP internals in this example are version dependent.

    As an example, we will use the following function, which is a -slightly modified benchmark function from module file:

    -module(foo).
    --export([create_file_slow/2]).
    +slightly modified benchmark function from module file:

    -module(foo).
    +-export([create_file_slow/2]).
     
    -create_file_slow(Name, N) when is_integer(N), N >= 0 ->
    -    {ok, FD} =
    -        file:open(Name, [raw, write, delayed_write, binary]),
    +create_file_slow(Name, N) when is_integer(N), N >= 0 ->
    +    {ok, FD} =
    +        file:open(Name, [raw, write, delayed_write, binary]),
         if N > 256 ->
    -            ok = file:write(FD,
    -                            lists:map(fun (X) -> <<X:32/unsigned>> end,
    -                            lists:seq(0, 255))),
    -            ok = create_file_slow(FD, 256, N);
    +            ok = file:write(FD,
    +                            lists:map(fun (X) -> <<X:32/unsigned>> end,
    +                            lists:seq(0, 255))),
    +            ok = create_file_slow(FD, 256, N);
            true ->
    -            ok = create_file_slow(FD, 0, N)
    +            ok = create_file_slow(FD, 0, N)
         end,
    -    ok = file:close(FD).
    +    ok = file:close(FD).
     
    -create_file_slow(FD, M, M) ->
    +create_file_slow(FD, M, M) ->
         ok;
    -create_file_slow(FD, M, N) ->
    -    ok = file:write(FD, <<M:32/unsigned>>),
    -    create_file_slow(FD, M+1, N).

    Let us have a look at the printout after running:

    1> fprof:apply(foo, create_file_slow, [junk, 1024]).
    -2> fprof:profile().
    -3> fprof:analyse().

    The printout starts with:

    %% Analysis results:
    -{  analysis_options,
    - [{callers, true},
    -  {sort, acc},
    -  {totals, false},
    -  {details, true}]}.
    +create_file_slow(FD, M, N) ->
    +    ok = file:write(FD, <<M:32/unsigned>>),
    +    create_file_slow(FD, M+1, N).

    Let us have a look at the printout after running:

    1> fprof:apply(foo, create_file_slow, [junk, 1024]).
    +2> fprof:profile().
    +3> fprof:analyse().

    The printout starts with:

    %% Analysis results:
    +{  analysis_options,
    + [{callers, true},
    +  {sort, acc},
    +  {totals, false},
    +  {details, true}]}.
     
     %                                       CNT       ACC       OWN
    -[{ totals,                             9627, 1691.119, 1659.074}].  %%%

    The CNT column shows the total number of function calls that was found in the +[{ totals, 9627, 1691.119, 1659.074}]. %%%

    The CNT column shows the total number of function calls that was found in the trace. In the ACC column is the total time of the trace from first timestamp to last. And in the OWN column is the sum of the execution time in functions found in the trace, not including called functions. In this case it is very close to the ACC time since the emulator had practically nothing to do except executing our test program.

    All time values in the printout are in milliseconds.

    The printout continues:

    %                                       CNT       ACC       OWN
    -[{ "<0.28.0>",                         9627,undefined, 1659.074}].   %%

    This is the printout header of one process. The printout contains only this one +[{ "<0.28.0>", 9627,undefined, 1659.074}]. %%

    This is the printout header of one process. The printout contains only this one process since we called fprof:apply/3 that traces only the current process. Therefore the CNT and OWN columns perfectly matches the totals above. The ACC column is undefined since summing the ACC times of all calls in the process makes no sense — one would get something like the ACC value from totals above multiplied by the average depth of the call stack.

    All paragraphs up to the next process header only concerns function calls within -this process.

    Now we come to something more interesting:

    {[{undefined,                             0, 1691.076,    0.030}],
    - { {fprof,apply_start_stop,4},            0, 1691.076,    0.030},     %
    - [{{foo,create_file_slow,2},              1, 1691.046,    0.103},
    -  {suspend,                               1,    0.000,    0.000}]}.
    -
    -{[{{fprof,apply_start_stop,4},            1, 1691.046,    0.103}],
    - { {foo,create_file_slow,2},              1, 1691.046,    0.103},     %
    - [{{file,close,1},                        1, 1398.873,    0.019},
    -  {{foo,create_file_slow,3},              1,  249.678,    0.029},
    -  {{file,open,2},                         1,   20.778,    0.055},
    -  {{lists,map,2},                         1,   16.590,    0.043},
    -  {{lists,seq,2},                         1,    4.708,    0.017},
    -  {{file,write,2},                        1,    0.316,    0.021}]}.

    The printout consists of one paragraph per called function. The function +this process.

    Now we come to something more interesting:

    {[{undefined,                             0, 1691.076,    0.030}],
    + { {fprof,apply_start_stop,4},            0, 1691.076,    0.030},     %
    + [{{foo,create_file_slow,2},              1, 1691.046,    0.103},
    +  {suspend,                               1,    0.000,    0.000}]}.
    +
    +{[{{fprof,apply_start_stop,4},            1, 1691.046,    0.103}],
    + { {foo,create_file_slow,2},              1, 1691.046,    0.103},     %
    + [{{file,close,1},                        1, 1398.873,    0.019},
    +  {{foo,create_file_slow,3},              1,  249.678,    0.029},
    +  {{file,open,2},                         1,   20.778,    0.055},
    +  {{lists,map,2},                         1,   16.590,    0.043},
    +  {{lists,seq,2},                         1,    4.708,    0.017},
    +  {{file,write,2},                        1,    0.316,    0.021}]}.

    The printout consists of one paragraph per called function. The function marked with % is the one the paragraph concerns — foo:create_file_slow/2. Above the marked function are the calling functions — those that has called the marked, and below are those called by the marked function.

    The paragraphs are per default sorted in descending order of the ACC column for @@ -246,12 +246,12 @@

    (lists:seq/2 and lists:map/2).

    The function undefined that has called fprof:apply_start_stop/4 is an unknown function because that call was not recorded in the trace. It was only recorded that the execution returned from fprof:apply_start_stop/4 to some -other function above in the call stack, or that the process exited from there.

    Let us continue down the printout to find:

    {[{{foo,create_file_slow,2},              1,  249.678,    0.029},
    -  {{foo,create_file_slow,3},            768,    0.000,   23.294}],
    - { {foo,create_file_slow,3},            769,  249.678,   23.323},     %
    - [{{file,write,2},                      768,  220.314,   14.539},
    -  {suspend,                              57,    6.041,    0.000},
    -  {{foo,create_file_slow,3},            768,    0.000,   23.294}]}.

    If you compare with the code you will see there also that +other function above in the call stack, or that the process exited from there.

    Let us continue down the printout to find:

    {[{{foo,create_file_slow,2},              1,  249.678,    0.029},
    +  {{foo,create_file_slow,3},            768,    0.000,   23.294}],
    + { {foo,create_file_slow,3},            769,  249.678,   23.323},     %
    + [{{file,write,2},                      768,  220.314,   14.539},
    +  {suspend,                              57,    6.041,    0.000},
    +  {{foo,create_file_slow,3},            768,    0.000,   23.294}]}.

    If you compare with the code you will see there also that foo:create_file_slow/3 was called only from foo:create_file_slow/2 and itself, and called only file:write/2, note the number of calls to file:write/2. But here we see that suspend was called a few times. This is a @@ -259,88 +259,88 @@

    foo:create_file_slow/3, and since there is no receive or erlang:yield/0 in the code, it must be Erlang scheduling suspensions, or the trace file driver compensating for large file write operations (these are regarded as a schedule -out followed by a schedule in to the same process).

    Let us find the suspend entry:

    {[{{file,write,2},                       53,    6.281,    0.000},
    -  {{foo,create_file_slow,3},             57,    6.041,    0.000},
    -  {{prim_file,drv_command,4},            50,    4.582,    0.000},
    -  {{prim_file,drv_get_response,1},       34,    2.986,    0.000},
    -  {{lists,map,2},                        10,    2.104,    0.000},
    -  {{prim_file,write,2},                  17,    1.852,    0.000},
    -  {{erlang,port_command,2},              15,    1.713,    0.000},
    -  {{prim_file,drv_command,2},            22,    1.482,    0.000},
    -  {{prim_file,translate_response,2},     11,    1.441,    0.000},
    -  {{prim_file,'-drv_command/2-fun-0-',1},  15,    1.340,    0.000},
    -  {{lists,seq,4},                         3,    0.880,    0.000},
    -  {{foo,'-create_file_slow/2-fun-0-',1},   5,    0.523,    0.000},
    -  {{erlang,bump_reductions,1},            4,    0.503,    0.000},
    -  {{prim_file,open_int_setopts,3},        1,    0.165,    0.000},
    -  {{prim_file,i32,4},                     1,    0.109,    0.000},
    -  {{fprof,apply_start_stop,4},            1,    0.000,    0.000}],
    - { suspend,                             299,   32.002,    0.000},     %
    - [ ]}.

    We find no particularly long suspend times, so no function seems to have waited +out followed by a schedule in to the same process).

    Let us find the suspend entry:

    {[{{file,write,2},                       53,    6.281,    0.000},
    +  {{foo,create_file_slow,3},             57,    6.041,    0.000},
    +  {{prim_file,drv_command,4},            50,    4.582,    0.000},
    +  {{prim_file,drv_get_response,1},       34,    2.986,    0.000},
    +  {{lists,map,2},                        10,    2.104,    0.000},
    +  {{prim_file,write,2},                  17,    1.852,    0.000},
    +  {{erlang,port_command,2},              15,    1.713,    0.000},
    +  {{prim_file,drv_command,2},            22,    1.482,    0.000},
    +  {{prim_file,translate_response,2},     11,    1.441,    0.000},
    +  {{prim_file,'-drv_command/2-fun-0-',1},  15,    1.340,    0.000},
    +  {{lists,seq,4},                         3,    0.880,    0.000},
    +  {{foo,'-create_file_slow/2-fun-0-',1},   5,    0.523,    0.000},
    +  {{erlang,bump_reductions,1},            4,    0.503,    0.000},
    +  {{prim_file,open_int_setopts,3},        1,    0.165,    0.000},
    +  {{prim_file,i32,4},                     1,    0.109,    0.000},
    +  {{fprof,apply_start_stop,4},            1,    0.000,    0.000}],
    + { suspend,                             299,   32.002,    0.000},     %
    + [ ]}.

    We find no particularly long suspend times, so no function seems to have waited in a receive statement. Actually, prim_file:drv_command/4 contains a receive statement, but in this test program, the message lies in the process receive buffer when the receive statement is entered. We also see that the total suspend time for the test run is small.

    The suspend pseudo function has an OWN time of zero. This is to prevent the process total OWN time from including time in suspension. Whether suspend -time is really ACC or OWN time is more of a philosophical question.

    Now we look at another interesting pseudo function, garbage_collect:

    {[{{prim_file,drv_command,4},            25,    0.873,    0.873},
    -  {{prim_file,write,2},                  16,    0.692,    0.692},
    -  {{lists,map,2},                         2,    0.195,    0.195}],
    - { garbage_collect,                      43,    1.760,    1.760},     %
    - [ ]}.

    Here we see that no function stands out, which is very normal.

    The garbage_collect pseudo function has not an OWN time of zero like +time is really ACC or OWN time is more of a philosophical question.

    Now we look at another interesting pseudo function, garbage_collect:

    {[{{prim_file,drv_command,4},            25,    0.873,    0.873},
    +  {{prim_file,write,2},                  16,    0.692,    0.692},
    +  {{lists,map,2},                         2,    0.195,    0.195}],
    + { garbage_collect,                      43,    1.760,    1.760},     %
    + [ ]}.

    Here we see that no function stands out, which is very normal.

    The garbage_collect pseudo function has not an OWN time of zero like suspend, instead it is equal to the ACC time.

    Garbage collection often occurs while a process is suspended, but fprof hides this fact by pretending that the suspended function was first unsuspended and then garbage collected. Otherwise the printout would show garbage_collect being called from suspend, but not which function that might have caused the -garbage collection.

    Let us now get back to the test code:

    {[{{foo,create_file_slow,3},            768,  220.314,   14.539},
    -  {{foo,create_file_slow,2},              1,    0.316,    0.021}],
    - { {file,write,2},                      769,  220.630,   14.560},     %
    - [{{prim_file,write,2},                 769,  199.789,   22.573},
    -  {suspend,                              53,    6.281,    0.000}]}.

    Not unexpectedly, we see that file:write/2 was called from +garbage collection.

    Let us now get back to the test code:

    {[{{foo,create_file_slow,3},            768,  220.314,   14.539},
    +  {{foo,create_file_slow,2},              1,    0.316,    0.021}],
    + { {file,write,2},                      769,  220.630,   14.560},     %
    + [{{prim_file,write,2},                 769,  199.789,   22.573},
    +  {suspend,                              53,    6.281,    0.000}]}.

    Not unexpectedly, we see that file:write/2 was called from foo:create_file_slow/3 and foo:create_file_slow/2. The number of calls in each case as well as the used time are also confirms the previous results.

    We see that file:write/2 only calls prim_file:write/2, but let us refrain from digging into the internals of the kernel application.

    If we nevertheless do dig down we find the call to the linked-in driver -that does the file operations towards the host operating system:

    {[{{prim_file,drv_command,4},           772, 1458.356, 1456.643}],
    - { {erlang,port_command,2},             772, 1458.356, 1456.643},     %
    - [{suspend,                              15,    1.713,    0.000}]}.

    This is 86 % of the total run time, and as we saw before it is the close +that does the file operations towards the host operating system:

    {[{{prim_file,drv_command,4},           772, 1458.356, 1456.643}],
    + { {erlang,port_command,2},             772, 1458.356, 1456.643},     %
    + [{suspend,                              15,    1.713,    0.000}]}.

    This is 86 % of the total run time, and as we saw before it is the close operation the absolutely biggest contributor. We find a comparison ratio a -little bit up in the call stack:

    {[{{prim_file,close,1},                   1, 1398.748,    0.024},
    -  {{prim_file,write,2},                 769,  174.672,   12.810},
    -  {{prim_file,open_int,4},                1,   19.755,    0.017},
    -  {{prim_file,open_int_setopts,3},        1,    0.147,    0.016}],
    - { {prim_file,drv_command,2},           772, 1593.322,   12.867},     %
    - [{{prim_file,drv_command,4},           772, 1578.973,   27.265},
    -  {suspend,                              22,    1.482,    0.000}]}.

    The time for file operations in the linked in driver distributes itself as 1 % +little bit up in the call stack:

    {[{{prim_file,close,1},                   1, 1398.748,    0.024},
    +  {{prim_file,write,2},                 769,  174.672,   12.810},
    +  {{prim_file,open_int,4},                1,   19.755,    0.017},
    +  {{prim_file,open_int_setopts,3},        1,    0.147,    0.016}],
    + { {prim_file,drv_command,2},           772, 1593.322,   12.867},     %
    + [{{prim_file,drv_command,4},           772, 1578.973,   27.265},
    +  {suspend,                              22,    1.482,    0.000}]}.

    The time for file operations in the linked in driver distributes itself as 1 % for open, 11 % for write, and 87 % for close. All data is probably buffered in the operating system until the close.

    The observant reader may notice that the ACC times for prim_file:drv_command/2 and prim_file:drv_command/4 is not equal between the paragraphs above, even though it is easy to believe that prim_file:drv_command/2 is just a passthrough function.

    The missing time can be found in the paragraph for prim_file:drv_command/4 where it is evident that not only prim_file:drv_command/2 is called but also a -fun:

    {[{{prim_file,drv_command,2},           772, 1578.973,   27.265}],
    - { {prim_file,drv_command,4},           772, 1578.973,   27.265},     %
    - [{{erlang,port_command,2},             772, 1458.356, 1456.643},
    -  {{prim_file,'-drv_command/2-fun-0-',1}, 772,   87.897,   12.736},
    -  {suspend,                              50,    4.582,    0.000},
    -  {garbage_collect,                      25,    0.873,    0.873}]}.

    And some more missing time can be explained by the fact that +fun:

    {[{{prim_file,drv_command,2},           772, 1578.973,   27.265}],
    + { {prim_file,drv_command,4},           772, 1578.973,   27.265},     %
    + [{{erlang,port_command,2},             772, 1458.356, 1456.643},
    +  {{prim_file,'-drv_command/2-fun-0-',1}, 772,   87.897,   12.736},
    +  {suspend,                              50,    4.582,    0.000},
    +  {garbage_collect,                      25,    0.873,    0.873}]}.

    And some more missing time can be explained by the fact that prim_file:open_int/4 both calls prim_file:drv_command/2 directly as well as -through prim_file:open_int_setopts/3, which complicates the picture.

    {[{{prim_file,open,2},                    1,   20.309,    0.029},
    -  {{prim_file,open_int,4},                1,    0.000,    0.057}],
    - { {prim_file,open_int,4},                2,   20.309,    0.086},     %
    - [{{prim_file,drv_command,2},             1,   19.755,    0.017},
    -  {{prim_file,open_int_setopts,3},        1,    0.360,    0.032},
    -  {{prim_file,drv_open,2},                1,    0.071,    0.030},
    -  {{erlang,list_to_binary,1},             1,    0.020,    0.020},
    -  {{prim_file,i32,1},                     1,    0.017,    0.017},
    -  {{prim_file,open_int,4},                1,    0.000,    0.057}]}.
    +through prim_file:open_int_setopts/3, which complicates the picture.

    {[{{prim_file,open,2},                    1,   20.309,    0.029},
    +  {{prim_file,open_int,4},                1,    0.000,    0.057}],
    + { {prim_file,open_int,4},                2,   20.309,    0.086},     %
    + [{{prim_file,drv_command,2},             1,   19.755,    0.017},
    +  {{prim_file,open_int_setopts,3},        1,    0.360,    0.032},
    +  {{prim_file,drv_open,2},                1,    0.071,    0.030},
    +  {{erlang,list_to_binary,1},             1,    0.020,    0.020},
    +  {{prim_file,i32,1},                     1,    0.017,    0.017},
    +  {{prim_file,open_int,4},                1,    0.000,    0.057}]}.
     .
     .
     .
    -{[{{prim_file,open_int,4},                1,    0.360,    0.032},
    -  {{prim_file,open_int_setopts,3},        1,    0.000,    0.016}],
    - { {prim_file,open_int_setopts,3},        2,    0.360,    0.048},     %
    - [{suspend,                               1,    0.165,    0.000},
    -  {{prim_file,drv_command,2},             1,    0.147,    0.016},
    -  {{prim_file,open_int_setopts,3},        1,    0.000,    0.016}]}.

    +{[{{prim_file,open_int,4}, 1, 0.360, 0.032}, + {{prim_file,open_int_setopts,3}, 1, 0.000, 0.016}], + { {prim_file,open_int_setopts,3}, 2, 0.360, 0.048}, % + [{suspend, 1, 0.165, 0.000}, + {{prim_file,drv_command,2}, 1, 0.147, 0.016}, + {{prim_file,open_int_setopts,3}, 1, 0.000, 0.016}]}.

    diff --git a/prs/8803/lib/tools-4.0/doc/html/fprof_chapter.html b/prs/8803/lib/tools-4.0/doc/html/fprof_chapter.html index 936926bee746d..9d16205eaf11c 100644 --- a/prs/8803/lib/tools-4.0/doc/html/fprof_chapter.html +++ b/prs/8803/lib/tools-4.0/doc/html/fprof_chapter.html @@ -176,10 +176,10 @@

    It is also possible to trace immediately into the profiling process that creates the raw profile data, that is to short circuit the tracing and profiling steps -so that the filesystem is not used for tracing.

    Do something like this:

    {ok, Tracer} = fprof:profile(start),
    -fprof:trace([start, {tracer, Tracer}]),
    +so that the filesystem is not used for tracing.

    Do something like this:

    {ok, Tracer} = fprof:profile(start),
    +fprof:trace([start, {tracer, Tracer}]),
     %% Run code to profile
    -fprof:trace(stop);

    This puts less load on the filesystem, but much more load on the Erlang runtime +fprof:trace(stop);

    This puts less load on the filesystem, but much more load on the Erlang runtime system.

    diff --git a/prs/8803/lib/tools-4.0/doc/html/lcnt_chapter.html b/prs/8803/lib/tools-4.0/doc/html/lcnt_chapter.html index 5d97767461fff..0497bb806488b 100644 --- a/prs/8803/lib/tools-4.0/doc/html/lcnt_chapter.html +++ b/prs/8803/lib/tools-4.0/doc/html/lcnt_chapter.html @@ -233,20 +233,20 @@

    Example with Mnesia Transaction Benchmark

    -

    From the Erlang shell:

    Erlang/OTP 27 [erts-15.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [lock-counting]
    +

    From the Erlang shell:

    Erlang/OTP 27 [erts-15.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [lock-counting]
     
    -Eshell V15.0 (press Ctrl+G to abort, type help(). for help)
    -1> Conf = [{db_nodes, [node()]}, {driver_nodes, [node()]}, {replica_nodes, [node()]},
    -    {n_drivers_per_node, 10}, {n_branches, 1000}, {n_accounts_per_branch, 10},
    -    {replica_type, ram_copies}, {stop_after, 60000}, {reuse_history_id, true}], ok.
    +Eshell V15.0 (press Ctrl+G to abort, type help(). for help)
    +1> Conf = [{db_nodes, [node()]}, {driver_nodes, [node()]}, {replica_nodes, [node()]},
    +    {n_drivers_per_node, 10}, {n_branches, 1000}, {n_accounts_per_branch, 10},
    +    {replica_type, ram_copies}, {stop_after, 60000}, {reuse_history_id, true}], ok.
     ok
    -2> mnesia_tpcb:init([{use_running_mnesia, false}|Conf]).
    +2> mnesia_tpcb:init([{use_running_mnesia, false}|Conf]).
         .
         .
         .
     ignore

    Initial configuring of the benchmark is done. It is time to profile the actual -Mnesia benchmark:

    3> lcnt:apply(fun() -> {ok,{time, Tps,_,_,_,_}} = mnesia_tpcb:run([{use_running_mnesia,
    -    true}|Conf]), Tps/60 end).
    +Mnesia benchmark:

    3> lcnt:apply(fun() -> {ok,{time, Tps,_,_,_,_}} = mnesia_tpcb:run([{use_running_mnesia,
    +    true}|Conf]), Tps/60 end).
           .
           .
           .
    @@ -350,63 +350,63 @@ 

    The Big Bang Benchmark

    -
    -module(big).
    --export([bang/1]).
    +
    -module(big).
    +-export([bang/1]).
     
    -pinger([], [], true) ->
    +pinger([], [], true) ->
         receive
    -	{procs, Procs, ReportTo} ->
    -	    pinger(Procs, [], ReportTo)
    +	{procs, Procs, ReportTo} ->
    +	    pinger(Procs, [], ReportTo)
         end;
    -pinger([], [], false) ->
    -    receive {ping, From} -> From ! {pong, self()} end,
    -    pinger([],[],false);
    -pinger([], [], ReportTo) ->
    -    ReportTo ! {done, self()},
    -    pinger([],[],false);
    -pinger([], [Po|Pos] = Pongers, ReportTo) ->
    +pinger([], [], false) ->
    +    receive {ping, From} -> From ! {pong, self()} end,
    +    pinger([],[],false);
    +pinger([], [], ReportTo) ->
    +    ReportTo ! {done, self()},
    +    pinger([],[],false);
    +pinger([], [Po|Pos] = Pongers, ReportTo) ->
         receive
    -	{ping, From} ->
    -	    From ! {pong, self()},
    -	    pinger([], Pongers, ReportTo);
    -	{pong, Po} ->
    -	    pinger([], Pos, ReportTo)
    +	{ping, From} ->
    +	    From ! {pong, self()},
    +	    pinger([], Pongers, ReportTo);
    +	{pong, Po} ->
    +	    pinger([], Pos, ReportTo)
         end;
    -pinger([Pi|Pis], Pongers, ReportTo) ->
    -    receive {ping, From} -> From ! {pong, self()}
    +pinger([Pi|Pis], Pongers, ReportTo) ->
    +    receive {ping, From} -> From ! {pong, self()}
         after 0 -> ok
         end,
    -    Pi ! {ping, self()},
    -    pinger(Pis, [Pi|Pongers], ReportTo).
    +    Pi ! {ping, self()},
    +    pinger(Pis, [Pi|Pongers], ReportTo).
     
    -spawn_procs(N) when N =< 0 ->
    -    [];
    -spawn_procs(N) ->
    -    [spawn_link(fun () -> pinger([],[],true) end) | spawn_procs(N-1)].
    +spawn_procs(N) when N =< 0 ->
    +    [];
    +spawn_procs(N) ->
    +    [spawn_link(fun () -> pinger([],[],true) end) | spawn_procs(N-1)].
     
    -send_procs([], Msg) ->
    +send_procs([], Msg) ->
         Msg;
    -send_procs([P|Ps], Msg) ->
    +send_procs([P|Ps], Msg) ->
         P ! Msg,
    -    send_procs(Ps, Msg).
    +    send_procs(Ps, Msg).
     
    -receive_msgs([]) ->
    +receive_msgs([]) ->
         ok;
    -receive_msgs([M|Ms]) ->
    +receive_msgs([M|Ms]) ->
         receive
     	M ->
    -	    receive_msgs(Ms)
    +	    receive_msgs(Ms)
         end.
     
    -bang(N) when integer(N) ->
    -    Procs = spawn_procs(N),
    -    RMsgs = lists:map(fun (P) -> {done, P} end, Procs),
    -    Start = now(),
    -    send_procs(Procs, {procs, Procs, self()}),
    -    receive_msgs(RMsgs),
    -    Stop = now(),
    -    lists:foreach(fun (P) -> exit(P, normal) end, Procs),
    -    timer:now_diff(Stop, Start).

    +bang(N) when integer(N) -> + Procs = spawn_procs(N), + RMsgs = lists:map(fun (P) -> {done, P} end, Procs), + Start = now(), + send_procs(Procs, {procs, Procs, self()}), + receive_msgs(RMsgs), + Stop = now(), + lists:foreach(fun (P) -> exit(P, normal) end, Procs), + timer:now_diff(Stop, Start).

    diff --git a/prs/8803/lib/tools-4.0/doc/html/make.html b/prs/8803/lib/tools-4.0/doc/html/make.html index 7c3ecf905bccb..812af65c4b9b9 100644 --- a/prs/8803/lib/tools-4.0/doc/html/make.html +++ b/prs/8803/lib/tools-4.0/doc/html/make.html @@ -142,8 +142,8 @@

    the first match is used. For example, the following Emakefile means that file1 should be compiled with the options [debug_info,{i,"../foo"}], while all other files in the current directory should be compiled with only the -debug_info flag.

    {'file1',[debug_info,{i,"../foo"}]}.
    -{'*',[debug_info]}.

    +debug_info flag.

    {'file1',[debug_info,{i,"../foo"}]}.
    +{'*',[debug_info]}.

    diff --git a/prs/8803/lib/tools-4.0/doc/html/notes.html b/prs/8803/lib/tools-4.0/doc/html/notes.html index 6c1b5b2f240af..94b60f51ada27 100644 --- a/prs/8803/lib/tools-4.0/doc/html/notes.html +++ b/prs/8803/lib/tools-4.0/doc/html/notes.html @@ -137,25 +137,25 @@

    Fixed Bugs and Malfunctions

    -
    • Dialyzer warnings due to type specs added in dbg have been eliminated.

      Own Id: OTP-18860

    • In Erlang/OTP 26, doing a cover analysis on the line level would return multiple entries for lines on which multiple functions were defined.

      For example, consider this module:

      -module(foo).
      --export([bar/0, baz/0]).
      +
      • Dialyzer warnings due to type specs added in dbg have been eliminated.

        Own Id: OTP-18860

      • In Erlang/OTP 26, doing a cover analysis on the line level would return multiple entries for lines on which multiple functions were defined.

        For example, consider this module:

        -module(foo).
        +-export([bar/0, baz/0]).
         
        -bar() -> ok. baz() -> not_ok.

        In Erlang/OTP 26, analysing on the line level would return two entries -for line 4:

        1> cover:compile_module(foo).
        -{ok,foo}
        -2> foo:bar().
        +bar() -> ok. baz() -> not_ok.

        In Erlang/OTP 26, analysing on the line level would return two entries +for line 4:

        1> cover:compile_module(foo).
        +{ok,foo}
        +2> foo:bar().
         ok
        -3> cover:analyse(foo, coverage, line).
        -{ok,[{{foo,4},{1,0}},{{foo,4},{0,1}}]}
        -4> cover:analyse(foo, calls, line).
        -{ok,[{{foo,4},1},{{foo,4},0}]}

        In Erlang/OTP 27, there will only be a single entry for line 4:

        1> cover:compile_module(foo).
        -{ok,foo}
        -2> foo:bar().
        +3> cover:analyse(foo, coverage, line).
        +{ok,[{{foo,4},{1,0}},{{foo,4},{0,1}}]}
        +4> cover:analyse(foo, calls, line).
        +{ok,[{{foo,4},1},{{foo,4},0}]}

        In Erlang/OTP 27, there will only be a single entry for line 4:

        1> cover:compile_module(foo).
        +{ok,foo}
        +2> foo:bar().
         ok
        -3> cover:analyse(foo, coverage, line).
        -{ok,[{{foo,4},{1,0}}]}
        -4> cover:analyse(foo, calls, line).
        -{ok,[{{foo,4},1}]}

        Own Id: OTP-18998 Aux Id: GH-8159, PR-8182

      • Fixed align command in emacs mode.

        Own Id: OTP-19026 Aux Id: PR-8155

      +3> cover:analyse(foo, coverage, line). +{ok,[{{foo,4},{1,0}}]} +4> cover:analyse(foo, calls, line). +{ok,[{{foo,4},1}]}

      Own Id: OTP-18998 Aux Id: GH-8159, PR-8182

    • Fixed align command in emacs mode.

      Own Id: OTP-19026 Aux Id: PR-8155

    @@ -168,12 +168,12 @@

    """. "a\nb\nc"

    Adjacent string literals without intervening white space is now a syntax error, to avoid possible confusion with triple-quoted strings. For example:

    1> "abc""xyz".
     "xyz".
    -* 1:6: adjacent string literals without intervening white space

    POTENTIAL INCOMPATIBILITY

    Own Id: OTP-18750 Aux Id: OTP-18746, PR-7313, PR-7451

  • There is a new tool tprof, which combines the functionality of eprof and cprof under one interface and adds heap profiling. It also has functionality to help with profiling process hierarchies.

    Example:

    1> tprof:profile(lists, seq, [1, 16], #{type => call_memory}).
    +* 1:6: adjacent string literals without intervening white space

    POTENTIAL INCOMPATIBILITY

    Own Id: OTP-18750 Aux Id: OTP-18746, PR-7313, PR-7451

  • There is a new tool tprof, which combines the functionality of eprof and cprof under one interface and adds heap profiling. It also has functionality to help with profiling process hierarchies.

    Example:

    1> tprof:profile(lists, seq, [1, 16], #{type => call_memory}).
     
     ****** Process <0.92.0>  --  100.00% of total *** 
    -FUNCTION          CALLS  WORDS  PER CALL  [     %]
    -lists:seq_loop/3      5     32      6.40  [100.00]
    -                            32            [ 100.0]
    +FUNCTION          CALLS  WORDS  PER CALL  [     %]
    +lists:seq_loop/3      5     32      6.40  [100.00]
    +                            32            [ 100.0]
     ok

    Own Id: OTP-18756 Aux Id: PR-6639

  • Native coverage support has been implemented in the JIT. It will automatically be used by the cover tool to reduce the execution overhead when running cover-compiled code.

    There are also new APIs to support native coverage without using the cover tool.

    To instrument code for native coverage it must be compiled with the line_coverage option.

    To enable native coverage in the runtime system, start it like so:

    $ erl +JPcover true

    There are also the following new functions for supporting native coverage:

    Own Id: OTP-18856 Aux Id: PR-7856

  • The documentation has been migrated to use Markdown and ExDoc.

    Own Id: OTP-18955 Aux Id: PR-8026

  • Improved the align command in emacs mode.

    Own Id: OTP-19080 Aux Id: PR-8288

  • diff --git a/prs/8803/lib/tools-4.0/doc/html/search.html b/prs/8803/lib/tools-4.0/doc/html/search.html index 3be83af99fa17..4fb54c2acc0fd 100644 --- a/prs/8803/lib/tools-4.0/doc/html/search.html +++ b/prs/8803/lib/tools-4.0/doc/html/search.html @@ -122,7 +122,7 @@

    - +